Loading arch/ia64/sn/kernel/irq.c +28 −22 Original line number Diff line number Diff line Loading @@ -317,6 +317,16 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) pci_dev_put(pci_dev); } static inline void sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) { struct sn_pcibus_provider *pci_provider; pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type]; if (pci_provider && pci_provider->force_interrupt) (*pci_provider->force_interrupt)(sn_irq_info); } static void force_interrupt(int irq) { struct sn_irq_info *sn_irq_info; Loading @@ -325,11 +335,9 @@ static void force_interrupt(int irq) return; rcu_read_lock(); list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) { if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && (sn_irq_info->irq_bridge != NULL)) pcibr_force_interrupt(sn_irq_info); } list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) sn_call_force_intr_provider(sn_irq_info); rcu_read_unlock(); } Loading @@ -351,6 +359,14 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) struct pcidev_info *pcidev_info; struct pcibus_info *pcibus_info; /* * Bridge types attached to TIO (anything but PIC) do not need this WAR * since they do not target Shub II interrupt registers. If that * ever changes, this check needs to accomodate. */ if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_PIC) return; pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; if (!pcidev_info) return; Loading @@ -377,16 +393,12 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) break; } if (!test_bit(irr_bit, &irr_reg)) { if (!test_bit(irq, pda->sn_soft_irr)) { if (!test_bit(irq, pda->sn_in_service_ivecs)) { regval &= 0xff; if (sn_irq_info->irq_int_bit & regval & sn_irq_info->irq_last_intr) { regval &= ~(sn_irq_info-> irq_int_bit & regval); pcibr_force_interrupt(sn_irq_info); } regval &= ~(sn_irq_info->irq_int_bit & regval); sn_call_force_intr_provider(sn_irq_info); } } } Loading @@ -404,12 +416,6 @@ void sn_lb_int_war_check(void) rcu_read_lock(); for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) { list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) { /* * Only call for PCI bridges that are fully * initialized. */ if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && (sn_irq_info->irq_bridge != NULL)) sn_check_intr(i, sn_irq_info); } } Loading arch/ia64/sn/pci/pcibr/pcibr_provider.c +4 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,9 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info) struct pcibus_info *pcibus_info; int bit = sn_irq_info->irq_int_bit; if (! sn_irq_info->irq_bridge) return; pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; if (pcidev_info) { pcibus_info = Loading Loading @@ -222,6 +225,7 @@ struct sn_pcibus_provider pcibr_provider = { .dma_map_consistent = pcibr_dma_map_consistent, .dma_unmap = pcibr_dma_unmap, .bus_fixup = pcibr_bus_fixup, .force_interrupt = pcibr_force_interrupt }; int Loading arch/ia64/sn/pci/tioca_provider.c +1 −0 Original line number Diff line number Diff line Loading @@ -657,6 +657,7 @@ static struct sn_pcibus_provider tioca_pci_interfaces = { .dma_map_consistent = tioca_dma_map, .dma_unmap = tioca_dma_unmap, .bus_fixup = tioca_bus_fixup, .force_interrupt = NULL }; /** Loading include/asm-ia64/sn/pcibus_provider_defs.h +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ struct sn_pcibus_provider { dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t); void (*dma_unmap)(struct pci_dev *, dma_addr_t, int); void * (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *); void (*force_interrupt)(struct sn_irq_info *); }; extern struct sn_pcibus_provider *sn_pci_provider[]; Loading include/asm-ia64/sn/pda.h +0 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ typedef struct pda_s { unsigned long pio_write_status_val; volatile unsigned long *pio_shub_war_cam_addr; unsigned long sn_soft_irr[4]; unsigned long sn_in_service_ivecs[4]; int sn_lb_int_war_ticks; int sn_last_irq; Loading Loading
arch/ia64/sn/kernel/irq.c +28 −22 Original line number Diff line number Diff line Loading @@ -317,6 +317,16 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) pci_dev_put(pci_dev); } static inline void sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) { struct sn_pcibus_provider *pci_provider; pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type]; if (pci_provider && pci_provider->force_interrupt) (*pci_provider->force_interrupt)(sn_irq_info); } static void force_interrupt(int irq) { struct sn_irq_info *sn_irq_info; Loading @@ -325,11 +335,9 @@ static void force_interrupt(int irq) return; rcu_read_lock(); list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) { if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && (sn_irq_info->irq_bridge != NULL)) pcibr_force_interrupt(sn_irq_info); } list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) sn_call_force_intr_provider(sn_irq_info); rcu_read_unlock(); } Loading @@ -351,6 +359,14 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) struct pcidev_info *pcidev_info; struct pcibus_info *pcibus_info; /* * Bridge types attached to TIO (anything but PIC) do not need this WAR * since they do not target Shub II interrupt registers. If that * ever changes, this check needs to accomodate. */ if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_PIC) return; pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; if (!pcidev_info) return; Loading @@ -377,16 +393,12 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) break; } if (!test_bit(irr_bit, &irr_reg)) { if (!test_bit(irq, pda->sn_soft_irr)) { if (!test_bit(irq, pda->sn_in_service_ivecs)) { regval &= 0xff; if (sn_irq_info->irq_int_bit & regval & sn_irq_info->irq_last_intr) { regval &= ~(sn_irq_info-> irq_int_bit & regval); pcibr_force_interrupt(sn_irq_info); } regval &= ~(sn_irq_info->irq_int_bit & regval); sn_call_force_intr_provider(sn_irq_info); } } } Loading @@ -404,12 +416,6 @@ void sn_lb_int_war_check(void) rcu_read_lock(); for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) { list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) { /* * Only call for PCI bridges that are fully * initialized. */ if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && (sn_irq_info->irq_bridge != NULL)) sn_check_intr(i, sn_irq_info); } } Loading
arch/ia64/sn/pci/pcibr/pcibr_provider.c +4 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,9 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info) struct pcibus_info *pcibus_info; int bit = sn_irq_info->irq_int_bit; if (! sn_irq_info->irq_bridge) return; pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; if (pcidev_info) { pcibus_info = Loading Loading @@ -222,6 +225,7 @@ struct sn_pcibus_provider pcibr_provider = { .dma_map_consistent = pcibr_dma_map_consistent, .dma_unmap = pcibr_dma_unmap, .bus_fixup = pcibr_bus_fixup, .force_interrupt = pcibr_force_interrupt }; int Loading
arch/ia64/sn/pci/tioca_provider.c +1 −0 Original line number Diff line number Diff line Loading @@ -657,6 +657,7 @@ static struct sn_pcibus_provider tioca_pci_interfaces = { .dma_map_consistent = tioca_dma_map, .dma_unmap = tioca_dma_unmap, .bus_fixup = tioca_bus_fixup, .force_interrupt = NULL }; /** Loading
include/asm-ia64/sn/pcibus_provider_defs.h +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ struct sn_pcibus_provider { dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t); void (*dma_unmap)(struct pci_dev *, dma_addr_t, int); void * (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *); void (*force_interrupt)(struct sn_irq_info *); }; extern struct sn_pcibus_provider *sn_pci_provider[]; Loading
include/asm-ia64/sn/pda.h +0 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ typedef struct pda_s { unsigned long pio_write_status_val; volatile unsigned long *pio_shub_war_cam_addr; unsigned long sn_soft_irr[4]; unsigned long sn_in_service_ivecs[4]; int sn_lb_int_war_ticks; int sn_last_irq; Loading