@@ -111,6 +111,9 @@ struct mvebu_pcie_port {
111111 struct mvebu_pcie_window iowin ;
112112 u32 saved_pcie_stat ;
113113 struct resource regs ;
114+ struct irq_domain * intx_irq_domain ;
115+ raw_spinlock_t irq_lock ;
116+ int intx_irq ;
114117};
115118
116119static inline void mvebu_writel (struct mvebu_pcie_port * port , u32 val , u32 reg )
@@ -289,7 +292,18 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
289292 /* Point PCIe unit MBUS decode windows to DRAM space. */
290293 mvebu_pcie_setup_wins (port );
291294
295+ /* Mask all interrupt sources. */
296+ mvebu_writel (port , ~PCIE_INT_ALL_MASK , PCIE_INT_UNMASK_OFF );
297+
298+ /* Clear all interrupt causes. */
299+ mvebu_writel (port , ~PCIE_INT_ALL_MASK , PCIE_INT_CAUSE_OFF );
300+
301+ /* Check if "intx" interrupt was specified in DT. */
302+ if (port -> intx_irq > 0 )
303+ return ;
304+
292305 /*
306+ * Fallback code when "intx" interrupt was not specified in DT:
293307 * Unmask all legacy INTx interrupts as driver does not provide a way
294308 * for masking and unmasking of individual legacy INTx interrupts.
295309 * Legacy INTx are reported via one shared GIC source and therefore
@@ -927,6 +941,108 @@ static struct pci_ops mvebu_pcie_ops = {
927941 .write = mvebu_pcie_wr_conf ,
928942};
929943
944+ static void mvebu_pcie_intx_irq_mask (struct irq_data * d )
945+ {
946+ struct mvebu_pcie_port * port = d -> domain -> host_data ;
947+ irq_hw_number_t hwirq = irqd_to_hwirq (d );
948+ unsigned long flags ;
949+ u32 unmask ;
950+
951+ raw_spin_lock_irqsave (& port -> irq_lock , flags );
952+ unmask = mvebu_readl (port , PCIE_INT_UNMASK_OFF );
953+ unmask &= ~PCIE_INT_INTX (hwirq );
954+ mvebu_writel (port , unmask , PCIE_INT_UNMASK_OFF );
955+ raw_spin_unlock_irqrestore (& port -> irq_lock , flags );
956+ }
957+
958+ static void mvebu_pcie_intx_irq_unmask (struct irq_data * d )
959+ {
960+ struct mvebu_pcie_port * port = d -> domain -> host_data ;
961+ irq_hw_number_t hwirq = irqd_to_hwirq (d );
962+ unsigned long flags ;
963+ u32 unmask ;
964+
965+ raw_spin_lock_irqsave (& port -> irq_lock , flags );
966+ unmask = mvebu_readl (port , PCIE_INT_UNMASK_OFF );
967+ unmask |= PCIE_INT_INTX (hwirq );
968+ mvebu_writel (port , unmask , PCIE_INT_UNMASK_OFF );
969+ raw_spin_unlock_irqrestore (& port -> irq_lock , flags );
970+ }
971+
972+ static struct irq_chip intx_irq_chip = {
973+ .name = "mvebu-INTx" ,
974+ .irq_mask = mvebu_pcie_intx_irq_mask ,
975+ .irq_unmask = mvebu_pcie_intx_irq_unmask ,
976+ };
977+
978+ static int mvebu_pcie_intx_irq_map (struct irq_domain * h ,
979+ unsigned int virq , irq_hw_number_t hwirq )
980+ {
981+ struct mvebu_pcie_port * port = h -> host_data ;
982+
983+ irq_set_status_flags (virq , IRQ_LEVEL );
984+ irq_set_chip_and_handler (virq , & intx_irq_chip , handle_level_irq );
985+ irq_set_chip_data (virq , port );
986+
987+ return 0 ;
988+ }
989+
990+ static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
991+ .map = mvebu_pcie_intx_irq_map ,
992+ .xlate = irq_domain_xlate_onecell ,
993+ };
994+
995+ static int mvebu_pcie_init_irq_domain (struct mvebu_pcie_port * port )
996+ {
997+ struct device * dev = & port -> pcie -> pdev -> dev ;
998+ struct device_node * pcie_intc_node ;
999+
1000+ raw_spin_lock_init (& port -> irq_lock );
1001+
1002+ pcie_intc_node = of_get_next_child (port -> dn , NULL );
1003+ if (!pcie_intc_node ) {
1004+ dev_err (dev , "No PCIe Intc node found for %s\n" , port -> name );
1005+ return - ENODEV ;
1006+ }
1007+
1008+ port -> intx_irq_domain = irq_domain_add_linear (pcie_intc_node , PCI_NUM_INTX ,
1009+ & mvebu_pcie_intx_irq_domain_ops ,
1010+ port );
1011+ of_node_put (pcie_intc_node );
1012+ if (!port -> intx_irq_domain ) {
1013+ dev_err (dev , "Failed to get INTx IRQ domain for %s\n" , port -> name );
1014+ return - ENOMEM ;
1015+ }
1016+
1017+ return 0 ;
1018+ }
1019+
1020+ static void mvebu_pcie_irq_handler (struct irq_desc * desc )
1021+ {
1022+ struct mvebu_pcie_port * port = irq_desc_get_handler_data (desc );
1023+ struct irq_chip * chip = irq_desc_get_chip (desc );
1024+ struct device * dev = & port -> pcie -> pdev -> dev ;
1025+ u32 cause , unmask , status ;
1026+ int i ;
1027+
1028+ chained_irq_enter (chip , desc );
1029+
1030+ cause = mvebu_readl (port , PCIE_INT_CAUSE_OFF );
1031+ unmask = mvebu_readl (port , PCIE_INT_UNMASK_OFF );
1032+ status = cause & unmask ;
1033+
1034+ /* Process legacy INTx interrupts */
1035+ for (i = 0 ; i < PCI_NUM_INTX ; i ++ ) {
1036+ if (!(status & PCIE_INT_INTX (i )))
1037+ continue ;
1038+
1039+ if (generic_handle_domain_irq (port -> intx_irq_domain , i ) == - EINVAL )
1040+ dev_err_ratelimited (dev , "unexpected INT%c IRQ\n" , (char )i + 'A' );
1041+ }
1042+
1043+ chained_irq_exit (chip , desc );
1044+ }
1045+
9301046static int mvebu_pcie_map_irq (const struct pci_dev * dev , u8 slot , u8 pin )
9311047{
9321048 /* Interrupt support on mvebu emulated bridges is not implemented yet */
@@ -1124,6 +1240,21 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
11241240 port -> io_attr = -1 ;
11251241 }
11261242
1243+ /*
1244+ * Old DT bindings do not contain "intx" interrupt
1245+ * so do not fail probing driver when interrupt does not exist.
1246+ */
1247+ port -> intx_irq = of_irq_get_byname (child , "intx" );
1248+ if (port -> intx_irq == - EPROBE_DEFER ) {
1249+ ret = port -> intx_irq ;
1250+ goto err ;
1251+ }
1252+ if (port -> intx_irq <= 0 ) {
1253+ dev_warn (dev , "%s: legacy INTx interrupts cannot be masked individually, "
1254+ "%pOF does not contain intx interrupt\n" ,
1255+ port -> name , child );
1256+ }
1257+
11271258 reset_gpio = of_get_named_gpio_flags (child , "reset-gpios" , 0 , & flags );
11281259 if (reset_gpio == - EPROBE_DEFER ) {
11291260 ret = reset_gpio ;
@@ -1320,6 +1451,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
13201451
13211452 for (i = 0 ; i < pcie -> nports ; i ++ ) {
13221453 struct mvebu_pcie_port * port = & pcie -> ports [i ];
1454+ int irq = port -> intx_irq ;
13231455
13241456 child = port -> dn ;
13251457 if (!child )
@@ -1347,6 +1479,22 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
13471479 continue ;
13481480 }
13491481
1482+ if (irq > 0 ) {
1483+ ret = mvebu_pcie_init_irq_domain (port );
1484+ if (ret ) {
1485+ dev_err (dev , "%s: cannot init irq domain\n" ,
1486+ port -> name );
1487+ pci_bridge_emul_cleanup (& port -> bridge );
1488+ devm_iounmap (dev , port -> base );
1489+ port -> base = NULL ;
1490+ mvebu_pcie_powerdown (port );
1491+ continue ;
1492+ }
1493+ irq_set_chained_handler_and_data (irq ,
1494+ mvebu_pcie_irq_handler ,
1495+ port );
1496+ }
1497+
13501498 /*
13511499 * PCIe topology exported by mvebu hw is quite complicated. In
13521500 * reality has something like N fully independent host bridges
@@ -1450,6 +1598,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
14501598
14511599 for (i = 0 ; i < pcie -> nports ; i ++ ) {
14521600 struct mvebu_pcie_port * port = & pcie -> ports [i ];
1601+ int irq = port -> intx_irq ;
14531602
14541603 if (!port -> base )
14551604 continue ;
@@ -1462,6 +1611,16 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
14621611 /* Mask all interrupt sources. */
14631612 mvebu_writel (port , ~PCIE_INT_ALL_MASK , PCIE_INT_UNMASK_OFF );
14641613
1614+ /* Clear all interrupt causes. */
1615+ mvebu_writel (port , ~PCIE_INT_ALL_MASK , PCIE_INT_CAUSE_OFF );
1616+
1617+ if (irq > 0 )
1618+ irq_set_chained_handler_and_data (irq , NULL , NULL );
1619+
1620+ /* Remove IRQ domains. */
1621+ if (port -> intx_irq_domain )
1622+ irq_domain_remove (port -> intx_irq_domain );
1623+
14651624 /* Free config space for emulated root bridge. */
14661625 pci_bridge_emul_cleanup (& port -> bridge );
14671626
0 commit comments