[PATCH v3] leds: Add DT support for leds-pca9532

2014-09-10 Thread Roland Stigge
This patch adds DT support for leds-pca9532.

Signed-off-by: Roland Stigge 

---
Applies to v3.17-rc4

 v3: Removed superfluous whitespace
 v2: Removed #ifdef statements

 Documentation/devicetree/bindings/leds/leds-pca9532.txt |   43 ++
 drivers/leds/leds-pca9532.c |   47 
 2 files changed, 90 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/leds/leds-pca9532.txt
@@ -0,0 +1,43 @@
+NXP PCA9532 LED (incl. GPIO) controller
+
+Required properties:
+- compatible: must be "nxp,pca9532"
+- reg: I2C address
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be 2:
+   1) pin number
+   2) optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- nxp,typecodes: groups of 2 bits for each of the 16 pins:
+  0: None
+  1: LED
+  2: Beep
+  3: GPIO
+- nxp,statecodes: groups of 2 bits for each of the 16 pins:
+  0: off
+  1: on
+  2: pwm0
+  3: pwm1
+
+Optional properties:
+- nxp,psc: array of 2 numbers: PSC values for the two PWM channels (see 
datasheet)
+- nxp,pwm: array of 2 numbers: PWM values for the two PWM channels (see 
datasheet)
+
+Example:
+
+   pca9532: pca9532@60 {
+   compatible = "nxp,pca9532";
+   gpio-controller;
+   #gpio-cells = <2>;
+   nxp,typecodes = <0x>;
+   nxp,statecodes = <0x>;
+   reg = <0x60>;
+   };
+
+   sd@20098000 {
+   wp-gpios = < 5 0>;
+   cd-gpios = < 4 0>;
+   cd-inverted;
+   bus-width = <4>;
+   status = "okay";
+   };
--- linux-2.6.orig/drivers/leds/leds-pca9532.c
+++ linux-2.6/drivers/leds/leds-pca9532.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* m =  num_leds*/
 #define PCA9532_REG_INPUT(i)   ((i) >> 3)
@@ -442,6 +443,43 @@ exit:
return err;
 }
 
+static struct pca9532_platform_data *pca9532_parse_dt(struct device *dev)
+{
+   struct device_node *np = dev->of_node;
+   struct pca9532_platform_data *pca9532_pdata;
+   u32 typecodes, statecodes;
+   u32 pwm[2];
+   u32 psc[2];
+   int i;
+
+   pca9532_pdata = devm_kzalloc(dev, sizeof(*pca9532_pdata), GFP_KERNEL);
+   if (!pca9532_pdata)
+   return NULL;
+
+   if (!of_property_read_u32(np, "nxp,typecodes", )) {
+   for (i = 0; i < 16; i++)
+   pca9532_pdata->leds[i].type =
+   (typecodes >> (2 * i)) & 0x3;
+   }
+   if (!of_property_read_u32(np, "nxp,statecodes", )) {
+   for (i = 0; i < 16; i++)
+   pca9532_pdata->leds[i].state =
+   (statecodes >> (2 * i)) & 0x3;
+   }
+   if (!of_property_read_u32_array(np, "nxp,pwm", [0], 2)) {
+   for (i = 0; i < 2; i++)
+   pca9532_pdata->pwm[i] = pwm[i];
+   }
+   if (!of_property_read_u32_array(np, "nxp,psc", [0], 2)) {
+   for (i = 0; i < 2; i++)
+   pca9532_pdata->psc[i] = psc[i];
+   }
+
+   pca9532_pdata->gpio_base = -1; /* dynamically assign gpio base */
+
+   return pca9532_pdata;
+}
+
 static int pca9532_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
@@ -449,6 +487,9 @@ static int pca9532_probe(struct i2c_clie
struct pca9532_platform_data *pca9532_pdata =
dev_get_platdata(>dev);
 
+   if (IS_ENABLED(CONFIG_OF) && !pca9532_pdata && client->dev.of_node)
+   pca9532_pdata = pca9532_parse_dt(>dev);
+
if (!pca9532_pdata)
return -EIO;
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] leds: Add DT support for leds-pca9532

2014-09-10 Thread Roland Stigge
On 09/09/2014 08:08 PM, Arnd Bergmann wrote:
> Is this a full PWM controller? If it is, it would be better to also
> provide a #pwm-cells property and register the device with the PWM
> subsystem to allow arbitrary users.
> 
> If the PWM is only really usable for LED, it's probably enough to
> leave this used by the LED subsystem.

Right, this PWM is really only intended for LED use (as already done w/o
DT).

Sending the updated patch.

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


[PATCH v2] leds: Add DT support for leds-pca9532

2014-09-10 Thread Roland Stigge
This patch adds DT support for leds-pca9532.

Signed-off-by: Roland Stigge 

---
Applies to v3.17-rc4

 v2: Removed #ifdef statements

 Documentation/devicetree/bindings/leds/leds-pca9532.txt |   43 ++
 drivers/leds/leds-pca9532.c |   47 
 2 files changed, 90 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/leds/leds-pca9532.txt
@@ -0,0 +1,43 @@
+NXP PCA9532 LED (incl. GPIO) controller
+
+Required properties:
+- compatible: must be "nxp,pca9532"
+- reg: I2C address
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be 2:
+   1) pin number
+   2) optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- nxp,typecodes: groups of 2 bits for each of the 16 pins:
+  0: None
+  1: LED
+  2: Beep
+  3: GPIO
+- nxp,statecodes: groups of 2 bits for each of the 16 pins:
+  0: off
+  1: on
+  2: pwm0
+  3: pwm1
+
+Optional properties:
+- nxp,psc: array of 2 numbers: PSC values for the two PWM channels (see 
datasheet)
+- nxp,pwm: array of 2 numbers: PWM values for the two PWM channels (see 
datasheet)
+
+Example:
+
+   pca9532: pca9532@60 {
+   compatible = "nxp,pca9532";
+   gpio-controller;
+   #gpio-cells = <2>;
+   nxp,typecodes = <0x>;
+   nxp,statecodes = <0x>;
+   reg = <0x60>;
+   };
+
+   sd@20098000 {
+   wp-gpios = < 5 0>;
+   cd-gpios = < 4 0>;
+   cd-inverted;
+   bus-width = <4>;
+   status = "okay";
+   };
--- linux-2.6.orig/drivers/leds/leds-pca9532.c
+++ linux-2.6/drivers/leds/leds-pca9532.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* m =  num_leds*/
 #define PCA9532_REG_INPUT(i)   ((i) >> 3)
@@ -442,6 +443,43 @@ exit:
return err;
 }
 
+static struct pca9532_platform_data *pca9532_parse_dt(struct device *dev)
+{
+   struct device_node *np = dev->of_node;
+   struct pca9532_platform_data *pca9532_pdata;
+   u32 typecodes, statecodes;
+   u32 pwm[2];
+   u32 psc[2];
+   int i;
+
+   pca9532_pdata = devm_kzalloc(dev, sizeof(*pca9532_pdata), GFP_KERNEL);
+   if (!pca9532_pdata)
+   return NULL;
+
+   if (!of_property_read_u32(np, "nxp,typecodes", )) {
+   for (i = 0; i < 16; i++)
+   pca9532_pdata->leds[i].type =
+   (typecodes >> (2 * i)) & 0x3;
+   }
+   if (!of_property_read_u32(np, "nxp,statecodes", )) {
+   for (i = 0; i < 16; i++)
+   pca9532_pdata->leds[i].state =
+   (statecodes >> (2 * i)) & 0x3;
+   }
+   if (!of_property_read_u32_array(np, "nxp,pwm", [0], 2)) {
+   for (i = 0; i < 2; i++)
+   pca9532_pdata->pwm[i] = pwm[i];
+   }
+   if (!of_property_read_u32_array(np, "nxp,psc", [0], 2)) {
+   for (i = 0; i < 2; i++)
+   pca9532_pdata->psc[i] = psc[i];
+   }
+
+   pca9532_pdata->gpio_base = -1; /* dynamically assign gpio base */
+
+   return pca9532_pdata;
+}
+
 static int pca9532_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
@@ -449,6 +487,10 @@ static int pca9532_probe(struct i2c_clie
struct pca9532_platform_data *pca9532_pdata =
dev_get_platdata(>dev);
 
+
+   if (IS_ENABLED(CONFIG_OF) && !pca9532_pdata && client->dev.of_node)
+   pca9532_pdata = pca9532_parse_dt(>dev);
+
if (!pca9532_pdata)
return -EIO;
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] leds: Add DT support for leds-pca9532

2014-09-10 Thread Roland Stigge
This patch adds DT support for leds-pca9532.

Signed-off-by: Roland Stigge sti...@antcom.de

---
Applies to v3.17-rc4

 v2: Removed #ifdef statements

 Documentation/devicetree/bindings/leds/leds-pca9532.txt |   43 ++
 drivers/leds/leds-pca9532.c |   47 
 2 files changed, 90 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/leds/leds-pca9532.txt
@@ -0,0 +1,43 @@
+NXP PCA9532 LED (incl. GPIO) controller
+
+Required properties:
+- compatible: must be nxp,pca9532
+- reg: I2C address
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be 2:
+   1) pin number
+   2) optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- nxp,typecodes: groups of 2 bits for each of the 16 pins:
+  0: None
+  1: LED
+  2: Beep
+  3: GPIO
+- nxp,statecodes: groups of 2 bits for each of the 16 pins:
+  0: off
+  1: on
+  2: pwm0
+  3: pwm1
+
+Optional properties:
+- nxp,psc: array of 2 numbers: PSC values for the two PWM channels (see 
datasheet)
+- nxp,pwm: array of 2 numbers: PWM values for the two PWM channels (see 
datasheet)
+
+Example:
+
+   pca9532: pca9532@60 {
+   compatible = nxp,pca9532;
+   gpio-controller;
+   #gpio-cells = 2;
+   nxp,typecodes = 0x;
+   nxp,statecodes = 0x;
+   reg = 0x60;
+   };
+
+   sd@20098000 {
+   wp-gpios = pca9532 5 0;
+   cd-gpios = pca9532 4 0;
+   cd-inverted;
+   bus-width = 4;
+   status = okay;
+   };
--- linux-2.6.orig/drivers/leds/leds-pca9532.c
+++ linux-2.6/drivers/leds/leds-pca9532.c
@@ -21,6 +21,7 @@
 #include linux/workqueue.h
 #include linux/leds-pca9532.h
 #include linux/gpio.h
+#include linux/of.h
 
 /* m =  num_leds*/
 #define PCA9532_REG_INPUT(i)   ((i)  3)
@@ -442,6 +443,43 @@ exit:
return err;
 }
 
+static struct pca9532_platform_data *pca9532_parse_dt(struct device *dev)
+{
+   struct device_node *np = dev-of_node;
+   struct pca9532_platform_data *pca9532_pdata;
+   u32 typecodes, statecodes;
+   u32 pwm[2];
+   u32 psc[2];
+   int i;
+
+   pca9532_pdata = devm_kzalloc(dev, sizeof(*pca9532_pdata), GFP_KERNEL);
+   if (!pca9532_pdata)
+   return NULL;
+
+   if (!of_property_read_u32(np, nxp,typecodes, typecodes)) {
+   for (i = 0; i  16; i++)
+   pca9532_pdata-leds[i].type =
+   (typecodes  (2 * i))  0x3;
+   }
+   if (!of_property_read_u32(np, nxp,statecodes, statecodes)) {
+   for (i = 0; i  16; i++)
+   pca9532_pdata-leds[i].state =
+   (statecodes  (2 * i))  0x3;
+   }
+   if (!of_property_read_u32_array(np, nxp,pwm, pwm[0], 2)) {
+   for (i = 0; i  2; i++)
+   pca9532_pdata-pwm[i] = pwm[i];
+   }
+   if (!of_property_read_u32_array(np, nxp,psc, psc[0], 2)) {
+   for (i = 0; i  2; i++)
+   pca9532_pdata-psc[i] = psc[i];
+   }
+
+   pca9532_pdata-gpio_base = -1; /* dynamically assign gpio base */
+
+   return pca9532_pdata;
+}
+
 static int pca9532_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
@@ -449,6 +487,10 @@ static int pca9532_probe(struct i2c_clie
struct pca9532_platform_data *pca9532_pdata =
dev_get_platdata(client-dev);
 
+
+   if (IS_ENABLED(CONFIG_OF)  !pca9532_pdata  client-dev.of_node)
+   pca9532_pdata = pca9532_parse_dt(client-dev);
+
if (!pca9532_pdata)
return -EIO;
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] leds: Add DT support for leds-pca9532

2014-09-10 Thread Roland Stigge
On 09/09/2014 08:08 PM, Arnd Bergmann wrote:
 Is this a full PWM controller? If it is, it would be better to also
 provide a #pwm-cells property and register the device with the PWM
 subsystem to allow arbitrary users.
 
 If the PWM is only really usable for LED, it's probably enough to
 leave this used by the LED subsystem.

Right, this PWM is really only intended for LED use (as already done w/o
DT).

Sending the updated patch.

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


[PATCH v3] leds: Add DT support for leds-pca9532

2014-09-10 Thread Roland Stigge
This patch adds DT support for leds-pca9532.

Signed-off-by: Roland Stigge sti...@antcom.de

---
Applies to v3.17-rc4

 v3: Removed superfluous whitespace
 v2: Removed #ifdef statements

 Documentation/devicetree/bindings/leds/leds-pca9532.txt |   43 ++
 drivers/leds/leds-pca9532.c |   47 
 2 files changed, 90 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/leds/leds-pca9532.txt
@@ -0,0 +1,43 @@
+NXP PCA9532 LED (incl. GPIO) controller
+
+Required properties:
+- compatible: must be nxp,pca9532
+- reg: I2C address
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be 2:
+   1) pin number
+   2) optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- nxp,typecodes: groups of 2 bits for each of the 16 pins:
+  0: None
+  1: LED
+  2: Beep
+  3: GPIO
+- nxp,statecodes: groups of 2 bits for each of the 16 pins:
+  0: off
+  1: on
+  2: pwm0
+  3: pwm1
+
+Optional properties:
+- nxp,psc: array of 2 numbers: PSC values for the two PWM channels (see 
datasheet)
+- nxp,pwm: array of 2 numbers: PWM values for the two PWM channels (see 
datasheet)
+
+Example:
+
+   pca9532: pca9532@60 {
+   compatible = nxp,pca9532;
+   gpio-controller;
+   #gpio-cells = 2;
+   nxp,typecodes = 0x;
+   nxp,statecodes = 0x;
+   reg = 0x60;
+   };
+
+   sd@20098000 {
+   wp-gpios = pca9532 5 0;
+   cd-gpios = pca9532 4 0;
+   cd-inverted;
+   bus-width = 4;
+   status = okay;
+   };
--- linux-2.6.orig/drivers/leds/leds-pca9532.c
+++ linux-2.6/drivers/leds/leds-pca9532.c
@@ -21,6 +21,7 @@
 #include linux/workqueue.h
 #include linux/leds-pca9532.h
 #include linux/gpio.h
+#include linux/of.h
 
 /* m =  num_leds*/
 #define PCA9532_REG_INPUT(i)   ((i)  3)
@@ -442,6 +443,43 @@ exit:
return err;
 }
 
+static struct pca9532_platform_data *pca9532_parse_dt(struct device *dev)
+{
+   struct device_node *np = dev-of_node;
+   struct pca9532_platform_data *pca9532_pdata;
+   u32 typecodes, statecodes;
+   u32 pwm[2];
+   u32 psc[2];
+   int i;
+
+   pca9532_pdata = devm_kzalloc(dev, sizeof(*pca9532_pdata), GFP_KERNEL);
+   if (!pca9532_pdata)
+   return NULL;
+
+   if (!of_property_read_u32(np, nxp,typecodes, typecodes)) {
+   for (i = 0; i  16; i++)
+   pca9532_pdata-leds[i].type =
+   (typecodes  (2 * i))  0x3;
+   }
+   if (!of_property_read_u32(np, nxp,statecodes, statecodes)) {
+   for (i = 0; i  16; i++)
+   pca9532_pdata-leds[i].state =
+   (statecodes  (2 * i))  0x3;
+   }
+   if (!of_property_read_u32_array(np, nxp,pwm, pwm[0], 2)) {
+   for (i = 0; i  2; i++)
+   pca9532_pdata-pwm[i] = pwm[i];
+   }
+   if (!of_property_read_u32_array(np, nxp,psc, psc[0], 2)) {
+   for (i = 0; i  2; i++)
+   pca9532_pdata-psc[i] = psc[i];
+   }
+
+   pca9532_pdata-gpio_base = -1; /* dynamically assign gpio base */
+
+   return pca9532_pdata;
+}
+
 static int pca9532_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
@@ -449,6 +487,9 @@ static int pca9532_probe(struct i2c_clie
struct pca9532_platform_data *pca9532_pdata =
dev_get_platdata(client-dev);
 
+   if (IS_ENABLED(CONFIG_OF)  !pca9532_pdata  client-dev.of_node)
+   pca9532_pdata = pca9532_parse_dt(client-dev);
+
if (!pca9532_pdata)
return -EIO;
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] leds: Add DT support for leds-pca9532

2014-09-09 Thread Roland Stigge
This patch adds DT support for leds-pca9532.

Signed-off-by: Roland Stigge 

---
Applies to v3.17-rc4

 Documentation/devicetree/bindings/leds/leds-pca9532.txt |   43 ++
 drivers/leds/leds-pca9532.c |   47 
 2 files changed, 90 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/leds/leds-pca9532.txt
@@ -0,0 +1,43 @@
+NXP PCA9532 LED (incl. GPIO) controller
+
+Required properties:
+- compatible: must be "nxp,pca9532"
+- reg: I2C address
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be 2:
+   1) pin number
+   2) optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- nxp,typecodes: groups of 2 bits for each of the 16 pins:
+  0: None
+  1: LED
+  2: Beep
+  3: GPIO
+- nxp,statecodes: groups of 2 bits for each of the 16 pins:
+  0: off
+  1: on
+  2: pwm0
+  3: pwm1
+
+Optional properties:
+- nxp,psc: array of 2 numbers: PSC values for the two PWM channels (see 
datasheet)
+- nxp,pwm: array of 2 numbers: PWM values for the two PWM channels (see 
datasheet)
+
+Example:
+
+   pca9532: pca9532@60 {
+   compatible = "nxp,pca9532";
+   gpio-controller;
+   #gpio-cells = <2>;
+   nxp,typecodes = <0x>;
+   nxp,statecodes = <0x>;
+   reg = <0x60>;
+   };
+
+   sd@20098000 {
+   wp-gpios = < 5 0>;
+   cd-gpios = < 4 0>;
+   cd-inverted;
+   bus-width = <4>;
+   status = "okay";
+   };
--- linux-2.6.orig/drivers/leds/leds-pca9532.c
+++ linux-2.6/drivers/leds/leds-pca9532.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* m =  num_leds*/
 #define PCA9532_REG_INPUT(i)   ((i) >> 3)
@@ -442,6 +443,45 @@ exit:
return err;
 }
 
+#ifdef CONFIG_OF
+static struct pca9532_platform_data *pca9532_parse_dt(struct device *dev)
+{
+   struct device_node *np = dev->of_node;
+   struct pca9532_platform_data *pca9532_pdata;
+   u32 typecodes, statecodes;
+   u32 pwm[2];
+   u32 psc[2];
+   int i;
+
+   pca9532_pdata = devm_kzalloc(dev, sizeof(*pca9532_pdata), GFP_KERNEL);
+   if (!pca9532_pdata)
+   return NULL;
+
+   if (!of_property_read_u32(np, "nxp,typecodes", )) {
+   for (i = 0; i < 16; i++)
+   pca9532_pdata->leds[i].type =
+   (typecodes >> (2 * i)) & 0x3;
+   }
+   if (!of_property_read_u32(np, "nxp,statecodes", )) {
+   for (i = 0; i < 16; i++)
+   pca9532_pdata->leds[i].state =
+   (statecodes >> (2 * i)) & 0x3;
+   }
+   if (!of_property_read_u32_array(np, "nxp,pwm", [0], 2)) {
+   for (i = 0; i < 2; i++)
+   pca9532_pdata->pwm[i] = pwm[i];
+   }
+   if (!of_property_read_u32_array(np, "nxp,psc", [0], 2)) {
+   for (i = 0; i < 2; i++)
+   pca9532_pdata->psc[i] = psc[i];
+   }
+
+   pca9532_pdata->gpio_base = -1; /* dynamically assign gpio base */
+
+   return pca9532_pdata;
+}
+#endif
+
 static int pca9532_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
@@ -449,6 +489,11 @@ static int pca9532_probe(struct i2c_clie
struct pca9532_platform_data *pca9532_pdata =
dev_get_platdata(>dev);
 
+#ifdef CONFIG_OF
+   if (!pca9532_pdata && client->dev.of_node)
+   pca9532_pdata = pca9532_parse_dt(>dev);
+#endif
+
if (!pca9532_pdata)
return -EIO;
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] SPI: Fix error message

2014-09-09 Thread Roland Stigge
This patch fixes an error message typo ("not" missing).

Signed-off-by: Roland Stigge 

---
 drivers/spi/spi-pl022.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2136,7 +2136,7 @@ static int pl022_probe(struct amba_devic
cs_gpio);
else if (gpio_direction_output(cs_gpio, 1))
dev_err(>dev,
-   "could set gpio %d as output\n",
+   "could not set gpio %d as 
output\n",
cs_gpio);
}
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] SPI: Fix error message

2014-09-09 Thread Roland Stigge
This patch fixes an error message typo (not missing).

Signed-off-by: Roland Stigge sti...@antcom.de

---
 drivers/spi/spi-pl022.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2136,7 +2136,7 @@ static int pl022_probe(struct amba_devic
cs_gpio);
else if (gpio_direction_output(cs_gpio, 1))
dev_err(adev-dev,
-   could set gpio %d as output\n,
+   could not set gpio %d as 
output\n,
cs_gpio);
}
}
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] leds: Add DT support for leds-pca9532

2014-09-09 Thread Roland Stigge
This patch adds DT support for leds-pca9532.

Signed-off-by: Roland Stigge sti...@antcom.de

---
Applies to v3.17-rc4

 Documentation/devicetree/bindings/leds/leds-pca9532.txt |   43 ++
 drivers/leds/leds-pca9532.c |   47 
 2 files changed, 90 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/leds/leds-pca9532.txt
@@ -0,0 +1,43 @@
+NXP PCA9532 LED (incl. GPIO) controller
+
+Required properties:
+- compatible: must be nxp,pca9532
+- reg: I2C address
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be 2:
+   1) pin number
+   2) optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- nxp,typecodes: groups of 2 bits for each of the 16 pins:
+  0: None
+  1: LED
+  2: Beep
+  3: GPIO
+- nxp,statecodes: groups of 2 bits for each of the 16 pins:
+  0: off
+  1: on
+  2: pwm0
+  3: pwm1
+
+Optional properties:
+- nxp,psc: array of 2 numbers: PSC values for the two PWM channels (see 
datasheet)
+- nxp,pwm: array of 2 numbers: PWM values for the two PWM channels (see 
datasheet)
+
+Example:
+
+   pca9532: pca9532@60 {
+   compatible = nxp,pca9532;
+   gpio-controller;
+   #gpio-cells = 2;
+   nxp,typecodes = 0x;
+   nxp,statecodes = 0x;
+   reg = 0x60;
+   };
+
+   sd@20098000 {
+   wp-gpios = pca9532 5 0;
+   cd-gpios = pca9532 4 0;
+   cd-inverted;
+   bus-width = 4;
+   status = okay;
+   };
--- linux-2.6.orig/drivers/leds/leds-pca9532.c
+++ linux-2.6/drivers/leds/leds-pca9532.c
@@ -21,6 +21,7 @@
 #include linux/workqueue.h
 #include linux/leds-pca9532.h
 #include linux/gpio.h
+#include linux/of.h
 
 /* m =  num_leds*/
 #define PCA9532_REG_INPUT(i)   ((i)  3)
@@ -442,6 +443,45 @@ exit:
return err;
 }
 
+#ifdef CONFIG_OF
+static struct pca9532_platform_data *pca9532_parse_dt(struct device *dev)
+{
+   struct device_node *np = dev-of_node;
+   struct pca9532_platform_data *pca9532_pdata;
+   u32 typecodes, statecodes;
+   u32 pwm[2];
+   u32 psc[2];
+   int i;
+
+   pca9532_pdata = devm_kzalloc(dev, sizeof(*pca9532_pdata), GFP_KERNEL);
+   if (!pca9532_pdata)
+   return NULL;
+
+   if (!of_property_read_u32(np, nxp,typecodes, typecodes)) {
+   for (i = 0; i  16; i++)
+   pca9532_pdata-leds[i].type =
+   (typecodes  (2 * i))  0x3;
+   }
+   if (!of_property_read_u32(np, nxp,statecodes, statecodes)) {
+   for (i = 0; i  16; i++)
+   pca9532_pdata-leds[i].state =
+   (statecodes  (2 * i))  0x3;
+   }
+   if (!of_property_read_u32_array(np, nxp,pwm, pwm[0], 2)) {
+   for (i = 0; i  2; i++)
+   pca9532_pdata-pwm[i] = pwm[i];
+   }
+   if (!of_property_read_u32_array(np, nxp,psc, psc[0], 2)) {
+   for (i = 0; i  2; i++)
+   pca9532_pdata-psc[i] = psc[i];
+   }
+
+   pca9532_pdata-gpio_base = -1; /* dynamically assign gpio base */
+
+   return pca9532_pdata;
+}
+#endif
+
 static int pca9532_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
@@ -449,6 +489,11 @@ static int pca9532_probe(struct i2c_clie
struct pca9532_platform_data *pca9532_pdata =
dev_get_platdata(client-dev);
 
+#ifdef CONFIG_OF
+   if (!pca9532_pdata  client-dev.of_node)
+   pca9532_pdata = pca9532_parse_dt(client-dev);
+#endif
+
if (!pca9532_pdata)
return -EIO;
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 05/12] ARM: lpc32xx: add MTD_SPI_NOR (new dependency for M25P80)

2014-05-01 Thread Roland Stigge
On 01/05/14 08:26, Brian Norris wrote:
> This defconfig contains the CONFIG_M25P80 symbol, which is now
> dependent on the MTD_SPI_NOR symbol. Add CONFIG_MTD_SPI_NOR to satisfy
> the new dependency.

Can't the CONFIG_M25P80 declare its dependency on CONFIG_MTD_SPI_NOR
itself, or put CONFIG_M25P80 etc. into a submenu under CONFIG_MTD_SPI_NOR?

> 
> At the same time, drop the now-nonexistent CONFIG_MTD_CHAR symbol.
> 
> Signed-off-by: Brian Norris 
> Cc: Roland Stigge 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  arch/arm/configs/lpc32xx_defconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/configs/lpc32xx_defconfig 
> b/arch/arm/configs/lpc32xx_defconfig
> index 398a367ffce8..2de54c35fb47 100644
> --- a/arch/arm/configs/lpc32xx_defconfig
> +++ b/arch/arm/configs/lpc32xx_defconfig
> @@ -53,12 +53,12 @@ CONFIG_DEVTMPFS_MOUNT=y
>  # CONFIG_FW_LOADER is not set
>  CONFIG_MTD=y
>  CONFIG_MTD_CMDLINE_PARTS=y
> -CONFIG_MTD_CHAR=y
>  CONFIG_MTD_BLOCK=y
>  CONFIG_MTD_M25P80=y
>  CONFIG_MTD_NAND=y
>  CONFIG_MTD_NAND_SLC_LPC32XX=y
>  CONFIG_MTD_NAND_MLC_LPC32XX=y
> +CONFIG_MTD_SPI_NOR=y
>  CONFIG_BLK_DEV_LOOP=y
>  CONFIG_BLK_DEV_CRYPTOLOOP=y
>  CONFIG_BLK_DEV_RAM=y
> 

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


Re: [PATCH v2 05/12] ARM: lpc32xx: add MTD_SPI_NOR (new dependency for M25P80)

2014-05-01 Thread Roland Stigge
On 01/05/14 08:26, Brian Norris wrote:
 This defconfig contains the CONFIG_M25P80 symbol, which is now
 dependent on the MTD_SPI_NOR symbol. Add CONFIG_MTD_SPI_NOR to satisfy
 the new dependency.

Can't the CONFIG_M25P80 declare its dependency on CONFIG_MTD_SPI_NOR
itself, or put CONFIG_M25P80 etc. into a submenu under CONFIG_MTD_SPI_NOR?

 
 At the same time, drop the now-nonexistent CONFIG_MTD_CHAR symbol.
 
 Signed-off-by: Brian Norris computersforpe...@gmail.com
 Cc: Roland Stigge sti...@antcom.de
 Cc: linux-arm-ker...@lists.infradead.org
 Cc: linux-kernel@vger.kernel.org
 ---
  arch/arm/configs/lpc32xx_defconfig | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/arch/arm/configs/lpc32xx_defconfig 
 b/arch/arm/configs/lpc32xx_defconfig
 index 398a367ffce8..2de54c35fb47 100644
 --- a/arch/arm/configs/lpc32xx_defconfig
 +++ b/arch/arm/configs/lpc32xx_defconfig
 @@ -53,12 +53,12 @@ CONFIG_DEVTMPFS_MOUNT=y
  # CONFIG_FW_LOADER is not set
  CONFIG_MTD=y
  CONFIG_MTD_CMDLINE_PARTS=y
 -CONFIG_MTD_CHAR=y
  CONFIG_MTD_BLOCK=y
  CONFIG_MTD_M25P80=y
  CONFIG_MTD_NAND=y
  CONFIG_MTD_NAND_SLC_LPC32XX=y
  CONFIG_MTD_NAND_MLC_LPC32XX=y
 +CONFIG_MTD_SPI_NOR=y
  CONFIG_BLK_DEV_LOOP=y
  CONFIG_BLK_DEV_CRYPTOLOOP=y
  CONFIG_BLK_DEV_RAM=y
 

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


Re: [PATCH 2/7] ARM: lpc32xx: don't select HAVE_PWM

2014-02-10 Thread Roland Stigge
On 10/02/14 02:09, Jingoo Han wrote:
> The HAVE_PWM symbol is only for legacy platforms that provide
> the PWM API without using the generic framework. The lpc32xx
> platforms use the generic PWM framework, after the commit "2132fa8
> pwm: add lpc32xx PWM support".
> 
> Signed-off-by: Jingoo Han 
> ---
>  arch/arm/Kconfig |1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index e254198..897fa15 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -632,7 +632,6 @@ config ARCH_LPC32XX
>   select CPU_ARM926T
>   select GENERIC_CLOCKEVENTS
>   select HAVE_IDE
> - select HAVE_PWM
>   select USB_ARCH_HAS_OHCI
>   select USE_OF
>   help
> 

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


Re: [PATCH 2/7] ARM: lpc32xx: don't select HAVE_PWM

2014-02-10 Thread Roland Stigge
On 10/02/14 02:09, Jingoo Han wrote:
 The HAVE_PWM symbol is only for legacy platforms that provide
 the PWM API without using the generic framework. The lpc32xx
 platforms use the generic PWM framework, after the commit 2132fa8
 pwm: add lpc32xx PWM support.
 
 Signed-off-by: Jingoo Han jg1@samsung.com
 ---
  arch/arm/Kconfig |1 -
  1 file changed, 1 deletion(-)
 
 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
 index e254198..897fa15 100644
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
 @@ -632,7 +632,6 @@ config ARCH_LPC32XX
   select CPU_ARM926T
   select GENERIC_CLOCKEVENTS
   select HAVE_IDE
 - select HAVE_PWM
   select USB_ARCH_HAS_OHCI
   select USE_OF
   help
 

