Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Thomas Abraham and committed by
Samuel Ortiz
b41511f7 bad76991

+41 -33
-4
arch/arm/mach-exynos/mach-nuri.c
··· 1067 1067 static void __init nuri_power_init(void) 1068 1068 { 1069 1069 int gpio; 1070 - int irq_base = IRQ_GPIO_END + 1; 1071 1070 int ta_en = 0; 1072 - 1073 - nuri_max8997_pdata.irq_base = irq_base; 1074 - irq_base += MAX8997_IRQ_NR; 1075 1071 1076 1072 gpio = EXYNOS4_GPX0(7); 1077 1073 gpio_request(gpio, "AP_PMIC_IRQ");
-1
arch/arm/mach-exynos/mach-origen.c
··· 425 425 .buck1_gpiodvs = false, 426 426 .buck2_gpiodvs = false, 427 427 .buck5_gpiodvs = false, 428 - .irq_base = IRQ_GPIO_END + 1, 429 428 430 429 .ignore_gpiodvs_side_effect = true, 431 430 .buck125_default_idx = 0x0,
+1
drivers/mfd/Kconfig
··· 464 464 bool "Maxim Semiconductor MAX8997/8966 PMIC Support" 465 465 depends on I2C=y && GENERIC_HARDIRQS 466 466 select MFD_CORE 467 + select IRQ_DOMAIN 467 468 help 468 469 Say yes here to support for Maxim Semiconductor MAX8997/8966. 469 470 This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
+37 -25
drivers/mfd/max8997-irq.c
··· 142 142 static const inline struct max8997_irq_data * 143 143 irq_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 148 149 static void max8997_irq_mask(struct irq_data *data) ··· 183 182 u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {}; 184 183 u8 irq_src; 185 184 int ret; 186 - int i; 185 + int i, cur_irq; 187 186 188 187 ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src); 189 188 if (ret < 0) { ··· 270 269 271 270 /* Report */ 272 271 for (i = 0; i < MAX8997_IRQ_NR; i++) { 273 - if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) 274 - handle_nested_irq(max8997->irq_base + i); 272 + if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) { 273 + cur_irq = irq_find_mapping(max8997->irq_domain, i); 274 + if (cur_irq) 275 + handle_nested_irq(cur_irq); 276 + } 275 277 } 276 278 277 279 return IRQ_HANDLED; ··· 282 278 283 279 int max8997_irq_resume(struct max8997_dev *max8997) 284 280 { 285 - if (max8997->irq && max8997->irq_base) 286 - max8997_irq_thread(max8997->irq_base, max8997); 281 + if (max8997->irq && max8997->irq_domain) 282 + max8997_irq_thread(0, max8997); 287 283 return 0; 288 284 } 289 285 286 + static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq, 287 + irq_hw_number_t hw) 288 + { 289 + struct max8997_dev *max8997 = d->host_data; 290 + 291 + irq_set_chip_data(irq, max8997); 292 + irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq); 293 + irq_set_nested_thread(irq, 1); 294 + #ifdef CONFIG_ARM 295 + set_irq_flags(irq, IRQF_VALID); 296 + #else 297 + irq_set_noprobe(irq); 298 + #endif 299 + return 0; 300 + } 301 + 302 + static struct irq_domain_ops max8997_irq_domain_ops = { 303 + .map = max8997_irq_domain_map, 304 + }; 305 + 290 306 int max8997_irq_init(struct max8997_dev *max8997) 291 307 { 308 + struct irq_domain *domain; 292 309 int i; 293 - int cur_irq; 294 310 int ret; 295 311 u8 val; 296 312 297 313 if (!max8997->irq) { 298 314 dev_warn(max8997->dev, "No interrupt specified.\n"); 299 - max8997->irq_base = 0; 300 - return 0; 301 - } 302 - 303 - if (!max8997->irq_base) { 304 - dev_err(max8997->dev, "No interrupt base specified.\n"); 305 315 return 0; 306 316 } 307 317 ··· 345 327 true : false; 346 328 } 347 329 348 - /* Register with genirq */ 349 - for (i = 0; i < MAX8997_IRQ_NR; i++) { 350 - cur_irq = i + max8997->irq_base; 351 - irq_set_chip_data(cur_irq, max8997); 352 - irq_set_chip_and_handler(cur_irq, &max8997_irq_chip, 353 - handle_edge_irq); 354 - irq_set_nested_thread(cur_irq, 1); 355 - #ifdef CONFIG_ARM 356 - set_irq_flags(cur_irq, IRQF_VALID); 357 - #else 358 - irq_set_noprobe(cur_irq); 359 - #endif 330 + domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR, 331 + &max8997_irq_domain_ops, max8997); 332 + if (!domain) { 333 + dev_err(max8997->dev, "could not create irq domain\n"); 334 + return -ENODEV; 360 335 } 336 + max8997->irq_domain = domain; 361 337 362 338 ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread, 363 339 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-1
drivers/mfd/max8997.c
··· 143 143 if (!pdata) 144 144 goto err; 145 145 146 - max8997->irq_base = pdata->irq_base; 147 146 max8997->ono = pdata->ono; 148 147 149 148 mutex_init(&max8997->iolock);
+3 -1
include/linux/mfd/max8997-private.h
··· 23 23 #define __LINUX_MFD_MAX8997_PRIV_H 24 24 25 25 #include <linux/i2c.h> 26 + #include <linux/export.h> 27 + #include <linux/irqdomain.h> 26 28 27 29 #define MAX8997_REG_INVALID (0xff) 28 30 ··· 327 325 328 326 int irq; 329 327 int ono; 330 - int irq_base; 328 + struct irq_domain *irq_domain; 331 329 struct mutex irqlock; 332 330 int irq_masks_cur[MAX8997_IRQ_GROUP_NR]; 333 331 int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
-1
include/linux/mfd/max8997.h
··· 181 181 182 182 struct max8997_platform_data { 183 183 /* IRQ */ 184 - int irq_base; 185 184 int ono; 186 185 int wakeup; 187 186