1 /* 2 * twl6030-irq.c - TWL6030 irq support 3 * 4 * Copyright (C) 2005-2009 Texas Instruments, Inc. 5 * 6 * Modifications to defer interrupt handling to a kernel thread: 7 * Copyright (C) 2006 MontaVista Software, Inc. 8 * 9 * Based on tlv320aic23.c: 10 * Copyright (c) by Kai Svahn <kai.svahn@nokia.com> 11 * 12 * Code cleanup and modifications to IRQ handler. 13 * by syed khasim <x0khasim@ti.com> 14 * 15 * TWL6030 specific code and IRQ handling changes by 16 * Jagadeesh Bhaskar Pakaravoor <j-pakaravoor@ti.com> 17 * Balaji T K <balajitk@ti.com> 18 * 19 * This program is free software; you can redistribute it and/or modify 20 * it under the terms of the GNU General Public License as published by 21 * the Free Software Foundation; either version 2 of the License, or 22 * (at your option) any later version. 23 * 24 * This program is distributed in the hope that it will be useful, 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * GNU General Public License for more details. 28 * 29 * You should have received a copy of the GNU General Public License 30 * along with this program; if not, write to the Free Software 31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 32 */ 33 34 #include <linux/init.h> 35 #include <linux/export.h> 36 #include <linux/interrupt.h> 37 #include <linux/irq.h> 38 #include <linux/kthread.h> 39 #include <linux/i2c/twl.h> 40 #include <linux/platform_device.h> 41 #include <linux/suspend.h> 42 #include <linux/of.h> 43 #include <linux/irqdomain.h> 44 45 #include "twl-core.h" 46 47 /* 48 * TWL6030 (unlike its predecessors, which had two level interrupt handling) 49 * three interrupt registers INT_STS_A, INT_STS_B and INT_STS_C. 50 * It exposes status bits saying who has raised an interrupt. There are 51 * three mask registers that corresponds to these status registers, that 52 * enables/disables these interrupts. 53 * 54 * We set up IRQs starting at a platform-specified base. An interrupt map table, 55 * specifies mapping between interrupt number and the associated module. 56 */ 57 #define TWL6030_NR_IRQS 20 58 59 static int twl6030_interrupt_mapping[24] = { 60 PWR_INTR_OFFSET, /* Bit 0 PWRON */ 61 PWR_INTR_OFFSET, /* Bit 1 RPWRON */ 62 PWR_INTR_OFFSET, /* Bit 2 BAT_VLOW */ 63 RTC_INTR_OFFSET, /* Bit 3 RTC_ALARM */ 64 RTC_INTR_OFFSET, /* Bit 4 RTC_PERIOD */ 65 HOTDIE_INTR_OFFSET, /* Bit 5 HOT_DIE */ 66 SMPSLDO_INTR_OFFSET, /* Bit 6 VXXX_SHORT */ 67 SMPSLDO_INTR_OFFSET, /* Bit 7 VMMC_SHORT */ 68 69 SMPSLDO_INTR_OFFSET, /* Bit 8 VUSIM_SHORT */ 70 BATDETECT_INTR_OFFSET, /* Bit 9 BAT */ 71 SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */ 72 MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */ 73 RSV_INTR_OFFSET, /* Bit 12 Reserved */ 74 MADC_INTR_OFFSET, /* Bit 13 GPADC_RT_EOC */ 75 MADC_INTR_OFFSET, /* Bit 14 GPADC_SW_EOC */ 76 GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */ 77 78 USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */ 79 USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */ 80 USBOTG_INTR_OFFSET, /* Bit 18 ID */ 81 USB_PRES_INTR_OFFSET, /* Bit 19 VBUS */ 82 CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ 83 CHARGERFAULT_INTR_OFFSET, /* Bit 21 EXT_CHRG */ 84 CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */ 85 RSV_INTR_OFFSET, /* Bit 23 Reserved */ 86 }; 87 /*----------------------------------------------------------------------*/ 88 89 static unsigned twl6030_irq_base; 90 static int twl_irq; 91 static bool twl_irq_wake_enabled; 92 93 static struct completion irq_event; 94 static atomic_t twl6030_wakeirqs = ATOMIC_INIT(0); 95 96 static int twl6030_irq_pm_notifier(struct notifier_block *notifier, 97 unsigned long pm_event, void *unused) 98 { 99 int chained_wakeups; 100 101 switch (pm_event) { 102 case PM_SUSPEND_PREPARE: 103 chained_wakeups = atomic_read(&twl6030_wakeirqs); 104 105 if (chained_wakeups && !twl_irq_wake_enabled) { 106 if (enable_irq_wake(twl_irq)) 107 pr_err("twl6030 IRQ wake enable failed\n"); 108 else 109 twl_irq_wake_enabled = true; 110 } else if (!chained_wakeups && twl_irq_wake_enabled) { 111 disable_irq_wake(twl_irq); 112 twl_irq_wake_enabled = false; 113 } 114 115 disable_irq(twl_irq); 116 break; 117 118 case PM_POST_SUSPEND: 119 enable_irq(twl_irq); 120 break; 121 122 default: 123 break; 124 } 125 126 return NOTIFY_DONE; 127 } 128 129 static struct notifier_block twl6030_irq_pm_notifier_block = { 130 .notifier_call = twl6030_irq_pm_notifier, 131 }; 132 133 /* 134 * This thread processes interrupts reported by the Primary Interrupt Handler. 135 */ 136 static int twl6030_irq_thread(void *data) 137 { 138 long irq = (long)data; 139 static unsigned i2c_errors; 140 static const unsigned max_i2c_errors = 100; 141 int ret; 142 143 while (!kthread_should_stop()) { 144 int i; 145 union { 146 u8 bytes[4]; 147 u32 int_sts; 148 } sts; 149 150 /* Wait for IRQ, then read PIH irq status (also blocking) */ 151 wait_for_completion_interruptible(&irq_event); 152 153 /* read INT_STS_A, B and C in one shot using a burst read */ 154 ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes, 155 REG_INT_STS_A, 3); 156 if (ret) { 157 pr_warning("twl6030: I2C error %d reading PIH ISR\n", 158 ret); 159 if (++i2c_errors >= max_i2c_errors) { 160 printk(KERN_ERR "Maximum I2C error count" 161 " exceeded. Terminating %s.\n", 162 __func__); 163 break; 164 } 165 complete(&irq_event); 166 continue; 167 } 168 169 170 171 sts.bytes[3] = 0; /* Only 24 bits are valid*/ 172 173 /* 174 * Since VBUS status bit is not reliable for VBUS disconnect 175 * use CHARGER VBUS detection status bit instead. 176 */ 177 if (sts.bytes[2] & 0x10) 178 sts.bytes[2] |= 0x08; 179 180 for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) { 181 local_irq_disable(); 182 if (sts.int_sts & 0x1) { 183 int module_irq = twl6030_irq_base + 184 twl6030_interrupt_mapping[i]; 185 generic_handle_irq(module_irq); 186 187 } 188 local_irq_enable(); 189 } 190 191 /* 192 * NOTE: 193 * Simulation confirms that documentation is wrong w.r.t the 194 * interrupt status clear operation. A single *byte* write to 195 * any one of STS_A to STS_C register results in all three 196 * STS registers being reset. Since it does not matter which 197 * value is written, all three registers are cleared on a 198 * single byte write, so we just use 0x0 to clear. 199 */ 200 ret = twl_i2c_write_u8(TWL_MODULE_PIH, 0x00, REG_INT_STS_A); 201 if (ret) 202 pr_warning("twl6030: I2C error in clearing PIH ISR\n"); 203 204 enable_irq(irq); 205 } 206 207 return 0; 208 } 209 210 /* 211 * handle_twl6030_int() is the desc->handle method for the twl6030 interrupt. 212 * This is a chained interrupt, so there is no desc->action method for it. 213 * Now we need to query the interrupt controller in the twl6030 to determine 214 * which module is generating the interrupt request. However, we can't do i2c 215 * transactions in interrupt context, so we must defer that work to a kernel 216 * thread. All we do here is acknowledge and mask the interrupt and wakeup 217 * the kernel thread. 218 */ 219 static irqreturn_t handle_twl6030_pih(int irq, void *devid) 220 { 221 disable_irq_nosync(irq); 222 complete(devid); 223 return IRQ_HANDLED; 224 } 225 226 /*----------------------------------------------------------------------*/ 227 228 static inline void activate_irq(int irq) 229 { 230 #ifdef CONFIG_ARM 231 /* ARM requires an extra step to clear IRQ_NOREQUEST, which it 232 * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE. 233 */ 234 set_irq_flags(irq, IRQF_VALID); 235 #else 236 /* same effect on other architectures */ 237 irq_set_noprobe(irq); 238 #endif 239 } 240 241 static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on) 242 { 243 if (on) 244 atomic_inc(&twl6030_wakeirqs); 245 else 246 atomic_dec(&twl6030_wakeirqs); 247 248 return 0; 249 } 250 251 int twl6030_interrupt_unmask(u8 bit_mask, u8 offset) 252 { 253 int ret; 254 u8 unmask_value; 255 ret = twl_i2c_read_u8(TWL_MODULE_PIH, &unmask_value, 256 REG_INT_STS_A + offset); 257 unmask_value &= (~(bit_mask)); 258 ret |= twl_i2c_write_u8(TWL_MODULE_PIH, unmask_value, 259 REG_INT_STS_A + offset); /* unmask INT_MSK_A/B/C */ 260 return ret; 261 } 262 EXPORT_SYMBOL(twl6030_interrupt_unmask); 263 264 int twl6030_interrupt_mask(u8 bit_mask, u8 offset) 265 { 266 int ret; 267 u8 mask_value; 268 ret = twl_i2c_read_u8(TWL_MODULE_PIH, &mask_value, 269 REG_INT_STS_A + offset); 270 mask_value |= (bit_mask); 271 ret |= twl_i2c_write_u8(TWL_MODULE_PIH, mask_value, 272 REG_INT_STS_A + offset); /* mask INT_MSK_A/B/C */ 273 return ret; 274 } 275 EXPORT_SYMBOL(twl6030_interrupt_mask); 276 277 int twl6030_mmc_card_detect_config(void) 278 { 279 int ret; 280 u8 reg_val = 0; 281 282 /* Unmasking the Card detect Interrupt line for MMC1 from Phoenix */ 283 twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK, 284 REG_INT_MSK_LINE_B); 285 twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK, 286 REG_INT_MSK_STS_B); 287 /* 288 * Initially Configuring MMC_CTRL for receiving interrupts & 289 * Card status on TWL6030 for MMC1 290 */ 291 ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, ®_val, TWL6030_MMCCTRL); 292 if (ret < 0) { 293 pr_err("twl6030: Failed to read MMCCTRL, error %d\n", ret); 294 return ret; 295 } 296 reg_val &= ~VMMC_AUTO_OFF; 297 reg_val |= SW_FC; 298 ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, TWL6030_MMCCTRL); 299 if (ret < 0) { 300 pr_err("twl6030: Failed to write MMCCTRL, error %d\n", ret); 301 return ret; 302 } 303 304 /* Configuring PullUp-PullDown register */ 305 ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, ®_val, 306 TWL6030_CFG_INPUT_PUPD3); 307 if (ret < 0) { 308 pr_err("twl6030: Failed to read CFG_INPUT_PUPD3, error %d\n", 309 ret); 310 return ret; 311 } 312 reg_val &= ~(MMC_PU | MMC_PD); 313 ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, 314 TWL6030_CFG_INPUT_PUPD3); 315 if (ret < 0) { 316 pr_err("twl6030: Failed to write CFG_INPUT_PUPD3, error %d\n", 317 ret); 318 return ret; 319 } 320 321 return twl6030_irq_base + MMCDETECT_INTR_OFFSET; 322 } 323 EXPORT_SYMBOL(twl6030_mmc_card_detect_config); 324 325 int twl6030_mmc_card_detect(struct device *dev, int slot) 326 { 327 int ret = -EIO; 328 u8 read_reg = 0; 329 struct platform_device *pdev = to_platform_device(dev); 330 331 if (pdev->id) { 332 /* TWL6030 provide's Card detect support for 333 * only MMC1 controller. 334 */ 335 pr_err("Unknown MMC controller %d in %s\n", pdev->id, __func__); 336 return ret; 337 } 338 /* 339 * BIT0 of MMC_CTRL on TWL6030 provides card status for MMC1 340 * 0 - Card not present ,1 - Card present 341 */ 342 ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, &read_reg, 343 TWL6030_MMCCTRL); 344 if (ret >= 0) 345 ret = read_reg & STS_MMC; 346 return ret; 347 } 348 EXPORT_SYMBOL(twl6030_mmc_card_detect); 349 350 int twl6030_init_irq(struct device *dev, int irq_num) 351 { 352 struct device_node *node = dev->of_node; 353 int nr_irqs, irq_base, irq_end; 354 struct task_struct *task; 355 static struct irq_chip twl6030_irq_chip; 356 int status = 0; 357 int i; 358 u8 mask[3]; 359 360 nr_irqs = TWL6030_NR_IRQS; 361 362 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); 363 if (IS_ERR_VALUE(irq_base)) { 364 dev_err(dev, "Fail to allocate IRQ descs\n"); 365 return irq_base; 366 } 367 368 irq_domain_add_legacy(node, nr_irqs, irq_base, 0, 369 &irq_domain_simple_ops, NULL); 370 371 irq_end = irq_base + nr_irqs; 372 373 mask[0] = 0xFF; 374 mask[1] = 0xFF; 375 mask[2] = 0xFF; 376 377 /* mask all int lines */ 378 twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3); 379 /* mask all int sts */ 380 twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3); 381 /* clear INT_STS_A,B,C */ 382 twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3); 383 384 twl6030_irq_base = irq_base; 385 386 /* 387 * install an irq handler for each of the modules; 388 * clone dummy irq_chip since PIH can't *do* anything 389 */ 390 twl6030_irq_chip = dummy_irq_chip; 391 twl6030_irq_chip.name = "twl6030"; 392 twl6030_irq_chip.irq_set_type = NULL; 393 twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; 394 395 for (i = irq_base; i < irq_end; i++) { 396 irq_set_chip_and_handler(i, &twl6030_irq_chip, 397 handle_simple_irq); 398 irq_set_chip_data(i, (void *)irq_num); 399 activate_irq(i); 400 } 401 402 dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n", 403 irq_num, irq_base, irq_end); 404 405 /* install an irq handler to demultiplex the TWL6030 interrupt */ 406 init_completion(&irq_event); 407 408 status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH", 409 &irq_event); 410 if (status < 0) { 411 dev_err(dev, "could not claim irq %d: %d\n", irq_num, status); 412 goto fail_irq; 413 } 414 415 task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); 416 if (IS_ERR(task)) { 417 dev_err(dev, "could not create irq %d thread!\n", irq_num); 418 status = PTR_ERR(task); 419 goto fail_kthread; 420 } 421 422 twl_irq = irq_num; 423 register_pm_notifier(&twl6030_irq_pm_notifier_block); 424 return irq_base; 425 426 fail_kthread: 427 free_irq(irq_num, &irq_event); 428 429 fail_irq: 430 for (i = irq_base; i < irq_end; i++) 431 irq_set_chip_and_handler(i, NULL, NULL); 432 433 return status; 434 } 435 436 int twl6030_exit_irq(void) 437 { 438 unregister_pm_notifier(&twl6030_irq_pm_notifier_block); 439 440 if (twl6030_irq_base) { 441 pr_err("twl6030: can't yet clean up IRQs?\n"); 442 return -ENOSYS; 443 } 444 return 0; 445 } 446 447