Acked-by: Roland Stigge sti...@antcom.de
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ARM: LPC32xx: Fix reset function

2013-09-04 Thread Roland Stigge
In the recent change to the reset function API (commit
7b6d864b48d95e6ea1df7df64475b9cb9616dcf9), the mode argument changed from a
char to an enum. lpc23xx_restart() only handles REBOOT_SOFT and REBOOT_HARD,
but the new kernel code emits REBOOT_COLD (0) on reboots now which leads to
lpc32xx simply not rebooting (but halting).

This patch fixes this by just resetting unconditionally as on other platforms
(e.g. mach-bcm2835).

Pulling lpc32xx_watchdog_reset() into lpc23xx_restart() since the while() in
lpc23xx_restart() is part of the procedure anyway and lpc32xx_watchdog_reset()
isn't used anywhere else anymore.

Signed-off-by: Roland Stigge 

--

Will provide a pull request for arm-soc when someone commented on this one.

---
 arch/arm/mach-lpc32xx/common.c |   29 ++---
 1 file changed, 6 insertions(+), 23 deletions(-)

--- linux-2.6.orig/arch/arm/mach-lpc32xx/common.c
+++ linux-2.6/arch/arm/mach-lpc32xx/common.c
@@ -57,20 +57,6 @@ int clk_is_sysclk_mainosc(void)
 }
 
 /*
- * System reset via the watchdog timer
- */
-static void lpc32xx_watchdog_reset(void)
-{
-   /* Make sure WDT clocks are enabled */
-   __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
-   LPC32XX_CLKPWR_TIMER_CLK_CTRL);
-
-   /* Instant assert of RESETOUT_N with pulse length 1mS */
-   __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18));
-   __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC));
-}
-
-/*
  * Detects and returns IRAM size for the device variation
  */
 #define LPC32XX_IRAM_BANK_SIZE SZ_128K
@@ -209,16 +195,13 @@ void __init lpc32xx_map_io(void)
 
 void lpc23xx_restart(enum reboot_mode mode, const char *cmd)
 {
-   switch (mode) {
-   case REBOOT_SOFT:
-   case REBOOT_HARD:
-   lpc32xx_watchdog_reset();
-   break;
+   /* Make sure WDT clocks are enabled */
+   __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
+   LPC32XX_CLKPWR_TIMER_CLK_CTRL);
 
-   default:
-   /* Do nothing */
-   break;
-   }
+   /* Instant assert of RESETOUT_N with pulse length 1mS */
+   __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18));
+   __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC));
 
/* Wait for watchdog to reset system */
while (1)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ARM: LPC32xx: Fix reset function

2013-09-04 Thread Roland Stigge
In the recent change to the reset function API (commit
7b6d864b48d95e6ea1df7df64475b9cb9616dcf9), the mode argument changed from a
char to an enum. lpc23xx_restart() only handles REBOOT_SOFT and REBOOT_HARD,
but the new kernel code emits REBOOT_COLD (0) on reboots now which leads to
lpc32xx simply not rebooting (but halting).

This patch fixes this by just resetting unconditionally as on other platforms
(e.g. mach-bcm2835).

Pulling lpc32xx_watchdog_reset() into lpc23xx_restart() since the while() in
lpc23xx_restart() is part of the procedure anyway and lpc32xx_watchdog_reset()
isn't used anywhere else anymore.

Signed-off-by: Roland Stigge sti...@antcom.de

--

Will provide a pull request for arm-soc when someone commented on this one.

---
 arch/arm/mach-lpc32xx/common.c |   29 ++---
 1 file changed, 6 insertions(+), 23 deletions(-)

--- linux-2.6.orig/arch/arm/mach-lpc32xx/common.c
+++ linux-2.6/arch/arm/mach-lpc32xx/common.c
@@ -57,20 +57,6 @@ int clk_is_sysclk_mainosc(void)
 }
 
 /*
- * System reset via the watchdog timer
- */
-static void lpc32xx_watchdog_reset(void)
-{
-   /* Make sure WDT clocks are enabled */
-   __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
-   LPC32XX_CLKPWR_TIMER_CLK_CTRL);
-
-   /* Instant assert of RESETOUT_N with pulse length 1mS */
-   __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18));
-   __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC));
-}
-
-/*
  * Detects and returns IRAM size for the device variation
  */
 #define LPC32XX_IRAM_BANK_SIZE SZ_128K
@@ -209,16 +195,13 @@ void __init lpc32xx_map_io(void)
 
 void lpc23xx_restart(enum reboot_mode mode, const char *cmd)
 {
-   switch (mode) {
-   case REBOOT_SOFT:
-   case REBOOT_HARD:
-   lpc32xx_watchdog_reset();
-   break;
+   /* Make sure WDT clocks are enabled */
+   __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
+   LPC32XX_CLKPWR_TIMER_CLK_CTRL);
 
-   default:
-   /* Do nothing */
-   break;
-   }
+   /* Instant assert of RESETOUT_N with pulse length 1mS */
+   __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18));
+   __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC));
 
/* Wait for watchdog to reset system */
while (1)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] MAX7301 GPIO: Reverting "Do not force SPI speed when using OF Platform"

2013-08-20 Thread Roland Stigge
On 08/20/2013 08:29 AM, Christophe Leroy wrote:
> This patch reverts commit 047b93a35961f7a6561e6f5dcb040738f822b892 which 
> breaks
> MAX7301 GPIO driver because that commit was dependant on a rejected patch that
> was implementing selection of SPI speed from the Device Tree.
> 
> Signed-off-by: Christophe Leroy 

Acked-by: Roland Stigge 

Good, thanks!

> 
> --- linux-3.11-rc6/drivers/gpio/gpio-max7301.c2013-08-17 
> 21:09:17.0 +0200
> +++ linux/drivers/gpio/gpio-max7301.c 2013-08-18 06:31:52.0 +0200
> @@ -56,8 +56,7 @@
>   int ret;
>  
>   /* bits_per_word cannot be configured in platform data */
> - if (spi->dev.platform_data)
> - spi->bits_per_word = 16;
> + spi->bits_per_word = 16;
>   ret = spi_setup(spi);
>   if (ret < 0)
>   return ret;
> 

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


Re: [PATCH] MAX7301 GPIO: Reverting Do not force SPI speed when using OF Platform

2013-08-20 Thread Roland Stigge
On 08/20/2013 08:29 AM, Christophe Leroy wrote:
 This patch reverts commit 047b93a35961f7a6561e6f5dcb040738f822b892 which 
 breaks
 MAX7301 GPIO driver because that commit was dependant on a rejected patch that
 was implementing selection of SPI speed from the Device Tree.
 
 Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

Acked-by: Roland Stigge sti...@antcom.de

Good, thanks!

 
 --- linux-3.11-rc6/drivers/gpio/gpio-max7301.c2013-08-17 
 21:09:17.0 +0200
 +++ linux/drivers/gpio/gpio-max7301.c 2013-08-18 06:31:52.0 +0200
 @@ -56,8 +56,7 @@
   int ret;
  
   /* bits_per_word cannot be configured in platform data */
 - if (spi-dev.platform_data)
 - spi-bits_per_word = 16;
 + spi-bits_per_word = 16;
   ret = spi_setup(spi);
   if (ret  0)
   return ret;
 

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


Re: [PATCH 4/5] USB: lpc32xx: USB_LPC32XX need not depend on USB_PHY

2013-05-29 Thread Roland Stigge
On 05/29/2013 01:43 PM, Roger Quadros wrote:
> As the USB PHY drivers no longer depend on USB_PHY but
> select it if needed, the controller drivers need not
> depend on USB_PHY. They can safely select the necessary
> PHY driver i.e. USB_ISP1301 in this case.
> 
> Signed-off-by: Roger Quadros 

Acked-by: Roland Stigge 
Tested-by: Roland Stigge 

Thanks!

> CC: Roland Stigge 
> ---
>  drivers/usb/gadget/Kconfig |1 -
>  1 files changed, 0 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index f41aa0d..2b98bce 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -144,7 +144,6 @@ config USB_AT91
>  config USB_LPC32XX
>   tristate "LPC32XX USB Peripheral Controller"
>   depends on ARCH_LPC32XX
> - depends on USB_PHY
>   select USB_ISP1301
>   help
>  This option selects the USB device controller in the LPC32xx SoC.

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


Re: [PATCH 4/5] USB: lpc32xx: USB_LPC32XX need not depend on USB_PHY

2013-05-29 Thread Roland Stigge
On 05/29/2013 01:43 PM, Roger Quadros wrote:
 As the USB PHY drivers no longer depend on USB_PHY but
 select it if needed, the controller drivers need not
 depend on USB_PHY. They can safely select the necessary
 PHY driver i.e. USB_ISP1301 in this case.
 
 Signed-off-by: Roger Quadros rog...@ti.com

Acked-by: Roland Stigge sti...@antcom.de
Tested-by: Roland Stigge sti...@antcom.de

Thanks!

 CC: Roland Stigge sti...@antcom.de
 ---
  drivers/usb/gadget/Kconfig |1 -
  1 files changed, 0 insertions(+), 1 deletions(-)
 
 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
 index f41aa0d..2b98bce 100644
 --- a/drivers/usb/gadget/Kconfig
 +++ b/drivers/usb/gadget/Kconfig
 @@ -144,7 +144,6 @@ config USB_AT91
  config USB_LPC32XX
   tristate LPC32XX USB Peripheral Controller
   depends on ARCH_LPC32XX
 - depends on USB_PHY
   select USB_ISP1301
   help
  This option selects the USB device controller in the LPC32xx SoC.

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


Re: [PATCH 19/21] USB: lpc32xx: ISP1301 needs USB_PHY

2013-04-25 Thread Roland Stigge
On 25/04/13 19:29, Arnd Bergmann wrote:
> The Kconfig entry for USB_LPC32XX unconditionally selects USB_ISP1301,
> which is now only visible when USB_PHY is also enabled.
> 
> This adds an appropriate dependency and enables USB_PHY in the msm
> defconfig, avoiding these build errors:
> 
> warning: (USB_LPC32XX) selects USB_ISP1301 which has unmet direct 
> dependencies (USB_SUPPORT && USB_PHY && (USB || USB_GADGET) && I2C)
> drivers/built-in.o: In function `usb_hcd_nxp_probe':
> drivers/usb/host/ohci-nxp.c:224: undefined reference to `isp1301_get_client'
> drivers/built-in.o: In function `lpc32xx_udc_probe':
> drivers/usb/gadget/lpc32xx_udc.c:3071: undefined reference to 
> `isp1301_get_client'
> 
> Signed-off-by: Arnd Bergmann 
> Cc: linux-...@vger.kernel.org
> Cc: Greg Kroah-Hartman 
> Cc: Felipe Balbi 
> Cc: Roland Stigge 

Tested-by: Roland Stigge 
Acked-by: Roland Stigge 

> ---
>  arch/arm/configs/lpc32xx_defconfig | 1 +
>  drivers/usb/gadget/Kconfig | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/arch/arm/configs/lpc32xx_defconfig 
> b/arch/arm/configs/lpc32xx_defconfig
> index 8fee514..398a367 100644
> --- a/arch/arm/configs/lpc32xx_defconfig
> +++ b/arch/arm/configs/lpc32xx_defconfig
> @@ -146,6 +146,7 @@ CONFIG_SND_DEBUG_VERBOSE=y
>  # CONFIG_SND_SPI is not set
>  CONFIG_SND_SOC=y
>  CONFIG_USB=y
> +CONFIG_USB_PHY=y
>  CONFIG_USB_OHCI_HCD=y
>  CONFIG_USB_STORAGE=y
>  CONFIG_USB_GADGET=y
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index a61d981..f85b427 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -144,6 +144,7 @@ config USB_AT91
>  config USB_LPC32XX
>   tristate "LPC32XX USB Peripheral Controller"
>   depends on ARCH_LPC32XX
> + depends on USB_PHY
>   select USB_ISP1301
>   select USB_OTG_UTILS
>   help

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


Re: [PATCH 19/21] USB: lpc32xx: ISP1301 needs USB_PHY

2013-04-25 Thread Roland Stigge
On 25/04/13 19:29, Arnd Bergmann wrote:
 The Kconfig entry for USB_LPC32XX unconditionally selects USB_ISP1301,
 which is now only visible when USB_PHY is also enabled.
 
 This adds an appropriate dependency and enables USB_PHY in the msm
 defconfig, avoiding these build errors:
 
 warning: (USB_LPC32XX) selects USB_ISP1301 which has unmet direct 
 dependencies (USB_SUPPORT  USB_PHY  (USB || USB_GADGET)  I2C)
 drivers/built-in.o: In function `usb_hcd_nxp_probe':
 drivers/usb/host/ohci-nxp.c:224: undefined reference to `isp1301_get_client'
 drivers/built-in.o: In function `lpc32xx_udc_probe':
 drivers/usb/gadget/lpc32xx_udc.c:3071: undefined reference to 
 `isp1301_get_client'
 
 Signed-off-by: Arnd Bergmann a...@arndb.de
 Cc: linux-...@vger.kernel.org
 Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
 Cc: Felipe Balbi ba...@ti.com
 Cc: Roland Stigge sti...@antcom.de

Tested-by: Roland Stigge sti...@antcom.de
Acked-by: Roland Stigge sti...@antcom.de

 ---
  arch/arm/configs/lpc32xx_defconfig | 1 +
  drivers/usb/gadget/Kconfig | 1 +
  2 files changed, 2 insertions(+)
 
 diff --git a/arch/arm/configs/lpc32xx_defconfig 
 b/arch/arm/configs/lpc32xx_defconfig
 index 8fee514..398a367 100644
 --- a/arch/arm/configs/lpc32xx_defconfig
 +++ b/arch/arm/configs/lpc32xx_defconfig
 @@ -146,6 +146,7 @@ CONFIG_SND_DEBUG_VERBOSE=y
  # CONFIG_SND_SPI is not set
  CONFIG_SND_SOC=y
  CONFIG_USB=y
 +CONFIG_USB_PHY=y
  CONFIG_USB_OHCI_HCD=y
  CONFIG_USB_STORAGE=y
  CONFIG_USB_GADGET=y
 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
 index a61d981..f85b427 100644
 --- a/drivers/usb/gadget/Kconfig
 +++ b/drivers/usb/gadget/Kconfig
 @@ -144,6 +144,7 @@ config USB_AT91
  config USB_LPC32XX
   tristate LPC32XX USB Peripheral Controller
   depends on ARCH_LPC32XX
 + depends on USB_PHY
   select USB_ISP1301
   select USB_OTG_UTILS
   help

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


Re: [RESEND][PATCH RFT 2/2] pwm: lpc32xx: Don't change PWM_ENABLE bit in lpc32xx_pwm_config

2013-04-23 Thread Roland Stigge
On 04/23/2013 08:02 AM, Axel Lin wrote:
> lpc32xx_pwm_config() is supposed to set duty_ns and period_ns,
> it should not change PWM_ENABLE bit.
> 
> Signed-off-by: Axel Lin 

Tested-by: Roland Stigge 

> ---
>  drivers/pwm/pwm-lpc32xx.c |7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c
> index 1a5075e..e936202 100644
> --- a/drivers/pwm/pwm-lpc32xx.c
> +++ b/drivers/pwm/pwm-lpc32xx.c
> @@ -37,6 +37,7 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct 
> pwm_device *pwm,
>   struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
>   unsigned long long c;
>   int period_cycles, duty_cycles;
> + u32 val;
>  
>   c = clk_get_rate(lpc32xx->clk) / 256;
>   c = c * period_ns;
> @@ -68,8 +69,10 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, 
> struct pwm_device *pwm,
>   c = 255;
>   duty_cycles = 256 - c;
>  
> - writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles),
> - lpc32xx->base + (pwm->hwpwm << 2));
> + val = readl(lpc32xx->base + (pwm->hwpwm << 2));
> + val &= ~0x;
> + val |= PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles);
> + writel(val, lpc32xx->base + (pwm->hwpwm << 2));
>  
>   return 0;
>  }

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


Re: [RESEND][PATCH RFT 1/2] pwm: lpc32xx: Properly set PWM_ENABLE bit in lpc32xx_pwm_[enable|disable]

2013-04-23 Thread Roland Stigge
On 04/23/2013 08:01 AM, Axel Lin wrote:
> According to the LPC32x0 User Manual [1]:
> 
> For both PWM1 and PWM2 Control Registers:
> BIT 31:
> This bit gates the PWM_CLK signal and enables the external output pin
> to the PWM_PIN_STATE logical level.
> 
> 0 = PWM disabled. (Default)
> 1 = PWM enabled
> 
> So in lpc32xx_pwm_enable(), we should set PWM_ENABLE bit.
> In lpc32xx_pwm_disable(), we should just clear PWM_ENABLE bit rather than
> write 0 to the register which will also clear PWMx_RELOADV and PWMx_DUTY bits.
> 
> [1] http://www.nxp.com/documents/user_manual/UM10326.pdf
> 
> Signed-off-by: Axel Lin 

Tested-by: Roland Stigge 

> ---
> Hi,
> I don't have this hardware handy so I'd appreciate if someone can test this
> patch serial.
> 
> This patch serial was sent on https://lkml.org/lkml/2013/3/30/104
> Seems no feedback so far.
> So I just try again, maybe someone can help testing it.
> Thanks,
> Axel
> 
>  drivers/pwm/pwm-lpc32xx.c |   18 --
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c
> index b3f0d0d..1a5075e 100644
> --- a/drivers/pwm/pwm-lpc32xx.c
> +++ b/drivers/pwm/pwm-lpc32xx.c
> @@ -77,15 +77,29 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, 
> struct pwm_device *pwm,
>  static int lpc32xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
>  {
>   struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
> + u32 val;
> + int ret;
> +
> + ret = clk_enable(lpc32xx->clk);
> + if (ret)
> + return ret;
>  
> - return clk_enable(lpc32xx->clk);
> + val = readl(lpc32xx->base + (pwm->hwpwm << 2));
> + val |= PWM_ENABLE;
> + writel(val, lpc32xx->base + (pwm->hwpwm << 2));
> +
> + return 0;
>  }
>  
>  static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device 
> *pwm)
>  {
>   struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
> + u32 val;
> +
> + val = readl(lpc32xx->base + (pwm->hwpwm << 2));
> + val &= ~PWM_ENABLE;
> + writel(val, lpc32xx->base + (pwm->hwpwm << 2));
>  
> - writel(0, lpc32xx->base + (pwm->hwpwm << 2));
>   clk_disable(lpc32xx->clk);
>  }
>  

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


Re: [RESEND][PATCH RFT 1/2] pwm: lpc32xx: Properly set PWM_ENABLE bit in lpc32xx_pwm_[enable|disable]

2013-04-23 Thread Roland Stigge
On 04/23/2013 08:01 AM, Axel Lin wrote:
 According to the LPC32x0 User Manual [1]:
 
 For both PWM1 and PWM2 Control Registers:
 BIT 31:
 This bit gates the PWM_CLK signal and enables the external output pin
 to the PWM_PIN_STATE logical level.
 
 0 = PWM disabled. (Default)
 1 = PWM enabled
 
 So in lpc32xx_pwm_enable(), we should set PWM_ENABLE bit.
 In lpc32xx_pwm_disable(), we should just clear PWM_ENABLE bit rather than
 write 0 to the register which will also clear PWMx_RELOADV and PWMx_DUTY bits.
 
 [1] http://www.nxp.com/documents/user_manual/UM10326.pdf
 
 Signed-off-by: Axel Lin axel@ingics.com

Tested-by: Roland Stigge sti...@antcom.de

 ---
 Hi,
 I don't have this hardware handy so I'd appreciate if someone can test this
 patch serial.
 
 This patch serial was sent on https://lkml.org/lkml/2013/3/30/104
 Seems no feedback so far.
 So I just try again, maybe someone can help testing it.
 Thanks,
 Axel
 
  drivers/pwm/pwm-lpc32xx.c |   18 --
  1 file changed, 16 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c
 index b3f0d0d..1a5075e 100644
 --- a/drivers/pwm/pwm-lpc32xx.c
 +++ b/drivers/pwm/pwm-lpc32xx.c
 @@ -77,15 +77,29 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, 
 struct pwm_device *pwm,
  static int lpc32xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
  {
   struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
 + u32 val;
 + int ret;
 +
 + ret = clk_enable(lpc32xx-clk);
 + if (ret)
 + return ret;
  
 - return clk_enable(lpc32xx-clk);
 + val = readl(lpc32xx-base + (pwm-hwpwm  2));
 + val |= PWM_ENABLE;
 + writel(val, lpc32xx-base + (pwm-hwpwm  2));
 +
 + return 0;
  }
  
  static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device 
 *pwm)
  {
   struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
 + u32 val;
 +
 + val = readl(lpc32xx-base + (pwm-hwpwm  2));
 + val = ~PWM_ENABLE;
 + writel(val, lpc32xx-base + (pwm-hwpwm  2));
  
 - writel(0, lpc32xx-base + (pwm-hwpwm  2));
   clk_disable(lpc32xx-clk);
  }
  

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


Re: [RESEND][PATCH RFT 2/2] pwm: lpc32xx: Don't change PWM_ENABLE bit in lpc32xx_pwm_config

2013-04-23 Thread Roland Stigge
On 04/23/2013 08:02 AM, Axel Lin wrote:
 lpc32xx_pwm_config() is supposed to set duty_ns and period_ns,
 it should not change PWM_ENABLE bit.
 
 Signed-off-by: Axel Lin axel@ingics.com

Tested-by: Roland Stigge sti...@antcom.de

 ---
  drivers/pwm/pwm-lpc32xx.c |7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c
 index 1a5075e..e936202 100644
 --- a/drivers/pwm/pwm-lpc32xx.c
 +++ b/drivers/pwm/pwm-lpc32xx.c
 @@ -37,6 +37,7 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct 
 pwm_device *pwm,
   struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
   unsigned long long c;
   int period_cycles, duty_cycles;
 + u32 val;
  
   c = clk_get_rate(lpc32xx-clk) / 256;
   c = c * period_ns;
 @@ -68,8 +69,10 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, 
 struct pwm_device *pwm,
   c = 255;
   duty_cycles = 256 - c;
  
 - writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles),
 - lpc32xx-base + (pwm-hwpwm  2));
 + val = readl(lpc32xx-base + (pwm-hwpwm  2));
 + val = ~0x;
 + val |= PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles);
 + writel(val, lpc32xx-base + (pwm-hwpwm  2));
  
   return 0;
  }

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


Re: [PATCH] ARM: LPC32xx: changed lpc23xx_restart to lpc32xx_restart

2013-04-02 Thread Roland Stigge
On 02/04/13 17:58, Olof Johansson wrote:
> On Wed, Mar 06, 2013 at 09:18:58PM +0100, Martin Knoll wrote:
>> This function has an odd name. This is probably a typo.
> 
> You should cc the platform maintainer on these kind of patches (Roland 
> Stigge).
> But it seems that he's not actually listed in MAINTAINERS.

I indeed missed the above patch - should be a simple syntactic fix in 3
places in arch/arm/. You can go ahead this time and directly take this
fix. Otherwise, please forward to me so I can add it to a lpc32xx tree
and do request pull.

> Roland, can you send a patch adding yourself as LPC32XX maintainer so these
> kind of patches don't get dropped? Thanks!

OK, just did.

Thanks for notifying!

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


[PATCH] MAINTAINERS: Add maintainer for LPC32xx

2013-04-02 Thread Roland Stigge
This patch adds Roland Stigge as maintainer for NXP LPC32xx.

Signed-off-by: Roland Stigge 

---
 MAINTAINERS |6 ++
 1 file changed, 6 insertions(+)

--- linux-2.6.orig/MAINTAINERS
+++ linux-2.6/MAINTAINERS
@@ -4941,6 +4941,12 @@ W:   logfs.org
 S: Maintained
 F: fs/logfs/
 
+LPC32XX MACHINE SUPPORT
+M: Roland Stigge 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-lpc32xx/
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M: Nagalakshmi Nandigama 
 M: Sreekanth Reddy 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MAINTAINERS: Add maintainer for LPC32xx

2013-04-02 Thread Roland Stigge
This patch adds Roland Stigge as maintainer for NXP LPC32xx.

Signed-off-by: Roland Stigge sti...@antcom.de

---
 MAINTAINERS |6 ++
 1 file changed, 6 insertions(+)

--- linux-2.6.orig/MAINTAINERS
+++ linux-2.6/MAINTAINERS
@@ -4941,6 +4941,12 @@ W:   logfs.org
 S: Maintained
 F: fs/logfs/
 
+LPC32XX MACHINE SUPPORT
+M: Roland Stigge sti...@antcom.de
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-lpc32xx/
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M: Nagalakshmi Nandigama nagalakshmi.nandig...@lsi.com
 M: Sreekanth Reddy sreekanth.re...@lsi.com
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ARM: LPC32xx: changed lpc23xx_restart to lpc32xx_restart

2013-04-02 Thread Roland Stigge
On 02/04/13 17:58, Olof Johansson wrote:
 On Wed, Mar 06, 2013 at 09:18:58PM +0100, Martin Knoll wrote:
 This function has an odd name. This is probably a typo.
 
 You should cc the platform maintainer on these kind of patches (Roland 
 Stigge).
 But it seems that he's not actually listed in MAINTAINERS.

I indeed missed the above patch - should be a simple syntactic fix in 3
places in arch/arm/. You can go ahead this time and directly take this
fix. Otherwise, please forward to me so I can add it to a lpc32xx tree
and do request pull.

 Roland, can you send a patch adding yourself as LPC32XX maintainer so these
 kind of patches don't get dropped? Thanks!

OK, just did.

Thanks for notifying!

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


Re: [PATCH] usb: Fix compile error by selecting USB_OTG_UTILS

2013-03-26 Thread Roland Stigge
-BEGIN PGP SIGNED MESSAGE-
Hash: RIPEMD160

On 03/26/2013 08:24 PM, Felipe Balbi wrote:
> commit ?

1c2088812f095df77f4b3224b65db79d7111a300

Seems to be based on the assumption that only OTG needs a PHY.
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFRUgQ/caH/YBv43g8RA7RwAKC5HfJmtZonZnwGs6h+hW6Nqi1++wCg25xt
0lckwMSSDwJ4PNiDKqqtRpY=
=Zpq1
-END PGP SIGNATURE-
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] usb: Fix compile error by selecting USB_OTG_UTILS

2013-03-26 Thread Roland Stigge
-BEGIN PGP SIGNED MESSAGE-
Hash: RIPEMD160

On 03/26/2013 07:03 PM, Felipe Balbi wrote:
> On Tue, Mar 26, 2013 at 06:36:01PM +0100, Roland Stigge wrote:
>> The current lpc32xx_defconfig breaks like this, caused by recent
>> phy restructuring:
> 
> which commit actually caused this ? I need to know to make sure if
> this should be sent to stable or not.

The issue definitely surfaced after v3.8, so no need for patching
stable, I guess.
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFRUfSMcaH/YBv43g8RA70DAKCigz7Qy4f01S9P5dNLH6jxlERF6gCg3H3q
qMlT8LpXfybr588cZFJUjcc=
=45cd
-END PGP SIGNATURE-
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] usb: Fix compile error by selecting USB_OTG_UTILS

2013-03-26 Thread Roland Stigge
The current lpc32xx_defconfig breaks like this, caused by recent phy
restructuring:

  LD  init/built-in.o
drivers/built-in.o: In function `usb_hcd_nxp_probe':
drivers/usb/host/ohci-nxp.c:224: undefined reference to `isp1301_get_client'
drivers/built-in.o: In function `lpc32xx_udc_probe':
drivers/usb/gadget/lpc32xx_udc.c:3104: undefined reference to
`isp1301_get_client' distcc[27867] ERROR: compile (null) on localhost failed
make: *** [vmlinux] Error 1

This patch fixes this by selecting USB_OTG_UTILS in Kconfig which
causes the phy driver to be built again.

Signed-off-by: Roland Stigge 

--
Applies to v3.9-rc4

---
 drivers/usb/gadget/Kconfig |1 +
 drivers/usb/phy/Kconfig|1 +
 2 files changed, 2 insertions(+)

--- linux-2.6.orig/drivers/usb/gadget/Kconfig
+++ linux-2.6/drivers/usb/gadget/Kconfig
@@ -145,6 +145,7 @@ config USB_LPC32XX
tristate "LPC32XX USB Peripheral Controller"
depends on ARCH_LPC32XX
select USB_ISP1301
+   select USB_OTG_UTILS
help
   This option selects the USB device controller in the LPC32xx SoC.
 
--- linux-2.6.orig/drivers/usb/phy/Kconfig
+++ linux-2.6/drivers/usb/phy/Kconfig
@@ -38,6 +38,7 @@ config USB_ISP1301
tristate "NXP ISP1301 USB transceiver support"
depends on USB || USB_GADGET
depends on I2C
+   select USB_OTG_UTILS
help
  Say Y here to add support for the NXP ISP1301 USB transceiver driver.
  This chip is typically used as USB transceiver for USB host, gadget
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] usb: Fix compile error by selecting USB_OTG_UTILS

2013-03-26 Thread Roland Stigge
The current lpc32xx_defconfig breaks like this, caused by recent phy
restructuring:

  LD  init/built-in.o
drivers/built-in.o: In function `usb_hcd_nxp_probe':
drivers/usb/host/ohci-nxp.c:224: undefined reference to `isp1301_get_client'
drivers/built-in.o: In function `lpc32xx_udc_probe':
drivers/usb/gadget/lpc32xx_udc.c:3104: undefined reference to
`isp1301_get_client' distcc[27867] ERROR: compile (null) on localhost failed
make: *** [vmlinux] Error 1

This patch fixes this by selecting USB_OTG_UTILS in Kconfig which
causes the phy driver to be built again.

Signed-off-by: Roland Stigge sti...@antcom.de

--
Applies to v3.9-rc4

---
 drivers/usb/gadget/Kconfig |1 +
 drivers/usb/phy/Kconfig|1 +
 2 files changed, 2 insertions(+)

--- linux-2.6.orig/drivers/usb/gadget/Kconfig
+++ linux-2.6/drivers/usb/gadget/Kconfig
@@ -145,6 +145,7 @@ config USB_LPC32XX
tristate LPC32XX USB Peripheral Controller
depends on ARCH_LPC32XX
select USB_ISP1301
+   select USB_OTG_UTILS
help
   This option selects the USB device controller in the LPC32xx SoC.
 
--- linux-2.6.orig/drivers/usb/phy/Kconfig
+++ linux-2.6/drivers/usb/phy/Kconfig
@@ -38,6 +38,7 @@ config USB_ISP1301
tristate NXP ISP1301 USB transceiver support
depends on USB || USB_GADGET
depends on I2C
+   select USB_OTG_UTILS
help
  Say Y here to add support for the NXP ISP1301 USB transceiver driver.
  This chip is typically used as USB transceiver for USB host, gadget
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] usb: Fix compile error by selecting USB_OTG_UTILS

2013-03-26 Thread Roland Stigge
-BEGIN PGP SIGNED MESSAGE-
Hash: RIPEMD160

On 03/26/2013 07:03 PM, Felipe Balbi wrote:
 On Tue, Mar 26, 2013 at 06:36:01PM +0100, Roland Stigge wrote:
 The current lpc32xx_defconfig breaks like this, caused by recent
 phy restructuring:
 
 which commit actually caused this ? I need to know to make sure if
 this should be sent to stable or not.

