2121#include <linux/slab.h>
2222#include <linux/types.h>
2323
24- #define PDC_MAX_IRQS 168
2524#define PDC_MAX_GPIO_IRQS 256
2625
27- #define CLEAR_INTR (reg , intr ) (reg & ~(1 << intr))
28- #define ENABLE_INTR (reg , intr ) (reg | (1 << intr))
29-
3026#define IRQ_ENABLE_BANK 0x10
3127#define IRQ_i_CFG 0x110
3228
33- #define PDC_NO_PARENT_IRQ ~0UL
34-
3529struct pdc_pin_region {
3630 u32 pin_base ;
3731 u32 parent_base ;
3832 u32 cnt ;
3933};
4034
35+ #define pin_to_hwirq (r , p ) ((r)->parent_base + (p) - (r)->pin_base)
36+
4137static DEFINE_RAW_SPINLOCK (pdc_lock );
4238static void __iomem * pdc_base ;
4339static struct pdc_pin_region * pdc_region ;
@@ -56,17 +52,18 @@ static u32 pdc_reg_read(int reg, u32 i)
5652static void pdc_enable_intr (struct irq_data * d , bool on )
5753{
5854 int pin_out = d -> hwirq ;
55+ unsigned long enable ;
56+ unsigned long flags ;
5957 u32 index , mask ;
60- u32 enable ;
6158
6259 index = pin_out / 32 ;
6360 mask = pin_out % 32 ;
6461
65- raw_spin_lock (& pdc_lock );
62+ raw_spin_lock_irqsave (& pdc_lock , flags );
6663 enable = pdc_reg_read (IRQ_ENABLE_BANK , index );
67- enable = on ? ENABLE_INTR ( enable , mask ) : CLEAR_INTR ( enable , mask );
64+ __assign_bit ( mask , & enable , on );
6865 pdc_reg_write (IRQ_ENABLE_BANK , index , enable );
69- raw_spin_unlock (& pdc_lock );
66+ raw_spin_unlock_irqrestore (& pdc_lock , flags );
7067}
7168
7269static void qcom_pdc_gic_disable (struct irq_data * d )
@@ -186,90 +183,30 @@ static struct irq_chip qcom_pdc_gic_chip = {
186183 .irq_set_affinity = irq_chip_set_affinity_parent ,
187184};
188185
189- static irq_hw_number_t get_parent_hwirq (int pin )
186+ static struct pdc_pin_region * get_pin_region (int pin )
190187{
191188 int i ;
192- struct pdc_pin_region * region ;
193189
194190 for (i = 0 ; i < pdc_region_cnt ; i ++ ) {
195- region = & pdc_region [i ];
196- if (pin >= region -> pin_base &&
197- pin < region -> pin_base + region -> cnt )
198- return (region -> parent_base + pin - region -> pin_base );
191+ if (pin >= pdc_region [i ].pin_base &&
192+ pin < pdc_region [i ].pin_base + pdc_region [i ].cnt )
193+ return & pdc_region [i ];
199194 }
200195
201- return PDC_NO_PARENT_IRQ ;
202- }
203-
204- static int qcom_pdc_translate (struct irq_domain * d , struct irq_fwspec * fwspec ,
205- unsigned long * hwirq , unsigned int * type )
206- {
207- if (is_of_node (fwspec -> fwnode )) {
208- if (fwspec -> param_count != 2 )
209- return - EINVAL ;
210-
211- * hwirq = fwspec -> param [0 ];
212- * type = fwspec -> param [1 ] & IRQ_TYPE_SENSE_MASK ;
213- return 0 ;
214- }
215-
216- return - EINVAL ;
196+ return NULL ;
217197}
218198
219199static int qcom_pdc_alloc (struct irq_domain * domain , unsigned int virq ,
220200 unsigned int nr_irqs , void * data )
221201{
222202 struct irq_fwspec * fwspec = data ;
223203 struct irq_fwspec parent_fwspec ;
224- irq_hw_number_t hwirq , parent_hwirq ;
225- unsigned int type ;
226- int ret ;
227-
228- ret = qcom_pdc_translate (domain , fwspec , & hwirq , & type );
229- if (ret )
230- return ret ;
231-
232- ret = irq_domain_set_hwirq_and_chip (domain , virq , hwirq ,
233- & qcom_pdc_gic_chip , NULL );
234- if (ret )
235- return ret ;
236-
237- parent_hwirq = get_parent_hwirq (hwirq );
238- if (parent_hwirq == PDC_NO_PARENT_IRQ )
239- return irq_domain_disconnect_hierarchy (domain -> parent , virq );
240-
241- if (type & IRQ_TYPE_EDGE_BOTH )
242- type = IRQ_TYPE_EDGE_RISING ;
243-
244- if (type & IRQ_TYPE_LEVEL_MASK )
245- type = IRQ_TYPE_LEVEL_HIGH ;
246-
247- parent_fwspec .fwnode = domain -> parent -> fwnode ;
248- parent_fwspec .param_count = 3 ;
249- parent_fwspec .param [0 ] = 0 ;
250- parent_fwspec .param [1 ] = parent_hwirq ;
251- parent_fwspec .param [2 ] = type ;
252-
253- return irq_domain_alloc_irqs_parent (domain , virq , nr_irqs ,
254- & parent_fwspec );
255- }
256-
257- static const struct irq_domain_ops qcom_pdc_ops = {
258- .translate = qcom_pdc_translate ,
259- .alloc = qcom_pdc_alloc ,
260- .free = irq_domain_free_irqs_common ,
261- };
262-
263- static int qcom_pdc_gpio_alloc (struct irq_domain * domain , unsigned int virq ,
264- unsigned int nr_irqs , void * data )
265- {
266- struct irq_fwspec * fwspec = data ;
267- struct irq_fwspec parent_fwspec ;
268- irq_hw_number_t hwirq , parent_hwirq ;
204+ struct pdc_pin_region * region ;
205+ irq_hw_number_t hwirq ;
269206 unsigned int type ;
270207 int ret ;
271208
272- ret = qcom_pdc_translate (domain , fwspec , & hwirq , & type );
209+ ret = irq_domain_translate_twocell (domain , fwspec , & hwirq , & type );
273210 if (ret )
274211 return ret ;
275212
@@ -281,8 +218,8 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
281218 if (ret )
282219 return ret ;
283220
284- parent_hwirq = get_parent_hwirq (hwirq );
285- if (parent_hwirq == PDC_NO_PARENT_IRQ )
221+ region = get_pin_region (hwirq );
222+ if (! region )
286223 return irq_domain_disconnect_hierarchy (domain -> parent , virq );
287224
288225 if (type & IRQ_TYPE_EDGE_BOTH )
@@ -294,23 +231,16 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
294231 parent_fwspec .fwnode = domain -> parent -> fwnode ;
295232 parent_fwspec .param_count = 3 ;
296233 parent_fwspec .param [0 ] = 0 ;
297- parent_fwspec .param [1 ] = parent_hwirq ;
234+ parent_fwspec .param [1 ] = pin_to_hwirq ( region , hwirq ) ;
298235 parent_fwspec .param [2 ] = type ;
299236
300237 return irq_domain_alloc_irqs_parent (domain , virq , nr_irqs ,
301238 & parent_fwspec );
302239}
303240
304- static int qcom_pdc_gpio_domain_select (struct irq_domain * d ,
305- struct irq_fwspec * fwspec ,
306- enum irq_domain_bus_token bus_token )
307- {
308- return bus_token == DOMAIN_BUS_WAKEUP ;
309- }
310-
311- static const struct irq_domain_ops qcom_pdc_gpio_ops = {
312- .select = qcom_pdc_gpio_domain_select ,
313- .alloc = qcom_pdc_gpio_alloc ,
241+ static const struct irq_domain_ops qcom_pdc_ops = {
242+ .translate = irq_domain_translate_twocell ,
243+ .alloc = qcom_pdc_alloc ,
314244 .free = irq_domain_free_irqs_common ,
315245};
316246
@@ -361,7 +291,7 @@ static int pdc_setup_pin_mapping(struct device_node *np)
361291
362292static int qcom_pdc_init (struct device_node * node , struct device_node * parent )
363293{
364- struct irq_domain * parent_domain , * pdc_domain , * pdc_gpio_domain ;
294+ struct irq_domain * parent_domain , * pdc_domain ;
365295 int ret ;
366296
367297 pdc_base = of_iomap (node , 0 );
@@ -383,32 +313,21 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
383313 goto fail ;
384314 }
385315
386- pdc_domain = irq_domain_create_hierarchy (parent_domain , 0 , PDC_MAX_IRQS ,
387- of_fwnode_handle (node ),
388- & qcom_pdc_ops , NULL );
389- if (!pdc_domain ) {
390- pr_err ("%pOF: GIC domain add failed\n" , node );
391- ret = - ENOMEM ;
392- goto fail ;
393- }
394-
395- pdc_gpio_domain = irq_domain_create_hierarchy (parent_domain ,
316+ pdc_domain = irq_domain_create_hierarchy (parent_domain ,
396317 IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP ,
397318 PDC_MAX_GPIO_IRQS ,
398319 of_fwnode_handle (node ),
399- & qcom_pdc_gpio_ops , NULL );
400- if (!pdc_gpio_domain ) {
401- pr_err ("%pOF: PDC domain add failed for GPIO domain \n" , node );
320+ & qcom_pdc_ops , NULL );
321+ if (!pdc_domain ) {
322+ pr_err ("%pOF: PDC domain add failed\n" , node );
402323 ret = - ENOMEM ;
403- goto remove ;
324+ goto fail ;
404325 }
405326
406- irq_domain_update_bus_token (pdc_gpio_domain , DOMAIN_BUS_WAKEUP );
327+ irq_domain_update_bus_token (pdc_domain , DOMAIN_BUS_WAKEUP );
407328
408329 return 0 ;
409330
410- remove :
411- irq_domain_remove (pdc_domain );
412331fail :
413332 kfree (pdc_region );
414333 iounmap (pdc_base );
0 commit comments