1/* 2 * tps65912-irq.c -- TI TPS6591x 3 * 4 * Copyright 2011 Texas Instruments Inc. 5 * 6 * Author: Margarita Olaya <magi@slimlogic.co.uk> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * This driver is based on wm8350 implementation. 14 */ 15 16#include <linux/kernel.h> 17#include <linux/module.h> 18#include <linux/init.h> 19#include <linux/bug.h> 20#include <linux/device.h> 21#include <linux/interrupt.h> 22#include <linux/irq.h> 23#include <linux/gpio.h> 24#include <linux/mfd/tps65912.h> 25 26static inline int irq_to_tps65912_irq(struct tps65912 *tps65912, 27 int irq) 28{ 29 return irq - tps65912->irq_base; 30} 31 32/* 33 * This is a threaded IRQ handler so can access I2C/SPI. Since the 34 * IRQ handler explicitly clears the IRQ it handles the IRQ line 35 * will be reasserted and the physical IRQ will be handled again if 36 * another interrupt is asserted while we run - in the normal course 37 * of events this is a rare occurrence so we save I2C/SPI reads. We're 38 * also assuming that it's rare to get lots of interrupts firing 39 * simultaneously so try to minimise I/O. 40 */ 41static irqreturn_t tps65912_irq(int irq, void *irq_data) 42{ 43 struct tps65912 *tps65912 = irq_data; 44 u32 irq_sts; 45 u32 irq_mask; 46 u8 reg; 47 int i; 48 49 50 tps65912->read(tps65912, TPS65912_INT_STS, 1, ®); 51 irq_sts = reg; 52 tps65912->read(tps65912, TPS65912_INT_STS2, 1, ®); 53 irq_sts |= reg << 8; 54 tps65912->read(tps65912, TPS65912_INT_STS3, 1, ®); 55 irq_sts |= reg << 16; 56 tps65912->read(tps65912, TPS65912_INT_STS4, 1, ®); 57 irq_sts |= reg << 24; 58 59 tps65912->read(tps65912, TPS65912_INT_MSK, 1, ®); 60 irq_mask = reg; 61 tps65912->read(tps65912, TPS65912_INT_MSK2, 1, ®); 62 irq_mask |= reg << 8; 63 tps65912->read(tps65912, TPS65912_INT_MSK3, 1, ®); 64 irq_mask |= reg << 16; 65 tps65912->read(tps65912, TPS65912_INT_MSK4, 1, ®); 66 irq_mask |= reg << 24; 67 68 irq_sts &= ~irq_mask; 69 if (!irq_sts) 70 return IRQ_NONE; 71 72 for (i = 0; i < tps65912->irq_num; i++) { 73 if (!(irq_sts & (1 << i))) 74 continue; 75 76 handle_nested_irq(tps65912->irq_base + i); 77 } 78 79 /* Write the STS register back to clear IRQs we handled */ 80 reg = irq_sts & 0xFF; 81 irq_sts >>= 8; 82 if (reg) 83 tps65912->write(tps65912, TPS65912_INT_STS, 1, ®); 84 reg = irq_sts & 0xFF; 85 irq_sts >>= 8; 86 if (reg) 87 tps65912->write(tps65912, TPS65912_INT_STS2, 1, ®); 88 reg = irq_sts & 0xFF; 89 irq_sts >>= 8; 90 if (reg) 91 tps65912->write(tps65912, TPS65912_INT_STS3, 1, ®); 92 reg = irq_sts & 0xFF; 93 if (reg) 94 tps65912->write(tps65912, TPS65912_INT_STS4, 1, ®); 95 96 return IRQ_HANDLED; 97} 98 99static void tps65912_irq_lock(struct irq_data *data) 100{ 101 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); 102 103 mutex_lock(&tps65912->irq_lock); 104} 105 106static void tps65912_irq_sync_unlock(struct irq_data *data) 107{ 108 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); 109 u32 reg_mask; 110 u8 reg; 111 112 tps65912->read(tps65912, TPS65912_INT_MSK, 1, ®); 113 reg_mask = reg; 114 tps65912->read(tps65912, TPS65912_INT_MSK2, 1, ®); 115 reg_mask |= reg << 8; 116 tps65912->read(tps65912, TPS65912_INT_MSK3, 1, ®); 117 reg_mask |= reg << 16; 118 tps65912->read(tps65912, TPS65912_INT_MSK4, 1, ®); 119 reg_mask |= reg << 24; 120 121 if (tps65912->irq_mask != reg_mask) { 122 reg = tps65912->irq_mask & 0xFF; 123 tps65912->write(tps65912, TPS65912_INT_MSK, 1, ®); 124 reg = tps65912->irq_mask >> 8 & 0xFF; 125 tps65912->write(tps65912, TPS65912_INT_MSK2, 1, ®); 126 reg = tps65912->irq_mask >> 16 & 0xFF; 127 tps65912->write(tps65912, TPS65912_INT_MSK3, 1, ®); 128 reg = tps65912->irq_mask >> 24 & 0xFF; 129 tps65912->write(tps65912, TPS65912_INT_MSK4, 1, ®); 130 } 131 132 mutex_unlock(&tps65912->irq_lock); 133} 134 135static void tps65912_irq_enable(struct irq_data *data) 136{ 137 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); 138 139 tps65912->irq_mask &= ~(1 << irq_to_tps65912_irq(tps65912, data->irq)); 140} 141 142static void tps65912_irq_disable(struct irq_data *data) 143{ 144 struct tps65912 *tps65912 = irq_data_get_irq_chip_data(data); 145 146 tps65912->irq_mask |= (1 << irq_to_tps65912_irq(tps65912, data->irq)); 147} 148 149static struct irq_chip tps65912_irq_chip = { 150 .name = "tps65912", 151 .irq_bus_lock = tps65912_irq_lock, 152 .irq_bus_sync_unlock = tps65912_irq_sync_unlock, 153 .irq_disable = tps65912_irq_disable, 154 .irq_enable = tps65912_irq_enable, 155}; 156 157int tps65912_irq_init(struct tps65912 *tps65912, int irq, 158 struct tps65912_platform_data *pdata) 159{ 160 int ret, cur_irq; 161 int flags = IRQF_ONESHOT; 162 u8 reg; 163 164 if (!irq) { 165 dev_warn(tps65912->dev, "No interrupt support, no core IRQ\n"); 166 return 0; 167 } 168 169 if (!pdata || !pdata->irq_base) { 170 dev_warn(tps65912->dev, "No interrupt support, no IRQ base\n"); 171 return 0; 172 } 173 174 /* Clear unattended interrupts */ 175 tps65912->read(tps65912, TPS65912_INT_STS, 1, ®); 176 tps65912->write(tps65912, TPS65912_INT_STS, 1, ®); 177 tps65912->read(tps65912, TPS65912_INT_STS2, 1, ®); 178 tps65912->write(tps65912, TPS65912_INT_STS2, 1, ®); 179 tps65912->read(tps65912, TPS65912_INT_STS3, 1, ®); 180 tps65912->write(tps65912, TPS65912_INT_STS3, 1, ®); 181 tps65912->read(tps65912, TPS65912_INT_STS4, 1, ®); 182 tps65912->write(tps65912, TPS65912_INT_STS4, 1, ®); 183 184 /* Mask top level interrupts */ 185 tps65912->irq_mask = 0xFFFFFFFF; 186 187 mutex_init(&tps65912->irq_lock); 188 tps65912->chip_irq = irq; 189 tps65912->irq_base = pdata->irq_base; 190 191 tps65912->irq_num = TPS65912_NUM_IRQ; 192 193 /* Register with genirq */ 194 for (cur_irq = tps65912->irq_base; 195 cur_irq < tps65912->irq_num + tps65912->irq_base; 196 cur_irq++) { 197 irq_set_chip_data(cur_irq, tps65912); 198 irq_set_chip_and_handler(cur_irq, &tps65912_irq_chip, 199 handle_edge_irq); 200 irq_set_nested_thread(cur_irq, 1); 201 /* ARM needs us to explicitly flag the IRQ as valid 202 * and will set them noprobe when we do so. */ 203#ifdef CONFIG_ARM 204 set_irq_flags(cur_irq, IRQF_VALID); 205#else 206 irq_set_noprobe(cur_irq); 207#endif 208 } 209 210 ret = request_threaded_irq(irq, NULL, tps65912_irq, flags, 211 "tps65912", tps65912); 212 213 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); 214 if (ret != 0) 215 dev_err(tps65912->dev, "Failed to request IRQ: %d\n", ret); 216 217 return ret; 218} 219 220int tps65912_irq_exit(struct tps65912 *tps65912) 221{ 222 free_irq(tps65912->chip_irq, tps65912); 223 return 0; 224} 225