aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 01:59:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 01:59:39 -0400
commit184475029a724b6b900d88fc3a5f462a6107d5af (patch)
tree408320b46df221a2424bf94282b1b8e5b7aff7a1 /arch/powerpc/sysdev
parent3b76eefe0f970c2e19f165d4a1650abc523d10bc (diff)
parentf1f4ee01c0d3dce0e3aa7d04e4332677db7af478 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (99 commits) drivers/virt: add missing linux/interrupt.h to fsl_hypervisor.c powerpc/85xx: fix mpic configuration in CAMP mode powerpc: Copy back TIF flags on return from softirq stack powerpc/64: Make server perfmon only built on ppc64 server devices powerpc/pseries: Fix hvc_vio.c build due to recent changes powerpc: Exporting boot_cpuid_phys powerpc: Add CFAR to oops output hvc_console: Add kdb support powerpc/pseries: Fix hvterm_raw_get_chars to accept < 16 chars, fixing xmon powerpc/irq: Quieten irq mapping printks powerpc: Enable lockup and hung task detectors in pseries and ppc64 defeconfigs powerpc: Add mpt2sas driver to pseries and ppc64 defconfig powerpc: Disable IRQs off tracer in ppc64 defconfig powerpc: Sync pseries and ppc64 defconfigs powerpc/pseries/hvconsole: Fix dropped console output hvc_console: Improve tty/console put_chars handling powerpc/kdump: Fix timeout in crash_kexec_wait_realmode powerpc/mm: Fix output of total_ram. powerpc/cpufreq: Add cpufreq driver for Momentum Maple boards powerpc: Correct annotations of pmu registration functions ... Fix up trivial Kconfig/Makefile conflicts in arch/powerpc, drivers, and drivers/cpufreq
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/ehv_pic.c302
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c83
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c27
-rw-r--r--arch/powerpc/sysdev/fsl_soc.h3
-rw-r--r--arch/powerpc/sysdev/mpic.c38
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c147
7 files changed, 438 insertions, 163 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 0efa990e3344..cf736ca0cf05 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
4 4
5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o 5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) 6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
7obj-$(CONFIG_PPC_EPAPR_HV_PIC) += ehv_pic.o
7fsl-msi-obj-$(CONFIG_PCI_MSI) += fsl_msi.o 8fsl-msi-obj-$(CONFIG_PCI_MSI) += fsl_msi.o
8obj-$(CONFIG_PPC_MSI_BITMAP) += msi_bitmap.o 9obj-$(CONFIG_PPC_MSI_BITMAP) += msi_bitmap.o
9 10
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
new file mode 100644
index 000000000000..af1a5df46b3e
--- /dev/null
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -0,0 +1,302 @@
1/*
2 * Driver for ePAPR Embedded Hypervisor PIC
3 *
4 * Copyright 2008-2011 Freescale Semiconductor, Inc.
5 *
6 * Author: Ashish Kalra <ashish.kalra@freescale.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/irq.h>
17#include <linux/smp.h>
18#include <linux/interrupt.h>
19#include <linux/slab.h>
20#include <linux/spinlock.h>
21#include <linux/of.h>
22
23#include <asm/io.h>
24#include <asm/irq.h>
25#include <asm/smp.h>
26#include <asm/machdep.h>
27#include <asm/ehv_pic.h>
28#include <asm/fsl_hcalls.h>
29
30#include "../../../kernel/irq/settings.h"
31
32static struct ehv_pic *global_ehv_pic;
33static DEFINE_SPINLOCK(ehv_pic_lock);
34
35static u32 hwirq_intspec[NR_EHV_PIC_INTS];
36static u32 __iomem *mpic_percpu_base_vaddr;
37
38#define IRQ_TYPE_MPIC_DIRECT 4
39#define MPIC_EOI 0x00B0
40
41/*
42 * Linux descriptor level callbacks
43 */
44
45void ehv_pic_unmask_irq(struct irq_data *d)
46{
47 unsigned int src = virq_to_hw(d->irq);
48
49 ev_int_set_mask(src, 0);
50}
51
52void ehv_pic_mask_irq(struct irq_data *d)
53{
54 unsigned int src = virq_to_hw(d->irq);
55
56 ev_int_set_mask(src, 1);
57}
58
59void ehv_pic_end_irq(struct irq_data *d)
60{
61 unsigned int src = virq_to_hw(d->irq);
62
63 ev_int_eoi(src);
64}
65
66void ehv_pic_direct_end_irq(struct irq_data *d)
67{
68 out_be32(mpic_percpu_base_vaddr + MPIC_EOI / 4, 0);
69}
70
71int ehv_pic_set_affinity(struct irq_data *d, const struct cpumask *dest,
72 bool force)
73{
74 unsigned int src = virq_to_hw(d->irq);
75 unsigned int config, prio, cpu_dest;
76 int cpuid = irq_choose_cpu(dest);
77 unsigned long flags;
78
79 spin_lock_irqsave(&ehv_pic_lock, flags);
80 ev_int_get_config(src, &config, &prio, &cpu_dest);
81 ev_int_set_config(src, config, prio, cpuid);
82 spin_unlock_irqrestore(&ehv_pic_lock, flags);
83
84 return 0;
85}
86
87static unsigned int ehv_pic_type_to_vecpri(unsigned int type)
88{
89 /* Now convert sense value */
90
91 switch (type & IRQ_TYPE_SENSE_MASK) {
92 case IRQ_TYPE_EDGE_RISING:
93 return EHV_PIC_INFO(VECPRI_SENSE_EDGE) |
94 EHV_PIC_INFO(VECPRI_POLARITY_POSITIVE);
95
96 case IRQ_TYPE_EDGE_FALLING:
97 case IRQ_TYPE_EDGE_BOTH:
98 return EHV_PIC_INFO(VECPRI_SENSE_EDGE) |
99 EHV_PIC_INFO(VECPRI_POLARITY_NEGATIVE);
100
101 case IRQ_TYPE_LEVEL_HIGH:
102 return EHV_PIC_INFO(VECPRI_SENSE_LEVEL) |
103 EHV_PIC_INFO(VECPRI_POLARITY_POSITIVE);
104
105 case IRQ_TYPE_LEVEL_LOW:
106 default:
107 return EHV_PIC_INFO(VECPRI_SENSE_LEVEL) |
108 EHV_PIC_INFO(VECPRI_POLARITY_NEGATIVE);
109 }
110}
111
112int ehv_pic_set_irq_type(struct irq_data *d, unsigned int flow_type)
113{
114 unsigned int src = virq_to_hw(d->irq);
115 struct irq_desc *desc = irq_to_desc(d->irq);
116 unsigned int vecpri, vold, vnew, prio, cpu_dest;
117 unsigned long flags;
118
119 if (flow_type == IRQ_TYPE_NONE)
120 flow_type = IRQ_TYPE_LEVEL_LOW;
121
122 irq_settings_clr_level(desc);
123 irq_settings_set_trigger_mask(desc, flow_type);
124 if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
125 irq_settings_set_level(desc);
126
127 vecpri = ehv_pic_type_to_vecpri(flow_type);
128
129 spin_lock_irqsave(&ehv_pic_lock, flags);
130 ev_int_get_config(src, &vold, &prio, &cpu_dest);
131 vnew = vold & ~(EHV_PIC_INFO(VECPRI_POLARITY_MASK) |
132 EHV_PIC_INFO(VECPRI_SENSE_MASK));
133 vnew |= vecpri;
134
135 /*
136 * TODO : Add specific interface call for platform to set
137 * individual interrupt priorities.
138 * platform currently using static/default priority for all ints
139 */
140
141 prio = 8;
142
143 ev_int_set_config(src, vecpri, prio, cpu_dest);
144
145 spin_unlock_irqrestore(&ehv_pic_lock, flags);
146 return 0;
147}
148
149static struct irq_chip ehv_pic_irq_chip = {
150 .irq_mask = ehv_pic_mask_irq,
151 .irq_unmask = ehv_pic_unmask_irq,
152 .irq_eoi = ehv_pic_end_irq,
153 .irq_set_type = ehv_pic_set_irq_type,
154};
155
156static struct irq_chip ehv_pic_direct_eoi_irq_chip = {
157 .irq_mask = ehv_pic_mask_irq,
158 .irq_unmask = ehv_pic_unmask_irq,
159 .irq_eoi = ehv_pic_direct_end_irq,
160 .irq_set_type = ehv_pic_set_irq_type,
161};
162
163/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
164unsigned int ehv_pic_get_irq(void)
165{
166 int irq;
167
168 BUG_ON(global_ehv_pic == NULL);
169
170 if (global_ehv_pic->coreint_flag)
171 irq = mfspr(SPRN_EPR); /* if core int mode */
172 else
173 ev_int_iack(0, &irq); /* legacy mode */
174
175 if (irq == 0xFFFF) /* 0xFFFF --> no irq is pending */
176 return NO_IRQ;
177
178 /*
179 * this will also setup revmap[] in the slow path for the first
180 * time, next calls will always use fast path by indexing revmap
181 */
182 return irq_linear_revmap(global_ehv_pic->irqhost, irq);
183}
184
185static int ehv_pic_host_match(struct irq_host *h, struct device_node *node)
186{
187 /* Exact match, unless ehv_pic node is NULL */
188 return h->of_node == NULL || h->of_node == node;
189}
190
191static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
192 irq_hw_number_t hw)
193{
194 struct ehv_pic *ehv_pic = h->host_data;
195 struct irq_chip *chip;
196
197 /* Default chip */
198 chip = &ehv_pic->hc_irq;
199
200 if (mpic_percpu_base_vaddr)
201 if (hwirq_intspec[hw] & IRQ_TYPE_MPIC_DIRECT)
202 chip = &ehv_pic_direct_eoi_irq_chip;
203
204 irq_set_chip_data(virq, chip);
205 /*
206 * using handle_fasteoi_irq as our irq handler, this will
207 * only call the eoi callback and suitable for the MPIC
208 * controller which set ISR/IPR automatically and clear the
209 * highest priority active interrupt in ISR/IPR when we do
210 * a specific eoi
211 */
212 irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);
213
214 /* Set default irq type */
215 irq_set_irq_type(virq, IRQ_TYPE_NONE);
216
217 return 0;
218}
219
220static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
221 const u32 *intspec, unsigned int intsize,
222 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
223
224{
225 /*
226 * interrupt sense values coming from the guest device tree
227 * interrupt specifiers can have four possible sense and
228 * level encoding information and they need to
229 * be translated between firmware type & linux type.
230 */
231
232 static unsigned char map_of_senses_to_linux_irqtype[4] = {
233 IRQ_TYPE_EDGE_FALLING,
234 IRQ_TYPE_EDGE_RISING,
235 IRQ_TYPE_LEVEL_LOW,
236 IRQ_TYPE_LEVEL_HIGH,
237 };
238
239 *out_hwirq = intspec[0];
240 if (intsize > 1) {
241 hwirq_intspec[intspec[0]] = intspec[1];
242 *out_flags = map_of_senses_to_linux_irqtype[intspec[1] &
243 ~IRQ_TYPE_MPIC_DIRECT];
244 } else {
245 *out_flags = IRQ_TYPE_NONE;
246 }
247
248 return 0;
249}
250
251static struct irq_host_ops ehv_pic_host_ops = {
252 .match = ehv_pic_host_match,
253 .map = ehv_pic_host_map,
254 .xlate = ehv_pic_host_xlate,
255};
256
257void __init ehv_pic_init(void)
258{
259 struct device_node *np, *np2;
260 struct ehv_pic *ehv_pic;
261 int coreint_flag = 1;
262
263 np = of_find_compatible_node(NULL, NULL, "epapr,hv-pic");
264 if (!np) {
265 pr_err("ehv_pic_init: could not find epapr,hv-pic node\n");
266 return;
267 }
268
269 if (!of_find_property(np, "has-external-proxy", NULL))
270 coreint_flag = 0;
271
272 ehv_pic = kzalloc(sizeof(struct ehv_pic), GFP_KERNEL);
273 if (!ehv_pic) {
274 of_node_put(np);
275 return;
276 }
277
278 ehv_pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
279 NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0);
280
281 if (!ehv_pic->irqhost) {
282 of_node_put(np);
283 return;
284 }
285
286 np2 = of_find_compatible_node(NULL, NULL, "fsl,hv-mpic-per-cpu");
287 if (np2) {
288 mpic_percpu_base_vaddr = of_iomap(np2, 0);
289 if (!mpic_percpu_base_vaddr)
290 pr_err("ehv_pic_init: of_iomap failed\n");
291
292 of_node_put(np2);
293 }
294
295 ehv_pic->irqhost->host_data = ehv_pic;
296 ehv_pic->hc_irq = ehv_pic_irq_chip;
297 ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity;
298 ehv_pic->coreint_flag = coreint_flag;
299
300 global_ehv_pic = ehv_pic;
301 irq_set_default_host(global_ehv_pic->irqhost);
302}
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ba5cb3fa7074..3bba8bdb58b0 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -38,10 +38,17 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
38 38
39static void __init quirk_fsl_pcie_header(struct pci_dev *dev) 39static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
40{ 40{
41 u8 progif;
42
41 /* if we aren't a PCIe don't bother */ 43 /* if we aren't a PCIe don't bother */
42 if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) 44 if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
43 return; 45 return;
44 46
47 /* if we aren't in host mode don't bother */
48 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
49 if (progif & 0x1)
50 return;
51
45 dev->class = PCI_CLASS_BRIDGE_PCI << 8; 52 dev->class = PCI_CLASS_BRIDGE_PCI << 8;
46 fsl_pcie_bus_fixup = 1; 53 fsl_pcie_bus_fixup = 1;
47 return; 54 return;
@@ -323,6 +330,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
323 struct pci_controller *hose; 330 struct pci_controller *hose;
324 struct resource rsrc; 331 struct resource rsrc;
325 const int *bus_range; 332 const int *bus_range;
333 u8 progif;
326 334
327 if (!of_device_is_available(dev)) { 335 if (!of_device_is_available(dev)) {
328 pr_warning("%s: disabled\n", dev->full_name); 336 pr_warning("%s: disabled\n", dev->full_name);
@@ -353,6 +361,18 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
353 361
354 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, 362 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
355 PPC_INDIRECT_TYPE_BIG_ENDIAN); 363 PPC_INDIRECT_TYPE_BIG_ENDIAN);
364
365 early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
366 if ((progif & 1) == 1) {
367 /* unmap cfg_data & cfg_addr separately if not on same page */
368 if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
369 ((unsigned long)hose->cfg_addr & PAGE_MASK))
370 iounmap(hose->cfg_data);
371 iounmap(hose->cfg_addr);
372 pcibios_free_controller(hose);
373 return 0;
374 }
375
356 setup_pci_cmd(hose); 376 setup_pci_cmd(hose);
357 377
358 /* check PCI express link status */ 378 /* check PCI express link status */
@@ -380,70 +400,11 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
380 400
381 return 0; 401 return 0;
382} 402}
383
384DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_header);
385DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_header);
386DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_header);
387DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header);
388DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header);
389DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header);
390DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header);
391DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569E, quirk_fsl_pcie_header);
392DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569, quirk_fsl_pcie_header);
393DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header);
394DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header);
395DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header);
396DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_header);
397DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_header);
398DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_header);
399DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_header);
400DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_header);
401DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_header);
402DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_header);
403DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536E, quirk_fsl_pcie_header);
404DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header);
405DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
406DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
407DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
408DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1011E, quirk_fsl_pcie_header);
409DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1011, quirk_fsl_pcie_header);
410DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013E, quirk_fsl_pcie_header);
411DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header);
412DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header);
413DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header);
414DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021E, quirk_fsl_pcie_header);
415DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021, quirk_fsl_pcie_header);
416DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header);
417DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header);
418DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header);
419DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010, quirk_fsl_pcie_header);
420DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020E, quirk_fsl_pcie_header);
421DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020, quirk_fsl_pcie_header);
422DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2040E, quirk_fsl_pcie_header);
423DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2040, quirk_fsl_pcie_header);
424DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P3041E, quirk_fsl_pcie_header);
425DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P3041, quirk_fsl_pcie_header);
426DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040E, quirk_fsl_pcie_header);
427DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040, quirk_fsl_pcie_header);
428DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080E, quirk_fsl_pcie_header);
429DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080, quirk_fsl_pcie_header);
430DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5010E, quirk_fsl_pcie_header);
431DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5010, quirk_fsl_pcie_header);
432DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5020E, quirk_fsl_pcie_header);
433DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5020, quirk_fsl_pcie_header);
434#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ 403#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
435 404
436#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) 405DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
437DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8308, quirk_fsl_pcie_header);
438DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header);
439DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header);
440DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header);
441DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315, quirk_fsl_pcie_header);
442DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377E, quirk_fsl_pcie_header);
443DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377, quirk_fsl_pcie_header);
444DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378E, quirk_fsl_pcie_header);
445DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378, quirk_fsl_pcie_header);
446 406
407#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
447struct mpc83xx_pcie_priv { 408struct mpc83xx_pcie_priv {
448 void __iomem *cfg_type0; 409 void __iomem *cfg_type0;
449 void __iomem *cfg_type1; 410 void __iomem *cfg_type1;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 19e5015e039b..265313e8396b 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -41,6 +41,7 @@
41#include <sysdev/fsl_soc.h> 41#include <sysdev/fsl_soc.h>
42#include <mm/mmu_decl.h> 42#include <mm/mmu_decl.h>
43#include <asm/cpm2.h> 43#include <asm/cpm2.h>
44#include <asm/fsl_hcalls.h> /* For the Freescale hypervisor */
44 45
45extern void init_fcc_ioports(struct fs_platform_info*); 46extern void init_fcc_ioports(struct fs_platform_info*);
46extern void init_fec_ioports(struct fs_platform_info*); 47extern void init_fec_ioports(struct fs_platform_info*);
@@ -252,3 +253,29 @@ void fsl_rstcr_restart(char *cmd)
252struct platform_diu_data_ops diu_ops; 253struct platform_diu_data_ops diu_ops;
253EXPORT_SYMBOL(diu_ops); 254EXPORT_SYMBOL(diu_ops);
254#endif 255#endif
256
257/*
258 * Restart the current partition
259 *
260 * This function should be assigned to the ppc_md.restart function pointer,
261 * to initiate a partition restart when we're running under the Freescale
262 * hypervisor.
263 */
264void fsl_hv_restart(char *cmd)
265{
266 pr_info("hv restart\n");
267 fh_partition_restart(-1);
268}
269
270/*
271 * Halt the current partition
272 *
273 * This function should be assigned to the ppc_md.power_off and ppc_md.halt
274 * function pointers, to shut down the partition when we're running under
275 * the Freescale hypervisor.
276 */
277void fsl_hv_halt(void)
278{
279 pr_info("hv exit\n");
280 fh_partition_stop(-1);
281}
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 53609489a62b..2ece02beb8ff 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -36,5 +36,8 @@ struct platform_diu_data_ops {
36extern struct platform_diu_data_ops diu_ops; 36extern struct platform_diu_data_ops diu_ops;
37#endif 37#endif
38 38
39void fsl_hv_restart(char *cmd);
40void fsl_hv_halt(void);
41
39#endif 42#endif
40#endif 43#endif
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 58d7a534f877..d5d3ff3d757e 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -598,42 +598,6 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
598 598
599#endif /* CONFIG_MPIC_U3_HT_IRQS */ 599#endif /* CONFIG_MPIC_U3_HT_IRQS */
600 600
601#ifdef CONFIG_SMP
602static int irq_choose_cpu(const struct cpumask *mask)
603{
604 int cpuid;
605
606 if (cpumask_equal(mask, cpu_all_mask)) {
607 static int irq_rover = 0;
608 static DEFINE_RAW_SPINLOCK(irq_rover_lock);
609 unsigned long flags;
610
611 /* Round-robin distribution... */
612 do_round_robin:
613 raw_spin_lock_irqsave(&irq_rover_lock, flags);
614
615 irq_rover = cpumask_next(irq_rover, cpu_online_mask);
616 if (irq_rover >= nr_cpu_ids)
617 irq_rover = cpumask_first(cpu_online_mask);
618
619 cpuid = irq_rover;
620
621 raw_spin_unlock_irqrestore(&irq_rover_lock, flags);
622 } else {
623 cpuid = cpumask_first_and(mask, cpu_online_mask);
624 if (cpuid >= nr_cpu_ids)
625 goto do_round_robin;
626 }
627
628 return get_hard_smp_processor_id(cpuid);
629}
630#else
631static int irq_choose_cpu(const struct cpumask *mask)
632{
633 return hard_smp_processor_id();
634}
635#endif
636
637/* Find an mpic associated with a given linux interrupt */ 601/* Find an mpic associated with a given linux interrupt */
638static struct mpic *mpic_find(unsigned int irq) 602static struct mpic *mpic_find(unsigned int irq)
639{ 603{
@@ -849,7 +813,7 @@ static void mpic_unmask_tm(struct irq_data *d)
849 struct mpic *mpic = mpic_from_irq_data(d); 813 struct mpic *mpic = mpic_from_irq_data(d);
850 unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0]; 814 unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0];
851 815
852 DBG("%s: enable_tm: %d (tm %d)\n", mpic->name, irq, src); 816 DBG("%s: enable_tm: %d (tm %d)\n", mpic->name, d->irq, src);
853 mpic_tm_write(src, mpic_tm_read(src) & ~MPIC_VECPRI_MASK); 817 mpic_tm_write(src, mpic_tm_read(src) & ~MPIC_VECPRI_MASK);
854 mpic_tm_read(src); 818 mpic_tm_read(src);
855} 819}
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index deda60a7f996..2ec4f3bb8160 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -650,12 +650,74 @@ struct ppc4xx_pciex_hwops
650 int (*core_init)(struct device_node *np); 650 int (*core_init)(struct device_node *np);
651 int (*port_init_hw)(struct ppc4xx_pciex_port *port); 651 int (*port_init_hw)(struct ppc4xx_pciex_port *port);
652 int (*setup_utl)(struct ppc4xx_pciex_port *port); 652 int (*setup_utl)(struct ppc4xx_pciex_port *port);
653 void (*check_link)(struct ppc4xx_pciex_port *port);
653}; 654};
654 655
655static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops; 656static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops;
656 657
657#ifdef CONFIG_44x 658#ifdef CONFIG_44x
658 659
660static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port,
661 unsigned int sdr_offset,
662 unsigned int mask,
663 unsigned int value,
664 int timeout_ms)
665{
666 u32 val;
667
668 while(timeout_ms--) {
669 val = mfdcri(SDR0, port->sdr_base + sdr_offset);
670 if ((val & mask) == value) {
671 pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n",
672 port->index, sdr_offset, timeout_ms, val);
673 return 0;
674 }
675 msleep(1);
676 }
677 return -1;
678}
679
680static int __init ppc4xx_pciex_port_reset_sdr(struct ppc4xx_pciex_port *port)
681{
682 /* Wait for reset to complete */
683 if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) {
684 printk(KERN_WARNING "PCIE%d: PGRST failed\n",
685 port->index);
686 return -1;
687 }
688 return 0;
689}
690
691static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port)
692{
693 printk(KERN_INFO "PCIE%d: Checking link...\n", port->index);
694
695 /* Check for card presence detect if supported, if not, just wait for
696 * link unconditionally.
697 *
698 * note that we don't fail if there is no link, we just filter out
699 * config space accesses. That way, it will be easier to implement
700 * hotplug later on.
701 */
702 if (!port->has_ibpre ||
703 !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
704 1 << 28, 1 << 28, 100)) {
705 printk(KERN_INFO
706 "PCIE%d: Device detected, waiting for link...\n",
707 port->index);
708 if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
709 0x1000, 0x1000, 2000))
710 printk(KERN_WARNING
711 "PCIE%d: Link up failed\n", port->index);
712 else {
713 printk(KERN_INFO
714 "PCIE%d: link is up !\n", port->index);
715 port->link = 1;
716 }
717 } else
718 printk(KERN_INFO "PCIE%d: No device detected.\n", port->index);
719}
720
659/* Check various reset bits of the 440SPe PCIe core */ 721/* Check various reset bits of the 440SPe PCIe core */
660static int __init ppc440spe_pciex_check_reset(struct device_node *np) 722static int __init ppc440spe_pciex_check_reset(struct device_node *np)
661{ 723{
@@ -806,7 +868,7 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
806 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 868 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
807 (1 << 24) | (1 << 16), 1 << 12); 869 (1 << 24) | (1 << 16), 1 << 12);
808 870
809 return 0; 871 return ppc4xx_pciex_port_reset_sdr(port);
810} 872}
811 873
812static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 874static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
@@ -856,6 +918,7 @@ static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata =
856 .core_init = ppc440spe_pciex_core_init, 918 .core_init = ppc440spe_pciex_core_init,
857 .port_init_hw = ppc440speA_pciex_init_port_hw, 919 .port_init_hw = ppc440speA_pciex_init_port_hw,
858 .setup_utl = ppc440speA_pciex_init_utl, 920 .setup_utl = ppc440speA_pciex_init_utl,
921 .check_link = ppc4xx_pciex_check_link_sdr,
859}; 922};
860 923
861static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = 924static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
@@ -863,6 +926,7 @@ static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
863 .core_init = ppc440spe_pciex_core_init, 926 .core_init = ppc440spe_pciex_core_init,
864 .port_init_hw = ppc440speB_pciex_init_port_hw, 927 .port_init_hw = ppc440speB_pciex_init_port_hw,
865 .setup_utl = ppc440speB_pciex_init_utl, 928 .setup_utl = ppc440speB_pciex_init_utl,
929 .check_link = ppc4xx_pciex_check_link_sdr,
866}; 930};
867 931
868static int __init ppc460ex_pciex_core_init(struct device_node *np) 932static int __init ppc460ex_pciex_core_init(struct device_node *np)
@@ -944,7 +1008,7 @@ static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
944 1008
945 port->has_ibpre = 1; 1009 port->has_ibpre = 1;
946 1010
947 return 0; 1011 return ppc4xx_pciex_port_reset_sdr(port);
948} 1012}
949 1013
950static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port) 1014static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
@@ -972,6 +1036,7 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata =
972 .core_init = ppc460ex_pciex_core_init, 1036 .core_init = ppc460ex_pciex_core_init,
973 .port_init_hw = ppc460ex_pciex_init_port_hw, 1037 .port_init_hw = ppc460ex_pciex_init_port_hw,
974 .setup_utl = ppc460ex_pciex_init_utl, 1038 .setup_utl = ppc460ex_pciex_init_utl,
1039 .check_link = ppc4xx_pciex_check_link_sdr,
975}; 1040};
976 1041
977static int __init ppc460sx_pciex_core_init(struct device_node *np) 1042static int __init ppc460sx_pciex_core_init(struct device_node *np)
@@ -1075,7 +1140,7 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1075 1140
1076 port->has_ibpre = 1; 1141 port->has_ibpre = 1;
1077 1142
1078 return 0; 1143 return ppc4xx_pciex_port_reset_sdr(port);
1079} 1144}
1080 1145
1081static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) 1146static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
@@ -1089,6 +1154,7 @@ static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
1089 .core_init = ppc460sx_pciex_core_init, 1154 .core_init = ppc460sx_pciex_core_init,
1090 .port_init_hw = ppc460sx_pciex_init_port_hw, 1155 .port_init_hw = ppc460sx_pciex_init_port_hw,
1091 .setup_utl = ppc460sx_pciex_init_utl, 1156 .setup_utl = ppc460sx_pciex_init_utl,
1157 .check_link = ppc4xx_pciex_check_link_sdr,
1092}; 1158};
1093 1159
1094#endif /* CONFIG_44x */ 1160#endif /* CONFIG_44x */
@@ -1154,7 +1220,7 @@ static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1154 1220
1155 port->has_ibpre = 1; 1221 port->has_ibpre = 1;
1156 1222
1157 return 0; 1223 return ppc4xx_pciex_port_reset_sdr(port);
1158} 1224}
1159 1225
1160static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port) 1226static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
@@ -1183,11 +1249,11 @@ static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
1183 .core_init = ppc405ex_pciex_core_init, 1249 .core_init = ppc405ex_pciex_core_init,
1184 .port_init_hw = ppc405ex_pciex_init_port_hw, 1250 .port_init_hw = ppc405ex_pciex_init_port_hw,
1185 .setup_utl = ppc405ex_pciex_init_utl, 1251 .setup_utl = ppc405ex_pciex_init_utl,
1252 .check_link = ppc4xx_pciex_check_link_sdr,
1186}; 1253};
1187 1254
1188#endif /* CONFIG_40x */ 1255#endif /* CONFIG_40x */
1189 1256
1190
1191/* Check that the core has been initied and if not, do it */ 1257/* Check that the core has been initied and if not, do it */
1192static int __init ppc4xx_pciex_check_core_init(struct device_node *np) 1258static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
1193{ 1259{
@@ -1261,26 +1327,6 @@ static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port
1261 dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0); 1327 dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0);
1262} 1328}
1263 1329
1264static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port,
1265 unsigned int sdr_offset,
1266 unsigned int mask,
1267 unsigned int value,
1268 int timeout_ms)
1269{
1270 u32 val;
1271
1272 while(timeout_ms--) {
1273 val = mfdcri(SDR0, port->sdr_base + sdr_offset);
1274 if ((val & mask) == value) {
1275 pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n",
1276 port->index, sdr_offset, timeout_ms, val);
1277 return 0;
1278 }
1279 msleep(1);
1280 }
1281 return -1;
1282}
1283
1284static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) 1330static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1285{ 1331{
1286 int rc = 0; 1332 int rc = 0;
@@ -1291,40 +1337,8 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1291 if (rc != 0) 1337 if (rc != 0)
1292 return rc; 1338 return rc;
1293 1339
1294 printk(KERN_INFO "PCIE%d: Checking link...\n", 1340 if (ppc4xx_pciex_hwops->check_link)
1295 port->index); 1341 ppc4xx_pciex_hwops->check_link(port);
1296
1297 /* Wait for reset to complete */
1298 if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) {
1299 printk(KERN_WARNING "PCIE%d: PGRST failed\n",
1300 port->index);
1301 return -1;
1302 }
1303
1304 /* Check for card presence detect if supported, if not, just wait for
1305 * link unconditionally.
1306 *
1307 * note that we don't fail if there is no link, we just filter out
1308 * config space accesses. That way, it will be easier to implement
1309 * hotplug later on.
1310 */
1311 if (!port->has_ibpre ||
1312 !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
1313 1 << 28, 1 << 28, 100)) {
1314 printk(KERN_INFO
1315 "PCIE%d: Device detected, waiting for link...\n",
1316 port->index);
1317 if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
1318 0x1000, 0x1000, 2000))
1319 printk(KERN_WARNING
1320 "PCIE%d: Link up failed\n", port->index);
1321 else {
1322 printk(KERN_INFO
1323 "PCIE%d: link is up !\n", port->index);
1324 port->link = 1;
1325 }
1326 } else
1327 printk(KERN_INFO "PCIE%d: No device detected.\n", port->index);
1328 1342
1329 /* 1343 /*
1330 * Initialize mapping: disable all regions and configure 1344 * Initialize mapping: disable all regions and configure
@@ -1347,14 +1361,17 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1347 /* 1361 /*
1348 * Check for VC0 active and assert RDY. 1362 * Check for VC0 active and assert RDY.
1349 */ 1363 */
1350 if (port->link && 1364 if (port->sdr_base) {
1351 ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1365 if (port->link &&
1352 1 << 16, 1 << 16, 5000)) { 1366 ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
1353 printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index); 1367 1 << 16, 1 << 16, 5000)) {
1354 port->link = 0; 1368 printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index);
1369 port->link = 0;
1370 }
1371
1372 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20);
1355 } 1373 }
1356 1374
1357 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20);
1358 msleep(100); 1375 msleep(100);
1359 1376
1360 return 0; 1377 return 0;