The issue definitely surfaced after v3.8, so no need for patching
stable, I guess.
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFRUfSMcaH/YBv43g8RA70DAKCigz7Qy4f01S9P5dNLH6jxlERF6gCg3H3q
qMlT8LpXfybr588cZFJUjcc=
=45cd
-END PGP SIGNATURE-
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] usb: Fix compile error by selecting USB_OTG_UTILS

2013-03-26 Thread Roland Stigge
-BEGIN PGP SIGNED MESSAGE-
Hash: RIPEMD160

On 03/26/2013 08:24 PM, Felipe Balbi wrote:
 commit ?

1c2088812f095df77f4b3224b65db79d7111a300

Seems to be based on the assumption that only OTG needs a PHY.
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFRUgQ/caH/YBv43g8RA7RwAKC5HfJmtZonZnwGs6h+hW6Nqi1++wCg25xt
0lckwMSSDwJ4PNiDKqqtRpY=
=Zpq1
-END PGP SIGNATURE-
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mmc: mmc_spi: Fix return value evaluation of irq_of_parse_and_map()

2013-01-30 Thread Roland Stigge
When irq_of_parse_and_map() returns an error, it does as zero. But in
mmc_spi_get_pdata(), the error return case is compared against NO_IRQ. This
might work where NO_IRQ is zero (defaults to zero when undefined, as on MIPS)
but not where NO_IRQ is sth. different, e.g. on ARM, where it is -1.

This patch changes to comparison with 0 which is the error return value of
irq_of_parse_and_map(). 

Tested on ARM that mmc_spi is working now.

Signed-off-by: Roland Stigge 

diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index 1534b58..d720b5e 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -146,7 +146,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct 
spi_device *spi)
oms->pdata.get_ro = of_mmc_spi_get_ro;
 
oms->detect_irq = irq_of_parse_and_map(np, 0);
-   if (oms->detect_irq != NO_IRQ) {
+   if (oms->detect_irq != 0) {
oms->pdata.init = of_mmc_spi_init;
oms->pdata.exit = of_mmc_spi_exit;
} else {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mmc: mmc_spi: Fix return value evaluation of irq_of_parse_and_map()

2013-01-30 Thread Roland Stigge
When irq_of_parse_and_map() returns an error, it does as zero. But in
mmc_spi_get_pdata(), the error return case is compared against NO_IRQ. This
might work where NO_IRQ is zero (defaults to zero when undefined, as on MIPS)
but not where NO_IRQ is sth. different, e.g. on ARM, where it is -1.

This patch changes to comparison with 0 which is the error return value of
irq_of_parse_and_map(). 

Tested on ARM that mmc_spi is working now.

Signed-off-by: Roland Stigge sti...@antcom.de

diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index 1534b58..d720b5e 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -146,7 +146,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct 
spi_device *spi)
oms-pdata.get_ro = of_mmc_spi_get_ro;
 
oms-detect_irq = irq_of_parse_and_map(np, 0);
-   if (oms-detect_irq != NO_IRQ) {
+   if (oms-detect_irq != 0) {
oms-pdata.init = of_mmc_spi_init;
oms-pdata.exit = of_mmc_spi_exit;
} else {
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 5/6 v14] gpio: Add device tree support to block GPIO API

2013-01-28 Thread Roland Stigge
On 01/28/2013 12:39 PM, Stijn Devriendt wrote:
>>> In the device-tree this is specified as:
>>>
>>> powr@0x20 {
>>>// other properties
>>>
>>>   gpios = < 4 0
>>> 5 0>;
>>> };
>>>
>>> Is this kind of integration also possible?
>>
>> You can reference the gpio block via a phandle, e.g.:
>>
>> blockgpio {
>> compatible = "linux,gpio-block";
>>
>> selector1 {
>> gpios = < 4 0>,
>> < 5 0>;
>> };
>> };
>>
>> powr@0x20 {
>> // ...
>>
>> gpios = <>;
>> };
>>
>>
>> In the driver, you can get the gpio block like this:
>>
>> block = gpio_block_find_by_name(of_parse_phandle(powr, "gpios", 0)->name);
>>
>> (Simplified by removed error/NULL handling!)
>>
>> If this turns out to be a common pattern, I can add a convenience "get"
>> function for this.
> 
> Given the pick-up of device-tree in ARM and MIPS, I think this stands
> a good chance
> of becoming a common pattern. Do mind the "gpios" name; it's already used by 
> the
> normal GPIO request functions...

Right, when providing the respective convenience function, I'll better
use sth. like "gpioblock" as property name.

Specifying a traditional list of GPIOs instead is easy, actually. The
respective driver just needs to allocate a gpio block explicitly
(insteady of implicitly via phandle as above). Unfortunately, gpio
blocks that should be exported and available to userspace can't be
specified this way. Therefore the strategy as above.

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


Re: [PATCH 5/6 v14] gpio: Add device tree support to block GPIO API

2013-01-28 Thread Roland Stigge
On 01/28/2013 12:39 PM, Stijn Devriendt wrote:
 In the device-tree this is specified as:

 powr@0x20 {
// other properties

   gpios = gpio 4 0
gpio 5 0;
 };

 Is this kind of integration also possible?

 You can reference the gpio block via a phandle, e.g.:

 blockgpio {
 compatible = linux,gpio-block;

 selector1 {
 gpios = gpio 4 0,
 gpio 5 0;
 };
 };

 powr@0x20 {
 // ...

 gpios = selector1;
 };


 In the driver, you can get the gpio block like this:

 block = gpio_block_find_by_name(of_parse_phandle(powr, gpios, 0)-name);

 (Simplified by removed error/NULL handling!)

 If this turns out to be a common pattern, I can add a convenience get
 function for this.
 
 Given the pick-up of device-tree in ARM and MIPS, I think this stands
 a good chance
 of becoming a common pattern. Do mind the gpios name; it's already used by 
 the
 normal GPIO request functions...

Right, when providing the respective convenience function, I'll better
use sth. like gpioblock as property name.

Specifying a traditional list of GPIOs instead is easy, actually. The
respective driver just needs to allocate a gpio block explicitly
(insteady of implicitly via phandle as above). Unfortunately, gpio
blocks that should be exported and available to userspace can't be
specified this way. Therefore the strategy as above.

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


Re: [PATCH 5/6 v14] gpio: Add device tree support to block GPIO API

2013-01-27 Thread Roland Stigge
On 27/01/13 14:07, Stijn Devriendt wrote:
>> +Example:
>> +
>> +blockgpio {
>> +compatible = "linux,gpio-block";
>> +
>> +block0 {
>> +gpios = < 3 0 0>,
>> +< 3 1 0>;
>> +};
>> +block1 {
>> +gpios = < 4 1 0>,
>> +< 4 3 0>,
>> +< 4 2 0>,
>> +< 4 4 0>,
>> +< 4 5 0>,
>> +< 4 6 0>,
>> +< 4 7 0>,
>> +< 4 8 0>,
>> +< 4 9 0>,
>> +< 4 10 0>,
>> +< 4 19 0>;
>> +};
>> +};
> 
> How do you see bindings for other kinds of drivers?
> 
> In my patchset, it's possible for other drivers to use gpio-blocks.
> One example we have is a power sequencer with 2 pins attached
> to GPIO pins. These 2 pins form a 2bit word to select power margining.
> These 2 pins need to be set synchronously (as otherwise when going
> from profile 0 to profile 3 you pass either profile 1 or profile 2 which
> could be bad for hardware)
> 
> In the device-tree this is specified as:
> 
> powr@0x20 {
>// other properties
> 
>   gpios = < 4 0
> 5 0>;
> };
> 
> Is this kind of integration also possible?

You can reference the gpio block via a phandle, e.g.:

blockgpio {
compatible = "linux,gpio-block";

selector1 {
gpios = < 4 0>,
< 5 0>;
};
};

powr@0x20 {
// ...

gpios = <>;
};


In the driver, you can get the gpio block like this:

block = gpio_block_find_by_name(of_parse_phandle(powr, "gpios", 0)->name);

(Simplified by removed error/NULL handling!)

If this turns out to be a common pattern, I can add a convenience "get"
function for this.

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


Re: [PATCH 1/6 v14] gpio: Add a block GPIO API to gpiolib

2013-01-27 Thread Roland Stigge
On 27/01/13 14:19, Stijn Devriendt wrote:
>> +Block GPIO
>> +--
>> +
>> +The above described interface concentrates on handling single GPIOs.  
>> However,
>> +in applications where it is critical to set several GPIOs at once, this
>> +interface doesn't work well, e.g. bit-banging protocols via grouped GPIO 
>> lines.
>> +Consider a GPIO controller that is connected via a slow I2C line. When
>> +switching two or more GPIOs one after another, there can be considerable 
>> time
>> +between those events. This is solved by an interface called Block GPIO:
>> +
>> +struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
>> +const char *name);
>> +
>> +This creates a new block of GPIOs as a list of GPIO numbers with the 
>> specified
>> +size which are accessible via the returned struct gpio_block and the 
>> accessor
>> +functions described below. Please note that you need to request the GPIOs
>> +separately via gpio_request(). Similarly, the direction of the used GPIOs 
>> need
>> +to be set by the user before using the block.
> 
> Is there anything holding you back from letting gpio_block_create() do
> the request
> for all the pins?

It's analoguous to plain GPIOs: They exist, but are not requested (by
whom?) by default.

> Also, wouldn't it make sense to have a gpio_block_direction_input()
> and _output()
> variant? On the other hand, for things like I2C and SPI emulation,
> some pins will
> naturally be always output (like clock lines) while other could be
> switched between
> in and output (like the i2c data line).

Right. Current implementation emphasizes on switching, not direction or
other convenience functions, which could be added, nevertheless.

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


Re: [PATCH 6/6 v14] gpio: Add block gpio to several gpio drivers

2013-01-27 Thread Roland Stigge
On 27/01/13 13:18, Stijn Devriendt wrote:
>>> In my patch, I go out of the way of this kind of thing for a simple reason:
>>> You may generate incorrect timing by doing this.
>>
>> You are right, certain things like synchronous on+off is not really
>> possible.
>>
>> However, the above at least supports switching on simulaneously, and
>> switching off simultaneously, which is an improvement in certain cases
>> (and this certain hardware part doesn't support more). Maybe this
>> certain driver behaviour can be documented even better than just in the
>> driver source.
>>
> 
> The question here is: do you expect a user of the block-GPIO API to
> go look into the base-driver code to see what will be supported?
> 
> In my version of the patch this means:
> - do not provide a single GPIO-block that crosses multiple base-drivers
> - only provide gpio_block_get/set for GPIO drivers that support the complete
> operation in a single go. (for example, in the above example there would be
> no gpio_block_set() function)
> 
> Perhaps the best approach is to make this explicit: Allow drivers to expose
> their capabilities wrt timing and allow users to request strict-timing or
> loose-timing. Loose-timing allows multiple gpio-drivers to be combined and
> allows drivers with separate set/clear, hi/lo registers to be used.

Interesting idea. However, it will be difficult to agree on good metrics
here. As Mark Brown pointed out, even when hardware seems to support
"simultaneousness" by registers, this doesn't actually mean that voltage
levels are switched simultaneously wrt. sub-nanosecond timing.

Also, it depends on further wiring between the actually supported GPIO
hardware chip and the integrated device's I/O connections.

Resulting in scenarios where GPIO chips (in terms of Linux drivers)
without explicit I/O set registers (e.g., set/clear regs) could be "more
simultaneous" than those having explicit I/O regs but hardware wiring
leading to bad "simultaneousness" behaviour.

Questionable if the kernel could address those details.

> Of course, for a first version you may as well leave it out. Perhaps the
> use-cases for cross-GPIO-driver blocks are not worth the extra complexity
> as of today?

I actually started the current block gpio patches to support this kind
of use case. :-)

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


Re: [PATCH 6/6 v14] gpio: Add block gpio to several gpio drivers

2013-01-27 Thread Roland Stigge
On 27/01/13 13:18, Stijn Devriendt wrote:
 In my patch, I go out of the way of this kind of thing for a simple reason:
 You may generate incorrect timing by doing this.

 You are right, certain things like synchronous on+off is not really
 possible.

 However, the above at least supports switching on simulaneously, and
 switching off simultaneously, which is an improvement in certain cases
 (and this certain hardware part doesn't support more). Maybe this
 certain driver behaviour can be documented even better than just in the
 driver source.

 
 The question here is: do you expect a user of the block-GPIO API to
 go look into the base-driver code to see what will be supported?
 
 In my version of the patch this means:
 - do not provide a single GPIO-block that crosses multiple base-drivers
 - only provide gpio_block_get/set for GPIO drivers that support the complete
 operation in a single go. (for example, in the above example there would be
 no gpio_block_set() function)
 
 Perhaps the best approach is to make this explicit: Allow drivers to expose
 their capabilities wrt timing and allow users to request strict-timing or
 loose-timing. Loose-timing allows multiple gpio-drivers to be combined and
 allows drivers with separate set/clear, hi/lo registers to be used.

Interesting idea. However, it will be difficult to agree on good metrics
here. As Mark Brown pointed out, even when hardware seems to support
simultaneousness by registers, this doesn't actually mean that voltage
levels are switched simultaneously wrt. sub-nanosecond timing.

Also, it depends on further wiring between the actually supported GPIO
hardware chip and the integrated device's I/O connections.

Resulting in scenarios where GPIO chips (in terms of Linux drivers)
without explicit I/O set registers (e.g., set/clear regs) could be more
simultaneous than those having explicit I/O regs but hardware wiring
leading to bad simultaneousness behaviour.

Questionable if the kernel could address those details.

 Of course, for a first version you may as well leave it out. Perhaps the
 use-cases for cross-GPIO-driver blocks are not worth the extra complexity
 as of today?

I actually started the current block gpio patches to support this kind
of use case. :-)

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


Re: [PATCH 1/6 v14] gpio: Add a block GPIO API to gpiolib

2013-01-27 Thread Roland Stigge
On 27/01/13 14:19, Stijn Devriendt wrote:
 +Block GPIO
 +--
 +
 +The above described interface concentrates on handling single GPIOs.  
 However,
 +in applications where it is critical to set several GPIOs at once, this
 +interface doesn't work well, e.g. bit-banging protocols via grouped GPIO 
 lines.
 +Consider a GPIO controller that is connected via a slow I2C line. When
 +switching two or more GPIOs one after another, there can be considerable 
 time
 +between those events. This is solved by an interface called Block GPIO:
 +
 +struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
 +const char *name);
 +
 +This creates a new block of GPIOs as a list of GPIO numbers with the 
 specified
 +size which are accessible via the returned struct gpio_block and the 
 accessor
 +functions described below. Please note that you need to request the GPIOs
 +separately via gpio_request(). Similarly, the direction of the used GPIOs 
 need
 +to be set by the user before using the block.
 
 Is there anything holding you back from letting gpio_block_create() do
 the request
 for all the pins?

It's analoguous to plain GPIOs: They exist, but are not requested (by
whom?) by default.

 Also, wouldn't it make sense to have a gpio_block_direction_input()
 and _output()
 variant? On the other hand, for things like I2C and SPI emulation,
 some pins will
 naturally be always output (like clock lines) while other could be
 switched between
 in and output (like the i2c data line).

Right. Current implementation emphasizes on switching, not direction or
other convenience functions, which could be added, nevertheless.

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


Re: [PATCH 5/6 v14] gpio: Add device tree support to block GPIO API

2013-01-27 Thread Roland Stigge
On 27/01/13 14:07, Stijn Devriendt wrote:
 +Example:
 +
 +blockgpio {
 +compatible = linux,gpio-block;
 +
 +block0 {
 +gpios = gpio 3 0 0,
 +gpio 3 1 0;
 +};
 +block1 {
 +gpios = gpio 4 1 0,
 +gpio 4 3 0,
 +gpio 4 2 0,
 +gpio 4 4 0,
 +gpio 4 5 0,
 +gpio 4 6 0,
 +gpio 4 7 0,
 +gpio 4 8 0,
 +gpio 4 9 0,
 +gpio 4 10 0,
 +gpio 4 19 0;
 +};
 +};
 
 How do you see bindings for other kinds of drivers?
 
 In my patchset, it's possible for other drivers to use gpio-blocks.
 One example we have is a power sequencer with 2 pins attached
 to GPIO pins. These 2 pins form a 2bit word to select power margining.
 These 2 pins need to be set synchronously (as otherwise when going
 from profile 0 to profile 3 you pass either profile 1 or profile 2 which
 could be bad for hardware)
 
 In the device-tree this is specified as:
 
 powr@0x20 {
// other properties
 
   gpios = gpio 4 0
gpio 5 0;
 };
 
 Is this kind of integration also possible?

You can reference the gpio block via a phandle, e.g.:

blockgpio {
compatible = linux,gpio-block;

selector1 {
gpios = gpio 4 0,
gpio 5 0;
};
};

powr@0x20 {
// ...

gpios = selector1;
};


In the driver, you can get the gpio block like this:

block = gpio_block_find_by_name(of_parse_phandle(powr, gpios, 0)-name);

(Simplified by removed error/NULL handling!)

If this turns out to be a common pattern, I can add a convenience get
function for this.

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


Re: [PATCH 6/6 v14] gpio: Add block gpio to several gpio drivers

2013-01-24 Thread Roland Stigge
On 01/24/2013 01:02 PM, Stijn Devriendt wrote:
>> +static void lpc32xx_gpio_set_block_p3(struct gpio_chip *chip,
>> + unsigned long mask,
>> + unsigned long values)
>> +{
>> +   struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
>> +   u32 set_bits = values & mask;
>> +   u32 clr_bits = ~values & mask;
>> +
>> +   /* States of GPIO 0-5 start at bit 25 */
>> +   set_bits <<= 25;
>> +   clr_bits <<= 25;
>> +
>> +   /* Note: On LPC32xx, GPOs can only be set at once or cleared at once,
>> +*   but not set and cleared at once
>> +*/
>> +   if (set_bits)
>> +   __raw_writel(set_bits, group->gpio_grp->outp_set);
>> +   if (clr_bits)
>> +   __raw_writel(clr_bits, group->gpio_grp->outp_clr);
>> +}
>> +
> 
> In my patch, I go out of the way of this kind of thing for a simple reason:
> You may generate incorrect timing by doing this.

You are right, certain things like synchronous on+off is not really
possible.

