1616#include <linux/of.h>
1717#include <linux/of_address.h>
1818
19- #define NUM_CHANNEL 8
19+ #define MAX_NUM_CHANNEL 64
2020#define MAX_INPUT_MUX 256
2121
2222#define REG_EDGE_POL 0x00
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
@@ -51,15 +53,22 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
5153 unsigned int channel ,
5254 unsigned long hwirq );
5355static void meson_a1_gpio_irq_init (struct meson_gpio_irq_controller * ctl );
56+ static int meson8_gpio_irq_set_type (struct meson_gpio_irq_controller * ctl ,
57+ 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 );
5460
5561struct irq_ctl_ops {
5662 void (* gpio_irq_sel_pin )(struct meson_gpio_irq_controller * ctl ,
5763 unsigned int channel , unsigned long hwirq );
5864 void (* gpio_irq_init )(struct meson_gpio_irq_controller * ctl );
65+ int (* gpio_irq_set_type )(struct meson_gpio_irq_controller * ctl ,
66+ unsigned int type , u32 * channel_hwirq );
5967};
6068
6169struct meson_gpio_irq_params {
6270 unsigned int nr_hwirq ;
71+ unsigned int nr_channels ;
6372 bool support_edge_both ;
6473 unsigned int edge_both_offset ;
6574 unsigned int edge_single_offset ;
@@ -68,28 +77,44 @@ struct meson_gpio_irq_params {
6877 struct irq_ctl_ops ops ;
6978};
7079
71- #define INIT_MESON_COMMON (irqs , init , sel ) \
80+ #define INIT_MESON_COMMON (irqs , init , sel , type ) \
7281 .nr_hwirq = irqs, \
7382 .ops = { \
7483 .gpio_irq_init = init, \
7584 .gpio_irq_sel_pin = sel, \
85+ .gpio_irq_set_type = type, \
7686 },
7787
7888#define INIT_MESON8_COMMON_DATA (irqs ) \
7989 INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy, \
80- meson8_gpio_irq_sel_pin) \
90+ meson8_gpio_irq_sel_pin, \
91+ meson8_gpio_irq_set_type) \
8192 .edge_single_offset = 0, \
8293 .pol_low_offset = 16, \
8394 .pin_sel_mask = 0xff, \
95+ .nr_channels = 8, \
8496
8597#define INIT_MESON_A1_COMMON_DATA (irqs ) \
8698 INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init, \
87- meson_a1_gpio_irq_sel_pin) \
99+ meson_a1_gpio_irq_sel_pin, \
100+ meson8_gpio_irq_set_type) \
88101 .support_edge_both = true, \
89102 .edge_both_offset = 16, \
90103 .edge_single_offset = 8, \
91104 .pol_low_offset = 0, \
92105 .pin_sel_mask = 0x7f, \
106+ .nr_channels = 8, \
107+
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, \
93118
94119static const struct meson_gpio_irq_params meson8_params = {
95120 INIT_MESON8_COMMON_DATA (134 )
@@ -121,6 +146,10 @@ static const struct meson_gpio_irq_params a1_params = {
121146 INIT_MESON_A1_COMMON_DATA (62 )
122147};
123148
149+ static const struct meson_gpio_irq_params s4_params = {
150+ INIT_MESON_S4_COMMON_DATA (82 )
151+ };
152+
124153static const struct of_device_id meson_irq_gpio_matches [] = {
125154 { .compatible = "amlogic,meson8-gpio-intc" , .data = & meson8_params },
126155 { .compatible = "amlogic,meson8b-gpio-intc" , .data = & meson8b_params },
@@ -130,14 +159,15 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
130159 { .compatible = "amlogic,meson-g12a-gpio-intc" , .data = & axg_params },
131160 { .compatible = "amlogic,meson-sm1-gpio-intc" , .data = & sm1_params },
132161 { .compatible = "amlogic,meson-a1-gpio-intc" , .data = & a1_params },
162+ { .compatible = "amlogic,meson-s4-gpio-intc" , .data = & s4_params },
133163 { }
134164};
135165
136166struct meson_gpio_irq_controller {
137167 const struct meson_gpio_irq_params * params ;
138168 void __iomem * base ;
139- u32 channel_irqs [NUM_CHANNEL ];
140- DECLARE_BITMAP (channel_map , NUM_CHANNEL );
169+ u32 channel_irqs [MAX_NUM_CHANNEL ];
170+ DECLARE_BITMAP (channel_map , MAX_NUM_CHANNEL );
141171 spinlock_t lock ;
142172};
143173
@@ -207,8 +237,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
207237 spin_lock_irqsave (& ctl -> lock , flags );
208238
209239 /* Find a free channel */
210- idx = find_first_zero_bit (ctl -> channel_map , NUM_CHANNEL );
211- if (idx >= NUM_CHANNEL ) {
240+ idx = find_first_zero_bit (ctl -> channel_map , ctl -> params -> nr_channels );
241+ if (idx >= ctl -> params -> nr_channels ) {
212242 spin_unlock_irqrestore (& ctl -> lock , flags );
213243 pr_err ("No channel available\n" );
214244 return - ENOSPC ;
@@ -256,9 +286,8 @@ meson_gpio_irq_release_channel(struct meson_gpio_irq_controller *ctl,
256286 clear_bit (idx , ctl -> channel_map );
257287}
258288
259- static int meson_gpio_irq_type_setup (struct meson_gpio_irq_controller * ctl ,
260- unsigned int type ,
261- u32 * channel_hwirq )
289+ static int meson8_gpio_irq_set_type (struct meson_gpio_irq_controller * ctl ,
290+ unsigned int type , u32 * channel_hwirq )
262291{
263292 u32 val = 0 ;
264293 unsigned int idx ;
@@ -299,6 +328,51 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
299328 return 0 ;
300329}
301330
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+
302376static unsigned int meson_gpio_irq_type_output (unsigned int type )
303377{
304378 unsigned int sense = type & IRQ_TYPE_SENSE_MASK ;
@@ -323,7 +397,7 @@ static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type)
323397 u32 * channel_hwirq = irq_data_get_irq_chip_data (data );
324398 int ret ;
325399
326- ret = meson_gpio_irq_type_setup (ctl , type , channel_hwirq );
400+ ret = ctl -> params -> ops . gpio_irq_set_type (ctl , type , channel_hwirq );
327401 if (ret )
328402 return ret ;
329403
@@ -450,10 +524,10 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
450524 ret = of_property_read_variable_u32_array (node ,
451525 "amlogic,channel-interrupts" ,
452526 ctl -> channel_irqs ,
453- NUM_CHANNEL ,
454- NUM_CHANNEL );
527+ ctl -> params -> nr_channels ,
528+ ctl -> params -> nr_channels );
455529 if (ret < 0 ) {
456- pr_err ("can't get %d channel interrupts\n" , NUM_CHANNEL );
530+ pr_err ("can't get %d channel interrupts\n" , ctl -> params -> nr_channels );
457531 return ret ;
458532 }
459533
@@ -507,7 +581,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
507581 }
508582
509583 pr_info ("%d to %d gpio interrupt mux initialized\n" ,
510- ctl -> params -> nr_hwirq , NUM_CHANNEL );
584+ ctl -> params -> nr_hwirq , ctl -> params -> nr_channels );
511585
512586 return 0 ;
513587
0 commit comments