diff options
author | Benoit Cousson <b-cousson@ti.com> | 2011-08-29 10:20:23 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-01-08 18:37:40 -0500 |
commit | aeb5032b3f8b9ab69daa545777433fa94b3494c4 (patch) | |
tree | 70a5ec2e43e0ae6c4e7d5793bf79da61c1ac7bf9 /drivers/mfd | |
parent | 5391b5c645a86d4657c2175acbf21c6461d34849 (diff) |
mfd: twl-core: Add initial DT support for twl4030/twl6030
Add initial device-tree support for twl familly chips.
The current version is missing the regulator entries due
to the lack of DT regulator bindings for the moment.
Only the simple sub-modules that do not depend on
platform_data information can be initialized properly.
Add irqdomain support.
Add documentation for the Texas Instruments TWL Integrated Chip.
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
Cc: Balaji T K <balajitk@ti.com>
Cc: Graeme Gregory <gg@slimlogic.co.uk>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Acked-by: Rob Herring <rob.herring@calxeda.com>
[grant.likely@secretlab.ca: Fix IRQ_DOMAIN dependency in kconfig]
Cc: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mfd/twl-core.c | 51 |
2 files changed, 51 insertions, 2 deletions
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 | ||
201 | config TWL4030_CORE | 201 | config 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 | ||
256 | static struct twl_client twl_modules[TWL_NUM_SLAVES]; | 264 | static struct twl_client twl_modules[TWL_NUM_SLAVES]; |
257 | 265 | ||
266 | static 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 */ |
260 | struct twl_mapping { | 269 | struct 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 | |||
1274 | fail: | 1323 | fail: |
1275 | if (status < 0) | 1324 | if (status < 0) |
1276 | twl_remove(client); | 1325 | twl_remove(client); |