aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-09-22 04:34:48 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-11-04 11:47:11 -0500
commit15ea76d407d560f985224b65fe59c9db01692a0d (patch)
treedd9dd1cd4cab4bff26c34853a1c67898e8500243
parent4c0eec7a86303ce6e3edf7825d0ef1d414e76767 (diff)
pccard: configure CLS on attach
For non hotplug PCI devices, the system firmware usually configures CLS correctly. For pccard devices system firmware can't do it and Linux PCI layer doesn't do it either. Unfortunately this leads to poor performance for certain devices (sata_sil). Unless MWI, which requires separate configuration, is to be used, CLS doesn't affect correctness, so the configuration should be harmless. This patch makes pci_set_cacheline_size() always built and export it and make pccard call it during attach. Please note that some other PCI hotplug drivers (shpchp and pciehp) also configure CLS on hotplug. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Daniel Ritz <daniel.ritz@gmx.ch> Cc: Dominik Brodowski <linux@dominikbrodowski.net> Cc: Greg KH <greg@kroah.com> Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Cc: Axel Birndt <towerlexa@gmx.de> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/pci.c40
-rw-r--r--drivers/pcmcia/cardbus.c23
-rw-r--r--include/linux/pci.h1
3 files changed, 36 insertions, 28 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 01337b7a215f..d1afbae5b1fb 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1875,23 +1875,6 @@ void pci_clear_master(struct pci_dev *dev)
1875 __pci_set_master(dev, false); 1875 __pci_set_master(dev, false);
1876} 1876}
1877 1877
1878#ifdef PCI_DISABLE_MWI
1879int pci_set_mwi(struct pci_dev *dev)
1880{
1881 return 0;
1882}
1883
1884int pci_try_set_mwi(struct pci_dev *dev)
1885{
1886 return 0;
1887}
1888
1889void pci_clear_mwi(struct pci_dev *dev)
1890{
1891}
1892
1893#else
1894
1895/** 1878/**
1896 * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed 1879 * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
1897 * @dev: the PCI device for which MWI is to be enabled 1880 * @dev: the PCI device for which MWI is to be enabled
@@ -1902,13 +1885,12 @@ void pci_clear_mwi(struct pci_dev *dev)
1902 * 1885 *
1903 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1886 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
1904 */ 1887 */
1905static int 1888int pci_set_cacheline_size(struct pci_dev *dev)
1906pci_set_cacheline_size(struct pci_dev *dev)
1907{ 1889{
1908 u8 cacheline_size; 1890 u8 cacheline_size;
1909 1891
1910 if (!pci_cache_line_size) 1892 if (!pci_cache_line_size)
1911 return -EINVAL; /* The system doesn't support MWI. */ 1893 return -EINVAL;
1912 1894
1913 /* Validate current setting: the PCI_CACHE_LINE_SIZE must be 1895 /* Validate current setting: the PCI_CACHE_LINE_SIZE must be
1914 equal to or multiple of the right value. */ 1896 equal to or multiple of the right value. */
@@ -1929,6 +1911,24 @@ pci_set_cacheline_size(struct pci_dev *dev)
1929 1911
1930 return -EINVAL; 1912 return -EINVAL;
1931} 1913}
1914EXPORT_SYMBOL_GPL(pci_set_cacheline_size);
1915
1916#ifdef PCI_DISABLE_MWI
1917int pci_set_mwi(struct pci_dev *dev)
1918{
1919 return 0;
1920}
1921
1922int pci_try_set_mwi(struct pci_dev *dev)
1923{
1924 return 0;
1925}
1926
1927void pci_clear_mwi(struct pci_dev *dev)
1928{
1929}
1930
1931#else
1932 1932
1933/** 1933/**
1934 * pci_set_mwi - enables memory-write-invalidate PCI transaction 1934 * pci_set_mwi - enables memory-write-invalidate PCI transaction
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index db77e1f3309a..98789c031a7c 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -184,26 +184,33 @@ fail:
184 184
185=====================================================================*/ 185=====================================================================*/
186 186
187/* 187static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
188 * Since there is only one interrupt available to CardBus
189 * devices, all devices downstream of this device must
190 * be using this IRQ.
191 */
192static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
193{ 188{
194 struct pci_dev *dev; 189 struct pci_dev *dev;
195 190
196 list_for_each_entry(dev, &bus->devices, bus_list) { 191 list_for_each_entry(dev, &bus->devices, bus_list) {
197 u8 irq_pin; 192 u8 irq_pin;
198 193
194 /*
195 * Since there is only one interrupt available to
196 * CardBus devices, all devices downstream of this
197 * device must be using this IRQ.
198 */
199 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); 199 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
200 if (irq_pin) { 200 if (irq_pin) {
201 dev->irq = irq; 201 dev->irq = irq;
202 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 202 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
203 } 203 }
204 204
205 /*
206 * Some controllers transfer very slowly with 0 CLS.
207 * Configure it. This may fail as CLS configuration
208 * is mandatory only for MWI.
209 */
210 pci_set_cacheline_size(dev);
211
205 if (dev->subordinate) 212 if (dev->subordinate)
206 cardbus_assign_irqs(dev->subordinate, irq); 213 cardbus_config_irq_and_cls(dev->subordinate, irq);
207 } 214 }
208} 215}
209 216
@@ -228,7 +235,7 @@ int __ref cb_alloc(struct pcmcia_socket * s)
228 */ 235 */
229 pci_bus_size_bridges(bus); 236 pci_bus_size_bridges(bus);
230 pci_bus_assign_resources(bus); 237 pci_bus_assign_resources(bus);
231 cardbus_assign_irqs(bus, s->pci_irq); 238 cardbus_config_irq_and_cls(bus, s->pci_irq);
232 239
233 /* socket specific tune function */ 240 /* socket specific tune function */
234 if (s->tune_bridge) 241 if (s->tune_bridge)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b849861d78e6..da4128f6e916 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -701,6 +701,7 @@ void pci_disable_device(struct pci_dev *dev);
701void pci_set_master(struct pci_dev *dev); 701void pci_set_master(struct pci_dev *dev);
702void pci_clear_master(struct pci_dev *dev); 702void pci_clear_master(struct pci_dev *dev);
703int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); 703int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
704int pci_set_cacheline_size(struct pci_dev *dev);
704#define HAVE_PCI_SET_MWI 705#define HAVE_PCI_SET_MWI
705int __must_check pci_set_mwi(struct pci_dev *dev); 706int __must_check pci_set_mwi(struct pci_dev *dev);
706int pci_try_set_mwi(struct pci_dev *dev); 707int pci_try_set_mwi(struct pci_dev *dev);