PCI: Pull PCI 'latency timer' setup up into the core
authorMyron Stowe <mstowe@redhat.com>
Fri, 28 Oct 2011 21:48:38 +0000 (15:48 -0600)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 6 Jan 2012 20:10:42 +0000 (12:10 -0800)
The 'latency timer' of PCI devices, both Type 0 and Type 1,
is setup in architecture-specific code [see: 'pcibios_set_master()'].
There are two approaches being taken by all the architectures - check
if the 'latency timer' is currently set between 16 and 255 and if not
bring it within bounds, or, do nothing (and then there is the
gratuitously different PA-RISC implementation).

There is nothing architecture-specific about PCI's 'latency timer' so
this patch pulls its setup functionality up into the PCI core by
creating a generic 'pcibios_set_master()' function using the '__weak'
attribute which can be used by all architectures as a default which,
if necessary, can then be over-ridden by architecture-specific code.

No functional change.

Signed-off-by: Myron Stowe <myron.stowe@redhat.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
12 files changed:
arch/blackfin/include/asm/pci.h
arch/frv/mb93090-mb00/pci-frv.c
arch/frv/mb93090-mb00/pci-frv.h
arch/h8300/include/asm/pci.h
arch/mips/pci/pci.c
arch/mn10300/unit-asb2305/pci-asb2305.c
arch/mn10300/unit-asb2305/pci-asb2305.h
arch/sh/drivers/pci/pci.c
arch/x86/include/asm/pci_x86.h
arch/x86/pci/i386.c
drivers/pci/pci.c
include/linux/pci.h

index 99cae2e3bac702259b9dc4c469b2eeb85890f2b3..74352c4597d92f5802531ac0ca86c08766b6a62f 100644 (file)
 #define PCIBIOS_MIN_IO 0x00001000
 #define PCIBIOS_MIN_MEM 0x10000000
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-       /* No special bus mastering setup handling */
-}
 static inline void pcibios_penalize_isa_irq(int irq)
 {
        /* We don't do dynamic PCI IRQ allocation */
index 6b4fb28e9f997d1a9bf64f19cd26fba08ac8b9df..6a0cd644d7ccff67b91a0f1b28f374d5a6bbb1f4 100644 (file)
@@ -195,12 +195,6 @@ void __init pcibios_resource_survey(void)
        pcibios_assign_resources();
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
        u8 lat;
index f3fe5591479388ba6c2b3d7b6320740dfd392701..089eeba4f3bc4f92b5a28c32e071289723cb8bc3 100644 (file)
@@ -26,8 +26,6 @@ extern unsigned int __nongpreldata pci_probe;
 
 /* pci-frv.c */
 
-extern unsigned int pcibios_max_latency;
-
 void pcibios_resource_survey(void);
 
 /* pci-vdk.c */
index cc9762091c0a3a47e3f66005c40df51712534228..0b2acaa3dd84c266000880ee604218fd4547a78b 100644 (file)
@@ -9,11 +9,6 @@
 
 #define pcibios_assign_all_busses()    0
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-       /* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
        /* We don't do dynamic PCI IRQ allocation */
index 41af7fa2887b7c6266800a1c000bff0d8da06099..f93f749b92e36134f79a9069fea9d2d597766f6d 100644 (file)
@@ -205,12 +205,6 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
        return 0;
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-static unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
        u8 lat;
index 8e6763e6f25011f9d4eb68509c12ccb0dcb5014a..2b299c413ae55a84ef58f9c0ca2e0a455b8c4192 100644 (file)
@@ -213,12 +213,6 @@ void __init pcibios_resource_survey(void)
        pcibios_allocate_resources(1);
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
        u8 lat;
index c3fa294b6e2840ecb39556c6064cfde2ae68797e..1194fe486b01e6334c5ec12ec4f43261723e9538 100644 (file)
@@ -31,8 +31,6 @@ extern unsigned int pci_probe;
 
 /* pci-asb2305.c */
 
-extern unsigned int pcibios_max_latency;
-
 extern void pcibios_resource_survey(void);
 
 /* pci.c */
index c2691afe8f79c9e08e402dae2f31a5231e34c6f5..cfdb2f65294943940373aab388405d16ddbf7d6e 100644 (file)
@@ -243,12 +243,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        return pci_enable_resources(dev, mask);
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check and set
- *  the latency timer as it may not be properly set.
- */
-static unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
        u8 lat;
index e381978068533292e67ef9dfc613b1b939671bbb..b3a531746026105ba70b4d29293696bc02e32779 100644 (file)
@@ -44,8 +44,6 @@ enum pci_bf_sort_state {
 
 /* pci-i386.c */
 
-extern unsigned int pcibios_max_latency;
-
 void pcibios_resource_survey(void);
 void pcibios_set_cache_line_size(void);
 
index 794b092d01aeb389ec9db257b00c03176066bd06..dd5806b0fc8b96c7b80cc48192cd87fc6399a4d4 100644 (file)
@@ -254,12 +254,6 @@ void __init pcibios_resource_survey(void)
  */
 fs_initcall(pcibios_assign_resources);
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
        u8 lat;
index 924193ef4fe1a84a3187265d10eb642f8166a18c..f9abe84cf5e085e4f288621f9d6ddc17fab07556 100644 (file)
@@ -88,6 +88,12 @@ enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
 u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2;
 u8 pci_cache_line_size;
 
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as certain BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -2595,6 +2601,29 @@ static void __pci_set_master(struct pci_dev *dev, bool enable)
        dev->is_busmaster = enable;
 }
 
+/**
+ * pcibios_set_master - enable PCI bus-mastering for device dev
+ * @dev: the PCI device to enable
+ *
+ * Enables PCI bus-mastering for the device.  This is the default
+ * implementation.  Architecture specific implementations can override
+ * this if necessary.
+ */
+void __weak pcibios_set_master(struct pci_dev *dev)
+{
+       u8 lat;
+
+       pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+       if (lat < 16)
+               lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+       else if (lat > pcibios_max_latency)
+               lat = pcibios_max_latency;
+       else
+               return;
+       dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
+       pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
 /**
  * pci_set_master - enables bus-mastering for device dev
  * @dev: the PCI device to enable
index 569341d2d527fae66b5c1053f83059fd53a5465b..4c16a57889986411a21364deb9682d444b903e46 100644 (file)
@@ -795,8 +795,11 @@ static inline int pci_is_managed(struct pci_dev *pdev)
 }
 
 void pci_disable_device(struct pci_dev *dev);
+
+extern unsigned int pcibios_max_latency;
 void pci_set_master(struct pci_dev *dev);
 void pci_clear_master(struct pci_dev *dev);
+
 int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
 int pci_set_cacheline_size(struct pci_dev *dev);
 #define HAVE_PCI_SET_MWI