static ssize_t gpp_wp_show(struct device *dev, struct device_attribute *attr, char *buf) { struct mmc_card *card = mmc_dev_to_card(dev); int err; u8 wp_status = 0; if (card == NULL) return -ENODEV; device_lock(dev); if (gpp_wppart < EXT_CSD_PART_CONFIG_ACC_GP0) { device_unlock(dev); return -EINVAL; } err = mmc_wp_status(card, gpp_wppart, gpp_wpgroup, &wp_status); if (err) { device_unlock(dev); return err; } device_unlock(dev); return sprintf(buf, "%d\n", wp_status); }
/* * protect: 1 means permanent write protect. Right now only allow this * protection method */ static ssize_t gpp_wp_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { long protect; struct mmc_card *card = mmc_dev_to_card(dev); int err; if (card == NULL) return -ENODEV; if (kstrtol(buf, 10, &protect) != 0 || protect != (u32)protect) return -EINVAL; if (protect != PERMANENT_PROTECT) return -EINVAL; device_lock(dev); if (gpp_wppart != EXT_CSD_PART_CONFIG_ACC_GP0 || gpp_wpgroup != GPP_WPG0) { device_unlock(dev); return -EINVAL; } err = mmc_set_user_wp(card, gpp_wppart, gpp_wpgroup); if (err) { pr_err("%s: err to set write protect\n", __func__); n = err; } device_unlock(dev); return n; }
/* * Manually attach a device to a driver. * Note: the driver must want to bind to the device, * it is not possible to override the driver's id table. */ static ssize_t driver_bind(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 == NULL && driver_match_device(drv, dev)) { if (dev->parent) /* Needed for USB */ device_lock(dev->parent); device_lock(dev); err = driver_probe_device(drv, dev); device_unlock(dev); if (dev->parent) device_unlock(dev->parent); if (err > 0) { /* success */ err = count; } else if (err == 0) { /* driver didn't accept device */ err = -ENODEV; } } put_device(dev); bus_put(bus); return err; }
/** * driver_detach - detach driver from all devices it controls. * @drv: driver. */ void driver_detach(struct device_driver *drv) { struct device_private *dev_prv; struct device *dev; for (;;) { spin_lock(&drv->p->klist_devices.k_lock); if (list_empty(&drv->p->klist_devices.k_list)) { spin_unlock(&drv->p->klist_devices.k_lock); break; } dev_prv = list_entry(drv->p->klist_devices.k_list.prev, struct device_private, knode_driver.n_node); dev = dev_prv->device; get_device(dev); spin_unlock(&drv->p->klist_devices.k_lock); if (dev->parent) /* Needed for USB */ device_lock(dev->parent); device_lock(dev); if (dev->driver == drv) __device_release_driver(dev); device_unlock(dev); if (dev->parent) device_unlock(dev->parent); put_device(dev); } }
static int __driver_attach(struct device *dev, void *data) { struct device_driver *drv = data; /* * Lock device and try to bind to it. We drop the error * here and always return 0, because we need to keep trying * to bind to devices and some drivers will return an error * simply if it didn't support the device. * * driver_probe_device() will spit a warning if there * is an error. */ if (!driver_match_device(drv, dev)) return 0; if (dev->parent) /* Needed for USB */ device_lock(dev->parent); device_lock(dev); if (!dev->driver) driver_probe_device(drv, dev); device_unlock(dev); if (dev->parent) device_unlock(dev->parent); return 0; }
/** * eeh_report_failure - Tell device driver that device is dead. * @dev: PCI device * @userdata: return value * * This informs the device driver that the device is permanently * dead, and that no further recovery attempts will be made on it. */ static int eeh_report_failure(struct pci_dev *dev, void *userdata) { struct pci_driver *driver; device_lock(&dev->dev); dev->error_state = pci_channel_io_perm_failure; driver = eeh_pcid_get(dev); if (!driver) goto out; eeh_disable_irq(dev); if (!driver->err_handler || !driver->err_handler->error_detected) { eeh_pcid_put(dev); goto out; } driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); eeh_pcid_put(dev); out: device_unlock(&dev->dev); return 0; }
/** * eeh_report_resume - Tell device to resume normal operations * @dev: PCI device * @userdata: return value * * This routine must be called to notify the device driver that it * could resume so that the device driver can do some initialization * to make the recovered device work again. */ static int eeh_report_resume(struct pci_dev *dev, void *userdata) { struct pci_driver *driver; device_lock(&dev->dev); dev->error_state = pci_channel_io_normal; driver = eeh_pcid_get(dev); if (!driver) goto out; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->resume) { eeh_pcid_put(dev); goto out; } driver->err_handler->resume(dev); eeh_pcid_put(dev); out: device_unlock(&dev->dev); return 0; }
/** * eeh_report_reset - Tell device that slot has been reset * @dev: PCI device * @userdata: return value * * This routine must be called while EEH tries to reset particular * PCI device so that the associated PCI device driver could take * some actions, usually to save data the driver needs so that the * driver can work again while the device is recovered. */ static int eeh_report_reset(struct pci_dev *dev, void *userdata) { enum pci_ers_result rc, *res = userdata; struct pci_driver *driver; device_lock(&dev->dev); dev->error_state = pci_channel_io_normal; driver = eeh_pcid_get(dev); if (!driver) goto out; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->slot_reset) { eeh_pcid_put(dev); goto out; } rc = driver->err_handler->slot_reset(dev); if ((*res == PCI_ERS_RESULT_NONE) || (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc; if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; eeh_pcid_put(dev); out: device_unlock(&dev->dev); return 0; }
static int flush_regions_dimms(struct device *dev, void *data) { device_lock(dev); device_unlock(dev); device_for_each_child(dev, NULL, flush_namespaces); return 0; }
/* If this is the alerting device, notify its driver */ static int smbus_do_alert(struct device *dev, void *addrp) { struct i2c_client *client = i2c_verify_client(dev); struct alert_data *data = addrp; struct i2c_driver *driver; if (!client || client->addr != data->addr) return 0; if (client->flags & I2C_CLIENT_TEN) return 0; /* * Drivers should either disable alerts, or provide at least * a minimal handler. Lock so the driver won't change. */ device_lock(dev); if (client->dev.driver) { driver = to_i2c_driver(client->dev.driver); if (driver->alert) driver->alert(client, data->flag); else dev_warn(&client->dev, "no driver alert()!\n"); } else dev_dbg(&client->dev, "alert with no driver\n"); device_unlock(dev); /* Stop iterating after we find the device */ return -EBUSY; }
static ssize_t store_port_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; int power_on, port; int err; err = sscanf(buf, "%d %d", &power_on, &port); if (err < 2 || port < 0 || port > 3 || power_on < 0 || power_on > 1) { pr_err("port power fail: port_power 1 2(port 2 enable 1)\n"); return count; } pr_debug("%s: Port:%d power: %d\n", __func__, port, power_on); device_lock(dev); s5p_ehci_port_control(pdev, port, power_on); /*HSIC IPC control the ACTIVE_STATE*/ if (pdata && pdata->noti_host_states && port == CP_PORT) pdata->noti_host_states(pdev, power_on ? S5P_HOST_ON : S5P_HOST_OFF); device_unlock(dev); return count; }
static ssize_t size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); ssize_t rc; device_lock(dev); if (dev->driver) { struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; u64 offset = __le64_to_cpu(pfn_sb->dataoff); struct nd_namespace_common *ndns = nd_pfn->ndns; u32 start_pad = __le32_to_cpu(pfn_sb->start_pad); u32 end_trunc = __le32_to_cpu(pfn_sb->end_trunc); struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); rc = sprintf(buf, "%llu\n", (unsigned long long) resource_size(&nsio->res) - start_pad - end_trunc - offset); } else { /* no size to convey if the pfn instance is disabled */ rc = -ENXIO; } device_unlock(dev); return rc; }
static ssize_t gpp_wpgroup_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { long group; struct mmc_card *card = mmc_dev_to_card(dev); if (card == NULL) return -ENODEV; if (kstrtol(buf, 10, &group) != 0 || group != (u32)group) return -EINVAL; if (group < 0 || gpp_wppart < EXT_CSD_PART_CONFIG_ACC_GP0 || gpp_wppart > EXT_CSD_PART_CONFIG_ACC_GP0 + EXT_CSD_GPP_NUM - 1) return -EINVAL; if (group > card->ext_csd.gpp_sz[gpp_wppart - EXT_CSD_PART_CONFIG_ACC_GP0] - 1) return -EINVAL; device_lock(dev); gpp_wpgroup = group; device_unlock(dev); return n; }
/** * eeh_report_mmio_enabled - Tell drivers that MMIO has been enabled * @dev: PCI device * @userdata: return value * * Tells each device driver that IO ports, MMIO and config space I/O * are now enabled. Collects up and merges the device driver responses. * Cumulative response passed back in "userdata". */ static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) { enum pci_ers_result rc, *res = userdata; struct pci_driver *driver; device_lock(&dev->dev); driver = eeh_pcid_get(dev); if (!driver) goto out; if (!driver->err_handler || !driver->err_handler->mmio_enabled) { eeh_pcid_put(dev); goto out; } rc = driver->err_handler->mmio_enabled(dev); /* A driver that needs a reset trumps all others */ if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc; eeh_pcid_put(dev); out: device_unlock(&dev->dev); return 0; }
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); }
static int nfc_genl_dump_targets(struct sk_buff *skb, struct netlink_callback *cb) { int i = cb->args[0]; struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; int rc; if (!dev) { dev = __get_device_from_cb(cb); if (IS_ERR(dev)) return PTR_ERR(dev); cb->args[1] = (long) dev; } device_lock(&dev->dev); cb->seq = dev->targets_generation; while (i < dev->n_targets) { rc = nfc_genl_send_target(skb, &dev->targets[i], cb, NLM_F_MULTI); if (rc < 0) break; i++; } device_unlock(&dev->dev); cb->args[0] = i; return skb->len; }
/** * device_attach - try to attach device to a driver. * @dev: device. * * Walk the list of drivers that the bus has and call * driver_probe_device() for each pair. If a compatible * pair is found, break out and return. * * Returns 1 if the device was bound to a driver; * 0 if no matching driver was found; * -ENODEV if the device is not registered. * * When called for a USB interface, @dev->parent lock must be held. */ int device_attach(struct device *dev) { int ret = 0; device_lock(dev); if (dev->driver) { if (klist_node_attached(&dev->p->knode_driver)) { ret = 1; goto out_unlock; } ret = device_bind_driver(dev); if (ret == 0) ret = 1; else { dev->driver = NULL; ret = 0; } } else { pm_runtime_get_noresume(dev); ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); pm_runtime_put_sync(dev); } out_unlock: device_unlock(dev); return ret; }
static ssize_t driver_override_store(struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) { struct amba_device *dev = to_amba_device(_dev); char *driver_override, *old, *cp; /* We need to keep extra room for a newline */ if (count >= (PAGE_SIZE - 1)) return -EINVAL; driver_override = kstrndup(buf, count, GFP_KERNEL); if (!driver_override) return -ENOMEM; cp = strchr(driver_override, '\n'); if (cp) *cp = '\0'; device_lock(_dev); old = dev->driver_override; if (strlen(driver_override)) { dev->driver_override = driver_override; } else { kfree(driver_override); dev->driver_override = NULL; } device_unlock(_dev); kfree(old); return count; }
static ssize_t mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct nd_pfn *nd_pfn = to_nd_pfn(dev); ssize_t rc = 0; device_lock(dev); nvdimm_bus_lock(dev); if (dev->driver) rc = -EBUSY; else { size_t n = len - 1; if (strncmp(buf, "pmem\n", n) == 0 || strncmp(buf, "pmem", n) == 0) { /* TODO: allocate from PMEM support */ rc = -ENOTTY; } else if (strncmp(buf, "ram\n", n) == 0 || strncmp(buf, "ram", n) == 0) nd_pfn->mode = PFN_MODE_RAM; else if (strncmp(buf, "none\n", n) == 0 || strncmp(buf, "none", n) == 0) nd_pfn->mode = PFN_MODE_NONE; else rc = -EINVAL; } dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, rc, buf, buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); return rc ? rc : len; }
static ssize_t ccwgroup_online_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); unsigned long value; int ret; device_lock(dev); if (!dev->driver) { ret = -EINVAL; goto out; } ret = kstrtoul(buf, 0, &value); if (ret) goto out; if (value == 1) ret = ccwgroup_set_online(gdev); else if (value == 0) ret = ccwgroup_set_offline(gdev); else ret = -EINVAL; out: device_unlock(dev); return (ret == 0) ? count : ret; }
static ssize_t store_ehci_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct usb_hcd *hcd = dev_get_drvdata(dev); struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd); int power_on; int irq; int retval; if (sscanf(buf, "%d", &power_on) != 1) return -EINVAL; device_lock(dev); if (!power_on && s5p_ehci->power_on) { dev_info(dev, "EHCI turn off\n"); pm_runtime_forbid(dev); s5p_ehci->power_on = 0; usb_remove_hcd(hcd); if (s5p_ehci->phy) { /* Shutdown PHY only if it wasn't shutdown before */ if (!s5p_ehci->post_lpa_resume) usb_phy_shutdown(s5p_ehci->phy); } else if (s5p_ehci->pdata->phy_exit) { s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); } } else if (power_on) { dev_info(dev, "EHCI turn on\n"); if (s5p_ehci->power_on) { pm_runtime_forbid(dev); usb_remove_hcd(hcd); } else { s5p_ehci_phy_init(pdev); } irq = platform_get_irq(pdev, 0); retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval < 0) { dev_err(dev, "Power On Fail\n"); goto exit; } /* * EHCI root hubs are expected to handle remote wakeup. * So, wakeup flag init defaults for root hubs. */ device_wakeup_enable(&hcd->self.root_hub->dev); s5p_ehci->power_on = 1; pm_runtime_allow(dev); } exit: device_unlock(dev); return count; }
int ehci_power_control(struct device *dev, int force_enable,const char *buf) { struct platform_device *pdev; if(dev ) pdev = to_platform_device(dev); else pdev = &s5p_device_ehci; struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); struct usb_hcd *hcd = s5p_ehci->hcd; int power_on; int irq; int retval; if(dev){ if (sscanf(buf, "%d", &power_on) != 1) return -EINVAL; device_lock(dev); pm_runtime_get_sync(dev); }else{ power_on = force_enable; } if (!power_on && s5p_ehci->power_on) { printk(KERN_DEBUG "%s: EHCI turns off\n", __func__); s5p_ehci->power_on = 0; usb_remove_hcd(hcd); if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); } else if (power_on) { printk(KERN_DEBUG "%s: EHCI turns on\n", __func__); if (s5p_ehci->power_on) { usb_remove_hcd(hcd); } if (pdata && pdata->phy_init) pdata->phy_init(pdev, S5P_USB_PHY_HOST); s5p_ehci_configurate(hcd); irq = platform_get_irq(pdev, 0); retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval < 0) { dev_err(dev, "Power On Fail\n"); goto exit; } s5p_ehci->power_on = 1; } exit: if(dev){ pm_runtime_put_sync(dev); device_unlock(dev); } return 0; }
static ssize_t store_ohci_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); struct usb_hcd *hcd = exynos_ohci->hcd; int power_on; int irq; int retval; if (sscanf(buf, "%d", &power_on) != 1) return -EINVAL; device_lock(dev); if (!power_on && exynos_ohci->power_on) { printk(KERN_DEBUG "%s: EHCI turns off\n", __func__); pm_runtime_forbid(dev); exynos_ohci->power_on = 0; usb_remove_hcd(hcd); if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); } else if (power_on) { printk(KERN_DEBUG "%s: EHCI turns on\n", __func__); if (exynos_ohci->power_on) { pm_runtime_forbid(dev); usb_remove_hcd(hcd); } else { if (pdata && pdata->phy_init) pdata->phy_init(pdev, S5P_USB_PHY_HOST); } irq = platform_get_irq(pdev, 0); retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval < 0) { dev_err(dev, "Power On Fail\n"); goto exit; } /* * OHCI root hubs are expected to handle remote wakeup. * So, wakeup flag init defaults for root hubs. */ device_wakeup_enable(&hcd->self.root_hub->dev); exynos_ohci->power_on = 1; pm_runtime_allow(dev); } exit: device_unlock(dev); return count; }
bool nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach, struct nd_namespace_common **_ndns) { bool claimed; device_lock(&attach->dev); claimed = __nd_attach_ndns(dev, attach, _ndns); device_unlock(&attach->dev); return claimed; }
static bool nd_btt_attach_ndns(struct nd_btt *nd_btt, struct nd_namespace_common *ndns) { bool claimed; device_lock(&ndns->dev); claimed = __nd_btt_attach_ndns(nd_btt, ndns); device_unlock(&ndns->dev); return claimed; }
/* Register I2C client subdev associated with @node. */ static int fimc_md_of_add_sensor(struct fimc_md *fmd, struct device_node *node, int index) { struct fimc_sensor_info *si; struct i2c_client *client; struct v4l2_subdev *sd; int ret; if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) return -EINVAL; si = &fmd->sensor[index]; client = of_find_i2c_device_by_node(node); if (!client) return -EPROBE_DEFER; device_lock(&client->dev); if (!client->driver || !try_module_get(client->driver->driver.owner)) { ret = -EPROBE_DEFER; v4l2_info(&fmd->v4l2_dev, "No driver found for %s\n", node->full_name); goto dev_put; } /* Enable sensor's master clock */ ret = __fimc_md_set_camclk(fmd, &si->pdata, true); if (ret < 0) goto mod_put; sd = i2c_get_clientdata(client); ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); __fimc_md_set_camclk(fmd, &si->pdata, false); if (ret < 0) goto mod_put; v4l2_set_subdev_hostdata(sd, &si->pdata); if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) sd->grp_id = GRP_ID_FIMC_IS_SENSOR; else sd->grp_id = GRP_ID_SENSOR; si->subdev = sd; v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n", sd->name, fmd->num_sensors); fmd->num_sensors++; mod_put: module_put(client->driver->driver.owner); dev_put: device_unlock(&client->dev); put_device(&client->dev); return ret; }
/** * 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); }
/** * device_release_driver - manually detach device from driver. * @dev: device. * * Manually detach device from driver. * When called for a USB interface, @dev->parent lock must be held. */ void device_release_driver(struct device *dev) { /* * If anyone calls device_release_driver() recursively from * within their ->remove callback for the same device, they * will deadlock right here. */ device_lock(dev); __device_release_driver(dev); device_unlock(dev); }
static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) { int rc; struct vc_mailbox *mailbox = dev_get_drvdata(dev); device_lock(dev); rc = mbox_read(mailbox, chan, data28); device_unlock(dev); return rc; }
static ssize_t driver_override_show(struct device *_dev, struct device_attribute *attr, char *buf) { struct amba_device *dev = to_amba_device(_dev); ssize_t len; device_lock(_dev); len = sprintf(buf, "%s\n", dev->driver_override); device_unlock(_dev); return len; }