@@ -85,10 +85,9 @@ static struct rzg2l_irqc_priv *irq_data_to_priv(struct irq_data *data)
8585 return data -> domain -> host_data ;
8686}
8787
88- static void rzg2l_irq_eoi (struct irq_data * d )
88+ static void rzg2l_clear_irq_int (struct rzg2l_irqc_priv * priv , unsigned int hwirq )
8989{
90- unsigned int hw_irq = irqd_to_hwirq (d ) - IRQC_IRQ_START ;
91- struct rzg2l_irqc_priv * priv = irq_data_to_priv (d );
90+ unsigned int hw_irq = hwirq - IRQC_IRQ_START ;
9291 u32 bit = BIT (hw_irq );
9392 u32 iitsr , iscr ;
9493
@@ -99,20 +98,30 @@ static void rzg2l_irq_eoi(struct irq_data *d)
9998 * ISCR can only be cleared if the type is falling-edge, rising-edge or
10099 * falling/rising-edge.
101100 */
102- if ((iscr & bit ) && (iitsr & IITSR_IITSEL_MASK (hw_irq )))
101+ if ((iscr & bit ) && (iitsr & IITSR_IITSEL_MASK (hw_irq ))) {
103102 writel_relaxed (iscr & ~bit , priv -> base + ISCR );
103+ /*
104+ * Enforce that the posted write is flushed to prevent that the
105+ * just handled interrupt is raised again.
106+ */
107+ readl_relaxed (priv -> base + ISCR );
108+ }
104109}
105110
106- static void rzg2l_tint_eoi (struct irq_data * d )
111+ static void rzg2l_clear_tint_int (struct rzg2l_irqc_priv * priv , unsigned int hwirq )
107112{
108- unsigned int hw_irq = irqd_to_hwirq (d ) - IRQC_TINT_START ;
109- struct rzg2l_irqc_priv * priv = irq_data_to_priv (d );
110- u32 bit = BIT (hw_irq );
113+ u32 bit = BIT (hwirq - IRQC_TINT_START );
111114 u32 reg ;
112115
113116 reg = readl_relaxed (priv -> base + TSCR );
114- if (reg & bit )
117+ if (reg & bit ) {
115118 writel_relaxed (reg & ~bit , priv -> base + TSCR );
119+ /*
120+ * Enforce that the posted write is flushed to prevent that the
121+ * just handled interrupt is raised again.
122+ */
123+ readl_relaxed (priv -> base + TSCR );
124+ }
116125}
117126
118127static void rzg2l_irqc_eoi (struct irq_data * d )
@@ -122,9 +131,9 @@ static void rzg2l_irqc_eoi(struct irq_data *d)
122131
123132 raw_spin_lock (& priv -> lock );
124133 if (hw_irq >= IRQC_IRQ_START && hw_irq <= IRQC_IRQ_COUNT )
125- rzg2l_irq_eoi ( d );
134+ rzg2l_clear_irq_int ( priv , hw_irq );
126135 else if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ )
127- rzg2l_tint_eoi ( d );
136+ rzg2l_clear_tint_int ( priv , hw_irq );
128137 raw_spin_unlock (& priv -> lock );
129138 irq_chip_eoi_parent (d );
130139}
@@ -142,7 +151,7 @@ static void rzg2l_irqc_irq_disable(struct irq_data *d)
142151
143152 raw_spin_lock (& priv -> lock );
144153 reg = readl_relaxed (priv -> base + TSSR (tssr_index ));
145- reg &= ~(TSSEL_MASK << TSSEL_SHIFT (tssr_offset ));
154+ reg &= ~(TIEN << TSSEL_SHIFT (tssr_offset ));
146155 writel_relaxed (reg , priv -> base + TSSR (tssr_index ));
147156 raw_spin_unlock (& priv -> lock );
148157 }
@@ -154,7 +163,6 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d)
154163 unsigned int hw_irq = irqd_to_hwirq (d );
155164
156165 if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ ) {
157- unsigned long tint = (uintptr_t )irq_data_get_irq_chip_data (d );
158166 struct rzg2l_irqc_priv * priv = irq_data_to_priv (d );
159167 u32 offset = hw_irq - IRQC_TINT_START ;
160168 u32 tssr_offset = TSSR_OFFSET (offset );
@@ -163,7 +171,7 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d)
163171
164172 raw_spin_lock (& priv -> lock );
165173 reg = readl_relaxed (priv -> base + TSSR (tssr_index ));
166- reg |= ( TIEN | tint ) << TSSEL_SHIFT (tssr_offset );
174+ reg |= TIEN << TSSEL_SHIFT (tssr_offset );
167175 writel_relaxed (reg , priv -> base + TSSR (tssr_index ));
168176 raw_spin_unlock (& priv -> lock );
169177 }
@@ -172,8 +180,10 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d)
172180
173181static int rzg2l_irq_set_type (struct irq_data * d , unsigned int type )
174182{
175- unsigned int hw_irq = irqd_to_hwirq (d ) - IRQC_IRQ_START ;
176183 struct rzg2l_irqc_priv * priv = irq_data_to_priv (d );
184+ unsigned int hwirq = irqd_to_hwirq (d );
185+ u32 iitseln = hwirq - IRQC_IRQ_START ;
186+ bool clear_irq_int = false;
177187 u16 sense , tmp ;
178188
179189 switch (type & IRQ_TYPE_SENSE_MASK ) {
@@ -183,14 +193,17 @@ static int rzg2l_irq_set_type(struct irq_data *d, unsigned int type)
183193
184194 case IRQ_TYPE_EDGE_FALLING :
185195 sense = IITSR_IITSEL_EDGE_FALLING ;
196+ clear_irq_int = true;
186197 break ;
187198
188199 case IRQ_TYPE_EDGE_RISING :
189200 sense = IITSR_IITSEL_EDGE_RISING ;
201+ clear_irq_int = true;
190202 break ;
191203
192204 case IRQ_TYPE_EDGE_BOTH :
193205 sense = IITSR_IITSEL_EDGE_BOTH ;
206+ clear_irq_int = true;
194207 break ;
195208
196209 default :
@@ -199,21 +212,40 @@ static int rzg2l_irq_set_type(struct irq_data *d, unsigned int type)
199212
200213 raw_spin_lock (& priv -> lock );
201214 tmp = readl_relaxed (priv -> base + IITSR );
202- tmp &= ~IITSR_IITSEL_MASK (hw_irq );
203- tmp |= IITSR_IITSEL (hw_irq , sense );
215+ tmp &= ~IITSR_IITSEL_MASK (iitseln );
216+ tmp |= IITSR_IITSEL (iitseln , sense );
217+ if (clear_irq_int )
218+ rzg2l_clear_irq_int (priv , hwirq );
204219 writel_relaxed (tmp , priv -> base + IITSR );
205220 raw_spin_unlock (& priv -> lock );
206221
207222 return 0 ;
208223}
209224
225+ static u32 rzg2l_disable_tint_and_set_tint_source (struct irq_data * d , struct rzg2l_irqc_priv * priv ,
226+ u32 reg , u32 tssr_offset , u8 tssr_index )
227+ {
228+ u32 tint = (u32 )(uintptr_t )irq_data_get_irq_chip_data (d );
229+ u32 tien = reg & (TIEN << TSSEL_SHIFT (tssr_offset ));
230+
231+ /* Clear the relevant byte in reg */
232+ reg &= ~(TSSEL_MASK << TSSEL_SHIFT (tssr_offset ));
233+ /* Set TINT and leave TIEN clear */
234+ reg |= tint << TSSEL_SHIFT (tssr_offset );
235+ writel_relaxed (reg , priv -> base + TSSR (tssr_index ));
236+
237+ return reg | tien ;
238+ }
239+
210240static int rzg2l_tint_set_edge (struct irq_data * d , unsigned int type )
211241{
212242 struct rzg2l_irqc_priv * priv = irq_data_to_priv (d );
213243 unsigned int hwirq = irqd_to_hwirq (d );
214244 u32 titseln = hwirq - IRQC_TINT_START ;
245+ u32 tssr_offset = TSSR_OFFSET (titseln );
246+ u8 tssr_index = TSSR_INDEX (titseln );
215247 u8 index , sense ;
216- u32 reg ;
248+ u32 reg , tssr ;
217249
218250 switch (type & IRQ_TYPE_SENSE_MASK ) {
219251 case IRQ_TYPE_EDGE_RISING :
@@ -235,10 +267,14 @@ static int rzg2l_tint_set_edge(struct irq_data *d, unsigned int type)
235267 }
236268
237269 raw_spin_lock (& priv -> lock );
270+ tssr = readl_relaxed (priv -> base + TSSR (tssr_index ));
271+ tssr = rzg2l_disable_tint_and_set_tint_source (d , priv , tssr , tssr_offset , tssr_index );
238272 reg = readl_relaxed (priv -> base + TITSR (index ));
239273 reg &= ~(IRQ_MASK << (titseln * TITSEL_WIDTH ));
240274 reg |= sense << (titseln * TITSEL_WIDTH );
241275 writel_relaxed (reg , priv -> base + TITSR (index ));
276+ rzg2l_clear_tint_int (priv , hwirq );
277+ writel_relaxed (tssr , priv -> base + TSSR (tssr_index ));
242278 raw_spin_unlock (& priv -> lock );
243279
244280 return 0 ;
0 commit comments