2012-10-05 15:32:01

by Lee Jones

[permalink] [raw]
Subject: [PATCH 00/10] Platform data clean-up and UIB device enablement

In this patch-set we move all Device Tree start-up code from the u8500
board file and into the more persistent db8500 cpu file. This will aid
future endeavours to remove platform code completely from Mainline. We
also enable some of the devices found on the STUIB (User Interface
board), which attaches to some of ST-Ericsson's reference platforms.

.../devicetree/bindings/input/stmpe-keypad.txt | 39 +++++
Documentation/devicetree/bindings/mfd/stmpe.txt | 25 ++++
arch/arm/boot/dts/stuib.dtsi | 40 ++++++
drivers/input/keyboard/stmpe-keypad.c | 67 +++++++--
drivers/mfd/stmpe.c | 152 +++++++++++++-------
drivers/of/of_i2c.c | 3 +
include/linux/mfd/stmpe.h | 2 +
7 files changed, 271 insertions(+), 57 deletions(-)


2012-10-05 15:32:09

by Lee Jones

[permalink] [raw]
Subject: [PATCH 01/10] mfd: Prevent STMPE from abusing mfd_add_devices' irq_base parameter

Originally IRQ incrementers were provided in some template resource
structures for keypad and touchscreen devices. These were passed as
IORESOURCE_IRQs to MFD core in the usual way. The true device IRQs
were instead added to the irq_base when mfd_add_devices was invoked.
This is clearly an abuse of the call, and does not scale when IRQ
Domains are brought into play. Before we can provide the STMPE with
its own IRQ Domain we must first fix this. This patche keeps most
of the driver's structure, keeping the template strategy. However,
instead of providing the IRQ as an increment to irq_base, we
dynamically populate the IORESOURCE_IRQ with the correct device IRQ.

Cc: Samuel Ortiz <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/stmpe.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index c94f521..ad13cb0 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -310,14 +310,10 @@ static struct mfd_cell stmpe_gpio_cell_noirq = {
static struct resource stmpe_keypad_resources[] = {
{
.name = "KEYPAD",
- .start = 0,
- .end = 0,
.flags = IORESOURCE_IRQ,
},
{
.name = "KEYPAD_OVER",
- .start = 1,
- .end = 1,
.flags = IORESOURCE_IRQ,
},
};
@@ -397,14 +393,10 @@ static struct stmpe_variant_info stmpe801_noirq = {
static struct resource stmpe_ts_resources[] = {
{
.name = "TOUCH_DET",
- .start = 0,
- .end = 0,
.flags = IORESOURCE_IRQ,
},
{
.name = "FIFO_TH",
- .start = 1,
- .end = 1,
.flags = IORESOURCE_IRQ,
},
};
@@ -959,10 +951,10 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
}

static int __devinit stmpe_add_device(struct stmpe *stmpe,
- struct mfd_cell *cell, int irq)
+ struct mfd_cell *cell)
{
return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
- NULL, stmpe->irq_base + irq, NULL);
+ NULL, stmpe->irq_base, NULL);
}

static int __devinit stmpe_devices_init(struct stmpe *stmpe)
@@ -970,7 +962,7 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
struct stmpe_variant_info *variant = stmpe->variant;
unsigned int platform_blocks = stmpe->pdata->blocks;
int ret = -EINVAL;
- int i;
+ int i, j;

for (i = 0; i < variant->num_blocks; i++) {
struct stmpe_variant_block *block = &variant->blocks[i];
@@ -978,8 +970,17 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
if (!(platform_blocks & block->block))
continue;

+ for (j = 0; j < block->cell->num_resources; j++) {
+ struct resource *res =
+ (struct resource *) &block->cell->resources[j];
+
+ /* Dynamically fill in a variant's IRQ. */
+ if (res->flags & IORESOURCE_IRQ)
+ res->start = res->end = block->irq + j;
+ }
+
platform_blocks &= ~block->block;
- ret = stmpe_add_device(stmpe, block->cell, block->irq);
+ ret = stmpe_add_device(stmpe, block->cell);
if (ret)
return ret;
}
--
1.7.9.5

2012-10-05 15:32:21

by Lee Jones

[permalink] [raw]
Subject: [PATCH 07/10] input: Enable STMPE keypad driver for Device Tree

This patch allows the STMPE driver to be successfully probed and
initialised when Device Tree support is enabled. Besides the usual
platform data changes, we also separate the process of filling in
the 'in use' pin bitmap, as we have to extract the information from
Device Tree in the DT boot case.

Cc: Dmitry Torokhov <[email protected]>
Cc: [email protected]
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/input/keyboard/stmpe-keypad.c | 67 ++++++++++++++++++++++++++++-----
drivers/mfd/stmpe.c | 1 +
2 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
index 470a877..c722d23 100644
--- a/drivers/input/keyboard/stmpe-keypad.c
+++ b/drivers/input/keyboard/stmpe-keypad.c
@@ -257,19 +257,73 @@ static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
(plat->debounce_ms << 1));
}

