Skip to content

Commit d6c47d2

Browse files
Qianggui SongMarc Zyngier
authored andcommitted
irqchip/meson-gpio: Add support for meson s4 SoCs
The meson s4 SoCs support 12 gpio irq lines compared with previous serial chips and have something different, details are as below. IRQ Number: - 80:68 13 pins on bank Z - 67:48 20 pins on bank X - 47:36 12 pins on bank H - 35:24 12 pins on bank D - 23:22 2 pins on bank E - 21:14 8 pins on bank C - 13:0 13 pins on bank B Signed-off-by: Qianggui Song <qianggui.song@amlogic.com> [maz: fixed some W=1 build warnings] Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220225055207.1048-5-qianggui.song@amlogic.com
1 parent be6692b commit d6c47d2

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

drivers/irqchip/irq-meson-gpio.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
/* use for A1 like chips */
2828
#define REG_PIN_A1_SEL 0x04
29+
/* Used for s4 chips */
30+
#define REG_EDGE_POL_S4 0x1c
2931

3032
/*
3133
* Note: The S905X3 datasheet reports that BOTH_EDGE is controlled by
@@ -53,6 +55,8 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
5355
static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
5456
static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
5557
unsigned int type, u32 *channel_hwirq);
58+
static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
59+
unsigned int type, u32 *channel_hwirq);
5660

5761
struct irq_ctl_ops {
5862
void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
@@ -101,6 +105,17 @@ struct meson_gpio_irq_params {
101105
.pin_sel_mask = 0x7f, \
102106
.nr_channels = 8, \
103107

108+
#define INIT_MESON_S4_COMMON_DATA(irqs) \
109+
INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init, \
110+
meson_a1_gpio_irq_sel_pin, \
111+
meson_s4_gpio_irq_set_type) \
112+
.support_edge_both = true, \
113+
.edge_both_offset = 0, \
114+
.edge_single_offset = 12, \
115+
.pol_low_offset = 0, \
116+
.pin_sel_mask = 0xff, \
117+
.nr_channels = 12, \
118+
104119
static const struct meson_gpio_irq_params meson8_params = {
105120
INIT_MESON8_COMMON_DATA(134)
106121
};
@@ -131,6 +146,10 @@ static const struct meson_gpio_irq_params a1_params = {
131146
INIT_MESON_A1_COMMON_DATA(62)
132147
};
133148

149+
static const struct meson_gpio_irq_params s4_params = {
150+
INIT_MESON_S4_COMMON_DATA(82)
151+
};
152+
134153
static const struct of_device_id meson_irq_gpio_matches[] = {
135154
{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
136155
{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
@@ -140,6 +159,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
140159
{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
141160
{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
142161
{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
162+
{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
143163
{ }
144164
};
145165

@@ -308,6 +328,51 @@ static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
308328
return 0;
309329
}
310330

331+
/*
332+
* gpio irq relative registers for s4
333+
* -PADCTRL_GPIO_IRQ_CTRL0
334+
* bit[31]: enable/disable all the irq lines
335+
* bit[12-23]: single edge trigger
336+
* bit[0-11]: polarity trigger
337+
*
338+
* -PADCTRL_GPIO_IRQ_CTRL[X]
339+
* bit[0-16]: 7 bits to choose gpio source for irq line 2*[X] - 2
340+
* bit[16-22]:7 bits to choose gpio source for irq line 2*[X] - 1
341+
* where X = 1-6
342+
*
343+
* -PADCTRL_GPIO_IRQ_CTRL[7]
344+
* bit[0-11]: both edge trigger
345+
*/
346+
static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
347+
unsigned int type, u32 *channel_hwirq)
348+
{
349+
u32 val = 0;
350+
unsigned int idx;
351+
352+
idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
353+
354+
type &= IRQ_TYPE_SENSE_MASK;
355+
356+
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(idx), 0);
357+
358+
if (type == IRQ_TYPE_EDGE_BOTH) {
359+
val |= BIT(ctl->params->edge_both_offset + idx);
360+
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
361+
BIT(ctl->params->edge_both_offset + idx), val);
362+
return 0;
363+
}
364+
365+
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
366+
val |= BIT(ctl->params->pol_low_offset + idx);
367+
368+
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
369+
val |= BIT(ctl->params->edge_single_offset + idx);
370+
371+
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
372+
BIT(idx) | BIT(12 + idx), val);
373+
return 0;
374+
};
375+
311376
static unsigned int meson_gpio_irq_type_output(unsigned int type)
312377
{
313378
unsigned int sense = type & IRQ_TYPE_SENSE_MASK;

0 commit comments

Comments
 (0)