Root/target/linux/ar71xx/patches-3.3/108-MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch

1From 39f3275077a5b143616fcb3e7a6457a5c42739ee Mon Sep 17 00:00:00 2001
2From: Gabor Juhos <juhosg@openwrt.org>
3Date: Wed, 14 Mar 2012 10:36:04 +0100
4Subject: [PATCH 13/47] MIPS: ath79: fix broken ar724x_pci_{read,write} functions
5
6The current ar724x_pci_{read,write} functions are
7broken. Due to that, pci_read_config_byte returns
8with bogus values, and pci_write_config_{byte,word}
9unconditionally clears the accessed PCI configuration
10registers instead of changing the value of them.
11
12The patch fixes the broken functions, thus the PCI
13configuration space can be accessed correctly.
14
15Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
16Cc: linux-mips@linux-mips.org
17Patchwork: https://patchwork.linux-mips.org/patch/3493/
18Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
19---
20 arch/mips/pci/pci-ar724x.c | 52 ++++++++++++++++++++++----------------------
21 1 files changed, 26 insertions(+), 26 deletions(-)
22
23--- a/arch/mips/pci/pci-ar724x.c
24+++ b/arch/mips/pci/pci-ar724x.c
25@@ -22,8 +22,9 @@ static void __iomem *ar724x_pci_devcfg_b
26 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
27                 int size, uint32_t *value)
28 {
29- unsigned long flags, addr, tval, mask;
30+ unsigned long flags;
31     void __iomem *base;
32+ u32 data;
33 
34     if (devfn)
35         return PCIBIOS_DEVICE_NOT_FOUND;
36@@ -31,24 +32,22 @@ static int ar724x_pci_read(struct pci_bu
37     base = ar724x_pci_devcfg_base;
38 
39     spin_lock_irqsave(&ar724x_pci_lock, flags);
40+ data = __raw_readl(base + (where & ~3));
41 
42     switch (size) {
43     case 1:
44- addr = where & ~3;
45- mask = 0xff000000 >> ((where % 4) * 8);
46- tval = __raw_readl(base + addr);
47- tval = tval & ~mask;
48- *value = (tval >> ((4 - (where % 4))*8));
49+ if (where & 1)
50+ data >>= 8;
51+ if (where & 2)
52+ data >>= 16;
53+ data &= 0xff;
54         break;
55     case 2:
56- addr = where & ~3;
57- mask = 0xffff0000 >> ((where % 4)*8);
58- tval = __raw_readl(base + addr);
59- tval = tval & ~mask;
60- *value = (tval >> ((4 - (where % 4))*8));
61+ if (where & 2)
62+ data >>= 16;
63+ data &= 0xffff;
64         break;
65     case 4:
66- *value = __raw_readl(base + where);
67         break;
68     default:
69         spin_unlock_irqrestore(&ar724x_pci_lock, flags);
70@@ -57,6 +56,7 @@ static int ar724x_pci_read(struct pci_bu
71     }
72 
73     spin_unlock_irqrestore(&ar724x_pci_lock, flags);
74+ *value = data;
75 
76     return PCIBIOS_SUCCESSFUL;
77 }
78@@ -64,8 +64,10 @@ static int ar724x_pci_read(struct pci_bu
79 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
80                  int size, uint32_t value)
81 {
82- unsigned long flags, tval, addr, mask;
83+ unsigned long flags;
84     void __iomem *base;
85+ u32 data;
86+ int s;
87 
88     if (devfn)
89         return PCIBIOS_DEVICE_NOT_FOUND;
90@@ -73,26 +75,21 @@ static int ar724x_pci_write(struct pci_b
91     base = ar724x_pci_devcfg_base;
92 
93     spin_lock_irqsave(&ar724x_pci_lock, flags);
94+ data = __raw_readl(base + (where & ~3));
95 
96     switch (size) {
97     case 1:
98- addr = where & ~3;
99- mask = 0xff000000 >> ((where % 4)*8);
100- tval = __raw_readl(base + addr);
101- tval = tval & ~mask;
102- tval |= (value << ((4 - (where % 4))*8)) & mask;
103- __raw_writel(tval, base + addr);
104+ s = ((where & 3) * 8);
105+ data &= ~(0xff << s);
106+ data |= ((value & 0xff) << s);
107         break;
108     case 2:
109- addr = where & ~3;
110- mask = 0xffff0000 >> ((where % 4)*8);
111- tval = __raw_readl(base + addr);
112- tval = tval & ~mask;
113- tval |= (value << ((4 - (where % 4))*8)) & mask;
114- __raw_writel(tval, base + addr);
115+ s = ((where & 2) * 8);
116+ data &= ~(0xffff << s);
117+ data |= ((value & 0xffff) << s);
118         break;
119     case 4:
120- __raw_writel(value, (base + where));
121+ data = value;
122         break;
123     default:
124         spin_unlock_irqrestore(&ar724x_pci_lock, flags);
125@@ -100,6 +97,9 @@ static int ar724x_pci_write(struct pci_b
126         return PCIBIOS_BAD_REGISTER_NUMBER;
127     }
128 
129+ __raw_writel(data, base + (where & ~3));
130+ /* flush write */
131+ __raw_readl(base + (where & ~3));
132     spin_unlock_irqrestore(&ar724x_pci_lock, flags);
133 
134     return PCIBIOS_SUCCESSFUL;
135

Archive Download this file



interactive