+static int stmpe_keypad_fill_used_pins(struct platform_device *pdev,
+ struct stmpe_keypad *keypad,
+ struct stmpe_keypad_platform_data *plat)
+{
+ struct device_node *np = pdev->dev.of_node;
+ unsigned int proplen;
+ const __be32 *prop;
+ int i;
+
+ if (np) {
+ prop = of_get_property(np, "linux,keymap", &proplen);
+ if (!prop) {
+ dev_err(&pdev->dev,
+ "linux,keymap property not defined\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < proplen / sizeof(u32); i++) {
+ unsigned int key = be32_to_cpup(prop + i);
+
+ keypad->cols |= 1 << KEY_COL(key);
+ keypad->rows |= 1 << KEY_ROW(key);
+ }
+ } else {
+ for (i = 0; i < plat->keymap_data->keymap_size; i++) {
+ unsigned int key = plat->keymap_data->keymap[i];
+
+ keypad->cols |= 1 << KEY_COL(key);
+ keypad->rows |= 1 << KEY_ROW(key);
+ }
+ }
+
+ return 0;
+}
+
+static void __devinit stmpe_keypad_of_probe(struct device_node *np,
+ struct stmpe_keypad_platform_data *plat)
+{
+ of_property_read_u32(np, "debounce-interval", &plat->debounce_ms);
+ of_property_read_u32(np, "stericsson,scan-count", &plat->scan_count);
+
+ if (of_get_property(np, "stericsson,no-autorepeat", NULL))
+ plat->no_autorepeat = true;
+}
+
static int __devinit stmpe_keypad_probe(struct platform_device *pdev)
{
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
struct stmpe_keypad_platform_data *plat;
+ struct device_node *np = pdev->dev.of_node;
struct stmpe_keypad *keypad;
struct input_dev *input;
int ret;
int irq;
- int i;

plat = stmpe->pdata->keypad;
- if (!plat)
- return -ENODEV;
+ if (!plat) {
+ if (np) {
+ plat = devm_kzalloc(&pdev->dev,
+ sizeof(*plat), GFP_KERNEL);
+ if (!plat)
+ return -ENOMEM;
+
+ stmpe_keypad_of_probe(np, plat);
+ } else
+ return -ENODEV;
+ }

irq = platform_get_irq(pdev, 0);
if (irq < 0)
@@ -300,12 +354,7 @@ static int __devinit stmpe_keypad_probe(struct platform_device *pdev)
if (!plat->no_autorepeat)
__set_bit(EV_REP, input->evbit);

- for (i = 0; i < plat->keymap_data->keymap_size; i++) {
- unsigned int key = plat->keymap_data->keymap[i];
-
- keypad->cols |= 1 << KEY_COL(key);
- keypad->rows |= 1 << KEY_ROW(key);
- }
+ stmpe_keypad_fill_used_pins(pdev, keypad, plat);

keypad->stmpe = stmpe;
keypad->plat = plat;
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index ba157d4..b03cc64 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -321,6 +321,7 @@ static struct resource stmpe_keypad_resources[] = {

static struct mfd_cell stmpe_keypad_cell = {
.name = "stmpe-keypad",
+ .of_compatible = "st,stmpe-keypad",
.resources = stmpe_keypad_resources,
.num_resources = ARRAY_SIZE(stmpe_keypad_resources),
};
--
1.7.9.5

2012-10-05 15:32:16

by Lee Jones

[permalink] [raw]
Subject: [PATCH 06/10] Documentation: Describe bindings for STMPE Multi-Functional Device driver

Here we add the required documentation for the STMPE Multi-Functional
Device (MFD) Device Tree bindings. It describes all of the bindings
currently supported by the driver.

Cc: Samuel Ortiz <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
Documentation/devicetree/bindings/mfd/stmpe.txt | 25 +++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/stmpe.txt

diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt
new file mode 100644
index 0000000..8f0aeda
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/stmpe.txt
@@ -0,0 +1,25 @@
+* STMPE Multi-Functional Device
+
+Required properties:
+ - compatible : "st,stmpe[811|1601|2401|2403]"
+ - reg : I2C address of the device
+
+Optional properties:
+ - interrupts : The interrupt outputs from the controller
+ - interrupt-controller : Marks the device node as an interrupt controller
+ - interrupt-parent : Specifies which IRQ controller we're connected to
+ - i2c-client-wake : Marks the input device as wakable
+ - st,autosleep-timeout : Valid entries (ms); 4, 16, 32, 64, 128, 256, 512 and 1024
+
+Example:
+
+ stmpe1601: stmpe1601@40 {
+ compatible = "st,stmpe1601";
+ reg = <0x40>;
+ interrupts = <26 0x4>;
+ interrupt-parent = <&gpio6>;
+ interrupt-controller;
+
+ i2c-client-wake;
+ st,autosleep-timeout = <1024>;
+ };
--
1.7.9.5

2012-10-05 15:32:42

by Lee Jones

[permalink] [raw]
Subject: [PATCH 09/10] ARM: ux500: Apply a Device Tree node for the STMPE MFD

Here we apply the STMPE Multi-Functional Device's node to the
ST User Interface Board Device Tree file. It includes all of
the properties required for correct device initialsation.

Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
arch/arm/boot/dts/stuib.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/stuib.dtsi b/arch/arm/boot/dts/stuib.dtsi
index 62f3ecd..b25663c 100644
--- a/arch/arm/boot/dts/stuib.dtsi
+++ b/arch/arm/boot/dts/stuib.dtsi
@@ -11,6 +11,19 @@

/ {
soc-u9500 {
+ i2c@80004000 {
+ stmpe1601: stmpe1601@40 {
+ compatible = "st,stmpe1601";
+ reg = <0x40>;
+ interrupts = <26 0x4>;
+ interrupt-parent = <&gpio6>;
+ interrupt-controller;
+
+ i2c-client-wake;
+ st,autosleep-timeout = <1024>;
+ };
+ };
+
i2c@80110000 {
bu21013_tp@0x5c {
compatible = "rhom,bu21013_tp";
--
1.7.9.5

2012-10-05 15:32:40

by Lee Jones

[permalink] [raw]
Subject: [PATCH 10/10] ARM: ux500: Supply the STMPE keypad Device Tree node to the STUIB DT

This patch allows the STMPE keypad driver to be successfully probed
and initialised during a Device Tree enabled boot sequence. It
contains all of the required properties needed to setup and map
each key on the 6x3 keypad located on the ST User Interface Board.

Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
arch/arm/boot/dts/stuib.dtsi | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/arch/arm/boot/dts/stuib.dtsi b/arch/arm/boot/dts/stuib.dtsi
index b25663c..b492e3e 100644
--- a/arch/arm/boot/dts/stuib.dtsi
+++ b/arch/arm/boot/dts/stuib.dtsi
@@ -21,6 +21,33 @@

i2c-client-wake;
st,autosleep-timeout = <1024>;
+
+ stmpe_keypad {
+ compatible = "st,stmpe-keypad";
+
+ debounce-interval = <64>;
+ stericsson,scan-count = <8>;
+ stericsson,no-autorepeat;
+
+ linux,keymap = <0x205006b
+ 0x4010074
+ 0x3050072
+ 0x1030004
+ 0x502006a
+ 0x500000a
+ 0x5008b
+ 0x706001c
+ 0x405000b
+ 0x6070003
+ 0x3040067
+ 0x303006c
+ 0x60400e7
+ 0x602009e
+ 0x4020073
+ 0x5050002
+ 0x4030069
+ 0x3020008>;
+ };
};
};

--
1.7.9.5

2012-10-05 15:33:28

by Lee Jones

[permalink] [raw]
Subject: [PATCH 08/10] Documentation: Describe bindings for STMPE Keypad driver

Here we add the required documentation for the STMPE Device
Tree bindings. It describes all of the bindings currently
supported by the driver.

Cc: Dmitry Torokhov <[email protected]>
Cc: [email protected]
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
.../devicetree/bindings/input/stmpe-keypad.txt | 39 ++++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/stmpe-keypad.txt

diff --git a/Documentation/devicetree/bindings/input/stmpe-keypad.txt b/Documentation/devicetree/bindings/input/stmpe-keypad.txt
new file mode 100644
index 0000000..e18e2de
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/stmpe-keypad.txt
@@ -0,0 +1,39 @@
+* STMPE Keypad
+
+Required properties:
+ - compatible : "st,stmpe-keypad"
+ - linux,keymap : See ./matrix-keymap.txt
+
+Optional properties:
+ - debounce-interval : Debouncing interval time in milliseconds
+ - stericsson,scan-count : Scanning cycles elapsed before key data is updated
+ - stericsson,no-autorepeat : If specified device will not autorepeat
+
+Example:
+
+ stmpe_keypad {
+ compatible = "st,stmpe-keypad";
+
+ debounce-interval = <64>;
+ stericsson,scan-count = <8>;
+ stericsson,no-autorepeat;
+
+ linux,keymap = <0x205006b
+ 0x4010074
+ 0x3050072
+ 0x1030004
+ 0x502006a
+ 0x500000a
+ 0x5008b
+ 0x706001c
+ 0x405000b
+ 0x6070003
+ 0x3040067
+ 0x303006c
+ 0x60400e7
+ 0x602009e
+ 0x4020073
+ 0x5050002
+ 0x4030069
+ 0x3020008>;
+ };
--
1.7.9.5

2012-10-05 15:34:07

by Lee Jones

[permalink] [raw]
Subject: [PATCH 05/10] mfd: Enable the STMPE MFD for Device Tree

This patch allows the STMPE Multi-Functional Device to be correctly
initialised when booting with Device Tree support enabled. Its
children are specified by the addition of subordinate devices to the
STMPE node in the Device Tree file.

Cc: Samuel Ortiz <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/stmpe.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index e50ebdf..ba157d4 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -885,18 +885,19 @@ static struct irq_domain_ops stmpe_irq_ops = {
.xlate = irq_domain_xlate_twocell,
};

-static int __devinit stmpe_irq_init(struct stmpe *stmpe)
+static int __devinit stmpe_irq_init(struct stmpe *stmpe,
+ struct device_node *np)
{
int base = stmpe->irq_base;
int num_irqs = stmpe->variant->num_irqs;

if (base) {
stmpe->domain = irq_domain_add_legacy(
- NULL, num_irqs, base, 0, &stmpe_irq_ops, stmpe);
+ np, num_irqs, base, 0, &stmpe_irq_ops, stmpe);
}
else {
stmpe->domain = irq_domain_add_linear(
- NULL, num_irqs, &stmpe_irq_ops, stmpe);
+ np, num_irqs, &stmpe_irq_ops, stmpe);
}

if (!stmpe->domain) {
@@ -1016,15 +1017,50 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
return ret;
}

+void __devinit stmpe_of_probe(struct stmpe_platform_data *pdata,
+ struct device_node *np)
+{
+ struct device_node *child;
+
+ of_property_read_u32(np, "st,autosleep-timeout",
+ &pdata->autosleep_timeout);
+
+ pdata->autosleep = (pdata->autosleep_timeout) ? true : false;
+
+ for_each_child_of_node(np, child) {
+ if (!strcmp(child->name, "stmpe_gpio")) {
+ pdata->blocks |= STMPE_BLOCK_GPIO;
+ }
+ if (!strcmp(child->name, "stmpe_keypad")) {
+ pdata->blocks |= STMPE_BLOCK_KEYPAD;
+ }
+ if (!strcmp(child->name, "stmpe_touchscreen")) {
+ pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN;
+ }
+ if (!strcmp(child->name, "stmpe_adc")) {
+ pdata->blocks |= STMPE_BLOCK_ADC;
+ }
+ }
+}
+
/* Called from client specific probe routines */
int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
{
struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
+ struct device_node *np = ci->dev->of_node;
struct stmpe *stmpe;
int ret;

- if (!pdata)
- return -EINVAL;
+ if (!pdata) {
+ if (np) {
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ stmpe_of_probe(pdata, np);
+ } else
+ return -EINVAL;
+ }

stmpe = kzalloc(sizeof(struct stmpe), GFP_KERNEL);
if (!stmpe)
@@ -1080,7 +1116,7 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
goto free_gpio;

if (stmpe->irq >= 0) {
- ret = stmpe_irq_init(stmpe);
+ ret = stmpe_irq_init(stmpe, np);
if (ret)
goto free_gpio;

--
1.7.9.5

2012-10-05 15:32:06

by Lee Jones

[permalink] [raw]
Subject: [PATCH 02/10] mfd: Provide the STMPE driver with its own IRQ domain

The STMPE driver is yet another IRQ controller which requires its
own IRQ domain. So, we provide it with one.

Cc: Samuel Ortiz <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/stmpe.c | 82 +++++++++++++++++++++++++++------------------
include/linux/mfd/stmpe.h | 2 ++
2 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index ad13cb0..5c8d8f2 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/mfd/core.h>
@@ -757,7 +758,9 @@ static irqreturn_t stmpe_irq(int irq, void *data)
int i;

if (variant->id_val == STMPE801_ID) {
- handle_nested_irq(stmpe->irq_base);
+ int base = irq_create_mapping(stmpe->domain, 0);
+
+ handle_nested_irq(base);
return IRQ_HANDLED;
}

@@ -778,8 +781,9 @@ static irqreturn_t stmpe_irq(int irq, void *data)
while (status) {
int bit = __ffs(status);
int line = bank * 8 + bit;
+ int nestedirq = irq_create_mapping(stmpe->domain, line);

- handle_nested_irq(stmpe->irq_base + line);
+ handle_nested_irq(nestedirq);
status &= ~(1 << bit);
}

@@ -820,7 +824,7 @@ static void stmpe_irq_sync_unlock(struct irq_data *data)
static void stmpe_irq_mask(struct irq_data *data)
{
struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
- int offset = data->irq - stmpe->irq_base;
+ int offset = data->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);

@@ -830,7 +834,7 @@ static void stmpe_irq_mask(struct irq_data *data)
static void stmpe_irq_unmask(struct irq_data *data)
{
struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
- int offset = data->irq - stmpe->irq_base;
+ int offset = data->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);

@@ -845,43 +849,62 @@ static struct irq_chip stmpe_irq_chip = {
.irq_unmask = stmpe_irq_unmask,
};

-static int __devinit stmpe_irq_init(struct stmpe *stmpe)
+static int stmpe_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hwirq)
{
+ struct stmpe *stmpe = d->host_data;
struct irq_chip *chip = NULL;
- int num_irqs = stmpe->variant->num_irqs;
- int base = stmpe->irq_base;
- int irq;

if (stmpe->variant->id_val != STMPE801_ID)
chip = &stmpe_irq_chip;

- for (irq = base; irq < base + num_irqs; irq++) {
- irq_set_chip_data(irq, stmpe);
- irq_set_chip_and_handler(irq, chip, handle_edge_irq);
- irq_set_nested_thread(irq, 1);
+ irq_set_chip_data(virq, stmpe);
+ irq_set_chip_and_handler(virq, chip, handle_edge_irq);
+ irq_set_nested_thread(virq, 1);
#ifdef CONFIG_ARM
- set_irq_flags(irq, IRQF_VALID);
+ set_irq_flags(virq, IRQF_VALID);
#else
- irq_set_noprobe(irq);
+ irq_set_noprobe(virq);
#endif
- }

return 0;
}

-static void stmpe_irq_remove(struct stmpe *stmpe)
+static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq)
{
- int num_irqs = stmpe->variant->num_irqs;
- int base = stmpe->irq_base;
- int irq;
-
- for (irq = base; irq < base + num_irqs; irq++) {
#ifdef CONFIG_ARM
- set_irq_flags(irq, 0);
+ set_irq_flags(virq, 0);
#endif
- irq_set_chip_and_handler(irq, NULL, NULL);
- irq_set_chip_data(irq, NULL);
+ irq_set_chip_and_handler(virq, NULL, NULL);
+ irq_set_chip_data(virq, NULL);
+}
+
+static struct irq_domain_ops stmpe_irq_ops = {
+ .map = stmpe_irq_map,
+ .unmap = stmpe_irq_unmap,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static int __devinit stmpe_irq_init(struct stmpe *stmpe)
+{
+ int base = stmpe->irq_base;
+ int num_irqs = stmpe->variant->num_irqs;
+
+ if (base) {
+ stmpe->domain = irq_domain_add_legacy(
+ NULL, num_irqs, base, 0, &stmpe_irq_ops, stmpe);
+ }
+ else {
+ stmpe->domain = irq_domain_add_linear(
+ NULL, num_irqs, &stmpe_irq_ops, stmpe);
+ }
+
+ if (!stmpe->domain) {
+ dev_err(stmpe->dev, "Failed to create irqdomain\n");
+ return -ENOSYS;
}
+
+ return 0;
}

static int __devinit stmpe_chip_init(struct stmpe *stmpe)
@@ -954,7 +977,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe,
struct mfd_cell *cell)
{
return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
- NULL, stmpe->irq_base, NULL);
+ NULL, stmpe->irq_base, stmpe->domain);
}

static int __devinit stmpe_devices_init(struct stmpe *stmpe)
@@ -1067,7 +1090,7 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
if (ret) {
dev_err(stmpe->dev, "failed to request IRQ: %d\n",
ret);
- goto out_removeirq;
+ goto free_gpio;
}
}

@@ -1083,9 +1106,6 @@ out_removedevs:
mfd_remove_devices(stmpe->dev);
if (stmpe->irq >= 0)
free_irq(stmpe->irq, stmpe);
-out_removeirq:
- if (stmpe->irq >= 0)
- stmpe_irq_remove(stmpe);
free_gpio:
if (pdata->irq_over_gpio)
gpio_free(pdata->irq_gpio);
@@ -1098,10 +1118,8 @@ int stmpe_remove(struct stmpe *stmpe)
{
mfd_remove_devices(stmpe->dev);

- if (stmpe->irq >= 0) {
+ if (stmpe->irq >= 0)
free_irq(stmpe->irq, stmpe);
- stmpe_irq_remove(stmpe);
- }

if (stmpe->pdata->irq_over_gpio)
gpio_free(stmpe->pdata->irq_gpio);
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index f8d5b4d..15dac79 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -62,6 +62,7 @@ struct stmpe_client_info;
* @lock: lock protecting I/O operations
* @irq_lock: IRQ bus lock
* @dev: device, mostly for dev_dbg()
+ * @irq_domain: IRQ domain
* @client: client - i2c or spi
* @ci: client specific information
* @partnum: part number
@@ -79,6 +80,7 @@ struct stmpe {
struct mutex lock;
struct mutex irq_lock;
struct device *dev;
+ struct irq_domain *domain;
void *client;
struct stmpe_client_info *ci;
enum stmpe_partnum partnum;
--
1.7.9.5

2012-10-05 15:34:39

by Lee Jones

[permalink] [raw]
Subject: [PATCH 04/10] of/i2c: Add support for I2C_CLIENT_WAKE when booting with Device Tree

It's important for wakeup sources such as keyboards, power buttons
and the like to identify themselves as wakeup devices. Until now
this has not been possible when platforms are booting via Device
Tree.

Cc: Rob Herring <[email protected]>
Cc: [email protected]
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/of/of_i2c.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 1e173f3..2f20019 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -61,6 +61,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
info.of_node = of_node_get(node);
info.archdata = &dev_ad;

+ if (of_get_property(node, "i2c-client-wake", NULL))
+ info.flags |= I2C_CLIENT_WAKE;
+
request_module("%s%s", I2C_MODULE_PREFIX, info.type);

result = i2c_new_device(adap, &info);
--
1.7.9.5

2012-10-05 15:34:46

by Lee Jones

[permalink] [raw]
Subject: [PATCH 03/10] mfd: Correct copy and paste mistake in stmpe

When specifying IRQ numbers for the stmpe1601, IRQ defines for the
stmpe24xx were used instead. Fortunately, the defined numbers are
the same, hence why it survived testing. This fix is merely an
aesthetic one.

Cc: Samuel Ortiz <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/stmpe.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 5c8d8f2..e50ebdf 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -519,12 +519,12 @@ static const u8 stmpe1601_regs[] = {
static struct stmpe_variant_block stmpe1601_blocks[] = {
{
.cell = &stmpe_gpio_cell,
- .irq = STMPE24XX_IRQ_GPIOC,
+ .irq = STMPE1601_IRQ_GPIOC,
.block = STMPE_BLOCK_GPIO,
},
{
.cell = &stmpe_keypad_cell,
- .irq = STMPE24XX_IRQ_KEYPAD,
+ .irq = STMPE1601_IRQ_KEYPAD,
.block = STMPE_BLOCK_KEYPAD,
},
};
--
1.7.9.5

2012-10-05 18:13:13

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 04/10] of/i2c: Add support for I2C_CLIENT_WAKE when booting with Device Tree

On 10/05/2012 10:31 AM, Lee Jones wrote:
> It's important for wakeup sources such as keyboards, power buttons
> and the like to identify themselves as wakeup devices. Until now
> this has not been possible when platforms are booting via Device
> Tree.

A similar feature from Olof already went in for 3.7.

Rob

> Cc: Rob Herring <[email protected]>
> Cc: [email protected]
> Acked-by: Linus Walleij <[email protected]>
> Signed-off-by: Lee Jones <[email protected]>
> ---
> drivers/of/of_i2c.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> index 1e173f3..2f20019 100644
> --- a/drivers/of/of_i2c.c
> +++ b/drivers/of/of_i2c.c
> @@ -61,6 +61,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
> info.of_node = of_node_get(node);
> info.archdata = &dev_ad;
>
> + if (of_get_property(node, "i2c-client-wake", NULL))
> + info.flags |= I2C_CLIENT_WAKE;
> +
> request_module("%s%s", I2C_MODULE_PREFIX, info.type);
>
> result = i2c_new_device(adap, &info);
>

Subject: Re: [PATCH 04/10] of/i2c: Add support for I2C_CLIENT_WAKE when booting with Device Tree

On 16:31 Fri 05 Oct , Lee Jones wrote:
> It's important for wakeup sources such as keyboards, power buttons
> and the like to identify themselves as wakeup devices. Until now
> this has not been possible when platforms are booting via Device
> Tree.
>
> Cc: Rob Herring <[email protected]>
> Cc: [email protected]
> Acked-by: Linus Walleij <[email protected]>
> Signed-off-by: Lee Jones <[email protected]>
> ---
> drivers/of/of_i2c.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> index 1e173f3..2f20019 100644
> --- a/drivers/of/of_i2c.c
> +++ b/drivers/of/of_i2c.c
> @@ -61,6 +61,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
> info.of_node = of_node_get(node);
> info.archdata = &dev_ad;
>
> + if (of_get_property(node, "i2c-client-wake", NULL))
> + info.flags |= I2C_CLIENT_WAKE;
use of_property_read_bool

Best Regards,
J.

2012-10-05 20:44:15

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 00/10] Platform data clean-up and UIB device enablement

On Friday 05 October 2012, Lee Jones wrote:
> In this patch-set we move all Device Tree start-up code from the u8500
> board file and into the more persistent db8500 cpu file. This will aid
> future endeavours to remove platform code completely from Mainline. We
> also enable some of the devices found on the STUIB (User Interface
> board), which attaches to some of ST-Ericsson's reference platforms.
>

Looks all good to me.

Acked-by: Arnd Bergmann <[email protected]>

2012-10-08 07:33:08

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 04/10] of/i2c: Add support for I2C_CLIENT_WAKE when booting with Device Tree

On Fri, 05 Oct 2012, Rob Herring wrote:

> On 10/05/2012 10:31 AM, Lee Jones wrote:
> > It's important for wakeup sources such as keyboards, power buttons
> > and the like to identify themselves as wakeup devices. Until now
> > this has not been possible when platforms are booting via Device
> > Tree.
>
> A similar feature from Olof already went in for 3.7.

Ah yes, I see it. Thanks Rob.

> > Cc: Rob Herring <[email protected]>
> > Cc: [email protected]
> > Acked-by: Linus Walleij <[email protected]>
> > Signed-off-by: Lee Jones <[email protected]>
> > ---
> > drivers/of/of_i2c.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> > index 1e173f3..2f20019 100644
> > --- a/drivers/of/of_i2c.c
> > +++ b/drivers/of/of_i2c.c
> > @@ -61,6 +61,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
> > info.of_node = of_node_get(node);
> > info.archdata = &dev_ad;
> >
> > + if (of_get_property(node, "i2c-client-wake", NULL))
> > + info.flags |= I2C_CLIENT_WAKE;
> > +
> > request_module("%s%s", I2C_MODULE_PREFIX, info.type);
> >
> > result = i2c_new_device(adap, &info);
> >

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2012-10-10 16:50:14

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 07/10] input: Enable STMPE keypad driver for Device Tree

Hi Lee,

On Fri, Oct 05, 2012 at 04:31:43PM +0100, Lee Jones wrote:
> This patch allows the STMPE driver to be successfully probed and
> initialised when Device Tree support is enabled. Besides the usual
> platform data changes, we also separate the process of filling in
> the 'in use' pin bitmap, as we have to extract the information from
> Device Tree in the DT boot case.


This generally looks OK although I wonder if we could not unify DT and
non-DT case by doing:

for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) {
if (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) {
int code = MATRIX_SCAN_CODE(row, col,
STMPE_KEYPAD_ROW_SHIFT);
if (keypad->keymap[code] != KEY_RESERVED) {
keypad->rows |= 1 << row;
keypad->cols |= 1 << col;
}
}
}

