aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorBenoit Cousson <b-cousson@ti.com>2011-08-29 10:20:23 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-01-08 18:37:40 -0500
commitaeb5032b3f8b9ab69daa545777433fa94b3494c4 (patch)
tree70a5ec2e43e0ae6c4e7d5793bf79da61c1ac7bf9 /drivers/mfd
parent5391b5c645a86d4657c2175acbf21c6461d34849 (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/Kconfig2
-rw-r--r--drivers/mfd/twl-core.c51
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
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);