ar71xx: add preliminary support for Mikrotik RB2011L
[openwrt/svn-archive/archive.git] / target / linux / ar71xx / patches-3.3 / 108-MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch
1 From 39f3275077a5b143616fcb3e7a6457a5c42739ee Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Wed, 14 Mar 2012 10:36:04 +0100
4 Subject: [PATCH 13/47] MIPS: ath79: fix broken ar724x_pci_{read,write} functions
5
6 The current ar724x_pci_{read,write} functions are
7 broken. Due to that, pci_read_config_byte returns
8 with bogus values, and pci_write_config_{byte,word}
9 unconditionally clears the accessed PCI configuration
10 registers instead of changing the value of them.
11
12 The patch fixes the broken functions, thus the PCI
13 configuration space can be accessed correctly.
14
15 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
16 Cc: linux-mips@linux-mips.org
17 Patchwork: https://patchwork.linux-mips.org/patch/3493/
18 Signed-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;