提交 cd427485 编写于 作者: B Benjamin Herrenschmidt

Merge remote-tracking branch 'scott/next' into next

Freescale updates from Scott. Mostly support for critical
and machine check exceptions on 64-bit BookE, some new
PCI suspend/resume work and misc bits.
Freescale L2 Cache Controller
L2 cache is present in Freescale's QorIQ and QorIQ Qonverge platforms.
The cache bindings explained below are ePAPR compliant
Required Properties:
- compatible : Should include "fsl,chip-l2-cache-controller" and "cache"
where chip is the processor (bsc9132, npc8572 etc.)
- reg : Address and size of L2 cache controller registers
- cache-size : Size of the entire L2 cache
- interrupts : Error interrupt of L2 controller
- cache-line-size : Size of L2 cache lines
Example:
L2: l2-cache-controller@20000 {
compatible = "fsl,bsc9132-l2-cache-controller", "cache";
reg = <0x20000 0x1000>;
cache-line-size = <32>; // 32 bytes
cache-size = <0x40000>; // L2,256K
interrupts = <16 2 1 0>;
};
Freescale DDR memory controller
Properties:
- compatible : Should include "fsl,chip-memory-controller" where
chip is the processor (bsc9132, mpc8572 etc.), or
"fsl,qoriq-memory-controller".
- reg : Address and size of DDR controller registers
- interrupts : Error interrupt of DDR controller
Example 1:
memory-controller@2000 {
compatible = "fsl,bsc9132-memory-controller";
reg = <0x2000 0x1000>;
interrupts = <16 2 1 8>;
};
Example 2:
ddr1: memory-controller@8000 {
compatible = "fsl,qoriq-memory-controller-v4.7",
"fsl,qoriq-memory-controller";
reg = <0x8000 0x1000>;
interrupts = <16 2 1 23>;
};
...@@ -8,7 +8,9 @@ and additions : ...@@ -8,7 +8,9 @@ and additions :
Required properties : Required properties :
- compatible : Should be "fsl-usb2-mph" for multi port host USB - compatible : Should be "fsl-usb2-mph" for multi port host USB
controllers, or "fsl-usb2-dr" for dual role USB controllers controllers, or "fsl-usb2-dr" for dual role USB controllers
or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121 or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121.
Wherever applicable, the IP version of the USB controller should
also be mentioned (for eg. fsl-usb2-dr-v2.2 for bsc9132).
- phy_type : For multi port host USB controllers, should be one of - phy_type : For multi port host USB controllers, should be one of
"ulpi", or "serial". For dual role USB controllers, should be "ulpi", or "serial". For dual role USB controllers, should be
one of "ulpi", "utmi", "utmi_wide", or "serial". one of "ulpi", "utmi", "utmi_wide", or "serial".
......
...@@ -86,6 +86,42 @@ ...@@ -86,6 +86,42 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0"; compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0";
ranges = <0x0 0xe1000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-2.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2", "pll0-div4";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2", "pll1-div4";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-2.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
<&pll1 0>, <&pll1 1>, <&pll1 2>;
clock-names = "pll0", "pll0-div2", "pll0-div4",
"pll1", "pll1-div2", "pll1-div4";
clock-output-names = "cmux0";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -64,11 +64,13 @@ ...@@ -64,11 +64,13 @@
cpu0: PowerPC,e6500@0 { cpu0: PowerPC,e6500@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0 1>; reg = <0 1>;
clocks = <&mux0>;
next-level-cache = <&L2>; next-level-cache = <&L2>;
}; };
cpu1: PowerPC,e6500@2 { cpu1: PowerPC,e6500@2 {
device_type = "cpu"; device_type = "cpu";
reg = <2 3>; reg = <2 3>;
clocks = <&mux0>;
next-level-cache = <&L2>; next-level-cache = <&L2>;
}; };
}; };
......
...@@ -130,6 +130,42 @@ ...@@ -130,6 +130,42 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2.0"; compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2.0";
ranges = <0x0 0xe1000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-2.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2", "pll0-div4";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2", "pll1-div4";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-2.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
<&pll1 0>, <&pll1 1>, <&pll1 2>;
clock-names = "pll0", "pll0-div2", "pll0-div4",
"pll1", "pll1-div2", "pll1-div4";
clock-output-names = "cmux0";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -64,21 +64,25 @@ ...@@ -64,21 +64,25 @@
cpu0: PowerPC,e6500@0 { cpu0: PowerPC,e6500@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0 1>; reg = <0 1>;
clocks = <&mux0>;
next-level-cache = <&L2>; next-level-cache = <&L2>;
}; };
cpu1: PowerPC,e6500@2 { cpu1: PowerPC,e6500@2 {
device_type = "cpu"; device_type = "cpu";
reg = <2 3>; reg = <2 3>;
clocks = <&mux0>;
next-level-cache = <&L2>; next-level-cache = <&L2>;
}; };
cpu2: PowerPC,e6500@4 { cpu2: PowerPC,e6500@4 {
device_type = "cpu"; device_type = "cpu";
reg = <4 5>; reg = <4 5>;
clocks = <&mux0>;
next-level-cache = <&L2>; next-level-cache = <&L2>;
}; };
cpu3: PowerPC,e6500@6 { cpu3: PowerPC,e6500@6 {
device_type = "cpu"; device_type = "cpu";
reg = <6 7>; reg = <6 7>;
clocks = <&mux0>;
next-level-cache = <&L2>; next-level-cache = <&L2>;
}; };
}; };
......
...@@ -306,8 +306,68 @@ ...@@ -306,8 +306,68 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0"; compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>; reg = <0xe1000 0x1000>;
clock-frequency = <0>; clock-frequency = <0>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-1.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux0";
};
mux1: mux1@20 {
#clock-cells = <0>;
reg = <0x20 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux1";
};
mux2: mux2@40 {
#clock-cells = <0>;
reg = <0x40 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
};
mux3: mux3@60 {
#clock-cells = <0>;
reg = <0x60 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux3";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
cpu0: PowerPC,e500mc@0 { cpu0: PowerPC,e500mc@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0>; reg = <0>;
clocks = <&mux0>;
next-level-cache = <&L2_0>; next-level-cache = <&L2_0>;
L2_0: l2-cache { L2_0: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -89,6 +90,7 @@ ...@@ -89,6 +90,7 @@
cpu1: PowerPC,e500mc@1 { cpu1: PowerPC,e500mc@1 {
device_type = "cpu"; device_type = "cpu";
reg = <1>; reg = <1>;
clocks = <&mux1>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
L2_1: l2-cache { L2_1: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -97,6 +99,7 @@ ...@@ -97,6 +99,7 @@
cpu2: PowerPC,e500mc@2 { cpu2: PowerPC,e500mc@2 {
device_type = "cpu"; device_type = "cpu";
reg = <2>; reg = <2>;
clocks = <&mux2>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
L2_2: l2-cache { L2_2: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -105,6 +108,7 @@ ...@@ -105,6 +108,7 @@
cpu3: PowerPC,e500mc@3 { cpu3: PowerPC,e500mc@3 {
device_type = "cpu"; device_type = "cpu";
reg = <3>; reg = <3>;
clocks = <&mux3>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
L2_3: l2-cache { L2_3: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
......
...@@ -333,8 +333,69 @@ ...@@ -333,8 +333,69 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0"; compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>; reg = <0xe1000 0x1000>;
clock-frequency = <0>; clock-frequency = <0>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-1.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux0";
};
mux1: mux1@20 {
#clock-cells = <0>;
reg = <0x20 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux1";
};
mux2: mux2@40 {
#clock-cells = <0>;
reg = <0x40 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux2";
};
mux3: mux3@60 {
#clock-cells = <0>;
reg = <0x60 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux3";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
cpu0: PowerPC,e500mc@0 { cpu0: PowerPC,e500mc@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0>; reg = <0>;
clocks = <&mux0>;
next-level-cache = <&L2_0>; next-level-cache = <&L2_0>;
L2_0: l2-cache { L2_0: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -90,6 +91,7 @@ ...@@ -90,6 +91,7 @@
cpu1: PowerPC,e500mc@1 { cpu1: PowerPC,e500mc@1 {
device_type = "cpu"; device_type = "cpu";
reg = <1>; reg = <1>;
clocks = <&mux1>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
L2_1: l2-cache { L2_1: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -98,6 +100,7 @@ ...@@ -98,6 +100,7 @@
cpu2: PowerPC,e500mc@2 { cpu2: PowerPC,e500mc@2 {
device_type = "cpu"; device_type = "cpu";
reg = <2>; reg = <2>;
clocks = <&mux2>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
L2_2: l2-cache { L2_2: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -106,6 +109,7 @@ ...@@ -106,6 +109,7 @@
cpu3: PowerPC,e500mc@3 { cpu3: PowerPC,e500mc@3 {
device_type = "cpu"; device_type = "cpu";
reg = <3>; reg = <3>;
clocks = <&mux3>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
L2_3: l2-cache { L2_3: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
......
...@@ -353,8 +353,121 @@ ...@@ -353,8 +353,121 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,p4080-clockgen", "fsl,qoriq-clockgen-1.0"; compatible = "fsl,p4080-clockgen", "fsl,qoriq-clockgen-1.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>; reg = <0xe1000 0x1000>;
clock-frequency = <0>; clock-frequency = <0>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-1.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2";
};
pll2: pll2@840 {
#clock-cells = <1>;
reg = <0x840 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll2", "pll2-div2";
};
pll3: pll3@860 {
#clock-cells = <1>;
reg = <0x860 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll3", "pll3-div2";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux0";
};
mux1: mux1@20 {
#clock-cells = <0>;
reg = <0x20 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux1";
};
mux2: mux2@40 {
#clock-cells = <0>;
reg = <0x40 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux2";
};
mux3: mux3@60 {
#clock-cells = <0>;
reg = <0x60 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux3";
};
mux4: mux4@80 {
#clock-cells = <0>;
reg = <0x80 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
clock-output-names = "cmux4";
};
mux5: mux5@a0 {
#clock-cells = <0>;
reg = <0xa0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
clock-output-names = "cmux5";
};
mux6: mux6@c0 {
#clock-cells = <0>;
reg = <0xc0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
clock-output-names = "cmux6";
};
mux7: mux7@e0 {
#clock-cells = <0>;
reg = <0xe0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
clock-output-names = "cmux7";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
cpu0: PowerPC,e500mc@0 { cpu0: PowerPC,e500mc@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0>; reg = <0>;
clocks = <&mux0>;
next-level-cache = <&L2_0>; next-level-cache = <&L2_0>;
L2_0: l2-cache { L2_0: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -89,6 +90,7 @@ ...@@ -89,6 +90,7 @@
cpu1: PowerPC,e500mc@1 { cpu1: PowerPC,e500mc@1 {
device_type = "cpu"; device_type = "cpu";
reg = <1>; reg = <1>;
clocks = <&mux1>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
L2_1: l2-cache { L2_1: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -97,6 +99,7 @@ ...@@ -97,6 +99,7 @@
cpu2: PowerPC,e500mc@2 { cpu2: PowerPC,e500mc@2 {
device_type = "cpu"; device_type = "cpu";
reg = <2>; reg = <2>;
clocks = <&mux2>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
L2_2: l2-cache { L2_2: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -105,6 +108,7 @@ ...@@ -105,6 +108,7 @@
cpu3: PowerPC,e500mc@3 { cpu3: PowerPC,e500mc@3 {
device_type = "cpu"; device_type = "cpu";
reg = <3>; reg = <3>;
clocks = <&mux3>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
L2_3: l2-cache { L2_3: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -113,6 +117,7 @@ ...@@ -113,6 +117,7 @@
cpu4: PowerPC,e500mc@4 { cpu4: PowerPC,e500mc@4 {
device_type = "cpu"; device_type = "cpu";
reg = <4>; reg = <4>;
clocks = <&mux4>;
next-level-cache = <&L2_4>; next-level-cache = <&L2_4>;
L2_4: l2-cache { L2_4: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -121,6 +126,7 @@ ...@@ -121,6 +126,7 @@
cpu5: PowerPC,e500mc@5 { cpu5: PowerPC,e500mc@5 {
device_type = "cpu"; device_type = "cpu";
reg = <5>; reg = <5>;
clocks = <&mux5>;
next-level-cache = <&L2_5>; next-level-cache = <&L2_5>;
L2_5: l2-cache { L2_5: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -129,6 +135,7 @@ ...@@ -129,6 +135,7 @@
cpu6: PowerPC,e500mc@6 { cpu6: PowerPC,e500mc@6 {
device_type = "cpu"; device_type = "cpu";
reg = <6>; reg = <6>;
clocks = <&mux6>;
next-level-cache = <&L2_6>; next-level-cache = <&L2_6>;
L2_6: l2-cache { L2_6: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -137,6 +144,7 @@ ...@@ -137,6 +144,7 @@
cpu7: PowerPC,e500mc@7 { cpu7: PowerPC,e500mc@7 {
device_type = "cpu"; device_type = "cpu";
reg = <7>; reg = <7>;
clocks = <&mux7>;
next-level-cache = <&L2_7>; next-level-cache = <&L2_7>;
L2_7: l2-cache { L2_7: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
......
...@@ -338,8 +338,51 @@ ...@@ -338,8 +338,51 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0"; compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>; reg = <0xe1000 0x1000>;
clock-frequency = <0>; clock-frequency = <0>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-1.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux0";
};
mux1: mux1@20 {
#clock-cells = <0>;
reg = <0x20 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux1";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
cpu0: PowerPC,e5500@0 { cpu0: PowerPC,e5500@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0>; reg = <0>;
clocks = <&mux0>;
next-level-cache = <&L2_0>; next-level-cache = <&L2_0>;
L2_0: l2-cache { L2_0: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -96,6 +97,7 @@ ...@@ -96,6 +97,7 @@
cpu1: PowerPC,e5500@1 { cpu1: PowerPC,e5500@1 {
device_type = "cpu"; device_type = "cpu";
reg = <1>; reg = <1>;
clocks = <&mux1>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
L2_1: l2-cache { L2_1: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
......
...@@ -298,8 +298,69 @@ ...@@ -298,8 +298,69 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0"; compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>; reg = <0xe1000 0x1000>;
clock-frequency = <0>; clock-frequency = <0>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-1.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-1.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux0";
};
mux1: mux1@20 {
#clock-cells = <0>;
reg = <0x20 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux1";
};
mux2: mux2@40 {
#clock-cells = <0>;
reg = <0x40 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux2";
};
mux3: mux3@60 {
#clock-cells = <0>;
reg = <0x60 0x4>;
compatible = "fsl,qoriq-core-mux-1.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
clock-output-names = "cmux3";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
cpu0: PowerPC,e5500@0 { cpu0: PowerPC,e5500@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0>; reg = <0>;
clocks = <&mux0>;
next-level-cache = <&L2_0>; next-level-cache = <&L2_0>;
L2_0: l2-cache { L2_0: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -89,6 +90,7 @@ ...@@ -89,6 +90,7 @@
cpu1: PowerPC,e5500@1 { cpu1: PowerPC,e5500@1 {
device_type = "cpu"; device_type = "cpu";
reg = <1>; reg = <1>;
clocks = <&mux1>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
L2_1: l2-cache { L2_1: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -97,6 +99,7 @@ ...@@ -97,6 +99,7 @@
cpu2: PowerPC,e5500@2 { cpu2: PowerPC,e5500@2 {
device_type = "cpu"; device_type = "cpu";
reg = <2>; reg = <2>;
clocks = <&mux2>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
L2_2: l2-cache { L2_2: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
...@@ -105,6 +108,7 @@ ...@@ -105,6 +108,7 @@
cpu3: PowerPC,e5500@3 { cpu3: PowerPC,e5500@3 {
device_type = "cpu"; device_type = "cpu";
reg = <3>; reg = <3>;
clocks = <&mux3>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
L2_3: l2-cache { L2_3: l2-cache {
next-level-cache = <&cpc>; next-level-cache = <&cpc>;
......
...@@ -369,7 +369,93 @@ ...@@ -369,7 +369,93 @@
clockgen: global-utilities@e1000 { clockgen: global-utilities@e1000 {
compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0"; compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>; reg = <0xe1000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
sysclk: sysclk {
#clock-cells = <0>;
compatible = "fsl,qoriq-sysclk-2.0";
clock-output-names = "sysclk";
};
pll0: pll0@800 {
#clock-cells = <1>;
reg = <0x800 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll0", "pll0-div2", "pll0-div4";
};
pll1: pll1@820 {
#clock-cells = <1>;
reg = <0x820 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll1", "pll1-div2", "pll1-div4";
};
pll2: pll2@840 {
#clock-cells = <1>;
reg = <0x840 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll2", "pll2-div2", "pll2-div4";
};
pll3: pll3@860 {
#clock-cells = <1>;
reg = <0x860 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll3", "pll3-div2", "pll3-div4";
};
pll4: pll4@880 {
#clock-cells = <1>;
reg = <0x880 0x4>;
compatible = "fsl,qoriq-core-pll-2.0";
clocks = <&sysclk>;
clock-output-names = "pll4", "pll4-div2", "pll4-div4";
};
mux0: mux0@0 {
#clock-cells = <0>;
reg = <0x0 0x4>;
compatible = "fsl,qoriq-core-mux-2.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
<&pll1 0>, <&pll1 1>, <&pll1 2>,
<&pll2 0>, <&pll2 1>, <&pll2 2>;
clock-names = "pll0", "pll0-div2", "pll0-div4",
"pll1", "pll1-div2", "pll1-div4",
"pll2", "pll2-div2", "pll2-div4";
clock-output-names = "cmux0";
};
mux1: mux1@20 {
#clock-cells = <0>;
reg = <0x20 0x4>;
compatible = "fsl,qoriq-core-mux-2.0";
clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
<&pll1 0>, <&pll1 1>, <&pll1 2>,
<&pll2 0>, <&pll2 1>, <&pll2 2>;
clock-names = "pll0", "pll0-div2", "pll0-div4",
"pll1", "pll1-div2", "pll1-div4",
"pll2", "pll2-div2", "pll2-div4";
clock-output-names = "cmux1";
};
mux2: mux2@40 {
#clock-cells = <0>;
reg = <0x40 0x4>;
compatible = "fsl,qoriq-core-mux-2.0";
clocks = <&pll3 0>, <&pll3 1>, <&pll3 2>,
<&pll4 0>, <&pll4 1>, <&pll4 2>;
clock-names = "pll3", "pll3-div2", "pll3-div4",
"pll4", "pll4-div2", "pll4-div4";
clock-output-names = "cmux2";
};
}; };
rcpm: global-utilities@e2000 { rcpm: global-utilities@e2000 {
......
...@@ -67,61 +67,73 @@ ...@@ -67,61 +67,73 @@
cpu0: PowerPC,e6500@0 { cpu0: PowerPC,e6500@0 {
device_type = "cpu"; device_type = "cpu";
reg = <0 1>; reg = <0 1>;
clocks = <&mux0>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
}; };
cpu1: PowerPC,e6500@2 { cpu1: PowerPC,e6500@2 {
device_type = "cpu"; device_type = "cpu";
reg = <2 3>; reg = <2 3>;
clocks = <&mux0>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
}; };
cpu2: PowerPC,e6500@4 { cpu2: PowerPC,e6500@4 {
device_type = "cpu"; device_type = "cpu";
reg = <4 5>; reg = <4 5>;
clocks = <&mux0>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
}; };
cpu3: PowerPC,e6500@6 { cpu3: PowerPC,e6500@6 {
device_type = "cpu"; device_type = "cpu";
reg = <6 7>; reg = <6 7>;
clocks = <&mux0>;
next-level-cache = <&L2_1>; next-level-cache = <&L2_1>;
}; };
cpu4: PowerPC,e6500@8 { cpu4: PowerPC,e6500@8 {
device_type = "cpu"; device_type = "cpu";
reg = <8 9>; reg = <8 9>;
clocks = <&mux1>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
}; };
cpu5: PowerPC,e6500@10 { cpu5: PowerPC,e6500@10 {
device_type = "cpu"; device_type = "cpu";
reg = <10 11>; reg = <10 11>;
clocks = <&mux1>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
}; };
cpu6: PowerPC,e6500@12 { cpu6: PowerPC,e6500@12 {
device_type = "cpu"; device_type = "cpu";
reg = <12 13>; reg = <12 13>;
clocks = <&mux1>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
}; };
cpu7: PowerPC,e6500@14 { cpu7: PowerPC,e6500@14 {
device_type = "cpu"; device_type = "cpu";
reg = <14 15>; reg = <14 15>;
clocks = <&mux1>;
next-level-cache = <&L2_2>; next-level-cache = <&L2_2>;
}; };
cpu8: PowerPC,e6500@16 { cpu8: PowerPC,e6500@16 {
device_type = "cpu"; device_type = "cpu";
reg = <16 17>; reg = <16 17>;
clocks = <&mux2>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
}; };
cpu9: PowerPC,e6500@18 { cpu9: PowerPC,e6500@18 {
device_type = "cpu"; device_type = "cpu";
reg = <18 19>; reg = <18 19>;
clocks = <&mux2>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
}; };
cpu10: PowerPC,e6500@20 { cpu10: PowerPC,e6500@20 {
device_type = "cpu"; device_type = "cpu";
reg = <20 21>; reg = <20 21>;
clocks = <&mux2>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
}; };
cpu11: PowerPC,e6500@22 { cpu11: PowerPC,e6500@22 {
device_type = "cpu"; device_type = "cpu";
reg = <22 23>; reg = <22 23>;
clocks = <&mux2>;
next-level-cache = <&L2_3>; next-level-cache = <&L2_3>;
}; };
}; };
......
...@@ -159,6 +159,48 @@ ...@@ -159,6 +159,48 @@
interrupts = <0x1 0x1 0 0>; interrupts = <0x1 0x1 0 0>;
}; };
}; };
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x2>;
ina220@40 {
compatible = "ti,ina220";
reg = <0x40>;
shunt-resistor = <1000>;
};
ina220@41 {
compatible = "ti,ina220";
reg = <0x41>;
shunt-resistor = <1000>;
};
ina220@44 {
compatible = "ti,ina220";
reg = <0x44>;
shunt-resistor = <1000>;
};
ina220@45 {
compatible = "ti,ina220";
reg = <0x45>;
shunt-resistor = <1000>;
};
ina220@46 {
compatible = "ti,ina220";
reg = <0x46>;
shunt-resistor = <1000>;
};
ina220@47 {
compatible = "ti,ina220";
reg = <0x47>;
shunt-resistor = <1000>;
};
};
}; };
}; };
......
...@@ -26,7 +26,6 @@ CONFIG_CORENET_GENERIC=y ...@@ -26,7 +26,6 @@ CONFIG_CORENET_GENERIC=y
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_MATH_EMULATION=y CONFIG_MATH_EMULATION=y
CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y
CONFIG_FSL_IFC=y
CONFIG_PCIEPORTBUS=y CONFIG_PCIEPORTBUS=y
CONFIG_PCI_MSI=y CONFIG_PCI_MSI=y
CONFIG_RAPIDIO=y CONFIG_RAPIDIO=y
......
...@@ -49,7 +49,6 @@ CONFIG_HIGHMEM=y ...@@ -49,7 +49,6 @@ CONFIG_HIGHMEM=y
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_MATH_EMULATION=y CONFIG_MATH_EMULATION=y
CONFIG_FORCE_MAX_ZONEORDER=12 CONFIG_FORCE_MAX_ZONEORDER=12
CONFIG_FSL_IFC=y
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_PCI_MSI=y CONFIG_PCI_MSI=y
CONFIG_RAPIDIO=y CONFIG_RAPIDIO=y
......
...@@ -52,7 +52,6 @@ CONFIG_HIGHMEM=y ...@@ -52,7 +52,6 @@ CONFIG_HIGHMEM=y
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_MATH_EMULATION=y CONFIG_MATH_EMULATION=y
CONFIG_FORCE_MAX_ZONEORDER=12 CONFIG_FORCE_MAX_ZONEORDER=12
CONFIG_FSL_IFC=y
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_PCI_MSI=y CONFIG_PCI_MSI=y
CONFIG_RAPIDIO=y CONFIG_RAPIDIO=y
......
...@@ -46,9 +46,8 @@ ...@@ -46,9 +46,8 @@
#define EX_CR (1 * 8) #define EX_CR (1 * 8)
#define EX_R10 (2 * 8) #define EX_R10 (2 * 8)
#define EX_R11 (3 * 8) #define EX_R11 (3 * 8)
#define EX_R13 (4 * 8) #define EX_R14 (4 * 8)
#define EX_R14 (5 * 8) #define EX_R15 (5 * 8)
#define EX_R15 (6 * 8)
/* /*
* The TLB miss exception uses different slots. * The TLB miss exception uses different slots.
...@@ -173,16 +172,6 @@ exc_##label##_book3e: ...@@ -173,16 +172,6 @@ exc_##label##_book3e:
ld r9,EX_TLB_R9(r12); \ ld r9,EX_TLB_R9(r12); \
ld r8,EX_TLB_R8(r12); \ ld r8,EX_TLB_R8(r12); \
mtlr r16; mtlr r16;
#define TLB_MISS_PROLOG_STATS_BOLTED \
mflr r10; \
std r8,PACA_EXTLB+EX_TLB_R8(r13); \
std r9,PACA_EXTLB+EX_TLB_R9(r13); \
std r10,PACA_EXTLB+EX_TLB_LR(r13);
#define TLB_MISS_RESTORE_STATS_BOLTED \
ld r16,PACA_EXTLB+EX_TLB_LR(r13); \
ld r9,PACA_EXTLB+EX_TLB_R9(r13); \
ld r8,PACA_EXTLB+EX_TLB_R8(r13); \
mtlr r16;
#define TLB_MISS_STATS_D(name) \ #define TLB_MISS_STATS_D(name) \
addi r9,r13,MMSTAT_DSTATS+name; \ addi r9,r13,MMSTAT_DSTATS+name; \
bl .tlb_stat_inc; bl .tlb_stat_inc;
......
...@@ -36,26 +36,21 @@ ...@@ -36,26 +36,21 @@
* *(r8 + GPR11) = saved r11 * *(r8 + GPR11) = saved r11
* *
* 64-bit host * 64-bit host
* Expected inputs (GEN/GDBELL/DBG/MC exception types): * Expected inputs (GEN/GDBELL/DBG/CRIT/MC exception types):
* r10 = saved CR * r10 = saved CR
* r13 = PACA_POINTER * r13 = PACA_POINTER
* *(r13 + PACA_EX##type + EX_R10) = saved r10 * *(r13 + PACA_EX##type + EX_R10) = saved r10
* *(r13 + PACA_EX##type + EX_R11) = saved r11 * *(r13 + PACA_EX##type + EX_R11) = saved r11
* SPRN_SPRG_##type##_SCRATCH = saved r13 * SPRN_SPRG_##type##_SCRATCH = saved r13
*
* Expected inputs (CRIT exception type):
* r10 = saved CR
* r13 = PACA_POINTER
* *(r13 + PACA_EX##type + EX_R10) = saved r10
* *(r13 + PACA_EX##type + EX_R11) = saved r11
* *(r13 + PACA_EX##type + EX_R13) = saved r13
* *
* Expected inputs (TLB exception type): * Expected inputs (TLB exception type):
* r10 = saved CR * r10 = saved CR
* r12 = extlb pointer
* r13 = PACA_POINTER * r13 = PACA_POINTER
* *(r13 + PACA_EX##type + EX_TLB_R10) = saved r10 * *(r12 + EX_TLB_R10) = saved r10
* *(r13 + PACA_EX##type + EX_TLB_R11) = saved r11 * *(r12 + EX_TLB_R11) = saved r11
* SPRN_SPRG_GEN_SCRATCH = saved r13 * *(r12 + EX_TLB_R13) = saved r13
* SPRN_SPRG_GEN_SCRATCH = saved r12
* *
* Only the bolted version of TLB miss exception handlers is supported now. * Only the bolted version of TLB miss exception handlers is supported now.
*/ */
......
...@@ -287,11 +287,14 @@ extern int mmu_linear_psize; ...@@ -287,11 +287,14 @@ extern int mmu_linear_psize;
extern int mmu_vmemmap_psize; extern int mmu_vmemmap_psize;
struct tlb_core_data { struct tlb_core_data {
/*
* Per-core spinlock for e6500 TLB handlers (no tlbsrx.)
* Must be the first struct element.
*/
u8 lock;
/* For software way selection, as on Freescale TLB1 */ /* For software way selection, as on Freescale TLB1 */
u8 esel_next, esel_max, esel_first; u8 esel_next, esel_max, esel_first;
/* Per-core spinlock for e6500 TLB handlers (no tlbsrx.) */
u8 lock;
}; };
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
......
...@@ -116,8 +116,11 @@ struct paca_struct { ...@@ -116,8 +116,11 @@ struct paca_struct {
/* Shared by all threads of a core -- points to tcd of first thread */ /* Shared by all threads of a core -- points to tcd of first thread */
struct tlb_core_data *tcd_ptr; struct tlb_core_data *tcd_ptr;
/* We can have up to 3 levels of reentrancy in the TLB miss handler */ /*
u64 extlb[3][EX_TLB_SIZE / sizeof(u64)]; * We can have up to 3 levels of reentrancy in the TLB miss handler,
* in each of four exception levels (normal, crit, mcheck, debug).
*/
u64 extlb[12][EX_TLB_SIZE / sizeof(u64)];
u64 exmc[8]; /* used for machine checks */ u64 exmc[8]; /* used for machine checks */
u64 excrit[8]; /* used for crit interrupts */ u64 excrit[8]; /* used for crit interrupts */
u64 exdbg[8]; /* used for debug interrupts */ u64 exdbg[8]; /* used for debug interrupts */
...@@ -146,7 +149,7 @@ struct paca_struct { ...@@ -146,7 +149,7 @@ struct paca_struct {
u8 io_sync; /* writel() needs spin_unlock sync */ u8 io_sync; /* writel() needs spin_unlock sync */
u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
u8 nap_state_lost; /* NV GPR values lost in power7_idle */ u8 nap_state_lost; /* NV GPR values lost in power7_idle */
u64 sprg3; /* Saved user-visible sprg */ u64 sprg_vdso; /* Saved user-visible sprg */
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
u64 tm_scratch; /* TM scratch area for reclaim */ u64 tm_scratch; /* TM scratch area for reclaim */
#endif #endif
......
...@@ -577,9 +577,13 @@ ...@@ -577,9 +577,13 @@
#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ #define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
#define SPRN_USPRG3 0x103 /* SPRG3 userspace read */ #define SPRN_USPRG3 0x103 /* SPRG3 userspace read */
#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */ #define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */
#define SPRN_USPRG4 0x104 /* SPRG4 userspace read */
#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */ #define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */
#define SPRN_USPRG5 0x105 /* SPRG5 userspace read */
#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */ #define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */
#define SPRN_USPRG6 0x106 /* SPRG6 userspace read */
#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */ #define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */
#define SPRN_USPRG7 0x107 /* SPRG7 userspace read */
#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ #define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
#define SRR1_ISI_NOPT 0x40000000 /* ISI: Not found in hash */ #define SRR1_ISI_NOPT 0x40000000 /* ISI: Not found in hash */
...@@ -882,11 +886,10 @@ ...@@ -882,11 +886,10 @@
* 64-bit embedded * 64-bit embedded
* - SPRG0 generic exception scratch * - SPRG0 generic exception scratch
* - SPRG2 TLB exception stack * - SPRG2 TLB exception stack
* - SPRG3 critical exception scratch and * - SPRG3 critical exception scratch (user visible, sorry!)
* CPU and NUMA node for VDSO getcpu (user visible)
* - SPRG4 unused (user visible) * - SPRG4 unused (user visible)
* - SPRG6 TLB miss scratch (user visible, sorry !) * - SPRG6 TLB miss scratch (user visible, sorry !)
* - SPRG7 critical exception scratch * - SPRG7 CPU and NUMA node for VDSO getcpu (user visible)
* - SPRG8 machine check exception scratch * - SPRG8 machine check exception scratch
* - SPRG9 debug exception scratch * - SPRG9 debug exception scratch
* *
...@@ -943,6 +946,8 @@ ...@@ -943,6 +946,8 @@
#define SPRN_SPRG_SCRATCH0 SPRN_SPRG2 #define SPRN_SPRG_SCRATCH0 SPRN_SPRG2
#define SPRN_SPRG_HPACA SPRN_HSPRG0 #define SPRN_SPRG_HPACA SPRN_HSPRG0
#define SPRN_SPRG_HSCRATCH0 SPRN_HSPRG1 #define SPRN_SPRG_HSCRATCH0 SPRN_HSPRG1
#define SPRN_SPRG_VDSO_READ SPRN_USPRG3
#define SPRN_SPRG_VDSO_WRITE SPRN_SPRG3
#define GET_PACA(rX) \ #define GET_PACA(rX) \
BEGIN_FTR_SECTION_NESTED(66); \ BEGIN_FTR_SECTION_NESTED(66); \
...@@ -986,6 +991,8 @@ ...@@ -986,6 +991,8 @@
#define SPRN_SPRG_TLB_SCRATCH SPRN_SPRG6 #define SPRN_SPRG_TLB_SCRATCH SPRN_SPRG6
#define SPRN_SPRG_GEN_SCRATCH SPRN_SPRG0 #define SPRN_SPRG_GEN_SCRATCH SPRN_SPRG0
#define SPRN_SPRG_GDBELL_SCRATCH SPRN_SPRG_GEN_SCRATCH #define SPRN_SPRG_GDBELL_SCRATCH SPRN_SPRG_GEN_SCRATCH
#define SPRN_SPRG_VDSO_READ SPRN_USPRG7
#define SPRN_SPRG_VDSO_WRITE SPRN_SPRG7
#define SET_PACA(rX) mtspr SPRN_SPRG_PACA,rX #define SET_PACA(rX) mtspr SPRN_SPRG_PACA,rX
#define GET_PACA(rX) mfspr rX,SPRN_SPRG_PACA #define GET_PACA(rX) mfspr rX,SPRN_SPRG_PACA
...@@ -1105,6 +1112,8 @@ ...@@ -1105,6 +1112,8 @@
#define PVR_8560 0x80200000 #define PVR_8560 0x80200000
#define PVR_VER_E500V1 0x8020 #define PVR_VER_E500V1 0x8020
#define PVR_VER_E500V2 0x8021 #define PVR_VER_E500V2 0x8021
#define PVR_VER_E500MC 0x8023
#define PVR_VER_E5500 0x8024
#define PVR_VER_E6500 0x8040 #define PVR_VER_E6500 0x8040
/* /*
......
...@@ -253,7 +253,7 @@ int main(void) ...@@ -253,7 +253,7 @@ int main(void)
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost)); DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
DEFINE(PACA_SPRG3, offsetof(struct paca_struct, sprg3)); DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
/* RTAS */ /* RTAS */
......
...@@ -34,7 +34,250 @@ ...@@ -34,7 +34,250 @@
* special interrupts from within a non-standard level will probably * special interrupts from within a non-standard level will probably
* blow you up * blow you up
*/ */
#define SPECIAL_EXC_FRAME_SIZE INT_FRAME_SIZE #define SPECIAL_EXC_SRR0 0
#define SPECIAL_EXC_SRR1 1
#define SPECIAL_EXC_SPRG_GEN 2
#define SPECIAL_EXC_SPRG_TLB 3
#define SPECIAL_EXC_MAS0 4
#define SPECIAL_EXC_MAS1 5
#define SPECIAL_EXC_MAS2 6
#define SPECIAL_EXC_MAS3 7
#define SPECIAL_EXC_MAS6 8
#define SPECIAL_EXC_MAS7 9
#define SPECIAL_EXC_MAS5 10 /* E.HV only */
#define SPECIAL_EXC_MAS8 11 /* E.HV only */
#define SPECIAL_EXC_IRQHAPPENED 12
#define SPECIAL_EXC_DEAR 13
#define SPECIAL_EXC_ESR 14
#define SPECIAL_EXC_SOFTE 15
#define SPECIAL_EXC_CSRR0 16
#define SPECIAL_EXC_CSRR1 17
/* must be even to keep 16-byte stack alignment */
#define SPECIAL_EXC_END 18
#define SPECIAL_EXC_FRAME_SIZE (INT_FRAME_SIZE + SPECIAL_EXC_END * 8)
#define SPECIAL_EXC_FRAME_OFFS (INT_FRAME_SIZE - 288)
#define SPECIAL_EXC_STORE(reg, name) \
std reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
#define SPECIAL_EXC_LOAD(reg, name) \
ld reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
special_reg_save:
lbz r9,PACAIRQHAPPENED(r13)
RECONCILE_IRQ_STATE(r3,r4)
/*
* We only need (or have stack space) to save this stuff if
* we interrupted the kernel.
*/
ld r3,_MSR(r1)
andi. r3,r3,MSR_PR
bnelr
/* Copy info into temporary exception thread info */
ld r11,PACAKSAVE(r13)
CURRENT_THREAD_INFO(r11, r11)
CURRENT_THREAD_INFO(r12, r1)
ld r10,TI_FLAGS(r11)
std r10,TI_FLAGS(r12)
ld r10,TI_PREEMPT(r11)
std r10,TI_PREEMPT(r12)
ld r10,TI_TASK(r11)
std r10,TI_TASK(r12)
/*
* Advance to the next TLB exception frame for handler
* types that don't do it automatically.
*/
LOAD_REG_ADDR(r11,extlb_level_exc)
lwz r12,0(r11)
mfspr r10,SPRN_SPRG_TLB_EXFRAME
add r10,r10,r12
mtspr SPRN_SPRG_TLB_EXFRAME,r10
/*
* Save registers needed to allow nesting of certain exceptions
* (such as TLB misses) inside special exception levels
*/
mfspr r10,SPRN_SRR0
SPECIAL_EXC_STORE(r10,SRR0)
mfspr r10,SPRN_SRR1
SPECIAL_EXC_STORE(r10,SRR1)
mfspr r10,SPRN_SPRG_GEN_SCRATCH
SPECIAL_EXC_STORE(r10,SPRG_GEN)
mfspr r10,SPRN_SPRG_TLB_SCRATCH
SPECIAL_EXC_STORE(r10,SPRG_TLB)
mfspr r10,SPRN_MAS0
SPECIAL_EXC_STORE(r10,MAS0)
mfspr r10,SPRN_MAS1
SPECIAL_EXC_STORE(r10,MAS1)
mfspr r10,SPRN_MAS2
SPECIAL_EXC_STORE(r10,MAS2)
mfspr r10,SPRN_MAS3
SPECIAL_EXC_STORE(r10,MAS3)
mfspr r10,SPRN_MAS6
SPECIAL_EXC_STORE(r10,MAS6)
mfspr r10,SPRN_MAS7
SPECIAL_EXC_STORE(r10,MAS7)
BEGIN_FTR_SECTION
mfspr r10,SPRN_MAS5
SPECIAL_EXC_STORE(r10,MAS5)
mfspr r10,SPRN_MAS8
SPECIAL_EXC_STORE(r10,MAS8)
/* MAS5/8 could have inappropriate values if we interrupted KVM code */
li r10,0
mtspr SPRN_MAS5,r10
mtspr SPRN_MAS8,r10
END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
SPECIAL_EXC_STORE(r9,IRQHAPPENED)
mfspr r10,SPRN_DEAR
SPECIAL_EXC_STORE(r10,DEAR)
mfspr r10,SPRN_ESR
SPECIAL_EXC_STORE(r10,ESR)
lbz r10,PACASOFTIRQEN(r13)
SPECIAL_EXC_STORE(r10,SOFTE)
ld r10,_NIP(r1)
SPECIAL_EXC_STORE(r10,CSRR0)
ld r10,_MSR(r1)
SPECIAL_EXC_STORE(r10,CSRR1)
blr
ret_from_level_except:
ld r3,_MSR(r1)
andi. r3,r3,MSR_PR
beq 1f
b ret_from_except
1:
LOAD_REG_ADDR(r11,extlb_level_exc)
lwz r12,0(r11)
mfspr r10,SPRN_SPRG_TLB_EXFRAME
sub r10,r10,r12
mtspr SPRN_SPRG_TLB_EXFRAME,r10
/*
* It's possible that the special level exception interrupted a
* TLB miss handler, and inserted the same entry that the
* interrupted handler was about to insert. On CPUs without TLB
* write conditional, this can result in a duplicate TLB entry.
* Wipe all non-bolted entries to be safe.
*
* Note that this doesn't protect against any TLB misses
* we may take accessing the stack from here to the end of
* the special level exception. It's not clear how we can
* reasonably protect against that, but only CPUs with
* neither TLB write conditional nor bolted kernel memory
* are affected. Do any such CPUs even exist?
*/
PPC_TLBILX_ALL(0,R0)
REST_NVGPRS(r1)
SPECIAL_EXC_LOAD(r10,SRR0)
mtspr SPRN_SRR0,r10
SPECIAL_EXC_LOAD(r10,SRR1)
mtspr SPRN_SRR1,r10
SPECIAL_EXC_LOAD(r10,SPRG_GEN)
mtspr SPRN_SPRG_GEN_SCRATCH,r10
SPECIAL_EXC_LOAD(r10,SPRG_TLB)
mtspr SPRN_SPRG_TLB_SCRATCH,r10
SPECIAL_EXC_LOAD(r10,MAS0)
mtspr SPRN_MAS0,r10
SPECIAL_EXC_LOAD(r10,MAS1)
mtspr SPRN_MAS1,r10
SPECIAL_EXC_LOAD(r10,MAS2)
mtspr SPRN_MAS2,r10
SPECIAL_EXC_LOAD(r10,MAS3)
mtspr SPRN_MAS3,r10
SPECIAL_EXC_LOAD(r10,MAS6)
mtspr SPRN_MAS6,r10
SPECIAL_EXC_LOAD(r10,MAS7)
mtspr SPRN_MAS7,r10
BEGIN_FTR_SECTION
SPECIAL_EXC_LOAD(r10,MAS5)
mtspr SPRN_MAS5,r10
SPECIAL_EXC_LOAD(r10,MAS8)
mtspr SPRN_MAS8,r10
END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
lbz r6,PACASOFTIRQEN(r13)
ld r5,SOFTE(r1)
/* Interrupts had better not already be enabled... */
twnei r6,0
cmpwi cr0,r5,0
beq 1f
TRACE_ENABLE_INTS
stb r5,PACASOFTIRQEN(r13)
1:
/*
* Restore PACAIRQHAPPENED rather than setting it based on
* the return MSR[EE], since we could have interrupted
* __check_irq_replay() or other inconsistent transitory
* states that must remain that way.
*/
SPECIAL_EXC_LOAD(r10,IRQHAPPENED)
stb r10,PACAIRQHAPPENED(r13)
SPECIAL_EXC_LOAD(r10,DEAR)
mtspr SPRN_DEAR,r10
SPECIAL_EXC_LOAD(r10,ESR)
mtspr SPRN_ESR,r10
stdcx. r0,0,r1 /* to clear the reservation */
REST_4GPRS(2, r1)
REST_4GPRS(6, r1)
ld r10,_CTR(r1)
ld r11,_XER(r1)
mtctr r10
mtxer r11
blr
.macro ret_from_level srr0 srr1 paca_ex scratch
bl ret_from_level_except
ld r10,_LINK(r1)
ld r11,_CCR(r1)
ld r0,GPR13(r1)
mtlr r10
mtcr r11
ld r10,GPR10(r1)
ld r11,GPR11(r1)
ld r12,GPR12(r1)
mtspr \scratch,r0
std r10,\paca_ex+EX_R10(r13);
std r11,\paca_ex+EX_R11(r13);
ld r10,_NIP(r1)
ld r11,_MSR(r1)
ld r0,GPR0(r1)
ld r1,GPR1(r1)
mtspr \srr0,r10
mtspr \srr1,r11
ld r10,\paca_ex+EX_R10(r13)
ld r11,\paca_ex+EX_R11(r13)
mfspr r13,\scratch
.endm
ret_from_crit_except:
ret_from_level SPRN_CSRR0 SPRN_CSRR1 PACA_EXCRIT SPRN_SPRG_CRIT_SCRATCH
rfci
ret_from_mc_except:
ret_from_level SPRN_MCSRR0 SPRN_MCSRR1 PACA_EXMC SPRN_SPRG_MC_SCRATCH
rfmci
/* Exception prolog code for all exceptions */ /* Exception prolog code for all exceptions */
#define EXCEPTION_PROLOG(n, intnum, type, addition) \ #define EXCEPTION_PROLOG(n, intnum, type, addition) \
...@@ -42,7 +285,6 @@ ...@@ -42,7 +285,6 @@
mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \ mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \
std r10,PACA_EX##type+EX_R10(r13); \ std r10,PACA_EX##type+EX_R10(r13); \
std r11,PACA_EX##type+EX_R11(r13); \ std r11,PACA_EX##type+EX_R11(r13); \
PROLOG_STORE_RESTORE_SCRATCH_##type; \
mfcr r10; /* save CR */ \ mfcr r10; /* save CR */ \
mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \ mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \
DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \ DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \
...@@ -69,19 +311,19 @@ ...@@ -69,19 +311,19 @@
#define CRIT_SET_KSTACK \ #define CRIT_SET_KSTACK \
ld r1,PACA_CRIT_STACK(r13); \ ld r1,PACA_CRIT_STACK(r13); \
subi r1,r1,SPECIAL_EXC_FRAME_SIZE; subi r1,r1,SPECIAL_EXC_FRAME_SIZE
#define SPRN_CRIT_SRR0 SPRN_CSRR0 #define SPRN_CRIT_SRR0 SPRN_CSRR0
#define SPRN_CRIT_SRR1 SPRN_CSRR1 #define SPRN_CRIT_SRR1 SPRN_CSRR1
#define DBG_SET_KSTACK \ #define DBG_SET_KSTACK \
ld r1,PACA_DBG_STACK(r13); \ ld r1,PACA_DBG_STACK(r13); \
subi r1,r1,SPECIAL_EXC_FRAME_SIZE; subi r1,r1,SPECIAL_EXC_FRAME_SIZE
#define SPRN_DBG_SRR0 SPRN_DSRR0 #define SPRN_DBG_SRR0 SPRN_DSRR0
#define SPRN_DBG_SRR1 SPRN_DSRR1 #define SPRN_DBG_SRR1 SPRN_DSRR1
#define MC_SET_KSTACK \ #define MC_SET_KSTACK \
ld r1,PACA_MC_STACK(r13); \ ld r1,PACA_MC_STACK(r13); \
subi r1,r1,SPECIAL_EXC_FRAME_SIZE; subi r1,r1,SPECIAL_EXC_FRAME_SIZE
#define SPRN_MC_SRR0 SPRN_MCSRR0 #define SPRN_MC_SRR0 SPRN_MCSRR0
#define SPRN_MC_SRR1 SPRN_MCSRR1 #define SPRN_MC_SRR1 SPRN_MCSRR1
...@@ -100,20 +342,6 @@ ...@@ -100,20 +342,6 @@
#define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \ #define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \
EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n)) EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n))
/*
* Store user-visible scratch in PACA exception slots and restore proper value
*/
#define PROLOG_STORE_RESTORE_SCRATCH_GEN
#define PROLOG_STORE_RESTORE_SCRATCH_GDBELL
#define PROLOG_STORE_RESTORE_SCRATCH_DBG
#define PROLOG_STORE_RESTORE_SCRATCH_MC
#define PROLOG_STORE_RESTORE_SCRATCH_CRIT \
mfspr r10,SPRN_SPRG_CRIT_SCRATCH; /* get r13 */ \
std r10,PACA_EXCRIT+EX_R13(r13); \
ld r11,PACA_SPRG3(r13); \
mtspr SPRN_SPRG_CRIT_SCRATCH,r11;
/* Variants of the "addition" argument for the prolog /* Variants of the "addition" argument for the prolog
*/ */
#define PROLOG_ADDITION_NONE_GEN(n) #define PROLOG_ADDITION_NONE_GEN(n)
...@@ -147,10 +375,8 @@ ...@@ -147,10 +375,8 @@
std r15,PACA_EXMC+EX_R15(r13) std r15,PACA_EXMC+EX_R15(r13)
/* Core exception code for all exceptions except TLB misses. /* Core exception code for all exceptions except TLB misses. */
* XXX: Needs to make SPRN_SPRG_GEN depend on exception type #define EXCEPTION_COMMON_LVL(n, scratch, excf) \
*/
#define EXCEPTION_COMMON(n, excf, ints) \
exc_##n##_common: \ exc_##n##_common: \
std r0,GPR0(r1); /* save r0 in stackframe */ \ std r0,GPR0(r1); /* save r0 in stackframe */ \
std r2,GPR2(r1); /* save r2 in stackframe */ \ std r2,GPR2(r1); /* save r2 in stackframe */ \
...@@ -163,7 +389,7 @@ exc_##n##_common: \ ...@@ -163,7 +389,7 @@ exc_##n##_common: \
ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */ \ ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */ \
2: ld r3,excf+EX_R10(r13); /* get back r10 */ \ 2: ld r3,excf+EX_R10(r13); /* get back r10 */ \
ld r4,excf+EX_R11(r13); /* get back r11 */ \ ld r4,excf+EX_R11(r13); /* get back r11 */ \
mfspr r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 */ \ mfspr r5,scratch; /* get back r13 */ \
std r12,GPR12(r1); /* save r12 in stackframe */ \ std r12,GPR12(r1); /* save r12 in stackframe */ \
ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
mflr r6; /* save LR in stackframe */ \ mflr r6; /* save LR in stackframe */ \
...@@ -187,24 +413,29 @@ exc_##n##_common: \ ...@@ -187,24 +413,29 @@ exc_##n##_common: \
std r11,SOFTE(r1); /* and save it to stackframe */ \ std r11,SOFTE(r1); /* and save it to stackframe */ \
std r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ \ std r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ \
std r3,_TRAP(r1); /* set trap number */ \ std r3,_TRAP(r1); /* set trap number */ \
std r0,RESULT(r1); /* clear regs->result */ \ std r0,RESULT(r1); /* clear regs->result */
ints;
/* Variants for the "ints" argument. This one does nothing when we want #define EXCEPTION_COMMON(n) \
* to keep interrupts in their original state EXCEPTION_COMMON_LVL(n, SPRN_SPRG_GEN_SCRATCH, PACA_EXGEN)
*/ #define EXCEPTION_COMMON_CRIT(n) \
#define INTS_KEEP EXCEPTION_COMMON_LVL(n, SPRN_SPRG_CRIT_SCRATCH, PACA_EXCRIT)
#define EXCEPTION_COMMON_MC(n) \
EXCEPTION_COMMON_LVL(n, SPRN_SPRG_MC_SCRATCH, PACA_EXMC)
#define EXCEPTION_COMMON_DBG(n) \
EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG)
/* This second version is meant for exceptions that don't immediately /*
* hard-enable. We set a bit in paca->irq_happened to ensure that * This is meant for exceptions that don't immediately hard-enable. We
* a subsequent call to arch_local_irq_restore() will properly * set a bit in paca->irq_happened to ensure that a subsequent call to
* hard-enable and avoid the fast-path, and then reconcile irq state. * arch_local_irq_restore() will properly hard-enable and avoid the
* fast-path, and then reconcile irq state.
*/ */
#define INTS_DISABLE RECONCILE_IRQ_STATE(r3,r4) #define INTS_DISABLE RECONCILE_IRQ_STATE(r3,r4)
/* This is called by exceptions that used INTS_KEEP (that did not touch /*
* irq indicators in the PACA). This will restore MSR:EE to it's previous * This is called by exceptions that don't use INTS_DISABLE (that did not
* value * touch irq indicators in the PACA). This will restore MSR:EE to it's
* previous value
* *
* XXX In the long run, we may want to open-code it in order to separate the * XXX In the long run, we may want to open-code it in order to separate the
* load from the wrtee, thus limiting the latency caused by the dependency * load from the wrtee, thus limiting the latency caused by the dependency
...@@ -262,7 +493,8 @@ exc_##n##_bad_stack: \ ...@@ -262,7 +493,8 @@ exc_##n##_bad_stack: \
#define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack) \ #define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack) \
START_EXCEPTION(label); \ START_EXCEPTION(label); \
NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\ NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE) \ EXCEPTION_COMMON(trapnum) \
INTS_DISABLE; \
ack(r8); \ ack(r8); \
CHECK_NAPPING(); \ CHECK_NAPPING(); \
addi r3,r1,STACK_FRAME_OVERHEAD; \ addi r3,r1,STACK_FRAME_OVERHEAD; \
...@@ -283,8 +515,8 @@ exception_marker: ...@@ -283,8 +515,8 @@ exception_marker:
.balign 0x1000 .balign 0x1000
.globl interrupt_base_book3e .globl interrupt_base_book3e
interrupt_base_book3e: /* fake trap */ interrupt_base_book3e: /* fake trap */
EXCEPTION_STUB(0x000, machine_check) /* 0x0200 */ EXCEPTION_STUB(0x000, machine_check)
EXCEPTION_STUB(0x020, critical_input) /* 0x0580 */ EXCEPTION_STUB(0x020, critical_input) /* 0x0100 */
EXCEPTION_STUB(0x040, debug_crit) /* 0x0d00 */ EXCEPTION_STUB(0x040, debug_crit) /* 0x0d00 */
EXCEPTION_STUB(0x060, data_storage) /* 0x0300 */ EXCEPTION_STUB(0x060, data_storage) /* 0x0300 */
EXCEPTION_STUB(0x080, instruction_storage) /* 0x0400 */ EXCEPTION_STUB(0x080, instruction_storage) /* 0x0400 */
...@@ -299,8 +531,8 @@ interrupt_base_book3e: /* fake trap */ ...@@ -299,8 +531,8 @@ interrupt_base_book3e: /* fake trap */
EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */
EXCEPTION_STUB(0x1c0, data_tlb_miss) EXCEPTION_STUB(0x1c0, data_tlb_miss)
EXCEPTION_STUB(0x1e0, instruction_tlb_miss) EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
EXCEPTION_STUB(0x200, altivec_unavailable) /* 0x0f20 */ EXCEPTION_STUB(0x200, altivec_unavailable)
EXCEPTION_STUB(0x220, altivec_assist) /* 0x1700 */ EXCEPTION_STUB(0x220, altivec_assist)
EXCEPTION_STUB(0x260, perfmon) EXCEPTION_STUB(0x260, perfmon)
EXCEPTION_STUB(0x280, doorbell) EXCEPTION_STUB(0x280, doorbell)
EXCEPTION_STUB(0x2a0, doorbell_crit) EXCEPTION_STUB(0x2a0, doorbell_crit)
...@@ -317,25 +549,25 @@ interrupt_end_book3e: ...@@ -317,25 +549,25 @@ interrupt_end_book3e:
START_EXCEPTION(critical_input); START_EXCEPTION(critical_input);
CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL, CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE) EXCEPTION_COMMON_CRIT(0x100)
// bl special_reg_save_crit bl .save_nvgprs
// CHECK_NAPPING(); bl special_reg_save
// addi r3,r1,STACK_FRAME_OVERHEAD CHECK_NAPPING();
// bl .critical_exception addi r3,r1,STACK_FRAME_OVERHEAD
// b ret_from_crit_except bl .unknown_exception
b . b ret_from_crit_except
/* Machine Check Interrupt */ /* Machine Check Interrupt */
START_EXCEPTION(machine_check); START_EXCEPTION(machine_check);
MC_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_MACHINE_CHECK, MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE) EXCEPTION_COMMON_MC(0x000)
// bl special_reg_save_mc bl .save_nvgprs
// addi r3,r1,STACK_FRAME_OVERHEAD bl special_reg_save
// CHECK_NAPPING(); CHECK_NAPPING();
// bl .machine_check_exception addi r3,r1,STACK_FRAME_OVERHEAD
// b ret_from_mc_except bl .machine_check_exception
b . b ret_from_mc_except
/* Data Storage Interrupt */ /* Data Storage Interrupt */
START_EXCEPTION(data_storage) START_EXCEPTION(data_storage)
...@@ -343,7 +575,8 @@ interrupt_end_book3e: ...@@ -343,7 +575,8 @@ interrupt_end_book3e:
PROLOG_ADDITION_2REGS) PROLOG_ADDITION_2REGS)
mfspr r14,SPRN_DEAR mfspr r14,SPRN_DEAR
mfspr r15,SPRN_ESR mfspr r15,SPRN_ESR
EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_DISABLE) EXCEPTION_COMMON(0x300)
INTS_DISABLE
b storage_fault_common b storage_fault_common
/* Instruction Storage Interrupt */ /* Instruction Storage Interrupt */
...@@ -352,7 +585,8 @@ interrupt_end_book3e: ...@@ -352,7 +585,8 @@ interrupt_end_book3e:
PROLOG_ADDITION_2REGS) PROLOG_ADDITION_2REGS)
li r15,0 li r15,0
mr r14,r10 mr r14,r10
EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_DISABLE) EXCEPTION_COMMON(0x400)
INTS_DISABLE
b storage_fault_common b storage_fault_common
/* External Input Interrupt */ /* External Input Interrupt */
...@@ -365,7 +599,7 @@ interrupt_end_book3e: ...@@ -365,7 +599,7 @@ interrupt_end_book3e:
PROLOG_ADDITION_2REGS) PROLOG_ADDITION_2REGS)
mfspr r14,SPRN_DEAR mfspr r14,SPRN_DEAR
mfspr r15,SPRN_ESR mfspr r15,SPRN_ESR
EXCEPTION_COMMON(0x600, PACA_EXGEN, INTS_KEEP) EXCEPTION_COMMON(0x600)
b alignment_more /* no room, go out of line */ b alignment_more /* no room, go out of line */
/* Program Interrupt */ /* Program Interrupt */
...@@ -373,7 +607,8 @@ interrupt_end_book3e: ...@@ -373,7 +607,8 @@ interrupt_end_book3e:
NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM, NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM,
PROLOG_ADDITION_1REG) PROLOG_ADDITION_1REG)
mfspr r14,SPRN_ESR mfspr r14,SPRN_ESR
EXCEPTION_COMMON(0x700, PACA_EXGEN, INTS_DISABLE) EXCEPTION_COMMON(0x700)
INTS_DISABLE
std r14,_DSISR(r1) std r14,_DSISR(r1)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
ld r14,PACA_EXGEN+EX_R14(r13) ld r14,PACA_EXGEN+EX_R14(r13)
...@@ -386,7 +621,7 @@ interrupt_end_book3e: ...@@ -386,7 +621,7 @@ interrupt_end_book3e:
NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL, NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
/* we can probably do a shorter exception entry for that one... */ /* we can probably do a shorter exception entry for that one... */
EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP) EXCEPTION_COMMON(0x800)
ld r12,_MSR(r1) ld r12,_MSR(r1)
andi. r0,r12,MSR_PR; andi. r0,r12,MSR_PR;
beq- 1f beq- 1f
...@@ -403,7 +638,7 @@ interrupt_end_book3e: ...@@ -403,7 +638,7 @@ interrupt_end_book3e:
NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL, NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
/* we can probably do a shorter exception entry for that one... */ /* we can probably do a shorter exception entry for that one... */
EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP) EXCEPTION_COMMON(0x200)
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
ld r12,_MSR(r1) ld r12,_MSR(r1)
...@@ -425,7 +660,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -425,7 +660,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
NORMAL_EXCEPTION_PROLOG(0x220, NORMAL_EXCEPTION_PROLOG(0x220,
BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST, BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE) EXCEPTION_COMMON(0x220)
INTS_DISABLE
bl .save_nvgprs bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
...@@ -450,13 +686,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -450,13 +686,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
START_EXCEPTION(watchdog); START_EXCEPTION(watchdog);
CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE) EXCEPTION_COMMON_CRIT(0x9f0)
// bl special_reg_save_crit bl .save_nvgprs
// CHECK_NAPPING(); bl special_reg_save
// addi r3,r1,STACK_FRAME_OVERHEAD CHECK_NAPPING();
// bl .unknown_exception addi r3,r1,STACK_FRAME_OVERHEAD
// b ret_from_crit_except #ifdef CONFIG_BOOKE_WDT
b . bl .WatchdogException
#else
bl .unknown_exception
#endif
b ret_from_crit_except
/* System Call Interrupt */ /* System Call Interrupt */
START_EXCEPTION(system_call) START_EXCEPTION(system_call)
...@@ -470,7 +710,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -470,7 +710,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
START_EXCEPTION(ap_unavailable); START_EXCEPTION(ap_unavailable);
NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL, NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_DISABLE) EXCEPTION_COMMON(0xf20)
INTS_DISABLE
bl .save_nvgprs bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl .unknown_exception bl .unknown_exception
...@@ -513,7 +754,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -513,7 +754,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
mtcr r10 mtcr r10
ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */ ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */
ld r11,PACA_EXCRIT+EX_R11(r13) ld r11,PACA_EXCRIT+EX_R11(r13)
ld r13,PACA_EXCRIT+EX_R13(r13) mfspr r13,SPRN_SPRG_CRIT_SCRATCH
rfci rfci
/* Normal debug exception */ /* Normal debug exception */
...@@ -526,10 +767,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -526,10 +767,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
/* Now we mash up things to make it look like we are coming on a /* Now we mash up things to make it look like we are coming on a
* normal exception * normal exception
*/ */
ld r15,PACA_EXCRIT+EX_R13(r13)
mtspr SPRN_SPRG_GEN_SCRATCH,r15
mfspr r14,SPRN_DBSR mfspr r14,SPRN_DBSR
EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE) EXCEPTION_COMMON_CRIT(0xd00)
std r14,_DSISR(r1) std r14,_DSISR(r1)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
mr r4,r14 mr r4,r14
...@@ -592,10 +831,9 @@ kernel_dbg_exc: ...@@ -592,10 +831,9 @@ kernel_dbg_exc:
/* Now we mash up things to make it look like we are coming on a /* Now we mash up things to make it look like we are coming on a
* normal exception * normal exception
*/ */
mfspr r15,SPRN_SPRG_DBG_SCRATCH
mtspr SPRN_SPRG_GEN_SCRATCH,r15
mfspr r14,SPRN_DBSR mfspr r14,SPRN_DBSR
EXCEPTION_COMMON(0xd08, PACA_EXDBG, INTS_DISABLE) EXCEPTION_COMMON_DBG(0xd08)
INTS_DISABLE
std r14,_DSISR(r1) std r14,_DSISR(r1)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
mr r4,r14 mr r4,r14
...@@ -608,7 +846,8 @@ kernel_dbg_exc: ...@@ -608,7 +846,8 @@ kernel_dbg_exc:
START_EXCEPTION(perfmon); START_EXCEPTION(perfmon);
NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x260, PACA_EXGEN, INTS_DISABLE) EXCEPTION_COMMON(0x260)
INTS_DISABLE
CHECK_NAPPING() CHECK_NAPPING()
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl .performance_monitor_exception bl .performance_monitor_exception
...@@ -622,13 +861,13 @@ kernel_dbg_exc: ...@@ -622,13 +861,13 @@ kernel_dbg_exc:
START_EXCEPTION(doorbell_crit); START_EXCEPTION(doorbell_crit);
CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL, CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x2a0, PACA_EXCRIT, INTS_DISABLE) EXCEPTION_COMMON_CRIT(0x2a0)
// bl special_reg_save_crit bl .save_nvgprs
// CHECK_NAPPING(); bl special_reg_save
// addi r3,r1,STACK_FRAME_OVERHEAD CHECK_NAPPING();
// bl .doorbell_critical_exception addi r3,r1,STACK_FRAME_OVERHEAD
// b ret_from_crit_except bl .unknown_exception
b . b ret_from_crit_except
/* /*
* Guest doorbell interrupt * Guest doorbell interrupt
...@@ -637,7 +876,7 @@ kernel_dbg_exc: ...@@ -637,7 +876,7 @@ kernel_dbg_exc:
START_EXCEPTION(guest_doorbell); START_EXCEPTION(guest_doorbell);
GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL, GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x2c0, PACA_EXGEN, INTS_KEEP) EXCEPTION_COMMON(0x2c0)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl .save_nvgprs bl .save_nvgprs
INTS_RESTORE_HARD INTS_RESTORE_HARD
...@@ -648,19 +887,19 @@ kernel_dbg_exc: ...@@ -648,19 +887,19 @@ kernel_dbg_exc:
START_EXCEPTION(guest_doorbell_crit); START_EXCEPTION(guest_doorbell_crit);
CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT, CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x2e0, PACA_EXCRIT, INTS_DISABLE) EXCEPTION_COMMON_CRIT(0x2e0)
// bl special_reg_save_crit bl .save_nvgprs
// CHECK_NAPPING(); bl special_reg_save
// addi r3,r1,STACK_FRAME_OVERHEAD CHECK_NAPPING();
// bl .guest_doorbell_critical_exception addi r3,r1,STACK_FRAME_OVERHEAD
// b ret_from_crit_except bl .unknown_exception
b . b ret_from_crit_except
/* Hypervisor call */ /* Hypervisor call */
START_EXCEPTION(hypercall); START_EXCEPTION(hypercall);
NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL, NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x310, PACA_EXGEN, INTS_KEEP) EXCEPTION_COMMON(0x310)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl .save_nvgprs bl .save_nvgprs
INTS_RESTORE_HARD INTS_RESTORE_HARD
...@@ -671,7 +910,7 @@ kernel_dbg_exc: ...@@ -671,7 +910,7 @@ kernel_dbg_exc:
START_EXCEPTION(ehpriv); START_EXCEPTION(ehpriv);
NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV, NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x320, PACA_EXGEN, INTS_KEEP) EXCEPTION_COMMON(0x320)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl .save_nvgprs bl .save_nvgprs
INTS_RESTORE_HARD INTS_RESTORE_HARD
...@@ -682,7 +921,7 @@ kernel_dbg_exc: ...@@ -682,7 +921,7 @@ kernel_dbg_exc:
START_EXCEPTION(lrat_error); START_EXCEPTION(lrat_error);
NORMAL_EXCEPTION_PROLOG(0x340, BOOKE_INTERRUPT_LRAT_ERROR, NORMAL_EXCEPTION_PROLOG(0x340, BOOKE_INTERRUPT_LRAT_ERROR,
PROLOG_ADDITION_NONE) PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x340, PACA_EXGEN, INTS_KEEP) EXCEPTION_COMMON(0x340)
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl .save_nvgprs bl .save_nvgprs
INTS_RESTORE_HARD INTS_RESTORE_HARD
......
...@@ -102,6 +102,8 @@ static void setup_tlb_core_data(void) ...@@ -102,6 +102,8 @@ static void setup_tlb_core_data(void)
{ {
int cpu; int cpu;
BUILD_BUG_ON(offsetof(struct tlb_core_data, lock) != 0);
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
int first = cpu_first_thread_sibling(cpu); int first = cpu_first_thread_sibling(cpu);
...@@ -552,14 +554,20 @@ static void __init irqstack_early_init(void) ...@@ -552,14 +554,20 @@ static void __init irqstack_early_init(void)
static void __init exc_lvl_early_init(void) static void __init exc_lvl_early_init(void)
{ {
unsigned int i; unsigned int i;
unsigned long sp;
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
critirq_ctx[i] = (struct thread_info *) sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); critirq_ctx[i] = (struct thread_info *)__va(sp);
dbgirq_ctx[i] = (struct thread_info *) paca[i].crit_kstack = __va(sp + THREAD_SIZE);
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
mcheckirq_ctx[i] = (struct thread_info *) sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); dbgirq_ctx[i] = (struct thread_info *)__va(sp);
paca[i].dbg_kstack = __va(sp + THREAD_SIZE);
sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
mcheckirq_ctx[i] = (struct thread_info *)__va(sp);
paca[i].mc_kstack = __va(sp + THREAD_SIZE);
} }
if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC)) if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC))
......
...@@ -715,8 +715,8 @@ int vdso_getcpu_init(void) ...@@ -715,8 +715,8 @@ int vdso_getcpu_init(void)
unsigned long cpu, node, val; unsigned long cpu, node, val;
/* /*
* SPRG3 contains the CPU in the bottom 16 bits and the NUMA node in * SPRG_VDSO contains the CPU in the bottom 16 bits and the NUMA node
* the next 16 bits. The VDSO uses this to implement getcpu(). * in the next 16 bits. The VDSO uses this to implement getcpu().
*/ */
cpu = get_cpu(); cpu = get_cpu();
WARN_ON_ONCE(cpu > 0xffff); WARN_ON_ONCE(cpu > 0xffff);
...@@ -725,8 +725,8 @@ int vdso_getcpu_init(void) ...@@ -725,8 +725,8 @@ int vdso_getcpu_init(void)
WARN_ON_ONCE(node > 0xffff); WARN_ON_ONCE(node > 0xffff);
val = (cpu & 0xfff) | ((node & 0xffff) << 16); val = (cpu & 0xfff) | ((node & 0xffff) << 16);
mtspr(SPRN_SPRG3, val); mtspr(SPRN_SPRG_VDSO_WRITE, val);
get_paca()->sprg3 = val; get_paca()->sprg_vdso = val;
put_cpu(); put_cpu();
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
*/ */
V_FUNCTION_BEGIN(__kernel_getcpu) V_FUNCTION_BEGIN(__kernel_getcpu)
.cfi_startproc .cfi_startproc
mfspr r5,SPRN_USPRG3 mfspr r5,SPRN_SPRG_VDSO_READ
cmpdi cr0,r3,0 cmpdi cr0,r3,0
cmpdi cr1,r4,0 cmpdi cr1,r4,0
clrlwi r6,r5,16 clrlwi r6,r5,16
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
*/ */
V_FUNCTION_BEGIN(__kernel_getcpu) V_FUNCTION_BEGIN(__kernel_getcpu)
.cfi_startproc .cfi_startproc
mfspr r5,SPRN_USPRG3 mfspr r5,SPRN_SPRG_VDSO_READ
cmpdi cr0,r3,0 cmpdi cr0,r3,0
cmpdi cr1,r4,0 cmpdi cr1,r4,0
clrlwi r6,r5,16 clrlwi r6,r5,16
......
...@@ -75,8 +75,8 @@ BEGIN_FTR_SECTION ...@@ -75,8 +75,8 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
/* Restore SPRG3 */ /* Restore SPRG3 */
ld r3,PACA_SPRG3(r13) ld r3,PACA_SPRG_VDSO(r13)
mtspr SPRN_SPRG3,r3 mtspr SPRN_SPRG_VDSO_WRITE,r3
/* Reload the host's PMU registers */ /* Reload the host's PMU registers */
ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */ ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */
......
...@@ -153,8 +153,8 @@ kvm_start_lightweight: ...@@ -153,8 +153,8 @@ kvm_start_lightweight:
* Reload kernel SPRG3 value. * Reload kernel SPRG3 value.
* No need to save guest value as usermode can't modify SPRG3. * No need to save guest value as usermode can't modify SPRG3.
*/ */
ld r3, PACA_SPRG3(r13) ld r3, PACA_SPRG_VDSO(r13)
mtspr SPRN_SPRG3, r3 mtspr SPRN_SPRG_VDSO_WRITE, r3
#endif /* CONFIG_PPC_BOOK3S_64 */ #endif /* CONFIG_PPC_BOOK3S_64 */
/* R7 = vcpu */ /* R7 = vcpu */
......
...@@ -229,17 +229,20 @@ ...@@ -229,17 +229,20 @@
stw r10, VCPU_CR(r4) stw r10, VCPU_CR(r4)
PPC_STL r11, VCPU_GPR(R4)(r4) PPC_STL r11, VCPU_GPR(R4)(r4)
PPC_STL r5, VCPU_GPR(R5)(r4) PPC_STL r5, VCPU_GPR(R5)(r4)
.if \type == EX_CRIT
PPC_LL r5, (\paca_ex + EX_R13)(r13)
.else
mfspr r5, \scratch
.endif
PPC_STL r6, VCPU_GPR(R6)(r4) PPC_STL r6, VCPU_GPR(R6)(r4)
PPC_STL r8, VCPU_GPR(R8)(r4) PPC_STL r8, VCPU_GPR(R8)(r4)
PPC_STL r9, VCPU_GPR(R9)(r4) PPC_STL r9, VCPU_GPR(R9)(r4)
PPC_STL r5, VCPU_GPR(R13)(r4) .if \type == EX_TLB
PPC_LL r5, EX_TLB_R13(r12)
PPC_LL r6, EX_TLB_R10(r12)
PPC_LL r8, EX_TLB_R11(r12)
mfspr r12, \scratch
.else
mfspr r5, \scratch
PPC_LL r6, (\paca_ex + \ex_r10)(r13) PPC_LL r6, (\paca_ex + \ex_r10)(r13)
PPC_LL r8, (\paca_ex + \ex_r11)(r13) PPC_LL r8, (\paca_ex + \ex_r11)(r13)
.endif
PPC_STL r5, VCPU_GPR(R13)(r4)
PPC_STL r3, VCPU_GPR(R3)(r4) PPC_STL r3, VCPU_GPR(R3)(r4)
PPC_STL r7, VCPU_GPR(R7)(r4) PPC_STL r7, VCPU_GPR(R7)(r4)
PPC_STL r12, VCPU_GPR(R12)(r4) PPC_STL r12, VCPU_GPR(R12)(r4)
...@@ -435,10 +438,16 @@ _GLOBAL(kvmppc_resume_host) ...@@ -435,10 +438,16 @@ _GLOBAL(kvmppc_resume_host)
PPC_STL r5, VCPU_LR(r4) PPC_STL r5, VCPU_LR(r4)
mfspr r7, SPRN_SPRG5 mfspr r7, SPRN_SPRG5
stw r3, VCPU_VRSAVE(r4) stw r3, VCPU_VRSAVE(r4)
#ifdef CONFIG_64BIT
PPC_LL r3, PACA_SPRG_VDSO(r13)
#endif
PPC_STD(r6, VCPU_SHARED_SPRG4, r11) PPC_STD(r6, VCPU_SHARED_SPRG4, r11)
mfspr r8, SPRN_SPRG6 mfspr r8, SPRN_SPRG6
PPC_STD(r7, VCPU_SHARED_SPRG5, r11) PPC_STD(r7, VCPU_SHARED_SPRG5, r11)
mfspr r9, SPRN_SPRG7 mfspr r9, SPRN_SPRG7
#ifdef CONFIG_64BIT
mtspr SPRN_SPRG_VDSO_WRITE, r3
#endif
PPC_STD(r8, VCPU_SHARED_SPRG6, r11) PPC_STD(r8, VCPU_SHARED_SPRG6, r11)
mfxer r3 mfxer r3
PPC_STD(r9, VCPU_SHARED_SPRG7, r11) PPC_STD(r9, VCPU_SHARED_SPRG7, r11)
......
...@@ -39,37 +39,49 @@ ...@@ -39,37 +39,49 @@
* * * *
**********************************************************************/ **********************************************************************/
/*
* Note that, unlike non-bolted handlers, TLB_EXFRAME is not
* modified by the TLB miss handlers themselves, since the TLB miss
* handler code will not itself cause a recursive TLB miss.
*
* TLB_EXFRAME will be modified when crit/mc/debug exceptions are
* entered/exited.
*/
.macro tlb_prolog_bolted intnum addr .macro tlb_prolog_bolted intnum addr
mtspr SPRN_SPRG_GEN_SCRATCH,r13 mtspr SPRN_SPRG_GEN_SCRATCH,r12
mfspr r12,SPRN_SPRG_TLB_EXFRAME
std r13,EX_TLB_R13(r12)
std r10,EX_TLB_R10(r12)
mfspr r13,SPRN_SPRG_PACA mfspr r13,SPRN_SPRG_PACA
std r10,PACA_EXTLB+EX_TLB_R10(r13)
mfcr r10 mfcr r10
std r11,PACA_EXTLB+EX_TLB_R11(r13) std r11,EX_TLB_R11(r12)
#ifdef CONFIG_KVM_BOOKE_HV #ifdef CONFIG_KVM_BOOKE_HV
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
mfspr r11, SPRN_SRR1 mfspr r11, SPRN_SRR1
END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
#endif #endif
DO_KVM \intnum, SPRN_SRR1 DO_KVM \intnum, SPRN_SRR1
std r16,PACA_EXTLB+EX_TLB_R16(r13) std r16,EX_TLB_R16(r12)
mfspr r16,\addr /* get faulting address */ mfspr r16,\addr /* get faulting address */
std r14,PACA_EXTLB+EX_TLB_R14(r13) std r14,EX_TLB_R14(r12)
ld r14,PACAPGD(r13) ld r14,PACAPGD(r13)
std r15,PACA_EXTLB+EX_TLB_R15(r13) std r15,EX_TLB_R15(r12)
std r10,PACA_EXTLB+EX_TLB_CR(r13) std r10,EX_TLB_CR(r12)
TLB_MISS_PROLOG_STATS_BOLTED TLB_MISS_PROLOG_STATS
.endm .endm
.macro tlb_epilog_bolted .macro tlb_epilog_bolted
ld r14,PACA_EXTLB+EX_TLB_CR(r13) ld r14,EX_TLB_CR(r12)
ld r10,PACA_EXTLB+EX_TLB_R10(r13) ld r10,EX_TLB_R10(r12)
ld r11,PACA_EXTLB+EX_TLB_R11(r13) ld r11,EX_TLB_R11(r12)
ld r13,EX_TLB_R13(r12)
mtcr r14 mtcr r14
ld r14,PACA_EXTLB+EX_TLB_R14(r13) ld r14,EX_TLB_R14(r12)
ld r15,PACA_EXTLB+EX_TLB_R15(r13) ld r15,EX_TLB_R15(r12)
TLB_MISS_RESTORE_STATS_BOLTED TLB_MISS_RESTORE_STATS
ld r16,PACA_EXTLB+EX_TLB_R16(r13) ld r16,EX_TLB_R16(r12)
mfspr r13,SPRN_SPRG_GEN_SCRATCH mfspr r12,SPRN_SPRG_GEN_SCRATCH
.endm .endm
/* Data TLB miss */ /* Data TLB miss */
...@@ -284,7 +296,7 @@ itlb_miss_fault_bolted: ...@@ -284,7 +296,7 @@ itlb_miss_fault_bolted:
* r14 = page table base * r14 = page table base
* r13 = PACA * r13 = PACA
* r11 = tlb_per_core ptr * r11 = tlb_per_core ptr
* r10 = crap (free to use) * r10 = cpu number
*/ */
tlb_miss_common_e6500: tlb_miss_common_e6500:
/* /*
...@@ -293,15 +305,18 @@ tlb_miss_common_e6500: ...@@ -293,15 +305,18 @@ tlb_miss_common_e6500:
* *
* MAS6:IND should be already set based on MAS4 * MAS6:IND should be already set based on MAS4
*/ */
addi r10,r11,TCD_LOCK 1: lbarx r15,0,r11
1: lbarx r15,0,r10 lhz r10,PACAPACAINDEX(r13)
cmpdi r15,0 cmpdi r15,0
cmpdi cr1,r15,1 /* set cr1.eq = 0 for non-recursive */
bne 2f bne 2f
li r15,1 stbcx. r10,0,r11
stbcx. r15,0,r10
bne 1b bne 1b
3:
.subsection 1 .subsection 1
2: lbz r15,0(r10) 2: cmpd cr1,r15,r10 /* recursive lock due to mcheck/crit/etc? */
beq cr1,3b /* unlock will happen if cr1.eq = 0 */
lbz r15,0(r11)
cmpdi r15,0 cmpdi r15,0
bne 2b bne 2b
b 1b b 1b
...@@ -379,9 +394,11 @@ tlb_miss_common_e6500: ...@@ -379,9 +394,11 @@ tlb_miss_common_e6500:
tlb_miss_done_e6500: tlb_miss_done_e6500:
.macro tlb_unlock_e6500 .macro tlb_unlock_e6500
beq cr1,1f /* no unlock if lock was recursively grabbed */
li r15,0 li r15,0
isync isync
stb r15,TCD_LOCK(r11) stb r15,0(r11)
1:
.endm .endm
tlb_unlock_e6500 tlb_unlock_e6500
......
...@@ -144,6 +144,15 @@ int mmu_vmemmap_psize; /* Page size used for the virtual mem map */ ...@@ -144,6 +144,15 @@ int mmu_vmemmap_psize; /* Page size used for the virtual mem map */
int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */ int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */
unsigned long linear_map_top; /* Top of linear mapping */ unsigned long linear_map_top; /* Top of linear mapping */
/*
* Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
* exceptions. This is used for bolted and e6500 TLB miss handlers which
* do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
* this is set to zero.
*/
int extlb_level_exc;
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
#ifdef CONFIG_PPC_FSL_BOOK3E #ifdef CONFIG_PPC_FSL_BOOK3E
...@@ -559,6 +568,7 @@ static void setup_mmu_htw(void) ...@@ -559,6 +568,7 @@ static void setup_mmu_htw(void)
break; break;
#ifdef CONFIG_PPC_FSL_BOOK3E #ifdef CONFIG_PPC_FSL_BOOK3E
case PPC_HTW_E6500: case PPC_HTW_E6500:
extlb_level_exc = EX_TLB_SIZE;
patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e); patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e); patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
break; break;
...@@ -652,6 +662,7 @@ static void __early_init_mmu(int boot_cpu) ...@@ -652,6 +662,7 @@ static void __early_init_mmu(int boot_cpu)
memblock_enforce_memory_limit(linear_map_top); memblock_enforce_memory_limit(linear_map_top);
if (book3e_htw_mode == PPC_HTW_NONE) { if (book3e_htw_mode == PPC_HTW_NONE) {
extlb_level_exc = EX_TLB_SIZE;
patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
patch_exception(0x1e0, patch_exception(0x1e0,
exc_instruction_tlb_miss_bolted_book3e); exc_instruction_tlb_miss_bolted_book3e);
......
...@@ -68,6 +68,7 @@ define_machine(c293_pcie) { ...@@ -68,6 +68,7 @@ define_machine(c293_pcie) {
.init_IRQ = c293_pcie_pic_init, .init_IRQ = c293_pcie_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -107,6 +107,12 @@ void __init mpc85xx_qe_init(void) ...@@ -107,6 +107,12 @@ void __init mpc85xx_qe_init(void)
qe_reset(); qe_reset();
of_node_put(np); of_node_put(np);
}
void __init mpc85xx_qe_par_io_init(void)
{
struct device_node *np;
np = of_find_node_by_name(NULL, "par_io"); np = of_find_node_by_name(NULL, "par_io");
if (np) { if (np) {
struct device_node *ucc; struct device_node *ucc;
......
...@@ -26,11 +26,13 @@ ...@@ -26,11 +26,13 @@
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/ehv_pic.h> #include <asm/ehv_pic.h>
#include <asm/qe_ic.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h> #include <sysdev/fsl_pci.h>
#include "smp.h" #include "smp.h"
#include "mpc85xx.h"
void __init corenet_gen_pic_init(void) void __init corenet_gen_pic_init(void)
{ {
...@@ -38,6 +40,8 @@ void __init corenet_gen_pic_init(void) ...@@ -38,6 +40,8 @@ void __init corenet_gen_pic_init(void)
unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU | unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
MPIC_NO_RESET; MPIC_NO_RESET;
struct device_node *np;
if (ppc_md.get_irq == mpic_get_coreint_irq) if (ppc_md.get_irq == mpic_get_coreint_irq)
flags |= MPIC_ENABLE_COREINT; flags |= MPIC_ENABLE_COREINT;
...@@ -45,6 +49,13 @@ void __init corenet_gen_pic_init(void) ...@@ -45,6 +49,13 @@ void __init corenet_gen_pic_init(void)
BUG_ON(mpic == NULL); BUG_ON(mpic == NULL);
mpic_init(mpic); mpic_init(mpic);
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
if (np) {
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
qe_ic_cascade_high_mpic);
of_node_put(np);
}
} }
/* /*
...@@ -57,6 +68,8 @@ void __init corenet_gen_setup_arch(void) ...@@ -57,6 +68,8 @@ void __init corenet_gen_setup_arch(void)
swiotlb_detect_4g(); swiotlb_detect_4g();
pr_info("%s board from Freescale Semiconductor\n", ppc_md.name); pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
mpc85xx_qe_init();
} }
static const struct of_device_id of_device_ids[] = { static const struct of_device_id of_device_ids[] = {
...@@ -81,6 +94,9 @@ static const struct of_device_id of_device_ids[] = { ...@@ -81,6 +94,9 @@ static const struct of_device_id of_device_ids[] = {
{ {
.compatible = "fsl,qoriq-pcie-v3.0", .compatible = "fsl,qoriq-pcie-v3.0",
}, },
{
.compatible = "fsl,qe",
},
/* The following two are for the Freescale hypervisor */ /* The following two are for the Freescale hypervisor */
{ {
.name = "hypervisor", .name = "hypervisor",
...@@ -163,6 +179,7 @@ define_machine(corenet_generic) { ...@@ -163,6 +179,7 @@ define_machine(corenet_generic) {
.init_IRQ = corenet_gen_pic_init, .init_IRQ = corenet_gen_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_coreint_irq, .get_irq = mpic_get_coreint_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -215,6 +215,7 @@ define_machine(ge_imp3a) { ...@@ -215,6 +215,7 @@ define_machine(ge_imp3a) {
.show_cpuinfo = ge_imp3a_show_cpuinfo, .show_cpuinfo = ge_imp3a_show_cpuinfo,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -76,6 +76,7 @@ define_machine(mpc8536_ds) { ...@@ -76,6 +76,7 @@ define_machine(mpc8536_ds) {
.init_IRQ = mpc8536_ds_pic_init, .init_IRQ = mpc8536_ds_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -10,8 +10,10 @@ static inline void __init mpc85xx_cpm2_pic_init(void) {} ...@@ -10,8 +10,10 @@ static inline void __init mpc85xx_cpm2_pic_init(void) {}
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
extern void mpc85xx_qe_init(void); extern void mpc85xx_qe_init(void);
extern void mpc85xx_qe_par_io_init(void);
#else #else
static inline void __init mpc85xx_qe_init(void) {} static inline void __init mpc85xx_qe_init(void) {}
static inline void __init mpc85xx_qe_par_io_init(void) {}
#endif #endif
#endif #endif
...@@ -385,6 +385,7 @@ define_machine(mpc85xx_cds) { ...@@ -385,6 +385,7 @@ define_machine(mpc85xx_cds) {
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.restart = mpc85xx_cds_restart, .restart = mpc85xx_cds_restart,
.pcibios_fixup_bus = mpc85xx_cds_fixup_bus, .pcibios_fixup_bus = mpc85xx_cds_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#else #else
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
#endif #endif
......
...@@ -209,6 +209,7 @@ define_machine(mpc8544_ds) { ...@@ -209,6 +209,7 @@ define_machine(mpc8544_ds) {
.init_IRQ = mpc85xx_ds_pic_init, .init_IRQ = mpc85xx_ds_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -223,6 +224,7 @@ define_machine(mpc8572_ds) { ...@@ -223,6 +224,7 @@ define_machine(mpc8572_ds) {
.init_IRQ = mpc85xx_ds_pic_init, .init_IRQ = mpc85xx_ds_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -237,6 +239,7 @@ define_machine(p2020_ds) { ...@@ -237,6 +239,7 @@ define_machine(p2020_ds) {
.init_IRQ = mpc85xx_ds_pic_init, .init_IRQ = mpc85xx_ds_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -239,6 +239,7 @@ static void __init mpc85xx_mds_qe_init(void) ...@@ -239,6 +239,7 @@ static void __init mpc85xx_mds_qe_init(void)
struct device_node *np; struct device_node *np;
mpc85xx_qe_init(); mpc85xx_qe_init();
mpc85xx_qe_par_io_init();
mpc85xx_mds_reset_ucc_phys(); mpc85xx_mds_reset_ucc_phys();
if (machine_is(p1021_mds)) { if (machine_is(p1021_mds)) {
...@@ -391,6 +392,7 @@ define_machine(mpc8568_mds) { ...@@ -391,6 +392,7 @@ define_machine(mpc8568_mds) {
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
}; };
...@@ -412,6 +414,7 @@ define_machine(mpc8569_mds) { ...@@ -412,6 +414,7 @@ define_machine(mpc8569_mds) {
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
}; };
...@@ -434,6 +437,7 @@ define_machine(p1021_mds) { ...@@ -434,6 +437,7 @@ define_machine(p1021_mds) {
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
}; };
...@@ -86,10 +86,6 @@ void __init mpc85xx_rdb_pic_init(void) ...@@ -86,10 +86,6 @@ void __init mpc85xx_rdb_pic_init(void)
*/ */
static void __init mpc85xx_rdb_setup_arch(void) static void __init mpc85xx_rdb_setup_arch(void)
{ {
#ifdef CONFIG_QUICC_ENGINE
struct device_node *np;
#endif
if (ppc_md.progress) if (ppc_md.progress)
ppc_md.progress("mpc85xx_rdb_setup_arch()", 0); ppc_md.progress("mpc85xx_rdb_setup_arch()", 0);
...@@ -99,8 +95,10 @@ static void __init mpc85xx_rdb_setup_arch(void) ...@@ -99,8 +95,10 @@ static void __init mpc85xx_rdb_setup_arch(void)
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
mpc85xx_qe_init(); mpc85xx_qe_init();
mpc85xx_qe_par_io_init();
#if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE) #if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
if (machine_is(p1025_rdb)) { if (machine_is(p1025_rdb)) {
struct device_node *np;
struct ccsr_guts __iomem *guts; struct ccsr_guts __iomem *guts;
...@@ -233,6 +231,7 @@ define_machine(p2020_rdb) { ...@@ -233,6 +231,7 @@ define_machine(p2020_rdb) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -247,6 +246,7 @@ define_machine(p1020_rdb) { ...@@ -247,6 +246,7 @@ define_machine(p1020_rdb) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -261,6 +261,7 @@ define_machine(p1021_rdb_pc) { ...@@ -261,6 +261,7 @@ define_machine(p1021_rdb_pc) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -275,6 +276,7 @@ define_machine(p2020_rdb_pc) { ...@@ -275,6 +276,7 @@ define_machine(p2020_rdb_pc) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -289,6 +291,7 @@ define_machine(p1025_rdb) { ...@@ -289,6 +291,7 @@ define_machine(p1025_rdb) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -303,6 +306,7 @@ define_machine(p1020_mbg_pc) { ...@@ -303,6 +306,7 @@ define_machine(p1020_mbg_pc) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -317,6 +321,7 @@ define_machine(p1020_utm_pc) { ...@@ -317,6 +321,7 @@ define_machine(p1020_utm_pc) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -331,6 +336,7 @@ define_machine(p1020_rdb_pc) { ...@@ -331,6 +336,7 @@ define_machine(p1020_rdb_pc) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -345,6 +351,7 @@ define_machine(p1020_rdb_pd) { ...@@ -345,6 +351,7 @@ define_machine(p1020_rdb_pd) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -359,6 +366,7 @@ define_machine(p1024_rdb) { ...@@ -359,6 +366,7 @@ define_machine(p1024_rdb) {
.init_IRQ = mpc85xx_rdb_pic_init, .init_IRQ = mpc85xx_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -78,6 +78,7 @@ define_machine(p1010_rdb) { ...@@ -78,6 +78,7 @@ define_machine(p1010_rdb) {
.init_IRQ = p1010_rdb_pic_init, .init_IRQ = p1010_rdb_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -567,6 +567,7 @@ define_machine(p1022_ds) { ...@@ -567,6 +567,7 @@ define_machine(p1022_ds) {
.init_IRQ = p1022_ds_pic_init, .init_IRQ = p1022_ds_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -147,6 +147,7 @@ define_machine(p1022_rdk) { ...@@ -147,6 +147,7 @@ define_machine(p1022_rdk) {
.init_IRQ = p1022_rdk_pic_init, .init_IRQ = p1022_rdk_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -126,6 +126,7 @@ define_machine(p1023_rds) { ...@@ -126,6 +126,7 @@ define_machine(p1023_rds) {
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
}; };
...@@ -140,5 +141,6 @@ define_machine(p1023_rdb) { ...@@ -140,5 +141,6 @@ define_machine(p1023_rdb) {
.progress = udbg_progress, .progress = udbg_progress,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
}; };
...@@ -66,6 +66,7 @@ define_machine(qemu_e500) { ...@@ -66,6 +66,7 @@ define_machine(qemu_e500) {
.init_IRQ = qemu_e500_pic_init, .init_IRQ = qemu_e500_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_coreint_irq, .get_irq = mpic_get_coreint_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -135,6 +135,7 @@ define_machine(sbc8548) { ...@@ -135,6 +135,7 @@ define_machine(sbc8548) {
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress, .progress = udbg_progress,
......
...@@ -77,6 +77,7 @@ static void __init twr_p1025_setup_arch(void) ...@@ -77,6 +77,7 @@ static void __init twr_p1025_setup_arch(void)
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
mpc85xx_qe_init(); mpc85xx_qe_init();
mpc85xx_qe_par_io_init();
#if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE) #if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
if (machine_is(twr_p1025)) { if (machine_is(twr_p1025)) {
......
...@@ -170,6 +170,7 @@ define_machine(xes_mpc8572) { ...@@ -170,6 +170,7 @@ define_machine(xes_mpc8572) {
.init_IRQ = xes_mpc85xx_pic_init, .init_IRQ = xes_mpc85xx_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -184,6 +185,7 @@ define_machine(xes_mpc8548) { ...@@ -184,6 +185,7 @@ define_machine(xes_mpc8548) {
.init_IRQ = xes_mpc85xx_pic_init, .init_IRQ = xes_mpc85xx_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
...@@ -198,6 +200,7 @@ define_machine(xes_mpc8540) { ...@@ -198,6 +200,7 @@ define_machine(xes_mpc8540) {
.init_IRQ = xes_mpc85xx_pic_init, .init_IRQ = xes_mpc85xx_pic_init,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif #endif
.get_irq = mpic_get_irq, .get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart, .restart = fsl_rstcr_restart,
......
...@@ -34,7 +34,6 @@ config MPC7448HPC2 ...@@ -34,7 +34,6 @@ config MPC7448HPC2
select TSI108_BRIDGE select TSI108_BRIDGE
select DEFAULT_UIMAGE select DEFAULT_UIMAGE
select PPC_UDBG_16550 select PPC_UDBG_16550
select TSI108_BRIDGE
help help
Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
platform platform
...@@ -44,7 +43,6 @@ config PPC_HOLLY ...@@ -44,7 +43,6 @@ config PPC_HOLLY
depends on EMBEDDED6xx depends on EMBEDDED6xx
select TSI108_BRIDGE select TSI108_BRIDGE
select PPC_UDBG_16550 select PPC_UDBG_16550
select TSI108_BRIDGE
help help
Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
Board with TSI108/9 bridge (Hickory/Holly) Board with TSI108/9 bridge (Hickory/Holly)
......
...@@ -22,10 +22,13 @@ ...@@ -22,10 +22,13 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -868,6 +871,14 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose) ...@@ -868,6 +871,14 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
pci_bus_read_config_dword(hose->bus, pci_bus_read_config_dword(hose->bus,
PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base); PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
/*
* For PEXCSRBAR, bit 3-0 indicate prefetchable and
* address type. So when getting base address, these
* bits should be masked
*/
base &= PCI_BASE_ADDRESS_MEM_MASK;
return base; return base;
} }
#endif #endif
...@@ -1086,55 +1097,171 @@ void fsl_pci_assign_primary(void) ...@@ -1086,55 +1097,171 @@ void fsl_pci_assign_primary(void)
} }
} }
static int fsl_pci_probe(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP
static irqreturn_t fsl_pci_pme_handle(int irq, void *dev_id)
{ {
int ret; struct pci_controller *hose = dev_id;
struct device_node *node; struct ccsr_pci __iomem *pci = hose->private_data;
u32 dr;
node = pdev->dev.of_node; dr = in_be32(&pci->pex_pme_mes_dr);
ret = fsl_add_bridge(pdev, fsl_pci_primary == node); if (!dr)
return IRQ_NONE;
mpc85xx_pci_err_probe(pdev); out_be32(&pci->pex_pme_mes_dr, dr);
return 0; return IRQ_HANDLED;
} }
#ifdef CONFIG_PM static int fsl_pci_pme_probe(struct pci_controller *hose)
static int fsl_pci_resume(struct device *dev)
{ {
struct pci_controller *hose; struct ccsr_pci __iomem *pci;
struct resource pci_rsrc; struct pci_dev *dev;
int pme_irq;
int res;
u16 pms;
hose = pci_find_hose_for_OF_device(dev->of_node); /* Get hose's pci_dev */
if (!hose) dev = list_first_entry(&hose->bus->devices, typeof(*dev), bus_list);
return -ENODEV;
/* PME Disable */
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms);
pms &= ~PCI_PM_CTRL_PME_ENABLE;
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms);
pme_irq = irq_of_parse_and_map(hose->dn, 0);
if (!pme_irq) {
dev_err(&dev->dev, "Failed to map PME interrupt.\n");
return -ENXIO;
}
res = devm_request_irq(hose->parent, pme_irq,
fsl_pci_pme_handle,
IRQF_SHARED,
"[PCI] PME", hose);
if (res < 0) {
dev_err(&dev->dev, "Unable to requiest irq %d for PME\n", pme_irq);
irq_dispose_mapping(pme_irq);
if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
dev_err(dev, "Get pci register base failed.");
return -ENODEV; return -ENODEV;
} }
setup_pci_atmu(hose); pci = hose->private_data;
/* Enable PTOD, ENL23D & EXL23D */
out_be32(&pci->pex_pme_mes_disr, 0);
setbits32(&pci->pex_pme_mes_disr,
PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
out_be32(&pci->pex_pme_mes_ier, 0);
setbits32(&pci->pex_pme_mes_ier,
PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
/* PME Enable */
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms);
pms |= PCI_PM_CTRL_PME_ENABLE;
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms);
return 0; return 0;
} }
static const struct dev_pm_ops pci_pm_ops = { static void send_pme_turnoff_message(struct pci_controller *hose)
.resume = fsl_pci_resume, {
}; struct ccsr_pci __iomem *pci = hose->private_data;
u32 dr;
int i;
#define PCI_PM_OPS (&pci_pm_ops) /* Send PME_Turn_Off Message Request */
setbits32(&pci->pex_pmcr, PEX_PMCR_PTOMR);
#else /* Wait trun off done */
for (i = 0; i < 150; i++) {
dr = in_be32(&pci->pex_pme_mes_dr);
if (dr) {
out_be32(&pci->pex_pme_mes_dr, dr);
break;
}
udelay(1000);
}
}
static void fsl_pci_syscore_do_suspend(struct pci_controller *hose)
{
send_pme_turnoff_message(hose);
}
static int fsl_pci_syscore_suspend(void)
{
struct pci_controller *hose, *tmp;
#define PCI_PM_OPS NULL list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
fsl_pci_syscore_do_suspend(hose);
return 0;
}
static void fsl_pci_syscore_do_resume(struct pci_controller *hose)
{
struct ccsr_pci __iomem *pci = hose->private_data;
u32 dr;
int i;
/* Send Exit L2 State Message */
setbits32(&pci->pex_pmcr, PEX_PMCR_EXL2S);
/* Wait exit done */
for (i = 0; i < 150; i++) {
dr = in_be32(&pci->pex_pme_mes_dr);
if (dr) {
out_be32(&pci->pex_pme_mes_dr, dr);
break;
}
udelay(1000);
}
setup_pci_atmu(hose);
}
static void fsl_pci_syscore_resume(void)
{
struct pci_controller *hose, *tmp;
list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
fsl_pci_syscore_do_resume(hose);
}
static struct syscore_ops pci_syscore_pm_ops = {
.suspend = fsl_pci_syscore_suspend,
.resume = fsl_pci_syscore_resume,
};
#endif #endif
void fsl_pcibios_fixup_phb(struct pci_controller *phb)
{
#ifdef CONFIG_PM_SLEEP
fsl_pci_pme_probe(phb);
#endif
}
static int fsl_pci_probe(struct platform_device *pdev)
{
struct device_node *node;
int ret;
node = pdev->dev.of_node;
ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
mpc85xx_pci_err_probe(pdev);
return 0;
}
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,
...@@ -1142,6 +1269,9 @@ static struct platform_driver fsl_pci_driver = { ...@@ -1142,6 +1269,9 @@ static struct platform_driver fsl_pci_driver = {
static int __init fsl_pci_init(void) static int __init fsl_pci_init(void)
{ {
#ifdef CONFIG_PM_SLEEP
register_syscore_ops(&pci_syscore_pm_ops);
#endif
return platform_driver_register(&fsl_pci_driver); return platform_driver_register(&fsl_pci_driver);
} }
arch_initcall(fsl_pci_init); arch_initcall(fsl_pci_init);
......
...@@ -32,6 +32,13 @@ struct platform_device; ...@@ -32,6 +32,13 @@ struct platform_device;
#define PIWAR_WRITE_SNOOP 0x00005000 #define PIWAR_WRITE_SNOOP 0x00005000
#define PIWAR_SZ_MASK 0x0000003f #define PIWAR_SZ_MASK 0x0000003f
#define PEX_PMCR_PTOMR 0x1
#define PEX_PMCR_EXL2S 0x2
#define PME_DISR_EN_PTOD 0x00008000
#define PME_DISR_EN_ENL23D 0x00002000
#define PME_DISR_EN_EXL23D 0x00001000
/* PCI/PCI Express outbound window reg */ /* PCI/PCI Express outbound window reg */
struct pci_outbound_window_regs { struct pci_outbound_window_regs {
__be32 potar; /* 0x.0 - Outbound translation address register */ __be32 potar; /* 0x.0 - Outbound translation address register */
...@@ -111,6 +118,7 @@ struct ccsr_pci { ...@@ -111,6 +118,7 @@ struct ccsr_pci {
extern int fsl_add_bridge(struct platform_device *pdev, int is_primary); extern int fsl_add_bridge(struct platform_device *pdev, int is_primary);
extern void fsl_pcibios_fixup_bus(struct pci_bus *bus); extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
extern void fsl_pcibios_fixup_phb(struct pci_controller *phb);
extern int mpc83xx_add_bridge(struct device_node *dev); extern int mpc83xx_add_bridge(struct device_node *dev);
u64 fsl_pci_immrbar_base(struct pci_controller *hose); u64 fsl_pci_immrbar_base(struct pci_controller *hose);
......
...@@ -138,14 +138,6 @@ static void __booke_wdt_enable(void *data) ...@@ -138,14 +138,6 @@ static void __booke_wdt_enable(void *data)
val &= ~WDTP_MASK; val &= ~WDTP_MASK;
val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
#ifdef CONFIG_PPC_BOOK3E_64
/*
* Crit ints are currently broken on PPC64 Book-E, so
* just disable them for now.
*/
val &= ~TCR_WIE;
#endif
mtspr(SPRN_TCR, val); mtspr(SPRN_TCR, val);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册