Commit 3efe2d84 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Greg Kroah-Hartman

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: default avatarMatthew Wilcox <matthew@wil.cx>
Acked-by: default avatarJeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 368c73d4
...@@ -738,75 +738,44 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) ...@@ -738,75 +738,44 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
return ret; return ret;
} }
/* It's defined in drivers/pci/pci.c */
extern u8 pci_cache_line_size;
/** /**
* pci_cacheline_size - determine cacheline size for PCI devices * set_pci_cacheline_size - determine cacheline size for PCI devices
* @dev: void
* *
* We want to use the line-size of the outer-most cache. We assume * We want to use the line-size of the outer-most cache. We assume
* that this line-size is the same for all CPUs. * that this line-size is the same for all CPUs.
* *
* Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
*
* RETURNS: An appropriate -ERRNO error value on eror, or zero for success.
*/ */
static unsigned long static void __init set_pci_cacheline_size(void)
pci_cacheline_size (void)
{ {
u64 levels, unique_caches; u64 levels, unique_caches;
s64 status; s64 status;
pal_cache_config_info_t cci; pal_cache_config_info_t cci;
static u8 cacheline_size;
if (cacheline_size)
return cacheline_size;
status = ia64_pal_cache_summary(&levels, &unique_caches); status = ia64_pal_cache_summary(&levels, &unique_caches);
if (status != 0) { if (status != 0) {
printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", printk(KERN_ERR "%s: ia64_pal_cache_summary() failed "
__FUNCTION__, status); "(status=%ld)\n", __FUNCTION__, status);
return SMP_CACHE_BYTES; return;
} }
status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2, status = ia64_pal_cache_config_info(levels - 1,
&cci); /* cache_type (data_or_unified)= */ 2, &cci);
if (status != 0) { if (status != 0) {
printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n", printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed "
__FUNCTION__, status); "(status=%ld)\n", __FUNCTION__, status);
return SMP_CACHE_BYTES; return;
} }
cacheline_size = 1 << cci.pcci_line_size; pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
return cacheline_size;
} }
/** static int __init pcibios_init(void)
* pcibios_prep_mwi - helper function for drivers/pci/pci.c:pci_set_mwi() {
* @dev: the PCI device for which MWI is enabled set_pci_cacheline_size();
* return 0;
* For ia64, we can get the cacheline sizes from PAL.
*
* RETURNS: An appropriate -ERRNO error value on eror, or zero for success.
*/
int
pcibios_prep_mwi (struct pci_dev *dev)
{
unsigned long desired_linesize, current_linesize;
int rc = 0;
u8 pci_linesize;
desired_linesize = pci_cacheline_size();
pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_linesize);
current_linesize = 4 * pci_linesize;
if (desired_linesize != current_linesize) {
printk(KERN_WARNING "PCI: slot %s has incorrect PCI cache line size of %lu bytes,",
pci_name(dev), current_linesize);
if (current_linesize > desired_linesize) {
printk(" expected %lu bytes instead\n", desired_linesize);
rc = -EINVAL;
} else {
printk(" correcting to %lu\n", desired_linesize);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, desired_linesize / 4);
}
}
return rc;
} }
subsys_initcall(pcibios_init);
...@@ -26,16 +26,18 @@ void pcibios_config_init(void); ...@@ -26,16 +26,18 @@ void pcibios_config_init(void);
struct pci_dev; struct pci_dev;
/* /*
* PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct correspondence * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct
* between device bus addresses and CPU physical addresses. Platforms with a hardware I/O * correspondence between device bus addresses and CPU physical addresses.
* MMU _must_ turn this off to suppress the bounce buffer handling code in the block and * Platforms with a hardware I/O MMU _must_ turn this off to suppress the
* network device layers. Platforms with separate bus address spaces _must_ turn this off * bounce buffer handling code in the block and network device layers.
* and provide a device DMA mapping implementation that takes care of the necessary * Platforms with separate bus address spaces _must_ turn this off and provide
* a device DMA mapping implementation that takes care of the necessary
* address translation. * address translation.
* *
* For now, the ia64 platforms which may have separate/multiple bus address spaces all * For now, the ia64 platforms which may have separate/multiple bus address
* have I/O MMUs which support the merging of physically discontiguous buffers, so we can * spaces all have I/O MMUs which support the merging of physically
* use that as the sole factor to determine the setting of PCI_DMA_BUS_IS_PHYS. * discontiguous buffers, so we can use that as the sole factor to determine
* the setting of PCI_DMA_BUS_IS_PHYS.
*/ */
extern unsigned long ia64_max_iommu_merge_mask; extern unsigned long ia64_max_iommu_merge_mask;
#define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) #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,9 +54,6 @@ pcibios_penalize_isa_irq (int irq, int active)
/* We don't do dynamic PCI IRQ allocation */ /* We don't do dynamic PCI IRQ allocation */
} }
#define HAVE_ARCH_PCI_MWI 1
extern int pcibios_prep_mwi (struct pci_dev *);
#include <asm-generic/pci-dma-compat.h> #include <asm-generic/pci-dma-compat.h>
/* pci_unmap_{single,page} is not a nop, thus... */ /* pci_unmap_{single,page} is not a nop, thus... */
......
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