diff options
Diffstat (limited to 'arch/powerpc/platforms')
90 files changed, 3258 insertions, 1839 deletions
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index 153022971daa..baae85584b1c 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig | |||
| @@ -100,6 +100,16 @@ config XILINX_VIRTEX_GENERIC_BOARD | |||
| 100 | Most Virtex designs should use this unless it needs to do some | 100 | Most Virtex designs should use this unless it needs to do some |
| 101 | special configuration at board probe time. | 101 | special configuration at board probe time. |
| 102 | 102 | ||
| 103 | config OBS600 | ||
| 104 | bool "OpenBlockS 600" | ||
| 105 | depends on 40x | ||
| 106 | default n | ||
| 107 | select 405EX | ||
| 108 | select PPC40x_SIMPLE | ||
| 109 | help | ||
| 110 | This option enables support for PlatHome OpenBlockS 600 server | ||
| 111 | |||
| 112 | |||
| 103 | config PPC40x_SIMPLE | 113 | config PPC40x_SIMPLE |
| 104 | bool "Simple PowerPC 40x board support" | 114 | bool "Simple PowerPC 40x board support" |
| 105 | depends on 40x | 115 | depends on 40x |
| @@ -186,3 +196,14 @@ config IBM405_ERR51 | |||
| 186 | # bool | 196 | # bool |
| 187 | # depends on !STB03xxx && PPC4xx_DMA | 197 | # depends on !STB03xxx && PPC4xx_DMA |
| 188 | # default y | 198 | # default y |
| 199 | # | ||
| 200 | |||
| 201 | config APM8018X | ||
| 202 | bool "APM8018X" | ||
| 203 | depends on 40x | ||
| 204 | default n | ||
| 205 | select PPC40x_SIMPLE | ||
| 206 | help | ||
| 207 | This option enables support for the AppliedMicro APM8018X evaluation | ||
| 208 | board. | ||
| 209 | |||
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c index e8dd5c5df7d9..97612068fae3 100644 --- a/arch/powerpc/platforms/40x/ppc40x_simple.c +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c | |||
| @@ -55,7 +55,9 @@ static const char *board[] __initdata = { | |||
| 55 | "amcc,haleakala", | 55 | "amcc,haleakala", |
| 56 | "amcc,kilauea", | 56 | "amcc,kilauea", |
| 57 | "amcc,makalu", | 57 | "amcc,makalu", |
| 58 | "est,hotfoot" | 58 | "apm,klondike", |
| 59 | "est,hotfoot", | ||
| 60 | "plathome,obs600" | ||
| 59 | }; | 61 | }; |
| 60 | 62 | ||
| 61 | static int __init ppc40x_probe(void) | 63 | static int __init ppc40x_probe(void) |
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 762322ce24a9..5d5aaf6c91aa 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
| @@ -186,6 +186,16 @@ config ISS4xx | |||
| 186 | help | 186 | help |
| 187 | This option enables support for the IBM ISS simulation environment | 187 | This option enables support for the IBM ISS simulation environment |
| 188 | 188 | ||
| 189 | config CURRITUCK | ||
| 190 | bool "IBM Currituck (476fpe) Support" | ||
| 191 | depends on PPC_47x | ||
| 192 | default n | ||
| 193 | select SWIOTLB | ||
| 194 | select 476FPE | ||
| 195 | select PPC4xx_PCI_EXPRESS | ||
| 196 | help | ||
| 197 | This option enables support for the IBM Currituck (476fpe) evaluation board | ||
| 198 | |||
| 189 | config ICON | 199 | config ICON |
| 190 | bool "Icon" | 200 | bool "Icon" |
| 191 | depends on 44x | 201 | depends on 44x |
| @@ -308,6 +318,10 @@ config 460SX | |||
| 308 | select IBM_EMAC_ZMII | 318 | select IBM_EMAC_ZMII |
| 309 | select IBM_EMAC_TAH | 319 | select IBM_EMAC_TAH |
| 310 | 320 | ||
| 321 | config 476FPE | ||
| 322 | bool | ||
| 323 | select PPC_FPU | ||
| 324 | |||
| 311 | config APM821xx | 325 | config APM821xx |
| 312 | bool | 326 | bool |
| 313 | select PPC_FPU | 327 | select PPC_FPU |
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index 553db6007217..d03833abec09 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile | |||
| @@ -10,3 +10,4 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o | |||
| 10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o | 10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o |
| 11 | obj-$(CONFIG_ISS4xx) += iss4xx.o | 11 | obj-$(CONFIG_ISS4xx) += iss4xx.o |
| 12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o | 12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o |
| 13 | obj-$(CONFIG_CURRITUCK) += currituck.o | ||
diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/currituck.c new file mode 100644 index 000000000000..3f6229b5dee0 --- /dev/null +++ b/arch/powerpc/platforms/44x/currituck.c | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | /* | ||
| 2 | * Currituck board specific routines | ||
| 3 | * | ||
| 4 | * Copyright © 2011 Tony Breeds IBM Corporation | ||
| 5 | * | ||
| 6 | * Based on earlier code: | ||
| 7 | * Matt Porter <mporter@kernel.crashing.org> | ||
| 8 | * Copyright 2002-2005 MontaVista Software Inc. | ||
| 9 | * | ||
| 10 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | ||
| 11 | * Copyright (c) 2003-2005 Zultys Technologies | ||
| 12 | * | ||
| 13 | * Rewritten and ported to the merged powerpc tree: | ||
| 14 | * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation. | ||
| 15 | * Copyright © 2011 David Kliekamp IBM Corporation | ||
| 16 | * | ||
| 17 | * This program is free software; you can redistribute it and/or modify it | ||
| 18 | * under the terms of the GNU General Public License as published by the | ||
| 19 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 20 | * option) any later version. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/memblock.h> | ||
| 25 | #include <linux/of.h> | ||
| 26 | #include <linux/of_platform.h> | ||
| 27 | #include <linux/rtc.h> | ||
| 28 | |||
| 29 | #include <asm/machdep.h> | ||
| 30 | #include <asm/prom.h> | ||
| 31 | #include <asm/udbg.h> | ||
| 32 | #include <asm/time.h> | ||
| 33 | #include <asm/uic.h> | ||
| 34 | #include <asm/ppc4xx.h> | ||
| 35 | #include <asm/mpic.h> | ||
| 36 | #include <asm/mmu.h> | ||
| 37 | |||
| 38 | #include <linux/pci.h> | ||
| 39 | |||
| 40 | static __initdata struct of_device_id ppc47x_of_bus[] = { | ||
| 41 | { .compatible = "ibm,plb4", }, | ||
| 42 | { .compatible = "ibm,plb6", }, | ||
| 43 | { .compatible = "ibm,opb", }, | ||
| 44 | { .compatible = "ibm,ebc", }, | ||
| 45 | {}, | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* The EEPROM is missing and the default values are bogus. This forces USB in | ||
| 49 | * to EHCI mode */ | ||
| 50 | static void __devinit quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) | ||
| 51 | { | ||
| 52 | if (of_machine_is_compatible("ibm,currituck")) { | ||
| 53 | pci_write_config_dword(dev, 0xe0, 0x0114231f); | ||
| 54 | pci_write_config_dword(dev, 0xe4, 0x00006c40); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup); | ||
| 58 | |||
| 59 | static int __init ppc47x_device_probe(void) | ||
| 60 | { | ||
| 61 | of_platform_bus_probe(NULL, ppc47x_of_bus, NULL); | ||
| 62 | |||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | machine_device_initcall(ppc47x, ppc47x_device_probe); | ||
| 66 | |||
| 67 | /* We can have either UICs or MPICs */ | ||
| 68 | static void __init ppc47x_init_irq(void) | ||
| 69 | { | ||
| 70 | struct device_node *np; | ||
| 71 | |||
| 72 | /* Find top level interrupt controller */ | ||
| 73 | for_each_node_with_property(np, "interrupt-controller") { | ||
| 74 | if (of_get_property(np, "interrupts", NULL) == NULL) | ||
| 75 | break; | ||
| 76 | } | ||
| 77 | if (np == NULL) | ||
| 78 | panic("Can't find top level interrupt controller"); | ||
| 79 | |||
| 80 | /* Check type and do appropriate initialization */ | ||
| 81 | if (of_device_is_compatible(np, "chrp,open-pic")) { | ||
| 82 | /* The MPIC driver will get everything it needs from the | ||
| 83 | * device-tree, just pass 0 to all arguments | ||
| 84 | */ | ||
| 85 | struct mpic *mpic = | ||
| 86 | mpic_alloc(np, 0, 0, 0, 0, " MPIC "); | ||
| 87 | BUG_ON(mpic == NULL); | ||
| 88 | mpic_init(mpic); | ||
| 89 | ppc_md.get_irq = mpic_get_irq; | ||
| 90 | } else | ||
| 91 | panic("Unrecognized top level interrupt controller"); | ||
| 92 | } | ||
| 93 | |||
| 94 | #ifdef CONFIG_SMP | ||
| 95 | static void __cpuinit smp_ppc47x_setup_cpu(int cpu) | ||
| 96 | { | ||
| 97 | mpic_setup_this_cpu(); | ||
| 98 | } | ||
| 99 | |||
| 100 | static int __cpuinit smp_ppc47x_kick_cpu(int cpu) | ||
| 101 | { | ||
| 102 | struct device_node *cpunode = of_get_cpu_node(cpu, NULL); | ||
| 103 | const u64 *spin_table_addr_prop; | ||
| 104 | u32 *spin_table; | ||
| 105 | extern void start_secondary_47x(void); | ||
| 106 | |||
| 107 | BUG_ON(cpunode == NULL); | ||
| 108 | |||
| 109 | /* Assume spin table. We could test for the enable-method in | ||
| 110 | * the device-tree but currently there's little point as it's | ||
| 111 | * our only supported method | ||
| 112 | */ | ||
| 113 | spin_table_addr_prop = | ||
| 114 | of_get_property(cpunode, "cpu-release-addr", NULL); | ||
| 115 | |||
| 116 | if (spin_table_addr_prop == NULL) { | ||
| 117 | pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", | ||
| 118 | cpu); | ||
| 119 | return 1; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* Assume it's mapped as part of the linear mapping. This is a bit | ||
| 123 | * fishy but will work fine for now | ||
| 124 | * | ||
| 125 | * XXX: Is there any reason to assume differently? | ||
| 126 | */ | ||
| 127 | spin_table = (u32 *)__va(*spin_table_addr_prop); | ||
| 128 | pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table); | ||
| 129 | |||
| 130 | spin_table[3] = cpu; | ||
| 131 | smp_wmb(); | ||
| 132 | spin_table[1] = __pa(start_secondary_47x); | ||
| 133 | mb(); | ||
| 134 | |||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | |||
| 138 | static struct smp_ops_t ppc47x_smp_ops = { | ||
| 139 | .probe = smp_mpic_probe, | ||
| 140 | .message_pass = smp_mpic_message_pass, | ||
| 141 | .setup_cpu = smp_ppc47x_setup_cpu, | ||
| 142 | .kick_cpu = smp_ppc47x_kick_cpu, | ||
| 143 | .give_timebase = smp_generic_give_timebase, | ||
| 144 | .take_timebase = smp_generic_take_timebase, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static void __init ppc47x_smp_init(void) | ||
| 148 | { | ||
| 149 | if (mmu_has_feature(MMU_FTR_TYPE_47x)) | ||
| 150 | smp_ops = &ppc47x_smp_ops; | ||
| 151 | } | ||
| 152 | |||
| 153 | #else /* CONFIG_SMP */ | ||
| 154 | static void __init ppc47x_smp_init(void) { } | ||
| 155 | #endif /* CONFIG_SMP */ | ||
| 156 | |||
| 157 | static void __init ppc47x_setup_arch(void) | ||
| 158 | { | ||
| 159 | |||
| 160 | /* No need to check the DMA config as we /know/ our windows are all of | ||
| 161 | * RAM. Lets hope that doesn't change */ | ||
| 162 | #ifdef CONFIG_SWIOTLB | ||
| 163 | if (memblock_end_of_DRAM() > 0xffffffff) { | ||
| 164 | ppc_swiotlb_enable = 1; | ||
| 165 | set_pci_dma_ops(&swiotlb_dma_ops); | ||
| 166 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | ||
| 167 | } | ||
| 168 | #endif | ||
| 169 | ppc47x_smp_init(); | ||
| 170 | } | ||
| 171 | |||
| 172 | /* | ||
| 173 | * Called very early, MMU is off, device-tree isn't unflattened | ||
| 174 | */ | ||
| 175 | static int __init ppc47x_probe(void) | ||
| 176 | { | ||
| 177 | unsigned long root = of_get_flat_dt_root(); | ||
| 178 | |||
| 179 | if (!of_flat_dt_is_compatible(root, "ibm,currituck")) | ||
| 180 | return 0; | ||
| 181 | |||
| 182 | return 1; | ||
| 183 | } | ||
| 184 | |||
| 185 | /* Use USB controller should have been hardware swizzled but it wasn't :( */ | ||
| 186 | static void ppc47x_pci_irq_fixup(struct pci_dev *dev) | ||
| 187 | { | ||
| 188 | if (dev->vendor == 0x1033 && (dev->device == 0x0035 || | ||
| 189 | dev->device == 0x00e0)) { | ||
| 190 | dev->irq = irq_create_mapping(NULL, 47); | ||
| 191 | pr_info("%s: Mapping irq 47 %d\n", __func__, dev->irq); | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | define_machine(ppc47x) { | ||
| 196 | .name = "PowerPC 47x", | ||
| 197 | .probe = ppc47x_probe, | ||
| 198 | .progress = udbg_progress, | ||
| 199 | .init_IRQ = ppc47x_init_irq, | ||
| 200 | .setup_arch = ppc47x_setup_arch, | ||
| 201 | .pci_irq_fixup = ppc47x_pci_irq_fixup, | ||
| 202 | .restart = ppc4xx_reset_system, | ||
| 203 | .calibrate_decr = generic_calibrate_decr, | ||
| 204 | }; | ||
diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c index 19395f18b1db..5b8cdbb82f80 100644 --- a/arch/powerpc/platforms/44x/iss4xx.c +++ b/arch/powerpc/platforms/44x/iss4xx.c | |||
| @@ -71,7 +71,7 @@ static void __init iss4xx_init_irq(void) | |||
| 71 | /* The MPIC driver will get everything it needs from the | 71 | /* The MPIC driver will get everything it needs from the |
| 72 | * device-tree, just pass 0 to all arguments | 72 | * device-tree, just pass 0 to all arguments |
| 73 | */ | 73 | */ |
| 74 | struct mpic *mpic = mpic_alloc(np, 0, MPIC_PRIMARY, 0, 0, | 74 | struct mpic *mpic = mpic_alloc(np, 0, 0, 0, 0, |
| 75 | " MPIC "); | 75 | " MPIC "); |
| 76 | BUG_ON(mpic == NULL); | 76 | BUG_ON(mpic == NULL); |
| 77 | mpic_init(mpic); | 77 | mpic_init(mpic); |
diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c index aa0d84d22585..464ea8e0292d 100644 --- a/arch/powerpc/platforms/83xx/asp834x.c +++ b/arch/powerpc/platforms/83xx/asp834x.c | |||
| @@ -36,38 +36,7 @@ static void __init asp834x_setup_arch(void) | |||
| 36 | mpc834x_usb_cfg(); | 36 | mpc834x_usb_cfg(); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static void __init asp834x_init_IRQ(void) | 39 | machine_device_initcall(asp834x, mpc83xx_declare_of_platform_devices); |
| 40 | { | ||
| 41 | struct device_node *np; | ||
| 42 | |||
| 43 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 44 | if (!np) | ||
| 45 | return; | ||
| 46 | |||
| 47 | ipic_init(np, 0); | ||
| 48 | |||
| 49 | of_node_put(np); | ||
| 50 | |||
| 51 | /* Initialize the default interrupt mapping priorities, | ||
| 52 | * in case the boot rom changed something on us. | ||
| 53 | */ | ||
| 54 | ipic_set_default_priority(); | ||
| 55 | } | ||
| 56 | |||
| 57 | static struct __initdata of_device_id asp8347_ids[] = { | ||
| 58 | { .type = "soc", }, | ||
| 59 | { .compatible = "soc", }, | ||
| 60 | { .compatible = "simple-bus", }, | ||
| 61 | { .compatible = "gianfar", }, | ||
| 62 | {}, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static int __init asp8347_declare_of_platform_devices(void) | ||
| 66 | { | ||
| 67 | of_platform_bus_probe(NULL, asp8347_ids, NULL); | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | machine_device_initcall(asp834x, asp8347_declare_of_platform_devices); | ||
| 71 | 40 | ||
| 72 | /* | 41 | /* |
| 73 | * Called very early, MMU is off, device-tree isn't unflattened | 42 | * Called very early, MMU is off, device-tree isn't unflattened |
| @@ -82,7 +51,7 @@ define_machine(asp834x) { | |||
| 82 | .name = "ASP8347E", | 51 | .name = "ASP8347E", |
| 83 | .probe = asp834x_probe, | 52 | .probe = asp834x_probe, |
| 84 | .setup_arch = asp834x_setup_arch, | 53 | .setup_arch = asp834x_setup_arch, |
| 85 | .init_IRQ = asp834x_init_IRQ, | 54 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 86 | .get_irq = ipic_get_irq, | 55 | .get_irq = ipic_get_irq, |
| 87 | .restart = mpc83xx_restart, | 56 | .restart = mpc83xx_restart, |
| 88 | .time_init = mpc83xx_time_init, | 57 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index c55129f5760a..65eb792a0d00 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c | |||
| @@ -51,15 +51,14 @@ | |||
| 51 | */ | 51 | */ |
| 52 | static void __init mpc83xx_km_setup_arch(void) | 52 | static void __init mpc83xx_km_setup_arch(void) |
| 53 | { | 53 | { |
| 54 | #ifdef CONFIG_QUICC_ENGINE | ||
| 54 | struct device_node *np; | 55 | struct device_node *np; |
| 56 | #endif | ||
| 55 | 57 | ||
| 56 | if (ppc_md.progress) | 58 | if (ppc_md.progress) |
| 57 | ppc_md.progress("kmpbec83xx_setup_arch()", 0); | 59 | ppc_md.progress("kmpbec83xx_setup_arch()", 0); |
| 58 | 60 | ||
| 59 | #ifdef CONFIG_PCI | 61 | mpc83xx_setup_pci(); |
| 60 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 61 | mpc83xx_add_bridge(np); | ||
| 62 | #endif | ||
| 63 | 62 | ||
| 64 | #ifdef CONFIG_QUICC_ENGINE | 63 | #ifdef CONFIG_QUICC_ENGINE |
| 65 | qe_reset(); | 64 | qe_reset(); |
| @@ -122,54 +121,7 @@ static void __init mpc83xx_km_setup_arch(void) | |||
| 122 | #endif /* CONFIG_QUICC_ENGINE */ | 121 | #endif /* CONFIG_QUICC_ENGINE */ |
| 123 | } | 122 | } |
| 124 | 123 | ||
| 125 | static struct of_device_id kmpbec83xx_ids[] = { | 124 | machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); |
| 126 | { .type = "soc", }, | ||
| 127 | { .compatible = "soc", }, | ||
| 128 | { .compatible = "simple-bus", }, | ||
| 129 | { .type = "qe", }, | ||
| 130 | { .compatible = "fsl,qe", }, | ||
| 131 | {}, | ||
| 132 | }; | ||
| 133 | |||
| 134 | static int __init kmeter_declare_of_platform_devices(void) | ||
| 135 | { | ||
| 136 | /* Publish the QE devices */ | ||
| 137 | of_platform_bus_probe(NULL, kmpbec83xx_ids, NULL); | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | machine_device_initcall(mpc83xx_km, kmeter_declare_of_platform_devices); | ||
| 142 | |||
| 143 | static void __init mpc83xx_km_init_IRQ(void) | ||
| 144 | { | ||
| 145 | struct device_node *np; | ||
| 146 | |||
| 147 | np = of_find_compatible_node(NULL, NULL, "fsl,pq2pro-pic"); | ||
| 148 | if (!np) { | ||
| 149 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 150 | if (!np) | ||
| 151 | return; | ||
| 152 | } | ||
| 153 | |||
| 154 | ipic_init(np, 0); | ||
| 155 | |||
| 156 | /* Initialize the default interrupt mapping priorities, | ||
| 157 | * in case the boot rom changed something on us. | ||
| 158 | */ | ||
| 159 | ipic_set_default_priority(); | ||
| 160 | of_node_put(np); | ||
| 161 | |||
| 162 | #ifdef CONFIG_QUICC_ENGINE | ||
| 163 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 164 | if (!np) { | ||
| 165 | np = of_find_node_by_type(NULL, "qeic"); | ||
| 166 | if (!np) | ||
| 167 | return; | ||
| 168 | } | ||
| 169 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
| 170 | of_node_put(np); | ||
| 171 | #endif /* CONFIG_QUICC_ENGINE */ | ||
| 172 | } | ||
| 173 | 125 | ||
| 174 | /* list of the supported boards */ | 126 | /* list of the supported boards */ |
| 175 | static char *board[] __initdata = { | 127 | static char *board[] __initdata = { |
| @@ -198,7 +150,7 @@ define_machine(mpc83xx_km) { | |||
| 198 | .name = "mpc83xx-km-platform", | 150 | .name = "mpc83xx-km-platform", |
| 199 | .probe = mpc83xx_km_probe, | 151 | .probe = mpc83xx_km_probe, |
| 200 | .setup_arch = mpc83xx_km_setup_arch, | 152 | .setup_arch = mpc83xx_km_setup_arch, |
| 201 | .init_IRQ = mpc83xx_km_init_IRQ, | 153 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
| 202 | .get_irq = ipic_get_irq, | 154 | .get_irq = ipic_get_irq, |
| 203 | .restart = mpc83xx_restart, | 155 | .restart = mpc83xx_restart, |
| 204 | .time_init = mpc83xx_time_init, | 156 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index f01806c940e1..125336f750c6 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c | |||
| @@ -11,10 +11,15 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/stddef.h> | 12 | #include <linux/stddef.h> |
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/of_platform.h> | ||
| 15 | #include <linux/pci.h> | ||
| 14 | 16 | ||
| 15 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 16 | #include <asm/hw_irq.h> | 18 | #include <asm/hw_irq.h> |
| 19 | #include <asm/ipic.h> | ||
| 20 | #include <asm/qe_ic.h> | ||
| 17 | #include <sysdev/fsl_soc.h> | 21 | #include <sysdev/fsl_soc.h> |
| 22 | #include <sysdev/fsl_pci.h> | ||
| 18 | 23 | ||
| 19 | #include "mpc83xx.h" | 24 | #include "mpc83xx.h" |
| 20 | 25 | ||
| @@ -65,3 +70,75 @@ long __init mpc83xx_time_init(void) | |||
| 65 | 70 | ||
| 66 | return 0; | 71 | return 0; |
| 67 | } | 72 | } |
| 73 | |||
| 74 | void __init mpc83xx_ipic_init_IRQ(void) | ||
| 75 | { | ||
| 76 | struct device_node *np; | ||
| 77 | |||
| 78 | /* looking for fsl,pq2pro-pic which is asl compatible with fsl,ipic */ | ||
| 79 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
| 80 | if (!np) | ||
| 81 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 82 | if (!np) | ||
| 83 | return; | ||
| 84 | |||
| 85 | ipic_init(np, 0); | ||
| 86 | |||
| 87 | of_node_put(np); | ||
| 88 | |||
| 89 | /* Initialize the default interrupt mapping priorities, | ||
| 90 | * in case the boot rom changed something on us. | ||
| 91 | */ | ||
| 92 | ipic_set_default_priority(); | ||
| 93 | } | ||
| 94 | |||
| 95 | #ifdef CONFIG_QUICC_ENGINE | ||
| 96 | void __init mpc83xx_qe_init_IRQ(void) | ||
| 97 | { | ||
| 98 | struct device_node *np; | ||
| 99 | |||
| 100 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 101 | if (!np) { | ||
| 102 | np = of_find_node_by_type(NULL, "qeic"); | ||
| 103 | if (!np) | ||
| 104 | return; | ||
| 105 | } | ||
| 106 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
| 107 | of_node_put(np); | ||
| 108 | } | ||
| 109 | |||
| 110 | void __init mpc83xx_ipic_and_qe_init_IRQ(void) | ||
| 111 | { | ||
| 112 | mpc83xx_ipic_init_IRQ(); | ||
| 113 | mpc83xx_qe_init_IRQ(); | ||
| 114 | } | ||
| 115 | #endif /* CONFIG_QUICC_ENGINE */ | ||
| 116 | |||
| 117 | static struct of_device_id __initdata of_bus_ids[] = { | ||
| 118 | { .type = "soc", }, | ||
| 119 | { .compatible = "soc", }, | ||
| 120 | { .compatible = "simple-bus" }, | ||
| 121 | { .compatible = "gianfar" }, | ||
| 122 | { .compatible = "gpio-leds", }, | ||
| 123 | { .type = "qe", }, | ||
| 124 | { .compatible = "fsl,qe", }, | ||
| 125 | {}, | ||
| 126 | }; | ||
| 127 | |||
| 128 | int __init mpc83xx_declare_of_platform_devices(void) | ||
| 129 | { | ||
| 130 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | #ifdef CONFIG_PCI | ||
| 135 | void __init mpc83xx_setup_pci(void) | ||
| 136 | { | ||
| 137 | struct device_node *np; | ||
| 138 | |||
| 139 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 140 | mpc83xx_add_bridge(np); | ||
| 141 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
| 142 | mpc83xx_add_bridge(np); | ||
| 143 | } | ||
| 144 | #endif | ||
diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c index d0c4e15b7794..4f2d9fea77b7 100644 --- a/arch/powerpc/platforms/83xx/mpc830x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c | |||
| @@ -27,36 +27,13 @@ | |||
| 27 | */ | 27 | */ |
| 28 | static void __init mpc830x_rdb_setup_arch(void) | 28 | static void __init mpc830x_rdb_setup_arch(void) |
| 29 | { | 29 | { |
| 30 | #ifdef CONFIG_PCI | ||
| 31 | struct device_node *np; | ||
| 32 | #endif | ||
| 33 | |||
| 34 | if (ppc_md.progress) | 30 | if (ppc_md.progress) |
| 35 | ppc_md.progress("mpc830x_rdb_setup_arch()", 0); | 31 | ppc_md.progress("mpc830x_rdb_setup_arch()", 0); |
| 36 | 32 | ||
| 37 | #ifdef CONFIG_PCI | 33 | mpc83xx_setup_pci(); |
| 38 | for_each_compatible_node(np, "pci", "fsl,mpc8308-pcie") | ||
| 39 | mpc83xx_add_bridge(np); | ||
| 40 | #endif | ||
| 41 | mpc831x_usb_cfg(); | 34 | mpc831x_usb_cfg(); |
| 42 | } | 35 | } |
| 43 | 36 | ||
| 44 | static void __init mpc830x_rdb_init_IRQ(void) | ||
| 45 | { | ||
| 46 | struct device_node *np; | ||
| 47 | |||
| 48 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 49 | if (!np) | ||
| 50 | return; | ||
| 51 | |||
| 52 | ipic_init(np, 0); | ||
| 53 | |||
| 54 | /* Initialize the default interrupt mapping priorities, | ||
| 55 | * in case the boot rom changed something on us. | ||
| 56 | */ | ||
| 57 | ipic_set_default_priority(); | ||
| 58 | } | ||
| 59 | |||
| 60 | static const char *board[] __initdata = { | 37 | static const char *board[] __initdata = { |
| 61 | "MPC8308RDB", | 38 | "MPC8308RDB", |
| 62 | "fsl,mpc8308rdb", | 39 | "fsl,mpc8308rdb", |
| @@ -72,24 +49,13 @@ static int __init mpc830x_rdb_probe(void) | |||
| 72 | return of_flat_dt_match(of_get_flat_dt_root(), board); | 49 | return of_flat_dt_match(of_get_flat_dt_root(), board); |
| 73 | } | 50 | } |
| 74 | 51 | ||
| 75 | static struct of_device_id __initdata of_bus_ids[] = { | 52 | machine_device_initcall(mpc830x_rdb, mpc83xx_declare_of_platform_devices); |
| 76 | { .compatible = "simple-bus" }, | ||
| 77 | { .compatible = "gianfar" }, | ||
| 78 | {}, | ||
| 79 | }; | ||
| 80 | |||
| 81 | static int __init declare_of_platform_devices(void) | ||
| 82 | { | ||
| 83 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | machine_device_initcall(mpc830x_rdb, declare_of_platform_devices); | ||
| 87 | 53 | ||
| 88 | define_machine(mpc830x_rdb) { | 54 | define_machine(mpc830x_rdb) { |
| 89 | .name = "MPC830x RDB", | 55 | .name = "MPC830x RDB", |
| 90 | .probe = mpc830x_rdb_probe, | 56 | .probe = mpc830x_rdb_probe, |
| 91 | .setup_arch = mpc830x_rdb_setup_arch, | 57 | .setup_arch = mpc830x_rdb_setup_arch, |
| 92 | .init_IRQ = mpc830x_rdb_init_IRQ, | 58 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 93 | .get_irq = ipic_get_irq, | 59 | .get_irq = ipic_get_irq, |
| 94 | .restart = mpc83xx_restart, | 60 | .restart = mpc83xx_restart, |
| 95 | .time_init = mpc83xx_time_init, | 61 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index f859ead49a8d..fa25977c52de 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c | |||
| @@ -28,38 +28,13 @@ | |||
| 28 | */ | 28 | */ |
| 29 | static void __init mpc831x_rdb_setup_arch(void) | 29 | static void __init mpc831x_rdb_setup_arch(void) |
| 30 | { | 30 | { |
| 31 | #ifdef CONFIG_PCI | ||
| 32 | struct device_node *np; | ||
| 33 | #endif | ||
| 34 | |||
| 35 | if (ppc_md.progress) | 31 | if (ppc_md.progress) |
| 36 | ppc_md.progress("mpc831x_rdb_setup_arch()", 0); | 32 | ppc_md.progress("mpc831x_rdb_setup_arch()", 0); |
| 37 | 33 | ||
| 38 | #ifdef CONFIG_PCI | 34 | mpc83xx_setup_pci(); |
| 39 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 40 | mpc83xx_add_bridge(np); | ||
| 41 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
| 42 | mpc83xx_add_bridge(np); | ||
| 43 | #endif | ||
| 44 | mpc831x_usb_cfg(); | 35 | mpc831x_usb_cfg(); |
| 45 | } | 36 | } |
| 46 | 37 | ||
| 47 | static void __init mpc831x_rdb_init_IRQ(void) | ||
| 48 | { | ||
| 49 | struct device_node *np; | ||
| 50 | |||
| 51 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 52 | if (!np) | ||
| 53 | return; | ||
| 54 | |||
| 55 | ipic_init(np, 0); | ||
| 56 | |||
| 57 | /* Initialize the default interrupt mapping priorities, | ||
| 58 | * in case the boot rom changed something on us. | ||
| 59 | */ | ||
| 60 | ipic_set_default_priority(); | ||
| 61 | } | ||
| 62 | |||
| 63 | static const char *board[] __initdata = { | 38 | static const char *board[] __initdata = { |
| 64 | "MPC8313ERDB", | 39 | "MPC8313ERDB", |
| 65 | "fsl,mpc8315erdb", | 40 | "fsl,mpc8315erdb", |
| @@ -74,25 +49,13 @@ static int __init mpc831x_rdb_probe(void) | |||
| 74 | return of_flat_dt_match(of_get_flat_dt_root(), board); | 49 | return of_flat_dt_match(of_get_flat_dt_root(), board); |
| 75 | } | 50 | } |
| 76 | 51 | ||
| 77 | static struct of_device_id __initdata of_bus_ids[] = { | 52 | machine_device_initcall(mpc831x_rdb, mpc83xx_declare_of_platform_devices); |
| 78 | { .compatible = "simple-bus" }, | ||
| 79 | { .compatible = "gianfar" }, | ||
| 80 | { .compatible = "gpio-leds", }, | ||
| 81 | {}, | ||
| 82 | }; | ||
| 83 | |||
| 84 | static int __init declare_of_platform_devices(void) | ||
| 85 | { | ||
| 86 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | machine_device_initcall(mpc831x_rdb, declare_of_platform_devices); | ||
| 90 | 53 | ||
| 91 | define_machine(mpc831x_rdb) { | 54 | define_machine(mpc831x_rdb) { |
| 92 | .name = "MPC831x RDB", | 55 | .name = "MPC831x RDB", |
| 93 | .probe = mpc831x_rdb_probe, | 56 | .probe = mpc831x_rdb_probe, |
| 94 | .setup_arch = mpc831x_rdb_setup_arch, | 57 | .setup_arch = mpc831x_rdb_setup_arch, |
| 95 | .init_IRQ = mpc831x_rdb_init_IRQ, | 58 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 96 | .get_irq = ipic_get_irq, | 59 | .get_irq = ipic_get_irq, |
| 97 | .restart = mpc83xx_restart, | 60 | .restart = mpc83xx_restart, |
| 98 | .time_init = mpc83xx_time_init, | 61 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 32a52896822f..e36bc611dd6e 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c | |||
| @@ -72,10 +72,7 @@ static void __init mpc832x_sys_setup_arch(void) | |||
| 72 | of_node_put(np); | 72 | of_node_put(np); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | #ifdef CONFIG_PCI | 75 | mpc83xx_setup_pci(); |
| 76 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 77 | mpc83xx_add_bridge(np); | ||
| 78 | #endif | ||
| 79 | 76 | ||
| 80 | #ifdef CONFIG_QUICC_ENGINE | 77 | #ifdef CONFIG_QUICC_ENGINE |
| 81 | qe_reset(); | 78 | qe_reset(); |
| @@ -101,51 +98,7 @@ static void __init mpc832x_sys_setup_arch(void) | |||
| 101 | #endif /* CONFIG_QUICC_ENGINE */ | 98 | #endif /* CONFIG_QUICC_ENGINE */ |
| 102 | } | 99 | } |
| 103 | 100 | ||
| 104 | static struct of_device_id mpc832x_ids[] = { | 101 | machine_device_initcall(mpc832x_mds, mpc83xx_declare_of_platform_devices); |
| 105 | { .type = "soc", }, | ||
| 106 | { .compatible = "soc", }, | ||
| 107 | { .compatible = "simple-bus", }, | ||
| 108 | { .type = "qe", }, | ||
| 109 | { .compatible = "fsl,qe", }, | ||
| 110 | {}, | ||
| 111 | }; | ||
| 112 | |||
| 113 | static int __init mpc832x_declare_of_platform_devices(void) | ||
| 114 | { | ||
| 115 | /* Publish the QE devices */ | ||
| 116 | of_platform_bus_probe(NULL, mpc832x_ids, NULL); | ||
| 117 | |||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | machine_device_initcall(mpc832x_mds, mpc832x_declare_of_platform_devices); | ||
| 121 | |||
| 122 | static void __init mpc832x_sys_init_IRQ(void) | ||
| 123 | { | ||
| 124 | struct device_node *np; | ||
| 125 | |||
| 126 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 127 | if (!np) | ||
| 128 | return; | ||
| 129 | |||
| 130 | ipic_init(np, 0); | ||
| 131 | |||
| 132 | /* Initialize the default interrupt mapping priorities, | ||
| 133 | * in case the boot rom changed something on us. | ||
| 134 | */ | ||
| 135 | ipic_set_default_priority(); | ||
| 136 | of_node_put(np); | ||
| 137 | |||
| 138 | #ifdef CONFIG_QUICC_ENGINE | ||
| 139 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 140 | if (!np) { | ||
| 141 | np = of_find_node_by_type(NULL, "qeic"); | ||
| 142 | if (!np) | ||
| 143 | return; | ||
| 144 | } | ||
| 145 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
| 146 | of_node_put(np); | ||
| 147 | #endif /* CONFIG_QUICC_ENGINE */ | ||
| 148 | } | ||
| 149 | 102 | ||
| 150 | /* | 103 | /* |
| 151 | * Called very early, MMU is off, device-tree isn't unflattened | 104 | * Called very early, MMU is off, device-tree isn't unflattened |
| @@ -161,7 +114,7 @@ define_machine(mpc832x_mds) { | |||
| 161 | .name = "MPC832x MDS", | 114 | .name = "MPC832x MDS", |
| 162 | .probe = mpc832x_sys_probe, | 115 | .probe = mpc832x_sys_probe, |
| 163 | .setup_arch = mpc832x_sys_setup_arch, | 116 | .setup_arch = mpc832x_sys_setup_arch, |
| 164 | .init_IRQ = mpc832x_sys_init_IRQ, | 117 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
| 165 | .get_irq = ipic_get_irq, | 118 | .get_irq = ipic_get_irq, |
| 166 | .restart = mpc83xx_restart, | 119 | .restart = mpc83xx_restart, |
| 167 | .time_init = mpc83xx_time_init, | 120 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 17f99745f0e4..eff5baabc3fb 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c | |||
| @@ -193,17 +193,14 @@ machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); | |||
| 193 | */ | 193 | */ |
| 194 | static void __init mpc832x_rdb_setup_arch(void) | 194 | static void __init mpc832x_rdb_setup_arch(void) |
| 195 | { | 195 | { |
| 196 | #if defined(CONFIG_PCI) || defined(CONFIG_QUICC_ENGINE) | 196 | #if defined(CONFIG_QUICC_ENGINE) |
| 197 | struct device_node *np; | 197 | struct device_node *np; |
| 198 | #endif | 198 | #endif |
| 199 | 199 | ||
| 200 | if (ppc_md.progress) | 200 | if (ppc_md.progress) |
| 201 | ppc_md.progress("mpc832x_rdb_setup_arch()", 0); | 201 | ppc_md.progress("mpc832x_rdb_setup_arch()", 0); |
| 202 | 202 | ||
| 203 | #ifdef CONFIG_PCI | 203 | mpc83xx_setup_pci(); |
| 204 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 205 | mpc83xx_add_bridge(np); | ||
| 206 | #endif | ||
| 207 | 204 | ||
| 208 | #ifdef CONFIG_QUICC_ENGINE | 205 | #ifdef CONFIG_QUICC_ENGINE |
| 209 | qe_reset(); | 206 | qe_reset(); |
| @@ -218,52 +215,7 @@ static void __init mpc832x_rdb_setup_arch(void) | |||
| 218 | #endif /* CONFIG_QUICC_ENGINE */ | 215 | #endif /* CONFIG_QUICC_ENGINE */ |
| 219 | } | 216 | } |
| 220 | 217 | ||
| 221 | static struct of_device_id mpc832x_ids[] = { | 218 | machine_device_initcall(mpc832x_rdb, mpc83xx_declare_of_platform_devices); |
| 222 | { .type = "soc", }, | ||
| 223 | { .compatible = "soc", }, | ||
| 224 | { .compatible = "simple-bus", }, | ||
| 225 | { .type = "qe", }, | ||
| 226 | { .compatible = "fsl,qe", }, | ||
| 227 | {}, | ||
| 228 | }; | ||
| 229 | |||
| 230 | static int __init mpc832x_declare_of_platform_devices(void) | ||
| 231 | { | ||
| 232 | /* Publish the QE devices */ | ||
| 233 | of_platform_bus_probe(NULL, mpc832x_ids, NULL); | ||
| 234 | |||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices); | ||
| 238 | |||
| 239 | static void __init mpc832x_rdb_init_IRQ(void) | ||
| 240 | { | ||
| 241 | |||
| 242 | struct device_node *np; | ||
| 243 | |||
| 244 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 245 | if (!np) | ||
| 246 | return; | ||
| 247 | |||
| 248 | ipic_init(np, 0); | ||
| 249 | |||
| 250 | /* Initialize the default interrupt mapping priorities, | ||
| 251 | * in case the boot rom changed something on us. | ||
| 252 | */ | ||
| 253 | ipic_set_default_priority(); | ||
| 254 | of_node_put(np); | ||
| 255 | |||
| 256 | #ifdef CONFIG_QUICC_ENGINE | ||
| 257 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 258 | if (!np) { | ||
| 259 | np = of_find_node_by_type(NULL, "qeic"); | ||
| 260 | if (!np) | ||
| 261 | return; | ||
| 262 | } | ||
| 263 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
| 264 | of_node_put(np); | ||
| 265 | #endif /* CONFIG_QUICC_ENGINE */ | ||
| 266 | } | ||
| 267 | 219 | ||
| 268 | /* | 220 | /* |
| 269 | * Called very early, MMU is off, device-tree isn't unflattened | 221 | * Called very early, MMU is off, device-tree isn't unflattened |
| @@ -279,7 +231,7 @@ define_machine(mpc832x_rdb) { | |||
| 279 | .name = "MPC832x RDB", | 231 | .name = "MPC832x RDB", |
| 280 | .probe = mpc832x_rdb_probe, | 232 | .probe = mpc832x_rdb_probe, |
| 281 | .setup_arch = mpc832x_rdb_setup_arch, | 233 | .setup_arch = mpc832x_rdb_setup_arch, |
| 282 | .init_IRQ = mpc832x_rdb_init_IRQ, | 234 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
| 283 | .get_irq = ipic_get_irq, | 235 | .get_irq = ipic_get_irq, |
| 284 | .restart = mpc83xx_restart, | 236 | .restart = mpc83xx_restart, |
| 285 | .time_init = mpc83xx_time_init, | 237 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 6b45969567d4..39849dd1b5bb 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c | |||
| @@ -41,13 +41,12 @@ | |||
| 41 | 41 | ||
| 42 | static struct of_device_id __initdata mpc834x_itx_ids[] = { | 42 | static struct of_device_id __initdata mpc834x_itx_ids[] = { |
| 43 | { .compatible = "fsl,pq2pro-localbus", }, | 43 | { .compatible = "fsl,pq2pro-localbus", }, |
| 44 | { .compatible = "simple-bus", }, | ||
| 45 | { .compatible = "gianfar", }, | ||
| 46 | {}, | 44 | {}, |
| 47 | }; | 45 | }; |
| 48 | 46 | ||
| 49 | static int __init mpc834x_itx_declare_of_platform_devices(void) | 47 | static int __init mpc834x_itx_declare_of_platform_devices(void) |
| 50 | { | 48 | { |
| 49 | mpc83xx_declare_of_platform_devices(); | ||
| 51 | return of_platform_bus_probe(NULL, mpc834x_itx_ids, NULL); | 50 | return of_platform_bus_probe(NULL, mpc834x_itx_ids, NULL); |
| 52 | } | 51 | } |
| 53 | machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); | 52 | machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); |
| @@ -59,37 +58,14 @@ machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); | |||
| 59 | */ | 58 | */ |
| 60 | static void __init mpc834x_itx_setup_arch(void) | 59 | static void __init mpc834x_itx_setup_arch(void) |
| 61 | { | 60 | { |
| 62 | #ifdef CONFIG_PCI | ||
| 63 | struct device_node *np; | ||
| 64 | #endif | ||
| 65 | |||
| 66 | if (ppc_md.progress) | 61 | if (ppc_md.progress) |
| 67 | ppc_md.progress("mpc834x_itx_setup_arch()", 0); | 62 | ppc_md.progress("mpc834x_itx_setup_arch()", 0); |
| 68 | 63 | ||
| 69 | #ifdef CONFIG_PCI | 64 | mpc83xx_setup_pci(); |
| 70 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 71 | mpc83xx_add_bridge(np); | ||
| 72 | #endif | ||
| 73 | 65 | ||
| 74 | mpc834x_usb_cfg(); | 66 | mpc834x_usb_cfg(); |
| 75 | } | 67 | } |
| 76 | 68 | ||
| 77 | static void __init mpc834x_itx_init_IRQ(void) | ||
| 78 | { | ||
| 79 | struct device_node *np; | ||
| 80 | |||
| 81 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 82 | if (!np) | ||
| 83 | return; | ||
| 84 | |||
| 85 | ipic_init(np, 0); | ||
| 86 | |||
| 87 | /* Initialize the default interrupt mapping priorities, | ||
| 88 | * in case the boot rom changed something on us. | ||
| 89 | */ | ||
| 90 | ipic_set_default_priority(); | ||
| 91 | } | ||
| 92 | |||
| 93 | /* | 69 | /* |
| 94 | * Called very early, MMU is off, device-tree isn't unflattened | 70 | * Called very early, MMU is off, device-tree isn't unflattened |
| 95 | */ | 71 | */ |
| @@ -104,7 +80,7 @@ define_machine(mpc834x_itx) { | |||
| 104 | .name = "MPC834x ITX", | 80 | .name = "MPC834x ITX", |
| 105 | .probe = mpc834x_itx_probe, | 81 | .probe = mpc834x_itx_probe, |
| 106 | .setup_arch = mpc834x_itx_setup_arch, | 82 | .setup_arch = mpc834x_itx_setup_arch, |
| 107 | .init_IRQ = mpc834x_itx_init_IRQ, | 83 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 108 | .get_irq = ipic_get_irq, | 84 | .get_irq = ipic_get_irq, |
| 109 | .restart = mpc83xx_restart, | 85 | .restart = mpc83xx_restart, |
| 110 | .time_init = mpc83xx_time_init, | 86 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index 041c5177e737..5828d8e97c37 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c | |||
| @@ -77,51 +77,15 @@ static int mpc834xemds_usb_cfg(void) | |||
| 77 | */ | 77 | */ |
| 78 | static void __init mpc834x_mds_setup_arch(void) | 78 | static void __init mpc834x_mds_setup_arch(void) |
| 79 | { | 79 | { |
| 80 | #ifdef CONFIG_PCI | ||
| 81 | struct device_node *np; | ||
| 82 | #endif | ||
| 83 | |||
| 84 | if (ppc_md.progress) | 80 | if (ppc_md.progress) |
| 85 | ppc_md.progress("mpc834x_mds_setup_arch()", 0); | 81 | ppc_md.progress("mpc834x_mds_setup_arch()", 0); |
| 86 | 82 | ||
| 87 | #ifdef CONFIG_PCI | 83 | mpc83xx_setup_pci(); |
| 88 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 89 | mpc83xx_add_bridge(np); | ||
| 90 | #endif | ||
| 91 | 84 | ||
| 92 | mpc834xemds_usb_cfg(); | 85 | mpc834xemds_usb_cfg(); |
| 93 | } | 86 | } |
| 94 | 87 | ||
| 95 | static void __init mpc834x_mds_init_IRQ(void) | 88 | machine_device_initcall(mpc834x_mds, mpc83xx_declare_of_platform_devices); |
| 96 | { | ||
| 97 | struct device_node *np; | ||
| 98 | |||
| 99 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 100 | if (!np) | ||
| 101 | return; | ||
| 102 | |||
| 103 | ipic_init(np, 0); | ||
| 104 | |||
| 105 | /* Initialize the default interrupt mapping priorities, | ||
| 106 | * in case the boot rom changed something on us. | ||
| 107 | */ | ||
| 108 | ipic_set_default_priority(); | ||
| 109 | } | ||
| 110 | |||
| 111 | static struct of_device_id mpc834x_ids[] = { | ||
| 112 | { .type = "soc", }, | ||
| 113 | { .compatible = "soc", }, | ||
| 114 | { .compatible = "simple-bus", }, | ||
| 115 | { .compatible = "gianfar", }, | ||
| 116 | {}, | ||
| 117 | }; | ||
| 118 | |||
| 119 | static int __init mpc834x_declare_of_platform_devices(void) | ||
| 120 | { | ||
| 121 | of_platform_bus_probe(NULL, mpc834x_ids, NULL); | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | machine_device_initcall(mpc834x_mds, mpc834x_declare_of_platform_devices); | ||
| 125 | 89 | ||
| 126 | /* | 90 | /* |
| 127 | * Called very early, MMU is off, device-tree isn't unflattened | 91 | * Called very early, MMU is off, device-tree isn't unflattened |
| @@ -137,7 +101,7 @@ define_machine(mpc834x_mds) { | |||
| 137 | .name = "MPC834x MDS", | 101 | .name = "MPC834x MDS", |
| 138 | .probe = mpc834x_mds_probe, | 102 | .probe = mpc834x_mds_probe, |
| 139 | .setup_arch = mpc834x_mds_setup_arch, | 103 | .setup_arch = mpc834x_mds_setup_arch, |
| 140 | .init_IRQ = mpc834x_mds_init_IRQ, | 104 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 141 | .get_irq = ipic_get_irq, | 105 | .get_irq = ipic_get_irq, |
| 142 | .restart = mpc83xx_restart, | 106 | .restart = mpc83xx_restart, |
| 143 | .time_init = mpc83xx_time_init, | 107 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 934cc8c46bbc..ad8e4bcd7d55 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c | |||
| @@ -80,10 +80,7 @@ static void __init mpc836x_mds_setup_arch(void) | |||
| 80 | of_node_put(np); | 80 | of_node_put(np); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | #ifdef CONFIG_PCI | 83 | mpc83xx_setup_pci(); |
| 84 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 85 | mpc83xx_add_bridge(np); | ||
| 86 | #endif | ||
| 87 | 84 | ||
| 88 | #ifdef CONFIG_QUICC_ENGINE | 85 | #ifdef CONFIG_QUICC_ENGINE |
| 89 | qe_reset(); | 86 | qe_reset(); |
| @@ -144,23 +141,7 @@ static void __init mpc836x_mds_setup_arch(void) | |||
| 144 | #endif /* CONFIG_QUICC_ENGINE */ | 141 | #endif /* CONFIG_QUICC_ENGINE */ |
| 145 | } | 142 | } |
| 146 | 143 | ||
| 147 | static struct of_device_id mpc836x_ids[] = { | 144 | machine_device_initcall(mpc836x_mds, mpc83xx_declare_of_platform_devices); |
| 148 | { .type = "soc", }, | ||
| 149 | { .compatible = "soc", }, | ||
| 150 | { .compatible = "simple-bus", }, | ||
| 151 | { .type = "qe", }, | ||
| 152 | { .compatible = "fsl,qe", }, | ||
| 153 | {}, | ||
| 154 | }; | ||
| 155 | |||
| 156 | static int __init mpc836x_declare_of_platform_devices(void) | ||
| 157 | { | ||
| 158 | /* Publish the QE devices */ | ||
| 159 | of_platform_bus_probe(NULL, mpc836x_ids, NULL); | ||
| 160 | |||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | machine_device_initcall(mpc836x_mds, mpc836x_declare_of_platform_devices); | ||
| 164 | 145 | ||
| 165 | #ifdef CONFIG_QE_USB | 146 | #ifdef CONFIG_QE_USB |
| 166 | static int __init mpc836x_usb_cfg(void) | 147 | static int __init mpc836x_usb_cfg(void) |
| @@ -226,34 +207,6 @@ err: | |||
| 226 | machine_arch_initcall(mpc836x_mds, mpc836x_usb_cfg); | 207 | machine_arch_initcall(mpc836x_mds, mpc836x_usb_cfg); |
| 227 | #endif /* CONFIG_QE_USB */ | 208 | #endif /* CONFIG_QE_USB */ |
| 228 | 209 | ||
| 229 | static void __init mpc836x_mds_init_IRQ(void) | ||
| 230 | { | ||
| 231 | struct device_node *np; | ||
| 232 | |||
| 233 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 234 | if (!np) | ||
| 235 | return; | ||
| 236 | |||
| 237 | ipic_init(np, 0); | ||
| 238 | |||
| 239 | /* Initialize the default interrupt mapping priorities, | ||
| 240 | * in case the boot rom changed something on us. | ||
| 241 | */ | ||
| 242 | ipic_set_default_priority(); | ||
| 243 | of_node_put(np); | ||
| 244 | |||
| 245 | #ifdef CONFIG_QUICC_ENGINE | ||
| 246 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 247 | if (!np) { | ||
| 248 | np = of_find_node_by_type(NULL, "qeic"); | ||
| 249 | if (!np) | ||
| 250 | return; | ||
| 251 | } | ||
| 252 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
| 253 | of_node_put(np); | ||
| 254 | #endif /* CONFIG_QUICC_ENGINE */ | ||
| 255 | } | ||
| 256 | |||
| 257 | /* | 210 | /* |
| 258 | * Called very early, MMU is off, device-tree isn't unflattened | 211 | * Called very early, MMU is off, device-tree isn't unflattened |
| 259 | */ | 212 | */ |
| @@ -268,7 +221,7 @@ define_machine(mpc836x_mds) { | |||
| 268 | .name = "MPC836x MDS", | 221 | .name = "MPC836x MDS", |
| 269 | .probe = mpc836x_mds_probe, | 222 | .probe = mpc836x_mds_probe, |
| 270 | .setup_arch = mpc836x_mds_setup_arch, | 223 | .setup_arch = mpc836x_mds_setup_arch, |
| 271 | .init_IRQ = mpc836x_mds_init_IRQ, | 224 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
| 272 | .get_irq = ipic_get_irq, | 225 | .get_irq = ipic_get_irq, |
| 273 | .restart = mpc83xx_restart, | 226 | .restart = mpc83xx_restart, |
| 274 | .time_init = mpc83xx_time_init, | 227 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c index b0090aac9642..f8769d713d61 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c | |||
| @@ -27,61 +27,19 @@ | |||
| 27 | 27 | ||
| 28 | #include "mpc83xx.h" | 28 | #include "mpc83xx.h" |
| 29 | 29 | ||
| 30 | static struct of_device_id __initdata mpc836x_rdk_ids[] = { | 30 | machine_device_initcall(mpc836x_rdk, mpc83xx_declare_of_platform_devices); |
| 31 | { .compatible = "simple-bus", }, | ||
| 32 | {}, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static int __init mpc836x_rdk_declare_of_platform_devices(void) | ||
| 36 | { | ||
| 37 | return of_platform_bus_probe(NULL, mpc836x_rdk_ids, NULL); | ||
| 38 | } | ||
| 39 | machine_device_initcall(mpc836x_rdk, mpc836x_rdk_declare_of_platform_devices); | ||
| 40 | 31 | ||
| 41 | static void __init mpc836x_rdk_setup_arch(void) | 32 | static void __init mpc836x_rdk_setup_arch(void) |
| 42 | { | 33 | { |
| 43 | #ifdef CONFIG_PCI | ||
| 44 | struct device_node *np; | ||
| 45 | #endif | ||
| 46 | |||
| 47 | if (ppc_md.progress) | 34 | if (ppc_md.progress) |
| 48 | ppc_md.progress("mpc836x_rdk_setup_arch()", 0); | 35 | ppc_md.progress("mpc836x_rdk_setup_arch()", 0); |
| 49 | 36 | ||
| 50 | #ifdef CONFIG_PCI | 37 | mpc83xx_setup_pci(); |
| 51 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 52 | mpc83xx_add_bridge(np); | ||
| 53 | #endif | ||
| 54 | #ifdef CONFIG_QUICC_ENGINE | 38 | #ifdef CONFIG_QUICC_ENGINE |
| 55 | qe_reset(); | 39 | qe_reset(); |
| 56 | #endif | 40 | #endif |
| 57 | } | 41 | } |
| 58 | 42 | ||
| 59 | static void __init mpc836x_rdk_init_IRQ(void) | ||
| 60 | { | ||
| 61 | struct device_node *np; | ||
| 62 | |||
| 63 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
| 64 | if (!np) | ||
| 65 | return; | ||
| 66 | |||
| 67 | ipic_init(np, 0); | ||
| 68 | |||
| 69 | /* | ||
| 70 | * Initialize the default interrupt mapping priorities, | ||
| 71 | * in case the boot rom changed something on us. | ||
| 72 | */ | ||
| 73 | ipic_set_default_priority(); | ||
| 74 | of_node_put(np); | ||
| 75 | #ifdef CONFIG_QUICC_ENGINE | ||
| 76 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 77 | if (!np) | ||
| 78 | return; | ||
| 79 | |||
| 80 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
| 81 | of_node_put(np); | ||
| 82 | #endif | ||
| 83 | } | ||
| 84 | |||
| 85 | /* | 43 | /* |
| 86 | * Called very early, MMU is off, device-tree isn't unflattened. | 44 | * Called very early, MMU is off, device-tree isn't unflattened. |
| 87 | */ | 45 | */ |
| @@ -96,7 +54,7 @@ define_machine(mpc836x_rdk) { | |||
| 96 | .name = "MPC836x RDK", | 54 | .name = "MPC836x RDK", |
| 97 | .probe = mpc836x_rdk_probe, | 55 | .probe = mpc836x_rdk_probe, |
| 98 | .setup_arch = mpc836x_rdk_setup_arch, | 56 | .setup_arch = mpc836x_rdk_setup_arch, |
| 99 | .init_IRQ = mpc836x_rdk_init_IRQ, | 57 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
| 100 | .get_irq = ipic_get_irq, | 58 | .get_irq = ipic_get_irq, |
| 101 | .restart = mpc83xx_restart, | 59 | .restart = mpc83xx_restart, |
| 102 | .time_init = mpc83xx_time_init, | 60 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 83068322abd1..e53a60b6c863 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c | |||
| @@ -79,54 +79,14 @@ out: | |||
| 79 | */ | 79 | */ |
| 80 | static void __init mpc837x_mds_setup_arch(void) | 80 | static void __init mpc837x_mds_setup_arch(void) |
| 81 | { | 81 | { |
| 82 | #ifdef CONFIG_PCI | ||
| 83 | struct device_node *np; | ||
| 84 | #endif | ||
| 85 | |||
| 86 | if (ppc_md.progress) | 82 | if (ppc_md.progress) |
| 87 | ppc_md.progress("mpc837x_mds_setup_arch()", 0); | 83 | ppc_md.progress("mpc837x_mds_setup_arch()", 0); |
| 88 | 84 | ||
| 89 | #ifdef CONFIG_PCI | 85 | mpc83xx_setup_pci(); |
| 90 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 91 | mpc83xx_add_bridge(np); | ||
| 92 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
| 93 | mpc83xx_add_bridge(np); | ||
| 94 | #endif | ||
| 95 | mpc837xmds_usb_cfg(); | 86 | mpc837xmds_usb_cfg(); |
| 96 | } | 87 | } |
| 97 | 88 | ||
| 98 | static struct of_device_id mpc837x_ids[] = { | 89 | machine_device_initcall(mpc837x_mds, mpc83xx_declare_of_platform_devices); |
| 99 | { .type = "soc", }, | ||
| 100 | { .compatible = "soc", }, | ||
| 101 | { .compatible = "simple-bus", }, | ||
| 102 | { .compatible = "gianfar", }, | ||
| 103 | {}, | ||
| 104 | }; | ||
| 105 | |||
| 106 | static int __init mpc837x_declare_of_platform_devices(void) | ||
| 107 | { | ||
| 108 | /* Publish platform_device */ | ||
| 109 | of_platform_bus_probe(NULL, mpc837x_ids, NULL); | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | machine_device_initcall(mpc837x_mds, mpc837x_declare_of_platform_devices); | ||
| 114 | |||
| 115 | static void __init mpc837x_mds_init_IRQ(void) | ||
| 116 | { | ||
| 117 | struct device_node *np; | ||
| 118 | |||
| 119 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
| 120 | if (!np) | ||
| 121 | return; | ||
| 122 | |||
| 123 | ipic_init(np, 0); | ||
| 124 | |||
| 125 | /* Initialize the default interrupt mapping priorities, | ||
| 126 | * in case the boot rom changed something on us. | ||
| 127 | */ | ||
| 128 | ipic_set_default_priority(); | ||
| 129 | } | ||
| 130 | 90 | ||
| 131 | /* | 91 | /* |
| 132 | * Called very early, MMU is off, device-tree isn't unflattened | 92 | * Called very early, MMU is off, device-tree isn't unflattened |
| @@ -142,7 +102,7 @@ define_machine(mpc837x_mds) { | |||
| 142 | .name = "MPC837x MDS", | 102 | .name = "MPC837x MDS", |
| 143 | .probe = mpc837x_mds_probe, | 103 | .probe = mpc837x_mds_probe, |
| 144 | .setup_arch = mpc837x_mds_setup_arch, | 104 | .setup_arch = mpc837x_mds_setup_arch, |
| 145 | .init_IRQ = mpc837x_mds_init_IRQ, | 105 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 146 | .get_irq = ipic_get_irq, | 106 | .get_irq = ipic_get_irq, |
| 147 | .restart = mpc83xx_restart, | 107 | .restart = mpc83xx_restart, |
| 148 | .time_init = mpc83xx_time_init, | 108 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 7bafbf2ec0f9..16c9c9cbbb7f 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c | |||
| @@ -50,56 +50,15 @@ static void mpc837x_rdb_sd_cfg(void) | |||
| 50 | */ | 50 | */ |
| 51 | static void __init mpc837x_rdb_setup_arch(void) | 51 | static void __init mpc837x_rdb_setup_arch(void) |
| 52 | { | 52 | { |
| 53 | #ifdef CONFIG_PCI | ||
| 54 | struct device_node *np; | ||
| 55 | #endif | ||
| 56 | |||
| 57 | if (ppc_md.progress) | 53 | if (ppc_md.progress) |
| 58 | ppc_md.progress("mpc837x_rdb_setup_arch()", 0); | 54 | ppc_md.progress("mpc837x_rdb_setup_arch()", 0); |
| 59 | 55 | ||
| 60 | #ifdef CONFIG_PCI | 56 | mpc83xx_setup_pci(); |
| 61 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 62 | mpc83xx_add_bridge(np); | ||
| 63 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
| 64 | mpc83xx_add_bridge(np); | ||
| 65 | #endif | ||
| 66 | mpc837x_usb_cfg(); | 57 | mpc837x_usb_cfg(); |
| 67 | mpc837x_rdb_sd_cfg(); | 58 | mpc837x_rdb_sd_cfg(); |
| 68 | } | 59 | } |
| 69 | 60 | ||
| 70 | static struct of_device_id mpc837x_ids[] = { | 61 | machine_device_initcall(mpc837x_rdb, mpc83xx_declare_of_platform_devices); |
| 71 | { .type = "soc", }, | ||
| 72 | { .compatible = "soc", }, | ||
| 73 | { .compatible = "simple-bus", }, | ||
| 74 | { .compatible = "gianfar", }, | ||
| 75 | { .compatible = "gpio-leds", }, | ||
| 76 | {}, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static int __init mpc837x_declare_of_platform_devices(void) | ||
| 80 | { | ||
| 81 | /* Publish platform_device */ | ||
| 82 | of_platform_bus_probe(NULL, mpc837x_ids, NULL); | ||
| 83 | |||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | machine_device_initcall(mpc837x_rdb, mpc837x_declare_of_platform_devices); | ||
| 87 | |||
| 88 | static void __init mpc837x_rdb_init_IRQ(void) | ||
| 89 | { | ||
| 90 | struct device_node *np; | ||
| 91 | |||
| 92 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
| 93 | if (!np) | ||
| 94 | return; | ||
| 95 | |||
| 96 | ipic_init(np, 0); | ||
| 97 | |||
| 98 | /* Initialize the default interrupt mapping priorities, | ||
| 99 | * in case the boot rom changed something on us. | ||
| 100 | */ | ||
| 101 | ipic_set_default_priority(); | ||
| 102 | } | ||
| 103 | 62 | ||
| 104 | static const char *board[] __initdata = { | 63 | static const char *board[] __initdata = { |
| 105 | "fsl,mpc8377rdb", | 64 | "fsl,mpc8377rdb", |
| @@ -121,7 +80,7 @@ define_machine(mpc837x_rdb) { | |||
| 121 | .name = "MPC837x RDB/WLAN", | 80 | .name = "MPC837x RDB/WLAN", |
| 122 | .probe = mpc837x_rdb_probe, | 81 | .probe = mpc837x_rdb_probe, |
| 123 | .setup_arch = mpc837x_rdb_setup_arch, | 82 | .setup_arch = mpc837x_rdb_setup_arch, |
| 124 | .init_IRQ = mpc837x_rdb_init_IRQ, | 83 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 125 | .get_irq = ipic_get_irq, | 84 | .get_irq = ipic_get_irq, |
| 126 | .restart = mpc83xx_restart, | 85 | .restart = mpc83xx_restart, |
| 127 | .time_init = mpc83xx_time_init, | 86 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index 82a434510d83..0cf74d7ea1c5 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h | |||
| @@ -70,5 +70,21 @@ extern long mpc83xx_time_init(void); | |||
| 70 | extern int mpc837x_usb_cfg(void); | 70 | extern int mpc837x_usb_cfg(void); |
| 71 | extern int mpc834x_usb_cfg(void); | 71 | extern int mpc834x_usb_cfg(void); |
| 72 | extern int mpc831x_usb_cfg(void); | 72 | extern int mpc831x_usb_cfg(void); |
| 73 | extern void mpc83xx_ipic_init_IRQ(void); | ||
| 74 | #ifdef CONFIG_QUICC_ENGINE | ||
| 75 | extern void mpc83xx_qe_init_IRQ(void); | ||
| 76 | extern void mpc83xx_ipic_and_qe_init_IRQ(void); | ||
| 77 | #else | ||
| 78 | static inline void __init mpc83xx_qe_init_IRQ(void) {} | ||
| 79 | #define mpc83xx_ipic_and_qe_init_IRQ mpc83xx_ipic_init_IRQ | ||
| 80 | #endif /* CONFIG_QUICC_ENGINE */ | ||
| 81 | |||
| 82 | #ifdef CONFIG_PCI | ||
| 83 | extern void mpc83xx_setup_pci(void); | ||
| 84 | #else | ||
| 85 | #define mpc83xx_setup_pci() do {} while (0) | ||
| 86 | #endif | ||
| 87 | |||
| 88 | extern int mpc83xx_declare_of_platform_devices(void); | ||
| 73 | 89 | ||
| 74 | #endif /* __MPC83XX_H__ */ | 90 | #endif /* __MPC83XX_H__ */ |
diff --git a/arch/powerpc/platforms/83xx/sbc834x.c b/arch/powerpc/platforms/83xx/sbc834x.c index af41d8c810a8..8a81d7640b1f 100644 --- a/arch/powerpc/platforms/83xx/sbc834x.c +++ b/arch/powerpc/platforms/83xx/sbc834x.c | |||
| @@ -48,52 +48,13 @@ | |||
| 48 | */ | 48 | */ |
| 49 | static void __init sbc834x_setup_arch(void) | 49 | static void __init sbc834x_setup_arch(void) |
| 50 | { | 50 | { |
| 51 | #ifdef CONFIG_PCI | ||
| 52 | struct device_node *np; | ||
| 53 | #endif | ||
| 54 | |||
| 55 | if (ppc_md.progress) | 51 | if (ppc_md.progress) |
| 56 | ppc_md.progress("sbc834x_setup_arch()", 0); | 52 | ppc_md.progress("sbc834x_setup_arch()", 0); |
| 57 | 53 | ||
| 58 | #ifdef CONFIG_PCI | 54 | mpc83xx_setup_pci(); |
| 59 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
| 60 | mpc83xx_add_bridge(np); | ||
| 61 | #endif | ||
| 62 | |||
| 63 | } | 55 | } |
| 64 | 56 | ||
| 65 | static void __init sbc834x_init_IRQ(void) | 57 | machine_device_initcall(sbc834x, mpc83xx_declare_of_platform_devices); |
| 66 | { | ||
| 67 | struct device_node *np; | ||
| 68 | |||
| 69 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 70 | if (!np) | ||
| 71 | return; | ||
| 72 | |||
| 73 | ipic_init(np, 0); | ||
| 74 | |||
| 75 | /* Initialize the default interrupt mapping priorities, | ||
| 76 | * in case the boot rom changed something on us. | ||
| 77 | */ | ||
| 78 | ipic_set_default_priority(); | ||
| 79 | |||
| 80 | of_node_put(np); | ||
| 81 | } | ||
| 82 | |||
| 83 | static struct __initdata of_device_id sbc834x_ids[] = { | ||
| 84 | { .type = "soc", }, | ||
| 85 | { .compatible = "soc", }, | ||
| 86 | { .compatible = "simple-bus", }, | ||
| 87 | { .compatible = "gianfar", }, | ||
| 88 | {}, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static int __init sbc834x_declare_of_platform_devices(void) | ||
| 92 | { | ||
| 93 | of_platform_bus_probe(NULL, sbc834x_ids, NULL); | ||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | machine_device_initcall(sbc834x, sbc834x_declare_of_platform_devices); | ||
| 97 | 58 | ||
| 98 | /* | 59 | /* |
| 99 | * Called very early, MMU is off, device-tree isn't unflattened | 60 | * Called very early, MMU is off, device-tree isn't unflattened |
| @@ -102,14 +63,14 @@ static int __init sbc834x_probe(void) | |||
| 102 | { | 63 | { |
| 103 | unsigned long root = of_get_flat_dt_root(); | 64 | unsigned long root = of_get_flat_dt_root(); |
| 104 | 65 | ||
| 105 | return of_flat_dt_is_compatible(root, "SBC834x"); | 66 | return of_flat_dt_is_compatible(root, "SBC834xE"); |
| 106 | } | 67 | } |
| 107 | 68 | ||
| 108 | define_machine(sbc834x) { | 69 | define_machine(sbc834x) { |
| 109 | .name = "SBC834x", | 70 | .name = "SBC834xE", |
| 110 | .probe = sbc834x_probe, | 71 | .probe = sbc834x_probe, |
| 111 | .setup_arch = sbc834x_setup_arch, | 72 | .setup_arch = sbc834x_setup_arch, |
| 112 | .init_IRQ = sbc834x_init_IRQ, | 73 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
| 113 | .get_irq = ipic_get_irq, | 74 | .get_irq = ipic_get_irq, |
| 114 | .restart = mpc83xx_restart, | 75 | .restart = mpc83xx_restart, |
| 115 | .time_init = mpc83xx_time_init, | 76 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index bc5acb95917a..9cb2d4320dcc 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | # | 3 | # |
| 4 | obj-$(CONFIG_SMP) += smp.o | 4 | obj-$(CONFIG_SMP) += smp.o |
| 5 | 5 | ||
| 6 | obj-y += common.o | ||
| 7 | |||
| 6 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o | 8 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o |
| 7 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o | 9 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o |
| 8 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o | 10 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o |
diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c new file mode 100644 index 000000000000..9fef5302adc1 --- /dev/null +++ b/arch/powerpc/platforms/85xx/common.c | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /* | ||
| 2 | * Routines common to most mpc85xx-based boards. | ||
| 3 | * | ||
| 4 | * This is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | #include <linux/of_platform.h> | ||
| 9 | |||
| 10 | #include <sysdev/cpm2_pic.h> | ||
| 11 | |||
| 12 | #include "mpc85xx.h" | ||
| 13 | |||
| 14 | static struct of_device_id __initdata mpc85xx_common_ids[] = { | ||
| 15 | { .type = "soc", }, | ||
| 16 | { .compatible = "soc", }, | ||
| 17 | { .compatible = "simple-bus", }, | ||
| 18 | { .name = "cpm", }, | ||
| 19 | { .name = "localbus", }, | ||
| 20 | { .compatible = "gianfar", }, | ||
| 21 | { .compatible = "fsl,qe", }, | ||
| 22 | { .compatible = "fsl,cpm2", }, | ||
| 23 | { .compatible = "fsl,srio", }, | ||
| 24 | {}, | ||
| 25 | }; | ||
| 26 | |||
| 27 | int __init mpc85xx_common_publish_devices(void) | ||
| 28 | { | ||
| 29 | return of_platform_bus_probe(NULL, mpc85xx_common_ids, NULL); | ||
| 30 | } | ||
| 31 | #ifdef CONFIG_CPM2 | ||
| 32 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 33 | { | ||
| 34 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 35 | int cascade_irq; | ||
| 36 | |||
| 37 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
| 38 | generic_handle_irq(cascade_irq); | ||
| 39 | |||
| 40 | chip->irq_eoi(&desc->irq_data); | ||
| 41 | } | ||
| 42 | |||
| 43 | |||
| 44 | void __init mpc85xx_cpm2_pic_init(void) | ||
| 45 | { | ||
| 46 | struct device_node *np; | ||
| 47 | int irq; | ||
| 48 | |||
| 49 | /* Setup CPM2 PIC */ | ||
| 50 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
| 51 | if (np == NULL) { | ||
| 52 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
| 53 | return; | ||
| 54 | } | ||
| 55 | irq = irq_of_parse_and_map(np, 0); | ||
| 56 | if (irq == NO_IRQ) { | ||
| 57 | of_node_put(np); | ||
| 58 | printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n"); | ||
| 59 | return; | ||
| 60 | } | ||
| 61 | |||
| 62 | cpm2_pic_init(np); | ||
| 63 | of_node_put(np); | ||
| 64 | irq_set_chained_handler(irq, cpm2_cascade); | ||
| 65 | } | ||
| 66 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c index 802ad110b757..07e3e6c47371 100644 --- a/arch/powerpc/platforms/85xx/corenet_ds.c +++ b/arch/powerpc/platforms/85xx/corenet_ds.c | |||
| @@ -31,32 +31,18 @@ | |||
| 31 | #include <linux/of_platform.h> | 31 | #include <linux/of_platform.h> |
| 32 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
| 33 | #include <sysdev/fsl_pci.h> | 33 | #include <sysdev/fsl_pci.h> |
| 34 | #include "smp.h" | ||
| 34 | 35 | ||
| 35 | void __init corenet_ds_pic_init(void) | 36 | void __init corenet_ds_pic_init(void) |
| 36 | { | 37 | { |
| 37 | struct mpic *mpic; | 38 | struct mpic *mpic; |
| 38 | struct resource r; | 39 | unsigned int flags = MPIC_BIG_ENDIAN | |
| 39 | struct device_node *np = NULL; | ||
| 40 | unsigned int flags = MPIC_PRIMARY | MPIC_BIG_ENDIAN | | ||
| 41 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU; | 40 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU; |
| 42 | 41 | ||
| 43 | np = of_find_node_by_type(np, "open-pic"); | ||
| 44 | |||
| 45 | if (np == NULL) { | ||
| 46 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (of_address_to_resource(np, 0, &r)) { | ||
| 51 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 52 | of_node_put(np); | ||
| 53 | return; | ||
| 54 | } | ||
| 55 | |||
| 56 | if (ppc_md.get_irq == mpic_get_coreint_irq) | 42 | if (ppc_md.get_irq == mpic_get_coreint_irq) |
| 57 | flags |= MPIC_ENABLE_COREINT; | 43 | flags |= MPIC_ENABLE_COREINT; |
| 58 | 44 | ||
| 59 | mpic = mpic_alloc(np, r.start, flags, 0, 256, " OpenPIC "); | 45 | mpic = mpic_alloc(NULL, 0, flags, 0, 256, " OpenPIC "); |
| 60 | BUG_ON(mpic == NULL); | 46 | BUG_ON(mpic == NULL); |
| 61 | 47 | ||
| 62 | mpic_init(mpic); | 48 | mpic_init(mpic); |
| @@ -65,10 +51,6 @@ void __init corenet_ds_pic_init(void) | |||
| 65 | /* | 51 | /* |
| 66 | * Setup the architecture | 52 | * Setup the architecture |
| 67 | */ | 53 | */ |
| 68 | #ifdef CONFIG_SMP | ||
| 69 | void __init mpc85xx_smp_init(void); | ||
| 70 | #endif | ||
| 71 | |||
| 72 | void __init corenet_ds_setup_arch(void) | 54 | void __init corenet_ds_setup_arch(void) |
| 73 | { | 55 | { |
| 74 | #ifdef CONFIG_PCI | 56 | #ifdef CONFIG_PCI |
| @@ -77,9 +59,7 @@ void __init corenet_ds_setup_arch(void) | |||
| 77 | #endif | 59 | #endif |
| 78 | dma_addr_t max = 0xffffffff; | 60 | dma_addr_t max = 0xffffffff; |
| 79 | 61 | ||
| 80 | #ifdef CONFIG_SMP | ||
| 81 | mpc85xx_smp_init(); | 62 | mpc85xx_smp_init(); |
| 82 | #endif | ||
| 83 | 63 | ||
| 84 | #ifdef CONFIG_PCI | 64 | #ifdef CONFIG_PCI |
| 85 | for_each_node_by_type(np, "pci") { | 65 | for_each_node_by_type(np, "pci") { |
| @@ -112,7 +92,7 @@ static const struct of_device_id of_device_ids[] __devinitconst = { | |||
| 112 | .compatible = "simple-bus" | 92 | .compatible = "simple-bus" |
| 113 | }, | 93 | }, |
| 114 | { | 94 | { |
| 115 | .compatible = "fsl,rapidio-delta", | 95 | .compatible = "fsl,srio", |
| 116 | }, | 96 | }, |
| 117 | { | 97 | { |
| 118 | .compatible = "fsl,p4080-pcie", | 98 | .compatible = "fsl,p4080-pcie", |
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index c46f9359be15..20f75d7819c6 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <asm/cpm2.h> | 35 | #include <asm/cpm2.h> |
| 36 | #include <sysdev/cpm2_pic.h> | 36 | #include <sysdev/cpm2_pic.h> |
| 37 | 37 | ||
| 38 | #include "mpc85xx.h" | ||
| 38 | 39 | ||
| 39 | #define KSI8560_CPLD_HVR 0x04 /* Hardware Version Register */ | 40 | #define KSI8560_CPLD_HVR 0x04 /* Hardware Version Register */ |
| 40 | #define KSI8560_CPLD_PVR 0x08 /* PLD Version Register */ | 41 | #define KSI8560_CPLD_PVR 0x08 /* PLD Version Register */ |
| @@ -54,60 +55,15 @@ static void machine_restart(char *cmd) | |||
| 54 | for (;;); | 55 | for (;;); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 58 | { | ||
| 59 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 60 | int cascade_irq; | ||
| 61 | |||
| 62 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
| 63 | generic_handle_irq(cascade_irq); | ||
| 64 | |||
| 65 | chip->irq_eoi(&desc->irq_data); | ||
| 66 | } | ||
| 67 | |||
| 68 | static void __init ksi8560_pic_init(void) | 58 | static void __init ksi8560_pic_init(void) |
| 69 | { | 59 | { |
| 70 | struct mpic *mpic; | 60 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 71 | struct resource r; | 61 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 72 | struct device_node *np; | ||
| 73 | #ifdef CONFIG_CPM2 | ||
| 74 | int irq; | ||
| 75 | #endif | ||
| 76 | |||
| 77 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 78 | |||
| 79 | if (np == NULL) { | ||
| 80 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 81 | return; | ||
| 82 | } | ||
| 83 | |||
| 84 | if (of_address_to_resource(np, 0, &r)) { | ||
| 85 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
| 86 | of_node_put(np); | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | |||
| 90 | mpic = mpic_alloc(np, r.start, | ||
| 91 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 92 | 0, 256, " OpenPIC "); | 62 | 0, 256, " OpenPIC "); |
| 93 | BUG_ON(mpic == NULL); | 63 | BUG_ON(mpic == NULL); |
| 94 | of_node_put(np); | ||
| 95 | |||
| 96 | mpic_init(mpic); | 64 | mpic_init(mpic); |
| 97 | 65 | ||
| 98 | #ifdef CONFIG_CPM2 | 66 | mpc85xx_cpm2_pic_init(); |
| 99 | /* Setup CPM2 PIC */ | ||
| 100 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
| 101 | if (np == NULL) { | ||
| 102 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
| 103 | return; | ||
| 104 | } | ||
| 105 | irq = irq_of_parse_and_map(np, 0); | ||
| 106 | |||
| 107 | cpm2_pic_init(np); | ||
| 108 | of_node_put(np); | ||
| 109 | irq_set_chained_handler(irq, cpm2_cascade); | ||
| 110 | #endif | ||
| 111 | } | 67 | } |
| 112 | 68 | ||
| 113 | #ifdef CONFIG_CPM2 | 69 | #ifdef CONFIG_CPM2 |
| @@ -215,22 +171,7 @@ static void ksi8560_show_cpuinfo(struct seq_file *m) | |||
| 215 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 171 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
| 216 | } | 172 | } |
| 217 | 173 | ||
| 218 | static struct of_device_id __initdata of_bus_ids[] = { | 174 | machine_device_initcall(ksi8560, mpc85xx_common_publish_devices); |
| 219 | { .type = "soc", }, | ||
| 220 | { .type = "simple-bus", }, | ||
| 221 | { .name = "cpm", }, | ||
| 222 | { .name = "localbus", }, | ||
| 223 | { .compatible = "gianfar", }, | ||
| 224 | {}, | ||
| 225 | }; | ||
| 226 | |||
| 227 | static int __init declare_of_platform_devices(void) | ||
| 228 | { | ||
| 229 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | machine_device_initcall(ksi8560, declare_of_platform_devices); | ||
| 234 | 175 | ||
| 235 | /* | 176 | /* |
| 236 | * Called very early, device-tree isn't unflattened | 177 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index f79f2f102141..cf266826682e 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c | |||
| @@ -32,31 +32,15 @@ | |||
| 32 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
| 33 | #include <sysdev/fsl_pci.h> | 33 | #include <sysdev/fsl_pci.h> |
| 34 | 34 | ||
| 35 | #include "mpc85xx.h" | ||
| 36 | |||
| 35 | void __init mpc8536_ds_pic_init(void) | 37 | void __init mpc8536_ds_pic_init(void) |
| 36 | { | 38 | { |
| 37 | struct mpic *mpic; | 39 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 38 | struct resource r; | 40 | MPIC_WANTS_RESET | |
| 39 | struct device_node *np; | ||
| 40 | |||
| 41 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 42 | if (np == NULL) { | ||
| 43 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 44 | return; | ||
| 45 | } | ||
| 46 | |||
| 47 | if (of_address_to_resource(np, 0, &r)) { | ||
| 48 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 49 | of_node_put(np); | ||
| 50 | return; | ||
| 51 | } | ||
| 52 | |||
| 53 | mpic = mpic_alloc(np, r.start, | ||
| 54 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
| 55 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, | 41 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, |
| 56 | 0, 256, " OpenPIC "); | 42 | 0, 256, " OpenPIC "); |
| 57 | BUG_ON(mpic == NULL); | 43 | BUG_ON(mpic == NULL); |
| 58 | of_node_put(np); | ||
| 59 | |||
| 60 | mpic_init(mpic); | 44 | mpic_init(mpic); |
| 61 | } | 45 | } |
| 62 | 46 | ||
| @@ -104,19 +88,7 @@ static void __init mpc8536_ds_setup_arch(void) | |||
| 104 | printk("MPC8536 DS board from Freescale Semiconductor\n"); | 88 | printk("MPC8536 DS board from Freescale Semiconductor\n"); |
| 105 | } | 89 | } |
| 106 | 90 | ||
| 107 | static struct of_device_id __initdata mpc8536_ds_ids[] = { | 91 | machine_device_initcall(mpc8536_ds, mpc85xx_common_publish_devices); |
| 108 | { .type = "soc", }, | ||
| 109 | { .compatible = "soc", }, | ||
| 110 | { .compatible = "simple-bus", }, | ||
| 111 | { .compatible = "gianfar", }, | ||
| 112 | {}, | ||
| 113 | }; | ||
| 114 | |||
| 115 | static int __init mpc8536_ds_publish_devices(void) | ||
| 116 | { | ||
| 117 | return of_platform_bus_probe(NULL, mpc8536_ds_ids, NULL); | ||
| 118 | } | ||
| 119 | machine_device_initcall(mpc8536_ds, mpc8536_ds_publish_devices); | ||
| 120 | 92 | ||
| 121 | machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier); | 93 | machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier); |
| 122 | 94 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h new file mode 100644 index 000000000000..2aa7c5dc2c7f --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx.h | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | #ifndef MPC85xx_H | ||
| 2 | #define MPC85xx_H | ||
| 3 | extern int mpc85xx_common_publish_devices(void); | ||
| 4 | |||
| 5 | #ifdef CONFIG_CPM2 | ||
| 6 | extern void mpc85xx_cpm2_pic_init(void); | ||
| 7 | #else | ||
| 8 | static inline void __init mpc85xx_cpm2_pic_init(void) {} | ||
| 9 | #endif /* CONFIG_CPM2 */ | ||
| 10 | |||
| 11 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 3b2c9bb66199..3bebb5173bfc 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c | |||
| @@ -35,6 +35,8 @@ | |||
| 35 | #include <sysdev/cpm2_pic.h> | 35 | #include <sysdev/cpm2_pic.h> |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | #include "mpc85xx.h" | ||
| 39 | |||
| 38 | #ifdef CONFIG_PCI | 40 | #ifdef CONFIG_PCI |
| 39 | static int mpc85xx_exclude_device(struct pci_controller *hose, | 41 | static int mpc85xx_exclude_device(struct pci_controller *hose, |
| 40 | u_char bus, u_char devfn) | 42 | u_char bus, u_char devfn) |
| @@ -46,63 +48,15 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, | |||
| 46 | } | 48 | } |
| 47 | #endif /* CONFIG_PCI */ | 49 | #endif /* CONFIG_PCI */ |
| 48 | 50 | ||
| 49 | #ifdef CONFIG_CPM2 | ||
| 50 | |||
| 51 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 52 | { | ||
| 53 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 54 | int cascade_irq; | ||
| 55 | |||
| 56 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
| 57 | generic_handle_irq(cascade_irq); | ||
| 58 | |||
| 59 | chip->irq_eoi(&desc->irq_data); | ||
| 60 | } | ||
| 61 | |||
| 62 | #endif /* CONFIG_CPM2 */ | ||
| 63 | |||
| 64 | static void __init mpc85xx_ads_pic_init(void) | 51 | static void __init mpc85xx_ads_pic_init(void) |
| 65 | { | 52 | { |
| 66 | struct mpic *mpic; | 53 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 67 | struct resource r; | 54 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 68 | struct device_node *np = NULL; | ||
| 69 | #ifdef CONFIG_CPM2 | ||
| 70 | int irq; | ||
| 71 | #endif | ||
| 72 | |||
| 73 | np = of_find_node_by_type(np, "open-pic"); | ||
| 74 | if (!np) { | ||
| 75 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 76 | return; | ||
| 77 | } | ||
| 78 | |||
| 79 | if (of_address_to_resource(np, 0, &r)) { | ||
| 80 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
| 81 | of_node_put(np); | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | |||
| 85 | mpic = mpic_alloc(np, r.start, | ||
| 86 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 87 | 0, 256, " OpenPIC "); | 55 | 0, 256, " OpenPIC "); |
| 88 | BUG_ON(mpic == NULL); | 56 | BUG_ON(mpic == NULL); |
| 89 | of_node_put(np); | ||
| 90 | |||
| 91 | mpic_init(mpic); | 57 | mpic_init(mpic); |
| 92 | 58 | ||
| 93 | #ifdef CONFIG_CPM2 | 59 | mpc85xx_cpm2_pic_init(); |
| 94 | /* Setup CPM2 PIC */ | ||
| 95 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
| 96 | if (np == NULL) { | ||
| 97 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
| 98 | return; | ||
| 99 | } | ||
| 100 | irq = irq_of_parse_and_map(np, 0); | ||
| 101 | |||
| 102 | cpm2_pic_init(np); | ||
| 103 | of_node_put(np); | ||
| 104 | irq_set_chained_handler(irq, cpm2_cascade); | ||
| 105 | #endif | ||
| 106 | } | 60 | } |
| 107 | 61 | ||
| 108 | /* | 62 | /* |
| @@ -221,23 +175,7 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) | |||
| 221 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 175 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
| 222 | } | 176 | } |
| 223 | 177 | ||
| 224 | static struct of_device_id __initdata of_bus_ids[] = { | 178 | machine_device_initcall(mpc85xx_ads, mpc85xx_common_publish_devices); |
| 225 | { .name = "soc", }, | ||
| 226 | { .type = "soc", }, | ||
| 227 | { .name = "cpm", }, | ||
| 228 | { .name = "localbus", }, | ||
| 229 | { .compatible = "simple-bus", }, | ||
| 230 | { .compatible = "gianfar", }, | ||
| 231 | {}, | ||
| 232 | }; | ||
| 233 | |||
| 234 | static int __init declare_of_platform_devices(void) | ||
| 235 | { | ||
| 236 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 237 | |||
| 238 | return 0; | ||
| 239 | } | ||
| 240 | machine_device_initcall(mpc85xx_ads, declare_of_platform_devices); | ||
| 241 | 179 | ||
| 242 | /* | 180 | /* |
| 243 | * Called very early, device-tree isn't unflattened | 181 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 66cb8d64079f..40f03da616a9 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
| @@ -46,6 +46,8 @@ | |||
| 46 | #include <sysdev/fsl_soc.h> | 46 | #include <sysdev/fsl_soc.h> |
| 47 | #include <sysdev/fsl_pci.h> | 47 | #include <sysdev/fsl_pci.h> |
| 48 | 48 | ||
| 49 | #include "mpc85xx.h" | ||
| 50 | |||
| 49 | /* CADMUS info */ | 51 | /* CADMUS info */ |
| 50 | /* xxx - galak, move into device tree */ | 52 | /* xxx - galak, move into device tree */ |
| 51 | #define CADMUS_BASE (0xf8004000) | 53 | #define CADMUS_BASE (0xf8004000) |
| @@ -177,7 +179,7 @@ static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id) | |||
| 177 | 179 | ||
| 178 | static struct irqaction mpc85xxcds_8259_irqaction = { | 180 | static struct irqaction mpc85xxcds_8259_irqaction = { |
| 179 | .handler = mpc85xx_8259_cascade_action, | 181 | .handler = mpc85xx_8259_cascade_action, |
| 180 | .flags = IRQF_SHARED, | 182 | .flags = IRQF_SHARED | IRQF_NO_THREAD, |
| 181 | .name = "8259 cascade", | 183 | .name = "8259 cascade", |
| 182 | }; | 184 | }; |
| 183 | #endif /* PPC_I8259 */ | 185 | #endif /* PPC_I8259 */ |
| @@ -186,30 +188,10 @@ static struct irqaction mpc85xxcds_8259_irqaction = { | |||
| 186 | static void __init mpc85xx_cds_pic_init(void) | 188 | static void __init mpc85xx_cds_pic_init(void) |
| 187 | { | 189 | { |
| 188 | struct mpic *mpic; | 190 | struct mpic *mpic; |
| 189 | struct resource r; | 191 | mpic = mpic_alloc(NULL, 0, |
| 190 | struct device_node *np = NULL; | 192 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 191 | |||
| 192 | np = of_find_node_by_type(np, "open-pic"); | ||
| 193 | |||
| 194 | if (np == NULL) { | ||
| 195 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 196 | return; | ||
| 197 | } | ||
| 198 | |||
| 199 | if (of_address_to_resource(np, 0, &r)) { | ||
| 200 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 201 | of_node_put(np); | ||
| 202 | return; | ||
| 203 | } | ||
| 204 | |||
| 205 | mpic = mpic_alloc(np, r.start, | ||
| 206 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 207 | 0, 256, " OpenPIC "); | 193 | 0, 256, " OpenPIC "); |
| 208 | BUG_ON(mpic == NULL); | 194 | BUG_ON(mpic == NULL); |
| 209 | |||
| 210 | /* Return the mpic node */ | ||
| 211 | of_node_put(np); | ||
| 212 | |||
| 213 | mpic_init(mpic); | 195 | mpic_init(mpic); |
| 214 | } | 196 | } |
| 215 | 197 | ||
| @@ -330,19 +312,7 @@ static int __init mpc85xx_cds_probe(void) | |||
| 330 | return of_flat_dt_is_compatible(root, "MPC85xxCDS"); | 312 | return of_flat_dt_is_compatible(root, "MPC85xxCDS"); |
| 331 | } | 313 | } |
| 332 | 314 | ||
| 333 | static struct of_device_id __initdata of_bus_ids[] = { | 315 | machine_device_initcall(mpc85xx_cds, mpc85xx_common_publish_devices); |
| 334 | { .type = "soc", }, | ||
| 335 | { .compatible = "soc", }, | ||
| 336 | { .compatible = "simple-bus", }, | ||
| 337 | { .compatible = "gianfar", }, | ||
| 338 | {}, | ||
| 339 | }; | ||
| 340 | |||
| 341 | static int __init declare_of_platform_devices(void) | ||
| 342 | { | ||
| 343 | return of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 344 | } | ||
| 345 | machine_device_initcall(mpc85xx_cds, declare_of_platform_devices); | ||
| 346 | 316 | ||
| 347 | define_machine(mpc85xx_cds) { | 317 | define_machine(mpc85xx_cds) { |
| 348 | .name = "MPC85xx CDS", | 318 | .name = "MPC85xx CDS", |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 1b9a8cf1873a..eefbb91e1d61 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c | |||
| @@ -35,6 +35,9 @@ | |||
| 35 | 35 | ||
| 36 | #include <sysdev/fsl_soc.h> | 36 | #include <sysdev/fsl_soc.h> |
| 37 | #include <sysdev/fsl_pci.h> | 37 | #include <sysdev/fsl_pci.h> |
| 38 | #include "smp.h" | ||
| 39 | |||
| 40 | #include "mpc85xx.h" | ||
| 38 | 41 | ||
| 39 | #undef DEBUG | 42 | #undef DEBUG |
| 40 | 43 | ||
| @@ -60,43 +63,27 @@ static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc) | |||
| 60 | void __init mpc85xx_ds_pic_init(void) | 63 | void __init mpc85xx_ds_pic_init(void) |
| 61 | { | 64 | { |
| 62 | struct mpic *mpic; | 65 | struct mpic *mpic; |
| 63 | struct resource r; | ||
| 64 | struct device_node *np; | ||
| 65 | #ifdef CONFIG_PPC_I8259 | 66 | #ifdef CONFIG_PPC_I8259 |
| 67 | struct device_node *np; | ||
| 66 | struct device_node *cascade_node = NULL; | 68 | struct device_node *cascade_node = NULL; |
| 67 | int cascade_irq; | 69 | int cascade_irq; |
| 68 | #endif | 70 | #endif |
| 69 | unsigned long root = of_get_flat_dt_root(); | 71 | unsigned long root = of_get_flat_dt_root(); |
| 70 | 72 | ||
| 71 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 72 | if (np == NULL) { | ||
| 73 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 74 | return; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (of_address_to_resource(np, 0, &r)) { | ||
| 78 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 79 | of_node_put(np); | ||
| 80 | return; | ||
| 81 | } | ||
| 82 | |||
| 83 | if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) { | 73 | if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) { |
| 84 | mpic = mpic_alloc(np, r.start, | 74 | mpic = mpic_alloc(NULL, 0, |
| 85 | MPIC_PRIMARY | | ||
| 86 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 75 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
| 87 | MPIC_SINGLE_DEST_CPU, | 76 | MPIC_SINGLE_DEST_CPU, |
| 88 | 0, 256, " OpenPIC "); | 77 | 0, 256, " OpenPIC "); |
| 89 | } else { | 78 | } else { |
| 90 | mpic = mpic_alloc(np, r.start, | 79 | mpic = mpic_alloc(NULL, 0, |
| 91 | MPIC_PRIMARY | MPIC_WANTS_RESET | | 80 | MPIC_WANTS_RESET | |
| 92 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 81 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
| 93 | MPIC_SINGLE_DEST_CPU, | 82 | MPIC_SINGLE_DEST_CPU, |
| 94 | 0, 256, " OpenPIC "); | 83 | 0, 256, " OpenPIC "); |
| 95 | } | 84 | } |
| 96 | 85 | ||
| 97 | BUG_ON(mpic == NULL); | 86 | BUG_ON(mpic == NULL); |
| 98 | of_node_put(np); | ||
| 99 | |||
| 100 | mpic_init(mpic); | 87 | mpic_init(mpic); |
| 101 | 88 | ||
| 102 | #ifdef CONFIG_PPC_I8259 | 89 | #ifdef CONFIG_PPC_I8259 |
| @@ -152,9 +139,6 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, | |||
| 152 | /* | 139 | /* |
| 153 | * Setup the architecture | 140 | * Setup the architecture |
| 154 | */ | 141 | */ |
| 155 | #ifdef CONFIG_SMP | ||
| 156 | extern void __init mpc85xx_smp_init(void); | ||
| 157 | #endif | ||
| 158 | static void __init mpc85xx_ds_setup_arch(void) | 142 | static void __init mpc85xx_ds_setup_arch(void) |
| 159 | { | 143 | { |
| 160 | #ifdef CONFIG_PCI | 144 | #ifdef CONFIG_PCI |
| @@ -187,9 +171,7 @@ static void __init mpc85xx_ds_setup_arch(void) | |||
| 187 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | 171 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; |
| 188 | #endif | 172 | #endif |
| 189 | 173 | ||
| 190 | #ifdef CONFIG_SMP | ||
| 191 | mpc85xx_smp_init(); | 174 | mpc85xx_smp_init(); |
| 192 | #endif | ||
| 193 | 175 | ||
| 194 | #ifdef CONFIG_SWIOTLB | 176 | #ifdef CONFIG_SWIOTLB |
| 195 | if (memblock_end_of_DRAM() > max) { | 177 | if (memblock_end_of_DRAM() > max) { |
| @@ -219,21 +201,9 @@ static int __init mpc8544_ds_probe(void) | |||
| 219 | return 0; | 201 | return 0; |
| 220 | } | 202 | } |
| 221 | 203 | ||
| 222 | static struct of_device_id __initdata mpc85xxds_ids[] = { | 204 | machine_device_initcall(mpc8544_ds, mpc85xx_common_publish_devices); |
| 223 | { .type = "soc", }, | 205 | machine_device_initcall(mpc8572_ds, mpc85xx_common_publish_devices); |
| 224 | { .compatible = "soc", }, | 206 | machine_device_initcall(p2020_ds, mpc85xx_common_publish_devices); |
| 225 | { .compatible = "simple-bus", }, | ||
| 226 | { .compatible = "gianfar", }, | ||
| 227 | {}, | ||
| 228 | }; | ||
| 229 | |||
| 230 | static int __init mpc85xxds_publish_devices(void) | ||
| 231 | { | ||
| 232 | return of_platform_bus_probe(NULL, mpc85xxds_ids, NULL); | ||
| 233 | } | ||
| 234 | machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices); | ||
| 235 | machine_device_initcall(mpc8572_ds, mpc85xxds_publish_devices); | ||
| 236 | machine_device_initcall(p2020_ds, mpc85xxds_publish_devices); | ||
| 237 | 207 | ||
| 238 | machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier); | 208 | machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier); |
| 239 | machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier); | 209 | machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier); |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index a23a3ff634c5..1d15a0cd2c82 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
| @@ -51,6 +51,9 @@ | |||
| 51 | #include <asm/qe_ic.h> | 51 | #include <asm/qe_ic.h> |
| 52 | #include <asm/mpic.h> | 52 | #include <asm/mpic.h> |
| 53 | #include <asm/swiotlb.h> | 53 | #include <asm/swiotlb.h> |
| 54 | #include "smp.h" | ||
| 55 | |||
| 56 | #include "mpc85xx.h" | ||
| 54 | 57 | ||
| 55 | #undef DEBUG | 58 | #undef DEBUG |
| 56 | #ifdef DEBUG | 59 | #ifdef DEBUG |
| @@ -153,30 +156,7 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) | |||
| 153 | * Setup the architecture | 156 | * Setup the architecture |
| 154 | * | 157 | * |
| 155 | */ | 158 | */ |
| 156 | #ifdef CONFIG_SMP | ||
| 157 | extern void __init mpc85xx_smp_init(void); | ||
| 158 | #endif | ||
| 159 | |||
| 160 | #ifdef CONFIG_QUICC_ENGINE | 159 | #ifdef CONFIG_QUICC_ENGINE |
| 161 | static struct of_device_id mpc85xx_qe_ids[] __initdata = { | ||
| 162 | { .type = "qe", }, | ||
| 163 | { .compatible = "fsl,qe", }, | ||
| 164 | { }, | ||
| 165 | }; | ||
| 166 | |||
| 167 | static void __init mpc85xx_publish_qe_devices(void) | ||
| 168 | { | ||
| 169 | struct device_node *np; | ||
| 170 | |||
| 171 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
| 172 | if (!of_device_is_available(np)) { | ||
| 173 | of_node_put(np); | ||
| 174 | return; | ||
| 175 | } | ||
| 176 | |||
| 177 | of_platform_bus_probe(NULL, mpc85xx_qe_ids, NULL); | ||
| 178 | } | ||
| 179 | |||
| 180 | static void __init mpc85xx_mds_reset_ucc_phys(void) | 160 | static void __init mpc85xx_mds_reset_ucc_phys(void) |
| 181 | { | 161 | { |
| 182 | struct device_node *np; | 162 | struct device_node *np; |
| @@ -347,7 +327,6 @@ static void __init mpc85xx_mds_qeic_init(void) | |||
| 347 | of_node_put(np); | 327 | of_node_put(np); |
| 348 | } | 328 | } |
| 349 | #else | 329 | #else |
| 350 | static void __init mpc85xx_publish_qe_devices(void) { } | ||
| 351 | static void __init mpc85xx_mds_qe_init(void) { } | 330 | static void __init mpc85xx_mds_qe_init(void) { } |
| 352 | static void __init mpc85xx_mds_qeic_init(void) { } | 331 | static void __init mpc85xx_mds_qeic_init(void) { } |
| 353 | #endif /* CONFIG_QUICC_ENGINE */ | 332 | #endif /* CONFIG_QUICC_ENGINE */ |
| @@ -381,9 +360,7 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
| 381 | } | 360 | } |
| 382 | #endif | 361 | #endif |
| 383 | 362 | ||
| 384 | #ifdef CONFIG_SMP | ||
| 385 | mpc85xx_smp_init(); | 363 | mpc85xx_smp_init(); |
| 386 | #endif | ||
| 387 | 364 | ||
| 388 | mpc85xx_mds_qe_init(); | 365 | mpc85xx_mds_qe_init(); |
| 389 | 366 | ||
| @@ -429,24 +406,11 @@ machine_arch_initcall(mpc8568_mds, board_fixups); | |||
| 429 | machine_arch_initcall(mpc8569_mds, board_fixups); | 406 | machine_arch_initcall(mpc8569_mds, board_fixups); |
| 430 | 407 | ||
| 431 | static struct of_device_id mpc85xx_ids[] = { | 408 | static struct of_device_id mpc85xx_ids[] = { |
| 432 | { .type = "soc", }, | ||
| 433 | { .compatible = "soc", }, | ||
| 434 | { .compatible = "simple-bus", }, | ||
| 435 | { .compatible = "gianfar", }, | ||
| 436 | { .compatible = "fsl,rapidio-delta", }, | ||
| 437 | { .compatible = "fsl,mpc8548-guts", }, | 409 | { .compatible = "fsl,mpc8548-guts", }, |
| 438 | { .compatible = "gpio-leds", }, | 410 | { .compatible = "gpio-leds", }, |
| 439 | {}, | 411 | {}, |
| 440 | }; | 412 | }; |
| 441 | 413 | ||
| 442 | static struct of_device_id p1021_ids[] = { | ||
| 443 | { .type = "soc", }, | ||
| 444 | { .compatible = "soc", }, | ||
| 445 | { .compatible = "simple-bus", }, | ||
| 446 | { .compatible = "gianfar", }, | ||
| 447 | {}, | ||
| 448 | }; | ||
| 449 | |||
| 450 | static int __init mpc85xx_publish_devices(void) | 414 | static int __init mpc85xx_publish_devices(void) |
| 451 | { | 415 | { |
| 452 | if (machine_is(mpc8568_mds)) | 416 | if (machine_is(mpc8568_mds)) |
| @@ -454,23 +418,15 @@ static int __init mpc85xx_publish_devices(void) | |||
| 454 | if (machine_is(mpc8569_mds)) | 418 | if (machine_is(mpc8569_mds)) |
| 455 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); | 419 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); |
| 456 | 420 | ||
| 421 | mpc85xx_common_publish_devices(); | ||
| 457 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); | 422 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); |
| 458 | mpc85xx_publish_qe_devices(); | ||
| 459 | |||
| 460 | return 0; | ||
| 461 | } | ||
| 462 | |||
| 463 | static int __init p1021_publish_devices(void) | ||
| 464 | { | ||
| 465 | of_platform_bus_probe(NULL, p1021_ids, NULL); | ||
| 466 | mpc85xx_publish_qe_devices(); | ||
| 467 | 423 | ||
| 468 | return 0; | 424 | return 0; |
| 469 | } | 425 | } |
| 470 | 426 | ||
| 471 | machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); | 427 | machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); |
| 472 | machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); | 428 | machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); |
| 473 | machine_device_initcall(p1021_mds, p1021_publish_devices); | 429 | machine_device_initcall(p1021_mds, mpc85xx_common_publish_devices); |
| 474 | 430 | ||
| 475 | machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); | 431 | machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); |
| 476 | machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); | 432 | machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); |
| @@ -478,26 +434,11 @@ machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier); | |||
| 478 | 434 | ||
| 479 | static void __init mpc85xx_mds_pic_init(void) | 435 | static void __init mpc85xx_mds_pic_init(void) |
| 480 | { | 436 | { |
| 481 | struct mpic *mpic; | 437 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 482 | struct resource r; | 438 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
| 483 | struct device_node *np = NULL; | ||
| 484 | |||
| 485 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 486 | if (!np) | ||
| 487 | return; | ||
| 488 | |||
| 489 | if (of_address_to_resource(np, 0, &r)) { | ||
| 490 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 491 | of_node_put(np); | ||
| 492 | return; | ||
| 493 | } | ||
| 494 | |||
| 495 | mpic = mpic_alloc(np, r.start, | ||
| 496 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | | ||
| 497 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, | 439 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
| 498 | 0, 256, " OpenPIC "); | 440 | 0, 256, " OpenPIC "); |
| 499 | BUG_ON(mpic == NULL); | 441 | BUG_ON(mpic == NULL); |
| 500 | of_node_put(np); | ||
| 501 | 442 | ||
| 502 | mpic_init(mpic); | 443 | mpic_init(mpic); |
| 503 | mpc85xx_mds_qeic_init(); | 444 | mpc85xx_mds_qeic_init(); |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index f5ff9110c97e..ccf520e890be 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c | |||
| @@ -29,6 +29,9 @@ | |||
| 29 | 29 | ||
| 30 | #include <sysdev/fsl_soc.h> | 30 | #include <sysdev/fsl_soc.h> |
| 31 | #include <sysdev/fsl_pci.h> | 31 | #include <sysdev/fsl_pci.h> |
| 32 | #include "smp.h" | ||
| 33 | |||
| 34 | #include "mpc85xx.h" | ||
| 32 | 35 | ||
| 33 | #undef DEBUG | 36 | #undef DEBUG |
| 34 | 37 | ||
| @@ -42,49 +45,28 @@ | |||
| 42 | void __init mpc85xx_rdb_pic_init(void) | 45 | void __init mpc85xx_rdb_pic_init(void) |
| 43 | { | 46 | { |
| 44 | struct mpic *mpic; | 47 | struct mpic *mpic; |
| 45 | struct resource r; | ||
| 46 | struct device_node *np; | ||
| 47 | unsigned long root = of_get_flat_dt_root(); | 48 | unsigned long root = of_get_flat_dt_root(); |
| 48 | 49 | ||
| 49 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 50 | if (np == NULL) { | ||
| 51 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | if (of_address_to_resource(np, 0, &r)) { | ||
| 56 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 57 | of_node_put(np); | ||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | if (of_flat_dt_is_compatible(root, "fsl,MPC85XXRDB-CAMP")) { | 50 | if (of_flat_dt_is_compatible(root, "fsl,MPC85XXRDB-CAMP")) { |
| 62 | mpic = mpic_alloc(np, r.start, | 51 | mpic = mpic_alloc(NULL, 0, |
| 63 | MPIC_PRIMARY | | ||
| 64 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 52 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
| 65 | MPIC_SINGLE_DEST_CPU, | 53 | MPIC_SINGLE_DEST_CPU, |
| 66 | 0, 256, " OpenPIC "); | 54 | 0, 256, " OpenPIC "); |
| 67 | } else { | 55 | } else { |
| 68 | mpic = mpic_alloc(np, r.start, | 56 | mpic = mpic_alloc(NULL, 0, |
| 69 | MPIC_PRIMARY | MPIC_WANTS_RESET | | 57 | MPIC_WANTS_RESET | |
| 70 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 58 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
| 71 | MPIC_SINGLE_DEST_CPU, | 59 | MPIC_SINGLE_DEST_CPU, |
| 72 | 0, 256, " OpenPIC "); | 60 | 0, 256, " OpenPIC "); |
| 73 | } | 61 | } |
| 74 | 62 | ||
| 75 | BUG_ON(mpic == NULL); | 63 | BUG_ON(mpic == NULL); |
| 76 | of_node_put(np); | ||
| 77 | |||
| 78 | mpic_init(mpic); | 64 | mpic_init(mpic); |
| 79 | |||
| 80 | } | 65 | } |
| 81 | 66 | ||
| 82 | /* | 67 | /* |
| 83 | * Setup the architecture | 68 | * Setup the architecture |
| 84 | */ | 69 | */ |
| 85 | #ifdef CONFIG_SMP | ||
| 86 | extern void __init mpc85xx_smp_init(void); | ||
| 87 | #endif | ||
| 88 | static void __init mpc85xx_rdb_setup_arch(void) | 70 | static void __init mpc85xx_rdb_setup_arch(void) |
| 89 | { | 71 | { |
| 90 | #ifdef CONFIG_PCI | 72 | #ifdef CONFIG_PCI |
| @@ -102,27 +84,12 @@ static void __init mpc85xx_rdb_setup_arch(void) | |||
| 102 | 84 | ||
| 103 | #endif | 85 | #endif |
| 104 | 86 | ||
| 105 | #ifdef CONFIG_SMP | ||
| 106 | mpc85xx_smp_init(); | 87 | mpc85xx_smp_init(); |
| 107 | #endif | ||
| 108 | |||
| 109 | printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n"); | 88 | printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n"); |
| 110 | } | 89 | } |
| 111 | 90 | ||
| 112 | static struct of_device_id __initdata mpc85xxrdb_ids[] = { | 91 | machine_device_initcall(p2020_rdb, mpc85xx_common_publish_devices); |
| 113 | { .type = "soc", }, | 92 | machine_device_initcall(p1020_rdb, mpc85xx_common_publish_devices); |
| 114 | { .compatible = "soc", }, | ||
| 115 | { .compatible = "simple-bus", }, | ||
| 116 | { .compatible = "gianfar", }, | ||
| 117 | {}, | ||
| 118 | }; | ||
| 119 | |||
| 120 | static int __init mpc85xxrdb_publish_devices(void) | ||
| 121 | { | ||
| 122 | return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL); | ||
| 123 | } | ||
| 124 | machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices); | ||
| 125 | machine_device_initcall(p1020_rdb, mpc85xxrdb_publish_devices); | ||
| 126 | 93 | ||
| 127 | /* | 94 | /* |
| 128 | * Called very early, device-tree isn't unflattened | 95 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c index d7387fa7f534..538bc3f57e9d 100644 --- a/arch/powerpc/platforms/85xx/p1010rdb.c +++ b/arch/powerpc/platforms/85xx/p1010rdb.c | |||
| @@ -28,33 +28,18 @@ | |||
| 28 | #include <sysdev/fsl_soc.h> | 28 | #include <sysdev/fsl_soc.h> |
| 29 | #include <sysdev/fsl_pci.h> | 29 | #include <sysdev/fsl_pci.h> |
| 30 | 30 | ||
| 31 | #include "mpc85xx.h" | ||
| 32 | |||
| 31 | void __init p1010_rdb_pic_init(void) | 33 | void __init p1010_rdb_pic_init(void) |
| 32 | { | 34 | { |
| 33 | struct mpic *mpic; | 35 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 34 | struct resource r; | 36 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
| 35 | struct device_node *np; | 37 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
| 36 | |||
| 37 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 38 | if (np == NULL) { | ||
| 39 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 40 | return; | ||
| 41 | } | ||
| 42 | |||
| 43 | if (of_address_to_resource(np, 0, &r)) { | ||
| 44 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 45 | of_node_put(np); | ||
| 46 | return; | ||
| 47 | } | ||
| 48 | |||
| 49 | mpic = mpic_alloc(np, r.start, MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
| 50 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, | ||
| 51 | 0, 256, " OpenPIC "); | 38 | 0, 256, " OpenPIC "); |
| 52 | 39 | ||
| 53 | BUG_ON(mpic == NULL); | 40 | BUG_ON(mpic == NULL); |
| 54 | of_node_put(np); | ||
| 55 | 41 | ||
| 56 | mpic_init(mpic); | 42 | mpic_init(mpic); |
| 57 | |||
| 58 | } | 43 | } |
| 59 | 44 | ||
| 60 | 45 | ||
| @@ -81,18 +66,7 @@ static void __init p1010_rdb_setup_arch(void) | |||
| 81 | printk(KERN_INFO "P1010 RDB board from Freescale Semiconductor\n"); | 66 | printk(KERN_INFO "P1010 RDB board from Freescale Semiconductor\n"); |
| 82 | } | 67 | } |
| 83 | 68 | ||
| 84 | static struct of_device_id __initdata p1010rdb_ids[] = { | 69 | machine_device_initcall(p1010_rdb, mpc85xx_common_publish_devices); |
| 85 | { .type = "soc", }, | ||
| 86 | { .compatible = "soc", }, | ||
| 87 | { .compatible = "simple-bus", }, | ||
| 88 | {}, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static int __init p1010rdb_publish_devices(void) | ||
| 92 | { | ||
| 93 | return of_platform_bus_probe(NULL, p1010rdb_ids, NULL); | ||
| 94 | } | ||
| 95 | machine_device_initcall(p1010_rdb, p1010rdb_publish_devices); | ||
| 96 | machine_arch_initcall(p1010_rdb, swiotlb_setup_bus_notifier); | 70 | machine_arch_initcall(p1010_rdb, swiotlb_setup_bus_notifier); |
| 97 | 71 | ||
| 98 | /* | 72 | /* |
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index fda15716fada..bb3d84f4046f 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
| @@ -26,6 +26,9 @@ | |||
| 26 | #include <sysdev/fsl_soc.h> | 26 | #include <sysdev/fsl_soc.h> |
| 27 | #include <sysdev/fsl_pci.h> | 27 | #include <sysdev/fsl_pci.h> |
| 28 | #include <asm/fsl_guts.h> | 28 | #include <asm/fsl_guts.h> |
| 29 | #include "smp.h" | ||
| 30 | |||
| 31 | #include "mpc85xx.h" | ||
| 29 | 32 | ||
| 30 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) | 33 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) |
| 31 | 34 | ||
| @@ -238,38 +241,15 @@ p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port) | |||
| 238 | 241 | ||
| 239 | void __init p1022_ds_pic_init(void) | 242 | void __init p1022_ds_pic_init(void) |
| 240 | { | 243 | { |
| 241 | struct mpic *mpic; | 244 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 242 | struct resource r; | 245 | MPIC_WANTS_RESET | |
| 243 | struct device_node *np; | ||
| 244 | |||
| 245 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 246 | if (!np) { | ||
| 247 | pr_err("Could not find open-pic node\n"); | ||
| 248 | return; | ||
| 249 | } | ||
| 250 | |||
| 251 | if (of_address_to_resource(np, 0, &r)) { | ||
| 252 | pr_err("Failed to map mpic register space\n"); | ||
| 253 | of_node_put(np); | ||
| 254 | return; | ||
| 255 | } | ||
| 256 | |||
| 257 | mpic = mpic_alloc(np, r.start, | ||
| 258 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
| 259 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 246 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
| 260 | MPIC_SINGLE_DEST_CPU, | 247 | MPIC_SINGLE_DEST_CPU, |
| 261 | 0, 256, " OpenPIC "); | 248 | 0, 256, " OpenPIC "); |
| 262 | |||
| 263 | BUG_ON(mpic == NULL); | 249 | BUG_ON(mpic == NULL); |
| 264 | of_node_put(np); | ||
| 265 | |||
| 266 | mpic_init(mpic); | 250 | mpic_init(mpic); |
| 267 | } | 251 | } |
| 268 | 252 | ||
| 269 | #ifdef CONFIG_SMP | ||
| 270 | void __init mpc85xx_smp_init(void); | ||
| 271 | #endif | ||
| 272 | |||
| 273 | /* | 253 | /* |
| 274 | * Setup the architecture | 254 | * Setup the architecture |
| 275 | */ | 255 | */ |
| @@ -309,9 +289,7 @@ static void __init p1022_ds_setup_arch(void) | |||
| 309 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; | 289 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; |
| 310 | #endif | 290 | #endif |
| 311 | 291 | ||
| 312 | #ifdef CONFIG_SMP | ||
| 313 | mpc85xx_smp_init(); | 292 | mpc85xx_smp_init(); |
| 314 | #endif | ||
| 315 | 293 | ||
| 316 | #ifdef CONFIG_SWIOTLB | 294 | #ifdef CONFIG_SWIOTLB |
| 317 | if (memblock_end_of_DRAM() > max) { | 295 | if (memblock_end_of_DRAM() > max) { |
| @@ -325,10 +303,6 @@ static void __init p1022_ds_setup_arch(void) | |||
| 325 | } | 303 | } |
| 326 | 304 | ||
| 327 | static struct of_device_id __initdata p1022_ds_ids[] = { | 305 | static struct of_device_id __initdata p1022_ds_ids[] = { |
| 328 | { .type = "soc", }, | ||
| 329 | { .compatible = "soc", }, | ||
| 330 | { .compatible = "simple-bus", }, | ||
| 331 | { .compatible = "gianfar", }, | ||
| 332 | /* So that the DMA channel nodes can be probed individually: */ | 306 | /* So that the DMA channel nodes can be probed individually: */ |
| 333 | { .compatible = "fsl,eloplus-dma", }, | 307 | { .compatible = "fsl,eloplus-dma", }, |
| 334 | {}, | 308 | {}, |
| @@ -336,6 +310,7 @@ static struct of_device_id __initdata p1022_ds_ids[] = { | |||
| 336 | 310 | ||
| 337 | static int __init p1022_ds_publish_devices(void) | 311 | static int __init p1022_ds_publish_devices(void) |
| 338 | { | 312 | { |
| 313 | mpc85xx_common_publish_devices(); | ||
| 339 | return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); | 314 | return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); |
| 340 | } | 315 | } |
| 341 | machine_device_initcall(p1022_ds, p1022_ds_publish_devices); | 316 | machine_device_initcall(p1022_ds, p1022_ds_publish_devices); |
diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c index 835e0b335bfa..d951e7027bb6 100644 --- a/arch/powerpc/platforms/85xx/p1023_rds.c +++ b/arch/powerpc/platforms/85xx/p1023_rds.c | |||
| @@ -30,19 +30,18 @@ | |||
| 30 | #include <asm/prom.h> | 30 | #include <asm/prom.h> |
| 31 | #include <asm/udbg.h> | 31 | #include <asm/udbg.h> |
| 32 | #include <asm/mpic.h> | 32 | #include <asm/mpic.h> |
| 33 | #include "smp.h" | ||
| 33 | 34 | ||
| 34 | #include <sysdev/fsl_soc.h> | 35 | #include <sysdev/fsl_soc.h> |
| 35 | #include <sysdev/fsl_pci.h> | 36 | #include <sysdev/fsl_pci.h> |
| 36 | 37 | ||
| 38 | #include "mpc85xx.h" | ||
| 39 | |||
| 37 | /* ************************************************************************ | 40 | /* ************************************************************************ |
| 38 | * | 41 | * |
| 39 | * Setup the architecture | 42 | * Setup the architecture |
| 40 | * | 43 | * |
| 41 | */ | 44 | */ |
| 42 | #ifdef CONFIG_SMP | ||
| 43 | void __init mpc85xx_smp_init(void); | ||
| 44 | #endif | ||
| 45 | |||
| 46 | static void __init mpc85xx_rds_setup_arch(void) | 45 | static void __init mpc85xx_rds_setup_arch(void) |
| 47 | { | 46 | { |
| 48 | struct device_node *np; | 47 | struct device_node *np; |
| @@ -87,53 +86,19 @@ static void __init mpc85xx_rds_setup_arch(void) | |||
| 87 | fsl_add_bridge(np, 0); | 86 | fsl_add_bridge(np, 0); |
| 88 | #endif | 87 | #endif |
| 89 | 88 | ||
| 90 | #ifdef CONFIG_SMP | ||
| 91 | mpc85xx_smp_init(); | 89 | mpc85xx_smp_init(); |
| 92 | #endif | ||
| 93 | } | ||
| 94 | |||
| 95 | static struct of_device_id p1023_ids[] = { | ||
| 96 | { .type = "soc", }, | ||
| 97 | { .compatible = "soc", }, | ||
| 98 | { .compatible = "simple-bus", }, | ||
| 99 | {}, | ||
| 100 | }; | ||
| 101 | |||
| 102 | |||
| 103 | static int __init p1023_publish_devices(void) | ||
| 104 | { | ||
| 105 | of_platform_bus_probe(NULL, p1023_ids, NULL); | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | 90 | } |
| 109 | 91 | ||
| 110 | machine_device_initcall(p1023_rds, p1023_publish_devices); | 92 | machine_device_initcall(p1023_rds, mpc85xx_common_publish_devices); |
| 111 | 93 | ||
| 112 | static void __init mpc85xx_rds_pic_init(void) | 94 | static void __init mpc85xx_rds_pic_init(void) |
| 113 | { | 95 | { |
| 114 | struct mpic *mpic; | 96 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 115 | struct resource r; | 97 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
| 116 | struct device_node *np = NULL; | ||
| 117 | |||
| 118 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 119 | if (!np) { | ||
| 120 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 121 | return; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (of_address_to_resource(np, 0, &r)) { | ||
| 125 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 126 | of_node_put(np); | ||
| 127 | return; | ||
| 128 | } | ||
| 129 | |||
| 130 | mpic = mpic_alloc(np, r.start, | ||
| 131 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | | ||
| 132 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, | 98 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
| 133 | 0, 256, " OpenPIC "); | 99 | 0, 256, " OpenPIC "); |
| 134 | 100 | ||
| 135 | BUG_ON(mpic == NULL); | 101 | BUG_ON(mpic == NULL); |
| 136 | of_node_put(np); | ||
| 137 | 102 | ||
| 138 | mpic_init(mpic); | 103 | mpic_init(mpic); |
| 139 | } | 104 | } |
diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index 14632a971225..184a50784617 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c | |||
| @@ -48,35 +48,16 @@ | |||
| 48 | #include <sysdev/fsl_soc.h> | 48 | #include <sysdev/fsl_soc.h> |
| 49 | #include <sysdev/fsl_pci.h> | 49 | #include <sysdev/fsl_pci.h> |
| 50 | 50 | ||
| 51 | #include "mpc85xx.h" | ||
| 52 | |||
| 51 | static int sbc_rev; | 53 | static int sbc_rev; |
| 52 | 54 | ||
| 53 | static void __init sbc8548_pic_init(void) | 55 | static void __init sbc8548_pic_init(void) |
| 54 | { | 56 | { |
| 55 | struct mpic *mpic; | 57 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 56 | struct resource r; | 58 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 57 | struct device_node *np = NULL; | ||
| 58 | |||
| 59 | np = of_find_node_by_type(np, "open-pic"); | ||
| 60 | |||
| 61 | if (np == NULL) { | ||
| 62 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 63 | return; | ||
| 64 | } | ||
| 65 | |||
| 66 | if (of_address_to_resource(np, 0, &r)) { | ||
| 67 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 68 | of_node_put(np); | ||
| 69 | return; | ||
| 70 | } | ||
| 71 | |||
| 72 | mpic = mpic_alloc(np, r.start, | ||
| 73 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 74 | 0, 256, " OpenPIC "); | 59 | 0, 256, " OpenPIC "); |
| 75 | BUG_ON(mpic == NULL); | 60 | BUG_ON(mpic == NULL); |
| 76 | |||
| 77 | /* Return the mpic node */ | ||
| 78 | of_node_put(np); | ||
| 79 | |||
| 80 | mpic_init(mpic); | 61 | mpic_init(mpic); |
| 81 | } | 62 | } |
| 82 | 63 | ||
| @@ -149,21 +130,7 @@ static void sbc8548_show_cpuinfo(struct seq_file *m) | |||
| 149 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 130 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
| 150 | } | 131 | } |
| 151 | 132 | ||
| 152 | static struct of_device_id __initdata of_bus_ids[] = { | 133 | machine_device_initcall(sbc8548, mpc85xx_common_publish_devices); |
| 153 | { .name = "soc", }, | ||
| 154 | { .type = "soc", }, | ||
| 155 | { .compatible = "simple-bus", }, | ||
| 156 | { .compatible = "gianfar", }, | ||
| 157 | {}, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static int __init declare_of_platform_devices(void) | ||
| 161 | { | ||
| 162 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | machine_device_initcall(sbc8548, declare_of_platform_devices); | ||
| 167 | 134 | ||
| 168 | /* | 135 | /* |
| 169 | * Called very early, device-tree isn't unflattened | 136 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index cebd786dc334..940752e93051 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c | |||
| @@ -32,68 +32,22 @@ | |||
| 32 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
| 33 | #include <sysdev/fsl_pci.h> | 33 | #include <sysdev/fsl_pci.h> |
| 34 | 34 | ||
| 35 | #include "mpc85xx.h" | ||
| 36 | |||
| 35 | #ifdef CONFIG_CPM2 | 37 | #ifdef CONFIG_CPM2 |
| 36 | #include <asm/cpm2.h> | 38 | #include <asm/cpm2.h> |
| 37 | #include <sysdev/cpm2_pic.h> | 39 | #include <sysdev/cpm2_pic.h> |
| 38 | #endif | 40 | #endif |
| 39 | 41 | ||
| 40 | #ifdef CONFIG_CPM2 | ||
| 41 | |||
| 42 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 43 | { | ||
| 44 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 45 | int cascade_irq; | ||
| 46 | |||
| 47 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
| 48 | generic_handle_irq(cascade_irq); | ||
| 49 | |||
| 50 | chip->irq_eoi(&desc->irq_data); | ||
| 51 | } | ||
| 52 | |||
| 53 | #endif /* CONFIG_CPM2 */ | ||
| 54 | |||
| 55 | static void __init sbc8560_pic_init(void) | 42 | static void __init sbc8560_pic_init(void) |
| 56 | { | 43 | { |
| 57 | struct mpic *mpic; | 44 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 58 | struct resource r; | 45 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 59 | struct device_node *np = NULL; | ||
| 60 | #ifdef CONFIG_CPM2 | ||
| 61 | int irq; | ||
| 62 | #endif | ||
| 63 | |||
| 64 | np = of_find_node_by_type(np, "open-pic"); | ||
| 65 | if (!np) { | ||
| 66 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 67 | return; | ||
| 68 | } | ||
| 69 | |||
| 70 | if (of_address_to_resource(np, 0, &r)) { | ||
| 71 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
| 72 | of_node_put(np); | ||
| 73 | return; | ||
| 74 | } | ||
| 75 | |||
| 76 | mpic = mpic_alloc(np, r.start, | ||
| 77 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 78 | 0, 256, " OpenPIC "); | 46 | 0, 256, " OpenPIC "); |
| 79 | BUG_ON(mpic == NULL); | 47 | BUG_ON(mpic == NULL); |
| 80 | of_node_put(np); | ||
| 81 | |||
| 82 | mpic_init(mpic); | 48 | mpic_init(mpic); |
| 83 | 49 | ||
| 84 | #ifdef CONFIG_CPM2 | 50 | mpc85xx_cpm2_pic_init(); |
| 85 | /* Setup CPM2 PIC */ | ||
| 86 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
| 87 | if (np == NULL) { | ||
| 88 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
| 89 | return; | ||
| 90 | } | ||
| 91 | irq = irq_of_parse_and_map(np, 0); | ||
| 92 | |||
| 93 | cpm2_pic_init(np); | ||
| 94 | of_node_put(np); | ||
| 95 | irq_set_chained_handler(irq, cpm2_cascade); | ||
| 96 | #endif | ||
| 97 | } | 51 | } |
| 98 | 52 | ||
| 99 | /* | 53 | /* |
| @@ -208,23 +162,7 @@ static void sbc8560_show_cpuinfo(struct seq_file *m) | |||
| 208 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 162 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
| 209 | } | 163 | } |
| 210 | 164 | ||
| 211 | static struct of_device_id __initdata of_bus_ids[] = { | 165 | machine_device_initcall(sbc8560, mpc85xx_common_publish_devices); |
| 212 | { .name = "soc", }, | ||
| 213 | { .type = "soc", }, | ||
| 214 | { .name = "cpm", }, | ||
| 215 | { .name = "localbus", }, | ||
| 216 | { .compatible = "simple-bus", }, | ||
| 217 | { .compatible = "gianfar", }, | ||
| 218 | {}, | ||
| 219 | }; | ||
| 220 | |||
| 221 | static int __init declare_of_platform_devices(void) | ||
| 222 | { | ||
| 223 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | machine_device_initcall(sbc8560, declare_of_platform_devices); | ||
| 228 | 166 | ||
| 229 | /* | 167 | /* |
| 230 | * Called very early, device-tree isn't unflattened | 168 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 2df4785ffd4e..ff4249044a3c 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #include <sysdev/fsl_soc.h> | 28 | #include <sysdev/fsl_soc.h> |
| 29 | #include <sysdev/mpic.h> | 29 | #include <sysdev/mpic.h> |
| 30 | #include "smp.h" | ||
| 30 | 31 | ||
| 31 | extern void __early_start(void); | 32 | extern void __early_start(void); |
| 32 | 33 | ||
diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h new file mode 100644 index 000000000000..e2b44933ff19 --- /dev/null +++ b/arch/powerpc/platforms/85xx/smp.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | #ifndef POWERPC_85XX_SMP_H_ | ||
| 2 | #define POWERPC_85XX_SMP_H_ 1 | ||
| 3 | |||
| 4 | #include <linux/init.h> | ||
| 5 | |||
| 6 | #ifdef CONFIG_SMP | ||
| 7 | void __init mpc85xx_smp_init(void); | ||
| 8 | #else | ||
| 9 | static inline void mpc85xx_smp_init(void) | ||
| 10 | { | ||
| 11 | /* Nothing to do */ | ||
| 12 | } | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #endif /* not POWERPC_85XX_SMP_H_ */ | ||
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c index 747d8fb3ab82..18f635906b27 100644 --- a/arch/powerpc/platforms/85xx/socrates.c +++ b/arch/powerpc/platforms/85xx/socrates.c | |||
| @@ -41,32 +41,17 @@ | |||
| 41 | #include <sysdev/fsl_soc.h> | 41 | #include <sysdev/fsl_soc.h> |
| 42 | #include <sysdev/fsl_pci.h> | 42 | #include <sysdev/fsl_pci.h> |
| 43 | 43 | ||
| 44 | #include "mpc85xx.h" | ||
| 44 | #include "socrates_fpga_pic.h" | 45 | #include "socrates_fpga_pic.h" |
| 45 | 46 | ||
| 46 | static void __init socrates_pic_init(void) | 47 | static void __init socrates_pic_init(void) |
| 47 | { | 48 | { |
| 48 | struct mpic *mpic; | ||
| 49 | struct resource r; | ||
| 50 | struct device_node *np; | 49 | struct device_node *np; |
| 51 | 50 | ||
| 52 | np = of_find_node_by_type(NULL, "open-pic"); | 51 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 53 | if (!np) { | 52 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 54 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 55 | return; | ||
| 56 | } | ||
| 57 | |||
| 58 | if (of_address_to_resource(np, 0, &r)) { | ||
| 59 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
| 60 | of_node_put(np); | ||
| 61 | return; | ||
| 62 | } | ||
| 63 | |||
| 64 | mpic = mpic_alloc(np, r.start, | ||
| 65 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 66 | 0, 256, " OpenPIC "); | 53 | 0, 256, " OpenPIC "); |
| 67 | BUG_ON(mpic == NULL); | 54 | BUG_ON(mpic == NULL); |
| 68 | of_node_put(np); | ||
| 69 | |||
| 70 | mpic_init(mpic); | 55 | mpic_init(mpic); |
| 71 | 56 | ||
| 72 | np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); | 57 | np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); |
| @@ -96,17 +81,7 @@ static void __init socrates_setup_arch(void) | |||
| 96 | #endif | 81 | #endif |
| 97 | } | 82 | } |
| 98 | 83 | ||
| 99 | static struct of_device_id __initdata socrates_of_bus_ids[] = { | 84 | machine_device_initcall(socrates, mpc85xx_common_publish_devices); |
| 100 | { .compatible = "simple-bus", }, | ||
| 101 | { .compatible = "gianfar", }, | ||
| 102 | {}, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static int __init socrates_publish_devices(void) | ||
| 106 | { | ||
| 107 | return of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); | ||
| 108 | } | ||
| 109 | machine_device_initcall(socrates, socrates_publish_devices); | ||
| 110 | 85 | ||
| 111 | /* | 86 | /* |
| 112 | * Called very early, device-tree isn't unflattened | 87 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index 5387e9f06bdb..e9e5234b4e76 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c | |||
| @@ -40,70 +40,21 @@ | |||
| 40 | #include <sysdev/fsl_soc.h> | 40 | #include <sysdev/fsl_soc.h> |
| 41 | #include <sysdev/fsl_pci.h> | 41 | #include <sysdev/fsl_pci.h> |
| 42 | 42 | ||
| 43 | #include "mpc85xx.h" | ||
| 44 | |||
| 43 | #ifdef CONFIG_CPM2 | 45 | #ifdef CONFIG_CPM2 |
| 44 | #include <asm/cpm2.h> | 46 | #include <asm/cpm2.h> |
| 45 | #include <sysdev/cpm2_pic.h> | ||
| 46 | |||
| 47 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 48 | { | ||
| 49 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 50 | int cascade_irq; | ||
| 51 | |||
| 52 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
| 53 | generic_handle_irq(cascade_irq); | ||
| 54 | |||
| 55 | chip->irq_eoi(&desc->irq_data); | ||
| 56 | } | ||
| 57 | #endif /* CONFIG_CPM2 */ | 47 | #endif /* CONFIG_CPM2 */ |
| 58 | 48 | ||
| 59 | static void __init stx_gp3_pic_init(void) | 49 | static void __init stx_gp3_pic_init(void) |
| 60 | { | 50 | { |
| 61 | struct mpic *mpic; | 51 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 62 | struct resource r; | 52 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 63 | struct device_node *np; | ||
| 64 | #ifdef CONFIG_CPM2 | ||
| 65 | int irq; | ||
| 66 | #endif | ||
| 67 | |||
| 68 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 69 | if (!np) { | ||
| 70 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 71 | return; | ||
| 72 | } | ||
| 73 | |||
| 74 | if (of_address_to_resource(np, 0, &r)) { | ||
| 75 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
| 76 | of_node_put(np); | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 80 | mpic = mpic_alloc(np, r.start, | ||
| 81 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 82 | 0, 256, " OpenPIC "); | 53 | 0, 256, " OpenPIC "); |
| 83 | BUG_ON(mpic == NULL); | 54 | BUG_ON(mpic == NULL); |
| 84 | of_node_put(np); | ||
| 85 | |||
| 86 | mpic_init(mpic); | 55 | mpic_init(mpic); |
| 87 | 56 | ||
| 88 | #ifdef CONFIG_CPM2 | 57 | mpc85xx_cpm2_pic_init(); |
| 89 | /* Setup CPM2 PIC */ | ||
| 90 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
| 91 | if (np == NULL) { | ||
| 92 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
| 93 | return; | ||
| 94 | } | ||
| 95 | irq = irq_of_parse_and_map(np, 0); | ||
| 96 | |||
| 97 | if (irq == NO_IRQ) { | ||
| 98 | of_node_put(np); | ||
| 99 | printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n"); | ||
| 100 | return; | ||
| 101 | } | ||
| 102 | |||
| 103 | cpm2_pic_init(np); | ||
| 104 | of_node_put(np); | ||
| 105 | irq_set_chained_handler(irq, cpm2_cascade); | ||
| 106 | #endif | ||
| 107 | } | 58 | } |
| 108 | 59 | ||
| 109 | /* | 60 | /* |
| @@ -144,19 +95,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) | |||
| 144 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 95 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
| 145 | } | 96 | } |
| 146 | 97 | ||
| 147 | static struct of_device_id __initdata of_bus_ids[] = { | 98 | machine_device_initcall(stx_gp3, mpc85xx_common_publish_devices); |
| 148 | { .compatible = "simple-bus", }, | ||
| 149 | { .compatible = "gianfar", }, | ||
| 150 | {}, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static int __init declare_of_platform_devices(void) | ||
| 154 | { | ||
| 155 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | machine_device_initcall(stx_gp3, declare_of_platform_devices); | ||
| 160 | 99 | ||
| 161 | /* | 100 | /* |
| 162 | * Called very early, device-tree isn't unflattened | 101 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 325de772725a..bf7c89fb75bb 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c | |||
| @@ -38,70 +38,21 @@ | |||
| 38 | #include <sysdev/fsl_soc.h> | 38 | #include <sysdev/fsl_soc.h> |
| 39 | #include <sysdev/fsl_pci.h> | 39 | #include <sysdev/fsl_pci.h> |
| 40 | 40 | ||
| 41 | #include "mpc85xx.h" | ||
| 42 | |||
| 41 | #ifdef CONFIG_CPM2 | 43 | #ifdef CONFIG_CPM2 |
| 42 | #include <asm/cpm2.h> | 44 | #include <asm/cpm2.h> |
| 43 | #include <sysdev/cpm2_pic.h> | ||
| 44 | |||
| 45 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 46 | { | ||
| 47 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 48 | int cascade_irq; | ||
| 49 | |||
| 50 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
| 51 | generic_handle_irq(cascade_irq); | ||
| 52 | |||
| 53 | chip->irq_eoi(&desc->irq_data); | ||
| 54 | } | ||
| 55 | #endif /* CONFIG_CPM2 */ | 45 | #endif /* CONFIG_CPM2 */ |
| 56 | 46 | ||
| 57 | static void __init tqm85xx_pic_init(void) | 47 | static void __init tqm85xx_pic_init(void) |
| 58 | { | 48 | { |
| 59 | struct mpic *mpic; | 49 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 60 | struct resource r; | 50 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
| 61 | struct device_node *np; | ||
| 62 | #ifdef CONFIG_CPM2 | ||
| 63 | int irq; | ||
| 64 | #endif | ||
| 65 | |||
| 66 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 67 | if (!np) { | ||
| 68 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 69 | return; | ||
| 70 | } | ||
| 71 | |||
| 72 | if (of_address_to_resource(np, 0, &r)) { | ||
| 73 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
| 74 | of_node_put(np); | ||
| 75 | return; | ||
| 76 | } | ||
| 77 | |||
| 78 | mpic = mpic_alloc(np, r.start, | ||
| 79 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
| 80 | 0, 256, " OpenPIC "); | 51 | 0, 256, " OpenPIC "); |
| 81 | BUG_ON(mpic == NULL); | 52 | BUG_ON(mpic == NULL); |
| 82 | of_node_put(np); | ||
| 83 | |||
| 84 | mpic_init(mpic); | 53 | mpic_init(mpic); |
| 85 | 54 | ||
| 86 | #ifdef CONFIG_CPM2 | 55 | mpc85xx_cpm2_pic_init(); |
| 87 | /* Setup CPM2 PIC */ | ||
| 88 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
| 89 | if (np == NULL) { | ||
| 90 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
| 91 | return; | ||
| 92 | } | ||
| 93 | irq = irq_of_parse_and_map(np, 0); | ||
| 94 | |||
| 95 | if (irq == NO_IRQ) { | ||
| 96 | of_node_put(np); | ||
| 97 | printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n"); | ||
| 98 | return; | ||
| 99 | } | ||
| 100 | |||
| 101 | cpm2_pic_init(np); | ||
| 102 | of_node_put(np); | ||
| 103 | irq_set_chained_handler(irq, cpm2_cascade); | ||
| 104 | #endif | ||
| 105 | } | 56 | } |
| 106 | 57 | ||
| 107 | /* | 58 | /* |
| @@ -173,19 +124,7 @@ static void __init tqm85xx_ti1520_fixup(struct pci_dev *pdev) | |||
| 173 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, | 124 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, |
| 174 | tqm85xx_ti1520_fixup); | 125 | tqm85xx_ti1520_fixup); |
| 175 | 126 | ||
| 176 | static struct of_device_id __initdata of_bus_ids[] = { | 127 | machine_device_initcall(tqm85xx, mpc85xx_common_publish_devices); |
| 177 | { .compatible = "simple-bus", }, | ||
| 178 | { .compatible = "gianfar", }, | ||
| 179 | {}, | ||
| 180 | }; | ||
| 181 | |||
| 182 | static int __init declare_of_platform_devices(void) | ||
| 183 | { | ||
| 184 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 185 | |||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | machine_device_initcall(tqm85xx, declare_of_platform_devices); | ||
| 189 | 128 | ||
| 190 | static const char *board[] __initdata = { | 129 | static const char *board[] __initdata = { |
| 191 | "tqc,tqm8540", | 130 | "tqc,tqm8540", |
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c index a9dc5e795123..3a69f8b77de6 100644 --- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c | |||
| @@ -32,6 +32,9 @@ | |||
| 32 | 32 | ||
| 33 | #include <sysdev/fsl_soc.h> | 33 | #include <sysdev/fsl_soc.h> |
| 34 | #include <sysdev/fsl_pci.h> | 34 | #include <sysdev/fsl_pci.h> |
| 35 | #include "smp.h" | ||
| 36 | |||
| 37 | #include "mpc85xx.h" | ||
| 35 | 38 | ||
| 36 | /* A few bit definitions needed for fixups on some boards */ | 39 | /* A few bit definitions needed for fixups on some boards */ |
| 37 | #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ | 40 | #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ |
| @@ -40,29 +43,11 @@ | |||
| 40 | 43 | ||
| 41 | void __init xes_mpc85xx_pic_init(void) | 44 | void __init xes_mpc85xx_pic_init(void) |
| 42 | { | 45 | { |
| 43 | struct mpic *mpic; | 46 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 44 | struct resource r; | 47 | MPIC_WANTS_RESET | |
| 45 | struct device_node *np; | ||
| 46 | |||
| 47 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 48 | if (np == NULL) { | ||
| 49 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
| 50 | return; | ||
| 51 | } | ||
| 52 | |||
| 53 | if (of_address_to_resource(np, 0, &r)) { | ||
| 54 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
| 55 | of_node_put(np); | ||
| 56 | return; | ||
| 57 | } | ||
| 58 | |||
| 59 | mpic = mpic_alloc(np, r.start, | ||
| 60 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
| 61 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, | 48 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, |
| 62 | 0, 256, " OpenPIC "); | 49 | 0, 256, " OpenPIC "); |
| 63 | BUG_ON(mpic == NULL); | 50 | BUG_ON(mpic == NULL); |
| 64 | of_node_put(np); | ||
| 65 | |||
| 66 | mpic_init(mpic); | 51 | mpic_init(mpic); |
| 67 | } | 52 | } |
| 68 | 53 | ||
| @@ -136,9 +121,6 @@ static int primary_phb_addr; | |||
| 136 | /* | 121 | /* |
| 137 | * Setup the architecture | 122 | * Setup the architecture |
| 138 | */ | 123 | */ |
| 139 | #ifdef CONFIG_SMP | ||
| 140 | extern void __init mpc85xx_smp_init(void); | ||
| 141 | #endif | ||
| 142 | static void __init xes_mpc85xx_setup_arch(void) | 124 | static void __init xes_mpc85xx_setup_arch(void) |
| 143 | { | 125 | { |
| 144 | #ifdef CONFIG_PCI | 126 | #ifdef CONFIG_PCI |
| @@ -172,26 +154,12 @@ static void __init xes_mpc85xx_setup_arch(void) | |||
| 172 | } | 154 | } |
| 173 | #endif | 155 | #endif |
| 174 | 156 | ||
| 175 | #ifdef CONFIG_SMP | ||
| 176 | mpc85xx_smp_init(); | 157 | mpc85xx_smp_init(); |
| 177 | #endif | ||
| 178 | } | 158 | } |
| 179 | 159 | ||
| 180 | static struct of_device_id __initdata xes_mpc85xx_ids[] = { | 160 | machine_device_initcall(xes_mpc8572, mpc85xx_common_publish_devices); |
| 181 | { .type = "soc", }, | 161 | machine_device_initcall(xes_mpc8548, mpc85xx_common_publish_devices); |
| 182 | { .compatible = "soc", }, | 162 | machine_device_initcall(xes_mpc8540, mpc85xx_common_publish_devices); |
| 183 | { .compatible = "simple-bus", }, | ||
| 184 | { .compatible = "gianfar", }, | ||
| 185 | {}, | ||
| 186 | }; | ||
| 187 | |||
| 188 | static int __init xes_mpc85xx_publish_devices(void) | ||
| 189 | { | ||
| 190 | return of_platform_bus_probe(NULL, xes_mpc85xx_ids, NULL); | ||
| 191 | } | ||
| 192 | machine_device_initcall(xes_mpc8572, xes_mpc85xx_publish_devices); | ||
| 193 | machine_device_initcall(xes_mpc8548, xes_mpc85xx_publish_devices); | ||
| 194 | machine_device_initcall(xes_mpc8540, xes_mpc85xx_publish_devices); | ||
| 195 | 163 | ||
| 196 | /* | 164 | /* |
| 197 | * Called very early, device-tree isn't unflattened | 165 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index b11c3535f350..569262ca499a 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
| @@ -161,7 +161,7 @@ mpc86xx_time_init(void) | |||
| 161 | 161 | ||
| 162 | static __initdata struct of_device_id of_bus_ids[] = { | 162 | static __initdata struct of_device_id of_bus_ids[] = { |
| 163 | { .compatible = "simple-bus", }, | 163 | { .compatible = "simple-bus", }, |
| 164 | { .compatible = "fsl,rapidio-delta", }, | 164 | { .compatible = "fsl,srio", }, |
| 165 | { .compatible = "gianfar", }, | 165 | { .compatible = "gianfar", }, |
| 166 | {}, | 166 | {}, |
| 167 | }; | 167 | }; |
diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c index 8ef8960abda6..52bbfa031531 100644 --- a/arch/powerpc/platforms/86xx/pic.c +++ b/arch/powerpc/platforms/86xx/pic.c | |||
| @@ -31,26 +31,16 @@ static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) | |||
| 31 | 31 | ||
| 32 | void __init mpc86xx_init_irq(void) | 32 | void __init mpc86xx_init_irq(void) |
| 33 | { | 33 | { |
| 34 | struct mpic *mpic; | ||
| 35 | struct device_node *np; | ||
| 36 | struct resource res; | ||
| 37 | #ifdef CONFIG_PPC_I8259 | 34 | #ifdef CONFIG_PPC_I8259 |
| 35 | struct device_node *np; | ||
| 38 | struct device_node *cascade_node = NULL; | 36 | struct device_node *cascade_node = NULL; |
| 39 | int cascade_irq; | 37 | int cascade_irq; |
| 40 | #endif | 38 | #endif |
| 41 | 39 | ||
| 42 | /* Determine PIC address. */ | 40 | struct mpic *mpic = mpic_alloc(NULL, 0, |
| 43 | np = of_find_node_by_type(NULL, "open-pic"); | 41 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
| 44 | if (np == NULL) | 42 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
| 45 | return; | ||
| 46 | of_address_to_resource(np, 0, &res); | ||
| 47 | |||
| 48 | mpic = mpic_alloc(np, res.start, | ||
| 49 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
| 50 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | ||
| 51 | MPIC_SINGLE_DEST_CPU, | ||
| 52 | 0, 256, " MPIC "); | 43 | 0, 256, " MPIC "); |
| 53 | of_node_put(np); | ||
| 54 | BUG_ON(mpic == NULL); | 44 | BUG_ON(mpic == NULL); |
| 55 | 45 | ||
| 56 | mpic_init(mpic); | 46 | mpic_init(mpic); |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 3fe6d927ad70..31e1adeaa92a 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
| @@ -211,6 +211,12 @@ config PPC_PASEMI_CPUFREQ | |||
| 211 | 211 | ||
| 212 | endmenu | 212 | endmenu |
| 213 | 213 | ||
| 214 | menu "CPUIdle driver" | ||
| 215 | |||
| 216 | source "drivers/cpuidle/Kconfig" | ||
| 217 | |||
| 218 | endmenu | ||
| 219 | |||
| 214 | config PPC601_SYNC_FIX | 220 | config PPC601_SYNC_FIX |
| 215 | bool "Workarounds for PPC601 bugs" | 221 | bool "Workarounds for PPC601 bugs" |
| 216 | depends on 6xx && (PPC_PREP || PPC_PMAC) | 222 | depends on 6xx && (PPC_PREP || PPC_PMAC) |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index fbecae0fbb49..425db18580a2 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
| @@ -174,7 +174,6 @@ config BOOKE | |||
| 174 | config FSL_BOOKE | 174 | config FSL_BOOKE |
| 175 | bool | 175 | bool |
| 176 | depends on (E200 || E500) && PPC32 | 176 | depends on (E200 || E500) && PPC32 |
| 177 | select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT | ||
| 178 | default y | 177 | default y |
| 179 | 178 | ||
| 180 | # this is for common code between PPC32 & PPC64 FSL BOOKE | 179 | # this is for common code between PPC32 & PPC64 FSL BOOKE |
| @@ -182,6 +181,7 @@ config PPC_FSL_BOOK3E | |||
| 182 | bool | 181 | bool |
| 183 | select FSL_EMB_PERFMON | 182 | select FSL_EMB_PERFMON |
| 184 | select PPC_SMP_MUXED_IPI | 183 | select PPC_SMP_MUXED_IPI |
| 184 | select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64 | ||
| 185 | default y if FSL_BOOKE | 185 | default y if FSL_BOOKE |
| 186 | 186 | ||
| 187 | config PTE_64BIT | 187 | config PTE_64BIT |
| @@ -236,7 +236,7 @@ config VSX | |||
| 236 | 236 | ||
| 237 | config PPC_ICSWX | 237 | config PPC_ICSWX |
| 238 | bool "Support for PowerPC icswx coprocessor instruction" | 238 | bool "Support for PowerPC icswx coprocessor instruction" |
| 239 | depends on POWER4 | 239 | depends on POWER4 || PPC_A2 |
| 240 | default n | 240 | default n |
| 241 | ---help--- | 241 | ---help--- |
| 242 | 242 | ||
| @@ -252,6 +252,25 @@ config PPC_ICSWX | |||
| 252 | 252 | ||
| 253 | If in doubt, say N here. | 253 | If in doubt, say N here. |
| 254 | 254 | ||
| 255 | config PPC_ICSWX_PID | ||
| 256 | bool "icswx requires direct PID management" | ||
| 257 | depends on PPC_ICSWX && POWER4 | ||
| 258 | default y | ||
| 259 | ---help--- | ||
| 260 | The PID register in server is used explicitly for ICSWX. In | ||
| 261 | embedded systems PID managment is done by the system. | ||
| 262 | |||
| 263 | config PPC_ICSWX_USE_SIGILL | ||
| 264 | bool "Should a bad CT cause a SIGILL?" | ||
| 265 | depends on PPC_ICSWX | ||
| 266 | default n | ||
| 267 | ---help--- | ||
| 268 | Should a bad CT used for "non-record form ICSWX" cause an | ||
| 269 | illegal intruction signal or should it be silent as | ||
| 270 | architected. | ||
| 271 | |||
| 272 | If in doubt, say N here. | ||
| 273 | |||
| 255 | config SPE | 274 | config SPE |
| 256 | bool "SPE Support" | 275 | bool "SPE Support" |
| 257 | depends on E200 || (E500 && !PPC_E500MC) | 276 | depends on E200 || (E500 && !PPC_E500MC) |
| @@ -290,7 +309,7 @@ config PPC_BOOK3E_MMU | |||
| 290 | 309 | ||
| 291 | config PPC_MM_SLICES | 310 | config PPC_MM_SLICES |
| 292 | bool | 311 | bool |
| 293 | default y if (PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) | 312 | default y if (!PPC_FSL_BOOK3E && PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) |
| 294 | default n | 313 | default n |
| 295 | 314 | ||
| 296 | config VIRT_CPU_ACCOUNTING | 315 | config VIRT_CPU_ACCOUNTING |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 592c3d51b817..ae9fc7bc17d6 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
| @@ -1037,6 +1037,8 @@ static int __init cell_iommu_fixed_mapping_init(void) | |||
| 1037 | 1037 | ||
| 1038 | /* The fixed mapping is only supported on axon machines */ | 1038 | /* The fixed mapping is only supported on axon machines */ |
| 1039 | np = of_find_node_by_name(NULL, "axon"); | 1039 | np = of_find_node_by_name(NULL, "axon"); |
| 1040 | of_node_put(np); | ||
| 1041 | |||
| 1040 | if (!np) { | 1042 | if (!np) { |
| 1041 | pr_debug("iommu: fixed mapping disabled, no axons found\n"); | 1043 | pr_debug("iommu: fixed mapping disabled, no axons found\n"); |
| 1042 | return -1; | 1044 | return -1; |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 0fc9b7256126..62002a7edfed 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
| @@ -184,24 +184,10 @@ static int __init cell_publish_devices(void) | |||
| 184 | } | 184 | } |
| 185 | machine_subsys_initcall(cell, cell_publish_devices); | 185 | machine_subsys_initcall(cell, cell_publish_devices); |
| 186 | 186 | ||
| 187 | static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 188 | { | ||
| 189 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 190 | struct mpic *mpic = irq_desc_get_handler_data(desc); | ||
| 191 | unsigned int virq; | ||
| 192 | |||
| 193 | virq = mpic_get_one_irq(mpic); | ||
| 194 | if (virq != NO_IRQ) | ||
| 195 | generic_handle_irq(virq); | ||
| 196 | |||
| 197 | chip->irq_eoi(&desc->irq_data); | ||
| 198 | } | ||
| 199 | |||
| 200 | static void __init mpic_init_IRQ(void) | 187 | static void __init mpic_init_IRQ(void) |
| 201 | { | 188 | { |
| 202 | struct device_node *dn; | 189 | struct device_node *dn; |
| 203 | struct mpic *mpic; | 190 | struct mpic *mpic; |
| 204 | unsigned int virq; | ||
| 205 | 191 | ||
| 206 | for (dn = NULL; | 192 | for (dn = NULL; |
| 207 | (dn = of_find_node_by_name(dn, "interrupt-controller"));) { | 193 | (dn = of_find_node_by_name(dn, "interrupt-controller"));) { |
| @@ -211,19 +197,10 @@ static void __init mpic_init_IRQ(void) | |||
| 211 | /* The MPIC driver will get everything it needs from the | 197 | /* The MPIC driver will get everything it needs from the |
| 212 | * device-tree, just pass 0 to all arguments | 198 | * device-tree, just pass 0 to all arguments |
| 213 | */ | 199 | */ |
| 214 | mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC "); | 200 | mpic = mpic_alloc(dn, 0, MPIC_SECONDARY, 0, 0, " MPIC "); |
| 215 | if (mpic == NULL) | 201 | if (mpic == NULL) |
| 216 | continue; | 202 | continue; |
| 217 | mpic_init(mpic); | 203 | mpic_init(mpic); |
| 218 | |||
| 219 | virq = irq_of_parse_and_map(dn, 0); | ||
| 220 | if (virq == NO_IRQ) | ||
| 221 | continue; | ||
| 222 | |||
| 223 | printk(KERN_INFO "%s : hooking up to IRQ %d\n", | ||
| 224 | dn->full_name, virq); | ||
| 225 | irq_set_handler_data(virq, mpic); | ||
| 226 | irq_set_chained_handler(virq, cell_mpic_cascade); | ||
| 227 | } | 204 | } |
| 228 | } | 205 | } |
| 229 | 206 | ||
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 122786498419..f1f17bb2c33c 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
| @@ -435,8 +435,7 @@ static void __init chrp_find_openpic(void) | |||
| 435 | if (len > 1) | 435 | if (len > 1) |
| 436 | isu_size = iranges[3]; | 436 | isu_size = iranges[3]; |
| 437 | 437 | ||
| 438 | chrp_mpic = mpic_alloc(np, opaddr, MPIC_PRIMARY, | 438 | chrp_mpic = mpic_alloc(np, opaddr, 0, isu_size, 0, " MPIC "); |
| 439 | isu_size, 0, " MPIC "); | ||
| 440 | if (chrp_mpic == NULL) { | 439 | if (chrp_mpic == NULL) { |
| 441 | printk(KERN_ERR "Failed to allocate MPIC structure\n"); | 440 | printk(KERN_ERR "Failed to allocate MPIC structure\n"); |
| 442 | goto bail; | 441 | goto bail; |
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c index 2e9bcf6444c8..9cfcf20c0560 100644 --- a/arch/powerpc/platforms/embedded6xx/holly.c +++ b/arch/powerpc/platforms/embedded6xx/holly.c | |||
| @@ -148,30 +148,14 @@ static void __init holly_setup_arch(void) | |||
| 148 | static void __init holly_init_IRQ(void) | 148 | static void __init holly_init_IRQ(void) |
| 149 | { | 149 | { |
| 150 | struct mpic *mpic; | 150 | struct mpic *mpic; |
| 151 | phys_addr_t mpic_paddr = 0; | ||
| 152 | struct device_node *tsi_pic; | ||
| 153 | #ifdef CONFIG_PCI | 151 | #ifdef CONFIG_PCI |
| 154 | unsigned int cascade_pci_irq; | 152 | unsigned int cascade_pci_irq; |
| 155 | struct device_node *tsi_pci; | 153 | struct device_node *tsi_pci; |
| 156 | struct device_node *cascade_node = NULL; | 154 | struct device_node *cascade_node = NULL; |
| 157 | #endif | 155 | #endif |
| 158 | 156 | ||
| 159 | tsi_pic = of_find_node_by_type(NULL, "open-pic"); | 157 | mpic = mpic_alloc(NULL, 0, |
| 160 | if (tsi_pic) { | 158 | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | |
| 161 | unsigned int size; | ||
| 162 | const void *prop = of_get_property(tsi_pic, "reg", &size); | ||
| 163 | mpic_paddr = of_translate_address(tsi_pic, prop); | ||
| 164 | } | ||
| 165 | |||
| 166 | if (mpic_paddr == 0) { | ||
| 167 | printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__); | ||
| 168 | return; | ||
| 169 | } | ||
| 170 | |||
| 171 | pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr); | ||
| 172 | |||
| 173 | mpic = mpic_alloc(tsi_pic, mpic_paddr, | ||
| 174 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | | ||
| 175 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, | 159 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, |
| 176 | 24, | 160 | 24, |
| 177 | NR_IRQS-4, /* num_sources used */ | 161 | NR_IRQS-4, /* num_sources used */ |
| @@ -179,7 +163,7 @@ static void __init holly_init_IRQ(void) | |||
| 179 | 163 | ||
| 180 | BUG_ON(mpic == NULL); | 164 | BUG_ON(mpic == NULL); |
| 181 | 165 | ||
| 182 | mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); | 166 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x100); |
| 183 | 167 | ||
| 184 | mpic_init(mpic); | 168 | mpic_init(mpic); |
| 185 | 169 | ||
| @@ -204,7 +188,6 @@ static void __init holly_init_IRQ(void) | |||
| 204 | #endif | 188 | #endif |
| 205 | /* Configure MPIC outputs to CPU0 */ | 189 | /* Configure MPIC outputs to CPU0 */ |
| 206 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); | 190 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); |
| 207 | of_node_put(tsi_pic); | ||
| 208 | } | 191 | } |
| 209 | 192 | ||
| 210 | void holly_show_cpuinfo(struct seq_file *m) | 193 | void holly_show_cpuinfo(struct seq_file *m) |
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index 244f997de791..bcfad92c9cec 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c | |||
| @@ -81,29 +81,19 @@ static void __init linkstation_setup_arch(void) | |||
| 81 | static void __init linkstation_init_IRQ(void) | 81 | static void __init linkstation_init_IRQ(void) |
| 82 | { | 82 | { |
| 83 | struct mpic *mpic; | 83 | struct mpic *mpic; |
| 84 | struct device_node *dnp; | ||
| 85 | const u32 *prop; | ||
| 86 | int size; | ||
| 87 | phys_addr_t paddr; | ||
| 88 | 84 | ||
| 89 | dnp = of_find_node_by_type(NULL, "open-pic"); | 85 | mpic = mpic_alloc(NULL, 0, MPIC_WANTS_RESET, |
| 90 | if (dnp == NULL) | 86 | 4, 32, " EPIC "); |
| 91 | return; | ||
| 92 | |||
| 93 | prop = of_get_property(dnp, "reg", &size); | ||
| 94 | paddr = (phys_addr_t)of_translate_address(dnp, prop); | ||
| 95 | |||
| 96 | mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC "); | ||
| 97 | BUG_ON(mpic == NULL); | 87 | BUG_ON(mpic == NULL); |
| 98 | 88 | ||
| 99 | /* PCI IRQs */ | 89 | /* PCI IRQs */ |
| 100 | mpic_assign_isu(mpic, 0, paddr + 0x10200); | 90 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x10200); |
| 101 | 91 | ||
| 102 | /* I2C */ | 92 | /* I2C */ |
| 103 | mpic_assign_isu(mpic, 1, paddr + 0x11000); | 93 | mpic_assign_isu(mpic, 1, mpic->paddr + 0x11000); |
| 104 | 94 | ||
| 105 | /* ttyS0, ttyS1 */ | 95 | /* ttyS0, ttyS1 */ |
| 106 | mpic_assign_isu(mpic, 2, paddr + 0x11100); | 96 | mpic_assign_isu(mpic, 2, mpic->paddr + 0x11100); |
| 107 | 97 | ||
| 108 | mpic_init(mpic); | 98 | mpic_init(mpic); |
| 109 | } | 99 | } |
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index f8f33e16c6b6..f3350d786f5b 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | |||
| @@ -102,31 +102,14 @@ static void __init mpc7448_hpc2_setup_arch(void) | |||
| 102 | static void __init mpc7448_hpc2_init_IRQ(void) | 102 | static void __init mpc7448_hpc2_init_IRQ(void) |
| 103 | { | 103 | { |
| 104 | struct mpic *mpic; | 104 | struct mpic *mpic; |
| 105 | phys_addr_t mpic_paddr = 0; | ||
| 106 | struct device_node *tsi_pic; | ||
| 107 | #ifdef CONFIG_PCI | 105 | #ifdef CONFIG_PCI |
| 108 | unsigned int cascade_pci_irq; | 106 | unsigned int cascade_pci_irq; |
| 109 | struct device_node *tsi_pci; | 107 | struct device_node *tsi_pci; |
| 110 | struct device_node *cascade_node = NULL; | 108 | struct device_node *cascade_node = NULL; |
| 111 | #endif | 109 | #endif |
| 112 | 110 | ||
| 113 | tsi_pic = of_find_node_by_type(NULL, "open-pic"); | 111 | mpic = mpic_alloc(NULL, 0, |
| 114 | if (tsi_pic) { | 112 | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | |
| 115 | unsigned int size; | ||
| 116 | const void *prop = of_get_property(tsi_pic, "reg", &size); | ||
| 117 | mpic_paddr = of_translate_address(tsi_pic, prop); | ||
| 118 | } | ||
| 119 | |||
| 120 | if (mpic_paddr == 0) { | ||
| 121 | printk("%s: No tsi108 PIC found !\n", __func__); | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | |||
| 125 | DBG("%s: tsi108 pic phys_addr = 0x%x\n", __func__, | ||
| 126 | (u32) mpic_paddr); | ||
| 127 | |||
| 128 | mpic = mpic_alloc(tsi_pic, mpic_paddr, | ||
| 129 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | | ||
| 130 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, | 113 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, |
| 131 | 24, | 114 | 24, |
| 132 | NR_IRQS-4, /* num_sources used */ | 115 | NR_IRQS-4, /* num_sources used */ |
| @@ -134,7 +117,7 @@ static void __init mpc7448_hpc2_init_IRQ(void) | |||
| 134 | 117 | ||
| 135 | BUG_ON(mpic == NULL); | 118 | BUG_ON(mpic == NULL); |
| 136 | 119 | ||
| 137 | mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); | 120 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x100); |
| 138 | 121 | ||
| 139 | mpic_init(mpic); | 122 | mpic_init(mpic); |
| 140 | 123 | ||
| @@ -159,7 +142,6 @@ static void __init mpc7448_hpc2_init_IRQ(void) | |||
| 159 | #endif | 142 | #endif |
| 160 | /* Configure MPIC outputs to CPU0 */ | 143 | /* Configure MPIC outputs to CPU0 */ |
| 161 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); | 144 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); |
| 162 | of_node_put(tsi_pic); | ||
| 163 | } | 145 | } |
| 164 | 146 | ||
| 165 | void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) | 147 | void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) |
diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c index f1eebcae9bf0..afa638834965 100644 --- a/arch/powerpc/platforms/embedded6xx/storcenter.c +++ b/arch/powerpc/platforms/embedded6xx/storcenter.c | |||
| @@ -83,35 +83,17 @@ static void __init storcenter_setup_arch(void) | |||
| 83 | static void __init storcenter_init_IRQ(void) | 83 | static void __init storcenter_init_IRQ(void) |
| 84 | { | 84 | { |
| 85 | struct mpic *mpic; | 85 | struct mpic *mpic; |
| 86 | struct device_node *dnp; | ||
| 87 | const void *prop; | ||
| 88 | int size; | ||
| 89 | phys_addr_t paddr; | ||
| 90 | |||
| 91 | dnp = of_find_node_by_type(NULL, "open-pic"); | ||
| 92 | if (dnp == NULL) | ||
| 93 | return; | ||
| 94 | |||
| 95 | prop = of_get_property(dnp, "reg", &size); | ||
| 96 | if (prop == NULL) { | ||
| 97 | of_node_put(dnp); | ||
| 98 | return; | ||
| 99 | } | ||
| 100 | |||
| 101 | paddr = (phys_addr_t)of_translate_address(dnp, prop); | ||
| 102 | mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, | ||
| 103 | 16, 32, " OpenPIC "); | ||
| 104 | |||
| 105 | of_node_put(dnp); | ||
| 106 | 86 | ||
| 87 | mpic = mpic_alloc(NULL, 0, MPIC_WANTS_RESET, | ||
| 88 | 16, 32, " OpenPIC "); | ||
| 107 | BUG_ON(mpic == NULL); | 89 | BUG_ON(mpic == NULL); |
| 108 | 90 | ||
| 109 | /* | 91 | /* |
| 110 | * 16 Serial Interrupts followed by 16 Internal Interrupts. | 92 | * 16 Serial Interrupts followed by 16 Internal Interrupts. |
| 111 | * I2C is the second internal, so it is at 17, 0x11020. | 93 | * I2C is the second internal, so it is at 17, 0x11020. |
| 112 | */ | 94 | */ |
| 113 | mpic_assign_isu(mpic, 0, paddr + 0x10200); | 95 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x10200); |
| 114 | mpic_assign_isu(mpic, 1, paddr + 0x11000); | 96 | mpic_assign_isu(mpic, 1, mpic->paddr + 0x11000); |
| 115 | 97 | ||
| 116 | mpic_init(mpic); | 98 | mpic_init(mpic); |
| 117 | } | 99 | } |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index dd2e48b28508..401e3f3f74c8 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
| @@ -207,6 +207,54 @@ static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose, | |||
| 207 | return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset); | 207 | return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static int u3_ht_root_read_config(struct pci_controller *hose, u8 offset, | ||
| 211 | int len, u32 *val) | ||
| 212 | { | ||
| 213 | volatile void __iomem *addr; | ||
| 214 | |||
| 215 | addr = hose->cfg_addr; | ||
| 216 | addr += ((offset & ~3) << 2) + (4 - len - (offset & 3)); | ||
| 217 | |||
| 218 | switch (len) { | ||
| 219 | case 1: | ||
| 220 | *val = in_8(addr); | ||
| 221 | break; | ||
| 222 | case 2: | ||
| 223 | *val = in_be16(addr); | ||
| 224 | break; | ||
| 225 | default: | ||
| 226 | *val = in_be32(addr); | ||
| 227 | break; | ||
| 228 | } | ||
| 229 | |||
| 230 | return PCIBIOS_SUCCESSFUL; | ||
| 231 | } | ||
| 232 | |||
| 233 | static int u3_ht_root_write_config(struct pci_controller *hose, u8 offset, | ||
| 234 | int len, u32 val) | ||
| 235 | { | ||
| 236 | volatile void __iomem *addr; | ||
| 237 | |||
| 238 | addr = hose->cfg_addr + ((offset & ~3) << 2) + (4 - len - (offset & 3)); | ||
| 239 | |||
| 240 | if (offset >= PCI_BASE_ADDRESS_0 && offset < PCI_CAPABILITY_LIST) | ||
| 241 | return PCIBIOS_SUCCESSFUL; | ||
| 242 | |||
| 243 | switch (len) { | ||
| 244 | case 1: | ||
| 245 | out_8(addr, val); | ||
| 246 | break; | ||
| 247 | case 2: | ||
| 248 | out_be16(addr, val); | ||
| 249 | break; | ||
| 250 | default: | ||
| 251 | out_be32(addr, val); | ||
| 252 | break; | ||
| 253 | } | ||
| 254 | |||
| 255 | return PCIBIOS_SUCCESSFUL; | ||
| 256 | } | ||
| 257 | |||
| 210 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | 258 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, |
| 211 | int offset, int len, u32 *val) | 259 | int offset, int len, u32 *val) |
| 212 | { | 260 | { |
| @@ -217,6 +265,9 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 217 | if (hose == NULL) | 265 | if (hose == NULL) |
| 218 | return PCIBIOS_DEVICE_NOT_FOUND; | 266 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 219 | 267 | ||
| 268 | if (bus->number == hose->first_busno && devfn == PCI_DEVFN(0, 0)) | ||
| 269 | return u3_ht_root_read_config(hose, offset, len, val); | ||
| 270 | |||
| 220 | if (offset > 0xff) | 271 | if (offset > 0xff) |
| 221 | return PCIBIOS_BAD_REGISTER_NUMBER; | 272 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 222 | 273 | ||
| @@ -252,6 +303,9 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 252 | if (hose == NULL) | 303 | if (hose == NULL) |
| 253 | return PCIBIOS_DEVICE_NOT_FOUND; | 304 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 254 | 305 | ||
| 306 | if (bus->number == hose->first_busno && devfn == PCI_DEVFN(0, 0)) | ||
| 307 | return u3_ht_root_write_config(hose, offset, len, val); | ||
| 308 | |||
| 255 | if (offset > 0xff) | 309 | if (offset > 0xff) |
| 256 | return PCIBIOS_BAD_REGISTER_NUMBER; | 310 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 257 | 311 | ||
| @@ -428,6 +482,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
| 428 | * reg_property and using some accessor functions instead | 482 | * reg_property and using some accessor functions instead |
| 429 | */ | 483 | */ |
| 430 | hose->cfg_data = ioremap(0xf2000000, 0x02000000); | 484 | hose->cfg_data = ioremap(0xf2000000, 0x02000000); |
| 485 | hose->cfg_addr = ioremap(0xf8070000, 0x1000); | ||
| 431 | 486 | ||
| 432 | hose->first_busno = 0; | 487 | hose->first_busno = 0; |
| 433 | hose->last_busno = 0xef; | 488 | hose->last_busno = 0xef; |
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 4c372047c94e..0bcbfe7b2c55 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c | |||
| @@ -221,7 +221,7 @@ static void __init maple_init_IRQ(void) | |||
| 221 | unsigned long openpic_addr = 0; | 221 | unsigned long openpic_addr = 0; |
| 222 | int naddr, n, i, opplen, has_isus = 0; | 222 | int naddr, n, i, opplen, has_isus = 0; |
| 223 | struct mpic *mpic; | 223 | struct mpic *mpic; |
| 224 | unsigned int flags = MPIC_PRIMARY; | 224 | unsigned int flags = 0; |
| 225 | 225 | ||
| 226 | /* Locate MPIC in the device-tree. Note that there is a bug | 226 | /* Locate MPIC in the device-tree. Note that there is a bug |
| 227 | * in Maple device-tree where the type of the controller is | 227 | * in Maple device-tree where the type of the controller is |
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 6f3558210554..98b7a7c13176 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c | |||
| @@ -224,7 +224,7 @@ static __init void pas_init_IRQ(void) | |||
| 224 | openpic_addr = of_read_number(opprop, naddr); | 224 | openpic_addr = of_read_number(opprop, naddr); |
| 225 | printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); | 225 | printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); |
| 226 | 226 | ||
| 227 | mpic_flags = MPIC_PRIMARY | MPIC_LARGE_VECTORS | MPIC_NO_BIAS; | 227 | mpic_flags = MPIC_LARGE_VECTORS | MPIC_NO_BIAS; |
| 228 | 228 | ||
| 229 | nmiprop = of_get_property(mpic_node, "nmi-source", NULL); | 229 | nmiprop = of_get_property(mpic_node, "nmi-source", NULL); |
| 230 | if (nmiprop) | 230 | if (nmiprop) |
| @@ -234,7 +234,7 @@ static __init void pas_init_IRQ(void) | |||
| 234 | mpic_flags, 0, 0, "PASEMI-OPIC"); | 234 | mpic_flags, 0, 0, "PASEMI-OPIC"); |
| 235 | BUG_ON(!mpic); | 235 | BUG_ON(!mpic); |
| 236 | 236 | ||
| 237 | mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); | 237 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x10000); |
| 238 | mpic_init(mpic); | 238 | mpic_init(mpic); |
| 239 | /* The NMI/MCK source needs to be prio 15 */ | 239 | /* The NMI/MCK source needs to be prio 15 */ |
| 240 | if (nmiprop) { | 240 | if (nmiprop) { |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 901bfbddc3dd..7761aabfc293 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
| @@ -52,13 +52,8 @@ struct device_node *of_irq_dflt_pic; | |||
| 52 | /* Default addresses */ | 52 | /* Default addresses */ |
| 53 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; | 53 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; |
| 54 | 54 | ||
| 55 | #define GC_LEVEL_MASK 0x3ff00000 | ||
| 56 | #define OHARE_LEVEL_MASK 0x1ff00000 | ||
| 57 | #define HEATHROW_LEVEL_MASK 0x1ff00000 | ||
| 58 | |||
| 59 | static int max_irqs; | 55 | static int max_irqs; |
| 60 | static int max_real_irqs; | 56 | static int max_real_irqs; |
| 61 | static u32 level_mask[4]; | ||
| 62 | 57 | ||
| 63 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); | 58 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); |
| 64 | 59 | ||
| @@ -217,8 +212,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) | |||
| 217 | for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { | 212 | for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { |
| 218 | int i = irq >> 5; | 213 | int i = irq >> 5; |
| 219 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | 214 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; |
| 220 | /* We must read level interrupts from the level register */ | 215 | bits |= in_le32(&pmac_irq_hw[i]->level); |
| 221 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
| 222 | bits &= ppc_cached_irq_mask[i]; | 216 | bits &= ppc_cached_irq_mask[i]; |
| 223 | if (bits == 0) | 217 | if (bits == 0) |
| 224 | continue; | 218 | continue; |
| @@ -248,8 +242,7 @@ static unsigned int pmac_pic_get_irq(void) | |||
| 248 | for (irq = max_real_irqs; (irq -= 32) >= 0; ) { | 242 | for (irq = max_real_irqs; (irq -= 32) >= 0; ) { |
| 249 | int i = irq >> 5; | 243 | int i = irq >> 5; |
| 250 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | 244 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; |
| 251 | /* We must read level interrupts from the level register */ | 245 | bits |= in_le32(&pmac_irq_hw[i]->level); |
| 252 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
| 253 | bits &= ppc_cached_irq_mask[i]; | 246 | bits &= ppc_cached_irq_mask[i]; |
| 254 | if (bits == 0) | 247 | if (bits == 0) |
| 255 | continue; | 248 | continue; |
| @@ -284,19 +277,14 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) | |||
| 284 | static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, | 277 | static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, |
| 285 | irq_hw_number_t hw) | 278 | irq_hw_number_t hw) |
| 286 | { | 279 | { |
| 287 | int level; | ||
| 288 | |||
| 289 | if (hw >= max_irqs) | 280 | if (hw >= max_irqs) |
| 290 | return -EINVAL; | 281 | return -EINVAL; |
| 291 | 282 | ||
| 292 | /* Mark level interrupts, set delayed disable for edge ones and set | 283 | /* Mark level interrupts, set delayed disable for edge ones and set |
| 293 | * handlers | 284 | * handlers |
| 294 | */ | 285 | */ |
| 295 | level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f))); | 286 | irq_set_status_flags(virq, IRQ_LEVEL); |
| 296 | if (level) | 287 | irq_set_chip_and_handler(virq, &pmac_pic, handle_level_irq); |
| 297 | irq_set_status_flags(virq, IRQ_LEVEL); | ||
| 298 | irq_set_chip_and_handler(virq, &pmac_pic, | ||
| 299 | level ? handle_level_irq : handle_edge_irq); | ||
| 300 | return 0; | 288 | return 0; |
| 301 | } | 289 | } |
| 302 | 290 | ||
| @@ -334,21 +322,14 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
| 334 | 322 | ||
| 335 | if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { | 323 | if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { |
| 336 | max_irqs = max_real_irqs = 32; | 324 | max_irqs = max_real_irqs = 32; |
| 337 | level_mask[0] = GC_LEVEL_MASK; | ||
| 338 | } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { | 325 | } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { |
| 339 | max_irqs = max_real_irqs = 32; | 326 | max_irqs = max_real_irqs = 32; |
| 340 | level_mask[0] = OHARE_LEVEL_MASK; | ||
| 341 | |||
| 342 | /* We might have a second cascaded ohare */ | 327 | /* We might have a second cascaded ohare */ |
| 343 | slave = of_find_node_by_name(NULL, "pci106b,7"); | 328 | slave = of_find_node_by_name(NULL, "pci106b,7"); |
| 344 | if (slave) { | 329 | if (slave) |
| 345 | max_irqs = 64; | 330 | max_irqs = 64; |
| 346 | level_mask[1] = OHARE_LEVEL_MASK; | ||
| 347 | } | ||
| 348 | } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { | 331 | } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { |
| 349 | max_irqs = max_real_irqs = 64; | 332 | max_irqs = max_real_irqs = 64; |
| 350 | level_mask[0] = HEATHROW_LEVEL_MASK; | ||
| 351 | level_mask[1] = 0; | ||
| 352 | 333 | ||
| 353 | /* We might have a second cascaded heathrow */ | 334 | /* We might have a second cascaded heathrow */ |
| 354 | slave = of_find_node_by_name(master, "mac-io"); | 335 | slave = of_find_node_by_name(master, "mac-io"); |
| @@ -363,11 +344,8 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
| 363 | } | 344 | } |
| 364 | 345 | ||
| 365 | /* We found a slave */ | 346 | /* We found a slave */ |
| 366 | if (slave) { | 347 | if (slave) |
| 367 | max_irqs = 128; | 348 | max_irqs = 128; |
| 368 | level_mask[2] = HEATHROW_LEVEL_MASK; | ||
| 369 | level_mask[3] = 0; | ||
| 370 | } | ||
| 371 | } | 349 | } |
| 372 | BUG_ON(master == NULL); | 350 | BUG_ON(master == NULL); |
| 373 | 351 | ||
| @@ -464,18 +442,6 @@ int of_irq_map_oldworld(struct device_node *device, int index, | |||
| 464 | } | 442 | } |
| 465 | #endif /* CONFIG_PPC32 */ | 443 | #endif /* CONFIG_PPC32 */ |
| 466 | 444 | ||
| 467 | static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 468 | { | ||
| 469 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 470 | struct mpic *mpic = irq_desc_get_handler_data(desc); | ||
| 471 | unsigned int cascade_irq = mpic_get_one_irq(mpic); | ||
| 472 | |||
| 473 | if (cascade_irq != NO_IRQ) | ||
| 474 | generic_handle_irq(cascade_irq); | ||
| 475 | |||
| 476 | chip->irq_eoi(&desc->irq_data); | ||
| 477 | } | ||
| 478 | |||
| 479 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) | 445 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) |
| 480 | { | 446 | { |
| 481 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) | 447 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) |
| @@ -498,14 +464,8 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, | |||
| 498 | int master) | 464 | int master) |
| 499 | { | 465 | { |
| 500 | const char *name = master ? " MPIC 1 " : " MPIC 2 "; | 466 | const char *name = master ? " MPIC 1 " : " MPIC 2 "; |
| 501 | struct resource r; | ||
| 502 | struct mpic *mpic; | 467 | struct mpic *mpic; |
| 503 | unsigned int flags = master ? MPIC_PRIMARY : 0; | 468 | unsigned int flags = master ? 0 : MPIC_SECONDARY; |
| 504 | int rc; | ||
| 505 | |||
| 506 | rc = of_address_to_resource(np, 0, &r); | ||
| 507 | if (rc) | ||
| 508 | return NULL; | ||
| 509 | 469 | ||
| 510 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); | 470 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); |
| 511 | 471 | ||
| @@ -519,7 +479,7 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, | |||
| 519 | if (master && (flags & MPIC_BIG_ENDIAN)) | 479 | if (master && (flags & MPIC_BIG_ENDIAN)) |
| 520 | flags |= MPIC_U3_HT_IRQS; | 480 | flags |= MPIC_U3_HT_IRQS; |
| 521 | 481 | ||
| 522 | mpic = mpic_alloc(np, r.start, flags, 0, 0, name); | 482 | mpic = mpic_alloc(np, 0, flags, 0, 0, name); |
| 523 | if (mpic == NULL) | 483 | if (mpic == NULL) |
| 524 | return NULL; | 484 | return NULL; |
| 525 | 485 | ||
| @@ -532,7 +492,6 @@ static int __init pmac_pic_probe_mpic(void) | |||
| 532 | { | 492 | { |
| 533 | struct mpic *mpic1, *mpic2; | 493 | struct mpic *mpic1, *mpic2; |
| 534 | struct device_node *np, *master = NULL, *slave = NULL; | 494 | struct device_node *np, *master = NULL, *slave = NULL; |
| 535 | unsigned int cascade; | ||
| 536 | 495 | ||
| 537 | /* We can have up to 2 MPICs cascaded */ | 496 | /* We can have up to 2 MPICs cascaded */ |
| 538 | for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) | 497 | for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) |
| @@ -568,27 +527,14 @@ static int __init pmac_pic_probe_mpic(void) | |||
| 568 | 527 | ||
| 569 | of_node_put(master); | 528 | of_node_put(master); |
| 570 | 529 | ||
| 571 | /* No slave, let's go out */ | 530 | /* Set up a cascaded controller, if present */ |
| 572 | if (slave == NULL) | 531 | if (slave) { |
| 573 | return 0; | 532 | mpic2 = pmac_setup_one_mpic(slave, 0); |
| 574 | 533 | if (mpic2 == NULL) | |
| 575 | /* Get/Map slave interrupt */ | 534 | printk(KERN_ERR "Failed to setup slave MPIC\n"); |
| 576 | cascade = irq_of_parse_and_map(slave, 0); | ||
| 577 | if (cascade == NO_IRQ) { | ||
| 578 | printk(KERN_ERR "Failed to map cascade IRQ\n"); | ||
| 579 | return 0; | ||
| 580 | } | ||
| 581 | |||
| 582 | mpic2 = pmac_setup_one_mpic(slave, 0); | ||
| 583 | if (mpic2 == NULL) { | ||
| 584 | printk(KERN_ERR "Failed to setup slave MPIC\n"); | ||
| 585 | of_node_put(slave); | 535 | of_node_put(slave); |
| 586 | return 0; | ||
| 587 | } | 536 | } |
| 588 | irq_set_handler_data(cascade, mpic2); | ||
| 589 | irq_set_chained_handler(cascade, pmac_u3_cascade); | ||
| 590 | 537 | ||
| 591 | of_node_put(slave); | ||
| 592 | return 0; | 538 | return 0; |
| 593 | } | 539 | } |
| 594 | 540 | ||
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 96580b189ec2..970ea1de4298 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
| @@ -494,11 +494,15 @@ static int __init pmac_declare_of_platform_devices(void) | |||
| 494 | return -1; | 494 | return -1; |
| 495 | 495 | ||
| 496 | np = of_find_node_by_name(NULL, "valkyrie"); | 496 | np = of_find_node_by_name(NULL, "valkyrie"); |
| 497 | if (np) | 497 | if (np) { |
| 498 | of_platform_device_create(np, "valkyrie", NULL); | 498 | of_platform_device_create(np, "valkyrie", NULL); |
| 499 | of_node_put(np); | ||
| 500 | } | ||
| 499 | np = of_find_node_by_name(NULL, "platinum"); | 501 | np = of_find_node_by_name(NULL, "platinum"); |
| 500 | if (np) | 502 | if (np) { |
| 501 | of_platform_device_create(np, "platinum", NULL); | 503 | of_platform_device_create(np, "platinum", NULL); |
| 504 | of_node_put(np); | ||
| 505 | } | ||
| 502 | np = of_find_node_by_type(NULL, "smu"); | 506 | np = of_find_node_by_type(NULL, "smu"); |
| 503 | if (np) { | 507 | if (np) { |
| 504 | of_platform_device_create(np, "smu", NULL); | 508 | of_platform_device_create(np, "smu", NULL); |
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 9b6a820bdd7d..44d769258ebf 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
| @@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void) | |||
| 200 | 200 | ||
| 201 | if (psurge_secondary_virq) | 201 | if (psurge_secondary_virq) |
| 202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, | 202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, |
| 203 | IRQF_PERCPU, "IPI", NULL); | 203 | IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL); |
| 204 | 204 | ||
| 205 | if (rc) | 205 | if (rc) |
| 206 | pr_err("Failed to setup secondary cpu IPI\n"); | 206 | pr_err("Failed to setup secondary cpu IPI\n"); |
| @@ -408,13 +408,13 @@ static int __init smp_psurge_kick_cpu(int nr) | |||
| 408 | 408 | ||
| 409 | static struct irqaction psurge_irqaction = { | 409 | static struct irqaction psurge_irqaction = { |
| 410 | .handler = psurge_ipi_intr, | 410 | .handler = psurge_ipi_intr, |
| 411 | .flags = IRQF_PERCPU, | 411 | .flags = IRQF_PERCPU | IRQF_NO_THREAD, |
| 412 | .name = "primary IPI", | 412 | .name = "primary IPI", |
| 413 | }; | 413 | }; |
| 414 | 414 | ||
| 415 | static void __init smp_psurge_setup_cpu(int cpu_nr) | 415 | static void __init smp_psurge_setup_cpu(int cpu_nr) |
| 416 | { | 416 | { |
| 417 | if (cpu_nr != 0) | 417 | if (cpu_nr != 0 || !psurge_start) |
| 418 | return; | 418 | return; |
| 419 | 419 | ||
| 420 | /* reset the entry point so if we get another intr we won't | 420 | /* reset the entry point so if we get another intr we won't |
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 31853008b418..bcc3cb48a44e 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile | |||
| @@ -2,4 +2,4 @@ obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o | |||
| 2 | obj-y += opal-rtc.o opal-nvram.o | 2 | obj-y += opal-rtc.o opal-nvram.o |
| 3 | 3 | ||
| 4 | obj-$(CONFIG_SMP) += smp.o | 4 | obj-$(CONFIG_SMP) += smp.o |
| 5 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o | 5 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 4a3f46d8533e..3bb07e5e43cd 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
| @@ -99,3 +99,11 @@ OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL); | |||
| 99 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); | 99 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); |
| 100 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); | 100 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); |
| 101 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); | 101 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); |
| 102 | OPAL_CALL(opal_pci_get_hub_diag_data, OPAL_PCI_GET_HUB_DIAG_DATA); | ||
| 103 | OPAL_CALL(opal_pci_get_phb_diag_data, OPAL_PCI_GET_PHB_DIAG_DATA); | ||
| 104 | OPAL_CALL(opal_pci_fence_phb, OPAL_PCI_FENCE_PHB); | ||
| 105 | OPAL_CALL(opal_pci_reinit, OPAL_PCI_REINIT); | ||
| 106 | OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); | ||
| 107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | ||
| 108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | ||
| 109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c new file mode 100644 index 000000000000..f31162cfdaa9 --- /dev/null +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
| @@ -0,0 +1,1330 @@ | |||
| 1 | /* | ||
| 2 | * Support PCI/PCIe on PowerNV platforms | ||
| 3 | * | ||
| 4 | * Copyright 2011 Benjamin Herrenschmidt, 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/kernel.h> | ||
| 15 | #include <linux/pci.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/bootmem.h> | ||
| 20 | #include <linux/irq.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/msi.h> | ||
| 23 | |||
| 24 | #include <asm/sections.h> | ||
| 25 | #include <asm/io.h> | ||
| 26 | #include <asm/prom.h> | ||
| 27 | #include <asm/pci-bridge.h> | ||
| 28 | #include <asm/machdep.h> | ||
| 29 | #include <asm/ppc-pci.h> | ||
| 30 | #include <asm/opal.h> | ||
| 31 | #include <asm/iommu.h> | ||
| 32 | #include <asm/tce.h> | ||
| 33 | #include <asm/abs_addr.h> | ||
| 34 | |||
| 35 | #include "powernv.h" | ||
| 36 | #include "pci.h" | ||
| 37 | |||
| 38 | struct resource_wrap { | ||
| 39 | struct list_head link; | ||
| 40 | resource_size_t size; | ||
| 41 | resource_size_t align; | ||
| 42 | struct pci_dev *dev; /* Set if it's a device */ | ||
| 43 | struct pci_bus *bus; /* Set if it's a bridge */ | ||
| 44 | }; | ||
| 45 | |||
| 46 | static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe, | ||
| 47 | struct va_format *vaf) | ||
| 48 | { | ||
| 49 | char pfix[32]; | ||
| 50 | |||
| 51 | if (pe->pdev) | ||
| 52 | strlcpy(pfix, dev_name(&pe->pdev->dev), sizeof(pfix)); | ||
| 53 | else | ||
| 54 | sprintf(pfix, "%04x:%02x ", | ||
| 55 | pci_domain_nr(pe->pbus), pe->pbus->number); | ||
| 56 | return printk("pci %s%s: [PE# %.3d] %pV", level, pfix, pe->pe_number, vaf); | ||
| 57 | } | ||
| 58 | |||
| 59 | #define define_pe_printk_level(func, kern_level) \ | ||
| 60 | static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \ | ||
| 61 | { \ | ||
| 62 | struct va_format vaf; \ | ||
| 63 | va_list args; \ | ||
| 64 | int r; \ | ||
| 65 | \ | ||
| 66 | va_start(args, fmt); \ | ||
| 67 | \ | ||
| 68 | vaf.fmt = fmt; \ | ||
| 69 | vaf.va = &args; \ | ||
| 70 | \ | ||
| 71 | r = __pe_printk(kern_level, pe, &vaf); \ | ||
| 72 | va_end(args); \ | ||
| 73 | \ | ||
| 74 | return r; \ | ||
| 75 | } \ | ||
| 76 | |||
| 77 | define_pe_printk_level(pe_err, KERN_ERR); | ||
| 78 | define_pe_printk_level(pe_warn, KERN_WARNING); | ||
| 79 | define_pe_printk_level(pe_info, KERN_INFO); | ||
| 80 | |||
| 81 | |||
| 82 | /* Calculate resource usage & alignment requirement of a single | ||
| 83 | * device. This will also assign all resources within the device | ||
| 84 | * for a given type starting at 0 for the biggest one and then | ||
| 85 | * assigning in decreasing order of size. | ||
| 86 | */ | ||
| 87 | static void __devinit pnv_ioda_calc_dev(struct pci_dev *dev, unsigned int flags, | ||
| 88 | resource_size_t *size, | ||
| 89 | resource_size_t *align) | ||
| 90 | { | ||
| 91 | resource_size_t start; | ||
| 92 | struct resource *r; | ||
| 93 | int i; | ||
| 94 | |||
| 95 | pr_devel(" -> CDR %s\n", pci_name(dev)); | ||
| 96 | |||
| 97 | *size = *align = 0; | ||
| 98 | |||
| 99 | /* Clear the resources out and mark them all unset */ | ||
| 100 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
| 101 | r = &dev->resource[i]; | ||
| 102 | if (!(r->flags & flags)) | ||
| 103 | continue; | ||
| 104 | if (r->start) { | ||
| 105 | r->end -= r->start; | ||
| 106 | r->start = 0; | ||
| 107 | } | ||
| 108 | r->flags |= IORESOURCE_UNSET; | ||
| 109 | } | ||
| 110 | |||
| 111 | /* We currently keep all memory resources together, we | ||
| 112 | * will handle prefetch & 64-bit separately in the future | ||
| 113 | * but for now we stick everybody in M32 | ||
| 114 | */ | ||
| 115 | start = 0; | ||
| 116 | for (;;) { | ||
| 117 | resource_size_t max_size = 0; | ||
| 118 | int max_no = -1; | ||
| 119 | |||
| 120 | /* Find next biggest resource */ | ||
| 121 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
| 122 | r = &dev->resource[i]; | ||
| 123 | if (!(r->flags & IORESOURCE_UNSET) || | ||
| 124 | !(r->flags & flags)) | ||
| 125 | continue; | ||
| 126 | if (resource_size(r) > max_size) { | ||
| 127 | max_size = resource_size(r); | ||
| 128 | max_no = i; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | if (max_no < 0) | ||
| 132 | break; | ||
| 133 | r = &dev->resource[max_no]; | ||
| 134 | if (max_size > *align) | ||
| 135 | *align = max_size; | ||
| 136 | *size += max_size; | ||
| 137 | r->start = start; | ||
| 138 | start += max_size; | ||
| 139 | r->end = r->start + max_size - 1; | ||
| 140 | r->flags &= ~IORESOURCE_UNSET; | ||
| 141 | pr_devel(" -> R%d %016llx..%016llx\n", | ||
| 142 | max_no, r->start, r->end); | ||
| 143 | } | ||
| 144 | pr_devel(" <- CDR %s size=%llx align=%llx\n", | ||
| 145 | pci_name(dev), *size, *align); | ||
| 146 | } | ||
| 147 | |||
| 148 | /* Allocate a resource "wrap" for a given device or bridge and | ||
| 149 | * insert it at the right position in the sorted list | ||
| 150 | */ | ||
| 151 | static void __devinit pnv_ioda_add_wrap(struct list_head *list, | ||
| 152 | struct pci_bus *bus, | ||
| 153 | struct pci_dev *dev, | ||
| 154 | resource_size_t size, | ||
| 155 | resource_size_t align) | ||
| 156 | { | ||
| 157 | struct resource_wrap *w1, *w = kzalloc(sizeof(*w), GFP_KERNEL); | ||
| 158 | |||
| 159 | w->size = size; | ||
| 160 | w->align = align; | ||
| 161 | w->dev = dev; | ||
| 162 | w->bus = bus; | ||
| 163 | |||
| 164 | list_for_each_entry(w1, list, link) { | ||
| 165 | if (w1->align < align) { | ||
| 166 | list_add_tail(&w->link, &w1->link); | ||
| 167 | return; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | list_add_tail(&w->link, list); | ||
| 171 | } | ||
| 172 | |||
| 173 | /* Offset device resources of a given type */ | ||
| 174 | static void __devinit pnv_ioda_offset_dev(struct pci_dev *dev, | ||
| 175 | unsigned int flags, | ||
| 176 | resource_size_t offset) | ||
| 177 | { | ||
| 178 | struct resource *r; | ||
| 179 | int i; | ||
| 180 | |||
| 181 | pr_devel(" -> ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); | ||
| 182 | |||
| 183 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
| 184 | r = &dev->resource[i]; | ||
| 185 | if (r->flags & flags) { | ||
| 186 | dev->resource[i].start += offset; | ||
| 187 | dev->resource[i].end += offset; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | pr_devel(" <- ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); | ||
| 192 | } | ||
| 193 | |||
| 194 | /* Offset bus resources (& all children) of a given type */ | ||
| 195 | static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus, | ||
| 196 | unsigned int flags, | ||
| 197 | resource_size_t offset) | ||
| 198 | { | ||
| 199 | struct resource *r; | ||
| 200 | struct pci_dev *dev; | ||
| 201 | struct pci_bus *cbus; | ||
| 202 | int i; | ||
| 203 | |||
| 204 | pr_devel(" -> OBR %s [%x] +%016llx\n", | ||
| 205 | bus->self ? pci_name(bus->self) : "root", flags, offset); | ||
| 206 | |||
| 207 | for (i = 0; i < 2; i++) { | ||
| 208 | r = bus->resource[i]; | ||
| 209 | if (r && (r->flags & flags)) { | ||
| 210 | bus->resource[i]->start += offset; | ||
| 211 | bus->resource[i]->end += offset; | ||
| 212 | } | ||
| 213 | } | ||
| 214 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
| 215 | pnv_ioda_offset_dev(dev, flags, offset); | ||
| 216 | list_for_each_entry(cbus, &bus->children, node) | ||
| 217 | pnv_ioda_offset_bus(cbus, flags, offset); | ||
| 218 | |||
| 219 | pr_devel(" <- OBR %s [%x]\n", | ||
| 220 | bus->self ? pci_name(bus->self) : "root", flags); | ||
| 221 | } | ||
| 222 | |||
| 223 | /* This is the guts of our IODA resource allocation. This is called | ||
| 224 | * recursively for each bus in the system. It calculates all the | ||
| 225 | * necessary size and requirements for children and assign them | ||
| 226 | * resources such that: | ||
| 227 | * | ||
| 228 | * - Each function fits in it's own contiguous set of IO/M32 | ||
| 229 | * segment | ||
| 230 | * | ||
| 231 | * - All segments behind a P2P bridge are contiguous and obey | ||
| 232 | * alignment constraints of those bridges | ||
| 233 | */ | ||
| 234 | static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags, | ||
| 235 | resource_size_t *size, | ||
| 236 | resource_size_t *align) | ||
| 237 | { | ||
| 238 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
| 239 | struct pnv_phb *phb = hose->private_data; | ||
| 240 | resource_size_t dev_size, dev_align, start; | ||
| 241 | resource_size_t min_align, min_balign; | ||
| 242 | struct pci_dev *cdev; | ||
| 243 | struct pci_bus *cbus; | ||
| 244 | struct list_head head; | ||
| 245 | struct resource_wrap *w; | ||
| 246 | unsigned int bres; | ||
| 247 | |||
| 248 | *size = *align = 0; | ||
| 249 | |||
| 250 | pr_devel("-> CBR %s [%x]\n", | ||
| 251 | bus->self ? pci_name(bus->self) : "root", flags); | ||
| 252 | |||
| 253 | /* Calculate alignment requirements based on the type | ||
| 254 | * of resource we are working on | ||
| 255 | */ | ||
| 256 | if (flags & IORESOURCE_IO) { | ||
| 257 | bres = 0; | ||
| 258 | min_align = phb->ioda.io_segsize; | ||
| 259 | min_balign = 0x1000; | ||
| 260 | } else { | ||
| 261 | bres = 1; | ||
| 262 | min_align = phb->ioda.m32_segsize; | ||
| 263 | min_balign = 0x100000; | ||
| 264 | } | ||
| 265 | |||
| 266 | /* Gather all our children resources ordered by alignment */ | ||
| 267 | INIT_LIST_HEAD(&head); | ||
| 268 | |||
| 269 | /* - Busses */ | ||
| 270 | list_for_each_entry(cbus, &bus->children, node) { | ||
| 271 | pnv_ioda_calc_bus(cbus, flags, &dev_size, &dev_align); | ||
| 272 | pnv_ioda_add_wrap(&head, cbus, NULL, dev_size, dev_align); | ||
| 273 | } | ||
| 274 | |||
| 275 | /* - Devices */ | ||
| 276 | list_for_each_entry(cdev, &bus->devices, bus_list) { | ||
| 277 | pnv_ioda_calc_dev(cdev, flags, &dev_size, &dev_align); | ||
| 278 | /* Align them to segment size */ | ||
| 279 | if (dev_align < min_align) | ||
| 280 | dev_align = min_align; | ||
| 281 | pnv_ioda_add_wrap(&head, NULL, cdev, dev_size, dev_align); | ||
| 282 | } | ||
| 283 | if (list_empty(&head)) | ||
| 284 | goto empty; | ||
| 285 | |||
| 286 | /* Now we can do two things: assign offsets to them within that | ||
| 287 | * level and get our total alignment & size requirements. The | ||
| 288 | * assignment algorithm is going to be uber-trivial for now, we | ||
| 289 | * can try to be smarter later at filling out holes. | ||
| 290 | */ | ||
| 291 | start = bus->self ? 0 : bus->resource[bres]->start; | ||
| 292 | |||
| 293 | /* Don't hand out IO 0 */ | ||
| 294 | if ((flags & IORESOURCE_IO) && !bus->self) | ||
| 295 | start += 0x1000; | ||
| 296 | |||
| 297 | while(!list_empty(&head)) { | ||
| 298 | w = list_first_entry(&head, struct resource_wrap, link); | ||
| 299 | list_del(&w->link); | ||
| 300 | if (w->size) { | ||
| 301 | if (start) { | ||
| 302 | start = ALIGN(start, w->align); | ||
| 303 | if (w->dev) | ||
| 304 | pnv_ioda_offset_dev(w->dev,flags,start); | ||
| 305 | else if (w->bus) | ||
| 306 | pnv_ioda_offset_bus(w->bus,flags,start); | ||
| 307 | } | ||
| 308 | if (w->align > *align) | ||
| 309 | *align = w->align; | ||
| 310 | } | ||
| 311 | start += w->size; | ||
| 312 | kfree(w); | ||
| 313 | } | ||
| 314 | *size = start; | ||
| 315 | |||
| 316 | /* Align and setup bridge resources */ | ||
| 317 | *align = max_t(resource_size_t, *align, | ||
| 318 | max_t(resource_size_t, min_align, min_balign)); | ||
| 319 | *size = ALIGN(*size, | ||
| 320 | max_t(resource_size_t, min_align, min_balign)); | ||
| 321 | empty: | ||
| 322 | /* Only setup P2P's, not the PHB itself */ | ||
| 323 | if (bus->self) { | ||
| 324 | WARN_ON(bus->resource[bres] == NULL); | ||
| 325 | bus->resource[bres]->start = 0; | ||
| 326 | bus->resource[bres]->flags = (*size) ? flags : 0; | ||
| 327 | bus->resource[bres]->end = (*size) ? (*size - 1) : 0; | ||
| 328 | |||
| 329 | /* Clear prefetch bus resources for now */ | ||
| 330 | bus->resource[2]->flags = 0; | ||
| 331 | } | ||
| 332 | |||
| 333 | pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n", | ||
| 334 | bus->self ? pci_name(bus->self) : "root", flags,*size,*align); | ||
| 335 | } | ||
| 336 | |||
| 337 | static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) | ||
| 338 | { | ||
| 339 | struct device_node *np; | ||
| 340 | |||
| 341 | np = pci_device_to_OF_node(dev); | ||
| 342 | if (!np) | ||
| 343 | return NULL; | ||
| 344 | return PCI_DN(np); | ||
| 345 | } | ||
| 346 | |||
| 347 | static void __devinit pnv_ioda_setup_pe_segments(struct pci_dev *dev) | ||
| 348 | { | ||
| 349 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
| 350 | struct pnv_phb *phb = hose->private_data; | ||
| 351 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
| 352 | unsigned int pe, i; | ||
| 353 | resource_size_t pos; | ||
| 354 | struct resource io_res; | ||
| 355 | struct resource m32_res; | ||
| 356 | struct pci_bus_region region; | ||
| 357 | int rc; | ||
| 358 | |||
| 359 | /* Anything not referenced in the device-tree gets PE#0 */ | ||
| 360 | pe = pdn ? pdn->pe_number : 0; | ||
| 361 | |||
| 362 | /* Calculate the device min/max */ | ||
| 363 | io_res.start = m32_res.start = (resource_size_t)-1; | ||
| 364 | io_res.end = m32_res.end = 0; | ||
| 365 | io_res.flags = IORESOURCE_IO; | ||
| 366 | m32_res.flags = IORESOURCE_MEM; | ||
| 367 | |||
| 368 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
| 369 | struct resource *r = NULL; | ||
| 370 | if (dev->resource[i].flags & IORESOURCE_IO) | ||
| 371 | r = &io_res; | ||
| 372 | if (dev->resource[i].flags & IORESOURCE_MEM) | ||
| 373 | r = &m32_res; | ||
| 374 | if (!r) | ||
| 375 | continue; | ||
| 376 | if (dev->resource[i].start < r->start) | ||
| 377 | r->start = dev->resource[i].start; | ||
| 378 | if (dev->resource[i].end > r->end) | ||
| 379 | r->end = dev->resource[i].end; | ||
| 380 | } | ||
| 381 | |||
| 382 | /* Setup IO segments */ | ||
| 383 | if (io_res.start < io_res.end) { | ||
| 384 | pcibios_resource_to_bus(dev, ®ion, &io_res); | ||
| 385 | pos = region.start; | ||
| 386 | i = pos / phb->ioda.io_segsize; | ||
| 387 | while(i < phb->ioda.total_pe && pos <= region.end) { | ||
| 388 | if (phb->ioda.io_segmap[i]) { | ||
| 389 | pr_err("%s: Trying to use IO seg #%d which is" | ||
| 390 | " already used by PE# %d\n", | ||
| 391 | pci_name(dev), i, | ||
| 392 | phb->ioda.io_segmap[i]); | ||
| 393 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
| 394 | break; | ||
| 395 | } | ||
| 396 | phb->ioda.io_segmap[i] = pe; | ||
| 397 | rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, | ||
| 398 | OPAL_IO_WINDOW_TYPE, | ||
| 399 | 0, i); | ||
| 400 | if (rc != OPAL_SUCCESS) { | ||
| 401 | pr_err("%s: OPAL error %d setting up mapping" | ||
| 402 | " for IO seg# %d\n", | ||
| 403 | pci_name(dev), rc, i); | ||
| 404 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
| 405 | break; | ||
| 406 | } | ||
| 407 | pos += phb->ioda.io_segsize; | ||
| 408 | i++; | ||
| 409 | }; | ||
| 410 | } | ||
| 411 | |||
| 412 | /* Setup M32 segments */ | ||
| 413 | if (m32_res.start < m32_res.end) { | ||
| 414 | pcibios_resource_to_bus(dev, ®ion, &m32_res); | ||
| 415 | pos = region.start; | ||
| 416 | i = pos / phb->ioda.m32_segsize; | ||
| 417 | while(i < phb->ioda.total_pe && pos <= region.end) { | ||
| 418 | if (phb->ioda.m32_segmap[i]) { | ||
| 419 | pr_err("%s: Trying to use M32 seg #%d which is" | ||
| 420 | " already used by PE# %d\n", | ||
| 421 | pci_name(dev), i, | ||
| 422 | phb->ioda.m32_segmap[i]); | ||
| 423 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | phb->ioda.m32_segmap[i] = pe; | ||
| 427 | rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, | ||
| 428 | OPAL_M32_WINDOW_TYPE, | ||
| 429 | 0, i); | ||
| 430 | if (rc != OPAL_SUCCESS) { | ||
| 431 | pr_err("%s: OPAL error %d setting up mapping" | ||
| 432 | " for M32 seg# %d\n", | ||
| 433 | pci_name(dev), rc, i); | ||
| 434 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
| 435 | break; | ||
| 436 | } | ||
| 437 | pos += phb->ioda.m32_segsize; | ||
| 438 | i++; | ||
| 439 | } | ||
| 440 | } | ||
| 441 | } | ||
| 442 | |||
| 443 | /* Check if a resource still fits in the total IO or M32 range | ||
| 444 | * for a given PHB | ||
| 445 | */ | ||
| 446 | static int __devinit pnv_ioda_resource_fit(struct pci_controller *hose, | ||
| 447 | struct resource *r) | ||
| 448 | { | ||
| 449 | struct resource *bounds; | ||
| 450 | |||
| 451 | if (r->flags & IORESOURCE_IO) | ||
| 452 | bounds = &hose->io_resource; | ||
| 453 | else if (r->flags & IORESOURCE_MEM) | ||
| 454 | bounds = &hose->mem_resources[0]; | ||
| 455 | else | ||
| 456 | return 1; | ||
| 457 | |||
| 458 | if (r->start >= bounds->start && r->end <= bounds->end) | ||
| 459 | return 1; | ||
| 460 | r->flags = 0; | ||
| 461 | return 0; | ||
| 462 | } | ||
| 463 | |||
| 464 | static void __devinit pnv_ioda_update_resources(struct pci_bus *bus) | ||
| 465 | { | ||
| 466 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
| 467 | struct pci_bus *cbus; | ||
| 468 | struct pci_dev *cdev; | ||
| 469 | unsigned int i; | ||
| 470 | |||
| 471 | /* We used to clear all device enables here. However it looks like | ||
| 472 | * clearing MEM enable causes Obsidian (IPR SCS) to go bonkers, | ||
| 473 | * and shoot fatal errors to the PHB which in turns fences itself | ||
| 474 | * and we can't recover from that ... yet. So for now, let's leave | ||
| 475 | * the enables as-is and hope for the best. | ||
| 476 | */ | ||
| 477 | |||
| 478 | /* Check if bus resources fit in our IO or M32 range */ | ||
| 479 | for (i = 0; bus->self && (i < 2); i++) { | ||
| 480 | struct resource *r = bus->resource[i]; | ||
| 481 | if (r && !pnv_ioda_resource_fit(hose, r)) | ||
| 482 | pr_err("%s: Bus %d resource %d disabled, no room\n", | ||
| 483 | pci_name(bus->self), bus->number, i); | ||
| 484 | } | ||
| 485 | |||
| 486 | /* Update self if it's not a PHB */ | ||
| 487 | if (bus->self) | ||
| 488 | pci_setup_bridge(bus); | ||
| 489 | |||
| 490 | /* Update child devices */ | ||
| 491 | list_for_each_entry(cdev, &bus->devices, bus_list) { | ||
| 492 | /* Check if resource fits, if not, disabled it */ | ||
| 493 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
| 494 | struct resource *r = &cdev->resource[i]; | ||
| 495 | if (!pnv_ioda_resource_fit(hose, r)) | ||
| 496 | pr_err("%s: Resource %d disabled, no room\n", | ||
| 497 | pci_name(cdev), i); | ||
| 498 | } | ||
| 499 | |||
| 500 | /* Assign segments */ | ||
| 501 | pnv_ioda_setup_pe_segments(cdev); | ||
| 502 | |||
| 503 | /* Update HW BARs */ | ||
| 504 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) | ||
| 505 | pci_update_resource(cdev, i); | ||
| 506 | } | ||
| 507 | |||
| 508 | /* Update child busses */ | ||
| 509 | list_for_each_entry(cbus, &bus->children, node) | ||
| 510 | pnv_ioda_update_resources(cbus); | ||
| 511 | } | ||
| 512 | |||
| 513 | static int __devinit pnv_ioda_alloc_pe(struct pnv_phb *phb) | ||
| 514 | { | ||
| 515 | unsigned long pe; | ||
| 516 | |||
| 517 | do { | ||
| 518 | pe = find_next_zero_bit(phb->ioda.pe_alloc, | ||
| 519 | phb->ioda.total_pe, 0); | ||
| 520 | if (pe >= phb->ioda.total_pe) | ||
| 521 | return IODA_INVALID_PE; | ||
| 522 | } while(test_and_set_bit(pe, phb->ioda.pe_alloc)); | ||
| 523 | |||
| 524 | phb->ioda.pe_array[pe].pe_number = pe; | ||
| 525 | return pe; | ||
| 526 | } | ||
| 527 | |||
| 528 | static void __devinit pnv_ioda_free_pe(struct pnv_phb *phb, int pe) | ||
| 529 | { | ||
| 530 | WARN_ON(phb->ioda.pe_array[pe].pdev); | ||
| 531 | |||
| 532 | memset(&phb->ioda.pe_array[pe], 0, sizeof(struct pnv_ioda_pe)); | ||
| 533 | clear_bit(pe, phb->ioda.pe_alloc); | ||
| 534 | } | ||
| 535 | |||
| 536 | /* Currently those 2 are only used when MSIs are enabled, this will change | ||
| 537 | * but in the meantime, we need to protect them to avoid warnings | ||
| 538 | */ | ||
| 539 | #ifdef CONFIG_PCI_MSI | ||
| 540 | static struct pnv_ioda_pe * __devinit __pnv_ioda_get_one_pe(struct pci_dev *dev) | ||
| 541 | { | ||
| 542 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
| 543 | struct pnv_phb *phb = hose->private_data; | ||
| 544 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
| 545 | |||
| 546 | if (!pdn) | ||
| 547 | return NULL; | ||
| 548 | if (pdn->pe_number == IODA_INVALID_PE) | ||
| 549 | return NULL; | ||
| 550 | return &phb->ioda.pe_array[pdn->pe_number]; | ||
| 551 | } | ||
| 552 | |||
| 553 | static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev) | ||
| 554 | { | ||
| 555 | struct pnv_ioda_pe *pe = __pnv_ioda_get_one_pe(dev); | ||
| 556 | |||
| 557 | while (!pe && dev->bus->self) { | ||
| 558 | dev = dev->bus->self; | ||
| 559 | pe = __pnv_ioda_get_one_pe(dev); | ||
| 560 | if (pe) | ||
| 561 | pe = pe->bus_pe; | ||
| 562 | } | ||
| 563 | return pe; | ||
| 564 | } | ||
| 565 | #endif /* CONFIG_PCI_MSI */ | ||
| 566 | |||
| 567 | static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, | ||
| 568 | struct pnv_ioda_pe *pe) | ||
| 569 | { | ||
| 570 | struct pci_dev *parent; | ||
| 571 | uint8_t bcomp, dcomp, fcomp; | ||
| 572 | long rc, rid_end, rid; | ||
| 573 | |||
| 574 | /* Bus validation ? */ | ||
| 575 | if (pe->pbus) { | ||
| 576 | int count; | ||
| 577 | |||
| 578 | dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; | ||
| 579 | fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; | ||
| 580 | parent = pe->pbus->self; | ||
| 581 | count = pe->pbus->subordinate - pe->pbus->secondary + 1; | ||
| 582 | switch(count) { | ||
| 583 | case 1: bcomp = OpalPciBusAll; break; | ||
| 584 | case 2: bcomp = OpalPciBus7Bits; break; | ||
| 585 | case 4: bcomp = OpalPciBus6Bits; break; | ||
| 586 | case 8: bcomp = OpalPciBus5Bits; break; | ||
| 587 | case 16: bcomp = OpalPciBus4Bits; break; | ||
| 588 | case 32: bcomp = OpalPciBus3Bits; break; | ||
| 589 | default: | ||
| 590 | pr_err("%s: Number of subordinate busses %d" | ||
| 591 | " unsupported\n", | ||
| 592 | pci_name(pe->pbus->self), count); | ||
| 593 | /* Do an exact match only */ | ||
| 594 | bcomp = OpalPciBusAll; | ||
| 595 | } | ||
| 596 | rid_end = pe->rid + (count << 8); | ||
| 597 | } else { | ||
| 598 | parent = pe->pdev->bus->self; | ||
| 599 | bcomp = OpalPciBusAll; | ||
| 600 | dcomp = OPAL_COMPARE_RID_DEVICE_NUMBER; | ||
| 601 | fcomp = OPAL_COMPARE_RID_FUNCTION_NUMBER; | ||
| 602 | rid_end = pe->rid + 1; | ||
| 603 | } | ||
| 604 | |||
| 605 | /* Associate PE in PELT */ | ||
| 606 | rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid, | ||
| 607 | bcomp, dcomp, fcomp, OPAL_MAP_PE); | ||
| 608 | if (rc) { | ||
| 609 | pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc); | ||
| 610 | return -ENXIO; | ||
| 611 | } | ||
| 612 | opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, | ||
| 613 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
| 614 | |||
| 615 | /* Add to all parents PELT-V */ | ||
| 616 | while (parent) { | ||
| 617 | struct pci_dn *pdn = pnv_ioda_get_pdn(parent); | ||
| 618 | if (pdn && pdn->pe_number != IODA_INVALID_PE) { | ||
| 619 | rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, | ||
| 620 | pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); | ||
| 621 | /* XXX What to do in case of error ? */ | ||
| 622 | } | ||
| 623 | parent = parent->bus->self; | ||
| 624 | } | ||
| 625 | /* Setup reverse map */ | ||
| 626 | for (rid = pe->rid; rid < rid_end; rid++) | ||
| 627 | phb->ioda.pe_rmap[rid] = pe->pe_number; | ||
| 628 | |||
| 629 | /* Setup one MVTs on IODA1 */ | ||
| 630 | if (phb->type == PNV_PHB_IODA1) { | ||
| 631 | pe->mve_number = pe->pe_number; | ||
| 632 | rc = opal_pci_set_mve(phb->opal_id, pe->mve_number, | ||
| 633 | pe->pe_number); | ||
| 634 | if (rc) { | ||
| 635 | pe_err(pe, "OPAL error %ld setting up MVE %d\n", | ||
| 636 | rc, pe->mve_number); | ||
| 637 | pe->mve_number = -1; | ||
| 638 | } else { | ||
| 639 | rc = opal_pci_set_mve_enable(phb->opal_id, | ||
| 640 | pe->mve_number, OPAL_ENABLE_MVE); | ||
| 641 | if (rc) { | ||
| 642 | pe_err(pe, "OPAL error %ld enabling MVE %d\n", | ||
| 643 | rc, pe->mve_number); | ||
| 644 | pe->mve_number = -1; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | } else if (phb->type == PNV_PHB_IODA2) | ||
| 648 | pe->mve_number = 0; | ||
| 649 | |||
| 650 | return 0; | ||
| 651 | } | ||
| 652 | |||
| 653 | static void __devinit pnv_ioda_link_pe_by_weight(struct pnv_phb *phb, | ||
| 654 | struct pnv_ioda_pe *pe) | ||
| 655 | { | ||
| 656 | struct pnv_ioda_pe *lpe; | ||
| 657 | |||
| 658 | list_for_each_entry(lpe, &phb->ioda.pe_list, link) { | ||
| 659 | if (lpe->dma_weight < pe->dma_weight) { | ||
| 660 | list_add_tail(&pe->link, &lpe->link); | ||
| 661 | return; | ||
| 662 | } | ||
| 663 | } | ||
| 664 | list_add_tail(&pe->link, &phb->ioda.pe_list); | ||
| 665 | } | ||
| 666 | |||
| 667 | static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev) | ||
| 668 | { | ||
| 669 | /* This is quite simplistic. The "base" weight of a device | ||
| 670 | * is 10. 0 means no DMA is to be accounted for it. | ||
| 671 | */ | ||
| 672 | |||
| 673 | /* If it's a bridge, no DMA */ | ||
| 674 | if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) | ||
| 675 | return 0; | ||
| 676 | |||
| 677 | /* Reduce the weight of slow USB controllers */ | ||
| 678 | if (dev->class == PCI_CLASS_SERIAL_USB_UHCI || | ||
| 679 | dev->class == PCI_CLASS_SERIAL_USB_OHCI || | ||
| 680 | dev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
| 681 | return 3; | ||
| 682 | |||
| 683 | /* Increase the weight of RAID (includes Obsidian) */ | ||
| 684 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID) | ||
| 685 | return 15; | ||
| 686 | |||
| 687 | /* Default */ | ||
| 688 | return 10; | ||
| 689 | } | ||
| 690 | |||
| 691 | static struct pnv_ioda_pe * __devinit pnv_ioda_setup_dev_PE(struct pci_dev *dev) | ||
| 692 | { | ||
| 693 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
| 694 | struct pnv_phb *phb = hose->private_data; | ||
| 695 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
| 696 | struct pnv_ioda_pe *pe; | ||
| 697 | int pe_num; | ||
| 698 | |||
| 699 | if (!pdn) { | ||
| 700 | pr_err("%s: Device tree node not associated properly\n", | ||
| 701 | pci_name(dev)); | ||
| 702 | return NULL; | ||
| 703 | } | ||
| 704 | if (pdn->pe_number != IODA_INVALID_PE) | ||
| 705 | return NULL; | ||
| 706 | |||
| 707 | /* PE#0 has been pre-set */ | ||
| 708 | if (dev->bus->number == 0) | ||
| 709 | pe_num = 0; | ||
| 710 | else | ||
| 711 | pe_num = pnv_ioda_alloc_pe(phb); | ||
| 712 | if (pe_num == IODA_INVALID_PE) { | ||
| 713 | pr_warning("%s: Not enough PE# available, disabling device\n", | ||
| 714 | pci_name(dev)); | ||
| 715 | return NULL; | ||
| 716 | } | ||
| 717 | |||
| 718 | /* NOTE: We get only one ref to the pci_dev for the pdn, not for the | ||
| 719 | * pointer in the PE data structure, both should be destroyed at the | ||
| 720 | * same time. However, this needs to be looked at more closely again | ||
| 721 | * once we actually start removing things (Hotplug, SR-IOV, ...) | ||
| 722 | * | ||
| 723 | * At some point we want to remove the PDN completely anyways | ||
| 724 | */ | ||
| 725 | pe = &phb->ioda.pe_array[pe_num]; | ||
| 726 | pci_dev_get(dev); | ||
| 727 | pdn->pcidev = dev; | ||
| 728 | pdn->pe_number = pe_num; | ||
| 729 | pe->pdev = dev; | ||
| 730 | pe->pbus = NULL; | ||
| 731 | pe->tce32_seg = -1; | ||
| 732 | pe->mve_number = -1; | ||
| 733 | pe->rid = dev->bus->number << 8 | pdn->devfn; | ||
| 734 | |||
| 735 | pe_info(pe, "Associated device to PE\n"); | ||
| 736 | |||
| 737 | if (pnv_ioda_configure_pe(phb, pe)) { | ||
| 738 | /* XXX What do we do here ? */ | ||
| 739 | if (pe_num) | ||
| 740 | pnv_ioda_free_pe(phb, pe_num); | ||
| 741 | pdn->pe_number = IODA_INVALID_PE; | ||
| 742 | pe->pdev = NULL; | ||
| 743 | pci_dev_put(dev); | ||
| 744 | return NULL; | ||
| 745 | } | ||
| 746 | |||
| 747 | /* Assign a DMA weight to the device */ | ||
| 748 | pe->dma_weight = pnv_ioda_dma_weight(dev); | ||
| 749 | if (pe->dma_weight != 0) { | ||
| 750 | phb->ioda.dma_weight += pe->dma_weight; | ||
| 751 | phb->ioda.dma_pe_count++; | ||
| 752 | } | ||
| 753 | |||
| 754 | /* Link the PE */ | ||
| 755 | pnv_ioda_link_pe_by_weight(phb, pe); | ||
| 756 | |||
| 757 | return pe; | ||
| 758 | } | ||
| 759 | |||
| 760 | static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) | ||
| 761 | { | ||
| 762 | struct pci_dev *dev; | ||
| 763 | |||
| 764 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 765 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
| 766 | |||
| 767 | if (pdn == NULL) { | ||
| 768 | pr_warn("%s: No device node associated with device !\n", | ||
| 769 | pci_name(dev)); | ||
| 770 | continue; | ||
| 771 | } | ||
| 772 | pci_dev_get(dev); | ||
| 773 | pdn->pcidev = dev; | ||
| 774 | pdn->pe_number = pe->pe_number; | ||
| 775 | pe->dma_weight += pnv_ioda_dma_weight(dev); | ||
| 776 | if (dev->subordinate) | ||
| 777 | pnv_ioda_setup_same_PE(dev->subordinate, pe); | ||
| 778 | } | ||
| 779 | } | ||
| 780 | |||
| 781 | static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev, | ||
| 782 | struct pnv_ioda_pe *ppe) | ||
| 783 | { | ||
| 784 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
| 785 | struct pnv_phb *phb = hose->private_data; | ||
| 786 | struct pci_bus *bus = dev->subordinate; | ||
| 787 | struct pnv_ioda_pe *pe; | ||
| 788 | int pe_num; | ||
| 789 | |||
| 790 | if (!bus) { | ||
| 791 | pr_warning("%s: Bridge without a subordinate bus !\n", | ||
| 792 | pci_name(dev)); | ||
| 793 | return; | ||
| 794 | } | ||
| 795 | pe_num = pnv_ioda_alloc_pe(phb); | ||
| 796 | if (pe_num == IODA_INVALID_PE) { | ||
| 797 | pr_warning("%s: Not enough PE# available, disabling bus\n", | ||
| 798 | pci_name(dev)); | ||
| 799 | return; | ||
| 800 | } | ||
| 801 | |||
| 802 | pe = &phb->ioda.pe_array[pe_num]; | ||
| 803 | ppe->bus_pe = pe; | ||
| 804 | pe->pbus = bus; | ||
| 805 | pe->pdev = NULL; | ||
| 806 | pe->tce32_seg = -1; | ||
| 807 | pe->mve_number = -1; | ||
| 808 | pe->rid = bus->secondary << 8; | ||
| 809 | pe->dma_weight = 0; | ||
| 810 | |||
| 811 | pe_info(pe, "Secondary busses %d..%d associated with PE\n", | ||
| 812 | bus->secondary, bus->subordinate); | ||
| 813 | |||
| 814 | if (pnv_ioda_configure_pe(phb, pe)) { | ||
| 815 | /* XXX What do we do here ? */ | ||
| 816 | if (pe_num) | ||
| 817 | pnv_ioda_free_pe(phb, pe_num); | ||
| 818 | pe->pbus = NULL; | ||
| 819 | return; | ||
| 820 | } | ||
| 821 | |||
| 822 | /* Associate it with all child devices */ | ||
| 823 | pnv_ioda_setup_same_PE(bus, pe); | ||
| 824 | |||
| 825 | /* Account for one DMA PE if at least one DMA capable device exist | ||
| 826 | * below the bridge | ||
| 827 | */ | ||
| 828 | if (pe->dma_weight != 0) { | ||
| 829 | phb->ioda.dma_weight += pe->dma_weight; | ||
| 830 | phb->ioda.dma_pe_count++; | ||
| 831 | } | ||
| 832 | |||
| 833 | /* Link the PE */ | ||
| 834 | pnv_ioda_link_pe_by_weight(phb, pe); | ||
| 835 | } | ||
| 836 | |||
| 837 | static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus) | ||
| 838 | { | ||
| 839 | struct pci_dev *dev; | ||
| 840 | struct pnv_ioda_pe *pe; | ||
| 841 | |||
| 842 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 843 | pe = pnv_ioda_setup_dev_PE(dev); | ||
| 844 | if (pe == NULL) | ||
| 845 | continue; | ||
| 846 | /* Leaving the PCIe domain ... single PE# */ | ||
| 847 | if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | ||
| 848 | pnv_ioda_setup_bus_PE(dev, pe); | ||
| 849 | else if (dev->subordinate) | ||
| 850 | pnv_ioda_setup_PEs(dev->subordinate); | ||
| 851 | } | ||
| 852 | } | ||
| 853 | |||
| 854 | static void __devinit pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, | ||
| 855 | struct pci_dev *dev) | ||
| 856 | { | ||
| 857 | /* We delay DMA setup after we have assigned all PE# */ | ||
| 858 | } | ||
| 859 | |||
| 860 | static void __devinit pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, | ||
| 861 | struct pci_bus *bus) | ||
| 862 | { | ||
| 863 | struct pci_dev *dev; | ||
| 864 | |||
| 865 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 866 | set_iommu_table_base(&dev->dev, &pe->tce32_table); | ||
| 867 | if (dev->subordinate) | ||
| 868 | pnv_ioda_setup_bus_dma(pe, dev->subordinate); | ||
| 869 | } | ||
| 870 | } | ||
| 871 | |||
| 872 | static void __devinit pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | ||
| 873 | struct pnv_ioda_pe *pe, | ||
| 874 | unsigned int base, | ||
| 875 | unsigned int segs) | ||
| 876 | { | ||
| 877 | |||
| 878 | struct page *tce_mem = NULL; | ||
| 879 | const __be64 *swinvp; | ||
| 880 | struct iommu_table *tbl; | ||
| 881 | unsigned int i; | ||
| 882 | int64_t rc; | ||
| 883 | void *addr; | ||
| 884 | |||
| 885 | /* 256M DMA window, 4K TCE pages, 8 bytes TCE */ | ||
| 886 | #define TCE32_TABLE_SIZE ((0x10000000 / 0x1000) * 8) | ||
| 887 | |||
| 888 | /* XXX FIXME: Handle 64-bit only DMA devices */ | ||
| 889 | /* XXX FIXME: Provide 64-bit DMA facilities & non-4K TCE tables etc.. */ | ||
| 890 | /* XXX FIXME: Allocate multi-level tables on PHB3 */ | ||
| 891 | |||
| 892 | /* We shouldn't already have a 32-bit DMA associated */ | ||
| 893 | if (WARN_ON(pe->tce32_seg >= 0)) | ||
| 894 | return; | ||
| 895 | |||
| 896 | /* Grab a 32-bit TCE table */ | ||
| 897 | pe->tce32_seg = base; | ||
| 898 | pe_info(pe, " Setting up 32-bit TCE table at %08x..%08x\n", | ||
| 899 | (base << 28), ((base + segs) << 28) - 1); | ||
| 900 | |||
| 901 | /* XXX Currently, we allocate one big contiguous table for the | ||
| 902 | * TCEs. We only really need one chunk per 256M of TCE space | ||
| 903 | * (ie per segment) but that's an optimization for later, it | ||
| 904 | * requires some added smarts with our get/put_tce implementation | ||
| 905 | */ | ||
| 906 | tce_mem = alloc_pages_node(phb->hose->node, GFP_KERNEL, | ||
| 907 | get_order(TCE32_TABLE_SIZE * segs)); | ||
| 908 | if (!tce_mem) { | ||
| 909 | pe_err(pe, " Failed to allocate a 32-bit TCE memory\n"); | ||
| 910 | goto fail; | ||
| 911 | } | ||
| 912 | addr = page_address(tce_mem); | ||
| 913 | memset(addr, 0, TCE32_TABLE_SIZE * segs); | ||
| 914 | |||
| 915 | /* Configure HW */ | ||
| 916 | for (i = 0; i < segs; i++) { | ||
| 917 | rc = opal_pci_map_pe_dma_window(phb->opal_id, | ||
| 918 | pe->pe_number, | ||
| 919 | base + i, 1, | ||
| 920 | __pa(addr) + TCE32_TABLE_SIZE * i, | ||
| 921 | TCE32_TABLE_SIZE, 0x1000); | ||
| 922 | if (rc) { | ||
| 923 | pe_err(pe, " Failed to configure 32-bit TCE table," | ||
| 924 | " err %ld\n", rc); | ||
| 925 | goto fail; | ||
| 926 | } | ||
| 927 | } | ||
| 928 | |||
| 929 | /* Setup linux iommu table */ | ||
| 930 | tbl = &pe->tce32_table; | ||
| 931 | pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs, | ||
| 932 | base << 28); | ||
| 933 | |||
| 934 | /* OPAL variant of P7IOC SW invalidated TCEs */ | ||
| 935 | swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL); | ||
| 936 | if (swinvp) { | ||
| 937 | /* We need a couple more fields -- an address and a data | ||
| 938 | * to or. Since the bus is only printed out on table free | ||
| 939 | * errors, and on the first pass the data will be a relative | ||
| 940 | * bus number, print that out instead. | ||
| 941 | */ | ||
| 942 | tbl->it_busno = 0; | ||
| 943 | tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); | ||
| 944 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | ||
| 945 | | TCE_PCI_SWINV_PAIR; | ||
| 946 | } | ||
| 947 | iommu_init_table(tbl, phb->hose->node); | ||
| 948 | |||
| 949 | if (pe->pdev) | ||
| 950 | set_iommu_table_base(&pe->pdev->dev, tbl); | ||
| 951 | else | ||
| 952 | pnv_ioda_setup_bus_dma(pe, pe->pbus); | ||
| 953 | |||
| 954 | return; | ||
| 955 | fail: | ||
| 956 | /* XXX Failure: Try to fallback to 64-bit only ? */ | ||
| 957 | if (pe->tce32_seg >= 0) | ||
| 958 | pe->tce32_seg = -1; | ||
| 959 | if (tce_mem) | ||
| 960 | __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs)); | ||
| 961 | } | ||
| 962 | |||
| 963 | static void __devinit pnv_ioda_setup_dma(struct pnv_phb *phb) | ||
| 964 | { | ||
| 965 | struct pci_controller *hose = phb->hose; | ||
| 966 | unsigned int residual, remaining, segs, tw, base; | ||
| 967 | struct pnv_ioda_pe *pe; | ||
| 968 | |||
| 969 | /* If we have more PE# than segments available, hand out one | ||
| 970 | * per PE until we run out and let the rest fail. If not, | ||
| 971 | * then we assign at least one segment per PE, plus more based | ||
| 972 | * on the amount of devices under that PE | ||
| 973 | */ | ||
| 974 | if (phb->ioda.dma_pe_count > phb->ioda.tce32_count) | ||
| 975 | residual = 0; | ||
| 976 | else | ||
| 977 | residual = phb->ioda.tce32_count - | ||
| 978 | phb->ioda.dma_pe_count; | ||
| 979 | |||
| 980 | pr_info("PCI: Domain %04x has %ld available 32-bit DMA segments\n", | ||
| 981 | hose->global_number, phb->ioda.tce32_count); | ||
| 982 | pr_info("PCI: %d PE# for a total weight of %d\n", | ||
| 983 | phb->ioda.dma_pe_count, phb->ioda.dma_weight); | ||
| 984 | |||
| 985 | /* Walk our PE list and configure their DMA segments, hand them | ||
| 986 | * out one base segment plus any residual segments based on | ||
| 987 | * weight | ||
| 988 | */ | ||
| 989 | remaining = phb->ioda.tce32_count; | ||
| 990 | tw = phb->ioda.dma_weight; | ||
| 991 | base = 0; | ||
| 992 | list_for_each_entry(pe, &phb->ioda.pe_list, link) { | ||
| 993 | if (!pe->dma_weight) | ||
| 994 | continue; | ||
| 995 | if (!remaining) { | ||
| 996 | pe_warn(pe, "No DMA32 resources available\n"); | ||
| 997 | continue; | ||
| 998 | } | ||
| 999 | segs = 1; | ||
| 1000 | if (residual) { | ||
| 1001 | segs += ((pe->dma_weight * residual) + (tw / 2)) / tw; | ||
| 1002 | if (segs > remaining) | ||
| 1003 | segs = remaining; | ||
| 1004 | } | ||
| 1005 | pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", | ||
| 1006 | pe->dma_weight, segs); | ||
| 1007 | pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); | ||
| 1008 | remaining -= segs; | ||
| 1009 | base += segs; | ||
| 1010 | } | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | #ifdef CONFIG_PCI_MSI | ||
| 1014 | static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | ||
| 1015 | unsigned int hwirq, unsigned int is_64, | ||
| 1016 | struct msi_msg *msg) | ||
| 1017 | { | ||
| 1018 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); | ||
| 1019 | unsigned int xive_num = hwirq - phb->msi_base; | ||
| 1020 | uint64_t addr64; | ||
| 1021 | uint32_t addr32, data; | ||
| 1022 | int rc; | ||
| 1023 | |||
| 1024 | /* No PE assigned ? bail out ... no MSI for you ! */ | ||
| 1025 | if (pe == NULL) | ||
| 1026 | return -ENXIO; | ||
| 1027 | |||
| 1028 | /* Check if we have an MVE */ | ||
| 1029 | if (pe->mve_number < 0) | ||
| 1030 | return -ENXIO; | ||
| 1031 | |||
| 1032 | /* Assign XIVE to PE */ | ||
| 1033 | rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num); | ||
| 1034 | if (rc) { | ||
| 1035 | pr_warn("%s: OPAL error %d setting XIVE %d PE\n", | ||
| 1036 | pci_name(dev), rc, xive_num); | ||
| 1037 | return -EIO; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | if (is_64) { | ||
| 1041 | rc = opal_get_msi_64(phb->opal_id, pe->mve_number, xive_num, 1, | ||
| 1042 | &addr64, &data); | ||
| 1043 | if (rc) { | ||
| 1044 | pr_warn("%s: OPAL error %d getting 64-bit MSI data\n", | ||
| 1045 | pci_name(dev), rc); | ||
| 1046 | return -EIO; | ||
| 1047 | } | ||
| 1048 | msg->address_hi = addr64 >> 32; | ||
| 1049 | msg->address_lo = addr64 & 0xfffffffful; | ||
| 1050 | } else { | ||
| 1051 | rc = opal_get_msi_32(phb->opal_id, pe->mve_number, xive_num, 1, | ||
| 1052 | &addr32, &data); | ||
| 1053 | if (rc) { | ||
| 1054 | pr_warn("%s: OPAL error %d getting 32-bit MSI data\n", | ||
| 1055 | pci_name(dev), rc); | ||
| 1056 | return -EIO; | ||
| 1057 | } | ||
| 1058 | msg->address_hi = 0; | ||
| 1059 | msg->address_lo = addr32; | ||
| 1060 | } | ||
| 1061 | msg->data = data; | ||
| 1062 | |||
| 1063 | pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," | ||
| 1064 | " address=%x_%08x data=%x PE# %d\n", | ||
| 1065 | pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, | ||
| 1066 | msg->address_hi, msg->address_lo, data, pe->pe_number); | ||
| 1067 | |||
| 1068 | return 0; | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) | ||
| 1072 | { | ||
| 1073 | unsigned int bmap_size; | ||
| 1074 | const __be32 *prop = of_get_property(phb->hose->dn, | ||
| 1075 | "ibm,opal-msi-ranges", NULL); | ||
| 1076 | if (!prop) { | ||
| 1077 | /* BML Fallback */ | ||
| 1078 | prop = of_get_property(phb->hose->dn, "msi-ranges", NULL); | ||
| 1079 | } | ||
| 1080 | if (!prop) | ||
| 1081 | return; | ||
| 1082 | |||
| 1083 | phb->msi_base = be32_to_cpup(prop); | ||
| 1084 | phb->msi_count = be32_to_cpup(prop + 1); | ||
| 1085 | bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); | ||
| 1086 | phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL); | ||
| 1087 | if (!phb->msi_map) { | ||
| 1088 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", | ||
| 1089 | phb->hose->global_number); | ||
| 1090 | return; | ||
| 1091 | } | ||
| 1092 | phb->msi_setup = pnv_pci_ioda_msi_setup; | ||
| 1093 | phb->msi32_support = 1; | ||
| 1094 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", | ||
| 1095 | phb->msi_count, phb->msi_base); | ||
| 1096 | } | ||
| 1097 | #else | ||
| 1098 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } | ||
| 1099 | #endif /* CONFIG_PCI_MSI */ | ||
| 1100 | |||
| 1101 | /* This is the starting point of our IODA specific resource | ||
| 1102 | * allocation process | ||
| 1103 | */ | ||
| 1104 | static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose) | ||
| 1105 | { | ||
| 1106 | resource_size_t size, align; | ||
| 1107 | struct pci_bus *child; | ||
| 1108 | |||
| 1109 | /* Associate PEs per functions */ | ||
| 1110 | pnv_ioda_setup_PEs(hose->bus); | ||
| 1111 | |||
| 1112 | /* Calculate all resources */ | ||
| 1113 | pnv_ioda_calc_bus(hose->bus, IORESOURCE_IO, &size, &align); | ||
| 1114 | pnv_ioda_calc_bus(hose->bus, IORESOURCE_MEM, &size, &align); | ||
| 1115 | |||
| 1116 | /* Apply then to HW */ | ||
| 1117 | pnv_ioda_update_resources(hose->bus); | ||
| 1118 | |||
| 1119 | /* Setup DMA */ | ||
| 1120 | pnv_ioda_setup_dma(hose->private_data); | ||
| 1121 | |||
| 1122 | /* Configure PCI Express settings */ | ||
| 1123 | list_for_each_entry(child, &hose->bus->children, node) { | ||
| 1124 | struct pci_dev *self = child->self; | ||
| 1125 | if (!self) | ||
| 1126 | continue; | ||
| 1127 | pcie_bus_configure_settings(child, self->pcie_mpss); | ||
| 1128 | } | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | /* Prevent enabling devices for which we couldn't properly | ||
| 1132 | * assign a PE | ||
| 1133 | */ | ||
| 1134 | static int __devinit pnv_pci_enable_device_hook(struct pci_dev *dev) | ||
| 1135 | { | ||
| 1136 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
| 1137 | |||
| 1138 | if (!pdn || pdn->pe_number == IODA_INVALID_PE) | ||
| 1139 | return -EINVAL; | ||
| 1140 | return 0; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus, | ||
| 1144 | u32 devfn) | ||
| 1145 | { | ||
| 1146 | return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | void __init pnv_pci_init_ioda1_phb(struct device_node *np) | ||
| 1150 | { | ||
| 1151 | struct pci_controller *hose; | ||
| 1152 | static int primary = 1; | ||
| 1153 | struct pnv_phb *phb; | ||
| 1154 | unsigned long size, m32map_off, iomap_off, pemap_off; | ||
| 1155 | const u64 *prop64; | ||
| 1156 | u64 phb_id; | ||
| 1157 | void *aux; | ||
| 1158 | long rc; | ||
| 1159 | |||
| 1160 | pr_info(" Initializing IODA OPAL PHB %s\n", np->full_name); | ||
| 1161 | |||
| 1162 | prop64 = of_get_property(np, "ibm,opal-phbid", NULL); | ||
| 1163 | if (!prop64) { | ||
| 1164 | pr_err(" Missing \"ibm,opal-phbid\" property !\n"); | ||
| 1165 | return; | ||
| 1166 | } | ||
| 1167 | phb_id = be64_to_cpup(prop64); | ||
| 1168 | pr_debug(" PHB-ID : 0x%016llx\n", phb_id); | ||
| 1169 | |||
| 1170 | phb = alloc_bootmem(sizeof(struct pnv_phb)); | ||
| 1171 | if (phb) { | ||
| 1172 | memset(phb, 0, sizeof(struct pnv_phb)); | ||
| 1173 | phb->hose = hose = pcibios_alloc_controller(np); | ||
| 1174 | } | ||
| 1175 | if (!phb || !phb->hose) { | ||
| 1176 | pr_err("PCI: Failed to allocate PCI controller for %s\n", | ||
| 1177 | np->full_name); | ||
| 1178 | return; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | spin_lock_init(&phb->lock); | ||
| 1182 | /* XXX Use device-tree */ | ||
| 1183 | hose->first_busno = 0; | ||
| 1184 | hose->last_busno = 0xff; | ||
| 1185 | hose->private_data = phb; | ||
| 1186 | phb->opal_id = phb_id; | ||
| 1187 | phb->type = PNV_PHB_IODA1; | ||
| 1188 | |||
| 1189 | /* Detect specific models for error handling */ | ||
| 1190 | if (of_device_is_compatible(np, "ibm,p7ioc-pciex")) | ||
| 1191 | phb->model = PNV_PHB_MODEL_P7IOC; | ||
| 1192 | else | ||
| 1193 | phb->model = PNV_PHB_MODEL_UNKNOWN; | ||
| 1194 | |||
| 1195 | /* We parse "ranges" now since we need to deduce the register base | ||
| 1196 | * from the IO base | ||
| 1197 | */ | ||
| 1198 | pci_process_bridge_OF_ranges(phb->hose, np, primary); | ||
| 1199 | primary = 0; | ||
| 1200 | |||
| 1201 | /* Magic formula from Milton */ | ||
| 1202 | phb->regs = of_iomap(np, 0); | ||
| 1203 | if (phb->regs == NULL) | ||
| 1204 | pr_err(" Failed to map registers !\n"); | ||
| 1205 | |||
| 1206 | |||
| 1207 | /* XXX This is hack-a-thon. This needs to be changed so that: | ||
| 1208 | * - we obtain stuff like PE# etc... from device-tree | ||
| 1209 | * - we properly re-allocate M32 ourselves | ||
| 1210 | * (the OFW one isn't very good) | ||
| 1211 | */ | ||
| 1212 | |||
| 1213 | /* Initialize more IODA stuff */ | ||
| 1214 | phb->ioda.total_pe = 128; | ||
| 1215 | |||
| 1216 | phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); | ||
| 1217 | /* OFW Has already off top 64k of M32 space (MSI space) */ | ||
| 1218 | phb->ioda.m32_size += 0x10000; | ||
| 1219 | |||
| 1220 | phb->ioda.m32_segsize = phb->ioda.m32_size / phb->ioda.total_pe; | ||
| 1221 | phb->ioda.m32_pci_base = hose->mem_resources[0].start - | ||
| 1222 | hose->pci_mem_offset; | ||
| 1223 | phb->ioda.io_size = hose->pci_io_size; | ||
| 1224 | phb->ioda.io_segsize = phb->ioda.io_size / phb->ioda.total_pe; | ||
| 1225 | phb->ioda.io_pci_base = 0; /* XXX calculate this ? */ | ||
| 1226 | |||
| 1227 | /* Allocate aux data & arrays */ | ||
| 1228 | size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long)); | ||
| 1229 | m32map_off = size; | ||
| 1230 | size += phb->ioda.total_pe; | ||
| 1231 | iomap_off = size; | ||
| 1232 | size += phb->ioda.total_pe; | ||
| 1233 | pemap_off = size; | ||
| 1234 | size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe); | ||
| 1235 | aux = alloc_bootmem(size); | ||
| 1236 | memset(aux, 0, size); | ||
| 1237 | phb->ioda.pe_alloc = aux; | ||
| 1238 | phb->ioda.m32_segmap = aux + m32map_off; | ||
| 1239 | phb->ioda.io_segmap = aux + iomap_off; | ||
| 1240 | phb->ioda.pe_array = aux + pemap_off; | ||
| 1241 | set_bit(0, phb->ioda.pe_alloc); | ||
| 1242 | |||
| 1243 | INIT_LIST_HEAD(&phb->ioda.pe_list); | ||
| 1244 | |||
| 1245 | /* Calculate how many 32-bit TCE segments we have */ | ||
| 1246 | phb->ioda.tce32_count = phb->ioda.m32_pci_base >> 28; | ||
| 1247 | |||
| 1248 | /* Clear unusable m64 */ | ||
| 1249 | hose->mem_resources[1].flags = 0; | ||
| 1250 | hose->mem_resources[1].start = 0; | ||
| 1251 | hose->mem_resources[1].end = 0; | ||
| 1252 | hose->mem_resources[2].flags = 0; | ||
| 1253 | hose->mem_resources[2].start = 0; | ||
| 1254 | hose->mem_resources[2].end = 0; | ||
| 1255 | |||
| 1256 | #if 0 | ||
| 1257 | rc = opal_pci_set_phb_mem_window(opal->phb_id, | ||
| 1258 | window_type, | ||
| 1259 | window_num, | ||
| 1260 | starting_real_address, | ||
| 1261 | starting_pci_address, | ||
| 1262 | segment_size); | ||
| 1263 | #endif | ||
| 1264 | |||
| 1265 | pr_info(" %d PE's M32: 0x%x [segment=0x%x] IO: 0x%x [segment=0x%x]\n", | ||
| 1266 | phb->ioda.total_pe, | ||
| 1267 | phb->ioda.m32_size, phb->ioda.m32_segsize, | ||
| 1268 | phb->ioda.io_size, phb->ioda.io_segsize); | ||
| 1269 | |||
| 1270 | if (phb->regs) { | ||
| 1271 | pr_devel(" BUID = 0x%016llx\n", in_be64(phb->regs + 0x100)); | ||
| 1272 | pr_devel(" PHB2_CR = 0x%016llx\n", in_be64(phb->regs + 0x160)); | ||
| 1273 | pr_devel(" IO_BAR = 0x%016llx\n", in_be64(phb->regs + 0x170)); | ||
| 1274 | pr_devel(" IO_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x178)); | ||
| 1275 | pr_devel(" IO_SAR = 0x%016llx\n", in_be64(phb->regs + 0x180)); | ||
| 1276 | pr_devel(" M32_BAR = 0x%016llx\n", in_be64(phb->regs + 0x190)); | ||
| 1277 | pr_devel(" M32_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x198)); | ||
| 1278 | pr_devel(" M32_SAR = 0x%016llx\n", in_be64(phb->regs + 0x1a0)); | ||
| 1279 | } | ||
| 1280 | phb->hose->ops = &pnv_pci_ops; | ||
| 1281 | |||
| 1282 | /* Setup RID -> PE mapping function */ | ||
| 1283 | phb->bdfn_to_pe = pnv_ioda_bdfn_to_pe; | ||
| 1284 | |||
| 1285 | /* Setup TCEs */ | ||
| 1286 | phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; | ||
| 1287 | |||
| 1288 | /* Setup MSI support */ | ||
| 1289 | pnv_pci_init_ioda_msis(phb); | ||
| 1290 | |||
| 1291 | /* We set both probe_only and PCI_REASSIGN_ALL_RSRC. This is an | ||
| 1292 | * odd combination which essentially means that we skip all resource | ||
| 1293 | * fixups and assignments in the generic code, and do it all | ||
| 1294 | * ourselves here | ||
| 1295 | */ | ||
| 1296 | pci_probe_only = 1; | ||
| 1297 | ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; | ||
| 1298 | ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; | ||
| 1299 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); | ||
| 1300 | |||
| 1301 | /* Reset IODA tables to a clean state */ | ||
| 1302 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); | ||
| 1303 | if (rc) | ||
| 1304 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); | ||
| 1305 | opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | void __init pnv_pci_init_ioda_hub(struct device_node *np) | ||
| 1309 | { | ||
| 1310 | struct device_node *phbn; | ||
| 1311 | const u64 *prop64; | ||
| 1312 | u64 hub_id; | ||
| 1313 | |||
| 1314 | pr_info("Probing IODA IO-Hub %s\n", np->full_name); | ||
| 1315 | |||
| 1316 | prop64 = of_get_property(np, "ibm,opal-hubid", NULL); | ||
| 1317 | if (!prop64) { | ||
| 1318 | pr_err(" Missing \"ibm,opal-hubid\" property !\n"); | ||
| 1319 | return; | ||
| 1320 | } | ||
| 1321 | hub_id = be64_to_cpup(prop64); | ||
| 1322 | pr_devel(" HUB-ID : 0x%016llx\n", hub_id); | ||
| 1323 | |||
| 1324 | /* Count child PHBs */ | ||
| 1325 | for_each_child_of_node(np, phbn) { | ||
| 1326 | /* Look for IODA1 PHBs */ | ||
| 1327 | if (of_device_is_compatible(phbn, "ibm,ioda-phb")) | ||
| 1328 | pnv_pci_init_ioda1_phb(phbn); | ||
| 1329 | } | ||
| 1330 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index 4c80f7c77d56..264967770c3a 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c | |||
| @@ -137,6 +137,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, | |||
| 137 | phb->hose->private_data = phb; | 137 | phb->hose->private_data = phb; |
| 138 | phb->opal_id = phb_id; | 138 | phb->opal_id = phb_id; |
| 139 | phb->type = PNV_PHB_P5IOC2; | 139 | phb->type = PNV_PHB_P5IOC2; |
| 140 | phb->model = PNV_PHB_MODEL_P5IOC2; | ||
| 140 | 141 | ||
| 141 | phb->regs = of_iomap(np, 0); | 142 | phb->regs = of_iomap(np, 0); |
| 142 | 143 | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 85bb66d7f933..a70bc1e385eb 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
| @@ -144,6 +144,112 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev) | |||
| 144 | } | 144 | } |
| 145 | #endif /* CONFIG_PCI_MSI */ | 145 | #endif /* CONFIG_PCI_MSI */ |
| 146 | 146 | ||
| 147 | static void pnv_pci_dump_p7ioc_diag_data(struct pnv_phb *phb) | ||
| 148 | { | ||
| 149 | struct OpalIoP7IOCPhbErrorData *data = &phb->diag.p7ioc; | ||
| 150 | int i; | ||
| 151 | |||
| 152 | pr_info("PHB %d diagnostic data:\n", phb->hose->global_number); | ||
| 153 | |||
| 154 | pr_info(" brdgCtl = 0x%08x\n", data->brdgCtl); | ||
| 155 | |||
| 156 | pr_info(" portStatusReg = 0x%08x\n", data->portStatusReg); | ||
| 157 | pr_info(" rootCmplxStatus = 0x%08x\n", data->rootCmplxStatus); | ||
| 158 | pr_info(" busAgentStatus = 0x%08x\n", data->busAgentStatus); | ||
| 159 | |||
| 160 | pr_info(" deviceStatus = 0x%08x\n", data->deviceStatus); | ||
| 161 | pr_info(" slotStatus = 0x%08x\n", data->slotStatus); | ||
| 162 | pr_info(" linkStatus = 0x%08x\n", data->linkStatus); | ||
| 163 | pr_info(" devCmdStatus = 0x%08x\n", data->devCmdStatus); | ||
| 164 | pr_info(" devSecStatus = 0x%08x\n", data->devSecStatus); | ||
| 165 | |||
| 166 | pr_info(" rootErrorStatus = 0x%08x\n", data->rootErrorStatus); | ||
| 167 | pr_info(" uncorrErrorStatus = 0x%08x\n", data->uncorrErrorStatus); | ||
| 168 | pr_info(" corrErrorStatus = 0x%08x\n", data->corrErrorStatus); | ||
| 169 | pr_info(" tlpHdr1 = 0x%08x\n", data->tlpHdr1); | ||
| 170 | pr_info(" tlpHdr2 = 0x%08x\n", data->tlpHdr2); | ||
| 171 | pr_info(" tlpHdr3 = 0x%08x\n", data->tlpHdr3); | ||
| 172 | pr_info(" tlpHdr4 = 0x%08x\n", data->tlpHdr4); | ||
| 173 | pr_info(" sourceId = 0x%08x\n", data->sourceId); | ||
| 174 | |||
| 175 | pr_info(" errorClass = 0x%016llx\n", data->errorClass); | ||
| 176 | pr_info(" correlator = 0x%016llx\n", data->correlator); | ||
| 177 | |||
| 178 | pr_info(" p7iocPlssr = 0x%016llx\n", data->p7iocPlssr); | ||
| 179 | pr_info(" p7iocCsr = 0x%016llx\n", data->p7iocCsr); | ||
| 180 | pr_info(" lemFir = 0x%016llx\n", data->lemFir); | ||
| 181 | pr_info(" lemErrorMask = 0x%016llx\n", data->lemErrorMask); | ||
| 182 | pr_info(" lemWOF = 0x%016llx\n", data->lemWOF); | ||
| 183 | pr_info(" phbErrorStatus = 0x%016llx\n", data->phbErrorStatus); | ||
| 184 | pr_info(" phbFirstErrorStatus = 0x%016llx\n", data->phbFirstErrorStatus); | ||
| 185 | pr_info(" phbErrorLog0 = 0x%016llx\n", data->phbErrorLog0); | ||
| 186 | pr_info(" phbErrorLog1 = 0x%016llx\n", data->phbErrorLog1); | ||
| 187 | pr_info(" mmioErrorStatus = 0x%016llx\n", data->mmioErrorStatus); | ||
| 188 | pr_info(" mmioFirstErrorStatus = 0x%016llx\n", data->mmioFirstErrorStatus); | ||
| 189 | pr_info(" mmioErrorLog0 = 0x%016llx\n", data->mmioErrorLog0); | ||
| 190 | pr_info(" mmioErrorLog1 = 0x%016llx\n", data->mmioErrorLog1); | ||
| 191 | pr_info(" dma0ErrorStatus = 0x%016llx\n", data->dma0ErrorStatus); | ||
| 192 | pr_info(" dma0FirstErrorStatus = 0x%016llx\n", data->dma0FirstErrorStatus); | ||
| 193 | pr_info(" dma0ErrorLog0 = 0x%016llx\n", data->dma0ErrorLog0); | ||
| 194 | pr_info(" dma0ErrorLog1 = 0x%016llx\n", data->dma0ErrorLog1); | ||
| 195 | pr_info(" dma1ErrorStatus = 0x%016llx\n", data->dma1ErrorStatus); | ||
| 196 | pr_info(" dma1FirstErrorStatus = 0x%016llx\n", data->dma1FirstErrorStatus); | ||
| 197 | pr_info(" dma1ErrorLog0 = 0x%016llx\n", data->dma1ErrorLog0); | ||
| 198 | pr_info(" dma1ErrorLog1 = 0x%016llx\n", data->dma1ErrorLog1); | ||
| 199 | |||
| 200 | for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { | ||
| 201 | if ((data->pestA[i] >> 63) == 0 && | ||
| 202 | (data->pestB[i] >> 63) == 0) | ||
| 203 | continue; | ||
| 204 | pr_info(" PE[%3d] PESTA = 0x%016llx\n", i, data->pestA[i]); | ||
| 205 | pr_info(" PESTB = 0x%016llx\n", data->pestB[i]); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | static void pnv_pci_dump_phb_diag_data(struct pnv_phb *phb) | ||
| 210 | { | ||
| 211 | switch(phb->model) { | ||
| 212 | case PNV_PHB_MODEL_P7IOC: | ||
| 213 | pnv_pci_dump_p7ioc_diag_data(phb); | ||
| 214 | break; | ||
| 215 | default: | ||
| 216 | pr_warning("PCI %d: Can't decode this PHB diag data\n", | ||
| 217 | phb->hose->global_number); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) | ||
| 222 | { | ||
| 223 | unsigned long flags, rc; | ||
| 224 | int has_diag; | ||
| 225 | |||
| 226 | spin_lock_irqsave(&phb->lock, flags); | ||
| 227 | |||
| 228 | rc = opal_pci_get_phb_diag_data(phb->opal_id, phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); | ||
| 229 | has_diag = (rc == OPAL_SUCCESS); | ||
| 230 | |||
| 231 | rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, | ||
| 232 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
| 233 | if (rc) { | ||
| 234 | pr_warning("PCI %d: Failed to clear EEH freeze state" | ||
| 235 | " for PE#%d, err %ld\n", | ||
| 236 | phb->hose->global_number, pe_no, rc); | ||
| 237 | |||
| 238 | /* For now, let's only display the diag buffer when we fail to clear | ||
| 239 | * the EEH status. We'll do more sensible things later when we have | ||
| 240 | * proper EEH support. We need to make sure we don't pollute ourselves | ||
| 241 | * with the normal errors generated when probing empty slots | ||
| 242 | */ | ||
| 243 | if (has_diag) | ||
| 244 | pnv_pci_dump_phb_diag_data(phb); | ||
| 245 | else | ||
| 246 | pr_warning("PCI %d: No diag data available\n", | ||
| 247 | phb->hose->global_number); | ||
| 248 | } | ||
| 249 | |||
| 250 | spin_unlock_irqrestore(&phb->lock, flags); | ||
| 251 | } | ||
| 252 | |||
| 147 | static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, | 253 | static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, |
| 148 | u32 bdfn) | 254 | u32 bdfn) |
| 149 | { | 255 | { |
| @@ -165,15 +271,8 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, | |||
| 165 | } | 271 | } |
| 166 | cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n", | 272 | cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n", |
| 167 | bdfn, pe_no, fstate); | 273 | bdfn, pe_no, fstate); |
| 168 | if (fstate != 0) { | 274 | if (fstate != 0) |
| 169 | rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, | 275 | pnv_pci_handle_eeh_config(phb, pe_no); |
| 170 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
| 171 | if (rc) { | ||
| 172 | pr_warning("PCI %d: Failed to clear EEH freeze state" | ||
| 173 | " for PE#%d, err %lld\n", | ||
| 174 | phb->hose->global_number, pe_no, rc); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | 276 | } |
| 178 | 277 | ||
| 179 | static int pnv_pci_read_config(struct pci_bus *bus, | 278 | static int pnv_pci_read_config(struct pci_bus *bus, |
| @@ -257,12 +356,54 @@ struct pci_ops pnv_pci_ops = { | |||
| 257 | .write = pnv_pci_write_config, | 356 | .write = pnv_pci_write_config, |
| 258 | }; | 357 | }; |
| 259 | 358 | ||
| 359 | |||
| 360 | static void pnv_tce_invalidate(struct iommu_table *tbl, | ||
| 361 | u64 *startp, u64 *endp) | ||
| 362 | { | ||
| 363 | u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; | ||
| 364 | unsigned long start, end, inc; | ||
| 365 | |||
| 366 | start = __pa(startp); | ||
| 367 | end = __pa(endp); | ||
| 368 | |||
| 369 | |||
| 370 | /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */ | ||
| 371 | if (tbl->it_busno) { | ||
| 372 | start <<= 12; | ||
| 373 | end <<= 12; | ||
| 374 | inc = 128 << 12; | ||
| 375 | start |= tbl->it_busno; | ||
| 376 | end |= tbl->it_busno; | ||
| 377 | } | ||
| 378 | /* p7ioc-style invalidation, 2 TCEs per write */ | ||
| 379 | else if (tbl->it_type & TCE_PCI_SWINV_PAIR) { | ||
| 380 | start |= (1ull << 63); | ||
| 381 | end |= (1ull << 63); | ||
| 382 | inc = 16; | ||
| 383 | } | ||
| 384 | /* Default (older HW) */ | ||
| 385 | else | ||
| 386 | inc = 128; | ||
| 387 | |||
| 388 | end |= inc - 1; /* round up end to be different than start */ | ||
| 389 | |||
| 390 | mb(); /* Ensure above stores are visible */ | ||
| 391 | while (start <= end) { | ||
| 392 | __raw_writeq(start, invalidate); | ||
| 393 | start += inc; | ||
| 394 | } | ||
| 395 | /* The iommu layer will do another mb() for us on build() and | ||
| 396 | * we don't care on free() | ||
| 397 | */ | ||
| 398 | } | ||
| 399 | |||
| 400 | |||
| 260 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | 401 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, |
| 261 | unsigned long uaddr, enum dma_data_direction direction, | 402 | unsigned long uaddr, enum dma_data_direction direction, |
| 262 | struct dma_attrs *attrs) | 403 | struct dma_attrs *attrs) |
| 263 | { | 404 | { |
| 264 | u64 proto_tce; | 405 | u64 proto_tce; |
| 265 | u64 *tcep; | 406 | u64 *tcep, *tces; |
| 266 | u64 rpn; | 407 | u64 rpn; |
| 267 | 408 | ||
| 268 | proto_tce = TCE_PCI_READ; // Read allowed | 409 | proto_tce = TCE_PCI_READ; // Read allowed |
| @@ -270,25 +411,33 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | |||
| 270 | if (direction != DMA_TO_DEVICE) | 411 | if (direction != DMA_TO_DEVICE) |
| 271 | proto_tce |= TCE_PCI_WRITE; | 412 | proto_tce |= TCE_PCI_WRITE; |
| 272 | 413 | ||
| 273 | tcep = ((u64 *)tbl->it_base) + index; | 414 | tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset; |
| 415 | rpn = __pa(uaddr) >> TCE_SHIFT; | ||
| 274 | 416 | ||
| 275 | while (npages--) { | 417 | while (npages--) |
| 276 | /* can't move this out since we might cross LMB boundary */ | 418 | *(tcep++) = proto_tce | (rpn++ << TCE_RPN_SHIFT); |
| 277 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 419 | |
| 278 | *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; | 420 | /* Some implementations won't cache invalid TCEs and thus may not |
| 421 | * need that flush. We'll probably turn it_type into a bit mask | ||
| 422 | * of flags if that becomes the case | ||
| 423 | */ | ||
| 424 | if (tbl->it_type & TCE_PCI_SWINV_CREATE) | ||
| 425 | pnv_tce_invalidate(tbl, tces, tcep - 1); | ||
| 279 | 426 | ||
| 280 | uaddr += TCE_PAGE_SIZE; | ||
| 281 | tcep++; | ||
| 282 | } | ||
| 283 | return 0; | 427 | return 0; |
| 284 | } | 428 | } |
| 285 | 429 | ||
| 286 | static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) | 430 | static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) |
| 287 | { | 431 | { |
| 288 | u64 *tcep = ((u64 *)tbl->it_base) + index; | 432 | u64 *tcep, *tces; |
| 433 | |||
| 434 | tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset; | ||
| 289 | 435 | ||
| 290 | while (npages--) | 436 | while (npages--) |
| 291 | *(tcep++) = 0; | 437 | *(tcep++) = 0; |
| 438 | |||
| 439 | if (tbl->it_type & TCE_PCI_SWINV_FREE) | ||
| 440 | pnv_tce_invalidate(tbl, tces, tcep - 1); | ||
| 292 | } | 441 | } |
| 293 | 442 | ||
| 294 | void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | 443 | void pnv_pci_setup_iommu_table(struct iommu_table *tbl, |
| @@ -308,13 +457,14 @@ static struct iommu_table * __devinit | |||
| 308 | pnv_pci_setup_bml_iommu(struct pci_controller *hose) | 457 | pnv_pci_setup_bml_iommu(struct pci_controller *hose) |
| 309 | { | 458 | { |
| 310 | struct iommu_table *tbl; | 459 | struct iommu_table *tbl; |
| 311 | const __be64 *basep; | 460 | const __be64 *basep, *swinvp; |
| 312 | const __be32 *sizep; | 461 | const __be32 *sizep; |
| 313 | 462 | ||
| 314 | basep = of_get_property(hose->dn, "linux,tce-base", NULL); | 463 | basep = of_get_property(hose->dn, "linux,tce-base", NULL); |
| 315 | sizep = of_get_property(hose->dn, "linux,tce-size", NULL); | 464 | sizep = of_get_property(hose->dn, "linux,tce-size", NULL); |
| 316 | if (basep == NULL || sizep == NULL) { | 465 | if (basep == NULL || sizep == NULL) { |
| 317 | pr_err("PCI: %s has missing tce entries !\n", hose->dn->full_name); | 466 | pr_err("PCI: %s has missing tce entries !\n", |
| 467 | hose->dn->full_name); | ||
| 318 | return NULL; | 468 | return NULL; |
| 319 | } | 469 | } |
| 320 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, hose->node); | 470 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, hose->node); |
| @@ -323,6 +473,15 @@ pnv_pci_setup_bml_iommu(struct pci_controller *hose) | |||
| 323 | pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)), | 473 | pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)), |
| 324 | be32_to_cpup(sizep), 0); | 474 | be32_to_cpup(sizep), 0); |
| 325 | iommu_init_table(tbl, hose->node); | 475 | iommu_init_table(tbl, hose->node); |
| 476 | |||
| 477 | /* Deal with SW invalidated TCEs when needed (BML way) */ | ||
| 478 | swinvp = of_get_property(hose->dn, "linux,tce-sw-invalidate-info", | ||
| 479 | NULL); | ||
| 480 | if (swinvp) { | ||
| 481 | tbl->it_busno = swinvp[1]; | ||
| 482 | tbl->it_index = (unsigned long)ioremap(swinvp[0], 8); | ||
| 483 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; | ||
| 484 | } | ||
| 326 | return tbl; | 485 | return tbl; |
| 327 | } | 486 | } |
| 328 | 487 | ||
| @@ -356,6 +515,13 @@ static void __devinit pnv_pci_dma_dev_setup(struct pci_dev *pdev) | |||
| 356 | pnv_pci_dma_fallback_setup(hose, pdev); | 515 | pnv_pci_dma_fallback_setup(hose, pdev); |
| 357 | } | 516 | } |
| 358 | 517 | ||
| 518 | /* Fixup wrong class code in p7ioc root complex */ | ||
| 519 | static void __devinit pnv_p7ioc_rc_quirk(struct pci_dev *dev) | ||
| 520 | { | ||
| 521 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; | ||
| 522 | } | ||
| 523 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk); | ||
| 524 | |||
| 359 | static int pnv_pci_probe_mode(struct pci_bus *bus) | 525 | static int pnv_pci_probe_mode(struct pci_bus *bus) |
| 360 | { | 526 | { |
| 361 | struct pci_controller *hose = pci_bus_to_host(bus); | 527 | struct pci_controller *hose = pci_bus_to_host(bus); |
| @@ -400,12 +566,24 @@ void __init pnv_pci_init(void) | |||
| 400 | init_pci_config_tokens(); | 566 | init_pci_config_tokens(); |
| 401 | find_and_init_phbs(); | 567 | find_and_init_phbs(); |
| 402 | #endif /* CONFIG_PPC_POWERNV_RTAS */ | 568 | #endif /* CONFIG_PPC_POWERNV_RTAS */ |
| 403 | } else { | 569 | } |
| 404 | /* OPAL is here, do our normal stuff */ | 570 | /* OPAL is here, do our normal stuff */ |
| 571 | else { | ||
| 572 | int found_ioda = 0; | ||
| 573 | |||
| 574 | /* Look for IODA IO-Hubs. We don't support mixing IODA | ||
| 575 | * and p5ioc2 due to the need to change some global | ||
| 576 | * probing flags | ||
| 577 | */ | ||
| 578 | for_each_compatible_node(np, NULL, "ibm,ioda-hub") { | ||
| 579 | pnv_pci_init_ioda_hub(np); | ||
| 580 | found_ioda = 1; | ||
| 581 | } | ||
| 405 | 582 | ||
| 406 | /* Look for p5ioc2 IO-Hubs */ | 583 | /* Look for p5ioc2 IO-Hubs */ |
| 407 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") | 584 | if (!found_ioda) |
| 408 | pnv_pci_init_p5ioc2_hub(np); | 585 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") |
| 586 | pnv_pci_init_p5ioc2_hub(np); | ||
| 409 | } | 587 | } |
| 410 | 588 | ||
| 411 | /* Setup the linkage between OF nodes and PHBs */ | 589 | /* Setup the linkage between OF nodes and PHBs */ |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index d4dbc4950936..8bc479634643 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
| @@ -9,9 +9,63 @@ enum pnv_phb_type { | |||
| 9 | PNV_PHB_IODA2, | 9 | PNV_PHB_IODA2, |
| 10 | }; | 10 | }; |
| 11 | 11 | ||
| 12 | /* Precise PHB model for error management */ | ||
| 13 | enum pnv_phb_model { | ||
| 14 | PNV_PHB_MODEL_UNKNOWN, | ||
| 15 | PNV_PHB_MODEL_P5IOC2, | ||
| 16 | PNV_PHB_MODEL_P7IOC, | ||
| 17 | }; | ||
| 18 | |||
| 19 | #define PNV_PCI_DIAG_BUF_SIZE 4096 | ||
| 20 | |||
| 21 | /* Data associated with a PE, including IOMMU tracking etc.. */ | ||
| 22 | struct pnv_ioda_pe { | ||
| 23 | /* A PE can be associated with a single device or an | ||
| 24 | * entire bus (& children). In the former case, pdev | ||
| 25 | * is populated, in the later case, pbus is. | ||
| 26 | */ | ||
| 27 | struct pci_dev *pdev; | ||
| 28 | struct pci_bus *pbus; | ||
| 29 | |||
| 30 | /* Effective RID (device RID for a device PE and base bus | ||
| 31 | * RID with devfn 0 for a bus PE) | ||
| 32 | */ | ||
| 33 | unsigned int rid; | ||
| 34 | |||
| 35 | /* PE number */ | ||
| 36 | unsigned int pe_number; | ||
| 37 | |||
| 38 | /* "Weight" assigned to the PE for the sake of DMA resource | ||
| 39 | * allocations | ||
| 40 | */ | ||
| 41 | unsigned int dma_weight; | ||
| 42 | |||
| 43 | /* This is a PCI-E -> PCI-X bridge, this points to the | ||
| 44 | * corresponding bus PE | ||
| 45 | */ | ||
| 46 | struct pnv_ioda_pe *bus_pe; | ||
| 47 | |||
| 48 | /* "Base" iommu table, ie, 4K TCEs, 32-bit DMA */ | ||
| 49 | int tce32_seg; | ||
| 50 | int tce32_segcount; | ||
| 51 | struct iommu_table tce32_table; | ||
| 52 | |||
| 53 | /* XXX TODO: Add support for additional 64-bit iommus */ | ||
| 54 | |||
| 55 | /* MSIs. MVE index is identical for for 32 and 64 bit MSI | ||
| 56 | * and -1 if not supported. (It's actually identical to the | ||
| 57 | * PE number) | ||
| 58 | */ | ||
| 59 | int mve_number; | ||
| 60 | |||
| 61 | /* Link in list of PE#s */ | ||
| 62 | struct list_head link; | ||
| 63 | }; | ||
| 64 | |||
| 12 | struct pnv_phb { | 65 | struct pnv_phb { |
| 13 | struct pci_controller *hose; | 66 | struct pci_controller *hose; |
| 14 | enum pnv_phb_type type; | 67 | enum pnv_phb_type type; |
| 68 | enum pnv_phb_model model; | ||
| 15 | u64 opal_id; | 69 | u64 opal_id; |
| 16 | void __iomem *regs; | 70 | void __iomem *regs; |
| 17 | spinlock_t lock; | 71 | spinlock_t lock; |
| @@ -34,7 +88,52 @@ struct pnv_phb { | |||
| 34 | struct { | 88 | struct { |
| 35 | struct iommu_table iommu_table; | 89 | struct iommu_table iommu_table; |
| 36 | } p5ioc2; | 90 | } p5ioc2; |
| 91 | |||
| 92 | struct { | ||
| 93 | /* Global bridge info */ | ||
| 94 | unsigned int total_pe; | ||
| 95 | unsigned int m32_size; | ||
| 96 | unsigned int m32_segsize; | ||
| 97 | unsigned int m32_pci_base; | ||
| 98 | unsigned int io_size; | ||
| 99 | unsigned int io_segsize; | ||
| 100 | unsigned int io_pci_base; | ||
| 101 | |||
| 102 | /* PE allocation bitmap */ | ||
| 103 | unsigned long *pe_alloc; | ||
| 104 | |||
| 105 | /* M32 & IO segment maps */ | ||
| 106 | unsigned int *m32_segmap; | ||
| 107 | unsigned int *io_segmap; | ||
| 108 | struct pnv_ioda_pe *pe_array; | ||
| 109 | |||
| 110 | /* Reverse map of PEs, will have to extend if | ||
| 111 | * we are to support more than 256 PEs, indexed | ||
| 112 | * bus { bus, devfn } | ||
| 113 | */ | ||
| 114 | unsigned char pe_rmap[0x10000]; | ||
| 115 | |||
| 116 | /* 32-bit TCE tables allocation */ | ||
| 117 | unsigned long tce32_count; | ||
| 118 | |||
| 119 | /* Total "weight" for the sake of DMA resources | ||
| 120 | * allocation | ||
| 121 | */ | ||
| 122 | unsigned int dma_weight; | ||
| 123 | unsigned int dma_pe_count; | ||
| 124 | |||
| 125 | /* Sorted list of used PE's, sorted at | ||
| 126 | * boot for resource allocation purposes | ||
| 127 | */ | ||
| 128 | struct list_head pe_list; | ||
| 129 | } ioda; | ||
| 37 | }; | 130 | }; |
| 131 | |||
| 132 | /* PHB status structure */ | ||
| 133 | union { | ||
| 134 | unsigned char blob[PNV_PCI_DIAG_BUF_SIZE]; | ||
| 135 | struct OpalIoP7IOCPhbErrorData p7ioc; | ||
| 136 | } diag; | ||
| 38 | }; | 137 | }; |
| 39 | 138 | ||
| 40 | extern struct pci_ops pnv_pci_ops; | 139 | extern struct pci_ops pnv_pci_ops; |
| @@ -43,6 +142,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | |||
| 43 | void *tce_mem, u64 tce_size, | 142 | void *tce_mem, u64 tce_size, |
| 44 | u64 dma_offset); | 143 | u64 dma_offset); |
| 45 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); | 144 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); |
| 145 | extern void pnv_pci_init_ioda_hub(struct device_node *np); | ||
| 46 | 146 | ||
| 47 | 147 | ||
| 48 | #endif /* __POWERNV_PCI_H */ | 148 | #endif /* __POWERNV_PCI_H */ |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index e87736685243..17210c526c52 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
| @@ -75,7 +75,7 @@ int __devinit pnv_smp_kick_cpu(int nr) | |||
| 75 | /* On OPAL v2 the CPU are still spinning inside OPAL itself, | 75 | /* On OPAL v2 the CPU are still spinning inside OPAL itself, |
| 76 | * get them back now | 76 | * get them back now |
| 77 | */ | 77 | */ |
| 78 | if (firmware_has_feature(FW_FEATURE_OPALv2)) { | 78 | if (!paca[nr].cpu_start && firmware_has_feature(FW_FEATURE_OPALv2)) { |
| 79 | pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); | 79 | pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); |
| 80 | rc = opal_start_cpu(pcpu, start_here); | 80 | rc = opal_start_cpu(pcpu, start_here); |
| 81 | if (rc != OPAL_SUCCESS) | 81 | if (rc != OPAL_SUCCESS) |
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 1d6f4f478fe2..617efa12a3a5 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c | |||
| @@ -31,18 +31,18 @@ | |||
| 31 | 31 | ||
| 32 | #if defined(DEBUG) | 32 | #if defined(DEBUG) |
| 33 | #define DBG udbg_printf | 33 | #define DBG udbg_printf |
| 34 | #define FAIL udbg_printf | ||
| 34 | #else | 35 | #else |
| 35 | #define DBG pr_debug | 36 | #define DBG pr_devel |
| 37 | #define FAIL pr_debug | ||
| 36 | #endif | 38 | #endif |
| 37 | 39 | ||
| 38 | /** | 40 | /** |
| 39 | * struct ps3_bmp - a per cpu irq status and mask bitmap structure | 41 | * struct ps3_bmp - a per cpu irq status and mask bitmap structure |
| 40 | * @status: 256 bit status bitmap indexed by plug | 42 | * @status: 256 bit status bitmap indexed by plug |
| 41 | * @unused_1: | 43 | * @unused_1: Alignment |
| 42 | * @mask: 256 bit mask bitmap indexed by plug | 44 | * @mask: 256 bit mask bitmap indexed by plug |
| 43 | * @unused_2: | 45 | * @unused_2: Alignment |
| 44 | * @lock: | ||
| 45 | * @ipi_debug_brk_mask: | ||
| 46 | * | 46 | * |
| 47 | * The HV maintains per SMT thread mappings of HV outlet to HV plug on | 47 | * The HV maintains per SMT thread mappings of HV outlet to HV plug on |
| 48 | * behalf of the guest. These mappings are implemented as 256 bit guest | 48 | * behalf of the guest. These mappings are implemented as 256 bit guest |
| @@ -73,21 +73,24 @@ struct ps3_bmp { | |||
| 73 | unsigned long mask; | 73 | unsigned long mask; |
| 74 | u64 unused_2[3]; | 74 | u64 unused_2[3]; |
| 75 | }; | 75 | }; |
| 76 | u64 ipi_debug_brk_mask; | ||
| 77 | spinlock_t lock; | ||
| 78 | }; | 76 | }; |
| 79 | 77 | ||
| 80 | /** | 78 | /** |
| 81 | * struct ps3_private - a per cpu data structure | 79 | * struct ps3_private - a per cpu data structure |
| 82 | * @bmp: ps3_bmp structure | 80 | * @bmp: ps3_bmp structure |
| 81 | * @bmp_lock: Syncronize access to bmp. | ||
| 82 | * @ipi_debug_brk_mask: Mask for debug break IPIs | ||
| 83 | * @ppe_id: HV logical_ppe_id | 83 | * @ppe_id: HV logical_ppe_id |
| 84 | * @thread_id: HV thread_id | 84 | * @thread_id: HV thread_id |
| 85 | * @ipi_mask: Mask of IPI virqs | ||
| 85 | */ | 86 | */ |
| 86 | 87 | ||
| 87 | struct ps3_private { | 88 | struct ps3_private { |
| 88 | struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); | 89 | struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); |
| 90 | spinlock_t bmp_lock; | ||
| 89 | u64 ppe_id; | 91 | u64 ppe_id; |
| 90 | u64 thread_id; | 92 | u64 thread_id; |
| 93 | unsigned long ipi_debug_brk_mask; | ||
| 91 | unsigned long ipi_mask; | 94 | unsigned long ipi_mask; |
| 92 | }; | 95 | }; |
| 93 | 96 | ||
| @@ -105,7 +108,7 @@ static void ps3_chip_mask(struct irq_data *d) | |||
| 105 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); | 108 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); |
| 106 | unsigned long flags; | 109 | unsigned long flags; |
| 107 | 110 | ||
| 108 | pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, | 111 | DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, |
| 109 | pd->thread_id, d->irq); | 112 | pd->thread_id, d->irq); |
| 110 | 113 | ||
| 111 | local_irq_save(flags); | 114 | local_irq_save(flags); |
| @@ -126,7 +129,7 @@ static void ps3_chip_unmask(struct irq_data *d) | |||
| 126 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); | 129 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); |
| 127 | unsigned long flags; | 130 | unsigned long flags; |
| 128 | 131 | ||
| 129 | pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, | 132 | DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, |
| 130 | pd->thread_id, d->irq); | 133 | pd->thread_id, d->irq); |
| 131 | 134 | ||
| 132 | local_irq_save(flags); | 135 | local_irq_save(flags); |
| @@ -190,19 +193,19 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
| 190 | *virq = irq_create_mapping(NULL, outlet); | 193 | *virq = irq_create_mapping(NULL, outlet); |
| 191 | 194 | ||
| 192 | if (*virq == NO_IRQ) { | 195 | if (*virq == NO_IRQ) { |
| 193 | pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n", | 196 | FAIL("%s:%d: irq_create_mapping failed: outlet %lu\n", |
| 194 | __func__, __LINE__, outlet); | 197 | __func__, __LINE__, outlet); |
| 195 | result = -ENOMEM; | 198 | result = -ENOMEM; |
| 196 | goto fail_create; | 199 | goto fail_create; |
| 197 | } | 200 | } |
| 198 | 201 | ||
| 199 | pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, | 202 | DBG("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, |
| 200 | outlet, cpu, *virq); | 203 | outlet, cpu, *virq); |
| 201 | 204 | ||
| 202 | result = irq_set_chip_data(*virq, pd); | 205 | result = irq_set_chip_data(*virq, pd); |
| 203 | 206 | ||
| 204 | if (result) { | 207 | if (result) { |
| 205 | pr_debug("%s:%d: irq_set_chip_data failed\n", | 208 | FAIL("%s:%d: irq_set_chip_data failed\n", |
| 206 | __func__, __LINE__); | 209 | __func__, __LINE__); |
| 207 | goto fail_set; | 210 | goto fail_set; |
| 208 | } | 211 | } |
| @@ -228,13 +231,13 @@ static int ps3_virq_destroy(unsigned int virq) | |||
| 228 | { | 231 | { |
| 229 | const struct ps3_private *pd = irq_get_chip_data(virq); | 232 | const struct ps3_private *pd = irq_get_chip_data(virq); |
| 230 | 233 | ||
| 231 | pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, | 234 | DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, |
| 232 | __LINE__, pd->ppe_id, pd->thread_id, virq); | 235 | __LINE__, pd->ppe_id, pd->thread_id, virq); |
| 233 | 236 | ||
| 234 | irq_set_chip_data(virq, NULL); | 237 | irq_set_chip_data(virq, NULL); |
| 235 | irq_dispose_mapping(virq); | 238 | irq_dispose_mapping(virq); |
| 236 | 239 | ||
| 237 | pr_debug("%s:%d <-\n", __func__, __LINE__); | 240 | DBG("%s:%d <-\n", __func__, __LINE__); |
| 238 | return 0; | 241 | return 0; |
| 239 | } | 242 | } |
| 240 | 243 | ||
| @@ -257,7 +260,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
| 257 | result = ps3_virq_setup(cpu, outlet, virq); | 260 | result = ps3_virq_setup(cpu, outlet, virq); |
| 258 | 261 | ||
| 259 | if (result) { | 262 | if (result) { |
| 260 | pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); | 263 | FAIL("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); |
| 261 | goto fail_setup; | 264 | goto fail_setup; |
| 262 | } | 265 | } |
| 263 | 266 | ||
| @@ -269,7 +272,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
| 269 | outlet, 0); | 272 | outlet, 0); |
| 270 | 273 | ||
| 271 | if (result) { | 274 | if (result) { |
| 272 | pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", | 275 | FAIL("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", |
| 273 | __func__, __LINE__, ps3_result(result)); | 276 | __func__, __LINE__, ps3_result(result)); |
| 274 | result = -EPERM; | 277 | result = -EPERM; |
| 275 | goto fail_connect; | 278 | goto fail_connect; |
| @@ -298,7 +301,7 @@ int ps3_irq_plug_destroy(unsigned int virq) | |||
| 298 | int result; | 301 | int result; |
| 299 | const struct ps3_private *pd = irq_get_chip_data(virq); | 302 | const struct ps3_private *pd = irq_get_chip_data(virq); |
| 300 | 303 | ||
| 301 | pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, | 304 | DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, |
| 302 | __LINE__, pd->ppe_id, pd->thread_id, virq); | 305 | __LINE__, pd->ppe_id, pd->thread_id, virq); |
| 303 | 306 | ||
| 304 | ps3_chip_mask(irq_get_irq_data(virq)); | 307 | ps3_chip_mask(irq_get_irq_data(virq)); |
| @@ -306,7 +309,7 @@ int ps3_irq_plug_destroy(unsigned int virq) | |||
| 306 | result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq); | 309 | result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq); |
| 307 | 310 | ||
| 308 | if (result) | 311 | if (result) |
| 309 | pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", | 312 | FAIL("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", |
| 310 | __func__, __LINE__, ps3_result(result)); | 313 | __func__, __LINE__, ps3_result(result)); |
| 311 | 314 | ||
| 312 | ps3_virq_destroy(virq); | 315 | ps3_virq_destroy(virq); |
| @@ -334,7 +337,7 @@ int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) | |||
| 334 | result = lv1_construct_event_receive_port(&outlet); | 337 | result = lv1_construct_event_receive_port(&outlet); |
| 335 | 338 | ||
| 336 | if (result) { | 339 | if (result) { |
| 337 | pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n", | 340 | FAIL("%s:%d: lv1_construct_event_receive_port failed: %s\n", |
| 338 | __func__, __LINE__, ps3_result(result)); | 341 | __func__, __LINE__, ps3_result(result)); |
| 339 | *virq = NO_IRQ; | 342 | *virq = NO_IRQ; |
| 340 | return result; | 343 | return result; |
| @@ -360,14 +363,14 @@ int ps3_event_receive_port_destroy(unsigned int virq) | |||
| 360 | { | 363 | { |
| 361 | int result; | 364 | int result; |
| 362 | 365 | ||
| 363 | pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq); | 366 | DBG(" -> %s:%d virq %u\n", __func__, __LINE__, virq); |
| 364 | 367 | ||
| 365 | ps3_chip_mask(irq_get_irq_data(virq)); | 368 | ps3_chip_mask(irq_get_irq_data(virq)); |
| 366 | 369 | ||
| 367 | result = lv1_destruct_event_receive_port(virq_to_hw(virq)); | 370 | result = lv1_destruct_event_receive_port(virq_to_hw(virq)); |
| 368 | 371 | ||
| 369 | if (result) | 372 | if (result) |
| 370 | pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", | 373 | FAIL("%s:%d: lv1_destruct_event_receive_port failed: %s\n", |
| 371 | __func__, __LINE__, ps3_result(result)); | 374 | __func__, __LINE__, ps3_result(result)); |
| 372 | 375 | ||
| 373 | /* | 376 | /* |
| @@ -375,7 +378,7 @@ int ps3_event_receive_port_destroy(unsigned int virq) | |||
| 375 | * calls from interrupt context (smp_call_function) when kexecing. | 378 | * calls from interrupt context (smp_call_function) when kexecing. |
| 376 | */ | 379 | */ |
| 377 | 380 | ||
| 378 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 381 | DBG(" <- %s:%d\n", __func__, __LINE__); |
| 379 | return result; | 382 | return result; |
| 380 | } | 383 | } |
| 381 | 384 | ||
| @@ -411,7 +414,7 @@ int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, | |||
| 411 | dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); | 414 | dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); |
| 412 | 415 | ||
| 413 | if (result) { | 416 | if (result) { |
| 414 | pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" | 417 | FAIL("%s:%d: lv1_connect_interrupt_event_receive_port" |
| 415 | " failed: %s\n", __func__, __LINE__, | 418 | " failed: %s\n", __func__, __LINE__, |
| 416 | ps3_result(result)); | 419 | ps3_result(result)); |
| 417 | ps3_event_receive_port_destroy(*virq); | 420 | ps3_event_receive_port_destroy(*virq); |
| @@ -419,7 +422,7 @@ int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, | |||
| 419 | return result; | 422 | return result; |
| 420 | } | 423 | } |
| 421 | 424 | ||
| 422 | pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, | 425 | DBG("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, |
| 423 | dev->interrupt_id, *virq); | 426 | dev->interrupt_id, *virq); |
| 424 | 427 | ||
| 425 | return 0; | 428 | return 0; |
| @@ -433,14 +436,14 @@ int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, | |||
| 433 | 436 | ||
| 434 | int result; | 437 | int result; |
| 435 | 438 | ||
| 436 | pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, | 439 | DBG(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, |
| 437 | dev->interrupt_id, virq); | 440 | dev->interrupt_id, virq); |
| 438 | 441 | ||
| 439 | result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, | 442 | result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, |
| 440 | dev->dev_id, virq_to_hw(virq), dev->interrupt_id); | 443 | dev->dev_id, virq_to_hw(virq), dev->interrupt_id); |
| 441 | 444 | ||
| 442 | if (result) | 445 | if (result) |
| 443 | pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" | 446 | FAIL("%s:%d: lv1_disconnect_interrupt_event_receive_port" |
| 444 | " failed: %s\n", __func__, __LINE__, | 447 | " failed: %s\n", __func__, __LINE__, |
| 445 | ps3_result(result)); | 448 | ps3_result(result)); |
| 446 | 449 | ||
| @@ -455,7 +458,7 @@ int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, | |||
| 455 | result = ps3_virq_destroy(virq); | 458 | result = ps3_virq_destroy(virq); |
| 456 | BUG_ON(result); | 459 | BUG_ON(result); |
| 457 | 460 | ||
| 458 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 461 | DBG(" <- %s:%d\n", __func__, __LINE__); |
| 459 | return result; | 462 | return result; |
| 460 | } | 463 | } |
| 461 | EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); | 464 | EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); |
| @@ -480,7 +483,7 @@ int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, | |||
| 480 | result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); | 483 | result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); |
| 481 | 484 | ||
| 482 | if (result) { | 485 | if (result) { |
| 483 | pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", | 486 | FAIL("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", |
| 484 | __func__, __LINE__, ps3_result(result)); | 487 | __func__, __LINE__, ps3_result(result)); |
| 485 | return result; | 488 | return result; |
| 486 | } | 489 | } |
| @@ -510,7 +513,7 @@ int ps3_io_irq_destroy(unsigned int virq) | |||
| 510 | result = lv1_destruct_io_irq_outlet(outlet); | 513 | result = lv1_destruct_io_irq_outlet(outlet); |
| 511 | 514 | ||
| 512 | if (result) | 515 | if (result) |
| 513 | pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", | 516 | FAIL("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", |
| 514 | __func__, __LINE__, ps3_result(result)); | 517 | __func__, __LINE__, ps3_result(result)); |
| 515 | 518 | ||
| 516 | return result; | 519 | return result; |
| @@ -542,7 +545,7 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, | |||
| 542 | result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); | 545 | result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); |
| 543 | 546 | ||
| 544 | if (result) { | 547 | if (result) { |
| 545 | pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", | 548 | FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", |
| 546 | __func__, __LINE__, ps3_result(result)); | 549 | __func__, __LINE__, ps3_result(result)); |
| 547 | return result; | 550 | return result; |
| 548 | } | 551 | } |
| @@ -562,7 +565,7 @@ int ps3_vuart_irq_destroy(unsigned int virq) | |||
| 562 | result = lv1_deconfigure_virtual_uart_irq(); | 565 | result = lv1_deconfigure_virtual_uart_irq(); |
| 563 | 566 | ||
| 564 | if (result) { | 567 | if (result) { |
| 565 | pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", | 568 | FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", |
| 566 | __func__, __LINE__, ps3_result(result)); | 569 | __func__, __LINE__, ps3_result(result)); |
| 567 | return result; | 570 | return result; |
| 568 | } | 571 | } |
| @@ -595,7 +598,7 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, | |||
| 595 | result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); | 598 | result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); |
| 596 | 599 | ||
| 597 | if (result) { | 600 | if (result) { |
| 598 | pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", | 601 | FAIL("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", |
| 599 | __func__, __LINE__, ps3_result(result)); | 602 | __func__, __LINE__, ps3_result(result)); |
| 600 | return result; | 603 | return result; |
| 601 | } | 604 | } |
| @@ -626,7 +629,7 @@ int ps3_spe_irq_destroy(unsigned int virq) | |||
| 626 | static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, | 629 | static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, |
| 627 | const char* func, int line) | 630 | const char* func, int line) |
| 628 | { | 631 | { |
| 629 | pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n", | 632 | pr_debug("%s:%d: %s %u {%04llx_%04llx_%04llx_%04llx}\n", |
| 630 | func, line, header, cpu, | 633 | func, line, header, cpu, |
| 631 | *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, | 634 | *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, |
| 632 | *p & 0xffff); | 635 | *p & 0xffff); |
| @@ -635,7 +638,7 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, | |||
| 635 | static void __maybe_unused _dump_256_bmp(const char *header, | 638 | static void __maybe_unused _dump_256_bmp(const char *header, |
| 636 | const u64 *p, unsigned cpu, const char* func, int line) | 639 | const u64 *p, unsigned cpu, const char* func, int line) |
| 637 | { | 640 | { |
| 638 | pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", | 641 | pr_debug("%s:%d: %s %u {%016llx:%016llx:%016llx:%016llx}\n", |
| 639 | func, line, header, cpu, p[0], p[1], p[2], p[3]); | 642 | func, line, header, cpu, p[0], p[1], p[2], p[3]); |
| 640 | } | 643 | } |
| 641 | 644 | ||
| @@ -644,10 +647,10 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line) | |||
| 644 | { | 647 | { |
| 645 | unsigned long flags; | 648 | unsigned long flags; |
| 646 | 649 | ||
| 647 | spin_lock_irqsave(&pd->bmp.lock, flags); | 650 | spin_lock_irqsave(&pd->bmp_lock, flags); |
| 648 | _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line); | 651 | _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line); |
| 649 | _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); | 652 | _dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line); |
| 650 | spin_unlock_irqrestore(&pd->bmp.lock, flags); | 653 | spin_unlock_irqrestore(&pd->bmp_lock, flags); |
| 651 | } | 654 | } |
| 652 | 655 | ||
| 653 | #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) | 656 | #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) |
| @@ -656,9 +659,9 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd, | |||
| 656 | { | 659 | { |
| 657 | unsigned long flags; | 660 | unsigned long flags; |
| 658 | 661 | ||
| 659 | spin_lock_irqsave(&pd->bmp.lock, flags); | 662 | spin_lock_irqsave(&pd->bmp_lock, flags); |
| 660 | _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); | 663 | _dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line); |
| 661 | spin_unlock_irqrestore(&pd->bmp.lock, flags); | 664 | spin_unlock_irqrestore(&pd->bmp_lock, flags); |
| 662 | } | 665 | } |
| 663 | #else | 666 | #else |
| 664 | static void dump_bmp(struct ps3_private* pd) {}; | 667 | static void dump_bmp(struct ps3_private* pd) {}; |
| @@ -667,7 +670,7 @@ static void dump_bmp(struct ps3_private* pd) {}; | |||
| 667 | static int ps3_host_map(struct irq_host *h, unsigned int virq, | 670 | static int ps3_host_map(struct irq_host *h, unsigned int virq, |
| 668 | irq_hw_number_t hwirq) | 671 | irq_hw_number_t hwirq) |
| 669 | { | 672 | { |
| 670 | pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, | 673 | DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, |
| 671 | virq); | 674 | virq); |
| 672 | 675 | ||
| 673 | irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); | 676 | irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); |
| @@ -690,10 +693,10 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) | |||
| 690 | { | 693 | { |
| 691 | struct ps3_private *pd = &per_cpu(ps3_private, cpu); | 694 | struct ps3_private *pd = &per_cpu(ps3_private, cpu); |
| 692 | 695 | ||
| 693 | pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; | 696 | set_bit(63 - virq, &pd->ipi_debug_brk_mask); |
| 694 | 697 | ||
| 695 | pr_debug("%s:%d: cpu %u, virq %u, mask %llxh\n", __func__, __LINE__, | 698 | DBG("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__, |
| 696 | cpu, virq, pd->bmp.ipi_debug_brk_mask); | 699 | cpu, virq, pd->ipi_debug_brk_mask); |
| 697 | } | 700 | } |
| 698 | 701 | ||
| 699 | void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) | 702 | void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) |
| @@ -714,14 +717,14 @@ static unsigned int ps3_get_irq(void) | |||
| 714 | 717 | ||
| 715 | /* check for ipi break first to stop this cpu ASAP */ | 718 | /* check for ipi break first to stop this cpu ASAP */ |
| 716 | 719 | ||
| 717 | if (x & pd->bmp.ipi_debug_brk_mask) | 720 | if (x & pd->ipi_debug_brk_mask) |
| 718 | x &= pd->bmp.ipi_debug_brk_mask; | 721 | x &= pd->ipi_debug_brk_mask; |
| 719 | 722 | ||
| 720 | asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); | 723 | asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); |
| 721 | plug &= 0x3f; | 724 | plug &= 0x3f; |
| 722 | 725 | ||
| 723 | if (unlikely(plug == NO_IRQ)) { | 726 | if (unlikely(plug == NO_IRQ)) { |
| 724 | pr_debug("%s:%d: no plug found: thread_id %llu\n", __func__, | 727 | DBG("%s:%d: no plug found: thread_id %llu\n", __func__, |
| 725 | __LINE__, pd->thread_id); | 728 | __LINE__, pd->thread_id); |
| 726 | dump_bmp(&per_cpu(ps3_private, 0)); | 729 | dump_bmp(&per_cpu(ps3_private, 0)); |
| 727 | dump_bmp(&per_cpu(ps3_private, 1)); | 730 | dump_bmp(&per_cpu(ps3_private, 1)); |
| @@ -760,9 +763,9 @@ void __init ps3_init_IRQ(void) | |||
| 760 | 763 | ||
| 761 | lv1_get_logical_ppe_id(&pd->ppe_id); | 764 | lv1_get_logical_ppe_id(&pd->ppe_id); |
| 762 | pd->thread_id = get_hard_smp_processor_id(cpu); | 765 | pd->thread_id = get_hard_smp_processor_id(cpu); |
| 763 | spin_lock_init(&pd->bmp.lock); | 766 | spin_lock_init(&pd->bmp_lock); |
| 764 | 767 | ||
| 765 | pr_debug("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", | 768 | DBG("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", |
| 766 | __func__, __LINE__, pd->ppe_id, pd->thread_id, | 769 | __func__, __LINE__, pd->ppe_id, pd->thread_id, |
| 767 | ps3_mm_phys_to_lpar(__pa(&pd->bmp))); | 770 | ps3_mm_phys_to_lpar(__pa(&pd->bmp))); |
| 768 | 771 | ||
| @@ -770,7 +773,7 @@ void __init ps3_init_IRQ(void) | |||
| 770 | pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); | 773 | pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); |
| 771 | 774 | ||
| 772 | if (result) | 775 | if (result) |
| 773 | pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" | 776 | FAIL("%s:%d: lv1_configure_irq_state_bitmap failed:" |
| 774 | " %s\n", __func__, __LINE__, | 777 | " %s\n", __func__, __LINE__, |
| 775 | ps3_result(result)); | 778 | ps3_result(result)); |
| 776 | } | 779 | } |
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index ca40f6afd35d..7bdfea336f5e 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c | |||
| @@ -44,7 +44,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) | |||
| 44 | s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.'; | 44 | s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.'; |
| 45 | s[i] = 0; | 45 | s[i] = 0; |
| 46 | 46 | ||
| 47 | pr_debug("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s); | 47 | pr_devel("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s); |
| 48 | #endif | 48 | #endif |
| 49 | } | 49 | } |
| 50 | 50 | ||
| @@ -53,7 +53,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) | |||
| 53 | static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, | 53 | static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, |
| 54 | u64 n4, const char *func, int line) | 54 | u64 n4, const char *func, int line) |
| 55 | { | 55 | { |
| 56 | pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); | 56 | pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id); |
| 57 | _dump_field("n1: ", n1, func, line); | 57 | _dump_field("n1: ", n1, func, line); |
| 58 | _dump_field("n2: ", n2, func, line); | 58 | _dump_field("n2: ", n2, func, line); |
| 59 | _dump_field("n3: ", n3, func, line); | 59 | _dump_field("n3: ", n3, func, line); |
| @@ -65,13 +65,13 @@ static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, | |||
| 65 | static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | 65 | static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, |
| 66 | u64 v1, u64 v2, const char *func, int line) | 66 | u64 v1, u64 v2, const char *func, int line) |
| 67 | { | 67 | { |
| 68 | pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); | 68 | pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id); |
| 69 | _dump_field("n1: ", n1, func, line); | 69 | _dump_field("n1: ", n1, func, line); |
| 70 | _dump_field("n2: ", n2, func, line); | 70 | _dump_field("n2: ", n2, func, line); |
| 71 | _dump_field("n3: ", n3, func, line); | 71 | _dump_field("n3: ", n3, func, line); |
| 72 | _dump_field("n4: ", n4, func, line); | 72 | _dump_field("n4: ", n4, func, line); |
| 73 | pr_debug("%s:%d: v1: %016llx\n", func, line, v1); | 73 | pr_devel("%s:%d: v1: %016llx\n", func, line, v1); |
| 74 | pr_debug("%s:%d: v2: %016llx\n", func, line, v2); | 74 | pr_devel("%s:%d: v2: %016llx\n", func, line, v2); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | /** | 77 | /** |
| @@ -131,11 +131,11 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | |||
| 131 | lpar_id = id; | 131 | lpar_id = id; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | result = lv1_get_repository_node_value(lpar_id, n1, n2, n3, n4, &v1, | 134 | result = lv1_read_repository_node(lpar_id, n1, n2, n3, n4, &v1, |
| 135 | &v2); | 135 | &v2); |
| 136 | 136 | ||
| 137 | if (result) { | 137 | if (result) { |
| 138 | pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", | 138 | pr_warn("%s:%d: lv1_read_repository_node failed: %s\n", |
| 139 | __func__, __LINE__, ps3_result(result)); | 139 | __func__, __LINE__, ps3_result(result)); |
| 140 | dump_node_name(lpar_id, n1, n2, n3, n4); | 140 | dump_node_name(lpar_id, n1, n2, n3, n4); |
| 141 | return -ENOENT; | 141 | return -ENOENT; |
| @@ -149,10 +149,10 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | |||
| 149 | *_v2 = v2; | 149 | *_v2 = v2; |
| 150 | 150 | ||
| 151 | if (v1 && !_v1) | 151 | if (v1 && !_v1) |
| 152 | pr_debug("%s:%d: warning: discarding non-zero v1: %016llx\n", | 152 | pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n", |
| 153 | __func__, __LINE__, v1); | 153 | __func__, __LINE__, v1); |
| 154 | if (v2 && !_v2) | 154 | if (v2 && !_v2) |
| 155 | pr_debug("%s:%d: warning: discarding non-zero v2: %016llx\n", | 155 | pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n", |
| 156 | __func__, __LINE__, v2); | 156 | __func__, __LINE__, v2); |
| 157 | 157 | ||
| 158 | return 0; | 158 | return 0; |
| @@ -323,16 +323,16 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) | |||
| 323 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); | 323 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); |
| 324 | 324 | ||
| 325 | if (result) { | 325 | if (result) { |
| 326 | pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); | 326 | pr_devel("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); |
| 327 | return result; | 327 | return result; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n", | 330 | pr_devel("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n", |
| 331 | __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, | 331 | __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, |
| 332 | num_dev); | 332 | num_dev); |
| 333 | 333 | ||
| 334 | if (tmp.dev_index >= num_dev) { | 334 | if (tmp.dev_index >= num_dev) { |
| 335 | pr_debug("%s:%d: no device found\n", __func__, __LINE__); | 335 | pr_devel("%s:%d: no device found\n", __func__, __LINE__); |
| 336 | return -ENODEV; | 336 | return -ENODEV; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| @@ -340,7 +340,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) | |||
| 340 | &tmp.dev_type); | 340 | &tmp.dev_type); |
| 341 | 341 | ||
| 342 | if (result) { | 342 | if (result) { |
| 343 | pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__); | 343 | pr_devel("%s:%d read_dev_type failed\n", __func__, __LINE__); |
| 344 | return result; | 344 | return result; |
| 345 | } | 345 | } |
| 346 | 346 | ||
| @@ -348,12 +348,12 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) | |||
| 348 | &tmp.dev_id); | 348 | &tmp.dev_id); |
| 349 | 349 | ||
| 350 | if (result) { | 350 | if (result) { |
| 351 | pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, | 351 | pr_devel("%s:%d ps3_repository_read_dev_id failed\n", __func__, |
| 352 | __LINE__); | 352 | __LINE__); |
| 353 | return result; | 353 | return result; |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n", | 356 | pr_devel("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n", |
| 357 | __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); | 357 | __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); |
| 358 | 358 | ||
| 359 | *repo = tmp; | 359 | *repo = tmp; |
| @@ -367,14 +367,14 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, | |||
| 367 | struct ps3_repository_device tmp; | 367 | struct ps3_repository_device tmp; |
| 368 | unsigned int num_dev; | 368 | unsigned int num_dev; |
| 369 | 369 | ||
| 370 | pr_debug(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__, | 370 | pr_devel(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__, |
| 371 | bus_id, dev_id); | 371 | bus_id, dev_id); |
| 372 | 372 | ||
| 373 | for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { | 373 | for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { |
| 374 | result = ps3_repository_read_bus_id(tmp.bus_index, | 374 | result = ps3_repository_read_bus_id(tmp.bus_index, |
| 375 | &tmp.bus_id); | 375 | &tmp.bus_id); |
| 376 | if (result) { | 376 | if (result) { |
| 377 | pr_debug("%s:%u read_bus_id(%u) failed\n", __func__, | 377 | pr_devel("%s:%u read_bus_id(%u) failed\n", __func__, |
| 378 | __LINE__, tmp.bus_index); | 378 | __LINE__, tmp.bus_index); |
| 379 | return result; | 379 | return result; |
| 380 | } | 380 | } |
| @@ -382,23 +382,23 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, | |||
| 382 | if (tmp.bus_id == bus_id) | 382 | if (tmp.bus_id == bus_id) |
| 383 | goto found_bus; | 383 | goto found_bus; |
| 384 | 384 | ||
| 385 | pr_debug("%s:%u: skip, bus_id %llu\n", __func__, __LINE__, | 385 | pr_devel("%s:%u: skip, bus_id %llu\n", __func__, __LINE__, |
| 386 | tmp.bus_id); | 386 | tmp.bus_id); |
| 387 | } | 387 | } |
| 388 | pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); | 388 | pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__); |
| 389 | return result; | 389 | return result; |
| 390 | 390 | ||
| 391 | found_bus: | 391 | found_bus: |
| 392 | result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type); | 392 | result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type); |
| 393 | if (result) { | 393 | if (result) { |
| 394 | pr_debug("%s:%u read_bus_type(%u) failed\n", __func__, | 394 | pr_devel("%s:%u read_bus_type(%u) failed\n", __func__, |
| 395 | __LINE__, tmp.bus_index); | 395 | __LINE__, tmp.bus_index); |
| 396 | return result; | 396 | return result; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); | 399 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); |
| 400 | if (result) { | 400 | if (result) { |
| 401 | pr_debug("%s:%u read_bus_num_dev failed\n", __func__, | 401 | pr_devel("%s:%u read_bus_num_dev failed\n", __func__, |
| 402 | __LINE__); | 402 | __LINE__); |
| 403 | return result; | 403 | return result; |
| 404 | } | 404 | } |
| @@ -408,7 +408,7 @@ found_bus: | |||
| 408 | tmp.dev_index, | 408 | tmp.dev_index, |
| 409 | &tmp.dev_id); | 409 | &tmp.dev_id); |
| 410 | if (result) { | 410 | if (result) { |
| 411 | pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__, | 411 | pr_devel("%s:%u read_dev_id(%u:%u) failed\n", __func__, |
| 412 | __LINE__, tmp.bus_index, tmp.dev_index); | 412 | __LINE__, tmp.bus_index, tmp.dev_index); |
| 413 | return result; | 413 | return result; |
| 414 | } | 414 | } |
| @@ -416,21 +416,21 @@ found_bus: | |||
| 416 | if (tmp.dev_id == dev_id) | 416 | if (tmp.dev_id == dev_id) |
| 417 | goto found_dev; | 417 | goto found_dev; |
| 418 | 418 | ||
| 419 | pr_debug("%s:%u: skip, dev_id %llu\n", __func__, __LINE__, | 419 | pr_devel("%s:%u: skip, dev_id %llu\n", __func__, __LINE__, |
| 420 | tmp.dev_id); | 420 | tmp.dev_id); |
| 421 | } | 421 | } |
| 422 | pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__); | 422 | pr_devel(" <- %s:%u: dev not found\n", __func__, __LINE__); |
| 423 | return result; | 423 | return result; |
| 424 | 424 | ||
| 425 | found_dev: | 425 | found_dev: |
| 426 | result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, | 426 | result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, |
| 427 | &tmp.dev_type); | 427 | &tmp.dev_type); |
| 428 | if (result) { | 428 | if (result) { |
| 429 | pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__); | 429 | pr_devel("%s:%u read_dev_type failed\n", __func__, __LINE__); |
| 430 | return result; | 430 | return result; |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n", | 433 | pr_devel(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n", |
| 434 | __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, | 434 | __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, |
| 435 | tmp.dev_index, tmp.bus_id, tmp.dev_id); | 435 | tmp.dev_index, tmp.bus_id, tmp.dev_id); |
| 436 | *repo = tmp; | 436 | *repo = tmp; |
| @@ -443,18 +443,18 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, | |||
| 443 | int result = 0; | 443 | int result = 0; |
| 444 | struct ps3_repository_device repo; | 444 | struct ps3_repository_device repo; |
| 445 | 445 | ||
| 446 | pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); | 446 | pr_devel(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); |
| 447 | 447 | ||
| 448 | repo.bus_type = bus_type; | 448 | repo.bus_type = bus_type; |
| 449 | result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); | 449 | result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); |
| 450 | if (result) { | 450 | if (result) { |
| 451 | pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); | 451 | pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__); |
| 452 | return result; | 452 | return result; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); | 455 | result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); |
| 456 | if (result) { | 456 | if (result) { |
| 457 | pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, | 457 | pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, |
| 458 | repo.bus_index); | 458 | repo.bus_index); |
| 459 | return result; | 459 | return result; |
| 460 | } | 460 | } |
| @@ -469,13 +469,13 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, | |||
| 469 | 469 | ||
| 470 | result = callback(&repo); | 470 | result = callback(&repo); |
| 471 | if (result) { | 471 | if (result) { |
| 472 | pr_debug("%s:%d: abort at callback\n", __func__, | 472 | pr_devel("%s:%d: abort at callback\n", __func__, |
| 473 | __LINE__); | 473 | __LINE__); |
| 474 | break; | 474 | break; |
| 475 | } | 475 | } |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 478 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
| 479 | return result; | 479 | return result; |
| 480 | } | 480 | } |
| 481 | 481 | ||
| @@ -489,7 +489,7 @@ int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, | |||
| 489 | for (i = from; i < 10; i++) { | 489 | for (i = from; i < 10; i++) { |
| 490 | error = ps3_repository_read_bus_type(i, &type); | 490 | error = ps3_repository_read_bus_type(i, &type); |
| 491 | if (error) { | 491 | if (error) { |
| 492 | pr_debug("%s:%d read_bus_type failed\n", | 492 | pr_devel("%s:%d read_bus_type failed\n", |
| 493 | __func__, __LINE__); | 493 | __func__, __LINE__); |
| 494 | *bus_index = UINT_MAX; | 494 | *bus_index = UINT_MAX; |
| 495 | return error; | 495 | return error; |
| @@ -509,7 +509,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, | |||
| 509 | int result = 0; | 509 | int result = 0; |
| 510 | unsigned int res_index; | 510 | unsigned int res_index; |
| 511 | 511 | ||
| 512 | pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type); | 512 | pr_devel("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type); |
| 513 | 513 | ||
| 514 | *interrupt_id = UINT_MAX; | 514 | *interrupt_id = UINT_MAX; |
| 515 | 515 | ||
| @@ -521,7 +521,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, | |||
| 521 | repo->dev_index, res_index, &t, &id); | 521 | repo->dev_index, res_index, &t, &id); |
| 522 | 522 | ||
| 523 | if (result) { | 523 | if (result) { |
| 524 | pr_debug("%s:%d read_dev_intr failed\n", | 524 | pr_devel("%s:%d read_dev_intr failed\n", |
| 525 | __func__, __LINE__); | 525 | __func__, __LINE__); |
| 526 | return result; | 526 | return result; |
| 527 | } | 527 | } |
| @@ -535,7 +535,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, | |||
| 535 | if (res_index == 10) | 535 | if (res_index == 10) |
| 536 | return -ENODEV; | 536 | return -ENODEV; |
| 537 | 537 | ||
| 538 | pr_debug("%s:%d: found intr_type %u at res_index %u\n", | 538 | pr_devel("%s:%d: found intr_type %u at res_index %u\n", |
| 539 | __func__, __LINE__, intr_type, res_index); | 539 | __func__, __LINE__, intr_type, res_index); |
| 540 | 540 | ||
| 541 | return result; | 541 | return result; |
| @@ -547,7 +547,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, | |||
| 547 | int result = 0; | 547 | int result = 0; |
| 548 | unsigned int res_index; | 548 | unsigned int res_index; |
| 549 | 549 | ||
| 550 | pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type); | 550 | pr_devel("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type); |
| 551 | 551 | ||
| 552 | *bus_addr = *len = 0; | 552 | *bus_addr = *len = 0; |
| 553 | 553 | ||
| @@ -560,7 +560,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, | |||
| 560 | repo->dev_index, res_index, &t, &a, &l); | 560 | repo->dev_index, res_index, &t, &a, &l); |
| 561 | 561 | ||
| 562 | if (result) { | 562 | if (result) { |
| 563 | pr_debug("%s:%d read_dev_reg failed\n", | 563 | pr_devel("%s:%d read_dev_reg failed\n", |
| 564 | __func__, __LINE__); | 564 | __func__, __LINE__); |
| 565 | return result; | 565 | return result; |
| 566 | } | 566 | } |
| @@ -575,7 +575,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, | |||
| 575 | if (res_index == 10) | 575 | if (res_index == 10) |
| 576 | return -ENODEV; | 576 | return -ENODEV; |
| 577 | 577 | ||
| 578 | pr_debug("%s:%d: found reg_type %u at res_index %u\n", | 578 | pr_devel("%s:%d: found reg_type %u at res_index %u\n", |
| 579 | __func__, __LINE__, reg_type, res_index); | 579 | __func__, __LINE__, reg_type, res_index); |
| 580 | 580 | ||
| 581 | return result; | 581 | return result; |
| @@ -1009,7 +1009,7 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | |||
| 1009 | int result = 0; | 1009 | int result = 0; |
| 1010 | unsigned int res_index; | 1010 | unsigned int res_index; |
| 1011 | 1011 | ||
| 1012 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | 1012 | pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, |
| 1013 | repo->bus_index, repo->dev_index); | 1013 | repo->bus_index, repo->dev_index); |
| 1014 | 1014 | ||
| 1015 | for (res_index = 0; res_index < 10; res_index++) { | 1015 | for (res_index = 0; res_index < 10; res_index++) { |
| @@ -1021,13 +1021,13 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | |||
| 1021 | 1021 | ||
| 1022 | if (result) { | 1022 | if (result) { |
| 1023 | if (result != LV1_NO_ENTRY) | 1023 | if (result != LV1_NO_ENTRY) |
| 1024 | pr_debug("%s:%d ps3_repository_read_dev_intr" | 1024 | pr_devel("%s:%d ps3_repository_read_dev_intr" |
| 1025 | " (%u:%u) failed\n", __func__, __LINE__, | 1025 | " (%u:%u) failed\n", __func__, __LINE__, |
| 1026 | repo->bus_index, repo->dev_index); | 1026 | repo->bus_index, repo->dev_index); |
| 1027 | break; | 1027 | break; |
| 1028 | } | 1028 | } |
| 1029 | 1029 | ||
| 1030 | pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", | 1030 | pr_devel("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", |
| 1031 | __func__, __LINE__, repo->bus_index, repo->dev_index, | 1031 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
| 1032 | intr_type, interrupt_id); | 1032 | intr_type, interrupt_id); |
| 1033 | } | 1033 | } |
| @@ -1042,18 +1042,18 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | |||
| 1042 | 1042 | ||
| 1043 | if (result) { | 1043 | if (result) { |
| 1044 | if (result != LV1_NO_ENTRY) | 1044 | if (result != LV1_NO_ENTRY) |
| 1045 | pr_debug("%s:%d ps3_repository_read_dev_reg" | 1045 | pr_devel("%s:%d ps3_repository_read_dev_reg" |
| 1046 | " (%u:%u) failed\n", __func__, __LINE__, | 1046 | " (%u:%u) failed\n", __func__, __LINE__, |
| 1047 | repo->bus_index, repo->dev_index); | 1047 | repo->bus_index, repo->dev_index); |
| 1048 | break; | 1048 | break; |
| 1049 | } | 1049 | } |
| 1050 | 1050 | ||
| 1051 | pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", | 1051 | pr_devel("%s:%d (%u:%u) reg_type %u, bus_addr %llxh, len %llxh\n", |
| 1052 | __func__, __LINE__, repo->bus_index, repo->dev_index, | 1052 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
| 1053 | reg_type, bus_addr, len); | 1053 | reg_type, bus_addr, len); |
| 1054 | } | 1054 | } |
| 1055 | 1055 | ||
| 1056 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1056 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
| 1057 | return result; | 1057 | return result; |
| 1058 | } | 1058 | } |
| 1059 | 1059 | ||
| @@ -1063,22 +1063,22 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo) | |||
| 1063 | unsigned int num_regions, region_index; | 1063 | unsigned int num_regions, region_index; |
| 1064 | u64 port, blk_size, num_blocks; | 1064 | u64 port, blk_size, num_blocks; |
| 1065 | 1065 | ||
| 1066 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | 1066 | pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, |
| 1067 | repo->bus_index, repo->dev_index); | 1067 | repo->bus_index, repo->dev_index); |
| 1068 | 1068 | ||
| 1069 | result = ps3_repository_read_stor_dev_info(repo->bus_index, | 1069 | result = ps3_repository_read_stor_dev_info(repo->bus_index, |
| 1070 | repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); | 1070 | repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); |
| 1071 | if (result) { | 1071 | if (result) { |
| 1072 | pr_debug("%s:%d ps3_repository_read_stor_dev_info" | 1072 | pr_devel("%s:%d ps3_repository_read_stor_dev_info" |
| 1073 | " (%u:%u) failed\n", __func__, __LINE__, | 1073 | " (%u:%u) failed\n", __func__, __LINE__, |
| 1074 | repo->bus_index, repo->dev_index); | 1074 | repo->bus_index, repo->dev_index); |
| 1075 | goto out; | 1075 | goto out; |
| 1076 | } | 1076 | } |
| 1077 | 1077 | ||
| 1078 | pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " | 1078 | pr_devel("%s:%d (%u:%u): port %llu, blk_size %llu, num_blocks " |
| 1079 | "%lu, num_regions %u\n", | 1079 | "%llu, num_regions %u\n", |
| 1080 | __func__, __LINE__, repo->bus_index, repo->dev_index, port, | 1080 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
| 1081 | blk_size, num_blocks, num_regions); | 1081 | port, blk_size, num_blocks, num_regions); |
| 1082 | 1082 | ||
| 1083 | for (region_index = 0; region_index < num_regions; region_index++) { | 1083 | for (region_index = 0; region_index < num_regions; region_index++) { |
| 1084 | unsigned int region_id; | 1084 | unsigned int region_id; |
| @@ -1088,19 +1088,20 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo) | |||
| 1088 | repo->dev_index, region_index, ®ion_id, | 1088 | repo->dev_index, region_index, ®ion_id, |
| 1089 | ®ion_start, ®ion_size); | 1089 | ®ion_start, ®ion_size); |
| 1090 | if (result) { | 1090 | if (result) { |
| 1091 | pr_debug("%s:%d ps3_repository_read_stor_dev_region" | 1091 | pr_devel("%s:%d ps3_repository_read_stor_dev_region" |
| 1092 | " (%u:%u) failed\n", __func__, __LINE__, | 1092 | " (%u:%u) failed\n", __func__, __LINE__, |
| 1093 | repo->bus_index, repo->dev_index); | 1093 | repo->bus_index, repo->dev_index); |
| 1094 | break; | 1094 | break; |
| 1095 | } | 1095 | } |
| 1096 | 1096 | ||
| 1097 | pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", | 1097 | pr_devel("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", |
| 1098 | __func__, __LINE__, repo->bus_index, repo->dev_index, | 1098 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
| 1099 | region_id, region_start, region_size); | 1099 | region_id, (unsigned long)region_start, |
| 1100 | (unsigned long)region_size); | ||
| 1100 | } | 1101 | } |
| 1101 | 1102 | ||
| 1102 | out: | 1103 | out: |
| 1103 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1104 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
| 1104 | return result; | 1105 | return result; |
| 1105 | } | 1106 | } |
| 1106 | 1107 | ||
| @@ -1109,7 +1110,7 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
| 1109 | { | 1110 | { |
| 1110 | int result = 0; | 1111 | int result = 0; |
| 1111 | 1112 | ||
| 1112 | pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); | 1113 | pr_devel(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); |
| 1113 | 1114 | ||
| 1114 | for (repo->dev_index = 0; repo->dev_index < num_dev; | 1115 | for (repo->dev_index = 0; repo->dev_index < num_dev; |
| 1115 | repo->dev_index++) { | 1116 | repo->dev_index++) { |
| @@ -1118,7 +1119,7 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
| 1118 | repo->dev_index, &repo->dev_type); | 1119 | repo->dev_index, &repo->dev_type); |
| 1119 | 1120 | ||
| 1120 | if (result) { | 1121 | if (result) { |
| 1121 | pr_debug("%s:%d ps3_repository_read_dev_type" | 1122 | pr_devel("%s:%d ps3_repository_read_dev_type" |
| 1122 | " (%u:%u) failed\n", __func__, __LINE__, | 1123 | " (%u:%u) failed\n", __func__, __LINE__, |
| 1123 | repo->bus_index, repo->dev_index); | 1124 | repo->bus_index, repo->dev_index); |
| 1124 | break; | 1125 | break; |
| @@ -1128,15 +1129,15 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
| 1128 | repo->dev_index, &repo->dev_id); | 1129 | repo->dev_index, &repo->dev_id); |
| 1129 | 1130 | ||
| 1130 | if (result) { | 1131 | if (result) { |
| 1131 | pr_debug("%s:%d ps3_repository_read_dev_id" | 1132 | pr_devel("%s:%d ps3_repository_read_dev_id" |
| 1132 | " (%u:%u) failed\n", __func__, __LINE__, | 1133 | " (%u:%u) failed\n", __func__, __LINE__, |
| 1133 | repo->bus_index, repo->dev_index); | 1134 | repo->bus_index, repo->dev_index); |
| 1134 | continue; | 1135 | continue; |
| 1135 | } | 1136 | } |
| 1136 | 1137 | ||
| 1137 | pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, | 1138 | pr_devel("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, |
| 1138 | __LINE__, repo->bus_index, repo->dev_index, | 1139 | __LINE__, repo->bus_index, repo->dev_index, |
| 1139 | repo->dev_type, repo->dev_id); | 1140 | repo->dev_type, (unsigned long)repo->dev_id); |
| 1140 | 1141 | ||
| 1141 | ps3_repository_dump_resource_info(repo); | 1142 | ps3_repository_dump_resource_info(repo); |
| 1142 | 1143 | ||
| @@ -1144,7 +1145,7 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
| 1144 | dump_stor_dev_info(repo); | 1145 | dump_stor_dev_info(repo); |
| 1145 | } | 1146 | } |
| 1146 | 1147 | ||
| 1147 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1148 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
| 1148 | return result; | 1149 | return result; |
| 1149 | } | 1150 | } |
| 1150 | 1151 | ||
| @@ -1153,7 +1154,7 @@ int ps3_repository_dump_bus_info(void) | |||
| 1153 | int result = 0; | 1154 | int result = 0; |
| 1154 | struct ps3_repository_device repo; | 1155 | struct ps3_repository_device repo; |
| 1155 | 1156 | ||
| 1156 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | 1157 | pr_devel(" -> %s:%d\n", __func__, __LINE__); |
| 1157 | 1158 | ||
| 1158 | memset(&repo, 0, sizeof(repo)); | 1159 | memset(&repo, 0, sizeof(repo)); |
| 1159 | 1160 | ||
| @@ -1164,7 +1165,7 @@ int ps3_repository_dump_bus_info(void) | |||
| 1164 | &repo.bus_type); | 1165 | &repo.bus_type); |
| 1165 | 1166 | ||
| 1166 | if (result) { | 1167 | if (result) { |
| 1167 | pr_debug("%s:%d read_bus_type(%u) failed\n", | 1168 | pr_devel("%s:%d read_bus_type(%u) failed\n", |
| 1168 | __func__, __LINE__, repo.bus_index); | 1169 | __func__, __LINE__, repo.bus_index); |
| 1169 | break; | 1170 | break; |
| 1170 | } | 1171 | } |
| @@ -1173,32 +1174,32 @@ int ps3_repository_dump_bus_info(void) | |||
| 1173 | &repo.bus_id); | 1174 | &repo.bus_id); |
| 1174 | 1175 | ||
| 1175 | if (result) { | 1176 | if (result) { |
| 1176 | pr_debug("%s:%d read_bus_id(%u) failed\n", | 1177 | pr_devel("%s:%d read_bus_id(%u) failed\n", |
| 1177 | __func__, __LINE__, repo.bus_index); | 1178 | __func__, __LINE__, repo.bus_index); |
| 1178 | continue; | 1179 | continue; |
| 1179 | } | 1180 | } |
| 1180 | 1181 | ||
| 1181 | if (repo.bus_index != repo.bus_id) | 1182 | if (repo.bus_index != repo.bus_id) |
| 1182 | pr_debug("%s:%d bus_index != bus_id\n", | 1183 | pr_devel("%s:%d bus_index != bus_id\n", |
| 1183 | __func__, __LINE__); | 1184 | __func__, __LINE__); |
| 1184 | 1185 | ||
| 1185 | result = ps3_repository_read_bus_num_dev(repo.bus_index, | 1186 | result = ps3_repository_read_bus_num_dev(repo.bus_index, |
| 1186 | &num_dev); | 1187 | &num_dev); |
| 1187 | 1188 | ||
| 1188 | if (result) { | 1189 | if (result) { |
| 1189 | pr_debug("%s:%d read_bus_num_dev(%u) failed\n", | 1190 | pr_devel("%s:%d read_bus_num_dev(%u) failed\n", |
| 1190 | __func__, __LINE__, repo.bus_index); | 1191 | __func__, __LINE__, repo.bus_index); |
| 1191 | continue; | 1192 | continue; |
| 1192 | } | 1193 | } |
| 1193 | 1194 | ||
| 1194 | pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", | 1195 | pr_devel("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", |
| 1195 | __func__, __LINE__, repo.bus_index, repo.bus_type, | 1196 | __func__, __LINE__, repo.bus_index, repo.bus_type, |
| 1196 | repo.bus_id, num_dev); | 1197 | (unsigned long)repo.bus_id, num_dev); |
| 1197 | 1198 | ||
| 1198 | dump_device_info(&repo, num_dev); | 1199 | dump_device_info(&repo, num_dev); |
| 1199 | } | 1200 | } |
| 1200 | 1201 | ||
| 1201 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1202 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
| 1202 | return result; | 1203 | return result; |
| 1203 | } | 1204 | } |
| 1204 | 1205 | ||
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index e8ec1b2bfffd..2d664c5a83b0 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c | |||
| @@ -193,10 +193,12 @@ static int ps3_set_dabr(unsigned long dabr) | |||
| 193 | 193 | ||
| 194 | static void __init ps3_setup_arch(void) | 194 | static void __init ps3_setup_arch(void) |
| 195 | { | 195 | { |
| 196 | u64 tmp; | ||
| 196 | 197 | ||
| 197 | DBG(" -> %s:%d\n", __func__, __LINE__); | 198 | DBG(" -> %s:%d\n", __func__, __LINE__); |
| 198 | 199 | ||
| 199 | lv1_get_version_info(&ps3_firmware_version.raw); | 200 | lv1_get_version_info(&ps3_firmware_version.raw, &tmp); |
| 201 | |||
| 200 | printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", | 202 | printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", |
| 201 | ps3_firmware_version.major, ps3_firmware_version.minor, | 203 | ps3_firmware_version.major, ps3_firmware_version.minor, |
| 202 | ps3_firmware_version.rev); | 204 | ps3_firmware_version.rev); |
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index efc1cd8c034a..4b35166229fe 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c | |||
| @@ -57,7 +57,7 @@ static void ps3_smp_message_pass(int cpu, int msg) | |||
| 57 | " (%d)\n", __func__, __LINE__, cpu, msg, result); | 57 | " (%d)\n", __func__, __LINE__, cpu, msg, result); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | static int ps3_smp_probe(void) | 60 | static int __init ps3_smp_probe(void) |
| 61 | { | 61 | { |
| 62 | int cpu; | 62 | int cpu; |
| 63 | 63 | ||
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index 451fad1c92a8..e17fa1432d80 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c | |||
| @@ -154,7 +154,7 @@ static unsigned long get_vas_id(void) | |||
| 154 | u64 id; | 154 | u64 id; |
| 155 | 155 | ||
| 156 | lv1_get_logical_ppe_id(&id); | 156 | lv1_get_logical_ppe_id(&id); |
| 157 | lv1_get_virtual_address_space_id_of_ppe(id, &id); | 157 | lv1_get_virtual_address_space_id_of_ppe(&id); |
| 158 | 158 | ||
| 159 | return id; | 159 | return id; |
| 160 | } | 160 | } |
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index c81f6bb9c10f..ae7b6d41fed3 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
| @@ -120,3 +120,12 @@ config DTL | |||
| 120 | which are accessible through a debugfs file. | 120 | which are accessible through a debugfs file. |
| 121 | 121 | ||
| 122 | Say N if you are unsure. | 122 | Say N if you are unsure. |
| 123 | |||
| 124 | config PSERIES_IDLE | ||
| 125 | tristate "Cpuidle driver for pSeries platforms" | ||
| 126 | depends on CPU_IDLE | ||
| 127 | depends on PPC_PSERIES | ||
| 128 | default y | ||
| 129 | help | ||
| 130 | Select this option to enable processor idle state management | ||
| 131 | through cpuidle subsystem. | ||
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 3556e402cbf5..236db46b4078 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
| @@ -22,6 +22,7 @@ obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o | |||
| 22 | obj-$(CONFIG_CMM) += cmm.o | 22 | obj-$(CONFIG_CMM) += cmm.o |
| 23 | obj-$(CONFIG_DTL) += dtl.o | 23 | obj-$(CONFIG_DTL) += dtl.o |
| 24 | obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o | 24 | obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o |
| 25 | obj-$(CONFIG_PSERIES_IDLE) += processor_idle.o | ||
| 25 | 26 | ||
| 26 | ifeq ($(CONFIG_PPC_PSERIES),y) | 27 | ifeq ($(CONFIG_PPC_PSERIES),y) |
| 27 | obj-$(CONFIG_SUSPEND) += suspend.o | 28 | obj-$(CONFIG_SUSPEND) += suspend.o |
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index f106662f4381..c9311cfdfcac 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c | |||
| @@ -109,7 +109,7 @@ static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long | |||
| 109 | if (opcode > MAX_HCALL_OPCODE) | 109 | if (opcode > MAX_HCALL_OPCODE) |
| 110 | return; | 110 | return; |
| 111 | 111 | ||
| 112 | h = &get_cpu_var(hcall_stats)[opcode / 4]; | 112 | h = &__get_cpu_var(hcall_stats)[opcode / 4]; |
| 113 | h->tb_start = mftb(); | 113 | h->tb_start = mftb(); |
| 114 | h->purr_start = mfspr(SPRN_PURR); | 114 | h->purr_start = mfspr(SPRN_PURR); |
| 115 | } | 115 | } |
| @@ -126,8 +126,6 @@ static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long | |||
| 126 | h->num_calls++; | 126 | h->num_calls++; |
| 127 | h->tb_total += mftb() - h->tb_start; | 127 | h->tb_total += mftb() - h->tb_start; |
| 128 | h->purr_total += mfspr(SPRN_PURR) - h->purr_start; | 128 | h->purr_total += mfspr(SPRN_PURR) - h->purr_start; |
| 129 | |||
| 130 | put_cpu_var(hcall_stats); | ||
| 131 | } | 129 | } |
| 132 | 130 | ||
| 133 | static int __init hcall_inst_init(void) | 131 | static int __init hcall_inst_init(void) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index b719d9709730..c442f2b1980f 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
| @@ -52,13 +52,42 @@ | |||
| 52 | #include "plpar_wrappers.h" | 52 | #include "plpar_wrappers.h" |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | static void tce_invalidate_pSeries_sw(struct iommu_table *tbl, | ||
| 56 | u64 *startp, u64 *endp) | ||
| 57 | { | ||
| 58 | u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; | ||
| 59 | unsigned long start, end, inc; | ||
| 60 | |||
| 61 | start = __pa(startp); | ||
| 62 | end = __pa(endp); | ||
| 63 | inc = L1_CACHE_BYTES; /* invalidate a cacheline of TCEs at a time */ | ||
| 64 | |||
| 65 | /* If this is non-zero, change the format. We shift the | ||
| 66 | * address and or in the magic from the device tree. */ | ||
| 67 | if (tbl->it_busno) { | ||
| 68 | start <<= 12; | ||
| 69 | end <<= 12; | ||
| 70 | inc <<= 12; | ||
| 71 | start |= tbl->it_busno; | ||
| 72 | end |= tbl->it_busno; | ||
| 73 | } | ||
| 74 | |||
| 75 | end |= inc - 1; /* round up end to be different than start */ | ||
| 76 | |||
| 77 | mb(); /* Make sure TCEs in memory are written */ | ||
| 78 | while (start <= end) { | ||
| 79 | out_be64(invalidate, start); | ||
| 80 | start += inc; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 55 | static int tce_build_pSeries(struct iommu_table *tbl, long index, | 84 | static int tce_build_pSeries(struct iommu_table *tbl, long index, |
| 56 | long npages, unsigned long uaddr, | 85 | long npages, unsigned long uaddr, |
| 57 | enum dma_data_direction direction, | 86 | enum dma_data_direction direction, |
| 58 | struct dma_attrs *attrs) | 87 | struct dma_attrs *attrs) |
| 59 | { | 88 | { |
| 60 | u64 proto_tce; | 89 | u64 proto_tce; |
| 61 | u64 *tcep; | 90 | u64 *tcep, *tces; |
| 62 | u64 rpn; | 91 | u64 rpn; |
| 63 | 92 | ||
| 64 | proto_tce = TCE_PCI_READ; // Read allowed | 93 | proto_tce = TCE_PCI_READ; // Read allowed |
| @@ -66,7 +95,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, | |||
| 66 | if (direction != DMA_TO_DEVICE) | 95 | if (direction != DMA_TO_DEVICE) |
| 67 | proto_tce |= TCE_PCI_WRITE; | 96 | proto_tce |= TCE_PCI_WRITE; |
| 68 | 97 | ||
| 69 | tcep = ((u64 *)tbl->it_base) + index; | 98 | tces = tcep = ((u64 *)tbl->it_base) + index; |
| 70 | 99 | ||
| 71 | while (npages--) { | 100 | while (npages--) { |
| 72 | /* can't move this out since we might cross MEMBLOCK boundary */ | 101 | /* can't move this out since we might cross MEMBLOCK boundary */ |
| @@ -76,18 +105,24 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, | |||
| 76 | uaddr += TCE_PAGE_SIZE; | 105 | uaddr += TCE_PAGE_SIZE; |
| 77 | tcep++; | 106 | tcep++; |
| 78 | } | 107 | } |
| 108 | |||
| 109 | if (tbl->it_type == TCE_PCI_SWINV_CREATE) | ||
| 110 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); | ||
| 79 | return 0; | 111 | return 0; |
| 80 | } | 112 | } |
| 81 | 113 | ||
| 82 | 114 | ||
| 83 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | 115 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) |
| 84 | { | 116 | { |
| 85 | u64 *tcep; | 117 | u64 *tcep, *tces; |
| 86 | 118 | ||
| 87 | tcep = ((u64 *)tbl->it_base) + index; | 119 | tces = tcep = ((u64 *)tbl->it_base) + index; |
| 88 | 120 | ||
| 89 | while (npages--) | 121 | while (npages--) |
| 90 | *(tcep++) = 0; | 122 | *(tcep++) = 0; |
| 123 | |||
| 124 | if (tbl->it_type == TCE_PCI_SWINV_FREE) | ||
| 125 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); | ||
| 91 | } | 126 | } |
| 92 | 127 | ||
| 93 | static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) | 128 | static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) |
| @@ -425,7 +460,7 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
| 425 | struct iommu_table *tbl) | 460 | struct iommu_table *tbl) |
| 426 | { | 461 | { |
| 427 | struct device_node *node; | 462 | struct device_node *node; |
| 428 | const unsigned long *basep; | 463 | const unsigned long *basep, *sw_inval; |
| 429 | const u32 *sizep; | 464 | const u32 *sizep; |
| 430 | 465 | ||
| 431 | node = phb->dn; | 466 | node = phb->dn; |
| @@ -462,6 +497,22 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
| 462 | tbl->it_index = 0; | 497 | tbl->it_index = 0; |
| 463 | tbl->it_blocksize = 16; | 498 | tbl->it_blocksize = 16; |
| 464 | tbl->it_type = TCE_PCI; | 499 | tbl->it_type = TCE_PCI; |
| 500 | |||
| 501 | sw_inval = of_get_property(node, "linux,tce-sw-invalidate-info", NULL); | ||
| 502 | if (sw_inval) { | ||
| 503 | /* | ||
| 504 | * This property contains information on how to | ||
| 505 | * invalidate the TCE entry. The first property is | ||
| 506 | * the base MMIO address used to invalidate entries. | ||
| 507 | * The second property tells us the format of the TCE | ||
| 508 | * invalidate (whether it needs to be shifted) and | ||
| 509 | * some magic routing info to add to our invalidate | ||
| 510 | * command. | ||
| 511 | */ | ||
| 512 | tbl->it_index = (unsigned long) ioremap(sw_inval[0], 8); | ||
| 513 | tbl->it_busno = sw_inval[1]; /* overload this with magic */ | ||
| 514 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; | ||
| 515 | } | ||
| 465 | } | 516 | } |
| 466 | 517 | ||
| 467 | /* | 518 | /* |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 52d429be6c76..948e0e3b3547 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
| @@ -554,6 +554,7 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args) | |||
| 554 | goto out; | 554 | goto out; |
| 555 | 555 | ||
| 556 | (*depth)++; | 556 | (*depth)++; |
| 557 | preempt_disable(); | ||
| 557 | trace_hcall_entry(opcode, args); | 558 | trace_hcall_entry(opcode, args); |
| 558 | if (opcode == H_CEDE) | 559 | if (opcode == H_CEDE) |
| 559 | rcu_idle_enter(); | 560 | rcu_idle_enter(); |
| @@ -580,6 +581,7 @@ void __trace_hcall_exit(long opcode, unsigned long retval, | |||
| 580 | if (opcode == H_CEDE) | 581 | if (opcode == H_CEDE) |
| 581 | rcu_idle_exit(); | 582 | rcu_idle_exit(); |
| 582 | trace_hcall_exit(opcode, retval, retbuf); | 583 | trace_hcall_exit(opcode, retval, retbuf); |
| 584 | preempt_enable(); | ||
| 583 | (*depth)--; | 585 | (*depth)--; |
| 584 | 586 | ||
| 585 | out: | 587 | out: |
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index a76b22844d18..330a57b7c17c 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c | |||
| @@ -625,6 +625,8 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
| 625 | { | 625 | { |
| 626 | static unsigned int oops_count = 0; | 626 | static unsigned int oops_count = 0; |
| 627 | static bool panicking = false; | 627 | static bool panicking = false; |
| 628 | static DEFINE_SPINLOCK(lock); | ||
| 629 | unsigned long flags; | ||
| 628 | size_t text_len; | 630 | size_t text_len; |
| 629 | unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; | 631 | unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; |
| 630 | int rc = -1; | 632 | int rc = -1; |
| @@ -655,6 +657,9 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
| 655 | if (clobbering_unread_rtas_event()) | 657 | if (clobbering_unread_rtas_event()) |
| 656 | return; | 658 | return; |
| 657 | 659 | ||
| 660 | if (!spin_trylock_irqsave(&lock, flags)) | ||
| 661 | return; | ||
| 662 | |||
| 658 | if (big_oops_buf) { | 663 | if (big_oops_buf) { |
| 659 | text_len = capture_last_msgs(old_msgs, old_len, | 664 | text_len = capture_last_msgs(old_msgs, old_len, |
| 660 | new_msgs, new_len, big_oops_buf, big_oops_buf_sz); | 665 | new_msgs, new_len, big_oops_buf, big_oops_buf_sz); |
| @@ -670,4 +675,6 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
| 670 | 675 | ||
| 671 | (void) nvram_write_os_partition(&oops_log_partition, oops_buf, | 676 | (void) nvram_write_os_partition(&oops_log_partition, oops_buf, |
| 672 | (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count); | 677 | (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count); |
| 678 | |||
| 679 | spin_unlock_irqrestore(&lock, flags); | ||
| 673 | } | 680 | } |
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c new file mode 100644 index 000000000000..085fd3f45ad2 --- /dev/null +++ b/arch/powerpc/platforms/pseries/processor_idle.c | |||
| @@ -0,0 +1,329 @@ | |||
| 1 | /* | ||
| 2 | * processor_idle - idle state cpuidle driver. | ||
| 3 | * Adapted from drivers/idle/intel_idle.c and | ||
| 4 | * drivers/acpi/processor_idle.c | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/moduleparam.h> | ||
| 12 | #include <linux/cpuidle.h> | ||
| 13 | #include <linux/cpu.h> | ||
| 14 | |||
| 15 | #include <asm/paca.h> | ||
| 16 | #include <asm/reg.h> | ||
| 17 | #include <asm/system.h> | ||
| 18 | #include <asm/machdep.h> | ||
| 19 | #include <asm/firmware.h> | ||
| 20 | |||
| 21 | #include "plpar_wrappers.h" | ||
| 22 | #include "pseries.h" | ||
| 23 | |||
| 24 | struct cpuidle_driver pseries_idle_driver = { | ||
| 25 | .name = "pseries_idle", | ||
| 26 | .owner = THIS_MODULE, | ||
| 27 | }; | ||
| 28 | |||
| 29 | #define MAX_IDLE_STATE_COUNT 2 | ||
| 30 | |||
| 31 | static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; | ||
| 32 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; | ||
| 33 | static struct cpuidle_state *cpuidle_state_table; | ||
| 34 | |||
| 35 | void update_smt_snooze_delay(int snooze) | ||
| 36 | { | ||
| 37 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
| 38 | if (drv) | ||
| 39 | drv->states[0].target_residency = snooze; | ||
| 40 | } | ||
| 41 | |||
| 42 | static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) | ||
| 43 | { | ||
| 44 | |||
| 45 | *kt_before = ktime_get_real(); | ||
| 46 | *in_purr = mfspr(SPRN_PURR); | ||
| 47 | /* | ||
| 48 | * Indicate to the HV that we are idle. Now would be | ||
| 49 | * a good time to find other work to dispatch. | ||
| 50 | */ | ||
| 51 | get_lppaca()->idle = 1; | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before) | ||
| 55 | { | ||
| 56 | get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr; | ||
| 57 | get_lppaca()->idle = 0; | ||
| 58 | |||
| 59 | return ktime_to_us(ktime_sub(ktime_get_real(), kt_before)); | ||
| 60 | } | ||
| 61 | |||
| 62 | static int snooze_loop(struct cpuidle_device *dev, | ||
| 63 | struct cpuidle_driver *drv, | ||
| 64 | int index) | ||
| 65 | { | ||
| 66 | unsigned long in_purr; | ||
| 67 | ktime_t kt_before; | ||
| 68 | unsigned long start_snooze; | ||
| 69 | long snooze = drv->states[0].target_residency; | ||
| 70 | |||
| 71 | idle_loop_prolog(&in_purr, &kt_before); | ||
| 72 | |||
| 73 | if (snooze) { | ||
| 74 | start_snooze = get_tb() + snooze * tb_ticks_per_usec; | ||
| 75 | local_irq_enable(); | ||
| 76 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
| 77 | |||
| 78 | while ((snooze < 0) || (get_tb() < start_snooze)) { | ||
| 79 | if (need_resched() || cpu_is_offline(dev->cpu)) | ||
| 80 | goto out; | ||
| 81 | ppc64_runlatch_off(); | ||
| 82 | HMT_low(); | ||
| 83 | HMT_very_low(); | ||
| 84 | } | ||
| 85 | |||
| 86 | HMT_medium(); | ||
| 87 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
| 88 | smp_mb(); | ||
| 89 | local_irq_disable(); | ||
| 90 | } | ||
| 91 | |||
| 92 | out: | ||
| 93 | HMT_medium(); | ||
| 94 | dev->last_residency = | ||
| 95 | (int)idle_loop_epilog(in_purr, kt_before); | ||
| 96 | return index; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int dedicated_cede_loop(struct cpuidle_device *dev, | ||
| 100 | struct cpuidle_driver *drv, | ||
| 101 | int index) | ||
| 102 | { | ||
| 103 | unsigned long in_purr; | ||
| 104 | ktime_t kt_before; | ||
| 105 | |||
| 106 | idle_loop_prolog(&in_purr, &kt_before); | ||
| 107 | get_lppaca()->donate_dedicated_cpu = 1; | ||
| 108 | |||
| 109 | ppc64_runlatch_off(); | ||
| 110 | HMT_medium(); | ||
| 111 | cede_processor(); | ||
| 112 | |||
| 113 | get_lppaca()->donate_dedicated_cpu = 0; | ||
| 114 | dev->last_residency = | ||
| 115 | (int)idle_loop_epilog(in_purr, kt_before); | ||
| 116 | return index; | ||
| 117 | } | ||
| 118 | |||
| 119 | static int shared_cede_loop(struct cpuidle_device *dev, | ||
| 120 | struct cpuidle_driver *drv, | ||
| 121 | int index) | ||
| 122 | { | ||
| 123 | unsigned long in_purr; | ||
| 124 | ktime_t kt_before; | ||
| 125 | |||
| 126 | idle_loop_prolog(&in_purr, &kt_before); | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Yield the processor to the hypervisor. We return if | ||
| 130 | * an external interrupt occurs (which are driven prior | ||
| 131 | * to returning here) or if a prod occurs from another | ||
| 132 | * processor. When returning here, external interrupts | ||
| 133 | * are enabled. | ||
| 134 | */ | ||
| 135 | cede_processor(); | ||
| 136 | |||
| 137 | dev->last_residency = | ||
| 138 | (int)idle_loop_epilog(in_purr, kt_before); | ||
| 139 | return index; | ||
| 140 | } | ||
| 141 | |||
| 142 | /* | ||
| 143 | * States for dedicated partition case. | ||
| 144 | */ | ||
| 145 | static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = { | ||
| 146 | { /* Snooze */ | ||
| 147 | .name = "snooze", | ||
| 148 | .desc = "snooze", | ||
| 149 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
| 150 | .exit_latency = 0, | ||
| 151 | .target_residency = 0, | ||
| 152 | .enter = &snooze_loop }, | ||
| 153 | { /* CEDE */ | ||
| 154 | .name = "CEDE", | ||
| 155 | .desc = "CEDE", | ||
| 156 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
| 157 | .exit_latency = 1, | ||
| 158 | .target_residency = 10, | ||
| 159 | .enter = &dedicated_cede_loop }, | ||
| 160 | }; | ||
| 161 | |||
| 162 | /* | ||
| 163 | * States for shared partition case. | ||
| 164 | */ | ||
| 165 | static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { | ||
| 166 | { /* Shared Cede */ | ||
| 167 | .name = "Shared Cede", | ||
| 168 | .desc = "Shared Cede", | ||
| 169 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
| 170 | .exit_latency = 0, | ||
| 171 | .target_residency = 0, | ||
| 172 | .enter = &shared_cede_loop }, | ||
| 173 | }; | ||
| 174 | |||
| 175 | int pseries_notify_cpuidle_add_cpu(int cpu) | ||
| 176 | { | ||
| 177 | struct cpuidle_device *dev = | ||
| 178 | per_cpu_ptr(pseries_cpuidle_devices, cpu); | ||
| 179 | if (dev && cpuidle_get_driver()) { | ||
| 180 | cpuidle_disable_device(dev); | ||
| 181 | cpuidle_enable_device(dev); | ||
| 182 | } | ||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | /* | ||
| 187 | * pseries_cpuidle_driver_init() | ||
| 188 | */ | ||
| 189 | static int pseries_cpuidle_driver_init(void) | ||
| 190 | { | ||
| 191 | int idle_state; | ||
| 192 | struct cpuidle_driver *drv = &pseries_idle_driver; | ||
| 193 | |||
| 194 | drv->state_count = 0; | ||
| 195 | |||
| 196 | for (idle_state = 0; idle_state < MAX_IDLE_STATE_COUNT; ++idle_state) { | ||
| 197 | |||
| 198 | if (idle_state > max_idle_state) | ||
| 199 | break; | ||
| 200 | |||
| 201 | /* is the state not enabled? */ | ||
| 202 | if (cpuidle_state_table[idle_state].enter == NULL) | ||
| 203 | continue; | ||
| 204 | |||
| 205 | drv->states[drv->state_count] = /* structure copy */ | ||
| 206 | cpuidle_state_table[idle_state]; | ||
| 207 | |||
| 208 | if (cpuidle_state_table == dedicated_states) | ||
| 209 | drv->states[drv->state_count].target_residency = | ||
| 210 | __get_cpu_var(smt_snooze_delay); | ||
| 211 | |||
| 212 | drv->state_count += 1; | ||
| 213 | } | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | /* pseries_idle_devices_uninit(void) | ||
| 219 | * unregister cpuidle devices and de-allocate memory | ||
| 220 | */ | ||
| 221 | static void pseries_idle_devices_uninit(void) | ||
| 222 | { | ||
| 223 | int i; | ||
| 224 | struct cpuidle_device *dev; | ||
| 225 | |||
| 226 | for_each_possible_cpu(i) { | ||
| 227 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
| 228 | cpuidle_unregister_device(dev); | ||
| 229 | } | ||
| 230 | |||
| 231 | free_percpu(pseries_cpuidle_devices); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | |||
| 235 | /* pseries_idle_devices_init() | ||
| 236 | * allocate, initialize and register cpuidle device | ||
| 237 | */ | ||
| 238 | static int pseries_idle_devices_init(void) | ||
| 239 | { | ||
| 240 | int i; | ||
| 241 | struct cpuidle_driver *drv = &pseries_idle_driver; | ||
| 242 | struct cpuidle_device *dev; | ||
| 243 | |||
| 244 | pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device); | ||
| 245 | if (pseries_cpuidle_devices == NULL) | ||
| 246 | return -ENOMEM; | ||
| 247 | |||
| 248 | for_each_possible_cpu(i) { | ||
| 249 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
| 250 | dev->state_count = drv->state_count; | ||
| 251 | dev->cpu = i; | ||
| 252 | if (cpuidle_register_device(dev)) { | ||
| 253 | printk(KERN_DEBUG \ | ||
| 254 | "cpuidle_register_device %d failed!\n", i); | ||
| 255 | return -EIO; | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | return 0; | ||
| 260 | } | ||
| 261 | |||
| 262 | /* | ||
| 263 | * pseries_idle_probe() | ||
| 264 | * Choose state table for shared versus dedicated partition | ||
| 265 | */ | ||
| 266 | static int pseries_idle_probe(void) | ||
| 267 | { | ||
| 268 | |||
| 269 | if (!firmware_has_feature(FW_FEATURE_SPLPAR)) | ||
| 270 | return -ENODEV; | ||
| 271 | |||
| 272 | if (cpuidle_disable != IDLE_NO_OVERRIDE) | ||
| 273 | return -ENODEV; | ||
| 274 | |||
| 275 | if (max_idle_state == 0) { | ||
| 276 | printk(KERN_DEBUG "pseries processor idle disabled.\n"); | ||
| 277 | return -EPERM; | ||
| 278 | } | ||
| 279 | |||
| 280 | if (get_lppaca()->shared_proc) | ||
| 281 | cpuidle_state_table = shared_states; | ||
| 282 | else | ||
| 283 | cpuidle_state_table = dedicated_states; | ||
| 284 | |||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | static int __init pseries_processor_idle_init(void) | ||
| 289 | { | ||
| 290 | int retval; | ||
| 291 | |||
| 292 | retval = pseries_idle_probe(); | ||
| 293 | if (retval) | ||
| 294 | return retval; | ||
| 295 | |||
| 296 | pseries_cpuidle_driver_init(); | ||
| 297 | retval = cpuidle_register_driver(&pseries_idle_driver); | ||
| 298 | if (retval) { | ||
| 299 | printk(KERN_DEBUG "Registration of pseries driver failed.\n"); | ||
| 300 | return retval; | ||
| 301 | } | ||
| 302 | |||
| 303 | retval = pseries_idle_devices_init(); | ||
| 304 | if (retval) { | ||
| 305 | pseries_idle_devices_uninit(); | ||
| 306 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
| 307 | return retval; | ||
| 308 | } | ||
| 309 | |||
| 310 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); | ||
| 311 | |||
| 312 | return 0; | ||
| 313 | } | ||
| 314 | |||
| 315 | static void __exit pseries_processor_idle_exit(void) | ||
| 316 | { | ||
| 317 | |||
| 318 | pseries_idle_devices_uninit(); | ||
| 319 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
| 320 | |||
| 321 | return; | ||
| 322 | } | ||
| 323 | |||
| 324 | module_init(pseries_processor_idle_init); | ||
| 325 | module_exit(pseries_processor_idle_exit); | ||
| 326 | |||
| 327 | MODULE_AUTHOR("Deepthi Dharwar <deepthi@linux.vnet.ibm.com>"); | ||
| 328 | MODULE_DESCRIPTION("Cpuidle driver for POWER"); | ||
| 329 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 24c7162f11d9..9a3dda07566f 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
| @@ -57,4 +57,7 @@ extern struct device_node *dlpar_configure_connector(u32); | |||
| 57 | extern int dlpar_attach_node(struct device_node *); | 57 | extern int dlpar_attach_node(struct device_node *); |
| 58 | extern int dlpar_detach_node(struct device_node *); | 58 | extern int dlpar_detach_node(struct device_node *); |
| 59 | 59 | ||
| 60 | /* Snooze Delay, pseries_idle */ | ||
| 61 | DECLARE_PER_CPU(long, smt_snooze_delay); | ||
| 62 | |||
| 60 | #endif /* _PSERIES_PSERIES_H */ | 63 | #endif /* _PSERIES_PSERIES_H */ |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index c3408ca8855e..f79f1278dfca 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
| 40 | #include <linux/seq_file.h> | 40 | #include <linux/seq_file.h> |
| 41 | #include <linux/root_dev.h> | 41 | #include <linux/root_dev.h> |
| 42 | #include <linux/cpuidle.h> | ||
| 42 | 43 | ||
| 43 | #include <asm/mmu.h> | 44 | #include <asm/mmu.h> |
| 44 | #include <asm/processor.h> | 45 | #include <asm/processor.h> |
| @@ -74,9 +75,6 @@ EXPORT_SYMBOL(CMO_PageSize); | |||
| 74 | 75 | ||
| 75 | int fwnmi_active; /* TRUE if an FWNMI handler is present */ | 76 | int fwnmi_active; /* TRUE if an FWNMI handler is present */ |
| 76 | 77 | ||
| 77 | static void pseries_shared_idle_sleep(void); | ||
| 78 | static void pseries_dedicated_idle_sleep(void); | ||
| 79 | |||
| 80 | static struct device_node *pSeries_mpic_node; | 78 | static struct device_node *pSeries_mpic_node; |
| 81 | 79 | ||
| 82 | static void pSeries_show_cpuinfo(struct seq_file *m) | 80 | static void pSeries_show_cpuinfo(struct seq_file *m) |
| @@ -192,8 +190,7 @@ static void __init pseries_mpic_init_IRQ(void) | |||
| 192 | BUG_ON(openpic_addr == 0); | 190 | BUG_ON(openpic_addr == 0); |
| 193 | 191 | ||
| 194 | /* Setup the openpic driver */ | 192 | /* Setup the openpic driver */ |
| 195 | mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, | 193 | mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, 0, |
| 196 | MPIC_PRIMARY, | ||
| 197 | 16, 250, /* isu size, irq count */ | 194 | 16, 250, /* isu size, irq count */ |
| 198 | " MPIC "); | 195 | " MPIC "); |
| 199 | BUG_ON(mpic == NULL); | 196 | BUG_ON(mpic == NULL); |
| @@ -352,8 +349,25 @@ static int alloc_dispatch_log_kmem_cache(void) | |||
| 352 | } | 349 | } |
| 353 | early_initcall(alloc_dispatch_log_kmem_cache); | 350 | early_initcall(alloc_dispatch_log_kmem_cache); |
| 354 | 351 | ||
| 352 | static void pSeries_idle(void) | ||
| 353 | { | ||
| 354 | /* This would call on the cpuidle framework, and the back-end pseries | ||
| 355 | * driver to go to idle states | ||
| 356 | */ | ||
| 357 | if (cpuidle_idle_call()) { | ||
| 358 | /* On error, execute default handler | ||
| 359 | * to go into low thread priority and possibly | ||
| 360 | * low power mode. | ||
| 361 | */ | ||
| 362 | HMT_low(); | ||
| 363 | HMT_very_low(); | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 355 | static void __init pSeries_setup_arch(void) | 367 | static void __init pSeries_setup_arch(void) |
| 356 | { | 368 | { |
| 369 | panic_timeout = 10; | ||
| 370 | |||
| 357 | /* Discover PIC type and setup ppc_md accordingly */ | 371 | /* Discover PIC type and setup ppc_md accordingly */ |
| 358 | pseries_discover_pic(); | 372 | pseries_discover_pic(); |
| 359 | 373 | ||
| @@ -374,18 +388,9 @@ static void __init pSeries_setup_arch(void) | |||
| 374 | 388 | ||
| 375 | pSeries_nvram_init(); | 389 | pSeries_nvram_init(); |
| 376 | 390 | ||
| 377 | /* Choose an idle loop */ | ||
| 378 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 391 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { |
| 379 | vpa_init(boot_cpuid); | 392 | vpa_init(boot_cpuid); |
| 380 | if (get_lppaca()->shared_proc) { | 393 | ppc_md.power_save = pSeries_idle; |
| 381 | printk(KERN_DEBUG "Using shared processor idle loop\n"); | ||
| 382 | ppc_md.power_save = pseries_shared_idle_sleep; | ||
| 383 | } else { | ||
| 384 | printk(KERN_DEBUG "Using dedicated idle loop\n"); | ||
| 385 | ppc_md.power_save = pseries_dedicated_idle_sleep; | ||
| 386 | } | ||
| 387 | } else { | ||
| 388 | printk(KERN_DEBUG "Using default idle loop\n"); | ||
| 389 | } | 394 | } |
| 390 | 395 | ||
| 391 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 396 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
| @@ -586,80 +591,6 @@ static int __init pSeries_probe(void) | |||
| 586 | return 1; | 591 | return 1; |
| 587 | } | 592 | } |
| 588 | 593 | ||
| 589 | |||
| 590 | DECLARE_PER_CPU(long, smt_snooze_delay); | ||
| 591 | |||
| 592 | static void pseries_dedicated_idle_sleep(void) | ||
| 593 | { | ||
| 594 | unsigned int cpu = smp_processor_id(); | ||
| 595 | unsigned long start_snooze; | ||
| 596 | unsigned long in_purr, out_purr; | ||
| 597 | long snooze = __get_cpu_var(smt_snooze_delay); | ||
| 598 | |||
| 599 | /* | ||
| 600 | * Indicate to the HV that we are idle. Now would be | ||
| 601 | * a good time to find other work to dispatch. | ||
| 602 | */ | ||
| 603 | get_lppaca()->idle = 1; | ||
| 604 | get_lppaca()->donate_dedicated_cpu = 1; | ||
| 605 | in_purr = mfspr(SPRN_PURR); | ||
| 606 | |||
| 607 | /* | ||
| 608 | * We come in with interrupts disabled, and need_resched() | ||
| 609 | * has been checked recently. If we should poll for a little | ||
| 610 | * while, do so. | ||
| 611 | */ | ||
| 612 | if (snooze) { | ||
| 613 | start_snooze = get_tb() + snooze * tb_ticks_per_usec; | ||
| 614 | local_irq_enable(); | ||
| 615 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
| 616 | |||
| 617 | while ((snooze < 0) || (get_tb() < start_snooze)) { | ||
| 618 | if (need_resched() || cpu_is_offline(cpu)) | ||
| 619 | goto out; | ||
| 620 | ppc64_runlatch_off(); | ||
| 621 | HMT_low(); | ||
| 622 | HMT_very_low(); | ||
| 623 | } | ||
| 624 | |||
| 625 | HMT_medium(); | ||
| 626 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
| 627 | smp_mb(); | ||
| 628 | local_irq_disable(); | ||
| 629 | if (need_resched() || cpu_is_offline(cpu)) | ||
| 630 | goto out; | ||
| 631 | } | ||
| 632 | |||
| 633 | cede_processor(); | ||
| 634 | |||
| 635 | out: | ||
| 636 | HMT_medium(); | ||
| 637 | out_purr = mfspr(SPRN_PURR); | ||
| 638 | get_lppaca()->wait_state_cycles += out_purr - in_purr; | ||
| 639 | get_lppaca()->donate_dedicated_cpu = 0; | ||
| 640 | get_lppaca()->idle = 0; | ||
| 641 | } | ||
| 642 | |||
| 643 | static void pseries_shared_idle_sleep(void) | ||
| 644 | { | ||
| 645 | /* | ||
| 646 | * Indicate to the HV that we are idle. Now would be | ||
| 647 | * a good time to find other work to dispatch. | ||
| 648 | */ | ||
| 649 | get_lppaca()->idle = 1; | ||
| 650 | |||
| 651 | /* | ||
| 652 | * Yield the processor to the hypervisor. We return if | ||
| 653 | * an external interrupt occurs (which are driven prior | ||
| 654 | * to returning here) or if a prod occurs from another | ||
| 655 | * processor. When returning here, external interrupts | ||
| 656 | * are enabled. | ||
| 657 | */ | ||
| 658 | cede_processor(); | ||
| 659 | |||
| 660 | get_lppaca()->idle = 0; | ||
| 661 | } | ||
| 662 | |||
| 663 | static int pSeries_pci_probe_mode(struct pci_bus *bus) | 594 | static int pSeries_pci_probe_mode(struct pci_bus *bus) |
| 664 | { | 595 | { |
| 665 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 596 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 26e93fd4c62b..bbc3c42f6730 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
| @@ -148,6 +148,7 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
| 148 | set_cpu_current_state(cpu, CPU_STATE_ONLINE); | 148 | set_cpu_current_state(cpu, CPU_STATE_ONLINE); |
| 149 | set_default_offline_state(cpu); | 149 | set_default_offline_state(cpu); |
| 150 | #endif | 150 | #endif |
| 151 | pseries_notify_cpuidle_add_cpu(cpu); | ||
| 151 | } | 152 | } |
| 152 | 153 | ||
| 153 | static int __devinit smp_pSeries_kick_cpu(int nr) | 154 | static int __devinit smp_pSeries_kick_cpu(int nr) |
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig index bd560c786ed6..57d22a2f4ba9 100644 --- a/arch/powerpc/platforms/wsp/Kconfig +++ b/arch/powerpc/platforms/wsp/Kconfig | |||
| @@ -1,20 +1,28 @@ | |||
| 1 | config PPC_WSP | 1 | config PPC_WSP |
| 2 | bool | 2 | bool |
| 3 | select PPC_A2 | 3 | select PPC_A2 |
| 4 | select GENERIC_TBSYNC | ||
| 5 | select PPC_ICSWX | ||
| 4 | select PPC_SCOM | 6 | select PPC_SCOM |
| 5 | select PPC_XICS | 7 | select PPC_XICS |
| 6 | select PPC_ICP_NATIVE | 8 | select PPC_ICP_NATIVE |
| 7 | select PCI | 9 | select PCI |
| 8 | select PPC_IO_WORKAROUNDS if PCI | 10 | select PPC_IO_WORKAROUNDS if PCI |
| 9 | select PPC_INDIRECT_PIO if PCI | 11 | select PPC_INDIRECT_PIO if PCI |
| 12 | select PPC_WSP_COPRO | ||
| 10 | default n | 13 | default n |
| 11 | 14 | ||
| 12 | menu "WSP platform selection" | 15 | menu "WSP platform selection" |
| 13 | depends on PPC_BOOK3E_64 | 16 | depends on PPC_BOOK3E_64 |
| 14 | 17 | ||
| 15 | config PPC_PSR2 | 18 | config PPC_PSR2 |
| 16 | bool "PSR-2 platform" | 19 | bool "PowerEN System Reference Platform 2" |
| 17 | select GENERIC_TBSYNC | 20 | select EPAPR_BOOT |
| 21 | select PPC_WSP | ||
| 22 | default y | ||
| 23 | |||
| 24 | config PPC_CHROMA | ||
| 25 | bool "PowerEN PCIe Chroma Card" | ||
| 18 | select EPAPR_BOOT | 26 | select EPAPR_BOOT |
| 19 | select PPC_WSP | 27 | select PPC_WSP |
| 20 | default y | 28 | default y |
diff --git a/arch/powerpc/platforms/wsp/Makefile b/arch/powerpc/platforms/wsp/Makefile index a1486b436f02..56817ac98fc9 100644 --- a/arch/powerpc/platforms/wsp/Makefile +++ b/arch/powerpc/platforms/wsp/Makefile | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | ccflags-y += -mno-minimal-toc | 1 | ccflags-y += -mno-minimal-toc |
| 2 | 2 | ||
| 3 | obj-y += setup.o ics.o | 3 | obj-y += setup.o ics.o wsp.o |
| 4 | obj-$(CONFIG_PPC_PSR2) += psr2.o opb_pic.o | 4 | obj-$(CONFIG_PPC_PSR2) += psr2.o |
| 5 | obj-$(CONFIG_PPC_CHROMA) += chroma.o h8.o | ||
| 6 | obj-$(CONFIG_PPC_WSP) += opb_pic.o | ||
| 5 | obj-$(CONFIG_PPC_WSP) += scom_wsp.o | 7 | obj-$(CONFIG_PPC_WSP) += scom_wsp.o |
| 6 | obj-$(CONFIG_SMP) += smp.o scom_smp.o | 8 | obj-$(CONFIG_SMP) += smp.o scom_smp.o |
| 7 | obj-$(CONFIG_PCI) += wsp_pci.o | 9 | obj-$(CONFIG_PCI) += wsp_pci.o |
| 8 | obj-$(CONFIG_PCI_MSI) += msi.o \ No newline at end of file | 10 | obj-$(CONFIG_PCI_MSI) += msi.o |
diff --git a/arch/powerpc/platforms/wsp/chroma.c b/arch/powerpc/platforms/wsp/chroma.c new file mode 100644 index 000000000000..ca6fa26f6e63 --- /dev/null +++ b/arch/powerpc/platforms/wsp/chroma.c | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2008-2011, IBM Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/delay.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/irq.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/mm.h> | ||
| 15 | #include <linux/of.h> | ||
| 16 | #include <linux/smp.h> | ||
| 17 | #include <linux/time.h> | ||
| 18 | |||
| 19 | #include <asm/machdep.h> | ||
| 20 | #include <asm/system.h> | ||
| 21 | #include <asm/udbg.h> | ||
| 22 | |||
| 23 | #include "ics.h" | ||
| 24 | #include "wsp.h" | ||
| 25 | |||
| 26 | void __init chroma_setup_arch(void) | ||
| 27 | { | ||
| 28 | wsp_setup_arch(); | ||
| 29 | wsp_setup_h8(); | ||
| 30 | |||
| 31 | } | ||
| 32 | |||
| 33 | static int __init chroma_probe(void) | ||
| 34 | { | ||
| 35 | unsigned long root = of_get_flat_dt_root(); | ||
| 36 | |||
| 37 | if (!of_flat_dt_is_compatible(root, "ibm,wsp-chroma")) | ||
| 38 | return 0; | ||
| 39 | |||
| 40 | return 1; | ||
| 41 | } | ||
| 42 | |||
| 43 | define_machine(chroma_md) { | ||
| 44 | .name = "Chroma PCIe", | ||
| 45 | .probe = chroma_probe, | ||
| 46 | .setup_arch = chroma_setup_arch, | ||
| 47 | .restart = wsp_h8_restart, | ||
| 48 | .power_off = wsp_h8_power_off, | ||
| 49 | .halt = wsp_halt, | ||
| 50 | .calibrate_decr = generic_calibrate_decr, | ||
| 51 | .init_IRQ = wsp_setup_irq, | ||
| 52 | .progress = udbg_progress, | ||
| 53 | .power_save = book3e_idle, | ||
| 54 | }; | ||
| 55 | |||
| 56 | machine_arch_initcall(chroma_md, wsp_probe_devices); | ||
diff --git a/arch/powerpc/platforms/wsp/h8.c b/arch/powerpc/platforms/wsp/h8.c new file mode 100644 index 000000000000..d18e6cc19df3 --- /dev/null +++ b/arch/powerpc/platforms/wsp/h8.c | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2008-2011, IBM Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/of.h> | ||
| 12 | #include <linux/io.h> | ||
| 13 | |||
| 14 | #include "wsp.h" | ||
| 15 | |||
| 16 | /* | ||
| 17 | * The UART connection to the H8 is over ttyS1 which is just a 16550. | ||
| 18 | * We assume that FW has it setup right and no one messes with it. | ||
| 19 | */ | ||
| 20 | |||
| 21 | |||
| 22 | static u8 __iomem *h8; | ||
| 23 | |||
| 24 | #define RBR 0 /* Receiver Buffer Register */ | ||
| 25 | #define THR 0 /* Transmitter Holding Register */ | ||
| 26 | #define LSR 5 /* Line Status Register */ | ||
| 27 | #define LSR_DR 0x01 /* LSR value for Data-Ready */ | ||
| 28 | #define LSR_THRE 0x20 /* LSR value for Transmitter-Holding-Register-Empty */ | ||
| 29 | static void wsp_h8_putc(int c) | ||
| 30 | { | ||
| 31 | u8 lsr; | ||
| 32 | |||
| 33 | do { | ||
| 34 | lsr = readb(h8 + LSR); | ||
| 35 | } while ((lsr & LSR_THRE) != LSR_THRE); | ||
| 36 | writeb(c, h8 + THR); | ||
| 37 | } | ||
| 38 | |||
| 39 | static int wsp_h8_getc(void) | ||
| 40 | { | ||
| 41 | u8 lsr; | ||
| 42 | |||
| 43 | do { | ||
| 44 | lsr = readb(h8 + LSR); | ||
| 45 | } while ((lsr & LSR_DR) != LSR_DR); | ||
| 46 | |||
| 47 | return readb(h8 + RBR); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void wsp_h8_puts(const char *s, int sz) | ||
| 51 | { | ||
| 52 | int i; | ||
| 53 | |||
| 54 | for (i = 0; i < sz; i++) { | ||
| 55 | wsp_h8_putc(s[i]); | ||
| 56 | |||
| 57 | /* no flow control so wait for echo */ | ||
| 58 | wsp_h8_getc(); | ||
| 59 | } | ||
| 60 | wsp_h8_putc('\r'); | ||
| 61 | wsp_h8_putc('\n'); | ||
| 62 | } | ||
| 63 | |||
| 64 | static void wsp_h8_terminal_cmd(const char *cmd, int sz) | ||
| 65 | { | ||
| 66 | hard_irq_disable(); | ||
| 67 | wsp_h8_puts(cmd, sz); | ||
| 68 | /* should never return, but just in case */ | ||
| 69 | for (;;) | ||
| 70 | continue; | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | void wsp_h8_restart(char *cmd) | ||
| 75 | { | ||
| 76 | static const char restart[] = "warm-reset"; | ||
| 77 | |||
| 78 | (void)cmd; | ||
| 79 | wsp_h8_terminal_cmd(restart, sizeof(restart) - 1); | ||
| 80 | } | ||
| 81 | |||
| 82 | void wsp_h8_power_off(void) | ||
| 83 | { | ||
| 84 | static const char off[] = "power-off"; | ||
| 85 | |||
| 86 | wsp_h8_terminal_cmd(off, sizeof(off) - 1); | ||
| 87 | } | ||
| 88 | |||
| 89 | static void __iomem *wsp_h8_getaddr(void) | ||
| 90 | { | ||
| 91 | struct device_node *aliases; | ||
| 92 | struct device_node *uart; | ||
| 93 | struct property *path; | ||
| 94 | void __iomem *va = NULL; | ||
| 95 | |||
| 96 | /* | ||
| 97 | * there is nothing in the devtree to tell us which is mapped | ||
| 98 | * to the H8, but se know it is the second serial port. | ||
| 99 | */ | ||
| 100 | |||
| 101 | aliases = of_find_node_by_path("/aliases"); | ||
| 102 | if (aliases == NULL) | ||
| 103 | return NULL; | ||
| 104 | |||
| 105 | path = of_find_property(aliases, "serial1", NULL); | ||
| 106 | if (path == NULL) | ||
| 107 | goto out; | ||
| 108 | |||
| 109 | uart = of_find_node_by_path(path->value); | ||
| 110 | if (uart == NULL) | ||
| 111 | goto out; | ||
| 112 | |||
| 113 | va = of_iomap(uart, 0); | ||
| 114 | |||
| 115 | /* remove it so no one messes with it */ | ||
| 116 | of_detach_node(uart); | ||
| 117 | of_node_put(uart); | ||
| 118 | |||
| 119 | out: | ||
| 120 | of_node_put(aliases); | ||
| 121 | |||
| 122 | return va; | ||
| 123 | } | ||
| 124 | |||
| 125 | void __init wsp_setup_h8(void) | ||
| 126 | { | ||
| 127 | h8 = wsp_h8_getaddr(); | ||
| 128 | |||
| 129 | /* Devtree change? lets hard map it anyway */ | ||
| 130 | if (h8 == NULL) { | ||
| 131 | pr_warn("UART to H8 could not be found"); | ||
| 132 | h8 = ioremap(0xffc0008000ULL, 0x100); | ||
| 133 | } | ||
| 134 | } | ||
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c index be05631a3c1c..19f353dfcd03 100644 --- a/arch/powerpc/platforms/wsp/opb_pic.c +++ b/arch/powerpc/platforms/wsp/opb_pic.c | |||
| @@ -320,7 +320,8 @@ void __init opb_pic_init(void) | |||
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | /* Attach opb interrupt handler to new virtual IRQ */ | 322 | /* Attach opb interrupt handler to new virtual IRQ */ |
| 323 | rc = request_irq(virq, opb_irq_handler, 0, "OPB LS Cascade", opb); | 323 | rc = request_irq(virq, opb_irq_handler, IRQF_NO_THREAD, |
| 324 | "OPB LS Cascade", opb); | ||
| 324 | if (rc) { | 325 | if (rc) { |
| 325 | printk("opb: request_irq failed: %d\n", rc); | 326 | printk("opb: request_irq failed: %d\n", rc); |
| 326 | continue; | 327 | continue; |
diff --git a/arch/powerpc/platforms/wsp/psr2.c b/arch/powerpc/platforms/wsp/psr2.c index 166f2e4b4bee..0c1ae06d0be1 100644 --- a/arch/powerpc/platforms/wsp/psr2.c +++ b/arch/powerpc/platforms/wsp/psr2.c | |||
| @@ -14,10 +14,10 @@ | |||
| 14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
| 15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <linux/smp.h> | 16 | #include <linux/smp.h> |
| 17 | #include <linux/time.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
| 19 | #include <asm/system.h> | 20 | #include <asm/system.h> |
| 20 | #include <asm/time.h> | ||
| 21 | #include <asm/udbg.h> | 21 | #include <asm/udbg.h> |
| 22 | 22 | ||
| 23 | #include "ics.h" | 23 | #include "ics.h" |
| @@ -27,7 +27,8 @@ | |||
| 27 | static void psr2_spin(void) | 27 | static void psr2_spin(void) |
| 28 | { | 28 | { |
| 29 | hard_irq_disable(); | 29 | hard_irq_disable(); |
| 30 | for (;;) ; | 30 | for (;;) |
| 31 | continue; | ||
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | static void psr2_restart(char *cmd) | 34 | static void psr2_restart(char *cmd) |
| @@ -35,65 +36,32 @@ static void psr2_restart(char *cmd) | |||
| 35 | psr2_spin(); | 36 | psr2_spin(); |
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | static int psr2_probe_devices(void) | ||
| 39 | { | ||
| 40 | struct device_node *np; | ||
| 41 | |||
| 42 | /* Our RTC is a ds1500. It seems to be programatically compatible | ||
| 43 | * with the ds1511 for which we have a driver so let's use that | ||
| 44 | */ | ||
| 45 | np = of_find_compatible_node(NULL, NULL, "dallas,ds1500"); | ||
| 46 | if (np != NULL) { | ||
| 47 | struct resource res; | ||
| 48 | if (of_address_to_resource(np, 0, &res) == 0) | ||
| 49 | platform_device_register_simple("ds1511", 0, &res, 1); | ||
| 50 | } | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | machine_arch_initcall(psr2_md, psr2_probe_devices); | ||
| 54 | |||
| 55 | static void __init psr2_setup_arch(void) | ||
| 56 | { | ||
| 57 | /* init to some ~sane value until calibrate_delay() runs */ | ||
| 58 | loops_per_jiffy = 50000000; | ||
| 59 | |||
| 60 | scom_init_wsp(); | ||
| 61 | |||
| 62 | /* Setup SMP callback */ | ||
| 63 | #ifdef CONFIG_SMP | ||
| 64 | a2_setup_smp(); | ||
| 65 | #endif | ||
| 66 | #ifdef CONFIG_PCI | ||
| 67 | wsp_setup_pci(); | ||
| 68 | #endif | ||
| 69 | |||
| 70 | } | ||
| 71 | |||
| 72 | static int __init psr2_probe(void) | 39 | static int __init psr2_probe(void) |
| 73 | { | 40 | { |
| 74 | unsigned long root = of_get_flat_dt_root(); | 41 | unsigned long root = of_get_flat_dt_root(); |
| 75 | 42 | ||
| 43 | if (of_flat_dt_is_compatible(root, "ibm,wsp-chroma")) { | ||
| 44 | /* chroma systems also claim they are psr2s */ | ||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 76 | if (!of_flat_dt_is_compatible(root, "ibm,psr2")) | 48 | if (!of_flat_dt_is_compatible(root, "ibm,psr2")) |
| 77 | return 0; | 49 | return 0; |
| 78 | 50 | ||
| 79 | return 1; | 51 | return 1; |
| 80 | } | 52 | } |
| 81 | 53 | ||
| 82 | static void __init psr2_init_irq(void) | ||
| 83 | { | ||
| 84 | wsp_init_irq(); | ||
| 85 | opb_pic_init(); | ||
| 86 | } | ||
| 87 | |||
| 88 | define_machine(psr2_md) { | 54 | define_machine(psr2_md) { |
| 89 | .name = "PSR2 A2", | 55 | .name = "PSR2 A2", |
| 90 | .probe = psr2_probe, | 56 | .probe = psr2_probe, |
| 91 | .setup_arch = psr2_setup_arch, | 57 | .setup_arch = wsp_setup_arch, |
| 92 | .restart = psr2_restart, | 58 | .restart = psr2_restart, |
| 93 | .power_off = psr2_spin, | 59 | .power_off = psr2_spin, |
| 94 | .halt = psr2_spin, | 60 | .halt = psr2_spin, |
| 95 | .calibrate_decr = generic_calibrate_decr, | 61 | .calibrate_decr = generic_calibrate_decr, |
| 96 | .init_IRQ = psr2_init_irq, | 62 | .init_IRQ = wsp_setup_irq, |
| 97 | .progress = udbg_progress, | 63 | .progress = udbg_progress, |
| 98 | .power_save = book3e_idle, | 64 | .power_save = book3e_idle, |
| 99 | }; | 65 | }; |
| 66 | |||
| 67 | machine_arch_initcall(psr2_md, wsp_probe_devices); | ||
diff --git a/arch/powerpc/platforms/wsp/wsp.c b/arch/powerpc/platforms/wsp/wsp.c new file mode 100644 index 000000000000..d25cc96c21b8 --- /dev/null +++ b/arch/powerpc/platforms/wsp/wsp.c | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2008-2011, IBM Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/of.h> | ||
| 12 | #include <linux/of_device.h> | ||
| 13 | #include <linux/smp.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | #include <linux/time.h> | ||
| 16 | |||
| 17 | #include <asm/scom.h> | ||
| 18 | |||
| 19 | #include "wsp.h" | ||
| 20 | #include "ics.h" | ||
| 21 | |||
| 22 | #define WSP_SOC_COMPATIBLE "ibm,wsp-soc" | ||
| 23 | #define PBIC_COMPATIBLE "ibm,wsp-pbic" | ||
| 24 | #define COPRO_COMPATIBLE "ibm,wsp-coprocessor" | ||
| 25 | |||
| 26 | static int __init wsp_probe_buses(void) | ||
| 27 | { | ||
| 28 | static __initdata struct of_device_id bus_ids[] = { | ||
| 29 | /* | ||
| 30 | * every node in between needs to be here or you won't | ||
| 31 | * find it | ||
| 32 | */ | ||
| 33 | { .compatible = WSP_SOC_COMPATIBLE, }, | ||
| 34 | { .compatible = PBIC_COMPATIBLE, }, | ||
| 35 | { .compatible = COPRO_COMPATIBLE, }, | ||
| 36 | {}, | ||
| 37 | }; | ||
| 38 | of_platform_bus_probe(NULL, bus_ids, NULL); | ||
| 39 | |||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | void __init wsp_setup_arch(void) | ||
| 44 | { | ||
| 45 | /* init to some ~sane value until calibrate_delay() runs */ | ||
| 46 | loops_per_jiffy = 50000000; | ||
| 47 | |||
| 48 | scom_init_wsp(); | ||
| 49 | |||
| 50 | /* Setup SMP callback */ | ||
| 51 | #ifdef CONFIG_SMP | ||
| 52 | a2_setup_smp(); | ||
| 53 | #endif | ||
| 54 | #ifdef CONFIG_PCI | ||
| 55 | wsp_setup_pci(); | ||
| 56 | #endif | ||
| 57 | } | ||
| 58 | |||
| 59 | void __init wsp_setup_irq(void) | ||
| 60 | { | ||
| 61 | wsp_init_irq(); | ||
| 62 | opb_pic_init(); | ||
| 63 | } | ||
| 64 | |||
| 65 | |||
| 66 | int __init wsp_probe_devices(void) | ||
| 67 | { | ||
| 68 | struct device_node *np; | ||
| 69 | |||
| 70 | /* Our RTC is a ds1500. It seems to be programatically compatible | ||
| 71 | * with the ds1511 for which we have a driver so let's use that | ||
| 72 | */ | ||
| 73 | np = of_find_compatible_node(NULL, NULL, "dallas,ds1500"); | ||
| 74 | if (np != NULL) { | ||
| 75 | struct resource res; | ||
| 76 | if (of_address_to_resource(np, 0, &res) == 0) | ||
| 77 | platform_device_register_simple("ds1511", 0, &res, 1); | ||
| 78 | } | ||
| 79 | |||
| 80 | wsp_probe_buses(); | ||
| 81 | |||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | void wsp_halt(void) | ||
| 86 | { | ||
| 87 | u64 val; | ||
| 88 | scom_map_t m; | ||
| 89 | struct device_node *dn; | ||
| 90 | struct device_node *mine; | ||
| 91 | struct device_node *me; | ||
| 92 | |||
| 93 | me = of_get_cpu_node(smp_processor_id(), NULL); | ||
| 94 | mine = scom_find_parent(me); | ||
| 95 | |||
| 96 | /* This will halt all the A2s but not power off the chip */ | ||
| 97 | for_each_node_with_property(dn, "scom-controller") { | ||
| 98 | if (dn == mine) | ||
| 99 | continue; | ||
| 100 | m = scom_map(dn, 0, 1); | ||
| 101 | |||
| 102 | /* read-modify-write it so the HW probe does not get | ||
| 103 | * confused */ | ||
| 104 | val = scom_read(m, 0); | ||
| 105 | val |= 1; | ||
| 106 | scom_write(m, 0, val); | ||
| 107 | scom_unmap(m); | ||
| 108 | } | ||
| 109 | m = scom_map(mine, 0, 1); | ||
| 110 | val = scom_read(m, 0); | ||
| 111 | val |= 1; | ||
| 112 | scom_write(m, 0, val); | ||
| 113 | /* should never return */ | ||
| 114 | scom_unmap(m); | ||
| 115 | } | ||
diff --git a/arch/powerpc/platforms/wsp/wsp.h b/arch/powerpc/platforms/wsp/wsp.h index 33479818f62a..10c1d1fff362 100644 --- a/arch/powerpc/platforms/wsp/wsp.h +++ b/arch/powerpc/platforms/wsp/wsp.h | |||
| @@ -6,15 +6,25 @@ | |||
| 6 | /* Devtree compatible strings for major devices */ | 6 | /* Devtree compatible strings for major devices */ |
| 7 | #define PCIE_COMPATIBLE "ibm,wsp-pciex" | 7 | #define PCIE_COMPATIBLE "ibm,wsp-pciex" |
| 8 | 8 | ||
| 9 | extern void wsp_setup_arch(void); | ||
| 10 | extern void wsp_setup_irq(void); | ||
| 11 | extern int wsp_probe_devices(void); | ||
| 12 | extern void wsp_halt(void); | ||
| 13 | |||
| 9 | extern void wsp_setup_pci(void); | 14 | extern void wsp_setup_pci(void); |
| 10 | extern void scom_init_wsp(void); | 15 | extern void scom_init_wsp(void); |
| 11 | 16 | ||
| 12 | extern void a2_setup_smp(void); | 17 | extern void a2_setup_smp(void); |
| 13 | extern int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, | 18 | extern int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, |
| 14 | struct device_node *np); | 19 | struct device_node *np); |
| 15 | int smp_a2_cpu_bootable(unsigned int nr); | 20 | extern int smp_a2_cpu_bootable(unsigned int nr); |
| 16 | int __devinit smp_a2_kick_cpu(int nr); | 21 | extern int __devinit smp_a2_kick_cpu(int nr); |
| 22 | |||
| 23 | extern void opb_pic_init(void); | ||
| 17 | 24 | ||
| 18 | void opb_pic_init(void); | 25 | /* chroma specific managment */ |
| 26 | extern void wsp_h8_restart(char *cmd); | ||
| 27 | extern void wsp_h8_power_off(void); | ||
| 28 | extern void __init wsp_setup_h8(void); | ||
| 19 | 29 | ||
| 20 | #endif /* __WSP_H */ | 30 | #endif /* __WSP_H */ |
