@@ -85,6 +85,17 @@ struct ti_sci_inta_vint_desc {
85
85
* @base: Base address of the memory mapped IO registers
86
86
* @pdev: Pointer to platform device.
87
87
* @ti_sci_id: TI-SCI device identifier
88
+ * @unmapped_cnt: Number of @unmapped_dev_ids entries
89
+ * @unmapped_dev_ids: Pointer to an array of TI-SCI device identifiers of
90
+ * unmapped event sources.
91
+ * Unmapped Events are not part of the Global Event Map and
92
+ * they are converted to Global event within INTA to be
93
+ * received by the same INTA to generate an interrupt.
94
+ * In case an interrupt request comes for a device which is
95
+ * generating Unmapped Event, we must use the INTA's TI-SCI
96
+ * device identifier in place of the source device
97
+ * identifier to let sysfw know where it has to program the
98
+ * Global Event number.
88
99
*/
89
100
struct ti_sci_inta_irq_domain {
90
101
const struct ti_sci_handle * sci ;
@@ -96,11 +107,37 @@ struct ti_sci_inta_irq_domain {
96
107
void __iomem * base ;
97
108
struct platform_device * pdev ;
98
109
u32 ti_sci_id ;
110
+
111
+ int unmapped_cnt ;
112
+ u16 * unmapped_dev_ids ;
99
113
};
100
114
101
115
#define to_vint_desc (e , i ) container_of(e, struct ti_sci_inta_vint_desc, \
102
116
events[i])
103
117
118
+ static u16 ti_sci_inta_get_dev_id (struct ti_sci_inta_irq_domain * inta , u32 hwirq )
119
+ {
120
+ u16 dev_id = HWIRQ_TO_DEVID (hwirq );
121
+ int i ;
122
+
123
+ if (inta -> unmapped_cnt == 0 )
124
+ return dev_id ;
125
+
126
+ /*
127
+ * For devices sending Unmapped Events we must use the INTA's TI-SCI
128
+ * device identifier number to be able to convert it to a Global Event
129
+ * and map it to an interrupt.
130
+ */
131
+ for (i = 0 ; i < inta -> unmapped_cnt ; i ++ ) {
132
+ if (dev_id == inta -> unmapped_dev_ids [i ]) {
133
+ dev_id = inta -> ti_sci_id ;
134
+ break ;
135
+ }
136
+ }
137
+
138
+ return dev_id ;
139
+ }
140
+
104
141
/**
105
142
* ti_sci_inta_irq_handler() - Chained IRQ handler for the vint irqs
106
143
* @desc: Pointer to irq_desc corresponding to the irq
@@ -251,7 +288,7 @@ static struct ti_sci_inta_event_desc *ti_sci_inta_alloc_event(struct ti_sci_inta
251
288
u16 dev_id , dev_index ;
252
289
int err ;
253
290
254
- dev_id = HWIRQ_TO_DEVID ( hwirq );
291
+ dev_id = ti_sci_inta_get_dev_id ( inta , hwirq );
255
292
dev_index = HWIRQ_TO_IRQID (hwirq );
256
293
257
294
event_desc = & vint_desc -> events [free_bit ];
@@ -352,14 +389,15 @@ static void ti_sci_inta_free_irq(struct ti_sci_inta_event_desc *event_desc,
352
389
{
353
390
struct ti_sci_inta_vint_desc * vint_desc ;
354
391
struct ti_sci_inta_irq_domain * inta ;
392
+ u16 dev_id ;
355
393
356
394
vint_desc = to_vint_desc (event_desc , event_desc -> vint_bit );
357
395
inta = vint_desc -> domain -> host_data ;
396
+ dev_id = ti_sci_inta_get_dev_id (inta , hwirq );
358
397
/* free event irq */
359
398
mutex_lock (& inta -> vint_mutex );
360
399
inta -> sci -> ops .rm_irq_ops .free_event_map (inta -> sci ,
361
- HWIRQ_TO_DEVID (hwirq ),
362
- HWIRQ_TO_IRQID (hwirq ),
400
+ dev_id , HWIRQ_TO_IRQID (hwirq ),
363
401
inta -> ti_sci_id ,
364
402
vint_desc -> vint_id ,
365
403
event_desc -> global_event ,
@@ -574,6 +612,41 @@ static struct msi_domain_info ti_sci_inta_msi_domain_info = {
574
612
.chip = & ti_sci_inta_msi_irq_chip ,
575
613
};
576
614
615
+ static int ti_sci_inta_get_unmapped_sources (struct ti_sci_inta_irq_domain * inta )
616
+ {
617
+ struct device * dev = & inta -> pdev -> dev ;
618
+ struct device_node * node = dev_of_node (dev );
619
+ struct of_phandle_iterator it ;
620
+ int count , err , ret , i ;
621
+
622
+ count = of_count_phandle_with_args (node , "ti,unmapped-event-sources" , NULL );
623
+ if (count <= 0 )
624
+ return 0 ;
625
+
626
+ inta -> unmapped_dev_ids = devm_kcalloc (dev , count ,
627
+ sizeof (* inta -> unmapped_dev_ids ),
628
+ GFP_KERNEL );
629
+ if (!inta -> unmapped_dev_ids )
630
+ return - ENOMEM ;
631
+
632
+ i = 0 ;
633
+ of_for_each_phandle (& it , err , node , "ti,unmapped-event-sources" , NULL , 0 ) {
634
+ u32 dev_id ;
635
+
636
+ ret = of_property_read_u32 (it .node , "ti,sci-dev-id" , & dev_id );
637
+ if (ret ) {
638
+ dev_err (dev , "ti,sci-dev-id read failure for %pOFf\n" , it .node );
639
+ of_node_put (it .node );
640
+ return ret ;
641
+ }
642
+ inta -> unmapped_dev_ids [i ++ ] = dev_id ;
643
+ }
644
+
645
+ inta -> unmapped_cnt = count ;
646
+
647
+ return 0 ;
648
+ }
649
+
577
650
static int ti_sci_inta_irq_domain_probe (struct platform_device * pdev )
578
651
{
579
652
struct irq_domain * parent_domain , * domain , * msi_domain ;
@@ -629,6 +702,10 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
629
702
if (IS_ERR (inta -> base ))
630
703
return PTR_ERR (inta -> base );
631
704
705
+ ret = ti_sci_inta_get_unmapped_sources (inta );
706
+ if (ret )
707
+ return ret ;
708
+
632
709
domain = irq_domain_add_linear (dev_of_node (dev ),
633
710
ti_sci_get_num_resources (inta -> vint ),
634
711
& ti_sci_inta_irq_domain_ops , inta );
0 commit comments