aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2013-02-07 14:28:14 -0500
committerJohn Crispin <blogic@openwrt.org>2013-02-16 19:25:40 -0500
commitf18118a868f1f7e7bdfea176a204fcc44fae2985 (patch)
tree30d921435da97f0fcc9c67b7e39a9338e1e96964 /arch/mips/pci
parent12401fc28d40aa5bf8bda6991a96b6d7a3dae3ac (diff)
MIPS: pci-ar71xx: use dynamically allocated PCI controller structure
Signed-off-by: Gabor Juhos <juhosg@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/4926/ Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips/pci')
-rw-r--r--arch/mips/pci/pci-ar71xx.c84
1 files changed, 53 insertions, 31 deletions
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c
index 69e0bb47de08..44dc5bf720c0 100644
--- a/arch/mips/pci/pci-ar71xx.c
+++ b/arch/mips/pci/pci-ar71xx.c
@@ -48,8 +48,12 @@
48 48
49#define AR71XX_PCI_IRQ_COUNT 5 49#define AR71XX_PCI_IRQ_COUNT 5
50 50
51static DEFINE_SPINLOCK(ar71xx_pci_lock); 51struct ar71xx_pci_controller {
52static void __iomem *ar71xx_pcicfg_base; 52 void __iomem *cfg_base;
53 spinlock_t lock;
54 int irq;
55 struct pci_controller pci_ctrl;
56};
53 57
54/* Byte lane enable bits */ 58/* Byte lane enable bits */
55static const u8 ar71xx_pci_ble_table[4][4] = { 59static const u8 ar71xx_pci_ble_table[4][4] = {
@@ -92,9 +96,18 @@ static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
92 return ret; 96 return ret;
93} 97}
94 98
95static int ar71xx_pci_check_error(int quiet) 99static inline struct ar71xx_pci_controller *
100pci_bus_to_ar71xx_controller(struct pci_bus *bus)
96{ 101{
97 void __iomem *base = ar71xx_pcicfg_base; 102 struct pci_controller *hose;
103
104 hose = (struct pci_controller *) bus->sysdata;
105 return container_of(hose, struct ar71xx_pci_controller, pci_ctrl);
106}
107
108static int ar71xx_pci_check_error(struct ar71xx_pci_controller *apc, int quiet)
109{
110 void __iomem *base = apc->cfg_base;
98 u32 pci_err; 111 u32 pci_err;
99 u32 ahb_err; 112 u32 ahb_err;
100 113
@@ -129,9 +142,10 @@ static int ar71xx_pci_check_error(int quiet)
129 return !!(ahb_err | pci_err); 142 return !!(ahb_err | pci_err);
130} 143}
131 144
132static inline void ar71xx_pci_local_write(int where, int size, u32 value) 145static inline void ar71xx_pci_local_write(struct ar71xx_pci_controller *apc,
146 int where, int size, u32 value)
133{ 147{
134 void __iomem *base = ar71xx_pcicfg_base; 148 void __iomem *base = apc->cfg_base;
135 u32 ad_cbe; 149 u32 ad_cbe;
136 150
137 value = value << (8 * (where & 3)); 151 value = value << (8 * (where & 3));
@@ -147,7 +161,8 @@ static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
147 unsigned int devfn, 161 unsigned int devfn,
148 int where, int size, u32 cmd) 162 int where, int size, u32 cmd)
149{ 163{
150 void __iomem *base = ar71xx_pcicfg_base; 164 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
165 void __iomem *base = apc->cfg_base;
151 u32 addr; 166 u32 addr;
152 167
153 addr = ar71xx_pci_bus_addr(bus, devfn, where); 168 addr = ar71xx_pci_bus_addr(bus, devfn, where);
@@ -156,13 +171,14 @@ static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
156 __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), 171 __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
157 base + AR71XX_PCI_REG_CFG_CBE); 172 base + AR71XX_PCI_REG_CFG_CBE);
158 173
159 return ar71xx_pci_check_error(1); 174 return ar71xx_pci_check_error(apc, 1);
160} 175}
161 176
162static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, 177static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
163 int where, int size, u32 *value) 178 int where, int size, u32 *value)
164{ 179{
165 void __iomem *base = ar71xx_pcicfg_base; 180 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
181 void __iomem *base = apc->cfg_base;
166 unsigned long flags; 182 unsigned long flags;
167 u32 data; 183 u32 data;
168 int err; 184 int err;
@@ -171,7 +187,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
171 ret = PCIBIOS_SUCCESSFUL; 187 ret = PCIBIOS_SUCCESSFUL;
172 data = ~0; 188 data = ~0;
173 189
174 spin_lock_irqsave(&ar71xx_pci_lock, flags); 190 spin_lock_irqsave(&apc->lock, flags);
175 191
176 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, 192 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
177 AR71XX_PCI_CFG_CMD_READ); 193 AR71XX_PCI_CFG_CMD_READ);
@@ -180,7 +196,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
180 else 196 else
181 data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); 197 data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA);
182 198
183 spin_unlock_irqrestore(&ar71xx_pci_lock, flags); 199 spin_unlock_irqrestore(&apc->lock, flags);
184 200
185 *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; 201 *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7];
186 202
@@ -190,7 +206,8 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
190static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, 206static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
191 int where, int size, u32 value) 207 int where, int size, u32 value)
192{ 208{
193 void __iomem *base = ar71xx_pcicfg_base; 209 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
210 void __iomem *base = apc->cfg_base;
194 unsigned long flags; 211 unsigned long flags;
195 int err; 212 int err;
196 int ret; 213 int ret;
@@ -198,7 +215,7 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
198 value = value << (8 * (where & 3)); 215 value = value << (8 * (where & 3));
199 ret = PCIBIOS_SUCCESSFUL; 216 ret = PCIBIOS_SUCCESSFUL;
200 217
201 spin_lock_irqsave(&ar71xx_pci_lock, flags); 218 spin_lock_irqsave(&apc->lock, flags);
202 219
203 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, 220 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
204 AR71XX_PCI_CFG_CMD_WRITE); 221 AR71XX_PCI_CFG_CMD_WRITE);
@@ -207,7 +224,7 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
207 else 224 else
208 __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); 225 __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA);
209 226
210 spin_unlock_irqrestore(&ar71xx_pci_lock, flags); 227 spin_unlock_irqrestore(&apc->lock, flags);
211 228
212 return ret; 229 return ret;
213} 230}
@@ -231,12 +248,6 @@ static struct resource ar71xx_pci_mem_resource = {
231 .flags = IORESOURCE_MEM 248 .flags = IORESOURCE_MEM
232}; 249};
233 250
234static struct pci_controller ar71xx_pci_controller = {
235 .pci_ops = &ar71xx_pci_ops,
236 .mem_resource = &ar71xx_pci_mem_resource,
237 .io_resource = &ar71xx_pci_io_resource,
238};
239
240static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) 251static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
241{ 252{
242 void __iomem *base = ath79_reset_base; 253 void __iomem *base = ath79_reset_base;
@@ -294,7 +305,7 @@ static struct irq_chip ar71xx_pci_irq_chip = {
294 .irq_mask_ack = ar71xx_pci_irq_mask, 305 .irq_mask_ack = ar71xx_pci_irq_mask,
295}; 306};
296 307
297static void ar71xx_pci_irq_init(int irq) 308static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
298{ 309{
299 void __iomem *base = ath79_reset_base; 310 void __iomem *base = ath79_reset_base;
300 int i; 311 int i;
@@ -309,7 +320,7 @@ static void ar71xx_pci_irq_init(int irq)
309 irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, 320 irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
310 handle_level_irq); 321 handle_level_irq);
311 322
312 irq_set_chained_handler(irq, ar71xx_pci_irq_handler); 323 irq_set_chained_handler(apc->irq, ar71xx_pci_irq_handler);
313} 324}
314 325
315static void ar71xx_pci_reset(void) 326static void ar71xx_pci_reset(void)
@@ -336,20 +347,27 @@ static void ar71xx_pci_reset(void)
336 347
337static int ar71xx_pci_probe(struct platform_device *pdev) 348static int ar71xx_pci_probe(struct platform_device *pdev)
338{ 349{
350 struct ar71xx_pci_controller *apc;
339 struct resource *res; 351 struct resource *res;
340 int irq;
341 u32 t; 352 u32 t;
342 353
354 apc = devm_kzalloc(&pdev->dev, sizeof(struct ar71xx_pci_controller),
355 GFP_KERNEL);
356 if (!apc)
357 return -ENOMEM;
358
359 spin_lock_init(&apc->lock);
360
343 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); 361 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
344 if (!res) 362 if (!res)
345 return -EINVAL; 363 return -EINVAL;
346 364
347 ar71xx_pcicfg_base = devm_request_and_ioremap(&pdev->dev, res); 365 apc->cfg_base = devm_request_and_ioremap(&pdev->dev, res);
348 if (!ar71xx_pcicfg_base) 366 if (!apc->cfg_base)
349 return -ENOMEM; 367 return -ENOMEM;
350 368
351 irq = platform_get_irq(pdev, 0); 369 apc->irq = platform_get_irq(pdev, 0);
352 if (irq < 0) 370 if (apc->irq < 0)
353 return -EINVAL; 371 return -EINVAL;
354 372
355 ar71xx_pci_reset(); 373 ar71xx_pci_reset();
@@ -357,14 +375,18 @@ static int ar71xx_pci_probe(struct platform_device *pdev)
357 /* setup COMMAND register */ 375 /* setup COMMAND register */
358 t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE 376 t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
359 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; 377 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
360 ar71xx_pci_local_write(PCI_COMMAND, 4, t); 378 ar71xx_pci_local_write(apc, PCI_COMMAND, 4, t);
361 379
362 /* clear bus errors */ 380 /* clear bus errors */
363 ar71xx_pci_check_error(1); 381 ar71xx_pci_check_error(apc, 1);
382
383 ar71xx_pci_irq_init(apc);
364 384
365 ar71xx_pci_irq_init(irq); 385 apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
386 apc->pci_ctrl.mem_resource = &ar71xx_pci_mem_resource;
387 apc->pci_ctrl.io_resource = &ar71xx_pci_io_resource;
366 388
367 register_pci_controller(&ar71xx_pci_controller); 389 register_pci_controller(&apc->pci_ctrl);
368 390
369 return 0; 391 return 0;
370} 392}