diff options
author | Matthew Wilcox <matthew@wil.cx> | 2006-10-10 10:01:19 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-01 17:36:56 -0500 |
commit | 3efe2d84c8d909567c7976a7106114127b8c3470 (patch) | |
tree | 28b93040c032fe5b90bf4fc61fc656eea45832dc | |
parent | 368c73d4f689dae0807d0a2aa74c61fd2b9b075f (diff) |
PCI: Use pci_generic_prep_mwi on ia64
The pci_generic_prep_mwi() code does everything that pcibios_prep_mwi()
does on ia64. All we need to do is be sure that pci_cache_line_size
is set appropriately, and we can delete pcibios_prep_mwi().
Using SMP_CACHE_BYTES as the default was wrong on uniprocessor machines
as it is only 8 bytes. The default in the generic code of L1_CACHE_BYTES
is at least as good.
Signed-off-by: Matthew Wilcox <matthew@wil.cx>
Acked-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | arch/ia64/pci/pci.c | 71 | ||||
-rw-r--r-- | include/asm-ia64/pci.h | 21 |
2 files changed, 30 insertions, 62 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index b30be7c48ba8..4f7747253467 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -738,75 +738,44 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) | |||
738 | return ret; | 738 | return ret; |
739 | } | 739 | } |
740 | 740 | ||
741 | /* It's defined in drivers/pci/pci.c */ | ||
742 | extern u8 pci_cache_line_size; | ||
743 | |||
741 | /** | 744 | /** |
742 | * pci_cacheline_size - determine cacheline size for PCI devices | 745 | * set_pci_cacheline_size - determine cacheline size for PCI devices |
743 | * @dev: void | ||
744 | * | 746 | * |
745 | * We want to use the line-size of the outer-most cache. We assume | 747 | * We want to use the line-size of the outer-most cache. We assume |
746 | * that this line-size is the same for all CPUs. | 748 | * that this line-size is the same for all CPUs. |
747 | * | 749 | * |
748 | * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). | 750 | * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). |
749 | * | ||
750 | * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. | ||
751 | */ | 751 | */ |
752 | static unsigned long | 752 | static void __init set_pci_cacheline_size(void) |
753 | pci_cacheline_size (void) | ||
754 | { | 753 | { |
755 | u64 levels, unique_caches; | 754 | u64 levels, unique_caches; |
756 | s64 status; | 755 | s64 status; |
757 | pal_cache_config_info_t cci; | 756 | pal_cache_config_info_t cci; |
758 | static u8 cacheline_size; | ||
759 | |||
760 | if (cacheline_size) | ||
761 | return cacheline_size; | ||
762 | 757 | ||
763 | status = ia64_pal_cache_summary(&levels, &unique_caches); | 758 | status = ia64_pal_cache_summary(&levels, &unique_caches); |
764 | if (status != 0) { | 759 | if (status != 0) { |
765 | printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", | 760 | printk(KERN_ERR "%s: ia64_pal_cache_summary() failed " |
766 | __FUNCTION__, status); | 761 | "(status=%ld)\n", __FUNCTION__, status); |
767 | return SMP_CACHE_BYTES; | 762 | return; |
768 | } | 763 | } |
769 | 764 | ||
770 | status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2, | 765 | status = ia64_pal_cache_config_info(levels - 1, |
771 | &cci); | 766 | /* cache_type (data_or_unified)= */ 2, &cci); |
772 | if (status != 0) { | 767 | if (status != 0) { |
773 | printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n", | 768 | printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed " |
774 | __FUNCTION__, status); | 769 | "(status=%ld)\n", __FUNCTION__, status); |
775 | return SMP_CACHE_BYTES; | 770 | return; |
776 | } | 771 | } |
777 | cacheline_size = 1 << cci.pcci_line_size; | 772 | pci_cache_line_size = (1 << cci.pcci_line_size) / 4; |
778 | return cacheline_size; | ||
779 | } | 773 | } |
780 | 774 | ||
781 | /** | 775 | static int __init pcibios_init(void) |
782 | * pcibios_prep_mwi - helper function for drivers/pci/pci.c:pci_set_mwi() | 776 | { |
783 | * @dev: the PCI device for which MWI is enabled | 777 | set_pci_cacheline_size(); |
784 | * | 778 | return 0; |
785 | * For ia64, we can get the cacheline sizes from PAL. | ||
786 | * | ||
787 | * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. | ||
788 | */ | ||
789 | int | ||
790 | pcibios_prep_mwi (struct pci_dev *dev) | ||
791 | { | ||
792 | unsigned long desired_linesize, current_linesize; | ||
793 | int rc = 0; | ||
794 | u8 pci_linesize; | ||
795 | |||
796 | desired_linesize = pci_cacheline_size(); | ||
797 | |||
798 | pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_linesize); | ||
799 | current_linesize = 4 * pci_linesize; | ||
800 | if (desired_linesize != current_linesize) { | ||
801 | printk(KERN_WARNING "PCI: slot %s has incorrect PCI cache line size of %lu bytes,", | ||
802 | pci_name(dev), current_linesize); | ||
803 | if (current_linesize > desired_linesize) { | ||
804 | printk(" expected %lu bytes instead\n", desired_linesize); | ||
805 | rc = -EINVAL; | ||
806 | } else { | ||
807 | printk(" correcting to %lu\n", desired_linesize); | ||
808 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, desired_linesize / 4); | ||
809 | } | ||
810 | } | ||
811 | return rc; | ||
812 | } | 779 | } |
780 | |||
781 | subsys_initcall(pcibios_init); | ||
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index ef616fd4cb1b..825eb7d882e6 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h | |||
@@ -26,16 +26,18 @@ void pcibios_config_init(void); | |||
26 | struct pci_dev; | 26 | struct pci_dev; |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct correspondence | 29 | * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct |
30 | * between device bus addresses and CPU physical addresses. Platforms with a hardware I/O | 30 | * correspondence between device bus addresses and CPU physical addresses. |
31 | * MMU _must_ turn this off to suppress the bounce buffer handling code in the block and | 31 | * Platforms with a hardware I/O MMU _must_ turn this off to suppress the |
32 | * network device layers. Platforms with separate bus address spaces _must_ turn this off | 32 | * bounce buffer handling code in the block and network device layers. |
33 | * and provide a device DMA mapping implementation that takes care of the necessary | 33 | * Platforms with separate bus address spaces _must_ turn this off and provide |
34 | * a device DMA mapping implementation that takes care of the necessary | ||
34 | * address translation. | 35 | * address translation. |
35 | * | 36 | * |
36 | * For now, the ia64 platforms which may have separate/multiple bus address spaces all | 37 | * For now, the ia64 platforms which may have separate/multiple bus address |
37 | * have I/O MMUs which support the merging of physically discontiguous buffers, so we can | 38 | * spaces all have I/O MMUs which support the merging of physically |
38 | * use that as the sole factor to determine the setting of PCI_DMA_BUS_IS_PHYS. | 39 | * discontiguous buffers, so we can use that as the sole factor to determine |
40 | * the setting of PCI_DMA_BUS_IS_PHYS. | ||
39 | */ | 41 | */ |
40 | extern unsigned long ia64_max_iommu_merge_mask; | 42 | extern unsigned long ia64_max_iommu_merge_mask; |
41 | #define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) | 43 | #define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) |
@@ -52,9 +54,6 @@ pcibios_penalize_isa_irq (int irq, int active) | |||
52 | /* We don't do dynamic PCI IRQ allocation */ | 54 | /* We don't do dynamic PCI IRQ allocation */ |
53 | } | 55 | } |
54 | 56 | ||
55 | #define HAVE_ARCH_PCI_MWI 1 | ||
56 | extern int pcibios_prep_mwi (struct pci_dev *); | ||
57 | |||
58 | #include <asm-generic/pci-dma-compat.h> | 57 | #include <asm-generic/pci-dma-compat.h> |
59 | 58 | ||
60 | /* pci_unmap_{single,page} is not a nop, thus... */ | 59 | /* pci_unmap_{single,page} is not a nop, thus... */ |