diff mbox

[05/11] pinctrl: mvebu: fix misdesigned resource allocation

Message ID 1390674856-4993-6-git-send-email-sebastian.hesselbarth@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sebastian Hesselbarth Jan. 25, 2014, 6:34 p.m. UTC
Allocating the pinctrl resource in common pinctrl-mvebu was a misdesign,
as it does not allow SoC specific parts to access the allocated resource.
This moves resource allocation from mvebu_pinctrl_probe to SoC specific
_probe functions and passes the base address to common pinctrl driver
instead.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Gregory Clement <gregory.clement@free-electrons.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pinctrl/mvebu/pinctrl-armada-370.c |  9 ++++++++-
 drivers/pinctrl/mvebu/pinctrl-armada-xp.c  |  9 ++++++++-
 drivers/pinctrl/mvebu/pinctrl-dove.c       | 10 +++++++++-
 drivers/pinctrl/mvebu/pinctrl-kirkwood.c   | 10 +++++++++-
 drivers/pinctrl/mvebu/pinctrl-mvebu.c      | 14 ++++++--------
 drivers/pinctrl/mvebu/pinctrl-mvebu.h      |  2 +-
 6 files changed, 41 insertions(+), 13 deletions(-)

Comments

Thomas Petazzoni Jan. 27, 2014, 2:45 p.m. UTC | #1
Dear Sebastian Hesselbarth,

On Sat, 25 Jan 2014 19:34:10 +0100, Sebastian Hesselbarth wrote:
> Allocating the pinctrl resource in common pinctrl-mvebu was a misdesign,
> as it does not allow SoC specific parts to access the allocated resource.
> This moves resource allocation from mvebu_pinctrl_probe to SoC specific
> _probe functions and passes the base address to common pinctrl driver
> instead.
> 
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>

I definitely agree with that: I had the same problem several months ago
when I started doing the pinctrl driver for Orion5x, which has a
non-linear MPP register set.

However, I'd like this to go a little bit further if possible. See
below.


> -	return mvebu_pinctrl_probe(pdev);
> +	return mvebu_pinctrl_probe(pdev, base);

I think there is no need to pass "base" to mvebu_pinctrl_probe(). The
only reason we have this is because the base gets stored in the
mvebu_pinctrl structure so that the mvebu_common_mpp_get() and
mvebu_common_mpp_set() functions that are the default behavior
for mvebu_pinconf_group_get() and mvebu_pinconf_group_set() work
properly.

Shouldn't we turn these functions mvebu_common_mpp_get() and
mvebu_common_mpp_set() into helper functions, accessible from the
per-SoC pinctrl drivers, so that they can easily implement their
->mpp_get() and ->mpp_set() callbacks?

This way, the "base" thing is completely owned by the per-SoC driver,
which would be more logical I believe.

Thanks!

Thomas
Sebastian Hesselbarth Jan. 27, 2014, 6:26 p.m. UTC | #2
On 01/27/14 15:45, Thomas Petazzoni wrote:
> On Sat, 25 Jan 2014 19:34:10 +0100, Sebastian Hesselbarth wrote:
>> Allocating the pinctrl resource in common pinctrl-mvebu was a misdesign,
>> as it does not allow SoC specific parts to access the allocated resource.
>> This moves resource allocation from mvebu_pinctrl_probe to SoC specific
>> _probe functions and passes the base address to common pinctrl driver
>> instead.
>>
>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
>
> I definitely agree with that: I had the same problem several months ago
> when I started doing the pinctrl driver for Orion5x, which has a
> non-linear MPP register set.
>
> However, I'd like this to go a little bit further if possible. See
> below.

Agreed.

>> -	return mvebu_pinctrl_probe(pdev);
>> +	return mvebu_pinctrl_probe(pdev, base);
>
> I think there is no need to pass "base" to mvebu_pinctrl_probe(). The
> only reason we have this is because the base gets stored in the
> mvebu_pinctrl structure so that the mvebu_common_mpp_get() and
> mvebu_common_mpp_set() functions that are the default behavior
> for mvebu_pinconf_group_get() and mvebu_pinconf_group_set() work
> properly.
>
> Shouldn't we turn these functions mvebu_common_mpp_get() and
> mvebu_common_mpp_set() into helper functions, accessible from the
> per-SoC pinctrl drivers, so that they can easily implement their
> ->mpp_get() and ->mpp_set() callbacks?