However, the above at least supports switching on simulaneously, and
switching off simultaneously, which is an improvement in certain cases
(and this certain hardware part doesn't support more). Maybe this
certain driver behaviour can be documented even better than just in the
driver source.

If there is consensus that everything else in the patch set is settled,
and we just don't want to support behaviour like the above - well, we
can still drop it.

Thanks for the note,

Roland

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


Re: [PATCH 6/6 v14] gpio: Add block gpio to several gpio drivers

2013-01-24 Thread Roland Stigge
On 01/24/2013 01:02 PM, Stijn Devriendt wrote:
 +static void lpc32xx_gpio_set_block_p3(struct gpio_chip *chip,
 + unsigned long mask,
 + unsigned long values)
 +{
 +   struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 +   u32 set_bits = values  mask;
 +   u32 clr_bits = ~values  mask;
 +
 +   /* States of GPIO 0-5 start at bit 25 */
 +   set_bits = 25;
 +   clr_bits = 25;
 +
 +   /* Note: On LPC32xx, GPOs can only be set at once or cleared at once,
 +*   but not set and cleared at once
 +*/
 +   if (set_bits)
 +   __raw_writel(set_bits, group-gpio_grp-outp_set);
 +   if (clr_bits)
 +   __raw_writel(clr_bits, group-gpio_grp-outp_clr);
 +}
 +
 
 In my patch, I go out of the way of this kind of thing for a simple reason:
 You may generate incorrect timing by doing this.

You are right, certain things like synchronous on+off is not really
possible.

However, the above at least supports switching on simulaneously, and
switching off simultaneously, which is an improvement in certain cases
(and this certain hardware part doesn't support more). Maybe this
certain driver behaviour can be documented even better than just in the
driver source.

If there is consensus that everything else in the patch set is settled,
and we just don't want to support behaviour like the above - well, we
can still drop it.

Thanks for the note,

Roland

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


Re: [PATCH 3/6 v14] gpio: Add userland device interface to block GPIO

2013-01-23 Thread Roland Stigge
On 23/01/13 02:03, Jonathan Corbet wrote:
> On Tue, 22 Jan 2013 13:06:41 +0100
> Roland Stigge  wrote:
> 
>> This patch adds a character device interface to the block GPIO system.
> 
> So I was looking at this, and a couple of things caught my eye...

Good points you mentioned. Will address them on a subsequent update.

Thanks,

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


Re: [PATCH 3/6 v14] gpio: Add userland device interface to block GPIO

2013-01-23 Thread Roland Stigge
On 23/01/13 02:03, Jonathan Corbet wrote:
 On Tue, 22 Jan 2013 13:06:41 +0100
 Roland Stigge sti...@antcom.de wrote:
 
 This patch adds a character device interface to the block GPIO system.
 
 So I was looking at this, and a couple of things caught my eye...

Good points you mentioned. Will address them on a subsequent update.

Thanks,

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


[PATCH 2/6 v14] gpio: Add sysfs support to block GPIO API

2013-01-22 Thread Roland Stigge
This patch adds sysfs support to the block GPIO API.

Signed-off-by: Roland Stigge 

---
 Documentation/ABI/testing/sysfs-gpio |   20 ++
 drivers/gpio/gpiolib.c   |  252 ++-
 include/asm-generic/gpio.h   |   11 +
 include/linux/gpio.h |   15 ++
 4 files changed, 297 insertions(+), 1 deletion(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -25,3 +25,23 @@ Description:
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
 
+What:  /sys/class/gpioblock/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:
+
+  Block GPIO devices are visible in sysfs as soon as they are registered
+  (e.g. via devicetree definition). For actual I/O use, their "exported"
+  boolean attribute must be set to "1". Then, the attribute "values" is
+  created and at the same time, the GPIOs in the block are requested for
+  exclusive use by sysfs.
+
+/sys/class/gpioblock
+   /BLOCKNAME ... for each GPIO block name
+   /ngpio ... (r/o) number of GPIOs in this group
+   /exported ... sysfs export state of this group (0, 1)
+   /value ... current value as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
+   /mask ... current mask as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -224,7 +224,8 @@ static bool gpio_block_is_output(struct
int i;
 
for (i = 0; i < block->ngpio; i++)
-   if (!test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
+   if ((block->cur_mask & BIT(i)) &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
return false;
return true;
 }
@@ -1020,6 +1021,240 @@ static void gpiochip_unexport(struct gpi
chip->label, status);
 }
 
+static ssize_t gpio_block_ngpio_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, "%u\n", block->ngpio);
+}
+
+static ssize_t gpio_block_value_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? "0x%08lx\n" :
+  "0x%016lx\n", gpio_block_get(block, block->cur_mask));
+}
+
+static ssize_t gpio_block_value_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   value;
+
+   status = kstrtoul(buf, 0, );
+   if (status == 0) {
+   mutex_lock(_lock);
+   if (gpio_block_is_output(block)) {
+   gpio_block_set(block, block->cur_mask, value);
+   status = size;
+   } else {
+   status = -EPERM;
+   }
+   mutex_unlock(_lock);
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_value = __ATTR(value, S_IWUSR | S_IRUGO, gpio_block_value_show,
+ gpio_block_value_store);
+
+static ssize_t gpio_block_mask_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? "0x%08lx\n" :
+  "0x%016lx\n", block->cur_mask);
+}
+
+static ssize_t gpio_block_mask_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   mask;
+
+   status = kstrtoul(buf, 0, );
+   if (status == 0) {
+   block->cur_mask = mask;
+   status = size;
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_mask = __ATTR(mask, S_IWUSR | S_IRUGO, gpio_block_mask_show,
+gpio_block_mask_store);
+
+static struct class gpio_block_class;
+
+static int gpio_block_value_is_exported(struct gpio_block *block)
+{
+   struct device   *dev;
+   struct sysf

[PATCH 4/6 v14] gpiolib: Fix default attributes for class

2013-01-22 Thread Roland Stigge
There is a race condition between creating a gpio or gpiochip device and adding
default attributes. This patch fixes this by defining the default attributes as
dev_attrs of the class. For this, it was necessary to create a separate
gpiochip_class besides gpio_class.

Signed-off-by: Roland Stigge 
---
 Documentation/ABI/testing/sysfs-gpio |   11 
 drivers/gpio/gpiolib.c   |   78 ++-
 2 files changed, 44 insertions(+), 45 deletions(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -20,6 +20,17 @@ Description:
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
+
+What:  /sys/class/gpiochip/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:
+
+  Each gpiochip is represented by a separate device having the following
+  attributes:
+
+/sys/class/gpiochip
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -362,9 +362,6 @@ static ssize_t gpio_value_store(struct d
return status;
 }
 
-static const DEVICE_ATTR(value, 0644,
-   gpio_value_show, gpio_value_store);
-
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
struct sysfs_dirent *value_sd = priv;
@@ -585,19 +582,6 @@ static ssize_t gpio_active_low_store(str
return status ? : size;
 }
 
-static const DEVICE_ATTR(active_low, 0644,
-   gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
-   _attr_value.attr,
-   _attr_active_low.attr,
-   NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
-   .attrs = (struct attribute **) gpio_attrs,
-};
-
 /*
  * /sys/class/gpio/gpiochipN/
  *   /base ... matching gpio_chip.base (N)
@@ -612,7 +596,6 @@ static ssize_t chip_base_show(struct dev
 
return sprintf(buf, "%d\n", chip->base);
 }
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
 
 static ssize_t chip_label_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -621,7 +604,6 @@ static ssize_t chip_label_show(struct de
 
return sprintf(buf, "%s\n", chip->label ? : "");
 }
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
 
 static ssize_t chip_ngpio_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -630,18 +612,6 @@ static ssize_t chip_ngpio_show(struct de
 
return sprintf(buf, "%u\n", chip->ngpio);
 }
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
-   _attr_base.attr,
-   _attr_label.attr,
-   _attr_ngpio.attr,
-   NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
-   .attrs = (struct attribute **) gpiochip_attrs,
-};
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -720,11 +690,32 @@ static struct class_attribute gpio_class
__ATTR_NULL,
 };
 
+static struct device_attribute gpio_attrs[] = {
+   __ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store),
+   __ATTR(value, 0644, gpio_value_show, gpio_value_store),
+   __ATTR_NULL,
+};
+
 static struct class gpio_class = {
.name = "gpio",
.owner =THIS_MODULE,
 
-   .class_attrs =  gpio_class_attrs,
+   .class_attrs = gpio_class_attrs,
+   .dev_attrs = gpio_attrs,
+};
+
+static struct device_attribute gpiochip_attrs[] = {
+   __ATTR(label, 0444, chip_label_show, NULL),
+   __ATTR(base, 0444, chip_base_show, NULL),
+   __ATTR(ngpio, 0444, chip_ngpio_show, NULL),
+   __ATTR_NULL,
+};
+
+static struct class gpiochip_class = {
+   .name = "gpiochip",
+   .owner =THIS_MODULE,
+
+   .dev_attrs =gpiochip_attrs,
 };
 
 
@@ -791,10 +782,6 @@ int gpio_export(unsigned gpio, bool dire
goto fail_unlock;
}
 
-   status = sysfs_create_group(>kobj, _attr_group);
-   if (status)
-   goto fail_unregister_device;
-
if (direction_may_change) {
status = device_create_file(dev, _attr_direction);
if (status)
@@ -962,25 +949,22 @@ EXPORT_SYMBOL_GPL(gpio_unexport);
 
 static int gpiochip_export(struct gpio_chip *chip)
 {
-   int status;
+   int status = 0;
struct device   *dev;
 
/* Many systems register gpio chips for SOC support very early,
 * before driver model support is available.  In those cases we
 * export this later, in g

[PATCH 0/6 v14] gpio: Add block GPIO

2013-01-22 Thread Roland Stigge
This set of patches adds:

* Block GPIO API to gpiolib
* Sysfs support for GPIO API, to provide userland access
* Device interface for userland access (alternative to sysfs)
* Devicetree support to instantiate GPIO blocks via DT
* Example implementations in several gpio drivers since they need
  special accessor functions for block wise GPIO access (only for some
  selected drivers since the feature is optional and not suitable for
  all GPIO hardware)
* Fix for race condition in gpiolib on device creation

Signed-off-by: Roland Stigge 
Tested by: Wolfgang Grandegger 
--

Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

Applies to v3.8-rc4

Changes since v13:
* Adjusted __raw_readl to readl_relaxed, __raw_writel to writel_relaxed
  (forward porting of pinctrl-at91.c)
* Adjusted to mainline change: Removed __devinit and __devinitdata

Changes since v12:
* Added support for gpio drivers ge, ks8695, mc33880, ml-ioh, mpc5200 and
  mpc8xxx
* Added support for pinctrl driver at91

Changes since v11:
* Removed support for at91, since this one is currently in the migration
  process to pinctrl implementation
* Fixed mask setting via sysfs
* Device interface: declare gpio_block_fop_poll() static

Changes since v10:
* gpioblock-of.c: Catch <1 specified GPIOs
* gpioblock-of.c: Fixed memory leak in probe()'s error path
* gpioblock-of.c: Fixed block node's refcount via of_node_put()
* Added driver support for samsung, mm-lantiq and sa1100
* Added driver support for at91 (by Wolfgang Grandegger)
* Added pinctrl driver support for pinctl-nomadik

Changed since v9:
* Changed IRQ flags for device interface's poll() from IRQF_TRIGGER_FALLING
  to IRQF_SHARED
* Use block name on gpio_request
* Added spinlock for ISR manipulated data (dev interface / poll())

Changed since v8:
* Added poll() function to dev interface for IRQ handling
* Fixed gpio_block_register() in case of missing CONFIG_GPIO_SYSFS
* Fixed mask handling in sysfs interface
* Fixed get_user/put_user pointer (cast)

Changes since v7:
* Fixed error in API documentation (name arg missing in prototype)
* Fixed compile error if sysfs is missing: Moved gpio_block_is_output()
  out of sysfs-ifdef
* Added error handling to gpio_block_register()
* Added mask attribute to sysfs (although dev interface exists now)

Changes since v6:
* Changed realloc to list handling
* Added mask to kernel API
* Added device interface as userspace API
* Changed sizeof() to BITS_PER_LONG
* Fixed multiline comment style
* Documented direction setting by the user
* Documented order of handled chips in case of multiple chips in one block

Changes since v5:
* Documented sysfs: elaborated on "exported" and "values" attributes
* Documented sysfs: gpiochip is a separate class now
* Aggregated driver support patches for block gpio into one single patch
* Added gpio block driver support for twl6040 and pch

Changes since v4:
* Documented word width
* Bugfix: export/unexport on register/unregister
* Using default dev_attrs for gpio_block_class
* Fix gpiolib: race condition on device creation
* Added driver support for ucb14500, vt8500, xilinx

Changes since v3:
* Added driver support for pca953x, em, pl061, max732x, pcf857x
* Coding style improvements
* Fixed krealloc memory leak in error case
* sysfs: values in hex
* Register blocks in a list
* Narrowing lock scope
* Use S_IWUSR and S_IRUGO instead of direct octal values
* Use for_each_set_bit()
* Change from unsigned to unsigned long for masks and values

Changes since v2:
* Added sysfs support
* Added devicetree support
* Added support for lpc32xx, generic
* Added functions for GPIO block registration
* Added more error checking
* Bit remapping bugfix

Changes since v1:
* API change to 32/64 bit word, bit masks

Thanks to Ryan Mallon, Linus Walleij, Stijn Devriendt, Jean-Christophe
Plagniol-Villard, Mark Brown, Greg Kroah-Hartman, Grant Likely, Stefan
Roese, Wolfgang Grandegger, Tobias Rutz, Fengguang Wu, Mark Rutland and
Nicolas Ferre for reviewing and testing!

Roland Stigge (6):
 gpio: Add a block GPIO API to gpiolib
 gpio: Add sysfs support to block GPIO API
 gpio: Add userland device interface to block GPIO
 gpiolib: Fix default attributes for class
 gpio: Add device tree support to block GPIO API
 gpio: Add block gpio to several gpio drivers

 Documentation/ABI/testing/dev-gpioblock   |   34 
 Documentation/ABI/testing/sysfs-gpio  |   31 
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 
 Documentation/gpio.txt|   58 +
 drivers/gpio/Kconfig  |2 
 drivers/gpio/Makefile |1 
 drivers/gpio/gpio-em.c|   23 
 drivers/gpio/gpio-ge.c|   29 
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 
 driv

[PATCH 6/6 v14] gpio: Add block gpio to several gpio drivers

2013-01-22 Thread Roland Stigge
This patch adds block GPIO support to several gpio drivers.

This implements block GPIO only for some selected drivers since block GPIO is
an optional feature which may not be suitable for every GPIO hardware. (With
automatic fallback to the single GPIO functions if not available in a driver.)

Signed-off-by: Roland Stigge 

For pinctrl-at91.c:
Acked-by: Nicolas Ferre  

---
 drivers/gpio/Kconfig  |2 
 drivers/gpio/gpio-em.c|   23 ++
 drivers/gpio/gpio-ge.c|   29 +
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 +++
 drivers/gpio/gpio-lpc32xx.c   |   82 ++
 drivers/gpio/gpio-max730x.c   |   61 
 drivers/gpio/gpio-max732x.c   |   59 +++
 drivers/gpio/gpio-mc33880.c   |   16 +++
 drivers/gpio/gpio-ml-ioh.c|   27 
 drivers/gpio/gpio-mm-lantiq.c |   22 ++
 drivers/gpio/gpio-mpc5200.c   |   64 +
 drivers/gpio/gpio-mpc8xxx.c   |   41 +++
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 +++
 drivers/gpio/gpio-pch.c   |   27 
 drivers/gpio/gpio-pl061.c |   17 +++
 drivers/gpio/gpio-sa1100.c|   20 +
 drivers/gpio/gpio-samsung.c   |   31 ++
 drivers/gpio/gpio-twl6040.c   |   32 ++
 drivers/gpio/gpio-ucb1400.c   |   23 ++
 drivers/gpio/gpio-vt8500.c|   24 +++
 drivers/gpio/gpio-xilinx.c|   44 
 drivers/pinctrl/pinctrl-at91.c|   29 +
 drivers/pinctrl/pinctrl-nomadik.c |   36 
 25 files changed, 887 insertions(+)

--- linux-2.6.orig/drivers/gpio/Kconfig
+++ linux-2.6/drivers/gpio/Kconfig
@@ -144,11 +144,13 @@ config GPIO_MM_LANTIQ
 config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
+   select BITREVERSE
 
 config GPIO_MPC8XXX
bool "MPC512x/MPC8xxx GPIO support"
depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
   FSL_SOC_BOOKE || PPC_86xx
+   select BITREVERSE
help
  Say Y here if you're going to use hardware that connects to the
  MPC512x/831x/834x/837x/8572/8610 GPIOs.
--- linux-2.6.orig/drivers/gpio/gpio-em.c
+++ linux-2.6/drivers/gpio/gpio-em.c
@@ -202,6 +202,27 @@ static void em_gio_set(struct gpio_chip
__em_gio_set(chip, GIO_OH, offset - 16, value);
 }
 
+static unsigned long em_gio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+   return (int)(em_gio_read(gpio_to_priv(chip), GIO_I) & mask);
+}
+
+static void em_gio_set_block(struct gpio_chip *chip, unsigned long mask,
+unsigned long values)
+{
+   unsigned long mask_ol = mask & 0x;
+   unsigned long mask_oh = mask >> 16;
+
+   unsigned long values_ol = values & mask_ol;
+   unsigned long values_oh = (values >> 16) & mask_oh;
+
+   em_gio_write(gpio_to_priv(chip), GIO_OL,
+mask_ol << 16 | values_ol);
+   em_gio_write(gpio_to_priv(chip), GIO_OH,
+mask_oh << 16 | values_oh);
+}
+
 static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
   int value)
 {
@@ -282,8 +303,10 @@ static int em_gio_probe(struct platform_
gpio_chip = >gpio_chip;
gpio_chip->direction_input = em_gio_direction_input;
gpio_chip->get = em_gio_get;
+   gpio_chip->get_block = em_gio_get_block;
gpio_chip->direction_output = em_gio_direction_output;
gpio_chip->set = em_gio_set;
+   gpio_chip->set_block = em_gio_set_block;
gpio_chip->to_irq = em_gio_to_irq;
gpio_chip->label = name;
gpio_chip->owner = THIS_MODULE;
--- linux-2.6.orig/drivers/gpio/gpio-ge.c
+++ linux-2.6/drivers/gpio/gpio-ge.c
@@ -100,6 +100,29 @@ static void gef_gpio_set(struct gpio_chi
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
 }
 
+static unsigned long gef_gpio_get_block(struct gpio_chip *chip,
+   unsigned long mask)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+
+   return ioread32be(mmchip->regs + GEF_GPIO_IN) & mask;
+}
+
+static void gef_gpio_set_block(struct gpio_chip *chip,
+  unsigned long mask, unsigned long values)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+   void __iomem *reg = mmchip->regs + GEF_GPIO_OUT;
+   unsigned int data;
+
+   data = ioread32be(reg);
+
+   data &= ~mask;
+   data |= values & mask;
+
+   

[PATCH 3/6 v14] gpio: Add userland device interface to block GPIO

2013-01-22 Thread Roland Stigge
This patch adds a character device interface to the block GPIO system.

Signed-off-by: Roland Stigge 
---
 Documentation/ABI/testing/dev-gpioblock |   34 
 drivers/gpio/gpiolib.c  |  225 +++-
 include/linux/gpio.h|   13 +
 3 files changed, 271 insertions(+), 1 deletion(-)

--- /dev/null
+++ linux-2.6/Documentation/ABI/testing/dev-gpioblock
@@ -0,0 +1,34 @@
+What:  /dev/
+Date:  Nov 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:   The /dev/ character device node provides userspace
+   access to GPIO blocks, named exactly as the block, e.g.
+   /dev/block0.
+
+   Reading:
+   When reading sizeof(unsigned long) bytes from the device, the
+   current state of the block, masked by the current mask (see
+   below) can be obtained as a word. When the device is opened
+   with O_NONBLOCK, read() always returns with data immediately,
+   otherwise it blocks until data is available, see IRQ handling
+   below.
+
+   Writing:
+   By writing sizeof(unsigned long) bytes to the device, the
+   current state of the block can be set. This operation is
+   masked by the current mask (see below).
+
+   IRQ handling:
+   When one or more IRQs in the block are IRQ capable, you can
+   poll() on the device to check/wait for this IRQ. If no IRQ
+   is available, poll() returns -ENOSYS and userspace needs to
+   (busy) poll itself if necessary.
+
+   Setting the mask (default: all bits set):
+   By doing an ioctl(fd, 0, ) with an unsigned long mask, the
+   current mask for read and write operations on this gpio block
+   can be set.
+
+   See also Documentation/gpio.txt for an explanation of block
+   GPIO.
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -11,6 +11,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define CREATE_TRACE_POINTS
 #include 
@@ -2243,6 +2245,207 @@ struct gpio_block *gpio_block_find_by_na
 }
 EXPORT_SYMBOL_GPL(gpio_block_find_by_name);
 
+static struct gpio_block *gpio_block_find_by_minor(int minor)
+{
+   struct gpio_block *i;
+
+   list_for_each_entry(i, _block_list, list)
+   if (i->miscdev.minor == minor)
+   return i;
+   return NULL;
+}
+
+static bool gpio_block_is_irq_duplicate(struct gpio_block *block, int index)
+{
+   int irq = gpio_to_irq(block->gpio[index]);
+   int i;
+
+   for (i = 0; i < index; i++)
+   if (gpio_to_irq(block->gpio[i]) == irq)
+   return true;
+   return false;
+}
+
+static irqreturn_t gpio_block_irq_handler(int irq, void *dev)
+{
+   struct gpio_block *block = dev;
+
+   wake_up_interruptible(>wait_queue);
+   block->got_int = true;
+
+   return IRQ_HANDLED;
+}
+
+static int gpio_block_fop_open(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = gpio_block_find_by_minor(MINOR(in->i_rdev));
+   int status;
+   int irq;
+
+   if (!block)
+   return -ENOENT;
+
+   block->irq_controlled = false;
+   block->got_int = false;
+   spin_lock_init(>lock);
+   init_waitqueue_head(>wait_queue);
+   f->private_data = block;
+
+   for (i = 0; i < block->ngpio; i++) {
+   status = gpio_request(block->gpio[i], block->name);
+   if (status)
+   goto err1;
+
+   irq = gpio_to_irq(block->gpio[i]);
+   if (irq >= 0 &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags) &&
+   !gpio_block_is_irq_duplicate(block, i)) {
+   status = request_irq(irq, gpio_block_irq_handler,
+IRQF_SHARED,
+block->name, block);
+   if (status)
+   goto err2;
+
+   block->irq_controlled = true;
+   }
+   }
+
+   return 0;
+
+err1:
+   while (i > 0) {
+   i--;
+
+   irq = gpio_to_irq(block->gpio[i]);
+   if (irq >= 0 &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags) &&
+   !gpio_block_is_irq_duplicate(block, i))
+   free_irq(irq, block);
+err2:
+   gpio_free(block->gpio[i]);
+   }
+   return status;
+}
+
+static int gpio_block_fop_release(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = (struct gpio_block *)f->

[PATCH 1/6 v14] gpio: Add a block GPIO API to gpiolib

2013-01-22 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal "Block GPIO" API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge 
---

 Documentation/gpio.txt |   58 +++
 drivers/gpio/gpiolib.c |  227 +
 include/asm-generic/gpio.h |   17 +++
 include/linux/gpio.h   |   97 +++
 4 files changed, 399 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -481,6 +481,64 @@ exact name string of pinctrl device has
 argument to this routine.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
+const char *name);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). Similarly, the direction of the used GPIOs need
+to be set by the user before using the block. An arbitrary list of globally
+valid GPIOs can be specified, even ranging over several gpio_chips. Actual
+handling of I/O operations will be done on a best effort base, i.e.
+simultaneous I/O only where possible by hardware and implemented in the
+respective GPIO driver. The number of GPIOs in one block is limited to the
+number of bits in an unsigned long, or BITS_PER_LONG, of the respective
+platform, i.e. typically at least 32 on a 32 bit system, and at least 64 on a
+64 bit system. However, several blocks can be defined at once.
+
+unsigned long gpio_block_get(struct gpio_block *block, unsigned long mask);
+void gpio_block_set(struct gpio_block *block, unsigned long mask,
+   unsigned long values);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). The mask parameters
+specify which bits in the block are acted upon. This is useful to let some bits
+untouched when doing a set operation on the block.
+
+Block operations in hardware are only possible where the respective GPIO driver
+implements it, falling back to using single GPIO operations where the driver
+only implements single GPIO access.
+
+If a GPIO block includes GPIOs from several chips, the chips are handled one
+after another in the order of first specification in the list of GPIOs defined
+in the GPIO block, starting with bit 0. Note that in this case, you typically
+can't assume simultaneous access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via userspace API.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -217,6 +219,16 @@ static int gpio_get_direction(unsigned g
return status;
 }
 
+static bool gpio_block_is_output(struct gpio_block *block)
+{
+   int i;
+
+   for (i = 0; i < block->ngpio; i++)
+   if (!test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
+   return false;
+   return true;
+}
+
 #ifdef CONFIG_GPIO_SYSFS
 
 /* lock protects against unexport_gpio() being called while
@@ -1799,6 +1811,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static struct gpio_block_chip *

[PATCH 5/6 v14] gpio: Add device tree support to block GPIO API

2013-01-22 Thread Roland Stigge
This patch adds device tree support to the block GPIO API.

Signed-off-by: Roland Stigge 

---
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 ++
 drivers/gpio/Makefile |1 
 drivers/gpio/gpioblock-of.c   |  100 ++
 3 files changed, 137 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be "linux,gpio-block"
+
+Required subnodes:
+- the name will be the registered name of the block
+- property "gpios" is a list of gpios for the respective block
+
+Example:
+
+blockgpio {
+compatible = "linux,gpio-block";
+
+block0 {
+gpios = < 3 0 0>,
+< 3 1 0>;
+};
+block1 {
+gpios = < 4 1 0>,
+< 4 3 0>,
+< 4 2 0>,
+< 4 4 0>,
+< 4 5 0>,
+< 4 6 0>,
+< 4 7 0>,
+< 4 8 0>,
+< 4 9 0>,
+< 4 10 0>,
+< 4 19 0>;
+};
+};
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)+= -DDEBUG
 obj-$(CONFIG_GPIOLIB)  += gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)  += gpiolib-of.o
 obj-$(CONFIG_GPIO_ACPI)+= gpiolib-acpi.o
+obj-$(CONFIG_OF_GPIO)  += gpioblock-of.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,100 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int gpioblock_of_probe(struct platform_device *pdev)
+{
+   struct device_node *block;
+   unsigned *gpios;
+   int ngpio;
+   int ret;
+   struct gpio_block *gb;
+
+   for_each_available_child_of_node(pdev->dev.of_node, block) {
+   int i;
+
+   ngpio = of_gpio_count(block);
+   if (ngpio < 1) {
+   ret = -ENODEV;
+   goto err1;
+   }
+
+   gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+   if (!gpios) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   for (i = 0; i < ngpio; i++) {
+   ret = of_get_gpio(block, i);
+   if (ret < 0)
+   goto err2; /* expect -EPROBE_DEFER */
+   gpios[i] = ret;
+   }
+   gb = gpio_block_create(gpios, ngpio, block->name);
+   if (IS_ERR(gb)) {
+   dev_err(>dev,
+   "Error creating GPIO block from device tree\n");
+   ret = PTR_ERR(gb);
+   goto err2;
+   }
+   ret = gpio_block_register(gb);
+   if (ret < 0)
+   goto err3;
+
+   kfree(gpios);
+   dev_info(>dev, "Registered gpio block %s: %d gpios\n",
+block->name, ngpio);
+   }
+   return 0;
+
+err3:
+   gpio_block_free(gb);
+err2:
+   kfree(gpios);
+err1:
+   of_node_put(block);
+   return ret;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] = {
+   { .compatible = "linux,gpio-block", },
+   { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+   .driver = {
+   .name = "gpio-block",
+   .owner = THIS_MODULE,
+   .of_match_table = of_match_ptr(gpioblock_of_match),
+
+   },
+   .probe  = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION("GPIO Block driver");
+MODULE_AUTHOR("R

[PATCH 1/6 v14] gpio: Add a block GPIO API to gpiolib

2013-01-22 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal Block GPIO API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge sti...@antcom.de
---

 Documentation/gpio.txt |   58 +++
 drivers/gpio/gpiolib.c |  227 +
 include/asm-generic/gpio.h |   17 +++
 include/linux/gpio.h   |   97 +++
 4 files changed, 399 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -481,6 +481,64 @@ exact name string of pinctrl device has
 argument to this routine.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
+const char *name);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). Similarly, the direction of the used GPIOs need
+to be set by the user before using the block. An arbitrary list of globally
+valid GPIOs can be specified, even ranging over several gpio_chips. Actual
+handling of I/O operations will be done on a best effort base, i.e.
+simultaneous I/O only where possible by hardware and implemented in the
+respective GPIO driver. The number of GPIOs in one block is limited to the
+number of bits in an unsigned long, or BITS_PER_LONG, of the respective
+platform, i.e. typically at least 32 on a 32 bit system, and at least 64 on a
+64 bit system. However, several blocks can be defined at once.
+
+unsigned long gpio_block_get(struct gpio_block *block, unsigned long mask);
+void gpio_block_set(struct gpio_block *block, unsigned long mask,
+   unsigned long values);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). The mask parameters
+specify which bits in the block are acted upon. This is useful to let some bits
+untouched when doing a set operation on the block.
+
+Block operations in hardware are only possible where the respective GPIO driver
+implements it, falling back to using single GPIO operations where the driver
+only implements single GPIO access.
+
+If a GPIO block includes GPIOs from several chips, the chips are handled one
+after another in the order of first specification in the list of GPIOs defined
+in the GPIO block, starting with bit 0. Note that in this case, you typically
+can't assume simultaneous access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via userspace API.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -217,6 +219,16 @@ static int gpio_get_direction(unsigned g
return status;
 }
 
