Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1229412

[PATCH v6 02/22] ARM: amba: Move reading of periphid to amba_match()

From Tomeu Vizoso <tomeu.vizoso@collabora.com>
Newsgroups linux.kernel
Subject [PATCH v6 02/22] ARM: amba: Move reading of periphid to amba_match()
Date 2015-09-21 16:20 +0200
Message-ID <qba6K-CY-3@gated-at.bofh.it> (permalink)
References <qb9X3-rF-9@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


Reading the periphid when the Primecell device is registered means that
the apb pclk must be available by then or the device won't be registered
at all.

By reading the periphid in amba_match() we can return -EPROBE_DEFER if
the apb pclk isn't there yet and the device will be retried later.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
---

Changes in v6:
- Drop bus_type.pre_probe and read the periphid in match() instead as
  suggested by Alan Stern.

Changes in v4:
- Added bus.pre_probe callback so the probes of Primecell devices can be
  deferred if their device IDs cannot be yet read because of the clock
  driver not having probed when they are registered. Maybe this goes
  overboard and the matching information should be in the DT if there is
  one.

 drivers/amba/bus.c | 88 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 46 insertions(+), 42 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index f0099360039e..72ebf9b1c715 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -24,6 +24,8 @@
 
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
+static int read_periphid(struct amba_device *d, unsigned int *periphid);
+
 static const struct amba_id *
 amba_lookup(const struct amba_id *table, struct amba_device *dev)
 {
@@ -43,11 +45,22 @@ static int amba_match(struct device *dev, struct device_driver *drv)
 {
 	struct amba_device *pcdev = to_amba_device(dev);
 	struct amba_driver *pcdrv = to_amba_driver(drv);
+	int ret;
 
 	/* When driver_override is set, only bind to the matching driver */
 	if (pcdev->driver_override)
 		return !strcmp(pcdev->driver_override, drv->name);
 
+	if (!pcdev->periphid) {
+		ret = read_periphid(pcdev, &pcdev->periphid);
+		if (ret) {
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to read periphid: %d",
+					ret);
+			return ret;
+		}
+	}
+
 	return amba_lookup(pcdrv->id_table, pcdev) != NULL;
 }
 
@@ -336,44 +349,22 @@ static void amba_device_release(struct device *dev)
 	kfree(d);
 }
 
-/**
- *	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)
+static int read_periphid(struct amba_device *d, unsigned int *periphid)
 {
 	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;
+	int i, ret = 0;
 
 	/*
 	 * 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;
-	}
+	size = resource_size(&d->res);
+	tmp = ioremap(d->res.start, size);
+	if (!tmp)
+		return -ENOMEM;
 
-	ret = amba_get_enable_pclk(dev);
+	ret = amba_get_enable_pclk(d);
 	if (ret == 0) {
 		u32 pid, cid;
 
@@ -388,37 +379,50 @@ int amba_device_add(struct amba_device *dev, struct resource *parent)
 			cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
 				(i * 8);
 
-		amba_put_disable_pclk(dev);
+		amba_put_disable_pclk(d);
 
 		if (cid == AMBA_CID || cid == CORESIGHT_CID)
-			dev->periphid = pid;
+			*periphid = pid;
 
-		if (!dev->periphid)
+		if (!*periphid)
 			ret = -ENODEV;
 	}
 
 	iounmap(tmp);
 
+	return ret;
+}
+
+/**
+ *	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 register the AMBA device with the Linux device
+ *	manager.
+ */
+int amba_device_add(struct amba_device *dev, struct resource *parent)
+{
+	int 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_release;
+		return ret;
 
- skip_probe:
 	ret = device_add(&dev->dev);
 	if (ret)
-		goto err_release;
+		return ret;
 
 	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);
+	if (ret)
+		device_unregister(&dev->dev);
 
- err_release:
-	release_resource(&dev->res);
- err_out:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(amba_device_add);
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH v6 0/22] On-demand device probing Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 14/22] usb: phy: Probe phy devices on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 09/22] drm: Probe panels on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 12/22] pwm: Probe PWM chip devices on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 01/22] driver core: handle -EPROBE_DEFER from bus_type.match() Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 15/22] clk: Probe clk providers on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 19/22] power-supply: Probe power supplies on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 20/22] driver core: Allow deferring probes until late init Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 16/22] pinctrl: Probe pinctrl devices on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 17/22] phy: core: Probe phy providers on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 21/22] driver core: Start processing deferred probes earlier Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:10 +0200
  [PATCH v6 07/22] regulator: core: Remove regulator_list Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:20 +0200
    Re: [PATCH v6 07/22] regulator: core: Remove regulator_list Mark Brown <broonie@kernel.org> - 2015-09-21 21:40 +0200
      Re: [PATCH v6 07/22] regulator: core: Remove regulator_list Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-22 09:30 +0200
  [PATCH v6 02/22] ARM: amba: Move reading of periphid to amba_match() Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:20 +0200
  [PATCH v6 04/22] of: add function to allow probing a device from a OF node Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:20 +0200
  [PATCH v6 05/22] gpio: Probe GPIO drivers on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:20 +0200
  [PATCH v6 11/22] i2c: core: Probe i2c adapters and devices on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:20 +0200
  [PATCH v6 06/22] gpio: Probe pinctrl devices on demand Tomeu Vizoso <tomeu.vizoso@collabora.com> - 2015-09-21 16:20 +0200

csiph-web