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

mfd: max8998: Add irq domain support

This patch adds irq domain support for max8998 interrupts.

To keep both non-DT and DT worlds happy, simple domain is used, which is
linear when no explicit IRQ base is specified and legacy, with static
mapping, otherwise.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Tomasz Figa and committed by
Samuel Ortiz
443c6ae2 b5c46787

+57 -28
+1
drivers/mfd/Kconfig
··· 363 363 bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support" 364 364 depends on I2C=y && GENERIC_HARDIRQS 365 365 select MFD_CORE 366 + select IRQ_DOMAIN 366 367 help 367 368 Say yes here to support for Maxim Semiconductor MAX8998 and 368 369 National Semiconductor LP3974. This is a Power Management IC.
+40 -25
drivers/mfd/max8998-irq.c
··· 14 14 #include <linux/device.h> 15 15 #include <linux/interrupt.h> 16 16 #include <linux/irq.h> 17 + #include <linux/irqdomain.h> 17 18 #include <linux/mfd/max8998-private.h> 18 19 19 20 struct max8998_irq_data { ··· 100 99 static inline struct max8998_irq_data * 101 100 irq_to_max8998_irq(struct max8998_dev *max8998, int irq) 102 101 { 103 - return &max8998_irqs[irq - max8998->irq_base]; 102 + struct irq_data *data = irq_get_irq_data(irq); 103 + return &max8998_irqs[data->hwirq]; 104 104 } 105 105 106 106 static void max8998_irq_lock(struct irq_data *data) ··· 178 176 179 177 /* Report */ 180 178 for (i = 0; i < MAX8998_IRQ_NR; i++) { 181 - if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) 182 - handle_nested_irq(max8998->irq_base + i); 179 + if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) { 180 + irq = irq_find_mapping(max8998->irq_domain, i); 181 + if (WARN_ON(!irq)) { 182 + disable_irq_nosync(max8998->irq); 183 + return IRQ_NONE; 184 + } 185 + handle_nested_irq(irq); 186 + } 183 187 } 184 188 185 189 return IRQ_HANDLED; ··· 193 185 194 186 int max8998_irq_resume(struct max8998_dev *max8998) 195 187 { 196 - if (max8998->irq && max8998->irq_base) 197 - max8998_irq_thread(max8998->irq_base, max8998); 188 + if (max8998->irq && max8998->irq_domain) 189 + max8998_irq_thread(max8998->irq, max8998); 198 190 return 0; 199 191 } 192 + 193 + static int max8998_irq_domain_map(struct irq_domain *d, unsigned int irq, 194 + irq_hw_number_t hw) 195 + { 196 + struct max8997_dev *max8998 = d->host_data; 197 + 198 + irq_set_chip_data(irq, max8998); 199 + irq_set_chip_and_handler(irq, &max8998_irq_chip, handle_edge_irq); 200 + irq_set_nested_thread(irq, 1); 201 + #ifdef CONFIG_ARM 202 + set_irq_flags(irq, IRQF_VALID); 203 + #else 204 + irq_set_noprobe(irq); 205 + #endif 206 + return 0; 207 + } 208 + 209 + static struct irq_domain_ops max8998_irq_domain_ops = { 210 + .map = max8998_irq_domain_map, 211 + }; 200 212 201 213 int max8998_irq_init(struct max8998_dev *max8998) 202 214 { 203 215 int i; 204 - int cur_irq; 205 216 int ret; 217 + struct irq_domain *domain; 206 218 207 219 if (!max8998->irq) { 208 220 dev_warn(max8998->dev, 209 221 "No interrupt specified, no interrupts\n"); 210 - max8998->irq_base = 0; 211 - return 0; 212 - } 213 - 214 - if (!max8998->irq_base) { 215 - dev_err(max8998->dev, 216 - "No interrupt base specified, no interrupts\n"); 217 222 return 0; 218 223 } 219 224 ··· 242 221 max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff); 243 222 max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff); 244 223 245 - /* register with genirq */ 246 - for (i = 0; i < MAX8998_IRQ_NR; i++) { 247 - cur_irq = i + max8998->irq_base; 248 - irq_set_chip_data(cur_irq, max8998); 249 - irq_set_chip_and_handler(cur_irq, &max8998_irq_chip, 250 - handle_edge_irq); 251 - irq_set_nested_thread(cur_irq, 1); 252 - #ifdef CONFIG_ARM 253 - set_irq_flags(cur_irq, IRQF_VALID); 254 - #else 255 - irq_set_noprobe(cur_irq); 256 - #endif 224 + domain = irq_domain_add_simple(NULL, MAX8998_IRQ_NR, 225 + max8998->irq_base, &max8998_irq_domain_ops, max8998); 226 + if (!domain) { 227 + dev_err(max8998->dev, "could not create irq domain\n"); 228 + return -ENODEV; 257 229 } 230 + max8998->irq_domain = domain; 258 231 259 232 ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread, 260 233 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+11 -1
drivers/rtc/rtc-max8998.c
··· 16 16 #include <linux/i2c.h> 17 17 #include <linux/slab.h> 18 18 #include <linux/bcd.h> 19 + #include <linux/irqdomain.h> 19 20 #include <linux/rtc.h> 20 21 #include <linux/platform_device.h> 21 22 #include <linux/mfd/max8998.h> ··· 265 264 info->dev = &pdev->dev; 266 265 info->max8998 = max8998; 267 266 info->rtc = max8998->rtc; 268 - info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0; 269 267 270 268 platform_set_drvdata(pdev, info); 271 269 ··· 277 277 goto out_rtc; 278 278 } 279 279 280 + if (!max8998->irq_domain) 281 + goto no_irq; 282 + 283 + info->irq = irq_create_mapping(max8998->irq_domain, MAX8998_IRQ_ALARM0); 284 + if (!info->irq) { 285 + dev_warn(&pdev->dev, "Failed to map alarm IRQ\n"); 286 + goto no_irq; 287 + } 288 + 280 289 ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, 281 290 max8998_rtc_alarm_irq, 0, "rtc-alarm0", info); 282 291 ··· 293 284 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", 294 285 info->irq, ret); 295 286 287 + no_irq: 296 288 dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); 297 289 if (pdata && pdata->rtc_delay) { 298 290 info->lp3974_bug_workaround = true;
+4 -1
include/linux/mfd/max8998-private.h
··· 132 132 133 133 #define MAX8998_ENRAMP (1 << 4) 134 134 135 + struct irq_domain; 136 + 135 137 /** 136 138 * struct max8998_dev - max8998 master device for sub-drivers 137 139 * @dev: master device of the chip (can be used to access platform data) ··· 155 153 struct mutex iolock; 156 154 struct mutex irqlock; 157 155 158 - int irq_base; 156 + unsigned int irq_base; 157 + struct irq_domain *irq_domain; 159 158 int irq; 160 159 int ono; 161 160 u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS];
+1 -1
include/linux/mfd/max8998.h
··· 100 100 struct max8998_platform_data { 101 101 struct max8998_regulator_data *regulators; 102 102 int num_regulators; 103 - int irq_base; 103 + unsigned int irq_base; 104 104 int ono; 105 105 bool buck_voltage_lock; 106 106 int buck1_voltage1;