aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2006-10-10 10:01:19 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-01 17:36:56 -0500
commit3efe2d84c8d909567c7976a7106114127b8c3470 (patch)
tree28b93040c032fe5b90bf4fc61fc656eea45832dc
parent368c73d4f689dae0807d0a2aa74c61fd2b9b075f (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.c71
-rw-r--r--include/asm-ia64/pci.h21
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 */
742extern 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 */
752static unsigned long 752static void __init set_pci_cacheline_size(void)
753pci_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/** 775static 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 */
789int
790pcibios_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
781subsys_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);
26struct pci_dev; 26struct 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 */
40extern unsigned long ia64_max_iommu_merge_mask; 42extern 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
56extern 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... */