blob: 1d466eeb5d88691feea3568ff085d7758aa177bc [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2 * zx234290-irq.c -- Interrupt controller support for ZX234290 PMICs
3 *
4 * Copyright 2016 ZTE Inc.
5 *
6 * Author: yuxiang<yu.xiang5@zte.com.cn>
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/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/bug.h>
19#include <linux/device.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22#include <linux/gpio.h>
23#include <linux/mfd/zx234290.h>
24#include <mach/pcu.h>
25#include <mach/gpio.h>
26#include <linux/sched.h>
27#include <linux/semaphore.h>
28#include <linux/kthread.h>
29
30#define INT_LOW_LEVEL /* yuxiang */
31#define ZX234290_INT_DEBUG
32#ifdef ZX234290_INT_DEBUG
33unsigned long int_irq_times = 0;
34unsigned long int_thread_times = 0;
35#endif
36struct semaphore zx234290_sem;
37
38#define ZX234290_WAKELOCK 1
39#ifdef ZX234290_WAKELOCK
40#include <linux/wakelock.h>
41static struct wake_lock zx234290_wake_lock;
42#endif
43
44#ifdef ZX234290_PWR_FAUL_PROCESS
45extern int zx234290_regulator_error_irq_request(struct zx234290 *zx234290);
46#endif
47
48static inline int irq_to_zx234290_irq(struct zx234290 *zx234290,
49 int irq)
50{
51 return irq - zx234290->irq_base;
52}
53
54/*
55 * This is a threaded IRQ handler so can access I2C/SPI. Since the
56 * IRQ handler explicitly clears the IRQ it handles the IRQ line
57 * will be reasserted and the physical IRQ will be handled again if
58 * another interrupt is asserted while we run - in the normal course
59 * of events this is a rare occurrence so we save I2C/SPI reads. We're
60 * also assuming that it's rare to get lots of interrupts firing
61 * simultaneously so try to minimise I/O.
62 */
63static int zx234290_irq(void *irq_data)
64{
65 struct zx234290 *zx234290 = irq_data;
66 u32 irq_sts;
67 u32 irq_mask;
68 u8 buck_sts=0, buck_mask=0;
69 u8 ldo_sts=0, ldo_mask=0;
70 u8 reg;
71 int i;
72 int irq = zx234290->chip_irq;
73
74 const struct sched_param param = {
75 .sched_priority = 31,
76 };
77 sched_setscheduler(current, SCHED_FIFO, &param);
78
79 while (!kthread_should_stop()) {
80 down(&zx234290_sem);
81 #ifdef ZX234290_WAKELOCK
82 wake_lock(&zx234290_wake_lock);
83 #endif
84
85#ifdef ZX234290_INT_DEBUG
86 int_thread_times ++;
87#endif
88 //printk(KERN_INFO "zx234290 irq handler:irq=%d.\n", irq);
89
90 zx234290->read(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
91 irq_sts = reg;
92 zx234290->read(zx234290, ZX234290_REG_ADDR_INTB, 1, &reg);
93 irq_sts |= reg << 8;
94
95 // printk(KERN_INFO "zx234290 irq handler:irq=%d, INTR_A=0x%02x, INTR_B=0x%02x\n", irq, irq_sts&0xFF, irq_sts>>8);
96
97 zx234290->read(zx234290, ZX234290_REG_ADDR_INTA_MASK, 1, &reg);
98 irq_mask = reg;
99 zx234290->read(zx234290, ZX234290_REG_ADDR_INTB_MASK, 1, &reg);
100 irq_mask |= reg << 8;
101
102 irq_sts &= ~irq_mask; /* */
103
104#ifdef ZX234290_PWR_FAUL_PROCESS
105//++
106 zx234290->read(zx234290, ZX234290_REG_ADDR_BUCK_FAULT_STATUS, 1, &buck_sts);
107 zx234290->read(zx234290, ZX234290_REG_ADDR_LDO_FAULT_STATUS, 1, &ldo_sts);
108 zx234290->read(zx234290, ZX234290_REG_ADDR_BUCK_INT_MASK, 1, &buck_mask);
109 zx234290->read(zx234290, ZX234290_REG_ADDR_LDO_INT_MASK, 1, &ldo_mask);
110
111 buck_sts &= ~buck_mask;
112 ldo_sts &= ~ldo_mask;
lh758261d2023-07-13 05:52:04 -0700113 buck_sts &=~(1<<ZX234290_LDO_RSTERR_LSH);//clear rst flag
lh9ed821d2023-04-07 01:36:19 -0700114 if(buck_sts )
115 irq_sts |= (1 << ZX234290_INT_BUCK_FAUL);
116 else
117 irq_sts &= ~(1 << ZX234290_INT_BUCK_FAUL);
118
119 if(ldo_sts )
120 irq_sts |= (1 << ZX234290_INT_LDO_FAUL);
121 else
122 irq_sts &= ~(1 << ZX234290_INT_LDO_FAUL);
123
124// if(buck_sts || ldo_sts)
125// printk(KERN_INFO "zx234290 irq handler:buck_sts=0x%02x, ldo_sts=0x%02x, irq_sts=0x%x\n", buck_sts, ldo_sts, irq_sts);
126#endif
127
128 if (!irq_sts)
129 {
130
131 #ifdef ZX234290_WAKELOCK
132 wake_unlock(&zx234290_wake_lock);
133 #endif
134
135 #ifdef INT_LOW_LEVEL
136 pcu_clr_irq_pending(irq);
137 enable_irq(irq);//yx
138 #endif
139 //return IRQ_NONE;
140 continue;
141 }
142
143 for (i = 0; i < zx234290->irq_num; i++) {
144 if (!(irq_sts & (1 << i)))
145 continue;
146
147 handle_nested_irq(zx234290->irq_base + i);
148 }
149 /*write bit7 to be 0, clear pmu INT*/
150 //zx234290->read(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
151 //reg &= ~(0x1<<7);
152 //zx234290->write(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
153 #if 0
154 /* Write the STS register back to clear IRQs we handled */
155 reg = irq_sts & 0xFF;
156 irq_sts >>= 8;
157 if (reg)
158 zx234290->write(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
159 reg = irq_sts & 0xFF;
160 irq_sts >>= 8;
161 if (reg)
162 zx234290->write(zx234290, ZX234290_REG_ADDR_INTB, 1, &reg);
163 #endif
164
165 #ifdef ZX234290_WAKELOCK
166 wake_unlock(&zx234290_wake_lock);
167 #endif
168
169
170#ifdef INT_LOW_LEVEL
171 pcu_clr_irq_pending(irq);
172 enable_irq(irq);//yx
173#endif
174 }
175 return 0;
176}
177
178static void zx234290_irq_lock(struct irq_data *data)
179{
180 struct zx234290 *zx234290 = irq_data_get_irq_chip_data(data);
181
182 mutex_lock(&zx234290->irq_lock);
183}
184
185static void zx234290_irq_sync_unlock(struct irq_data *data)
186{
187 struct zx234290 *zx234290 = irq_data_get_irq_chip_data(data);
188 u32 reg_mask;
189 u8 reg, reg2;
190
191 zx234290->read(zx234290, ZX234290_REG_ADDR_INTA_MASK, 1, &reg);
192 reg_mask = reg;
193 zx234290->read(zx234290, ZX234290_REG_ADDR_INTB_MASK, 1, &reg);
194 reg_mask |= reg << 8;
195 /* take ldo6 & ldo8 error as buck error */
196 zx234290->read(zx234290, ZX234290_REG_ADDR_BUCK_INT_MASK, 1, &reg);
197 if (reg)
198 reg_mask |= BIT(ZX234290_INT_BUCK_FAUL);
199 zx234290->read(zx234290, ZX234290_REG_ADDR_LDO_INT_MASK, 1, &reg);
200 if (reg)
201 reg_mask |= BIT(ZX234290_INT_LDO_FAUL);
202
203 if (zx234290->irq_mask != reg_mask) {
204 reg = zx234290->irq_mask & 0xFC;
205 zx234290->write(zx234290, ZX234290_REG_ADDR_INTA_MASK, 1, &reg);
206
207 reg = zx234290->irq_mask >> 8 & 0xFF;
208 zx234290->write(zx234290, ZX234290_REG_ADDR_INTB_MASK, 1, &reg);
209
210 reg = (zx234290->irq_mask & BIT(ZX234290_INT_BUCK_FAUL)) ? 0xFF : 0;
211 zx234290->write(zx234290, ZX234290_REG_ADDR_BUCK_INT_MASK, 1, &reg);
212
213 reg = (zx234290->irq_mask & BIT(ZX234290_INT_LDO_FAUL)) ? 0xFF : 0;
214 zx234290->write(zx234290, ZX234290_REG_ADDR_LDO_INT_MASK, 1, &reg);
215 }
216
217 mutex_unlock(&zx234290->irq_lock);
218}
219
220static void zx234290_irq_enable(struct irq_data *data)
221{
222 struct zx234290 *zx234290 = irq_data_get_irq_chip_data(data);
223
224 zx234290->irq_mask &= ~(1 << irq_to_zx234290_irq(zx234290, data->irq));
225}
226
227static void zx234290_irq_disable(struct irq_data *data)
228{
229 struct zx234290 *zx234290 = irq_data_get_irq_chip_data(data);
230
231 zx234290->irq_mask |= (1 << irq_to_zx234290_irq(zx234290, data->irq));
232}
233
234static struct irq_chip zx234290_irq_chip = {
235 .name = "zx234290",
236 .irq_bus_lock = zx234290_irq_lock,
237 .irq_bus_sync_unlock = zx234290_irq_sync_unlock,
238 .irq_disable = zx234290_irq_disable,
239 .irq_enable = zx234290_irq_enable,
240};
241static irqreturn_t irq_primary_handler(int irq, void *dev_id)
242{
243#ifdef INT_LOW_LEVEL
244 disable_irq_nosync(irq);//yx
245#endif
246 //pcu_int_clear(PCU_EX0_INT); //xzg
247 pcu_clr_irq_pending(irq);
248 up(&zx234290_sem);
249#ifdef ZX234290_INT_DEBUG
250 int_irq_times ++;
251#endif
252
253 //return IRQ_WAKE_THREAD;
254 return IRQ_HANDLED;
255}
256
257int zx234290_irq_init(struct zx234290 *zx234290, int irq,
258 struct zx234290_board *pdata)
259{
260 int ret, cur_irq;
261/* int flags = IRQF_ONESHOT; */
262 u8 reg;
263
264 #ifdef ZX234290_WAKELOCK
265 wake_lock_init(&zx234290_wake_lock, WAKE_LOCK_SUSPEND, "zx234290");
266 #endif
267
268 if (!irq) {
269 dev_warn(zx234290->dev, "No interrupt support, no core IRQ\n");
270 return 0;
271 }
272
273 if (!pdata || !pdata->irq_base) {
274 dev_warn(zx234290->dev, "No interrupt support, no IRQ base\n");
275 return 0;
276 }
277
278 sema_init(&zx234290_sem, 0);
279 /* Clear unattended interrupts */
280 zx234290->read(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
281 //zx234290->write(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
282 zx234290->read(zx234290, ZX234290_REG_ADDR_INTB, 1, &reg);
283 //zx234290->write(zx234290, ZX234290_REG_ADDR_INTB, 1, &reg);
284
285 /*write bit7 to be 0, clear pmu INT*/
286 zx234290->read(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
287 reg &= ~(0x1<<7);
288 zx234290->write(zx234290, ZX234290_REG_ADDR_INTA, 1, &reg);
289
290 /* Mask top level interrupts */
291 zx234290->irq_mask = 0xFFFF;
292
293 mutex_init(&zx234290->irq_lock);
294 zx234290->chip_irq = irq; /* irq */
295 zx234290->irq_base = pdata->irq_base; /* irq_base 32+49 */
296
297 zx234290->irq_num = ZX234290_NUM_IRQ;
298
299 /* Register with genirq */
300 for (cur_irq = zx234290->irq_base;
301 cur_irq < zx234290->irq_num + zx234290->irq_base;
302 cur_irq++) {
303 irq_set_chip_data(cur_irq, zx234290);
304 irq_set_chip_and_handler(cur_irq, &zx234290_irq_chip,
305 handle_edge_irq);
306 irq_set_nested_thread(cur_irq, 1);
307 /* ARM needs us to explicitly flag the IRQ as valid
308 * and will set them noprobe when we do so. */
309#ifdef CONFIG_ARM
310 set_irq_flags(cur_irq, IRQF_VALID);
311#else
312 irq_set_noprobe(cur_irq);
313#endif
314 }
315
316#ifdef ZX234290_PWR_FAUL_PROCESS
317 zx234290_regulator_error_irq_request(zx234290);
318#endif
319 //unsigned int gpio_num = irq_to_gpio(irq);//by yuxiang
320 //#define GPIO_PMU_INT ZX29_GPIO_50
321 /* GPIO reuse*/
322 zx29_gpio_config(pdata->irq_gpio_num, pdata->irq_gpio_func);
323#ifdef INT_LOW_LEVEL
324 zx29_gpio_set_inttype(pdata->irq_gpio_num, IRQ_TYPE_LEVEL_LOW);
325#else
326 zx29_gpio_set_inttype(pdata->irq_gpio_num, IRQ_TYPE_EDGE_FALLING);
327#endif
328 zx29_gpio_pd_pu_set(pdata->irq_gpio_num, 0);
329 //pcu_int_clear(PCU_EX0_INT); //by yuxiang
330 pcu_clr_irq_pending(irq);
331 //irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);//by yuxiang
332 //ret = request_threaded_irq(irq, irq_primary_handler, zx234290_irq, IRQF_ONESHOT,
333 // "zx234290", zx234290);
334 //µÈµ½pmuËùÓÐÄÚ²¿ÖжÏ×¢²áºó£¬ÔÙʹÄÜpmuÖжÏ
335 /* irq_set_status_flags(irq, IRQ_NOAUTOEN); */
336 ret = request_irq(irq, irq_primary_handler, IRQF_NO_THREAD,
337 "zx234290", zx234290);
338 if (ret != 0)
339 dev_err(zx234290->dev, "Failed to request IRQ: %d\n", ret);
340 #ifndef CONFIG_ARCH_ZX297520V3_CAP
341 irq_set_irq_wake(irq, 1);
342 #endif
343 kthread_run(zx234290_irq, zx234290, "irq/%d-%s", irq, "zx234290");
344 return ret;
345}
346
347int zx234290_irq_exit(struct zx234290 *zx234290)
348{
349 free_irq(zx234290->chip_irq, zx234290);
350
351 #ifdef ZX234290_WAKELOCK
352 wake_lock_destroy(&zx234290_wake_lock);
353 #endif
354
355 return 0;
356}