+static bool gpio_block_is_output(struct gpio_block *block)
+{
+   int i;
+
+   for (i = 0; i  block-ngpio; i++)
+   if (!test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
+   return false;
+   return true;
+}
+
 #ifdef CONFIG_GPIO_SYSFS
 
 /* lock protects against unexport_gpio() being called while
@@ -1799,6 +1811,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static struct gpio_block_chip

[PATCH 6/6 v14] gpio: Add block gpio to several gpio drivers

2013-01-22 Thread Roland Stigge
This patch adds block GPIO support to several gpio drivers.

This implements block GPIO only for some selected drivers since block GPIO is
an optional feature which may not be suitable for every GPIO hardware. (With
automatic fallback to the single GPIO functions if not available in a driver.)

Signed-off-by: Roland Stigge sti...@antcom.de

For pinctrl-at91.c:
Acked-by: Nicolas Ferre nicolas.fe...@atmel.com 

---
 drivers/gpio/Kconfig  |2 
 drivers/gpio/gpio-em.c|   23 ++
 drivers/gpio/gpio-ge.c|   29 +
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 +++
 drivers/gpio/gpio-lpc32xx.c   |   82 ++
 drivers/gpio/gpio-max730x.c   |   61 
 drivers/gpio/gpio-max732x.c   |   59 +++
 drivers/gpio/gpio-mc33880.c   |   16 +++
 drivers/gpio/gpio-ml-ioh.c|   27 
 drivers/gpio/gpio-mm-lantiq.c |   22 ++
 drivers/gpio/gpio-mpc5200.c   |   64 +
 drivers/gpio/gpio-mpc8xxx.c   |   41 +++
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 +++
 drivers/gpio/gpio-pch.c   |   27 
 drivers/gpio/gpio-pl061.c |   17 +++
 drivers/gpio/gpio-sa1100.c|   20 +
 drivers/gpio/gpio-samsung.c   |   31 ++
 drivers/gpio/gpio-twl6040.c   |   32 ++
 drivers/gpio/gpio-ucb1400.c   |   23 ++
 drivers/gpio/gpio-vt8500.c|   24 +++
 drivers/gpio/gpio-xilinx.c|   44 
 drivers/pinctrl/pinctrl-at91.c|   29 +
 drivers/pinctrl/pinctrl-nomadik.c |   36 
 25 files changed, 887 insertions(+)

--- linux-2.6.orig/drivers/gpio/Kconfig
+++ linux-2.6/drivers/gpio/Kconfig
@@ -144,11 +144,13 @@ config GPIO_MM_LANTIQ
 config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
+   select BITREVERSE
 
 config GPIO_MPC8XXX
bool MPC512x/MPC8xxx GPIO support
depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
   FSL_SOC_BOOKE || PPC_86xx
+   select BITREVERSE
help
  Say Y here if you're going to use hardware that connects to the
  MPC512x/831x/834x/837x/8572/8610 GPIOs.
--- linux-2.6.orig/drivers/gpio/gpio-em.c
+++ linux-2.6/drivers/gpio/gpio-em.c
@@ -202,6 +202,27 @@ static void em_gio_set(struct gpio_chip
__em_gio_set(chip, GIO_OH, offset - 16, value);
 }
 
+static unsigned long em_gio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+   return (int)(em_gio_read(gpio_to_priv(chip), GIO_I)  mask);
+}
+
+static void em_gio_set_block(struct gpio_chip *chip, unsigned long mask,
+unsigned long values)
+{
+   unsigned long mask_ol = mask  0x;
+   unsigned long mask_oh = mask  16;
+
+   unsigned long values_ol = values  mask_ol;
+   unsigned long values_oh = (values  16)  mask_oh;
+
+   em_gio_write(gpio_to_priv(chip), GIO_OL,
+mask_ol  16 | values_ol);
+   em_gio_write(gpio_to_priv(chip), GIO_OH,
+mask_oh  16 | values_oh);
+}
+
 static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
   int value)
 {
@@ -282,8 +303,10 @@ static int em_gio_probe(struct platform_
gpio_chip = p-gpio_chip;
gpio_chip-direction_input = em_gio_direction_input;
gpio_chip-get = em_gio_get;
+   gpio_chip-get_block = em_gio_get_block;
gpio_chip-direction_output = em_gio_direction_output;
gpio_chip-set = em_gio_set;
+   gpio_chip-set_block = em_gio_set_block;
gpio_chip-to_irq = em_gio_to_irq;
gpio_chip-label = name;
gpio_chip-owner = THIS_MODULE;
--- linux-2.6.orig/drivers/gpio/gpio-ge.c
+++ linux-2.6/drivers/gpio/gpio-ge.c
@@ -100,6 +100,29 @@ static void gef_gpio_set(struct gpio_chi
_gef_gpio_set(mmchip-regs + GEF_GPIO_OUT, offset, value);
 }
 
+static unsigned long gef_gpio_get_block(struct gpio_chip *chip,
+   unsigned long mask)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+
+   return ioread32be(mmchip-regs + GEF_GPIO_IN)  mask;
+}
+
+static void gef_gpio_set_block(struct gpio_chip *chip,
+  unsigned long mask, unsigned long values)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+   void __iomem *reg = mmchip-regs + GEF_GPIO_OUT;
+   unsigned int data;
+
+   data = ioread32be(reg);
+
+   data = ~mask;
+   data |= values  mask;
+
+   iowrite32be(data, reg);
+}
+
 static int __init gef_gpio_init(void)
 {
struct

[PATCH 3/6 v14] gpio: Add userland device interface to block GPIO

2013-01-22 Thread Roland Stigge
This patch adds a character device interface to the block GPIO system.

Signed-off-by: Roland Stigge sti...@antcom.de
---
 Documentation/ABI/testing/dev-gpioblock |   34 
 drivers/gpio/gpiolib.c  |  225 +++-
 include/linux/gpio.h|   13 +
 3 files changed, 271 insertions(+), 1 deletion(-)

--- /dev/null
+++ linux-2.6/Documentation/ABI/testing/dev-gpioblock
@@ -0,0 +1,34 @@
+What:  /dev/gpioblock
+Date:  Nov 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:   The /dev/gpioblock character device node provides userspace
+   access to GPIO blocks, named exactly as the block, e.g.
+   /dev/block0.
+
+   Reading:
+   When reading sizeof(unsigned long) bytes from the device, the
+   current state of the block, masked by the current mask (see
+   below) can be obtained as a word. When the device is opened
+   with O_NONBLOCK, read() always returns with data immediately,
+   otherwise it blocks until data is available, see IRQ handling
+   below.
+
+   Writing:
+   By writing sizeof(unsigned long) bytes to the device, the
+   current state of the block can be set. This operation is
+   masked by the current mask (see below).
+
+   IRQ handling:
+   When one or more IRQs in the block are IRQ capable, you can
+   poll() on the device to check/wait for this IRQ. If no IRQ
+   is available, poll() returns -ENOSYS and userspace needs to
+   (busy) poll itself if necessary.
+
+   Setting the mask (default: all bits set):
+   By doing an ioctl(fd, 0, mask) with an unsigned long mask, the
+   current mask for read and write operations on this gpio block
+   can be set.
+
+   See also Documentation/gpio.txt for an explanation of block
+   GPIO.
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -11,6 +11,8 @@
 #include linux/of_gpio.h
 #include linux/idr.h
 #include linux/slab.h
+#include linux/uaccess.h
+#include linux/poll.h
 
 #define CREATE_TRACE_POINTS
 #include trace/events/gpio.h
@@ -2243,6 +2245,207 @@ struct gpio_block *gpio_block_find_by_na
 }
 EXPORT_SYMBOL_GPL(gpio_block_find_by_name);
 
+static struct gpio_block *gpio_block_find_by_minor(int minor)
+{
+   struct gpio_block *i;
+
+   list_for_each_entry(i, gpio_block_list, list)
+   if (i-miscdev.minor == minor)
+   return i;
+   return NULL;
+}
+
+static bool gpio_block_is_irq_duplicate(struct gpio_block *block, int index)
+{
+   int irq = gpio_to_irq(block-gpio[index]);
+   int i;
+
+   for (i = 0; i  index; i++)
+   if (gpio_to_irq(block-gpio[i]) == irq)
+   return true;
+   return false;
+}
+
+static irqreturn_t gpio_block_irq_handler(int irq, void *dev)
+{
+   struct gpio_block *block = dev;
+
+   wake_up_interruptible(block-wait_queue);
+   block-got_int = true;
+
+   return IRQ_HANDLED;
+}
+
+static int gpio_block_fop_open(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = gpio_block_find_by_minor(MINOR(in-i_rdev));
+   int status;
+   int irq;
+
+   if (!block)
+   return -ENOENT;
+
+   block-irq_controlled = false;
+   block-got_int = false;
+   spin_lock_init(block-lock);
+   init_waitqueue_head(block-wait_queue);
+   f-private_data = block;
+
+   for (i = 0; i  block-ngpio; i++) {
+   status = gpio_request(block-gpio[i], block-name);
+   if (status)
+   goto err1;
+
+   irq = gpio_to_irq(block-gpio[i]);
+   if (irq = 0 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags) 
+   !gpio_block_is_irq_duplicate(block, i)) {
+   status = request_irq(irq, gpio_block_irq_handler,
+IRQF_SHARED,
+block-name, block);
+   if (status)
+   goto err2;
+
+   block-irq_controlled = true;
+   }
+   }
+
+   return 0;
+
+err1:
+   while (i  0) {
+   i--;
+
+   irq = gpio_to_irq(block-gpio[i]);
+   if (irq = 0 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags) 
+   !gpio_block_is_irq_duplicate(block, i))
+   free_irq(irq, block);
+err2:
+   gpio_free(block-gpio[i]);
+   }
+   return status;
+}
+
+static int gpio_block_fop_release(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = (struct gpio_block *)f

[PATCH 5/6 v14] gpio: Add device tree support to block GPIO API

2013-01-22 Thread Roland Stigge
This patch adds device tree support to the block GPIO API.

Signed-off-by: Roland Stigge sti...@antcom.de

---
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 ++
 drivers/gpio/Makefile |1 
 drivers/gpio/gpioblock-of.c   |  100 ++
 3 files changed, 137 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be linux,gpio-block
+
+Required subnodes:
+- the name will be the registered name of the block
+- property gpios is a list of gpios for the respective block
+
+Example:
+
+blockgpio {
+compatible = linux,gpio-block;
+
+block0 {
+gpios = gpio 3 0 0,
+gpio 3 1 0;
+};
+block1 {
+gpios = gpio 4 1 0,
+gpio 4 3 0,
+gpio 4 2 0,
+gpio 4 4 0,
+gpio 4 5 0,
+gpio 4 6 0,
+gpio 4 7 0,
+gpio 4 8 0,
+gpio 4 9 0,
+gpio 4 10 0,
+gpio 4 19 0;
+};
+};
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)+= -DDEBUG
 obj-$(CONFIG_GPIOLIB)  += gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)  += gpiolib-of.o
 obj-$(CONFIG_GPIO_ACPI)+= gpiolib-acpi.o
+obj-$(CONFIG_OF_GPIO)  += gpioblock-of.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,100 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge sti...@antcom.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/platform_device.h
+#include linux/gpio.h
+#include linux/of.h
+#include linux/of_gpio.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/err.h
+
+static int gpioblock_of_probe(struct platform_device *pdev)
+{
+   struct device_node *block;
+   unsigned *gpios;
+   int ngpio;
+   int ret;
+   struct gpio_block *gb;
+
+   for_each_available_child_of_node(pdev-dev.of_node, block) {
+   int i;
+
+   ngpio = of_gpio_count(block);
+   if (ngpio  1) {
+   ret = -ENODEV;
+   goto err1;
+   }
+
+   gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+   if (!gpios) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   for (i = 0; i  ngpio; i++) {
+   ret = of_get_gpio(block, i);
+   if (ret  0)
+   goto err2; /* expect -EPROBE_DEFER */
+   gpios[i] = ret;
+   }
+   gb = gpio_block_create(gpios, ngpio, block-name);
+   if (IS_ERR(gb)) {
+   dev_err(pdev-dev,
+   Error creating GPIO block from device tree\n);
+   ret = PTR_ERR(gb);
+   goto err2;
+   }
+   ret = gpio_block_register(gb);
+   if (ret  0)
+   goto err3;
+
+   kfree(gpios);
+   dev_info(pdev-dev, Registered gpio block %s: %d gpios\n,
+block-name, ngpio);
+   }
+   return 0;
+
+err3:
+   gpio_block_free(gb);
+err2:
+   kfree(gpios);
+err1:
+   of_node_put(block);
+   return ret;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] = {
+   { .compatible = linux,gpio-block, },
+   { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+   .driver = {
+   .name = gpio-block,
+   .owner = THIS_MODULE,
+   .of_match_table = of_match_ptr(gpioblock_of_match),
+
+   },
+   .probe  = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION(GPIO Block driver);
+MODULE_AUTHOR(Roland Stigge sti...@antcom.de

[PATCH 0/6 v14] gpio: Add block GPIO

2013-01-22 Thread Roland Stigge
This set of patches adds:

* Block GPIO API to gpiolib
* Sysfs support for GPIO API, to provide userland access
* Device interface for userland access (alternative to sysfs)
* Devicetree support to instantiate GPIO blocks via DT
* Example implementations in several gpio drivers since they need
  special accessor functions for block wise GPIO access (only for some
  selected drivers since the feature is optional and not suitable for
  all GPIO hardware)
* Fix for race condition in gpiolib on device creation

Signed-off-by: Roland Stigge sti...@antcom.de
Tested by: Wolfgang Grandegger w...@grandegger.com
--

Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

Applies to v3.8-rc4

Changes since v13:
* Adjusted __raw_readl to readl_relaxed, __raw_writel to writel_relaxed
  (forward porting of pinctrl-at91.c)
* Adjusted to mainline change: Removed __devinit and __devinitdata

Changes since v12:
* Added support for gpio drivers ge, ks8695, mc33880, ml-ioh, mpc5200 and
  mpc8xxx
* Added support for pinctrl driver at91

Changes since v11:
* Removed support for at91, since this one is currently in the migration
  process to pinctrl implementation
* Fixed mask setting via sysfs
* Device interface: declare gpio_block_fop_poll() static

Changes since v10:
* gpioblock-of.c: Catch 1 specified GPIOs
* gpioblock-of.c: Fixed memory leak in probe()'s error path
* gpioblock-of.c: Fixed block node's refcount via of_node_put()
* Added driver support for samsung, mm-lantiq and sa1100
* Added driver support for at91 (by Wolfgang Grandegger)
* Added pinctrl driver support for pinctl-nomadik

Changed since v9:
* Changed IRQ flags for device interface's poll() from IRQF_TRIGGER_FALLING
  to IRQF_SHARED
* Use block name on gpio_request
* Added spinlock for ISR manipulated data (dev interface / poll())

Changed since v8:
* Added poll() function to dev interface for IRQ handling
* Fixed gpio_block_register() in case of missing CONFIG_GPIO_SYSFS
* Fixed mask handling in sysfs interface
* Fixed get_user/put_user pointer (cast)

Changes since v7:
* Fixed error in API documentation (name arg missing in prototype)
* Fixed compile error if sysfs is missing: Moved gpio_block_is_output()
  out of sysfs-ifdef
* Added error handling to gpio_block_register()
* Added mask attribute to sysfs (although dev interface exists now)

Changes since v6:
* Changed realloc to list handling
* Added mask to kernel API
* Added device interface as userspace API
* Changed sizeof() to BITS_PER_LONG
* Fixed multiline comment style
* Documented direction setting by the user
* Documented order of handled chips in case of multiple chips in one block

Changes since v5:
* Documented sysfs: elaborated on exported and values attributes
* Documented sysfs: gpiochip is a separate class now
* Aggregated driver support patches for block gpio into one single patch
* Added gpio block driver support for twl6040 and pch

Changes since v4:
* Documented word width
* Bugfix: export/unexport on register/unregister
* Using default dev_attrs for gpio_block_class
* Fix gpiolib: race condition on device creation
* Added driver support for ucb14500, vt8500, xilinx

Changes since v3:
* Added driver support for pca953x, em, pl061, max732x, pcf857x
* Coding style improvements
* Fixed krealloc memory leak in error case
* sysfs: values in hex
* Register blocks in a list
* Narrowing lock scope
* Use S_IWUSR and S_IRUGO instead of direct octal values
* Use for_each_set_bit()
* Change from unsigned to unsigned long for masks and values

Changes since v2:
* Added sysfs support
* Added devicetree support
* Added support for lpc32xx, generic
* Added functions for GPIO block registration
* Added more error checking
* Bit remapping bugfix

Changes since v1:
* API change to 32/64 bit word, bit masks

Thanks to Ryan Mallon, Linus Walleij, Stijn Devriendt, Jean-Christophe
Plagniol-Villard, Mark Brown, Greg Kroah-Hartman, Grant Likely, Stefan
Roese, Wolfgang Grandegger, Tobias Rutz, Fengguang Wu, Mark Rutland and
Nicolas Ferre for reviewing and testing!

Roland Stigge (6):
 gpio: Add a block GPIO API to gpiolib
 gpio: Add sysfs support to block GPIO API
 gpio: Add userland device interface to block GPIO
 gpiolib: Fix default attributes for class
 gpio: Add device tree support to block GPIO API
 gpio: Add block gpio to several gpio drivers

 Documentation/ABI/testing/dev-gpioblock   |   34 
 Documentation/ABI/testing/sysfs-gpio  |   31 
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 
 Documentation/gpio.txt|   58 +
 drivers/gpio/Kconfig  |2 
 drivers/gpio/Makefile |1 
 drivers/gpio/gpio-em.c|   23 
 drivers/gpio/gpio-ge.c|   29 
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 
 drivers/gpio/gpio

[PATCH 2/6 v14] gpio: Add sysfs support to block GPIO API

2013-01-22 Thread Roland Stigge
This patch adds sysfs support to the block GPIO API.

Signed-off-by: Roland Stigge sti...@antcom.de

---
 Documentation/ABI/testing/sysfs-gpio |   20 ++
 drivers/gpio/gpiolib.c   |  252 ++-
 include/asm-generic/gpio.h   |   11 +
 include/linux/gpio.h |   15 ++
 4 files changed, 297 insertions(+), 1 deletion(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -25,3 +25,23 @@ Description:
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
 
+What:  /sys/class/gpioblock/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:
+
+  Block GPIO devices are visible in sysfs as soon as they are registered
+  (e.g. via devicetree definition). For actual I/O use, their exported
+  boolean attribute must be set to 1. Then, the attribute values is
+  created and at the same time, the GPIOs in the block are requested for
+  exclusive use by sysfs.
+
+/sys/class/gpioblock
+   /BLOCKNAME ... for each GPIO block name
+   /ngpio ... (r/o) number of GPIOs in this group
+   /exported ... sysfs export state of this group (0, 1)
+   /value ... current value as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
+   /mask ... current mask as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -224,7 +224,8 @@ static bool gpio_block_is_output(struct
int i;
 
for (i = 0; i  block-ngpio; i++)
-   if (!test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
+   if ((block-cur_mask  BIT(i)) 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
return false;
return true;
 }
@@ -1020,6 +1021,240 @@ static void gpiochip_unexport(struct gpi
chip-label, status);
 }
 
+static ssize_t gpio_block_ngpio_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, %u\n, block-ngpio);
+}
+
+static ssize_t gpio_block_value_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? 0x%08lx\n :
+  0x%016lx\n, gpio_block_get(block, block-cur_mask));
+}
+
+static ssize_t gpio_block_value_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   value;
+
+   status = kstrtoul(buf, 0, value);
+   if (status == 0) {
+   mutex_lock(sysfs_lock);
+   if (gpio_block_is_output(block)) {
+   gpio_block_set(block, block-cur_mask, value);
+   status = size;
+   } else {
+   status = -EPERM;
+   }
+   mutex_unlock(sysfs_lock);
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_value = __ATTR(value, S_IWUSR | S_IRUGO, gpio_block_value_show,
+ gpio_block_value_store);
+
+static ssize_t gpio_block_mask_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? 0x%08lx\n :
+  0x%016lx\n, block-cur_mask);
+}
+
+static ssize_t gpio_block_mask_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   mask;
+
+   status = kstrtoul(buf, 0, mask);
+   if (status == 0) {
+   block-cur_mask = mask;
+   status = size;
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_mask = __ATTR(mask, S_IWUSR | S_IRUGO, gpio_block_mask_show,
+gpio_block_mask_store);
+
+static struct class gpio_block_class;
+
+static int gpio_block_value_is_exported(struct gpio_block *block)
+{
+   struct device   *dev;
+   struct sysfs_dirent *sd = NULL;
+
+   mutex_lock(sysfs_lock);
+   dev = class_find_device

[PATCH 4/6 v14] gpiolib: Fix default attributes for class

2013-01-22 Thread Roland Stigge
There is a race condition between creating a gpio or gpiochip device and adding
default attributes. This patch fixes this by defining the default attributes as
dev_attrs of the class. For this, it was necessary to create a separate
gpiochip_class besides gpio_class.

Signed-off-by: Roland Stigge sti...@antcom.de
---
 Documentation/ABI/testing/sysfs-gpio |   11 
 drivers/gpio/gpiolib.c   |   78 ++-
 2 files changed, 44 insertions(+), 45 deletions(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -20,6 +20,17 @@ Description:
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
+
+What:  /sys/class/gpiochip/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:
+
+  Each gpiochip is represented by a separate device having the following
+  attributes:
+
+/sys/class/gpiochip
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -362,9 +362,6 @@ static ssize_t gpio_value_store(struct d
return status;
 }
 
-static const DEVICE_ATTR(value, 0644,
-   gpio_value_show, gpio_value_store);
-
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
struct sysfs_dirent *value_sd = priv;
@@ -585,19 +582,6 @@ static ssize_t gpio_active_low_store(str
return status ? : size;
 }
 
-static const DEVICE_ATTR(active_low, 0644,
-   gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
-   dev_attr_value.attr,
-   dev_attr_active_low.attr,
-   NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
-   .attrs = (struct attribute **) gpio_attrs,
-};
-
 /*
  * /sys/class/gpio/gpiochipN/
  *   /base ... matching gpio_chip.base (N)
@@ -612,7 +596,6 @@ static ssize_t chip_base_show(struct dev
 
return sprintf(buf, %d\n, chip-base);
 }
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
 
 static ssize_t chip_label_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -621,7 +604,6 @@ static ssize_t chip_label_show(struct de
 
return sprintf(buf, %s\n, chip-label ? : );
 }
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
 
 static ssize_t chip_ngpio_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -630,18 +612,6 @@ static ssize_t chip_ngpio_show(struct de
 
return sprintf(buf, %u\n, chip-ngpio);
 }
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
-   dev_attr_base.attr,
-   dev_attr_label.attr,
-   dev_attr_ngpio.attr,
-   NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
-   .attrs = (struct attribute **) gpiochip_attrs,
-};
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -720,11 +690,32 @@ static struct class_attribute gpio_class
__ATTR_NULL,
 };
 
+static struct device_attribute gpio_attrs[] = {
+   __ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store),
+   __ATTR(value, 0644, gpio_value_show, gpio_value_store),
+   __ATTR_NULL,
+};
+
 static struct class gpio_class = {
.name = gpio,
.owner =THIS_MODULE,
 
-   .class_attrs =  gpio_class_attrs,
+   .class_attrs = gpio_class_attrs,
+   .dev_attrs = gpio_attrs,
+};
+
+static struct device_attribute gpiochip_attrs[] = {
+   __ATTR(label, 0444, chip_label_show, NULL),
+   __ATTR(base, 0444, chip_base_show, NULL),
+   __ATTR(ngpio, 0444, chip_ngpio_show, NULL),
+   __ATTR_NULL,
+};
+
+static struct class gpiochip_class = {
+   .name = gpiochip,
+   .owner =THIS_MODULE,
+
+   .dev_attrs =gpiochip_attrs,
 };
 
 
@@ -791,10 +782,6 @@ int gpio_export(unsigned gpio, bool dire
goto fail_unlock;
}
 
-   status = sysfs_create_group(dev-kobj, gpio_attr_group);
-   if (status)
-   goto fail_unregister_device;
-
if (direction_may_change) {
status = device_create_file(dev, dev_attr_direction);
if (status)
@@ -962,25 +949,22 @@ EXPORT_SYMBOL_GPL(gpio_unexport);
 
 static int gpiochip_export(struct gpio_chip *chip)
 {
-   int status;
+   int status = 0;
struct device   *dev;
 
/* Many systems register gpio chips for SOC support very early,
 * before driver model support is available.  In those cases we
 * export this later, in gpiolib_sysfs_init() ... here

Re: [PATCH RESEND 1/6 v13] gpio: Add a block GPIO API to gpiolib

2013-01-18 Thread Roland Stigge
Hi Stijn,

On 01/18/2013 01:13 PM, Stijn Devriendt wrote:
> Hi Roland,
> 
> This mail has been long overdue due to issues with some internal
> permission-tool.
> Just to be clear, this is not a competing implementation, it's what we
> currently use as-is. I'm just posting this as a reference to see if
> perhaps more concepts could be reused. It's based on a 2.6.32 kernel.
> 
> It includes:
> - labels in sysfs (to provide useful names to userspace)
> - gpio group support
> - exporting individual/groups of gpios dictated by platform-data or 
> device-tree
> - open-drain support (different from mainline)
> - examplary support for multi-gpio to pcf8575 driver
> - gpio_direction_output_keep() function that prevents toggling when
> changing direction
> 
> Provided-as-is-by: Stijn Devriendt 

Thanks for posting.

Except for open-drain support, everything in the above list is supported
in the last posted version of block GPIO.

So please tell if there are certain details you would like to discuss
about or need an alternative implementation.

Thanks in advance,

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


Re: [PATCH RESEND 1/6 v13] gpio: Add a block GPIO API to gpiolib

2013-01-18 Thread Roland Stigge
Hi Stijn,

On 01/18/2013 01:13 PM, Stijn Devriendt wrote:
 Hi Roland,
 
 This mail has been long overdue due to issues with some internal
 permission-tool.
 Just to be clear, this is not a competing implementation, it's what we
 currently use as-is. I'm just posting this as a reference to see if
 perhaps more concepts could be reused. It's based on a 2.6.32 kernel.
 
 It includes:
 - labels in sysfs (to provide useful names to userspace)
 - gpio group support
 - exporting individual/groups of gpios dictated by platform-data or 
 device-tree
 - open-drain support (different from mainline)
 - examplary support for multi-gpio to pcf8575 driver
 - gpio_direction_output_keep() function that prevents toggling when
 changing direction
 
 Provided-as-is-by: Stijn Devriendt sdevr...@cisco.com

Thanks for posting.

Except for open-drain support, everything in the above list is supported
in the last posted version of block GPIO.

So please tell if there are certain details you would like to discuss
about or need an alternative implementation.

Thanks in advance,

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


Re: [PATCH RESEND 6/6 v13] gpio: Add block gpio to several gpio drivers

2013-01-15 Thread Roland Stigge
On 01/15/2013 02:18 PM, Nicolas Ferre wrote:
>> --- linux-2.6.orig/drivers/pinctrl/pinctrl-at91.c
>> +++ linux-2.6/drivers/pinctrl/pinctrl-at91.c
>> @@ -49,6 +49,7 @@ struct at91_gpio_chip {
>>   struct clk*clock;/* associated clock */
>>   struct irq_domain*domain;/* associated irq domain */
>>   struct at91_pinctrl_mux_ops *ops;/* ops */
>> +unsigned longmask_cache;/* cached mask for block gpio */
>>   };
>>
>>   #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip,
>> chip)
>> @@ -1125,6 +1126,32 @@ static void at91_gpio_set(struct gpio_ch
>>   writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
>>   }
>>
>> +static unsigned long at91_gpio_get_block(struct gpio_chip *chip,
>> + unsigned long mask)
>> +{
>> +struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
>> +void __iomem *pio = at91_gpio->regbase;
>> +u32 pdsr;
>> +
>> +pdsr = __raw_readl(pio + PIO_PDSR);
> 
> Maybe you should use readl_relaxed() here as it is used in the
> at91_gpio_[get|set]() functions.

Thanks for the note! Seem to have missed this when forward porting in
pinctrl-at91.c was due.

Will include the respective change in a subsequent update.

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


[PATCH RESEND 2/6 v13] gpio: Add sysfs support to block GPIO API

2013-01-15 Thread Roland Stigge
This patch adds sysfs support to the block GPIO API.

Signed-off-by: Roland Stigge 

---
 Documentation/ABI/testing/sysfs-gpio |   20 ++
 drivers/gpio/gpiolib.c   |  252 ++-
 include/asm-generic/gpio.h   |   11 +
 include/linux/gpio.h |   15 ++
 4 files changed, 297 insertions(+), 1 deletion(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -25,3 +25,23 @@ Description:
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
 
+What:  /sys/class/gpioblock/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:
+
+  Block GPIO devices are visible in sysfs as soon as they are registered
+  (e.g. via devicetree definition). For actual I/O use, their "exported"
+  boolean attribute must be set to "1". Then, the attribute "values" is
+  created and at the same time, the GPIOs in the block are requested for
+  exclusive use by sysfs.
+
+/sys/class/gpioblock
+   /BLOCKNAME ... for each GPIO block name
+   /ngpio ... (r/o) number of GPIOs in this group
+   /exported ... sysfs export state of this group (0, 1)
+   /value ... current value as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
+   /mask ... current mask as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -224,7 +224,8 @@ static bool gpio_block_is_output(struct
int i;
 
for (i = 0; i < block->ngpio; i++)
-   if (!test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
+   if ((block->cur_mask & BIT(i)) &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
return false;
return true;
 }
@@ -1020,6 +1021,240 @@ static void gpiochip_unexport(struct gpi
chip->label, status);
 }
 
+static ssize_t gpio_block_ngpio_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, "%u\n", block->ngpio);
+}
+
+static ssize_t gpio_block_value_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? "0x%08lx\n" :
+  "0x%016lx\n", gpio_block_get(block, block->cur_mask));
+}
+
+static ssize_t gpio_block_value_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   value;
+
+   status = kstrtoul(buf, 0, );
+   if (status == 0) {
+   mutex_lock(_lock);
+   if (gpio_block_is_output(block)) {
+   gpio_block_set(block, block->cur_mask, value);
+   status = size;
+   } else {
+   status = -EPERM;
+   }
+   mutex_unlock(_lock);
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_value = __ATTR(value, S_IWUSR | S_IRUGO, gpio_block_value_show,
+ gpio_block_value_store);
+
+static ssize_t gpio_block_mask_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? "0x%08lx\n" :
+  "0x%016lx\n", block->cur_mask);
+}
+
+static ssize_t gpio_block_mask_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   mask;
+
+   status = kstrtoul(buf, 0, );
+   if (status == 0) {
+   block->cur_mask = mask;
+   status = size;
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_mask = __ATTR(mask, S_IWUSR | S_IRUGO, gpio_block_mask_show,
+gpio_block_mask_store);
+
+static struct class gpio_block_class;
+
+static int gpio_block_value_is_exported(struct gpio_block *block)
+{
+   struct device   *dev;
+   struct sysf

[PATCH RESEND 1/6 v13] gpio: Add a block GPIO API to gpiolib

2013-01-15 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal "Block GPIO" API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge 
---

 Documentation/gpio.txt |   58 +++
 drivers/gpio/gpiolib.c |  227 +
 include/asm-generic/gpio.h |   17 +++
 include/linux/gpio.h   |   97 +++
 4 files changed, 399 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -481,6 +481,64 @@ exact name string of pinctrl device has
 argument to this routine.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
+const char *name);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). Similarly, the direction of the used GPIOs need
+to be set by the user before using the block. An arbitrary list of globally
+valid GPIOs can be specified, even ranging over several gpio_chips. Actual
+handling of I/O operations will be done on a best effort base, i.e.
+simultaneous I/O only where possible by hardware and implemented in the
+respective GPIO driver. The number of GPIOs in one block is limited to the
+number of bits in an unsigned long, or BITS_PER_LONG, of the respective
+platform, i.e. typically at least 32 on a 32 bit system, and at least 64 on a
+64 bit system. However, several blocks can be defined at once.
+
+unsigned long gpio_block_get(struct gpio_block *block, unsigned long mask);
+void gpio_block_set(struct gpio_block *block, unsigned long mask,
+   unsigned long values);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). The mask parameters
+specify which bits in the block are acted upon. This is useful to let some bits
+untouched when doing a set operation on the block.
+
+Block operations in hardware are only possible where the respective GPIO driver
+implements it, falling back to using single GPIO operations where the driver
+only implements single GPIO access.
+
+If a GPIO block includes GPIOs from several chips, the chips are handled one
+after another in the order of first specification in the list of GPIOs defined
+in the GPIO block, starting with bit 0. Note that in this case, you typically
+can't assume simultaneous access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via userspace API.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -217,6 +219,16 @@ static int gpio_get_direction(unsigned g
return status;
 }
 
