summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2012-11-05 16:10:33 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2012-11-11 23:35:03 +0100
commit909582caae384418723ccdb00e848f4140257195 (patch)
tree0e6afb4f420f202e7ccc777bce3bd9798f238e14
parent5204e51d30ceb9715e3d690efe84c50e2e9d557d (diff)
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. Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/stmpe.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index e50ebdfeed0f..ba157d45192d 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;