forked from Minki/linux
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc update from Benjamin Herrenschmidt: "The main highlight is probably some base POWER8 support. There's more to come such as transactional memory support but that will wait for the next one. Overall it's pretty quiet, or rather I've been pretty poor at picking things up from patchwork and reviewing them this time around and Kumar no better on the FSL side it seems..." * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (73 commits) powerpc+of: Rename and fix OF reconfig notifier error inject module powerpc: mpc5200: Add a3m071 board support powerpc/512x: don't compile any platform DIU code if the DIU is not enabled powerpc/mpc52xx: use module_platform_driver macro powerpc+of: Export of_reconfig_notifier_[register,unregister] powerpc/dma/raidengine: add raidengine device powerpc/iommu/fsl: Add PAMU bypass enable register to ccsr_guts struct powerpc/mpc85xx: Change spin table to cached memory powerpc/fsl-pci: Add PCI controller ATMU PM support powerpc/86xx: fsl_pcibios_fixup_bus requires CONFIG_PCI drivers/virt: the Freescale hypervisor driver doesn't need to check MSR[GS] powerpc/85xx: p1022ds: Use NULL instead of 0 for pointers powerpc: Disable relocation on exceptions when kexecing powerpc: Enable relocation on during exceptions at boot powerpc: Move get_longbusy_msecs into hvcall.h and remove duplicate function powerpc: Add wrappers to enable/disable relocation on exceptions powerpc: Add set_mode hcall powerpc: Setup relocation on exceptions for bare metal systems powerpc: Move initial mfspr LPCR out of __init_LPCR powerpc: Add relocation on exception vector handlers ...
This commit is contained in:
commit
16e024f30c
81
Documentation/devicetree/bindings/powerpc/fsl/raideng.txt
Normal file
81
Documentation/devicetree/bindings/powerpc/fsl/raideng.txt
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
* Freescale 85xx RAID Engine nodes
|
||||||
|
|
||||||
|
RAID Engine nodes are defined to describe on-chip RAID accelerators. Each RAID
|
||||||
|
Engine should have a separate node.
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
P5020, P5040
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible: Should contain "fsl,raideng-v1.0" as the value
|
||||||
|
This identifies RAID Engine block. 1 in 1.0 represents
|
||||||
|
major number whereas 0 represents minor number. The
|
||||||
|
version matches the hardware IP version.
|
||||||
|
- reg: offset and length of the register set for the device
|
||||||
|
- ranges: standard ranges property specifying the translation
|
||||||
|
between child address space and parent address space
|
||||||
|
|
||||||
|
Example:
|
||||||
|
/* P5020 */
|
||||||
|
raideng: raideng@320000 {
|
||||||
|
compatible = "fsl,raideng-v1.0";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
reg = <0x320000 0x10000>;
|
||||||
|
ranges = <0 0x320000 0x10000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
There must be a sub-node for each job queue present in RAID Engine
|
||||||
|
This node must be a sub-node of the main RAID Engine node
|
||||||
|
|
||||||
|
- compatible: Should contain "fsl,raideng-v1.0-job-queue" as the value
|
||||||
|
This identifies the job queue interface
|
||||||
|
- reg: offset and length of the register set for job queue
|
||||||
|
- ranges: standard ranges property specifying the translation
|
||||||
|
between child address space and parent address space
|
||||||
|
|
||||||
|
Example:
|
||||||
|
/* P5020 */
|
||||||
|
raideng_jq0@1000 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-queue";
|
||||||
|
reg = <0x1000 0x1000>;
|
||||||
|
ranges = <0x0 0x1000 0x1000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
There must be a sub-node for each job ring present in RAID Engine
|
||||||
|
This node must be a sub-node of job queue node
|
||||||
|
|
||||||
|
- compatible: Must contain "fsl,raideng-v1.0-job-ring" as the value
|
||||||
|
This identifies job ring. Should contain either
|
||||||
|
"fsl,raideng-v1.0-hp-ring" or "fsl,raideng-v1.0-lp-ring"
|
||||||
|
depending upon whether ring has high or low priority
|
||||||
|
- reg: offset and length of the register set for job ring
|
||||||
|
- interrupts: interrupt mapping for job ring IRQ
|
||||||
|
|
||||||
|
Optional property:
|
||||||
|
|
||||||
|
- fsl,liodn: Specifies the LIODN to be used for Job Ring. This
|
||||||
|
property is normally set by firmware. Value
|
||||||
|
is of 12-bits which is the LIODN number for this JR.
|
||||||
|
This property is used by the IOMMU (PAMU) to distinquish
|
||||||
|
transactions from this JR and than be able to do address
|
||||||
|
translation & protection accordingly.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
/* P5020 */
|
||||||
|
raideng_jq0@1000 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-queue";
|
||||||
|
reg = <0x1000 0x1000>;
|
||||||
|
ranges = <0x0 0x1000 0x1000>;
|
||||||
|
|
||||||
|
raideng_jr0: jr@0 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring";
|
||||||
|
reg = <0x0 0x400>;
|
||||||
|
interrupts = <139 2 0 0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
fsl,liodn = <0x41>;
|
||||||
|
};
|
||||||
|
};
|
@ -127,6 +127,22 @@ Some examples of using the structure to:
|
|||||||
p.addr2 = (uint64_t) end_range;
|
p.addr2 = (uint64_t) end_range;
|
||||||
p.condition_value = 0;
|
p.condition_value = 0;
|
||||||
|
|
||||||
|
- set a watchpoint in server processors (BookS)
|
||||||
|
|
||||||
|
p.version = 1;
|
||||||
|
p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW;
|
||||||
|
p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
|
||||||
|
or
|
||||||
|
p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
|
||||||
|
|
||||||
|
p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
|
||||||
|
p.addr = (uint64_t) begin_range;
|
||||||
|
/* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
|
||||||
|
* addr2 - addr <= 8 Bytes.
|
||||||
|
*/
|
||||||
|
p.addr2 = (uint64_t) end_range;
|
||||||
|
p.condition_value = 0;
|
||||||
|
|
||||||
3. PTRACE_DELHWDEBUG
|
3. PTRACE_DELHWDEBUG
|
||||||
|
|
||||||
Takes an integer which identifies an existing breakpoint or watchpoint
|
Takes an integer which identifies an existing breakpoint or watchpoint
|
||||||
|
@ -240,7 +240,7 @@ static void __init update_fec_mac_prop(enum mac_oui oui)
|
|||||||
macaddr[4] = (val >> 8) & 0xff;
|
macaddr[4] = (val >> 8) & 0xff;
|
||||||
macaddr[5] = (val >> 0) & 0xff;
|
macaddr[5] = (val >> 0) & 0xff;
|
||||||
|
|
||||||
prom_update_property(np, newmac);
|
of_update_property(np, newmac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ $(BOOT_TARGETS2): vmlinux
|
|||||||
bootwrapper_install:
|
bootwrapper_install:
|
||||||
$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
|
$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
|
||||||
|
|
||||||
%.dtb:
|
%.dtb: scripts
|
||||||
$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
|
$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
|
||||||
|
|
||||||
define archhelp
|
define archhelp
|
||||||
|
144
arch/powerpc/boot/dts/a3m071.dts
Normal file
144
arch/powerpc/boot/dts/a3m071.dts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* a3m071 board Device Tree Source
|
||||||
|
*
|
||||||
|
* Copyright 2012 Stefan Roese <sr@denx.de>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 DENX Software Engineering GmbH
|
||||||
|
* Heiko Schocher <hs@denx.de>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Semihalf
|
||||||
|
* Marian Balakowicz <m8@semihalf.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/include/ "mpc5200b.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "anonymous,a3m071";
|
||||||
|
compatible = "anonymous,a3m071";
|
||||||
|
|
||||||
|
soc5200@f0000000 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "fsl,mpc5200b-immr";
|
||||||
|
ranges = <0 0xf0000000 0x0000c000>;
|
||||||
|
reg = <0xf0000000 0x00000100>;
|
||||||
|
bus-frequency = <0>; /* From boot loader */
|
||||||
|
system-frequency = <0>; /* From boot loader */
|
||||||
|
|
||||||
|
timer@600 {
|
||||||
|
fsl,has-wdt;
|
||||||
|
};
|
||||||
|
|
||||||
|
spi@f00 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
usb: usb@1000 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
psc@2000 {
|
||||||
|
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
|
||||||
|
reg = <0x2000 0x100>;
|
||||||
|
interrupts = <2 1 0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
psc@2200 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
psc@2400 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
psc@2600 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
psc@2800 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
psc@2c00 { // PSC6
|
||||||
|
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
|
||||||
|
reg = <0x2c00 0x100>;
|
||||||
|
interrupts = <2 4 0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
ethernet@3000 {
|
||||||
|
phy-handle = <&phy0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
mdio@3000 {
|
||||||
|
phy0: ethernet-phy@3 {
|
||||||
|
reg = <0x03>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ata@3a00 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c@3d00 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c@3d40 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
localbus {
|
||||||
|
compatible = "fsl,mpc5200b-lpb","simple-bus";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges = <0 0 0xfc000000 0x02000000
|
||||||
|
3 0 0xe9000000 0x00080000
|
||||||
|
5 0 0xe8000000 0x00010000>;
|
||||||
|
|
||||||
|
flash@0,0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
reg = <0 0x0 0x02000000>;
|
||||||
|
compatible = "cfi-flash";
|
||||||
|
bank-width = <2>;
|
||||||
|
partition@0x0 {
|
||||||
|
label = "u-boot";
|
||||||
|
reg = <0x00000000 0x00040000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@0x00040000 {
|
||||||
|
label = "env";
|
||||||
|
reg = <0x00040000 0x00020000>;
|
||||||
|
};
|
||||||
|
partition@0x00060000 {
|
||||||
|
label = "dtb";
|
||||||
|
reg = <0x00060000 0x00020000>;
|
||||||
|
};
|
||||||
|
partition@0x00080000 {
|
||||||
|
label = "kernel";
|
||||||
|
reg = <0x00080000 0x00500000>;
|
||||||
|
};
|
||||||
|
partition@0x00580000 {
|
||||||
|
label = "root";
|
||||||
|
reg = <0x00580000 0x00A80000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fpga@3,0 {
|
||||||
|
compatible = "anonymous,a3m071-fpga";
|
||||||
|
reg = <3 0x0 0x00080000
|
||||||
|
5 0x0 0x00010000>;
|
||||||
|
interrupts = <0 0 3>; /* level low */
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pci@f0000d00 {
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
};
|
@ -354,4 +354,5 @@
|
|||||||
/include/ "qoriq-sata2-0.dtsi"
|
/include/ "qoriq-sata2-0.dtsi"
|
||||||
/include/ "qoriq-sata2-1.dtsi"
|
/include/ "qoriq-sata2-1.dtsi"
|
||||||
/include/ "qoriq-sec4.2-0.dtsi"
|
/include/ "qoriq-sec4.2-0.dtsi"
|
||||||
|
/include/ "qoriq-raid1.0-0.dtsi"
|
||||||
};
|
};
|
||||||
|
@ -73,6 +73,12 @@
|
|||||||
rtic_c = &rtic_c;
|
rtic_c = &rtic_c;
|
||||||
rtic_d = &rtic_d;
|
rtic_d = &rtic_d;
|
||||||
sec_mon = &sec_mon;
|
sec_mon = &sec_mon;
|
||||||
|
|
||||||
|
raideng = &raideng;
|
||||||
|
raideng_jr0 = &raideng_jr0;
|
||||||
|
raideng_jr1 = &raideng_jr1;
|
||||||
|
raideng_jr2 = &raideng_jr2;
|
||||||
|
raideng_jr3 = &raideng_jr3;
|
||||||
};
|
};
|
||||||
|
|
||||||
cpus {
|
cpus {
|
||||||
|
85
arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi
Normal file
85
arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* QorIQ RAID 1.0 device tree stub [ controller @ offset 0x320000 ]
|
||||||
|
*
|
||||||
|
* Copyright 2012 Freescale Semiconductor Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Freescale Semiconductor nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ALTERNATIVELY, this software may be distributed under the terms of the
|
||||||
|
* GNU General Public License ("GPL") as published by the Free Software
|
||||||
|
* Foundation, either version 2 of that License or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
raideng: raideng@320000 {
|
||||||
|
compatible = "fsl,raideng-v1.0";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
reg = <0x320000 0x10000>;
|
||||||
|
ranges = <0 0x320000 0x10000>;
|
||||||
|
|
||||||
|
raideng_jq0@1000 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-queue";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
reg = <0x1000 0x1000>;
|
||||||
|
ranges = <0x0 0x1000 0x1000>;
|
||||||
|
|
||||||
|
raideng_jr0: jr@0 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring";
|
||||||
|
reg = <0x0 0x400>;
|
||||||
|
interrupts = <139 2 0 0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
};
|
||||||
|
|
||||||
|
raideng_jr1: jr@400 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring";
|
||||||
|
reg = <0x400 0x400>;
|
||||||
|
interrupts = <140 2 0 0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
raideng_jq1@2000 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-queue";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
reg = <0x2000 0x1000>;
|
||||||
|
ranges = <0x0 0x2000 0x1000>;
|
||||||
|
|
||||||
|
raideng_jr2: jr@0 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring";
|
||||||
|
reg = <0x0 0x400>;
|
||||||
|
interrupts = <141 2 0 0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
};
|
||||||
|
|
||||||
|
raideng_jr3: jr@400 {
|
||||||
|
compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring";
|
||||||
|
reg = <0x400 0x400>;
|
||||||
|
interrupts = <142 2 0 0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -2,7 +2,7 @@ CONFIG_PPC64=y
|
|||||||
CONFIG_ALTIVEC=y
|
CONFIG_ALTIVEC=y
|
||||||
CONFIG_VSX=y
|
CONFIG_VSX=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
CONFIG_NR_CPUS=1024
|
CONFIG_NR_CPUS=2048
|
||||||
CONFIG_EXPERIMENTAL=y
|
CONFIG_EXPERIMENTAL=y
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
@ -52,8 +52,6 @@
|
|||||||
#define smp_mb__before_clear_bit() smp_mb()
|
#define smp_mb__before_clear_bit() smp_mb()
|
||||||
#define smp_mb__after_clear_bit() smp_mb()
|
#define smp_mb__after_clear_bit() smp_mb()
|
||||||
|
|
||||||
#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
|
||||||
#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
|
|
||||||
#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
|
#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
|
||||||
|
|
||||||
/* Macro for generating the ***_bits() functions */
|
/* Macro for generating the ***_bits() functions */
|
||||||
@ -83,22 +81,22 @@ DEFINE_BITOP(change_bits, xor, "", "")
|
|||||||
|
|
||||||
static __inline__ void set_bit(int nr, volatile unsigned long *addr)
|
static __inline__ void set_bit(int nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
|
set_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
|
static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
|
clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
|
static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
clear_bits_unlock(BITOP_MASK(nr), addr + BITOP_WORD(nr));
|
clear_bits_unlock(BIT_MASK(nr), addr + BIT_WORD(nr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void change_bit(int nr, volatile unsigned long *addr)
|
static __inline__ void change_bit(int nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
|
change_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
|
/* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
|
||||||
@ -136,26 +134,26 @@ DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER,
|
|||||||
static __inline__ int test_and_set_bit(unsigned long nr,
|
static __inline__ int test_and_set_bit(unsigned long nr,
|
||||||
volatile unsigned long *addr)
|
volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
return test_and_set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
|
return test_and_set_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ int test_and_set_bit_lock(unsigned long nr,
|
static __inline__ int test_and_set_bit_lock(unsigned long nr,
|
||||||
volatile unsigned long *addr)
|
volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
return test_and_set_bits_lock(BITOP_MASK(nr),
|
return test_and_set_bits_lock(BIT_MASK(nr),
|
||||||
addr + BITOP_WORD(nr)) != 0;
|
addr + BIT_WORD(nr)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ int test_and_clear_bit(unsigned long nr,
|
static __inline__ int test_and_clear_bit(unsigned long nr,
|
||||||
volatile unsigned long *addr)
|
volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
return test_and_clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
|
return test_and_clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ int test_and_change_bit(unsigned long nr,
|
static __inline__ int test_and_change_bit(unsigned long nr,
|
||||||
volatile unsigned long *addr)
|
volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
return test_and_change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
|
return test_and_change_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <asm-generic/bitops/non-atomic.h>
|
#include <asm-generic/bitops/non-atomic.h>
|
||||||
@ -280,61 +278,8 @@ unsigned long __arch_hweight64(__u64 w);
|
|||||||
#include <asm-generic/bitops/find.h>
|
#include <asm-generic/bitops/find.h>
|
||||||
|
|
||||||
/* Little-endian versions */
|
/* Little-endian versions */
|
||||||
|
#include <asm-generic/bitops/le.h>
|
||||||
|
|
||||||
static __inline__ int test_bit_le(unsigned long nr,
|
|
||||||
__const__ void *addr)
|
|
||||||
{
|
|
||||||
__const__ unsigned char *tmp = (__const__ unsigned char *) addr;
|
|
||||||
return (tmp[nr >> 3] >> (nr & 7)) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void set_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void clear_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __set_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
__set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __clear_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
__clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int test_and_set_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
return test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int test_and_clear_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
return test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int __test_and_set_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
return __test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int __test_and_clear_bit_le(int nr, void *addr)
|
|
||||||
{
|
|
||||||
return __test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define find_first_zero_bit_le(addr, size) \
|
|
||||||
find_next_zero_bit_le((addr), (size), 0)
|
|
||||||
unsigned long find_next_zero_bit_le(const void *addr,
|
|
||||||
unsigned long size, unsigned long offset);
|
|
||||||
|
|
||||||
unsigned long find_next_bit_le(const void *addr,
|
|
||||||
unsigned long size, unsigned long offset);
|
|
||||||
/* Bitmap functions for the ext2 filesystem */
|
/* Bitmap functions for the ext2 filesystem */
|
||||||
|
|
||||||
#include <asm-generic/bitops/ext2-atomic-setbit.h>
|
#include <asm-generic/bitops/ext2-atomic-setbit.h>
|
||||||
|
@ -401,6 +401,14 @@ extern const char *powerpc_base_platform;
|
|||||||
CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
|
CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
|
||||||
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
|
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
|
||||||
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
|
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
|
||||||
|
#define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
||||||
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
|
||||||
|
CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
||||||
|
CPU_FTR_COHERENT_ICACHE | \
|
||||||
|
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
|
||||||
|
CPU_FTR_DSCR | CPU_FTR_SAO | \
|
||||||
|
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
|
||||||
|
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
|
||||||
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
|
||||||
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
||||||
@ -421,8 +429,8 @@ extern const char *powerpc_base_platform;
|
|||||||
#define CPU_FTRS_POSSIBLE \
|
#define CPU_FTRS_POSSIBLE \
|
||||||
(CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
|
(CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
|
||||||
CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
|
CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
|
||||||
CPU_FTRS_POWER7 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
|
CPU_FTRS_POWER7 | CPU_FTRS_POWER8 | CPU_FTRS_CELL | \
|
||||||
CPU_FTR_VSX)
|
CPU_FTRS_PA6T | CPU_FTR_VSX)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
enum {
|
enum {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009 Freescale Semicondutor, Inc.
|
* Copyright 2009 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -48,6 +48,35 @@
|
|||||||
#define EX_LR 72
|
#define EX_LR 72
|
||||||
#define EX_CFAR 80
|
#define EX_CFAR 80
|
||||||
|
|
||||||
|
#ifdef CONFIG_RELOCATABLE
|
||||||
|
#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
|
||||||
|
ld r12,PACAKBASE(r13); /* get high part of &label */ \
|
||||||
|
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
|
||||||
|
LOAD_HANDLER(r12,label); \
|
||||||
|
mtlr r12; \
|
||||||
|
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
|
||||||
|
li r10,MSR_RI; \
|
||||||
|
mtmsrd r10,1; /* Set RI (EE=0) */ \
|
||||||
|
blr;
|
||||||
|
#else
|
||||||
|
/* If not relocatable, we can jump directly -- and save messing with LR */
|
||||||
|
#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
|
||||||
|
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
|
||||||
|
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
|
||||||
|
li r10,MSR_RI; \
|
||||||
|
mtmsrd r10,1; /* Set RI (EE=0) */ \
|
||||||
|
b label;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As EXCEPTION_PROLOG_PSERIES(), except we've already got relocation on
|
||||||
|
* so no need to rfid. Save lr in case we're CONFIG_RELOCATABLE, in which
|
||||||
|
* case EXCEPTION_RELON_PROLOG_PSERIES_1 will be using lr.
|
||||||
|
*/
|
||||||
|
#define EXCEPTION_RELON_PROLOG_PSERIES(area, label, h, extra, vec) \
|
||||||
|
EXCEPTION_PROLOG_1(area, extra, vec); \
|
||||||
|
EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're short on space and time in the exception prolog, so we can't
|
* We're short on space and time in the exception prolog, so we can't
|
||||||
* use the normal SET_REG_IMMEDIATE macro. Normally we just need the
|
* use the normal SET_REG_IMMEDIATE macro. Normally we just need the
|
||||||
@ -55,12 +84,29 @@
|
|||||||
* word.
|
* word.
|
||||||
*/
|
*/
|
||||||
#define LOAD_HANDLER(reg, label) \
|
#define LOAD_HANDLER(reg, label) \
|
||||||
addi reg,reg,(label)-_stext; /* virt addr of handler ... */
|
/* Handlers must be within 64K of kbase, which must be 64k aligned */ \
|
||||||
|
ori reg,reg,(label)-_stext; /* virt addr of handler ... */
|
||||||
|
|
||||||
/* Exception register prefixes */
|
/* Exception register prefixes */
|
||||||
#define EXC_HV H
|
#define EXC_HV H
|
||||||
#define EXC_STD
|
#define EXC_STD
|
||||||
|
|
||||||
|
#if defined(CONFIG_RELOCATABLE)
|
||||||
|
/*
|
||||||
|
* If we support interrupts with relocation on AND we're a relocatable
|
||||||
|
* kernel, we need to use LR to get to the 2nd level handler. So, save/restore
|
||||||
|
* it when required.
|
||||||
|
*/
|
||||||
|
#define SAVE_LR(reg, area) mflr reg ; std reg,area+EX_LR(r13)
|
||||||
|
#define GET_LR(reg, area) ld reg,area+EX_LR(r13)
|
||||||
|
#define RESTORE_LR(reg, area) ld reg,area+EX_LR(r13) ; mtlr reg
|
||||||
|
#else
|
||||||
|
/* ...else LR is unused and in register. */
|
||||||
|
#define SAVE_LR(reg, area)
|
||||||
|
#define GET_LR(reg, area) mflr reg
|
||||||
|
#define RESTORE_LR(reg, area)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define __EXCEPTION_PROLOG_1(area, extra, vec) \
|
#define __EXCEPTION_PROLOG_1(area, extra, vec) \
|
||||||
GET_PACA(r13); \
|
GET_PACA(r13); \
|
||||||
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
|
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
|
||||||
@ -69,6 +115,7 @@
|
|||||||
mfspr r10,SPRN_CFAR; \
|
mfspr r10,SPRN_CFAR; \
|
||||||
std r10,area+EX_CFAR(r13); \
|
std r10,area+EX_CFAR(r13); \
|
||||||
END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
|
END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
|
||||||
|
SAVE_LR(r10, area); \
|
||||||
mfcr r9; \
|
mfcr r9; \
|
||||||
extra(vec); \
|
extra(vec); \
|
||||||
std r11,area+EX_R11(r13); \
|
std r11,area+EX_R11(r13); \
|
||||||
@ -169,6 +216,7 @@ do_kvm_##n: \
|
|||||||
sth r1,PACA_TRAP_SAVE(r13); \
|
sth r1,PACA_TRAP_SAVE(r13); \
|
||||||
std r3,area+EX_R3(r13); \
|
std r3,area+EX_R3(r13); \
|
||||||
addi r3,r13,area; /* r3 -> where regs are saved*/ \
|
addi r3,r13,area; /* r3 -> where regs are saved*/ \
|
||||||
|
RESTORE_LR(r1, area); \
|
||||||
b bad_stack; \
|
b bad_stack; \
|
||||||
3: std r9,_CCR(r1); /* save CR in stackframe */ \
|
3: std r9,_CCR(r1); /* save CR in stackframe */ \
|
||||||
std r11,_NIP(r1); /* save SRR0 in stackframe */ \
|
std r11,_NIP(r1); /* save SRR0 in stackframe */ \
|
||||||
@ -194,8 +242,8 @@ do_kvm_##n: \
|
|||||||
ld r10,area+EX_CFAR(r13); \
|
ld r10,area+EX_CFAR(r13); \
|
||||||
std r10,ORIG_GPR3(r1); \
|
std r10,ORIG_GPR3(r1); \
|
||||||
END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
|
END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
|
||||||
|
GET_LR(r9,area); /* Get LR, later save to stack */ \
|
||||||
ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
|
ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
|
||||||
mflr r9; /* save LR in stackframe */ \
|
|
||||||
std r9,_LINK(r1); \
|
std r9,_LINK(r1); \
|
||||||
mfctr r10; /* save CTR in stackframe */ \
|
mfctr r10; /* save CTR in stackframe */ \
|
||||||
std r10,_CTR(r1); \
|
std r10,_CTR(r1); \
|
||||||
@ -232,6 +280,26 @@ label##_hv: \
|
|||||||
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
|
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
|
||||||
EXC_HV, KVMTEST, vec)
|
EXC_HV, KVMTEST, vec)
|
||||||
|
|
||||||
|
#define STD_RELON_EXCEPTION_PSERIES(loc, vec, label) \
|
||||||
|
. = loc; \
|
||||||
|
.globl label##_relon_pSeries; \
|
||||||
|
label##_relon_pSeries: \
|
||||||
|
HMT_MEDIUM; \
|
||||||
|
/* No guest interrupts come through here */ \
|
||||||
|
SET_SCRATCH0(r13); /* save r13 */ \
|
||||||
|
EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
|
||||||
|
EXC_STD, KVMTEST_PR, vec)
|
||||||
|
|
||||||
|
#define STD_RELON_EXCEPTION_HV(loc, vec, label) \
|
||||||
|
. = loc; \
|
||||||
|
.globl label##_relon_hv; \
|
||||||
|
label##_relon_hv: \
|
||||||
|
HMT_MEDIUM; \
|
||||||
|
/* No guest interrupts come through here */ \
|
||||||
|
SET_SCRATCH0(r13); /* save r13 */ \
|
||||||
|
EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
|
||||||
|
EXC_HV, KVMTEST, vec)
|
||||||
|
|
||||||
/* This associate vector numbers with bits in paca->irq_happened */
|
/* This associate vector numbers with bits in paca->irq_happened */
|
||||||
#define SOFTEN_VALUE_0x500 PACA_IRQ_EE
|
#define SOFTEN_VALUE_0x500 PACA_IRQ_EE
|
||||||
#define SOFTEN_VALUE_0x502 PACA_IRQ_EE
|
#define SOFTEN_VALUE_0x502 PACA_IRQ_EE
|
||||||
@ -257,6 +325,9 @@ label##_hv: \
|
|||||||
KVMTEST(vec); \
|
KVMTEST(vec); \
|
||||||
_SOFTEN_TEST(EXC_STD, vec)
|
_SOFTEN_TEST(EXC_STD, vec)
|
||||||
|
|
||||||
|
#define SOFTEN_NOTEST_PR(vec) _SOFTEN_TEST(EXC_STD, vec)
|
||||||
|
#define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec)
|
||||||
|
|
||||||
#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
|
#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
|
||||||
HMT_MEDIUM; \
|
HMT_MEDIUM; \
|
||||||
SET_SCRATCH0(r13); /* save r13 */ \
|
SET_SCRATCH0(r13); /* save r13 */ \
|
||||||
@ -279,6 +350,28 @@ label##_hv: \
|
|||||||
_MASKABLE_EXCEPTION_PSERIES(vec, label, \
|
_MASKABLE_EXCEPTION_PSERIES(vec, label, \
|
||||||
EXC_HV, SOFTEN_TEST_HV)
|
EXC_HV, SOFTEN_TEST_HV)
|
||||||
|
|
||||||
|
#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
|
||||||
|
HMT_MEDIUM; \
|
||||||
|
SET_SCRATCH0(r13); /* save r13 */ \
|
||||||
|
__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
|
||||||
|
EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, h);
|
||||||
|
#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
|
||||||
|
__MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra)
|
||||||
|
|
||||||
|
#define MASKABLE_RELON_EXCEPTION_PSERIES(loc, vec, label) \
|
||||||
|
. = loc; \
|
||||||
|
.globl label##_relon_pSeries; \
|
||||||
|
label##_relon_pSeries: \
|
||||||
|
_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
|
||||||
|
EXC_STD, SOFTEN_NOTEST_PR)
|
||||||
|
|
||||||
|
#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label) \
|
||||||
|
. = loc; \
|
||||||
|
.globl label##_relon_hv; \
|
||||||
|
label##_relon_hv: \
|
||||||
|
_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
|
||||||
|
EXC_HV, SOFTEN_NOTEST_HV)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our exception common code can be passed various "additions"
|
* Our exception common code can be passed various "additions"
|
||||||
* to specify the behaviour of interrupts, whether to kick the
|
* to specify the behaviour of interrupts, whether to kick the
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000)
|
#define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000)
|
||||||
#define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000)
|
#define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000)
|
||||||
#define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000)
|
#define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000)
|
||||||
|
#define FW_FEATURE_SET_MODE ASM_CONST(0x0000000040000000)
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ enum {
|
|||||||
FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
|
FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
|
||||||
FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
|
FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
|
||||||
FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
|
FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
|
||||||
FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO,
|
FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO |
|
||||||
|
FW_FEATURE_SET_MODE,
|
||||||
FW_FEATURE_PSERIES_ALWAYS = 0,
|
FW_FEATURE_PSERIES_ALWAYS = 0,
|
||||||
FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2,
|
FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2,
|
||||||
FW_FEATURE_POWERNV_ALWAYS = 0,
|
FW_FEATURE_POWERNV_ALWAYS = 0,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Freescale General-purpose Timers Module
|
* Freescale General-purpose Timers Module
|
||||||
*
|
*
|
||||||
* Copyright (c) Freescale Semicondutor, Inc. 2006.
|
* Copyright 2006 Freescale Semiconductor, Inc.
|
||||||
* Shlomi Gridish <gridish@freescale.com>
|
* Shlomi Gridish <gridish@freescale.com>
|
||||||
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
||||||
* Copyright (c) MontaVista Software, Inc. 2008.
|
* Copyright (c) MontaVista Software, Inc. 2008.
|
||||||
|
@ -71,7 +71,9 @@ struct ccsr_guts {
|
|||||||
u8 res0c4[0x224 - 0xc4];
|
u8 res0c4[0x224 - 0xc4];
|
||||||
__be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
|
__be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
|
||||||
__be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
|
__be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
|
||||||
u8 res22c[0x800 - 0x22c];
|
u8 res22c[0x604 - 0x22c];
|
||||||
|
__be32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
|
||||||
|
u8 res608[0x800 - 0x608];
|
||||||
__be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
|
__be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
|
||||||
u8 res804[0x900 - 0x804];
|
u8 res804[0x900 - 0x804];
|
||||||
__be32 ircr; /* 0x.0900 - Infrared Control Register */
|
__be32 ircr; /* 0x.0900 - Infrared Control Register */
|
||||||
|
@ -267,7 +267,8 @@
|
|||||||
#define H_RANDOM 0x300
|
#define H_RANDOM 0x300
|
||||||
#define H_COP 0x304
|
#define H_COP 0x304
|
||||||
#define H_GET_MPP_X 0x314
|
#define H_GET_MPP_X 0x314
|
||||||
#define MAX_HCALL_OPCODE H_GET_MPP_X
|
#define H_SET_MODE 0x31C
|
||||||
|
#define MAX_HCALL_OPCODE H_SET_MODE
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
@ -355,6 +356,26 @@ struct hvcall_mpp_x_data {
|
|||||||
|
|
||||||
int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data);
|
int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data);
|
||||||
|
|
||||||
|
static inline unsigned int get_longbusy_msecs(int longbusy_rc)
|
||||||
|
{
|
||||||
|
switch (longbusy_rc) {
|
||||||
|
case H_LONG_BUSY_ORDER_1_MSEC:
|
||||||
|
return 1;
|
||||||
|
case H_LONG_BUSY_ORDER_10_MSEC:
|
||||||
|
return 10;
|
||||||
|
case H_LONG_BUSY_ORDER_100_MSEC:
|
||||||
|
return 100;
|
||||||
|
case H_LONG_BUSY_ORDER_1_SEC:
|
||||||
|
return 1000;
|
||||||
|
case H_LONG_BUSY_ORDER_10_SEC:
|
||||||
|
return 10000;
|
||||||
|
case H_LONG_BUSY_ORDER_100_SEC:
|
||||||
|
return 100000;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
#ifdef CONFIG_PPC_PSERIES
|
||||||
extern int CMO_PrPSP;
|
extern int CMO_PrPSP;
|
||||||
extern int CMO_SecPSP;
|
extern int CMO_SecPSP;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* The Internal Memory Map for devices with QE on them. This
|
* The Internal Memory Map for devices with QE on them. This
|
||||||
* is the superset of all QE devices (8360, etc.).
|
* is the superset of all QE devices (8360, etc.).
|
||||||
|
|
||||||
* Copyright (C) 2006. Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006. Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -166,9 +166,6 @@ struct machdep_calls {
|
|||||||
unsigned long size,
|
unsigned long size,
|
||||||
pgprot_t vma_prot);
|
pgprot_t vma_prot);
|
||||||
|
|
||||||
/* Idle loop for this platform, leave empty for default idle loop */
|
|
||||||
void (*idle_loop)(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function for waiting for work with reduced power in idle loop;
|
* Function for waiting for work with reduced power in idle loop;
|
||||||
* called with interrupts disabled.
|
* called with interrupts disabled.
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
#define MMU_FTRS_POWER5 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
|
#define MMU_FTRS_POWER5 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
|
||||||
#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
|
#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
|
||||||
#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
|
#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
|
||||||
|
#define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
|
||||||
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
|
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
|
||||||
MMU_FTR_CI_LARGE_PAGE
|
MMU_FTR_CI_LARGE_PAGE
|
||||||
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
|
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
#ifndef _PPC64_PSERIES_RECONFIG_H
|
|
||||||
#define _PPC64_PSERIES_RECONFIG_H
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
|
|
||||||
#include <linux/notifier.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use this API if your code needs to know about OF device nodes being
|
|
||||||
* added or removed on pSeries systems.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PSERIES_RECONFIG_ADD 0x0001
|
|
||||||
#define PSERIES_RECONFIG_REMOVE 0x0002
|
|
||||||
#define PSERIES_DRCONF_MEM_ADD 0x0003
|
|
||||||
#define PSERIES_DRCONF_MEM_REMOVE 0x0004
|
|
||||||
#define PSERIES_UPDATE_PROPERTY 0x0005
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pSeries_reconfig_notify - Notifier value structure for OFDT property updates
|
|
||||||
*
|
|
||||||
* @node: Device tree node which owns the property being updated
|
|
||||||
* @property: Updated property
|
|
||||||
*/
|
|
||||||
struct pSeries_reconfig_prop_update {
|
|
||||||
struct device_node *node;
|
|
||||||
struct property *property;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
|
||||||
extern int pSeries_reconfig_notifier_register(struct notifier_block *);
|
|
||||||
extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
|
|
||||||
extern int pSeries_reconfig_notify(unsigned long action, void *p);
|
|
||||||
/* Not the best place to put this, will be fixed when we move some
|
|
||||||
* of the rtas suspend-me stuff to pseries */
|
|
||||||
extern void pSeries_coalesce_init(void);
|
|
||||||
#else /* !CONFIG_PPC_PSERIES */
|
|
||||||
static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { }
|
|
||||||
static inline void pSeries_coalesce_init(void) { }
|
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
#endif /* _PPC64_PSERIES_RECONFIG_H */
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009 Freescale Semicondutor, Inc.
|
* Copyright 2009 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -86,6 +86,7 @@
|
|||||||
#define PPC_INST_DCBA_MASK 0xfc0007fe
|
#define PPC_INST_DCBA_MASK 0xfc0007fe
|
||||||
#define PPC_INST_DCBAL 0x7c2005ec
|
#define PPC_INST_DCBAL 0x7c2005ec
|
||||||
#define PPC_INST_DCBZL 0x7c2007ec
|
#define PPC_INST_DCBZL 0x7c2007ec
|
||||||
|
#define PPC_INST_ICBT 0x7c00002c
|
||||||
#define PPC_INST_ISEL 0x7c00001e
|
#define PPC_INST_ISEL 0x7c00001e
|
||||||
#define PPC_INST_ISEL_MASK 0xfc00003e
|
#define PPC_INST_ISEL_MASK 0xfc00003e
|
||||||
#define PPC_INST_LDARX 0x7c0000a8
|
#define PPC_INST_LDARX 0x7c0000a8
|
||||||
@ -201,6 +202,7 @@
|
|||||||
#define __PPC_MB(s) (((s) & 0x1f) << 6)
|
#define __PPC_MB(s) (((s) & 0x1f) << 6)
|
||||||
#define __PPC_ME(s) (((s) & 0x1f) << 1)
|
#define __PPC_ME(s) (((s) & 0x1f) << 1)
|
||||||
#define __PPC_BI(s) (((s) & 0x1f) << 16)
|
#define __PPC_BI(s) (((s) & 0x1f) << 16)
|
||||||
|
#define __PPC_CT(t) (((t) & 0x0f) << 21)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
|
* Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
|
||||||
@ -263,6 +265,8 @@
|
|||||||
__PPC_RS(t) | __PPC_RA0(a) | __PPC_RB(b))
|
__PPC_RS(t) | __PPC_RA0(a) | __PPC_RB(b))
|
||||||
#define PPC_SLBFEE_DOT(t, b) stringify_in_c(.long PPC_INST_SLBFEE | \
|
#define PPC_SLBFEE_DOT(t, b) stringify_in_c(.long PPC_INST_SLBFEE | \
|
||||||
__PPC_RT(t) | __PPC_RB(b))
|
__PPC_RT(t) | __PPC_RB(b))
|
||||||
|
#define PPC_ICBT(c,a,b) stringify_in_c(.long PPC_INST_ICBT | \
|
||||||
|
__PPC_CT(c) | __PPC_RA0(a) | __PPC_RB(b))
|
||||||
/* PASemi instructions */
|
/* PASemi instructions */
|
||||||
#define LBZCIX(t,a,b) stringify_in_c(.long PPC_INST_LBZCIX | \
|
#define LBZCIX(t,a,b) stringify_in_c(.long PPC_INST_LBZCIX | \
|
||||||
__PPC_RT(t) | __PPC_RA(a) | __PPC_RB(b))
|
__PPC_RT(t) | __PPC_RA(a) | __PPC_RB(b))
|
||||||
|
@ -58,6 +58,22 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
|
|||||||
|
|
||||||
extern void of_instantiate_rtc(void);
|
extern void of_instantiate_rtc(void);
|
||||||
|
|
||||||
|
/* The of_drconf_cell struct defines the layout of the LMB array
|
||||||
|
* specified in the device tree property
|
||||||
|
* ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory
|
||||||
|
*/
|
||||||
|
struct of_drconf_cell {
|
||||||
|
u64 base_addr;
|
||||||
|
u32 drc_index;
|
||||||
|
u32 reserved;
|
||||||
|
u32 aa_index;
|
||||||
|
u32 flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DRCONF_MEM_ASSIGNED 0x00000008
|
||||||
|
#define DRCONF_MEM_AI_INVALID 0x00000040
|
||||||
|
#define DRCONF_MEM_RESERVED 0x00000080
|
||||||
|
|
||||||
/* These includes are put at the bottom because they may contain things
|
/* These includes are put at the bottom because they may contain things
|
||||||
* that are overridden by this file. Ideally they shouldn't be included
|
* that are overridden by this file. Ideally they shouldn't be included
|
||||||
* by this file, but there are a bunch of .c files that currently depend
|
* by this file, but there are a bunch of .c files that currently depend
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -249,6 +249,8 @@
|
|||||||
#define LPCR_RMLS 0x1C000000 /* impl dependent rmo limit sel */
|
#define LPCR_RMLS 0x1C000000 /* impl dependent rmo limit sel */
|
||||||
#define LPCR_RMLS_SH (63-37)
|
#define LPCR_RMLS_SH (63-37)
|
||||||
#define LPCR_ILE 0x02000000 /* !HV irqs set MSR:LE */
|
#define LPCR_ILE 0x02000000 /* !HV irqs set MSR:LE */
|
||||||
|
#define LPCR_AIL_0 0x00000000 /* MMU off exception offset 0x0 */
|
||||||
|
#define LPCR_AIL_3 0x01800000 /* MMU on exception offset 0xc00...4xxx */
|
||||||
#define LPCR_PECE 0x00007000 /* powersave exit cause enable */
|
#define LPCR_PECE 0x00007000 /* powersave exit cause enable */
|
||||||
#define LPCR_PECE0 0x00004000 /* ext. exceptions can cause exit */
|
#define LPCR_PECE0 0x00004000 /* ext. exceptions can cause exit */
|
||||||
#define LPCR_PECE1 0x00002000 /* decrementer can cause exit */
|
#define LPCR_PECE1 0x00002000 /* decrementer can cause exit */
|
||||||
@ -1030,6 +1032,7 @@
|
|||||||
#define PVR_970MP 0x0044
|
#define PVR_970MP 0x0044
|
||||||
#define PVR_970GX 0x0045
|
#define PVR_970GX 0x0045
|
||||||
#define PVR_POWER7p 0x004A
|
#define PVR_POWER7p 0x004A
|
||||||
|
#define PVR_POWER8 0x004B
|
||||||
#define PVR_BE 0x0070
|
#define PVR_BE 0x0070
|
||||||
#define PVR_PA6T 0x0090
|
#define PVR_PA6T 0x0090
|
||||||
|
|
||||||
|
@ -353,8 +353,13 @@ static inline int page_is_rtas_user_buf(unsigned long pfn)
|
|||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Not the best place to put pSeries_coalesce_init, will be fixed when we
|
||||||
|
* move some of the rtas suspend-me stuff to pseries */
|
||||||
|
extern void pSeries_coalesce_init(void);
|
||||||
#else
|
#else
|
||||||
static inline int page_is_rtas_user_buf(unsigned long pfn) { return 0;}
|
static inline int page_is_rtas_user_buf(unsigned long pfn) { return 0;}
|
||||||
|
static inline void pSeries_coalesce_init(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int call_rtas(const char *, int, int, unsigned long *, ...);
|
extern int call_rtas(const char *, int, int, unsigned long *, ...);
|
||||||
|
29
arch/powerpc/include/asm/setup.h
Normal file
29
arch/powerpc/include/asm/setup.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef _ASM_POWERPC_SETUP_H
|
||||||
|
#define _ASM_POWERPC_SETUP_H
|
||||||
|
|
||||||
|
#include <uapi/asm/setup.h>
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
extern void ppc_printk_progress(char *s, unsigned short hex);
|
||||||
|
|
||||||
|
extern unsigned int rtas_data;
|
||||||
|
extern int mem_init_done; /* set on boot once kmalloc can be called */
|
||||||
|
extern int init_bootmem_done; /* set once bootmem is available */
|
||||||
|
extern unsigned long long memory_limit;
|
||||||
|
extern unsigned long klimit;
|
||||||
|
extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
|
||||||
|
|
||||||
|
struct device_node;
|
||||||
|
extern void note_scsi_host(struct device_node *, void *);
|
||||||
|
|
||||||
|
/* Used in very early kernel initialization. */
|
||||||
|
extern unsigned long reloc_offset(void);
|
||||||
|
extern unsigned long add_reloc_offset(unsigned long);
|
||||||
|
extern void reloc_got2(unsigned long);
|
||||||
|
|
||||||
|
#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
|
||||||
|
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _ASM_POWERPC_SETUP_H */
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Internal header file for UCC FAST unit routines.
|
* Internal header file for UCC FAST unit routines.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -21,7 +21,6 @@ extern int (*udbg_getc_poll)(void);
|
|||||||
|
|
||||||
extern void udbg_puts(const char *s);
|
extern void udbg_puts(const char *s);
|
||||||
extern int udbg_write(const char *s, int n);
|
extern int udbg_write(const char *s, int n);
|
||||||
extern int udbg_read(char *buf, int buflen);
|
|
||||||
|
|
||||||
extern void register_early_udbg_console(void);
|
extern void register_early_udbg_console(void);
|
||||||
extern void udbg_printf(const char *fmt, ...)
|
extern void udbg_printf(const char *fmt, ...)
|
||||||
|
@ -1,32 +1 @@
|
|||||||
#ifndef _ASM_POWERPC_SETUP_H
|
|
||||||
#define _ASM_POWERPC_SETUP_H
|
|
||||||
|
|
||||||
#include <asm-generic/setup.h>
|
#include <asm-generic/setup.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
extern void ppc_printk_progress(char *s, unsigned short hex);
|
|
||||||
|
|
||||||
extern unsigned int rtas_data;
|
|
||||||
extern int mem_init_done; /* set on boot once kmalloc can be called */
|
|
||||||
extern int init_bootmem_done; /* set once bootmem is available */
|
|
||||||
extern unsigned long long memory_limit;
|
|
||||||
extern unsigned long klimit;
|
|
||||||
extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
|
|
||||||
|
|
||||||
extern void via_cuda_init(void);
|
|
||||||
extern void read_rtc_time(void);
|
|
||||||
extern void pmac_find_display(void);
|
|
||||||
|
|
||||||
struct device_node;
|
|
||||||
extern void note_scsi_host(struct device_node *, void *);
|
|
||||||
|
|
||||||
/* Used in very early kernel initialization. */
|
|
||||||
extern unsigned long reloc_offset(void);
|
|
||||||
extern unsigned long add_reloc_offset(unsigned long);
|
|
||||||
extern void reloc_got2(unsigned long);
|
|
||||||
|
|
||||||
#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_SETUP_H */
|
|
||||||
|
@ -38,7 +38,7 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
|
|||||||
paca.o nvram_64.o firmware.o
|
paca.o nvram_64.o firmware.o
|
||||||
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
||||||
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
|
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
|
||||||
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power7.o
|
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o
|
||||||
obj64-$(CONFIG_RELOCATABLE) += reloc_64.o
|
obj64-$(CONFIG_RELOCATABLE) += reloc_64.o
|
||||||
obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o
|
obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o
|
||||||
obj-$(CONFIG_PPC_A2) += cpu_setup_a2.o
|
obj-$(CONFIG_PPC_A2) += cpu_setup_a2.o
|
||||||
|
@ -27,6 +27,7 @@ _GLOBAL(__setup_cpu_power7)
|
|||||||
beqlr
|
beqlr
|
||||||
li r0,0
|
li r0,0
|
||||||
mtspr SPRN_LPID,r0
|
mtspr SPRN_LPID,r0
|
||||||
|
mfspr r3,SPRN_LPCR
|
||||||
bl __init_LPCR
|
bl __init_LPCR
|
||||||
bl __init_TLB
|
bl __init_TLB
|
||||||
mtlr r11
|
mtlr r11
|
||||||
@ -39,6 +40,35 @@ _GLOBAL(__restore_cpu_power7)
|
|||||||
beqlr
|
beqlr
|
||||||
li r0,0
|
li r0,0
|
||||||
mtspr SPRN_LPID,r0
|
mtspr SPRN_LPID,r0
|
||||||
|
mfspr r3,SPRN_LPCR
|
||||||
|
bl __init_LPCR
|
||||||
|
bl __init_TLB
|
||||||
|
mtlr r11
|
||||||
|
blr
|
||||||
|
|
||||||
|
_GLOBAL(__setup_cpu_power8)
|
||||||
|
mflr r11
|
||||||
|
bl __init_hvmode_206
|
||||||
|
mtlr r11
|
||||||
|
beqlr
|
||||||
|
li r0,0
|
||||||
|
mtspr SPRN_LPID,r0
|
||||||
|
mfspr r3,SPRN_LPCR
|
||||||
|
oris r3, r3, LPCR_AIL_3@h
|
||||||
|
bl __init_LPCR
|
||||||
|
bl __init_TLB
|
||||||
|
mtlr r11
|
||||||
|
blr
|
||||||
|
|
||||||
|
_GLOBAL(__restore_cpu_power8)
|
||||||
|
mflr r11
|
||||||
|
mfmsr r3
|
||||||
|
rldicl. r0,r3,4,63
|
||||||
|
beqlr
|
||||||
|
li r0,0
|
||||||
|
mtspr SPRN_LPID,r0
|
||||||
|
mfspr r3,SPRN_LPCR
|
||||||
|
oris r3, r3, LPCR_AIL_3@h
|
||||||
bl __init_LPCR
|
bl __init_LPCR
|
||||||
bl __init_TLB
|
bl __init_TLB
|
||||||
mtlr r11
|
mtlr r11
|
||||||
@ -57,6 +87,7 @@ __init_hvmode_206:
|
|||||||
|
|
||||||
__init_LPCR:
|
__init_LPCR:
|
||||||
/* Setup a sane LPCR:
|
/* Setup a sane LPCR:
|
||||||
|
* Called with initial LPCR in R3
|
||||||
*
|
*
|
||||||
* LPES = 0b01 (HSRR0/1 used for 0x500)
|
* LPES = 0b01 (HSRR0/1 used for 0x500)
|
||||||
* PECE = 0b111
|
* PECE = 0b111
|
||||||
@ -67,7 +98,6 @@ __init_LPCR:
|
|||||||
*
|
*
|
||||||
* Other bits untouched for now
|
* Other bits untouched for now
|
||||||
*/
|
*/
|
||||||
mfspr r3,SPRN_LPCR
|
|
||||||
li r5,1
|
li r5,1
|
||||||
rldimi r3,r5, LPCR_LPES_SH, 64-LPCR_LPES_SH-2
|
rldimi r3,r5, LPCR_LPES_SH, 64-LPCR_LPES_SH-2
|
||||||
ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
|
ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
|
@ -68,6 +68,8 @@ extern void __restore_cpu_pa6t(void);
|
|||||||
extern void __restore_cpu_ppc970(void);
|
extern void __restore_cpu_ppc970(void);
|
||||||
extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
|
extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
|
||||||
extern void __restore_cpu_power7(void);
|
extern void __restore_cpu_power7(void);
|
||||||
|
extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec);
|
||||||
|
extern void __restore_cpu_power8(void);
|
||||||
extern void __restore_cpu_a2(void);
|
extern void __restore_cpu_a2(void);
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
#if defined(CONFIG_E500)
|
#if defined(CONFIG_E500)
|
||||||
@ -94,6 +96,10 @@ extern void __restore_cpu_e5500(void);
|
|||||||
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
|
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
|
||||||
PPC_FEATURE_TRUE_LE | \
|
PPC_FEATURE_TRUE_LE | \
|
||||||
PPC_FEATURE_PSERIES_PERFMON_COMPAT)
|
PPC_FEATURE_PSERIES_PERFMON_COMPAT)
|
||||||
|
#define COMMON_USER_POWER8 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_06 |\
|
||||||
|
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
|
||||||
|
PPC_FEATURE_TRUE_LE | \
|
||||||
|
PPC_FEATURE_PSERIES_PERFMON_COMPAT)
|
||||||
#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
|
#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
|
||||||
PPC_FEATURE_TRUE_LE | \
|
PPC_FEATURE_TRUE_LE | \
|
||||||
PPC_FEATURE_HAS_ALTIVEC_COMP)
|
PPC_FEATURE_HAS_ALTIVEC_COMP)
|
||||||
@ -429,6 +435,21 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
|||||||
.cpu_restore = __restore_cpu_power7,
|
.cpu_restore = __restore_cpu_power7,
|
||||||
.platform = "power7",
|
.platform = "power7",
|
||||||
},
|
},
|
||||||
|
{ /* 2.07-compliant processor, i.e. Power8 "architected" mode */
|
||||||
|
.pvr_mask = 0xffffffff,
|
||||||
|
.pvr_value = 0x0f000004,
|
||||||
|
.cpu_name = "POWER8 (architected)",
|
||||||
|
.cpu_features = CPU_FTRS_POWER8,
|
||||||
|
.cpu_user_features = COMMON_USER_POWER8,
|
||||||
|
.mmu_features = MMU_FTRS_POWER8,
|
||||||
|
.icache_bsize = 128,
|
||||||
|
.dcache_bsize = 128,
|
||||||
|
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||||
|
.oprofile_cpu_type = "ppc64/ibm-compat-v1",
|
||||||
|
.cpu_setup = __setup_cpu_power8,
|
||||||
|
.cpu_restore = __restore_cpu_power8,
|
||||||
|
.platform = "power8",
|
||||||
|
},
|
||||||
{ /* Power7 */
|
{ /* Power7 */
|
||||||
.pvr_mask = 0xffff0000,
|
.pvr_mask = 0xffff0000,
|
||||||
.pvr_value = 0x003f0000,
|
.pvr_value = 0x003f0000,
|
||||||
@ -463,6 +484,23 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
|||||||
.cpu_restore = __restore_cpu_power7,
|
.cpu_restore = __restore_cpu_power7,
|
||||||
.platform = "power7+",
|
.platform = "power7+",
|
||||||
},
|
},
|
||||||
|
{ /* Power8 */
|
||||||
|
.pvr_mask = 0xffff0000,
|
||||||
|
.pvr_value = 0x004b0000,
|
||||||
|
.cpu_name = "POWER8 (raw)",
|
||||||
|
.cpu_features = CPU_FTRS_POWER8,
|
||||||
|
.cpu_user_features = COMMON_USER_POWER8,
|
||||||
|
.mmu_features = MMU_FTRS_POWER8,
|
||||||
|
.icache_bsize = 128,
|
||||||
|
.dcache_bsize = 128,
|
||||||
|
.num_pmcs = 6,
|
||||||
|
.pmc_type = PPC_PMC_IBM,
|
||||||
|
.oprofile_cpu_type = "ppc64/power8",
|
||||||
|
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||||
|
.cpu_setup = __setup_cpu_power8,
|
||||||
|
.cpu_restore = __restore_cpu_power8,
|
||||||
|
.platform = "power8",
|
||||||
|
},
|
||||||
{ /* Cell Broadband Engine */
|
{ /* Cell Broadband Engine */
|
||||||
.pvr_mask = 0xffff0000,
|
.pvr_mask = 0xffff0000,
|
||||||
.pvr_value = 0x00700000,
|
.pvr_value = 0x00700000,
|
||||||
|
@ -373,6 +373,8 @@ _GLOBAL(ret_from_fork)
|
|||||||
_GLOBAL(ret_from_kernel_thread)
|
_GLOBAL(ret_from_kernel_thread)
|
||||||
bl .schedule_tail
|
bl .schedule_tail
|
||||||
REST_NVGPRS(r1)
|
REST_NVGPRS(r1)
|
||||||
|
li r3,0
|
||||||
|
std r3,0(r1)
|
||||||
ld r14, 0(r14)
|
ld r14, 0(r14)
|
||||||
mtlr r14
|
mtlr r14
|
||||||
mr r3,r15
|
mr r3,r15
|
||||||
|
@ -19,12 +19,76 @@
|
|||||||
/*
|
/*
|
||||||
* We layout physical memory as follows:
|
* We layout physical memory as follows:
|
||||||
* 0x0000 - 0x00ff : Secondary processor spin code
|
* 0x0000 - 0x00ff : Secondary processor spin code
|
||||||
* 0x0100 - 0x2fff : pSeries Interrupt prologs
|
* 0x0100 - 0x17ff : pSeries Interrupt prologs
|
||||||
* 0x3000 - 0x5fff : interrupt support common interrupt prologs
|
* 0x1800 - 0x4000 : interrupt support common interrupt prologs
|
||||||
* 0x6000 - 0x6fff : Initial (CPU0) segment table
|
* 0x4000 - 0x5fff : pSeries interrupts with IR=1,DR=1
|
||||||
|
* 0x6000 - 0x6fff : more interrupt support including for IR=1,DR=1
|
||||||
* 0x7000 - 0x7fff : FWNMI data area
|
* 0x7000 - 0x7fff : FWNMI data area
|
||||||
* 0x8000 - : Early init and support code
|
* 0x8000 - 0x8fff : Initial (CPU0) segment table
|
||||||
|
* 0x9000 - : Early init and support code
|
||||||
*/
|
*/
|
||||||
|
/* Syscall routine is used twice, in reloc-off and reloc-on paths */
|
||||||
|
#define SYSCALL_PSERIES_1 \
|
||||||
|
BEGIN_FTR_SECTION \
|
||||||
|
cmpdi r0,0x1ebe ; \
|
||||||
|
beq- 1f ; \
|
||||||
|
END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
|
||||||
|
mr r9,r13 ; \
|
||||||
|
GET_PACA(r13) ; \
|
||||||
|
mfspr r11,SPRN_SRR0 ; \
|
||||||
|
0:
|
||||||
|
|
||||||
|
#define SYSCALL_PSERIES_2_RFID \
|
||||||
|
mfspr r12,SPRN_SRR1 ; \
|
||||||
|
ld r10,PACAKBASE(r13) ; \
|
||||||
|
LOAD_HANDLER(r10, system_call_entry) ; \
|
||||||
|
mtspr SPRN_SRR0,r10 ; \
|
||||||
|
ld r10,PACAKMSR(r13) ; \
|
||||||
|
mtspr SPRN_SRR1,r10 ; \
|
||||||
|
rfid ; \
|
||||||
|
b . ; /* prevent speculative execution */
|
||||||
|
|
||||||
|
#define SYSCALL_PSERIES_3 \
|
||||||
|
/* Fast LE/BE switch system call */ \
|
||||||
|
1: mfspr r12,SPRN_SRR1 ; \
|
||||||
|
xori r12,r12,MSR_LE ; \
|
||||||
|
mtspr SPRN_SRR1,r12 ; \
|
||||||
|
rfid ; /* return to userspace */ \
|
||||||
|
b . ; \
|
||||||
|
2: mfspr r12,SPRN_SRR1 ; \
|
||||||
|
andi. r12,r12,MSR_PR ; \
|
||||||
|
bne 0b ; \
|
||||||
|
mtspr SPRN_SRR0,r3 ; \
|
||||||
|
mtspr SPRN_SRR1,r4 ; \
|
||||||
|
mtspr SPRN_SDR1,r5 ; \
|
||||||
|
rfid ; \
|
||||||
|
b . ; /* prevent speculative execution */
|
||||||
|
|
||||||
|
#if defined(CONFIG_RELOCATABLE)
|
||||||
|
/*
|
||||||
|
* We can't branch directly; in the direct case we use LR
|
||||||
|
* and system_call_entry restores LR. (We thus need to move
|
||||||
|
* LR to r10 in the RFID case too.)
|
||||||
|
*/
|
||||||
|
#define SYSCALL_PSERIES_2_DIRECT \
|
||||||
|
mflr r10 ; \
|
||||||
|
ld r12,PACAKBASE(r13) ; \
|
||||||
|
LOAD_HANDLER(r12, system_call_entry_direct) ; \
|
||||||
|
mtlr r12 ; \
|
||||||
|
mfspr r12,SPRN_SRR1 ; \
|
||||||
|
/* Re-use of r13... No spare regs to do this */ \
|
||||||
|
li r13,MSR_RI ; \
|
||||||
|
mtmsrd r13,1 ; \
|
||||||
|
GET_PACA(r13) ; /* get r13 back */ \
|
||||||
|
blr ;
|
||||||
|
#else
|
||||||
|
/* We can branch directly */
|
||||||
|
#define SYSCALL_PSERIES_2_DIRECT \
|
||||||
|
mfspr r12,SPRN_SRR1 ; \
|
||||||
|
li r10,MSR_RI ; \
|
||||||
|
mtmsrd r10,1 ; /* Set RI (EE=0) */ \
|
||||||
|
b system_call_entry_direct ;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the start of the interrupt handlers for pSeries
|
* This is the start of the interrupt handlers for pSeries
|
||||||
@ -207,31 +271,11 @@ system_call_pSeries:
|
|||||||
KVMTEST(0xc00)
|
KVMTEST(0xc00)
|
||||||
GET_SCRATCH0(r13)
|
GET_SCRATCH0(r13)
|
||||||
#endif
|
#endif
|
||||||
BEGIN_FTR_SECTION
|
SYSCALL_PSERIES_1
|
||||||
cmpdi r0,0x1ebe
|
SYSCALL_PSERIES_2_RFID
|
||||||
beq- 1f
|
SYSCALL_PSERIES_3
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
|
|
||||||
mr r9,r13
|
|
||||||
GET_PACA(r13)
|
|
||||||
mfspr r11,SPRN_SRR0
|
|
||||||
mfspr r12,SPRN_SRR1
|
|
||||||
ld r10,PACAKBASE(r13)
|
|
||||||
LOAD_HANDLER(r10, system_call_entry)
|
|
||||||
mtspr SPRN_SRR0,r10
|
|
||||||
ld r10,PACAKMSR(r13)
|
|
||||||
mtspr SPRN_SRR1,r10
|
|
||||||
rfid
|
|
||||||
b . /* prevent speculative execution */
|
|
||||||
|
|
||||||
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
|
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
|
||||||
|
|
||||||
/* Fast LE/BE switch system call */
|
|
||||||
1: mfspr r12,SPRN_SRR1
|
|
||||||
xori r12,r12,MSR_LE
|
|
||||||
mtspr SPRN_SRR1,r12
|
|
||||||
rfid /* return to userspace */
|
|
||||||
b .
|
|
||||||
|
|
||||||
STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
|
STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
|
||||||
KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xd00)
|
KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xd00)
|
||||||
|
|
||||||
@ -276,7 +320,7 @@ vsx_unavailable_pSeries_1:
|
|||||||
KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
|
KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
|
||||||
|
|
||||||
. = 0x1500
|
. = 0x1500
|
||||||
.global denorm_Hypervisor
|
.global denorm_exception_hv
|
||||||
denorm_exception_hv:
|
denorm_exception_hv:
|
||||||
HMT_MEDIUM
|
HMT_MEDIUM
|
||||||
mtspr SPRN_SPRG_HSCRATCH0,r13
|
mtspr SPRN_SPRG_HSCRATCH0,r13
|
||||||
@ -311,12 +355,14 @@ denorm_exception_hv:
|
|||||||
#ifdef CONFIG_CBE_RAS
|
#ifdef CONFIG_CBE_RAS
|
||||||
STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
|
STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
|
||||||
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
|
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
|
||||||
|
#else
|
||||||
|
. = 0x1800
|
||||||
#endif /* CONFIG_CBE_RAS */
|
#endif /* CONFIG_CBE_RAS */
|
||||||
|
|
||||||
. = 0x3000
|
|
||||||
|
|
||||||
/*** Out of line interrupts support ***/
|
/*** Out of line interrupts support ***/
|
||||||
|
|
||||||
|
.align 7
|
||||||
/* moved from 0x200 */
|
/* moved from 0x200 */
|
||||||
machine_check_pSeries:
|
machine_check_pSeries:
|
||||||
.globl machine_check_fwnmi
|
.globl machine_check_fwnmi
|
||||||
@ -575,16 +621,12 @@ slb_miss_user_pseries:
|
|||||||
b . /* prevent spec. execution */
|
b . /* prevent spec. execution */
|
||||||
#endif /* __DISABLED__ */
|
#endif /* __DISABLED__ */
|
||||||
|
|
||||||
.align 7
|
|
||||||
.globl __end_interrupts
|
|
||||||
__end_interrupts:
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code from here down to __end_handlers is invoked from the
|
* Code from here down to __end_handlers is invoked from the
|
||||||
* exception prologs above. Because the prologs assemble the
|
* exception prologs above. Because the prologs assemble the
|
||||||
* addresses of these handlers using the LOAD_HANDLER macro,
|
* addresses of these handlers using the LOAD_HANDLER macro,
|
||||||
* which uses an addi instruction, these handlers must be in
|
* which uses an ori instruction, these handlers must be in
|
||||||
* the first 32k of the kernel image.
|
* the first 64k of the kernel image.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*** Common interrupt handlers ***/
|
/*** Common interrupt handlers ***/
|
||||||
@ -613,8 +655,8 @@ machine_check_common:
|
|||||||
STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
|
STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
|
||||||
STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
|
STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
|
||||||
STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
|
STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
|
||||||
STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
|
STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
|
||||||
STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
|
STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
|
||||||
STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
|
STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
|
||||||
STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
|
STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
|
||||||
STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
|
STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
|
||||||
@ -629,7 +671,158 @@ machine_check_common:
|
|||||||
STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
|
STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
|
||||||
#endif /* CONFIG_CBE_RAS */
|
#endif /* CONFIG_CBE_RAS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relocation-on interrupts: A subset of the interrupts can be delivered
|
||||||
|
* with IR=1/DR=1, if AIL==2 and MSR.HV won't be changed by delivering
|
||||||
|
* it. Addresses are the same as the original interrupt addresses, but
|
||||||
|
* offset by 0xc000000000004000.
|
||||||
|
* It's impossible to receive interrupts below 0x300 via this mechanism.
|
||||||
|
* KVM: None of these traps are from the guest ; anything that escalated
|
||||||
|
* to HV=1 from HV=0 is delivered via real mode handlers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This uses the standard macro, since the original 0x300 vector
|
||||||
|
* only has extra guff for STAB-based processors -- which never
|
||||||
|
* come here.
|
||||||
|
*/
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x4300, 0x300, data_access)
|
||||||
|
. = 0x4380
|
||||||
|
.globl data_access_slb_relon_pSeries
|
||||||
|
data_access_slb_relon_pSeries:
|
||||||
|
HMT_MEDIUM
|
||||||
|
SET_SCRATCH0(r13)
|
||||||
|
EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
|
||||||
|
std r3,PACA_EXSLB+EX_R3(r13)
|
||||||
|
mfspr r3,SPRN_DAR
|
||||||
|
mfspr r12,SPRN_SRR1
|
||||||
|
#ifndef CONFIG_RELOCATABLE
|
||||||
|
b .slb_miss_realmode
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* We can't just use a direct branch to .slb_miss_realmode
|
||||||
|
* because the distance from here to there depends on where
|
||||||
|
* the kernel ends up being put.
|
||||||
|
*/
|
||||||
|
mfctr r11
|
||||||
|
ld r10,PACAKBASE(r13)
|
||||||
|
LOAD_HANDLER(r10, .slb_miss_realmode)
|
||||||
|
mtctr r10
|
||||||
|
bctr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x4400, 0x400, instruction_access)
|
||||||
|
. = 0x4480
|
||||||
|
.globl instruction_access_slb_relon_pSeries
|
||||||
|
instruction_access_slb_relon_pSeries:
|
||||||
|
HMT_MEDIUM
|
||||||
|
SET_SCRATCH0(r13)
|
||||||
|
EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
|
||||||
|
std r3,PACA_EXSLB+EX_R3(r13)
|
||||||
|
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
|
||||||
|
mfspr r12,SPRN_SRR1
|
||||||
|
#ifndef CONFIG_RELOCATABLE
|
||||||
|
b .slb_miss_realmode
|
||||||
|
#else
|
||||||
|
mfctr r11
|
||||||
|
ld r10,PACAKBASE(r13)
|
||||||
|
LOAD_HANDLER(r10, .slb_miss_realmode)
|
||||||
|
mtctr r10
|
||||||
|
bctr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
. = 0x4500
|
||||||
|
.globl hardware_interrupt_relon_pSeries;
|
||||||
|
.globl hardware_interrupt_relon_hv;
|
||||||
|
hardware_interrupt_relon_pSeries:
|
||||||
|
hardware_interrupt_relon_hv:
|
||||||
|
BEGIN_FTR_SECTION
|
||||||
|
_MASKABLE_RELON_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV, SOFTEN_TEST_HV)
|
||||||
|
FTR_SECTION_ELSE
|
||||||
|
_MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD, SOFTEN_TEST_PR)
|
||||||
|
ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_206)
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x4600, 0x600, alignment)
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x4700, 0x700, program_check)
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x4800, 0x800, fp_unavailable)
|
||||||
|
MASKABLE_RELON_EXCEPTION_PSERIES(0x4900, 0x900, decrementer)
|
||||||
|
STD_RELON_EXCEPTION_HV(0x4980, 0x982, hdecrementer)
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x4b00, 0xb00, trap_0b)
|
||||||
|
|
||||||
|
. = 0x4c00
|
||||||
|
.globl system_call_relon_pSeries
|
||||||
|
system_call_relon_pSeries:
|
||||||
|
HMT_MEDIUM
|
||||||
|
SYSCALL_PSERIES_1
|
||||||
|
SYSCALL_PSERIES_2_DIRECT
|
||||||
|
SYSCALL_PSERIES_3
|
||||||
|
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x4d00, 0xd00, single_step)
|
||||||
|
|
||||||
|
. = 0x4e00
|
||||||
|
b h_data_storage_relon_hv
|
||||||
|
|
||||||
|
. = 0x4e20
|
||||||
|
b h_instr_storage_relon_hv
|
||||||
|
|
||||||
|
. = 0x4e40
|
||||||
|
b emulation_assist_relon_hv
|
||||||
|
|
||||||
|
. = 0x4e50
|
||||||
|
b hmi_exception_relon_hv
|
||||||
|
|
||||||
|
. = 0x4e60
|
||||||
|
b hmi_exception_relon_hv
|
||||||
|
|
||||||
|
/* For when we support the doorbell interrupt:
|
||||||
|
STD_RELON_EXCEPTION_HYPERVISOR(0x4e80, 0xe80, doorbell_hyper)
|
||||||
|
*/
|
||||||
|
|
||||||
|
performance_monitor_relon_pSeries_1:
|
||||||
|
. = 0x4f00
|
||||||
|
b performance_monitor_relon_pSeries
|
||||||
|
|
||||||
|
altivec_unavailable_relon_pSeries_1:
|
||||||
|
. = 0x4f20
|
||||||
|
b altivec_unavailable_relon_pSeries
|
||||||
|
|
||||||
|
vsx_unavailable_relon_pSeries_1:
|
||||||
|
. = 0x4f40
|
||||||
|
b vsx_unavailable_relon_pSeries
|
||||||
|
|
||||||
|
#ifdef CONFIG_CBE_RAS
|
||||||
|
STD_RELON_EXCEPTION_HV(0x5200, 0x1202, cbe_system_error)
|
||||||
|
#endif /* CONFIG_CBE_RAS */
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
|
||||||
|
#ifdef CONFIG_PPC_DENORMALISATION
|
||||||
|
. = 0x5500
|
||||||
|
b denorm_exception_hv
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_CBE_RAS
|
||||||
|
STD_RELON_EXCEPTION_HV(0x5600, 0x1602, cbe_maintenance)
|
||||||
|
#else
|
||||||
|
#ifdef CONFIG_HVC_SCOM
|
||||||
|
STD_RELON_EXCEPTION_HV(0x5600, 0x1600, maintence_interrupt)
|
||||||
|
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1600)
|
||||||
|
#endif /* CONFIG_HVC_SCOM */
|
||||||
|
#endif /* CONFIG_CBE_RAS */
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
|
||||||
|
#ifdef CONFIG_CBE_RAS
|
||||||
|
STD_RELON_EXCEPTION_HV(0x5800, 0x1802, cbe_thermal)
|
||||||
|
#endif /* CONFIG_CBE_RAS */
|
||||||
|
|
||||||
|
/* Other future vectors */
|
||||||
.align 7
|
.align 7
|
||||||
|
.globl __end_interrupts
|
||||||
|
__end_interrupts:
|
||||||
|
|
||||||
|
.align 7
|
||||||
|
system_call_entry_direct:
|
||||||
|
#if defined(CONFIG_RELOCATABLE)
|
||||||
|
/* The first level prologue may have used LR to get here, saving
|
||||||
|
* orig in r10. To save hacking/ifdeffing common code, restore here.
|
||||||
|
*/
|
||||||
|
mtlr r10
|
||||||
|
#endif
|
||||||
system_call_entry:
|
system_call_entry:
|
||||||
b system_call_common
|
b system_call_common
|
||||||
|
|
||||||
@ -714,21 +907,21 @@ data_access_common:
|
|||||||
ld r3,PACA_EXGEN+EX_DAR(r13)
|
ld r3,PACA_EXGEN+EX_DAR(r13)
|
||||||
lwz r4,PACA_EXGEN+EX_DSISR(r13)
|
lwz r4,PACA_EXGEN+EX_DSISR(r13)
|
||||||
li r5,0x300
|
li r5,0x300
|
||||||
b .do_hash_page /* Try to handle as hpte fault */
|
b .do_hash_page /* Try to handle as hpte fault */
|
||||||
|
|
||||||
.align 7
|
.align 7
|
||||||
.globl h_data_storage_common
|
.globl h_data_storage_common
|
||||||
h_data_storage_common:
|
h_data_storage_common:
|
||||||
mfspr r10,SPRN_HDAR
|
mfspr r10,SPRN_HDAR
|
||||||
std r10,PACA_EXGEN+EX_DAR(r13)
|
std r10,PACA_EXGEN+EX_DAR(r13)
|
||||||
mfspr r10,SPRN_HDSISR
|
mfspr r10,SPRN_HDSISR
|
||||||
stw r10,PACA_EXGEN+EX_DSISR(r13)
|
stw r10,PACA_EXGEN+EX_DSISR(r13)
|
||||||
EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
|
EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
|
||||||
bl .save_nvgprs
|
bl .save_nvgprs
|
||||||
DISABLE_INTS
|
DISABLE_INTS
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
bl .unknown_exception
|
bl .unknown_exception
|
||||||
b .ret_from_except
|
b .ret_from_except
|
||||||
|
|
||||||
.align 7
|
.align 7
|
||||||
.globl instruction_access_common
|
.globl instruction_access_common
|
||||||
@ -741,7 +934,7 @@ instruction_access_common:
|
|||||||
li r5,0x400
|
li r5,0x400
|
||||||
b .do_hash_page /* Try to handle as hpte fault */
|
b .do_hash_page /* Try to handle as hpte fault */
|
||||||
|
|
||||||
STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception)
|
STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here is the common SLB miss user that is used when going to virtual
|
* Here is the common SLB miss user that is used when going to virtual
|
||||||
@ -1152,6 +1345,21 @@ _GLOBAL(do_stab_bolted)
|
|||||||
rfid
|
rfid
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
|
|
||||||
|
/* Equivalents to the above handlers for relocation-on interrupt vectors */
|
||||||
|
STD_RELON_EXCEPTION_HV(., 0xe00, h_data_storage)
|
||||||
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe00)
|
||||||
|
STD_RELON_EXCEPTION_HV(., 0xe20, h_instr_storage)
|
||||||
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe20)
|
||||||
|
STD_RELON_EXCEPTION_HV(., 0xe40, emulation_assist)
|
||||||
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe40)
|
||||||
|
STD_RELON_EXCEPTION_HV(., 0xe60, hmi_exception)
|
||||||
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe60)
|
||||||
|
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable)
|
||||||
|
STD_RELON_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable)
|
||||||
|
|
||||||
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
|
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
|
||||||
/*
|
/*
|
||||||
* Data area reserved for FWNMI option.
|
* Data area reserved for FWNMI option.
|
||||||
@ -1164,7 +1372,7 @@ fwnmi_data_area:
|
|||||||
/* pseries and powernv need to keep the whole page from
|
/* pseries and powernv need to keep the whole page from
|
||||||
* 0x7000 to 0x8000 free for use by the firmware
|
* 0x7000 to 0x8000 free for use by the firmware
|
||||||
*/
|
*/
|
||||||
. = 0x8000
|
. = 0x8000
|
||||||
#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
|
#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
|
||||||
|
|
||||||
/* Space for CPU0's segment table */
|
/* Space for CPU0's segment table */
|
||||||
|
@ -422,7 +422,7 @@ _STATIC(__after_prom_start)
|
|||||||
tovirt(r6,r6) /* on booke, we already run at PAGE_OFFSET */
|
tovirt(r6,r6) /* on booke, we already run at PAGE_OFFSET */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CRASH_DUMP
|
#ifdef CONFIG_RELOCATABLE
|
||||||
/*
|
/*
|
||||||
* Check if the kernel has to be running as relocatable kernel based on the
|
* Check if the kernel has to be running as relocatable kernel based on the
|
||||||
* variable __run_at_load, if it is set the kernel is treated as relocatable
|
* variable __run_at_load, if it is set the kernel is treated as relocatable
|
||||||
@ -432,7 +432,8 @@ _STATIC(__after_prom_start)
|
|||||||
cmplwi cr0,r7,1
|
cmplwi cr0,r7,1
|
||||||
bne 3f
|
bne 3f
|
||||||
|
|
||||||
li r5,__end_interrupts - _stext /* just copy interrupts */
|
/* just copy interrupts */
|
||||||
|
LOAD_REG_IMMEDIATE(r5, __end_interrupts - _stext)
|
||||||
b 5f
|
b 5f
|
||||||
3:
|
3:
|
||||||
#endif
|
#endif
|
||||||
@ -703,6 +704,7 @@ _INIT_STATIC(start_here_multiplatform)
|
|||||||
|
|
||||||
#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
|
#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
|
||||||
/* Setup OPAL entry */
|
/* Setup OPAL entry */
|
||||||
|
LOAD_REG_ADDR(r11, opal)
|
||||||
std r28,0(r11);
|
std r28,0(r11);
|
||||||
std r29,8(r11);
|
std r29,8(r11);
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,9 +55,6 @@ __setup("powersave=off", powersave_off);
|
|||||||
*/
|
*/
|
||||||
void cpu_idle(void)
|
void cpu_idle(void)
|
||||||
{
|
{
|
||||||
if (ppc_md.idle_loop)
|
|
||||||
ppc_md.idle_loop(); /* doesn't return */
|
|
||||||
|
|
||||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_idle_enter();
|
tick_nohz_idle_enter();
|
||||||
|
@ -656,7 +656,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
|
|||||||
struct iommu_pool *p;
|
struct iommu_pool *p;
|
||||||
|
|
||||||
/* number of bytes needed for the bitmap */
|
/* number of bytes needed for the bitmap */
|
||||||
sz = (tbl->it_size + 7) >> 3;
|
sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
|
||||||
|
|
||||||
page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
|
page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
|
||||||
if (!page)
|
if (!page)
|
||||||
@ -708,7 +708,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
|
|||||||
|
|
||||||
void iommu_free_table(struct iommu_table *tbl, const char *node_name)
|
void iommu_free_table(struct iommu_table *tbl, const char *node_name)
|
||||||
{
|
{
|
||||||
unsigned long bitmap_sz, i;
|
unsigned long bitmap_sz;
|
||||||
unsigned int order;
|
unsigned int order;
|
||||||
|
|
||||||
if (!tbl || !tbl->it_map) {
|
if (!tbl || !tbl->it_map) {
|
||||||
@ -718,17 +718,11 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* verify that table contains no entries */
|
/* verify that table contains no entries */
|
||||||
/* it_size is in entries, and we're examining 64 at a time */
|
if (!bitmap_empty(tbl->it_map, tbl->it_size))
|
||||||
for (i = 0; i < (tbl->it_size/64); i++) {
|
pr_warn("%s: Unexpected TCEs for %s\n", __func__, node_name);
|
||||||
if (tbl->it_map[i] != 0) {
|
|
||||||
printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
|
|
||||||
__func__, node_name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate bitmap size in bytes */
|
/* calculate bitmap size in bytes */
|
||||||
bitmap_sz = (tbl->it_size + 7) / 8;
|
bitmap_sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
|
||||||
|
|
||||||
/* free bitmap */
|
/* free bitmap */
|
||||||
order = get_order(bitmap_sz);
|
order = get_order(bitmap_sz);
|
||||||
|
@ -218,23 +218,23 @@ static void __init export_crashk_values(struct device_node *node)
|
|||||||
* be sure what's in them, so remove them. */
|
* be sure what's in them, so remove them. */
|
||||||
prop = of_find_property(node, "linux,crashkernel-base", NULL);
|
prop = of_find_property(node, "linux,crashkernel-base", NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
prom_remove_property(node, prop);
|
of_remove_property(node, prop);
|
||||||
|
|
||||||
prop = of_find_property(node, "linux,crashkernel-size", NULL);
|
prop = of_find_property(node, "linux,crashkernel-size", NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
prom_remove_property(node, prop);
|
of_remove_property(node, prop);
|
||||||
|
|
||||||
if (crashk_res.start != 0) {
|
if (crashk_res.start != 0) {
|
||||||
prom_add_property(node, &crashk_base_prop);
|
of_add_property(node, &crashk_base_prop);
|
||||||
crashk_size = resource_size(&crashk_res);
|
crashk_size = resource_size(&crashk_res);
|
||||||
prom_add_property(node, &crashk_size_prop);
|
of_add_property(node, &crashk_size_prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* memory_limit is required by the kexec-tools to limit the
|
* memory_limit is required by the kexec-tools to limit the
|
||||||
* crash regions to the actual memory used.
|
* crash regions to the actual memory used.
|
||||||
*/
|
*/
|
||||||
prom_update_property(node, &memory_limit_prop);
|
of_update_property(node, &memory_limit_prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init kexec_setup(void)
|
static int __init kexec_setup(void)
|
||||||
@ -249,11 +249,11 @@ static int __init kexec_setup(void)
|
|||||||
/* remove any stale properties so ours can be found */
|
/* remove any stale properties so ours can be found */
|
||||||
prop = of_find_property(node, kernel_end_prop.name, NULL);
|
prop = of_find_property(node, kernel_end_prop.name, NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
prom_remove_property(node, prop);
|
of_remove_property(node, prop);
|
||||||
|
|
||||||
/* information needed by userspace when using default_machine_kexec */
|
/* information needed by userspace when using default_machine_kexec */
|
||||||
kernel_end = __pa(_end);
|
kernel_end = __pa(_end);
|
||||||
prom_add_property(node, &kernel_end_prop);
|
of_add_property(node, &kernel_end_prop);
|
||||||
|
|
||||||
export_crashk_values(node);
|
export_crashk_values(node);
|
||||||
|
|
||||||
|
@ -389,14 +389,14 @@ static int __init export_htab_values(void)
|
|||||||
/* remove any stale propertys so ours can be found */
|
/* remove any stale propertys so ours can be found */
|
||||||
prop = of_find_property(node, htab_base_prop.name, NULL);
|
prop = of_find_property(node, htab_base_prop.name, NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
prom_remove_property(node, prop);
|
of_remove_property(node, prop);
|
||||||
prop = of_find_property(node, htab_size_prop.name, NULL);
|
prop = of_find_property(node, htab_size_prop.name, NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
prom_remove_property(node, prop);
|
of_remove_property(node, prop);
|
||||||
|
|
||||||
htab_base = __pa(htab_address);
|
htab_base = __pa(htab_address);
|
||||||
prom_add_property(node, &htab_base_prop);
|
of_add_property(node, &htab_base_prop);
|
||||||
prom_add_property(node, &htab_size_prop);
|
of_add_property(node, &htab_size_prop);
|
||||||
|
|
||||||
of_node_put(node);
|
of_node_put(node);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -208,7 +208,7 @@ pci_create_OF_bus_map(void)
|
|||||||
of_prop->name = "pci-OF-bus-map";
|
of_prop->name = "pci-OF-bus-map";
|
||||||
of_prop->length = 256;
|
of_prop->length = 256;
|
||||||
of_prop->value = &of_prop[1];
|
of_prop->value = &of_prop[1];
|
||||||
prom_add_property(dn, of_prop);
|
of_add_property(dn, of_prop);
|
||||||
of_node_put(dn);
|
of_node_put(dn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
@ -49,11 +50,11 @@
|
|||||||
#include <asm/btext.h>
|
#include <asm/btext.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
#include <asm/pci-bridge.h>
|
#include <asm/pci-bridge.h>
|
||||||
#include <asm/kexec.h>
|
#include <asm/kexec.h>
|
||||||
#include <asm/opal.h>
|
#include <asm/opal.h>
|
||||||
#include <asm/fadump.h>
|
#include <asm/fadump.h>
|
||||||
|
#include <asm/debug.h>
|
||||||
|
|
||||||
#include <mm/mmu_decl.h>
|
#include <mm/mmu_decl.h>
|
||||||
|
|
||||||
@ -802,7 +803,7 @@ static int prom_reconfig_notifier(struct notifier_block *nb,
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case PSERIES_RECONFIG_ADD:
|
case OF_RECONFIG_ATTACH_NODE:
|
||||||
err = of_finish_dynamic_node(node);
|
err = of_finish_dynamic_node(node);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
printk(KERN_ERR "finish_node returned %d\n", err);
|
printk(KERN_ERR "finish_node returned %d\n", err);
|
||||||
@ -821,7 +822,7 @@ static struct notifier_block prom_reconfig_nb = {
|
|||||||
|
|
||||||
static int __init prom_reconfig_setup(void)
|
static int __init prom_reconfig_setup(void)
|
||||||
{
|
{
|
||||||
return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
|
return of_reconfig_notifier_register(&prom_reconfig_nb);
|
||||||
}
|
}
|
||||||
__initcall(prom_reconfig_setup);
|
__initcall(prom_reconfig_setup);
|
||||||
#endif
|
#endif
|
||||||
|
@ -671,6 +671,7 @@ static void __init early_cmdline_parse(void)
|
|||||||
#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
|
#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
|
||||||
#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
|
#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
|
||||||
#define OV1_PPC_2_06 0x02 /* set if we support PowerPC 2.06 */
|
#define OV1_PPC_2_06 0x02 /* set if we support PowerPC 2.06 */
|
||||||
|
#define OV1_PPC_2_07 0x01 /* set if we support PowerPC 2.07 */
|
||||||
|
|
||||||
/* Option vector 2: Open Firmware options supported */
|
/* Option vector 2: Open Firmware options supported */
|
||||||
#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
|
#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
|
||||||
@ -707,6 +708,7 @@ static void __init early_cmdline_parse(void)
|
|||||||
#define OV5_PFO_HW_RNG 0x80 /* PFO Random Number Generator */
|
#define OV5_PFO_HW_RNG 0x80 /* PFO Random Number Generator */
|
||||||
#define OV5_PFO_HW_842 0x40 /* PFO Compression Accelerator */
|
#define OV5_PFO_HW_842 0x40 /* PFO Compression Accelerator */
|
||||||
#define OV5_PFO_HW_ENCR 0x20 /* PFO Encryption Accelerator */
|
#define OV5_PFO_HW_ENCR 0x20 /* PFO Encryption Accelerator */
|
||||||
|
#define OV5_SUB_PROCESSORS 0x01 /* 1,2,or 4 Sub-Processors supported */
|
||||||
|
|
||||||
/* Option Vector 6: IBM PAPR hints */
|
/* Option Vector 6: IBM PAPR hints */
|
||||||
#define OV6_LINUX 0x02 /* Linux is our OS */
|
#define OV6_LINUX 0x02 /* Linux is our OS */
|
||||||
@ -719,6 +721,8 @@ static unsigned char ibm_architecture_vec[] = {
|
|||||||
W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
|
W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
|
||||||
W(0xffff0000), W(0x003e0000), /* POWER6 */
|
W(0xffff0000), W(0x003e0000), /* POWER6 */
|
||||||
W(0xffff0000), W(0x003f0000), /* POWER7 */
|
W(0xffff0000), W(0x003f0000), /* POWER7 */
|
||||||
|
W(0xffff0000), W(0x004b0000), /* POWER8 */
|
||||||
|
W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
|
||||||
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
|
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
|
||||||
W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
|
W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
|
||||||
W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
|
W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
|
||||||
@ -728,7 +732,7 @@ static unsigned char ibm_architecture_vec[] = {
|
|||||||
3 - 2, /* length */
|
3 - 2, /* length */
|
||||||
0, /* don't ignore, don't halt */
|
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_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
|
||||||
OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06,
|
OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
|
||||||
|
|
||||||
/* option vector 2: Open Firmware options supported */
|
/* option vector 2: Open Firmware options supported */
|
||||||
34 - 2, /* length */
|
34 - 2, /* length */
|
||||||
@ -755,7 +759,7 @@ static unsigned char ibm_architecture_vec[] = {
|
|||||||
OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */
|
OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */
|
||||||
|
|
||||||
/* option vector 5: PAPR/OF options */
|
/* option vector 5: PAPR/OF options */
|
||||||
18 - 2, /* length */
|
19 - 2, /* length */
|
||||||
0, /* don't ignore, don't halt */
|
0, /* don't ignore, don't halt */
|
||||||
OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
|
OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
|
||||||
OV5_DONATE_DEDICATE_CPU | OV5_MSI,
|
OV5_DONATE_DEDICATE_CPU | OV5_MSI,
|
||||||
@ -769,13 +773,14 @@ static unsigned char ibm_architecture_vec[] = {
|
|||||||
* must match by the macro below. Update the definition if
|
* must match by the macro below. Update the definition if
|
||||||
* the structure layout changes.
|
* the structure layout changes.
|
||||||
*/
|
*/
|
||||||
#define IBM_ARCH_VEC_NRCORES_OFFSET 101
|
#define IBM_ARCH_VEC_NRCORES_OFFSET 117
|
||||||
W(NR_CPUS), /* number of cores supported */
|
W(NR_CPUS), /* number of cores supported */
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR | OV5_PFO_HW_842,
|
OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR | OV5_PFO_HW_842,
|
||||||
|
OV5_SUB_PROCESSORS,
|
||||||
/* option vector 6: IBM PAPR hints */
|
/* option vector 6: IBM PAPR hints */
|
||||||
4 - 2, /* length */
|
4 - 2, /* length */
|
||||||
0,
|
0,
|
||||||
|
@ -952,6 +952,10 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
|
|||||||
arch_bp_generic_fields(data &
|
arch_bp_generic_fields(data &
|
||||||
(DABR_DATA_WRITE | DABR_DATA_READ),
|
(DABR_DATA_WRITE | DABR_DATA_READ),
|
||||||
&attr.bp_type);
|
&attr.bp_type);
|
||||||
|
|
||||||
|
/* Enable breakpoint */
|
||||||
|
attr.disabled = false;
|
||||||
|
|
||||||
ret = modify_user_hw_breakpoint(bp, &attr);
|
ret = modify_user_hw_breakpoint(bp, &attr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ptrace_put_breakpoints(task);
|
ptrace_put_breakpoints(task);
|
||||||
@ -1037,7 +1041,7 @@ void ptrace_disable(struct task_struct *child)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||||
static long set_intruction_bp(struct task_struct *child,
|
static long set_instruction_bp(struct task_struct *child,
|
||||||
struct ppc_hw_breakpoint *bp_info)
|
struct ppc_hw_breakpoint *bp_info)
|
||||||
{
|
{
|
||||||
int slot;
|
int slot;
|
||||||
@ -1338,6 +1342,12 @@ static int set_dac_range(struct task_struct *child,
|
|||||||
static long ppc_set_hwdebug(struct task_struct *child,
|
static long ppc_set_hwdebug(struct task_struct *child,
|
||||||
struct ppc_hw_breakpoint *bp_info)
|
struct ppc_hw_breakpoint *bp_info)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||||
|
int len = 0;
|
||||||
|
struct thread_struct *thread = &(child->thread);
|
||||||
|
struct perf_event *bp;
|
||||||
|
struct perf_event_attr attr;
|
||||||
|
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
||||||
#ifndef CONFIG_PPC_ADV_DEBUG_REGS
|
#ifndef CONFIG_PPC_ADV_DEBUG_REGS
|
||||||
unsigned long dabr;
|
unsigned long dabr;
|
||||||
#endif
|
#endif
|
||||||
@ -1365,7 +1375,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
|
|||||||
if ((bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE) ||
|
if ((bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE) ||
|
||||||
(bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
|
(bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
return set_intruction_bp(child, bp_info);
|
return set_instruction_bp(child, bp_info);
|
||||||
}
|
}
|
||||||
if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
|
if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
|
||||||
return set_dac(child, bp_info);
|
return set_dac(child, bp_info);
|
||||||
@ -1381,13 +1391,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
|
|||||||
*/
|
*/
|
||||||
if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
|
if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
|
||||||
(bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
|
(bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
|
||||||
bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
|
|
||||||
bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
|
bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (child->thread.dabr)
|
|
||||||
return -ENOSPC;
|
|
||||||
|
|
||||||
if ((unsigned long)bp_info->addr >= TASK_SIZE)
|
if ((unsigned long)bp_info->addr >= TASK_SIZE)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
@ -1397,6 +1403,50 @@ static long ppc_set_hwdebug(struct task_struct *child,
|
|||||||
dabr |= DABR_DATA_READ;
|
dabr |= DABR_DATA_READ;
|
||||||
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
|
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
|
||||||
dabr |= DABR_DATA_WRITE;
|
dabr |= DABR_DATA_WRITE;
|
||||||
|
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||||
|
if (ptrace_get_breakpoints(child) < 0)
|
||||||
|
return -ESRCH;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the request is for 'range' breakpoints. We can
|
||||||
|
* support it if range < 8 bytes.
|
||||||
|
*/
|
||||||
|
if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
|
||||||
|
len = bp_info->addr2 - bp_info->addr;
|
||||||
|
} else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
|
||||||
|
ptrace_put_breakpoints(child);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
bp = thread->ptrace_bps[0];
|
||||||
|
if (bp) {
|
||||||
|
ptrace_put_breakpoints(child);
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new breakpoint request if one doesn't exist already */
|
||||||
|
hw_breakpoint_init(&attr);
|
||||||
|
attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
|
||||||
|
attr.bp_len = len;
|
||||||
|
arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
|
||||||
|
&attr.bp_type);
|
||||||
|
|
||||||
|
thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
|
||||||
|
ptrace_triggered, NULL, child);
|
||||||
|
if (IS_ERR(bp)) {
|
||||||
|
thread->ptrace_bps[0] = NULL;
|
||||||
|
ptrace_put_breakpoints(child);
|
||||||
|
return PTR_ERR(bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrace_put_breakpoints(child);
|
||||||
|
return 1;
|
||||||
|
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
||||||
|
|
||||||
|
if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (child->thread.dabr)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
child->thread.dabr = dabr;
|
child->thread.dabr = dabr;
|
||||||
child->thread.dabrx = DABRX_ALL;
|
child->thread.dabrx = DABRX_ALL;
|
||||||
@ -1405,8 +1455,13 @@ static long ppc_set_hwdebug(struct task_struct *child,
|
|||||||
#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
|
#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
|
||||||
}
|
}
|
||||||
|
|
||||||
static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
|
static long ppc_del_hwdebug(struct task_struct *child, long data)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||||
|
int ret = 0;
|
||||||
|
struct thread_struct *thread = &(child->thread);
|
||||||
|
struct perf_event *bp;
|
||||||
|
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
||||||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -1426,10 +1481,25 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
|
|||||||
#else
|
#else
|
||||||
if (data != 1)
|
if (data != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||||
|
if (ptrace_get_breakpoints(child) < 0)
|
||||||
|
return -ESRCH;
|
||||||
|
|
||||||
|
bp = thread->ptrace_bps[0];
|
||||||
|
if (bp) {
|
||||||
|
unregister_hw_breakpoint(bp);
|
||||||
|
thread->ptrace_bps[0] = NULL;
|
||||||
|
} else
|
||||||
|
ret = -ENOENT;
|
||||||
|
ptrace_put_breakpoints(child);
|
||||||
|
return ret;
|
||||||
|
#else /* CONFIG_HAVE_HW_BREAKPOINT */
|
||||||
if (child->thread.dabr == 0)
|
if (child->thread.dabr == 0)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
child->thread.dabr = 0;
|
child->thread.dabr = 0;
|
||||||
|
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@ -1536,7 +1606,11 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||||||
dbginfo.data_bp_alignment = 4;
|
dbginfo.data_bp_alignment = 4;
|
||||||
#endif
|
#endif
|
||||||
dbginfo.sizeof_condition = 0;
|
dbginfo.sizeof_condition = 0;
|
||||||
|
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||||
|
dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE;
|
||||||
|
#else
|
||||||
dbginfo.features = 0;
|
dbginfo.features = 0;
|
||||||
|
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
||||||
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
|
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, datavp,
|
if (!access_ok(VERIFY_WRITE, datavp,
|
||||||
@ -1563,7 +1637,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case PPC_PTRACE_DELHWDEBUG: {
|
case PPC_PTRACE_DELHWDEBUG: {
|
||||||
ret = ppc_del_hwdebug(child, addr, data);
|
ret = ppc_del_hwdebug(child, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/topology.h>
|
#include <asm/topology.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
|
|
||||||
struct rtas_t rtas = {
|
struct rtas_t rtas = {
|
||||||
.lock = __ARCH_SPIN_LOCK_UNLOCKED
|
.lock = __ARCH_SPIN_LOCK_UNLOCKED
|
||||||
|
@ -650,10 +650,8 @@ static int initialize_flash_pde_data(const char *rtas_call_name,
|
|||||||
int token;
|
int token;
|
||||||
|
|
||||||
dp->data = kzalloc(buf_size, GFP_KERNEL);
|
dp->data = kzalloc(buf_size, GFP_KERNEL);
|
||||||
if (dp->data == NULL) {
|
if (dp->data == NULL)
|
||||||
remove_flash_pde(dp);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code assumes that the status int is the first member of the
|
* This code assumes that the status int is the first member of the
|
||||||
|
@ -601,6 +601,11 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
|
|
||||||
kvm_linear_init();
|
kvm_linear_init();
|
||||||
|
|
||||||
|
/* Interrupt code needs to be 64K-aligned */
|
||||||
|
if ((unsigned long)_stext & 0xffff)
|
||||||
|
panic("Kernelbase not 64K-aligned (0x%lx)!\n",
|
||||||
|
(unsigned long)_stext);
|
||||||
|
|
||||||
ppc64_boot_msg(0x15, "Setup Done");
|
ppc64_boot_msg(0x15, "Setup Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,29 +122,6 @@ int udbg_write(const char *s, int n)
|
|||||||
return n - remain;
|
return n - remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
int udbg_read(char *buf, int buflen)
|
|
||||||
{
|
|
||||||
char *p = buf;
|
|
||||||
int i, c;
|
|
||||||
|
|
||||||
if (!udbg_getc)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < buflen; ++i) {
|
|
||||||
do {
|
|
||||||
c = udbg_getc();
|
|
||||||
if (c == -1 && i == 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
} while (c == 0x11 || c == 0x13);
|
|
||||||
if (c == 0 || c == -1)
|
|
||||||
break;
|
|
||||||
*p++ = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UDBG_BUFSIZE 256
|
#define UDBG_BUFSIZE 256
|
||||||
void udbg_printf(const char *fmt, ...)
|
void udbg_printf(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -399,18 +399,6 @@ static unsigned long read_n_cells(int n, const unsigned int **buf)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct of_drconf_cell {
|
|
||||||
u64 base_addr;
|
|
||||||
u32 drc_index;
|
|
||||||
u32 reserved;
|
|
||||||
u32 aa_index;
|
|
||||||
u32 flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DRCONF_MEM_ASSIGNED 0x00000008
|
|
||||||
#define DRCONF_MEM_AI_INVALID 0x00000040
|
|
||||||
#define DRCONF_MEM_RESERVED 0x00000080
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the next memblock list entry from the ibm,dynamic-memory property
|
* Read the next memblock list entry from the ibm,dynamic-memory property
|
||||||
* and return the information in the provided of_drconf_cell structure.
|
* and return the information in the provided of_drconf_cell structure.
|
||||||
|
@ -190,12 +190,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
|
|||||||
|
|
||||||
#ifdef CONFIG_PPC_47x
|
#ifdef CONFIG_PPC_47x
|
||||||
|
|
||||||
/*
|
|
||||||
* 47x variant of icbt
|
|
||||||
*/
|
|
||||||
# define ICBT(CT,RA,RB) \
|
|
||||||
.long 0x7c00002c | ((CT) << 21) | ((RA) << 16) | ((RB) << 11)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _tlbivax_bcast is only on 47x. We don't bother doing a runtime
|
* _tlbivax_bcast is only on 47x. We don't bother doing a runtime
|
||||||
* check though, it will blow up soon enough if we mistakenly try
|
* check though, it will blow up soon enough if we mistakenly try
|
||||||
@ -208,8 +202,7 @@ _GLOBAL(_tlbivax_bcast)
|
|||||||
wrteei 0
|
wrteei 0
|
||||||
mtspr SPRN_MMUCR,r5
|
mtspr SPRN_MMUCR,r5
|
||||||
isync
|
isync
|
||||||
/* tlbivax 0,r3 - use .long to avoid binutils deps */
|
PPC_TLBIVAX(0, R3)
|
||||||
.long 0x7c000624 | (r3 << 11)
|
|
||||||
isync
|
isync
|
||||||
eieio
|
eieio
|
||||||
tlbsync
|
tlbsync
|
||||||
@ -227,11 +220,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_476_DD2)
|
|||||||
bl 2f
|
bl 2f
|
||||||
2: mflr r6
|
2: mflr r6
|
||||||
li r7,32
|
li r7,32
|
||||||
ICBT(0,r6,r7) /* touch next cache line */
|
PPC_ICBT(0,R6,R7) /* touch next cache line */
|
||||||
add r6,r6,r7
|
add r6,r6,r7
|
||||||
ICBT(0,r6,r7) /* touch next cache line */
|
PPC_ICBT(0,R6,R7) /* touch next cache line */
|
||||||
add r6,r6,r7
|
add r6,r6,r7
|
||||||
ICBT(0,r6,r7) /* touch next cache line */
|
PPC_ICBT(0,R6,R7) /* touch next cache line */
|
||||||
sync
|
sync
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
@ -54,8 +54,10 @@
|
|||||||
* Layout of constraint bits:
|
* Layout of constraint bits:
|
||||||
* 6666555555555544444444443333333333222222222211111111110000000000
|
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||||
* 3210987654321098765432109876543210987654321098765432109876543210
|
* 3210987654321098765432109876543210987654321098765432109876543210
|
||||||
* [ ><><><><><><>
|
* < >< ><><><><><><>
|
||||||
* NC P6P5P4P3P2P1
|
* L2 NC P6P5P4P3P2P1
|
||||||
|
*
|
||||||
|
* L2 - 16-18 - Required L2SEL value (select field)
|
||||||
*
|
*
|
||||||
* NC - number of counters
|
* NC - number of counters
|
||||||
* 15: NC error 0x8000
|
* 15: NC error 0x8000
|
||||||
@ -72,7 +74,7 @@
|
|||||||
static int power7_get_constraint(u64 event, unsigned long *maskp,
|
static int power7_get_constraint(u64 event, unsigned long *maskp,
|
||||||
unsigned long *valp)
|
unsigned long *valp)
|
||||||
{
|
{
|
||||||
int pmc, sh;
|
int pmc, sh, unit;
|
||||||
unsigned long mask = 0, value = 0;
|
unsigned long mask = 0, value = 0;
|
||||||
|
|
||||||
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
@ -90,6 +92,15 @@ static int power7_get_constraint(u64 event, unsigned long *maskp,
|
|||||||
mask |= 0x8000;
|
mask |= 0x8000;
|
||||||
value |= 0x1000;
|
value |= 0x1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
if (unit == 6) {
|
||||||
|
/* L2SEL must be identical across events */
|
||||||
|
int l2sel = (event >> PM_L2SEL_SH) & PM_L2SEL_MSK;
|
||||||
|
mask |= 0x7 << 16;
|
||||||
|
value |= l2sel << 16;
|
||||||
|
}
|
||||||
|
|
||||||
*maskp = mask;
|
*maskp = mask;
|
||||||
*valp = value;
|
*valp = value;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2,7 +2,6 @@ config PPC_MPC512x
|
|||||||
bool "512x-based boards"
|
bool "512x-based boards"
|
||||||
depends on 6xx
|
depends on 6xx
|
||||||
select FSL_SOC
|
select FSL_SOC
|
||||||
select FB_FSL_DIU
|
|
||||||
select IPIC
|
select IPIC
|
||||||
select PPC_CLOCK
|
select PPC_CLOCK
|
||||||
select PPC_PCI_CHOICE
|
select PPC_PCI_CHOICE
|
||||||
|
@ -42,7 +42,10 @@ static void __init mpc5121_ads_setup_arch(void)
|
|||||||
for_each_compatible_node(np, "pci", "fsl,mpc5121-pci")
|
for_each_compatible_node(np, "pci", "fsl,mpc5121-pci")
|
||||||
mpc83xx_add_bridge(np);
|
mpc83xx_add_bridge(np);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||||
mpc512x_setup_diu();
|
mpc512x_setup_diu();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init mpc5121_ads_init_IRQ(void)
|
static void __init mpc5121_ads_init_IRQ(void)
|
||||||
|
@ -16,6 +16,13 @@ extern void __init mpc512x_init(void);
|
|||||||
extern int __init mpc5121_clk_init(void);
|
extern int __init mpc5121_clk_init(void);
|
||||||
void __init mpc512x_declare_of_platform_devices(void);
|
void __init mpc512x_declare_of_platform_devices(void);
|
||||||
extern void mpc512x_restart(char *cmd);
|
extern void mpc512x_restart(char *cmd);
|
||||||
extern void mpc512x_init_diu(void);
|
|
||||||
extern void mpc512x_setup_diu(void);
|
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||||
|
void mpc512x_init_diu(void);
|
||||||
|
void mpc512x_setup_diu(void);
|
||||||
|
#else
|
||||||
|
#define mpc512x_init_diu NULL
|
||||||
|
#define mpc512x_setup_diu NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __MPC512X_H__ */
|
#endif /* __MPC512X_H__ */
|
||||||
|
@ -58,6 +58,8 @@ void mpc512x_restart(char *cmd)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||||
|
|
||||||
struct fsl_diu_shared_fb {
|
struct fsl_diu_shared_fb {
|
||||||
u8 gamma[0x300]; /* 32-bit aligned! */
|
u8 gamma[0x300]; /* 32-bit aligned! */
|
||||||
struct diu_ad ad0; /* 32-bit aligned! */
|
struct diu_ad ad0; /* 32-bit aligned! */
|
||||||
@ -66,25 +68,6 @@ struct fsl_diu_shared_fb {
|
|||||||
bool in_use;
|
bool in_use;
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 mpc512x_get_pixel_format(enum fsl_diu_monitor_port port,
|
|
||||||
unsigned int bits_per_pixel)
|
|
||||||
{
|
|
||||||
switch (bits_per_pixel) {
|
|
||||||
case 32:
|
|
||||||
return 0x88883316;
|
|
||||||
case 24:
|
|
||||||
return 0x88082219;
|
|
||||||
case 16:
|
|
||||||
return 0x65053118;
|
|
||||||
}
|
|
||||||
return 0x00000400;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mpc512x_set_gamma_table(enum fsl_diu_monitor_port port,
|
|
||||||
char *gamma_table_base)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
|
void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -320,14 +303,14 @@ void __init mpc512x_setup_diu(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diu_ops.get_pixel_format = mpc512x_get_pixel_format;
|
|
||||||
diu_ops.set_gamma_table = mpc512x_set_gamma_table;
|
|
||||||
diu_ops.set_monitor_port = mpc512x_set_monitor_port;
|
diu_ops.set_monitor_port = mpc512x_set_monitor_port;
|
||||||
diu_ops.set_pixel_clock = mpc512x_set_pixel_clock;
|
diu_ops.set_pixel_clock = mpc512x_set_pixel_clock;
|
||||||
diu_ops.valid_monitor_port = mpc512x_valid_monitor_port;
|
diu_ops.valid_monitor_port = mpc512x_valid_monitor_port;
|
||||||
diu_ops.release_bootmem = mpc512x_release_bootmem;
|
diu_ops.release_bootmem = mpc512x_release_bootmem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void __init mpc512x_init_IRQ(void)
|
void __init mpc512x_init_IRQ(void)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* Written by: Grant Likely <grant.likely@secretlab.ca>
|
* Written by: Grant Likely <grant.likely@secretlab.ca>
|
||||||
*
|
*
|
||||||
* Copyright (C) Secret Lab Technologies Ltd. 2006. All rights reserved.
|
* Copyright (C) Secret Lab Technologies Ltd. 2006. All rights reserved.
|
||||||
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
|
* Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void)
|
|||||||
|
|
||||||
/* list of the supported boards */
|
/* list of the supported boards */
|
||||||
static const char *board[] __initdata = {
|
static const char *board[] __initdata = {
|
||||||
|
"anonymous,a3m071",
|
||||||
"anonymous,a4m072",
|
"anonymous,a4m072",
|
||||||
"anon,charon",
|
"anon,charon",
|
||||||
"ifm,o2d",
|
"ifm,o2d",
|
||||||
|
@ -578,18 +578,4 @@ static struct platform_driver mpc52xx_lpbfifo_driver = {
|
|||||||
.probe = mpc52xx_lpbfifo_probe,
|
.probe = mpc52xx_lpbfifo_probe,
|
||||||
.remove = __devexit_p(mpc52xx_lpbfifo_remove),
|
.remove = __devexit_p(mpc52xx_lpbfifo_remove),
|
||||||
};
|
};
|
||||||
|
module_platform_driver(mpc52xx_lpbfifo_driver);
|
||||||
/***********************************************************************
|
|
||||||
* Module init/exit
|
|
||||||
*/
|
|
||||||
static int __init mpc52xx_lpbfifo_init(void)
|
|
||||||
{
|
|
||||||
return platform_driver_register(&mpc52xx_lpbfifo_driver);
|
|
||||||
}
|
|
||||||
module_init(mpc52xx_lpbfifo_init);
|
|
||||||
|
|
||||||
static void __exit mpc52xx_lpbfifo_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&mpc52xx_lpbfifo_driver);
|
|
||||||
}
|
|
||||||
module_exit(mpc52xx_lpbfifo_exit);
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/bootmem.h>
|
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@ -149,7 +148,7 @@ int __init pq2ads_pci_init_irq(void)
|
|||||||
priv->regs = of_iomap(np, 0);
|
priv->regs = of_iomap(np, 0);
|
||||||
if (!priv->regs) {
|
if (!priv->regs) {
|
||||||
printk(KERN_ERR "Cannot map PCI PIC registers.\n");
|
printk(KERN_ERR "Cannot map PCI PIC registers.\n");
|
||||||
goto out_free_bootmem;
|
goto out_free_kmalloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mask all PCI interrupts */
|
/* mask all PCI interrupts */
|
||||||
@ -171,9 +170,8 @@ int __init pq2ads_pci_init_irq(void)
|
|||||||
|
|
||||||
out_unmap_regs:
|
out_unmap_regs:
|
||||||
iounmap(priv->regs);
|
iounmap(priv->regs);
|
||||||
out_free_bootmem:
|
out_free_kmalloc:
|
||||||
free_bootmem((unsigned long)priv,
|
kfree(priv);
|
||||||
sizeof(struct pq2ads_pci_pic));
|
|
||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
out_unmap_irq:
|
out_unmap_irq:
|
||||||
irq_dispose_mapping(irq);
|
irq_dispose_mapping(irq);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
|
* Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* MPC832xE MDS board specific routines.
|
* MPC832xE MDS board specific routines.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
|
* Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Author: Li Yang <LeoLi@freescale.com>
|
* Author: Li Yang <LeoLi@freescale.com>
|
||||||
* Yin Olivia <Hong-hua.Yin@freescale.com>
|
* Yin Olivia <Hong-hua.Yin@freescale.com>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* MPC8360E-RDK board file.
|
* MPC8360E-RDK board file.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Freescale Semicondutor, Inc.
|
* Copyright (c) 2006 Freescale Semiconductor, Inc.
|
||||||
* Copyright (c) 2007-2008 MontaVista Software, Inc.
|
* Copyright (c) 2007-2008 MontaVista Software, Inc.
|
||||||
*
|
*
|
||||||
* Author: Anton Vorontsov <avorontsov@ru.mvista.com>
|
* Author: Anton Vorontsov <avorontsov@ru.mvista.com>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* arch/powerpc/platforms/83xx/mpc837x_rdb.c
|
* arch/powerpc/platforms/83xx/mpc837x_rdb.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* MPC837x RDB board specific routines
|
* MPC837x RDB board specific routines
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2010, 2012 Freescale Semicondutor, Inc.
|
* Copyright (C) 2006-2010, 2012 Freescale Semiconductor, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Author: Andy Fleming <afleming@freescale.com>
|
* Author: Andy Fleming <afleming@freescale.com>
|
||||||
|
@ -249,7 +249,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
iprop = of_get_property(law_node, "fsl,num-laws", 0);
|
iprop = of_get_property(law_node, "fsl,num-laws", NULL);
|
||||||
if (!iprop) {
|
if (!iprop) {
|
||||||
pr_err("p1022ds: LAW node is missing fsl,num-laws property\n");
|
pr_err("p1022ds: LAW node is missing fsl,num-laws property\n");
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -539,7 +539,7 @@ static void __init p1022_ds_setup_arch(void)
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prom_update_property() is called before
|
* of_update_property() is called before
|
||||||
* kmalloc() is available, so the 'new' object
|
* kmalloc() is available, so the 'new' object
|
||||||
* should be allocated in the global area.
|
* should be allocated in the global area.
|
||||||
* The easiest way is to do that is to
|
* The easiest way is to do that is to
|
||||||
@ -548,7 +548,7 @@ static void __init p1022_ds_setup_arch(void)
|
|||||||
*/
|
*/
|
||||||
pr_info("p1022ds: disabling %s node",
|
pr_info("p1022ds: disabling %s node",
|
||||||
np2->full_name);
|
np2->full_name);
|
||||||
prom_update_property(np2, &nor_status);
|
of_update_property(np2, &nor_status);
|
||||||
of_node_put(np2);
|
of_node_put(np2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,7 +564,7 @@ static void __init p1022_ds_setup_arch(void)
|
|||||||
|
|
||||||
pr_info("p1022ds: disabling %s node",
|
pr_info("p1022ds: disabling %s node",
|
||||||
np2->full_name);
|
np2->full_name);
|
||||||
prom_update_property(np2, &nand_status);
|
of_update_property(np2, &nand_status);
|
||||||
of_node_put(np2);
|
of_node_put(np2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +128,19 @@ static void __cpuinit smp_85xx_mach_cpu_die(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void flush_spin_table(void *spin_table)
|
||||||
|
{
|
||||||
|
flush_dcache_range((ulong)spin_table,
|
||||||
|
(ulong)spin_table + sizeof(struct epapr_spin_table));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 read_spin_table_addr_l(void *spin_table)
|
||||||
|
{
|
||||||
|
flush_dcache_range((ulong)spin_table,
|
||||||
|
(ulong)spin_table + sizeof(struct epapr_spin_table));
|
||||||
|
return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
|
||||||
|
}
|
||||||
|
|
||||||
static int __cpuinit smp_85xx_kick_cpu(int nr)
|
static int __cpuinit smp_85xx_kick_cpu(int nr)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -161,8 +174,8 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
|
|||||||
|
|
||||||
/* Map the spin table */
|
/* Map the spin table */
|
||||||
if (ioremappable)
|
if (ioremappable)
|
||||||
spin_table = ioremap(*cpu_rel_addr,
|
spin_table = ioremap_prot(*cpu_rel_addr,
|
||||||
sizeof(struct epapr_spin_table));
|
sizeof(struct epapr_spin_table), _PAGE_COHERENT);
|
||||||
else
|
else
|
||||||
spin_table = phys_to_virt(*cpu_rel_addr);
|
spin_table = phys_to_virt(*cpu_rel_addr);
|
||||||
|
|
||||||
@ -173,7 +186,16 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
|
|||||||
generic_set_cpu_up(nr);
|
generic_set_cpu_up(nr);
|
||||||
|
|
||||||
if (system_state == SYSTEM_RUNNING) {
|
if (system_state == SYSTEM_RUNNING) {
|
||||||
|
/*
|
||||||
|
* To keep it compatible with old boot program which uses
|
||||||
|
* cache-inhibit spin table, we need to flush the cache
|
||||||
|
* before accessing spin table to invalidate any staled data.
|
||||||
|
* We also need to flush the cache after writing to spin
|
||||||
|
* table to push data out.
|
||||||
|
*/
|
||||||
|
flush_spin_table(spin_table);
|
||||||
out_be32(&spin_table->addr_l, 0);
|
out_be32(&spin_table->addr_l, 0);
|
||||||
|
flush_spin_table(spin_table);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't set the BPTR register here since it already points
|
* We don't set the BPTR register here since it already points
|
||||||
@ -181,9 +203,14 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
|
|||||||
*/
|
*/
|
||||||
mpic_reset_core(hw_cpu);
|
mpic_reset_core(hw_cpu);
|
||||||
|
|
||||||
/* wait until core is ready... */
|
/*
|
||||||
if (!spin_event_timeout(in_be32(&spin_table->addr_l) == 1,
|
* wait until core is ready...
|
||||||
10000, 100)) {
|
* We need to invalidate the stale data, in case the boot
|
||||||
|
* loader uses a cache-inhibited spin table.
|
||||||
|
*/
|
||||||
|
if (!spin_event_timeout(
|
||||||
|
read_spin_table_addr_l(spin_table) == 1,
|
||||||
|
10000, 100)) {
|
||||||
pr_err("%s: timeout waiting for core %d to reset\n",
|
pr_err("%s: timeout waiting for core %d to reset\n",
|
||||||
__func__, hw_cpu);
|
__func__, hw_cpu);
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
@ -194,12 +221,10 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
|
|||||||
__secondary_hold_acknowledge = -1;
|
__secondary_hold_acknowledge = -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
flush_spin_table(spin_table);
|
||||||
out_be32(&spin_table->pir, hw_cpu);
|
out_be32(&spin_table->pir, hw_cpu);
|
||||||
out_be32(&spin_table->addr_l, __pa(__early_start));
|
out_be32(&spin_table->addr_l, __pa(__early_start));
|
||||||
|
flush_spin_table(spin_table);
|
||||||
if (!ioremappable)
|
|
||||||
flush_dcache_range((ulong)spin_table,
|
|
||||||
(ulong)spin_table + sizeof(struct epapr_spin_table));
|
|
||||||
|
|
||||||
/* Wait a bit for the CPU to ack. */
|
/* Wait a bit for the CPU to ack. */
|
||||||
if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
|
if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
|
||||||
@ -213,13 +238,11 @@ out:
|
|||||||
#else
|
#else
|
||||||
smp_generic_kick_cpu(nr);
|
smp_generic_kick_cpu(nr);
|
||||||
|
|
||||||
|
flush_spin_table(spin_table);
|
||||||
out_be32(&spin_table->pir, hw_cpu);
|
out_be32(&spin_table->pir, hw_cpu);
|
||||||
out_be64((u64 *)(&spin_table->addr_h),
|
out_be64((u64 *)(&spin_table->addr_h),
|
||||||
__pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
|
__pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
|
||||||
|
flush_spin_table(spin_table);
|
||||||
if (!ioremappable)
|
|
||||||
flush_dcache_range((ulong)spin_table,
|
|
||||||
(ulong)spin_table + sizeof(struct epapr_spin_table));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
@ -353,5 +353,7 @@ define_machine(mpc86xx_hpcd) {
|
|||||||
.time_init = mpc86xx_time_init,
|
.time_init = mpc86xx_time_init,
|
||||||
.calibrate_decr = generic_calibrate_decr,
|
.calibrate_decr = generic_calibrate_decr,
|
||||||
.progress = udbg_progress,
|
.progress = udbg_progress,
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -55,6 +55,7 @@ static unsigned int low_freq;
|
|||||||
static unsigned int hi_freq;
|
static unsigned int hi_freq;
|
||||||
static unsigned int cur_freq;
|
static unsigned int cur_freq;
|
||||||
static unsigned int sleep_freq;
|
static unsigned int sleep_freq;
|
||||||
|
static unsigned long transition_latency;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Different models uses different mechanisms to switch the frequency
|
* Different models uses different mechanisms to switch the frequency
|
||||||
@ -403,7 +404,7 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
|||||||
if (policy->cpu != 0)
|
if (policy->cpu != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
|
policy->cpuinfo.transition_latency = transition_latency;
|
||||||
policy->cur = cur_freq;
|
policy->cur = cur_freq;
|
||||||
|
|
||||||
cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
|
cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
|
||||||
@ -658,12 +659,14 @@ static int __init pmac_cpufreq_setup(void)
|
|||||||
if (!value)
|
if (!value)
|
||||||
goto out;
|
goto out;
|
||||||
cur_freq = (*value) / 1000;
|
cur_freq = (*value) / 1000;
|
||||||
|
transition_latency = CPUFREQ_ETERNAL;
|
||||||
|
|
||||||
/* Check for 7447A based MacRISC3 */
|
/* Check for 7447A based MacRISC3 */
|
||||||
if (of_machine_is_compatible("MacRISC3") &&
|
if (of_machine_is_compatible("MacRISC3") &&
|
||||||
of_get_property(cpunode, "dynamic-power-step", NULL) &&
|
of_get_property(cpunode, "dynamic-power-step", NULL) &&
|
||||||
PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
|
PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
|
||||||
pmac_cpufreq_init_7447A(cpunode);
|
pmac_cpufreq_init_7447A(cpunode);
|
||||||
|
transition_latency = 8000000;
|
||||||
/* Check for other MacRISC3 machines */
|
/* Check for other MacRISC3 machines */
|
||||||
} else if (of_machine_is_compatible("PowerBook3,4") ||
|
} else if (of_machine_is_compatible("PowerBook3,4") ||
|
||||||
of_machine_is_compatible("PowerBook3,5") ||
|
of_machine_is_compatible("PowerBook3,5") ||
|
||||||
|
@ -34,24 +34,12 @@
|
|||||||
#include "powernv.h"
|
#include "powernv.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
|
||||||
static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe,
|
|
||||||
struct va_format *vaf)
|
|
||||||
{
|
|
||||||
char pfix[32];
|
|
||||||
|
|
||||||
if (pe->pdev)
|
|
||||||
strlcpy(pfix, dev_name(&pe->pdev->dev), sizeof(pfix));
|
|
||||||
else
|
|
||||||
sprintf(pfix, "%04x:%02x ",
|
|
||||||
pci_domain_nr(pe->pbus), pe->pbus->number);
|
|
||||||
return printk("pci %s%s: [PE# %.3d] %pV", level, pfix, pe->pe_number, vaf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define define_pe_printk_level(func, kern_level) \
|
#define define_pe_printk_level(func, kern_level) \
|
||||||
static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \
|
static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \
|
||||||
{ \
|
{ \
|
||||||
struct va_format vaf; \
|
struct va_format vaf; \
|
||||||
va_list args; \
|
va_list args; \
|
||||||
|
char pfix[32]; \
|
||||||
int r; \
|
int r; \
|
||||||
\
|
\
|
||||||
va_start(args, fmt); \
|
va_start(args, fmt); \
|
||||||
@ -59,7 +47,16 @@ static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \
|
|||||||
vaf.fmt = fmt; \
|
vaf.fmt = fmt; \
|
||||||
vaf.va = &args; \
|
vaf.va = &args; \
|
||||||
\
|
\
|
||||||
r = __pe_printk(kern_level, pe, &vaf); \
|
if (pe->pdev) \
|
||||||
|
strlcpy(pfix, dev_name(&pe->pdev->dev), \
|
||||||
|
sizeof(pfix)); \
|
||||||
|
else \
|
||||||
|
sprintf(pfix, "%04x:%02x ", \
|
||||||
|
pci_domain_nr(pe->pbus), \
|
||||||
|
pe->pbus->number); \
|
||||||
|
r = printk(kern_level "pci %s: [PE# %.3d] %pV", \
|
||||||
|
pfix, pe->pe_number, &vaf); \
|
||||||
|
\
|
||||||
va_end(args); \
|
va_end(args); \
|
||||||
\
|
\
|
||||||
return r; \
|
return r; \
|
||||||
|
@ -280,13 +280,13 @@ static void os_area_set_property(struct device_node *node,
|
|||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name);
|
pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name);
|
||||||
prom_remove_property(node, tmp);
|
of_remove_property(node, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = prom_add_property(node, prop);
|
result = of_add_property(node, prop);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
pr_debug("%s:%d prom_set_property failed\n", __func__,
|
pr_debug("%s:%d of_set_property failed\n", __func__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,17 +13,16 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/kref.h>
|
#include <linux/kref.h>
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/proc_fs.h>
|
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include "offline_states.h"
|
#include "offline_states.h"
|
||||||
|
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
|
|
||||||
struct cc_workarea {
|
struct cc_workarea {
|
||||||
u32 drc_index;
|
u32 drc_index;
|
||||||
@ -255,9 +254,6 @@ static struct device_node *derive_parent(const char *path)
|
|||||||
|
|
||||||
int dlpar_attach_node(struct device_node *dn)
|
int dlpar_attach_node(struct device_node *dn)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PROC_DEVICETREE
|
|
||||||
struct proc_dir_entry *ent;
|
|
||||||
#endif
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
of_node_set_flag(dn, OF_DYNAMIC);
|
of_node_set_flag(dn, OF_DYNAMIC);
|
||||||
@ -266,44 +262,26 @@ int dlpar_attach_node(struct device_node *dn)
|
|||||||
if (!dn->parent)
|
if (!dn->parent)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rc = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, dn);
|
rc = of_attach_node(dn);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "Failed to add device node %s\n",
|
printk(KERN_ERR "Failed to add device node %s\n",
|
||||||
dn->full_name);
|
dn->full_name);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_attach_node(dn);
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_DEVICETREE
|
|
||||||
ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
|
|
||||||
if (ent)
|
|
||||||
proc_device_tree_add_node(dn, ent);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
of_node_put(dn->parent);
|
of_node_put(dn->parent);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dlpar_detach_node(struct device_node *dn)
|
int dlpar_detach_node(struct device_node *dn)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PROC_DEVICETREE
|
int rc;
|
||||||
struct device_node *parent = dn->parent;
|
|
||||||
struct property *prop = dn->properties;
|
|
||||||
|
|
||||||
while (prop) {
|
rc = of_detach_node(dn);
|
||||||
remove_proc_entry(prop->name, dn->pde);
|
if (rc)
|
||||||
prop = prop->next;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
if (dn->pde)
|
|
||||||
remove_proc_entry(dn->pde->name, parent->pde);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, dn);
|
|
||||||
of_detach_node(dn);
|
|
||||||
of_node_put(dn); /* Must decrement the refcount */
|
of_node_put(dn); /* Must decrement the refcount */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
|
|||||||
{FW_FEATURE_MULTITCE, "hcall-multi-tce"},
|
{FW_FEATURE_MULTITCE, "hcall-multi-tce"},
|
||||||
{FW_FEATURE_SPLPAR, "hcall-splpar"},
|
{FW_FEATURE_SPLPAR, "hcall-splpar"},
|
||||||
{FW_FEATURE_VPHN, "hcall-vphn"},
|
{FW_FEATURE_VPHN, "hcall-vphn"},
|
||||||
|
{FW_FEATURE_SET_MODE, "hcall-set-mode"},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Build up the firmware features bitmask using the contents of
|
/* Build up the firmware features bitmask using the contents of
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/sched.h> /* for idle_task_exit */
|
#include <linux/sched.h> /* for idle_task_exit */
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/vdso_datapage.h>
|
#include <asm/vdso_datapage.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
#include <asm/xics.h>
|
#include <asm/xics.h>
|
||||||
#include "plpar_wrappers.h"
|
#include "plpar_wrappers.h"
|
||||||
#include "offline_states.h"
|
#include "offline_states.h"
|
||||||
@ -333,10 +333,10 @@ static int pseries_smp_notifier(struct notifier_block *nb,
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case PSERIES_RECONFIG_ADD:
|
case OF_RECONFIG_ATTACH_NODE:
|
||||||
err = pseries_add_processor(node);
|
err = pseries_add_processor(node);
|
||||||
break;
|
break;
|
||||||
case PSERIES_RECONFIG_REMOVE:
|
case OF_RECONFIG_DETACH_NODE:
|
||||||
pseries_remove_processor(node);
|
pseries_remove_processor(node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -399,7 +399,7 @@ static int __init pseries_cpu_hotplug_init(void)
|
|||||||
|
|
||||||
/* Processors can be added/removed only on LPAR */
|
/* Processors can be added/removed only on LPAR */
|
||||||
if (firmware_has_feature(FW_FEATURE_LPAR)) {
|
if (firmware_has_feature(FW_FEATURE_LPAR)) {
|
||||||
pSeries_reconfig_notifier_register(&pseries_smp_nb);
|
of_reconfig_notifier_register(&pseries_smp_nb);
|
||||||
cpu_maps_update_begin();
|
cpu_maps_update_begin();
|
||||||
if (cede_offline_enabled && parse_cede_parameters() == 0) {
|
if (cede_offline_enabled && parse_cede_parameters() == 0) {
|
||||||
default_offline_state = CPU_STATE_INACTIVE;
|
default_offline_state = CPU_STATE_INACTIVE;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
#include <asm/sparsemem.h>
|
#include <asm/sparsemem.h>
|
||||||
|
|
||||||
static unsigned long get_memblock_size(void)
|
static unsigned long get_memblock_size(void)
|
||||||
@ -187,42 +186,69 @@ static int pseries_add_memory(struct device_node *np)
|
|||||||
return (ret < 0) ? -EINVAL : 0;
|
return (ret < 0) ? -EINVAL : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pseries_drconf_memory(unsigned long *base, unsigned int action)
|
static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
|
||||||
{
|
{
|
||||||
|
struct of_drconf_cell *new_drmem, *old_drmem;
|
||||||
unsigned long memblock_size;
|
unsigned long memblock_size;
|
||||||
int rc;
|
u32 entries;
|
||||||
|
u32 *p;
|
||||||
|
int i, rc = -EINVAL;
|
||||||
|
|
||||||
memblock_size = get_memblock_size();
|
memblock_size = get_memblock_size();
|
||||||
if (!memblock_size)
|
if (!memblock_size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (action == PSERIES_DRCONF_MEM_ADD) {
|
p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL);
|
||||||
rc = memblock_add(*base, memblock_size);
|
if (!p)
|
||||||
rc = (rc < 0) ? -EINVAL : 0;
|
return -EINVAL;
|
||||||
} else if (action == PSERIES_DRCONF_MEM_REMOVE) {
|
|
||||||
rc = pseries_remove_memblock(*base, memblock_size);
|
/* The first int of the property is the number of lmb's described
|
||||||
} else {
|
* by the property. This is followed by an array of of_drconf_cell
|
||||||
rc = -EINVAL;
|
* entries. Get the niumber of entries and skip to the array of
|
||||||
|
* of_drconf_cell's.
|
||||||
|
*/
|
||||||
|
entries = *p++;
|
||||||
|
old_drmem = (struct of_drconf_cell *)p;
|
||||||
|
|
||||||
|
p = (u32 *)pr->prop->value;
|
||||||
|
p++;
|
||||||
|
new_drmem = (struct of_drconf_cell *)p;
|
||||||
|
|
||||||
|
for (i = 0; i < entries; i++) {
|
||||||
|
if ((old_drmem[i].flags & DRCONF_MEM_ASSIGNED) &&
|
||||||
|
(!(new_drmem[i].flags & DRCONF_MEM_ASSIGNED))) {
|
||||||
|
rc = pseries_remove_memblock(old_drmem[i].base_addr,
|
||||||
|
memblock_size);
|
||||||
|
break;
|
||||||
|
} else if ((!(old_drmem[i].flags & DRCONF_MEM_ASSIGNED)) &&
|
||||||
|
(new_drmem[i].flags & DRCONF_MEM_ASSIGNED)) {
|
||||||
|
rc = memblock_add(old_drmem[i].base_addr,
|
||||||
|
memblock_size);
|
||||||
|
rc = (rc < 0) ? -EINVAL : 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pseries_memory_notifier(struct notifier_block *nb,
|
static int pseries_memory_notifier(struct notifier_block *nb,
|
||||||
unsigned long action, void *node)
|
unsigned long action, void *node)
|
||||||
{
|
{
|
||||||
|
struct of_prop_reconfig *pr;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case PSERIES_RECONFIG_ADD:
|
case OF_RECONFIG_ATTACH_NODE:
|
||||||
err = pseries_add_memory(node);
|
err = pseries_add_memory(node);
|
||||||
break;
|
break;
|
||||||
case PSERIES_RECONFIG_REMOVE:
|
case OF_RECONFIG_DETACH_NODE:
|
||||||
err = pseries_remove_memory(node);
|
err = pseries_remove_memory(node);
|
||||||
break;
|
break;
|
||||||
case PSERIES_DRCONF_MEM_ADD:
|
case OF_RECONFIG_UPDATE_PROPERTY:
|
||||||
case PSERIES_DRCONF_MEM_REMOVE:
|
pr = (struct of_prop_reconfig *)node;
|
||||||
err = pseries_drconf_memory(node, action);
|
if (!strcmp(pr->prop->name, "ibm,dynamic-memory"))
|
||||||
|
err = pseries_update_drconf_memory(pr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return notifier_from_errno(err);
|
return notifier_from_errno(err);
|
||||||
@ -235,7 +261,7 @@ static struct notifier_block pseries_mem_nb = {
|
|||||||
static int __init pseries_memory_hotplug_init(void)
|
static int __init pseries_memory_hotplug_init(void)
|
||||||
{
|
{
|
||||||
if (firmware_has_feature(FW_FEATURE_LPAR))
|
if (firmware_has_feature(FW_FEATURE_LPAR))
|
||||||
pSeries_reconfig_notifier_register(&pseries_mem_nb);
|
of_reconfig_notifier_register(&pseries_mem_nb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,13 @@
|
|||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/crash_dump.h>
|
#include <linux/crash_dump.h>
|
||||||
#include <linux/memory.h>
|
#include <linux/memory.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
#include <asm/iommu.h>
|
#include <asm/iommu.h>
|
||||||
#include <asm/pci-bridge.h>
|
#include <asm/pci-bridge.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/tce.h>
|
#include <asm/tce.h>
|
||||||
#include <asm/ppc-pci.h>
|
#include <asm/ppc-pci.h>
|
||||||
@ -760,7 +760,7 @@ static void remove_ddw(struct device_node *np)
|
|||||||
__remove_ddw(np, ddw_avail, liobn);
|
__remove_ddw(np, ddw_avail, liobn);
|
||||||
|
|
||||||
delprop:
|
delprop:
|
||||||
ret = prom_remove_property(np, win64);
|
ret = of_remove_property(np, win64);
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warning("%s: failed to remove direct window property: %d\n",
|
pr_warning("%s: failed to remove direct window property: %d\n",
|
||||||
np->full_name, ret);
|
np->full_name, ret);
|
||||||
@ -1070,7 +1070,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
|
|||||||
goto out_free_window;
|
goto out_free_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = prom_add_property(pdn, win64);
|
ret = of_add_property(pdn, win64);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&dev->dev, "unable to add dma window property for %s: %d",
|
dev_err(&dev->dev, "unable to add dma window property for %s: %d",
|
||||||
pdn->full_name, ret);
|
pdn->full_name, ret);
|
||||||
@ -1294,7 +1294,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
|
|||||||
struct direct_window *window;
|
struct direct_window *window;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case PSERIES_RECONFIG_REMOVE:
|
case OF_RECONFIG_DETACH_NODE:
|
||||||
if (pci && pci->iommu_table)
|
if (pci && pci->iommu_table)
|
||||||
iommu_free_table(pci->iommu_table, np->full_name);
|
iommu_free_table(pci->iommu_table, np->full_name);
|
||||||
|
|
||||||
@ -1357,7 +1357,7 @@ void iommu_init_early_pSeries(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
|
of_reconfig_notifier_register(&iommu_reconfig_nb);
|
||||||
register_memory_notifier(&iommu_mem_nb);
|
register_memory_notifier(&iommu_mem_nb);
|
||||||
|
|
||||||
set_pci_dma_ops(&dma_iommu_ops);
|
set_pci_dma_ops(&dma_iommu_ops);
|
||||||
|
@ -116,7 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!more) {
|
if (!more) {
|
||||||
prom_update_property(dn, new_prop);
|
of_update_property(dn, new_prop);
|
||||||
new_prop = NULL;
|
new_prop = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ static int update_dt_node(u32 phandle)
|
|||||||
|
|
||||||
case 0x80000000:
|
case 0x80000000:
|
||||||
prop = of_find_property(dn, prop_name, NULL);
|
prop = of_find_property(dn, prop_name, NULL);
|
||||||
prom_remove_property(dn, prop);
|
of_remove_property(dn, prop);
|
||||||
prop = NULL;
|
prop = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -273,4 +273,35 @@ static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
|
|||||||
lbuf[1]);
|
lbuf[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set various resource mode parameters */
|
||||||
|
static inline long plpar_set_mode(unsigned long mflags, unsigned long resource,
|
||||||
|
unsigned long value1, unsigned long value2)
|
||||||
|
{
|
||||||
|
return plpar_hcall_norets(H_SET_MODE, mflags, resource, value1, value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable relocation on exceptions on this partition
|
||||||
|
*
|
||||||
|
* Note: this call has a partition wide scope and can take a while to complete.
|
||||||
|
* If it returns H_LONG_BUSY_* it should be retried periodically until it
|
||||||
|
* returns H_SUCCESS.
|
||||||
|
*/
|
||||||
|
static inline long enable_reloc_on_exceptions(void)
|
||||||
|
{
|
||||||
|
/* mflags = 3: Exceptions at 0xC000000000004000 */
|
||||||
|
return plpar_set_mode(3, 3, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable relocation on exceptions on this partition
|
||||||
|
*
|
||||||
|
* Note: this call has a partition wide scope and can take a while to complete.
|
||||||
|
* If it returns H_LONG_BUSY_* it should be retried periodically until it
|
||||||
|
* returns H_SUCCESS.
|
||||||
|
*/
|
||||||
|
static inline long disable_reloc_on_exceptions(void) {
|
||||||
|
return plpar_set_mode(0, 3, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _PSERIES_PLPAR_WRAPPERS_H */
|
#endif /* _PSERIES_PLPAR_WRAPPERS_H */
|
||||||
|
@ -16,55 +16,13 @@
|
|||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Routines for "runtime" addition and removal of device tree nodes.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_PROC_DEVICETREE
|
|
||||||
/*
|
|
||||||
* Add a node to /proc/device-tree.
|
|
||||||
*/
|
|
||||||
static void add_node_proc_entries(struct device_node *np)
|
|
||||||
{
|
|
||||||
struct proc_dir_entry *ent;
|
|
||||||
|
|
||||||
ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
|
|
||||||
if (ent)
|
|
||||||
proc_device_tree_add_node(np, ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_node_proc_entries(struct device_node *np)
|
|
||||||
{
|
|
||||||
struct property *pp = np->properties;
|
|
||||||
struct device_node *parent = np->parent;
|
|
||||||
|
|
||||||
while (pp) {
|
|
||||||
remove_proc_entry(pp->name, np->pde);
|
|
||||||
pp = pp->next;
|
|
||||||
}
|
|
||||||
if (np->pde)
|
|
||||||
remove_proc_entry(np->pde->name, parent->pde);
|
|
||||||
}
|
|
||||||
#else /* !CONFIG_PROC_DEVICETREE */
|
|
||||||
static void add_node_proc_entries(struct device_node *np)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_node_proc_entries(struct device_node *np)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_PROC_DEVICETREE */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* derive_parent - basically like dirname(1)
|
* derive_parent - basically like dirname(1)
|
||||||
* @path: the full_name of a node to be added to the tree
|
* @path: the full_name of a node to be added to the tree
|
||||||
@ -97,28 +55,6 @@ static struct device_node *derive_parent(const char *path)
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
|
|
||||||
|
|
||||||
int pSeries_reconfig_notifier_register(struct notifier_block *nb)
|
|
||||||
{
|
|
||||||
return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_register);
|
|
||||||
|
|
||||||
void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
|
|
||||||
{
|
|
||||||
blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_unregister);
|
|
||||||
|
|
||||||
int pSeries_reconfig_notify(unsigned long action, void *p)
|
|
||||||
{
|
|
||||||
int err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
|
|
||||||
action, p);
|
|
||||||
|
|
||||||
return notifier_to_errno(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
|
static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
@ -142,16 +78,12 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
|
|||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, np);
|
err = of_attach_node(np);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "Failed to add device node %s\n", path);
|
printk(KERN_ERR "Failed to add device node %s\n", path);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_attach_node(np);
|
|
||||||
|
|
||||||
add_node_proc_entries(np);
|
|
||||||
|
|
||||||
of_node_put(np->parent);
|
of_node_put(np->parent);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -179,11 +111,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_node_proc_entries(np);
|
|
||||||
|
|
||||||
pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, np);
|
|
||||||
of_detach_node(np);
|
of_detach_node(np);
|
||||||
|
|
||||||
of_node_put(parent);
|
of_node_put(parent);
|
||||||
of_node_put(np); /* Must decrement the refcount */
|
of_node_put(np); /* Must decrement the refcount */
|
||||||
return 0;
|
return 0;
|
||||||
@ -397,7 +325,7 @@ static int do_add_property(char *buf, size_t bufsize)
|
|||||||
if (!prop)
|
if (!prop)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
prom_add_property(np, prop);
|
of_add_property(np, prop);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -421,16 +349,15 @@ static int do_remove_property(char *buf, size_t bufsize)
|
|||||||
|
|
||||||
prop = of_find_property(np, buf, NULL);
|
prop = of_find_property(np, buf, NULL);
|
||||||
|
|
||||||
return prom_remove_property(np, prop);
|
return of_remove_property(np, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_update_property(char *buf, size_t bufsize)
|
static int do_update_property(char *buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
struct pSeries_reconfig_prop_update upd_value;
|
|
||||||
unsigned char *value;
|
unsigned char *value;
|
||||||
char *name, *end, *next_prop;
|
char *name, *end, *next_prop;
|
||||||
int rc, length;
|
int length;
|
||||||
struct property *newprop;
|
struct property *newprop;
|
||||||
buf = parse_node(buf, bufsize, &np);
|
buf = parse_node(buf, bufsize, &np);
|
||||||
end = buf + bufsize;
|
end = buf + bufsize;
|
||||||
@ -452,41 +379,7 @@ static int do_update_property(char *buf, size_t bufsize)
|
|||||||
if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
|
if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
|
||||||
slb_set_size(*(int *)value);
|
slb_set_size(*(int *)value);
|
||||||
|
|
||||||
upd_value.node = np;
|
return of_update_property(np, newprop);
|
||||||
upd_value.property = newprop;
|
|
||||||
pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value);
|
|
||||||
|
|
||||||
rc = prom_update_property(np, newprop);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/* For memory under the ibm,dynamic-reconfiguration-memory node
|
|
||||||
* of the device tree, adding and removing memory is just an update
|
|
||||||
* to the ibm,dynamic-memory property instead of adding/removing a
|
|
||||||
* memory node in the device tree. For these cases we still need to
|
|
||||||
* involve the notifier chain.
|
|
||||||
*/
|
|
||||||
if (!strcmp(name, "ibm,dynamic-memory")) {
|
|
||||||
int action;
|
|
||||||
|
|
||||||
next_prop = parse_next_property(next_prop, end, &name,
|
|
||||||
&length, &value);
|
|
||||||
if (!next_prop)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!strcmp(name, "add"))
|
|
||||||
action = PSERIES_DRCONF_MEM_ADD;
|
|
||||||
else
|
|
||||||
action = PSERIES_DRCONF_MEM_REMOVE;
|
|
||||||
|
|
||||||
rc = pSeries_reconfig_notify(action, value);
|
|
||||||
if (rc) {
|
|
||||||
prom_update_property(np, newprop);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/root_dev.h>
|
#include <linux/root_dev.h>
|
||||||
#include <linux/cpuidle.h>
|
#include <linux/cpuidle.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/kexec.h>
|
||||||
|
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
@ -63,7 +65,6 @@
|
|||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/eeh.h>
|
#include <asm/eeh.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
|
|
||||||
#include "plpar_wrappers.h"
|
#include "plpar_wrappers.h"
|
||||||
#include "pseries.h"
|
#include "pseries.h"
|
||||||
@ -258,7 +259,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act
|
|||||||
int err = NOTIFY_OK;
|
int err = NOTIFY_OK;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case PSERIES_RECONFIG_ADD:
|
case OF_RECONFIG_ATTACH_NODE:
|
||||||
pci = np->parent->data;
|
pci = np->parent->data;
|
||||||
if (pci) {
|
if (pci) {
|
||||||
update_dn_pci_info(np, pci->phb);
|
update_dn_pci_info(np, pci->phb);
|
||||||
@ -367,6 +368,65 @@ static void pSeries_idle(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable relocation on during exceptions. This has partition wide scope and
|
||||||
|
* may take a while to complete, if it takes longer than one second we will
|
||||||
|
* just give up rather than wasting any more time on this - if that turns out
|
||||||
|
* to ever be a problem in practice we can move this into a kernel thread to
|
||||||
|
* finish off the process later in boot.
|
||||||
|
*/
|
||||||
|
static int __init pSeries_enable_reloc_on_exc(void)
|
||||||
|
{
|
||||||
|
long rc;
|
||||||
|
unsigned int delay, total_delay = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
rc = enable_reloc_on_exceptions();
|
||||||
|
if (!H_IS_LONG_BUSY(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
delay = get_longbusy_msecs(rc);
|
||||||
|
total_delay += delay;
|
||||||
|
if (total_delay > 1000) {
|
||||||
|
pr_warn("Warning: Giving up waiting to enable "
|
||||||
|
"relocation on exceptions (%u msec)!\n",
|
||||||
|
total_delay);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdelay(delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
static long pSeries_disable_reloc_on_exc(void)
|
||||||
|
{
|
||||||
|
long rc;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
rc = disable_reloc_on_exceptions();
|
||||||
|
if (!H_IS_LONG_BUSY(rc))
|
||||||
|
return rc;
|
||||||
|
mdelay(get_longbusy_msecs(rc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pSeries_machine_kexec(struct kimage *image)
|
||||||
|
{
|
||||||
|
long rc;
|
||||||
|
|
||||||
|
if (firmware_has_feature(FW_FEATURE_SET_MODE) &&
|
||||||
|
(image->type != KEXEC_TYPE_CRASH)) {
|
||||||
|
rc = pSeries_disable_reloc_on_exc();
|
||||||
|
if (rc != H_SUCCESS)
|
||||||
|
pr_warning("Warning: Failed to disable relocation on "
|
||||||
|
"exceptions: %ld\n", rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
default_machine_kexec(image);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void __init pSeries_setup_arch(void)
|
static void __init pSeries_setup_arch(void)
|
||||||
{
|
{
|
||||||
panic_timeout = 10;
|
panic_timeout = 10;
|
||||||
@ -389,7 +449,7 @@ static void __init pSeries_setup_arch(void)
|
|||||||
/* Find and initialize PCI host bridges */
|
/* Find and initialize PCI host bridges */
|
||||||
init_pci_config_tokens();
|
init_pci_config_tokens();
|
||||||
find_and_init_phbs();
|
find_and_init_phbs();
|
||||||
pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
|
of_reconfig_notifier_register(&pci_dn_reconfig_nb);
|
||||||
|
|
||||||
pSeries_nvram_init();
|
pSeries_nvram_init();
|
||||||
|
|
||||||
@ -402,6 +462,14 @@ static void __init pSeries_setup_arch(void)
|
|||||||
ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
|
ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
|
||||||
else
|
else
|
||||||
ppc_md.enable_pmcs = power4_enable_pmcs;
|
ppc_md.enable_pmcs = power4_enable_pmcs;
|
||||||
|
|
||||||
|
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
|
||||||
|
long rc;
|
||||||
|
if ((rc = pSeries_enable_reloc_on_exc()) != H_SUCCESS) {
|
||||||
|
pr_warn("Unable to enable relocation on exceptions: "
|
||||||
|
"%ld\n", rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init pSeries_init_panel(void)
|
static int __init pSeries_init_panel(void)
|
||||||
@ -659,4 +727,7 @@ define_machine(pseries) {
|
|||||||
.progress = rtas_progress,
|
.progress = rtas_progress,
|
||||||
.system_reset_exception = pSeries_system_reset_exception,
|
.system_reset_exception = pSeries_system_reset_exception,
|
||||||
.machine_check_exception = pSeries_machine_check_exception,
|
.machine_check_exception = pSeries_machine_check_exception,
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.machine_kexec = pSeries_machine_kexec,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
#include <asm/mpic.h>
|
#include <asm/mpic.h>
|
||||||
#include <asm/vdso_datapage.h>
|
#include <asm/vdso_datapage.h>
|
||||||
#include <asm/cputhreads.h>
|
#include <asm/cputhreads.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Freescale General-purpose Timers Module
|
* Freescale General-purpose Timers Module
|
||||||
*
|
*
|
||||||
* Copyright (c) Freescale Semicondutor, Inc. 2006.
|
* Copyright (c) Freescale Semiconductor, Inc. 2006.
|
||||||
* Shlomi Gridish <gridish@freescale.com>
|
* Shlomi Gridish <gridish@freescale.com>
|
||||||
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
||||||
* Copyright (c) MontaVista Software, Inc. 2008.
|
* Copyright (c) MontaVista Software, Inc. 2008.
|
||||||
|
@ -89,7 +89,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
|
static int setup_one_atmu(struct ccsr_pci __iomem *pci,
|
||||||
unsigned int index, const struct resource *res,
|
unsigned int index, const struct resource *res,
|
||||||
resource_size_t offset)
|
resource_size_t offset)
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* atmu setup for fsl pci/pcie controller */
|
/* atmu setup for fsl pci/pcie controller */
|
||||||
static void __init setup_pci_atmu(struct pci_controller *hose,
|
static void setup_pci_atmu(struct pci_controller *hose,
|
||||||
struct resource *rsrc)
|
struct resource *rsrc)
|
||||||
{
|
{
|
||||||
struct ccsr_pci __iomem *pci;
|
struct ccsr_pci __iomem *pci;
|
||||||
@ -902,9 +902,42 @@ static int __devinit fsl_pci_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int fsl_pci_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct pci_controller *hose;
|
||||||
|
struct resource pci_rsrc;
|
||||||
|
|
||||||
|
hose = pci_find_hose_for_OF_device(dev->of_node);
|
||||||
|
if (!hose)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
|
||||||
|
dev_err(dev, "Get pci register base failed.");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pci_atmu(hose, &pci_rsrc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dev_pm_ops pci_pm_ops = {
|
||||||
|
.resume = fsl_pci_resume,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PCI_PM_OPS (&pci_pm_ops)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define PCI_PM_OPS NULL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct platform_driver fsl_pci_driver = {
|
static struct platform_driver fsl_pci_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "fsl-pci",
|
.name = "fsl-pci",
|
||||||
|
.pm = PCI_PM_OPS,
|
||||||
.of_match_table = pci_ids,
|
.of_match_table = pci_ids,
|
||||||
},
|
},
|
||||||
.probe = fsl_pci_probe,
|
.probe = fsl_pci_probe,
|
||||||
|
@ -214,18 +214,7 @@ static struct platform_driver pmi_of_platform_driver = {
|
|||||||
.of_match_table = pmi_match,
|
.of_match_table = pmi_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
module_platform_driver(pmi_of_platform_driver);
|
||||||
static int __init pmi_module_init(void)
|
|
||||||
{
|
|
||||||
return platform_driver_register(&pmi_of_platform_driver);
|
|
||||||
}
|
|
||||||
module_init(pmi_module_init);
|
|
||||||
|
|
||||||
static void __exit pmi_module_exit(void)
|
|
||||||
{
|
|
||||||
platform_driver_unregister(&pmi_of_platform_driver);
|
|
||||||
}
|
|
||||||
module_exit(pmi_module_exit);
|
|
||||||
|
|
||||||
int pmi_send_message(pmi_message_t msg)
|
int pmi_send_message(pmi_message_t msg)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2010 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* arch/powerpc/sysdev/qe_lib/qe_ic.c
|
* arch/powerpc/sysdev/qe_lib/qe_ic.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Author: Li Yang <leoli@freescale.com>
|
* Author: Li Yang <leoli@freescale.com>
|
||||||
* Based on code from Shlomi Gridish <gridish@freescale.com>
|
* Based on code from Shlomi Gridish <gridish@freescale.com>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* QUICC ENGINE Interrupt Controller Header
|
* QUICC ENGINE Interrupt Controller Header
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Author: Li Yang <leoli@freescale.com>
|
* Author: Li Yang <leoli@freescale.com>
|
||||||
* Based on code from Shlomi Gridish <gridish@freescale.com>
|
* Based on code from Shlomi Gridish <gridish@freescale.com>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* QE Parallel I/O ports configuration routines
|
* QE Parallel I/O ports configuration routines
|
||||||
*
|
*
|
||||||
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
|
* Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Author: Li Yang <LeoLi@freescale.com>
|
* Author: Li Yang <LeoLi@freescale.com>
|
||||||
* Based on code from Shlomi Gridish <gridish@freescale.com>
|
* Based on code from Shlomi Gridish <gridish@freescale.com>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* QE UCC API Set - UCC specific routines implementations.
|
* QE UCC API Set - UCC specific routines implementations.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
|
* Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Authors: Shlomi Gridish <gridish@freescale.com>
|
* Authors: Shlomi Gridish <gridish@freescale.com>
|
||||||
* Li Yang <leoli@freescale.com>
|
* Li Yang <leoli@freescale.com>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* QE USB routines
|
* QE USB routines
|
||||||
*
|
*
|
||||||
* Copyright (c) Freescale Semicondutor, Inc. 2006.
|
* Copyright 2006 Freescale Semiconductor, Inc.
|
||||||
* Shlomi Gridish <gridish@freescale.com>
|
* Shlomi Gridish <gridish@freescale.com>
|
||||||
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
* Jerry Huang <Chang-Ming.Huang@freescale.com>
|
||||||
* Copyright (c) MontaVista Software, Inc. 2008.
|
* Copyright (c) MontaVista Software, Inc. 2008.
|
||||||
|
@ -6,7 +6,7 @@ GCOV_PROFILE := n
|
|||||||
|
|
||||||
ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
|
ccflags-$(CONFIG_PPC64) := -mno-minimal-toc
|
||||||
|
|
||||||
obj-y += xmon.o start.o nonstdio.o
|
obj-y += xmon.o nonstdio.o
|
||||||
|
|
||||||
ifdef CONFIG_XMON_DISASSEMBLY
|
ifdef CONFIG_XMON_DISASSEMBLY
|
||||||
obj-y += ppc-dis.o ppc-opc.o
|
obj-y += ppc-dis.o ppc-opc.o
|
||||||
|
@ -7,9 +7,23 @@
|
|||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
#include <asm/udbg.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include "nonstdio.h"
|
#include "nonstdio.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int xmon_write(const void *ptr, int nb)
|
||||||
|
{
|
||||||
|
return udbg_write(ptr, nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xmon_readchar(void)
|
||||||
|
{
|
||||||
|
if (udbg_getc)
|
||||||
|
return udbg_getc();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int xmon_putchar(int c)
|
int xmon_putchar(int c)
|
||||||
{
|
{
|
||||||
char ch = c;
|
char ch = c;
|
||||||
@ -23,34 +37,7 @@ static char line[256];
|
|||||||
static char *lineptr;
|
static char *lineptr;
|
||||||
static int lineleft;
|
static int lineleft;
|
||||||
|
|
||||||
int xmon_expect(const char *str, unsigned long timeout)
|
static int xmon_getchar(void)
|
||||||
{
|
|
||||||
int c;
|
|
||||||
unsigned long t0;
|
|
||||||
|
|
||||||
/* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
|
|
||||||
timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
|
|
||||||
t0 = get_tbl();
|
|
||||||
do {
|
|
||||||
lineptr = line;
|
|
||||||
for (;;) {
|
|
||||||
c = xmon_read_poll();
|
|
||||||
if (c == -1) {
|
|
||||||
if (get_tbl() - t0 > timeout)
|
|
||||||
return 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == '\n')
|
|
||||||
break;
|
|
||||||
if (c != '\r' && lineptr < &line[sizeof(line) - 1])
|
|
||||||
*lineptr++ = c;
|
|
||||||
}
|
|
||||||
*lineptr = 0;
|
|
||||||
} while (strstr(line, str) == NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmon_getchar(void)
|
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -124,13 +111,19 @@ char *xmon_gets(char *str, int nb)
|
|||||||
void xmon_printf(const char *format, ...)
|
void xmon_printf(const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
int n;
|
|
||||||
static char xmon_outbuf[1024];
|
static char xmon_outbuf[1024];
|
||||||
|
int rc, n;
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
|
n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
xmon_write(xmon_outbuf, n);
|
|
||||||
|
rc = xmon_write(xmon_outbuf, n);
|
||||||
|
|
||||||
|
if (n && rc == 0) {
|
||||||
|
/* No udbg hooks, fallback to printk() - dangerous */
|
||||||
|
printk(xmon_outbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xmon_puts(const char *str)
|
void xmon_puts(const char *str)
|
||||||
|
@ -4,12 +4,6 @@
|
|||||||
#define putchar xmon_putchar
|
#define putchar xmon_putchar
|
||||||
|
|
||||||
extern int xmon_putchar(int c);
|
extern int xmon_putchar(int c);
|
||||||
extern int xmon_getchar(void);
|
|
||||||
extern void xmon_puts(const char *);
|
extern void xmon_puts(const char *);
|
||||||
extern char *xmon_gets(char *, int);
|
extern char *xmon_gets(char *, int);
|
||||||
extern void xmon_printf(const char *, ...);
|
extern void xmon_printf(const char *, ...);
|
||||||
extern void xmon_map_scc(void);
|
|
||||||
extern int xmon_expect(const char *str, unsigned long timeout);
|
|
||||||
extern int xmon_write(const void *ptr, int nb);
|
|
||||||
extern int xmon_readchar(void);
|
|
||||||
extern int xmon_read_poll(void);
|
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 1996 Paul Mackerras.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
#include <asm/machdep.h>
|
|
||||||
#include <asm/udbg.h>
|
|
||||||
#include "nonstdio.h"
|
|
||||||
|
|
||||||
void xmon_map_scc(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmon_write(const void *ptr, int nb)
|
|
||||||
{
|
|
||||||
return udbg_write(ptr, nb);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmon_readchar(void)
|
|
||||||
{
|
|
||||||
if (udbg_getc)
|
|
||||||
return udbg_getc();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmon_read_poll(void)
|
|
||||||
{
|
|
||||||
if (udbg_getc_poll)
|
|
||||||
return udbg_getc_poll();
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -52,9 +52,6 @@
|
|||||||
#include "nonstdio.h"
|
#include "nonstdio.h"
|
||||||
#include "dis-asm.h"
|
#include "dis-asm.h"
|
||||||
|
|
||||||
#define scanhex xmon_scanhex
|
|
||||||
#define skipbl xmon_skipbl
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
|
static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
|
||||||
static unsigned long xmon_taken = 1;
|
static unsigned long xmon_taken = 1;
|
||||||
@ -169,12 +166,8 @@ extern void xmon_leave(void);
|
|||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
#define REG "%.16lx"
|
#define REG "%.16lx"
|
||||||
#define REGS_PER_LINE 4
|
|
||||||
#define LAST_VOLATILE 13
|
|
||||||
#else
|
#else
|
||||||
#define REG "%.8lx"
|
#define REG "%.8lx"
|
||||||
#define REGS_PER_LINE 8
|
|
||||||
#define LAST_VOLATILE 12
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
|
#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
|
||||||
@ -1288,27 +1281,19 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
|
|||||||
catch_memory_errors = 0;
|
catch_memory_errors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xmon_depth_to_print = 64;
|
|
||||||
|
|
||||||
#define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
|
#define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
|
||||||
#define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
|
#define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
|
||||||
|
|
||||||
#ifdef __powerpc64__
|
|
||||||
#define REGS_OFFSET 0x70
|
|
||||||
#else
|
|
||||||
#define REGS_OFFSET 16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void xmon_show_stack(unsigned long sp, unsigned long lr,
|
static void xmon_show_stack(unsigned long sp, unsigned long lr,
|
||||||
unsigned long pc)
|
unsigned long pc)
|
||||||
{
|
{
|
||||||
|
int max_to_print = 64;
|
||||||
unsigned long ip;
|
unsigned long ip;
|
||||||
unsigned long newsp;
|
unsigned long newsp;
|
||||||
unsigned long marker;
|
unsigned long marker;
|
||||||
int count = 0;
|
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
|
|
||||||
do {
|
while (max_to_print--) {
|
||||||
if (sp < PAGE_OFFSET) {
|
if (sp < PAGE_OFFSET) {
|
||||||
if (sp != 0)
|
if (sp != 0)
|
||||||
printf("SP (%lx) is in userspace\n", sp);
|
printf("SP (%lx) is in userspace\n", sp);
|
||||||
@ -1362,10 +1347,10 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
|
|||||||
an exception frame. */
|
an exception frame. */
|
||||||
if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
|
if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
|
||||||
&& marker == STACK_FRAME_REGS_MARKER) {
|
&& marker == STACK_FRAME_REGS_MARKER) {
|
||||||
if (mread(sp + REGS_OFFSET, ®s, sizeof(regs))
|
if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
|
||||||
!= sizeof(regs)) {
|
!= sizeof(regs)) {
|
||||||
printf("Couldn't read registers at %lx\n",
|
printf("Couldn't read registers at %lx\n",
|
||||||
sp + REGS_OFFSET);
|
sp + STACK_FRAME_OVERHEAD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("--- Exception: %lx %s at ", regs.trap,
|
printf("--- Exception: %lx %s at ", regs.trap,
|
||||||
@ -1379,7 +1364,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
sp = newsp;
|
sp = newsp;
|
||||||
} while (count++ < xmon_depth_to_print);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void backtrace(struct pt_regs *excp)
|
static void backtrace(struct pt_regs *excp)
|
||||||
@ -2943,7 +2928,6 @@ static void xmon_init(int enable)
|
|||||||
__debugger_dabr_match = NULL;
|
__debugger_dabr_match = NULL;
|
||||||
__debugger_fault_handler = NULL;
|
__debugger_fault_handler = NULL;
|
||||||
}
|
}
|
||||||
xmon_map_scc();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MAGIC_SYSRQ
|
#ifdef CONFIG_MAGIC_SYSRQ
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/pSeries_reconfig.h>
|
|
||||||
#include <asm/vio.h>
|
#include <asm/vio.h>
|
||||||
|
|
||||||
#include "nx_csbcpb.h" /* struct nx_csbcpb */
|
#include "nx_csbcpb.h" /* struct nx_csbcpb */
|
||||||
@ -1014,26 +1013,23 @@ error_out:
|
|||||||
* NOTIFY_BAD encoded with error number on failure, use
|
* NOTIFY_BAD encoded with error number on failure, use
|
||||||
* notifier_to_errno() to decode this value
|
* notifier_to_errno() to decode this value
|
||||||
*/
|
*/
|
||||||
static int nx842_OF_notifier(struct notifier_block *np,
|
static int nx842_OF_notifier(struct notifier_block *np, unsigned long action,
|
||||||
unsigned long action,
|
void *update)
|
||||||
void *update)
|
|
||||||
{
|
{
|
||||||
struct pSeries_reconfig_prop_update *upd;
|
struct of_prop_reconfig *upd = update;
|
||||||
struct nx842_devdata *local_devdata;
|
struct nx842_devdata *local_devdata;
|
||||||
struct device_node *node = NULL;
|
struct device_node *node = NULL;
|
||||||
|
|
||||||
upd = (struct pSeries_reconfig_prop_update *)update;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
local_devdata = rcu_dereference(devdata);
|
local_devdata = rcu_dereference(devdata);
|
||||||
if (local_devdata)
|
if (local_devdata)
|
||||||
node = local_devdata->dev->of_node;
|
node = local_devdata->dev->of_node;
|
||||||
|
|
||||||
if (local_devdata &&
|
if (local_devdata &&
|
||||||
action == PSERIES_UPDATE_PROPERTY &&
|
action == OF_RECONFIG_UPDATE_PROPERTY &&
|
||||||
!strcmp(upd->node->name, node->name)) {
|
!strcmp(upd->dn->name, node->name)) {
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
nx842_OF_upd(upd->property);
|
nx842_OF_upd(upd->prop);
|
||||||
} else
|
} else
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
@ -1182,7 +1178,7 @@ static int __init nx842_probe(struct vio_dev *viodev,
|
|||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
kfree(old_devdata);
|
kfree(old_devdata);
|
||||||
|
|
||||||
pSeries_reconfig_notifier_register(&nx842_of_nb);
|
of_reconfig_notifier_register(&nx842_of_nb);
|
||||||
|
|
||||||
ret = nx842_OF_upd(NULL);
|
ret = nx842_OF_upd(NULL);
|
||||||
if (ret && ret != -ENODEV) {
|
if (ret && ret != -ENODEV) {
|
||||||
@ -1228,7 +1224,7 @@ static int __exit nx842_remove(struct vio_dev *viodev)
|
|||||||
spin_lock_irqsave(&devdata_mutex, flags);
|
spin_lock_irqsave(&devdata_mutex, flags);
|
||||||
old_devdata = rcu_dereference_check(devdata,
|
old_devdata = rcu_dereference_check(devdata,
|
||||||
lockdep_is_held(&devdata_mutex));
|
lockdep_is_held(&devdata_mutex));
|
||||||
pSeries_reconfig_notifier_unregister(&nx842_of_nb);
|
of_reconfig_notifier_unregister(&nx842_of_nb);
|
||||||
rcu_assign_pointer(devdata, NULL);
|
rcu_assign_pointer(devdata, NULL);
|
||||||
spin_unlock_irqrestore(&devdata_mutex, flags);
|
spin_unlock_irqrestore(&devdata_mutex, flags);
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user