1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (c) 2020 MediaTek Inc.
5 #include <linux/interrupt.h>
6 #include <linux/mfd/mt6358/core.h>
7 #include <linux/mfd/mt6358/registers.h>
8 #include <linux/mfd/mt6397/core.h>
9 #include <linux/module.h>
11 #include <linux/of_device.h>
12 #include <linux/of_irq.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
16 static struct irq_top_t mt6358_ints
[] = {
27 static void pmic_irq_enable(struct irq_data
*data
)
29 unsigned int hwirq
= irqd_to_hwirq(data
);
30 struct mt6397_chip
*chip
= irq_data_get_irq_chip_data(data
);
31 struct pmic_irq_data
*irqd
= chip
->irq_data
;
33 irqd
->enable_hwirq
[hwirq
] = true;
36 static void pmic_irq_disable(struct irq_data
*data
)
38 unsigned int hwirq
= irqd_to_hwirq(data
);
39 struct mt6397_chip
*chip
= irq_data_get_irq_chip_data(data
);
40 struct pmic_irq_data
*irqd
= chip
->irq_data
;
42 irqd
->enable_hwirq
[hwirq
] = false;
45 static void pmic_irq_lock(struct irq_data
*data
)
47 struct mt6397_chip
*chip
= irq_data_get_irq_chip_data(data
);
49 mutex_lock(&chip
->irqlock
);
52 static void pmic_irq_sync_unlock(struct irq_data
*data
)
54 unsigned int i
, top_gp
, gp_offset
, en_reg
, int_regs
, shift
;
55 struct mt6397_chip
*chip
= irq_data_get_irq_chip_data(data
);
56 struct pmic_irq_data
*irqd
= chip
->irq_data
;
58 for (i
= 0; i
< irqd
->num_pmic_irqs
; i
++) {
59 if (irqd
->enable_hwirq
[i
] == irqd
->cache_hwirq
[i
])
62 /* Find out the IRQ group */
64 while ((top_gp
+ 1) < irqd
->num_top
&&
65 i
>= mt6358_ints
[top_gp
+ 1].hwirq_base
)
68 /* Find the IRQ registers */
69 gp_offset
= i
- mt6358_ints
[top_gp
].hwirq_base
;
70 int_regs
= gp_offset
/ MT6358_REG_WIDTH
;
71 shift
= gp_offset
% MT6358_REG_WIDTH
;
72 en_reg
= mt6358_ints
[top_gp
].en_reg
+
73 (mt6358_ints
[top_gp
].en_reg_shift
* int_regs
);
75 regmap_update_bits(chip
->regmap
, en_reg
, BIT(shift
),
76 irqd
->enable_hwirq
[i
] << shift
);
78 irqd
->cache_hwirq
[i
] = irqd
->enable_hwirq
[i
];
80 mutex_unlock(&chip
->irqlock
);
83 static struct irq_chip mt6358_irq_chip
= {
85 .flags
= IRQCHIP_SKIP_SET_WAKE
,
86 .irq_enable
= pmic_irq_enable
,
87 .irq_disable
= pmic_irq_disable
,
88 .irq_bus_lock
= pmic_irq_lock
,
89 .irq_bus_sync_unlock
= pmic_irq_sync_unlock
,
92 static void mt6358_irq_sp_handler(struct mt6397_chip
*chip
,
95 unsigned int irq_status
, sta_reg
, status
;
96 unsigned int hwirq
, virq
;
99 for (i
= 0; i
< mt6358_ints
[top_gp
].num_int_regs
; i
++) {
100 sta_reg
= mt6358_ints
[top_gp
].sta_reg
+
101 mt6358_ints
[top_gp
].sta_reg_shift
* i
;
103 ret
= regmap_read(chip
->regmap
, sta_reg
, &irq_status
);
106 "Failed to read IRQ status, ret=%d\n", ret
);
117 hwirq
= mt6358_ints
[top_gp
].hwirq_base
+
118 MT6358_REG_WIDTH
* i
+ j
;
120 virq
= irq_find_mapping(chip
->irq_domain
, hwirq
);
122 handle_nested_irq(virq
);
127 regmap_write(chip
->regmap
, sta_reg
, irq_status
);
131 static irqreturn_t
mt6358_irq_handler(int irq
, void *data
)
133 struct mt6397_chip
*chip
= data
;
134 struct pmic_irq_data
*mt6358_irq_data
= chip
->irq_data
;
135 unsigned int bit
, i
, top_irq_status
= 0;
138 ret
= regmap_read(chip
->regmap
,
139 mt6358_irq_data
->top_int_status_reg
,
143 "Failed to read status from the device, ret=%d\n", ret
);
147 for (i
= 0; i
< mt6358_irq_data
->num_top
; i
++) {
148 bit
= BIT(mt6358_ints
[i
].top_offset
);
149 if (top_irq_status
& bit
) {
150 mt6358_irq_sp_handler(chip
, i
);
151 top_irq_status
&= ~bit
;
160 static int pmic_irq_domain_map(struct irq_domain
*d
, unsigned int irq
,
163 struct mt6397_chip
*mt6397
= d
->host_data
;
165 irq_set_chip_data(irq
, mt6397
);
166 irq_set_chip_and_handler(irq
, &mt6358_irq_chip
, handle_level_irq
);
167 irq_set_nested_thread(irq
, 1);
168 irq_set_noprobe(irq
);
173 static const struct irq_domain_ops mt6358_irq_domain_ops
= {
174 .map
= pmic_irq_domain_map
,
175 .xlate
= irq_domain_xlate_twocell
,
178 int mt6358_irq_init(struct mt6397_chip
*chip
)
181 struct pmic_irq_data
*irqd
;
183 irqd
= devm_kzalloc(chip
->dev
, sizeof(*irqd
), GFP_KERNEL
);
187 chip
->irq_data
= irqd
;
189 mutex_init(&chip
->irqlock
);
190 irqd
->top_int_status_reg
= MT6358_TOP_INT_STATUS0
;
191 irqd
->num_pmic_irqs
= MT6358_IRQ_NR
;
192 irqd
->num_top
= ARRAY_SIZE(mt6358_ints
);
194 irqd
->enable_hwirq
= devm_kcalloc(chip
->dev
,
196 sizeof(*irqd
->enable_hwirq
),
198 if (!irqd
->enable_hwirq
)
201 irqd
->cache_hwirq
= devm_kcalloc(chip
->dev
,
203 sizeof(*irqd
->cache_hwirq
),
205 if (!irqd
->cache_hwirq
)
208 /* Disable all interrupts for initializing */
209 for (i
= 0; i
< irqd
->num_top
; i
++) {
210 for (j
= 0; j
< mt6358_ints
[i
].num_int_regs
; j
++)
211 regmap_write(chip
->regmap
,
212 mt6358_ints
[i
].en_reg
+
213 mt6358_ints
[i
].en_reg_shift
* j
, 0);
216 chip
->irq_domain
= irq_domain_add_linear(chip
->dev
->of_node
,
218 &mt6358_irq_domain_ops
, chip
);
219 if (!chip
->irq_domain
) {
220 dev_err(chip
->dev
, "Could not create IRQ domain\n");
224 ret
= devm_request_threaded_irq(chip
->dev
, chip
->irq
, NULL
,
225 mt6358_irq_handler
, IRQF_ONESHOT
,
226 mt6358_irq_chip
.name
, chip
);
228 dev_err(chip
->dev
, "Failed to register IRQ=%d, ret=%d\n",
233 enable_irq_wake(chip
->irq
);