All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i2c-gpio: add devicetree support
@ 2011-01-30 15:56 ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-30 15:56 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Jean Delvare, Albert Herranz, Thomas Chou

From: Albert Herranz <albert_herranz@yahoo.es>

This patch is based on an earlier patch from Albert Herranz,
http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
9854eb78607c641ab5ae85bcbe3c9d14ac113733

The dts binding is modified as Grant suggested. The of probing
is merged inline instead of a separate file. It uses the newer
of gpio probe.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
 Documentation/devicetree/bindings/gpio/i2c.txt |   39 ++++++++++++++
 drivers/i2c/busses/i2c-gpio.c                  |   67 ++++++++++++++++++++++-
 2 files changed, 103 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/i2c.txt

diff --git a/Documentation/devicetree/bindings/gpio/i2c.txt b/Documentation/devicetree/bindings/gpio/i2c.txt
new file mode 100644
index 0000000..402569e
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/i2c.txt
@@ -0,0 +1,39 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if SCL is an output gpio only.
+- udelay : signal toggle delay. SCL frequency is (500 / udelay) kHz
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	udelay = <2>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..9648201 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,6 +14,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
 
 #include <asm/gpio.h>
 
@@ -83,11 +86,52 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
+	struct device_node *np = pdev->dev.of_node;
 	int ret;
 
 	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	if (!pdata) {
+		if (np && of_gpio_count(np) >= 2) {
+			const __be32 *prop;
+			int sda_pin, scl_pin;
+
+			sda_pin = of_get_gpio_flags(np, 0, NULL);
+			scl_pin = of_get_gpio_flags(np, 1, NULL);
+			if (sda_pin < 0 || scl_pin < 0) {
+				pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+				       np->full_name, sda_pin, scl_pin);
+				ret = -EINVAL;
+				goto err_gpio_pin;
+			}
+			pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+			if (!pdata) {
+				ret = -ENOMEM;
+				goto err_alloc_pdata;
+			}
+			pdata->sda_pin = sda_pin;
+			pdata->scl_pin = scl_pin;
+			prop = of_get_property(np, "sda-is-open-drain", NULL);
+			if (prop)
+				pdata->sda_is_open_drain = 1;
+			prop = of_get_property(np, "scl-is-open-drain", NULL);
+			if (prop)
+				pdata->scl_is_open_drain = 1;
+			prop = of_get_property(np, "scl-is-output-only", NULL);
+			if (prop)
+				pdata->scl_is_output_only = 1;
+			prop = of_get_property(np, "udelay", NULL);
+			if (prop)
+				pdata->udelay = be32_to_cpup(prop);
+			prop = of_get_property(np, "timeout", NULL);
+			if (prop) {
+				pdata->timeout =
+					msecs_to_jiffies(be32_to_cpup(prop));
+			}
+		} else {
+			ret = -ENXIO;
+			goto err_no_pdata;
+		}
+	}
 
 	ret = -ENOMEM;
 	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
@@ -143,6 +187,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = np;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -161,6 +206,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -172,6 +220,9 @@ err_request_sda:
 err_alloc_bit_data:
 	kfree(adap);
 err_alloc_adap:
+err_no_pdata:
+err_alloc_pdata:
+err_gpio_pin:
 	return ret;
 }
 
@@ -179,23 +230,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
+	struct i2c_algo_bit_data *bit_data;
 
 	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	bit_data = adap->algo_data;
+	pdata = bit_data->data;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
 	kfree(adap->algo_data);
 	kfree(adap);
+	if (!pdev->dev.platform_data)
+		kfree(pdata);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.3.5


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

* [PATCH] i2c-gpio: add devicetree support
@ 2011-01-30 15:56 ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-30 15:56 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz

From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>

This patch is based on an earlier patch from Albert Herranz,
http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
9854eb78607c641ab5ae85bcbe3c9d14ac113733

The dts binding is modified as Grant suggested. The of probing
is merged inline instead of a separate file. It uses the newer
of gpio probe.

Signed-off-by: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
---
 Documentation/devicetree/bindings/gpio/i2c.txt |   39 ++++++++++++++
 drivers/i2c/busses/i2c-gpio.c                  |   67 ++++++++++++++++++++++-
 2 files changed, 103 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/i2c.txt

diff --git a/Documentation/devicetree/bindings/gpio/i2c.txt b/Documentation/devicetree/bindings/gpio/i2c.txt
new file mode 100644
index 0000000..402569e
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/i2c.txt
@@ -0,0 +1,39 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if SCL is an output gpio only.
+- udelay : signal toggle delay. SCL frequency is (500 / udelay) kHz
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	udelay = <2>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..9648201 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,6 +14,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
 
 #include <asm/gpio.h>
 
@@ -83,11 +86,52 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
+	struct device_node *np = pdev->dev.of_node;
 	int ret;
 
 	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	if (!pdata) {
+		if (np && of_gpio_count(np) >= 2) {
+			const __be32 *prop;
+			int sda_pin, scl_pin;
+
+			sda_pin = of_get_gpio_flags(np, 0, NULL);
+			scl_pin = of_get_gpio_flags(np, 1, NULL);
+			if (sda_pin < 0 || scl_pin < 0) {
+				pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+				       np->full_name, sda_pin, scl_pin);
+				ret = -EINVAL;
+				goto err_gpio_pin;
+			}
+			pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+			if (!pdata) {
+				ret = -ENOMEM;
+				goto err_alloc_pdata;
+			}
+			pdata->sda_pin = sda_pin;
+			pdata->scl_pin = scl_pin;
+			prop = of_get_property(np, "sda-is-open-drain", NULL);
+			if (prop)
+				pdata->sda_is_open_drain = 1;
+			prop = of_get_property(np, "scl-is-open-drain", NULL);
+			if (prop)
+				pdata->scl_is_open_drain = 1;
+			prop = of_get_property(np, "scl-is-output-only", NULL);
+			if (prop)
+				pdata->scl_is_output_only = 1;
+			prop = of_get_property(np, "udelay", NULL);
+			if (prop)
+				pdata->udelay = be32_to_cpup(prop);
+			prop = of_get_property(np, "timeout", NULL);
+			if (prop) {
+				pdata->timeout =
+					msecs_to_jiffies(be32_to_cpup(prop));
+			}
+		} else {
+			ret = -ENXIO;
+			goto err_no_pdata;
+		}
+	}
 
 	ret = -ENOMEM;
 	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
@@ -143,6 +187,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = np;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -161,6 +206,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -172,6 +220,9 @@ err_request_sda:
 err_alloc_bit_data:
 	kfree(adap);
 err_alloc_adap:
+err_no_pdata:
+err_alloc_pdata:
+err_gpio_pin:
 	return ret;
 }
 
@@ -179,23 +230,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
+	struct i2c_algo_bit_data *bit_data;
 
 	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	bit_data = adap->algo_data;
+	pdata = bit_data->data;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
 	kfree(adap->algo_data);
 	kfree(adap);
+	if (!pdev->dev.platform_data)
+		kfree(pdata);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.3.5

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31  3:26   ` Håvard Skinnemoen
  0 siblings, 0 replies; 51+ messages in thread
From: Håvard Skinnemoen @ 2011-01-31  3:26 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Grant Likely, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare, Albert Herranz

Hi,

On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas@wytron.com.tw> wrote:
> From: Albert Herranz <albert_herranz@yahoo.es>
>
> This patch is based on an earlier patch from Albert Herranz,
> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
> 9854eb78607c641ab5ae85bcbe3c9d14ac113733

That commit has a single-line description of which I don't understand
a single word (unless "wii" is what I think it is, which seems
likely). Could you please explain how that commit relates to this
patch?

> The dts binding is modified as Grant suggested. The of probing
> is merged inline instead of a separate file. It uses the newer
> of gpio probe.

It seems like a terrible idea to merge firmware-specific code into the
driver. Is there are reason why of-based platforms can't just pass the
data they need in pdata like everyone else?

Not saying that it necessarily _is_ a terrible idea, but I think the
reasoning behind it needs to be included in the patch description.

> Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> ---
>  Documentation/devicetree/bindings/gpio/i2c.txt |   39 ++++++++++++++
>  drivers/i2c/busses/i2c-gpio.c                  |   67 ++++++++++++++++++++++-
>  2 files changed, 103 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/gpio/i2c.txt
>
> diff --git a/Documentation/devicetree/bindings/gpio/i2c.txt b/Documentation/devicetree/bindings/gpio/i2c.txt
> new file mode 100644
> index 0000000..402569e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/i2c.txt

This looks a bit backwards. i2c-gpio is a i2c driver which happens to
utilize the gpio framework, not the other way around.

> @@ -0,0 +1,39 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if SCL is an output gpio only.

I think "present if the output driver for SCL cannot be turned off" is
more accurate. Might also be worth mentioning that this will prevent
clock stretching from working.

> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,6 +14,9 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_i2c.h>

Do these headers provide stubs so non-of platforms won't break?

> @@ -83,11 +86,52 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>        struct i2c_gpio_platform_data *pdata;
>        struct i2c_algo_bit_data *bit_data;
>        struct i2c_adapter *adap;
> +       struct device_node *np = pdev->dev.of_node;

Would be nice if this could be eliminated on non-of platforms.

>        int ret;
>
>        pdata = pdev->dev.platform_data;
> -       if (!pdata)
> -               return -ENXIO;
> +       if (!pdata) {
> +               if (np && of_gpio_count(np) >= 2) {

If that expression somehow always evaluates to false on non-of
platforms, this might be ok. But please confirm if this is the case;
otherwise, it looks like a pretty large addition to an otherwise very
small driver.

How about a tiny bit of restructuring: Move the block below into a
separate function, which is only called if some constant expression
says that of is enabled. Then you can move the declaration above
either into the if block or into the function, depending on where you
want to do the conditional above.

>  static struct platform_driver i2c_gpio_driver = {
>        .driver         = {
>                .name   = "i2c-gpio",
>                .owner  = THIS_MODULE,
> +               .of_match_table = i2c_gpio_match,

Is this field always present even when of is disabled?

Havard

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31  3:26   ` Håvard Skinnemoen
  0 siblings, 0 replies; 51+ messages in thread
From: Håvard Skinnemoen @ 2011-01-31  3:26 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Grant Likely, Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz

Hi,

On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org> wrote:
> From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
>
> This patch is based on an earlier patch from Albert Herranz,
> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
> 9854eb78607c641ab5ae85bcbe3c9d14ac113733

That commit has a single-line description of which I don't understand
a single word (unless "wii" is what I think it is, which seems
likely). Could you please explain how that commit relates to this
patch?

> The dts binding is modified as Grant suggested. The of probing
> is merged inline instead of a separate file. It uses the newer
> of gpio probe.

It seems like a terrible idea to merge firmware-specific code into the
driver. Is there are reason why of-based platforms can't just pass the
data they need in pdata like everyone else?

Not saying that it necessarily _is_ a terrible idea, but I think the
reasoning behind it needs to be included in the patch description.

> Signed-off-by: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/gpio/i2c.txt |   39 ++++++++++++++
>  drivers/i2c/busses/i2c-gpio.c                  |   67 ++++++++++++++++++++++-
>  2 files changed, 103 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/gpio/i2c.txt
>
> diff --git a/Documentation/devicetree/bindings/gpio/i2c.txt b/Documentation/devicetree/bindings/gpio/i2c.txt
> new file mode 100644
> index 0000000..402569e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/i2c.txt

This looks a bit backwards. i2c-gpio is a i2c driver which happens to
utilize the gpio framework, not the other way around.

> @@ -0,0 +1,39 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if SCL is an output gpio only.

I think "present if the output driver for SCL cannot be turned off" is
more accurate. Might also be worth mentioning that this will prevent
clock stretching from working.

> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,6 +14,9 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_i2c.h>

Do these headers provide stubs so non-of platforms won't break?

> @@ -83,11 +86,52 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>        struct i2c_gpio_platform_data *pdata;
>        struct i2c_algo_bit_data *bit_data;
>        struct i2c_adapter *adap;
> +       struct device_node *np = pdev->dev.of_node;

Would be nice if this could be eliminated on non-of platforms.

