Commit a435ae1d51e2f18414f2a87219fdbe068231e692

Authored by Lee Jones
Committed by Samuel Ortiz
1 parent 15e27b1088

mfd: Enable the tc3589x for Device Tree

Here we provide a means to probe and extract vital information
from Device Tree when booting with it enabled. Without this
patch sub-devices wouldn't be able to reference the tc3589x
from Device Tree.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 1 changed file with 40 additions and 3 deletions Side-by-side Diff

drivers/mfd/tc3589x.c
... ... @@ -12,6 +12,7 @@
12 12 #include <linux/irqdomain.h>
13 13 #include <linux/slab.h>
14 14 #include <linux/i2c.h>
  15 +#include <linux/of.h>
15 16 #include <linux/mfd/core.h>
16 17 #include <linux/mfd/tc3589x.h>
17 18  
... ... @@ -146,6 +147,7 @@
146 147 .name = "tc3589x-gpio",
147 148 .num_resources = ARRAY_SIZE(gpio_resources),
148 149 .resources = &gpio_resources[0],
  150 + .of_compatible = "tc3589x-gpio",
149 151 },
150 152 };
151 153  
... ... @@ -154,6 +156,7 @@
154 156 .name = "tc3589x-keypad",
155 157 .num_resources = ARRAY_SIZE(keypad_resources),
156 158 .resources = &keypad_resources[0],
  159 + .of_compatible = "tc3589x-keypad",
157 160 },
158 161 };
159 162  
... ... @@ -221,7 +224,7 @@
221 224 .xlate = irq_domain_xlate_twocell,
222 225 };
223 226  
224   -static int tc3589x_irq_init(struct tc3589x *tc3589x)
  227 +static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
225 228 {
226 229 int base = tc3589x->irq_base;
227 230  
... ... @@ -232,7 +235,7 @@
232 235 }
233 236 else {
234 237 tc3589x->domain = irq_domain_add_linear(
235   - NULL, TC3589x_NR_INTERNAL_IRQS,
  238 + np, TC3589x_NR_INTERNAL_IRQS,
236 239 &tc3589x_irq_ops, tc3589x);
237 240 }
238 241  
239 242  
240 243  
... ... @@ -309,13 +312,47 @@
309 312 return ret;
310 313 }
311 314  
  315 +static int tc3589x_of_probe(struct device_node *np,
  316 + struct tc3589x_platform_data *pdata)
  317 +{
  318 + struct device_node *child;
  319 +
  320 + for_each_child_of_node(np, child) {
  321 + if (!strcmp(child->name, "tc3589x_gpio")) {
  322 + pdata->block |= TC3589x_BLOCK_GPIO;
  323 + }
  324 + if (!strcmp(child->name, "tc3589x_keypad")) {
  325 + pdata->block |= TC3589x_BLOCK_KEYPAD;
  326 + }
  327 + }
  328 +
  329 + return 0;
  330 +}
  331 +
312 332 static int __devinit tc3589x_probe(struct i2c_client *i2c,
313 333 const struct i2c_device_id *id)
314 334 {
315 335 struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
  336 + struct device_node *np = i2c->dev.of_node;
316 337 struct tc3589x *tc3589x;
317 338 int ret;
318 339  
  340 + if (!pdata) {
  341 + if (np) {
  342 + pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
  343 + if (!pdata)
  344 + return -ENOMEM;
  345 +
  346 + ret = tc3589x_of_probe(np, pdata);
  347 + if (ret)
  348 + return ret;
  349 + }
  350 + else {
  351 + dev_err(&i2c->dev, "No platform data or DT found\n");
  352 + return -EINVAL;
  353 + }
  354 + }
  355 +
319 356 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
320 357 | I2C_FUNC_SMBUS_I2C_BLOCK))
321 358 return -EIO;
... ... @@ -338,7 +375,7 @@
338 375 if (ret)
339 376 goto out_free;
340 377  
341   - ret = tc3589x_irq_init(tc3589x);
  378 + ret = tc3589x_irq_init(tc3589x, np);
342 379 if (ret)
343 380 goto out_free;
344 381