BTW, am I supposed to merge it or ack it?

Thanks!

>
> Cc: Dmitry Torokhov <[email protected]>
> Cc: [email protected]
> Acked-by: Linus Walleij <[email protected]>
> Signed-off-by: Lee Jones <[email protected]>
> ---
> drivers/input/keyboard/stmpe-keypad.c | 67 ++++++++++++++++++++++++++++-----
> drivers/mfd/stmpe.c | 1 +
> 2 files changed, 59 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
> index 470a877..c722d23 100644
> --- a/drivers/input/keyboard/stmpe-keypad.c
> +++ b/drivers/input/keyboard/stmpe-keypad.c
> @@ -257,19 +257,73 @@ static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
> (plat->debounce_ms << 1));
> }
>
> +static int stmpe_keypad_fill_used_pins(struct platform_device *pdev,
> + struct stmpe_keypad *keypad,
> + struct stmpe_keypad_platform_data *plat)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + unsigned int proplen;
> + const __be32 *prop;
> + int i;
> +
> + if (np) {
> + prop = of_get_property(np, "linux,keymap", &proplen);
> + if (!prop) {
> + dev_err(&pdev->dev,
> + "linux,keymap property not defined\n");
> + return -EINVAL;
> + }
> +
> + for (i = 0; i < proplen / sizeof(u32); i++) {
> + unsigned int key = be32_to_cpup(prop + i);
> +
> + keypad->cols |= 1 << KEY_COL(key);
> + keypad->rows |= 1 << KEY_ROW(key);
> + }
> + } else {
> + for (i = 0; i < plat->keymap_data->keymap_size; i++) {
> + unsigned int key = plat->keymap_data->keymap[i];
> +
> + keypad->cols |= 1 << KEY_COL(key);
> + keypad->rows |= 1 << KEY_ROW(key);
> + }
> + }
> +
> + return 0;
> +}
> +
> +static void __devinit stmpe_keypad_of_probe(struct device_node *np,
> + struct stmpe_keypad_platform_data *plat)
> +{
> + of_property_read_u32(np, "debounce-interval", &plat->debounce_ms);
> + of_property_read_u32(np, "stericsson,scan-count", &plat->scan_count);
> +
> + if (of_get_property(np, "stericsson,no-autorepeat", NULL))
> + plat->no_autorepeat = true;
> +}
> +
> static int __devinit stmpe_keypad_probe(struct platform_device *pdev)
> {
> struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
> struct stmpe_keypad_platform_data *plat;
> + struct device_node *np = pdev->dev.of_node;
> struct stmpe_keypad *keypad;
> struct input_dev *input;
> int ret;
> int irq;
> - int i;
>
> plat = stmpe->pdata->keypad;
> - if (!plat)
> - return -ENODEV;
> + if (!plat) {
> + if (np) {
> + plat = devm_kzalloc(&pdev->dev,
> + sizeof(*plat), GFP_KERNEL);
> + if (!plat)
> + return -ENOMEM;
> +
> + stmpe_keypad_of_probe(np, plat);
> + } else
> + return -ENODEV;
> + }
>
> irq = platform_get_irq(pdev, 0);
> if (irq < 0)
> @@ -300,12 +354,7 @@ static int __devinit stmpe_keypad_probe(struct platform_device *pdev)
> if (!plat->no_autorepeat)
> __set_bit(EV_REP, input->evbit);
>
> - for (i = 0; i < plat->keymap_data->keymap_size; i++) {
> - unsigned int key = plat->keymap_data->keymap[i];
> -
> - keypad->cols |= 1 << KEY_COL(key);
> - keypad->rows |= 1 << KEY_ROW(key);
> - }
> + stmpe_keypad_fill_used_pins(pdev, keypad, plat);
>
> keypad->stmpe = stmpe;
> keypad->plat = plat;
> diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> index ba157d4..b03cc64 100644
> --- a/drivers/mfd/stmpe.c
> +++ b/drivers/mfd/stmpe.c
> @@ -321,6 +321,7 @@ static struct resource stmpe_keypad_resources[] = {
>
> static struct mfd_cell stmpe_keypad_cell = {
> .name = "stmpe-keypad",
> + .of_compatible = "st,stmpe-keypad",
> .resources = stmpe_keypad_resources,
> .num_resources = ARRAY_SIZE(stmpe_keypad_resources),
> };
> --
> 1.7.9.5
>

--
Dmitry

2012-10-11 08:10:44

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 07/10] input: Enable STMPE keypad driver for Device Tree

On Wed, 10 Oct 2012, Dmitry Torokhov wrote:

> Hi Lee,
>
> On Fri, Oct 05, 2012 at 04:31:43PM +0100, Lee Jones wrote:
> > This patch allows the STMPE driver to be successfully probed and
> > initialised when Device Tree support is enabled. Besides the usual
> > platform data changes, we also separate the process of filling in
> > the 'in use' pin bitmap, as we have to extract the information from
> > Device Tree in the DT boot case.
>
>
> This generally looks OK although I wonder if we could not unify DT and
> non-DT case by doing:
>
> for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) {
> if (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) {
> int code = MATRIX_SCAN_CODE(row, col,
> STMPE_KEYPAD_ROW_SHIFT);
> if (keypad->keymap[code] != KEY_RESERVED) {
> keypad->rows |= 1 << row;
> keypad->cols |= 1 << col;
> }
> }
> }