+static bool gpio_block_is_output(struct gpio_block *block)
+{
+   int i;
+
+   for (i = 0; i < block->ngpio; i++)
+   if (!test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
+   return false;
+   return true;
+}
+
 #ifdef CONFIG_GPIO_SYSFS
 
 /* lock protects against unexport_gpio() being called while
@@ -1799,6 +1811,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static struct gpio_block_chip *

[PATCH RESEND 3/6 v13] gpio: Add userland device interface to block GPIO

2013-01-15 Thread Roland Stigge
This patch adds a character device interface to the block GPIO system.

Signed-off-by: Roland Stigge 
---
 Documentation/ABI/testing/dev-gpioblock |   34 
 drivers/gpio/gpiolib.c  |  225 +++-
 include/linux/gpio.h|   13 +
 3 files changed, 271 insertions(+), 1 deletion(-)

--- /dev/null
+++ linux-2.6/Documentation/ABI/testing/dev-gpioblock
@@ -0,0 +1,34 @@
+What:  /dev/
+Date:  Nov 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:   The /dev/ character device node provides userspace
+   access to GPIO blocks, named exactly as the block, e.g.
+   /dev/block0.
+
+   Reading:
+   When reading sizeof(unsigned long) bytes from the device, the
+   current state of the block, masked by the current mask (see
+   below) can be obtained as a word. When the device is opened
+   with O_NONBLOCK, read() always returns with data immediately,
+   otherwise it blocks until data is available, see IRQ handling
+   below.
+
+   Writing:
+   By writing sizeof(unsigned long) bytes to the device, the
+   current state of the block can be set. This operation is
+   masked by the current mask (see below).
+
+   IRQ handling:
+   When one or more IRQs in the block are IRQ capable, you can
+   poll() on the device to check/wait for this IRQ. If no IRQ
+   is available, poll() returns -ENOSYS and userspace needs to
+   (busy) poll itself if necessary.
+
+   Setting the mask (default: all bits set):
+   By doing an ioctl(fd, 0, ) with an unsigned long mask, the
+   current mask for read and write operations on this gpio block
+   can be set.
+
+   See also Documentation/gpio.txt for an explanation of block
+   GPIO.
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -11,6 +11,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define CREATE_TRACE_POINTS
 #include 
@@ -2243,6 +2245,207 @@ struct gpio_block *gpio_block_find_by_na
 }
 EXPORT_SYMBOL_GPL(gpio_block_find_by_name);
 
+static struct gpio_block *gpio_block_find_by_minor(int minor)
+{
+   struct gpio_block *i;
+
+   list_for_each_entry(i, _block_list, list)
+   if (i->miscdev.minor == minor)
+   return i;
+   return NULL;
+}
+
+static bool gpio_block_is_irq_duplicate(struct gpio_block *block, int index)
+{
+   int irq = gpio_to_irq(block->gpio[index]);
+   int i;
+
+   for (i = 0; i < index; i++)
+   if (gpio_to_irq(block->gpio[i]) == irq)
+   return true;
+   return false;
+}
+
+static irqreturn_t gpio_block_irq_handler(int irq, void *dev)
+{
+   struct gpio_block *block = dev;
+
+   wake_up_interruptible(>wait_queue);
+   block->got_int = true;
+
+   return IRQ_HANDLED;
+}
+
+static int gpio_block_fop_open(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = gpio_block_find_by_minor(MINOR(in->i_rdev));
+   int status;
+   int irq;
+
+   if (!block)
+   return -ENOENT;
+
+   block->irq_controlled = false;
+   block->got_int = false;
+   spin_lock_init(>lock);
+   init_waitqueue_head(>wait_queue);
+   f->private_data = block;
+
+   for (i = 0; i < block->ngpio; i++) {
+   status = gpio_request(block->gpio[i], block->name);
+   if (status)
+   goto err1;
+
+   irq = gpio_to_irq(block->gpio[i]);
+   if (irq >= 0 &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags) &&
+   !gpio_block_is_irq_duplicate(block, i)) {
+   status = request_irq(irq, gpio_block_irq_handler,
+IRQF_SHARED,
+block->name, block);
+   if (status)
+   goto err2;
+
+   block->irq_controlled = true;
+   }
+   }
+
+   return 0;
+
+err1:
+   while (i > 0) {
+   i--;
+
+   irq = gpio_to_irq(block->gpio[i]);
+   if (irq >= 0 &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags) &&
+   !gpio_block_is_irq_duplicate(block, i))
+   free_irq(irq, block);
+err2:
+   gpio_free(block->gpio[i]);
+   }
+   return status;
+}
+
+static int gpio_block_fop_release(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = (struct gpio_block *)f->

[PATCH RESEND 6/6 v13] gpio: Add block gpio to several gpio drivers

2013-01-15 Thread Roland Stigge
This patch adds block GPIO support to several gpio drivers.

This implements block GPIO only for some selected drivers since block GPIO is
an optional feature which may not be suitable for every GPIO hardware. (With
automatic fallback to the single GPIO functions if not available in a driver.)

Signed-off-by: Roland Stigge 

---
 drivers/gpio/Kconfig  |2 
 drivers/gpio/gpio-em.c|   23 ++
 drivers/gpio/gpio-ge.c|   29 +
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 +++
 drivers/gpio/gpio-lpc32xx.c   |   82 ++
 drivers/gpio/gpio-max730x.c   |   61 
 drivers/gpio/gpio-max732x.c   |   59 +++
 drivers/gpio/gpio-mc33880.c   |   16 +++
 drivers/gpio/gpio-ml-ioh.c|   27 
 drivers/gpio/gpio-mm-lantiq.c |   22 ++
 drivers/gpio/gpio-mpc5200.c   |   64 +
 drivers/gpio/gpio-mpc8xxx.c   |   41 +++
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 +++
 drivers/gpio/gpio-pch.c   |   27 
 drivers/gpio/gpio-pl061.c |   17 +++
 drivers/gpio/gpio-sa1100.c|   20 +
 drivers/gpio/gpio-samsung.c   |   31 ++
 drivers/gpio/gpio-twl6040.c   |   32 ++
 drivers/gpio/gpio-ucb1400.c   |   23 ++
 drivers/gpio/gpio-vt8500.c|   24 +++
 drivers/gpio/gpio-xilinx.c|   44 
 drivers/pinctrl/pinctrl-at91.c|   29 +
 drivers/pinctrl/pinctrl-nomadik.c |   36 
 25 files changed, 887 insertions(+)

--- linux-2.6.orig/drivers/gpio/Kconfig
+++ linux-2.6/drivers/gpio/Kconfig
@@ -144,11 +144,13 @@ config GPIO_MM_LANTIQ
 config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
+   select BITREVERSE
 
 config GPIO_MPC8XXX
bool "MPC512x/MPC8xxx GPIO support"
depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
   FSL_SOC_BOOKE || PPC_86xx
+   select BITREVERSE
help
  Say Y here if you're going to use hardware that connects to the
  MPC512x/831x/834x/837x/8572/8610 GPIOs.
--- linux-2.6.orig/drivers/gpio/gpio-em.c
+++ linux-2.6/drivers/gpio/gpio-em.c
@@ -202,6 +202,27 @@ static void em_gio_set(struct gpio_chip
__em_gio_set(chip, GIO_OH, offset - 16, value);
 }
 
+static unsigned long em_gio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+   return (int)(em_gio_read(gpio_to_priv(chip), GIO_I) & mask);
+}
+
+static void em_gio_set_block(struct gpio_chip *chip, unsigned long mask,
+unsigned long values)
+{
+   unsigned long mask_ol = mask & 0x;
+   unsigned long mask_oh = mask >> 16;
+
+   unsigned long values_ol = values & mask_ol;
+   unsigned long values_oh = (values >> 16) & mask_oh;
+
+   em_gio_write(gpio_to_priv(chip), GIO_OL,
+mask_ol << 16 | values_ol);
+   em_gio_write(gpio_to_priv(chip), GIO_OH,
+mask_oh << 16 | values_oh);
+}
+
 static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
   int value)
 {
@@ -282,8 +303,10 @@ static int em_gio_probe(struct platform_
gpio_chip = >gpio_chip;
gpio_chip->direction_input = em_gio_direction_input;
gpio_chip->get = em_gio_get;
+   gpio_chip->get_block = em_gio_get_block;
gpio_chip->direction_output = em_gio_direction_output;
gpio_chip->set = em_gio_set;
+   gpio_chip->set_block = em_gio_set_block;
gpio_chip->to_irq = em_gio_to_irq;
gpio_chip->label = name;
gpio_chip->owner = THIS_MODULE;
--- linux-2.6.orig/drivers/gpio/gpio-ge.c
+++ linux-2.6/drivers/gpio/gpio-ge.c
@@ -100,6 +100,29 @@ static void gef_gpio_set(struct gpio_chi
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
 }
 
+static unsigned long gef_gpio_get_block(struct gpio_chip *chip,
+   unsigned long mask)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+
+   return ioread32be(mmchip->regs + GEF_GPIO_IN) & mask;
+}
+
+static void gef_gpio_set_block(struct gpio_chip *chip,
+  unsigned long mask, unsigned long values)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+   void __iomem *reg = mmchip->regs + GEF_GPIO_OUT;
+   unsigned int data;
+
+   data = ioread32be(reg);
+
+   data &= ~mask;
+   data |= values & mask;
+
+   iowrite32be(data, reg);
+}
+
 static in

[PATCH RESEND 0/6 v13] gpio: Add block GPIO

2013-01-15 Thread Roland Stigge
This set of patches adds:

* Block GPIO API to gpiolib
* Sysfs support for GPIO API, to provide userland access
* Device interface for userland access (alternative to sysfs)
* Devicetree support to instantiate GPIO blocks via DT
* Example implementations in several gpio drivers since they need
  special accessor functions for block wise GPIO access (only for some
  selected drivers since the feature is optional and not suitable for
  all GPIO hardware)
* Fix for race condition in gpiolib on device creation

Signed-off-by: Roland Stigge 
Tested by: Wolfgang Grandegger 
--

Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

Changes since v12:
* Added support for gpio drivers ge, ks8695, mc33880, ml-ioh, mpc5200 and
  mpc8xxx
* Added support for pinctrl driver at91

Changes since v11:
* Removed support for at91, since this one is currently in the migration
  process to pinctrl implementation
* Fixed mask setting via sysfs
* Device interface: declare gpio_block_fop_poll() static

Changes since v10:
* gpioblock-of.c: Catch <1 specified GPIOs
* gpioblock-of.c: Fixed memory leak in probe()'s error path
* gpioblock-of.c: Fixed block node's refcount via of_node_put()
* Added driver support for samsung, mm-lantiq and sa1100
* Added driver support for at91 (by Wolfgang Grandegger)
* Added pinctrl driver support for pinctl-nomadik

Changed since v9:
* Changed IRQ flags for device interface's poll() from IRQF_TRIGGER_FALLING
  to IRQF_SHARED
* Use block name on gpio_request
* Added spinlock for ISR manipulated data (dev interface / poll())

Changed since v8:
* Added poll() function to dev interface for IRQ handling
* Fixed gpio_block_register() in case of missing CONFIG_GPIO_SYSFS
* Fixed mask handling in sysfs interface
* Fixed get_user/put_user pointer (cast)

Changes since v7:
* Fixed error in API documentation (name arg missing in prototype)
* Fixed compile error if sysfs is missing: Moved gpio_block_is_output()
  out of sysfs-ifdef
* Added error handling to gpio_block_register()
* Added mask attribute to sysfs (although dev interface exists now)

Changes since v6:
* Changed realloc to list handling
* Added mask to kernel API
* Added device interface as userspace API
* Changed sizeof() to BITS_PER_LONG
* Fixed multiline comment style
* Documented direction setting by the user
* Documented order of handled chips in case of multiple chips in one block

Changes since v5:
* Documented sysfs: elaborated on "exported" and "values" attributes
* Documented sysfs: gpiochip is a separate class now
* Aggregated driver support patches for block gpio into one single patch
* Added gpio block driver support for twl6040 and pch

Changes since v4:
* Documented word width
* Bugfix: export/unexport on register/unregister
* Using default dev_attrs for gpio_block_class
* Fix gpiolib: race condition on device creation
* Added driver support for ucb14500, vt8500, xilinx

Changes since v3:
* Added driver support for pca953x, em, pl061, max732x, pcf857x
* Coding style improvements
* Fixed krealloc memory leak in error case
* sysfs: values in hex
* Register blocks in a list
* Narrowing lock scope
* Use S_IWUSR and S_IRUGO instead of direct octal values
* Use for_each_set_bit()
* Change from unsigned to unsigned long for masks and values

Changes since v2:
* Added sysfs support
* Added devicetree support
* Added support for lpc32xx, generic
* Added functions for GPIO block registration
* Added more error checking
* Bit remapping bugfix

Changes since v1:
* API change to 32/64 bit word, bit masks

Thanks to Ryan Mallon, Linus Walleij, Stijn Devriendt, Jean-Christophe
Plagniol-Villard, Mark Brown, Greg Kroah-Hartman, Grant Likely, Stefan
Roese, Wolfgang Grandegger, Tobias Rutz, Fengguang Wu and Mark Rutland
for reviewing and testing!

Roland Stigge (6):
 gpio: Add a block GPIO API to gpiolib
 gpio: Add sysfs support to block GPIO API
 gpio: Add userland device interface to block GPIO
 gpiolib: Fix default attributes for class
 gpio: Add device tree support to block GPIO API
 gpio: Add block gpio to several gpio drivers

 Documentation/ABI/testing/dev-gpioblock   |   34 
 Documentation/ABI/testing/sysfs-gpio  |   31 
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 
 Documentation/gpio.txt|   58 +
 drivers/gpio/Kconfig  |2 
 drivers/gpio/Makefile |1 
 drivers/gpio/gpio-em.c|   23 
 drivers/gpio/gpio-ge.c|   29 
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 
 drivers/gpio/gpio-lpc32xx.c   |   82 +
 drivers/gpio/gpio-max730x.c   |   61 +
 drivers/gpio/gpio-max732x.c   |   59 +
 drivers/gpio/gpio-mc33880.c   |   16 
 dri

[PATCH RESEND 5/6 v13] gpio: Add device tree support to block GPIO API

2013-01-15 Thread Roland Stigge
This patch adds device tree support to the block GPIO API.

Signed-off-by: Roland Stigge 

---
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 ++
 drivers/gpio/Makefile |1 
 drivers/gpio/gpioblock-of.c   |  100 ++
 3 files changed, 137 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be "linux,gpio-block"
+
+Required subnodes:
+- the name will be the registered name of the block
+- property "gpios" is a list of gpios for the respective block
+
+Example:
+
+blockgpio {
+compatible = "linux,gpio-block";
+
+block0 {
+gpios = < 3 0 0>,
+< 3 1 0>;
+};
+block1 {
+gpios = < 4 1 0>,
+< 4 3 0>,
+< 4 2 0>,
+< 4 4 0>,
+< 4 5 0>,
+< 4 6 0>,
+< 4 7 0>,
+< 4 8 0>,
+< 4 9 0>,
+< 4 10 0>,
+< 4 19 0>;
+};
+};
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)+= -DDEBUG
 obj-$(CONFIG_GPIOLIB)  += gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)  += gpiolib-of.o
 obj-$(CONFIG_GPIO_ACPI)+= gpiolib-acpi.o
+obj-$(CONFIG_OF_GPIO)  += gpioblock-of.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,100 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int __devinit gpioblock_of_probe(struct platform_device *pdev)
+{
+   struct device_node *block;
+   unsigned *gpios;
+   int ngpio;
+   int ret;
+   struct gpio_block *gb;
+
+   for_each_available_child_of_node(pdev->dev.of_node, block) {
+   int i;
+
+   ngpio = of_gpio_count(block);
+   if (ngpio < 1) {
+   ret = -ENODEV;
+   goto err1;
+   }
+
+   gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+   if (!gpios) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   for (i = 0; i < ngpio; i++) {
+   ret = of_get_gpio(block, i);
+   if (ret < 0)
+   goto err2; /* expect -EPROBE_DEFER */
+   gpios[i] = ret;
+   }
+   gb = gpio_block_create(gpios, ngpio, block->name);
+   if (IS_ERR(gb)) {
+   dev_err(>dev,
+   "Error creating GPIO block from device tree\n");
+   ret = PTR_ERR(gb);
+   goto err2;
+   }
+   ret = gpio_block_register(gb);
+   if (ret < 0)
+   goto err3;
+
+   kfree(gpios);
+   dev_info(>dev, "Registered gpio block %s: %d gpios\n",
+block->name, ngpio);
+   }
+   return 0;
+
+err3:
+   gpio_block_free(gb);
+err2:
+   kfree(gpios);
+err1:
+   of_node_put(block);
+   return ret;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] __devinitdata = {
+   { .compatible = "linux,gpio-block", },
+   { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+   .driver = {
+   .name = "gpio-block",
+   .owner = THIS_MODULE,
+   .of_match_table = of_match_ptr(gpioblock_of_match),
+
+   },
+   .probe  = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION("GPIO Block driver");

[PATCH RESEND 4/6 v13] gpiolib: Fix default attributes for class

2013-01-15 Thread Roland Stigge
There is a race condition between creating a gpio or gpiochip device and adding
default attributes. This patch fixes this by defining the default attributes as
dev_attrs of the class. For this, it was necessary to create a separate
gpiochip_class besides gpio_class.

Signed-off-by: Roland Stigge 
---
 Documentation/ABI/testing/sysfs-gpio |   11 
 drivers/gpio/gpiolib.c   |   78 ++-
 2 files changed, 44 insertions(+), 45 deletions(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -20,6 +20,17 @@ Description:
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
+
+What:  /sys/class/gpiochip/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:
+
+  Each gpiochip is represented by a separate device having the following
+  attributes:
+
+/sys/class/gpiochip
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -362,9 +362,6 @@ static ssize_t gpio_value_store(struct d
return status;
 }
 
-static const DEVICE_ATTR(value, 0644,
-   gpio_value_show, gpio_value_store);
-
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
struct sysfs_dirent *value_sd = priv;
@@ -585,19 +582,6 @@ static ssize_t gpio_active_low_store(str
return status ? : size;
 }
 
-static const DEVICE_ATTR(active_low, 0644,
-   gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
-   _attr_value.attr,
-   _attr_active_low.attr,
-   NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
-   .attrs = (struct attribute **) gpio_attrs,
-};
-
 /*
  * /sys/class/gpio/gpiochipN/
  *   /base ... matching gpio_chip.base (N)
@@ -612,7 +596,6 @@ static ssize_t chip_base_show(struct dev
 
return sprintf(buf, "%d\n", chip->base);
 }
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
 
 static ssize_t chip_label_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -621,7 +604,6 @@ static ssize_t chip_label_show(struct de
 
return sprintf(buf, "%s\n", chip->label ? : "");
 }
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
 
 static ssize_t chip_ngpio_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -630,18 +612,6 @@ static ssize_t chip_ngpio_show(struct de
 
return sprintf(buf, "%u\n", chip->ngpio);
 }
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
-   _attr_base.attr,
-   _attr_label.attr,
-   _attr_ngpio.attr,
-   NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
-   .attrs = (struct attribute **) gpiochip_attrs,
-};
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -720,11 +690,32 @@ static struct class_attribute gpio_class
__ATTR_NULL,
 };
 
+static struct device_attribute gpio_attrs[] = {
+   __ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store),
+   __ATTR(value, 0644, gpio_value_show, gpio_value_store),
+   __ATTR_NULL,
+};
+
 static struct class gpio_class = {
.name = "gpio",
.owner =THIS_MODULE,
 
-   .class_attrs =  gpio_class_attrs,
+   .class_attrs = gpio_class_attrs,
+   .dev_attrs = gpio_attrs,
+};
+
+static struct device_attribute gpiochip_attrs[] = {
+   __ATTR(label, 0444, chip_label_show, NULL),
+   __ATTR(base, 0444, chip_base_show, NULL),
+   __ATTR(ngpio, 0444, chip_ngpio_show, NULL),
+   __ATTR_NULL,
+};
+
+static struct class gpiochip_class = {
+   .name = "gpiochip",
+   .owner =THIS_MODULE,
+
+   .dev_attrs =gpiochip_attrs,
 };
 
 
@@ -791,10 +782,6 @@ int gpio_export(unsigned gpio, bool dire
goto fail_unlock;
}
 
-   status = sysfs_create_group(>kobj, _attr_group);
-   if (status)
-   goto fail_unregister_device;
-
if (direction_may_change) {
status = device_create_file(dev, _attr_direction);
if (status)
@@ -962,25 +949,22 @@ EXPORT_SYMBOL_GPL(gpio_unexport);
 
 static int gpiochip_export(struct gpio_chip *chip)
 {
-   int status;
+   int status = 0;
struct device   *dev;
 
/* Many systems register gpio chips for SOC support very early,
 * before driver model support is available.  In those cases we
 * export this later, in g

[PATCH RESEND 4/6 v13] gpiolib: Fix default attributes for class

2013-01-15 Thread Roland Stigge
There is a race condition between creating a gpio or gpiochip device and adding
default attributes. This patch fixes this by defining the default attributes as
dev_attrs of the class. For this, it was necessary to create a separate
gpiochip_class besides gpio_class.

Signed-off-by: Roland Stigge sti...@antcom.de
---
 Documentation/ABI/testing/sysfs-gpio |   11 
 drivers/gpio/gpiolib.c   |   78 ++-
 2 files changed, 44 insertions(+), 45 deletions(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -20,6 +20,17 @@ Description:
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
+
+What:  /sys/class/gpiochip/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:
+
+  Each gpiochip is represented by a separate device having the following
+  attributes:
+
+/sys/class/gpiochip
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -362,9 +362,6 @@ static ssize_t gpio_value_store(struct d
return status;
 }
 
-static const DEVICE_ATTR(value, 0644,
-   gpio_value_show, gpio_value_store);
-
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
struct sysfs_dirent *value_sd = priv;
@@ -585,19 +582,6 @@ static ssize_t gpio_active_low_store(str
return status ? : size;
 }
 
-static const DEVICE_ATTR(active_low, 0644,
-   gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
-   dev_attr_value.attr,
-   dev_attr_active_low.attr,
-   NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
-   .attrs = (struct attribute **) gpio_attrs,
-};
-
 /*
  * /sys/class/gpio/gpiochipN/
  *   /base ... matching gpio_chip.base (N)
@@ -612,7 +596,6 @@ static ssize_t chip_base_show(struct dev
 
return sprintf(buf, %d\n, chip-base);
 }
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
 
 static ssize_t chip_label_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -621,7 +604,6 @@ static ssize_t chip_label_show(struct de
 
return sprintf(buf, %s\n, chip-label ? : );
 }
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
 
 static ssize_t chip_ngpio_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -630,18 +612,6 @@ static ssize_t chip_ngpio_show(struct de
 
return sprintf(buf, %u\n, chip-ngpio);
 }
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
-   dev_attr_base.attr,
-   dev_attr_label.attr,
-   dev_attr_ngpio.attr,
-   NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
-   .attrs = (struct attribute **) gpiochip_attrs,
-};
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -720,11 +690,32 @@ static struct class_attribute gpio_class
__ATTR_NULL,
 };
 
+static struct device_attribute gpio_attrs[] = {
+   __ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store),
+   __ATTR(value, 0644, gpio_value_show, gpio_value_store),
+   __ATTR_NULL,
+};
+
 static struct class gpio_class = {
.name = gpio,
.owner =THIS_MODULE,
 
-   .class_attrs =  gpio_class_attrs,
+   .class_attrs = gpio_class_attrs,
+   .dev_attrs = gpio_attrs,
+};
+
+static struct device_attribute gpiochip_attrs[] = {
+   __ATTR(label, 0444, chip_label_show, NULL),
+   __ATTR(base, 0444, chip_base_show, NULL),
+   __ATTR(ngpio, 0444, chip_ngpio_show, NULL),
+   __ATTR_NULL,
+};
+
+static struct class gpiochip_class = {
+   .name = gpiochip,
+   .owner =THIS_MODULE,
+
+   .dev_attrs =gpiochip_attrs,
 };
 
 
@@ -791,10 +782,6 @@ int gpio_export(unsigned gpio, bool dire
goto fail_unlock;
}
 
-   status = sysfs_create_group(dev-kobj, gpio_attr_group);
-   if (status)
-   goto fail_unregister_device;
-
if (direction_may_change) {
status = device_create_file(dev, dev_attr_direction);
if (status)
@@ -962,25 +949,22 @@ EXPORT_SYMBOL_GPL(gpio_unexport);
 
 static int gpiochip_export(struct gpio_chip *chip)
 {
-   int status;
+   int status = 0;
struct device   *dev;
 
/* Many systems register gpio chips for SOC support very early,
 * before driver model support is available.  In those cases we
 * export this later, in gpiolib_sysfs_init() ... here

[PATCH RESEND 5/6 v13] gpio: Add device tree support to block GPIO API

2013-01-15 Thread Roland Stigge
This patch adds device tree support to the block GPIO API.

Signed-off-by: Roland Stigge sti...@antcom.de

---
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 ++
 drivers/gpio/Makefile |1 
 drivers/gpio/gpioblock-of.c   |  100 ++
 3 files changed, 137 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be linux,gpio-block
+
+Required subnodes:
+- the name will be the registered name of the block
+- property gpios is a list of gpios for the respective block
+
+Example:
+
+blockgpio {
+compatible = linux,gpio-block;
+
+block0 {
+gpios = gpio 3 0 0,
+gpio 3 1 0;
+};
+block1 {
+gpios = gpio 4 1 0,
+gpio 4 3 0,
+gpio 4 2 0,
+gpio 4 4 0,
+gpio 4 5 0,
+gpio 4 6 0,
+gpio 4 7 0,
+gpio 4 8 0,
+gpio 4 9 0,
+gpio 4 10 0,
+gpio 4 19 0;
+};
+};
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)+= -DDEBUG
 obj-$(CONFIG_GPIOLIB)  += gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)  += gpiolib-of.o
 obj-$(CONFIG_GPIO_ACPI)+= gpiolib-acpi.o
+obj-$(CONFIG_OF_GPIO)  += gpioblock-of.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,100 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge sti...@antcom.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/platform_device.h
+#include linux/gpio.h
+#include linux/of.h
+#include linux/of_gpio.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/err.h
+
+static int __devinit gpioblock_of_probe(struct platform_device *pdev)
+{
+   struct device_node *block;
+   unsigned *gpios;
+   int ngpio;
+   int ret;
+   struct gpio_block *gb;
+
+   for_each_available_child_of_node(pdev-dev.of_node, block) {
+   int i;
+
+   ngpio = of_gpio_count(block);
+   if (ngpio  1) {
+   ret = -ENODEV;
+   goto err1;
+   }
+
+   gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+   if (!gpios) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   for (i = 0; i  ngpio; i++) {
+   ret = of_get_gpio(block, i);
+   if (ret  0)
+   goto err2; /* expect -EPROBE_DEFER */
+   gpios[i] = ret;
+   }
+   gb = gpio_block_create(gpios, ngpio, block-name);
+   if (IS_ERR(gb)) {
+   dev_err(pdev-dev,
+   Error creating GPIO block from device tree\n);
+   ret = PTR_ERR(gb);
+   goto err2;
+   }
+   ret = gpio_block_register(gb);
+   if (ret  0)
+   goto err3;
+
+   kfree(gpios);
+   dev_info(pdev-dev, Registered gpio block %s: %d gpios\n,
+block-name, ngpio);
+   }
+   return 0;
+
+err3:
+   gpio_block_free(gb);
+err2:
+   kfree(gpios);
+err1:
+   of_node_put(block);
+   return ret;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] __devinitdata = {
+   { .compatible = linux,gpio-block, },
+   { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+   .driver = {
+   .name = gpio-block,
+   .owner = THIS_MODULE,
+   .of_match_table = of_match_ptr(gpioblock_of_match),
+
+   },
+   .probe  = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION(GPIO Block driver);
+MODULE_AUTHOR(Roland

[PATCH RESEND 0/6 v13] gpio: Add block GPIO

2013-01-15 Thread Roland Stigge
This set of patches adds:

* Block GPIO API to gpiolib
* Sysfs support for GPIO API, to provide userland access
* Device interface for userland access (alternative to sysfs)
* Devicetree support to instantiate GPIO blocks via DT
* Example implementations in several gpio drivers since they need
  special accessor functions for block wise GPIO access (only for some
  selected drivers since the feature is optional and not suitable for
  all GPIO hardware)
* Fix for race condition in gpiolib on device creation

Signed-off-by: Roland Stigge sti...@antcom.de
Tested by: Wolfgang Grandegger w...@grandegger.com
--

Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

Changes since v12:
* Added support for gpio drivers ge, ks8695, mc33880, ml-ioh, mpc5200 and
  mpc8xxx
* Added support for pinctrl driver at91

Changes since v11:
* Removed support for at91, since this one is currently in the migration
  process to pinctrl implementation
* Fixed mask setting via sysfs
* Device interface: declare gpio_block_fop_poll() static

Changes since v10:
* gpioblock-of.c: Catch 1 specified GPIOs
* gpioblock-of.c: Fixed memory leak in probe()'s error path
* gpioblock-of.c: Fixed block node's refcount via of_node_put()
* Added driver support for samsung, mm-lantiq and sa1100
* Added driver support for at91 (by Wolfgang Grandegger)
* Added pinctrl driver support for pinctl-nomadik

Changed since v9:
* Changed IRQ flags for device interface's poll() from IRQF_TRIGGER_FALLING
  to IRQF_SHARED
* Use block name on gpio_request
* Added spinlock for ISR manipulated data (dev interface / poll())

Changed since v8:
* Added poll() function to dev interface for IRQ handling
* Fixed gpio_block_register() in case of missing CONFIG_GPIO_SYSFS
* Fixed mask handling in sysfs interface
* Fixed get_user/put_user pointer (cast)

Changes since v7:
* Fixed error in API documentation (name arg missing in prototype)
* Fixed compile error if sysfs is missing: Moved gpio_block_is_output()
  out of sysfs-ifdef
* Added error handling to gpio_block_register()
* Added mask attribute to sysfs (although dev interface exists now)

Changes since v6:
* Changed realloc to list handling
* Added mask to kernel API
* Added device interface as userspace API
* Changed sizeof() to BITS_PER_LONG
* Fixed multiline comment style
* Documented direction setting by the user
* Documented order of handled chips in case of multiple chips in one block

Changes since v5:
* Documented sysfs: elaborated on exported and values attributes
* Documented sysfs: gpiochip is a separate class now
* Aggregated driver support patches for block gpio into one single patch
* Added gpio block driver support for twl6040 and pch

Changes since v4:
* Documented word width
* Bugfix: export/unexport on register/unregister
* Using default dev_attrs for gpio_block_class
* Fix gpiolib: race condition on device creation
* Added driver support for ucb14500, vt8500, xilinx

Changes since v3:
* Added driver support for pca953x, em, pl061, max732x, pcf857x
* Coding style improvements
* Fixed krealloc memory leak in error case
* sysfs: values in hex
* Register blocks in a list
* Narrowing lock scope
* Use S_IWUSR and S_IRUGO instead of direct octal values
* Use for_each_set_bit()
* Change from unsigned to unsigned long for masks and values

Changes since v2:
* Added sysfs support
* Added devicetree support
* Added support for lpc32xx, generic
* Added functions for GPIO block registration
* Added more error checking
* Bit remapping bugfix

Changes since v1:
* API change to 32/64 bit word, bit masks

Thanks to Ryan Mallon, Linus Walleij, Stijn Devriendt, Jean-Christophe
Plagniol-Villard, Mark Brown, Greg Kroah-Hartman, Grant Likely, Stefan
Roese, Wolfgang Grandegger, Tobias Rutz, Fengguang Wu and Mark Rutland
for reviewing and testing!

Roland Stigge (6):
 gpio: Add a block GPIO API to gpiolib
 gpio: Add sysfs support to block GPIO API
 gpio: Add userland device interface to block GPIO
 gpiolib: Fix default attributes for class
 gpio: Add device tree support to block GPIO API
 gpio: Add block gpio to several gpio drivers

 Documentation/ABI/testing/dev-gpioblock   |   34 
 Documentation/ABI/testing/sysfs-gpio  |   31 
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 
 Documentation/gpio.txt|   58 +
 drivers/gpio/Kconfig  |2 
 drivers/gpio/Makefile |1 
 drivers/gpio/gpio-em.c|   23 
 drivers/gpio/gpio-ge.c|   29 
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 
 drivers/gpio/gpio-lpc32xx.c   |   82 +
 drivers/gpio/gpio-max730x.c   |   61 +
 drivers/gpio/gpio-max732x.c   |   59 +
 drivers/gpio/gpio-mc33880.c   |   16

[PATCH RESEND 3/6 v13] gpio: Add userland device interface to block GPIO

2013-01-15 Thread Roland Stigge
This patch adds a character device interface to the block GPIO system.

Signed-off-by: Roland Stigge sti...@antcom.de
---
 Documentation/ABI/testing/dev-gpioblock |   34 
 drivers/gpio/gpiolib.c  |  225 +++-
 include/linux/gpio.h|   13 +
 3 files changed, 271 insertions(+), 1 deletion(-)

--- /dev/null
+++ linux-2.6/Documentation/ABI/testing/dev-gpioblock
@@ -0,0 +1,34 @@
+What:  /dev/gpioblock
+Date:  Nov 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:   The /dev/gpioblock character device node provides userspace
+   access to GPIO blocks, named exactly as the block, e.g.
+   /dev/block0.
+
+   Reading:
+   When reading sizeof(unsigned long) bytes from the device, the
+   current state of the block, masked by the current mask (see
+   below) can be obtained as a word. When the device is opened
+   with O_NONBLOCK, read() always returns with data immediately,
+   otherwise it blocks until data is available, see IRQ handling
+   below.
+
+   Writing:
+   By writing sizeof(unsigned long) bytes to the device, the
+   current state of the block can be set. This operation is
+   masked by the current mask (see below).
+
+   IRQ handling:
+   When one or more IRQs in the block are IRQ capable, you can
+   poll() on the device to check/wait for this IRQ. If no IRQ
+   is available, poll() returns -ENOSYS and userspace needs to
+   (busy) poll itself if necessary.
+
+   Setting the mask (default: all bits set):
+   By doing an ioctl(fd, 0, mask) with an unsigned long mask, the
+   current mask for read and write operations on this gpio block
+   can be set.
+
+   See also Documentation/gpio.txt for an explanation of block
+   GPIO.
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -11,6 +11,8 @@
 #include linux/of_gpio.h
 #include linux/idr.h
 #include linux/slab.h
+#include linux/uaccess.h
+#include linux/poll.h
 
 #define CREATE_TRACE_POINTS
 #include trace/events/gpio.h
@@ -2243,6 +2245,207 @@ struct gpio_block *gpio_block_find_by_na
 }
 EXPORT_SYMBOL_GPL(gpio_block_find_by_name);
 
+static struct gpio_block *gpio_block_find_by_minor(int minor)
+{
+   struct gpio_block *i;
+
+   list_for_each_entry(i, gpio_block_list, list)
+   if (i-miscdev.minor == minor)
+   return i;
+   return NULL;
+}
+
+static bool gpio_block_is_irq_duplicate(struct gpio_block *block, int index)
+{
+   int irq = gpio_to_irq(block-gpio[index]);
+   int i;
+
+   for (i = 0; i  index; i++)
+   if (gpio_to_irq(block-gpio[i]) == irq)
+   return true;
+   return false;
+}
+
+static irqreturn_t gpio_block_irq_handler(int irq, void *dev)
+{
+   struct gpio_block *block = dev;
+
+   wake_up_interruptible(block-wait_queue);
+   block-got_int = true;
+
+   return IRQ_HANDLED;
+}
+
+static int gpio_block_fop_open(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = gpio_block_find_by_minor(MINOR(in-i_rdev));
+   int status;
+   int irq;
+
+   if (!block)
+   return -ENOENT;
+
+   block-irq_controlled = false;
+   block-got_int = false;
+   spin_lock_init(block-lock);
+   init_waitqueue_head(block-wait_queue);
+   f-private_data = block;
+
+   for (i = 0; i  block-ngpio; i++) {
+   status = gpio_request(block-gpio[i], block-name);
+   if (status)
+   goto err1;
+
+   irq = gpio_to_irq(block-gpio[i]);
+   if (irq = 0 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags) 
+   !gpio_block_is_irq_duplicate(block, i)) {
+   status = request_irq(irq, gpio_block_irq_handler,
+IRQF_SHARED,
+block-name, block);
+   if (status)
+   goto err2;
+
+   block-irq_controlled = true;
+   }
+   }
+
+   return 0;
+
+err1:
+   while (i  0) {
+   i--;
+
+   irq = gpio_to_irq(block-gpio[i]);
+   if (irq = 0 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags) 
+   !gpio_block_is_irq_duplicate(block, i))
+   free_irq(irq, block);
+err2:
+   gpio_free(block-gpio[i]);
+   }
+   return status;
+}
+
+static int gpio_block_fop_release(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = (struct gpio_block *)f

[PATCH RESEND 6/6 v13] gpio: Add block gpio to several gpio drivers

2013-01-15 Thread Roland Stigge
This patch adds block GPIO support to several gpio drivers.

This implements block GPIO only for some selected drivers since block GPIO is
an optional feature which may not be suitable for every GPIO hardware. (With
automatic fallback to the single GPIO functions if not available in a driver.)

Signed-off-by: Roland Stigge sti...@antcom.de

---
 drivers/gpio/Kconfig  |2 
 drivers/gpio/gpio-em.c|   23 ++
 drivers/gpio/gpio-ge.c|   29 +
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 +++
 drivers/gpio/gpio-lpc32xx.c   |   82 ++
 drivers/gpio/gpio-max730x.c   |   61 
 drivers/gpio/gpio-max732x.c   |   59 +++
 drivers/gpio/gpio-mc33880.c   |   16 +++
 drivers/gpio/gpio-ml-ioh.c|   27 
 drivers/gpio/gpio-mm-lantiq.c |   22 ++
 drivers/gpio/gpio-mpc5200.c   |   64 +
 drivers/gpio/gpio-mpc8xxx.c   |   41 +++
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 +++
 drivers/gpio/gpio-pch.c   |   27 
 drivers/gpio/gpio-pl061.c |   17 +++
 drivers/gpio/gpio-sa1100.c|   20 +
 drivers/gpio/gpio-samsung.c   |   31 ++
 drivers/gpio/gpio-twl6040.c   |   32 ++
 drivers/gpio/gpio-ucb1400.c   |   23 ++
 drivers/gpio/gpio-vt8500.c|   24 +++
 drivers/gpio/gpio-xilinx.c|   44 
 drivers/pinctrl/pinctrl-at91.c|   29 +
 drivers/pinctrl/pinctrl-nomadik.c |   36 
 25 files changed, 887 insertions(+)

--- linux-2.6.orig/drivers/gpio/Kconfig
+++ linux-2.6/drivers/gpio/Kconfig
@@ -144,11 +144,13 @@ config GPIO_MM_LANTIQ
 config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
+   select BITREVERSE
 
 config GPIO_MPC8XXX
bool MPC512x/MPC8xxx GPIO support
depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
   FSL_SOC_BOOKE || PPC_86xx
+   select BITREVERSE
help
  Say Y here if you're going to use hardware that connects to the
  MPC512x/831x/834x/837x/8572/8610 GPIOs.
--- linux-2.6.orig/drivers/gpio/gpio-em.c
+++ linux-2.6/drivers/gpio/gpio-em.c
@@ -202,6 +202,27 @@ static void em_gio_set(struct gpio_chip
__em_gio_set(chip, GIO_OH, offset - 16, value);
 }
 
+static unsigned long em_gio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+   return (int)(em_gio_read(gpio_to_priv(chip), GIO_I)  mask);
+}
+
+static void em_gio_set_block(struct gpio_chip *chip, unsigned long mask,
+unsigned long values)
+{
+   unsigned long mask_ol = mask  0x;
+   unsigned long mask_oh = mask  16;
+
+   unsigned long values_ol = values  mask_ol;
+   unsigned long values_oh = (values  16)  mask_oh;
+
+   em_gio_write(gpio_to_priv(chip), GIO_OL,
+mask_ol  16 | values_ol);
+   em_gio_write(gpio_to_priv(chip), GIO_OH,
+mask_oh  16 | values_oh);
+}
+
 static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
   int value)
 {
@@ -282,8 +303,10 @@ static int em_gio_probe(struct platform_
gpio_chip = p-gpio_chip;
gpio_chip-direction_input = em_gio_direction_input;
gpio_chip-get = em_gio_get;
+   gpio_chip-get_block = em_gio_get_block;
gpio_chip-direction_output = em_gio_direction_output;
gpio_chip-set = em_gio_set;
+   gpio_chip-set_block = em_gio_set_block;
gpio_chip-to_irq = em_gio_to_irq;
gpio_chip-label = name;
gpio_chip-owner = THIS_MODULE;
--- linux-2.6.orig/drivers/gpio/gpio-ge.c
+++ linux-2.6/drivers/gpio/gpio-ge.c
@@ -100,6 +100,29 @@ static void gef_gpio_set(struct gpio_chi
_gef_gpio_set(mmchip-regs + GEF_GPIO_OUT, offset, value);
 }
 
+static unsigned long gef_gpio_get_block(struct gpio_chip *chip,
+   unsigned long mask)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+
+   return ioread32be(mmchip-regs + GEF_GPIO_IN)  mask;
+}
+
+static void gef_gpio_set_block(struct gpio_chip *chip,
+  unsigned long mask, unsigned long values)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+   void __iomem *reg = mmchip-regs + GEF_GPIO_OUT;
+   unsigned int data;
+
+   data = ioread32be(reg);
+
+   data = ~mask;
+   data |= values  mask;
+
+   iowrite32be(data, reg);
+}
+
 static int __init gef_gpio_init(void)
 {
struct device_node *np;
@@ -125,6 +148,8 @@ static int __init gef_gpio_init(void

[PATCH RESEND 2/6 v13] gpio: Add sysfs support to block GPIO API

2013-01-15 Thread Roland Stigge
This patch adds sysfs support to the block GPIO API.

Signed-off-by: Roland Stigge sti...@antcom.de

---
 Documentation/ABI/testing/sysfs-gpio |   20 ++
 drivers/gpio/gpiolib.c   |  252 ++-
 include/asm-generic/gpio.h   |   11 +
 include/linux/gpio.h |   15 ++
 4 files changed, 297 insertions(+), 1 deletion(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -25,3 +25,23 @@ Description:
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
 
+What:  /sys/class/gpioblock/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:
+
+  Block GPIO devices are visible in sysfs as soon as they are registered
+  (e.g. via devicetree definition). For actual I/O use, their exported
+  boolean attribute must be set to 1. Then, the attribute values is
+  created and at the same time, the GPIOs in the block are requested for
+  exclusive use by sysfs.
+
+/sys/class/gpioblock
+   /BLOCKNAME ... for each GPIO block name
+   /ngpio ... (r/o) number of GPIOs in this group
+   /exported ... sysfs export state of this group (0, 1)
+   /value ... current value as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
+   /mask ... current mask as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -224,7 +224,8 @@ static bool gpio_block_is_output(struct
int i;
 
for (i = 0; i  block-ngpio; i++)
-   if (!test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
+   if ((block-cur_mask  BIT(i)) 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
return false;
return true;
 }
@@ -1020,6 +1021,240 @@ static void gpiochip_unexport(struct gpi
chip-label, status);
 }
 
+static ssize_t gpio_block_ngpio_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, %u\n, block-ngpio);
+}
+
+static ssize_t gpio_block_value_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? 0x%08lx\n :
+  0x%016lx\n, gpio_block_get(block, block-cur_mask));
+}
+
+static ssize_t gpio_block_value_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   value;
+
+   status = kstrtoul(buf, 0, value);
+   if (status == 0) {
+   mutex_lock(sysfs_lock);
+   if (gpio_block_is_output(block)) {
+   gpio_block_set(block, block-cur_mask, value);
+   status = size;
+   } else {
+   status = -EPERM;
+   }
+   mutex_unlock(sysfs_lock);
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_value = __ATTR(value, S_IWUSR | S_IRUGO, gpio_block_value_show,
+ gpio_block_value_store);
+
+static ssize_t gpio_block_mask_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? 0x%08lx\n :
+  0x%016lx\n, block-cur_mask);
+}
+
+static ssize_t gpio_block_mask_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   mask;
+
+   status = kstrtoul(buf, 0, mask);
+   if (status == 0) {
+   block-cur_mask = mask;
+   status = size;
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_mask = __ATTR(mask, S_IWUSR | S_IRUGO, gpio_block_mask_show,
+gpio_block_mask_store);
+
+static struct class gpio_block_class;
+
+static int gpio_block_value_is_exported(struct gpio_block *block)
+{
+   struct device   *dev;
+   struct sysfs_dirent *sd = NULL;
+
+   mutex_lock(sysfs_lock);
+   dev = class_find_device

[PATCH RESEND 1/6 v13] gpio: Add a block GPIO API to gpiolib

2013-01-15 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal Block GPIO API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge sti...@antcom.de
---

 Documentation/gpio.txt |   58 +++
 drivers/gpio/gpiolib.c |  227 +
 include/asm-generic/gpio.h |   17 +++
 include/linux/gpio.h   |   97 +++
 4 files changed, 399 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -481,6 +481,64 @@ exact name string of pinctrl device has
 argument to this routine.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
+const char *name);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). Similarly, the direction of the used GPIOs need
+to be set by the user before using the block. An arbitrary list of globally
+valid GPIOs can be specified, even ranging over several gpio_chips. Actual
+handling of I/O operations will be done on a best effort base, i.e.
+simultaneous I/O only where possible by hardware and implemented in the
+respective GPIO driver. The number of GPIOs in one block is limited to the
+number of bits in an unsigned long, or BITS_PER_LONG, of the respective
+platform, i.e. typically at least 32 on a 32 bit system, and at least 64 on a
+64 bit system. However, several blocks can be defined at once.
+
+unsigned long gpio_block_get(struct gpio_block *block, unsigned long mask);
+void gpio_block_set(struct gpio_block *block, unsigned long mask,
+   unsigned long values);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). The mask parameters
+specify which bits in the block are acted upon. This is useful to let some bits
+untouched when doing a set operation on the block.
+
+Block operations in hardware are only possible where the respective GPIO driver
+implements it, falling back to using single GPIO operations where the driver
+only implements single GPIO access.
+
+If a GPIO block includes GPIOs from several chips, the chips are handled one
+after another in the order of first specification in the list of GPIOs defined
+in the GPIO block, starting with bit 0. Note that in this case, you typically
+can't assume simultaneous access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via userspace API.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -217,6 +219,16 @@ static int gpio_get_direction(unsigned g
return status;
 }
 
