/** * bus_add_device - add device to bus * @dev: device being added * * - Add the device to its bus's list of devices. * - Create link to device's bus. */ int bus_add_device(struct device * dev) { struct bus_type * bus = get_bus(dev->bus); int error = 0; if (bus) { pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); error = device_add_attrs(bus, dev); if (error) goto out_put; error = sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); if (error) goto out_id; error = sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); if (error) goto out_subsys; error = make_deprecated_bus_links(dev); if (error) goto out_deprecated; } return 0; out_deprecated: sysfs_remove_link(&dev->kobj, "subsystem"); out_subsys: sysfs_remove_link(&bus->devices.kobj, dev->bus_id); out_id: device_remove_attrs(bus, dev); out_put: put_bus(dev->bus); return error; }
int uwb_pal_register(struct uwb_pal *pal) { struct uwb_rc *rc = pal->rc; int ret; if (pal->device) { ret = sysfs_create_link(&pal->device->kobj, &rc->uwb_dev.dev.kobj, "uwb_rc"); if (ret < 0) return ret; ret = sysfs_create_link(&rc->uwb_dev.dev.kobj, &pal->device->kobj, pal->name); if (ret < 0) { sysfs_remove_link(&pal->device->kobj, "uwb_rc"); return ret; } } pal->debugfs_dir = uwb_dbg_create_pal_dir(pal); mutex_lock(&rc->uwb_dev.mutex); list_add(&pal->node, &rc->pals); mutex_unlock(&rc->uwb_dev.mutex); return 0; }
/** * bus_add_device - add device to bus * @dev: device being added * * - Add device's bus attributes. * - Create links to device's bus. * - Add the device to its bus's list of devices. */ int bus_add_device(struct device *dev) { struct bus_type *bus = bus_get(dev->bus); int error = 0; if (bus) { pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev)); error = device_add_attrs(bus, dev); if (error) goto out_put; error = sysfs_create_link(&bus->p->devices_kset->kobj, &dev->kobj, dev_name(dev)); if (error) goto out_id; error = sysfs_create_link(&dev->kobj, &dev->bus->p->subsys.kobj, "subsystem"); if (error) goto out_subsys; error = make_deprecated_bus_links(dev); if (error) goto out_deprecated; klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); } return 0; out_deprecated: sysfs_remove_link(&dev->kobj, "subsystem"); out_subsys: sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); out_id: device_remove_attrs(bus, dev); out_put: bus_put(dev->bus); return error; }
static inline int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev) { char str[8]; int i, rc; for (i = 0; i < gdev->count; i++) { rc = sysfs_create_link(&gdev->cdev[i]->dev.kobj, &gdev->dev.kobj, "group_device"); if (rc) { for (--i; i >= 0; i--) sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device"); return rc; } } for (i = 0; i < gdev->count; i++) { sprintf(str, "cdev%d", i); rc = sysfs_create_link(&gdev->dev.kobj, &gdev->cdev[i]->dev.kobj, str); if (rc) { for (--i; i >= 0; i--) { sprintf(str, "cdev%d", i); sysfs_remove_link(&gdev->dev.kobj, str); } for (i = 0; i < gdev->count; i++) sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device"); return rc; } } return 0; }
static int link_peers(struct usb_port *left, struct usb_port *right) { struct usb_port *ss_port, *hs_port; int rc; if (left->peer == right && right->peer == left) return 0; if (left->peer || right->peer) { struct usb_port *lpeer = left->peer; struct usb_port *rpeer = right->peer; WARN(1, "failed to peer %s and %s (%s -> %p) (%s -> %p)\n", dev_name(&left->dev), dev_name(&right->dev), dev_name(&left->dev), lpeer, dev_name(&right->dev), rpeer); return -EBUSY; } rc = sysfs_create_link(&left->dev.kobj, &right->dev.kobj, "peer"); if (rc) return rc; rc = sysfs_create_link(&right->dev.kobj, &left->dev.kobj, "peer"); if (rc) { sysfs_remove_link(&left->dev.kobj, "peer"); return rc; } /* * We need to wake the HiSpeed port to make sure we don't race * setting ->peer with usb_port_runtime_suspend(). Otherwise we * may miss a suspend event for the SuperSpeed port. */ if (left->is_superspeed) { ss_port = left; WARN_ON(right->is_superspeed); hs_port = right; } else { ss_port = right; WARN_ON(!right->is_superspeed); hs_port = left; } pm_runtime_get_sync(&hs_port->dev); left->peer = right; right->peer = left; /* * The SuperSpeed reference is dropped when the HiSpeed port in * this relationship suspends, i.e. when it is safe to allow a * SuperSpeed connection to drop since there is no risk of a * device degrading to its powered-off HiSpeed connection. * * Also, drop the HiSpeed ref taken above. */ pm_runtime_get_sync(&ss_port->dev); pm_runtime_put(&hs_port->dev); return 0; }
/* TODO: register fan, cpu as the cooling devices */ static int yeeloong_thermal_init(struct device *dev) { int ret; if (!dev) return -1; yeeloong_thermal_cdev = thermal_cooling_device_register("LCD", dev, &video_cooling_ops); if (IS_ERR(yeeloong_thermal_cdev)) { ret = PTR_ERR(yeeloong_thermal_cdev); return ret; } ret = sysfs_create_link(&dev->kobj, &yeeloong_thermal_cdev->device.kobj, "thermal_cooling"); if (ret) { printk(KERN_ERR "Create sysfs link\n"); return ret; } ret = sysfs_create_link(&yeeloong_thermal_cdev->device.kobj, &dev->kobj, "device"); if (ret) { printk(KERN_ERR "Create sysfs link\n"); return ret; } return 0; }
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) { int trips = 0; int result; acpi_status status; int i; if (tz->trips.critical.flags.valid) trips++; if (tz->trips.hot.flags.valid) trips++; if (tz->trips.passive.flags.valid) trips++; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; i++, trips++); if (tz->trips.passive.flags.valid) tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, &acpi_thermal_zone_ops, NULL, tz->trips.passive.tsp*100, tz->polling_frequency*100); else tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, &acpi_thermal_zone_ops, NULL, 0, tz->polling_frequency*100); if (IS_ERR(tz->thermal_zone)) return -ENODEV; result = sysfs_create_link(&tz->device->dev.kobj, &tz->thermal_zone->device.kobj, "thermal_zone"); if (result) return result; result = sysfs_create_link(&tz->thermal_zone->device.kobj, &tz->device->dev.kobj, "device"); if (result) return result; status = acpi_attach_data(tz->device->handle, acpi_bus_private_data_handler, tz->thermal_zone); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Error attaching device data\n"); return -ENODEV; } tz->tz_enabled = 1; dev_info(&tz->device->dev, "registered as thermal_zone%d\n", tz->thermal_zone->id); return 0; }
static int acpi_fan_add(struct acpi_device *device) { int result = 0; int state = 0; struct thermal_cooling_device *cdev; if (!device) return -EINVAL; strcpy(acpi_device_name(device), "Fan"); strcpy(acpi_device_class(device), ACPI_FAN_CLASS); result = acpi_bus_get_power(device->handle, &state); if (result) { printk(KERN_ERR PREFIX "Reading power state\n"); goto end; } device->flags.force_power_state = 1; acpi_bus_set_power(device->handle, state); device->flags.force_power_state = 0; cdev = thermal_cooling_device_register("Fan", device, &fan_cooling_ops); if (IS_ERR(cdev)) { result = PTR_ERR(cdev); goto end; } dev_dbg(&device->dev, "registered as cooling_device%d\n", cdev->id); device->driver_data = cdev; result = sysfs_create_link(&device->dev.kobj, &cdev->device.kobj, "thermal_cooling"); if (result) dev_err(&device->dev, "Failed to create sysfs link " "'thermal_cooling'\n"); result = sysfs_create_link(&cdev->device.kobj, &device->dev.kobj, "device"); if (result) dev_err(&device->dev, "Failed to create sysfs link " "'device'\n"); result = acpi_fan_add_fs(device); if (result) goto end; printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), !device->power.state ? "on" : "off"); end: return result; }
/* * acpi_processor_start() is called by the cpu_hotplug_notifier func: * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the * root cause seem to be that acpi_processor_uninstall_hotplug_notify() * is in the module_exit (__exit) func. Allowing acpi_processor_start() * to not be in __cpuinit section, but being called from __cpuinit funcs * via __ref looks like the right thing to do here. */ static __ref int acpi_processor_start(struct acpi_processor *pr) { struct acpi_device *device = per_cpu(processor_device_array, pr->id); int result = 0; #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); acpi_processor_load_module(pr); #endif acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) acpi_processor_power_init(pr); pr->cdev = thermal_cooling_device_register("Processor", device, &processor_cooling_ops); if (IS_ERR(pr->cdev)) { result = PTR_ERR(pr->cdev); goto err_power_exit; } dev_dbg(&device->dev, "registered as cooling_device%d\n", pr->cdev->id); result = sysfs_create_link(&device->dev.kobj, &pr->cdev->device.kobj, "thermal_cooling"); if (result) { dev_err(&device->dev, "Failed to create sysfs link 'thermal_cooling'\n"); goto err_thermal_unregister; } result = sysfs_create_link(&pr->cdev->device.kobj, &device->dev.kobj, "device"); if (result) { dev_err(&pr->cdev->device, "Failed to create sysfs link 'device'\n"); goto err_remove_sysfs_thermal; } return 0; err_remove_sysfs_thermal: sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); err_thermal_unregister: thermal_cooling_device_unregister(pr->cdev); err_power_exit: acpi_processor_power_exit(pr); return result; }
static int acpi_pss_perf_init(struct acpi_processor *pr, struct acpi_device *device) { int result = 0; acpi_processor_ppc_has_changed(pr, 0); acpi_processor_get_throttling_info(pr); if (pr->flags.throttling) pr->flags.limit = 1; pr->cdev = thermal_cooling_device_register("Processor", device, &processor_cooling_ops); if (IS_ERR(pr->cdev)) { result = PTR_ERR(pr->cdev); return result; } dev_dbg(&device->dev, "registered as cooling_device%d\n", pr->cdev->id); result = sysfs_create_link(&device->dev.kobj, &pr->cdev->device.kobj, "thermal_cooling"); if (result) { dev_err(&device->dev, "Failed to create sysfs link 'thermal_cooling'\n"); goto err_thermal_unregister; } result = sysfs_create_link(&pr->cdev->device.kobj, &device->dev.kobj, "device"); if (result) { dev_err(&pr->cdev->device, "Failed to create sysfs link 'device'\n"); goto err_remove_sysfs_thermal; } return 0; err_remove_sysfs_thermal: sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); err_thermal_unregister: thermal_cooling_device_unregister(pr->cdev); return result; }
static int driver_sysfs_add(struct device *dev) { int ret; ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj, kobject_name(&dev->kobj)); if (ret == 0) { ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj, "driver"); if (ret) sysfs_remove_link(&dev->driver->p->kobj, kobject_name(&dev->kobj)); } return ret; }
void gk20a_create_sysfs(struct platform_device *dev) { struct gk20a *g = get_gk20a(dev); int error = 0; error |= device_create_file(&dev->dev, &dev_attr_elcg_enable); error |= device_create_file(&dev->dev, &dev_attr_blcg_enable); error |= device_create_file(&dev->dev, &dev_attr_slcg_enable); error |= device_create_file(&dev->dev, &dev_attr_ptimer_scale_factor); error |= device_create_file(&dev->dev, &dev_attr_elpg_enable); error |= device_create_file(&dev->dev, &dev_attr_emc3d_ratio); error |= device_create_file(&dev->dev, &dev_attr_counters); error |= device_create_file(&dev->dev, &dev_attr_counters_reset); error |= device_create_file(&dev->dev, &dev_attr_load); error |= device_create_file(&dev->dev, &dev_attr_railgate_delay); error |= device_create_file(&dev->dev, &dev_attr_clockgate_delay); #ifdef CONFIG_PM_RUNTIME error |= device_create_file(&dev->dev, &dev_attr_force_idle); #endif error |= device_create_file(&dev->dev, &dev_attr_aelpg_param); error |= device_create_file(&dev->dev, &dev_attr_aelpg_enable); error |= device_create_file(&dev->dev, &dev_attr_allow_all); error |= device_create_file(&dev->dev, &dev_attr_tpc_fs_mask); if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev)) error |= sysfs_create_link(&g->host1x_dev->dev.kobj, &dev->dev.kobj, dev_name(&dev->dev)); if (error) dev_err(&dev->dev, "Failed to create sysfs attributes!\n"); }
int hci_register_sysfs(struct hci_dev *hdev) { struct device *dev = &hdev->dev; unsigned int i; int err; BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); dev->bus = &bt_bus; dev->parent = hdev->parent; strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); dev->release = bt_release; dev_set_drvdata(dev, hdev); err = device_register(dev); if (err < 0) return err; for (i = 0; bt_attrs[i]; i++) if (device_create_file(dev, bt_attrs[i]) < 0) BT_ERR("Failed to create device attribute"); if (sysfs_create_link(&bt_class->subsys.kobj, &dev->kobj, kobject_name(&dev->kobj)) < 0) BT_ERR("Failed to create class symlink"); return 0; }
/** * bus_add_device - add device to bus * @dev: device being added * * - Add the device to its bus's list of devices. * - Create link to device's bus. */ int bus_add_device(struct device * dev) { struct bus_type * bus = get_bus(dev->bus); int error = 0; if (bus) { pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); error = device_add_attrs(bus, dev); if (!error) { sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); } } return error; }
int o2cb_sys_init(void) { int ret; o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj); if (!o2cb_kset) return -ENOMEM; /* * Create this symlink for backwards compatibility with old * versions of ocfs2-tools which look for things in /sys/o2cb. */ ret = sysfs_create_link(NULL, &o2cb_kset->kobj, "o2cb"); if (ret) goto error; ret = sysfs_create_group(&o2cb_kset->kobj, &o2cb_attr_group); if (ret) goto error; ret = mlog_sys_init(o2cb_kset); if (ret) goto error; return 0; error: kset_unregister(o2cb_kset); return ret; }
/* * Register a tape device and return a pointer to the cdev structure. * * device * The pointer to the struct device of the physical (base) device. * drivername * The pointer to the drivers name for it's character devices. * dev * The intended major/minor number. The major number may be 0 to * get a dynamic major number. * fops * The pointer to the drivers file operations for the tape device. * devname * The pointer to the name of the character device. */ struct tape_class_device *register_tape_dev( struct device * device, dev_t dev, struct file_operations *fops, char * device_name, char * mode_name) { struct tape_class_device * tcd; int rc; char * s; tcd = kmalloc(sizeof(struct tape_class_device), GFP_KERNEL); if (!tcd) return ERR_PTR(-ENOMEM); memset(tcd, 0, sizeof(struct tape_class_device)); strncpy(tcd->device_name, device_name, TAPECLASS_NAME_LEN); for (s = strchr(tcd->device_name, '/'); s; s = strchr(s, '/')) *s = '!'; strncpy(tcd->mode_name, mode_name, TAPECLASS_NAME_LEN); for (s = strchr(tcd->mode_name, '/'); s; s = strchr(s, '/')) *s = '!'; tcd->char_device = cdev_alloc(); if (!tcd->char_device) { rc = -ENOMEM; goto fail_with_tcd; } tcd->char_device->owner = fops->owner; tcd->char_device->ops = fops; tcd->char_device->dev = dev; rc = cdev_add(tcd->char_device, tcd->char_device->dev, 1); if (rc) goto fail_with_cdev; tcd->class_device = class_device_create( tape_class, NULL, tcd->char_device->dev, device, "%s", tcd->device_name ); sysfs_create_link( &device->kobj, &tcd->class_device->kobj, tcd->mode_name ); return tcd; fail_with_cdev: cdev_del(tcd->char_device); fail_with_tcd: kfree(tcd); return ERR_PTR(rc); }
static int __init mykobj_init(void) { printk("kboj init\n"); int ret = 0; obj1 = kzalloc(sizeof(struct my_kobj),GFP_KERNEL); obj2 = kzalloc(sizeof(struct my_kobj), GFP_KERNEL); obj2->val = 2; my_type.release = obj_release; my_type.default_attrs = my_attrs; my_type.sysfs_ops = &my_sysfsops; kobject_init_and_add(&obj1->kobj, &my_type, NULL, "mykobj1"); kobject_init_and_add(&obj2->kobj, &my_type, &obj1->kobj, "mykobj2"); kobject_init_and_add(&obj3.kobj, &my_type, &obj2->kobj, "mykobj3"); ret = sysfs_create_file(&obj1->kobj, &length_attr); ret = sysfs_create_bin_file(&obj1->kobj, &bin_attri); ret = sysfs_create_link(&obj1->kobj, &obj3.kobj,"link_file"); return ret; }
static int create_sysfs_interfaces(struct yas_state *st) { int res; st->sensor_class = class_create(THIS_MODULE, "htc_g_sensor"); if (st->sensor_class == NULL) goto custom_class_error; st->sensor_dev = device_create(st->sensor_class, NULL, 0, "%s", "kxtj2"); if (st->sensor_dev == NULL) goto custom_device_error; res = sysfs_create_link( &st->sensor_dev->kobj, &st->indio_dev->dev.kobj, "iio"); if (res < 0) { E("link create error, res = %d\n", res); goto err_fail_sysfs_create_link; } return 0; err_fail_sysfs_create_link: if (st->sensor_dev) device_destroy(st->sensor_class, 0); custom_device_error: if (st->sensor_class) class_destroy(st->sensor_class); custom_class_error: dev_err(&st->client->dev, "%s:Unable to create class\n", __func__); return -1; }
/* * * edac_pci_create_sysfs * * Create the controls/attributes for the specified EDAC PCI device */ int edac_pci_create_sysfs(struct edac_pci_ctl_info *pci) { int err; struct kobject *edac_kobj = &pci->kobj; debugf0("%s() idx=%d\n", __func__, pci->pci_idx); /* create the top main EDAC PCI kobject, IF needed */ err = edac_pci_main_kobj_setup(); if (err) return err; /* Create this instance's kobject under the MAIN kobject */ err = edac_pci_create_instance_kobj(pci, pci->pci_idx); if (err) goto unregister_cleanup; err = sysfs_create_link(edac_kobj, &pci->dev->kobj, EDAC_PCI_SYMLINK); if (err) { debugf0("%s() sysfs_create_link() returned err= %d\n", __func__, err); goto symlink_fail; } return 0; /* Error unwind stack */ symlink_fail: edac_pci_unregister_sysfs_instance_kobj(pci); unregister_cleanup: edac_pci_main_kobj_teardown(); return err; }
int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info) { struct sys_device *dev = &chan->dev; char name[16]; int ret; dev->id = chan->vchan; dev->cls = &dma_sysclass; ret = sysdev_register(dev); if (ret) return ret; ret |= sysdev_create_file(dev, &attr_dev_id); ret |= sysdev_create_file(dev, &attr_count); ret |= sysdev_create_file(dev, &attr_mode); ret |= sysdev_create_file(dev, &attr_flags); ret |= sysdev_create_file(dev, &attr_config); if (unlikely(ret)) { dev_err(&info->pdev->dev, "Failed creating attrs\n"); return ret; } snprintf(name, sizeof(name), "dma%d", chan->chan); return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name); }
void register_disk(struct gendisk *disk) { struct device *ddev = disk_to_dev(disk); struct block_device *bdev; struct disk_part_iter piter; struct hd_struct *part; int err; #ifdef MY_ABC_HERE int error; #endif ddev->parent = disk->driverfs_dev; dev_set_name(ddev, disk->disk_name); /* delay uevents, until we scanned partition table */ dev_set_uevent_suppress(ddev, 1); if (device_add(ddev)) return; #ifdef MY_ABC_HERE if (ddev->parent) { char *class_name; class_name = make_class_name(ddev->class->name, &ddev->kobj); if (class_name) { error = sysfs_create_link(&ddev->parent->kobj, &ddev->kobj, class_name); } kfree(class_name); }
/** * device_bind_driver - bind a driver to one device. * @dev: device. * * Allow manual attachment of a driver to a device. * Caller must have already set @dev->driver. * * Note that this does not modify the bus reference count * nor take the bus's rwsem. Please verify those are accounted * for before calling this. (It is ok to call with no other effort * from a driver's probe() method.) * * This function must be called with @dev->sem held. */ void device_bind_driver(struct device * dev) { if (klist_node_attached(&dev->knode_driver)) return; pr_debug("bound device '%s' to driver '%s'\n", dev->bus_id, dev->driver->name); if (dev->bus) blocking_notifier_call_chain(&dev->bus->bus_notifier, BUS_NOTIFY_BOUND_DRIVER, dev); klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); sysfs_create_link(&dev->driver->kobj, &dev->kobj, kobject_name(&dev->kobj)); sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); }
/* * Add sysfs entries to ethernet device added to a bridge. * Creates a brport subdirectory with bridge attributes. * Puts symlink in bridge's brport subdirectory */ int dp_sysfs_add_if(struct dp_port *p) { struct kobject *kobj = vport_get_kobj(p->vport); struct datapath *dp = p->dp; struct brport_attribute **a; int err; /* Create /sys/class/net/<devname>/brport directory. */ if (!kobj) return -ENOENT; err = kobject_add(&p->kobj, kobj, SYSFS_BRIDGE_PORT_ATTR); if (err) goto err; /* Create symlink from /sys/class/net/<devname>/brport/bridge to * /sys/class/net/<bridgename>. */ err = sysfs_create_link(&p->kobj, vport_get_kobj(dp->ports[ODPP_LOCAL]->vport), SYSFS_BRIDGE_PORT_LINK); /* "bridge" */ if (err) goto err_del; /* Populate /sys/class/net/<devname>/brport directory with files. */ for (a = brport_attrs; *a; ++a) { err = sysfs_create_file(&p->kobj, &((*a)->attr)); if (err) goto err_del; } /* Create symlink from /sys/class/net/<bridgename>/brif/<devname> to * /sys/class/net/<devname>/brport. */ err = sysfs_create_link(&dp->ifobj, &p->kobj, vport_get_name(p->vport)); if (err) goto err_del; strcpy(p->linkname, vport_get_name(p->vport)); kobject_uevent(&p->kobj, KOBJ_ADD); return 0; err_del: kobject_del(&p->kobj); err: p->linkname[0] = 0; return err; }
int register_early_suspend_device(struct device *dev) { if (!early_suspend_kobj || !dev) return -ENODEV; return sysfs_create_link(early_suspend_kobj, &dev->kobj, dev_name(dev)); }
static int make_deprecated_bus_links(struct device *dev) { if (sysfs_deprecated) return sysfs_create_link(&dev->kobj, &dev->bus->p->subsys.kobj, "bus"); else return 0; }
static int edd_create_symlink_to_pcidev(struct edd_device *edev) { struct pci_dev *pci_dev = edd_get_pci_dev(edev); if (!pci_dev) return 1; return sysfs_create_link(&edev->kobj,&pci_dev->dev.kobj,"pci_dev"); }
int ath10k_thermal_register(struct ath10k *ar) { struct thermal_cooling_device *cdev; struct device *hwmon_dev; int ret; if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map)) return 0; cdev = thermal_cooling_device_register("ath10k_thermal", ar, &ath10k_thermal_ops); if (IS_ERR(cdev)) { ath10k_err(ar, "failed to setup thermal device result: %ld\n", PTR_ERR(cdev)); return -EINVAL; } ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj, "cooling_device"); if (ret) { ath10k_err(ar, "failed to create cooling device symlink\n"); goto err_cooling_destroy; } ar->thermal.cdev = cdev; ar->thermal.quiet_period = ATH10K_QUIET_PERIOD_DEFAULT; /* Do not register hwmon device when temperature reading is not * supported by firmware */ if (!(ar->wmi.ops->gen_pdev_get_temperature)) return 0; /* Avoid linking error on devm_hwmon_device_register_with_groups, I * guess linux/hwmon.h is missing proper stubs. */ if (!IS_REACHABLE(CONFIG_HWMON)) return 0; hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev, "ath10k_hwmon", ar, ath10k_hwmon_groups); if (IS_ERR(hwmon_dev)) { ath10k_err(ar, "failed to register hwmon device: %ld\n", PTR_ERR(hwmon_dev)); ret = -EINVAL; goto err_remove_link; } return 0; err_remove_link: sysfs_remove_link(&ar->dev->kobj, "cooling_device"); err_cooling_destroy: thermal_cooling_device_unregister(cdev); return ret; }
static int driver_sysfs_add(struct device *dev) { int ret; if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_BIND_DRIVER, dev); ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj, kobject_name(&dev->kobj)); if (ret == 0) { ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj, "driver"); if (ret) sysfs_remove_link(&dev->driver->p->kobj, kobject_name(&dev->kobj)); } return ret; }
static int macvtap_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); struct macvtap_dev *vlantap; struct device *classdev; dev_t devt; int err; char tap_name[IFNAMSIZ]; if (dev->rtnl_link_ops != &macvtap_link_ops) return NOTIFY_DONE; snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex); vlantap = netdev_priv(dev); switch (event) { case NETDEV_REGISTER: /* Create the device node here after the network device has * been registered but before register_netdevice has * finished running. */ err = tap_get_minor(macvtap_major, &vlantap->tap); if (err) return notifier_from_errno(err); devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); classdev = device_create(&macvtap_class, &dev->dev, devt, dev, tap_name); if (IS_ERR(classdev)) { tap_free_minor(macvtap_major, &vlantap->tap); return notifier_from_errno(PTR_ERR(classdev)); } err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj, tap_name); if (err) return notifier_from_errno(err); break; case NETDEV_UNREGISTER: /* vlan->minor == 0 if NETDEV_REGISTER above failed */ if (vlantap->tap.minor == 0) break; sysfs_remove_link(&dev->dev.kobj, tap_name); devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); device_destroy(&macvtap_class, devt); tap_free_minor(macvtap_major, &vlantap->tap); break; case NETDEV_CHANGE_TX_QUEUE_LEN: if (tap_queue_resize(&vlantap->tap)) return NOTIFY_BAD; break; } return NOTIFY_DONE; }
/* * Add sysfs entries to ethernet device added to a bridge. * Creates a brport subdirectory with bridge attributes. * Puts symlink in bridge's brif subdirectory */ int br_sysfs_addif(struct net_bridge_port *p) { struct net_bridge *br = p->br; const struct brport_attribute **a; int err; err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj, SYSFS_BRIDGE_PORT_LINK); if (err) return err; for (a = brport_attrs; *a; ++a) { err = sysfs_create_file(&p->kobj, &((*a)->attr)); if (err) return err; } strlcpy(p->sysfs_name, p->dev->name, IFNAMSIZ); return sysfs_create_link(br->ifobj, &p->kobj, p->sysfs_name); }