aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2012-07-01 20:02:55 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-07-08 18:16:13 -0400
commitb41511f713ccaef666e450fae8cb18909897fe4e (patch)
tree078c2a625964f7769a1fecc4fa5f6cf24dc2df68
parentbad76991d7847b7877ae797cc79745d82ffd9120 (diff)
mfd: Add irq domain support for max8997 interrupts
Add irq domain support for max8997 interrupts. The reverse mapping method used is linear mapping since the sub-drivers of max8997 such as regulator and charger drivers can use the max8997 irq_domain to get the linux irq number for max8997 interrupts. All uses of irq_base in platform data and max8997 driver private data are removed. Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c4
-rw-r--r--arch/arm/mach-exynos/mach-origen.c1
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/max8997-irq.c62
-rw-r--r--drivers/mfd/max8997.c1
-rw-r--r--include/linux/mfd/max8997-private.h4
-rw-r--r--include/linux/mfd/max8997.h1
7 files changed, 41 insertions, 33 deletions
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 656f8fc9addd..acb58f5cee8d 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1067,12 +1067,8 @@ static struct platform_device nuri_max8903_device = {
1067static void __init nuri_power_init(void) 1067static void __init nuri_power_init(void)
1068{ 1068{
1069 int gpio; 1069 int gpio;
1070 int irq_base = IRQ_GPIO_END + 1;
1071 int ta_en = 0; 1070 int ta_en = 0;
1072 1071
1073 nuri_max8997_pdata.irq_base = irq_base;
1074 irq_base += MAX8997_IRQ_NR;
1075
1076 gpio = EXYNOS4_GPX0(7); 1072 gpio = EXYNOS4_GPX0(7);
1077 gpio_request(gpio, "AP_PMIC_IRQ"); 1073 gpio_request(gpio, "AP_PMIC_IRQ");
1078 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); 1074 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index f5572be9d7bf..3ce403d7cf1c 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -425,7 +425,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
425 .buck1_gpiodvs = false, 425 .buck1_gpiodvs = false,
426 .buck2_gpiodvs = false, 426 .buck2_gpiodvs = false,
427 .buck5_gpiodvs = false, 427 .buck5_gpiodvs = false,
428 .irq_base = IRQ_GPIO_END + 1,
429 428
430 .ignore_gpiodvs_side_effect = true, 429 .ignore_gpiodvs_side_effect = true,
431 .buck125_default_idx = 0x0, 430 .buck125_default_idx = 0x0,
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b3dee92fd3a8..aaa048a437c0 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -464,6 +464,7 @@ config MFD_MAX8997
464 bool "Maxim Semiconductor MAX8997/8966 PMIC Support" 464 bool "Maxim Semiconductor MAX8997/8966 PMIC Support"
465 depends on I2C=y && GENERIC_HARDIRQS 465 depends on I2C=y && GENERIC_HARDIRQS
466 select MFD_CORE 466 select MFD_CORE
467 select IRQ_DOMAIN
467 help 468 help
468 Say yes here to support for Maxim Semiconductor MAX8997/8966. 469 Say yes here to support for Maxim Semiconductor MAX8997/8966.
469 This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic, 470 This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
index 09274cf7c33b..43fa61413e93 100644
--- a/drivers/mfd/max8997-irq.c
+++ b/drivers/mfd/max8997-irq.c
@@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
142static const inline struct max8997_irq_data * 142static const inline struct max8997_irq_data *
143irq_to_max8997_irq(struct max8997_dev *max8997, int irq) 143irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
144{ 144{
145 return &max8997_irqs[irq - max8997->irq_base]; 145 struct irq_data *data = irq_get_irq_data(irq);
146 return &max8997_irqs[data->hwirq];
146} 147}
147 148
148static void max8997_irq_mask(struct irq_data *data) 149static void max8997_irq_mask(struct irq_data *data)
@@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
182 u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {}; 183 u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
183 u8 irq_src; 184 u8 irq_src;
184 int ret; 185 int ret;
185 int i; 186 int i, cur_irq;
186 187
187 ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src); 188 ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
188 if (ret < 0) { 189 if (ret < 0) {
@@ -269,8 +270,11 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
269 270
270 /* Report */ 271 /* Report */
271 for (i = 0; i < MAX8997_IRQ_NR; i++) { 272 for (i = 0; i < MAX8997_IRQ_NR; i++) {
272 if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) 273 if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
273 handle_nested_irq(max8997->irq_base + i); 274 cur_irq = irq_find_mapping(max8997->irq_domain, i);
275 if (cur_irq)
276 handle_nested_irq(cur_irq);
277 }
274 } 278 }
275 279
276 return IRQ_HANDLED; 280 return IRQ_HANDLED;
@@ -278,26 +282,40 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
278 282
279int max8997_irq_resume(struct max8997_dev *max8997) 283int max8997_irq_resume(struct max8997_dev *max8997)
280{ 284{
281 if (max8997->irq && max8997->irq_base) 285 if (max8997->irq && max8997->irq_domain)
282 max8997_irq_thread(max8997->irq_base, max8997); 286 max8997_irq_thread(0, max8997);
287 return 0;
288}
289
290static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
291 irq_hw_number_t hw)
292{
293 struct max8997_dev *max8997 = d->host_data;
294
295 irq_set_chip_data(irq, max8997);
296 irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
297 irq_set_nested_thread(irq, 1);
298#ifdef CONFIG_ARM
299 set_irq_flags(irq, IRQF_VALID);
300#else
301 irq_set_noprobe(irq);
302#endif
283 return 0; 303 return 0;
284} 304}
285 305
306static struct irq_domain_ops max8997_irq_domain_ops = {
307 .map = max8997_irq_domain_map,
308};
309
286int max8997_irq_init(struct max8997_dev *max8997) 310int max8997_irq_init(struct max8997_dev *max8997)
287{ 311{
312 struct irq_domain *domain;
288 int i; 313 int i;
289 int cur_irq;
290 int ret; 314 int ret;
291 u8 val; 315 u8 val;
292 316
293 if (!max8997->irq) { 317 if (!max8997->irq) {
294 dev_warn(max8997->dev, "No interrupt specified.\n"); 318 dev_warn(max8997->dev, "No interrupt specified.\n");
295 max8997->irq_base = 0;
296 return 0;
297 }
298
299 if (!max8997->irq_base) {
300 dev_err(max8997->dev, "No interrupt base specified.\n");
301 return 0; 319 return 0;
302 } 320 }
303 321
@@ -327,19 +345,13 @@ int max8997_irq_init(struct max8997_dev *max8997)
327 true : false; 345 true : false;
328 } 346 }
329 347
330 /* Register with genirq */ 348 domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
331 for (i = 0; i < MAX8997_IRQ_NR; i++) { 349 &max8997_irq_domain_ops, max8997);
332 cur_irq = i + max8997->irq_base; 350 if (!domain) {
333 irq_set_chip_data(cur_irq, max8997); 351 dev_err(max8997->dev, "could not create irq domain\n");
334 irq_set_chip_and_handler(cur_irq, &max8997_irq_chip, 352 return -ENODEV;
335 handle_edge_irq);
336 irq_set_nested_thread(cur_irq, 1);
337#ifdef CONFIG_ARM
338 set_irq_flags(cur_irq, IRQF_VALID);
339#else
340 irq_set_noprobe(cur_irq);
341#endif
342 } 353 }
354 max8997->irq_domain = domain;
343 355
344 ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread, 356 ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
345 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 357 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index 454f4992cfc3..10b629c245b6 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
143 if (!pdata) 143 if (!pdata)
144 goto err; 144 goto err;
145 145
146 max8997->irq_base = pdata->irq_base;
147 max8997->ono = pdata->ono; 146 max8997->ono = pdata->ono;
148 147
149 mutex_init(&max8997->iolock); 148 mutex_init(&max8997->iolock);
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 3f4deb62d6b0..830152cfae33 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -23,6 +23,8 @@
23#define __LINUX_MFD_MAX8997_PRIV_H 23#define __LINUX_MFD_MAX8997_PRIV_H
24 24
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/export.h>
27#include <linux/irqdomain.h>
26 28
27#define MAX8997_REG_INVALID (0xff) 29#define MAX8997_REG_INVALID (0xff)
28 30
@@ -325,7 +327,7 @@ struct max8997_dev {
325 327
326 int irq; 328 int irq;
327 int ono; 329 int ono;
328 int irq_base; 330 struct irq_domain *irq_domain;
329 struct mutex irqlock; 331 struct mutex irqlock;
330 int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; 332 int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
331 int irq_masks_cache[MAX8997_IRQ_GROUP_NR]; 333 int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index b40c08cd30bc..328d8e24b533 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -181,7 +181,6 @@ struct max8997_led_platform_data {
181 181
182struct max8997_platform_data { 182struct max8997_platform_data {
183 /* IRQ */ 183 /* IRQ */
184 int irq_base;
185 int ono; 184 int ono;
186 int wakeup; 185 int wakeup;
187 186