aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2012-11-05 10:10:30 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2012-11-11 17:35:03 -0500
commit7da0cbfc54c82eec793ff3d1b23b7a25406c6dba (patch)
tree59548dc5476e9e94f4c7d9ad7ed4f16414ad181b
parent8ae754ebd5edffa0b2a2bafa4879a9ace01d5477 (diff)
mfd: Prevent STMPE from abusing mfd_add_devices' irq_base parameter
Originally IRQ incrementers were provided in some template resource structures for keypad and touchscreen devices. These were passed as IORESOURCE_IRQs to MFD core in the usual way. The true device IRQs were instead added to the irq_base when mfd_add_devices was invoked. This is clearly an abuse of the call, and does not scale when IRQ Domains are brought into play. Before we can provide the STMPE with its own IRQ Domain we must first fix this. This patche keeps most of the driver's structure, keeping the template strategy. However, instead of providing the IRQ as an increment to irq_base, we dynamically populate the IORESOURCE_IRQ with the correct device IRQ. Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/stmpe.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index c94f521f392c..ad13cb00a749 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -310,14 +310,10 @@ static struct mfd_cell stmpe_gpio_cell_noirq = {
310static struct resource stmpe_keypad_resources[] = { 310static struct resource stmpe_keypad_resources[] = {
311 { 311 {
312 .name = "KEYPAD", 312 .name = "KEYPAD",
313 .start = 0,
314 .end = 0,
315 .flags = IORESOURCE_IRQ, 313 .flags = IORESOURCE_IRQ,
316 }, 314 },
317 { 315 {
318 .name = "KEYPAD_OVER", 316 .name = "KEYPAD_OVER",
319 .start = 1,
320 .end = 1,
321 .flags = IORESOURCE_IRQ, 317 .flags = IORESOURCE_IRQ,
322 }, 318 },
323}; 319};
@@ -397,14 +393,10 @@ static struct stmpe_variant_info stmpe801_noirq = {
397static struct resource stmpe_ts_resources[] = { 393static struct resource stmpe_ts_resources[] = {
398 { 394 {
399 .name = "TOUCH_DET", 395 .name = "TOUCH_DET",
400 .start = 0,
401 .end = 0,
402 .flags = IORESOURCE_IRQ, 396 .flags = IORESOURCE_IRQ,
403 }, 397 },
404 { 398 {
405 .name = "FIFO_TH", 399 .name = "FIFO_TH",
406 .start = 1,
407 .end = 1,
408 .flags = IORESOURCE_IRQ, 400 .flags = IORESOURCE_IRQ,
409 }, 401 },
410}; 402};
@@ -959,10 +951,10 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
959} 951}
960 952
961static int __devinit stmpe_add_device(struct stmpe *stmpe, 953static int __devinit stmpe_add_device(struct stmpe *stmpe,
962 struct mfd_cell *cell, int irq) 954 struct mfd_cell *cell)
963{ 955{
964 return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, 956 return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
965 NULL, stmpe->irq_base + irq, NULL); 957 NULL, stmpe->irq_base, NULL);
966} 958}
967 959
968static int __devinit stmpe_devices_init(struct stmpe *stmpe) 960static int __devinit stmpe_devices_init(struct stmpe *stmpe)
@@ -970,7 +962,7 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
970 struct stmpe_variant_info *variant = stmpe->variant; 962 struct stmpe_variant_info *variant = stmpe->variant;
971 unsigned int platform_blocks = stmpe->pdata->blocks; 963 unsigned int platform_blocks = stmpe->pdata->blocks;
972 int ret = -EINVAL; 964 int ret = -EINVAL;
973 int i; 965 int i, j;
974 966
975 for (i = 0; i < variant->num_blocks; i++) { 967 for (i = 0; i < variant->num_blocks; i++) {
976 struct stmpe_variant_block *block = &variant->blocks[i]; 968 struct stmpe_variant_block *block = &variant->blocks[i];
@@ -978,8 +970,17 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
978 if (!(platform_blocks & block->block)) 970 if (!(platform_blocks & block->block))
979 continue; 971 continue;
980 972
973 for (j = 0; j < block->cell->num_resources; j++) {
974 struct resource *res =
975 (struct resource *) &block->cell->resources[j];
976
977 /* Dynamically fill in a variant's IRQ. */
978 if (res->flags & IORESOURCE_IRQ)
979 res->start = res->end = block->irq + j;
980 }
981
981 platform_blocks &= ~block->block; 982 platform_blocks &= ~block->block;
982 ret = stmpe_add_device(stmpe, block->cell, block->irq); 983 ret = stmpe_add_device(stmpe, block->cell);
983 if (ret) 984 if (ret)
984 return ret; 985 return ret;
985 } 986 }