diff options
author | Gabor Juhos <juhosg@openwrt.org> | 2013-02-07 14:28:14 -0500 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2013-02-16 19:25:40 -0500 |
commit | f18118a868f1f7e7bdfea176a204fcc44fae2985 (patch) | |
tree | 30d921435da97f0fcc9c67b7e39a9338e1e96964 /arch/mips/pci | |
parent | 12401fc28d40aa5bf8bda6991a96b6d7a3dae3ac (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.c | 84 |
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 | ||
51 | static DEFINE_SPINLOCK(ar71xx_pci_lock); | 51 | struct ar71xx_pci_controller { |
52 | static 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 */ |
55 | static const u8 ar71xx_pci_ble_table[4][4] = { | 59 | static 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 | ||
95 | static int ar71xx_pci_check_error(int quiet) | 99 | static inline struct ar71xx_pci_controller * |
100 | pci_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 | |||
108 | static 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 | ||
132 | static inline void ar71xx_pci_local_write(int where, int size, u32 value) | 145 | static 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 | ||
162 | static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | 177 | static 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, | |||
190 | static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | 206 | static 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 | ||
234 | static 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 | |||
240 | static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | 251 | static 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 | ||
297 | static void ar71xx_pci_irq_init(int irq) | 308 | static 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 | ||
315 | static void ar71xx_pci_reset(void) | 326 | static void ar71xx_pci_reset(void) |
@@ -336,20 +347,27 @@ static void ar71xx_pci_reset(void) | |||
336 | 347 | ||
337 | static int ar71xx_pci_probe(struct platform_device *pdev) | 348 | static 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 | } |