linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 1/2] amba: Defer device peripheral ID read
@ 2016-04-11 14:58 Georgi Djakov
  2016-04-11 14:58 ` [PATCH v1 2/2] amba: Propagate match errors to the driver core Georgi Djakov
  2016-04-11 15:01 ` [PATCH v1 1/2] amba: Defer device peripheral ID read Russell King - ARM Linux
  0 siblings, 2 replies; 3+ messages in thread
From: Georgi Djakov @ 2016-04-11 14:58 UTC (permalink / raw)
  To: linux
  Cc: linux-kernel, linux-arm-kernel, linux-arm-msm, iivanov.xz, georgi.djakov

From: "Ivan T. Ivanov" <ivan.ivanov@linaro.org>

To be able to read peripheral ID during device create time
bus code have turn on device interface clock, but this
clock could be unavailable at this time. Fix this by defer
device ID read until driver match time.

Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
 drivers/amba/bus.c |  138 ++++++++++++++++++++++++++--------------------------
 1 file changed, 69 insertions(+), 69 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index f0099360039e..a32a43dbaccc 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -24,11 +24,79 @@
 
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
+static int amba_get_enable_pclk(struct amba_device *pcdev)
+{
+	int ret;
+
+	pcdev->pclk = clk_get(&pcdev->dev, "apb_pclk");
+	if (IS_ERR(pcdev->pclk))
+		return PTR_ERR(pcdev->pclk);
+
+	ret = clk_prepare_enable(pcdev->pclk);
+	if (ret)
+		clk_put(pcdev->pclk);
+
+	return ret;
+}
+
+static void amba_put_disable_pclk(struct amba_device *pcdev)
+{
+	clk_disable_unprepare(pcdev->pclk);
+	clk_put(pcdev->pclk);
+}
+
+static int amba_read_periphid(struct amba_device *adev)
+{
+	resource_size_t size;
+	void __iomem *tmp;
+	int r, i;
+
+	if (adev->periphid)
+		return 0;
+
+	/*
+	 * Dynamically calculate the size of the resource
+	 * and use this for iomap
+	 */
+	size = resource_size(&adev->res);
+	tmp = ioremap(adev->res.start, size);
+	if (!tmp)
+		return -ENODEV;
+
+	r = amba_get_enable_pclk(adev);
+	if (r == 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(adev);
+
+		if (cid == AMBA_CID || cid == CORESIGHT_CID)
+			adev->periphid = pid;
+	}
+
+	iounmap(tmp);
+
+	return adev->periphid ? 0 : -ENODEV;
+}
+
 static const struct amba_id *
 amba_lookup(const struct amba_id *table, struct amba_device *dev)
 {
 	int ret = 0;
 
+	if (amba_read_periphid(dev))
+		return NULL;
+
 	while (table->mask) {
 		ret = (dev->periphid & table->mask) == table->id;
 		if (ret)
@@ -204,27 +272,6 @@ static int __init amba_init(void)
 
 postcore_initcall(amba_init);
 
-static int amba_get_enable_pclk(struct amba_device *pcdev)
-{
-	int ret;
-
-	pcdev->pclk = clk_get(&pcdev->dev, "apb_pclk");
-	if (IS_ERR(pcdev->pclk))
-		return PTR_ERR(pcdev->pclk);
-
-	ret = clk_prepare_enable(pcdev->pclk);
-	if (ret)
-		clk_put(pcdev->pclk);
-
-	return ret;
-}
-
-static void amba_put_disable_pclk(struct amba_device *pcdev)
-{
-	clk_disable_unprepare(pcdev->pclk);
-	clk_put(pcdev->pclk);
-}
-
 /*
  * These are the device model conversion veneers; they convert the
  * device model structures to our more specific structures.
@@ -347,9 +394,7 @@ static void amba_device_release(struct device *dev)
  */
 int amba_device_add(struct amba_device *dev, struct resource *parent)
 {
-	u32 size;
-	void __iomem *tmp;
-	int i, ret;
+	int ret;
 
 	WARN_ON(dev->irq[0] == (unsigned int)-1);
 	WARN_ON(dev->irq[1] == (unsigned int)-1);
@@ -358,51 +403,6 @@ int amba_device_add(struct amba_device *dev, struct resource *parent)
 	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);
-	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 || cid == CORESIGHT_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;

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v1 2/2] amba: Propagate match errors to the driver core
  2016-04-11 14:58 [PATCH v1 1/2] amba: Defer device peripheral ID read Georgi Djakov
@ 2016-04-11 14:58 ` Georgi Djakov
  2016-04-11 15:01 ` [PATCH v1 1/2] amba: Defer device peripheral ID read Russell King - ARM Linux
  1 sibling, 0 replies; 3+ messages in thread
From: Georgi Djakov @ 2016-04-11 14:58 UTC (permalink / raw)
  To: linux
  Cc: linux-kernel, linux-arm-kernel, linux-arm-msm, iivanov.xz, georgi.djakov

Currently, when we scan the bus for matching devices, we assume that
the clock controller is probed and available, but that might be not
always true. If the bus clock is unavailable, we just silently fail
to detect devices.

Handle this by propagating the errors up to the driver core, so that
it can retry the scan later.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
 drivers/amba/bus.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index a32a43dbaccc..0d9a342a73f8 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -86,15 +86,21 @@ static int amba_read_periphid(struct amba_device *adev)
 
 	iounmap(tmp);
 
+	if (r < 0)
+		return r;
+
 	return adev->periphid ? 0 : -ENODEV;
 }
 
 static const struct amba_id *
 amba_lookup(const struct amba_id *table, struct amba_device *dev)
 {
-	int ret = 0;
+	int ret;
 
-	if (amba_read_periphid(dev))
+	ret = amba_read_periphid(dev);
+	if (ret < 0)
+		return ERR_PTR(ret);
+	if (ret)
 		return NULL;
 
 	while (table->mask) {
@@ -111,12 +117,17 @@ 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);
+	const struct amba_id *id;
 
 	/* When driver_override is set, only bind to the matching driver */
 	if (pcdev->driver_override)
 		return !strcmp(pcdev->driver_override, drv->name);
 
-	return amba_lookup(pcdrv->id_table, pcdev) != NULL;
+	id = amba_lookup(pcdrv->id_table, pcdev);
+	if (IS_ERR(id))
+		return PTR_ERR(id);
+
+	return id != NULL;
 }
 
 static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v1 1/2] amba: Defer device peripheral ID read
  2016-04-11 14:58 [PATCH v1 1/2] amba: Defer device peripheral ID read Georgi Djakov
  2016-04-11 14:58 ` [PATCH v1 2/2] amba: Propagate match errors to the driver core Georgi Djakov
@ 2016-04-11 15:01 ` Russell King - ARM Linux
  1 sibling, 0 replies; 3+ messages in thread
From: Russell King - ARM Linux @ 2016-04-11 15:01 UTC (permalink / raw)
  To: Georgi Djakov; +Cc: linux-kernel, linux-arm-kernel, linux-arm-msm, iivanov.xz

On Mon, Apr 11, 2016 at 05:58:35PM +0300, Georgi Djakov wrote:
> From: "Ivan T. Ivanov" <ivan.ivanov@linaro.org>
> 
> To be able to read peripheral ID during device create time
> bus code have turn on device interface clock, but this
> clock could be unavailable at this time. Fix this by defer
> device ID read until driver match time.
> 
> Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>

Can't do this.  See comments on previous similar patches trying to do the
very same thing.  (Sorry, I don't have time to provide a fuller reply,
especially given that there's already a fuller reply in the last two
months of mailing list archives.)

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-04-11 15:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-11 14:58 [PATCH v1 1/2] amba: Defer device peripheral ID read Georgi Djakov
2016-04-11 14:58 ` [PATCH v1 2/2] amba: Propagate match errors to the driver core Georgi Djakov
2016-04-11 15:01 ` [PATCH v1 1/2] amba: Defer device peripheral ID read Russell King - ARM Linux

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).