@@ -231,12 +231,6 @@ static int xgene_allocate_domains(struct device_node *node,
231231 return msi -> inner_domain ? 0 : - ENOMEM ;
232232}
233233
234- static void xgene_free_domains (struct xgene_msi * msi )
235- {
236- if (msi -> inner_domain )
237- irq_domain_remove (msi -> inner_domain );
238- }
239-
240234static int xgene_msi_init_allocator (struct device * dev )
241235{
242236 xgene_msi_ctrl -> bitmap = devm_bitmap_zalloc (dev , NR_MSI_VEC , GFP_KERNEL );
@@ -283,34 +277,56 @@ static void xgene_msi_isr(struct irq_desc *desc)
283277 chained_irq_exit (chip , desc );
284278}
285279
286- static enum cpuhp_state pci_xgene_online ;
287-
288280static void xgene_msi_remove (struct platform_device * pdev )
289281{
290- struct xgene_msi * msi = platform_get_drvdata (pdev );
291-
292- if (pci_xgene_online )
293- cpuhp_remove_state (pci_xgene_online );
294- cpuhp_remove_state (CPUHP_PCI_XGENE_DEAD );
282+ for (int i = 0 ; i < NR_HW_IRQS ; i ++ ) {
283+ unsigned int irq = xgene_msi_ctrl -> gic_irq [i ];
284+ if (!irq )
285+ continue ;
286+ irq_set_chained_handler_and_data (irq , NULL , NULL );
287+ }
295288
296- xgene_free_domains (msi );
289+ if (xgene_msi_ctrl -> inner_domain )
290+ irq_domain_remove (xgene_msi_ctrl -> inner_domain );
297291}
298292
299- static int xgene_msi_hwirq_alloc ( unsigned int cpu )
293+ static int xgene_msi_handler_setup ( struct platform_device * pdev )
300294{
295+ struct xgene_msi * xgene_msi = xgene_msi_ctrl ;
301296 int i ;
302- int err ;
303297
304- for (i = cpu ; i < NR_HW_IRQS ; i += num_possible_cpus ()) {
305- unsigned int irq = xgene_msi_ctrl -> gic_irq [i ];
298+ for (i = 0 ; i < NR_HW_IRQS ; i ++ ) {
299+ u32 msi_val ;
300+ int irq , err ;
301+
302+ /*
303+ * MSInIRx registers are read-to-clear; before registering
304+ * interrupt handlers, read all of them to clear spurious
305+ * interrupts that may occur before the driver is probed.
306+ */
307+ for (int msi_idx = 0 ; msi_idx < IDX_PER_GROUP ; msi_idx ++ )
308+ xgene_msi_ir_read (xgene_msi , i , msi_idx );
309+
310+ /* Read MSIINTn to confirm */
311+ msi_val = xgene_msi_int_read (xgene_msi , i );
312+ if (msi_val ) {
313+ dev_err (& pdev -> dev , "Failed to clear spurious IRQ\n" );
314+ return EINVAL ;
315+ }
316+
317+ irq = platform_get_irq (pdev , i );
318+ if (irq < 0 )
319+ return irq ;
320+
321+ xgene_msi -> gic_irq [i ] = irq ;
306322
307323 /*
308324 * Statically allocate MSI GIC IRQs to each CPU core.
309325 * With 8-core X-Gene v1, 2 MSI GIC IRQs are allocated
310326 * to each core.
311327 */
312328 irq_set_status_flags (irq , IRQ_NO_BALANCING );
313- err = irq_set_affinity (irq , cpumask_of (cpu ));
329+ err = irq_set_affinity (irq , cpumask_of (i % num_possible_cpus () ));
314330 if (err ) {
315331 pr_err ("failed to set affinity for GIC IRQ" );
316332 return err ;
@@ -323,17 +339,6 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu)
323339 return 0 ;
324340}
325341
326- static int xgene_msi_hwirq_free (unsigned int cpu )
327- {
328- struct xgene_msi * msi = xgene_msi_ctrl ;
329- int i ;
330-
331- for (i = cpu ; i < NR_HW_IRQS ; i += num_possible_cpus ())
332- irq_set_chained_handler_and_data (msi -> gic_irq [i ], NULL , NULL );
333-
334- return 0 ;
335- }
336-
337342static const struct of_device_id xgene_msi_match_table [] = {
338343 {.compatible = "apm,xgene1-msi" },
339344 {},
@@ -343,7 +348,6 @@ static int xgene_msi_probe(struct platform_device *pdev)
343348{
344349 struct resource * res ;
345350 struct xgene_msi * xgene_msi ;
346- u32 msi_val , msi_idx ;
347351 int rc ;
348352
349353 xgene_msi_ctrl = devm_kzalloc (& pdev -> dev , sizeof (* xgene_msi_ctrl ),
@@ -353,8 +357,6 @@ static int xgene_msi_probe(struct platform_device *pdev)
353357
354358 xgene_msi = xgene_msi_ctrl ;
355359
356- platform_set_drvdata (pdev , xgene_msi );
357-
358360 xgene_msi -> msi_regs = devm_platform_get_and_ioremap_resource (pdev , 0 , & res );
359361 if (IS_ERR (xgene_msi -> msi_regs )) {
360362 rc = PTR_ERR (xgene_msi -> msi_regs );
@@ -374,48 +376,13 @@ static int xgene_msi_probe(struct platform_device *pdev)
374376 goto error ;
375377 }
376378
377- for (int irq_index = 0 ; irq_index < NR_HW_IRQS ; irq_index ++ ) {
378- rc = platform_get_irq (pdev , irq_index );
379- if (rc < 0 )
380- goto error ;
381-
382- xgene_msi -> gic_irq [irq_index ] = rc ;
383- }
384-
385- /*
386- * MSInIRx registers are read-to-clear; before registering
387- * interrupt handlers, read all of them to clear spurious
388- * interrupts that may occur before the driver is probed.
389- */
390- for (int irq_index = 0 ; irq_index < NR_HW_IRQS ; irq_index ++ ) {
391- for (msi_idx = 0 ; msi_idx < IDX_PER_GROUP ; msi_idx ++ )
392- xgene_msi_ir_read (xgene_msi , irq_index , msi_idx );
393-
394- /* Read MSIINTn to confirm */
395- msi_val = xgene_msi_int_read (xgene_msi , irq_index );
396- if (msi_val ) {
397- dev_err (& pdev -> dev , "Failed to clear spurious IRQ\n" );
398- rc = - EINVAL ;
399- goto error ;
400- }
401- }
402-
403- rc = cpuhp_setup_state (CPUHP_AP_ONLINE_DYN , "pci/xgene:online" ,
404- xgene_msi_hwirq_alloc , NULL );
405- if (rc < 0 )
406- goto err_cpuhp ;
407- pci_xgene_online = rc ;
408- rc = cpuhp_setup_state (CPUHP_PCI_XGENE_DEAD , "pci/xgene:dead" , NULL ,
409- xgene_msi_hwirq_free );
379+ rc = xgene_msi_handler_setup (pdev );
410380 if (rc )
411- goto err_cpuhp ;
381+ goto error ;
412382
413383 dev_info (& pdev -> dev , "APM X-Gene PCIe MSI driver loaded\n" );
414384
415385 return 0 ;
416-
417- err_cpuhp :
418- dev_err (& pdev -> dev , "failed to add CPU MSI notifier\n" );
419386error :
420387 xgene_msi_remove (pdev );
421388 return rc ;
0 commit comments