diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-06 20:12:03 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-06 20:12:03 -0500 |
commit | 1197ab2942f920f261952de0c392ac749a35796b (patch) | |
tree | 4922ccc8a6061e5ece6ac7420001f3bf4524ea92 /arch/powerpc/sysdev | |
parent | ec773e99ab4abce07b1ae23117179c2861831964 (diff) | |
parent | 96cc017c5b7ec095ef047d3c1952b6b6bbf98943 (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: (106 commits)
powerpc/p3060qds: Add support for P3060QDS board
powerpc/83xx: Add shutdown request support to MCU handling on MPC8349 MITX
powerpc/85xx: Make kexec to interate over online cpus
powerpc/fsl_booke: Fix comment in head_fsl_booke.S
powerpc/85xx: issue 15 EOI after core reset for FSL CoreNet devices
powerpc/8xxx: Fix interrupt handling in MPC8xxx GPIO driver
powerpc/85xx: Add 'fsl,pq3-gpio' compatiable for GPIO driver
powerpc/86xx: Correct Gianfar support for GE boards
powerpc/cpm: Clear muram before it is in use.
drivers/virt: add ioctl for 32-bit compat on 64-bit to fsl-hv-manager
powerpc/fsl_msi: add support for "msi-address-64" property
powerpc/85xx: Setup secondary cores PIR with hard SMP id
powerpc/fsl-booke: Fix settlbcam for 64-bit
powerpc/85xx: Adding DCSR node to dtsi device trees
powerpc/85xx: clean up FPGA device tree nodes for Freecsale QorIQ boards
powerpc/85xx: fix PHYS_64BIT selection for P1022DS
powerpc/fsl-booke: Fix setup_initial_memory_limit to not blindly map
powerpc: respect mem= setting for early memory limit setup
powerpc: Update corenet64_smp_defconfig
powerpc: Update mpc85xx/corenet 32-bit defconfigs
...
Fix up trivial conflicts in:
- arch/powerpc/configs/40x/hcu4_defconfig
removed stale file, edited elsewhere
- arch/powerpc/include/asm/udbg.h, arch/powerpc/kernel/udbg.c:
added opal and gelic drivers vs added ePAPR driver
- drivers/tty/serial/8250.c
moved UPIO_TSI to powerpc vs removed UPIO_DWAPB support
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/cpm_common.c | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_msi.c | 28 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_msi.h | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpc8xxx_gpio.c | 395 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 34 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.c | 101 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.h | 12 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xics/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xics/icp-native.c | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xics/ics-opal.c | 244 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xics/xics-common.c | 8 |
12 files changed, 385 insertions, 447 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index cf736ca0cf05..84e13253aec5 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -18,7 +18,6 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) | |||
18 | obj-$(CONFIG_FSL_PMC) += fsl_pmc.o | 18 | obj-$(CONFIG_FSL_PMC) += fsl_pmc.o |
19 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o | 19 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o |
20 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o | 20 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o |
21 | obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o | ||
22 | obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o | 21 | obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o |
23 | obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o | 22 | obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o |
24 | obj-$(CONFIG_FSL_RIO) += fsl_rio.o | 23 | obj-$(CONFIG_FSL_RIO) += fsl_rio.o |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index d55d0ad0deab..8db10bb90042 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Author: Scott Wood <scottwood@freescale.com> | 4 | * Author: Scott Wood <scottwood@freescale.com> |
5 | * | 5 | * |
6 | * Copyright 2007 Freescale Semiconductor, Inc. | 6 | * Copyright 2007-2008,2010 Freescale Semiconductor, Inc. |
7 | * | 7 | * |
8 | * Some parts derived from commproc.c/cpm2_common.c, which is: | 8 | * Some parts derived from commproc.c/cpm2_common.c, which is: |
9 | * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) | 9 | * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) |
@@ -146,6 +146,7 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) | |||
146 | spin_lock_irqsave(&cpm_muram_lock, flags); | 146 | spin_lock_irqsave(&cpm_muram_lock, flags); |
147 | cpm_muram_info.alignment = align; | 147 | cpm_muram_info.alignment = align; |
148 | start = rh_alloc(&cpm_muram_info, size, "commproc"); | 148 | start = rh_alloc(&cpm_muram_info, size, "commproc"); |
149 | memset(cpm_muram_addr(start), 0, size); | ||
149 | spin_unlock_irqrestore(&cpm_muram_lock, flags); | 150 | spin_unlock_irqrestore(&cpm_muram_lock, flags); |
150 | 151 | ||
151 | return start; | 152 | return start; |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 419a77239bd7..e5c344d336ea 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
@@ -30,7 +30,7 @@ LIST_HEAD(msi_head); | |||
30 | 30 | ||
31 | struct fsl_msi_feature { | 31 | struct fsl_msi_feature { |
32 | u32 fsl_pic_ip; | 32 | u32 fsl_pic_ip; |
33 | u32 msiir_offset; | 33 | u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */ |
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct fsl_msi_cascade_data { | 36 | struct fsl_msi_cascade_data { |
@@ -126,10 +126,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, | |||
126 | { | 126 | { |
127 | struct fsl_msi *msi_data = fsl_msi_data; | 127 | struct fsl_msi *msi_data = fsl_msi_data; |
128 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 128 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
129 | u64 base = fsl_pci_immrbar_base(hose); | 129 | u64 address; /* Physical address of the MSIIR */ |
130 | int len; | ||
131 | const u64 *reg; | ||
132 | |||
133 | /* If the msi-address-64 property exists, then use it */ | ||
134 | reg = of_get_property(hose->dn, "msi-address-64", &len); | ||
135 | if (reg && (len == sizeof(u64))) | ||
136 | address = be64_to_cpup(reg); | ||
137 | else | ||
138 | address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset; | ||
130 | 139 | ||
131 | msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base); | 140 | msg->address_lo = lower_32_bits(address); |
132 | msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base); | 141 | msg->address_hi = upper_32_bits(address); |
133 | 142 | ||
134 | msg->data = hwirq; | 143 | msg->data = hwirq; |
135 | 144 | ||
@@ -296,7 +305,7 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, | |||
296 | } | 305 | } |
297 | 306 | ||
298 | msi->msi_virqs[irq_index] = virt_msir; | 307 | msi->msi_virqs[irq_index] = virt_msir; |
299 | cascade_data->index = offset + irq_index; | 308 | cascade_data->index = offset; |
300 | cascade_data->msi_data = msi; | 309 | cascade_data->msi_data = msi; |
301 | irq_set_handler_data(virt_msir, cascade_data); | 310 | irq_set_handler_data(virt_msir, cascade_data); |
302 | irq_set_chained_handler(virt_msir, fsl_msi_cascade); | 311 | irq_set_chained_handler(virt_msir, fsl_msi_cascade); |
@@ -359,8 +368,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
359 | 368 | ||
360 | msi->irqhost->host_data = msi; | 369 | msi->irqhost->host_data = msi; |
361 | 370 | ||
362 | msi->msi_addr_hi = 0x0; | 371 | msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff); |
363 | msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff); | ||
364 | 372 | ||
365 | rc = fsl_msi_init_allocator(msi); | 373 | rc = fsl_msi_init_allocator(msi); |
366 | if (rc) { | 374 | if (rc) { |
@@ -376,8 +384,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
376 | goto error_out; | 384 | goto error_out; |
377 | } | 385 | } |
378 | 386 | ||
379 | if (!p) | 387 | if (!p) { |
380 | p = all_avail; | 388 | p = all_avail; |
389 | len = sizeof(all_avail); | ||
390 | } | ||
381 | 391 | ||
382 | for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { | 392 | for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { |
383 | if (p[i * 2] % IRQS_PER_MSI_REG || | 393 | if (p[i * 2] % IRQS_PER_MSI_REG || |
@@ -393,7 +403,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
393 | count = p[i * 2 + 1] / IRQS_PER_MSI_REG; | 403 | count = p[i * 2 + 1] / IRQS_PER_MSI_REG; |
394 | 404 | ||
395 | for (j = 0; j < count; j++, irq_index++) { | 405 | for (j = 0; j < count; j++, irq_index++) { |
396 | err = fsl_msi_setup_hwirq(msi, dev, offset, irq_index); | 406 | err = fsl_msi_setup_hwirq(msi, dev, offset + j, irq_index); |
397 | if (err) | 407 | if (err) |
398 | goto error_out; | 408 | goto error_out; |
399 | } | 409 | } |
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index 624580c252d7..1313abbc5200 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h | |||
@@ -28,8 +28,7 @@ struct fsl_msi { | |||
28 | 28 | ||
29 | unsigned long cascade_irq; | 29 | unsigned long cascade_irq; |
30 | 30 | ||
31 | u32 msi_addr_lo; | 31 | u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */ |
32 | u32 msi_addr_hi; | ||
33 | void __iomem *msi_regs; | 32 | void __iomem *msi_regs; |
34 | u32 feature; | 33 | u32 feature; |
35 | int msi_virqs[NR_MSI_REG]; | 34 | int msi_virqs[NR_MSI_REG]; |
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c deleted file mode 100644 index fb4963abdf55..000000000000 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ /dev/null | |||
@@ -1,395 +0,0 @@ | |||
1 | /* | ||
2 | * GPIOs on MPC512x/8349/8572/8610 and compatible | ||
3 | * | ||
4 | * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public License | ||
7 | * version 2. This program is licensed "as is" without any warranty of any | ||
8 | * kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_gpio.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/irq.h> | ||
20 | |||
21 | #define MPC8XXX_GPIO_PINS 32 | ||
22 | |||
23 | #define GPIO_DIR 0x00 | ||
24 | #define GPIO_ODR 0x04 | ||
25 | #define GPIO_DAT 0x08 | ||
26 | #define GPIO_IER 0x0c | ||
27 | #define GPIO_IMR 0x10 | ||
28 | #define GPIO_ICR 0x14 | ||
29 | #define GPIO_ICR2 0x18 | ||
30 | |||
31 | struct mpc8xxx_gpio_chip { | ||
32 | struct of_mm_gpio_chip mm_gc; | ||
33 | spinlock_t lock; | ||
34 | |||
35 | /* | ||
36 | * shadowed data register to be able to clear/set output pins in | ||
37 | * open drain mode safely | ||
38 | */ | ||
39 | u32 data; | ||
40 | struct irq_host *irq; | ||
41 | void *of_dev_id_data; | ||
42 | }; | ||
43 | |||
44 | static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) | ||
45 | { | ||
46 | return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio); | ||
47 | } | ||
48 | |||
49 | static inline struct mpc8xxx_gpio_chip * | ||
50 | to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm) | ||
51 | { | ||
52 | return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc); | ||
53 | } | ||
54 | |||
55 | static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) | ||
56 | { | ||
57 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
58 | |||
59 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); | ||
60 | } | ||
61 | |||
62 | /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs | ||
63 | * defined as output cannot be determined by reading GPDAT register, | ||
64 | * so we use shadow data register instead. The status of input pins | ||
65 | * is determined by reading GPDAT register. | ||
66 | */ | ||
67 | static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
68 | { | ||
69 | u32 val; | ||
70 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
71 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
72 | |||
73 | val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); | ||
74 | |||
75 | return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); | ||
76 | } | ||
77 | |||
78 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
79 | { | ||
80 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
81 | |||
82 | return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio); | ||
83 | } | ||
84 | |||
85 | static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
86 | { | ||
87 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
88 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
89 | unsigned long flags; | ||
90 | |||
91 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
92 | |||
93 | if (val) | ||
94 | mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio); | ||
95 | else | ||
96 | mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio); | ||
97 | |||
98 | out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); | ||
99 | |||
100 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
101 | } | ||
102 | |||
103 | static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
104 | { | ||
105 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
106 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
107 | unsigned long flags; | ||
108 | |||
109 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
110 | |||
111 | clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
112 | |||
113 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
119 | { | ||
120 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
121 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
122 | unsigned long flags; | ||
123 | |||
124 | mpc8xxx_gpio_set(gc, gpio, val); | ||
125 | |||
126 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
127 | |||
128 | setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
129 | |||
130 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
136 | { | ||
137 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
138 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
139 | |||
140 | if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS) | ||
141 | return irq_create_mapping(mpc8xxx_gc->irq, offset); | ||
142 | else | ||
143 | return -ENXIO; | ||
144 | } | ||
145 | |||
146 | static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) | ||
147 | { | ||
148 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); | ||
149 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
150 | unsigned int mask; | ||
151 | |||
152 | mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR); | ||
153 | if (mask) | ||
154 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, | ||
155 | 32 - ffs(mask))); | ||
156 | } | ||
157 | |||
158 | static void mpc8xxx_irq_unmask(struct irq_data *d) | ||
159 | { | ||
160 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
161 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
162 | unsigned long flags; | ||
163 | |||
164 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
165 | |||
166 | setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
167 | |||
168 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
169 | } | ||
170 | |||
171 | static void mpc8xxx_irq_mask(struct irq_data *d) | ||
172 | { | ||
173 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
174 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
175 | unsigned long flags; | ||
176 | |||
177 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
178 | |||
179 | clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
180 | |||
181 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
182 | } | ||
183 | |||
184 | static void mpc8xxx_irq_ack(struct irq_data *d) | ||
185 | { | ||
186 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
187 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
188 | |||
189 | out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
190 | } | ||
191 | |||
192 | static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
193 | { | ||
194 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
195 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
196 | unsigned long flags; | ||
197 | |||
198 | switch (flow_type) { | ||
199 | case IRQ_TYPE_EDGE_FALLING: | ||
200 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
201 | setbits32(mm->regs + GPIO_ICR, | ||
202 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
203 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
204 | break; | ||
205 | |||
206 | case IRQ_TYPE_EDGE_BOTH: | ||
207 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
208 | clrbits32(mm->regs + GPIO_ICR, | ||
209 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
210 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
211 | break; | ||
212 | |||
213 | default: | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
221 | { | ||
222 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
223 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
224 | unsigned long gpio = irqd_to_hwirq(d); | ||
225 | void __iomem *reg; | ||
226 | unsigned int shift; | ||
227 | unsigned long flags; | ||
228 | |||
229 | if (gpio < 16) { | ||
230 | reg = mm->regs + GPIO_ICR; | ||
231 | shift = (15 - gpio) * 2; | ||
232 | } else { | ||
233 | reg = mm->regs + GPIO_ICR2; | ||
234 | shift = (15 - (gpio % 16)) * 2; | ||
235 | } | ||
236 | |||
237 | switch (flow_type) { | ||
238 | case IRQ_TYPE_EDGE_FALLING: | ||
239 | case IRQ_TYPE_LEVEL_LOW: | ||
240 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
241 | clrsetbits_be32(reg, 3 << shift, 2 << shift); | ||
242 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
243 | break; | ||
244 | |||
245 | case IRQ_TYPE_EDGE_RISING: | ||
246 | case IRQ_TYPE_LEVEL_HIGH: | ||
247 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
248 | clrsetbits_be32(reg, 3 << shift, 1 << shift); | ||
249 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
250 | break; | ||
251 | |||
252 | case IRQ_TYPE_EDGE_BOTH: | ||
253 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
254 | clrbits32(reg, 3 << shift); | ||
255 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
256 | break; | ||
257 | |||
258 | default: | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static struct irq_chip mpc8xxx_irq_chip = { | ||
266 | .name = "mpc8xxx-gpio", | ||
267 | .irq_unmask = mpc8xxx_irq_unmask, | ||
268 | .irq_mask = mpc8xxx_irq_mask, | ||
269 | .irq_ack = mpc8xxx_irq_ack, | ||
270 | .irq_set_type = mpc8xxx_irq_set_type, | ||
271 | }; | ||
272 | |||
273 | static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, | ||
274 | irq_hw_number_t hw) | ||
275 | { | ||
276 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data; | ||
277 | |||
278 | if (mpc8xxx_gc->of_dev_id_data) | ||
279 | mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data; | ||
280 | |||
281 | irq_set_chip_data(virq, h->host_data); | ||
282 | irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); | ||
283 | irq_set_irq_type(virq, IRQ_TYPE_NONE); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct, | ||
289 | const u32 *intspec, unsigned int intsize, | ||
290 | irq_hw_number_t *out_hwirq, | ||
291 | unsigned int *out_flags) | ||
292 | |||
293 | { | ||
294 | /* interrupt sense values coming from the device tree equal either | ||
295 | * EDGE_FALLING or EDGE_BOTH | ||
296 | */ | ||
297 | *out_hwirq = intspec[0]; | ||
298 | *out_flags = intspec[1]; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static struct irq_host_ops mpc8xxx_gpio_irq_ops = { | ||
304 | .map = mpc8xxx_gpio_irq_map, | ||
305 | .xlate = mpc8xxx_gpio_irq_xlate, | ||
306 | }; | ||
307 | |||
308 | static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { | ||
309 | { .compatible = "fsl,mpc8349-gpio", }, | ||
310 | { .compatible = "fsl,mpc8572-gpio", }, | ||
311 | { .compatible = "fsl,mpc8610-gpio", }, | ||
312 | { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, }, | ||
313 | { .compatible = "fsl,qoriq-gpio", }, | ||
314 | {} | ||
315 | }; | ||
316 | |||
317 | static void __init mpc8xxx_add_controller(struct device_node *np) | ||
318 | { | ||
319 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; | ||
320 | struct of_mm_gpio_chip *mm_gc; | ||
321 | struct gpio_chip *gc; | ||
322 | const struct of_device_id *id; | ||
323 | unsigned hwirq; | ||
324 | int ret; | ||
325 | |||
326 | mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); | ||
327 | if (!mpc8xxx_gc) { | ||
328 | ret = -ENOMEM; | ||
329 | goto err; | ||
330 | } | ||
331 | |||
332 | spin_lock_init(&mpc8xxx_gc->lock); | ||
333 | |||
334 | mm_gc = &mpc8xxx_gc->mm_gc; | ||
335 | gc = &mm_gc->gc; | ||
336 | |||
337 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | ||
338 | gc->ngpio = MPC8XXX_GPIO_PINS; | ||
339 | gc->direction_input = mpc8xxx_gpio_dir_in; | ||
340 | gc->direction_output = mpc8xxx_gpio_dir_out; | ||
341 | if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) | ||
342 | gc->get = mpc8572_gpio_get; | ||
343 | else | ||
344 | gc->get = mpc8xxx_gpio_get; | ||
345 | gc->set = mpc8xxx_gpio_set; | ||
346 | gc->to_irq = mpc8xxx_gpio_to_irq; | ||
347 | |||
348 | ret = of_mm_gpiochip_add(np, mm_gc); | ||
349 | if (ret) | ||
350 | goto err; | ||
351 | |||
352 | hwirq = irq_of_parse_and_map(np, 0); | ||
353 | if (hwirq == NO_IRQ) | ||
354 | goto skip_irq; | ||
355 | |||
356 | mpc8xxx_gc->irq = | ||
357 | irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS, | ||
358 | &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS); | ||
359 | if (!mpc8xxx_gc->irq) | ||
360 | goto skip_irq; | ||
361 | |||
362 | id = of_match_node(mpc8xxx_gpio_ids, np); | ||
363 | if (id) | ||
364 | mpc8xxx_gc->of_dev_id_data = id->data; | ||
365 | |||
366 | mpc8xxx_gc->irq->host_data = mpc8xxx_gc; | ||
367 | |||
368 | /* ack and mask all irqs */ | ||
369 | out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); | ||
370 | out_be32(mm_gc->regs + GPIO_IMR, 0); | ||
371 | |||
372 | irq_set_handler_data(hwirq, mpc8xxx_gc); | ||
373 | irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); | ||
374 | |||
375 | skip_irq: | ||
376 | return; | ||
377 | |||
378 | err: | ||
379 | pr_err("%s: registration failed with status %d\n", | ||
380 | np->full_name, ret); | ||
381 | kfree(mpc8xxx_gc); | ||
382 | |||
383 | return; | ||
384 | } | ||
385 | |||
386 | static int __init mpc8xxx_add_gpiochips(void) | ||
387 | { | ||
388 | struct device_node *np; | ||
389 | |||
390 | for_each_matching_node(np, mpc8xxx_gpio_ids) | ||
391 | mpc8xxx_add_controller(np); | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | arch_initcall(mpc8xxx_add_gpiochips); | ||
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index d5d3ff3d757e..0842c6f8a3e6 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -1285,13 +1285,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1285 | mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) | 1285 | mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) |
1286 | | MPIC_GREG_GCONF_MCK); | 1286 | | MPIC_GREG_GCONF_MCK); |
1287 | 1287 | ||
1288 | /* Read feature register, calculate num CPUs and, for non-ISU | 1288 | /* |
1289 | * MPICs, num sources as well. On ISU MPICs, sources are counted | 1289 | * Read feature register. For non-ISU MPICs, num sources as well. On |
1290 | * as ISUs are added | 1290 | * ISU MPICs, sources are counted as ISUs are added |
1291 | */ | 1291 | */ |
1292 | greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); | 1292 | greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); |
1293 | mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK) | ||
1294 | >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; | ||
1295 | if (isu_size == 0) { | 1293 | if (isu_size == 0) { |
1296 | if (flags & MPIC_BROKEN_FRR_NIRQS) | 1294 | if (flags & MPIC_BROKEN_FRR_NIRQS) |
1297 | mpic->num_sources = mpic->irq_count; | 1295 | mpic->num_sources = mpic->irq_count; |
@@ -1301,10 +1299,18 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1301 | >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; | 1299 | >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; |
1302 | } | 1300 | } |
1303 | 1301 | ||
1302 | /* | ||
1303 | * The MPIC driver will crash if there are more cores than we | ||
1304 | * can initialize, so we may as well catch that problem here. | ||
1305 | */ | ||
1306 | BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS); | ||
1307 | |||
1304 | /* Map the per-CPU registers */ | 1308 | /* Map the per-CPU registers */ |
1305 | for (i = 0; i < mpic->num_cpus; i++) { | 1309 | for_each_possible_cpu(i) { |
1306 | mpic_map(mpic, node, paddr, &mpic->cpuregs[i], | 1310 | unsigned int cpu = get_hard_smp_processor_id(i); |
1307 | MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), | 1311 | |
1312 | mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu], | ||
1313 | MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE), | ||
1308 | 0x1000); | 1314 | 0x1000); |
1309 | } | 1315 | } |
1310 | 1316 | ||
@@ -1343,7 +1349,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1343 | } | 1349 | } |
1344 | printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," | 1350 | printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," |
1345 | " max %d CPUs\n", | 1351 | " max %d CPUs\n", |
1346 | name, vers, (unsigned long long)paddr, mpic->num_cpus); | 1352 | name, vers, (unsigned long long)paddr, num_possible_cpus()); |
1347 | printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", | 1353 | printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", |
1348 | mpic->isu_size, mpic->isu_shift, mpic->isu_mask); | 1354 | mpic->isu_size, mpic->isu_shift, mpic->isu_mask); |
1349 | 1355 | ||
@@ -1742,6 +1748,7 @@ void mpic_reset_core(int cpu) | |||
1742 | struct mpic *mpic = mpic_primary; | 1748 | struct mpic *mpic = mpic_primary; |
1743 | u32 pir; | 1749 | u32 pir; |
1744 | int cpuid = get_hard_smp_processor_id(cpu); | 1750 | int cpuid = get_hard_smp_processor_id(cpu); |
1751 | int i; | ||
1745 | 1752 | ||
1746 | /* Set target bit for core reset */ | 1753 | /* Set target bit for core reset */ |
1747 | pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | 1754 | pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); |
@@ -1753,6 +1760,15 @@ void mpic_reset_core(int cpu) | |||
1753 | pir &= ~(1 << cpuid); | 1760 | pir &= ~(1 << cpuid); |
1754 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); | 1761 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); |
1755 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | 1762 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); |
1763 | |||
1764 | /* Perform 15 EOI on each reset core to clear pending interrupts. | ||
1765 | * This is required for FSL CoreNet based devices */ | ||
1766 | if (mpic->flags & MPIC_FSL) { | ||
1767 | for (i = 0; i < 15; i++) { | ||
1768 | _mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid], | ||
1769 | MPIC_CPU_EOI, 0); | ||
1770 | } | ||
1771 | } | ||
1756 | } | 1772 | } |
1757 | #endif /* CONFIG_SMP */ | 1773 | #endif /* CONFIG_SMP */ |
1758 | 1774 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index dbfe96bc878a..862f11b3821e 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -834,7 +834,7 @@ static int __init ppc440spe_pciex_core_init(struct device_node *np) | |||
834 | return 3; | 834 | return 3; |
835 | } | 835 | } |
836 | 836 | ||
837 | static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 837 | static int __init ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
838 | { | 838 | { |
839 | u32 val = 1 << 24; | 839 | u32 val = 1 << 24; |
840 | 840 | ||
@@ -872,12 +872,12 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | |||
872 | return ppc4xx_pciex_port_reset_sdr(port); | 872 | return ppc4xx_pciex_port_reset_sdr(port); |
873 | } | 873 | } |
874 | 874 | ||
875 | static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 875 | static int __init ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
876 | { | 876 | { |
877 | return ppc440spe_pciex_init_port_hw(port); | 877 | return ppc440spe_pciex_init_port_hw(port); |
878 | } | 878 | } |
879 | 879 | ||
880 | static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 880 | static int __init ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
881 | { | 881 | { |
882 | int rc = ppc440spe_pciex_init_port_hw(port); | 882 | int rc = ppc440spe_pciex_init_port_hw(port); |
883 | 883 | ||
@@ -936,7 +936,7 @@ static int __init ppc460ex_pciex_core_init(struct device_node *np) | |||
936 | return 2; | 936 | return 2; |
937 | } | 937 | } |
938 | 938 | ||
939 | static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 939 | static int __init ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
940 | { | 940 | { |
941 | u32 val; | 941 | u32 val; |
942 | u32 utlset1; | 942 | u32 utlset1; |
@@ -1092,6 +1092,10 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np) | |||
1092 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); | 1092 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); |
1093 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); | 1093 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); |
1094 | 1094 | ||
1095 | /* Set HSS PRBS enabled */ | ||
1096 | mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130); | ||
1097 | mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130); | ||
1098 | |||
1095 | udelay(100); | 1099 | udelay(100); |
1096 | 1100 | ||
1097 | /* De-assert PLLRESET */ | 1101 | /* De-assert PLLRESET */ |
@@ -1122,7 +1126,7 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np) | |||
1122 | return 2; | 1126 | return 2; |
1123 | } | 1127 | } |
1124 | 1128 | ||
1125 | static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1129 | static int __init ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1126 | { | 1130 | { |
1127 | 1131 | ||
1128 | if (port->endpoint) | 1132 | if (port->endpoint) |
@@ -1132,9 +1136,6 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | |||
1132 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | 1136 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, |
1133 | 0, 0x01000000); | 1137 | 0, 0x01000000); |
1134 | 1138 | ||
1135 | /*Gen-1*/ | ||
1136 | mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000); | ||
1137 | |||
1138 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, | 1139 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, |
1139 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), | 1140 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), |
1140 | PESDRx_RCSSET_RSTPYN); | 1141 | PESDRx_RCSSET_RSTPYN); |
@@ -1148,14 +1149,42 @@ static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) | |||
1148 | { | 1149 | { |
1149 | /* Max 128 Bytes */ | 1150 | /* Max 128 Bytes */ |
1150 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); | 1151 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); |
1152 | /* Assert VRB and TXE - per datasheet turn off addr validation */ | ||
1153 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800000); | ||
1151 | return 0; | 1154 | return 0; |
1152 | } | 1155 | } |
1153 | 1156 | ||
1157 | static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port) | ||
1158 | { | ||
1159 | void __iomem *mbase; | ||
1160 | int attempt = 50; | ||
1161 | |||
1162 | port->link = 0; | ||
1163 | |||
1164 | mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); | ||
1165 | if (mbase == NULL) { | ||
1166 | printk(KERN_ERR "%s: Can't map internal config space !", | ||
1167 | port->node->full_name); | ||
1168 | goto done; | ||
1169 | } | ||
1170 | |||
1171 | while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA) | ||
1172 | & PECFG_460SX_DLLSTA_LINKUP))) { | ||
1173 | attempt--; | ||
1174 | mdelay(10); | ||
1175 | } | ||
1176 | if (attempt) | ||
1177 | port->link = 1; | ||
1178 | done: | ||
1179 | iounmap(mbase); | ||
1180 | |||
1181 | } | ||
1182 | |||
1154 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { | 1183 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { |
1155 | .core_init = ppc460sx_pciex_core_init, | 1184 | .core_init = ppc460sx_pciex_core_init, |
1156 | .port_init_hw = ppc460sx_pciex_init_port_hw, | 1185 | .port_init_hw = ppc460sx_pciex_init_port_hw, |
1157 | .setup_utl = ppc460sx_pciex_init_utl, | 1186 | .setup_utl = ppc460sx_pciex_init_utl, |
1158 | .check_link = ppc4xx_pciex_check_link_sdr, | 1187 | .check_link = ppc460sx_pciex_check_link, |
1159 | }; | 1188 | }; |
1160 | 1189 | ||
1161 | #endif /* CONFIG_44x */ | 1190 | #endif /* CONFIG_44x */ |
@@ -1189,7 +1218,7 @@ static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port) | |||
1189 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); | 1218 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); |
1190 | } | 1219 | } |
1191 | 1220 | ||
1192 | static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1221 | static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1193 | { | 1222 | { |
1194 | u32 val; | 1223 | u32 val; |
1195 | 1224 | ||
@@ -1338,15 +1367,15 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) | |||
1338 | if (rc != 0) | 1367 | if (rc != 0) |
1339 | return rc; | 1368 | return rc; |
1340 | 1369 | ||
1341 | if (ppc4xx_pciex_hwops->check_link) | ||
1342 | ppc4xx_pciex_hwops->check_link(port); | ||
1343 | |||
1344 | /* | 1370 | /* |
1345 | * Initialize mapping: disable all regions and configure | 1371 | * Initialize mapping: disable all regions and configure |
1346 | * CFG and REG regions based on resources in the device tree | 1372 | * CFG and REG regions based on resources in the device tree |
1347 | */ | 1373 | */ |
1348 | ppc4xx_pciex_port_init_mapping(port); | 1374 | ppc4xx_pciex_port_init_mapping(port); |
1349 | 1375 | ||
1376 | if (ppc4xx_pciex_hwops->check_link) | ||
1377 | ppc4xx_pciex_hwops->check_link(port); | ||
1378 | |||
1350 | /* | 1379 | /* |
1351 | * Map UTL | 1380 | * Map UTL |
1352 | */ | 1381 | */ |
@@ -1360,13 +1389,23 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) | |||
1360 | ppc4xx_pciex_hwops->setup_utl(port); | 1389 | ppc4xx_pciex_hwops->setup_utl(port); |
1361 | 1390 | ||
1362 | /* | 1391 | /* |
1363 | * Check for VC0 active and assert RDY. | 1392 | * Check for VC0 active or PLL Locked and assert RDY. |
1364 | */ | 1393 | */ |
1365 | if (port->sdr_base) { | 1394 | if (port->sdr_base) { |
1366 | if (port->link && | 1395 | if (of_device_is_compatible(port->node, |
1367 | ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, | 1396 | "ibm,plb-pciex-460sx")){ |
1368 | 1 << 16, 1 << 16, 5000)) { | 1397 | if (port->link && ppc4xx_pciex_wait_on_sdr(port, |
1369 | printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index); | 1398 | PESDRn_RCSSTS, |
1399 | 1 << 12, 1 << 12, 5000)) { | ||
1400 | printk(KERN_INFO "PCIE%d: PLL not locked\n", | ||
1401 | port->index); | ||
1402 | port->link = 0; | ||
1403 | } | ||
1404 | } else if (port->link && | ||
1405 | ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, | ||
1406 | 1 << 16, 1 << 16, 5000)) { | ||
1407 | printk(KERN_INFO "PCIE%d: VC0 not active\n", | ||
1408 | port->index); | ||
1370 | port->link = 0; | 1409 | port->link = 0; |
1371 | } | 1410 | } |
1372 | 1411 | ||
@@ -1573,8 +1612,15 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1573 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); | 1612 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); |
1574 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); | 1613 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); |
1575 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); | 1614 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); |
1576 | /* Note that 3 here means enabled | single region */ | 1615 | /*Enabled and single region */ |
1577 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3); | 1616 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) |
1617 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | ||
1618 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT | ||
1619 | | DCRO_PEGPL_OMRxMSKL_VAL); | ||
1620 | else | ||
1621 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | ||
1622 | sa | DCRO_PEGPL_OMR1MSKL_UOT | ||
1623 | | DCRO_PEGPL_OMRxMSKL_VAL); | ||
1578 | break; | 1624 | break; |
1579 | case 1: | 1625 | case 1: |
1580 | out_le32(mbase + PECFG_POM1LAH, pciah); | 1626 | out_le32(mbase + PECFG_POM1LAH, pciah); |
@@ -1582,8 +1628,8 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1582 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); | 1628 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); |
1583 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); | 1629 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); |
1584 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); | 1630 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); |
1585 | /* Note that 3 here means enabled | single region */ | 1631 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, |
1586 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3); | 1632 | sa | DCRO_PEGPL_OMRxMSKL_VAL); |
1587 | break; | 1633 | break; |
1588 | case 2: | 1634 | case 2: |
1589 | out_le32(mbase + PECFG_POM2LAH, pciah); | 1635 | out_le32(mbase + PECFG_POM2LAH, pciah); |
@@ -1592,7 +1638,9 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1592 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); | 1638 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); |
1593 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); | 1639 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); |
1594 | /* Note that 3 here means enabled | IO space !!! */ | 1640 | /* Note that 3 here means enabled | IO space !!! */ |
1595 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3); | 1641 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, |
1642 | sa | DCRO_PEGPL_OMR3MSKL_IO | ||
1643 | | DCRO_PEGPL_OMRxMSKL_VAL); | ||
1596 | break; | 1644 | break; |
1597 | } | 1645 | } |
1598 | 1646 | ||
@@ -1693,6 +1741,9 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, | |||
1693 | if (res->flags & IORESOURCE_PREFETCH) | 1741 | if (res->flags & IORESOURCE_PREFETCH) |
1694 | sa |= 0x8; | 1742 | sa |= 0x8; |
1695 | 1743 | ||
1744 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) | ||
1745 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; | ||
1746 | |||
1696 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); | 1747 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); |
1697 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); | 1748 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); |
1698 | 1749 | ||
@@ -1854,6 +1905,10 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) | |||
1854 | } | 1905 | } |
1855 | out_le16(mbase + 0x202, val); | 1906 | out_le16(mbase + 0x202, val); |
1856 | 1907 | ||
1908 | /* Enable Bus master, memory, and io space */ | ||
1909 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) | ||
1910 | out_le16(mbase + 0x204, 0x7); | ||
1911 | |||
1857 | if (!port->endpoint) { | 1912 | if (!port->endpoint) { |
1858 | /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ | 1913 | /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ |
1859 | out_le32(mbase + 0x208, 0x06040001); | 1914 | out_le32(mbase + 0x208, 0x06040001); |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index c39a134e8684..32ce763a375a 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h | |||
@@ -464,6 +464,18 @@ | |||
464 | #define PECFG_POM2LAL 0x390 | 464 | #define PECFG_POM2LAL 0x390 |
465 | #define PECFG_POM2LAH 0x394 | 465 | #define PECFG_POM2LAH 0x394 |
466 | 466 | ||
467 | /* 460sx only */ | ||
468 | #define PECFG_460SX_DLLSTA 0x3f8 | ||
469 | |||
470 | /* 460sx Bit Mappings */ | ||
471 | #define PECFG_460SX_DLLSTA_LINKUP 0x00000010 | ||
472 | #define DCRO_PEGPL_460SX_OMR1MSKL_UOT 0x00000004 | ||
473 | |||
474 | /* PEGPL Bit Mappings */ | ||
475 | #define DCRO_PEGPL_OMRxMSKL_VAL 0x00000001 | ||
476 | #define DCRO_PEGPL_OMR1MSKL_UOT 0x00000002 | ||
477 | #define DCRO_PEGPL_OMR3MSKL_IO 0x00000002 | ||
478 | |||
467 | /* SDR Bit Mappings */ | 479 | /* SDR Bit Mappings */ |
468 | #define PESDRx_RCSSET_HLDPLB 0x10000000 | 480 | #define PESDRx_RCSSET_HLDPLB 0x10000000 |
469 | #define PESDRx_RCSSET_RSTGU 0x01000000 | 481 | #define PESDRx_RCSSET_RSTGU 0x01000000 |
diff --git a/arch/powerpc/sysdev/xics/Makefile b/arch/powerpc/sysdev/xics/Makefile index b75a6059337f..c606aa8ba60a 100644 --- a/arch/powerpc/sysdev/xics/Makefile +++ b/arch/powerpc/sysdev/xics/Makefile | |||
@@ -4,3 +4,4 @@ obj-y += xics-common.o | |||
4 | obj-$(CONFIG_PPC_ICP_NATIVE) += icp-native.o | 4 | obj-$(CONFIG_PPC_ICP_NATIVE) += icp-native.o |
5 | obj-$(CONFIG_PPC_ICP_HV) += icp-hv.o | 5 | obj-$(CONFIG_PPC_ICP_HV) += icp-hv.o |
6 | obj-$(CONFIG_PPC_ICS_RTAS) += ics-rtas.o | 6 | obj-$(CONFIG_PPC_ICS_RTAS) += ics-rtas.o |
7 | obj-$(CONFIG_PPC_POWERNV) += ics-opal.o | ||
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index 50e32afe392e..4c79b6fbee1c 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c | |||
@@ -276,7 +276,7 @@ static const struct icp_ops icp_native_ops = { | |||
276 | #endif | 276 | #endif |
277 | }; | 277 | }; |
278 | 278 | ||
279 | int icp_native_init(void) | 279 | int __init icp_native_init(void) |
280 | { | 280 | { |
281 | struct device_node *np; | 281 | struct device_node *np; |
282 | u32 indx = 0; | 282 | u32 indx = 0; |
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c new file mode 100644 index 000000000000..f7e8609df0d5 --- /dev/null +++ b/arch/powerpc/sysdev/xics/ics-opal.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * ICS backend for OPAL managed interrupts. | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #undef DEBUG | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/smp.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/cpu.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/msi.h> | ||
24 | |||
25 | #include <asm/prom.h> | ||
26 | #include <asm/smp.h> | ||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/errno.h> | ||
30 | #include <asm/xics.h> | ||
31 | #include <asm/opal.h> | ||
32 | #include <asm/firmware.h> | ||
33 | |||
34 | static int ics_opal_mangle_server(int server) | ||
35 | { | ||
36 | /* No link for now */ | ||
37 | return server << 2; | ||
38 | } | ||
39 | |||
40 | static int ics_opal_unmangle_server(int server) | ||
41 | { | ||
42 | /* No link for now */ | ||
43 | return server >> 2; | ||
44 | } | ||
45 | |||
46 | static void ics_opal_unmask_irq(struct irq_data *d) | ||
47 | { | ||
48 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
49 | int64_t rc; | ||
50 | int server; | ||
51 | |||
52 | pr_devel("ics-hal: unmask virq %d [hw 0x%x]\n", d->irq, hw_irq); | ||
53 | |||
54 | if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) | ||
55 | return; | ||
56 | |||
57 | server = xics_get_irq_server(d->irq, d->affinity, 0); | ||
58 | server = ics_opal_mangle_server(server); | ||
59 | |||
60 | rc = opal_set_xive(hw_irq, server, DEFAULT_PRIORITY); | ||
61 | if (rc != OPAL_SUCCESS) | ||
62 | pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)" | ||
63 | " error %lld\n", | ||
64 | __func__, d->irq, hw_irq, server, rc); | ||
65 | } | ||
66 | |||
67 | static unsigned int ics_opal_startup(struct irq_data *d) | ||
68 | { | ||
69 | #ifdef CONFIG_PCI_MSI | ||
70 | /* | ||
71 | * The generic MSI code returns with the interrupt disabled on the | ||
72 | * card, using the MSI mask bits. Firmware doesn't appear to unmask | ||
73 | * at that level, so we do it here by hand. | ||
74 | */ | ||
75 | if (d->msi_desc) | ||
76 | unmask_msi_irq(d); | ||
77 | #endif | ||
78 | |||
79 | /* unmask it */ | ||
80 | ics_opal_unmask_irq(d); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static void ics_opal_mask_real_irq(unsigned int hw_irq) | ||
85 | { | ||
86 | int server = ics_opal_mangle_server(xics_default_server); | ||
87 | int64_t rc; | ||
88 | |||
89 | if (hw_irq == XICS_IPI) | ||
90 | return; | ||
91 | |||
92 | /* Have to set XIVE to 0xff to be able to remove a slot */ | ||
93 | rc = opal_set_xive(hw_irq, server, 0xff); | ||
94 | if (rc != OPAL_SUCCESS) | ||
95 | pr_err("%s: opal_set_xive(0xff) irq=%u returned %lld\n", | ||
96 | __func__, hw_irq, rc); | ||
97 | } | ||
98 | |||
99 | static void ics_opal_mask_irq(struct irq_data *d) | ||
100 | { | ||
101 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
102 | |||
103 | pr_devel("ics-hal: mask virq %d [hw 0x%x]\n", d->irq, hw_irq); | ||
104 | |||
105 | if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) | ||
106 | return; | ||
107 | ics_opal_mask_real_irq(hw_irq); | ||
108 | } | ||
109 | |||
110 | static int ics_opal_set_affinity(struct irq_data *d, | ||
111 | const struct cpumask *cpumask, | ||
112 | bool force) | ||
113 | { | ||
114 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
115 | int16_t server; | ||
116 | int8_t priority; | ||
117 | int64_t rc; | ||
118 | int wanted_server; | ||
119 | |||
120 | if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) | ||
121 | return -1; | ||
122 | |||
123 | rc = opal_get_xive(hw_irq, &server, &priority); | ||
124 | if (rc != OPAL_SUCCESS) { | ||
125 | pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)" | ||
126 | " error %lld\n", | ||
127 | __func__, d->irq, hw_irq, server, rc); | ||
128 | return -1; | ||
129 | } | ||
130 | |||
131 | wanted_server = xics_get_irq_server(d->irq, cpumask, 1); | ||
132 | if (wanted_server < 0) { | ||
133 | char cpulist[128]; | ||
134 | cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); | ||
135 | pr_warning("%s: No online cpus in the mask %s for irq %d\n", | ||
136 | __func__, cpulist, d->irq); | ||
137 | return -1; | ||
138 | } | ||
139 | server = ics_opal_mangle_server(wanted_server); | ||
140 | |||
141 | pr_devel("ics-hal: set-affinity irq %d [hw 0x%x] server: 0x%x/0x%x\n", | ||
142 | d->irq, hw_irq, wanted_server, server); | ||
143 | |||
144 | rc = opal_set_xive(hw_irq, server, priority); | ||
145 | if (rc != OPAL_SUCCESS) { | ||
146 | pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)" | ||
147 | " error %lld\n", | ||
148 | __func__, d->irq, hw_irq, server, rc); | ||
149 | return -1; | ||
150 | } | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static struct irq_chip ics_opal_irq_chip = { | ||
155 | .name = "OPAL ICS", | ||
156 | .irq_startup = ics_opal_startup, | ||
157 | .irq_mask = ics_opal_mask_irq, | ||
158 | .irq_unmask = ics_opal_unmask_irq, | ||
159 | .irq_eoi = NULL, /* Patched at init time */ | ||
160 | .irq_set_affinity = ics_opal_set_affinity | ||
161 | }; | ||
162 | |||
163 | static int ics_opal_map(struct ics *ics, unsigned int virq); | ||
164 | static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec); | ||
165 | static long ics_opal_get_server(struct ics *ics, unsigned long vec); | ||
166 | |||
167 | static int ics_opal_host_match(struct ics *ics, struct device_node *node) | ||
168 | { | ||
169 | return 1; | ||
170 | } | ||
171 | |||
172 | /* Only one global & state struct ics */ | ||
173 | static struct ics ics_hal = { | ||
174 | .map = ics_opal_map, | ||
175 | .mask_unknown = ics_opal_mask_unknown, | ||
176 | .get_server = ics_opal_get_server, | ||
177 | .host_match = ics_opal_host_match, | ||
178 | }; | ||
179 | |||
180 | static int ics_opal_map(struct ics *ics, unsigned int virq) | ||
181 | { | ||
182 | unsigned int hw_irq = (unsigned int)virq_to_hw(virq); | ||
183 | int64_t rc; | ||
184 | int16_t server; | ||
185 | int8_t priority; | ||
186 | |||
187 | if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)) | ||
188 | return -EINVAL; | ||
189 | |||
190 | /* Check if HAL knows about this interrupt */ | ||
191 | rc = opal_get_xive(hw_irq, &server, &priority); | ||
192 | if (rc != OPAL_SUCCESS) | ||
193 | return -ENXIO; | ||
194 | |||
195 | irq_set_chip_and_handler(virq, &ics_opal_irq_chip, handle_fasteoi_irq); | ||
196 | irq_set_chip_data(virq, &ics_hal); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec) | ||
202 | { | ||
203 | int64_t rc; | ||
204 | int16_t server; | ||
205 | int8_t priority; | ||
206 | |||
207 | /* Check if HAL knows about this interrupt */ | ||
208 | rc = opal_get_xive(vec, &server, &priority); | ||
209 | if (rc != OPAL_SUCCESS) | ||
210 | return; | ||
211 | |||
212 | ics_opal_mask_real_irq(vec); | ||
213 | } | ||
214 | |||
215 | static long ics_opal_get_server(struct ics *ics, unsigned long vec) | ||
216 | { | ||
217 | int64_t rc; | ||
218 | int16_t server; | ||
219 | int8_t priority; | ||
220 | |||
221 | /* Check if HAL knows about this interrupt */ | ||
222 | rc = opal_get_xive(vec, &server, &priority); | ||
223 | if (rc != OPAL_SUCCESS) | ||
224 | return -1; | ||
225 | return ics_opal_unmangle_server(server); | ||
226 | } | ||
227 | |||
228 | int __init ics_opal_init(void) | ||
229 | { | ||
230 | if (!firmware_has_feature(FW_FEATURE_OPAL)) | ||
231 | return -ENODEV; | ||
232 | |||
233 | /* We need to patch our irq chip's EOI to point to the | ||
234 | * right ICP | ||
235 | */ | ||
236 | ics_opal_irq_chip.irq_eoi = icp_ops->eoi; | ||
237 | |||
238 | /* Register ourselves */ | ||
239 | xics_register_ics(&ics_hal); | ||
240 | |||
241 | pr_info("ICS OPAL backend registered\n"); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 445c5a01b766..3d93a8ded0f8 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c | |||
@@ -409,14 +409,10 @@ void __init xics_init(void) | |||
409 | int rc = -1; | 409 | int rc = -1; |
410 | 410 | ||
411 | /* Fist locate ICP */ | 411 | /* Fist locate ICP */ |
412 | #ifdef CONFIG_PPC_ICP_HV | ||
413 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 412 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
414 | rc = icp_hv_init(); | 413 | rc = icp_hv_init(); |
415 | #endif | ||
416 | #ifdef CONFIG_PPC_ICP_NATIVE | ||
417 | if (rc < 0) | 414 | if (rc < 0) |
418 | rc = icp_native_init(); | 415 | rc = icp_native_init(); |
419 | #endif | ||
420 | if (rc < 0) { | 416 | if (rc < 0) { |
421 | pr_warning("XICS: Cannot find a Presentation Controller !\n"); | 417 | pr_warning("XICS: Cannot find a Presentation Controller !\n"); |
422 | return; | 418 | return; |
@@ -429,9 +425,9 @@ void __init xics_init(void) | |||
429 | xics_ipi_chip.irq_eoi = icp_ops->eoi; | 425 | xics_ipi_chip.irq_eoi = icp_ops->eoi; |
430 | 426 | ||
431 | /* Now locate ICS */ | 427 | /* Now locate ICS */ |
432 | #ifdef CONFIG_PPC_ICS_RTAS | ||
433 | rc = ics_rtas_init(); | 428 | rc = ics_rtas_init(); |
434 | #endif | 429 | if (rc < 0) |
430 | rc = ics_opal_init(); | ||
435 | if (rc < 0) | 431 | if (rc < 0) |
436 | pr_warning("XICS: Cannot find a Source Controller !\n"); | 432 | pr_warning("XICS: Cannot find a Source Controller !\n"); |
437 | 433 | ||