Looks like it could work. I have a quite a long TODO list at the
moment, but I will add testing this to it.

> BTW, am I supposed to merge it or ack it?

If you Ack it, I can carry it for you no problem.

> > Cc: Dmitry Torokhov <[email protected]>
> > Cc: [email protected]
> > Acked-by: Linus Walleij <[email protected]>
> > Signed-off-by: Lee Jones <[email protected]>
> > ---
> > drivers/input/keyboard/stmpe-keypad.c | 67 ++++++++++++++++++++++++++++-----
> > drivers/mfd/stmpe.c | 1 +
> > 2 files changed, 59 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
> > index 470a877..c722d23 100644
> > --- a/drivers/input/keyboard/stmpe-keypad.c
> > +++ b/drivers/input/keyboard/stmpe-keypad.c
> > @@ -257,19 +257,73 @@ static int __devinit stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
> > (plat->debounce_ms << 1));
> > }
> >
> > +static int stmpe_keypad_fill_used_pins(struct platform_device *pdev,
> > + struct stmpe_keypad *keypad,
> > + struct stmpe_keypad_platform_data *plat)
> > +{
> > + struct device_node *np = pdev->dev.of_node;
> > + unsigned int proplen;
> > + const __be32 *prop;
> > + int i;
> > +
> > + if (np) {
> > + prop = of_get_property(np, "linux,keymap", &proplen);
> > + if (!prop) {
> > + dev_err(&pdev->dev,
> > + "linux,keymap property not defined\n");
> > + return -EINVAL;
> > + }
> > +
> > + for (i = 0; i < proplen / sizeof(u32); i++) {
> > + unsigned int key = be32_to_cpup(prop + i);
> > +
> > + keypad->cols |= 1 << KEY_COL(key);
> > + keypad->rows |= 1 << KEY_ROW(key);
> > + }
> > + } else {
> > + for (i = 0; i < plat->keymap_data->keymap_size; i++) {
> > + unsigned int key = plat->keymap_data->keymap[i];
> > +
> > + keypad->cols |= 1 << KEY_COL(key);
> > + keypad->rows |= 1 << KEY_ROW(key);
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void __devinit stmpe_keypad_of_probe(struct device_node *np,
> > + struct stmpe_keypad_platform_data *plat)
> > +{
> > + of_property_read_u32(np, "debounce-interval", &plat->debounce_ms);
> > + of_property_read_u32(np, "stericsson,scan-count", &plat->scan_count);
> > +
> > + if (of_get_property(np, "stericsson,no-autorepeat", NULL))
> > + plat->no_autorepeat = true;
> > +}
> > +
> > static int __devinit stmpe_keypad_probe(struct platform_device *pdev)
> > {
> > struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
> > struct stmpe_keypad_platform_data *plat;
> > + struct device_node *np = pdev->dev.of_node;
> > struct stmpe_keypad *keypad;
> > struct input_dev *input;
> > int ret;
> > int irq;
> > - int i;
> >
> > plat = stmpe->pdata->keypad;
> > - if (!plat)
> > - return -ENODEV;
> > + if (!plat) {
> > + if (np) {
> > + plat = devm_kzalloc(&pdev->dev,
> > + sizeof(*plat), GFP_KERNEL);
> > + if (!plat)
> > + return -ENOMEM;
> > +
> > + stmpe_keypad_of_probe(np, plat);
> > + } else
> > + return -ENODEV;
> > + }
> >
> > irq = platform_get_irq(pdev, 0);
> > if (irq < 0)
> > @@ -300,12 +354,7 @@ static int __devinit stmpe_keypad_probe(struct platform_device *pdev)
> > if (!plat->no_autorepeat)
> > __set_bit(EV_REP, input->evbit);
> >
> > - for (i = 0; i < plat->keymap_data->keymap_size; i++) {
> > - unsigned int key = plat->keymap_data->keymap[i];
> > -
> > - keypad->cols |= 1 << KEY_COL(key);
> > - keypad->rows |= 1 << KEY_ROW(key);
> > - }
> > + stmpe_keypad_fill_used_pins(pdev, keypad, plat);
> >
> > keypad->stmpe = stmpe;
> > keypad->plat = plat;
> > diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
> > index ba157d4..b03cc64 100644
> > --- a/drivers/mfd/stmpe.c
> > +++ b/drivers/mfd/stmpe.c
> > @@ -321,6 +321,7 @@ static struct resource stmpe_keypad_resources[] = {
> >
> > static struct mfd_cell stmpe_keypad_cell = {
> > .name = "stmpe-keypad",
> > + .of_compatible = "st,stmpe-keypad",
> > .resources = stmpe_keypad_resources,
> > .num_resources = ARRAY_SIZE(stmpe_keypad_resources),
> > };
> > --
> > 1.7.9.5
> >
>
> --
> Dmitry

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog