Commit a435ae1d51e2f18414f2a87219fdbe068231e692
Committed by
Samuel Ortiz
1 parent
15e27b1088
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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 |