Commit 735e60f4 authored by Mark Maule's avatar Mark Maule Committed by Tony Luck

[IA64-SGI] abstract force_interrupt() mechanism

Altix patch to abstract the force_interrupt() mechanism away from the
pcibr provider.
Signed-off-by: default avatarMark Maule <maule@sgi.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 89963d16
...@@ -317,6 +317,16 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) ...@@ -317,6 +317,16 @@ void sn_irq_unfixup(struct pci_dev *pci_dev)
pci_dev_put(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) static void force_interrupt(int irq)
{ {
struct sn_irq_info *sn_irq_info; struct sn_irq_info *sn_irq_info;
...@@ -325,11 +335,9 @@ static void force_interrupt(int irq) ...@@ -325,11 +335,9 @@ static void force_interrupt(int irq)
return; return;
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) { 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_call_force_intr_provider(sn_irq_info);
(sn_irq_info->irq_bridge != NULL))
pcibr_force_interrupt(sn_irq_info);
}
rcu_read_unlock(); rcu_read_unlock();
} }
...@@ -351,6 +359,14 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) ...@@ -351,6 +359,14 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
struct pcidev_info *pcidev_info; struct pcidev_info *pcidev_info;
struct pcibus_info *pcibus_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; pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
if (!pcidev_info) if (!pcidev_info)
return; return;
...@@ -377,16 +393,12 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) ...@@ -377,16 +393,12 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
break; break;
} }
if (!test_bit(irr_bit, &irr_reg)) { if (!test_bit(irr_bit, &irr_reg)) {
if (!test_bit(irq, pda->sn_soft_irr)) { if (!test_bit(irq, pda->sn_in_service_ivecs)) {
if (!test_bit(irq, pda->sn_in_service_ivecs)) { regval &= 0xff;
regval &= 0xff; if (sn_irq_info->irq_int_bit & regval &
if (sn_irq_info->irq_int_bit & regval & sn_irq_info->irq_last_intr) {
sn_irq_info->irq_last_intr) { regval &= ~(sn_irq_info->irq_int_bit & regval);
regval &= sn_call_force_intr_provider(sn_irq_info);
~(sn_irq_info->
irq_int_bit & regval);
pcibr_force_interrupt(sn_irq_info);
}
} }
} }
} }
...@@ -404,13 +416,7 @@ void sn_lb_int_war_check(void) ...@@ -404,13 +416,7 @@ void sn_lb_int_war_check(void)
rcu_read_lock(); rcu_read_lock();
for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) { 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) { list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) {
/* sn_check_intr(i, sn_irq_info);
* 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);
} }
} }
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -178,6 +178,9 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info) ...@@ -178,6 +178,9 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info)
struct pcibus_info *pcibus_info; struct pcibus_info *pcibus_info;
int bit = sn_irq_info->irq_int_bit; 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; pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
if (pcidev_info) { if (pcidev_info) {
pcibus_info = pcibus_info =
...@@ -222,6 +225,7 @@ struct sn_pcibus_provider pcibr_provider = { ...@@ -222,6 +225,7 @@ struct sn_pcibus_provider pcibr_provider = {
.dma_map_consistent = pcibr_dma_map_consistent, .dma_map_consistent = pcibr_dma_map_consistent,
.dma_unmap = pcibr_dma_unmap, .dma_unmap = pcibr_dma_unmap,
.bus_fixup = pcibr_bus_fixup, .bus_fixup = pcibr_bus_fixup,
.force_interrupt = pcibr_force_interrupt
}; };
int int
......
...@@ -657,6 +657,7 @@ static struct sn_pcibus_provider tioca_pci_interfaces = { ...@@ -657,6 +657,7 @@ static struct sn_pcibus_provider tioca_pci_interfaces = {
.dma_map_consistent = tioca_dma_map, .dma_map_consistent = tioca_dma_map,
.dma_unmap = tioca_dma_unmap, .dma_unmap = tioca_dma_unmap,
.bus_fixup = tioca_bus_fixup, .bus_fixup = tioca_bus_fixup,
.force_interrupt = NULL
}; };
/** /**
......
...@@ -48,6 +48,7 @@ struct sn_pcibus_provider { ...@@ -48,6 +48,7 @@ struct sn_pcibus_provider {
dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t); dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t);
void (*dma_unmap)(struct pci_dev *, dma_addr_t, int); void (*dma_unmap)(struct pci_dev *, dma_addr_t, int);
void * (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *); void * (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *);
void (*force_interrupt)(struct sn_irq_info *);
}; };
extern struct sn_pcibus_provider *sn_pci_provider[]; extern struct sn_pcibus_provider *sn_pci_provider[];
......
...@@ -39,7 +39,6 @@ typedef struct pda_s { ...@@ -39,7 +39,6 @@ typedef struct pda_s {
unsigned long pio_write_status_val; unsigned long pio_write_status_val;
volatile unsigned long *pio_shub_war_cam_addr; volatile unsigned long *pio_shub_war_cam_addr;
unsigned long sn_soft_irr[4];
unsigned long sn_in_service_ivecs[4]; unsigned long sn_in_service_ivecs[4];
int sn_lb_int_war_ticks; int sn_lb_int_war_ticks;
int sn_last_irq; int sn_last_irq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment