aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2013-02-03 04:58:38 -0500
committerJohn Crispin <blogic@openwrt.org>2013-02-16 19:25:38 -0500
commit908339ef25b1d5e80f1c6fab22b9958174708b4a (patch)
tree6dceee739cc3dfa1cd956916c417b26a2e64b745 /arch/mips
parent617fed41e98417f3ea3e9974be251e125c8796f2 (diff)
MIPS: pci-ar724x: use dynamically allocated PCI controller structure
The current code uses static variables to store the PCI controller specific data. This works if the system contains one PCI controller only, however it becomes impractical when multiple PCI controllers are present. Move the variables into a dynamically allocated controller specific structure, and use that instead of the static variables. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/4912/ Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/pci/pci-ar724x.c129
1 files changed, 82 insertions, 47 deletions
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
index 8f008d9a112c..93ab8778ce10 100644
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -9,6 +9,7 @@
9 * by the Free Software Foundation. 9 * by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/spinlock.h>
12#include <linux/irq.h> 13#include <linux/irq.h>
13#include <linux/pci.h> 14#include <linux/pci.h>
14#include <linux/module.h> 15#include <linux/module.h>
@@ -28,38 +29,56 @@
28 29
29#define AR7240_BAR0_WAR_VALUE 0xffff 30#define AR7240_BAR0_WAR_VALUE 0xffff
30 31
31static DEFINE_SPINLOCK(ar724x_pci_lock); 32struct ar724x_pci_controller {
32static void __iomem *ar724x_pci_devcfg_base; 33 void __iomem *devcfg_base;
33static void __iomem *ar724x_pci_ctrl_base; 34 void __iomem *ctrl_base;
34 35
35static u32 ar724x_pci_bar0_value; 36 int irq;
36static bool ar724x_pci_bar0_is_cached; 37
37static bool ar724x_pci_link_up; 38 bool link_up;
39 bool bar0_is_cached;
40 u32 bar0_value;
41
42 spinlock_t lock;
43
44 struct pci_controller pci_controller;
45};
38 46
39static inline bool ar724x_pci_check_link(void) 47static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
40{ 48{
41 u32 reset; 49 u32 reset;
42 50
43 reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); 51 reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
44 return reset & AR724X_PCI_RESET_LINK_UP; 52 return reset & AR724X_PCI_RESET_LINK_UP;
45} 53}
46 54
55static inline struct ar724x_pci_controller *
56pci_bus_to_ar724x_controller(struct pci_bus *bus)
57{
58 struct pci_controller *hose;
59
60 hose = (struct pci_controller *) bus->sysdata;
61 return container_of(hose, struct ar724x_pci_controller, pci_controller);
62}
63
47static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, 64static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
48 int size, uint32_t *value) 65 int size, uint32_t *value)
49{ 66{
67 struct ar724x_pci_controller *apc;
50 unsigned long flags; 68 unsigned long flags;
51 void __iomem *base; 69 void __iomem *base;
52 u32 data; 70 u32 data;
53 71
54 if (!ar724x_pci_link_up) 72 apc = pci_bus_to_ar724x_controller(bus);
73 if (!apc->link_up)
55 return PCIBIOS_DEVICE_NOT_FOUND; 74 return PCIBIOS_DEVICE_NOT_FOUND;
56 75
57 if (devfn) 76 if (devfn)
58 return PCIBIOS_DEVICE_NOT_FOUND; 77 return PCIBIOS_DEVICE_NOT_FOUND;
59 78
60 base = ar724x_pci_devcfg_base; 79 base = apc->devcfg_base;
61 80
62 spin_lock_irqsave(&ar724x_pci_lock, flags); 81 spin_lock_irqsave(&apc->lock, flags);
63 data = __raw_readl(base + (where & ~3)); 82 data = __raw_readl(base + (where & ~3));
64 83
65 switch (size) { 84 switch (size) {
@@ -78,17 +97,17 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
78 case 4: 97 case 4:
79 break; 98 break;
80 default: 99 default:
81 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 100 spin_unlock_irqrestore(&apc->lock, flags);
82 101
83 return PCIBIOS_BAD_REGISTER_NUMBER; 102 return PCIBIOS_BAD_REGISTER_NUMBER;
84 } 103 }
85 104
86 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 105 spin_unlock_irqrestore(&apc->lock, flags);
87 106
88 if (where == PCI_BASE_ADDRESS_0 && size == 4 && 107 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
89 ar724x_pci_bar0_is_cached) { 108 apc->bar0_is_cached) {
90 /* use the cached value */ 109 /* use the cached value */
91 *value = ar724x_pci_bar0_value; 110 *value = apc->bar0_value;
92 } else { 111 } else {
93 *value = data; 112 *value = data;
94 } 113 }
@@ -99,12 +118,14 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
99static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, 118static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
100 int size, uint32_t value) 119 int size, uint32_t value)
101{ 120{
121 struct ar724x_pci_controller *apc;
102 unsigned long flags; 122 unsigned long flags;
103 void __iomem *base; 123 void __iomem *base;
104 u32 data; 124 u32 data;
105 int s; 125 int s;
106 126
107 if (!ar724x_pci_link_up) 127 apc = pci_bus_to_ar724x_controller(bus);
128 if (!apc->link_up)
108 return PCIBIOS_DEVICE_NOT_FOUND; 129 return PCIBIOS_DEVICE_NOT_FOUND;
109 130
110 if (devfn) 131 if (devfn)
@@ -122,18 +143,18 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
122 * BAR0 register in order to make the device memory 143 * BAR0 register in order to make the device memory
123 * accessible. 144 * accessible.
124 */ 145 */
125 ar724x_pci_bar0_is_cached = true; 146 apc->bar0_is_cached = true;
126 ar724x_pci_bar0_value = value; 147 apc->bar0_value = value;
127 148
128 value = AR7240_BAR0_WAR_VALUE; 149 value = AR7240_BAR0_WAR_VALUE;
129 } else { 150 } else {
130 ar724x_pci_bar0_is_cached = false; 151 apc->bar0_is_cached = false;
131 } 152 }
132 } 153 }
133 154
134 base = ar724x_pci_devcfg_base; 155 base = apc->devcfg_base;
135 156
136 spin_lock_irqsave(&ar724x_pci_lock, flags); 157 spin_lock_irqsave(&apc->lock, flags);
137 data = __raw_readl(base + (where & ~3)); 158 data = __raw_readl(base + (where & ~3));
138 159
139 switch (size) { 160 switch (size) {
@@ -151,7 +172,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
151 data = value; 172 data = value;
152 break; 173 break;
153 default: 174 default:
154 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 175 spin_unlock_irqrestore(&apc->lock, flags);
155 176
156 return PCIBIOS_BAD_REGISTER_NUMBER; 177 return PCIBIOS_BAD_REGISTER_NUMBER;
157 } 178 }
@@ -159,7 +180,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
159 __raw_writel(data, base + (where & ~3)); 180 __raw_writel(data, base + (where & ~3));
160 /* flush write */ 181 /* flush write */
161 __raw_readl(base + (where & ~3)); 182 __raw_readl(base + (where & ~3));
162 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 183 spin_unlock_irqrestore(&apc->lock, flags);
163 184
164 return PCIBIOS_SUCCESSFUL; 185 return PCIBIOS_SUCCESSFUL;
165} 186}
@@ -183,18 +204,14 @@ static struct resource ar724x_mem_resource = {
183 .flags = IORESOURCE_MEM, 204 .flags = IORESOURCE_MEM,
184}; 205};
185 206
186static struct pci_controller ar724x_pci_controller = {
187 .pci_ops = &ar724x_pci_ops,
188 .io_resource = &ar724x_io_resource,
189 .mem_resource = &ar724x_mem_resource,
190};
191
192static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) 207static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
193{ 208{
209 struct ar724x_pci_controller *apc;
194 void __iomem *base; 210 void __iomem *base;
195 u32 pending; 211 u32 pending;
196 212
197 base = ar724x_pci_ctrl_base; 213 apc = irq_get_handler_data(irq);
214 base = apc->ctrl_base;
198 215
199 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & 216 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
200 __raw_readl(base + AR724X_PCI_REG_INT_MASK); 217 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
@@ -208,10 +225,12 @@ static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
208 225
209static void ar724x_pci_irq_unmask(struct irq_data *d) 226static void ar724x_pci_irq_unmask(struct irq_data *d)
210{ 227{
228 struct ar724x_pci_controller *apc;
211 void __iomem *base; 229 void __iomem *base;
212 u32 t; 230 u32 t;
213 231
214 base = ar724x_pci_ctrl_base; 232 apc = irq_data_get_irq_chip_data(d);
233 base = apc->ctrl_base;
215 234
216 switch (d->irq) { 235 switch (d->irq) {
217 case ATH79_PCI_IRQ(0): 236 case ATH79_PCI_IRQ(0):
@@ -225,10 +244,12 @@ static void ar724x_pci_irq_unmask(struct irq_data *d)
225 244
226static void ar724x_pci_irq_mask(struct irq_data *d) 245static void ar724x_pci_irq_mask(struct irq_data *d)
227{ 246{
247 struct ar724x_pci_controller *apc;
228 void __iomem *base; 248 void __iomem *base;
229 u32 t; 249 u32 t;
230 250
231 base = ar724x_pci_ctrl_base; 251 apc = irq_data_get_irq_chip_data(d);
252 base = apc->ctrl_base;
232 253
233 switch (d->irq) { 254 switch (d->irq) {
234 case ATH79_PCI_IRQ(0): 255 case ATH79_PCI_IRQ(0):
@@ -255,12 +276,12 @@ static struct irq_chip ar724x_pci_irq_chip = {
255 .irq_mask_ack = ar724x_pci_irq_mask, 276 .irq_mask_ack = ar724x_pci_irq_mask,
256}; 277};
257 278
258static void ar724x_pci_irq_init(int irq) 279static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc)
259{ 280{
260 void __iomem *base; 281 void __iomem *base;
261 int i; 282 int i;
262 283
263 base = ar724x_pci_ctrl_base; 284 base = apc->ctrl_base;
264 285
265 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); 286 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
266 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); 287 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
@@ -268,45 +289,59 @@ static void ar724x_pci_irq_init(int irq)
268 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); 289 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
269 290
270 for (i = ATH79_PCI_IRQ_BASE; 291 for (i = ATH79_PCI_IRQ_BASE;
271 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) 292 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) {
272 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, 293 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
273 handle_level_irq); 294 handle_level_irq);
295 irq_set_chip_data(i, apc);
296 }
274 297
275 irq_set_chained_handler(irq, ar724x_pci_irq_handler); 298 irq_set_handler_data(apc->irq, apc);
299 irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
276} 300}
277 301
278static int ar724x_pci_probe(struct platform_device *pdev) 302static int ar724x_pci_probe(struct platform_device *pdev)
279{ 303{
304 struct ar724x_pci_controller *apc;
280 struct resource *res; 305 struct resource *res;
281 int irq; 306
307 apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
308 GFP_KERNEL);
309 if (!apc)
310 return -ENOMEM;
282 311
283 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base"); 312 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
284 if (!res) 313 if (!res)
285 return -EINVAL; 314 return -EINVAL;
286 315
287 ar724x_pci_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); 316 apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
288 if (ar724x_pci_ctrl_base == NULL) 317 if (apc->ctrl_base == NULL)
289 return -EBUSY; 318 return -EBUSY;
290 319
291 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); 320 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
292 if (!res) 321 if (!res)
293 return -EINVAL; 322 return -EINVAL;
294 323
295 ar724x_pci_devcfg_base = devm_request_and_ioremap(&pdev->dev, res); 324 apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
296 if (!ar724x_pci_devcfg_base) 325 if (!apc->devcfg_base)
297 return -EBUSY; 326 return -EBUSY;
298 327
299 irq = platform_get_irq(pdev, 0); 328 apc->irq = platform_get_irq(pdev, 0);
300 if (irq < 0) 329 if (apc->irq < 0)
301 return -EINVAL; 330 return -EINVAL;
302 331
303 ar724x_pci_link_up = ar724x_pci_check_link(); 332 spin_lock_init(&apc->lock);
304 if (!ar724x_pci_link_up) 333
334 apc->pci_controller.pci_ops = &ar724x_pci_ops;
335 apc->pci_controller.io_resource = &ar724x_io_resource;
336 apc->pci_controller.mem_resource = &ar724x_mem_resource;
337
338 apc->link_up = ar724x_pci_check_link(apc);
339 if (!apc->link_up)
305 dev_warn(&pdev->dev, "PCIe link is down\n"); 340 dev_warn(&pdev->dev, "PCIe link is down\n");
306 341
307 ar724x_pci_irq_init(irq); 342 ar724x_pci_irq_init(apc);
308 343
309 register_pci_controller(&ar724x_pci_controller); 344 register_pci_controller(&apc->pci_controller);
310 345
311 return 0; 346 return 0;
312} 347}