Sounds reasonable to do so. I have a look at removing the base address
from common.c completely.

Sebastian

> This way, the "base" thing is completely owned by the per-SoC driver,
> which would be more logical I believe.
diff mbox

Patch

diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
index ae1f760cbdd2..4f6a65b32f06 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-370.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
@@ -385,6 +385,13 @@  static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
 static int armada_370_pinctrl_probe(struct platform_device *pdev)
 {
 	struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info;
+	struct resource *res;
+	void __iomem *base;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 
 	soc->variant = 0; /* no variants for Armada 370 */
 	soc->controls = mv88f6710_mpp_controls;
@@ -396,7 +403,7 @@  static int armada_370_pinctrl_probe(struct platform_device *pdev)
 
 	pdev->dev.platform_data = soc;
 
-	return mvebu_pinctrl_probe(pdev);
+	return mvebu_pinctrl_probe(pdev, base);
 }
 
 static int armada_370_pinctrl_remove(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
index 843a51f9d129..e4be7ab4c948 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
@@ -399,10 +399,17 @@  static int armada_xp_pinctrl_probe(struct platform_device *pdev)
 	struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
 	const struct of_device_id *match =
 		of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
+	struct resource *res;
+	void __iomem *base;
 
 	if (!match)
 		return -ENODEV;
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
 	soc->variant = (unsigned) match->data & 0xff;
 
 	switch (soc->variant) {
@@ -443,7 +450,7 @@  static int armada_xp_pinctrl_probe(struct platform_device *pdev)
 
 	pdev->dev.platform_data = soc;
 
-	return mvebu_pinctrl_probe(pdev);
+	return mvebu_pinctrl_probe(pdev, base);
 }
 
 static int armada_xp_pinctrl_remove(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index 47268393af34..f4141e60a52b 100644
--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
@@ -776,6 +776,14 @@  static int dove_pinctrl_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match =
 		of_match_device(dove_pinctrl_of_match, &pdev->dev);
+	struct resource *res;
+	void __iomem *base;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
 	pdev->dev.platform_data = (void *)match->data;
 
 	/*
@@ -789,7 +797,7 @@  static int dove_pinctrl_probe(struct platform_device *pdev)
 	}
 	clk_prepare_enable(clk);
 
-	return mvebu_pinctrl_probe(pdev);
+	return mvebu_pinctrl_probe(pdev, base);
 }
 
 static int dove_pinctrl_remove(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
index 6b504b5935a5..e515288bde35 100644
--- a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
+++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
@@ -458,8 +458,16 @@  static int kirkwood_pinctrl_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match =
 		of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
+	struct resource *res;
+	void __iomem *base;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
 	pdev->dev.platform_data = (void *)match->data;
-	return mvebu_pinctrl_probe(pdev);
+	return mvebu_pinctrl_probe(pdev, base);
 }
 
 static int kirkwood_pinctrl_remove(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index 0fd1ad31fbf9..90c35b20a7af 100644
--- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -590,26 +590,24 @@  static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
 	return 0;
 }
 
-int mvebu_pinctrl_probe(struct platform_device *pdev)
+int mvebu_pinctrl_probe(struct platform_device *pdev, void __iomem *base)
 {
 	struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
-	struct resource *res;
 	struct mvebu_pinctrl *pctl;
-	void __iomem *base;
 	struct pinctrl_pin_desc *pdesc;
 	unsigned gid, n, k;
 	int ret;
 
+	if (!base) {
+		dev_err(&pdev->dev, "missing base address\n");
+		return -EINVAL;
+	}
+
 	if (!soc || !soc->controls || !soc->modes) {
 		dev_err(&pdev->dev, "wrong pinctrl soc info\n");
 		return -EINVAL;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(base))
-		return PTR_ERR(base);
-
 	pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
 			GFP_KERNEL);
 	if (!pctl) {
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
index 90bd3beee860..b66949040e0a 100644
--- a/drivers/pinctrl/mvebu/pinctrl-mvebu.h
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h
@@ -186,7 +186,7 @@  struct mvebu_pinctrl_soc_info {
 		.npins = _npins,				\
 	}
 
-int mvebu_pinctrl_probe(struct platform_device *pdev);
+int mvebu_pinctrl_probe(struct platform_device *pdev, void __iomem *base);
 int mvebu_pinctrl_remove(struct platform_device *pdev);
 
 #endif