xref: /openbmc/linux/drivers/mfd/pcf50633-irq.c (revision 12eb4683)
1 /* NXP PCF50633 Power Management Unit (PMU) driver
2  *
3  * (C) 2006-2008 by Openmoko, Inc.
4  * Author: Harald Welte <laforge@openmoko.org>
5  * 	   Balaji Rao <balajirrao@openmoko.org>
6  * All rights reserved.
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  */
14 
15 #include <linux/interrupt.h>
16 #include <linux/kernel.h>
17 #include <linux/mutex.h>
18 #include <linux/export.h>
19 #include <linux/slab.h>
20 
21 #include <linux/mfd/pcf50633/core.h>
22 #include <linux/mfd/pcf50633/mbc.h>
23 
24 int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
25 			void (*handler) (int, void *), void *data)
26 {
27 	if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler)
28 		return -EINVAL;
29 
30 	if (WARN_ON(pcf->irq_handler[irq].handler))
31 		return -EBUSY;
32 
33 	mutex_lock(&pcf->lock);
34 	pcf->irq_handler[irq].handler = handler;
35 	pcf->irq_handler[irq].data = data;
36 	mutex_unlock(&pcf->lock);
37 
38 	return 0;
39 }
40 EXPORT_SYMBOL_GPL(pcf50633_register_irq);
41 
42 int pcf50633_free_irq(struct pcf50633 *pcf, int irq)
43 {
44 	if (irq < 0 || irq >= PCF50633_NUM_IRQ)
45 		return -EINVAL;
46 
47 	mutex_lock(&pcf->lock);
48 	pcf->irq_handler[irq].handler = NULL;
49 	mutex_unlock(&pcf->lock);
50 
51 	return 0;
52 }
53 EXPORT_SYMBOL_GPL(pcf50633_free_irq);
54 
55 static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
56 {
57 	u8 reg, bit;
58 	int ret = 0, idx;
59 
60 	idx = irq >> 3;
61 	reg = PCF50633_REG_INT1M + idx;
62 	bit = 1 << (irq & 0x07);
63 
64 	pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0);
65 
66 	mutex_lock(&pcf->lock);
67 
68 	if (mask)
69 		pcf->mask_regs[idx] |= bit;
70 	else
71 		pcf->mask_regs[idx] &= ~bit;
72 
73 	mutex_unlock(&pcf->lock);
74 
75 	return ret;
76 }
77 
78 int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
79 {
80 	dev_dbg(pcf->dev, "Masking IRQ %d\n", irq);
81 
82 	return __pcf50633_irq_mask_set(pcf, irq, 1);
83 }
84 EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
85 
86 int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
87 {
88 	dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq);
89 
90 	return __pcf50633_irq_mask_set(pcf, irq, 0);
91 }
92 EXPORT_SYMBOL_GPL(pcf50633_irq_unmask);
93 
94 int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq)
95 {
96 	u8 reg, bits;
97 
98 	reg =  irq >> 3;
99 	bits = 1 << (irq & 0x07);
100 
101 	return pcf->mask_regs[reg] & bits;
102 }
103 EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get);
104 
105 static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq)
106 {
107 	if (pcf->irq_handler[irq].handler)
108 		pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data);
109 }
110 
111 /* Maximum amount of time ONKEY is held before emergency action is taken */
112 #define PCF50633_ONKEY1S_TIMEOUT 8
113 
114 static irqreturn_t pcf50633_irq(int irq, void *data)
115 {
116 	struct pcf50633 *pcf = data;
117 	int ret, i, j;
118 	u8 pcf_int[5], chgstat;
119 
120 	/* Read the 5 INT regs in one transaction */
121 	ret = pcf50633_read_block(pcf, PCF50633_REG_INT1,
122 						ARRAY_SIZE(pcf_int), pcf_int);
123 	if (ret != ARRAY_SIZE(pcf_int)) {
124 		dev_err(pcf->dev, "Error reading INT registers\n");
125 
126 		/*
127 		 * If this doesn't ACK the interrupt to the chip, we'll be
128 		 * called once again as we're level triggered.
129 		 */
130 		goto out;
131 	}
132 
133 	/* defeat 8s death from lowsys on A5 */
134 	pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN,  0x04);
135 
136 	/* We immediately read the usb and adapter status. We thus make sure
137 	 * only of USBINS/USBREM IRQ handlers are called */
138 	if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
139 		chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
140 		if (chgstat & (0x3 << 4))
141 			pcf_int[0] &= ~PCF50633_INT1_USBREM;
142 		else
143 			pcf_int[0] &= ~PCF50633_INT1_USBINS;
144 	}
145 
146 	/* Make sure only one of ADPINS or ADPREM is set */
147 	if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
148 		chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
149 		if (chgstat & (0x3 << 4))
150 			pcf_int[0] &= ~PCF50633_INT1_ADPREM;
151 		else
152 			pcf_int[0] &= ~PCF50633_INT1_ADPINS;
153 	}
154 
155 	dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
156 			"INT4=0x%02x INT5=0x%02x\n", pcf_int[0],
157 			pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]);
158 
159 	/* Some revisions of the chip don't have a 8s standby mode on
160 	 * ONKEY1S press. We try to manually do it in such cases. */
161 	if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) {
162 		dev_info(pcf->dev, "ONKEY1S held for %d secs\n",
163 							pcf->onkey1s_held);
164 		if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT)
165 			if (pcf->pdata->force_shutdown)
166 				pcf->pdata->force_shutdown(pcf);
167 	}
168 
169 	if (pcf_int[2] & PCF50633_INT3_ONKEY1S) {
170 		dev_info(pcf->dev, "ONKEY1S held\n");
171 		pcf->onkey1s_held = 1 ;
172 
173 		/* Unmask IRQ_SECOND */
174 		pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M,
175 						PCF50633_INT1_SECOND);
176 
177 		/* Unmask IRQ_ONKEYR */
178 		pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M,
179 						PCF50633_INT2_ONKEYR);
180 	}
181 
182 	if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) {
183 		pcf->onkey1s_held = 0;
184 
185 		/* Mask SECOND and ONKEYR interrupts */
186 		if (pcf->mask_regs[0] & PCF50633_INT1_SECOND)
187 			pcf50633_reg_set_bit_mask(pcf,
188 					PCF50633_REG_INT1M,
189 					PCF50633_INT1_SECOND,
190 					PCF50633_INT1_SECOND);
191 
192 		if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR)
193 			pcf50633_reg_set_bit_mask(pcf,
194 					PCF50633_REG_INT2M,
195 					PCF50633_INT2_ONKEYR,
196 					PCF50633_INT2_ONKEYR);
197 	}
198 
199 	/* Have we just resumed ? */
200 	if (pcf->is_suspended) {
201 		pcf->is_suspended = 0;
202 
203 		/* Set the resume reason filtering out non resumers */
204 		for (i = 0; i < ARRAY_SIZE(pcf_int); i++)
205 			pcf->resume_reason[i] = pcf_int[i] &
206 						pcf->pdata->resumers[i];
207 
208 		/* Make sure we don't pass on any ONKEY events to
209 		 * userspace now */
210 		pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF);
211 	}
212 
213 	for (i = 0; i < ARRAY_SIZE(pcf_int); i++) {
214 		/* Unset masked interrupts */
215 		pcf_int[i] &= ~pcf->mask_regs[i];
216 
217 		for (j = 0; j < 8 ; j++)
218 			if (pcf_int[i] & (1 << j))
219 				pcf50633_irq_call_handler(pcf, (i * 8) + j);
220 	}
221 
222 out:
223 	return IRQ_HANDLED;
224 }
225 
226 #ifdef CONFIG_PM
227 
228 int pcf50633_irq_suspend(struct pcf50633 *pcf)
229 {
230 	int ret;
231 	int i;
232 	u8 res[5];
233 
234 
235 	/* Make sure our interrupt handlers are not called
236 	 * henceforth */
237 	disable_irq(pcf->irq);
238 
239 	/* Save the masks */
240 	ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
241 				ARRAY_SIZE(pcf->suspend_irq_masks),
242 					pcf->suspend_irq_masks);
243 	if (ret < 0) {
244 		dev_err(pcf->dev, "error saving irq masks\n");
245 		goto out;
246 	}
247 
248 	/* Write wakeup irq masks */
249 	for (i = 0; i < ARRAY_SIZE(res); i++)
250 		res[i] = ~pcf->pdata->resumers[i];
251 
252 	ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
253 					ARRAY_SIZE(res), &res[0]);
254 	if (ret < 0) {
255 		dev_err(pcf->dev, "error writing wakeup irq masks\n");
256 		goto out;
257 	}
258 
259 	pcf->is_suspended = 1;
260 
261 out:
262 	return ret;
263 }
264 
265 int pcf50633_irq_resume(struct pcf50633 *pcf)
266 {
267 	int ret;
268 
269 	/* Write the saved mask registers */
270 	ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
271 				ARRAY_SIZE(pcf->suspend_irq_masks),
272 					pcf->suspend_irq_masks);
273 	if (ret < 0)
274 		dev_err(pcf->dev, "Error restoring saved suspend masks\n");
275 
276 	enable_irq(pcf->irq);
277 
278 	return ret;
279 }
280 
281 #endif
282 
283 int pcf50633_irq_init(struct pcf50633 *pcf, int irq)
284 {
285 	int ret;
286 
287 	pcf->irq = irq;
288 
289 	/* Enable all interrupts except RTC SECOND */
290 	pcf->mask_regs[0] = 0x80;
291 	pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]);
292 	pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00);
293 	pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00);
294 	pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
295 	pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
296 
297 	ret = request_threaded_irq(irq, NULL, pcf50633_irq,
298 					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
299 					"pcf50633", pcf);
300 
301 	if (ret)
302 		dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
303 
304 	if (enable_irq_wake(irq) < 0)
305 		dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
306 			"in this hardware revision", irq);
307 
308 	return ret;
309 }
310 
311 void pcf50633_irq_free(struct pcf50633 *pcf)
312 {
313 	free_irq(pcf->irq, pcf);
314 }
315