aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c19
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_l2ctlr.c10
-rw-r--r--arch/powerpc/sysdev/fsl_ifc.c20
-rw-r--r--arch/powerpc/sysdev/fsl_mpic_err.c149
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c157
-rw-r--r--arch/powerpc/sysdev/fsl_pci.h20
-rw-r--r--arch/powerpc/sysdev/mpic.c102
-rw-r--r--arch/powerpc/sysdev/mpic.h22
9 files changed, 403 insertions, 98 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 1bd7ecb24620..a57600b3a4e3 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o
15obj-$(CONFIG_PPC_PMI) += pmi.o 15obj-$(CONFIG_PPC_PMI) += pmi.o
16obj-$(CONFIG_U3_DART) += dart_iommu.o 16obj-$(CONFIG_U3_DART) += dart_iommu.o
17obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 17obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
18obj-$(CONFIG_FSL_SOC) += fsl_soc.o 18obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o
19obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) 19obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
20obj-$(CONFIG_FSL_PMC) += fsl_pmc.o 20obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
21obj-$(CONFIG_FSL_LBC) += fsl_lbc.o 21obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 4f2680f431b5..bd968a43a48b 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -43,7 +43,6 @@
43#include <asm/iommu.h> 43#include <asm/iommu.h>
44#include <asm/pci-bridge.h> 44#include <asm/pci-bridge.h>
45#include <asm/machdep.h> 45#include <asm/machdep.h>
46#include <asm/abs_addr.h>
47#include <asm/cacheflush.h> 46#include <asm/cacheflush.h>
48#include <asm/ppc-pci.h> 47#include <asm/ppc-pci.h>
49 48
@@ -74,11 +73,16 @@ static int dart_is_u4;
74 73
75#define DBG(...) 74#define DBG(...)
76 75
76static DEFINE_SPINLOCK(invalidate_lock);
77
77static inline void dart_tlb_invalidate_all(void) 78static inline void dart_tlb_invalidate_all(void)
78{ 79{
79 unsigned long l = 0; 80 unsigned long l = 0;
80 unsigned int reg, inv_bit; 81 unsigned int reg, inv_bit;
81 unsigned long limit; 82 unsigned long limit;
83 unsigned long flags;
84
85 spin_lock_irqsave(&invalidate_lock, flags);
82 86
83 DBG("dart: flush\n"); 87 DBG("dart: flush\n");
84 88
@@ -111,12 +115,17 @@ retry:
111 panic("DART: TLB did not flush after waiting a long " 115 panic("DART: TLB did not flush after waiting a long "
112 "time. Buggy U3 ?"); 116 "time. Buggy U3 ?");
113 } 117 }
118
119 spin_unlock_irqrestore(&invalidate_lock, flags);
114} 120}
115 121
116static inline void dart_tlb_invalidate_one(unsigned long bus_rpn) 122static inline void dart_tlb_invalidate_one(unsigned long bus_rpn)
117{ 123{
118 unsigned int reg; 124 unsigned int reg;
119 unsigned int l, limit; 125 unsigned int l, limit;
126 unsigned long flags;
127
128 spin_lock_irqsave(&invalidate_lock, flags);
120 129
121 reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE | 130 reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE |
122 (bus_rpn & DART_CNTL_U4_IONE_MASK); 131 (bus_rpn & DART_CNTL_U4_IONE_MASK);
@@ -138,6 +147,8 @@ wait_more:
138 panic("DART: TLB did not flush after waiting a long " 147 panic("DART: TLB did not flush after waiting a long "
139 "time. Buggy U4 ?"); 148 "time. Buggy U4 ?");
140 } 149 }
150
151 spin_unlock_irqrestore(&invalidate_lock, flags);
141} 152}
142 153
143static void dart_flush(struct iommu_table *tbl) 154static void dart_flush(struct iommu_table *tbl)
@@ -167,7 +178,7 @@ static int dart_build(struct iommu_table *tbl, long index,
167 */ 178 */
168 l = npages; 179 l = npages;
169 while (l--) { 180 while (l--) {
170 rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; 181 rpn = __pa(uaddr) >> DART_PAGE_SHIFT;
171 182
172 *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); 183 *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
173 184
@@ -244,7 +255,7 @@ static int __init dart_init(struct device_node *dart_node)
244 panic("DART: Cannot map registers!"); 255 panic("DART: Cannot map registers!");
245 256
246 /* Map in DART table */ 257 /* Map in DART table */
247 dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); 258 dart_vbase = ioremap(__pa(dart_tablebase), dart_tablesize);
248 259
249 /* Fill initial table */ 260 /* Fill initial table */
250 for (i = 0; i < dart_tablesize/4; i++) 261 for (i = 0; i < dart_tablesize/4; i++)
@@ -463,7 +474,7 @@ void __init alloc_dart_table(void)
463 * will blow up an entire large page anyway in the kernel mapping 474 * will blow up an entire large page anyway in the kernel mapping
464 */ 475 */
465 dart_tablebase = (unsigned long) 476 dart_tablebase = (unsigned long)
466 abs_to_virt(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); 477 __va(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
467 478
468 printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase); 479 printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase);
469} 480}
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
index 68ac3aacb191..d131c8a1cb15 100644
--- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
@@ -193,6 +193,16 @@ static struct of_device_id mpc85xx_l2ctlr_of_match[] = {
193 { 193 {
194 .compatible = "fsl,mpc8548-l2-cache-controller", 194 .compatible = "fsl,mpc8548-l2-cache-controller",
195 }, 195 },
196 { .compatible = "fsl,mpc8544-l2-cache-controller",},
197 { .compatible = "fsl,mpc8572-l2-cache-controller",},
198 { .compatible = "fsl,mpc8536-l2-cache-controller",},
199 { .compatible = "fsl,p1021-l2-cache-controller",},
200 { .compatible = "fsl,p1012-l2-cache-controller",},
201 { .compatible = "fsl,p1025-l2-cache-controller",},
202 { .compatible = "fsl,p1016-l2-cache-controller",},
203 { .compatible = "fsl,p1024-l2-cache-controller",},
204 { .compatible = "fsl,p1015-l2-cache-controller",},
205 { .compatible = "fsl,p1010-l2-cache-controller",},
196 {}, 206 {},
197}; 207};
198 208
diff --git a/arch/powerpc/sysdev/fsl_ifc.c b/arch/powerpc/sysdev/fsl_ifc.c
index b31f19f61031..097cc9d2585b 100644
--- a/arch/powerpc/sysdev/fsl_ifc.c
+++ b/arch/powerpc/sysdev/fsl_ifc.c
@@ -244,12 +244,6 @@ static int __devinit fsl_ifc_ctrl_probe(struct platform_device *dev)
244 /* get the nand machine irq */ 244 /* get the nand machine irq */
245 fsl_ifc_ctrl_dev->nand_irq = 245 fsl_ifc_ctrl_dev->nand_irq =
246 irq_of_parse_and_map(dev->dev.of_node, 1); 246 irq_of_parse_and_map(dev->dev.of_node, 1);
247 if (fsl_ifc_ctrl_dev->nand_irq == NO_IRQ) {
248 dev_err(&dev->dev, "failed to get irq resource "
249 "for NAND Machine\n");
250 ret = -ENODEV;
251 goto err;
252 }
253 247
254 fsl_ifc_ctrl_dev->dev = &dev->dev; 248 fsl_ifc_ctrl_dev->dev = &dev->dev;
255 249
@@ -267,12 +261,14 @@ static int __devinit fsl_ifc_ctrl_probe(struct platform_device *dev)
267 goto err_irq; 261 goto err_irq;
268 } 262 }
269 263
270 ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq, 0, 264 if (fsl_ifc_ctrl_dev->nand_irq) {
271 "fsl-ifc-nand", fsl_ifc_ctrl_dev); 265 ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq,
272 if (ret != 0) { 266 0, "fsl-ifc-nand", fsl_ifc_ctrl_dev);
273 dev_err(&dev->dev, "failed to install irq (%d)\n", 267 if (ret != 0) {
274 fsl_ifc_ctrl_dev->nand_irq); 268 dev_err(&dev->dev, "failed to install irq (%d)\n",
275 goto err_nandirq; 269 fsl_ifc_ctrl_dev->nand_irq);
270 goto err_nandirq;
271 }
276 } 272 }
277 273
278 return 0; 274 return 0;
diff --git a/arch/powerpc/sysdev/fsl_mpic_err.c b/arch/powerpc/sysdev/fsl_mpic_err.c
new file mode 100644
index 000000000000..b83f32562a37
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_mpic_err.c
@@ -0,0 +1,149 @@
1/*
2 * Copyright (C) 2012 Freescale Semiconductor, Inc.
3 *
4 * Author: Varun Sethi <varun.sethi@freescale.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; version 2 of the
9 * License.
10 *
11 */
12
13#include <linux/irq.h>
14#include <linux/smp.h>
15#include <linux/interrupt.h>
16
17#include <asm/io.h>
18#include <asm/irq.h>
19#include <asm/mpic.h>
20
21#include "mpic.h"
22
23#define MPIC_ERR_INT_BASE 0x3900
24#define MPIC_ERR_INT_EISR 0x0000
25#define MPIC_ERR_INT_EIMR 0x0010
26
27static inline u32 mpic_fsl_err_read(u32 __iomem *base, unsigned int err_reg)
28{
29 return in_be32(base + (err_reg >> 2));
30}
31
32static inline void mpic_fsl_err_write(u32 __iomem *base, u32 value)
33{
34 out_be32(base + (MPIC_ERR_INT_EIMR >> 2), value);
35}
36
37static void fsl_mpic_mask_err(struct irq_data *d)
38{
39 u32 eimr;
40 struct mpic *mpic = irq_data_get_irq_chip_data(d);
41 unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0];
42
43 eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
44 eimr |= (1 << (31 - src));
45 mpic_fsl_err_write(mpic->err_regs, eimr);
46}
47
48static void fsl_mpic_unmask_err(struct irq_data *d)
49{
50 u32 eimr;
51 struct mpic *mpic = irq_data_get_irq_chip_data(d);
52 unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0];
53
54 eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
55 eimr &= ~(1 << (31 - src));
56 mpic_fsl_err_write(mpic->err_regs, eimr);
57}
58
59static struct irq_chip fsl_mpic_err_chip = {
60 .irq_disable = fsl_mpic_mask_err,
61 .irq_mask = fsl_mpic_mask_err,
62 .irq_unmask = fsl_mpic_unmask_err,
63};
64
65int mpic_setup_error_int(struct mpic *mpic, int intvec)
66{
67 int i;
68
69 mpic->err_regs = ioremap(mpic->paddr + MPIC_ERR_INT_BASE, 0x1000);
70 if (!mpic->err_regs) {
71 pr_err("could not map mpic error registers\n");
72 return -ENOMEM;
73 }
74 mpic->hc_err = fsl_mpic_err_chip;
75 mpic->hc_err.name = mpic->name;
76 mpic->flags |= MPIC_FSL_HAS_EIMR;
77 /* allocate interrupt vectors for error interrupts */
78 for (i = MPIC_MAX_ERR - 1; i >= 0; i--)
79 mpic->err_int_vecs[i] = --intvec;
80
81 return 0;
82}
83
84int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw)
85{
86 if ((mpic->flags & MPIC_FSL_HAS_EIMR) &&
87 (hw >= mpic->err_int_vecs[0] &&
88 hw <= mpic->err_int_vecs[MPIC_MAX_ERR - 1])) {
89 WARN_ON(mpic->flags & MPIC_SECONDARY);
90
91 pr_debug("mpic: mapping as Error Interrupt\n");
92 irq_set_chip_data(virq, mpic);
93 irq_set_chip_and_handler(virq, &mpic->hc_err,
94 handle_level_irq);
95 return 1;
96 }
97
98 return 0;
99}
100
101static irqreturn_t fsl_error_int_handler(int irq, void *data)
102{
103 struct mpic *mpic = (struct mpic *) data;
104 u32 eisr, eimr;
105 int errint;
106 unsigned int cascade_irq;
107
108 eisr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EISR);
109 eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
110
111 if (!(eisr & ~eimr))
112 return IRQ_NONE;
113
114 while (eisr) {
115 errint = __builtin_clz(eisr);
116 cascade_irq = irq_linear_revmap(mpic->irqhost,
117 mpic->err_int_vecs[errint]);
118 WARN_ON(cascade_irq == NO_IRQ);
119 if (cascade_irq != NO_IRQ) {
120 generic_handle_irq(cascade_irq);
121 } else {
122 eimr |= 1 << (31 - errint);
123 mpic_fsl_err_write(mpic->err_regs, eimr);
124 }
125 eisr &= ~(1 << (31 - errint));
126 }
127
128 return IRQ_HANDLED;
129}
130
131void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum)
132{
133 unsigned int virq;
134 int ret;
135
136 virq = irq_create_mapping(mpic->irqhost, irqnum);
137 if (virq == NO_IRQ) {
138 pr_err("Error interrupt setup failed\n");
139 return;
140 }
141
142 /* Mask all error interrupts */
143 mpic_fsl_err_write(mpic->err_regs, ~0);
144
145 ret = request_irq(virq, fsl_error_int_handler, IRQF_NO_THREAD,
146 "mpic-error-int", mpic);
147 if (ret)
148 pr_err("Failed to register error interrupt handler\n");
149}
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index c37f46136321..ffb93ae9379b 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
38 38
39static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev) 39static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev)
40{ 40{
41 u8 progif; 41 u8 hdr_type;
42 42
43 /* if we aren't a PCIe don't bother */ 43 /* if we aren't a PCIe don't bother */
44 if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) 44 if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
45 return; 45 return;
46 46
47 /* if we aren't in host mode don't bother */ 47 /* if we aren't in host mode don't bother */
48 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); 48 pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
49 if (progif & 0x1) 49 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
50 return; 50 return;
51 51
52 dev->class = PCI_CLASS_BRIDGE_PCI << 8; 52 dev->class = PCI_CLASS_BRIDGE_PCI << 8;
@@ -143,18 +143,20 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
143 pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", 143 pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
144 (u64)rsrc->start, (u64)resource_size(rsrc)); 144 (u64)rsrc->start, (u64)resource_size(rsrc));
145 145
146 if (of_device_is_compatible(hose->dn, "fsl,qoriq-pcie-v2.2")) {
147 win_idx = 2;
148 start_idx = 0;
149 end_idx = 3;
150 }
151
152 pci = ioremap(rsrc->start, resource_size(rsrc)); 146 pci = ioremap(rsrc->start, resource_size(rsrc));
153 if (!pci) { 147 if (!pci) {
154 dev_err(hose->parent, "Unable to map ATMU registers\n"); 148 dev_err(hose->parent, "Unable to map ATMU registers\n");
155 return; 149 return;
156 } 150 }
157 151
152 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
153 if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
154 win_idx = 2;
155 start_idx = 0;
156 end_idx = 3;
157 }
158 }
159
158 /* Disable all windows (except powar0 since it's ignored) */ 160 /* Disable all windows (except powar0 since it's ignored) */
159 for(i = 1; i < 5; i++) 161 for(i = 1; i < 5; i++)
160 out_be32(&pci->pow[i].powar, 0); 162 out_be32(&pci->pow[i].powar, 0);
@@ -425,7 +427,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
425 struct pci_controller *hose; 427 struct pci_controller *hose;
426 struct resource rsrc; 428 struct resource rsrc;
427 const int *bus_range; 429 const int *bus_range;
428 u8 progif; 430 u8 hdr_type, progif;
429 431
430 if (!of_device_is_available(dev)) { 432 if (!of_device_is_available(dev)) {
431 pr_warning("%s: disabled\n", dev->full_name); 433 pr_warning("%s: disabled\n", dev->full_name);
@@ -457,15 +459,17 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
457 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, 459 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
458 PPC_INDIRECT_TYPE_BIG_ENDIAN); 460 PPC_INDIRECT_TYPE_BIG_ENDIAN);
459 461
460 early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif); 462 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
461 if ((progif & 1) == 1) { 463 /* For PCIE read HEADER_TYPE to identify controler mode */
462 /* unmap cfg_data & cfg_addr separately if not on same page */ 464 early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
463 if (((unsigned long)hose->cfg_data & PAGE_MASK) != 465 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
464 ((unsigned long)hose->cfg_addr & PAGE_MASK)) 466 goto no_bridge;
465 iounmap(hose->cfg_data); 467
466 iounmap(hose->cfg_addr); 468 } else {
467 pcibios_free_controller(hose); 469 /* For PCI read PROG to identify controller mode */
468 return -ENODEV; 470 early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
471 if ((progif & 1) == 1)
472 goto no_bridge;
469 } 473 }
470 474
471 setup_pci_cmd(hose); 475 setup_pci_cmd(hose);
@@ -494,6 +498,15 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
494 setup_pci_atmu(hose, &rsrc); 498 setup_pci_atmu(hose, &rsrc);
495 499
496 return 0; 500 return 0;
501
502no_bridge:
503 /* unmap cfg_data & cfg_addr separately if not on same page */
504 if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
505 ((unsigned long)hose->cfg_addr & PAGE_MASK))
506 iounmap(hose->cfg_data);
507 iounmap(hose->cfg_addr);
508 pcibios_free_controller(hose);
509 return -ENODEV;
497} 510}
498#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ 511#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
499 512
@@ -818,6 +831,7 @@ static const struct of_device_id pci_ids[] = {
818 { .compatible = "fsl,p1010-pcie", }, 831 { .compatible = "fsl,p1010-pcie", },
819 { .compatible = "fsl,p1023-pcie", }, 832 { .compatible = "fsl,p1023-pcie", },
820 { .compatible = "fsl,p4080-pcie", }, 833 { .compatible = "fsl,p4080-pcie", },
834 { .compatible = "fsl,qoriq-pcie-v2.4", },
821 { .compatible = "fsl,qoriq-pcie-v2.3", }, 835 { .compatible = "fsl,qoriq-pcie-v2.3", },
822 { .compatible = "fsl,qoriq-pcie-v2.2", }, 836 { .compatible = "fsl,qoriq-pcie-v2.2", },
823 {}, 837 {},
@@ -825,57 +839,80 @@ static const struct of_device_id pci_ids[] = {
825 839
826struct device_node *fsl_pci_primary; 840struct device_node *fsl_pci_primary;
827 841
828void __devinit fsl_pci_init(void) 842void fsl_pci_assign_primary(void)
829{ 843{
830 int ret; 844 struct device_node *np;
831 struct device_node *node;
832 struct pci_controller *hose;
833 dma_addr_t max = 0xffffffff;
834 845
835 /* Callers can specify the primary bus using other means. */ 846 /* Callers can specify the primary bus using other means. */
836 if (!fsl_pci_primary) { 847 if (fsl_pci_primary)
837 /* If a PCI host bridge contains an ISA node, it's primary. */ 848 return;
838 node = of_find_node_by_type(NULL, "isa"); 849
839 while ((fsl_pci_primary = of_get_parent(node))) { 850 /* If a PCI host bridge contains an ISA node, it's primary. */
840 of_node_put(node); 851 np = of_find_node_by_type(NULL, "isa");
841 node = fsl_pci_primary; 852 while ((fsl_pci_primary = of_get_parent(np))) {
842 853 of_node_put(np);
843 if (of_match_node(pci_ids, node)) 854 np = fsl_pci_primary;
844 break; 855
845 } 856 if (of_match_node(pci_ids, np) && of_device_is_available(np))
857 return;
846 } 858 }
847 859
848 node = NULL; 860 /*
849 for_each_node_by_type(node, "pci") { 861 * If there's no PCI host bridge with ISA, arbitrarily
850 if (of_match_node(pci_ids, node)) { 862 * designate one as primary. This can go away once
851 /* 863 * various bugs with primary-less systems are fixed.
852 * If there's no PCI host bridge with ISA, arbitrarily 864 */
853 * designate one as primary. This can go away once 865 for_each_matching_node(np, pci_ids) {
854 * various bugs with primary-less systems are fixed. 866 if (of_device_is_available(np)) {
855 */ 867 fsl_pci_primary = np;
856 if (!fsl_pci_primary) 868 of_node_put(np);
857 fsl_pci_primary = node; 869 return;
858
859 ret = fsl_add_bridge(node, fsl_pci_primary == node);
860 if (ret == 0) {
861 hose = pci_find_hose_for_OF_device(node);
862 max = min(max, hose->dma_window_base_cur +
863 hose->dma_window_size);
864 }
865 } 870 }
866 } 871 }
872}
867 873
874static int __devinit fsl_pci_probe(struct platform_device *pdev)
875{
876 int ret;
877 struct device_node *node;
868#ifdef CONFIG_SWIOTLB 878#ifdef CONFIG_SWIOTLB
869 /* 879 struct pci_controller *hose;
870 * if we couldn't map all of DRAM via the dma windows 880#endif
871 * we need SWIOTLB to handle buffers located outside of 881
872 * dma capable memory region 882 node = pdev->dev.of_node;
873 */ 883 ret = fsl_add_bridge(node, fsl_pci_primary == node);
874 if (memblock_end_of_DRAM() - 1 > max) { 884
875 ppc_swiotlb_enable = 1; 885#ifdef CONFIG_SWIOTLB
876 set_pci_dma_ops(&swiotlb_dma_ops); 886 if (ret == 0) {
877 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; 887 hose = pci_find_hose_for_OF_device(pdev->dev.of_node);
888
889 /*
890 * if we couldn't map all of DRAM via the dma windows
891 * we need SWIOTLB to handle buffers located outside of
892 * dma capable memory region
893 */
894 if (memblock_end_of_DRAM() - 1 > hose->dma_window_base_cur +
895 hose->dma_window_size)
896 ppc_swiotlb_enable = 1;
878 } 897 }
879#endif 898#endif
899
900 mpc85xx_pci_err_probe(pdev);
901
902 return 0;
903}
904
905static struct platform_driver fsl_pci_driver = {
906 .driver = {
907 .name = "fsl-pci",
908 .of_match_table = pci_ids,
909 },
910 .probe = fsl_pci_probe,
911};
912
913static int __init fsl_pci_init(void)
914{
915 return platform_driver_register(&fsl_pci_driver);
880} 916}
917arch_initcall(fsl_pci_init);
881#endif 918#endif
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index baa0fd18289f..d078537adece 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -16,6 +16,7 @@
16 16
17#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ 17#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */
18#define PCIE_LTSSM_L0 0x16 /* L0 state */ 18#define PCIE_LTSSM_L0 0x16 /* L0 state */
19#define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */
19#define PIWAR_EN 0x80000000 /* Enable */ 20#define PIWAR_EN 0x80000000 /* Enable */
20#define PIWAR_PF 0x20000000 /* prefetch */ 21#define PIWAR_PF 0x20000000 /* prefetch */
21#define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */ 22#define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */
@@ -57,7 +58,9 @@ struct ccsr_pci {
57 __be32 pex_pme_mes_disr; /* 0x.024 - PCIE PME and message disable register */ 58 __be32 pex_pme_mes_disr; /* 0x.024 - PCIE PME and message disable register */
58 __be32 pex_pme_mes_ier; /* 0x.028 - PCIE PME and message interrupt enable register */ 59 __be32 pex_pme_mes_ier; /* 0x.028 - PCIE PME and message interrupt enable register */
59 __be32 pex_pmcr; /* 0x.02c - PCIE power management command register */ 60 __be32 pex_pmcr; /* 0x.02c - PCIE power management command register */
60 u8 res3[3024]; 61 u8 res3[3016];
62 __be32 block_rev1; /* 0x.bf8 - PCIE Block Revision register 1 */
63 __be32 block_rev2; /* 0x.bfc - PCIE Block Revision register 2 */
61 64
62/* PCI/PCI Express outbound window 0-4 65/* PCI/PCI Express outbound window 0-4
63 * Window 0 is the default window and is the only window enabled upon reset. 66 * Window 0 is the default window and is the only window enabled upon reset.
@@ -95,10 +98,19 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose);
95 98
96extern struct device_node *fsl_pci_primary; 99extern struct device_node *fsl_pci_primary;
97 100
98#ifdef CONFIG_FSL_PCI 101#ifdef CONFIG_PCI
99void fsl_pci_init(void); 102void fsl_pci_assign_primary(void);
100#else 103#else
101static inline void fsl_pci_init(void) {} 104static inline void fsl_pci_assign_primary(void) {}
105#endif
106
107#ifdef CONFIG_EDAC_MPC85XX
108int mpc85xx_pci_err_probe(struct platform_device *op);
109#else
110static inline int mpc85xx_pci_err_probe(struct platform_device *op)
111{
112 return -ENOTSUPP;
113}
102#endif 114#endif
103 115
104#endif /* __POWERPC_FSL_PCI_H */ 116#endif /* __POWERPC_FSL_PCI_H */
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index bfc6211e5422..9c6e535daad2 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -6,7 +6,7 @@
6 * with various broken implementations of this HW. 6 * with various broken implementations of this HW.
7 * 7 *
8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. 8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
9 * Copyright 2010-2011 Freescale Semiconductor, Inc. 9 * Copyright 2010-2012 Freescale Semiconductor, Inc.
10 * 10 *
11 * This file is subject to the terms and conditions of the GNU General Public 11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive 12 * License. See the file COPYING in the main directory of this archive
@@ -221,24 +221,24 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu
221 _mpic_write(mpic->reg_type, &mpic->gregs, offset, value); 221 _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
222} 222}
223 223
224static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm) 224static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
225{ 225{
226 unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + 226 return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
227 ((tm & 3) * MPIC_INFO(TIMER_STRIDE)); 227 (tm & 3) * MPIC_INFO(TIMER_STRIDE);
228}
228 229
229 if (tm >= 4) 230static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
230 offset += 0x1000 / 4; 231{
232 unsigned int offset = mpic_tm_offset(mpic, tm) +
233 MPIC_INFO(TIMER_VECTOR_PRI);
231 234
232 return _mpic_read(mpic->reg_type, &mpic->tmregs, offset); 235 return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
233} 236}
234 237
235static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value) 238static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
236{ 239{
237 unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + 240 unsigned int offset = mpic_tm_offset(mpic, tm) +
238 ((tm & 3) * MPIC_INFO(TIMER_STRIDE)); 241 MPIC_INFO(TIMER_VECTOR_PRI);
239
240 if (tm >= 4)
241 offset += 0x1000 / 4;
242 242
243 _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value); 243 _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
244} 244}
@@ -1026,6 +1026,9 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
1026 return 0; 1026 return 0;
1027 } 1027 }
1028 1028
1029 if (mpic_map_error_int(mpic, virq, hw))
1030 return 0;
1031
1029 if (hw >= mpic->num_sources) 1032 if (hw >= mpic->num_sources)
1030 return -EINVAL; 1033 return -EINVAL;
1031 1034
@@ -1085,7 +1088,16 @@ static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
1085 */ 1088 */
1086 switch (intspec[2]) { 1089 switch (intspec[2]) {
1087 case 0: 1090 case 0:
1088 case 1: /* no EISR/EIMR support for now, treat as shared IRQ */ 1091 break;
1092 case 1:
1093 if (!(mpic->flags & MPIC_FSL_HAS_EIMR))
1094 break;
1095
1096 if (intspec[3] >= ARRAY_SIZE(mpic->err_int_vecs))
1097 return -EINVAL;
1098
1099 *out_hwirq = mpic->err_int_vecs[intspec[3]];
1100
1089 break; 1101 break;
1090 case 2: 1102 case 2:
1091 if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs)) 1103 if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs))
@@ -1301,6 +1313,42 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1301 mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); 1313 mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
1302 mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); 1314 mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
1303 1315
1316 if (mpic->flags & MPIC_FSL) {
1317 u32 brr1, version;
1318 int ret;
1319
1320 /*
1321 * Yes, Freescale really did put global registers in the
1322 * magic per-cpu area -- and they don't even show up in the
1323 * non-magic per-cpu copies that this driver normally uses.
1324 */
1325 mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
1326 MPIC_CPU_THISBASE, 0x1000);
1327
1328 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
1329 MPIC_FSL_BRR1);
1330 version = brr1 & MPIC_FSL_BRR1_VER;
1331
1332 /* Error interrupt mask register (EIMR) is required for
1333 * handling individual device error interrupts. EIMR
1334 * was added in MPIC version 4.1.
1335 *
1336 * Over here we reserve vector number space for error
1337 * interrupt vectors. This space is stolen from the
1338 * global vector number space, as in case of ipis
1339 * and timer interrupts.
1340 *
1341 * Available vector space = intvec_top - 12, where 12
1342 * is the number of vectors which have been consumed by
1343 * ipis and timer interrupts.
1344 */
1345 if (version >= 0x401) {
1346 ret = mpic_setup_error_int(mpic, intvec_top - 12);
1347 if (ret)
1348 return NULL;
1349 }
1350 }
1351
1304 /* Reset */ 1352 /* Reset */
1305 1353
1306 /* When using a device-node, reset requests are only honored if the MPIC 1354 /* When using a device-node, reset requests are only honored if the MPIC
@@ -1440,6 +1488,7 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
1440void __init mpic_init(struct mpic *mpic) 1488void __init mpic_init(struct mpic *mpic)
1441{ 1489{
1442 int i, cpu; 1490 int i, cpu;
1491 int num_timers = 4;
1443 1492
1444 BUG_ON(mpic->num_sources == 0); 1493 BUG_ON(mpic->num_sources == 0);
1445 1494
@@ -1448,15 +1497,34 @@ void __init mpic_init(struct mpic *mpic)
1448 /* Set current processor priority to max */ 1497 /* Set current processor priority to max */
1449 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); 1498 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
1450 1499
1500 if (mpic->flags & MPIC_FSL) {
1501 u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
1502 MPIC_FSL_BRR1);
1503 u32 version = brr1 & MPIC_FSL_BRR1_VER;
1504
1505 /*
1506 * Timer group B is present at the latest in MPIC 3.1 (e.g.
1507 * mpc8536). It is not present in MPIC 2.0 (e.g. mpc8544).
1508 * I don't know about the status of intermediate versions (or
1509 * whether they even exist).
1510 */
1511 if (version >= 0x0301)
1512 num_timers = 8;
1513 }
1514
1515 /* FSL mpic error interrupt intialization */
1516 if (mpic->flags & MPIC_FSL_HAS_EIMR)
1517 mpic_err_int_init(mpic, MPIC_FSL_ERR_INT);
1518
1451 /* Initialize timers to our reserved vectors and mask them for now */ 1519 /* Initialize timers to our reserved vectors and mask them for now */
1452 for (i = 0; i < 4; i++) { 1520 for (i = 0; i < num_timers; i++) {
1521 unsigned int offset = mpic_tm_offset(mpic, i);
1522
1453 mpic_write(mpic->tmregs, 1523 mpic_write(mpic->tmregs,
1454 i * MPIC_INFO(TIMER_STRIDE) + 1524 offset + MPIC_INFO(TIMER_DESTINATION),
1455 MPIC_INFO(TIMER_DESTINATION),
1456 1 << hard_smp_processor_id()); 1525 1 << hard_smp_processor_id());
1457 mpic_write(mpic->tmregs, 1526 mpic_write(mpic->tmregs,
1458 i * MPIC_INFO(TIMER_STRIDE) + 1527 offset + MPIC_INFO(TIMER_VECTOR_PRI),
1459 MPIC_INFO(TIMER_VECTOR_PRI),
1460 MPIC_VECPRI_MASK | 1528 MPIC_VECPRI_MASK |
1461 (9 << MPIC_VECPRI_PRIORITY_SHIFT) | 1529 (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
1462 (mpic->timer_vecs[0] + i)); 1530 (mpic->timer_vecs[0] + i));
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index 13f3e8913a93..24bf07a63924 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -40,4 +40,26 @@ extern int mpic_set_affinity(struct irq_data *d,
40 const struct cpumask *cpumask, bool force); 40 const struct cpumask *cpumask, bool force);
41extern void mpic_reset_core(int cpu); 41extern void mpic_reset_core(int cpu);
42 42
43#ifdef CONFIG_FSL_SOC
44extern int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw);
45extern void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum);
46extern int mpic_setup_error_int(struct mpic *mpic, int intvec);
47#else
48static inline int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw)
49{
50 return 0;
51}
52
53
54static inline void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum)
55{
56 return;
57}
58
59static inline int mpic_setup_error_int(struct mpic *mpic, int intvec)
60{
61 return -1;
62}
63#endif
64
43#endif /* _POWERPC_SYSDEV_MPIC_H */ 65#endif /* _POWERPC_SYSDEV_MPIC_H */