[IA64-SGI] abstract force_interrupt() mechanism
Altix patch to abstract the force_interrupt() mechanism away from the pcibr provider. Signed-off-by: Mark Maule <maule@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
parent
89963d16dc
commit
735e60f4c6
5 changed files with 34 additions and 23 deletions
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 = {
|
||||||
.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 = {
|
||||||
.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 {
|
||||||
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 {
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue