diff options
author | Gabor Juhos <juhosg@openwrt.org> | 2013-02-03 05:00:16 -0500 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2013-02-16 19:25:39 -0500 |
commit | 8b66d461187ff61c5755001af7296e6edde48423 (patch) | |
tree | ee07c7274d2c31e083418ac9e9f497ae97f73664 /arch/mips/pci | |
parent | 34b134aebda89888b6985b7a3139e9cbdf209236 (diff) |
MIPS: pci-ar724x: use per-controller IRQ base
Change to the code to use per-controller IRQ base.
This is needed for multiple PCI controller support.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4915/
Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips/pci')
-rw-r--r-- | arch/mips/pci/pci-ar724x.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index d0d707de6c6c..0440d8800f8a 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c | |||
@@ -34,6 +34,7 @@ struct ar724x_pci_controller { | |||
34 | void __iomem *ctrl_base; | 34 | void __iomem *ctrl_base; |
35 | 35 | ||
36 | int irq; | 36 | int irq; |
37 | int irq_base; | ||
37 | 38 | ||
38 | bool link_up; | 39 | bool link_up; |
39 | bool bar0_is_cached; | 40 | bool bar0_is_cached; |
@@ -205,7 +206,7 @@ static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
205 | __raw_readl(base + AR724X_PCI_REG_INT_MASK); | 206 | __raw_readl(base + AR724X_PCI_REG_INT_MASK); |
206 | 207 | ||
207 | if (pending & AR724X_PCI_INT_DEV0) | 208 | if (pending & AR724X_PCI_INT_DEV0) |
208 | generic_handle_irq(ATH79_PCI_IRQ(0)); | 209 | generic_handle_irq(apc->irq_base + 0); |
209 | 210 | ||
210 | else | 211 | else |
211 | spurious_interrupt(); | 212 | spurious_interrupt(); |
@@ -215,13 +216,15 @@ static void ar724x_pci_irq_unmask(struct irq_data *d) | |||
215 | { | 216 | { |
216 | struct ar724x_pci_controller *apc; | 217 | struct ar724x_pci_controller *apc; |
217 | void __iomem *base; | 218 | void __iomem *base; |
219 | int offset; | ||
218 | u32 t; | 220 | u32 t; |
219 | 221 | ||
220 | apc = irq_data_get_irq_chip_data(d); | 222 | apc = irq_data_get_irq_chip_data(d); |
221 | base = apc->ctrl_base; | 223 | base = apc->ctrl_base; |
224 | offset = apc->irq_base - d->irq; | ||
222 | 225 | ||
223 | switch (d->irq) { | 226 | switch (offset) { |
224 | case ATH79_PCI_IRQ(0): | 227 | case 0: |
225 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); | 228 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); |
226 | __raw_writel(t | AR724X_PCI_INT_DEV0, | 229 | __raw_writel(t | AR724X_PCI_INT_DEV0, |
227 | base + AR724X_PCI_REG_INT_MASK); | 230 | base + AR724X_PCI_REG_INT_MASK); |
@@ -234,13 +237,15 @@ static void ar724x_pci_irq_mask(struct irq_data *d) | |||
234 | { | 237 | { |
235 | struct ar724x_pci_controller *apc; | 238 | struct ar724x_pci_controller *apc; |
236 | void __iomem *base; | 239 | void __iomem *base; |
240 | int offset; | ||
237 | u32 t; | 241 | u32 t; |
238 | 242 | ||
239 | apc = irq_data_get_irq_chip_data(d); | 243 | apc = irq_data_get_irq_chip_data(d); |
240 | base = apc->ctrl_base; | 244 | base = apc->ctrl_base; |
245 | offset = apc->irq_base - d->irq; | ||
241 | 246 | ||
242 | switch (d->irq) { | 247 | switch (offset) { |
243 | case ATH79_PCI_IRQ(0): | 248 | case 0: |
244 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); | 249 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); |
245 | __raw_writel(t & ~AR724X_PCI_INT_DEV0, | 250 | __raw_writel(t & ~AR724X_PCI_INT_DEV0, |
246 | base + AR724X_PCI_REG_INT_MASK); | 251 | base + AR724X_PCI_REG_INT_MASK); |
@@ -264,7 +269,8 @@ static struct irq_chip ar724x_pci_irq_chip = { | |||
264 | .irq_mask_ack = ar724x_pci_irq_mask, | 269 | .irq_mask_ack = ar724x_pci_irq_mask, |
265 | }; | 270 | }; |
266 | 271 | ||
267 | static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc) | 272 | static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc, |
273 | int id) | ||
268 | { | 274 | { |
269 | void __iomem *base; | 275 | void __iomem *base; |
270 | int i; | 276 | int i; |
@@ -274,10 +280,10 @@ static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc) | |||
274 | __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); | 280 | __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); |
275 | __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); | 281 | __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); |
276 | 282 | ||
277 | BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); | 283 | apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT); |
278 | 284 | ||
279 | for (i = ATH79_PCI_IRQ_BASE; | 285 | for (i = apc->irq_base; |
280 | i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) { | 286 | i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) { |
281 | irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, | 287 | irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, |
282 | handle_level_irq); | 288 | handle_level_irq); |
283 | irq_set_chip_data(i, apc); | 289 | irq_set_chip_data(i, apc); |
@@ -291,6 +297,11 @@ static int ar724x_pci_probe(struct platform_device *pdev) | |||
291 | { | 297 | { |
292 | struct ar724x_pci_controller *apc; | 298 | struct ar724x_pci_controller *apc; |
293 | struct resource *res; | 299 | struct resource *res; |
300 | int id; | ||
301 | |||
302 | id = pdev->id; | ||
303 | if (id == -1) | ||
304 | id = 0; | ||
294 | 305 | ||
295 | apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller), | 306 | apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller), |
296 | GFP_KERNEL); | 307 | GFP_KERNEL); |
@@ -347,7 +358,7 @@ static int ar724x_pci_probe(struct platform_device *pdev) | |||
347 | if (!apc->link_up) | 358 | if (!apc->link_up) |
348 | dev_warn(&pdev->dev, "PCIe link is down\n"); | 359 | dev_warn(&pdev->dev, "PCIe link is down\n"); |
349 | 360 | ||
350 | ar724x_pci_irq_init(apc); | 361 | ar724x_pci_irq_init(apc, id); |
351 | 362 | ||
352 | register_pci_controller(&apc->pci_controller); | 363 | register_pci_controller(&apc->pci_controller); |
353 | 364 | ||