aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mfd/twl-familly.txt47
-rw-r--r--drivers/mfd/Kconfig2
-rw-r--r--drivers/mfd/twl-core.c51
3 files changed, 98 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/mfd/twl-familly.txt b/Documentation/devicetree/bindings/mfd/twl-familly.txt
new file mode 100644
index 000000000000..a66fcf946759
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl-familly.txt
@@ -0,0 +1,47 @@
1Texas Instruments TWL family
2
3The TWLs are Integrated Power Management Chips.
4Some version might contain much more analog function like
5USB transceiver or Audio amplifier.
6These chips are connected to an i2c bus.
7
8
9Required properties:
10- compatible : Must be "ti,twl4030";
11 For Integrated power-management/audio CODEC device used in OMAP3
12 based boards
13- compatible : Must be "ti,twl6030";
14 For Integrated power-management used in OMAP4 based boards
15- interrupts : This i2c device has an IRQ line connected to the main SoC
16- interrupt-controller : Since the twl support several interrupts internally,
17 it is considered as an interrupt controller cascaded to the SoC one.
18- #interrupt-cells = <1>;
19- interrupt-parent : The parent interrupt controller.
20
21Optional node:
22- Child nodes contain in the twl. The twl family is made of several variants
23 that support a different number of features.
24 The children nodes will thus depend of the capability of the variant.
25
26
27Example:
28/*
29 * Integrated Power Management Chip
30 * http://www.ti.com/lit/ds/symlink/twl6030.pdf
31 */
32twl@48 {
33 compatible = "ti,twl6030";
34 reg = <0x48>;
35 interrupts = <39>; /* IRQ_SYS_1N cascaded to gic */
36 interrupt-controller;
37 #interrupt-cells = <1>;
38 interrupt-parent = <&gic>;
39 #address-cells = <1>;
40 #size-cells = <0>;
41
42 twl_rtc {
43 compatible = "ti,twl_rtc";
44 interrupts = <11>;
45 reg = <0>;
46 };
47};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 0f6db32240f4..08a3e087bcea 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -200,7 +200,7 @@ config MENELAUS
200 200
201config TWL4030_CORE 201config TWL4030_CORE
202 bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support" 202 bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
203 depends on I2C=y && GENERIC_HARDIRQS 203 depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN
204 help 204 help
205 Say yes here if you have TWL4030 / TWL6030 family chip on your board. 205 Say yes here if you have TWL4030 / TWL6030 family chip on your board.
206 This core driver provides register access and IRQ handling 206 This core driver provides register access and IRQ handling
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 61e70cfaa774..e04e04ddc15e 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -34,6 +34,11 @@
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/err.h> 36#include <linux/err.h>
37#include <linux/device.h>
38#include <linux/of.h>
39#include <linux/of_irq.h>
40#include <linux/of_platform.h>
41#include <linux/irqdomain.h>
37 42
38#include <linux/regulator/machine.h> 43#include <linux/regulator/machine.h>
39 44
@@ -144,6 +149,9 @@
144 149
145#define TWL_MODULE_LAST TWL4030_MODULE_LAST 150#define TWL_MODULE_LAST TWL4030_MODULE_LAST
146 151
152#define TWL4030_NR_IRQS 8
153#define TWL6030_NR_IRQS 20
154
147/* Base Address defns for twl4030_map[] */ 155/* Base Address defns for twl4030_map[] */
148 156
149/* subchip/slave 0 - USB ID */ 157/* subchip/slave 0 - USB ID */
@@ -255,6 +263,7 @@ struct twl_client {
255 263
256static struct twl_client twl_modules[TWL_NUM_SLAVES]; 264static struct twl_client twl_modules[TWL_NUM_SLAVES];
257 265
266static struct irq_domain domain;
258 267
259/* mapping the module id to slave id and base address */ 268/* mapping the module id to slave id and base address */
260struct twl_mapping { 269struct twl_mapping {
@@ -1183,14 +1192,48 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1183 int status; 1192 int status;
1184 unsigned i; 1193 unsigned i;
1185 struct twl4030_platform_data *pdata = client->dev.platform_data; 1194 struct twl4030_platform_data *pdata = client->dev.platform_data;
1195 struct device_node *node = client->dev.of_node;
1186 u8 temp; 1196 u8 temp;
1187 int ret = 0; 1197 int ret = 0;
1198 int nr_irqs = TWL4030_NR_IRQS;
1199
1200 if ((id->driver_data) & TWL6030_CLASS)
1201 nr_irqs = TWL6030_NR_IRQS;
1202
1203 if (node && !pdata) {
1204 /*
1205 * XXX: Temporary pdata until the information is correctly
1206 * retrieved by every TWL modules from DT.
1207 */
1208 pdata = devm_kzalloc(&client->dev,
1209 sizeof(struct twl4030_platform_data),
1210 GFP_KERNEL);
1211 if (!pdata)
1212 return -ENOMEM;
1213 }
1188 1214
1189 if (!pdata) { 1215 if (!pdata) {
1190 dev_dbg(&client->dev, "no platform data?\n"); 1216 dev_dbg(&client->dev, "no platform data?\n");
1191 return -EINVAL; 1217 return -EINVAL;
1192 } 1218 }
1193 1219
1220 status = irq_alloc_descs(-1, pdata->irq_base, nr_irqs, 0);
1221 if (IS_ERR_VALUE(status)) {
1222 dev_err(&client->dev, "Fail to allocate IRQ descs\n");
1223 return status;
1224 }
1225
1226 pdata->irq_base = status;
1227 pdata->irq_end = pdata->irq_base + nr_irqs;
1228
1229 domain.irq_base = pdata->irq_base;
1230 domain.nr_irq = nr_irqs;
1231#ifdef CONFIG_OF_IRQ
1232 domain.of_node = of_node_get(node);
1233 domain.ops = &irq_domain_simple_ops;
1234#endif
1235 irq_domain_add(&domain);
1236
1194 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { 1237 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
1195 dev_dbg(&client->dev, "can't talk I2C?\n"); 1238 dev_dbg(&client->dev, "can't talk I2C?\n");
1196 return -EIO; 1239 return -EIO;
@@ -1270,7 +1313,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1270 twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); 1313 twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
1271 } 1314 }
1272 1315
1273 status = add_children(pdata, id->driver_data); 1316#ifdef CONFIG_OF_DEVICE
1317 if (node)
1318 status = of_platform_populate(node, NULL, NULL, &client->dev);
1319 else
1320#endif
1321 status = add_children(pdata, id->driver_data);
1322
1274fail: 1323fail:
1275 if (status < 0) 1324 if (status < 0)
1276 twl_remove(client); 1325 twl_remove(client);