@@ -85,6 +85,17 @@ struct ti_sci_inta_vint_desc {
8585 * @base: Base address of the memory mapped IO registers
8686 * @pdev: Pointer to platform device.
8787 * @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.
8899 */
89100struct ti_sci_inta_irq_domain {
90101 const struct ti_sci_handle * sci ;
@@ -96,11 +107,37 @@ struct ti_sci_inta_irq_domain {
96107 void __iomem * base ;
97108 struct platform_device * pdev ;
98109 u32 ti_sci_id ;
110+
111+ int unmapped_cnt ;
112+ u16 * unmapped_dev_ids ;
99113};
100114
101115#define to_vint_desc (e , i ) container_of(e, struct ti_sci_inta_vint_desc, \
102116 events[i])
103117
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+
104141/**
105142 * ti_sci_inta_irq_handler() - Chained IRQ handler for the vint irqs
106143 * @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
251288 u16 dev_id , dev_index ;
252289 int err ;
253290
254- dev_id = HWIRQ_TO_DEVID ( hwirq );
291+ dev_id = ti_sci_inta_get_dev_id ( inta , hwirq );
255292 dev_index = HWIRQ_TO_IRQID (hwirq );
256293
257294 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,
352389{
353390 struct ti_sci_inta_vint_desc * vint_desc ;
354391 struct ti_sci_inta_irq_domain * inta ;
392+ u16 dev_id ;
355393
356394 vint_desc = to_vint_desc (event_desc , event_desc -> vint_bit );
357395 inta = vint_desc -> domain -> host_data ;
396+ dev_id = ti_sci_inta_get_dev_id (inta , hwirq );
358397 /* free event irq */
359398 mutex_lock (& inta -> vint_mutex );
360399 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 ),
363401 inta -> ti_sci_id ,
364402 vint_desc -> vint_id ,
365403 event_desc -> global_event ,
@@ -574,6 +612,41 @@ static struct msi_domain_info ti_sci_inta_msi_domain_info = {
574612 .chip = & ti_sci_inta_msi_irq_chip ,
575613};
576614
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+
577650static int ti_sci_inta_irq_domain_probe (struct platform_device * pdev )
578651{
579652 struct irq_domain * parent_domain , * domain , * msi_domain ;
@@ -629,6 +702,10 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
629702 if (IS_ERR (inta -> base ))
630703 return PTR_ERR (inta -> base );
631704
705+ ret = ti_sci_inta_get_unmapped_sources (inta );
706+ if (ret )
707+ return ret ;
708+
632709 domain = irq_domain_add_linear (dev_of_node (dev ),
633710 ti_sci_get_num_resources (inta -> vint ),
634711 & ti_sci_inta_irq_domain_ops , inta );
0 commit comments