>        int ret;
>
>        pdata = pdev->dev.platform_data;
> -       if (!pdata)
> -               return -ENXIO;
> +       if (!pdata) {
> +               if (np && of_gpio_count(np) >= 2) {

If that expression somehow always evaluates to false on non-of
platforms, this might be ok. But please confirm if this is the case;
otherwise, it looks like a pretty large addition to an otherwise very
small driver.

How about a tiny bit of restructuring: Move the block below into a
separate function, which is only called if some constant expression
says that of is enabled. Then you can move the declaration above
either into the if block or into the function, depending on where you
want to do the conditional above.

>  static struct platform_driver i2c_gpio_driver = {
>        .driver         = {
>                .name   = "i2c-gpio",
>                .owner  = THIS_MODULE,
> +               .of_match_table = i2c_gpio_match,

Is this field always present even when of is disabled?

Havard

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31  8:09     ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31  8:09 UTC (permalink / raw)
  To: Håvard Skinnemoen
  Cc: Thomas Chou, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare, Albert Herranz

On Sun, Jan 30, 2011 at 8:26 PM, Håvard Skinnemoen
<hskinnemoen@gmail.com> wrote:
> Hi,
>
> On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas@wytron.com.tw> wrote:
>> From: Albert Herranz <albert_herranz@yahoo.es>
>>
>> This patch is based on an earlier patch from Albert Herranz,
>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
>
> That commit has a single-line description of which I don't understand
> a single word (unless "wii" is what I think it is, which seems
> likely). Could you please explain how that commit relates to this
> patch?

The URL got wrapped.  Try this one (assuming my mailer doesn't wrap it):

http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/9854eb78607c641ab5ae85bcbe3c9d14ac113733

>
>> The dts binding is modified as Grant suggested. The of probing
>> is merged inline instead of a separate file. It uses the newer
>> of gpio probe.
>
> It seems like a terrible idea to merge firmware-specific code into the
> driver. Is there are reason why of-based platforms can't just pass the
> data they need in pdata like everyone else?

Overall Thomas is doing the right thing here.  The driver data has to
be decoded *somewhere*, but since that code is definitely
driver-specific (as opposed to platform, subsystem, or arch specific)
putting it into the driver is absolutely the right thing to do.  Quite
a few drivers now do exactly this.

It is however generally a wise practice to limit the of-support code
to a hook in the drivers probe hook, and as you point out, care must
be taken to make sure both CONFIG_OF and !CONFIG_OF kernel builds
work.

>
> Not saying that it necessarily _is_ a terrible idea, but I think the
> reasoning behind it needs to be included in the patch description.

Nah, he doesn't really need to defend this since it is a well
established pattern.  device tree support is in core code now (see
of_node an of_match_table in include/linux/device.h), and other
drivers do exactly this.

>> Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
>> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
>> ---
>>  Documentation/devicetree/bindings/gpio/i2c.txt |   39 ++++++++++++++
>>  drivers/i2c/busses/i2c-gpio.c                  |   67 ++++++++++++++++++++++-
>>  2 files changed, 103 insertions(+), 3 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/gpio/i2c.txt
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/i2c.txt b/Documentation/devicetree/bindings/gpio/i2c.txt
>> new file mode 100644
>> index 0000000..402569e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/i2c.txt
>
> This looks a bit backwards. i2c-gpio is a i2c driver which happens to
> utilize the gpio framework, not the other way around.

Yes, this should be in devicetree/bindings/i2c/i2c-gpio.txt

>
>> @@ -0,0 +1,39 @@
>> +GPIO-based I2C
>> +
>> +Required properties:
>> +- compatible : should be "i2c-gpio".
>> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
>> +Optional properties:
>> +- sda-is-open-drain : present if SDA gpio is open-drain.
>> +- scl-is-open-drain : present if SCL gpio is open-drain.
>> +- scl-is-output-only : present if SCL is an output gpio only.
>
> I think "present if the output driver for SCL cannot be turned off" is
> more accurate. Might also be worth mentioning that this will prevent
> clock stretching from working.
>
>> --- a/drivers/i2c/busses/i2c-gpio.c
>> +++ b/drivers/i2c/busses/i2c-gpio.c
>> @@ -14,6 +14,9 @@
>>  #include <linux/module.h>
>>  #include <linux/slab.h>
>>  #include <linux/platform_device.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/of_i2c.h>
>
> Do these headers provide stubs so non-of platforms won't break?

yes.

>
>> @@ -83,11 +86,52 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>>        struct i2c_gpio_platform_data *pdata;
>>        struct i2c_algo_bit_data *bit_data;
>>        struct i2c_adapter *adap;
>> +       struct device_node *np = pdev->dev.of_node;
>
> Would be nice if this could be eliminated on non-of platforms.

It's pretty benign.  However, for current mainline this needs to be
protected with a #ifdef CONFIG_OF.  In 2.6.29, the conditional can be
removed since of_node will be a permanent part of struct device.

>
>>        int ret;
>>
>>        pdata = pdev->dev.platform_data;
>> -       if (!pdata)
>> -               return -ENXIO;
>> +       if (!pdata) {
>> +               if (np && of_gpio_count(np) >= 2) {
>
> If that expression somehow always evaluates to false on non-of
> platforms, this might be ok. But please confirm if this is the case;
> otherwise, it looks like a pretty large addition to an otherwise very
> small driver.
>
> How about a tiny bit of restructuring: Move the block below into a
> separate function, which is only called if some constant expression
> says that of is enabled. Then you can move the declaration above
> either into the if block or into the function, depending on where you
> want to do the conditional above.

Yes, moving the dt decoding code to a separate function would keep the
dt-support better isolated from the core of the driver and would make
the CONFIG_OF/!CONFIG_OF handling better.

>
>>  static struct platform_driver i2c_gpio_driver = {
>>        .driver         = {
>>                .name   = "i2c-gpio",
>>                .owner  = THIS_MODULE,
>> +               .of_match_table = i2c_gpio_match,
>
> Is this field always present even when of is disabled?

No, not yet.  It will be in 2.6.29.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31  8:09     ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31  8:09 UTC (permalink / raw)
  To: Håvard Skinnemoen
  Cc: Thomas Chou, Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz

On Sun, Jan 30, 2011 at 8:26 PM, Håvard Skinnemoen
<hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi,
>
> On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org> wrote:
>> From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
>>
>> This patch is based on an earlier patch from Albert Herranz,
>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
>
> That commit has a single-line description of which I don't understand
> a single word (unless "wii" is what I think it is, which seems
> likely). Could you please explain how that commit relates to this
> patch?

The URL got wrapped.  Try this one (assuming my mailer doesn't wrap it):

http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/9854eb78607c641ab5ae85bcbe3c9d14ac113733

>
>> The dts binding is modified as Grant suggested. The of probing
>> is merged inline instead of a separate file. It uses the newer
>> of gpio probe.
>
> It seems like a terrible idea to merge firmware-specific code into the
> driver. Is there are reason why of-based platforms can't just pass the
> data they need in pdata like everyone else?

Overall Thomas is doing the right thing here.  The driver data has to
be decoded *somewhere*, but since that code is definitely
driver-specific (as opposed to platform, subsystem, or arch specific)
putting it into the driver is absolutely the right thing to do.  Quite
a few drivers now do exactly this.

It is however generally a wise practice to limit the of-support code
to a hook in the drivers probe hook, and as you point out, care must
be taken to make sure both CONFIG_OF and !CONFIG_OF kernel builds
work.

>
> Not saying that it necessarily _is_ a terrible idea, but I think the
> reasoning behind it needs to be included in the patch description.

Nah, he doesn't really need to defend this since it is a well
established pattern.  device tree support is in core code now (see
of_node an of_match_table in include/linux/device.h), and other
drivers do exactly this.

>> Signed-off-by: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
>> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/gpio/i2c.txt |   39 ++++++++++++++
>>  drivers/i2c/busses/i2c-gpio.c                  |   67 ++++++++++++++++++++++-
>>  2 files changed, 103 insertions(+), 3 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/gpio/i2c.txt
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/i2c.txt b/Documentation/devicetree/bindings/gpio/i2c.txt
>> new file mode 100644
>> index 0000000..402569e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/i2c.txt
>
> This looks a bit backwards. i2c-gpio is a i2c driver which happens to
> utilize the gpio framework, not the other way around.

Yes, this should be in devicetree/bindings/i2c/i2c-gpio.txt

>
>> @@ -0,0 +1,39 @@
>> +GPIO-based I2C
>> +
>> +Required properties:
>> +- compatible : should be "i2c-gpio".
>> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
>> +Optional properties:
>> +- sda-is-open-drain : present if SDA gpio is open-drain.
>> +- scl-is-open-drain : present if SCL gpio is open-drain.
>> +- scl-is-output-only : present if SCL is an output gpio only.
>
> I think "present if the output driver for SCL cannot be turned off" is
> more accurate. Might also be worth mentioning that this will prevent
> clock stretching from working.
>
>> --- a/drivers/i2c/busses/i2c-gpio.c
>> +++ b/drivers/i2c/busses/i2c-gpio.c
>> @@ -14,6 +14,9 @@
>>  #include <linux/module.h>
>>  #include <linux/slab.h>
>>  #include <linux/platform_device.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/of_i2c.h>
>
> Do these headers provide stubs so non-of platforms won't break?

yes.

>
>> @@ -83,11 +86,52 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>>        struct i2c_gpio_platform_data *pdata;
>>        struct i2c_algo_bit_data *bit_data;
>>        struct i2c_adapter *adap;
>> +       struct device_node *np = pdev->dev.of_node;
>
> Would be nice if this could be eliminated on non-of platforms.

It's pretty benign.  However, for current mainline this needs to be
protected with a #ifdef CONFIG_OF.  In 2.6.29, the conditional can be
removed since of_node will be a permanent part of struct device.

>
>>        int ret;
>>
>>        pdata = pdev->dev.platform_data;
>> -       if (!pdata)
>> -               return -ENXIO;
>> +       if (!pdata) {
>> +               if (np && of_gpio_count(np) >= 2) {
>
> If that expression somehow always evaluates to false on non-of
> platforms, this might be ok. But please confirm if this is the case;
> otherwise, it looks like a pretty large addition to an otherwise very
> small driver.
>
> How about a tiny bit of restructuring: Move the block below into a
> separate function, which is only called if some constant expression
> says that of is enabled. Then you can move the declaration above
> either into the if block or into the function, depending on where you
> want to do the conditional above.

Yes, moving the dt decoding code to a separate function would keep the
dt-support better isolated from the core of the driver and would make
the CONFIG_OF/!CONFIG_OF handling better.

>
>>  static struct platform_driver i2c_gpio_driver = {
>>        .driver         = {
>>                .name   = "i2c-gpio",
>>                .owner  = THIS_MODULE,
>> +               .of_match_table = i2c_gpio_match,
>
> Is this field always present even when of is disabled?

No, not yet.  It will be in 2.6.29.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31 13:55       ` Jon Loeliger
  0 siblings, 0 replies; 51+ messages in thread
From: Jon Loeliger @ 2011-01-31 13:55 UTC (permalink / raw)
  To: Grant Likely
  Cc: Håvard Skinnemoen, nios2-dev, devicetree-discuss,
	linux-kernel, linux-i2c, Ben Dooks, Jean Delvare, Albert Herranz

> > Is this field always present even when of is disabled?
> 
> No, not yet.  It will be in 2.6.29.

Perhaps even 2.6.39? :-)

jdl

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31 13:55       ` Jon Loeliger
  0 siblings, 0 replies; 51+ messages in thread
From: Jon Loeliger @ 2011-01-31 13:55 UTC (permalink / raw)
  To: Grant Likely
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Jean Delvare,
	Albert Herranz, Håvard Skinnemoen

> > Is this field always present even when of is disabled?
> 
> No, not yet.  It will be in 2.6.29.

Perhaps even 2.6.39? :-)

jdl

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

* Re: [PATCH] i2c-gpio: add devicetree support
       [not found]       ` <E1PjuE3-0002Xy-6z-CYoMK+44s/E@public.gmane.org>
@ 2011-01-31 14:54         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 14:54 UTC (permalink / raw)
  To: Jon Loeliger
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH, Albert Herranz,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Jean Delvare,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Håvard Skinnemoen


[-- Attachment #1.1: Type: text/plain, Size: 281 bytes --]

On Jan 31, 2011 6:55 AM, "Jon Loeliger" <jdl-CYoMK+44s/E@public.gmane.org> wrote:
>
> > > Is this field always present even when of is disabled?
> >
> > No, not yet.  It will be in 2.6.29.
>
> Perhaps even 2.6.39? :-)

Gah!  Yes.  I keep doing that, I don't know why.

g.

>
> jdl

[-- Attachment #1.2: Type: text/html, Size: 446 bytes --]

[-- Attachment #2: Type: text/plain, Size: 192 bytes --]

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* [PATCH 1/3] of: define dummy of_get_property if not CONFIG_OF
@ 2011-01-31 15:25       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-31 15:25 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Jean Delvare, Thomas Chou

This will help to reduce the ifdef CONFIG_OF needed in most
platform data probing.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
 include/linux/of.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/linux/of.h b/include/linux/of.h
index cad7cf0..5e122cb 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -222,5 +222,13 @@ extern void of_attach_node(struct device_node *);
 extern void of_detach_node(struct device_node *);
 #endif
 
+#else /* !CONFIG_OF */
+
+static inline const void *of_get_property(const struct device_node *node,
+				const char *name, int *lenp)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_OF */
 #endif /* _LINUX_OF_H */
-- 
1.7.3.5


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

* [PATCH 1/3] of: define dummy of_get_property if not CONFIG_OF
@ 2011-01-31 15:25       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-31 15:25 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Thomas Chou

This will help to reduce the ifdef CONFIG_OF needed in most
platform data probing.

Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
---
 include/linux/of.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/linux/of.h b/include/linux/of.h
index cad7cf0..5e122cb 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -222,5 +222,13 @@ extern void of_attach_node(struct device_node *);
 extern void of_detach_node(struct device_node *);
 #endif
 
+#else /* !CONFIG_OF */
+
+static inline const void *of_get_property(const struct device_node *node,
+				const char *name, int *lenp)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_OF */
 #endif /* _LINUX_OF_H */
-- 
1.7.3.5

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

* [PATCH 2/3] of: of_gpiochip_add is needed only for gpiolib
@ 2011-01-31 15:25       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-31 15:25 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Jean Delvare, Thomas Chou

Some gpio drivers may not use gpiolib. In this case, struct gpio_chip
is not defined and of_gpiochip_add/remove are not needed.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
 include/linux/of_gpio.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 6598c04..fc96af0 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -71,9 +71,13 @@ static inline unsigned int of_gpio_count(struct device_node *np)
 	return 0;
 }
 
+#ifdef CONFIG_GPIOLIB
+
 static inline void of_gpiochip_add(struct gpio_chip *gc) { }
 static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
 
+#endif /* CONFIG_GPIOLIB */
+
 #endif /* CONFIG_OF_GPIO */
 
 /**
-- 
1.7.3.5


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

* [PATCH 2/3] of: of_gpiochip_add is needed only for gpiolib
@ 2011-01-31 15:25       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-31 15:25 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Thomas Chou

Some gpio drivers may not use gpiolib. In this case, struct gpio_chip
is not defined and of_gpiochip_add/remove are not needed.

Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
---
 include/linux/of_gpio.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 6598c04..fc96af0 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -71,9 +71,13 @@ static inline unsigned int of_gpio_count(struct device_node *np)
 	return 0;
 }
 
+#ifdef CONFIG_GPIOLIB
+
 static inline void of_gpiochip_add(struct gpio_chip *gc) { }
 static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
 
+#endif /* CONFIG_GPIOLIB */
+
 #endif /* CONFIG_OF_GPIO */
 
 /**
-- 
1.7.3.5

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

* [PATCH 3/3 v2] i2c-gpio: add devicetree support
@ 2011-01-31 15:25       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-31 15:25 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Jean Delvare, Albert Herranz, Thomas Chou

From: Albert Herranz <albert_herranz@yahoo.es>

This patch is based on an earlier patch from Albert Herranz,
http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
9854eb78607c641ab5ae85bcbe3c9d14ac113733

The dts binding is modified as Grant suggested. The of probing
is merged inline instead of a separate file. It uses the newer
of gpio probe.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++++++
 drivers/i2c/busses/i2c-gpio.c                      |   73 +++++++++++++++++++-
 2 files changed, 110 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..541fb10
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- udelay : signal toggle delay. SCL frequency is (500 / udelay) kHz
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	udelay = <2>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..dbf5b85 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,10 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,6 +80,53 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+/* Check if devicetree nodes exist and build platform data */
+static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
+	struct platform_device *pdev)
+{
+	struct i2c_gpio_platform_data *pdata = NULL;
+	struct device_node *np = pdev->dev.of_node;
+
+	if (np && of_gpio_count(np) >= 2) {
+		const __be32 *prop;
+		int sda_pin, scl_pin;
+
+		sda_pin = of_get_gpio_flags(np, 0, NULL);
+		scl_pin = of_get_gpio_flags(np, 1, NULL);
+		if (sda_pin < 0 || scl_pin < 0) {
+			pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+			       np->full_name, sda_pin, scl_pin);
+			goto err_gpio_pin;
+		}
+		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+		if (!pdata)
+			goto err_alloc_pdata;
+		pdata->sda_pin = sda_pin;
+		pdata->scl_pin = scl_pin;
+		prop = of_get_property(np, "sda-is-open-drain", NULL);
+		if (prop)
+			pdata->sda_is_open_drain = 1;
+		prop = of_get_property(np, "scl-is-open-drain", NULL);
+		if (prop)
+			pdata->scl_is_open_drain = 1;
+		prop = of_get_property(np, "scl-is-output-only", NULL);
+		if (prop)
+			pdata->scl_is_output_only = 1;
+		prop = of_get_property(np, "udelay", NULL);
+		if (prop)
+			pdata->udelay = be32_to_cpup(prop);
+		prop = of_get_property(np, "timeout", NULL);
+		if (prop) {
+			pdata->timeout =
+				msecs_to_jiffies(be32_to_cpup(prop));
+		}
+	}
+
+err_gpio_pin:
+err_alloc_pdata:
+	return pdata;
+}
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
@@ -87,6 +136,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 
 	pdata = pdev->dev.platform_data;
 	if (!pdata)
+		pdata = i2c_gpio_of_probe(pdev);
+	if (!pdata)
 		return -ENXIO;
 
 	ret = -ENOMEM;
@@ -143,6 +194,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -161,6 +213,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -172,6 +227,8 @@ err_request_sda:
 err_alloc_bit_data:
 	kfree(adap);
 err_alloc_adap:
+	if (!pdev->dev.platform_data)
+		kfree(pdata);
 	return ret;
 }
 
@@ -179,23 +236,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
+	struct i2c_algo_bit_data *bit_data;
 
 	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	bit_data = adap->algo_data;
+	pdata = bit_data->data;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
 	kfree(adap->algo_data);
 	kfree(adap);
+	if (!pdev->dev.platform_data)
+		kfree(pdata);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.3.5


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

* [PATCH 3/3 v2] i2c-gpio: add devicetree support
@ 2011-01-31 15:25       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-01-31 15:25 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz

From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>

This patch is based on an earlier patch from Albert Herranz,
http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
9854eb78607c641ab5ae85bcbe3c9d14ac113733

The dts binding is modified as Grant suggested. The of probing
is merged inline instead of a separate file. It uses the newer
of gpio probe.

Signed-off-by: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++++++
 drivers/i2c/busses/i2c-gpio.c                      |   73 +++++++++++++++++++-
 2 files changed, 110 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..541fb10
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- udelay : signal toggle delay. SCL frequency is (500 / udelay) kHz
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	udelay = <2>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..dbf5b85 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,10 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,6 +80,53 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+/* Check if devicetree nodes exist and build platform data */
+static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
+	struct platform_device *pdev)
+{
+	struct i2c_gpio_platform_data *pdata = NULL;
+	struct device_node *np = pdev->dev.of_node;
+
+	if (np && of_gpio_count(np) >= 2) {
+		const __be32 *prop;
+		int sda_pin, scl_pin;
+
+		sda_pin = of_get_gpio_flags(np, 0, NULL);
+		scl_pin = of_get_gpio_flags(np, 1, NULL);
+		if (sda_pin < 0 || scl_pin < 0) {
+			pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+			       np->full_name, sda_pin, scl_pin);
+			goto err_gpio_pin;
+		}
+		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+		if (!pdata)
+			goto err_alloc_pdata;
+		pdata->sda_pin = sda_pin;
+		pdata->scl_pin = scl_pin;
+		prop = of_get_property(np, "sda-is-open-drain", NULL);
+		if (prop)
+			pdata->sda_is_open_drain = 1;
+		prop = of_get_property(np, "scl-is-open-drain", NULL);
+		if (prop)
+			pdata->scl_is_open_drain = 1;
+		prop = of_get_property(np, "scl-is-output-only", NULL);
+		if (prop)
+			pdata->scl_is_output_only = 1;
+		prop = of_get_property(np, "udelay", NULL);
+		if (prop)
+			pdata->udelay = be32_to_cpup(prop);
+		prop = of_get_property(np, "timeout", NULL);
+		if (prop) {
+			pdata->timeout =
+				msecs_to_jiffies(be32_to_cpup(prop));
+		}
+	}
+
+err_gpio_pin:
+err_alloc_pdata:
+	return pdata;
+}
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
@@ -87,6 +136,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 
 	pdata = pdev->dev.platform_data;
 	if (!pdata)
+		pdata = i2c_gpio_of_probe(pdev);
+	if (!pdata)
 		return -ENXIO;
 
 	ret = -ENOMEM;
@@ -143,6 +194,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -161,6 +213,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -172,6 +227,8 @@ err_request_sda:
 err_alloc_bit_data:
 	kfree(adap);
 err_alloc_adap:
+	if (!pdev->dev.platform_data)
+		kfree(pdata);
 	return ret;
 }
 
@@ -179,23 +236,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
+	struct i2c_algo_bit_data *bit_data;
 
 	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	bit_data = adap->algo_data;
+	pdata = bit_data->data;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
 	kfree(adap->algo_data);
 	kfree(adap);
+	if (!pdev->dev.platform_data)
+		kfree(pdata);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.3.5

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

* Re: [3/3,v2] i2c-gpio: add devicetree support
@ 2011-01-31 21:14         ` Milton Miller
  0 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-01-31 21:14 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Haavard Skinnemoen, Grant Likely, Ben Dooks, linux-kernel,
	nios2-dev, devicetree-discuss, linux-i2c, Jean Delvare,
	Albert Herranz, Thomas Chou

On Mon, 31 Jan 2011 about 15:25:51 -0000, Thomas Chou wrote:

> This patch is based on an earlier patch from Albert Herranz,
> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
> 
> The dts binding is modified as Grant suggested. The of probing
> is merged inline instead of a separate file. It uses the newer
> of gpio probe.

> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..541fb10
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- udelay : signal toggle delay. SCL frequency is (500 / udelay) kHz
> +- timeout : clock stretching timeout in milliseconds.


This description needs a lot more text, specifically what happens
when these optional parameters are not present.

Why are the sda / sdl properties required, why can't the gpio description
describe them?   Should't they be part of the flags on the gpio?

And come to think about it, udelay is not a good property name.  The
fact linux uses it for a name of a function that causes a microsecond
delay not withstanding.


>  
> +/* Check if devicetree nodes exist and build platform data */
> +static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
> +	struct platform_device *pdev)
> +{
> +	struct i2c_gpio_platform_data *pdata = NULL;
> +	struct device_node *np = pdev->dev.of_node;
> +
> +	if (np && of_gpio_count(np) >= 2) {
> +		const __be32 *prop;
> +		int sda_pin, scl_pin;
> +
> +		sda_pin = of_get_gpio_flags(np, 0, NULL);
> +		scl_pin = of_get_gpio_flags(np, 1, NULL);
> +		if (sda_pin < 0 || scl_pin < 0) {
> +			pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +			       np->full_name, sda_pin, scl_pin);
> +			goto err_gpio_pin;
> +		}
> +		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
> +		if (!pdata)
> +			goto err_alloc_pdata;
> +		pdata->sda_pin = sda_pin;
> +		pdata->scl_pin = scl_pin;
> +		prop = of_get_property(np, "sda-is-open-drain", NULL);
> +		if (prop)
> +			pdata->sda_is_open_drain = 1;
> +		prop = of_get_property(np, "scl-is-open-drain", NULL);
> +		if (prop)
> +			pdata->scl_is_open_drain = 1;
> +		prop = of_get_property(np, "scl-is-output-only", NULL);
> +		if (prop)
> +			pdata->scl_is_output_only = 1;
> +		prop = of_get_property(np, "udelay", NULL);
> +		if (prop)
> +			pdata->udelay = be32_to_cpup(prop);
> +		prop = of_get_property(np, "timeout", NULL);
> +		if (prop) {
> +			pdata->timeout =
> +				msecs_to_jiffies(be32_to_cpup(prop));
> +		}
> +	}
> +
> +err_gpio_pin:
> +err_alloc_pdata:
> +	return pdata;
> +}

This looks nicer but  we don't really need two labels for the same point.
Also, it seems the whole function could be shifted left one tab by
returning early if the gpio count doesn't exist.


> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
>  	struct i2c_gpio_platform_data *pdata;
> @@ -87,6 +136,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  
>  	pdata = pdev->dev.platform_data;
>  	if (!pdata)
> +		pdata = i2c_gpio_of_probe(pdev);
> +	if (!pdata)
>  		return -ENXIO;
>  
>  	ret = -ENOMEM;
> @@ -143,6 +194,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -161,6 +213,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -172,6 +227,8 @@ err_request_sda:
>  err_alloc_bit_data:
>  	kfree(adap);
>  err_alloc_adap:
> +	if (!pdev->dev.platform_data)
> +		kfree(pdata);

This looks better with the code move to the function above, but
I don't like the condition on this free here ...

>  	return ret;
>  }
>  
> @@ -179,23 +236,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
> +	struct i2c_algo_bit_data *bit_data;
>  
>  	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	bit_data = adap->algo_data;
> +	pdata = bit_data->data;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
>  	kfree(adap->algo_data);
>  	kfree(adap);
> +	if (!pdev->dev.platform_data)
> +		kfree(pdata);

and especially here ... it seems unrelated.

Looking at devices/base/platform.c, how about just allocating the
initial platform data struct on the stack in i2c_gpio_of_probe
and then calling platform_device_add_data?  That way the pdev
is responsible for freeing the data.

>  
>  	return 0;
>  }
>  
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),

milton

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

* Re: [3/3,v2] i2c-gpio: add devicetree support
@ 2011-01-31 21:14         ` Milton Miller
  0 siblings, 0 replies; 51+ messages in thread
From: Milton Miller @ 2011-01-31 21:14 UTC (permalink / raw)
  Cc: Haavard Skinnemoen, Grant Likely, Ben Dooks,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz,
	Thomas Chou

On Mon, 31 Jan 2011 about 15:25:51 -0000, Thomas Chou wrote:

> This patch is based on an earlier patch from Albert Herranz,
> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
> 
> The dts binding is modified as Grant suggested. The of probing
> is merged inline instead of a separate file. It uses the newer
> of gpio probe.

> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..541fb10
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- udelay : signal toggle delay. SCL frequency is (500 / udelay) kHz
> +- timeout : clock stretching timeout in milliseconds.


This description needs a lot more text, specifically what happens
when these optional parameters are not present.

Why are the sda / sdl properties required, why can't the gpio description
describe them?   Should't they be part of the flags on the gpio?

And come to think about it, udelay is not a good property name.  The
fact linux uses it for a name of a function that causes a microsecond
delay not withstanding.


>  
> +/* Check if devicetree nodes exist and build platform data */
> +static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
> +	struct platform_device *pdev)
> +{
> +	struct i2c_gpio_platform_data *pdata = NULL;
> +	struct device_node *np = pdev->dev.of_node;
> +
> +	if (np && of_gpio_count(np) >= 2) {
> +		const __be32 *prop;
> +		int sda_pin, scl_pin;
> +
> +		sda_pin = of_get_gpio_flags(np, 0, NULL);
> +		scl_pin = of_get_gpio_flags(np, 1, NULL);
> +		if (sda_pin < 0 || scl_pin < 0) {
> +			pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +			       np->full_name, sda_pin, scl_pin);
> +			goto err_gpio_pin;
> +		}
> +		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
> +		if (!pdata)
> +			goto err_alloc_pdata;
> +		pdata->sda_pin = sda_pin;
> +		pdata->scl_pin = scl_pin;
> +		prop = of_get_property(np, "sda-is-open-drain", NULL);
> +		if (prop)
> +			pdata->sda_is_open_drain = 1;
> +		prop = of_get_property(np, "scl-is-open-drain", NULL);
> +		if (prop)
> +			pdata->scl_is_open_drain = 1;
> +		prop = of_get_property(np, "scl-is-output-only", NULL);
> +		if (prop)
> +			pdata->scl_is_output_only = 1;
> +		prop = of_get_property(np, "udelay", NULL);
> +		if (prop)
> +			pdata->udelay = be32_to_cpup(prop);
> +		prop = of_get_property(np, "timeout", NULL);
> +		if (prop) {
> +			pdata->timeout =
> +				msecs_to_jiffies(be32_to_cpup(prop));
> +		}
> +	}
> +
> +err_gpio_pin:
> +err_alloc_pdata:
> +	return pdata;
> +}

This looks nicer but  we don't really need two labels for the same point.
Also, it seems the whole function could be shifted left one tab by
returning early if the gpio count doesn't exist.


> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
>  	struct i2c_gpio_platform_data *pdata;
> @@ -87,6 +136,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  
>  	pdata = pdev->dev.platform_data;
>  	if (!pdata)
> +		pdata = i2c_gpio_of_probe(pdev);
> +	if (!pdata)
>  		return -ENXIO;
>  
>  	ret = -ENOMEM;
> @@ -143,6 +194,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -161,6 +213,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -172,6 +227,8 @@ err_request_sda:
>  err_alloc_bit_data:
>  	kfree(adap);
>  err_alloc_adap:
> +	if (!pdev->dev.platform_data)
> +		kfree(pdata);

This looks better with the code move to the function above, but
I don't like the condition on this free here ...

>  	return ret;
>  }
>  
> @@ -179,23 +236,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
> +	struct i2c_algo_bit_data *bit_data;
>  
>  	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	bit_data = adap->algo_data;
> +	pdata = bit_data->data;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
>  	kfree(adap->algo_data);
>  	kfree(adap);
> +	if (!pdev->dev.platform_data)
> +		kfree(pdata);

and especially here ... it seems unrelated.

Looking at devices/base/platform.c, how about just allocating the
initial platform data struct on the stack in i2c_gpio_of_probe
and then calling platform_device_add_data?  That way the pdev
is responsible for freeing the data.

>  
>  	return 0;
>  }
>  
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),

milton

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

* Re: [3/3,v2] i2c-gpio: add devicetree support
@ 2011-01-31 21:29           ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 21:29 UTC (permalink / raw)
  To: Milton Miller
  Cc: Thomas Chou, Haavard Skinnemoen, Ben Dooks, linux-kernel,
	nios2-dev, devicetree-discuss, linux-i2c, Jean Delvare,
	Albert Herranz

On Mon, Jan 31, 2011 at 2:14 PM, Milton Miller <miltonm@bga.com> wrote:
> On Mon, 31 Jan 2011 about 15:25:51 -0000, Thomas Chou wrote:
>
>> This patch is based on an earlier patch from Albert Herranz,
>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
>>
>> The dts binding is modified as Grant suggested. The of probing
>> is merged inline instead of a separate file. It uses the newer
>> of gpio probe.
>
>> @@ -172,6 +227,8 @@ err_request_sda:
>>  err_alloc_bit_data:
>>       kfree(adap);
>>  err_alloc_adap:
>> +     if (!pdev->dev.platform_data)
>> +             kfree(pdata);
>
> This looks better with the code move to the function above, but
> I don't like the condition on this free here ...
>
>>       return ret;
>>  }
>>
>> @@ -179,23 +236,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>>  {
>>       struct i2c_gpio_platform_data *pdata;
>>       struct i2c_adapter *adap;
>> +     struct i2c_algo_bit_data *bit_data;
>>
>>       adap = platform_get_drvdata(pdev);
>> -     pdata = pdev->dev.platform_data;
>> +     bit_data = adap->algo_data;
>> +     pdata = bit_data->data;
>>
>>       i2c_del_adapter(adap);
>>       gpio_free(pdata->scl_pin);
>>       gpio_free(pdata->sda_pin);
>>       kfree(adap->algo_data);
>>       kfree(adap);
>> +     if (!pdev->dev.platform_data)
>> +             kfree(pdata);
>
> and especially here ... it seems unrelated.
>
> Looking at devices/base/platform.c, how about just allocating the
> initial platform data struct on the stack in i2c_gpio_of_probe
> and then calling platform_device_add_data?  That way the pdev
> is responsible for freeing the data.

No, *do not* use platform_device_add_data().  It stores the pointer in
pdev->dev.platform_data which gets freed when the last reference to
the device is dropped (it gets removed from the bus).  Thomas wants
something that gets freed when the driver is unbound.

Driver code must never modify the pdev->dev.platform_data pointer.
Doing so causes all kinds of lifecycle ambiguity which messes up
driver unbinding/rebinding and module load/unload.  When a driver
needs a modifiable copy of platform data, then it must include a copy
of the platform_data in the driver private data structure.  It should
be straight forward to refactor this driver to do so.

g.

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

* Re: [3/3,v2] i2c-gpio: add devicetree support
@ 2011-01-31 21:29           ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 21:29 UTC (permalink / raw)
  To: Milton Miller
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Jean Delvare,
	Albert Herranz, Haavard Skinnemoen

On Mon, Jan 31, 2011 at 2:14 PM, Milton Miller <miltonm-ogEGBHC/i9Y@public.gmane.org> wrote:
> On Mon, 31 Jan 2011 about 15:25:51 -0000, Thomas Chou wrote:
>
>> This patch is based on an earlier patch from Albert Herranz,
>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
>>
>> The dts binding is modified as Grant suggested. The of probing
>> is merged inline instead of a separate file. It uses the newer
>> of gpio probe.
>
>> @@ -172,6 +227,8 @@ err_request_sda:
>>  err_alloc_bit_data:
>>       kfree(adap);
>>  err_alloc_adap:
>> +     if (!pdev->dev.platform_data)
>> +             kfree(pdata);
>
> This looks better with the code move to the function above, but
> I don't like the condition on this free here ...
>
>>       return ret;
>>  }
>>
>> @@ -179,23 +236,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>>  {
>>       struct i2c_gpio_platform_data *pdata;
>>       struct i2c_adapter *adap;
>> +     struct i2c_algo_bit_data *bit_data;
>>
>>       adap = platform_get_drvdata(pdev);
>> -     pdata = pdev->dev.platform_data;
>> +     bit_data = adap->algo_data;
>> +     pdata = bit_data->data;
>>
>>       i2c_del_adapter(adap);
>>       gpio_free(pdata->scl_pin);
>>       gpio_free(pdata->sda_pin);
>>       kfree(adap->algo_data);
>>       kfree(adap);
>> +     if (!pdev->dev.platform_data)
>> +             kfree(pdata);
>
> and especially here ... it seems unrelated.
>
> Looking at devices/base/platform.c, how about just allocating the
> initial platform data struct on the stack in i2c_gpio_of_probe
> and then calling platform_device_add_data?  That way the pdev
> is responsible for freeing the data.

No, *do not* use platform_device_add_data().  It stores the pointer in
pdev->dev.platform_data which gets freed when the last reference to
the device is dropped (it gets removed from the bus).  Thomas wants
something that gets freed when the driver is unbound.

Driver code must never modify the pdev->dev.platform_data pointer.
Doing so causes all kinds of lifecycle ambiguity which messes up
driver unbinding/rebinding and module load/unload.  When a driver
needs a modifiable copy of platform data, then it must include a copy
of the platform_data in the driver private data structure.  It should
be straight forward to refactor this driver to do so.

g.

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

* Re: [PATCH 1/3] of: define dummy of_get_property if not CONFIG_OF
@ 2011-01-31 22:10         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 22:10 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Haavard Skinnemoen, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare

On Mon, Jan 31, 2011 at 11:25:49PM +0800, Thomas Chou wrote:
> This will help to reduce the ifdef CONFIG_OF needed in most
> platform data probing.
> 
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>

With moving the dt reading into a separate function protected by
CONFIG_OF, this patch shouldn't be necessary.

g.

> ---
>  include/linux/of.h |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index cad7cf0..5e122cb 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -222,5 +222,13 @@ extern void of_attach_node(struct device_node *);
>  extern void of_detach_node(struct device_node *);
>  #endif
>  
> +#else /* !CONFIG_OF */
> +
> +static inline const void *of_get_property(const struct device_node *node,
> +				const char *name, int *lenp)
> +{
> +	return NULL;
> +}
> +
>  #endif /* CONFIG_OF */
>  #endif /* _LINUX_OF_H */
> -- 
> 1.7.3.5
> 

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

* Re: [PATCH 1/3] of: define dummy of_get_property if not CONFIG_OF
@ 2011-01-31 22:10         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 22:10 UTC (permalink / raw)
  To: Thomas Chou
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Jean Delvare,
	Haavard Skinnemoen

On Mon, Jan 31, 2011 at 11:25:49PM +0800, Thomas Chou wrote:
> This will help to reduce the ifdef CONFIG_OF needed in most
> platform data probing.
> 
> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>

With moving the dt reading into a separate function protected by
CONFIG_OF, this patch shouldn't be necessary.

g.

> ---
>  include/linux/of.h |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index cad7cf0..5e122cb 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -222,5 +222,13 @@ extern void of_attach_node(struct device_node *);
>  extern void of_detach_node(struct device_node *);
>  #endif
>  
> +#else /* !CONFIG_OF */
> +
> +static inline const void *of_get_property(const struct device_node *node,
> +				const char *name, int *lenp)
> +{
> +	return NULL;
> +}
> +
>  #endif /* CONFIG_OF */
>  #endif /* _LINUX_OF_H */
> -- 
> 1.7.3.5
> 

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

* Re: [PATCH 2/3] of: of_gpiochip_add is needed only for gpiolib
@ 2011-01-31 22:16         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 22:16 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Haavard Skinnemoen, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare

On Mon, Jan 31, 2011 at 11:25:50PM +0800, Thomas Chou wrote:
> Some gpio drivers may not use gpiolib. In this case, struct gpio_chip
> is not defined and of_gpiochip_add/remove are not needed.
> 
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>

I'm not thrilled with the idea of supporting a gpio subsystem that
doesn't use gpiolib.  These functions don't even make sense if gpiolib
isn't being used (gpio_chip is a gpiolib construct).

Have you posted a patch that depends on this change?  Patch 3 in this
series doesn't seem to need it.

g.

> ---
>  include/linux/of_gpio.h |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
> index 6598c04..fc96af0 100644
> --- a/include/linux/of_gpio.h
> +++ b/include/linux/of_gpio.h
> @@ -71,9 +71,13 @@ static inline unsigned int of_gpio_count(struct device_node *np)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_GPIOLIB
> +
>  static inline void of_gpiochip_add(struct gpio_chip *gc) { }
>  static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
>  
> +#endif /* CONFIG_GPIOLIB */
> +
>  #endif /* CONFIG_OF_GPIO */
>  
>  /**
> -- 
> 1.7.3.5
> 

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

* Re: [PATCH 2/3] of: of_gpiochip_add is needed only for gpiolib
@ 2011-01-31 22:16         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 22:16 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Haavard Skinnemoen, Ben Dooks,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare

On Mon, Jan 31, 2011 at 11:25:50PM +0800, Thomas Chou wrote:
> Some gpio drivers may not use gpiolib. In this case, struct gpio_chip
> is not defined and of_gpiochip_add/remove are not needed.
> 
> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>

I'm not thrilled with the idea of supporting a gpio subsystem that
doesn't use gpiolib.  These functions don't even make sense if gpiolib
isn't being used (gpio_chip is a gpiolib construct).

Have you posted a patch that depends on this change?  Patch 3 in this
series doesn't seem to need it.

g.

> ---
>  include/linux/of_gpio.h |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
> index 6598c04..fc96af0 100644
> --- a/include/linux/of_gpio.h
> +++ b/include/linux/of_gpio.h
> @@ -71,9 +71,13 @@ static inline unsigned int of_gpio_count(struct device_node *np)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_GPIOLIB
> +
>  static inline void of_gpiochip_add(struct gpio_chip *gc) { }
>  static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
>  
> +#endif /* CONFIG_GPIOLIB */
> +
>  #endif /* CONFIG_OF_GPIO */
>  
>  /**
> -- 
> 1.7.3.5
> 

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31 22:35       ` Håvard Skinnemoen
  0 siblings, 0 replies; 51+ messages in thread
From: Håvard Skinnemoen @ 2011-01-31 22:35 UTC (permalink / raw)
  To: Grant Likely
  Cc: Thomas Chou, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare, Albert Herranz

Hi,

On Mon, Jan 31, 2011 at 12:09 AM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> On Sun, Jan 30, 2011 at 8:26 PM, Håvard Skinnemoen
> <hskinnemoen@gmail.com> wrote:
>> Hi,
>>
>> On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas@wytron.com.tw> wrote:
>>> From: Albert Herranz <albert_herranz@yahoo.es>
>>>
>>> This patch is based on an earlier patch from Albert Herranz,
>>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
>>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
>>
>> That commit has a single-line description of which I don't understand
>> a single word (unless "wii" is what I think it is, which seems
>> likely). Could you please explain how that commit relates to this
>> patch?
>
> The URL got wrapped.  Try this one (assuming my mailer doesn't wrap it):
>
> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/9854eb78607c641ab5ae85bcbe3c9d14ac113733

Ok, that seems to be a _bit_ more related, but not that much. I'd
really prefer a patch description which can stand on its own.

>>> The dts binding is modified as Grant suggested. The of probing
>>> is merged inline instead of a separate file. It uses the newer
>>> of gpio probe.
>>
>> It seems like a terrible idea to merge firmware-specific code into the
>> driver. Is there are reason why of-based platforms can't just pass the
>> data they need in pdata like everyone else?
>
> Overall Thomas is doing the right thing here.  The driver data has to
> be decoded *somewhere*, but since that code is definitely
> driver-specific (as opposed to platform, subsystem, or arch specific)
> putting it into the driver is absolutely the right thing to do.  Quite
> a few drivers now do exactly this.

Ok, I'm convinced that this is the right thing to do.

> It is however generally a wise practice to limit the of-support code
> to a hook in the drivers probe hook, and as you point out, care must
> be taken to make sure both CONFIG_OF and !CONFIG_OF kernel builds
> work.
>
>>
>> Not saying that it necessarily _is_ a terrible idea, but I think the
>> reasoning behind it needs to be included in the patch description.
>
> Nah, he doesn't really need to defend this since it is a well
> established pattern.  device tree support is in core code now (see
> of_node an of_match_table in include/linux/device.h), and other
> drivers do exactly this.

Well, perhaps you're right, but I still think the patch description is
a bit on the thin side. In particular, terms like "as Grant suggested"
isn't very helpful for people like me who don't know what you
suggested (even though I'm sure it was a good suggestion).

I think the patch lacks a good description of what's being changed and
why. The references may be nice to have as a supplement to that, but
describing things entirely in terms of some unknown e-mail discussion
that happened earlier is not very helpful for people who want to
figure out what's going on a couple of months or years from now.

Havard

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31 22:35       ` Håvard Skinnemoen
  0 siblings, 0 replies; 51+ messages in thread
From: Håvard Skinnemoen @ 2011-01-31 22:35 UTC (permalink / raw)
  To: Grant Likely
  Cc: Thomas Chou, Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz

Hi,

On Mon, Jan 31, 2011 at 12:09 AM, Grant Likely
<grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> On Sun, Jan 30, 2011 at 8:26 PM, Håvard Skinnemoen
> <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Hi,
>>
>> On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org> wrote:
>>> From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
>>>
>>> This patch is based on an earlier patch from Albert Herranz,
>>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
>>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
>>
>> That commit has a single-line description of which I don't understand
>> a single word (unless "wii" is what I think it is, which seems
>> likely). Could you please explain how that commit relates to this
>> patch?
>
> The URL got wrapped.  Try this one (assuming my mailer doesn't wrap it):
>
> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/9854eb78607c641ab5ae85bcbe3c9d14ac113733

Ok, that seems to be a _bit_ more related, but not that much. I'd
really prefer a patch description which can stand on its own.

>>> The dts binding is modified as Grant suggested. The of probing
>>> is merged inline instead of a separate file. It uses the newer
>>> of gpio probe.
>>
>> It seems like a terrible idea to merge firmware-specific code into the
>> driver. Is there are reason why of-based platforms can't just pass the
>> data they need in pdata like everyone else?
>
> Overall Thomas is doing the right thing here.  The driver data has to
> be decoded *somewhere*, but since that code is definitely
> driver-specific (as opposed to platform, subsystem, or arch specific)
> putting it into the driver is absolutely the right thing to do.  Quite
> a few drivers now do exactly this.

Ok, I'm convinced that this is the right thing to do.

> It is however generally a wise practice to limit the of-support code
> to a hook in the drivers probe hook, and as you point out, care must
> be taken to make sure both CONFIG_OF and !CONFIG_OF kernel builds
> work.
>
>>
>> Not saying that it necessarily _is_ a terrible idea, but I think the
>> reasoning behind it needs to be included in the patch description.
>
> Nah, he doesn't really need to defend this since it is a well
> established pattern.  device tree support is in core code now (see
> of_node an of_match_table in include/linux/device.h), and other
> drivers do exactly this.

Well, perhaps you're right, but I still think the patch description is
a bit on the thin side. In particular, terms like "as Grant suggested"
isn't very helpful for people like me who don't know what you
suggested (even though I'm sure it was a good suggestion).

I think the patch lacks a good description of what's being changed and
why. The references may be nice to have as a supplement to that, but
describing things entirely in terms of some unknown e-mail discussion
that happened earlier is not very helpful for people who want to
figure out what's going on a couple of months or years from now.

Havard

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31 23:01         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 23:01 UTC (permalink / raw)
  To: Håvard Skinnemoen
  Cc: Thomas Chou, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare, Albert Herranz

On Mon, Jan 31, 2011 at 02:35:31PM -0800, Håvard Skinnemoen wrote:
> Hi,
> 
> On Mon, Jan 31, 2011 at 12:09 AM, Grant Likely
> <grant.likely@secretlab.ca> wrote:
> > On Sun, Jan 30, 2011 at 8:26 PM, Håvard Skinnemoen
> > <hskinnemoen@gmail.com> wrote:
> >> Hi,
> >>
> >> On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas@wytron.com.tw> wrote:
> >>> From: Albert Herranz <albert_herranz@yahoo.es>
> >>>
> >>> This patch is based on an earlier patch from Albert Herranz,
> >>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
> >>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
> >>
> >> That commit has a single-line description of which I don't understand
> >> a single word (unless "wii" is what I think it is, which seems
> >> likely). Could you please explain how that commit relates to this
> >> patch?
> >
> > The URL got wrapped.  Try this one (assuming my mailer doesn't wrap it):
> >
> > http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/9854eb78607c641ab5ae85bcbe3c9d14ac113733
> 
> Ok, that seems to be a _bit_ more related, but not that much. I'd
> really prefer a patch description which can stand on its own.
> 
[...]
>
> >> Not saying that it necessarily _is_ a terrible idea, but I think the
> >> reasoning behind it needs to be included in the patch description.
> >
> > Nah, he doesn't really need to defend this since it is a well
> > established pattern.  device tree support is in core code now (see
> > of_node an of_match_table in include/linux/device.h), and other
> > drivers do exactly this.
> 
> Well, perhaps you're right, but I still think the patch description is
> a bit on the thin side. In particular, terms like "as Grant suggested"
> isn't very helpful for people like me who don't know what you
> suggested (even though I'm sure it was a good suggestion).
> 
> I think the patch lacks a good description of what's being changed and
> why. The references may be nice to have as a supplement to that, but
> describing things entirely in terms of some unknown e-mail discussion
> that happened earlier is not very helpful for people who want to
> figure out what's going on a couple of months or years from now.

No arguments from me on those points.

g.

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-01-31 23:01         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-01-31 23:01 UTC (permalink / raw)
  To: Håvard Skinnemoen
  Cc: Thomas Chou, Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz

On Mon, Jan 31, 2011 at 02:35:31PM -0800, Håvard Skinnemoen wrote:
> Hi,
> 
> On Mon, Jan 31, 2011 at 12:09 AM, Grant Likely
> <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> > On Sun, Jan 30, 2011 at 8:26 PM, Håvard Skinnemoen
> > <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> >> Hi,
> >>
> >> On Sun, Jan 30, 2011 at 7:56 AM, Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org> wrote:
> >>> From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> >>>
> >>> This patch is based on an earlier patch from Albert Herranz,
> >>> http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/
> >>> 9854eb78607c641ab5ae85bcbe3c9d14ac113733
> >>
> >> That commit has a single-line description of which I don't understand
> >> a single word (unless "wii" is what I think it is, which seems
> >> likely). Could you please explain how that commit relates to this
> >> patch?
> >
> > The URL got wrapped.  Try this one (assuming my mailer doesn't wrap it):
> >
> > http://git.infradead.org/users/herraa1/gc-linux-2.6.git/commit/9854eb78607c641ab5ae85bcbe3c9d14ac113733
> 
> Ok, that seems to be a _bit_ more related, but not that much. I'd
> really prefer a patch description which can stand on its own.
> 
[...]
>
> >> Not saying that it necessarily _is_ a terrible idea, but I think the
> >> reasoning behind it needs to be included in the patch description.
> >
> > Nah, he doesn't really need to defend this since it is a well
> > established pattern.  device tree support is in core code now (see
> > of_node an of_match_table in include/linux/device.h), and other
> > drivers do exactly this.
> 
> Well, perhaps you're right, but I still think the patch description is
> a bit on the thin side. In particular, terms like "as Grant suggested"
> isn't very helpful for people like me who don't know what you
> suggested (even though I'm sure it was a good suggestion).
> 
> I think the patch lacks a good description of what's being changed and
> why. The references may be nice to have as a supplement to that, but
> describing things entirely in terms of some unknown e-mail discussion
> that happened earlier is not very helpful for people who want to
> figure out what's going on a couple of months or years from now.

No arguments from me on those points.

g.

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

* [PATCH] i2c-gpio: add devicetree support
@ 2011-02-03  2:26             ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-03  2:26 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Jean Delvare, Thomas Chou, Albert Herranz

This patch adds devicetree support to i2c-gpio driver. It converts
dts bindings and allocates a struct i2c_gpio_platform_data, which
will be freed on driver removal.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 ++++++++++
 drivers/i2c/busses/i2c-gpio.c                      |   83 +++++++++++++++++++-
 2 files changed, 119 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..4b31bbe 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,8 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,15 +78,74 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
+	struct platform_device *pdev)
+{
+	struct i2c_gpio_platform_data *pdata = NULL;
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+
+	if (!np || of_gpio_count(np) < 2)
+		goto err;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		goto err;
+	}
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto err;
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", NULL);
+	if (prop)
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", NULL);
+	if (prop) {
+		pdata->timeout =
+			msecs_to_jiffies(be32_to_cpup(prop));
+	}
+err:
+	return pdata;
+}
+#else
+static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
+	struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
-	struct i2c_gpio_platform_data *pdata;
+	struct i2c_gpio_platform_data *pdata, *pdata_of = NULL;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
 	pdata = pdev->dev.platform_data;
 	if (!pdata)
+		pdata = pdata_of = i2c_gpio_of_probe(pdev);
+	if (!pdata)
 		return -ENXIO;
 
 	ret = -ENOMEM;
@@ -143,6 +202,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	if (pdata_of)
+		adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -161,6 +222,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -172,6 +236,7 @@ err_request_sda:
 err_alloc_bit_data:
 	kfree(adap);
 err_alloc_adap:
+	kfree(pdata_of);
 	return ret;
 }
 
@@ -179,23 +244,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
+	struct i2c_algo_bit_data *bit_data;
 
 	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	bit_data = adap->algo_data;
+	pdata = bit_data->data;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
 	kfree(adap->algo_data);
+	if (adap->dev.of_node)
+		kfree(pdata);
 	kfree(adap);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.3.5


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

* [PATCH] i2c-gpio: add devicetree support
@ 2011-02-03  2:26             ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-03  2:26 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Thomas Chou,
	Albert Herranz

This patch adds devicetree support to i2c-gpio driver. It converts
dts bindings and allocates a struct i2c_gpio_platform_data, which
will be freed on driver removal.

Signed-off-by: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 ++++++++++
 drivers/i2c/busses/i2c-gpio.c                      |   83 +++++++++++++++++++-
 2 files changed, 119 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..4b31bbe 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,8 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,15 +78,74 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
+	struct platform_device *pdev)
+{
+	struct i2c_gpio_platform_data *pdata = NULL;
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+
+	if (!np || of_gpio_count(np) < 2)
+		goto err;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		goto err;
+	}
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto err;
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", NULL);
+	if (prop)
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", NULL);
+	if (prop) {
+		pdata->timeout =
+			msecs_to_jiffies(be32_to_cpup(prop));
+	}
+err:
+	return pdata;
+}
+#else
+static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
+	struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
-	struct i2c_gpio_platform_data *pdata;
+	struct i2c_gpio_platform_data *pdata, *pdata_of = NULL;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
 	pdata = pdev->dev.platform_data;
 	if (!pdata)
+		pdata = pdata_of = i2c_gpio_of_probe(pdev);
+	if (!pdata)
 		return -ENXIO;
 
 	ret = -ENOMEM;
@@ -143,6 +202,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	if (pdata_of)
+		adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -161,6 +222,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -172,6 +236,7 @@ err_request_sda:
 err_alloc_bit_data:
 	kfree(adap);
 err_alloc_adap:
+	kfree(pdata_of);
 	return ret;
 }
 
@@ -179,23 +244,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
+	struct i2c_algo_bit_data *bit_data;
 
 	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	bit_data = adap->algo_data;
+	pdata = bit_data->data;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
 	kfree(adap->algo_data);
+	if (adap->dev.of_node)
+		kfree(pdata);
 	kfree(adap);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.3.5

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

* Re: [PATCH] i2c-gpio: add devicetree support
  2011-02-03  2:26             ` Thomas Chou
  (?)
@ 2011-02-03  4:24             ` Håvard Skinnemoen
  -1 siblings, 0 replies; 51+ messages in thread
From: Håvard Skinnemoen @ 2011-02-03  4:24 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Grant Likely, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare, Albert Herranz

On Wed, Feb 2, 2011 at 6:26 PM, Thomas Chou <thomas@wytron.com.tw> wrote:
> This patch adds devicetree support to i2c-gpio driver. It converts
> dts bindings and allocates a struct i2c_gpio_platform_data, which
> will be freed on driver removal.
>
> Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>

Acked-by: Haavard Skinnemoen <hskinnemoen@gmail.com>

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-02-03 18:07               ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-02-03 18:07 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Haavard Skinnemoen, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Jean Delvare, Albert Herranz

On Thu, Feb 03, 2011 at 10:26:20AM +0800, Thomas Chou wrote:
> This patch adds devicetree support to i2c-gpio driver. It converts
> dts bindings and allocates a struct i2c_gpio_platform_data, which
> will be freed on driver removal.
> 
> Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> ---
> for v2.6.39
> v2 move of nodes probing to a hook, which will be optimized out
>      when devicetree is not used.
>    use linux/gpio.h.
>    move binding doc to i2c/i2c-gpio.txt.
> v3 use speed-hz instead of udelay in dts binding.
>    condition the devicetree probe.
> 
>  Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 ++++++++++
>  drivers/i2c/busses/i2c-gpio.c                      |   83 +++++++++++++++++++-
>  2 files changed, 119 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.
> +- timeout : clock stretching timeout in milliseconds.
> +
> +Example:
> +
> +gpio0: starlet-gpio@0d8000c0 {
> +	compatible = "nintendo,starlet-gpio";
> +	reg = <0d8000c0 4>;
> +	gpio-controller;
> +	#gpio-cells = <2>;
> +};
> +
> +i2c-video {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "i2c-gpio";
> +
> +	gpios = <&gpio0 10 0	/* SDA line */
> +		 &gpio0 11 0	/* SCL line */
> +		>;
> +	sda-is-open-drain;
> +	scl-is-open-drain;
> +	scl-is-output-only;
> +	speed-hz = <250000>;
> +
> +	audio-video-encoder {
> +		compatible = "nintendo,wii-ave-rvl";
> +		reg = <70>;
> +	};
> +};
> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
> index d9aa9a6..4b31bbe 100644
> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,8 +14,8 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> -
> -#include <asm/gpio.h>
> +#include <linux/gpio.h>
> +#include <linux/of_i2c.h>
>  
>  /* Toggle SDA by changing the direction of the pin */
>  static void i2c_gpio_setsda_dir(void *data, int state)
> @@ -78,15 +78,74 @@ static int i2c_gpio_getscl(void *data)
>  	return gpio_get_value(pdata->scl_pin);
>  }
>  
> +#ifdef CONFIG_OF
> +#include <linux/of_gpio.h>
> +
> +/* Check if devicetree nodes exist and build platform data */
> +static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
> +	struct platform_device *pdev)
> +{
> +	struct i2c_gpio_platform_data *pdata = NULL;
> +	struct device_node *np = pdev->dev.of_node;
> +	const __be32 *prop;
> +	int sda_pin, scl_pin;
> +
> +	if (!np || of_gpio_count(np) < 2)
> +		goto err;
> +
> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
> +	if (sda_pin < 0 || scl_pin < 0) {
> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +		       np->full_name, sda_pin, scl_pin);
> +		goto err;
> +	}
> +
> +	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
> +	if (!pdata)
> +		goto err;
> +
> +	pdata->sda_pin = sda_pin;
> +	pdata->scl_pin = scl_pin;
> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
> +	if (prop)
> +		pdata->sda_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
> +	if (prop)
> +		pdata->scl_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-output-only", NULL);
> +	if (prop)
> +		pdata->scl_is_output_only = 1;
> +	prop = of_get_property(np, "speed-hz", NULL);
> +	if (prop)
> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
> +	prop = of_get_property(np, "timeout", NULL);
> +	if (prop) {
> +		pdata->timeout =
> +			msecs_to_jiffies(be32_to_cpup(prop));
> +	}
> +err:
> +	return pdata;
> +}
> +#else
> +static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
> +	struct platform_device *pdev)
> +{
> +	return NULL;
> +}
> +#endif
> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
> -	struct i2c_gpio_platform_data *pdata;
> +	struct i2c_gpio_platform_data *pdata, *pdata_of = NULL;
>  	struct i2c_algo_bit_data *bit_data;
>  	struct i2c_adapter *adap;
>  	int ret;
>  
>  	pdata = pdev->dev.platform_data;
>  	if (!pdata)
> +		pdata = pdata_of = i2c_gpio_of_probe(pdev);
> +	if (!pdata)
>  		return -ENXIO;
>  
>  	ret = -ENOMEM;
> @@ -143,6 +202,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	if (pdata_of)
> +		adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -161,6 +222,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -172,6 +236,7 @@ err_request_sda:
>  err_alloc_bit_data:
>  	kfree(adap);
>  err_alloc_adap:
> +	kfree(pdata_of);
>  	return ret;
>  }
>  
> @@ -179,23 +244,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
> +	struct i2c_algo_bit_data *bit_data;
>  
>  	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	bit_data = adap->algo_data;
> +	pdata = bit_data->data;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
>  	kfree(adap->algo_data);
> +	if (adap->dev.of_node)
> +		kfree(pdata);

Oh, wow.  Okay, so this driver does an odd thing.  It doesn't have
its own private data structure and instead uses pdata as private data.
Rather than doing these gymnastics with the pdata pointer, may I
suggest the following refactorization:

1) Add a private data structure:
struct i2c_gpio_private_data {
	struct i2c_adapter adap;
	struct i2c_algo_bit_data bit_data;
	struct i2c_gpio_platform_data pdata;
}

2) simplify the alloc/free of data in probe/remove:

alloc:
	struct i2c_gpio_private_data *priv;
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	adap = &priv->adap;
	bit_data = &priv->bit_data;
	pdata = &priv->pdata;
	...
	platform_set_drvdata(pdev, priv);

free:
	priv = platform_get_drvdata(pdev);
	kfree(priv);

3) Copy pdata into the allocated private data

	if (pdev->dev.platform_data)
		adap->pdata = *pdev->dev.platform_data;
	else
		if (i2c_gpio_of_probe(pdev, &adap->pdata))
			return -ENXIO;

Which should make the driver simpler and gets it away from using
platform_data directly.  It also gets rid of the pdata pointer
management gymnastics.

g.


>  	kfree(adap);
>  
>  	return 0;
>  }
>  
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),
> -- 
> 1.7.3.5
> 

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

* Re: [PATCH] i2c-gpio: add devicetree support
@ 2011-02-03 18:07               ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-02-03 18:07 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Haavard Skinnemoen, Ben Dooks,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Jean Delvare, Albert Herranz

On Thu, Feb 03, 2011 at 10:26:20AM +0800, Thomas Chou wrote:
> This patch adds devicetree support to i2c-gpio driver. It converts
> dts bindings and allocates a struct i2c_gpio_platform_data, which
> will be freed on driver removal.
> 
> Signed-off-by: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
> ---
> for v2.6.39
> v2 move of nodes probing to a hook, which will be optimized out
>      when devicetree is not used.
>    use linux/gpio.h.
>    move binding doc to i2c/i2c-gpio.txt.
> v3 use speed-hz instead of udelay in dts binding.
>    condition the devicetree probe.
> 
>  Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 ++++++++++
>  drivers/i2c/busses/i2c-gpio.c                      |   83 +++++++++++++++++++-
>  2 files changed, 119 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.
> +- timeout : clock stretching timeout in milliseconds.
> +
> +Example:
> +
> +gpio0: starlet-gpio@0d8000c0 {
> +	compatible = "nintendo,starlet-gpio";
> +	reg = <0d8000c0 4>;
> +	gpio-controller;
> +	#gpio-cells = <2>;
> +};
> +
> +i2c-video {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "i2c-gpio";
> +
> +	gpios = <&gpio0 10 0	/* SDA line */
> +		 &gpio0 11 0	/* SCL line */
> +		>;
> +	sda-is-open-drain;
> +	scl-is-open-drain;
> +	scl-is-output-only;
> +	speed-hz = <250000>;
> +
> +	audio-video-encoder {
> +		compatible = "nintendo,wii-ave-rvl";
> +		reg = <70>;
> +	};
> +};
> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
> index d9aa9a6..4b31bbe 100644
> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,8 +14,8 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> -
> -#include <asm/gpio.h>
> +#include <linux/gpio.h>
> +#include <linux/of_i2c.h>
>  
>  /* Toggle SDA by changing the direction of the pin */
>  static void i2c_gpio_setsda_dir(void *data, int state)
> @@ -78,15 +78,74 @@ static int i2c_gpio_getscl(void *data)
>  	return gpio_get_value(pdata->scl_pin);
>  }
>  
> +#ifdef CONFIG_OF
> +#include <linux/of_gpio.h>
> +
> +/* Check if devicetree nodes exist and build platform data */
> +static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
> +	struct platform_device *pdev)
> +{
> +	struct i2c_gpio_platform_data *pdata = NULL;
> +	struct device_node *np = pdev->dev.of_node;
> +	const __be32 *prop;
> +	int sda_pin, scl_pin;
> +
> +	if (!np || of_gpio_count(np) < 2)
> +		goto err;
> +
> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
> +	if (sda_pin < 0 || scl_pin < 0) {
> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +		       np->full_name, sda_pin, scl_pin);
> +		goto err;
> +	}
> +
> +	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
> +	if (!pdata)
> +		goto err;
> +
> +	pdata->sda_pin = sda_pin;
> +	pdata->scl_pin = scl_pin;
> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
> +	if (prop)
> +		pdata->sda_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
> +	if (prop)
> +		pdata->scl_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-output-only", NULL);
> +	if (prop)
> +		pdata->scl_is_output_only = 1;
> +	prop = of_get_property(np, "speed-hz", NULL);
> +	if (prop)
> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
> +	prop = of_get_property(np, "timeout", NULL);
> +	if (prop) {
> +		pdata->timeout =
> +			msecs_to_jiffies(be32_to_cpup(prop));
> +	}
> +err:
> +	return pdata;
> +}
> +#else
> +static struct i2c_gpio_platform_data *i2c_gpio_of_probe(
> +	struct platform_device *pdev)
> +{
> +	return NULL;
> +}
> +#endif
> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
> -	struct i2c_gpio_platform_data *pdata;
> +	struct i2c_gpio_platform_data *pdata, *pdata_of = NULL;
>  	struct i2c_algo_bit_data *bit_data;
>  	struct i2c_adapter *adap;
>  	int ret;
>  
>  	pdata = pdev->dev.platform_data;
>  	if (!pdata)
> +		pdata = pdata_of = i2c_gpio_of_probe(pdev);
> +	if (!pdata)
>  		return -ENXIO;
>  
>  	ret = -ENOMEM;
> @@ -143,6 +202,8 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	if (pdata_of)
> +		adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -161,6 +222,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -172,6 +236,7 @@ err_request_sda:
>  err_alloc_bit_data:
>  	kfree(adap);
>  err_alloc_adap:
> +	kfree(pdata_of);
>  	return ret;
>  }
>  
> @@ -179,23 +244,33 @@ static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
> +	struct i2c_algo_bit_data *bit_data;
>  
>  	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	bit_data = adap->algo_data;
> +	pdata = bit_data->data;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
>  	kfree(adap->algo_data);
> +	if (adap->dev.of_node)
> +		kfree(pdata);

Oh, wow.  Okay, so this driver does an odd thing.  It doesn't have
its own private data structure and instead uses pdata as private data.
Rather than doing these gymnastics with the pdata pointer, may I
suggest the following refactorization:

1) Add a private data structure:
struct i2c_gpio_private_data {
	struct i2c_adapter adap;
	struct i2c_algo_bit_data bit_data;
	struct i2c_gpio_platform_data pdata;
}

2) simplify the alloc/free of data in probe/remove:

alloc:
	struct i2c_gpio_private_data *priv;
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	adap = &priv->adap;
	bit_data = &priv->bit_data;
	pdata = &priv->pdata;
	...
	platform_set_drvdata(pdev, priv);

free:
	priv = platform_get_drvdata(pdev);
	kfree(priv);

3) Copy pdata into the allocated private data

	if (pdev->dev.platform_data)
		adap->pdata = *pdev->dev.platform_data;
	else
		if (i2c_gpio_of_probe(pdev, &adap->pdata))
			return -ENXIO;

Which should make the driver simpler and gets it away from using
platform_data directly.  It also gets rid of the pdata pointer
management gymnastics.

g.


>  	kfree(adap);
>  
>  	return 0;
>  }
>  
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),
> -- 
> 1.7.3.5
> 

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

* [PATCH v4] i2c-gpio: add devicetree support
@ 2011-02-10  2:29                 ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-10  2:29 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Jean Delvare, Thomas Chou

This patch adds devicetree support to i2c-gpio driver. The allocation
of local data is integrated to a private structure, and use devm_*
helper for easy cleanup.

It is base on an earlier patch for gc-linux from
Albert Herranz <albert_herranz@yahoo.es>.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Acked-by: Haavard Skinnemoen <hskinnemoen@gmail.com>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.
v4 simplify private allocation.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |  108 ++++++++++++++++----
 2 files changed, 128 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..3b2d694 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,14 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+	int len;
+
+	if (!np || of_gpio_count(np) < 2)
+		return -ENXIO;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		return -ENXIO;
+	}
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
+
+	return 0;
+}
+#else
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -ENXIO;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.platform_data) {
+		*pdata = *(struct i2c_gpio_platform_data *)
+			pdev->dev.platform_data;
+	} else {
+		ret = i2c_gpio_of_probe(pdev, pdata);
+		if (ret)
+			return ret;
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -168,34 +234,36 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.4


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

* [PATCH v4] i2c-gpio: add devicetree support
@ 2011-02-10  2:29                 ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-10  2:29 UTC (permalink / raw)
  To: Haavard Skinnemoen, Grant Likely, Ben Dooks
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jean Delvare,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA

This patch adds devicetree support to i2c-gpio driver. The allocation
of local data is integrated to a private structure, and use devm_*
helper for easy cleanup.

It is base on an earlier patch for gc-linux from
Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>.

Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
Acked-by: Haavard Skinnemoen <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.
v4 simplify private allocation.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |  108 ++++++++++++++++----
 2 files changed, 128 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..3b2d694 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,14 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+	int len;
+
+	if (!np || of_gpio_count(np) < 2)
+		return -ENXIO;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		return -ENXIO;
+	}
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
+
+	return 0;
+}
+#else
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -ENXIO;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.platform_data) {
+		*pdata = *(struct i2c_gpio_platform_data *)
+			pdev->dev.platform_data;
+	} else {
+		ret = i2c_gpio_of_probe(pdev, pdata);
+		if (ret)
+			return ret;
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -168,34 +234,36 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.4

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

* [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-14  2:30                   ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-14  2:30 UTC (permalink / raw)
  To: Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Albert Herranz, Thomas Chou

From: Albert Herranz <albert_herranz@yahoo.es>

This patch adds devicetree support to i2c-gpio driver. The allocation
of local data is integrated to a private structure, and use devm_*
helper for easy cleanup.

It is base on an earlier patch for gc-linux from
Albert Herranz <albert_herranz@yahoo.es>.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
CC: Albert Herranz <albert_herranz@yahoo.es>
Acked-by: Haavard Skinnemoen <hskinnemoen@gmail.com>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.
v4 simplify private allocation.
v5 condition module device table export for of.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
 2 files changed, 133 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..6cc5f15 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,14 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+	int len;
+
+	if (!np || of_gpio_count(np) < 2)
+		return -ENXIO;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		return -ENXIO;
+	}
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
+
+	return 0;
+}
+#else
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -ENXIO;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.platform_data) {
+		*pdata = *(struct i2c_gpio_platform_data *)
+			pdev->dev.platform_data;
+	} else {
+		ret = i2c_gpio_of_probe(pdev, pdata);
+		if (ret)
+			return ret;
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -168,34 +234,41 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, i2c_gpio_match);
+#else /* CONFIG_OF */
+#define i2c_gpio_match NULL
+#endif /* CONFIG_OF */
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.4


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

* [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-14  2:30                   ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-14  2:30 UTC (permalink / raw)
  To: Grant Likely, Ben Dooks
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Albert Herranz, Thomas Chou

From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>

This patch adds devicetree support to i2c-gpio driver. The allocation
of local data is integrated to a private structure, and use devm_*
helper for easy cleanup.

It is base on an earlier patch for gc-linux from
Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>.

Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
CC: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
Acked-by: Haavard Skinnemoen <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.
v4 simplify private allocation.
v5 condition module device table export for of.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
 2 files changed, 133 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..6cc5f15 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,14 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+	int len;
+
+	if (!np || of_gpio_count(np) < 2)
+		return -ENXIO;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		return -ENXIO;
+	}
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
+
+	return 0;
+}
+#else
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -ENXIO;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.platform_data) {
+		*pdata = *(struct i2c_gpio_platform_data *)
+			pdev->dev.platform_data;
+	} else {
+		ret = i2c_gpio_of_probe(pdev, pdata);
+		if (ret)
+			return ret;
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -168,34 +234,41 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, i2c_gpio_match);
+#else /* CONFIG_OF */
+#define i2c_gpio_match NULL
+#endif /* CONFIG_OF */
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.4

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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-16  5:49                     ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-02-16  5:49 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Ben Dooks, linux-kernel, nios2-dev, devicetree-discuss,
	linux-i2c, Albert Herranz

On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
> From: Albert Herranz <albert_herranz@yahoo.es>
> 
> This patch adds devicetree support to i2c-gpio driver. The allocation
> of local data is integrated to a private structure, and use devm_*
> helper for easy cleanup.
> 
> It is base on an earlier patch for gc-linux from
> Albert Herranz <albert_herranz@yahoo.es>.
> 
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> CC: Albert Herranz <albert_herranz@yahoo.es>
> Acked-by: Haavard Skinnemoen <hskinnemoen@gmail.com>

One minor nitpick below, but I'd be fine with cleaning that up via a
followup patch.  This one looks correct to me.

Acked-by: Grant Likely <grant.likely@secretlab.ca>

Ben, this one depends on a patch in my devicetree/next tree.  How do
you want to handle it?

g.

> ---
> for v2.6.39
> v2 move of nodes probing to a hook, which will be optimized out
>      when devicetree is not used.
>    use linux/gpio.h.
>    move binding doc to i2c/i2c-gpio.txt.
> v3 use speed-hz instead of udelay in dts binding.
>    condition the devicetree probe.
> v4 simplify private allocation.
> v5 condition module device table export for of.
> 
>  Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
>  drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
>  2 files changed, 133 insertions(+), 20 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.
> +- timeout : clock stretching timeout in milliseconds.
> +
> +Example:
> +
> +gpio0: starlet-gpio@0d8000c0 {
> +	compatible = "nintendo,starlet-gpio";
> +	reg = <0d8000c0 4>;
> +	gpio-controller;
> +	#gpio-cells = <2>;
> +};
> +
> +i2c-video {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "i2c-gpio";
> +
> +	gpios = <&gpio0 10 0	/* SDA line */
> +		 &gpio0 11 0	/* SCL line */
> +		>;
> +	sda-is-open-drain;
> +	scl-is-open-drain;
> +	scl-is-output-only;
> +	speed-hz = <250000>;
> +
> +	audio-video-encoder {
> +		compatible = "nintendo,wii-ave-rvl";
> +		reg = <70>;
> +	};
> +};
> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
> index d9aa9a6..6cc5f15 100644
> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,8 +14,14 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/of_i2c.h>
>  
> -#include <asm/gpio.h>
> +struct i2c_gpio_private_data {
> +	struct i2c_adapter adap;
> +	struct i2c_algo_bit_data bit_data;
> +	struct i2c_gpio_platform_data pdata;
> +};
>  
>  /* Toggle SDA by changing the direction of the pin */
>  static void i2c_gpio_setsda_dir(void *data, int state)
> @@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
>  	return gpio_get_value(pdata->scl_pin);
>  }
>  
> +#ifdef CONFIG_OF
> +#include <linux/of_gpio.h>

Instead of putting the include here, please add #ifdef CONFIG_OF
protection around the contents of linux/of_gpio.h itself.  I fully
support that change so that includes can remain at the top where they
belong.

> +
> +/* Check if devicetree nodes exist and build platform data */
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	const __be32 *prop;
> +	int sda_pin, scl_pin;
> +	int len;
> +
> +	if (!np || of_gpio_count(np) < 2)
> +		return -ENXIO;
> +
> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
> +	if (sda_pin < 0 || scl_pin < 0) {
> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +		       np->full_name, sda_pin, scl_pin);
> +		return -ENXIO;
> +	}
> +
> +	pdata->sda_pin = sda_pin;
> +	pdata->scl_pin = scl_pin;
> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
> +	if (prop)
> +		pdata->sda_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
> +	if (prop)
> +		pdata->scl_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-output-only", NULL);
> +	if (prop)
> +		pdata->scl_is_output_only = 1;
> +	prop = of_get_property(np, "speed-hz", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
> +	prop = of_get_property(np, "timeout", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
> +
> +	return 0;
> +}
> +#else
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	return -ENXIO;
> +}
> +#endif
> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_algo_bit_data *bit_data;
>  	struct i2c_adapter *adap;
>  	int ret;
>  
> -	pdata = pdev->dev.platform_data;
> -	if (!pdata)
> -		return -ENXIO;
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +	adap = &priv->adap;
> +	bit_data = &priv->bit_data;
> +	pdata = &priv->pdata;
>  
> -	ret = -ENOMEM;
> -	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
> -	if (!adap)
> -		goto err_alloc_adap;
> -	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
> -	if (!bit_data)
> -		goto err_alloc_bit_data;
> +	if (pdev->dev.platform_data) {
> +		*pdata = *(struct i2c_gpio_platform_data *)
> +			pdev->dev.platform_data;
> +	} else {
> +		ret = i2c_gpio_of_probe(pdev, pdata);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	ret = gpio_request(pdata->sda_pin, "sda");
>  	if (ret)
> @@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_add_bus;
>  
> -	platform_set_drvdata(pdev, adap);
> +	platform_set_drvdata(pdev, priv);
>  
>  	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
>  		 pdata->sda_pin, pdata->scl_pin,
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -168,34 +234,41 @@ err_add_bus:
>  err_request_scl:
>  	gpio_free(pdata->sda_pin);
>  err_request_sda:
> -	kfree(bit_data);
> -err_alloc_bit_data:
> -	kfree(adap);
> -err_alloc_adap:
>  	return ret;
>  }
>  
>  static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
>  
> -	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	priv = platform_get_drvdata(pdev);
> +	adap = &priv->adap;
> +	pdata = &priv->pdata;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
> -	kfree(adap->algo_data);
> -	kfree(adap);
>  
>  	return 0;
>  }
>  
> +#ifdef CONFIG_OF
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, i2c_gpio_match);
> +#else /* CONFIG_OF */
> +#define i2c_gpio_match NULL
> +#endif /* CONFIG_OF */
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),
> -- 
> 1.7.4
> 

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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-16  5:49                     ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-02-16  5:49 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Albert Herranz

On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
> From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> 
> This patch adds devicetree support to i2c-gpio driver. The allocation
> of local data is integrated to a private structure, and use devm_*
> helper for easy cleanup.
> 
> It is base on an earlier patch for gc-linux from
> Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>.
> 
> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
> CC: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> Acked-by: Haavard Skinnemoen <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

One minor nitpick below, but I'd be fine with cleaning that up via a
followup patch.  This one looks correct to me.

Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>

Ben, this one depends on a patch in my devicetree/next tree.  How do
you want to handle it?

g.

> ---
> for v2.6.39
> v2 move of nodes probing to a hook, which will be optimized out
>      when devicetree is not used.
>    use linux/gpio.h.
>    move binding doc to i2c/i2c-gpio.txt.
> v3 use speed-hz instead of udelay in dts binding.
>    condition the devicetree probe.
> v4 simplify private allocation.
> v5 condition module device table export for of.
> 
>  Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
>  drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
>  2 files changed, 133 insertions(+), 20 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.
> +- timeout : clock stretching timeout in milliseconds.
> +
> +Example:
> +
> +gpio0: starlet-gpio@0d8000c0 {
> +	compatible = "nintendo,starlet-gpio";
> +	reg = <0d8000c0 4>;
> +	gpio-controller;
> +	#gpio-cells = <2>;
> +};
> +
> +i2c-video {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "i2c-gpio";
> +
> +	gpios = <&gpio0 10 0	/* SDA line */
> +		 &gpio0 11 0	/* SCL line */
> +		>;
> +	sda-is-open-drain;
> +	scl-is-open-drain;
> +	scl-is-output-only;
> +	speed-hz = <250000>;
> +
> +	audio-video-encoder {
> +		compatible = "nintendo,wii-ave-rvl";
> +		reg = <70>;
> +	};
> +};
> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
> index d9aa9a6..6cc5f15 100644
> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,8 +14,14 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/of_i2c.h>
>  
> -#include <asm/gpio.h>
> +struct i2c_gpio_private_data {
> +	struct i2c_adapter adap;
> +	struct i2c_algo_bit_data bit_data;
> +	struct i2c_gpio_platform_data pdata;
> +};
>  
>  /* Toggle SDA by changing the direction of the pin */
>  static void i2c_gpio_setsda_dir(void *data, int state)
> @@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
>  	return gpio_get_value(pdata->scl_pin);
>  }
>  
> +#ifdef CONFIG_OF
> +#include <linux/of_gpio.h>

Instead of putting the include here, please add #ifdef CONFIG_OF
protection around the contents of linux/of_gpio.h itself.  I fully
support that change so that includes can remain at the top where they
belong.

> +
> +/* Check if devicetree nodes exist and build platform data */
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	const __be32 *prop;
> +	int sda_pin, scl_pin;
> +	int len;
> +
> +	if (!np || of_gpio_count(np) < 2)
> +		return -ENXIO;
> +
> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
> +	if (sda_pin < 0 || scl_pin < 0) {
> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +		       np->full_name, sda_pin, scl_pin);
> +		return -ENXIO;
> +	}
> +
> +	pdata->sda_pin = sda_pin;
> +	pdata->scl_pin = scl_pin;
> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
> +	if (prop)
> +		pdata->sda_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
> +	if (prop)
> +		pdata->scl_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-output-only", NULL);
> +	if (prop)
> +		pdata->scl_is_output_only = 1;
> +	prop = of_get_property(np, "speed-hz", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
> +	prop = of_get_property(np, "timeout", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
> +
> +	return 0;
> +}
> +#else
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	return -ENXIO;
> +}
> +#endif
> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_algo_bit_data *bit_data;
>  	struct i2c_adapter *adap;
>  	int ret;
>  
> -	pdata = pdev->dev.platform_data;
> -	if (!pdata)
> -		return -ENXIO;
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +	adap = &priv->adap;
> +	bit_data = &priv->bit_data;
> +	pdata = &priv->pdata;
>  
> -	ret = -ENOMEM;
> -	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
> -	if (!adap)
> -		goto err_alloc_adap;
> -	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
> -	if (!bit_data)
> -		goto err_alloc_bit_data;
> +	if (pdev->dev.platform_data) {
> +		*pdata = *(struct i2c_gpio_platform_data *)
> +			pdev->dev.platform_data;
> +	} else {
> +		ret = i2c_gpio_of_probe(pdev, pdata);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	ret = gpio_request(pdata->sda_pin, "sda");
>  	if (ret)
> @@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_add_bus;
>  
> -	platform_set_drvdata(pdev, adap);
> +	platform_set_drvdata(pdev, priv);
>  
>  	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
>  		 pdata->sda_pin, pdata->scl_pin,
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -168,34 +234,41 @@ err_add_bus:
>  err_request_scl:
>  	gpio_free(pdata->sda_pin);
>  err_request_sda:
> -	kfree(bit_data);
> -err_alloc_bit_data:
> -	kfree(adap);
> -err_alloc_adap:
>  	return ret;
>  }
>  
>  static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
>  
> -	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	priv = platform_get_drvdata(pdev);
> +	adap = &priv->adap;
> +	pdata = &priv->pdata;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
> -	kfree(adap->algo_data);
> -	kfree(adap);
>  
>  	return 0;
>  }
>  
> +#ifdef CONFIG_OF
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, i2c_gpio_match);
> +#else /* CONFIG_OF */
> +#define i2c_gpio_match NULL
> +#endif /* CONFIG_OF */
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),
> -- 
> 1.7.4
> 

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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-16  6:13                       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-16  6:13 UTC (permalink / raw)
  To: Grant Likely
  Cc: Ben Dooks, linux-kernel, nios2-dev, devicetree-discuss,
	linux-i2c, Albert Herranz

Hi Grant,

On 02/16/2011 01:49 PM, Grant Likely wrote:
> On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
>> From: Albert Herranz<albert_herranz@yahoo.es>
>>
>> This patch adds devicetree support to i2c-gpio driver. The allocation
>> of local data is integrated to a private structure, and use devm_*
>> helper for easy cleanup.
>>
>> It is base on an earlier patch for gc-linux from
>> Albert Herranz<albert_herranz@yahoo.es>.
>>
>> Signed-off-by: Thomas Chou<thomas@wytron.com.tw>
>> CC: Albert Herranz<albert_herranz@yahoo.es>
>> Acked-by: Haavard Skinnemoen<hskinnemoen@gmail.com>
>
> One minor nitpick below, but I'd be fine with cleaning that up via a
> followup patch.  This one looks correct to me.
>
> Acked-by: Grant Likely<grant.likely@secretlab.ca>
>
> Ben, this one depends on a patch in my devicetree/next tree.  How do
> you want to handle it?
>
> g.
>

Thanks a lot.

>> +#ifdef CONFIG_OF
>> +#include<linux/of_gpio.h>
>
> Instead of putting the include here, please add #ifdef CONFIG_OF
> protection around the contents of linux/of_gpio.h itself.  I fully
> support that change so that includes can remain at the top where they
> belong.

Then, my earlier patch on Jan 31, might be another solution. This way 
of_gpio.h can be included at the top, and those of_gpio users will be 
optimized out when of or of_gpio is not configured.

[PATCH 2/3] of: of_gpiochip_add is needed only for gpiolib

Cheers,
Thomas


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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-16  6:13                       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-16  6:13 UTC (permalink / raw)
  To: Grant Likely
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Albert Herranz

Hi Grant,

On 02/16/2011 01:49 PM, Grant Likely wrote:
> On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
>> From: Albert Herranz<albert_herranz-mRCrAkd8dF0@public.gmane.org>
>>
>> This patch adds devicetree support to i2c-gpio driver. The allocation
>> of local data is integrated to a private structure, and use devm_*
>> helper for easy cleanup.
>>
>> It is base on an earlier patch for gc-linux from
>> Albert Herranz<albert_herranz-mRCrAkd8dF0@public.gmane.org>.
>>
>> Signed-off-by: Thomas Chou<thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
>> CC: Albert Herranz<albert_herranz-mRCrAkd8dF0@public.gmane.org>
>> Acked-by: Haavard Skinnemoen<hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> One minor nitpick below, but I'd be fine with cleaning that up via a
> followup patch.  This one looks correct to me.
>
> Acked-by: Grant Likely<grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
>
> Ben, this one depends on a patch in my devicetree/next tree.  How do
> you want to handle it?
>
> g.
>

Thanks a lot.

>> +#ifdef CONFIG_OF
>> +#include<linux/of_gpio.h>
>
> Instead of putting the include here, please add #ifdef CONFIG_OF
> protection around the contents of linux/of_gpio.h itself.  I fully
> support that change so that includes can remain at the top where they
> belong.

Then, my earlier patch on Jan 31, might be another solution. This way 
of_gpio.h can be included at the top, and those of_gpio users will be 
optimized out when of or of_gpio is not configured.

[PATCH 2/3] of: of_gpiochip_add is needed only for gpiolib

Cheers,
Thomas

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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-23  1:12                     ` Ben Dooks
  0 siblings, 0 replies; 51+ messages in thread
From: Ben Dooks @ 2011-02-23  1:12 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Grant Likely, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Albert Herranz

On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
> From: Albert Herranz <albert_herranz@yahoo.es>
> 
> This patch adds devicetree support to i2c-gpio driver. The allocation
> of local data is integrated to a private structure, and use devm_*
> helper for easy cleanup.
> 
> It is base on an earlier patch for gc-linux from
> Albert Herranz <albert_herranz@yahoo.es>.
> 
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> CC: Albert Herranz <albert_herranz@yahoo.es>
> Acked-by: Haavard Skinnemoen <hskinnemoen@gmail.com>
> ---
> for v2.6.39
> v2 move of nodes probing to a hook, which will be optimized out
>      when devicetree is not used.
>    use linux/gpio.h.
>    move binding doc to i2c/i2c-gpio.txt.
> v3 use speed-hz instead of udelay in dts binding.
>    condition the devicetree probe.
> v4 simplify private allocation.
> v5 condition module device table export for of.
> 
>  Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
>  drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
>  2 files changed, 133 insertions(+), 20 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.
> +- timeout : clock stretching timeout in milliseconds.
> +
> +Example:
> +
> +gpio0: starlet-gpio@0d8000c0 {
> +	compatible = "nintendo,starlet-gpio";
> +	reg = <0d8000c0 4>;
> +	gpio-controller;
> +	#gpio-cells = <2>;
> +};
> +
> +i2c-video {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "i2c-gpio";
> +
> +	gpios = <&gpio0 10 0	/* SDA line */
> +		 &gpio0 11 0	/* SCL line */
> +		>;
> +	sda-is-open-drain;
> +	scl-is-open-drain;
> +	scl-is-output-only;
> +	speed-hz = <250000>;
> +
> +	audio-video-encoder {
> +		compatible = "nintendo,wii-ave-rvl";
> +		reg = <70>;
> +	};
> +};
> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
> index d9aa9a6..6cc5f15 100644
> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,8 +14,14 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/of_i2c.h>
>  
> -#include <asm/gpio.h>
> +struct i2c_gpio_private_data {
> +	struct i2c_adapter adap;
> +	struct i2c_algo_bit_data bit_data;
> +	struct i2c_gpio_platform_data pdata;
> +};
>  
>  /* Toggle SDA by changing the direction of the pin */
>  static void i2c_gpio_setsda_dir(void *data, int state)
> @@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
>  	return gpio_get_value(pdata->scl_pin);
>  }
>  
> +#ifdef CONFIG_OF
> +#include <linux/of_gpio.h>
> +
> +/* Check if devicetree nodes exist and build platform data */
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	const __be32 *prop;
> +	int sda_pin, scl_pin;
> +	int len;
> +
> +	if (!np || of_gpio_count(np) < 2)
> +		return -ENXIO;

Would prefer to see different return code, most bus probe functions
tend to drop these without signalling to the user as they assume the
device was either never there or totally faulty.

> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
> +	if (sda_pin < 0 || scl_pin < 0) {
> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +		       np->full_name, sda_pin, scl_pin);
> +		return -ENXIO;
> +	}

see same as above.

> +	pdata->sda_pin = sda_pin;
> +	pdata->scl_pin = scl_pin;
> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
> +	if (prop)
> +		pdata->sda_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
> +	if (prop)
> +		pdata->scl_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-output-only", NULL);
> +	if (prop)
> +		pdata->scl_is_output_only = 1;
> +	prop = of_get_property(np, "speed-hz", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
> +	prop = of_get_property(np, "timeout", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
> +
> +	return 0;
> +}
> +#else
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	return -ENXIO;
> +}

might be valid here, however can we make this NULL if no support?

> +#endif
> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_algo_bit_data *bit_data;
>  	struct i2c_adapter *adap;
>  	int ret;
>  
> -	pdata = pdev->dev.platform_data;
> -	if (!pdata)
> -		return -ENXIO;
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +	adap = &priv->adap;
> +	bit_data = &priv->bit_data;
> +	pdata = &priv->pdata;
>  
> -	ret = -ENOMEM;
> -	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
> -	if (!adap)
> -		goto err_alloc_adap;
> -	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
> -	if (!bit_data)
> -		goto err_alloc_bit_data;
> +	if (pdev->dev.platform_data) {
> +		*pdata = *(struct i2c_gpio_platform_data *)
> +			pdev->dev.platform_data;
> +	} else {
> +		ret = i2c_gpio_of_probe(pdev, pdata);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	ret = gpio_request(pdata->sda_pin, "sda");
>  	if (ret)
> @@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_add_bus;
>  
> -	platform_set_drvdata(pdev, adap);
> +	platform_set_drvdata(pdev, priv);
>  
>  	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
>  		 pdata->sda_pin, pdata->scl_pin,
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -168,34 +234,41 @@ err_add_bus:
>  err_request_scl:
>  	gpio_free(pdata->sda_pin);
>  err_request_sda:
> -	kfree(bit_data);
> -err_alloc_bit_data:
> -	kfree(adap);
> -err_alloc_adap:
>  	return ret;
>  }
>  
>  static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
>  
> -	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	priv = platform_get_drvdata(pdev);
> +	adap = &priv->adap;
> +	pdata = &priv->pdata;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
> -	kfree(adap->algo_data);
> -	kfree(adap);
>  
>  	return 0;
>  }
>  
> +#ifdef CONFIG_OF
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, i2c_gpio_match);
> +#else /* CONFIG_OF */
> +#define i2c_gpio_match NULL
> +#endif /* CONFIG_OF */
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),
> -- 
> 1.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Ben Dooks, ben@fluff.org, http://www.fluff.org/ben/

Large Hadron Colada: A large Pina Colada that makes the universe disappear.


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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-23  1:12                     ` Ben Dooks
  0 siblings, 0 replies; 51+ messages in thread
From: Ben Dooks @ 2011-02-23  1:12 UTC (permalink / raw)
  To: Thomas Chou
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Albert Herranz

On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
> From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> 
> This patch adds devicetree support to i2c-gpio driver. The allocation
> of local data is integrated to a private structure, and use devm_*
> helper for easy cleanup.
> 
> It is base on an earlier patch for gc-linux from
> Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>.
> 
> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
> CC: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> Acked-by: Haavard Skinnemoen <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> for v2.6.39
> v2 move of nodes probing to a hook, which will be optimized out
>      when devicetree is not used.
>    use linux/gpio.h.
>    move binding doc to i2c/i2c-gpio.txt.
> v3 use speed-hz instead of udelay in dts binding.
>    condition the devicetree probe.
> v4 simplify private allocation.
> v5 condition module device table export for of.
> 
>  Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
>  drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
>  2 files changed, 133 insertions(+), 20 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.
> +- timeout : clock stretching timeout in milliseconds.
> +
> +Example:
> +
> +gpio0: starlet-gpio@0d8000c0 {
> +	compatible = "nintendo,starlet-gpio";
> +	reg = <0d8000c0 4>;
> +	gpio-controller;
> +	#gpio-cells = <2>;
> +};
> +
> +i2c-video {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	compatible = "i2c-gpio";
> +
> +	gpios = <&gpio0 10 0	/* SDA line */
> +		 &gpio0 11 0	/* SCL line */
> +		>;
> +	sda-is-open-drain;
> +	scl-is-open-drain;
> +	scl-is-output-only;
> +	speed-hz = <250000>;
> +
> +	audio-video-encoder {
> +		compatible = "nintendo,wii-ave-rvl";
> +		reg = <70>;
> +	};
> +};
> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
> index d9aa9a6..6cc5f15 100644
> --- a/drivers/i2c/busses/i2c-gpio.c
> +++ b/drivers/i2c/busses/i2c-gpio.c
> @@ -14,8 +14,14 @@
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/of_i2c.h>
>  
> -#include <asm/gpio.h>
> +struct i2c_gpio_private_data {
> +	struct i2c_adapter adap;
> +	struct i2c_algo_bit_data bit_data;
> +	struct i2c_gpio_platform_data pdata;
> +};
>  
>  /* Toggle SDA by changing the direction of the pin */
>  static void i2c_gpio_setsda_dir(void *data, int state)
> @@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
>  	return gpio_get_value(pdata->scl_pin);
>  }
>  
> +#ifdef CONFIG_OF
> +#include <linux/of_gpio.h>
> +
> +/* Check if devicetree nodes exist and build platform data */
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	const __be32 *prop;
> +	int sda_pin, scl_pin;
> +	int len;
> +
> +	if (!np || of_gpio_count(np) < 2)
> +		return -ENXIO;

Would prefer to see different return code, most bus probe functions
tend to drop these without signalling to the user as they assume the
device was either never there or totally faulty.

> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
> +	if (sda_pin < 0 || scl_pin < 0) {
> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
> +		       np->full_name, sda_pin, scl_pin);
> +		return -ENXIO;
> +	}

see same as above.

> +	pdata->sda_pin = sda_pin;
> +	pdata->scl_pin = scl_pin;
> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
> +	if (prop)
> +		pdata->sda_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
> +	if (prop)
> +		pdata->scl_is_open_drain = 1;
> +	prop = of_get_property(np, "scl-is-output-only", NULL);
> +	if (prop)
> +		pdata->scl_is_output_only = 1;
> +	prop = of_get_property(np, "speed-hz", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
> +	prop = of_get_property(np, "timeout", &len);
> +	if (prop && len >= sizeof(__be32))
> +		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
> +
> +	return 0;
> +}
> +#else
> +static int i2c_gpio_of_probe(struct platform_device *pdev,
> +			     struct i2c_gpio_platform_data *pdata)
> +{
> +	return -ENXIO;
> +}

might be valid here, however can we make this NULL if no support?

> +#endif
> +
>  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_algo_bit_data *bit_data;
>  	struct i2c_adapter *adap;
>  	int ret;
>  
> -	pdata = pdev->dev.platform_data;
> -	if (!pdata)
> -		return -ENXIO;
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +	adap = &priv->adap;
> +	bit_data = &priv->bit_data;
> +	pdata = &priv->pdata;
>  
> -	ret = -ENOMEM;
> -	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
> -	if (!adap)
> -		goto err_alloc_adap;
> -	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
> -	if (!bit_data)
> -		goto err_alloc_bit_data;
> +	if (pdev->dev.platform_data) {
> +		*pdata = *(struct i2c_gpio_platform_data *)
> +			pdev->dev.platform_data;
> +	} else {
> +		ret = i2c_gpio_of_probe(pdev, pdata);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	ret = gpio_request(pdata->sda_pin, "sda");
>  	if (ret)
> @@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	adap->algo_data = bit_data;
>  	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
>  	adap->dev.parent = &pdev->dev;
> +	adap->dev.of_node = pdev->dev.of_node;
>  
>  	/*
>  	 * If "dev->id" is negative we consider it as zero.
> @@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_add_bus;
>  
> -	platform_set_drvdata(pdev, adap);
> +	platform_set_drvdata(pdev, priv);
>  
>  	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
>  		 pdata->sda_pin, pdata->scl_pin,
>  		 pdata->scl_is_output_only
>  		 ? ", no clock stretching" : "");
>  
> +	/* Now register all the child nodes */
> +	of_i2c_register_devices(adap);
> +
>  	return 0;
>  
>  err_add_bus:
> @@ -168,34 +234,41 @@ err_add_bus:
>  err_request_scl:
>  	gpio_free(pdata->sda_pin);
>  err_request_sda:
> -	kfree(bit_data);
> -err_alloc_bit_data:
> -	kfree(adap);
> -err_alloc_adap:
>  	return ret;
>  }
>  
>  static int __devexit i2c_gpio_remove(struct platform_device *pdev)
>  {
> +	struct i2c_gpio_private_data *priv;
>  	struct i2c_gpio_platform_data *pdata;
>  	struct i2c_adapter *adap;
>  
> -	adap = platform_get_drvdata(pdev);
> -	pdata = pdev->dev.platform_data;
> +	priv = platform_get_drvdata(pdev);
> +	adap = &priv->adap;
> +	pdata = &priv->pdata;
>  
>  	i2c_del_adapter(adap);
>  	gpio_free(pdata->scl_pin);
>  	gpio_free(pdata->sda_pin);
> -	kfree(adap->algo_data);
> -	kfree(adap);
>  
>  	return 0;
>  }
>  
> +#ifdef CONFIG_OF
> +static const struct of_device_id i2c_gpio_match[] = {
> +	{ .compatible = "i2c-gpio", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, i2c_gpio_match);
> +#else /* CONFIG_OF */
> +#define i2c_gpio_match NULL
> +#endif /* CONFIG_OF */
> +
>  static struct platform_driver i2c_gpio_driver = {
>  	.driver		= {
>  		.name	= "i2c-gpio",
>  		.owner	= THIS_MODULE,
> +		.of_match_table = i2c_gpio_match,
>  	},
>  	.probe		= i2c_gpio_probe,
>  	.remove		= __devexit_p(i2c_gpio_remove),
> -- 
> 1.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Ben Dooks, ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/ben/

Large Hadron Colada: A large Pina Colada that makes the universe disappear.

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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-23 13:18                       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-23 13:18 UTC (permalink / raw)
  To: Ben Dooks
  Cc: Grant Likely, Ben Dooks, linux-kernel, nios2-dev,
	devicetree-discuss, linux-i2c, Albert Herranz

Hi Ben,

On 02/23/2011 09:12 AM, Ben Dooks wrote:
> On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
>> From: Albert Herranz<albert_herranz@yahoo.es>
>>
>> This patch adds devicetree support to i2c-gpio driver. The allocation
>> of local data is integrated to a private structure, and use devm_*
>> helper for easy cleanup.
>>
>> It is base on an earlier patch for gc-linux from
>> Albert Herranz<albert_herranz@yahoo.es>.
>>
>> Signed-off-by: Thomas Chou<thomas@wytron.com.tw>
>> CC: Albert Herranz<albert_herranz@yahoo.es>
>> Acked-by: Haavard Skinnemoen<hskinnemoen@gmail.com>
>> ---
>> for v2.6.39
>> v2 move of nodes probing to a hook, which will be optimized out
>>       when devicetree is not used.
>>     use linux/gpio.h.
>>     move binding doc to i2c/i2c-gpio.txt.
>> v3 use speed-hz instead of udelay in dts binding.
>>     condition the devicetree probe.
>> v4 simplify private allocation.
>> v5 condition module device table export for of.
>>

>> +/* Check if devicetree nodes exist and build platform data */
>> +static int i2c_gpio_of_probe(struct platform_device *pdev,
>> +			     struct i2c_gpio_platform_data *pdata)
>> +{
>> +	struct device_node *np = pdev->dev.of_node;
>> +	const __be32 *prop;
>> +	int sda_pin, scl_pin;
>> +	int len;
>> +
>> +	if (!np || of_gpio_count(np)<  2)
>> +		return -ENXIO;
>
> Would prefer to see different return code, most bus probe functions
> tend to drop these without signalling to the user as they assume the
> device was either never there or totally faulty.
>
>> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
>> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
>> +	if (sda_pin<  0 || scl_pin<  0) {
>> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
>> +		       np->full_name, sda_pin, scl_pin);
>> +		return -ENXIO;
>> +	}
>
> see same as above.
>
>> +	pdata->sda_pin = sda_pin;
>> +	pdata->scl_pin = scl_pin;
>> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
>> +	if (prop)
>> +		pdata->sda_is_open_drain = 1;
>> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
>> +	if (prop)
>> +		pdata->scl_is_open_drain = 1;
>> +	prop = of_get_property(np, "scl-is-output-only", NULL);
>> +	if (prop)
>> +		pdata->scl_is_output_only = 1;
>> +	prop = of_get_property(np, "speed-hz",&len);
>> +	if (prop&&  len>= sizeof(__be32))
>> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
>> +	prop = of_get_property(np, "timeout",&len);
>> +	if (prop&&  len>= sizeof(__be32))
>> +		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
>> +
>> +	return 0;
>> +}
>> +#else
>> +static int i2c_gpio_of_probe(struct platform_device *pdev,
>> +			     struct i2c_gpio_platform_data *pdata)
>> +{
>> +	return -ENXIO;
>> +}
>
> might be valid here, however can we make this NULL if no support?
>

Thanks. How about return NULL if no support, and return pdata if support?

- Thomas

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

* Re: [PATCH v5] i2c-gpio: add devicetree support
@ 2011-02-23 13:18                       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-23 13:18 UTC (permalink / raw)
  To: Ben Dooks
  Cc: Grant Likely, Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Albert Herranz

Hi Ben,

On 02/23/2011 09:12 AM, Ben Dooks wrote:
> On Mon, Feb 14, 2011 at 10:30:10AM +0800, Thomas Chou wrote:
>> From: Albert Herranz<albert_herranz-mRCrAkd8dF0@public.gmane.org>
>>
>> This patch adds devicetree support to i2c-gpio driver. The allocation
>> of local data is integrated to a private structure, and use devm_*
>> helper for easy cleanup.
>>
>> It is base on an earlier patch for gc-linux from
>> Albert Herranz<albert_herranz-mRCrAkd8dF0@public.gmane.org>.
>>
>> Signed-off-by: Thomas Chou<thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
>> CC: Albert Herranz<albert_herranz-mRCrAkd8dF0@public.gmane.org>
>> Acked-by: Haavard Skinnemoen<hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>> for v2.6.39
>> v2 move of nodes probing to a hook, which will be optimized out
>>       when devicetree is not used.
>>     use linux/gpio.h.
>>     move binding doc to i2c/i2c-gpio.txt.
>> v3 use speed-hz instead of udelay in dts binding.
>>     condition the devicetree probe.
>> v4 simplify private allocation.
>> v5 condition module device table export for of.
>>

>> +/* Check if devicetree nodes exist and build platform data */
>> +static int i2c_gpio_of_probe(struct platform_device *pdev,
>> +			     struct i2c_gpio_platform_data *pdata)
>> +{
>> +	struct device_node *np = pdev->dev.of_node;
>> +	const __be32 *prop;
>> +	int sda_pin, scl_pin;
>> +	int len;
>> +
>> +	if (!np || of_gpio_count(np)<  2)
>> +		return -ENXIO;
>
> Would prefer to see different return code, most bus probe functions
> tend to drop these without signalling to the user as they assume the
> device was either never there or totally faulty.
>
>> +	sda_pin = of_get_gpio_flags(np, 0, NULL);
>> +	scl_pin = of_get_gpio_flags(np, 1, NULL);
>> +	if (sda_pin<  0 || scl_pin<  0) {
>> +		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
>> +		       np->full_name, sda_pin, scl_pin);
>> +		return -ENXIO;
>> +	}
>
> see same as above.
>
>> +	pdata->sda_pin = sda_pin;
>> +	pdata->scl_pin = scl_pin;
>> +	prop = of_get_property(np, "sda-is-open-drain", NULL);
>> +	if (prop)
>> +		pdata->sda_is_open_drain = 1;
>> +	prop = of_get_property(np, "scl-is-open-drain", NULL);
>> +	if (prop)
>> +		pdata->scl_is_open_drain = 1;
>> +	prop = of_get_property(np, "scl-is-output-only", NULL);
>> +	if (prop)
>> +		pdata->scl_is_output_only = 1;
>> +	prop = of_get_property(np, "speed-hz",&len);
>> +	if (prop&&  len>= sizeof(__be32))
>> +		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
>> +	prop = of_get_property(np, "timeout",&len);
>> +	if (prop&&  len>= sizeof(__be32))
>> +		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
>> +
>> +	return 0;
>> +}
>> +#else
>> +static int i2c_gpio_of_probe(struct platform_device *pdev,
>> +			     struct i2c_gpio_platform_data *pdata)
>> +{
>> +	return -ENXIO;
>> +}
>
> might be valid here, however can we make this NULL if no support?
>

Thanks. How about return NULL if no support, and return pdata if support?

- Thomas

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

* [PATCH v6] i2c-gpio: add devicetree support
@ 2011-02-24  4:00                       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-24  4:00 UTC (permalink / raw)
  To: Grant Likely, Ben Dooks
  Cc: linux-kernel, nios2-dev, devicetree-discuss, linux-i2c,
	Albert Herranz, Thomas Chou

From: Albert Herranz <albert_herranz@yahoo.es>

This patch adds devicetree support to i2c-gpio driver. The allocation
of local data is integrated to a private structure, and use devm_*
helper for easy cleanup.

It is base on an earlier patch for gc-linux from
Albert Herranz <albert_herranz@yahoo.es>.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
CC: Albert Herranz <albert_herranz@yahoo.es>
Acked-by: Haavard Skinnemoen <hskinnemoen@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.
v4 simplify private allocation.
v5 condition module device table export for of.
v6 change return code if probe fail.

Hi Ben, this driver must get gpio pins from platform data or devicetree,
  so it should fail if there is no platform data and devicetree is not
  configured.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
 2 files changed, 133 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..feac3e5 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,14 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+	int len;
+
+	if (!np || of_gpio_count(np) < 2)
+		return -ENODEV;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		return -ENODEV;
+	}
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
+
+	return 0;
+}
+#else
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -ENODEV;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.platform_data) {
+		*pdata = *(struct i2c_gpio_platform_data *)
+			pdev->dev.platform_data;
+	} else {
+		ret = i2c_gpio_of_probe(pdev, pdata);
+		if (ret)
+			return ret;
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -168,34 +234,41 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, i2c_gpio_match);
+#else /* CONFIG_OF */
+#define i2c_gpio_match NULL
+#endif /* CONFIG_OF */
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.4


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

* [PATCH v6] i2c-gpio: add devicetree support
@ 2011-02-24  4:00                       ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-24  4:00 UTC (permalink / raw)
  To: Grant Likely, Ben Dooks
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Albert Herranz, Thomas Chou

From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>

This patch adds devicetree support to i2c-gpio driver. The allocation
of local data is integrated to a private structure, and use devm_*
helper for easy cleanup.

It is base on an earlier patch for gc-linux from
Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>.

Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
CC: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
Acked-by: Haavard Skinnemoen <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
---
for v2.6.39
v2 move of nodes probing to a hook, which will be optimized out
     when devicetree is not used.
   use linux/gpio.h.
   move binding doc to i2c/i2c-gpio.txt.
v3 use speed-hz instead of udelay in dts binding.
   condition the devicetree probe.
v4 simplify private allocation.
v5 condition module device table export for of.
v6 change return code if probe fail.

Hi Ben, this driver must get gpio pins from platform data or devicetree,
  so it should fail if there is no platform data and devicetree is not
  configured.

 Documentation/devicetree/bindings/i2c/i2c-gpio.txt |   40 +++++++
 drivers/i2c/busses/i2c-gpio.c                      |  113 ++++++++++++++++----
 2 files changed, 133 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..38ef4f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,40 @@
+GPIO-based I2C
+
+Required properties:
+- compatible : should be "i2c-gpio".
+- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
+Optional properties:
+- sda-is-open-drain : present if SDA gpio is open-drain.
+- scl-is-open-drain : present if SCL gpio is open-drain.
+- scl-is-output-only : present if the output driver for SCL cannot be
+	turned off. this will prevent clock stretching from working.
+- speed-hz : SCL frequency.
+- timeout : clock stretching timeout in milliseconds.
+
+Example:
+
+gpio0: starlet-gpio@0d8000c0 {
+	compatible = "nintendo,starlet-gpio";
+	reg = <0d8000c0 4>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+i2c-video {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "i2c-gpio";
+
+	gpios = <&gpio0 10 0	/* SDA line */
+		 &gpio0 11 0	/* SCL line */
+		>;
+	sda-is-open-drain;
+	scl-is-open-drain;
+	scl-is-output-only;
+	speed-hz = <250000>;
+
+	audio-video-encoder {
+		compatible = "nintendo,wii-ave-rvl";
+		reg = <70>;
+	};
+};
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index d9aa9a6..feac3e5 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,14 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_i2c.h>
 
-#include <asm/gpio.h>
+struct i2c_gpio_private_data {
+	struct i2c_adapter adap;
+	struct i2c_algo_bit_data bit_data;
+	struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +84,80 @@ static int i2c_gpio_getscl(void *data)
 	return gpio_get_value(pdata->scl_pin);
 }
 
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+
+/* Check if devicetree nodes exist and build platform data */
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *prop;
+	int sda_pin, scl_pin;
+	int len;
+
+	if (!np || of_gpio_count(np) < 2)
+		return -ENODEV;
+
+	sda_pin = of_get_gpio_flags(np, 0, NULL);
+	scl_pin = of_get_gpio_flags(np, 1, NULL);
+	if (sda_pin < 0 || scl_pin < 0) {
+		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+		       np->full_name, sda_pin, scl_pin);
+		return -ENODEV;
+	}
+
+	pdata->sda_pin = sda_pin;
+	pdata->scl_pin = scl_pin;
+	prop = of_get_property(np, "sda-is-open-drain", NULL);
+	if (prop)
+		pdata->sda_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-open-drain", NULL);
+	if (prop)
+		pdata->scl_is_open_drain = 1;
+	prop = of_get_property(np, "scl-is-output-only", NULL);
+	if (prop)
+		pdata->scl_is_output_only = 1;
+	prop = of_get_property(np, "speed-hz", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->udelay = DIV_ROUND_UP(1000000, be32_to_cpup(prop) * 2);
+	prop = of_get_property(np, "timeout", &len);
+	if (prop && len >= sizeof(__be32))
+		pdata->timeout = msecs_to_jiffies(be32_to_cpup(prop));
+
+	return 0;
+}
+#else
+static int i2c_gpio_of_probe(struct platform_device *pdev,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -ENODEV;
+}
+#endif
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_algo_bit_data *bit_data;
 	struct i2c_adapter *adap;
 	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	adap = &priv->adap;
+	bit_data = &priv->bit_data;
+	pdata = &priv->pdata;
 
-	ret = -ENOMEM;
-	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (!adap)
-		goto err_alloc_adap;
-	bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-	if (!bit_data)
-		goto err_alloc_bit_data;
+	if (pdev->dev.platform_data) {
+		*pdata = *(struct i2c_gpio_platform_data *)
+			pdev->dev.platform_data;
+	} else {
+		ret = i2c_gpio_of_probe(pdev, pdata);
+		if (ret)
+			return ret;
+	}
 
 	ret = gpio_request(pdata->sda_pin, "sda");
 	if (ret)
@@ -143,6 +205,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	adap->algo_data = bit_data;
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	/*
 	 * If "dev->id" is negative we consider it as zero.
@@ -154,13 +217,16 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_add_bus;
 
-	platform_set_drvdata(pdev, adap);
+	platform_set_drvdata(pdev, priv);
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 		 pdata->sda_pin, pdata->scl_pin,
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
+	/* Now register all the child nodes */
+	of_i2c_register_devices(adap);
+
 	return 0;
 
 err_add_bus:
@@ -168,34 +234,41 @@ err_add_bus:
 err_request_scl:
 	gpio_free(pdata->sda_pin);
 err_request_sda:
-	kfree(bit_data);
-err_alloc_bit_data:
-	kfree(adap);
-err_alloc_adap:
 	return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+	struct i2c_gpio_private_data *priv;
 	struct i2c_gpio_platform_data *pdata;
 	struct i2c_adapter *adap;
 
-	adap = platform_get_drvdata(pdev);
-	pdata = pdev->dev.platform_data;
+	priv = platform_get_drvdata(pdev);
+	adap = &priv->adap;
+	pdata = &priv->pdata;
 
 	i2c_del_adapter(adap);
 	gpio_free(pdata->scl_pin);
 	gpio_free(pdata->sda_pin);
-	kfree(adap->algo_data);
-	kfree(adap);
 
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id i2c_gpio_match[] = {
+	{ .compatible = "i2c-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, i2c_gpio_match);
+#else /* CONFIG_OF */
+#define i2c_gpio_match NULL
+#endif /* CONFIG_OF */
+
 static struct platform_driver i2c_gpio_driver = {
 	.driver		= {
 		.name	= "i2c-gpio",
 		.owner	= THIS_MODULE,
+		.of_match_table = i2c_gpio_match,
 	},
 	.probe		= i2c_gpio_probe,
 	.remove		= __devexit_p(i2c_gpio_remove),
-- 
1.7.4

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

* Re: [PATCH v6] i2c-gpio: add devicetree support
@ 2011-02-24 16:22                         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-02-24 16:22 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Ben Dooks, linux-kernel, nios2-dev, devicetree-discuss,
	linux-i2c, Albert Herranz

On Thu, Feb 24, 2011 at 12:00:13PM +0800, Thomas Chou wrote:
> From: Albert Herranz <albert_herranz@yahoo.es>
> 
> This patch adds devicetree support to i2c-gpio driver. The allocation
> of local data is integrated to a private structure, and use devm_*
> helper for easy cleanup.
> 
> It is base on an earlier patch for gc-linux from
> Albert Herranz <albert_herranz@yahoo.es>.
> 
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> CC: Albert Herranz <albert_herranz@yahoo.es>
> Acked-by: Haavard Skinnemoen <hskinnemoen@gmail.com>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.

Hi Thomas,

One nitpick; I just looked, and other i2c controllers are already
using 'clock-frequency' instead of 'speed-hz' for the speed of the
bus.  I'd like to see this patch use the same terminology.

Otherwise this looks good to me.

Thanks,
g.

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

* Re: [PATCH v6] i2c-gpio: add devicetree support
@ 2011-02-24 16:22                         ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-02-24 16:22 UTC (permalink / raw)
  To: Thomas Chou
  Cc: Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Albert Herranz

On Thu, Feb 24, 2011 at 12:00:13PM +0800, Thomas Chou wrote:
> From: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> 
> This patch adds devicetree support to i2c-gpio driver. The allocation
> of local data is integrated to a private structure, and use devm_*
> helper for easy cleanup.
> 
> It is base on an earlier patch for gc-linux from
> Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>.
> 
> Signed-off-by: Thomas Chou <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
> CC: Albert Herranz <albert_herranz-mRCrAkd8dF0@public.gmane.org>
> Acked-by: Haavard Skinnemoen <hskinnemoen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
> ---
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> new file mode 100644
> index 0000000..38ef4f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt
> @@ -0,0 +1,40 @@
> +GPIO-based I2C
> +
> +Required properties:
> +- compatible : should be "i2c-gpio".
> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
> +Optional properties:
> +- sda-is-open-drain : present if SDA gpio is open-drain.
> +- scl-is-open-drain : present if SCL gpio is open-drain.
> +- scl-is-output-only : present if the output driver for SCL cannot be
> +	turned off. this will prevent clock stretching from working.
> +- speed-hz : SCL frequency.

Hi Thomas,

One nitpick; I just looked, and other i2c controllers are already
using 'clock-frequency' instead of 'speed-hz' for the speed of the
bus.  I'd like to see this patch use the same terminology.

Otherwise this looks good to me.

Thanks,
g.

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

* Re: [PATCH v6] i2c-gpio: add devicetree support
@ 2011-02-25  2:04                           ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-25  2:04 UTC (permalink / raw)
  To: Grant Likely
  Cc: Ben Dooks, linux-kernel, nios2-dev, devicetree-discuss,
	linux-i2c, Albert Herranz

Hi Grant,

On 02/25/2011 12:22 AM, Grant Likely wrote:
>> +Required properties:
>> +- compatible : should be "i2c-gpio".
>> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
>> +Optional properties:
>> +- sda-is-open-drain : present if SDA gpio is open-drain.
>> +- scl-is-open-drain : present if SCL gpio is open-drain.
>> +- scl-is-output-only : present if the output driver for SCL cannot be
>> +	turned off. this will prevent clock stretching from working.
>> +- speed-hz : SCL frequency.
>
> Hi Thomas,
>
> One nitpick; I just looked, and other i2c controllers are already
> using 'clock-frequency' instead of 'speed-hz' for the speed of the
> bus.  I'd like to see this patch use the same terminology.

I studied 'clock-frequency' usage of existing i2c drivers before working 
on this patch.

i2c-ibm_iic.c, i2c-mpc.c, i2c-ocores.c : use as bus clock frequency 
input to the core.

i2c-cpm.c : use as i2c SCL output frequency.

Most other non-i2c drivers use clock-frequency as bus clock frequency 
input, too.

I think the SCL freq usage in i2c-cpm.c is confusing. So I would suggest 
we borrow 'speed-hz' from spi subsystem, which means the clock freq 
output on the peripheral bus.

Best regards,
Thomas


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

* Re: [PATCH v6] i2c-gpio: add devicetree support
@ 2011-02-25  2:04                           ` Thomas Chou
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Chou @ 2011-02-25  2:04 UTC (permalink / raw)
  To: Grant Likely
  Cc: Ben Dooks, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Albert Herranz

Hi Grant,

On 02/25/2011 12:22 AM, Grant Likely wrote:
>> +Required properties:
>> +- compatible : should be "i2c-gpio".
>> +- gpios : should specify GPIOs used for SDA and SCL lines, in that order.
>> +Optional properties:
>> +- sda-is-open-drain : present if SDA gpio is open-drain.
>> +- scl-is-open-drain : present if SCL gpio is open-drain.
>> +- scl-is-output-only : present if the output driver for SCL cannot be
>> +	turned off. this will prevent clock stretching from working.
>> +- speed-hz : SCL frequency.
>
> Hi Thomas,
>
> One nitpick; I just looked, and other i2c controllers are already
> using 'clock-frequency' instead of 'speed-hz' for the speed of the
> bus.  I'd like to see this patch use the same terminology.

I studied 'clock-frequency' usage of existing i2c drivers before working 
on this patch.

i2c-ibm_iic.c, i2c-mpc.c, i2c-ocores.c : use as bus clock frequency 
input to the core.

i2c-cpm.c : use as i2c SCL output frequency.

Most other non-i2c drivers use clock-frequency as bus clock frequency 
input, too.

I think the SCL freq usage in i2c-cpm.c is confusing. So I would suggest 
we borrow 'speed-hz' from spi subsystem, which means the clock freq 
output on the peripheral bus.

Best regards,
Thomas

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

* Re: [PATCH v6] i2c-gpio: add devicetree support
       [not found]                           ` <4D670E4B.6000407-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
@ 2011-02-25  2:07                             ` Grant Likely
  0 siblings, 0 replies; 51+ messages in thread
From: Grant Likely @ 2011-02-25  2:07 UTC (permalink / raw)
  To: Thomas Chou
  Cc: nios2-dev-1eJk0qcHJCcaeqlQEoCUNoJY59XmG8rH,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Ben Dooks, Albert Herranz


[-- Attachment #1.1: Type: text/plain, Size: 1407 bytes --]

Okay.
On Feb 24, 2011 7:04 PM, "Thomas Chou" <thomas-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org> wrote:
>
> Hi Grant,
>
>
> On 02/25/2011 12:22 AM, Grant Likely wrote:
>>>
>>> +Required properties:
>>> +- compatible : should be "i2c-gpio".
>>> +- gpios : should specify GPIOs used for SDA and SCL lines, in that
order.
>>> +Optional properties:
>>> +- sda-is-open-drain : present if SDA gpio is open-drain.
>>> +- scl-is-open-drain : present if SCL gpio is open-drain.
>>> +- scl-is-output-only : present if the output driver for SCL cannot be
>>> +       turned off. this will prevent clock stretching from working.
>>> +- speed-hz : SCL frequency.
>>
>>
>> Hi Thomas,
>>
>> One nitpick; I just looked, and other i2c controllers are already
>> using 'clock-frequency' instead of 'speed-hz' for the speed of the
>> bus.  I'd like to see this patch use the same terminology.
>
>
> I studied 'clock-frequency' usage of existing i2c drivers before working
on this patch.
>
> i2c-ibm_iic.c, i2c-mpc.c, i2c-ocores.c : use as bus clock frequency input
to the core.
>
> i2c-cpm.c : use as i2c SCL output frequency.
>
> Most other non-i2c drivers use clock-frequency as bus clock frequency
input, too.
>
> I think the SCL freq usage in i2c-cpm.c is confusing. So I would suggest
we borrow 'speed-hz' from spi subsystem, which means the clock freq output
on the peripheral bus.

Okay.

g.

>
> Best regards,
> Thomas
>

[-- Attachment #1.2: Type: text/html, Size: 1949 bytes --]

[-- Attachment #2: Type: text/plain, Size: 192 bytes --]

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

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

end of thread, other threads:[~2011-02-25  2:07 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-30 15:56 [PATCH] i2c-gpio: add devicetree support Thomas Chou
2011-01-30 15:56 ` Thomas Chou
2011-01-31  3:26 ` Håvard Skinnemoen
2011-01-31  3:26   ` Håvard Skinnemoen
2011-01-31  8:09   ` Grant Likely
2011-01-31  8:09     ` Grant Likely
2011-01-31 13:55     ` Jon Loeliger
2011-01-31 13:55       ` Jon Loeliger
     [not found]       ` <E1PjuE3-0002Xy-6z-CYoMK+44s/E@public.gmane.org>
2011-01-31 14:54         ` Grant Likely
2011-01-31 15:25     ` [PATCH 1/3] of: define dummy of_get_property if not CONFIG_OF Thomas Chou
2011-01-31 15:25       ` Thomas Chou
2011-01-31 22:10       ` Grant Likely
2011-01-31 22:10         ` Grant Likely
2011-01-31 15:25     ` [PATCH 2/3] of: of_gpiochip_add is needed only for gpiolib Thomas Chou
2011-01-31 15:25       ` Thomas Chou
2011-01-31 22:16       ` Grant Likely
2011-01-31 22:16         ` Grant Likely
2011-01-31 15:25     ` [PATCH 3/3 v2] i2c-gpio: add devicetree support Thomas Chou
2011-01-31 15:25       ` Thomas Chou
2011-01-31 21:14       ` [3/3,v2] " Milton Miller
2011-01-31 21:14         ` Milton Miller
2011-01-31 21:29         ` Grant Likely
2011-01-31 21:29           ` Grant Likely
2011-02-03  2:26           ` [PATCH] " Thomas Chou
2011-02-03  2:26             ` Thomas Chou
2011-02-03  4:24             ` Håvard Skinnemoen
2011-02-03 18:07             ` Grant Likely
2011-02-03 18:07               ` Grant Likely
2011-02-10  2:29               ` [PATCH v4] " Thomas Chou
2011-02-10  2:29                 ` Thomas Chou
2011-02-14  2:30                 ` [PATCH v5] " Thomas Chou
2011-02-14  2:30                   ` Thomas Chou
2011-02-16  5:49                   ` Grant Likely
2011-02-16  5:49                     ` Grant Likely
2011-02-16  6:13                     ` Thomas Chou
2011-02-16  6:13                       ` Thomas Chou
2011-02-23  1:12                   ` Ben Dooks
2011-02-23  1:12                     ` Ben Dooks
2011-02-23 13:18                     ` Thomas Chou
2011-02-23 13:18                       ` Thomas Chou
2011-02-24  4:00                     ` [PATCH v6] " Thomas Chou
2011-02-24  4:00                       ` Thomas Chou
2011-02-24 16:22                       ` Grant Likely
2011-02-24 16:22                         ` Grant Likely
2011-02-25  2:04                         ` Thomas Chou
2011-02-25  2:04                           ` Thomas Chou
     [not found]                           ` <4D670E4B.6000407-SDxUXYEhEBiCuPEqFHbRBg@public.gmane.org>
2011-02-25  2:07                             ` Grant Likely
2011-01-31 22:35     ` [PATCH] " Håvard Skinnemoen
2011-01-31 22:35       ` Håvard Skinnemoen
2011-01-31 23:01       ` Grant Likely
2011-01-31 23:01         ` Grant Likely

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.