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,
5355static void meson_a1_gpio_irq_init (struct meson_gpio_irq_controller * ctl );
5456static 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
5761struct 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+
104119static 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+
134153static 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+
311376static unsigned int meson_gpio_irq_type_output (unsigned int type )
312377{
313378 unsigned int sense = type & IRQ_TYPE_SENSE_MASK ;
0 commit comments