static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) { struct brcmf_fw *fwctx = ctx; int ret; brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); if (!fw) goto fail; /* only requested code so done here */ if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) { fwctx->done(fwctx->dev, fw, NULL, 0); kfree(fwctx); return; } fwctx->code = fw; ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name, fwctx->dev, GFP_KERNEL, fwctx, brcmf_fw_request_nvram_done); if (!ret) return; brcmf_fw_request_nvram_done(NULL, fwctx); return; fail: brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); device_release_driver(fwctx->dev); kfree(fwctx); }
static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) { struct device *parent = aru->udev->dev.parent; struct usb_device *udev; /* * Store a copy of the usb_device pointer locally. * This is because device_release_driver initiates * ar9170_usb_disconnect, which in turn frees our * driver context (aru). */ udev = aru->udev; complete(&aru->firmware_loading_complete); /* unbind anything failed */ if (parent) down(&parent->sem); device_release_driver(&udev->dev); if (parent) up(&parent->sem); usb_put_dev(udev); }
/** * bus_remove_device - remove device from bus * @dev: device to be removed * * - Remove device from all interfaces. * - Remove symlink from bus' directory. * - Delete device from bus's list. * - Detach from its driver. * - Drop reference taken in bus_add_device(). */ void bus_remove_device(struct device *dev) { struct bus_type *bus = dev->bus; struct subsys_interface *sif; if (!bus) return; mutex_lock(&bus->p->mutex); list_for_each_entry(sif, &bus->p->interfaces, node) if (sif->remove_dev) sif->remove_dev(dev, sif); mutex_unlock(&bus->p->mutex); sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->bus->p->devices_kset->kobj, dev_name(dev)); device_remove_attrs(dev->bus, dev); if (klist_node_attached(&dev->p->knode_bus)) klist_del(&dev->p->knode_bus); pr_debug("bus: '%s': remove device %s\n", dev->bus->name, dev_name(dev)); device_release_driver(dev); bus_put(dev->bus); }
static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) { struct device *dev = &drive->gendev; int ret = 1; int err; device_release_driver(dev); /* FIXME: device can still be in use by previous driver */ strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); err = device_attach(dev); if (err < 0) printk(KERN_WARNING "IDE: %s: device_attach error: %d\n", __func__, err); drive->driver_req[0] = 0; if (dev->driver == NULL) { err = device_attach(dev); if (err < 0) printk(KERN_WARNING "IDE: %s: device_attach(2) error: %d\n", __func__, err); } if (dev->driver && !strcmp(dev->driver->name, driver)) ret = 0; return ret; }
static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw, void *nvram, u32 nvram_len) { struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie; struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo; struct brcmf_commonring **flowrings; int ret; u32 i; brcmf_pcie_attach(devinfo); ret = brcmf_pcie_download_fw_nvram(devinfo, fw, nvram, nvram_len); if (ret) goto fail; devinfo->state = BRCMFMAC_PCIE_STATE_UP; ret = brcmf_pcie_init_ringbuffers(devinfo); if (ret) goto fail; ret = brcmf_pcie_init_scratchbuffers(devinfo); if (ret) goto fail; brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); ret = brcmf_pcie_request_irq(devinfo); if (ret) goto fail; /* hook the commonrings in the bus structure. */ for (i = 0; i < BRCMF_NROF_COMMON_MSGRINGS; i++) bus->msgbuf->commonrings[i] = &devinfo->shared.commonrings[i]->commonring; flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(flowrings), GFP_KERNEL); if (!flowrings) goto fail; for (i = 0; i < devinfo->shared.nrof_flowrings; i++) flowrings[i] = &devinfo->shared.flowrings[i].commonring; bus->msgbuf->flowrings = flowrings; bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset; bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost; bus->msgbuf->nrof_flowrings = devinfo->shared.nrof_flowrings; init_waitqueue_head(&devinfo->mbdata_resp_wait); brcmf_pcie_intr_enable(devinfo); if (brcmf_pcie_attach_bus(bus->dev) == 0) return; brcmf_pcie_bus_console_read(devinfo); fail: device_release_driver(dev); }
static void carl9170_usb_firmware_failed(struct ar9170 *ar) { struct device *parent = ar->udev->dev.parent; struct usb_device *udev; /* * Store a copy of the usb_device pointer locally. * This is because device_release_driver initiates * carl9170_usb_disconnect, which in turn frees our * driver context (ar). */ udev = ar->udev; complete(&ar->fw_load_wait); /* unbind anything failed */ if (parent) device_lock(parent); device_release_driver(&udev->dev); if (parent) device_unlock(parent); usb_put_dev(udev); }
/** * device_reprobe - remove driver for a device and probe for a new driver * @dev: the device to reprobe * * This function detaches the attached driver (if any) for the given * device and restarts the driver probing process. It is intended * to use if probing criteria changed during a devices lifetime and * driver attachment should change accordingly. */ int device_reprobe(struct device *dev) { if (dev->driver) { if (dev->parent) /* Needed for USB */ down(&dev->parent->sem); device_release_driver(dev); if (dev->parent) up(&dev->parent->sem); } return bus_rescan_devices_helper(dev, NULL); }
/** * device_reprobe - remove driver for a device and probe for a new driver * @dev: the device to reprobe * * This function detaches the attached driver (if any) for the given * device and restarts the driver probing process. It is intended * to use if probing criteria changed during a devices lifetime and * driver attachment should change accordingly. */ int device_reprobe(struct device *dev) { if (dev->driver) { if (dev->parent) /* Needed for USB */ device_lock(dev->parent); device_release_driver(dev); if (dev->parent) device_unlock(dev->parent); } return bus_rescan_devices_helper(dev, NULL); }
/** * phy_detach - detach a PHY device from its network device * @phydev: target phy_device struct */ void phy_detach(struct phy_device *phydev) { phydev->attached_dev = NULL; /* If the device had no specific driver before (i.e. - it * was using the generic driver), we unbind the device * from the generic driver so that there's a chance a * real driver could be loaded */ if (phydev->dev.driver == &genphy_driver.driver) device_release_driver(&phydev->dev); }
/** called when module unloaded */ static void __exit mod_exit(void) { lpc313x_deinit_adc(); device_release_driver(driv_dev); device_destroy(driv_class,driv_number); class_destroy(driv_class); cdev_del(driv_object); unregister_chrdev_region(driv_number,1); dev_info(driv_dev, "[lpc313x_adc] driver unloaded\n"); }
/** * bus_remove_device - remove device from bus * @dev: device to be removed * * - Remove symlink from bus's directory. * - Delete device from bus's list. * - Detach from its driver. * - Drop reference taken in bus_add_device(). */ void bus_remove_device(struct device * dev) { if (dev->bus) { sysfs_remove_link(&dev->kobj, "bus"); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); klist_remove(&dev->knode_bus); pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); put_bus(dev->bus); } }
static void p54p_firmware_step2(const struct firmware *fw, void *context) { struct p54p_priv *priv = context; struct ieee80211_hw *dev = priv->common.hw; struct pci_dev *pdev = priv->pdev; int err; if (!fw) { dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n"); err = -ENOENT; goto out; } priv->firmware = fw; err = p54p_open(dev); if (err) goto out; err = p54_read_eeprom(dev); p54p_stop(dev); if (err) goto out; err = p54_register_common(dev, &pdev->dev); if (err) goto out; out: complete(&priv->fw_loaded); if (err) { struct device *parent = pdev->dev.parent; if (parent) device_lock(parent); /* * This will indirectly result in a call to p54p_remove. * Hence, we don't need to bother with freeing any * allocated ressources at all. */ device_release_driver(&pdev->dev); if (parent) device_unlock(parent); } pci_dev_put(pdev); }
static void pci_stop_dev(struct pci_dev *dev) { pci_pme_active(dev, false); if (dev->is_added) { pci_proc_detach_device(dev); pci_remove_sysfs_dev_files(dev); device_release_driver(&dev->dev); dev->is_added = 0; } if (dev->bus->self) pcie_aspm_exit_link_state(dev); }
static int umc_bus_pre_reset_helper(struct device *dev, void *data) { int ret = 0; if (dev->driver) { struct umc_dev *umc = to_umc_dev(dev); struct umc_driver *umc_drv = to_umc_driver(dev->driver); if (umc_drv->pre_reset) ret = umc_drv->pre_reset(umc); else device_release_driver(dev); } return ret; }
static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) { struct device *parent = aru->udev->dev.parent; complete(&aru->firmware_loading_complete); /* unbind anything failed */ if (parent) device_lock(parent); device_release_driver(&aru->udev->dev); if (parent) device_unlock(parent); usb_put_dev(aru->udev); }
void pci_stop_root_bus(struct pci_bus *bus) { struct pci_dev *child, *tmp; struct pci_host_bridge *host_bridge; if (!pci_is_root_bus(bus)) return; host_bridge = to_pci_host_bridge(bus->bridge); list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list) pci_stop_bus_device(child); /* stop the host bridge */ device_release_driver(&host_bridge->dev); }
/** * bus_remove_device - remove device from bus * @dev: device to be removed * * - Remove symlink from bus's directory. * - Delete device from bus's list. * - Detach from its driver. * - Drop reference taken in bus_add_device(). */ void bus_remove_device(struct device * dev) { if (dev->bus) { sysfs_remove_link(&dev->kobj, "subsystem"); remove_deprecated_bus_links(dev); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); if (dev->is_registered) { dev->is_registered = 0; klist_del(&dev->knode_bus); } pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); put_bus(dev->bus); } }
/** * bus_remove_device - remove device from bus * @dev: device to be removed * * - Remove symlink from bus's directory. * - Delete device from bus's list. * - Detach from its driver. * - Drop reference taken in bus_add_device(). */ void bus_remove_device(struct device *dev) { if (dev->bus) { sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->bus->p->devices_kset->kobj, dev_name(dev)); device_remove_attrs(dev->bus, dev); if (klist_node_attached(&dev->p->knode_bus)) klist_del(&dev->p->knode_bus); pr_debug("bus: '%s': remove device %s\n", dev->bus->name, dev_name(dev)); device_release_driver(dev); bus_put(dev->bus); } }
static ssize_t driver_unbind(struct device_driver *drv, const char *buf, size_t count) { struct bus_type *bus = get_bus(drv->bus); struct device *dev; int err = -ENODEV; dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); if (dev && dev->driver == drv) { device_release_driver(dev); err = count; } put_device(dev); put_bus(bus); return err; }
static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) { struct device *dev = &drive->gendev; int ret = 1; down_write(&dev->bus->subsys.rwsem); device_release_driver(dev); /* FIXME: device can still be in use by previous driver */ strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); device_attach(dev); drive->driver_req[0] = 0; if (dev->driver == NULL) device_attach(dev); if (dev->driver && !strcmp(dev->driver->name, driver)) ret = 0; up_write(&dev->bus->subsys.rwsem); return ret; }
static void brcmf_usb_probe_phase2(struct device *dev, int ret, struct brcmf_fw_request *fwreq) { struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; const struct firmware *fw; if (ret) goto error; brcmf_dbg(USB, "Start fw downloading\n"); fw = fwreq->items[BRCMF_USB_FW_CODE].binary; kfree(fwreq); ret = check_file(fw->data); if (ret < 0) { brcmf_err("invalid firmware\n"); release_firmware(fw); goto error; } devinfo->image = fw->data; devinfo->image_len = fw->size; ret = brcmf_usb_fw_download(devinfo); release_firmware(fw); if (ret) goto error; /* Attach to the common driver interface */ ret = brcmf_attach(devinfo->dev, devinfo->settings); if (ret) goto error; complete(&devinfo->dev_init_done); return; error: brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); complete(&devinfo->dev_init_done); device_release_driver(dev); }
static void acpi_processor_remove(struct acpi_device *device) { struct acpi_processor *pr; if (!device || !acpi_driver_data(device)) return; pr = acpi_driver_data(device); if (pr->id >= nr_cpu_ids) goto out; /* * The only reason why we ever get here is CPU hot-removal. The CPU is * already offline and the ACPI device removal locking prevents it from * being put back online at this point. * * Unbind the driver from the processor device and detach it from the * ACPI companion object. */ device_release_driver(pr->dev); acpi_unbind_one(pr->dev); /* Clean up. */ per_cpu(processor_device_array, pr->id) = NULL; per_cpu(processors, pr->id) = NULL; cpu_maps_update_begin(); cpu_hotplug_begin(); /* Remove the CPU. */ arch_unregister_cpu(pr->id); acpi_unmap_lsapic(pr->id); cpu_hotplug_done(); cpu_maps_update_done(); try_offline_node(cpu_to_node(pr->id)); out: free_cpumask_var(pr->throttling.shared_cpu_map); kfree(pr); }
static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) { struct brcmf_fw *fwctx = ctx; u32 nvram_length = 0; void *nvram = NULL; u8 *data = NULL; size_t data_len; bool raw_nvram; brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); if (fw && fw->data) { data = (u8 *)fw->data; data_len = fw->size; raw_nvram = false; } else { data = bcm47xx_nvram_get_contents(&data_len); if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) goto fail; raw_nvram = true; } if (data) nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, fwctx->domain_nr, fwctx->bus_nr); if (raw_nvram) bcm47xx_nvram_release_contents(data); if (fw) release_firmware(fw); if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) goto fail; fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length); kfree(fwctx); return; fail: brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); release_firmware(fwctx->code); device_release_driver(fwctx->dev); kfree(fwctx); }
/* Manually detach a device from its associated driver. */ static ssize_t driver_unbind(struct device_driver *drv, const char *buf, size_t count) { struct bus_type *bus = bus_get(drv->bus); struct device *dev; int err = -ENODEV; dev = bus_find_device_by_name(bus, NULL, buf); if (dev && dev->driver == drv) { if (dev->parent) /* Needed for USB */ device_lock(dev->parent); device_release_driver(dev); if (dev->parent) device_unlock(dev->parent); err = count; } put_device(dev); bus_put(bus); return err; }
static ssize_t driver_unbind(struct device_driver *drv, const char *buf, size_t count) { struct bus_type *bus = bus_get(drv->bus); struct device *dev; int err = -ENODEV; dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); if (dev && dev->driver == drv) { if (dev->parent) /* Needed for USB */ down(&dev->parent->sem); device_release_driver(dev); if (dev->parent) up(&dev->parent->sem); err = count; } put_device(dev); bus_put(bus); return err; }
static void rtl_usb_unbind(struct ieee80211_hw *hw) { struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); struct device *parent = rtlusb->udev->dev.parent; struct usb_device *udev; /* Store a copy of the usb_device pointer locally. * This is because device_release_driver initiates * rtl_usb_disconnect, which in turn frees our * driver context (rtl_priv). */ udev = rtlusb->udev; /* unbind anything failed */ if (parent) device_lock(parent); device_release_driver(&udev->dev); if (parent) device_unlock(parent); }
/** * check_plugged_state_change - Check change in an MC object's plugged state * * @mc_dev: pointer to the fsl-mc device for a given MC object * @obj_desc: pointer to the MC object's descriptor in the MC * * If the plugged state has changed from unplugged to plugged, the fsl-mc * device is bound to the corresponding device driver. * If the plugged state has changed from plugged to unplugged, the fsl-mc * device is unbound from the corresponding device driver. */ static void check_plugged_state_change(struct fsl_mc_device *mc_dev, struct dprc_obj_desc *obj_desc) { int error; u32 plugged_flag_at_mc = obj_desc->state & DPRC_OBJ_STATE_PLUGGED; if (plugged_flag_at_mc != (mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED)) { if (plugged_flag_at_mc) { mc_dev->obj_desc.state |= DPRC_OBJ_STATE_PLUGGED; error = device_attach(&mc_dev->dev); if (error < 0) { dev_err(&mc_dev->dev, "device_attach() failed: %d\n", error); } } else { mc_dev->obj_desc.state &= ~DPRC_OBJ_STATE_PLUGGED; device_release_driver(&mc_dev->dev); } } }
static void brcmf_usb_probe_phase2(struct device *dev, const struct firmware *fw, void *nvram, u32 nvlen) { struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_usbdev_info *devinfo; int ret; brcmf_dbg(USB, "Start fw downloading\n"); devinfo = bus->bus_priv.usb->devinfo; ret = check_file(fw->data); if (ret < 0) { brcmf_err("invalid firmware\n"); release_firmware(fw); goto error; } devinfo->image = fw->data; devinfo->image_len = fw->size; ret = brcmf_usb_fw_download(devinfo); release_firmware(fw); if (ret) goto error; ret = brcmf_usb_bus_setup(devinfo); if (ret) goto error; mutex_unlock(&devinfo->dev_init_lock); return; error: brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); mutex_unlock(&devinfo->dev_init_lock); device_release_driver(dev); }
/** * usb_driver_release_interface - unbind a driver from an interface * @driver: the driver to be unbound * @iface: the interface from which it will be unbound * * This can be used by drivers to release an interface without waiting * for their disconnect() methods to be called. In typical cases this * also causes the driver disconnect() method to be called. * * This call is synchronous, and may not be used in an interrupt context. * Callers must own the device lock and the driver model's usb_bus_type.subsys * writelock. So driver disconnect() entries don't need extra locking, * but other call contexts may need to explicitly claim those locks. */ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface) { struct device *dev = &iface->dev; /* this should never happen, don't release something that's not ours */ if (!dev->driver || dev->driver != &driver->driver) return; /* don't release from within disconnect() */ if (iface->condition != USB_INTERFACE_BOUND) return; /* don't release if the interface hasn't been added yet */ if (device_is_registered(dev)) { iface->condition = USB_INTERFACE_UNBINDING; device_release_driver(dev); } dev->driver = NULL; usb_set_intfdata(iface, NULL); iface->condition = USB_INTERFACE_UNBOUND; mark_quiesced(iface); }
static int intel_th_child_remove(struct device *dev, void *data) { device_release_driver(dev); return 0; }