static void my_bus_exit(void) { device_unregister(&my_bus); bus_unregister(&my_bus_type); }
void sensors_unregister(struct device *dev) { device_unregister(dev); }
static void omap_dss_unregister_device(struct omap_dss_device *dssdev) { device_unregister(&dssdev->dev); }
void sys_device_unregister(struct sys_device * sysdev) { if (sysdev) device_unregister(&sysdev->dev); }
/** * zfcp_unit_enqueue - enqueue unit to unit list of a port. * @port: pointer to port where unit is added * @fcp_lun: FCP LUN of unit to be enqueued * Returns: pointer to enqueued unit on success, ERR_PTR on error * Locks: config_mutex must be held to serialize changes to the unit list * * Sets up some unit internal structures and creates sysfs entry. */ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun) { struct zfcp_unit *unit; read_lock_irq(&zfcp_data.config_lock); if (zfcp_get_unit_by_lun(port, fcp_lun)) { read_unlock_irq(&zfcp_data.config_lock); return ERR_PTR(-EINVAL); } read_unlock_irq(&zfcp_data.config_lock); unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); if (!unit) return ERR_PTR(-ENOMEM); atomic_set(&unit->refcount, 0); init_waitqueue_head(&unit->remove_wq); INIT_WORK(&unit->scsi_work, zfcp_scsi_scan_work); unit->port = port; unit->fcp_lun = fcp_lun; if (dev_set_name(&unit->sysfs_device, "0x%016llx", (unsigned long long) fcp_lun)) { kfree(unit); return ERR_PTR(-ENOMEM); } unit->sysfs_device.parent = &port->sysfs_device; unit->sysfs_device.release = zfcp_sysfs_unit_release; dev_set_drvdata(&unit->sysfs_device, unit); /* mark unit unusable as long as sysfs registration is not complete */ atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); spin_lock_init(&unit->latencies.lock); unit->latencies.write.channel.min = 0xFFFFFFFF; unit->latencies.write.fabric.min = 0xFFFFFFFF; unit->latencies.read.channel.min = 0xFFFFFFFF; unit->latencies.read.fabric.min = 0xFFFFFFFF; unit->latencies.cmd.channel.min = 0xFFFFFFFF; unit->latencies.cmd.fabric.min = 0xFFFFFFFF; if (device_register(&unit->sysfs_device)) { put_device(&unit->sysfs_device); return ERR_PTR(-EINVAL); } if (sysfs_create_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs)) { device_unregister(&unit->sysfs_device); return ERR_PTR(-EINVAL); } zfcp_unit_get(unit); write_lock_irq(&zfcp_data.config_lock); list_add_tail(&unit->list, &port->unit_list_head); atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); write_unlock_irq(&zfcp_data.config_lock); zfcp_port_get(port); return unit; }
static int rpmsg_remove_device(struct device *dev, void *data) { device_unregister(dev); return 0; }
static void __exit camera_detector_exit(void) { detect_print("Bye, camera detect driver exit\n"); device_unregister(&camera_detector_device); }
/** * amba_device_add - add a previously allocated AMBA device structure * @dev: AMBA device allocated by amba_device_alloc * @parent: resource parent for this devices resources * * Claim the resource, and read the device cell ID if not already * initialized. Register the AMBA device with the Linux device * manager. */ int amba_device_add(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; int i, ret; WARN_ON(dev->irq[0] == (unsigned int)-1); WARN_ON(dev->irq[1] == (unsigned int)-1); ret = request_resource(parent, &dev->res); if (ret) goto err_out; /* Hard-coded primecell ID instead of plug-n-play */ if (dev->periphid != 0) goto skip_probe; /* * Dynamically calculate the size of the resource * and use this for iomap */ size = resource_size(&dev->res); tmp = ioremap(dev->res.start, size); if (!tmp) { ret = -ENOMEM; goto err_release; } // ret = amba_get_enable_pclk(dev); ret = 0; if (ret == 0) { u32 pid, cid; /* * Read pid and cid based on size of resource * they are located at end of region */ for (pid = 0, i = 0; i < 4; i++) pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8); for (cid = 0, i = 0; i < 4; i++) cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8); // amba_put_disable_pclk(dev); if (cid == AMBA_CID) dev->periphid = pid; if (!dev->periphid) ret = -ENODEV; } iounmap(tmp); if (ret) goto err_release; skip_probe: ret = device_add(&dev->dev); if (ret) goto err_release; if (dev->irq[0]) ret = device_create_file(&dev->dev, &dev_attr_irq0); if (ret == 0 && dev->irq[1]) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; device_unregister(&dev->dev); err_release: release_resource(&dev->res); err_out: return ret; }
static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct asus_oled_dev *odev = NULL; int retval = -ENOMEM; uint16_t dev_width = 0; oled_pack_mode_t pack_mode = PACK_MODE_LAST; const struct oled_dev_desc_str * dev_desc = oled_dev_desc_table; const char *desc = 0; if (id == 0) { // Even possible? Just to make sure... dev_err(&interface->dev, "No usb_device_id provided!\n"); return -ENODEV; } for (; dev_desc->idVendor; dev_desc++) { if (dev_desc->idVendor == id->idVendor && dev_desc->idProduct == id->idProduct) { dev_width = dev_desc->devWidth; desc = dev_desc->devDesc; pack_mode = dev_desc->packMode; break; } } if ( !desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) { dev_err(&interface->dev, "Missing or incomplete device description!\n"); return -ENODEV; } odev = kzalloc(sizeof(struct asus_oled_dev), GFP_KERNEL); if (odev == NULL) { dev_err(&interface->dev, "Out of memory\n"); return -ENOMEM; } odev->udev = usb_get_dev(udev); odev->pic_mode = ASUS_OLED_STATIC; odev->dev_width = dev_width; odev->pack_mode = pack_mode; odev->height = 0; odev->width = 0; odev->x_shift = 0; odev->y_shift = 0; odev->buf_offs = 0; odev->buf_size = 0; odev->last_val = 0; odev->buf = NULL; odev->enabled = 1; odev->dev = 0; usb_set_intfdata (interface, odev); if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)))) { goto err_files; } if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)))) { goto err_files; } odev->dev = device_create(oled_class, &interface->dev, MKDEV(0,0), NULL,"oled_%d", ++oled_num); if (IS_ERR(odev->dev)) { retval = PTR_ERR(odev->dev); goto err_files; } dev_set_drvdata(odev->dev, odev); if ( (retval = device_create_file(odev->dev, &dev_attr_enabled))) { goto err_class_enabled; } if ( (retval = device_create_file(odev->dev, &dev_attr_picture))) { goto err_class_picture; } dev_info(&interface->dev, "Attached Asus OLED device: %s [width %u, pack_mode %d]\n", desc, odev->dev_width, odev->pack_mode); if (start_off) enable_oled(odev, 0); return 0; err_class_picture: device_remove_file(odev->dev, &dev_attr_picture); err_class_enabled: device_remove_file(odev->dev, &dev_attr_enabled); device_unregister(odev->dev); err_files: device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)); device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)); usb_set_intfdata (interface, NULL); usb_put_dev(odev->udev); kfree(odev); return retval; }
struct qcom_glink *qcom_glink_smem_register(struct device *parent, struct device_node *node) { struct glink_smem_pipe *rx_pipe; struct glink_smem_pipe *tx_pipe; struct qcom_glink *glink; struct device *dev; u32 remote_pid; __le32 *descs; size_t size; int ret; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return ERR_PTR(-ENOMEM); dev->parent = parent; dev->of_node = node; dev->release = qcom_glink_smem_release; dev_set_name(dev, "%s:%s", node->parent->name, node->name); ret = device_register(dev); if (ret) { pr_err("failed to register glink edge\n"); put_device(dev); return ERR_PTR(ret); } ret = of_property_read_u32(dev->of_node, "qcom,remote-pid", &remote_pid); if (ret) { dev_err(dev, "failed to parse qcom,remote-pid\n"); goto err_put_dev; } rx_pipe = devm_kzalloc(dev, sizeof(*rx_pipe), GFP_KERNEL); tx_pipe = devm_kzalloc(dev, sizeof(*tx_pipe), GFP_KERNEL); if (!rx_pipe || !tx_pipe) { ret = -ENOMEM; goto err_put_dev; } ret = qcom_smem_alloc(remote_pid, SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, 32); if (ret && ret != -EEXIST) { dev_err(dev, "failed to allocate glink descriptors\n"); goto err_put_dev; } descs = qcom_smem_get(remote_pid, SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, &size); if (IS_ERR(descs)) { dev_err(dev, "failed to acquire xprt descriptor\n"); ret = PTR_ERR(descs); goto err_put_dev; } if (size != 32) { dev_err(dev, "glink descriptor of invalid size\n"); ret = -EINVAL; goto err_put_dev; } tx_pipe->tail = &descs[0]; tx_pipe->head = &descs[1]; rx_pipe->tail = &descs[2]; rx_pipe->head = &descs[3]; ret = qcom_smem_alloc(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0, SZ_16K); if (ret && ret != -EEXIST) { dev_err(dev, "failed to allocate TX fifo\n"); goto err_put_dev; } tx_pipe->fifo = qcom_smem_get(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0, &tx_pipe->native.length); if (IS_ERR(tx_pipe->fifo)) { dev_err(dev, "failed to acquire TX fifo\n"); ret = PTR_ERR(tx_pipe->fifo); goto err_put_dev; } rx_pipe->native.avail = glink_smem_rx_avail; rx_pipe->native.peak = glink_smem_rx_peak; rx_pipe->native.advance = glink_smem_rx_advance; rx_pipe->remote_pid = remote_pid; tx_pipe->native.avail = glink_smem_tx_avail; tx_pipe->native.write = glink_smem_tx_write; tx_pipe->remote_pid = remote_pid; *rx_pipe->tail = 0; *tx_pipe->head = 0; glink = qcom_glink_native_probe(dev, GLINK_FEATURE_INTENT_REUSE, &rx_pipe->native, &tx_pipe->native, false); if (IS_ERR(glink)) { ret = PTR_ERR(glink); goto err_put_dev; } return glink; err_put_dev: device_unregister(dev); return ERR_PTR(ret); }
void gio_device_unregister(struct gio_device *giodev) { device_unregister(&giodev->dev); }
static void snd_devm_unregister_child(struct device *dev, void *res) { struct device *childdev = *(struct device **)res; device_unregister(childdev); }
int __init rpi_power_switch_init(void) { int ret = 0; old_pm_power_off = pm_power_off; pm_power_off = rpi_power_switch_power_off; pr_info("Adafruit Industries' power switch driver v%s\n", RPI_POWER_SWITCH_VERSION); INIT_DELAYED_WORK(&initiate_shutdown_work, initiate_shutdown); /* Register our own class for the power switch */ ret = class_register(&power_switch_class); if (ret < 0) { pr_err("%s: Unable to register class\n", power_switch_class.name); goto out0; } /* Create devices for each PWM present */ switch_dev = device_create(&power_switch_class, &platform_bus, MKDEV(0, 0), NULL, "pswitch%u", 0); if (IS_ERR(switch_dev)) { pr_err("%s: device_create failed\n", power_switch_class.name); ret = PTR_ERR(switch_dev); goto out1; } ret = sysfs_create_group(&switch_dev->kobj, &rpi_power_switch_attribute_group); if (ret < 0) { pr_err("%s: create_group failed\n", power_switch_class.name); goto out2; } /* GPIO register memory must be mapped before doing any direct * accesses such as changing GPIO alt functions or changing GPIO * pull ups or pull downs. */ gpio_reg = ioremap(GPIO_BASE, 1024); /* Set the specified pin as a GPIO input */ SET_GPIO_INPUT(gpio_pin); /* Set the pin as a pulldown. Most pins should default to having * pulldowns, and this seems most intuitive. */ set_gpio_pull(gpio_pin, GPIO_PULL_UP); gpio_request(gpio_pin, "Power switch"); gpio_direction_input(gpio_pin); /* The targeted polarity should be the opposite of the current value. * I.e. we want the pin to transition to this state in order to * initiate a shutdown. */ gpio_pol = !gpio_get_value(gpio_pin); /* Request an interrupt to fire when the pin transitions to our * desired state. */ ret = request_irq(__gpio_to_irq(gpio_pin), power_isr, gpio_pol?IRQF_TRIGGER_RISING:IRQF_TRIGGER_FALLING, "Power button", NULL); if (ret) { pr_err("Unable to request IRQ\n"); goto out3; } return 0; /* Error handling */ out3: sysfs_remove_group(&switch_dev->kobj,&rpi_power_switch_attribute_group); out2: device_unregister(switch_dev); out1: class_unregister(&power_switch_class); out0: iounmap(gpio_reg); pm_power_off = old_pm_power_off; return ret; }
/** * led_classdev_register - register a new object of led_classdev class. * @parent: The device to register. * @led_cdev: the led_classdev structure for this device. */ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) { int rc; led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, "%s", led_cdev->name); if (IS_ERR(led_cdev->dev)) return PTR_ERR(led_cdev->dev); /* register the attributes */ rc = device_create_file(led_cdev->dev, &led_class_attrs[2]); if (rc) goto err_out; #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); #endif /* add to the list of leds */ down_write(&leds_list_lock); list_add_tail(&led_cdev->node, &leds_list); up_write(&leds_list_lock); if (!led_cdev->max_brightness) led_cdev->max_brightness = LED_FULL; rc = device_create_file(led_cdev->dev, &led_class_attrs[3]); if (rc) goto err_out_attr_max; led_update_brightness(led_cdev); #ifdef CONFIG_LEDS_TRIGGERS #ifndef SUPPORT_LCD_ACL_CTL rc = device_create_file(led_cdev->dev, &led_class_attrs[4]); #else rc = device_create_file(led_cdev->dev, &led_class_attrs[5]); #endif if (rc) goto err_out_led_list; led_trigger_set_default(led_cdev); #endif #if 1 // Archer custom feature /* register the attributes */ rc = device_create_file(led_cdev->dev, &led_class_attrs[1]); if (rc) goto err_out; led_update_lcd_gamma(led_cdev); #ifdef SUPPORT_LCD_ACL_CTL /* register the attributes */ rc = device_create_file(led_cdev->dev, &led_class_attrs[4]); if (rc) goto err_out; lcd_update_ACL_state(led_cdev); #endif rc = device_create_file(led_cdev->dev, &led_class_attrs[0]); if (rc) goto err_out; led_update_flashlight(led_cdev); #endif printk(KERN_INFO "Registered led device: %s\n", led_cdev->name); return 0; #ifdef CONFIG_LEDS_TRIGGERS err_out_led_list: device_remove_file(led_cdev->dev, &led_class_attrs[3]); #endif err_out_attr_max: device_remove_file(led_cdev->dev, &led_class_attrs[2]); device_remove_file(led_cdev->dev, &led_class_attrs[1]); #ifdef SUPPORT_LCD_ACL_CTL device_remove_file(led_cdev->dev, &led_class_attrs[4]); #endif list_del(&led_cdev->node); err_out: device_unregister(led_cdev->dev); return rc; }
/** * amba_device_register - register an AMBA device * @dev: AMBA device to register * @parent: parent memory resource * * Setup the AMBA device, reading the cell ID if present. * Claim the resource, and register the AMBA device with * the Linux device manager. */ int amba_device_register(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; int i, ret; device_initialize(&dev->dev); /* * Copy from device_add */ if (dev->dev.init_name) { dev_set_name(&dev->dev, "%s", dev->dev.init_name); dev->dev.init_name = NULL; } dev->dev.release = amba_device_release; dev->dev.bus = &amba_bustype; dev->dev.dma_mask = &dev->dma_mask; dev->res.name = dev_name(&dev->dev); if (!dev->dev.coherent_dma_mask && dev->dma_mask) dev_warn(&dev->dev, "coherent dma mask is unset\n"); ret = request_resource(parent, &dev->res); if (ret) goto err_out; /* * Dynamically calculate the size of the resource * and use this for iomap */ size = resource_size(&dev->res); tmp = ioremap(dev->res.start, size); if (!tmp) { ret = -ENOMEM; goto err_release; } ret = amba_get_enable_pclk(dev); if (ret == 0) { u32 pid, cid; /* * Read pid and cid based on size of resource * they are located at end of region */ for (pid = 0, i = 0; i < 4; i++) pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8); for (cid = 0, i = 0; i < 4; i++) cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8); amba_put_disable_pclk(dev); if (cid == AMBA_CID) dev->periphid = pid; if (!dev->periphid) ret = -ENODEV; } iounmap(tmp); if (ret) goto err_release; ret = device_add(&dev->dev); if (ret) goto err_release; if (dev->irq[0] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq0); if (ret == 0 && dev->irq[1] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; device_unregister(&dev->dev); err_release: release_resource(&dev->res); err_out: return ret; }
void ide_unregister(unsigned int index) { ide_drive_t *drive; ide_hwif_t *hwif, *g; static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ ide_hwgroup_t *hwgroup; int irq_count = 0, unit; BUG_ON(index >= MAX_HWIFS); BUG_ON(in_interrupt()); BUG_ON(irqs_disabled()); down(&ide_cfg_sem); spin_lock_irq(&ide_lock); hwif = &ide_hwifs[index]; if (!hwif->present) goto abort; for (unit = 0; unit < MAX_DRIVES; ++unit) { drive = &hwif->drives[unit]; if (!drive->present) continue; spin_unlock_irq(&ide_lock); device_unregister(&drive->gendev); wait_for_completion(&drive->gendev_rel_comp); spin_lock_irq(&ide_lock); } hwif->present = 0; spin_unlock_irq(&ide_lock); ide_proc_unregister_port(hwif); hwgroup = hwif->hwgroup; /* * free the irq if we were the only hwif using it */ g = hwgroup->hwif; do { if (g->irq == hwif->irq) ++irq_count; g = g->next; } while (g != hwgroup->hwif); if (irq_count == 1) free_irq(hwif->irq, hwgroup); spin_lock_irq(&ide_lock); /* * Note that we only release the standard ports, * and do not even try to handle any extra ports * allocated for weird IDE interface chipsets. */ ide_hwif_release_regions(hwif); /* * Remove us from the hwgroup, and free * the hwgroup if we were the only member */ if (hwif->next == hwif) { BUG_ON(hwgroup->hwif != hwif); kfree(hwgroup); } else { /* There is another interface in hwgroup. * Unlink us, and set hwgroup->drive and ->hwif to * something sane. */ g = hwgroup->hwif; while (g->next != hwif) g = g->next; g->next = hwif->next; if (hwgroup->hwif == hwif) { /* Chose a random hwif for hwgroup->hwif. * It's guaranteed that there are no drives * left in the hwgroup. */ BUG_ON(hwgroup->drive != NULL); hwgroup->hwif = g; } BUG_ON(hwgroup->hwif == hwif); } /* More messed up locking ... */ spin_unlock_irq(&ide_lock); device_unregister(&hwif->gendev); wait_for_completion(&hwif->gendev_rel_comp); /* * Remove us from the kernel's knowledge */ blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS); kfree(hwif->sg_table); unregister_blkdev(hwif->major, hwif->name); spin_lock_irq(&ide_lock); if (hwif->dma_base) { (void) ide_release_dma(hwif); hwif->dma_base = 0; hwif->dma_master = 0; hwif->dma_command = 0; hwif->dma_vendor1 = 0; hwif->dma_status = 0; hwif->dma_vendor3 = 0; hwif->dma_prdtable = 0; hwif->extra_base = 0; hwif->extra_ports = 0; } /* copy original settings */ tmp_hwif = *hwif; /* restore hwif data to pristine status */ init_hwif_data(hwif, index); init_hwif_default(hwif, index); ide_hwif_restore(hwif, &tmp_hwif); abort: spin_unlock_irq(&ide_lock); up(&ide_cfg_sem); }
/** * amba_device_unregister - unregister an AMBA device * @dev: AMBA device to remove * * Remove the specified AMBA device from the Linux device * manager. All files associated with this object will be * destroyed, and device drivers notified that the device has * been removed. The AMBA device's resources including * the amba_device structure will be freed once all * references to it have been dropped. */ void amba_device_unregister(struct amba_device *dev) { device_unregister(&dev->dev); }
/*----------------------------------------------------------------------------- * This func is used to create all the necessary stuff, bind * the fixed phy driver and register all it on the mdio_bus_type. * speed is either 10 or 100, duplex is boolean. * number is used to create multiple fixed PHYs, so that several devices can * utilize them simultaneously. *-----------------------------------------------------------------------------*/ static int fixed_mdio_register_device(int number, int speed, int duplex) { struct mii_bus *new_bus; struct fixed_info *fixed; struct phy_device *phydev; int err = 0; struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL); if (NULL == dev) return -ENOMEM; new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); if (NULL == new_bus) { kfree(dev); return -ENOMEM; } fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL); if (NULL == fixed) { kfree(dev); kfree(new_bus); return -ENOMEM; } fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL); fixed->regs_num = MII_REGS_NUM; fixed->phy_status.speed = speed; fixed->phy_status.duplex = duplex; fixed->phy_status.link = 1; new_bus->name = "Fixed MII Bus", new_bus->read = &fixed_mii_read, new_bus->write = &fixed_mii_write, new_bus->reset = &fixed_mii_reset, /*set up workspace*/ fixed_mdio_update_regs(fixed); new_bus->priv = fixed; new_bus->dev = dev; dev_set_drvdata(dev, new_bus); /* create phy_device and register it on the mdio bus */ phydev = phy_device_create(new_bus, 0, 0); /* Put the phydev pointer into the fixed pack so that bus read/write code could be able to access for instance attached netdev. Well it doesn't have to do so, only in case of utilizing user-specified link-update... */ fixed->phydev = phydev; if(NULL == phydev) { err = -ENOMEM; goto device_create_fail; } phydev->irq = -1; phydev->dev.bus = &mdio_bus_type; if(number) snprintf(phydev->dev.bus_id, BUS_ID_SIZE, "fixed_%d@%d:%d", number, speed, duplex); else snprintf(phydev->dev.bus_id, BUS_ID_SIZE, "fixed@%d:%d", speed, duplex); phydev->bus = new_bus; err = device_register(&phydev->dev); if(err) { printk(KERN_ERR "Phy %s failed to register\n", phydev->dev.bus_id); goto bus_register_fail; } /* the mdio bus has phy_id match... In order not to do it artificially, we are binding the driver here by hand; it will be the same for all the fixed phys anyway. */ down_write(&phydev->dev.bus->subsys.rwsem); phydev->dev.driver = &fixed_mdio_driver.driver; err = phydev->dev.driver->probe(&phydev->dev); if(err < 0) { printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id); up_write(&phydev->dev.bus->subsys.rwsem); goto probe_fail; } device_bind_driver(&phydev->dev); up_write(&phydev->dev.bus->subsys.rwsem); return 0; probe_fail: device_unregister(&phydev->dev); bus_register_fail: kfree(phydev); device_create_fail: kfree(dev); kfree(new_bus); kfree(fixed); return err; }
static int register_attributes(void) { int ret = 0; hi->htc_accessory_class = class_create(THIS_MODULE, "htc_accessory"); if (IS_ERR(hi->htc_accessory_class)) { ret = PTR_ERR(hi->htc_accessory_class); hi->htc_accessory_class = NULL; goto err_create_class; } /* Register headset attributes */ hi->headset_dev = device_create(hi->htc_accessory_class, NULL, 0, "%s", "headset"); if (unlikely(IS_ERR(hi->headset_dev))) { ret = PTR_ERR(hi->headset_dev); hi->headset_dev = NULL; goto err_create_headset_device; } ret = device_create_file(hi->headset_dev, &dev_attr_headset_state); if (ret) goto err_create_headset_state_device_file; ret = device_create_file(hi->headset_dev, &dev_attr_headset_1wire); if (ret) goto err_create_headset_state_device_file; /* Register TTY attributes */ hi->tty_dev = device_create(hi->htc_accessory_class, NULL, 0, "%s", "tty"); if (unlikely(IS_ERR(hi->tty_dev))) { ret = PTR_ERR(hi->tty_dev); hi->tty_dev = NULL; goto err_create_tty_device; } ret = device_create_file(hi->tty_dev, &dev_attr_tty); if (ret) goto err_create_tty_device_file; /* Register FM attributes */ hi->fm_dev = device_create(hi->htc_accessory_class, NULL, 0, "%s", "fm"); if (unlikely(IS_ERR(hi->fm_dev))) { ret = PTR_ERR(hi->fm_dev); hi->fm_dev = NULL; goto err_create_fm_device; } ret = device_create_file(hi->fm_dev, &dev_attr_fm); if (ret) goto err_create_fm_device_file; /* Register debug attributes */ hi->debug_dev = device_create(hi->htc_accessory_class, NULL, 0, "%s", "debug"); if (unlikely(IS_ERR(hi->debug_dev))) { ret = PTR_ERR(hi->debug_dev); hi->debug_dev = NULL; goto err_create_debug_device; } /* register the attributes */ ret = device_create_file(hi->debug_dev, &dev_attr_debug); if (ret) goto err_create_debug_device_file; return 0; err_create_debug_device_file: device_unregister(hi->debug_dev); err_create_debug_device: device_remove_file(hi->fm_dev, &dev_attr_fm); err_create_fm_device_file: device_unregister(hi->fm_dev); err_create_fm_device: device_remove_file(hi->tty_dev, &dev_attr_tty); err_create_tty_device_file: device_unregister(hi->tty_dev); err_create_tty_device: device_remove_file(hi->headset_dev, &dev_attr_headset_state); err_create_headset_state_device_file: device_unregister(hi->headset_dev); err_create_headset_device: class_destroy(hi->htc_accessory_class); err_create_class: return ret; }
/** * cx_device_unregister - Unregister a device. * @cx_dev: part/mfg id for the device */ int cx_device_unregister(struct cx_dev *cx_dev) { put_device(&cx_dev->dev); device_unregister(&cx_dev->dev); return 0; }
static void __exit my_exit(void) { release_firmware(fw); device_unregister(&dev); printk(KERN_INFO "release firwmare and unregistered device\n"); }
/** * zfcp_unit_enqueue - enqueue unit to unit list of a port. * @port: pointer to port where unit is added * @fcp_lun: FCP LUN of unit to be enqueued * Returns: pointer to enqueued unit on success, ERR_PTR on error * * Sets up some unit internal structures and creates sysfs entry. */ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun) { struct zfcp_unit *unit; int retval = -ENOMEM; get_device(&port->sysfs_device); unit = zfcp_get_unit_by_lun(port, fcp_lun); if (unit) { put_device(&unit->sysfs_device); retval = -EEXIST; goto err_out; } unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); if (!unit) goto err_out; unit->port = port; unit->fcp_lun = fcp_lun; unit->sysfs_device.parent = &port->sysfs_device; unit->sysfs_device.release = zfcp_unit_release; if (dev_set_name(&unit->sysfs_device, "0x%016llx", (unsigned long long) fcp_lun)) { kfree(unit); goto err_out; } retval = -EINVAL; INIT_WORK(&unit->scsi_work, zfcp_scsi_scan); spin_lock_init(&unit->latencies.lock); unit->latencies.write.channel.min = 0xFFFFFFFF; unit->latencies.write.fabric.min = 0xFFFFFFFF; unit->latencies.read.channel.min = 0xFFFFFFFF; unit->latencies.read.fabric.min = 0xFFFFFFFF; unit->latencies.cmd.channel.min = 0xFFFFFFFF; unit->latencies.cmd.fabric.min = 0xFFFFFFFF; if (device_register(&unit->sysfs_device)) { put_device(&unit->sysfs_device); goto err_out; } if (sysfs_create_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs)) goto err_out_put; write_lock_irq(&port->unit_list_lock); list_add_tail(&unit->list, &port->unit_list); write_unlock_irq(&port->unit_list_lock); atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); return unit; err_out_put: device_unregister(&unit->sysfs_device); err_out: put_device(&port->sysfs_device); return ERR_PTR(retval); }
/** * sys_unregister_root - remove subordinate root from tree * @root: subordinate root in question. * * We only decrement the reference count on @root->sysdev * and @root->dev. * If both are 0, they will be cleaned up by the core. */ void sys_unregister_root(struct sys_root *root) { device_unregister(&root->sysdev); device_unregister(&root->dev); }
/** * zfcp_device_unregister - remove port, unit from system * @dev: reference to device which is to be removed * @grp: related reference to attribute group * * Helper function to unregister port, unit from system */ void zfcp_device_unregister(struct device *dev, const struct attribute_group *grp) { sysfs_remove_group(&dev->kobj, grp); device_unregister(dev); }
/** * zfcp_port_enqueue - enqueue port to port list of adapter * @adapter: adapter where remote port is added * @wwpn: WWPN of the remote port to be enqueued * @status: initial status for the port * @d_id: destination id of the remote port to be enqueued * Returns: pointer to enqueued port on success, ERR_PTR on error * Locks: config_mutex must be held to serialize changes to the port list * * All port internal structures are set up and the sysfs entry is generated. * d_id is used to enqueue ports with a well known address like the Directory * Service for nameserver lookup. */ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, u32 status, u32 d_id) { struct zfcp_port *port; read_lock_irq(&zfcp_data.config_lock); if (zfcp_get_port_by_wwpn(adapter, wwpn)) { read_unlock_irq(&zfcp_data.config_lock); return ERR_PTR(-EINVAL); } read_unlock_irq(&zfcp_data.config_lock); port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); if (!port) return ERR_PTR(-ENOMEM); init_waitqueue_head(&port->remove_wq); INIT_LIST_HEAD(&port->unit_list_head); INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup); INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work); INIT_WORK(&port->rport_work, zfcp_scsi_rport_work); port->adapter = adapter; port->d_id = d_id; port->wwpn = wwpn; port->rport_task = RPORT_NONE; /* mark port unusable as long as sysfs registration is not complete */ atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); atomic_set(&port->refcount, 0); if (dev_set_name(&port->sysfs_device, "0x%016llx", (unsigned long long)wwpn)) { kfree(port); return ERR_PTR(-ENOMEM); } port->sysfs_device.parent = &adapter->ccw_device->dev; port->sysfs_device.release = zfcp_sysfs_port_release; dev_set_drvdata(&port->sysfs_device, port); if (device_register(&port->sysfs_device)) { put_device(&port->sysfs_device); return ERR_PTR(-EINVAL); } if (sysfs_create_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs)) { device_unregister(&port->sysfs_device); return ERR_PTR(-EINVAL); } zfcp_port_get(port); write_lock_irq(&zfcp_data.config_lock); list_add_tail(&port->list, &adapter->port_list_head); atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); write_unlock_irq(&zfcp_data.config_lock); zfcp_adapter_get(adapter); return port; }
/** * zfcp_port_enqueue - enqueue port to port list of adapter * @adapter: adapter where remote port is added * @wwpn: WWPN of the remote port to be enqueued * @status: initial status for the port * @d_id: destination id of the remote port to be enqueued * Returns: pointer to enqueued port on success, ERR_PTR on error * * All port internal structures are set up and the sysfs entry is generated. * d_id is used to enqueue ports with a well known address like the Directory * Service for nameserver lookup. */ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, u32 status, u32 d_id) { struct zfcp_port *port; int retval = -ENOMEM; kref_get(&adapter->ref); port = zfcp_get_port_by_wwpn(adapter, wwpn); if (port) { put_device(&port->sysfs_device); retval = -EEXIST; goto err_out; } port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); if (!port) goto err_out; rwlock_init(&port->unit_list_lock); INIT_LIST_HEAD(&port->unit_list); INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup); INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work); INIT_WORK(&port->rport_work, zfcp_scsi_rport_work); port->adapter = adapter; port->d_id = d_id; port->wwpn = wwpn; port->rport_task = RPORT_NONE; port->sysfs_device.parent = &adapter->ccw_device->dev; port->sysfs_device.release = zfcp_port_release; if (dev_set_name(&port->sysfs_device, "0x%016llx", (unsigned long long)wwpn)) { kfree(port); goto err_out; } retval = -EINVAL; if (device_register(&port->sysfs_device)) { put_device(&port->sysfs_device); goto err_out; } if (sysfs_create_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs)) goto err_out_put; write_lock_irq(&adapter->port_list_lock); list_add_tail(&port->list, &adapter->port_list); write_unlock_irq(&adapter->port_list_lock); atomic_set_mask(status | ZFCP_STATUS_COMMON_RUNNING, &port->status); return port; err_out_put: device_unregister(&port->sysfs_device); err_out: zfcp_ccw_adapter_put(adapter); return ERR_PTR(retval); }
void ipack_device_unregister(struct ipack_device *dev) { device_unregister(&dev->dev); }
int xenbus_probe_node(struct xen_bus_type *bus, const char *type, const char *nodename) { int err; struct xenbus_device *xendev; size_t stringlen; char *tmpstring; enum xenbus_state state = xenbus_read_driver_state(nodename); if (bus->error) return bus->error; if (state != XenbusStateInitialising) { /* Device is not new, so ignore it. This can happen if a device is going away after switching to Closed. */ return 0; } stringlen = strlen(nodename) + 1 + strlen(type) + 1; xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL); if (!xendev) return -ENOMEM; xendev->state = XenbusStateInitialising; /* Copy the strings into the extra space. */ tmpstring = (char *)(xendev + 1); strcpy(tmpstring, nodename); xendev->nodename = tmpstring; tmpstring += strlen(tmpstring) + 1; strcpy(tmpstring, type); xendev->devicetype = tmpstring; init_completion(&xendev->down); xendev->dev.parent = &bus->dev; xendev->dev.bus = &bus->bus; xendev->dev.release = xenbus_dev_release; err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename); if (err) goto fail; /* Register with generic device framework. */ err = device_register(&xendev->dev); if (err) goto fail; err = device_create_file(&xendev->dev, &dev_attr_nodename); if (err) goto unregister; err = device_create_file(&xendev->dev, &dev_attr_devtype); if (err) goto unregister; err = device_create_file(&xendev->dev, &dev_attr_modalias); if (err) goto unregister; return 0; unregister: device_remove_file(&xendev->dev, &dev_attr_nodename); device_remove_file(&xendev->dev, &dev_attr_devtype); device_unregister(&xendev->dev); fail: kfree(xendev); return err; }
static void omap_dss_bus_unregister(void) { device_unregister(&dss_bus); bus_unregister(&dss_bus_type); }
/* * try to add a new ccwgroup device for one driver * argc and argv[] are a list of bus_id's of devices * belonging to the driver. */ int ccwgroup_create(struct device *root, unsigned int creator_id, struct ccw_driver *cdrv, int argc, char *argv[]) { struct ccwgroup_device *gdev; int i; int rc; if (argc > 256) /* disallow dumb users */ return -EINVAL; gdev = kmalloc(sizeof(*gdev) + argc*sizeof(gdev->cdev[0]), GFP_KERNEL); if (!gdev) return -ENOMEM; memset(gdev, 0, sizeof(*gdev) + argc*sizeof(gdev->cdev[0])); atomic_set(&gdev->onoff, 0); for (i = 0; i < argc; i++) { gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); /* all devices have to be of the same type in * order to be grouped */ if (!gdev->cdev[i] || gdev->cdev[i]->id.driver_info != gdev->cdev[0]->id.driver_info) { rc = -EINVAL; goto free_dev; } /* Don't allow a device to belong to more than one group. */ if (gdev->cdev[i]->dev.driver_data) { rc = -EINVAL; goto free_dev; } gdev->cdev[i]->dev.driver_data = gdev; } gdev->creator_id = creator_id; gdev->count = argc; gdev->dev = (struct device ) { .bus = &ccwgroup_bus_type, .parent = root, .release = ccwgroup_release, }; snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s", gdev->cdev[0]->dev.bus_id); rc = device_register(&gdev->dev); if (rc) goto free_dev; get_device(&gdev->dev); rc = device_create_file(&gdev->dev, &dev_attr_ungroup); if (rc) { device_unregister(&gdev->dev); goto error; } rc = __ccwgroup_create_symlinks(gdev); if (!rc) { put_device(&gdev->dev); return 0; } device_remove_file(&gdev->dev, &dev_attr_ungroup); device_unregister(&gdev->dev); error: for (i = 0; i < argc; i++) if (gdev->cdev[i]) { put_device(&gdev->cdev[i]->dev); gdev->cdev[i]->dev.driver_data = NULL; } put_device(&gdev->dev); return rc; free_dev: for (i = 0; i < argc; i++) if (gdev->cdev[i]) { if (gdev->cdev[i]->dev.driver_data == gdev) gdev->cdev[i]->dev.driver_data = NULL; put_device(&gdev->cdev[i]->dev); } kfree(gdev); return rc; }