diff options
author | Mark Maule <maule@sgi.com> | 2005-08-25 14:45:00 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-08-26 15:09:01 -0400 |
commit | 8409668b561fbe464f7a392e8dc77eca225d27ac (patch) | |
tree | 7783a2e701b7ae866be858e9121ec70f91fe4fa9 /arch | |
parent | 5b9021bc5800796e23e4994f8cf2dc61536be0a7 (diff) |
[IA64] altix: Abstract irq_affinity at the sn pci provider
Altix patch to abstract irq_affinity down to the pci provider level since
different SGI hardware implements this in different ways.
Signed-off-by: Mark Maule <maule@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/sn/kernel/irq.c | 6 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_provider.c | 5 | ||||
-rw-r--r-- | arch/ia64/sn/pci/tioca_provider.c | 3 | ||||
-rw-r--r-- | arch/ia64/sn/pci/tioce_provider.c | 40 |
4 files changed, 48 insertions, 6 deletions
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 607938c288bb..9fc74631ba8a 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
@@ -127,6 +127,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | |||
127 | int local_widget, status; | 127 | int local_widget, status; |
128 | nasid_t local_nasid; | 128 | nasid_t local_nasid; |
129 | struct sn_irq_info *new_irq_info; | 129 | struct sn_irq_info *new_irq_info; |
130 | struct sn_pcibus_provider *pci_provider; | ||
130 | 131 | ||
131 | new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); | 132 | new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); |
132 | if (new_irq_info == NULL) | 133 | if (new_irq_info == NULL) |
@@ -166,8 +167,9 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | |||
166 | new_irq_info->irq_cpuid = cpuid; | 167 | new_irq_info->irq_cpuid = cpuid; |
167 | register_intr_pda(new_irq_info); | 168 | register_intr_pda(new_irq_info); |
168 | 169 | ||
169 | if (IS_PCI_BRIDGE_ASIC(new_irq_info->irq_bridge_type)) | 170 | pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; |
170 | pcibr_change_devices_irq(new_irq_info); | 171 | if (pci_provider && pci_provider->target_interrupt) |
172 | (pci_provider->target_interrupt)(new_irq_info); | ||
171 | 173 | ||
172 | spin_lock(&sn_irq_info_lock); | 174 | spin_lock(&sn_irq_info_lock); |
173 | list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); | 175 | list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 5862a709adf5..7b03b8084ffc 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
@@ -198,7 +198,7 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info) | |||
198 | } | 198 | } |
199 | } | 199 | } |
200 | 200 | ||
201 | void pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info) | 201 | void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info) |
202 | { | 202 | { |
203 | struct pcidev_info *pcidev_info; | 203 | struct pcidev_info *pcidev_info; |
204 | struct pcibus_info *pcibus_info; | 204 | struct pcibus_info *pcibus_info; |
@@ -233,7 +233,8 @@ struct sn_pcibus_provider pcibr_provider = { | |||
233 | .dma_map_consistent = pcibr_dma_map_consistent, | 233 | .dma_map_consistent = pcibr_dma_map_consistent, |
234 | .dma_unmap = pcibr_dma_unmap, | 234 | .dma_unmap = pcibr_dma_unmap, |
235 | .bus_fixup = pcibr_bus_fixup, | 235 | .bus_fixup = pcibr_bus_fixup, |
236 | .force_interrupt = pcibr_force_interrupt | 236 | .force_interrupt = pcibr_force_interrupt, |
237 | .target_interrupt = pcibr_target_interrupt | ||
237 | }; | 238 | }; |
238 | 239 | ||
239 | int | 240 | int |
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 4ea04cfa30ff..ea09c12f0258 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c | |||
@@ -657,7 +657,8 @@ static struct sn_pcibus_provider tioca_pci_interfaces = { | |||
657 | .dma_map_consistent = tioca_dma_map, | 657 | .dma_map_consistent = tioca_dma_map, |
658 | .dma_unmap = tioca_dma_unmap, | 658 | .dma_unmap = tioca_dma_unmap, |
659 | .bus_fixup = tioca_bus_fixup, | 659 | .bus_fixup = tioca_bus_fixup, |
660 | .force_interrupt = NULL | 660 | .force_interrupt = NULL, |
661 | .target_interrupt = NULL | ||
661 | }; | 662 | }; |
662 | 663 | ||
663 | /** | 664 | /** |
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index d9081369cf96..8e75db2b825d 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c | |||
@@ -669,6 +669,43 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) | |||
669 | } | 669 | } |
670 | 670 | ||
671 | /** | 671 | /** |
672 | * tioce_target_interrupt - implement set_irq_affinity for tioce resident | ||
673 | * functions. Note: only applies to line interrupts, not MSI's. | ||
674 | * | ||
675 | * @sn_irq_info: SN IRQ context | ||
676 | * | ||
677 | * Given an sn_irq_info, set the associated CE device's interrupt destination | ||
678 | * register. Since the interrupt destination registers are on a per-ce-slot | ||
679 | * basis, this will retarget line interrupts for all functions downstream of | ||
680 | * the slot. | ||
681 | */ | ||
682 | static void | ||
683 | tioce_target_interrupt(struct sn_irq_info *sn_irq_info) | ||
684 | { | ||
685 | struct pcidev_info *pcidev_info; | ||
686 | struct tioce_common *ce_common; | ||
687 | struct tioce *ce_mmr; | ||
688 | int bit; | ||
689 | |||
690 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | ||
691 | if (!pcidev_info) | ||
692 | return; | ||
693 | |||
694 | ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info; | ||
695 | ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base; | ||
696 | |||
697 | bit = sn_irq_info->irq_int_bit; | ||
698 | |||
699 | ce_mmr->ce_adm_int_mask |= (1UL << bit); | ||
700 | ce_mmr->ce_adm_int_dest[bit] = | ||
701 | ((uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT) | | ||
702 | sn_irq_info->irq_xtalkaddr; | ||
703 | ce_mmr->ce_adm_int_mask &= ~(1UL << bit); | ||
704 | |||
705 | tioce_force_interrupt(sn_irq_info); | ||
706 | } | ||
707 | |||
708 | /** | ||
672 | * tioce_bus_fixup - perform final PCI fixup for a TIO CE bus | 709 | * tioce_bus_fixup - perform final PCI fixup for a TIO CE bus |
673 | * @prom_bussoft: Common prom/kernel struct representing the bus | 710 | * @prom_bussoft: Common prom/kernel struct representing the bus |
674 | * | 711 | * |
@@ -719,7 +756,8 @@ static struct sn_pcibus_provider tioce_pci_interfaces = { | |||
719 | .dma_map_consistent = tioce_dma_consistent, | 756 | .dma_map_consistent = tioce_dma_consistent, |
720 | .dma_unmap = tioce_dma_unmap, | 757 | .dma_unmap = tioce_dma_unmap, |
721 | .bus_fixup = tioce_bus_fixup, | 758 | .bus_fixup = tioce_bus_fixup, |
722 | .force_interrupt = tioce_force_interrupt | 759 | .force_interrupt = tioce_force_interrupt, |
760 | .target_interrupt = tioce_target_interrupt | ||
723 | }; | 761 | }; |
724 | 762 | ||
725 | /** | 763 | /** |