diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-30 21:44:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-30 21:44:06 -0700 |
commit | 4c15343167b5febe7bb0ba96aad5bef42ae94d3b (patch) | |
tree | e70f835cc57a6e4b7e18bcb1908217a95a389ba7 /arch | |
parent | eb36c2884a1a2190791afe65fd833b2d3cd4b999 (diff) | |
parent | d0027bf09f09d95a23b8f476ba8cea28f2576781 (diff) |
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc:
[POWERPC] Fix return value from memcpy
[POWERPC] iseries: Define insw et al. so libata/ide will compile
[POWERPC] Fix irq enable/disable in smp_generic_take_timebase
[POWERPC] Fix problem with time not advancing on 32-bit platforms
[POWERPC] Restore copyright notice in arch/powerpc/kernel/fpu.S
[POWERPC] Fix up ibm_architecture_vec definition
[POWERPC] Make OF irq map code detect more error cases
[POWERPC] Support for "weird" MPICs and fixup mpc7448_hpc2
[POWERPC] Fix MPIC sense codes in documentation
[POWERPC] Fix performance regression in IRQ radix tree locking
[POWERPC] Add mpc7448hpc2 device tree source file
[POWERPC] Add MPC8349E MDS device tree source file to arch/powerpc/boot/dts
[POWERPC] modify mpc83xx platforms to use new IRQ layer
[POWERPC] Adapt ipic driver to new host_ops interface, add set_irq_type to set IRQ sense
[POWERPC] back up old school ipic.[hc] to arch/ppc
[POWERPC] Use mpc8641hpcn PIC base address from dev tree.
[POWERPC] Allow MPC8641 HPCN to build with CONFIG_PCI disabled too.
[POWERPC] Fix powerpc 44x_mmu build
[POWERPC] Remove flush_dcache_all export
Diffstat (limited to 'arch')
29 files changed, 1781 insertions, 310 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index abb325eb8f7..4d4b6fb156e 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -354,6 +354,7 @@ endchoice config PPC_PSERIES depends on PPC_MULTIPLATFORM && PPC64 bool "IBM pSeries & new (POWER5-based) iSeries" + select MPIC select PPC_I8259 select PPC_RTAS select RTAS_ERROR_LOGGING @@ -363,6 +364,7 @@ config PPC_PSERIES config PPC_CHRP bool "Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM && PPC32 + select MPIC select PPC_I8259 select PPC_INDIRECT_PCI select PPC_RTAS @@ -373,6 +375,7 @@ config PPC_CHRP config PPC_PMAC bool "Apple PowerMac based machines" depends on PPC_MULTIPLATFORM + select MPIC select PPC_INDIRECT_PCI if PPC32 select PPC_MPC106 if PPC32 default y @@ -380,6 +383,7 @@ config PPC_PMAC config PPC_PMAC64 bool depends on PPC_PMAC && POWER4 + select MPIC select U3_DART select MPIC_BROKEN_U3 select GENERIC_TBSYNC @@ -389,6 +393,7 @@ config PPC_PMAC64 config PPC_PREP bool "PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM && PPC32 && BROKEN + select MPIC select PPC_I8259 select PPC_INDIRECT_PCI select PPC_UDBG_16550 @@ -397,6 +402,7 @@ config PPC_PREP config PPC_MAPLE depends on PPC_MULTIPLATFORM && PPC64 bool "Maple 970FX Evaluation Board" + select MPIC select U3_DART select MPIC_BROKEN_U3 select GENERIC_TBSYNC @@ -439,12 +445,6 @@ config U3_DART depends on PPC_MULTIPLATFORM && PPC64 default n -config MPIC - depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \ - || MPC7448HPC2 - bool - default y - config PPC_RTAS bool default n @@ -812,6 +812,14 @@ config GENERIC_ISA_DMA depends on PPC64 || POWER4 || 6xx && !CPM2 default y +config MPIC + bool + default n + +config MPIC_WEIRD + bool + default n + config PPC_I8259 bool default n diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts new file mode 100644 index 00000000000..d7b985e6bd2 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts @@ -0,0 +1,190 @@ +/* + * MPC7448HPC2 (Taiga) board Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * 2006 Roy Zang <Roy Zang at freescale.com>. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "mpc7448hpc2"; + compatible = "mpc74xx"; + #address-cells = <1>; + #size-cells = <1>; + linux,phandle = <100>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells =<0>; + linux,phandle = <200>; + + PowerPC,7448@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K bytes + i-cache-size = <8000>; // L1, 32K bytes + timebase-frequency = <0>; // 33 MHz, from uboot + clock-frequency = <0>; // From U-Boot + bus-frequency = <0>; // From U-Boot + 32-bit; + linux,phandle = <201>; + linux,boot-cpu; + }; + }; + + memory { + device_type = "memory"; + linux,phandle = <300>; + reg = <00000000 20000000 // DDR2 512M at 0 + >; + }; + + tsi108@c0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "tsi-bridge"; + ranges = <00000000 c0000000 00010000>; + reg = <c0000000 00010000>; + bus-frequency = <0>; + + i2c@7000 { + interrupt-parent = <7400>; + interrupts = <E 0>; + reg = <7000 400>; + device_type = "i2c"; + compatible = "tsi-i2c"; + }; + + mdio@6000 { + device_type = "mdio"; + compatible = "tsi-ethernet"; + + ethernet-phy@6000 { + linux,phandle = <6000>; + interrupt-parent = <7400>; + interrupts = <2 1>; + reg = <6000 50>; + phy-id = <8>; + device_type = "ethernet-phy"; + }; + + ethernet-phy@6400 { + linux,phandle = <6400>; + interrupt-parent = <7400>; + interrupts = <2 1>; + reg = <6000 50>; + phy-id = <9>; + device_type = "ethernet-phy"; + }; + + }; + + ethernet@6200 { + #size-cells = <0>; + device_type = "network"; + model = "TSI-ETH"; + compatible = "tsi-ethernet"; + reg = <6000 200>; + address = [ 00 06 D2 00 00 01 ]; + interrupts = <10 2>; + interrupt-parent = <7400>; + phy-handle = <6000>; + }; + + ethernet@6600 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSI-ETH"; + compatible = "tsi-ethernet"; + reg = <6400 200>; + address = [ 00 06 D2 00 00 02 ]; + interrupts = <11 2>; + interrupt-parent = <7400>; + phy-handle = <6400>; + }; + + serial@7808 { + device_type = "serial"; + compatible = "ns16550"; + reg = <7808 200>; + clock-frequency = <3f6b5a00>; + interrupts = <c 0>; + interrupt-parent = <7400>; + }; + + serial@7c08 { + device_type = "serial"; + compatible = "ns16550"; + reg = <7c08 200>; + clock-frequency = <3f6b5a00>; + interrupts = <d 0>; + interrupt-parent = <7400>; + }; + + pic@7400 { + linux,phandle = <7400>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <7400 400>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + pci@1000 { + compatible = "tsi10x"; + device_type = "pci"; + linux,phandle = <1000>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <1000 1000>; + bus-range = <0 0>; + ranges = <02000000 0 e0000000 e0000000 0 1A000000 + 01000000 0 00000000 fa000000 0 00010000>; + clock-frequency = <7f28154>; + interrupt-parent = <7400>; + interrupts = <17 2>; + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x11 */ + 0800 0 0 1 7400 24 0 + 0800 0 0 2 7400 25 0 + 0800 0 0 3 7400 26 0 + 0800 0 0 4 7400 27 0 + + /* IDSEL 0x12 */ + 1000 0 0 1 7400 25 0 + 1000 0 0 2 7400 26 0 + 1000 0 0 3 7400 27 0 + 1000 0 0 4 7400 24 0 + + /* IDSEL 0x13 */ + 1800 0 0 1 7400 26 0 + 1800 0 0 2 7400 27 0 + 1800 0 0 3 7400 24 0 + 1800 0 0 4 7400 25 0 + + /* IDSEL 0x14 */ + 2000 0 0 1 7400 27 0 + 2000 0 0 2 7400 24 0 + 2000 0 0 3 7400 25 0 + 2000 0 0 4 7400 26 0 + >; + }; + }; + +}; diff --git a/arch/powerpc/boot/dts/mpc8349emds.dts b/arch/powerpc/boot/dts/mpc8349emds.dts new file mode 100644 index 00000000000..12f5dbf3055 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8349emds.dts @@ -0,0 +1,328 @@ +/* + * MPC8349E MDS Device Tree Source + * + * Copyright 2005, 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/ { + model = "MPC8349EMDS"; + compatible = "MPC834xMDS"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8349@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + 32-bit; + }; + }; + + memory { + device_type = "memory"; + reg = <00000000 10000000>; // 256MB at 0 + }; + + soc8349@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 e0000000 00100000>; + reg = <e0000000 00000200>; + bus-frequency = <0>; + + wdt@200 { + device_type = "watchdog"; + compatible = "mpc83xx_wdt"; + reg = <200 100>; + }; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <e 8>; + interrupt-parent = <700>; + dfsrr; + }; + + i2c@3100 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3100 100>; + interrupts = <f 8>; + interrupt-parent = <700>; + dfsrr; + }; + + spi@7000 { + device_type = "spi"; + compatible = "mpc83xx_spi"; + reg = <7000 1000>; + interrupts = <10 8>; + interrupt-parent = <700>; + mode = <0>; + }; + + /* phy type (ULPI or SERIAL) are only types supportted for MPH */ + /* port = 0 or 1 */ + usb@22000 { + device_type = "usb"; + compatible = "fsl-usb2-mph"; + reg = <22000 1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <700>; + interrupts = <27 2>; + phy_type = "ulpi"; + port1; + }; + /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ + usb@23000 { + device_type = "usb"; + compatible = "fsl-usb2-dr"; + reg = <23000 1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <700>; + interrupts = <26 2>; + phy_type = "ulpi"; + }; + + mdio@24520 { + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + #address-cells = <1>; + #size-cells = <0>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <700>; + interrupts = <11 2>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <700>; + interrupts = <12 2>; + reg = <1>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + address = [ 00 00 00 00 00 00 ]; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <20 8 21 8 22 8>; + interrupt-parent = <700>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + address = [ 00 00 00 00 00 00 ]; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <23 8 24 8 25 8>; + interrupt-parent = <700>; + phy-handle = <2452001>; + }; + + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; + clock-frequency = <0>; + interrupts = <9 8>; + interrupt-parent = <700>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; + clock-frequency = <0>; + interrupts = <a 8>; + interrupt-parent = <700>; + }; + + pci@8500 { + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x11 */ + 8800 0 0 1 700 14 8 + 8800 0 0 2 700 15 8 + 8800 0 0 3 700 16 8 + 8800 0 0 4 700 17 8 + + /* IDSEL 0x12 */ + 9000 0 0 1 700 16 8 + 9000 0 0 2 700 17 8 + 9000 0 0 3 700 14 8 + 9000 0 0 4 700 15 8 + + /* IDSEL 0x13 */ + 9800 0 0 1 700 17 8 + 9800 0 0 2 700 14 8 + 9800 0 0 3 700 15 8 + 9800 0 0 4 700 16 8 + + /* IDSEL 0x15 */ + a800 0 0 1 700 14 8 + a800 0 0 2 700 15 8 + a800 0 0 3 700 16 8 + a800 0 0 4 700 17 8 + + /* IDSEL 0x16 */ + b000 0 0 1 700 17 8 + b000 0 0 2 700 14 8 + b000 0 0 3 700 15 8 + b000 0 0 4 700 16 8 + + /* IDSEL 0x17 */ + b800 0 0 1 700 16 8 + b800 0 0 2 700 17 8 + b800 0 0 3 700 14 8 + b800 0 0 4 700 15 8 + + /* IDSEL 0x18 */ + b000 0 0 1 700 15 8 + b000 0 0 2 700 16 8 + b000 0 0 3 700 17 8 + b000 0 0 4 700 14 8>; + interrupt-parent = <700>; + interrupts = <42 8>; + bus-range = <0 0>; + ranges = <02000000 0 a0000000 a0000000 0 10000000 + 42000000 0 80000000 80000000 0 10000000 + 01000000 0 00000000 e2000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8500 100>; + compatible = "83xx"; + device_type = "pci"; + }; + + pci@8600 { + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x11 */ + 8800 0 0 1 700 14 8 + 8800 0 0 2 700 15 8 + 8800 0 0 3 700 16 8 + 8800 0 0 4 700 17 8 + + /* IDSEL 0x12 */ + 9000 0 0 1 700 16 8 + 9000 0 0 2 700 17 8 + 9000 0 0 3 700 14 8 + 9000 0 0 4 700 15 8 + + /* IDSEL 0x13 */ + 9800 0 0 1 700 17 8 + 9800 0 0 2 700 14 8 + 9800 0 0 3 700 15 8 + 9800 0 0 4 700 16 8 + + /* IDSEL 0x15 */ + a800 0 0 1 700 14 8 + a800 0 0 2 700 15 8 + a800 0 0 3 700 16 8 + a800 0 0 4 700 17 8 + + /* IDSEL 0x16 */ + b000 0 0 1 700 17 8 + b000 0 0 2 700 14 8 + b000 0 0 3 700 15 8 + b000 0 0 4 700 16 8 + + /* IDSEL 0x17 */ + b800 0 0 1 700 16 8 + b800 0 0 2 700 17 8 + b800 0 0 3 700 14 8 + b800 0 0 4 700 15 8 + + /* IDSEL 0x18 */ + b000 0 0 1 700 15 8 + b000 0 0 2 700 16 8 + b000 0 0 3 700 17 8 + b000 0 0 4 700 14 8>; + interrupt-parent = <700>; + interrupts = <42 8>; + bus-range = <0 0>; + ranges = <02000000 0 b0000000 b0000000 0 10000000 + 42000000 0 90000000 90000000 0 10000000 + 01000000 0 00000000 e2100000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8600 100>; + compatible = "83xx"; + device_type = "pci"; + }; + + /* May need to remove if on a part without crypto engine */ + crypto@30000 { + device_type = "crypto"; + model = "SEC2"; + compatible = "talitos"; + reg = <30000 10000>; + interrupts = <b 8>; + interrupt-parent = <700>; + num-channels = <4>; + channel-fifo-len = <18>; + exec-units-mask = <0000007e>; + /* desc mask is for rev2.0, + * we need runtime fixup for >2.0 */ + descriptor-types-mask = <01010ebf>; + }; + + /* IPIC + * interrupts cell = <intr #, sense> + * sense values match linux IORESOURCE_IRQ_* defines: + * sense == 8: Level, low assertion + * sense == 2: Edge, high-to-low change + */ + pic@700 { + linux,phandle = <700>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <700 100>; + built-in; + device_type = "ipic"; + }; + }; +}; diff --git a/arch/powerpc/configs/mpc834x_sys_defconfig b/arch/powerpc/configs/mpc834x_mds_defconfig index 5078b0441d6..5078b0441d6 100644 --- a/arch/powerpc/configs/mpc834x_sys_defconfig +++ b/arch/powerpc/configs/mpc834x_mds_defconfig diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 7e2c9fe44ac..821e152e093 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -2,6 +2,11 @@ * FPU support code, moved here from head.S so that it can be used * by chips which use other head-whatever.S files. * + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> + * Copyright (C) 1996 Paul Mackerras. + * Copyright (C) 1997 Dan Malek (dmalek@jlc.net). + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 7ee68543331..12c5971d656 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -322,7 +322,8 @@ EXPORT_SYMBOL(do_softirq); static LIST_HEAD(irq_hosts); static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED; - +static DEFINE_PER_CPU(unsigned int, irq_radix_reader); +static unsigned int irq_radix_writer; struct irq_map_entry irq_map[NR_IRQS]; static unsigned int irq_virq_count = NR_IRQS; static struct irq_host *irq_default_host; @@ -455,6 +456,58 @@ void irq_set_virq_count(unsigned int count) irq_virq_count = count; } +/* radix tree not lockless safe ! we use a brlock-type mecanism + * for now, until we can use a lockless radix tree + */ +static void irq_radix_wrlock(unsigned long *flags) +{ + unsigned int cpu, ok; + + spin_lock_irqsave(&irq_big_lock, *flags); + irq_radix_writer = 1; + smp_mb(); + do { + barrier(); + ok = 1; + for_each_possible_cpu(cpu) { + if (per_cpu(irq_radix_reader, cpu)) { + ok = 0; + break; + } + } + if (!ok) + cpu_relax(); + } while(!ok); +} + +static void irq_radix_wrunlock(unsigned long flags) +{ + smp_wmb(); + irq_radix_writer = 0; + spin_unlock_irqrestore(&irq_big_lock, flags); +} + +static void irq_radix_rdlock(unsigned long *flags) +{ + local_irq_save(*flags); + __get_cpu_var(irq_radix_reader) = 1; + smp_mb(); + if (likely(irq_radix_writer == 0)) + return; + __get_cpu_var(irq_radix_reader) = 0; + smp_wmb(); + spin_lock(&irq_big_lock); + __get_cpu_var(irq_radix_reader) = 1; + spin_unlock(&irq_big_lock); +} + +static void irq_radix_rdunlock(unsigned long flags) +{ + __get_cpu_var(irq_radix_reader) = 0; + local_irq_restore(flags); +} + + unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) { @@ -604,13 +657,9 @@ void irq_dispose_mapping(unsigned int virq) /* Check if radix tree allocated yet */ if (host->revmap_data.tree.gfp_mask == 0) break; - /* XXX radix tree not safe ! remove lock whem it becomes safe - * and use some RCU sync to make sure everything is ok before we - * can re-use that map entry - */ - spin_lock_irqsave(&irq_big_lock, flags); + irq_radix_wrlock(&flags); radix_tree_delete(&host->revmap_data.tree, hwirq); - spin_unlock_irqrestore(&irq_big_lock, flags); + irq_radix_wrunlock(flags); break; } @@ -677,25 +726,24 @@ unsigned int irq_radix_revmap(struct irq_host *host, if (tree->gfp_mask == 0) return irq_find_mapping(host, hwirq); - /* XXX Current radix trees are NOT SMP safe !!! Remove that lock - * when that is fixed (when Nick's patch gets in - */ - spin_lock_irqsave(&irq_big_lock, flags); - /* Now try to resolve */ + irq_radix_rdlock(&flags); ptr = radix_tree_lookup(tree, hwirq); + irq_radix_rdunlock(flags); + /* Found it, return */ if (ptr) { virq = ptr - irq_map; - goto bail; + return virq; } /* If not there, try to insert it */ virq = irq_find_mapping(host, hwirq); - if (virq != NO_IRQ) + if (virq != NO_IRQ) { + irq_radix_wrlock(&flags); radix_tree_insert(tree, hwirq, &irq_map[virq]); - bail: - spin_unlock_irqrestore(&irq_big_lock, flags); + irq_radix_wrunlock(flags); + } return virq; } @@ -806,12 +854,12 @@ static int irq_late_init(void) struct irq_host *h; unsigned long flags; - spin_lock_irqsave(&irq_big_lock, flags); + irq_radix_wrlock(&flags); list_for_each_entry(h, &irq_hosts, link) { if (h->revmap_type == IRQ_HOST_MAP_TREE) INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC); } - spin_unlock_irqrestore(&irq_big_lock, flags); + irq_radix_wrunlock(flags); return 0; } diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 2fce7738e9e..138134c8c17 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -1289,6 +1289,9 @@ int pci_read_irq_line(struct pci_dev *pci_dev) DBG("Try to map irq for %s...\n", pci_name(pci_dev)); +#ifdef DEBUG + memset(&oirq, 0xff, sizeof(oirq)); +#endif /* Try to get a mapping from the device-tree */ if (of_irq_map_pci(pci_dev, &oirq)) { u8 line, pin; @@ -1314,8 +1317,9 @@ int pci_read_irq_line(struct pci_dev *pci_dev) if (virq != NO_IRQ) set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); } else { - DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", - oirq.size, oirq.specifier[0], oirq.controller->full_name); + DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", + oirq.size, oirq.specifier[0], oirq.specifier[1], + oirq.controller->full_name); virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); @@ -1324,6 +1328,9 @@ int pci_read_irq_line(struct pci_dev *pci_dev) DBG(" -> failed to map !\n"); return -1; } + + DBG(" -> mapped to linux irq %d\n", virq); + pci_dev->irq = virq; pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index f6a05f090b2..39d3bfcabcd 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -126,10 +126,6 @@ EXPORT_SYMBOL(pci_bus_mem_base_phys); EXPORT_SYMBOL(pci_bus_to_hose); #endif /* CONFIG_PCI */ -#ifdef CONFIG_NOT_COHERENT_CACHE -EXPORT_SYMBOL(flush_dcache_all); -#endif - EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 462bced40c1..4394e545f9f 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -646,13 +646,13 @@ static unsigned char ibm_architecture_vec[] = { 5 - 1, /* 5 option vectors */ /* option vector 1: processor architectures supported */ - 3 - 1, /* length */ + 3 - 2, /* length */ 0, /* don't ignore, don't halt */ OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 | OV1_PPC_2_04 | OV1_PPC_2_05, /* option vector 2: Open Firmware options supported */ - 34 - 1, /* length */ + 34 - 2, /* length */ OV2_REAL_MODE, 0, 0, W(0xffffffff), /* real_base */ @@ -666,16 +666,16 @@ static unsigned char ibm_architecture_vec[] = { 48, /* max log_2(hash table size) */ /* option vector 3: processor options supported */ - 3 - 1, /* length */ + 3 - 2, /* length */ 0, /* don't ignore, don't halt */ OV3_FP | OV3_VMX, /* option vector 4: IBM PAPR implementation */ - 2 - 1, /* length */ + 2 - 2, /* length */ 0, /* don't halt */ /* option vector 5: PAPR/OF options */ - 3 - 1, /* length */ + 3 - 2, /* length */ 0, /* don't ignore, don't halt */ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, }; diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 11052c212ad..a10825a5dfe 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -639,14 +639,17 @@ void of_irq_map_init(unsigned int flags) } -int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr, - struct of_irq *out_irq) +int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize, + u32 *addr, struct of_irq *out_irq) { struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; u32 *tmp, *imap, *imask; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; + DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", + parent->full_name, intspec[0], intspec[1], ointsize); + ipar = of_node_get(parent); /* First get the #interrupt-cells property of the current cursor @@ -670,6 +673,9 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr, DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); + if (ointsize != intsize) + return -EINVAL; + /* Look for this #address-cells. We have to implement the old linux * trick of looking for the parent here as some devi |