+static bool gpio_block_is_output(struct gpio_block *block)
+{
+   int i;
+
+   for (i = 0; i  block-ngpio; i++)
+   if (!test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
+   return false;
+   return true;
+}
+
 #ifdef CONFIG_GPIO_SYSFS
 
 /* lock protects against unexport_gpio() being called while
@@ -1799,6 +1811,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static struct gpio_block_chip

Re: [PATCH RESEND 6/6 v13] gpio: Add block gpio to several gpio drivers

2013-01-15 Thread Roland Stigge
On 01/15/2013 02:18 PM, Nicolas Ferre wrote:
 --- linux-2.6.orig/drivers/pinctrl/pinctrl-at91.c
 +++ linux-2.6/drivers/pinctrl/pinctrl-at91.c
 @@ -49,6 +49,7 @@ struct at91_gpio_chip {
   struct clk*clock;/* associated clock */
   struct irq_domain*domain;/* associated irq domain */
   struct at91_pinctrl_mux_ops *ops;/* ops */
 +unsigned longmask_cache;/* cached mask for block gpio */
   };

   #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip,
 chip)
 @@ -1125,6 +1126,32 @@ static void at91_gpio_set(struct gpio_ch
   writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
   }

 +static unsigned long at91_gpio_get_block(struct gpio_chip *chip,
 + unsigned long mask)
 +{
 +struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
 +void __iomem *pio = at91_gpio-regbase;
 +u32 pdsr;
 +
 +pdsr = __raw_readl(pio + PIO_PDSR);
 
 Maybe you should use readl_relaxed() here as it is used in the
 at91_gpio_[get|set]() functions.

Thanks for the note! Seem to have missed this when forward porting in
pinctrl-at91.c was due.

Will include the respective change in a subsequent update.

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


[PATCH 6/6 v13] gpio: Add block gpio to several gpio drivers

2012-12-30 Thread Roland Stigge
This patch adds block GPIO support to several gpio drivers.

This implements block GPIO only for some selected drivers since block GPIO is
an optional feature which may not be suitable for every GPIO hardware. (With
automatic fallback to the single GPIO functions if not available in a driver.)

Signed-off-by: Roland Stigge 

---
 drivers/gpio/Kconfig  |2 
 drivers/gpio/gpio-em.c|   23 ++
 drivers/gpio/gpio-ge.c|   29 +
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 +++
 drivers/gpio/gpio-lpc32xx.c   |   82 ++
 drivers/gpio/gpio-max730x.c   |   61 
 drivers/gpio/gpio-max732x.c   |   59 +++
 drivers/gpio/gpio-mc33880.c   |   16 +++
 drivers/gpio/gpio-ml-ioh.c|   27 
 drivers/gpio/gpio-mm-lantiq.c |   22 ++
 drivers/gpio/gpio-mpc5200.c   |   64 +
 drivers/gpio/gpio-mpc8xxx.c   |   41 +++
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 +++
 drivers/gpio/gpio-pch.c   |   27 
 drivers/gpio/gpio-pl061.c |   17 +++
 drivers/gpio/gpio-sa1100.c|   20 +
 drivers/gpio/gpio-samsung.c   |   31 ++
 drivers/gpio/gpio-twl6040.c   |   32 ++
 drivers/gpio/gpio-ucb1400.c   |   23 ++
 drivers/gpio/gpio-vt8500.c|   24 +++
 drivers/gpio/gpio-xilinx.c|   44 
 drivers/pinctrl/pinctrl-at91.c|   29 +
 drivers/pinctrl/pinctrl-nomadik.c |   36 
 25 files changed, 887 insertions(+)

--- linux-2.6.orig/drivers/gpio/Kconfig
+++ linux-2.6/drivers/gpio/Kconfig
@@ -144,11 +144,13 @@ config GPIO_MM_LANTIQ
 config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
+   select BITREVERSE
 
 config GPIO_MPC8XXX
bool "MPC512x/MPC8xxx GPIO support"
depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
   FSL_SOC_BOOKE || PPC_86xx
+   select BITREVERSE
help
  Say Y here if you're going to use hardware that connects to the
  MPC512x/831x/834x/837x/8572/8610 GPIOs.
--- linux-2.6.orig/drivers/gpio/gpio-em.c
+++ linux-2.6/drivers/gpio/gpio-em.c
@@ -202,6 +202,27 @@ static void em_gio_set(struct gpio_chip
__em_gio_set(chip, GIO_OH, offset - 16, value);
 }
 
+static unsigned long em_gio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+   return (int)(em_gio_read(gpio_to_priv(chip), GIO_I) & mask);
+}
+
+static void em_gio_set_block(struct gpio_chip *chip, unsigned long mask,
+unsigned long values)
+{
+   unsigned long mask_ol = mask & 0x;
+   unsigned long mask_oh = mask >> 16;
+
+   unsigned long values_ol = values & mask_ol;
+   unsigned long values_oh = (values >> 16) & mask_oh;
+
+   em_gio_write(gpio_to_priv(chip), GIO_OL,
+mask_ol << 16 | values_ol);
+   em_gio_write(gpio_to_priv(chip), GIO_OH,
+mask_oh << 16 | values_oh);
+}
+
 static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
   int value)
 {
@@ -282,8 +303,10 @@ static int em_gio_probe(struct platform_
gpio_chip = >gpio_chip;
gpio_chip->direction_input = em_gio_direction_input;
gpio_chip->get = em_gio_get;
+   gpio_chip->get_block = em_gio_get_block;
gpio_chip->direction_output = em_gio_direction_output;
gpio_chip->set = em_gio_set;
+   gpio_chip->set_block = em_gio_set_block;
gpio_chip->to_irq = em_gio_to_irq;
gpio_chip->label = name;
gpio_chip->owner = THIS_MODULE;
--- linux-2.6.orig/drivers/gpio/gpio-ge.c
+++ linux-2.6/drivers/gpio/gpio-ge.c
@@ -100,6 +100,29 @@ static void gef_gpio_set(struct gpio_chi
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
 }
 
+static unsigned long gef_gpio_get_block(struct gpio_chip *chip,
+   unsigned long mask)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+
+   return ioread32be(mmchip->regs + GEF_GPIO_IN) & mask;
+}
+
+static void gef_gpio_set_block(struct gpio_chip *chip,
+  unsigned long mask, unsigned long values)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+   void __iomem *reg = mmchip->regs + GEF_GPIO_OUT;
+   unsigned int data;
+
+   data = ioread32be(reg);
+
+   data &= ~mask;
+   data |= values & mask;
+
+   iowrite32be(data, reg);
+}
+
 static in

[PATCH 1/6 v13] gpio: Add a block GPIO API to gpiolib

2012-12-30 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal "Block GPIO" API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge 
---

 Documentation/gpio.txt |   58 +++
 drivers/gpio/gpiolib.c |  227 +
 include/asm-generic/gpio.h |   17 +++
 include/linux/gpio.h   |   97 +++
 4 files changed, 399 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -481,6 +481,64 @@ exact name string of pinctrl device has
 argument to this routine.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
+const char *name);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). Similarly, the direction of the used GPIOs need
+to be set by the user before using the block. An arbitrary list of globally
+valid GPIOs can be specified, even ranging over several gpio_chips. Actual
+handling of I/O operations will be done on a best effort base, i.e.
+simultaneous I/O only where possible by hardware and implemented in the
+respective GPIO driver. The number of GPIOs in one block is limited to the
+number of bits in an unsigned long, or BITS_PER_LONG, of the respective
+platform, i.e. typically at least 32 on a 32 bit system, and at least 64 on a
+64 bit system. However, several blocks can be defined at once.
+
+unsigned long gpio_block_get(struct gpio_block *block, unsigned long mask);
+void gpio_block_set(struct gpio_block *block, unsigned long mask,
+   unsigned long values);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). The mask parameters
+specify which bits in the block are acted upon. This is useful to let some bits
+untouched when doing a set operation on the block.
+
+Block operations in hardware are only possible where the respective GPIO driver
+implements it, falling back to using single GPIO operations where the driver
+only implements single GPIO access.
+
+If a GPIO block includes GPIOs from several chips, the chips are handled one
+after another in the order of first specification in the list of GPIOs defined
+in the GPIO block, starting with bit 0. Note that in this case, you typically
+can't assume simultaneous access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via userspace API.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -217,6 +219,16 @@ static int gpio_get_direction(unsigned g
return status;
 }
 
+static bool gpio_block_is_output(struct gpio_block *block)
+{
+   int i;
+
+   for (i = 0; i < block->ngpio; i++)
+   if (!test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
+   return false;
+   return true;
+}
+
 #ifdef CONFIG_GPIO_SYSFS
 
 /* lock protects against unexport_gpio() being called while
@@ -1799,6 +1811,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static struct gpio_block_chip *

[PATCH 2/6 v13] gpio: Add sysfs support to block GPIO API

2012-12-30 Thread Roland Stigge
This patch adds sysfs support to the block GPIO API.

Signed-off-by: Roland Stigge 

---
 Documentation/ABI/testing/sysfs-gpio |   20 ++
 drivers/gpio/gpiolib.c   |  252 ++-
 include/asm-generic/gpio.h   |   11 +
 include/linux/gpio.h |   15 ++
 4 files changed, 297 insertions(+), 1 deletion(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -25,3 +25,23 @@ Description:
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
 
+What:  /sys/class/gpioblock/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:
+
+  Block GPIO devices are visible in sysfs as soon as they are registered
+  (e.g. via devicetree definition). For actual I/O use, their "exported"
+  boolean attribute must be set to "1". Then, the attribute "values" is
+  created and at the same time, the GPIOs in the block are requested for
+  exclusive use by sysfs.
+
+/sys/class/gpioblock
+   /BLOCKNAME ... for each GPIO block name
+   /ngpio ... (r/o) number of GPIOs in this group
+   /exported ... sysfs export state of this group (0, 1)
+   /value ... current value as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
+   /mask ... current mask as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -224,7 +224,8 @@ static bool gpio_block_is_output(struct
int i;
 
for (i = 0; i < block->ngpio; i++)
-   if (!test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
+   if ((block->cur_mask & BIT(i)) &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags))
return false;
return true;
 }
@@ -1020,6 +1021,240 @@ static void gpiochip_unexport(struct gpi
chip->label, status);
 }
 
+static ssize_t gpio_block_ngpio_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, "%u\n", block->ngpio);
+}
+
+static ssize_t gpio_block_value_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? "0x%08lx\n" :
+  "0x%016lx\n", gpio_block_get(block, block->cur_mask));
+}
+
+static ssize_t gpio_block_value_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   value;
+
+   status = kstrtoul(buf, 0, );
+   if (status == 0) {
+   mutex_lock(_lock);
+   if (gpio_block_is_output(block)) {
+   gpio_block_set(block, block->cur_mask, value);
+   status = size;
+   } else {
+   status = -EPERM;
+   }
+   mutex_unlock(_lock);
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_value = __ATTR(value, S_IWUSR | S_IRUGO, gpio_block_value_show,
+ gpio_block_value_store);
+
+static ssize_t gpio_block_mask_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? "0x%08lx\n" :
+  "0x%016lx\n", block->cur_mask);
+}
+
+static ssize_t gpio_block_mask_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   mask;
+
+   status = kstrtoul(buf, 0, );
+   if (status == 0) {
+   block->cur_mask = mask;
+   status = size;
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_mask = __ATTR(mask, S_IWUSR | S_IRUGO, gpio_block_mask_show,
+gpio_block_mask_store);
+
+static struct class gpio_block_class;
+
+static int gpio_block_value_is_exported(struct gpio_block *block)
+{
+   struct device   *dev;
+   struct sysf

[PATCH 4/6 v13] gpiolib: Fix default attributes for class

2012-12-30 Thread Roland Stigge
There is a race condition between creating a gpio or gpiochip device and adding
default attributes. This patch fixes this by defining the default attributes as
dev_attrs of the class. For this, it was necessary to create a separate
gpiochip_class besides gpio_class.

Signed-off-by: Roland Stigge 
---
 Documentation/ABI/testing/sysfs-gpio |   11 
 drivers/gpio/gpiolib.c   |   78 ++-
 2 files changed, 44 insertions(+), 45 deletions(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -20,6 +20,17 @@ Description:
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
+
+What:  /sys/class/gpiochip/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:
+
+  Each gpiochip is represented by a separate device having the following
+  attributes:
+
+/sys/class/gpiochip
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -362,9 +362,6 @@ static ssize_t gpio_value_store(struct d
return status;
 }
 
-static const DEVICE_ATTR(value, 0644,
-   gpio_value_show, gpio_value_store);
-
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
struct sysfs_dirent *value_sd = priv;
@@ -585,19 +582,6 @@ static ssize_t gpio_active_low_store(str
return status ? : size;
 }
 
-static const DEVICE_ATTR(active_low, 0644,
-   gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
-   _attr_value.attr,
-   _attr_active_low.attr,
-   NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
-   .attrs = (struct attribute **) gpio_attrs,
-};
-
 /*
  * /sys/class/gpio/gpiochipN/
  *   /base ... matching gpio_chip.base (N)
@@ -612,7 +596,6 @@ static ssize_t chip_base_show(struct dev
 
return sprintf(buf, "%d\n", chip->base);
 }
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
 
 static ssize_t chip_label_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -621,7 +604,6 @@ static ssize_t chip_label_show(struct de
 
return sprintf(buf, "%s\n", chip->label ? : "");
 }
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
 
 static ssize_t chip_ngpio_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -630,18 +612,6 @@ static ssize_t chip_ngpio_show(struct de
 
return sprintf(buf, "%u\n", chip->ngpio);
 }
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
-   _attr_base.attr,
-   _attr_label.attr,
-   _attr_ngpio.attr,
-   NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
-   .attrs = (struct attribute **) gpiochip_attrs,
-};
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -720,11 +690,32 @@ static struct class_attribute gpio_class
__ATTR_NULL,
 };
 
+static struct device_attribute gpio_attrs[] = {
+   __ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store),
+   __ATTR(value, 0644, gpio_value_show, gpio_value_store),
+   __ATTR_NULL,
+};
+
 static struct class gpio_class = {
.name = "gpio",
.owner =THIS_MODULE,
 
-   .class_attrs =  gpio_class_attrs,
+   .class_attrs = gpio_class_attrs,
+   .dev_attrs = gpio_attrs,
+};
+
+static struct device_attribute gpiochip_attrs[] = {
+   __ATTR(label, 0444, chip_label_show, NULL),
+   __ATTR(base, 0444, chip_base_show, NULL),
+   __ATTR(ngpio, 0444, chip_ngpio_show, NULL),
+   __ATTR_NULL,
+};
+
+static struct class gpiochip_class = {
+   .name = "gpiochip",
+   .owner =THIS_MODULE,
+
+   .dev_attrs =gpiochip_attrs,
 };
 
 
@@ -791,10 +782,6 @@ int gpio_export(unsigned gpio, bool dire
goto fail_unlock;
}
 
-   status = sysfs_create_group(>kobj, _attr_group);
-   if (status)
-   goto fail_unregister_device;
-
if (direction_may_change) {
status = device_create_file(dev, _attr_direction);
if (status)
@@ -962,25 +949,22 @@ EXPORT_SYMBOL_GPL(gpio_unexport);
 
 static int gpiochip_export(struct gpio_chip *chip)
 {
-   int status;
+   int status = 0;
struct device   *dev;
 
/* Many systems register gpio chips for SOC support very early,
 * before driver model support is available.  In those cases we
 * export this later, in g

[PATCH 0/6 v13] gpio: Add block GPIO

2012-12-30 Thread Roland Stigge
This set of patches adds:

* Block GPIO API to gpiolib
* Sysfs support for GPIO API, to provide userland access
* Device interface for userland access (alternative to sysfs)
* Devicetree support to instantiate GPIO blocks via DT
* Example implementations in several gpio drivers since they need
  special accessor functions for block wise GPIO access (only for some
  selected drivers since the feature is optional and not suitable for
  all GPIO hardware)
* Fix for race condition in gpiolib on device creation

Signed-off-by: Roland Stigge 
Tested by: Wolfgang Grandegger 
--

Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

Changes since v12:
* Added support for gpio drivers ge, ks8695, mc33880, ml-ioh, mpc5200 and
  mpc8xxx
* Added support for pinctrl driver at91

Changes since v11:
* Removed support for at91, since this one is currently in the migration
  process to pinctrl implementation
* Fixed mask setting via sysfs
* Device interface: declare gpio_block_fop_poll() static

Changes since v10:
* gpioblock-of.c: Catch <1 specified GPIOs
* gpioblock-of.c: Fixed memory leak in probe()'s error path
* gpioblock-of.c: Fixed block node's refcount via of_node_put()
* Added driver support for samsung, mm-lantiq and sa1100
* Added driver support for at91 (by Wolfgang Grandegger)
* Added pinctrl driver support for pinctl-nomadik

Changed since v9:
* Changed IRQ flags for device interface's poll() from IRQF_TRIGGER_FALLING
  to IRQF_SHARED
* Use block name on gpio_request
* Added spinlock for ISR manipulated data (dev interface / poll())

Changed since v8:
* Added poll() function to dev interface for IRQ handling
* Fixed gpio_block_register() in case of missing CONFIG_GPIO_SYSFS
* Fixed mask handling in sysfs interface
* Fixed get_user/put_user pointer (cast)

Changes since v7:
* Fixed error in API documentation (name arg missing in prototype)
* Fixed compile error if sysfs is missing: Moved gpio_block_is_output()
  out of sysfs-ifdef
* Added error handling to gpio_block_register()
* Added mask attribute to sysfs (although dev interface exists now)

Changes since v6:
* Changed realloc to list handling
* Added mask to kernel API
* Added device interface as userspace API
* Changed sizeof() to BITS_PER_LONG
* Fixed multiline comment style
* Documented direction setting by the user
* Documented order of handled chips in case of multiple chips in one block

Changes since v5:
* Documented sysfs: elaborated on "exported" and "values" attributes
* Documented sysfs: gpiochip is a separate class now
* Aggregated driver support patches for block gpio into one single patch
* Added gpio block driver support for twl6040 and pch

Changes since v4:
* Documented word width
* Bugfix: export/unexport on register/unregister
* Using default dev_attrs for gpio_block_class
* Fix gpiolib: race condition on device creation
* Added driver support for ucb14500, vt8500, xilinx

Changes since v3:
* Added driver support for pca953x, em, pl061, max732x, pcf857x
* Coding style improvements
* Fixed krealloc memory leak in error case
* sysfs: values in hex
* Register blocks in a list
* Narrowing lock scope
* Use S_IWUSR and S_IRUGO instead of direct octal values
* Use for_each_set_bit()
* Change from unsigned to unsigned long for masks and values

Changes since v2:
* Added sysfs support
* Added devicetree support
* Added support for lpc32xx, generic
* Added functions for GPIO block registration
* Added more error checking
* Bit remapping bugfix

Changes since v1:
* API change to 32/64 bit word, bit masks

Thanks to Ryan Mallon, Linus Walleij, Stijn Devriendt, Jean-Christophe
Plagniol-Villard, Mark Brown, Greg Kroah-Hartman, Grant Likely, Stefan
Roese, Wolfgang Grandegger, Tobias Rutz, Fengguang Wu and Mark Rutland
for reviewing and testing!

Roland Stigge (6):
 gpio: Add a block GPIO API to gpiolib
 gpio: Add sysfs support to block GPIO API
 gpio: Add userland device interface to block GPIO
 gpiolib: Fix default attributes for class
 gpio: Add device tree support to block GPIO API
 gpio: Add block gpio to several gpio drivers

 Documentation/ABI/testing/dev-gpioblock   |   34 
 Documentation/ABI/testing/sysfs-gpio  |   31 
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 
 Documentation/gpio.txt|   58 +
 drivers/gpio/Makefile |1 
 drivers/gpio/gpio-em.c|   23 
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-lpc32xx.c   |   82 +
 drivers/gpio/gpio-max730x.c   |   61 +
 drivers/gpio/gpio-max732x.c   |   59 +
 drivers/gpio/gpio-mm-lantiq.c |   22 
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 
 drivers/gpio/gpio-pch.c   |   27 
 dr

[PATCH 3/6 v13] gpio: Add userland device interface to block GPIO

2012-12-30 Thread Roland Stigge
This patch adds a character device interface to the block GPIO system.

Signed-off-by: Roland Stigge 
---
 Documentation/ABI/testing/dev-gpioblock |   34 
 drivers/gpio/gpiolib.c  |  225 +++-
 include/linux/gpio.h|   13 +
 3 files changed, 271 insertions(+), 1 deletion(-)

--- /dev/null
+++ linux-2.6/Documentation/ABI/testing/dev-gpioblock
@@ -0,0 +1,34 @@
+What:  /dev/
+Date:  Nov 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge 
+Description:   The /dev/ character device node provides userspace
+   access to GPIO blocks, named exactly as the block, e.g.
+   /dev/block0.
+
+   Reading:
+   When reading sizeof(unsigned long) bytes from the device, the
+   current state of the block, masked by the current mask (see
+   below) can be obtained as a word. When the device is opened
+   with O_NONBLOCK, read() always returns with data immediately,
+   otherwise it blocks until data is available, see IRQ handling
+   below.
+
+   Writing:
+   By writing sizeof(unsigned long) bytes to the device, the
+   current state of the block can be set. This operation is
+   masked by the current mask (see below).
+
+   IRQ handling:
+   When one or more IRQs in the block are IRQ capable, you can
+   poll() on the device to check/wait for this IRQ. If no IRQ
+   is available, poll() returns -ENOSYS and userspace needs to
+   (busy) poll itself if necessary.
+
+   Setting the mask (default: all bits set):
+   By doing an ioctl(fd, 0, ) with an unsigned long mask, the
+   current mask for read and write operations on this gpio block
+   can be set.
+
+   See also Documentation/gpio.txt for an explanation of block
+   GPIO.
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -11,6 +11,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define CREATE_TRACE_POINTS
 #include 
@@ -2243,6 +2245,207 @@ struct gpio_block *gpio_block_find_by_na
 }
 EXPORT_SYMBOL_GPL(gpio_block_find_by_name);
 
+static struct gpio_block *gpio_block_find_by_minor(int minor)
+{
+   struct gpio_block *i;
+
+   list_for_each_entry(i, _block_list, list)
+   if (i->miscdev.minor == minor)
+   return i;
+   return NULL;
+}
+
+static bool gpio_block_is_irq_duplicate(struct gpio_block *block, int index)
+{
+   int irq = gpio_to_irq(block->gpio[index]);
+   int i;
+
+   for (i = 0; i < index; i++)
+   if (gpio_to_irq(block->gpio[i]) == irq)
+   return true;
+   return false;
+}
+
+static irqreturn_t gpio_block_irq_handler(int irq, void *dev)
+{
+   struct gpio_block *block = dev;
+
+   wake_up_interruptible(>wait_queue);
+   block->got_int = true;
+
+   return IRQ_HANDLED;
+}
+
+static int gpio_block_fop_open(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = gpio_block_find_by_minor(MINOR(in->i_rdev));
+   int status;
+   int irq;
+
+   if (!block)
+   return -ENOENT;
+
+   block->irq_controlled = false;
+   block->got_int = false;
+   spin_lock_init(>lock);
+   init_waitqueue_head(>wait_queue);
+   f->private_data = block;
+
+   for (i = 0; i < block->ngpio; i++) {
+   status = gpio_request(block->gpio[i], block->name);
+   if (status)
+   goto err1;
+
+   irq = gpio_to_irq(block->gpio[i]);
+   if (irq >= 0 &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags) &&
+   !gpio_block_is_irq_duplicate(block, i)) {
+   status = request_irq(irq, gpio_block_irq_handler,
+IRQF_SHARED,
+block->name, block);
+   if (status)
+   goto err2;
+
+   block->irq_controlled = true;
+   }
+   }
+
+   return 0;
+
+err1:
+   while (i > 0) {
+   i--;
+
+   irq = gpio_to_irq(block->gpio[i]);
+   if (irq >= 0 &&
+   !test_bit(FLAG_IS_OUT, _desc[block->gpio[i]].flags) &&
+   !gpio_block_is_irq_duplicate(block, i))
+   free_irq(irq, block);
+err2:
+   gpio_free(block->gpio[i]);
+   }
+   return status;
+}
+
+static int gpio_block_fop_release(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = (struct gpio_block *)f->

[PATCH 5/6 v13] gpio: Add device tree support to block GPIO API

2012-12-30 Thread Roland Stigge
This patch adds device tree support to the block GPIO API.

Signed-off-by: Roland Stigge 

---
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 ++
 drivers/gpio/Makefile |1 
 drivers/gpio/gpioblock-of.c   |  100 ++
 3 files changed, 137 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be "linux,gpio-block"
+
+Required subnodes:
+- the name will be the registered name of the block
+- property "gpios" is a list of gpios for the respective block
+
+Example:
+
+blockgpio {
+compatible = "linux,gpio-block";
+
+block0 {
+gpios = < 3 0 0>,
+< 3 1 0>;
+};
+block1 {
+gpios = < 4 1 0>,
+< 4 3 0>,
+< 4 2 0>,
+< 4 4 0>,
+< 4 5 0>,
+< 4 6 0>,
+< 4 7 0>,
+< 4 8 0>,
+< 4 9 0>,
+< 4 10 0>,
+< 4 19 0>;
+};
+};
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)+= -DDEBUG
 obj-$(CONFIG_GPIOLIB)  += gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)  += gpiolib-of.o
 obj-$(CONFIG_GPIO_ACPI)+= gpiolib-acpi.o
+obj-$(CONFIG_OF_GPIO)  += gpioblock-of.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,100 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int __devinit gpioblock_of_probe(struct platform_device *pdev)
+{
+   struct device_node *block;
+   unsigned *gpios;
+   int ngpio;
+   int ret;
+   struct gpio_block *gb;
+
+   for_each_available_child_of_node(pdev->dev.of_node, block) {
+   int i;
+
+   ngpio = of_gpio_count(block);
+   if (ngpio < 1) {
+   ret = -ENODEV;
+   goto err1;
+   }
+
+   gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+   if (!gpios) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   for (i = 0; i < ngpio; i++) {
+   ret = of_get_gpio(block, i);
+   if (ret < 0)
+   goto err2; /* expect -EPROBE_DEFER */
+   gpios[i] = ret;
+   }
+   gb = gpio_block_create(gpios, ngpio, block->name);
+   if (IS_ERR(gb)) {
+   dev_err(>dev,
+   "Error creating GPIO block from device tree\n");
+   ret = PTR_ERR(gb);
+   goto err2;
+   }
+   ret = gpio_block_register(gb);
+   if (ret < 0)
+   goto err3;
+
+   kfree(gpios);
+   dev_info(>dev, "Registered gpio block %s: %d gpios\n",
+block->name, ngpio);
+   }
+   return 0;
+
+err3:
+   gpio_block_free(gb);
+err2:
+   kfree(gpios);
+err1:
+   of_node_put(block);
+   return ret;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] __devinitdata = {
+   { .compatible = "linux,gpio-block", },
+   { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+   .driver = {
+   .name = "gpio-block",
+   .owner = THIS_MODULE,
+   .of_match_table = of_match_ptr(gpioblock_of_match),
+
+   },
+   .probe  = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION("GPIO Block driver");

[PATCH 3/6 v13] gpio: Add userland device interface to block GPIO

2012-12-30 Thread Roland Stigge
This patch adds a character device interface to the block GPIO system.

Signed-off-by: Roland Stigge sti...@antcom.de
---
 Documentation/ABI/testing/dev-gpioblock |   34 
 drivers/gpio/gpiolib.c  |  225 +++-
 include/linux/gpio.h|   13 +
 3 files changed, 271 insertions(+), 1 deletion(-)

--- /dev/null
+++ linux-2.6/Documentation/ABI/testing/dev-gpioblock
@@ -0,0 +1,34 @@
+What:  /dev/gpioblock
+Date:  Nov 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:   The /dev/gpioblock character device node provides userspace
+   access to GPIO blocks, named exactly as the block, e.g.
+   /dev/block0.
+
+   Reading:
+   When reading sizeof(unsigned long) bytes from the device, the
+   current state of the block, masked by the current mask (see
+   below) can be obtained as a word. When the device is opened
+   with O_NONBLOCK, read() always returns with data immediately,
+   otherwise it blocks until data is available, see IRQ handling
+   below.
+
+   Writing:
+   By writing sizeof(unsigned long) bytes to the device, the
+   current state of the block can be set. This operation is
+   masked by the current mask (see below).
+
+   IRQ handling:
+   When one or more IRQs in the block are IRQ capable, you can
+   poll() on the device to check/wait for this IRQ. If no IRQ
+   is available, poll() returns -ENOSYS and userspace needs to
+   (busy) poll itself if necessary.
+
+   Setting the mask (default: all bits set):
+   By doing an ioctl(fd, 0, mask) with an unsigned long mask, the
+   current mask for read and write operations on this gpio block
+   can be set.
+
+   See also Documentation/gpio.txt for an explanation of block
+   GPIO.
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -11,6 +11,8 @@
 #include linux/of_gpio.h
 #include linux/idr.h
 #include linux/slab.h
+#include linux/uaccess.h
+#include linux/poll.h
 
 #define CREATE_TRACE_POINTS
 #include trace/events/gpio.h
@@ -2243,6 +2245,207 @@ struct gpio_block *gpio_block_find_by_na
 }
 EXPORT_SYMBOL_GPL(gpio_block_find_by_name);
 
+static struct gpio_block *gpio_block_find_by_minor(int minor)
+{
+   struct gpio_block *i;
+
+   list_for_each_entry(i, gpio_block_list, list)
+   if (i-miscdev.minor == minor)
+   return i;
+   return NULL;
+}
+
+static bool gpio_block_is_irq_duplicate(struct gpio_block *block, int index)
+{
+   int irq = gpio_to_irq(block-gpio[index]);
+   int i;
+
+   for (i = 0; i  index; i++)
+   if (gpio_to_irq(block-gpio[i]) == irq)
+   return true;
+   return false;
+}
+
+static irqreturn_t gpio_block_irq_handler(int irq, void *dev)
+{
+   struct gpio_block *block = dev;
+
+   wake_up_interruptible(block-wait_queue);
+   block-got_int = true;
+
+   return IRQ_HANDLED;
+}
+
+static int gpio_block_fop_open(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = gpio_block_find_by_minor(MINOR(in-i_rdev));
+   int status;
+   int irq;
+
+   if (!block)
+   return -ENOENT;
+
+   block-irq_controlled = false;
+   block-got_int = false;
+   spin_lock_init(block-lock);
+   init_waitqueue_head(block-wait_queue);
+   f-private_data = block;
+
+   for (i = 0; i  block-ngpio; i++) {
+   status = gpio_request(block-gpio[i], block-name);
+   if (status)
+   goto err1;
+
+   irq = gpio_to_irq(block-gpio[i]);
+   if (irq = 0 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags) 
+   !gpio_block_is_irq_duplicate(block, i)) {
+   status = request_irq(irq, gpio_block_irq_handler,
+IRQF_SHARED,
+block-name, block);
+   if (status)
+   goto err2;
+
+   block-irq_controlled = true;
+   }
+   }
+
+   return 0;
+
+err1:
+   while (i  0) {
+   i--;
+
+   irq = gpio_to_irq(block-gpio[i]);
+   if (irq = 0 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags) 
+   !gpio_block_is_irq_duplicate(block, i))
+   free_irq(irq, block);
+err2:
+   gpio_free(block-gpio[i]);
+   }
+   return status;
+}
+
+static int gpio_block_fop_release(struct inode *in, struct file *f)
+{
+   int i;
+   struct gpio_block *block = (struct gpio_block *)f

[PATCH 5/6 v13] gpio: Add device tree support to block GPIO API

2012-12-30 Thread Roland Stigge
This patch adds device tree support to the block GPIO API.

Signed-off-by: Roland Stigge sti...@antcom.de

---
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 ++
 drivers/gpio/Makefile |1 
 drivers/gpio/gpioblock-of.c   |  100 ++
 3 files changed, 137 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be linux,gpio-block
+
+Required subnodes:
+- the name will be the registered name of the block
+- property gpios is a list of gpios for the respective block
+
+Example:
+
+blockgpio {
+compatible = linux,gpio-block;
+
+block0 {
+gpios = gpio 3 0 0,
+gpio 3 1 0;
+};
+block1 {
+gpios = gpio 4 1 0,
+gpio 4 3 0,
+gpio 4 2 0,
+gpio 4 4 0,
+gpio 4 5 0,
+gpio 4 6 0,
+gpio 4 7 0,
+gpio 4 8 0,
+gpio 4 9 0,
+gpio 4 10 0,
+gpio 4 19 0;
+};
+};
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)+= -DDEBUG
 obj-$(CONFIG_GPIOLIB)  += gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)  += gpiolib-of.o
 obj-$(CONFIG_GPIO_ACPI)+= gpiolib-acpi.o
