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