Exemplo n.º 1
0
Arquivo: mmc.c Projeto: BORETS24/za580
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);
}
Exemplo n.º 2
0
Arquivo: mmc.c Projeto: BORETS24/za580
/*
 * 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;
}
Exemplo n.º 3
0
/*
 * 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;
}
Exemplo n.º 4
0
/**
 * 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);
	}
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
/**
 * 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;
}
Exemplo n.º 15
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);
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
/**
 * 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;
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 26
0
/* 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;
}
Exemplo n.º 27
0
/**
 * 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);
}
Exemplo n.º 28
0
/**
 * 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);
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
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;
}