+obj-$(CONFIG_OF_GPIO)  += gpioblock-of.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,100 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge sti...@antcom.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/platform_device.h
+#include linux/gpio.h
+#include linux/of.h
+#include linux/of_gpio.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/err.h
+
+static int __devinit gpioblock_of_probe(struct platform_device *pdev)
+{
+   struct device_node *block;
+   unsigned *gpios;
+   int ngpio;
+   int ret;
+   struct gpio_block *gb;
+
+   for_each_available_child_of_node(pdev-dev.of_node, block) {
+   int i;
+
+   ngpio = of_gpio_count(block);
+   if (ngpio  1) {
+   ret = -ENODEV;
+   goto err1;
+   }
+
+   gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+   if (!gpios) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   for (i = 0; i  ngpio; i++) {
+   ret = of_get_gpio(block, i);
+   if (ret  0)
+   goto err2; /* expect -EPROBE_DEFER */
+   gpios[i] = ret;
+   }
+   gb = gpio_block_create(gpios, ngpio, block-name);
+   if (IS_ERR(gb)) {
+   dev_err(pdev-dev,
+   Error creating GPIO block from device tree\n);
+   ret = PTR_ERR(gb);
+   goto err2;
+   }
+   ret = gpio_block_register(gb);
+   if (ret  0)
+   goto err3;
+
+   kfree(gpios);
+   dev_info(pdev-dev, Registered gpio block %s: %d gpios\n,
+block-name, ngpio);
+   }
+   return 0;
+
+err3:
+   gpio_block_free(gb);
+err2:
+   kfree(gpios);
+err1:
+   of_node_put(block);
+   return ret;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] __devinitdata = {
+   { .compatible = linux,gpio-block, },
+   { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+   .driver = {
+   .name = gpio-block,
+   .owner = THIS_MODULE,
+   .of_match_table = of_match_ptr(gpioblock_of_match),
+
+   },
+   .probe  = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION(GPIO Block driver);
+MODULE_AUTHOR(Roland

[PATCH 0/6 v13] gpio: Add block GPIO

2012-12-30 Thread Roland Stigge
This set of patches adds:

* Block GPIO API to gpiolib
* Sysfs support for GPIO API, to provide userland access
* Device interface for userland access (alternative to sysfs)
* Devicetree support to instantiate GPIO blocks via DT
* Example implementations in several gpio drivers since they need
  special accessor functions for block wise GPIO access (only for some
  selected drivers since the feature is optional and not suitable for
  all GPIO hardware)
* Fix for race condition in gpiolib on device creation

Signed-off-by: Roland Stigge sti...@antcom.de
Tested by: Wolfgang Grandegger w...@grandegger.com
--

Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

Changes since v12:
* Added support for gpio drivers ge, ks8695, mc33880, ml-ioh, mpc5200 and
  mpc8xxx
* Added support for pinctrl driver at91

Changes since v11:
* Removed support for at91, since this one is currently in the migration
  process to pinctrl implementation
* Fixed mask setting via sysfs
* Device interface: declare gpio_block_fop_poll() static

Changes since v10:
* gpioblock-of.c: Catch 1 specified GPIOs
* gpioblock-of.c: Fixed memory leak in probe()'s error path
* gpioblock-of.c: Fixed block node's refcount via of_node_put()
* Added driver support for samsung, mm-lantiq and sa1100
* Added driver support for at91 (by Wolfgang Grandegger)
* Added pinctrl driver support for pinctl-nomadik

Changed since v9:
* Changed IRQ flags for device interface's poll() from IRQF_TRIGGER_FALLING
  to IRQF_SHARED
* Use block name on gpio_request
* Added spinlock for ISR manipulated data (dev interface / poll())

Changed since v8:
* Added poll() function to dev interface for IRQ handling
* Fixed gpio_block_register() in case of missing CONFIG_GPIO_SYSFS
* Fixed mask handling in sysfs interface
* Fixed get_user/put_user pointer (cast)

Changes since v7:
* Fixed error in API documentation (name arg missing in prototype)
* Fixed compile error if sysfs is missing: Moved gpio_block_is_output()
  out of sysfs-ifdef
* Added error handling to gpio_block_register()
* Added mask attribute to sysfs (although dev interface exists now)

Changes since v6:
* Changed realloc to list handling
* Added mask to kernel API
* Added device interface as userspace API
* Changed sizeof() to BITS_PER_LONG
* Fixed multiline comment style
* Documented direction setting by the user
* Documented order of handled chips in case of multiple chips in one block

Changes since v5:
* Documented sysfs: elaborated on exported and values attributes
* Documented sysfs: gpiochip is a separate class now
* Aggregated driver support patches for block gpio into one single patch
* Added gpio block driver support for twl6040 and pch

Changes since v4:
* Documented word width
* Bugfix: export/unexport on register/unregister
* Using default dev_attrs for gpio_block_class
* Fix gpiolib: race condition on device creation
* Added driver support for ucb14500, vt8500, xilinx

Changes since v3:
* Added driver support for pca953x, em, pl061, max732x, pcf857x
* Coding style improvements
* Fixed krealloc memory leak in error case
* sysfs: values in hex
* Register blocks in a list
* Narrowing lock scope
* Use S_IWUSR and S_IRUGO instead of direct octal values
* Use for_each_set_bit()
* Change from unsigned to unsigned long for masks and values

Changes since v2:
* Added sysfs support
* Added devicetree support
* Added support for lpc32xx, generic
* Added functions for GPIO block registration
* Added more error checking
* Bit remapping bugfix

Changes since v1:
* API change to 32/64 bit word, bit masks

Thanks to Ryan Mallon, Linus Walleij, Stijn Devriendt, Jean-Christophe
Plagniol-Villard, Mark Brown, Greg Kroah-Hartman, Grant Likely, Stefan
Roese, Wolfgang Grandegger, Tobias Rutz, Fengguang Wu and Mark Rutland
for reviewing and testing!

Roland Stigge (6):
 gpio: Add a block GPIO API to gpiolib
 gpio: Add sysfs support to block GPIO API
 gpio: Add userland device interface to block GPIO
 gpiolib: Fix default attributes for class
 gpio: Add device tree support to block GPIO API
 gpio: Add block gpio to several gpio drivers

 Documentation/ABI/testing/dev-gpioblock   |   34 
 Documentation/ABI/testing/sysfs-gpio  |   31 
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 
 Documentation/gpio.txt|   58 +
 drivers/gpio/Makefile |1 
 drivers/gpio/gpio-em.c|   23 
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-lpc32xx.c   |   82 +
 drivers/gpio/gpio-max730x.c   |   61 +
 drivers/gpio/gpio-max732x.c   |   59 +
 drivers/gpio/gpio-mm-lantiq.c |   22 
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 
 drivers/gpio/gpio-pch.c   |   27

[PATCH 2/6 v13] gpio: Add sysfs support to block GPIO API

2012-12-30 Thread Roland Stigge
This patch adds sysfs support to the block GPIO API.

Signed-off-by: Roland Stigge sti...@antcom.de

---
 Documentation/ABI/testing/sysfs-gpio |   20 ++
 drivers/gpio/gpiolib.c   |  252 ++-
 include/asm-generic/gpio.h   |   11 +
 include/linux/gpio.h |   15 ++
 4 files changed, 297 insertions(+), 1 deletion(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -25,3 +25,23 @@ Description:
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
 
+What:  /sys/class/gpioblock/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:
+
+  Block GPIO devices are visible in sysfs as soon as they are registered
+  (e.g. via devicetree definition). For actual I/O use, their exported
+  boolean attribute must be set to 1. Then, the attribute values is
+  created and at the same time, the GPIOs in the block are requested for
+  exclusive use by sysfs.
+
+/sys/class/gpioblock
+   /BLOCKNAME ... for each GPIO block name
+   /ngpio ... (r/o) number of GPIOs in this group
+   /exported ... sysfs export state of this group (0, 1)
+   /value ... current value as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
+   /mask ... current mask as 32 or 64 bit integer in hex
+   (only available if /exported is 1)
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -224,7 +224,8 @@ static bool gpio_block_is_output(struct
int i;
 
for (i = 0; i  block-ngpio; i++)
-   if (!test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
+   if ((block-cur_mask  BIT(i)) 
+   !test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
return false;
return true;
 }
@@ -1020,6 +1021,240 @@ static void gpiochip_unexport(struct gpi
chip-label, status);
 }
 
+static ssize_t gpio_block_ngpio_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, %u\n, block-ngpio);
+}
+
+static ssize_t gpio_block_value_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? 0x%08lx\n :
+  0x%016lx\n, gpio_block_get(block, block-cur_mask));
+}
+
+static ssize_t gpio_block_value_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   value;
+
+   status = kstrtoul(buf, 0, value);
+   if (status == 0) {
+   mutex_lock(sysfs_lock);
+   if (gpio_block_is_output(block)) {
+   gpio_block_set(block, block-cur_mask, value);
+   status = size;
+   } else {
+   status = -EPERM;
+   }
+   mutex_unlock(sysfs_lock);
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_value = __ATTR(value, S_IWUSR | S_IRUGO, gpio_block_value_show,
+ gpio_block_value_store);
+
+static ssize_t gpio_block_mask_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   const struct gpio_block *block = dev_get_drvdata(dev);
+
+   return sprintf(buf, sizeof(unsigned long) == 4 ? 0x%08lx\n :
+  0x%016lx\n, block-cur_mask);
+}
+
+static ssize_t gpio_block_mask_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   ssize_t status;
+   struct gpio_block   *block = dev_get_drvdata(dev);
+   unsigned long   mask;
+
+   status = kstrtoul(buf, 0, mask);
+   if (status == 0) {
+   block-cur_mask = mask;
+   status = size;
+   }
+   return status;
+}
+
+static struct device_attribute
+dev_attr_block_mask = __ATTR(mask, S_IWUSR | S_IRUGO, gpio_block_mask_show,
+gpio_block_mask_store);
+
+static struct class gpio_block_class;
+
+static int gpio_block_value_is_exported(struct gpio_block *block)
+{
+   struct device   *dev;
+   struct sysfs_dirent *sd = NULL;
+
+   mutex_lock(sysfs_lock);
+   dev = class_find_device

[PATCH 4/6 v13] gpiolib: Fix default attributes for class

2012-12-30 Thread Roland Stigge
There is a race condition between creating a gpio or gpiochip device and adding
default attributes. This patch fixes this by defining the default attributes as
dev_attrs of the class. For this, it was necessary to create a separate
gpiochip_class besides gpio_class.

Signed-off-by: Roland Stigge sti...@antcom.de
---
 Documentation/ABI/testing/sysfs-gpio |   11 
 drivers/gpio/gpiolib.c   |   78 ++-
 2 files changed, 44 insertions(+), 45 deletions(-)

--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -20,6 +20,17 @@ Description:
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
+
+What:  /sys/class/gpiochip/
+Date:  October 2012
+KernelVersion: 3.7
+Contact:   Roland Stigge sti...@antcom.de
+Description:
+
+  Each gpiochip is represented by a separate device having the following
+  attributes:
+
+/sys/class/gpiochip
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -362,9 +362,6 @@ static ssize_t gpio_value_store(struct d
return status;
 }
 
-static const DEVICE_ATTR(value, 0644,
-   gpio_value_show, gpio_value_store);
-
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
struct sysfs_dirent *value_sd = priv;
@@ -585,19 +582,6 @@ static ssize_t gpio_active_low_store(str
return status ? : size;
 }
 
-static const DEVICE_ATTR(active_low, 0644,
-   gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
-   dev_attr_value.attr,
-   dev_attr_active_low.attr,
-   NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
-   .attrs = (struct attribute **) gpio_attrs,
-};
-
 /*
  * /sys/class/gpio/gpiochipN/
  *   /base ... matching gpio_chip.base (N)
@@ -612,7 +596,6 @@ static ssize_t chip_base_show(struct dev
 
return sprintf(buf, %d\n, chip-base);
 }
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
 
 static ssize_t chip_label_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -621,7 +604,6 @@ static ssize_t chip_label_show(struct de
 
return sprintf(buf, %s\n, chip-label ? : );
 }
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
 
 static ssize_t chip_ngpio_show(struct device *dev,
   struct device_attribute *attr, char *buf)
@@ -630,18 +612,6 @@ static ssize_t chip_ngpio_show(struct de
 
return sprintf(buf, %u\n, chip-ngpio);
 }
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
-   dev_attr_base.attr,
-   dev_attr_label.attr,
-   dev_attr_ngpio.attr,
-   NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
-   .attrs = (struct attribute **) gpiochip_attrs,
-};
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -720,11 +690,32 @@ static struct class_attribute gpio_class
__ATTR_NULL,
 };
 
+static struct device_attribute gpio_attrs[] = {
+   __ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store),
+   __ATTR(value, 0644, gpio_value_show, gpio_value_store),
+   __ATTR_NULL,
+};
+
 static struct class gpio_class = {
.name = gpio,
.owner =THIS_MODULE,
 
-   .class_attrs =  gpio_class_attrs,
+   .class_attrs = gpio_class_attrs,
+   .dev_attrs = gpio_attrs,
+};
+
+static struct device_attribute gpiochip_attrs[] = {
+   __ATTR(label, 0444, chip_label_show, NULL),
+   __ATTR(base, 0444, chip_base_show, NULL),
+   __ATTR(ngpio, 0444, chip_ngpio_show, NULL),
+   __ATTR_NULL,
+};
+
+static struct class gpiochip_class = {
+   .name = gpiochip,
+   .owner =THIS_MODULE,
+
+   .dev_attrs =gpiochip_attrs,
 };
 
 
@@ -791,10 +782,6 @@ int gpio_export(unsigned gpio, bool dire
goto fail_unlock;
}
 
-   status = sysfs_create_group(dev-kobj, gpio_attr_group);
-   if (status)
-   goto fail_unregister_device;
-
if (direction_may_change) {
status = device_create_file(dev, dev_attr_direction);
if (status)
@@ -962,25 +949,22 @@ EXPORT_SYMBOL_GPL(gpio_unexport);
 
 static int gpiochip_export(struct gpio_chip *chip)
 {
-   int status;
+   int status = 0;
struct device   *dev;
 
/* Many systems register gpio chips for SOC support very early,
 * before driver model support is available.  In those cases we
 * export this later, in gpiolib_sysfs_init() ... here

[PATCH 6/6 v13] gpio: Add block gpio to several gpio drivers

2012-12-30 Thread Roland Stigge
This patch adds block GPIO support to several gpio drivers.

This implements block GPIO only for some selected drivers since block GPIO is
an optional feature which may not be suitable for every GPIO hardware. (With
automatic fallback to the single GPIO functions if not available in a driver.)

Signed-off-by: Roland Stigge sti...@antcom.de

---
 drivers/gpio/Kconfig  |2 
 drivers/gpio/gpio-em.c|   23 ++
 drivers/gpio/gpio-ge.c|   29 +
 drivers/gpio/gpio-generic.c   |   56 +
 drivers/gpio/gpio-ks8695.c|   34 +++
 drivers/gpio/gpio-lpc32xx.c   |   82 ++
 drivers/gpio/gpio-max730x.c   |   61 
 drivers/gpio/gpio-max732x.c   |   59 +++
 drivers/gpio/gpio-mc33880.c   |   16 +++
 drivers/gpio/gpio-ml-ioh.c|   27 
 drivers/gpio/gpio-mm-lantiq.c |   22 ++
 drivers/gpio/gpio-mpc5200.c   |   64 +
 drivers/gpio/gpio-mpc8xxx.c   |   41 +++
 drivers/gpio/gpio-pca953x.c   |   64 +
 drivers/gpio/gpio-pcf857x.c   |   24 +++
 drivers/gpio/gpio-pch.c   |   27 
 drivers/gpio/gpio-pl061.c |   17 +++
 drivers/gpio/gpio-sa1100.c|   20 +
 drivers/gpio/gpio-samsung.c   |   31 ++
 drivers/gpio/gpio-twl6040.c   |   32 ++
 drivers/gpio/gpio-ucb1400.c   |   23 ++
 drivers/gpio/gpio-vt8500.c|   24 +++
 drivers/gpio/gpio-xilinx.c|   44 
 drivers/pinctrl/pinctrl-at91.c|   29 +
 drivers/pinctrl/pinctrl-nomadik.c |   36 
 25 files changed, 887 insertions(+)

--- linux-2.6.orig/drivers/gpio/Kconfig
+++ linux-2.6/drivers/gpio/Kconfig
@@ -144,11 +144,13 @@ config GPIO_MM_LANTIQ
 config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
+   select BITREVERSE
 
 config GPIO_MPC8XXX
bool MPC512x/MPC8xxx GPIO support
depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
   FSL_SOC_BOOKE || PPC_86xx
+   select BITREVERSE
help
  Say Y here if you're going to use hardware that connects to the
  MPC512x/831x/834x/837x/8572/8610 GPIOs.
--- linux-2.6.orig/drivers/gpio/gpio-em.c
+++ linux-2.6/drivers/gpio/gpio-em.c
@@ -202,6 +202,27 @@ static void em_gio_set(struct gpio_chip
__em_gio_set(chip, GIO_OH, offset - 16, value);
 }
 
+static unsigned long em_gio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+   return (int)(em_gio_read(gpio_to_priv(chip), GIO_I)  mask);
+}
+
+static void em_gio_set_block(struct gpio_chip *chip, unsigned long mask,
+unsigned long values)
+{
+   unsigned long mask_ol = mask  0x;
+   unsigned long mask_oh = mask  16;
+
+   unsigned long values_ol = values  mask_ol;
+   unsigned long values_oh = (values  16)  mask_oh;
+
+   em_gio_write(gpio_to_priv(chip), GIO_OL,
+mask_ol  16 | values_ol);
+   em_gio_write(gpio_to_priv(chip), GIO_OH,
+mask_oh  16 | values_oh);
+}
+
 static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
   int value)
 {
@@ -282,8 +303,10 @@ static int em_gio_probe(struct platform_
gpio_chip = p-gpio_chip;
gpio_chip-direction_input = em_gio_direction_input;
gpio_chip-get = em_gio_get;
+   gpio_chip-get_block = em_gio_get_block;
gpio_chip-direction_output = em_gio_direction_output;
gpio_chip-set = em_gio_set;
+   gpio_chip-set_block = em_gio_set_block;
gpio_chip-to_irq = em_gio_to_irq;
gpio_chip-label = name;
gpio_chip-owner = THIS_MODULE;
--- linux-2.6.orig/drivers/gpio/gpio-ge.c
+++ linux-2.6/drivers/gpio/gpio-ge.c
@@ -100,6 +100,29 @@ static void gef_gpio_set(struct gpio_chi
_gef_gpio_set(mmchip-regs + GEF_GPIO_OUT, offset, value);
 }
 
+static unsigned long gef_gpio_get_block(struct gpio_chip *chip,
+   unsigned long mask)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+
+   return ioread32be(mmchip-regs + GEF_GPIO_IN)  mask;
+}
+
+static void gef_gpio_set_block(struct gpio_chip *chip,
+  unsigned long mask, unsigned long values)
+{
+   struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+   void __iomem *reg = mmchip-regs + GEF_GPIO_OUT;
+   unsigned int data;
+
+   data = ioread32be(reg);
+
+   data = ~mask;
+   data |= values  mask;
+
+   iowrite32be(data, reg);
+}
+
 static int __init gef_gpio_init(void)
 {
struct device_node *np;
@@ -125,6 +148,8 @@ static int __init gef_gpio_init(void

[PATCH 1/6 v13] gpio: Add a block GPIO API to gpiolib

2012-12-30 Thread Roland Stigge
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.

This patch adds a kernel internal Block GPIO API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.

Signed-off-by: Roland Stigge sti...@antcom.de
---

 Documentation/gpio.txt |   58 +++
 drivers/gpio/gpiolib.c |  227 +
 include/asm-generic/gpio.h |   17 +++
 include/linux/gpio.h   |   97 +++
 4 files changed, 399 insertions(+)

--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -481,6 +481,64 @@ exact name string of pinctrl device has
 argument to this routine.
 
 
+Block GPIO
+--
+
+The above described interface concentrates on handling single GPIOs.  However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size,
+const char *name);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). Similarly, the direction of the used GPIOs need
+to be set by the user before using the block. An arbitrary list of globally
+valid GPIOs can be specified, even ranging over several gpio_chips. Actual
+handling of I/O operations will be done on a best effort base, i.e.
+simultaneous I/O only where possible by hardware and implemented in the
+respective GPIO driver. The number of GPIOs in one block is limited to the
+number of bits in an unsigned long, or BITS_PER_LONG, of the respective
+platform, i.e. typically at least 32 on a 32 bit system, and at least 64 on a
+64 bit system. However, several blocks can be defined at once.
+
+unsigned long gpio_block_get(struct gpio_block *block, unsigned long mask);
+void gpio_block_set(struct gpio_block *block, unsigned long mask,
+   unsigned long values);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). The mask parameters
+specify which bits in the block are acted upon. This is useful to let some bits
+untouched when doing a set operation on the block.
+
+Block operations in hardware are only possible where the respective GPIO driver
+implements it, falling back to using single GPIO operations where the driver
+only implements single GPIO access.
+
+If a GPIO block includes GPIOs from several chips, the chips are handled one
+after another in the order of first specification in the list of GPIOs defined
+in the GPIO block, starting with bit 0. Note that in this case, you typically
+can't assume simultaneous access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via userspace API.
+
+
 What do these conventions omit?
 ===
 One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
 #endif
 }
 
+static LIST_HEAD(gpio_block_list);
+
 /* Warn when drivers omit gpio_request() calls -- legal but ill-advised
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
@@ -217,6 +219,16 @@ static int gpio_get_direction(unsigned g
return status;
 }
 
+static bool gpio_block_is_output(struct gpio_block *block)
+{
+   int i;
+
+   for (i = 0; i  block-ngpio; i++)
+   if (!test_bit(FLAG_IS_OUT, gpio_desc[block-gpio[i]].flags))
+   return false;
+   return true;
+}
+
 #ifdef CONFIG_GPIO_SYSFS
 
 /* lock protects against unexport_gpio() being called while
@@ -1799,6 +1811,221 @@ void __gpio_set_value(unsigned gpio, int
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
 
+static struct gpio_block_chip

Re: [PATCH 0/6 v12] gpio: Add block GPIO

2012-12-29 Thread Roland Stigge
On 29/12/12 13:13, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 13:01 Sat 29 Dec , Roland Stigge wrote:
>> On 29/12/12 11:20, Jean-Christophe PLAGNIOL-VILLARD wrote:
>>> On 17:49 Sun 23 Dec     , Roland Stigge wrote:
>>>> This set of patches adds:
>>>>
>>>> * Block GPIO API to gpiolib
>>>> * Sysfs support for GPIO API, to provide userland access
>>>> * Device interface for userland access (alternative to sysfs)
>>>> * Devicetree support to instantiate GPIO blocks via DT
>>>> * Example implementations in several gpio drivers since they need
>>>>   special accessor functions for block wise GPIO access (only for some
>>>>   selected drivers since the feature is optional and not suitable for
>>>>   all GPIO hardware)
>>>> * Fix for race condition in gpiolib on device creation
>>>>
>>>> Signed-off-by: Roland Stigge 
>>>> Tested by: Wolfgang Grandegger 
>>>> --
>>>>
>>>> Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio
>>>>
>>>> Changes since v11:
>>>> * Removed support for at91, since this one is currently in the migration
>>>>   process to pinctrl implementation
>>> already done for 3.8
>>>
>>> in Linus tree
>>
>> Good, thanks for the note! So we include support for block GPIO in
>> pinctrl-at91.c now.
>>
>> I guess the redundant code in arch/arm/mach-at91/gpio.c will be removed?
> no we keep for non DT platform

So would it be helpful it to maintain/mainline Wolfgang's patch for this
one regarding block GPIO? (Besides patching pinctrl-at91.c?)

Thanks,

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


Re: [PATCH 0/6 v12] gpio: Add block GPIO

2012-12-29 Thread Roland Stigge
Hi,

On 29/12/12 11:20, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 17:49 Sun 23 Dec , Roland Stigge wrote:
>> This set of patches adds:
>>
>> * Block GPIO API to gpiolib
>> * Sysfs support for GPIO API, to provide userland access
>> * Device interface for userland access (alternative to sysfs)
>> * Devicetree support to instantiate GPIO blocks via DT
>> * Example implementations in several gpio drivers since they need
>>   special accessor functions for block wise GPIO access (only for some
>>   selected drivers since the feature is optional and not suitable for
>>   all GPIO hardware)
>> * Fix for race condition in gpiolib on device creation
>>
>> Signed-off-by: Roland Stigge 
>> Tested by: Wolfgang Grandegger 
>> --
>>
>> Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio
>>
>> Changes since v11:
>> * Removed support for at91, since this one is currently in the migration
>>   process to pinctrl implementation
> already done for 3.8
> 
> in Linus tree

Good, thanks for the note! So we include support for block GPIO in
pinctrl-at91.c now.

I guess the redundant code in arch/arm/mach-at91/gpio.c will be removed?

Thanks,

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


Re: [PATCH 0/6 v12] gpio: Add block GPIO

2012-12-29 Thread Roland Stigge
Hi,

On 29/12/12 11:20, Jean-Christophe PLAGNIOL-VILLARD wrote:
 On 17:49 Sun 23 Dec , Roland Stigge wrote:
 This set of patches adds:

 * Block GPIO API to gpiolib
 * Sysfs support for GPIO API, to provide userland access
 * Device interface for userland access (alternative to sysfs)
 * Devicetree support to instantiate GPIO blocks via DT
 * Example implementations in several gpio drivers since they need
   special accessor functions for block wise GPIO access (only for some
   selected drivers since the feature is optional and not suitable for
   all GPIO hardware)
 * Fix for race condition in gpiolib on device creation

 Signed-off-by: Roland Stigge sti...@antcom.de
 Tested by: Wolfgang Grandegger w...@grandegger.com
 --

 Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

 Changes since v11:
 * Removed support for at91, since this one is currently in the migration
   process to pinctrl implementation
 already done for 3.8
 
 in Linus tree

Good, thanks for the note! So we include support for block GPIO in
pinctrl-at91.c now.

I guess the redundant code in arch/arm/mach-at91/gpio.c will be removed?

Thanks,

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


Re: [PATCH 0/6 v12] gpio: Add block GPIO

2012-12-29 Thread Roland Stigge
On 29/12/12 13:13, Jean-Christophe PLAGNIOL-VILLARD wrote:
 On 13:01 Sat 29 Dec , Roland Stigge wrote:
 On 29/12/12 11:20, Jean-Christophe PLAGNIOL-VILLARD wrote:
 On 17:49 Sun 23 Dec , Roland Stigge wrote:
 This set of patches adds:

 * Block GPIO API to gpiolib
 * Sysfs support for GPIO API, to provide userland access
 * Device interface for userland access (alternative to sysfs)
 * Devicetree support to instantiate GPIO blocks via DT
 * Example implementations in several gpio drivers since they need
   special accessor functions for block wise GPIO access (only for some
   selected drivers since the feature is optional and not suitable for
   all GPIO hardware)
 * Fix for race condition in gpiolib on device creation

 Signed-off-by: Roland Stigge sti...@antcom.de
 Tested by: Wolfgang Grandegger w...@grandegger.com
 --

 Testing branch available at: git://git.antcom.de/linux-2.6.git blockgpio

 Changes since v11:
 * Removed support for at91, since this one is currently in the migration
   process to pinctrl implementation
 already done for 3.8

 in Linus tree

 Good, thanks for the note! So we include support for block GPIO in
 pinctrl-at91.c now.

 I guess the redundant code in arch/arm/mach-at91/gpio.c will be removed?
 no we keep for non DT platform

So would it be helpful it to maintain/mainline Wolfgang's patch for this
one regarding block GPIO? (Besides patching pinctrl-at91.c?)

Thanks,

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


  1   2   3   4   5   6   7   >