diff options
Diffstat (limited to 'arch')
188 files changed, 3989 insertions, 1844 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7980873525b2..e91c7cdc6fe5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1151,6 +1151,7 @@ config PLAT_ORION | |||
1151 | bool | 1151 | bool |
1152 | select CLKSRC_MMIO | 1152 | select CLKSRC_MMIO |
1153 | select GENERIC_IRQ_CHIP | 1153 | select GENERIC_IRQ_CHIP |
1154 | select IRQ_DOMAIN | ||
1154 | select COMMON_CLK | 1155 | select COMMON_CLK |
1155 | 1156 | ||
1156 | config PLAT_PXA | 1157 | config PLAT_PXA |
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index e1fa7e6edfe8..71d6b5d0daf1 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi | |||
@@ -12,7 +12,7 @@ | |||
12 | * License version 2. This program is licensed "as is" without any | 12 | * License version 2. This program is licensed "as is" without any |
13 | * warranty of any kind, whether express or implied. | 13 | * warranty of any kind, whether express or implied. |
14 | * | 14 | * |
15 | * Contains definitions specific to the Armada 370 SoC that are not | 15 | * Contains definitions specific to the Armada XP SoC that are not |
16 | * common to all Armada SoCs. | 16 | * common to all Armada SoCs. |
17 | */ | 17 | */ |
18 | 18 | ||
diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts index 9a33077130e8..5bb0bf39d3b8 100644 --- a/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/arch/arm/boot/dts/kirkwood-dns320.dts | |||
@@ -1,6 +1,6 @@ | |||
1 | /dts-v1/; | 1 | /dts-v1/; |
2 | 2 | ||
3 | /include/ "kirkwood.dtsi" | 3 | /include/ "kirkwood-dnskw.dtsi" |
4 | 4 | ||
5 | / { | 5 | / { |
6 | model = "D-Link DNS-320 NAS (Rev A1)"; | 6 | model = "D-Link DNS-320 NAS (Rev A1)"; |
@@ -15,6 +15,31 @@ | |||
15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; | 15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | gpio-leds { | ||
19 | compatible = "gpio-leds"; | ||
20 | blue-power { | ||
21 | label = "dns320:blue:power"; | ||
22 | gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ | ||
23 | linux,default-trigger = "default-on"; | ||
24 | }; | ||
25 | blue-usb { | ||
26 | label = "dns320:blue:usb"; | ||
27 | gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ | ||
28 | }; | ||
29 | orange-l_hdd { | ||
30 | label = "dns320:orange:l_hdd"; | ||
31 | gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ | ||
32 | }; | ||
33 | orange-r_hdd { | ||
34 | label = "dns320:orange:r_hdd"; | ||
35 | gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ | ||
36 | }; | ||
37 | orange-usb { | ||
38 | label = "dns320:orange:usb"; | ||
39 | gpios = <&gpio1 3 1>; /* GPIO 35 Active Low */ | ||
40 | }; | ||
41 | }; | ||
42 | |||
18 | ocp@f1000000 { | 43 | ocp@f1000000 { |
19 | serial@12000 { | 44 | serial@12000 { |
20 | clock-frequency = <166666667>; | 45 | clock-frequency = <166666667>; |
@@ -25,40 +50,5 @@ | |||
25 | clock-frequency = <166666667>; | 50 | clock-frequency = <166666667>; |
26 | status = "okay"; | 51 | status = "okay"; |
27 | }; | 52 | }; |
28 | |||
29 | nand@3000000 { | ||
30 | status = "okay"; | ||
31 | |||
32 | partition@0 { | ||
33 | label = "u-boot"; | ||
34 | reg = <0x0000000 0x100000>; | ||
35 | read-only; | ||
36 | }; | ||
37 | |||
38 | partition@100000 { | ||
39 | label = "uImage"; | ||
40 | reg = <0x0100000 0x500000>; | ||
41 | }; | ||
42 | |||
43 | partition@600000 { | ||
44 | label = "ramdisk"; | ||
45 | reg = <0x0600000 0x500000>; | ||
46 | }; | ||
47 | |||
48 | partition@b00000 { | ||
49 | label = "image"; | ||
50 | reg = <0x0b00000 0x6600000>; | ||
51 | }; | ||
52 | |||
53 | partition@7100000 { | ||
54 | label = "mini firmware"; | ||
55 | reg = <0x7100000 0xa00000>; | ||
56 | }; | ||
57 | |||
58 | partition@7b00000 { | ||
59 | label = "config"; | ||
60 | reg = <0x7b00000 0x500000>; | ||
61 | }; | ||
62 | }; | ||
63 | }; | 53 | }; |
64 | }; | 54 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts index 16734c1b5dfe..d430713ea9b9 100644 --- a/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/arch/arm/boot/dts/kirkwood-dns325.dts | |||
@@ -1,6 +1,6 @@ | |||
1 | /dts-v1/; | 1 | /dts-v1/; |
2 | 2 | ||
3 | /include/ "kirkwood.dtsi" | 3 | /include/ "kirkwood-dnskw.dtsi" |
4 | 4 | ||
5 | / { | 5 | / { |
6 | model = "D-Link DNS-325 NAS (Rev A1)"; | 6 | model = "D-Link DNS-325 NAS (Rev A1)"; |
@@ -15,45 +15,43 @@ | |||
15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; | 15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | ocp@f1000000 { | 18 | gpio-leds { |
19 | serial@12000 { | 19 | compatible = "gpio-leds"; |
20 | clock-frequency = <200000000>; | 20 | white-power { |
21 | status = "okay"; | 21 | label = "dns325:white:power"; |
22 | gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ | ||
23 | linux,default-trigger = "default-on"; | ||
24 | }; | ||
25 | white-usb { | ||
26 | label = "dns325:white:usb"; | ||
27 | gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ | ||
28 | }; | ||
29 | red-l_hdd { | ||
30 | label = "dns325:red:l_hdd"; | ||
31 | gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ | ||
22 | }; | 32 | }; |
33 | red-r_hdd { | ||
34 | label = "dns325:red:r_hdd"; | ||
35 | gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ | ||
36 | }; | ||
37 | red-usb { | ||
38 | label = "dns325:red:usb"; | ||
39 | gpios = <&gpio0 29 1>; /* GPIO 29 Active Low */ | ||
40 | }; | ||
41 | }; | ||
23 | 42 | ||
24 | nand@3000000 { | 43 | ocp@f1000000 { |
44 | i2c@11000 { | ||
25 | status = "okay"; | 45 | status = "okay"; |
26 | 46 | ||
27 | partition@0 { | 47 | lm75: lm75@48 { |
28 | label = "u-boot"; | 48 | compatible = "national,lm75"; |
29 | reg = <0x0000000 0x100000>; | 49 | reg = <0x48>; |
30 | read-only; | ||
31 | }; | ||
32 | |||
33 | partition@100000 { | ||
34 | label = "uImage"; | ||
35 | reg = <0x0100000 0x500000>; | ||
36 | }; | ||
37 | |||
38 | partition@600000 { | ||
39 | label = "ramdisk"; | ||
40 | reg = <0x0600000 0x500000>; | ||
41 | }; | ||
42 | |||
43 | partition@b00000 { | ||
44 | label = "image"; | ||
45 | reg = <0x0b00000 0x6600000>; | ||
46 | }; | ||
47 | |||
48 | partition@7100000 { | ||
49 | label = "mini firmware"; | ||
50 | reg = <0x7100000 0xa00000>; | ||
51 | }; | ||
52 | |||
53 | partition@7b00000 { | ||
54 | label = "config"; | ||
55 | reg = <0x7b00000 0x500000>; | ||
56 | }; | 50 | }; |
57 | }; | 51 | }; |
52 | serial@12000 { | ||
53 | clock-frequency = <200000000>; | ||
54 | status = "okay"; | ||
55 | }; | ||
58 | }; | 56 | }; |
59 | }; | 57 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi new file mode 100644 index 000000000000..7408655f91b5 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi | |||
@@ -0,0 +1,69 @@ | |||
1 | /include/ "kirkwood.dtsi" | ||
2 | |||
3 | / { | ||
4 | model = "D-Link DNS NASes (kirkwood-based)"; | ||
5 | compatible = "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
6 | |||
7 | gpio_keys { | ||
8 | compatible = "gpio-keys"; | ||
9 | #address-cells = <1>; | ||
10 | #size-cells = <0>; | ||
11 | button@1 { | ||
12 | label = "Power button"; | ||
13 | linux,code = <116>; | ||
14 | gpios = <&gpio1 2 1>; | ||
15 | }; | ||
16 | button@2 { | ||
17 | label = "USB unmount button"; | ||
18 | linux,code = <161>; | ||
19 | gpios = <&gpio1 15 1>; | ||
20 | }; | ||
21 | button@3 { | ||
22 | label = "Reset button"; | ||
23 | linux,code = <0x198>; | ||
24 | gpios = <&gpio1 16 1>; | ||
25 | }; | ||
26 | }; | ||
27 | |||
28 | ocp@f1000000 { | ||
29 | sata@80000 { | ||
30 | status = "okay"; | ||
31 | nr-ports = <2>; | ||
32 | }; | ||
33 | |||
34 | nand@3000000 { | ||
35 | status = "okay"; | ||
36 | |||
37 | partition@0 { | ||
38 | label = "u-boot"; | ||
39 | reg = <0x0000000 0x100000>; | ||
40 | read-only; | ||
41 | }; | ||
42 | |||
43 | partition@100000 { | ||
44 | label = "uImage"; | ||
45 | reg = <0x0100000 0x500000>; | ||
46 | }; | ||
47 | |||
48 | partition@600000 { | ||
49 | label = "ramdisk"; | ||
50 | reg = <0x0600000 0x500000>; | ||
51 | }; | ||
52 | |||
53 | partition@b00000 { | ||
54 | label = "image"; | ||
55 | reg = <0x0b00000 0x6600000>; | ||
56 | }; | ||
57 | |||
58 | partition@7100000 { | ||
59 | label = "mini firmware"; | ||
60 | reg = <0x7100000 0xa00000>; | ||
61 | }; | ||
62 | |||
63 | partition@7b00000 { | ||
64 | label = "config"; | ||
65 | reg = <0x7b00000 0x500000>; | ||
66 | }; | ||
67 | }; | ||
68 | }; | ||
69 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index 78b0f06a09a2..26e281fbf6bc 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts | |||
@@ -20,5 +20,55 @@ | |||
20 | clock-frequency = <200000000>; | 20 | clock-frequency = <200000000>; |
21 | status = "ok"; | 21 | status = "ok"; |
22 | }; | 22 | }; |
23 | |||
24 | spi@10600 { | ||
25 | status = "okay"; | ||
26 | |||
27 | m25p40@0 { | ||
28 | #address-cells = <1>; | ||
29 | #size-cells = <1>; | ||
30 | compatible = "mx25l1606e"; | ||
31 | reg = <0>; | ||
32 | spi-max-frequency = <50000000>; | ||
33 | mode = <0>; | ||
34 | |||
35 | partition@0 { | ||
36 | reg = <0x0 0x80000>; | ||
37 | label = "u-boot"; | ||
38 | }; | ||
39 | |||
40 | partition@100000 { | ||
41 | reg = <0x100000 0x10000>; | ||
42 | label = "u-boot env"; | ||
43 | }; | ||
44 | |||
45 | partition@180000 { | ||
46 | reg = <0x180000 0x10000>; | ||
47 | label = "dtb"; | ||
48 | }; | ||
49 | }; | ||
50 | }; | ||
51 | |||
52 | sata@80000 { | ||
53 | status = "okay"; | ||
54 | nr-ports = <1>; | ||
55 | }; | ||
56 | }; | ||
57 | |||
58 | gpio-leds { | ||
59 | compatible = "gpio-leds"; | ||
60 | |||
61 | bluetooth { | ||
62 | label = "dreamplug:blue:bluetooth"; | ||
63 | gpios = <&gpio1 15 1>; | ||
64 | }; | ||
65 | wifi { | ||
66 | label = "dreamplug:green:wifi"; | ||
67 | gpios = <&gpio1 16 1>; | ||
68 | }; | ||
69 | wifi-ap { | ||
70 | label = "dreamplug:green:wifi_ap"; | ||
71 | gpios = <&gpio1 17 1>; | ||
72 | }; | ||
23 | }; | 73 | }; |
24 | }; | 74 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts new file mode 100644 index 000000000000..7c8238fbb6f9 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts | |||
@@ -0,0 +1,99 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "Seagate GoFlex Net"; | ||
7 | compatible = "seagate,goflexnet", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
8 | |||
9 | memory { | ||
10 | device_type = "memory"; | ||
11 | reg = <0x00000000 0x8000000>; | ||
12 | }; | ||
13 | |||
14 | chosen { | ||
15 | bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10"; | ||
16 | }; | ||
17 | |||
18 | ocp@f1000000 { | ||
19 | serial@12000 { | ||
20 | clock-frequency = <200000000>; | ||
21 | status = "ok"; | ||
22 | }; | ||
23 | |||
24 | nand@3000000 { | ||
25 | status = "okay"; | ||
26 | |||
27 | partition@0 { | ||
28 | label = "u-boot"; | ||
29 | reg = <0x0000000 0x100000>; | ||
30 | read-only; | ||
31 | }; | ||
32 | |||
33 | partition@100000 { | ||
34 | label = "uImage"; | ||
35 | reg = <0x0100000 0x400000>; | ||
36 | }; | ||
37 | |||
38 | partition@500000 { | ||
39 | label = "pogoplug"; | ||
40 | reg = <0x0500000 0x2000000>; | ||
41 | }; | ||
42 | |||
43 | partition@2500000 { | ||
44 | label = "root"; | ||
45 | reg = <0x02500000 0xd800000>; | ||
46 | }; | ||
47 | }; | ||
48 | sata@80000 { | ||
49 | status = "okay"; | ||
50 | nr-ports = <2>; | ||
51 | }; | ||
52 | |||
53 | }; | ||
54 | gpio-leds { | ||
55 | compatible = "gpio-leds"; | ||
56 | |||
57 | health { | ||
58 | label = "status:green:health"; | ||
59 | gpios = <&gpio1 14 1>; | ||
60 | linux,default-trigger = "default-on"; | ||
61 | }; | ||
62 | fault { | ||
63 | label = "status:orange:fault"; | ||
64 | gpios = <&gpio1 15 1>; | ||
65 | }; | ||
66 | left0 { | ||
67 | label = "status:white:left0"; | ||
68 | gpios = <&gpio1 10 0>; | ||
69 | }; | ||
70 | left1 { | ||
71 | label = "status:white:left1"; | ||
72 | gpios = <&gpio1 11 0>; | ||
73 | }; | ||
74 | left2 { | ||
75 | label = "status:white:left2"; | ||
76 | gpios = <&gpio1 12 0>; | ||
77 | }; | ||
78 | left3 { | ||
79 | label = "status:white:left3"; | ||
80 | gpios = <&gpio1 13 0>; | ||
81 | }; | ||
82 | right0 { | ||
83 | label = "status:white:right0"; | ||
84 | gpios = <&gpio1 6 0>; | ||
85 | }; | ||
86 | right1 { | ||
87 | label = "status:white:right1"; | ||
88 | gpios = <&gpio1 7 0>; | ||
89 | }; | ||
90 | right2 { | ||
91 | label = "status:white:right2"; | ||
92 | gpios = <&gpio1 8 0>; | ||
93 | }; | ||
94 | right3 { | ||
95 | label = "status:white:right3"; | ||
96 | gpios = <&gpio1 9 0>; | ||
97 | }; | ||
98 | }; | ||
99 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index f59dcf6dc45f..66794ed75ff1 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts | |||
@@ -21,6 +21,11 @@ | |||
21 | status = "okay"; | 21 | status = "okay"; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | sata@80000 { | ||
25 | status = "okay"; | ||
26 | nr-ports = <2>; | ||
27 | }; | ||
28 | |||
24 | nand@3000000 { | 29 | nand@3000000 { |
25 | status = "okay"; | 30 | status = "okay"; |
26 | 31 | ||
@@ -41,4 +46,37 @@ | |||
41 | 46 | ||
42 | }; | 47 | }; |
43 | }; | 48 | }; |
49 | |||
50 | gpio_keys { | ||
51 | compatible = "gpio-keys"; | ||
52 | #address-cells = <1>; | ||
53 | #size-cells = <0>; | ||
54 | button@1 { | ||
55 | label = "USB Copy"; | ||
56 | linux,code = <133>; | ||
57 | gpios = <&gpio0 29 1>; | ||
58 | }; | ||
59 | button@2 { | ||
60 | label = "Reset"; | ||
61 | linux,code = <0x198>; | ||
62 | gpios = <&gpio0 28 1>; | ||
63 | }; | ||
64 | }; | ||
65 | gpio-leds { | ||
66 | compatible = "gpio-leds"; | ||
67 | |||
68 | green-os { | ||
69 | label = "ib62x0:green:os"; | ||
70 | gpios = <&gpio0 25 0>; | ||
71 | linux,default-trigger = "default-on"; | ||
72 | }; | ||
73 | red-os { | ||
74 | label = "ib62x0:red:os"; | ||
75 | gpios = <&gpio0 22 0>; | ||
76 | }; | ||
77 | usb-copy { | ||
78 | label = "ib62x0:red:usb_copy"; | ||
79 | gpios = <&gpio0 27 0>; | ||
80 | }; | ||
81 | }; | ||
44 | }; | 82 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 026a1f82d813..52d947045106 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts | |||
@@ -18,9 +18,51 @@ | |||
18 | }; | 18 | }; |
19 | 19 | ||
20 | ocp@f1000000 { | 20 | ocp@f1000000 { |
21 | i2c@11000 { | ||
22 | status = "okay"; | ||
23 | |||
24 | lm63: lm63@4c { | ||
25 | compatible = "national,lm63"; | ||
26 | reg = <0x4c>; | ||
27 | }; | ||
28 | }; | ||
21 | serial@12000 { | 29 | serial@12000 { |
22 | clock-frequency = <200000000>; | 30 | clock-frequency = <200000000>; |
23 | status = "ok"; | 31 | status = "ok"; |
24 | }; | 32 | }; |
25 | }; | 33 | }; |
34 | gpio-leds { | ||
35 | compatible = "gpio-leds"; | ||
36 | |||
37 | led-level { | ||
38 | label = "led_level"; | ||
39 | gpios = <&gpio1 9 0>; | ||
40 | linux,default-trigger = "default-on"; | ||
41 | }; | ||
42 | power-blue { | ||
43 | label = "power:blue"; | ||
44 | gpios = <&gpio1 11 0>; | ||
45 | linux,default-trigger = "timer"; | ||
46 | }; | ||
47 | usb1 { | ||
48 | label = "usb1:blue"; | ||
49 | gpios = <&gpio1 12 0>; | ||
50 | }; | ||
51 | usb2 { | ||
52 | label = "usb2:blue"; | ||
53 | gpios = <&gpio1 13 0>; | ||
54 | }; | ||
55 | usb3 { | ||
56 | label = "usb3:blue"; | ||
57 | gpios = <&gpio1 14 0>; | ||
58 | }; | ||
59 | usb4 { | ||
60 | label = "usb4:blue"; | ||
61 | gpios = <&gpio1 15 0>; | ||
62 | }; | ||
63 | otb { | ||
64 | label = "otb:blue"; | ||
65 | gpios = <&gpio1 16 0>; | ||
66 | }; | ||
67 | }; | ||
26 | }; | 68 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-lschlv2.dts b/arch/arm/boot/dts/kirkwood-lschlv2.dts new file mode 100644 index 000000000000..9510c9ea666c --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-lschlv2.dts | |||
@@ -0,0 +1,20 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-lsxl.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "Buffalo Linkstation LS-CHLv2"; | ||
7 | compatible = "buffalo,lschlv2", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
8 | |||
9 | memory { | ||
10 | device_type = "memory"; | ||
11 | reg = <0x00000000 0x4000000>; | ||
12 | }; | ||
13 | |||
14 | ocp@f1000000 { | ||
15 | serial@12000 { | ||
16 | clock-frequency = <166666667>; | ||
17 | status = "okay"; | ||
18 | }; | ||
19 | }; | ||
20 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-lsxhl.dts b/arch/arm/boot/dts/kirkwood-lsxhl.dts new file mode 100644 index 000000000000..739019c4cba9 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-lsxhl.dts | |||
@@ -0,0 +1,20 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-lsxl.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "Buffalo Linkstation LS-XHL"; | ||
7 | compatible = "buffalo,lsxhl", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
8 | |||
9 | memory { | ||
10 | device_type = "memory"; | ||
11 | reg = <0x00000000 0x10000000>; | ||
12 | }; | ||
13 | |||
14 | ocp@f1000000 { | ||
15 | serial@12000 { | ||
16 | clock-frequency = <200000000>; | ||
17 | status = "okay"; | ||
18 | }; | ||
19 | }; | ||
20 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi new file mode 100644 index 000000000000..8ac51c08269d --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi | |||
@@ -0,0 +1,95 @@ | |||
1 | /include/ "kirkwood.dtsi" | ||
2 | |||
3 | / { | ||
4 | chosen { | ||
5 | bootargs = "console=ttyS0,115200n8 earlyprintk"; | ||
6 | }; | ||
7 | |||
8 | ocp@f1000000 { | ||
9 | sata@80000 { | ||
10 | status = "okay"; | ||
11 | nr-ports = <1>; | ||
12 | }; | ||
13 | |||
14 | spi@10600 { | ||
15 | status = "okay"; | ||
16 | |||
17 | m25p40@0 { | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <1>; | ||
20 | compatible = "m25p40"; | ||
21 | reg = <0>; | ||
22 | spi-max-frequency = <25000000>; | ||
23 | mode = <0>; | ||
24 | |||
25 | partition@0 { | ||
26 | reg = <0x0 0x60000>; | ||
27 | label = "uboot"; | ||
28 | read-only; | ||
29 | }; | ||
30 | |||
31 | partition@60000 { | ||
32 | reg = <0x60000 0x10000>; | ||
33 | label = "dtb"; | ||
34 | read-only; | ||
35 | }; | ||
36 | |||
37 | partition@70000 { | ||
38 | reg = <0x70000 0x10000>; | ||
39 | label = "uboot_env"; | ||
40 | }; | ||
41 | }; | ||
42 | }; | ||
43 | }; | ||
44 | |||
45 | gpio_keys { | ||
46 | compatible = "gpio-keys"; | ||
47 | #address-cells = <1>; | ||
48 | #size-cells = <0>; | ||
49 | button@1 { | ||
50 | label = "Function Button"; | ||
51 | linux,code = <132>; | ||
52 | gpios = <&gpio1 9 1>; | ||
53 | }; | ||
54 | button@2 { | ||
55 | label = "Power-on Switch"; | ||
56 | linux,code = <116>; | ||
57 | gpios = <&gpio1 10 1>; | ||
58 | }; | ||
59 | button@3 { | ||
60 | label = "Power-auto Switch"; | ||
61 | linux,code = <142>; | ||
62 | gpios = <&gpio1 11 1>; | ||
63 | }; | ||
64 | }; | ||
65 | |||
66 | gpio_leds { | ||
67 | compatible = "gpio-leds"; | ||
68 | |||
69 | led@1 { | ||
70 | label = "lschlv2:blue:func"; | ||
71 | gpios = <&gpio1 4 1>; | ||
72 | }; | ||
73 | |||
74 | led@2 { | ||
75 | label = "lschlv2:red:alarm"; | ||
76 | gpios = <&gpio1 5 1>; | ||
77 | }; | ||
78 | |||
79 | led@3 { | ||
80 | label = "lschlv2:amber:info"; | ||
81 | gpios = <&gpio1 6 1>; | ||
82 | }; | ||
83 | |||
84 | led@4 { | ||
85 | label = "lschlv2:blue:power"; | ||
86 | gpios = <&gpio1 7 1>; | ||
87 | linux,default-trigger = "default-on"; | ||
88 | }; | ||
89 | |||
90 | led@5 { | ||
91 | label = "lschlv2:red:func"; | ||
92 | gpios = <&gpio1 16 1>; | ||
93 | }; | ||
94 | }; | ||
95 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts new file mode 100644 index 000000000000..ccbf32757800 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts | |||
@@ -0,0 +1,21 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-ts219.dtsi" | ||
4 | |||
5 | / { | ||
6 | gpio_keys { | ||
7 | compatible = "gpio-keys"; | ||
8 | #address-cells = <1>; | ||
9 | #size-cells = <0>; | ||
10 | button@1 { | ||
11 | label = "USB Copy"; | ||
12 | linux,code = <133>; | ||
13 | gpios = <&gpio0 15 1>; | ||
14 | }; | ||
15 | button@2 { | ||
16 | label = "Reset"; | ||
17 | linux,code = <0x198>; | ||
18 | gpios = <&gpio0 16 1>; | ||
19 | }; | ||
20 | }; | ||
21 | }; \ No newline at end of file | ||
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts new file mode 100644 index 000000000000..fbe9932161a1 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts | |||
@@ -0,0 +1,21 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-ts219.dtsi" | ||
4 | |||
5 | / { | ||
6 | gpio_keys { | ||
7 | compatible = "gpio-keys"; | ||
8 | #address-cells = <1>; | ||
9 | #size-cells = <0>; | ||
10 | button@1 { | ||
11 | label = "USB Copy"; | ||
12 | linux,code = <133>; | ||
13 | gpios = <&gpio1 11 1>; | ||
14 | }; | ||
15 | button@2 { | ||
16 | label = "Reset"; | ||
17 | linux,code = <0x198>; | ||
18 | gpios = <&gpio1 5 1>; | ||
19 | }; | ||
20 | }; | ||
21 | }; \ No newline at end of file | ||
diff --git a/arch/arm/boot/dts/kirkwood-ts219.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi new file mode 100644 index 000000000000..64ea27cb3298 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi | |||
@@ -0,0 +1,78 @@ | |||
1 | /include/ "kirkwood.dtsi" | ||
2 | |||
3 | / { | ||
4 | model = "QNAP TS219 family"; | ||
5 | compatible = "qnap,ts219", "marvell,kirkwood"; | ||
6 | |||
7 | memory { | ||
8 | device_type = "memory"; | ||
9 | reg = <0x00000000 0x20000000>; | ||
10 | }; | ||
11 | |||
12 | chosen { | ||
13 | bootargs = "console=ttyS0,115200n8"; | ||
14 | }; | ||
15 | |||
16 | ocp@f1000000 { | ||
17 | i2c@11000 { | ||
18 | status = "okay"; | ||
19 | clock-frequency = <400000>; | ||
20 | |||
21 | s35390a: s35390a@30 { | ||
22 | compatible = "s35390a"; | ||
23 | reg = <0x30>; | ||
24 | }; | ||
25 | }; | ||
26 | serial@12000 { | ||
27 | clock-frequency = <200000000>; | ||
28 | status = "okay"; | ||
29 | }; | ||
30 | serial@12100 { | ||
31 | clock-frequency = <200000000>; | ||
32 | status = "okay"; | ||
33 | }; | ||
34 | spi@10600 { | ||
35 | status = "okay"; | ||
36 | |||
37 | m25p128@0 { | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <1>; | ||
40 | compatible = "m25p128"; | ||
41 | reg = <0>; | ||
42 | spi-max-frequency = <20000000>; | ||
43 | mode = <0>; | ||
44 | |||
45 | partition@0000000 { | ||
46 | reg = <0x00000000 0x00080000>; | ||
47 | label = "U-Boot"; | ||
48 | }; | ||
49 | |||
50 | partition@00200000 { | ||
51 | reg = <0x00200000 0x00200000>; | ||
52 | label = "Kernel"; | ||
53 | }; | ||
54 | |||
55 | partition@00400000 { | ||
56 | reg = <0x00400000 0x00900000>; | ||
57 | label = "RootFS1"; | ||
58 | }; | ||
59 | partition@00d00000 { | ||
60 | reg = <0x00d00000 0x00300000>; | ||
61 | label = "RootFS2"; | ||
62 | }; | ||
63 | partition@00040000 { | ||
64 | reg = <0x00080000 0x00040000>; | ||
65 | label = "U-Boot Config"; | ||
66 | }; | ||
67 | partition@000c0000 { | ||
68 | reg = <0x000c0000 0x00140000>; | ||
69 | label = "NAS Config"; | ||
70 | }; | ||
71 | }; | ||
72 | }; | ||
73 | sata@80000 { | ||
74 | status = "okay"; | ||
75 | nr-ports = <2>; | ||
76 | }; | ||
77 | }; | ||
78 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index f95dbc190ab6..cef9616f330a 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi | |||
@@ -2,6 +2,15 @@ | |||
2 | 2 | ||
3 | / { | 3 | / { |
4 | compatible = "marvell,kirkwood"; | 4 | compatible = "marvell,kirkwood"; |
5 | interrupt-parent = <&intc>; | ||
6 | |||
7 | intc: interrupt-controller { | ||
8 | compatible = "marvell,orion-intc", "marvell,intc"; | ||
9 | interrupt-controller; | ||
10 | #interrupt-cells = <1>; | ||
11 | reg = <0xf1020204 0x04>, | ||
12 | <0xf1020214 0x04>; | ||
13 | }; | ||
5 | 14 | ||
6 | ocp@f1000000 { | 15 | ocp@f1000000 { |
7 | compatible = "simple-bus"; | 16 | compatible = "simple-bus"; |
@@ -9,6 +18,24 @@ | |||
9 | #address-cells = <1>; | 18 | #address-cells = <1>; |
10 | #size-cells = <1>; | 19 | #size-cells = <1>; |
11 | 20 | ||
21 | gpio0: gpio@10100 { | ||
22 | compatible = "marvell,orion-gpio"; | ||
23 | #gpio-cells = <2>; | ||
24 | gpio-controller; | ||
25 | reg = <0x10100 0x40>; | ||
26 | ngpio = <32>; | ||
27 | interrupts = <35>, <36>, <37>, <38>; | ||
28 | }; | ||
29 | |||
30 | gpio1: gpio@10140 { | ||
31 | compatible = "marvell,orion-gpio"; | ||
32 | #gpio-cells = <2>; | ||
33 | gpio-controller; | ||
34 | reg = <0x10140 0x40>; | ||
35 | ngpio = <18>; | ||
36 | interrupts = <39>, <40>, <41>; | ||
37 | }; | ||
38 | |||
12 | serial@12000 { | 39 | serial@12000 { |
13 | compatible = "ns16550a"; | 40 | compatible = "ns16550a"; |
14 | reg = <0x12000 0x100>; | 41 | reg = <0x12000 0x100>; |
@@ -33,6 +60,29 @@ | |||
33 | interrupts = <53>; | 60 | interrupts = <53>; |
34 | }; | 61 | }; |
35 | 62 | ||
63 | spi@10600 { | ||
64 | compatible = "marvell,orion-spi"; | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <0>; | ||
67 | cell-index = <0>; | ||
68 | interrupts = <23>; | ||
69 | reg = <0x10600 0x28>; | ||
70 | status = "disabled"; | ||
71 | }; | ||
72 | |||
73 | wdt@20300 { | ||
74 | compatible = "marvell,orion-wdt"; | ||
75 | reg = <0x20300 0x28>; | ||
76 | status = "okay"; | ||
77 | }; | ||
78 | |||
79 | sata@80000 { | ||
80 | compatible = "marvell,orion-sata"; | ||
81 | reg = <0x80000 0x5000>; | ||
82 | interrupts = <21>; | ||
83 | status = "disabled"; | ||
84 | }; | ||
85 | |||
36 | nand@3000000 { | 86 | nand@3000000 { |
37 | #address-cells = <1>; | 87 | #address-cells = <1>; |
38 | #size-cells = <1>; | 88 | #size-cells = <1>; |
@@ -45,5 +95,15 @@ | |||
45 | /* set partition map and/or chip-delay in board dts */ | 95 | /* set partition map and/or chip-delay in board dts */ |
46 | status = "disabled"; | 96 | status = "disabled"; |
47 | }; | 97 | }; |
98 | |||
99 | i2c@11000 { | ||
100 | compatible = "marvell,mv64xxx-i2c"; | ||
101 | reg = <0x11000 0x20>; | ||
102 | #address-cells = <1>; | ||
103 | #size-cells = <0>; | ||
104 | interrupts = <29>; | ||
105 | clock-frequency = <100000>; | ||
106 | status = "disabled"; | ||
107 | }; | ||
48 | }; | 108 | }; |
49 | }; | 109 | }; |
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index b152de79fd95..e58edc36b406 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig | |||
@@ -193,6 +193,8 @@ CONFIG_MMC_OMAP_HS=y | |||
193 | CONFIG_RTC_CLASS=y | 193 | CONFIG_RTC_CLASS=y |
194 | CONFIG_RTC_DRV_TWL92330=y | 194 | CONFIG_RTC_DRV_TWL92330=y |
195 | CONFIG_RTC_DRV_TWL4030=y | 195 | CONFIG_RTC_DRV_TWL4030=y |
196 | CONFIG_DMADEVICES=y | ||
197 | CONFIG_DMA_OMAP=y | ||
196 | CONFIG_EXT2_FS=y | 198 | CONFIG_EXT2_FS=y |
197 | CONFIG_EXT3_FS=y | 199 | CONFIG_EXT3_FS=y |
198 | # CONFIG_EXT3_FS_XATTR is not set | 200 | # CONFIG_EXT3_FS_XATTR is not set |
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 004c1bc95d2b..e4448e16046d 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -215,7 +215,9 @@ static inline void vivt_flush_cache_mm(struct mm_struct *mm) | |||
215 | static inline void | 215 | static inline void |
216 | vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) | 216 | vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
217 | { | 217 | { |
218 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) | 218 | struct mm_struct *mm = vma->vm_mm; |
219 | |||
220 | if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) | ||
219 | __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), | 221 | __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), |
220 | vma->vm_flags); | 222 | vma->vm_flags); |
221 | } | 223 | } |
@@ -223,7 +225,9 @@ vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned | |||
223 | static inline void | 225 | static inline void |
224 | vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) | 226 | vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) |
225 | { | 227 | { |
226 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { | 228 | struct mm_struct *mm = vma->vm_mm; |
229 | |||
230 | if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) { | ||
227 | unsigned long addr = user_addr & PAGE_MASK; | 231 | unsigned long addr = user_addr & PAGE_MASK; |
228 | __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); | 232 | __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); |
229 | } | 233 | } |
diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h index 93226cf23ae0..b1479fd04a95 100644 --- a/arch/arm/include/asm/mutex.h +++ b/arch/arm/include/asm/mutex.h | |||
@@ -7,121 +7,10 @@ | |||
7 | */ | 7 | */ |
8 | #ifndef _ASM_MUTEX_H | 8 | #ifndef _ASM_MUTEX_H |
9 | #define _ASM_MUTEX_H | 9 | #define _ASM_MUTEX_H |
10 | |||
11 | #if __LINUX_ARM_ARCH__ < 6 | ||
12 | /* On pre-ARMv6 hardware the swp based implementation is the most efficient. */ | ||
13 | # include <asm-generic/mutex-xchg.h> | ||
14 | #else | ||
15 | |||
16 | /* | 10 | /* |
17 | * Attempting to lock a mutex on ARMv6+ can be done with a bastardized | 11 | * On pre-ARMv6 hardware this results in a swp-based implementation, |
18 | * atomic decrement (it is not a reliable atomic decrement but it satisfies | 12 | * which is the most efficient. For ARMv6+, we emit a pair of exclusive |
19 | * the defined semantics for our purpose, while being smaller and faster | 13 | * accesses instead. |
20 | * than a real atomic decrement or atomic swap. The idea is to attempt | ||
21 | * decrementing the lock value only once. If once decremented it isn't zero, | ||
22 | * or if its store-back fails due to a dispute on the exclusive store, we | ||
23 | * simply bail out immediately through the slow path where the lock will be | ||
24 | * reattempted until it succeeds. | ||
25 | */ | 14 | */ |
26 | static inline void | 15 | #include <asm-generic/mutex-xchg.h> |
27 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) | ||
28 | { | ||
29 | int __ex_flag, __res; | ||
30 | |||
31 | __asm__ ( | ||
32 | |||
33 | "ldrex %0, [%2] \n\t" | ||
34 | "sub %0, %0, #1 \n\t" | ||
35 | "strex %1, %0, [%2] " | ||
36 | |||
37 | : "=&r" (__res), "=&r" (__ex_flag) | ||
38 | : "r" (&(count)->counter) | ||
39 | : "cc","memory" ); | ||
40 | |||
41 | __res |= __ex_flag; | ||
42 | if (unlikely(__res != 0)) | ||
43 | fail_fn(count); | ||
44 | } | ||
45 | |||
46 | static inline int | ||
47 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
48 | { | ||
49 | int __ex_flag, __res; | ||
50 | |||
51 | __asm__ ( | ||
52 | |||
53 | "ldrex %0, [%2] \n\t" | ||
54 | "sub %0, %0, #1 \n\t" | ||
55 | "strex %1, %0, [%2] " | ||
56 | |||
57 | : "=&r" (__res), "=&r" (__ex_flag) | ||
58 | : "r" (&(count)->counter) | ||
59 | : "cc","memory" ); | ||
60 | |||
61 | __res |= __ex_flag; | ||
62 | if (unlikely(__res != 0)) | ||
63 | __res = fail_fn(count); | ||
64 | return __res; | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * Same trick is used for the unlock fast path. However the original value, | ||
69 | * rather than the result, is used to test for success in order to have | ||
70 | * better generated assembly. | ||
71 | */ | ||
72 | static inline void | ||
73 | __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) | ||
74 | { | ||
75 | int __ex_flag, __res, __orig; | ||
76 | |||
77 | __asm__ ( | ||
78 | |||
79 | "ldrex %0, [%3] \n\t" | ||
80 | "add %1, %0, #1 \n\t" | ||
81 | "strex %2, %1, [%3] " | ||
82 | |||
83 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) | ||
84 | : "r" (&(count)->counter) | ||
85 | : "cc","memory" ); | ||
86 | |||
87 | __orig |= __ex_flag; | ||
88 | if (unlikely(__orig != 0)) | ||
89 | fail_fn(count); | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * If the unlock was done on a contended lock, or if the unlock simply fails | ||
94 | * then the mutex remains locked. | ||
95 | */ | ||
96 | #define __mutex_slowpath_needs_to_unlock() 1 | ||
97 | |||
98 | /* | ||
99 | * For __mutex_fastpath_trylock we use another construct which could be | ||
100 | * described as a "single value cmpxchg". | ||
101 | * | ||
102 | * This provides the needed trylock semantics like cmpxchg would, but it is | ||
103 | * lighter and less generic than a true cmpxchg implementation. | ||
104 | */ | ||
105 | static inline int | ||
106 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
107 | { | ||
108 | int __ex_flag, __res, __orig; | ||
109 | |||
110 | __asm__ ( | ||
111 | |||
112 | "1: ldrex %0, [%3] \n\t" | ||
113 | "subs %1, %0, #1 \n\t" | ||
114 | "strexeq %2, %1, [%3] \n\t" | ||
115 | "movlt %0, #0 \n\t" | ||
116 | "cmpeq %2, #0 \n\t" | ||
117 | "bgt 1b " | ||
118 | |||
119 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) | ||
120 | : "r" (&count->counter) | ||
121 | : "cc", "memory" ); | ||
122 | |||
123 | return __orig; | ||
124 | } | ||
125 | |||
126 | #endif | ||
127 | #endif | 16 | #endif |
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 23ebc0c82a39..24d284a1bfc7 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h | |||
@@ -196,7 +196,7 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn } | |||
196 | 196 | ||
197 | struct membank { | 197 | struct membank { |
198 | phys_addr_t start; | 198 | phys_addr_t start; |
199 | unsigned long size; | 199 | phys_addr_t size; |
200 | unsigned int highmem; | 200 | unsigned int highmem; |
201 | }; | 201 | }; |
202 | 202 | ||
@@ -217,7 +217,7 @@ extern struct meminfo meminfo; | |||
217 | #define bank_phys_end(bank) ((bank)->start + (bank)->size) | 217 | #define bank_phys_end(bank) ((bank)->start + (bank)->size) |
218 | #define bank_phys_size(bank) (bank)->size | 218 | #define bank_phys_size(bank) (bank)->size |
219 | 219 | ||
220 | extern int arm_add_memory(phys_addr_t start, unsigned long size); | 220 | extern int arm_add_memory(phys_addr_t start, phys_addr_t size); |
221 | extern void early_print(const char *str, ...); | 221 | extern void early_print(const char *str, ...); |
222 | extern void dump_machine_table(void); | 222 | extern void dump_machine_table(void); |
223 | 223 | ||
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 0d1851ca6eb9..0f82098c9bfe 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -244,6 +244,19 @@ svc_preempt: | |||
244 | b 1b | 244 | b 1b |
245 | #endif | 245 | #endif |
246 | 246 | ||
247 | __und_fault: | ||
248 | @ Correct the PC such that it is pointing at the instruction | ||
249 | @ which caused the fault. If the faulting instruction was ARM | ||
250 | @ the PC will be pointing at the next instruction, and have to | ||
251 | @ subtract 4. Otherwise, it is Thumb, and the PC will be | ||
252 | @ pointing at the second half of the Thumb instruction. We | ||
253 | @ have to subtract 2. | ||
254 | ldr r2, [r0, #S_PC] | ||
255 | sub r2, r2, r1 | ||
256 | str r2, [r0, #S_PC] | ||
257 | b do_undefinstr | ||
258 | ENDPROC(__und_fault) | ||
259 | |||
247 | .align 5 | 260 | .align 5 |
248 | __und_svc: | 261 | __und_svc: |
249 | #ifdef CONFIG_KPROBES | 262 | #ifdef CONFIG_KPROBES |
@@ -261,25 +274,32 @@ __und_svc: | |||
261 | @ | 274 | @ |
262 | @ r0 - instruction | 275 | @ r0 - instruction |
263 | @ | 276 | @ |
264 | #ifndef CONFIG_THUMB2_KERNEL | 277 | #ifndef CONFIG_THUMB2_KERNEL |
265 | ldr r0, [r4, #-4] | 278 | ldr r0, [r4, #-4] |
266 | #else | 279 | #else |
280 | mov r1, #2 | ||
267 | ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 | 281 | ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 |
268 | cmp r0, #0xe800 @ 32-bit instruction if xx >= 0 | 282 | cmp r0, #0xe800 @ 32-bit instruction if xx >= 0 |
269 | ldrhhs r9, [r4] @ bottom 16 bits | 283 | blo __und_svc_fault |
270 | orrhs r0, r9, r0, lsl #16 | 284 | ldrh r9, [r4] @ bottom 16 bits |
285 | add r4, r4, #2 | ||
286 | str r4, [sp, #S_PC] | ||
287 | orr r0, r9, r0, lsl #16 | ||
271 | #endif | 288 | #endif |
272 | adr r9, BSYM(1f) | 289 | adr r9, BSYM(__und_svc_finish) |
273 | mov r2, r4 | 290 | mov r2, r4 |
274 | bl call_fpe | 291 | bl call_fpe |
275 | 292 | ||
293 | mov r1, #4 @ PC correction to apply | ||
294 | __und_svc_fault: | ||
276 | mov r0, sp @ struct pt_regs *regs | 295 | mov r0, sp @ struct pt_regs *regs |
277 | bl do_undefinstr | 296 | bl __und_fault |
278 | 297 | ||
279 | @ | 298 | @ |
280 | @ IRQs off again before pulling preserved data off the stack | 299 | @ IRQs off again before pulling preserved data off the stack |
281 | @ | 300 | @ |
282 | 1: disable_irq_notrace | 301 | __und_svc_finish: |
302 | disable_irq_notrace | ||
283 | 303 | ||
284 | @ | 304 | @ |
285 | @ restore SPSR and restart the instruction | 305 | @ restore SPSR and restart the instruction |
@@ -423,25 +443,33 @@ __und_usr: | |||
423 | mov r2, r4 | 443 | mov r2, r4 |
424 | mov r3, r5 | 444 | mov r3, r5 |
425 | 445 | ||
446 | @ r2 = regs->ARM_pc, which is either 2 or 4 bytes ahead of the | ||
447 | @ faulting instruction depending on Thumb mode. | ||
448 | @ r3 = regs->ARM_cpsr | ||
426 | @ | 449 | @ |
427 | @ fall through to the emulation code, which returns using r9 if | 450 | @ The emulation code returns using r9 if it has emulated the |
428 | @ it has emulated the instruction, or the more conventional lr | 451 | @ instruction, or the more conventional lr if we are to treat |
429 | @ if we are to treat this as a real undefined instruction | 452 | @ this as a real undefined instruction |
430 | @ | ||
431 | @ r0 - instruction | ||
432 | @ | 453 | @ |
433 | adr r9, BSYM(ret_from_exception) | 454 | adr r9, BSYM(ret_from_exception) |
434 | adr lr, BSYM(__und_usr_unknown) | 455 | |
435 | tst r3, #PSR_T_BIT @ Thumb mode? | 456 | tst r3, #PSR_T_BIT @ Thumb mode? |
436 | itet eq @ explicit IT needed for the 1f label | 457 | bne __und_usr_thumb |
437 | subeq r4, r2, #4 @ ARM instr at LR - 4 | 458 | sub r4, r2, #4 @ ARM instr at LR - 4 |
438 | subne r4, r2, #2 @ Thumb instr at LR - 2 | 459 | 1: ldrt r0, [r4] |
439 | 1: ldreqt r0, [r4] | ||
440 | #ifdef CONFIG_CPU_ENDIAN_BE8 | 460 | #ifdef CONFIG_CPU_ENDIAN_BE8 |
441 | reveq r0, r0 @ little endian instruction | 461 | rev r0, r0 @ little endian instruction |
442 | #endif | 462 | #endif |
443 | beq call_fpe | 463 | @ r0 = 32-bit ARM instruction which caused the exception |
464 | @ r2 = PC value for the following instruction (:= regs->ARM_pc) | ||
465 | @ r4 = PC value for the faulting instruction | ||
466 | @ lr = 32-bit undefined instruction function | ||
467 | adr lr, BSYM(__und_usr_fault_32) | ||
468 | b call_fpe | ||
469 | |||
470 | __und_usr_thumb: | ||
444 | @ Thumb instruction | 471 | @ Thumb instruction |
472 | sub r4, r2, #2 @ First half of thumb instr at LR - 2 | ||
445 | #if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7 | 473 | #if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7 |
446 | /* | 474 | /* |
447 | * Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms | 475 | * Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms |
@@ -455,7 +483,7 @@ __und_usr: | |||
455 | ldr r5, .LCcpu_architecture | 483 | ldr r5, .LCcpu_architecture |
456 | ldr r5, [r5] | 484 | ldr r5, [r5] |
457 | cmp r5, #CPU_ARCH_ARMv7 | 485 | cmp r5, #CPU_ARCH_ARMv7 |
458 | blo __und_usr_unknown | 486 | blo __und_usr_fault_16 @ 16bit undefined instruction |
459 | /* | 487 | /* |
460 | * The following code won't get run unless the running CPU really is v7, so | 488 | * The following code won't get run unless the running CPU really is v7, so |
461 | * coding round the lack of ldrht on older arches is pointless. Temporarily | 489 | * coding round the lack of ldrht on older arches is pointless. Temporarily |
@@ -463,15 +491,18 @@ __und_usr: | |||
463 | */ | 491 | */ |
464 | .arch armv6t2 | 492 | .arch armv6t2 |
465 | #endif | 493 | #endif |
466 | 2: | 494 | 2: ldrht r5, [r4] |
467 | ARM( ldrht r5, [r4], #2 ) | ||
468 | THUMB( ldrht r5, [r4] ) | ||
469 | THUMB( add r4, r4, #2 ) | ||
470 | cmp r5, #0xe800 @ 32bit instruction if xx != 0 | 495 | cmp r5, #0xe800 @ 32bit instruction if xx != 0 |
471 | blo __und_usr_unknown | 496 | blo __und_usr_fault_16 @ 16bit undefined instruction |
472 | 3: ldrht r0, [r4] | 497 | 3: ldrht r0, [r2] |
473 | add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 | 498 | add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 |
499 | str r2, [sp, #S_PC] @ it's a 2x16bit instr, update | ||
474 | orr r0, r0, r5, lsl #16 | 500 | orr r0, r0, r5, lsl #16 |
501 | adr lr, BSYM(__und_usr_fault_32) | ||
502 | @ r0 = the two 16-bit Thumb instructions which caused the exception | ||
503 | @ r2 = PC value for the following Thumb instruction (:= regs->ARM_pc) | ||
504 | @ r4 = PC value for the first 16-bit Thumb instruction | ||
505 | @ lr = 32bit undefined instruction function | ||
475 | 506 | ||
476 | #if __LINUX_ARM_ARCH__ < 7 | 507 | #if __LINUX_ARM_ARCH__ < 7 |
477 | /* If the target arch was overridden, change it back: */ | 508 | /* If the target arch was overridden, change it back: */ |
@@ -482,17 +513,13 @@ __und_usr: | |||
482 | #endif | 513 | #endif |
483 | #endif /* __LINUX_ARM_ARCH__ < 7 */ | 514 | #endif /* __LINUX_ARM_ARCH__ < 7 */ |
484 | #else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */ | 515 | #else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */ |
485 | b __und_usr_unknown | 516 | b __und_usr_fault_16 |
486 | #endif | 517 | #endif |
487 | UNWIND(.fnend ) | 518 | UNWIND(.fnend) |
488 | ENDPROC(__und_usr) | 519 | ENDPROC(__und_usr) |
489 | 520 | ||
490 | @ | ||
491 | @ fallthrough to call_fpe | ||
492 | @ | ||
493 | |||
494 | /* | 521 | /* |
495 | * The out of line fixup for the ldrt above. | 522 | * The out of line fixup for the ldrt instructions above. |
496 | */ | 523 | */ |
497 | .pushsection .fixup, "ax" | 524 | .pushsection .fixup, "ax" |
498 | .align 2 | 525 | .align 2 |
@@ -524,11 +551,12 @@ ENDPROC(__und_usr) | |||
524 | * NEON handler code. | 551 | * NEON handler code. |
525 | * | 552 | * |
526 | * Emulators may wish to make use of the following registers: | 553 | * Emulators may wish to make use of the following registers: |
527 | * r0 = instruction opcode. | 554 | * r0 = instruction opcode (32-bit ARM or two 16-bit Thumb) |
528 | * r2 = PC+4 | 555 | * r2 = PC value to resume execution after successful emulation |
529 | * r9 = normal "successful" return address | 556 | * r9 = normal "successful" return address |
530 | * r10 = this threads thread_info structure. | 557 | * r10 = this threads thread_info structure |
531 | * lr = unrecognised instruction return address | 558 | * lr = unrecognised instruction return address |
559 | * IRQs disabled, FIQs enabled. | ||
532 | */ | 560 | */ |
533 | @ | 561 | @ |
534 | @ Fall-through from Thumb-2 __und_usr | 562 | @ Fall-through from Thumb-2 __und_usr |
@@ -659,12 +687,17 @@ ENTRY(no_fp) | |||
659 | mov pc, lr | 687 | mov pc, lr |
660 | ENDPROC(no_fp) | 688 | ENDPROC(no_fp) |
661 | 689 | ||
662 | __und_usr_unknown: | 690 | __und_usr_fault_32: |
663 | enable_irq | 691 | mov r1, #4 |
692 | b 1f | ||
693 | __und_usr_fault_16: | ||
694 | mov r1, #2 | ||
695 | 1: enable_irq | ||
664 | mov r0, sp | 696 | mov r0, sp |
665 | adr lr, BSYM(ret_from_exception) | 697 | adr lr, BSYM(ret_from_exception) |
666 | b do_undefinstr | 698 | b __und_fault |
667 | ENDPROC(__und_usr_unknown) | 699 | ENDPROC(__und_usr_fault_32) |
700 | ENDPROC(__und_usr_fault_16) | ||
668 | 701 | ||
669 | .align 5 | 702 | .align 5 |
670 | __pabt_usr: | 703 | __pabt_usr: |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 49d9f9305247..978eac57e04a 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -51,23 +51,15 @@ ret_fast_syscall: | |||
51 | fast_work_pending: | 51 | fast_work_pending: |
52 | str r0, [sp, #S_R0+S_OFF]! @ returned r0 | 52 | str r0, [sp, #S_R0+S_OFF]! @ returned r0 |
53 | work_pending: | 53 | work_pending: |
54 | tst r1, #_TIF_NEED_RESCHED | ||
55 | bne work_resched | ||
56 | /* | ||
57 | * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here | ||
58 | */ | ||
59 | ldr r2, [sp, #S_PSR] | ||
60 | mov r0, sp @ 'regs' | 54 | mov r0, sp @ 'regs' |
61 | tst r2, #15 @ are we returning to user mode? | ||
62 | bne no_work_pending @ no? just leave, then... | ||
63 | mov r2, why @ 'syscall' | 55 | mov r2, why @ 'syscall' |
64 | tst r1, #_TIF_SIGPENDING @ delivering a signal? | 56 | bl do_work_pending |
65 | movne why, #0 @ prevent further restarts | 57 | cmp r0, #0 |
66 | bl do_notify_resume | 58 | beq no_work_pending |
67 | b ret_slow_syscall @ Check work again | 59 | movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE) |
60 | ldmia sp, {r0 - r6} @ have to reload r0 - r6 | ||
61 | b local_restart @ ... and off we go | ||
68 | 62 | ||
69 | work_resched: | ||
70 | bl schedule | ||
71 | /* | 63 | /* |
72 | * "slow" syscall return path. "why" tells us if this was a real syscall. | 64 | * "slow" syscall return path. "why" tells us if this was a real syscall. |
73 | */ | 65 | */ |
@@ -409,6 +401,7 @@ ENTRY(vector_swi) | |||
409 | eor scno, scno, #__NR_SYSCALL_BASE @ check OS number | 401 | eor scno, scno, #__NR_SYSCALL_BASE @ check OS number |
410 | #endif | 402 | #endif |
411 | 403 | ||
404 | local_restart: | ||
412 | ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing | 405 | ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing |
413 | stmdb sp!, {r4, r5} @ push fifth and sixth args | 406 | stmdb sp!, {r4, r5} @ push fifth and sixth args |
414 | 407 | ||
@@ -450,7 +443,8 @@ __sys_trace: | |||
450 | mov scno, r0 @ syscall number (possibly new) | 443 | mov scno, r0 @ syscall number (possibly new) |
451 | add r1, sp, #S_R0 + S_OFF @ pointer to regs | 444 | add r1, sp, #S_R0 + S_OFF @ pointer to regs |
452 | cmp scno, #NR_syscalls @ check upper syscall limit | 445 | cmp scno, #NR_syscalls @ check upper syscall limit |
453 | ldmccia r1, {r0 - r3} @ have to reload r0 - r3 | 446 | ldmccia r1, {r0 - r6} @ have to reload r0 - r6 |
447 | stmccia sp, {r4, r5} @ and update the stack args | ||
454 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine | 448 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine |
455 | b 2b | 449 | b 2b |
456 | 450 | ||
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index df0bf0c8cb79..34e56647dcee 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c | |||
@@ -179,19 +179,20 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
179 | old = *parent; | 179 | old = *parent; |
180 | *parent = return_hooker; | 180 | *parent = return_hooker; |
181 | 181 | ||
182 | err = ftrace_push_return_trace(old, self_addr, &trace.depth, | ||
183 | frame_pointer); | ||
184 | if (err == -EBUSY) { | ||
185 | *parent = old; | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | trace.func = self_addr; | 182 | trace.func = self_addr; |
183 | trace.depth = current->curr_ret_stack + 1; | ||
190 | 184 | ||
191 | /* Only trace if the calling function expects to */ | 185 | /* Only trace if the calling function expects to */ |
192 | if (!ftrace_graph_entry(&trace)) { | 186 | if (!ftrace_graph_entry(&trace)) { |
193 | current->curr_ret_stack--; | ||
194 | *parent = old; | 187 | *parent = old; |
188 | return; | ||
189 | } | ||
190 | |||
191 | err = ftrace_push_return_trace(old, self_addr, &trace.depth, | ||
192 | frame_pointer); | ||
193 | if (err == -EBUSY) { | ||
194 | *parent = old; | ||
195 | return; | ||
195 | } | 196 | } |
196 | } | 197 | } |
197 | 198 | ||
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 19c95ea65b2f..693b744fd572 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -247,6 +247,7 @@ void machine_shutdown(void) | |||
247 | void machine_halt(void) | 247 | void machine_halt(void) |
248 | { | 248 | { |
249 | machine_shutdown(); | 249 | machine_shutdown(); |
250 | local_irq_disable(); | ||
250 | while (1); | 251 | while (1); |
251 | } | 252 | } |
252 | 253 | ||
@@ -268,6 +269,7 @@ void machine_restart(char *cmd) | |||
268 | 269 | ||
269 | /* Whoops - the platform was unable to reboot. Tell the user! */ | 270 | /* Whoops - the platform was unable to reboot. Tell the user! */ |
270 | printk("Reboot failed -- System halted\n"); | 271 | printk("Reboot failed -- System halted\n"); |
272 | local_irq_disable(); | ||
271 | while (1); | 273 | while (1); |
272 | } | 274 | } |
273 | 275 | ||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index dab711e6e1ca..3e0fc5f7ed4b 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/regset.h> | 25 | #include <linux/regset.h> |
26 | #include <linux/audit.h> | 26 | #include <linux/audit.h> |
27 | #include <linux/tracehook.h> | 27 | #include <linux/tracehook.h> |
28 | #include <linux/unistd.h> | ||
28 | 29 | ||
29 | #include <asm/pgtable.h> | 30 | #include <asm/pgtable.h> |
30 | #include <asm/traps.h> | 31 | #include <asm/traps.h> |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index e15d83bb4ea3..a81dcecc7343 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -508,7 +508,7 @@ void __init dump_machine_table(void) | |||
508 | /* can't use cpu_relax() here as it may require MMU setup */; | 508 | /* can't use cpu_relax() here as it may require MMU setup */; |
509 | } | 509 | } |
510 | 510 | ||
511 | int __init arm_add_memory(phys_addr_t start, unsigned long size) | 511 | int __init arm_add_memory(phys_addr_t start, phys_addr_t size) |
512 | { | 512 | { |
513 | struct membank *bank = &meminfo.bank[meminfo.nr_banks]; | 513 | struct membank *bank = &meminfo.bank[meminfo.nr_banks]; |
514 | 514 | ||
@@ -538,7 +538,7 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size) | |||
538 | } | 538 | } |
539 | #endif | 539 | #endif |
540 | 540 | ||
541 | bank->size = size & PAGE_MASK; | 541 | bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1); |
542 | 542 | ||
543 | /* | 543 | /* |
544 | * Check whether this memory region has non-zero size or | 544 | * Check whether this memory region has non-zero size or |
@@ -558,7 +558,7 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size) | |||
558 | static int __init early_mem(char *p) | 558 | static int __init early_mem(char *p) |
559 | { | 559 | { |
560 | static int usermem __initdata = 0; | 560 | static int usermem __initdata = 0; |
561 | unsigned long size; | 561 | phys_addr_t size; |
562 | phys_addr_t start; | 562 | phys_addr_t start; |
563 | char *endp; | 563 | char *endp; |
564 | 564 | ||
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 536c5d6b340b..f27789e4e38a 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -27,7 +27,6 @@ | |||
27 | */ | 27 | */ |
28 | #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) | 28 | #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) |
29 | #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) | 29 | #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) |
30 | #define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE) | ||
31 | 30 | ||
32 | /* | 31 | /* |
33 | * With EABI, the syscall number has to be loaded into r7. | 32 | * With EABI, the syscall number has to be loaded into r7. |
@@ -48,18 +47,6 @@ const unsigned long sigreturn_codes[7] = { | |||
48 | }; | 47 | }; |
49 | 48 | ||
50 | /* | 49 | /* |
51 | * Either we support OABI only, or we have EABI with the OABI | ||
52 | * compat layer enabled. In the later case we don't know if | ||
53 | * user space is EABI or not, and if not we must not clobber r7. | ||
54 | * Always using the OABI syscall solves that issue and works for | ||
55 | * all those cases. | ||
56 | */ | ||
57 | const unsigned long syscall_restart_code[2] = { | ||
58 | SWI_SYS_RESTART, /* swi __NR_restart_syscall */ | ||
59 | 0xe49df004, /* ldr pc, [sp], #4 */ | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | * atomically swap in the new signal mask, and wait for a signal. | 50 | * atomically swap in the new signal mask, and wait for a signal. |
64 | */ | 51 | */ |
65 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) | 52 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) |
@@ -582,12 +569,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
582 | * the kernel can handle, and then we build all the user-level signal handling | 569 | * the kernel can handle, and then we build all the user-level signal handling |
583 | * stack-frames in one go after that. | 570 | * stack-frames in one go after that. |
584 | */ | 571 | */ |
585 | static void do_signal(struct pt_regs *regs, int syscall) | 572 | static int do_signal(struct pt_regs *regs, int syscall) |
586 | { | 573 | { |
587 | unsigned int retval = 0, continue_addr = 0, restart_addr = 0; | 574 | unsigned int retval = 0, continue_addr = 0, restart_addr = 0; |
588 | struct k_sigaction ka; | 575 | struct k_sigaction ka; |
589 | siginfo_t info; | 576 | siginfo_t info; |
590 | int signr; | 577 | int signr; |
578 | int restart = 0; | ||
591 | 579 | ||
592 | /* | 580 | /* |
593 | * If we were from a system call, check for system call restarting... | 581 | * If we were from a system call, check for system call restarting... |
@@ -602,15 +590,15 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
602 | * debugger will see the already changed PSW. | 590 | * debugger will see the already changed PSW. |
603 | */ | 591 | */ |
604 | switch (retval) { | 592 | switch (retval) { |
593 | case -ERESTART_RESTARTBLOCK: | ||
594 | restart -= 2; | ||
605 | case -ERESTARTNOHAND: | 595 | case -ERESTARTNOHAND: |
606 | case -ERESTARTSYS: | 596 | case -ERESTARTSYS: |
607 | case -ERESTARTNOINTR: | 597 | case -ERESTARTNOINTR: |
598 | restart++; | ||
608 | regs->ARM_r0 = regs->ARM_ORIG_r0; | 599 | regs->ARM_r0 = regs->ARM_ORIG_r0; |
609 | regs->ARM_pc = restart_addr; | 600 | regs->ARM_pc = restart_addr; |
610 | break; | 601 | break; |
611 | case -ERESTART_RESTARTBLOCK: | ||
612 | regs->ARM_r0 = -EINTR; | ||
613 | break; | ||
614 | } | 602 | } |
615 | } | 603 | } |
616 | 604 | ||
@@ -619,14 +607,17 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
619 | * point the debugger may change all our registers ... | 607 | * point the debugger may change all our registers ... |
620 | */ | 608 | */ |
621 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 609 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
610 | /* | ||
611 | * Depending on the signal settings we may need to revert the | ||
612 | * decision to restart the system call. But skip this if a | ||
613 | * debugger has chosen to restart at a different PC. | ||
614 | */ | ||
615 | if (regs->ARM_pc != restart_addr) | ||
616 | restart = 0; | ||
622 | if (signr > 0) { | 617 | if (signr > 0) { |
623 | /* | 618 | if (unlikely(restart)) { |
624 | * Depending on the signal settings we may need to revert the | 619 | if (retval == -ERESTARTNOHAND || |
625 | * decision to restart the system call. But skip this if a | 620 | retval == -ERESTART_RESTARTBLOCK |
626 | * debugger has chosen to restart at a different PC. | ||
627 | */ | ||
628 | if (regs->ARM_pc == restart_addr) { | ||
629 | if (retval == -ERESTARTNOHAND | ||
630 | || (retval == -ERESTARTSYS | 621 | || (retval == -ERESTARTSYS |
631 | && !(ka.sa.sa_flags & SA_RESTART))) { | 622 | && !(ka.sa.sa_flags & SA_RESTART))) { |
632 | regs->ARM_r0 = -EINTR; | 623 | regs->ARM_r0 = -EINTR; |
@@ -635,52 +626,43 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
635 | } | 626 | } |
636 | 627 | ||
637 | handle_signal(signr, &ka, &info, regs); | 628 | handle_signal(signr, &ka, &info, regs); |
638 | return; | 629 | return 0; |
639 | } | ||
640 | |||
641 | if (syscall) { | ||
642 | /* | ||
643 | * Handle restarting a different system call. As above, | ||
644 | * if a debugger has chosen to restart at a different PC, | ||
645 | * ignore the restart. | ||
646 | */ | ||
647 | if (retval == -ERESTART_RESTARTBLOCK | ||
648 | && regs->ARM_pc == continue_addr) { | ||
649 | if (thumb_mode(regs)) { | ||
650 | regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; | ||
651 | regs->ARM_pc -= 2; | ||
652 | } else { | ||
653 | #if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT) | ||
654 | regs->ARM_r7 = __NR_restart_syscall; | ||
655 | regs->ARM_pc -= 4; | ||
656 | #else | ||
657 | u32 __user *usp; | ||
658 | |||
659 | regs->ARM_sp -= 4; | ||
660 | usp = (u32 __user *)regs->ARM_sp; | ||
661 | |||
662 | if (put_user(regs->ARM_pc, usp) == 0) { | ||
663 | regs->ARM_pc = KERN_RESTART_CODE; | ||
664 | } else { | ||
665 | regs->ARM_sp += 4; | ||
666 | force_sigsegv(0, current); | ||
667 | } | ||
668 | #endif | ||
669 | } | ||
670 | } | ||
671 | } | 630 | } |
672 | 631 | ||
673 | restore_saved_sigmask(); | 632 | restore_saved_sigmask(); |
633 | if (unlikely(restart)) | ||
634 | regs->ARM_pc = continue_addr; | ||
635 | return restart; | ||
674 | } | 636 | } |
675 | 637 | ||
676 | asmlinkage void | 638 | asmlinkage int |
677 | do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) | 639 | do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) |
678 | { | 640 | { |
679 | if (thread_flags & _TIF_SIGPENDING) | 641 | do { |
680 | do_signal(regs, syscall); | 642 | if (likely(thread_flags & _TIF_NEED_RESCHED)) { |
681 | 643 | schedule(); | |
682 | if (thread_flags & _TIF_NOTIFY_RESUME) { | 644 | } else { |
683 | clear_thread_flag(TIF_NOTIFY_RESUME); | 645 | if (unlikely(!user_mode(regs))) |
684 | tracehook_notify_resume(regs); | 646 | return 0; |
685 | } | 647 | local_irq_enable(); |
648 | if (thread_flags & _TIF_SIGPENDING) { | ||
649 | int restart = do_signal(regs, syscall); | ||
650 | if (unlikely(restart)) { | ||
651 | /* | ||
652 | * Restart without handlers. | ||
653 | * Deal with it without leaving | ||
654 | * the kernel space. | ||
655 | */ | ||
656 | return restart; | ||
657 | } | ||
658 | syscall = 0; | ||
659 | } else { | ||
660 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
661 | tracehook_notify_resume(regs); | ||
662 | } | ||
663 | } | ||
664 | local_irq_disable(); | ||
665 | thread_flags = current_thread_info()->flags; | ||
666 | } while (thread_flags & _TIF_WORK_MASK); | ||
667 | return 0; | ||
686 | } | 668 | } |
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h index 6fcfe8398aa4..5ff067b7c752 100644 --- a/arch/arm/kernel/signal.h +++ b/arch/arm/kernel/signal.h | |||
@@ -8,7 +8,5 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) | 10 | #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) |
11 | #define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) | ||
12 | 11 | ||
13 | extern const unsigned long sigreturn_codes[7]; | 12 | extern const unsigned long sigreturn_codes[7]; |
14 | extern const unsigned long syscall_restart_code[2]; | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index aea74f5bc34a..ebd8ad274d76 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -563,7 +563,8 @@ void smp_send_stop(void) | |||
563 | 563 | ||
564 | cpumask_copy(&mask, cpu_online_mask); | 564 | cpumask_copy(&mask, cpu_online_mask); |
565 | cpumask_clear_cpu(smp_processor_id(), &mask); | 565 | cpumask_clear_cpu(smp_processor_id(), &mask); |
566 | smp_cross_call(&mask, IPI_CPU_STOP); | 566 | if (!cpumask_empty(&mask)) |
567 | smp_cross_call(&mask, IPI_CPU_STOP); | ||
567 | 568 | ||
568 | /* Wait up to one second for other CPUs to stop */ | 569 | /* Wait up to one second for other CPUs to stop */ |
569 | timeout = USEC_PER_SEC; | 570 | timeout = USEC_PER_SEC; |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 8b97d739b17b..f7945218b8c6 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -402,18 +402,10 @@ static int call_undef_hook(struct pt_regs *regs, unsigned int instr) | |||
402 | 402 | ||
403 | asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | 403 | asmlinkage void __exception do_undefinstr(struct pt_regs *regs) |
404 | { | 404 | { |
405 | unsigned int correction = thumb_mode(regs) ? 2 : 4; | ||
406 | unsigned int instr; | 405 | unsigned int instr; |
407 | siginfo_t info; | 406 | siginfo_t info; |
408 | void __user *pc; | 407 | void __user *pc; |
409 | 408 | ||
410 | /* | ||
411 | * According to the ARM ARM, PC is 2 or 4 bytes ahead, | ||
412 | * depending whether we're in Thumb mode or not. | ||
413 | * Correct this offset. | ||
414 | */ | ||
415 | regs->ARM_pc -= correction; | ||
416 | |||
417 | pc = (void __user *)instruction_pointer(regs); | 409 | pc = (void __user *)instruction_pointer(regs); |
418 | 410 | ||
419 | if (processor_mode(regs) == SVC_MODE) { | 411 | if (processor_mode(regs) == SVC_MODE) { |
@@ -852,8 +844,6 @@ void __init early_trap_init(void *vectors_base) | |||
852 | */ | 844 | */ |
853 | memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), | 845 | memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), |
854 | sigreturn_codes, sizeof(sigreturn_codes)); | 846 | sigreturn_codes, sizeof(sigreturn_codes)); |
855 | memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE), | ||
856 | syscall_restart_code, sizeof(syscall_restart_code)); | ||
857 | 847 | ||
858 | flush_icache_range(vectors, vectors + PAGE_SIZE); | 848 | flush_icache_range(vectors, vectors + PAGE_SIZE); |
859 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); | 849 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); |
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index d1624a315c9a..783eab6845c4 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c | |||
@@ -546,6 +546,7 @@ static struct lcd_ctrl_config lcd_cfg = { | |||
546 | .sync_edge = 0, | 546 | .sync_edge = 0, |
547 | .sync_ctrl = 1, | 547 | .sync_ctrl = 1, |
548 | .raster_order = 0, | 548 | .raster_order = 0, |
549 | .fifo_th = 6, | ||
549 | }; | 550 | }; |
550 | 551 | ||
551 | struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = { | 552 | struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = { |
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index f07fd16e0c9b..9bc97a5baaa8 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c | |||
@@ -20,22 +20,6 @@ | |||
20 | #include <mach/bridge-regs.h> | 20 | #include <mach/bridge-regs.h> |
21 | #include "common.h" | 21 | #include "common.h" |
22 | 22 | ||
23 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
24 | { | ||
25 | int irqoff; | ||
26 | BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO); | ||
27 | |||
28 | irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 : | ||
29 | 3 + irq - IRQ_DOVE_GPIO_24_31; | ||
30 | |||
31 | orion_gpio_irq_handler(irqoff << 3); | ||
32 | if (irq == IRQ_DOVE_HIGH_GPIO) { | ||
33 | orion_gpio_irq_handler(40); | ||
34 | orion_gpio_irq_handler(48); | ||
35 | orion_gpio_irq_handler(56); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | static void pmu_irq_mask(struct irq_data *d) | 23 | static void pmu_irq_mask(struct irq_data *d) |
40 | { | 24 | { |
41 | int pin = irq_to_pmu(d->irq); | 25 | int pin = irq_to_pmu(d->irq); |
@@ -90,6 +74,27 @@ static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
90 | } | 74 | } |
91 | } | 75 | } |
92 | 76 | ||
77 | static int __initdata gpio0_irqs[4] = { | ||
78 | IRQ_DOVE_GPIO_0_7, | ||
79 | IRQ_DOVE_GPIO_8_15, | ||
80 | IRQ_DOVE_GPIO_16_23, | ||
81 | IRQ_DOVE_GPIO_24_31, | ||
82 | }; | ||
83 | |||
84 | static int __initdata gpio1_irqs[4] = { | ||
85 | IRQ_DOVE_HIGH_GPIO, | ||
86 | 0, | ||
87 | 0, | ||
88 | 0, | ||
89 | }; | ||
90 | |||
91 | static int __initdata gpio2_irqs[4] = { | ||
92 | 0, | ||
93 | 0, | ||
94 | 0, | ||
95 | 0, | ||
96 | }; | ||
97 | |||
93 | void __init dove_init_irq(void) | 98 | void __init dove_init_irq(void) |
94 | { | 99 | { |
95 | int i; | 100 | int i; |
@@ -100,19 +105,14 @@ void __init dove_init_irq(void) | |||
100 | /* | 105 | /* |
101 | * Initialize gpiolib for GPIOs 0-71. | 106 | * Initialize gpiolib for GPIOs 0-71. |
102 | */ | 107 | */ |
103 | orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0, | 108 | orion_gpio_init(NULL, 0, 32, (void __iomem *)DOVE_GPIO_LO_VIRT_BASE, 0, |
104 | IRQ_DOVE_GPIO_START); | 109 | IRQ_DOVE_GPIO_START, gpio0_irqs); |
105 | irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); | 110 | |
106 | irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); | 111 | orion_gpio_init(NULL, 32, 32, (void __iomem *)DOVE_GPIO_HI_VIRT_BASE, 0, |
107 | irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); | 112 | IRQ_DOVE_GPIO_START + 32, gpio1_irqs); |
108 | irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); | 113 | |
109 | 114 | orion_gpio_init(NULL, 64, 8, (void __iomem *)DOVE_GPIO2_VIRT_BASE, 0, | |
110 | orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0, | 115 | IRQ_DOVE_GPIO_START + 64, gpio2_irqs); |
111 | IRQ_DOVE_GPIO_START + 32); | ||
112 | irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); | ||
113 | |||
114 | orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0, | ||
115 | IRQ_DOVE_GPIO_START + 64); | ||
116 | 116 | ||
117 | /* | 117 | /* |
118 | * Mask and clear PMU interrupts | 118 | * Mask and clear PMU interrupts |
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 199764fe0fb0..ca5c15a4e626 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig | |||
@@ -80,6 +80,35 @@ config MACH_IB62X0_DT | |||
80 | RaidSonic IB-NAS6210 & IB-NAS6220 devices, using | 80 | RaidSonic IB-NAS6210 & IB-NAS6220 devices, using |
81 | Flattened Device Tree. | 81 | Flattened Device Tree. |
82 | 82 | ||
83 | config MACH_TS219_DT | ||
84 | bool "Device Tree for QNAP TS-11X, TS-21X NAS" | ||
85 | select ARCH_KIRKWOOD_DT | ||
86 | select ARM_APPENDED_DTB | ||
87 | select ARM_ATAG_DTB_COMPAT | ||
88 | help | ||
89 | Say 'Y' here if you want your kernel to support the QNAP | ||
90 | TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and | ||
91 | TS-219P+ Turbo NAS devices using Fattened Device Tree. | ||
92 | There are two different Device Tree descriptions, depending | ||
93 | on if the device is based on an if the board uses the MV6281 | ||
94 | or MV6282. If you have the wrong one, the buttons will not | ||
95 | work. | ||
96 | |||
97 | config MACH_GOFLEXNET_DT | ||
98 | bool "Seagate GoFlex Net (Flattened Device Tree)" | ||
99 | select ARCH_KIRKWOOD_DT | ||
100 | help | ||
101 | Say 'Y' here if you want your kernel to support the | ||
102 | Seagate GoFlex Net (Flattened Device Tree). | ||
103 | |||
104 | config MACH_LSXL_DT | ||
105 | bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)" | ||
106 | select ARCH_KIRKWOOD_DT | ||
107 | help | ||
108 | Say 'Y' here if you want your kernel to support the | ||
109 | Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using | ||
110 | Flattened Device Tree. | ||
111 | |||
83 | config MACH_TS219 | 112 | config MACH_TS219 |
84 | bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" | 113 | bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" |
85 | help | 114 | help |
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index d2b05907b10e..055c85a1cc46 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile | |||
@@ -25,3 +25,6 @@ obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o | |||
25 | obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o | 25 | obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o |
26 | obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o | 26 | obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o |
27 | obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o | 27 | obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o |
28 | obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o | ||
29 | obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o | ||
30 | obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o | ||
diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot index 02edbdf5b065..2a576abf409b 100644 --- a/arch/arm/mach-kirkwood/Makefile.boot +++ b/arch/arm/mach-kirkwood/Makefile.boot | |||
@@ -7,3 +7,7 @@ dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb | |||
7 | dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb | 7 | dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb |
8 | dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb | 8 | dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb |
9 | dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb | 9 | dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb |
10 | dtb-$(CONFIG_MACH_TS219_DT) += kirkwood-qnap-ts219.dtb | ||
11 | dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb | ||
12 | dbt-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb | ||
13 | dbt-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb | ||
diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c index 58c2d68f9443..4ab35065a144 100644 --- a/arch/arm/mach-kirkwood/board-dnskw.c +++ b/arch/arm/mach-kirkwood/board-dnskw.c | |||
@@ -14,13 +14,11 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/i2c.h> | ||
18 | #include <linux/ata_platform.h> | 17 | #include <linux/ata_platform.h> |
19 | #include <linux/mv643xx_eth.h> | 18 | #include <linux/mv643xx_eth.h> |
20 | #include <linux/of.h> | 19 | #include <linux/of.h> |
21 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
22 | #include <linux/input.h> | 21 | #include <linux/input.h> |
23 | #include <linux/gpio_keys.h> | ||
24 | #include <linux/gpio-fan.h> | 22 | #include <linux/gpio-fan.h> |
25 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
26 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
@@ -35,10 +33,6 @@ static struct mv643xx_eth_platform_data dnskw_ge00_data = { | |||
35 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | 33 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), |
36 | }; | 34 | }; |
37 | 35 | ||
38 | static struct mv_sata_platform_data dnskw_sata_data = { | ||
39 | .n_ports = 2, | ||
40 | }; | ||
41 | |||
42 | static unsigned int dnskw_mpp_config[] __initdata = { | 36 | static unsigned int dnskw_mpp_config[] __initdata = { |
43 | MPP13_UART1_TXD, /* Custom ... */ | 37 | MPP13_UART1_TXD, /* Custom ... */ |
44 | MPP14_UART1_RXD, /* ... Controller (DNS-320 only) */ | 38 | MPP14_UART1_RXD, /* ... Controller (DNS-320 only) */ |
@@ -73,132 +67,6 @@ static unsigned int dnskw_mpp_config[] __initdata = { | |||
73 | 0 | 67 | 0 |
74 | }; | 68 | }; |
75 | 69 | ||
76 | static struct gpio_led dns325_led_pins[] = { | ||
77 | { | ||
78 | .name = "dns325:white:power", | ||
79 | .gpio = 26, | ||
80 | .active_low = 1, | ||
81 | .default_trigger = "default-on", | ||
82 | }, | ||
83 | { | ||
84 | .name = "dns325:white:usb", | ||
85 | .gpio = 43, | ||
86 | .active_low = 1, | ||
87 | }, | ||
88 | { | ||
89 | .name = "dns325:red:l_hdd", | ||
90 | .gpio = 28, | ||
91 | .active_low = 1, | ||
92 | }, | ||
93 | { | ||
94 | .name = "dns325:red:r_hdd", | ||
95 | .gpio = 27, | ||
96 | .active_low = 1, | ||
97 | }, | ||
98 | { | ||
99 | .name = "dns325:red:usb", | ||
100 | .gpio = 29, | ||
101 | .active_low = 1, | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | static struct gpio_led_platform_data dns325_led_data = { | ||
106 | .num_leds = ARRAY_SIZE(dns325_led_pins), | ||
107 | .leds = dns325_led_pins, | ||
108 | }; | ||
109 | |||
110 | static struct platform_device dns325_led_device = { | ||
111 | .name = "leds-gpio", | ||
112 | .id = -1, | ||
113 | .dev = { | ||
114 | .platform_data = &dns325_led_data, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static struct gpio_led dns320_led_pins[] = { | ||
119 | { | ||
120 | .name = "dns320:blue:power", | ||
121 | .gpio = 26, | ||
122 | .active_low = 1, | ||
123 | .default_trigger = "default-on", | ||
124 | }, | ||
125 | { | ||
126 | .name = "dns320:blue:usb", | ||
127 | .gpio = 43, | ||
128 | .active_low = 1, | ||
129 | }, | ||
130 | { | ||
131 | .name = "dns320:orange:l_hdd", | ||
132 | .gpio = 28, | ||
133 | .active_low = 1, | ||
134 | }, | ||
135 | { | ||
136 | .name = "dns320:orange:r_hdd", | ||
137 | .gpio = 27, | ||
138 | .active_low = 1, | ||
139 | }, | ||
140 | { | ||
141 | .name = "dns320:orange:usb", | ||
142 | .gpio = 35, | ||
143 | .active_low = 1, | ||
144 | }, | ||
145 | }; | ||
146 | |||
147 | static struct gpio_led_platform_data dns320_led_data = { | ||
148 | .num_leds = ARRAY_SIZE(dns320_led_pins), | ||
149 | .leds = dns320_led_pins, | ||
150 | }; | ||
151 | |||
152 | static struct platform_device dns320_led_device = { | ||
153 | .name = "leds-gpio", | ||
154 | .id = -1, | ||
155 | .dev = { | ||
156 | .platform_data = &dns320_led_data, | ||
157 | }, | ||
158 | }; | ||
159 | |||
160 | static struct i2c_board_info dns325_i2c_board_info[] __initdata = { | ||
161 | { | ||
162 | I2C_BOARD_INFO("lm75", 0x48), | ||
163 | }, | ||
164 | /* Something at 0x0c also */ | ||
165 | }; | ||
166 | |||
167 | static struct gpio_keys_button dnskw_button_pins[] = { | ||
168 | { | ||
169 | .code = KEY_POWER, | ||
170 | .gpio = 34, | ||
171 | .desc = "Power button", | ||
172 | .active_low = 1, | ||
173 | }, | ||
174 | { | ||
175 | .code = KEY_EJECTCD, | ||
176 | .gpio = 47, | ||
177 | .desc = "USB unmount button", | ||
178 | .active_low = 1, | ||
179 | }, | ||
180 | { | ||
181 | .code = KEY_RESTART, | ||
182 | .gpio = 48, | ||
183 | .desc = "Reset button", | ||
184 | .active_low = 1, | ||
185 | }, | ||
186 | }; | ||
187 | |||
188 | static struct gpio_keys_platform_data dnskw_button_data = { | ||
189 | .buttons = dnskw_button_pins, | ||
190 | .nbuttons = ARRAY_SIZE(dnskw_button_pins), | ||
191 | }; | ||
192 | |||
193 | static struct platform_device dnskw_button_device = { | ||
194 | .name = "gpio-keys", | ||
195 | .id = -1, | ||
196 | .num_resources = 0, | ||
197 | .dev = { | ||
198 | .platform_data = &dnskw_button_data, | ||
199 | } | ||
200 | }; | ||
201 | |||
202 | /* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */ | 70 | /* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */ |
203 | static struct gpio_fan_speed dnskw_fan_speed[] = { | 71 | static struct gpio_fan_speed dnskw_fan_speed[] = { |
204 | { 0, 0 }, | 72 | { 0, 0 }, |
@@ -245,20 +113,9 @@ void __init dnskw_init(void) | |||
245 | 113 | ||
246 | kirkwood_ehci_init(); | 114 | kirkwood_ehci_init(); |
247 | kirkwood_ge00_init(&dnskw_ge00_data); | 115 | kirkwood_ge00_init(&dnskw_ge00_data); |
248 | kirkwood_sata_init(&dnskw_sata_data); | ||
249 | kirkwood_i2c_init(); | ||
250 | 116 | ||
251 | platform_device_register(&dnskw_button_device); | ||
252 | platform_device_register(&dnskw_fan_device); | 117 | platform_device_register(&dnskw_fan_device); |
253 | 118 | ||
254 | if (of_machine_is_compatible("dlink,dns-325")) { | ||
255 | i2c_register_board_info(0, dns325_i2c_board_info, | ||
256 | ARRAY_SIZE(dns325_i2c_board_info)); | ||
257 | platform_device_register(&dns325_led_device); | ||
258 | |||
259 | } else if (of_machine_is_compatible("dlink,dns-320")) | ||
260 | platform_device_register(&dns320_led_device); | ||
261 | |||
262 | /* Register power-off GPIO. */ | 119 | /* Register power-off GPIO. */ |
263 | if (gpio_request(36, "dnskw:power:off") == 0 | 120 | if (gpio_request(36, "dnskw:power:off") == 0 |
264 | && gpio_direction_output(36, 0) == 0) | 121 | && gpio_direction_output(36, 0) == 0) |
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c index 55e357ab2923..aeb234d0d0e3 100644 --- a/arch/arm/mach-kirkwood/board-dreamplug.c +++ b/arch/arm/mach-kirkwood/board-dreamplug.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mtd/partitions.h> | ||
18 | #include <linux/ata_platform.h> | 17 | #include <linux/ata_platform.h> |
19 | #include <linux/mv643xx_eth.h> | 18 | #include <linux/mv643xx_eth.h> |
20 | #include <linux/of.h> | 19 | #include <linux/of.h> |
@@ -23,7 +22,6 @@ | |||
23 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
24 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
25 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
26 | #include <linux/leds.h> | ||
27 | #include <linux/mtd/physmap.h> | 25 | #include <linux/mtd/physmap.h> |
28 | #include <linux/spi/flash.h> | 26 | #include <linux/spi/flash.h> |
29 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
@@ -36,42 +34,6 @@ | |||
36 | #include "common.h" | 34 | #include "common.h" |
37 | #include "mpp.h" | 35 | #include "mpp.h" |
38 | 36 | ||
39 | struct mtd_partition dreamplug_partitions[] = { | ||
40 | { | ||
41 | .name = "u-boot", | ||
42 | .size = SZ_512K, | ||
43 | .offset = 0, | ||
44 | }, | ||
45 | { | ||
46 | .name = "u-boot env", | ||
47 | .size = SZ_64K, | ||
48 | .offset = SZ_512K + SZ_512K, | ||
49 | }, | ||
50 | { | ||
51 | .name = "dtb", | ||
52 | .size = SZ_64K, | ||
53 | .offset = SZ_512K + SZ_512K + SZ_512K, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | static const struct flash_platform_data dreamplug_spi_slave_data = { | ||
58 | .type = "mx25l1606e", | ||
59 | .name = "spi_flash", | ||
60 | .parts = dreamplug_partitions, | ||
61 | .nr_parts = ARRAY_SIZE(dreamplug_partitions), | ||
62 | }; | ||
63 | |||
64 | static struct spi_board_info __initdata dreamplug_spi_slave_info[] = { | ||
65 | { | ||
66 | .modalias = "m25p80", | ||
67 | .platform_data = &dreamplug_spi_slave_data, | ||
68 | .irq = -1, | ||
69 | .max_speed_hz = 50000000, | ||
70 | .bus_num = 0, | ||
71 | .chip_select = 0, | ||
72 | }, | ||
73 | }; | ||
74 | |||
75 | static struct mv643xx_eth_platform_data dreamplug_ge00_data = { | 37 | static struct mv643xx_eth_platform_data dreamplug_ge00_data = { |
76 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), | 38 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), |
77 | }; | 39 | }; |
@@ -80,45 +42,10 @@ static struct mv643xx_eth_platform_data dreamplug_ge01_data = { | |||
80 | .phy_addr = MV643XX_ETH_PHY_ADDR(1), | 42 | .phy_addr = MV643XX_ETH_PHY_ADDR(1), |
81 | }; | 43 | }; |
82 | 44 | ||
83 | static struct mv_sata_platform_data dreamplug_sata_data = { | ||
84 | .n_ports = 1, | ||
85 | }; | ||
86 | |||
87 | static struct mvsdio_platform_data dreamplug_mvsdio_data = { | 45 | static struct mvsdio_platform_data dreamplug_mvsdio_data = { |
88 | /* unfortunately the CD signal has not been connected */ | 46 | /* unfortunately the CD signal has not been connected */ |
89 | }; | 47 | }; |
90 | 48 | ||
91 | static struct gpio_led dreamplug_led_pins[] = { | ||
92 | { | ||
93 | .name = "dreamplug:blue:bluetooth", | ||
94 | .gpio = 47, | ||
95 | .active_low = 1, | ||
96 | }, | ||
97 | { | ||
98 | .name = "dreamplug:green:wifi", | ||
99 | .gpio = 48, | ||
100 | .active_low = 1, | ||
101 | }, | ||
102 | { | ||
103 | .name = "dreamplug:green:wifi_ap", | ||
104 | .gpio = 49, | ||
105 | .active_low = 1, | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | static struct gpio_led_platform_data dreamplug_led_data = { | ||
110 | .leds = dreamplug_led_pins, | ||
111 | .num_leds = ARRAY_SIZE(dreamplug_led_pins), | ||
112 | }; | ||
113 | |||
114 | static struct platform_device dreamplug_leds = { | ||
115 | .name = "leds-gpio", | ||
116 | .id = -1, | ||
117 | .dev = { | ||
118 | .platform_data = &dreamplug_led_data, | ||
119 | } | ||
120 | }; | ||
121 | |||
122 | static unsigned int dreamplug_mpp_config[] __initdata = { | 49 | static unsigned int dreamplug_mpp_config[] __initdata = { |
123 | MPP0_SPI_SCn, | 50 | MPP0_SPI_SCn, |
124 | MPP1_SPI_MOSI, | 51 | MPP1_SPI_MOSI, |
@@ -137,15 +64,8 @@ void __init dreamplug_init(void) | |||
137 | */ | 64 | */ |
138 | kirkwood_mpp_conf(dreamplug_mpp_config); | 65 | kirkwood_mpp_conf(dreamplug_mpp_config); |
139 | 66 | ||
140 | spi_register_board_info(dreamplug_spi_slave_info, | ||
141 | ARRAY_SIZE(dreamplug_spi_slave_info)); | ||
142 | kirkwood_spi_init(); | ||
143 | |||
144 | kirkwood_ehci_init(); | 67 | kirkwood_ehci_init(); |
145 | kirkwood_ge00_init(&dreamplug_ge00_data); | 68 | kirkwood_ge00_init(&dreamplug_ge00_data); |
146 | kirkwood_ge01_init(&dreamplug_ge01_data); | 69 | kirkwood_ge01_init(&dreamplug_ge01_data); |
147 | kirkwood_sata_init(&dreamplug_sata_data); | ||
148 | kirkwood_sdio_init(&dreamplug_mvsdio_data); | 70 | kirkwood_sdio_init(&dreamplug_mvsdio_data); |
149 | |||
150 | platform_device_register(&dreamplug_leds); | ||
151 | } | 71 | } |
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index edc3f8a9d45e..e4eb450de301 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
19 | #include <asm/mach/map.h> | 19 | #include <asm/mach/map.h> |
20 | #include <mach/bridge-regs.h> | 20 | #include <mach/bridge-regs.h> |
21 | #include <plat/irq.h> | ||
21 | #include "common.h" | 22 | #include "common.h" |
22 | 23 | ||
23 | static struct of_device_id kirkwood_dt_match_table[] __initdata = { | 24 | static struct of_device_id kirkwood_dt_match_table[] __initdata = { |
@@ -25,6 +26,16 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = { | |||
25 | { } | 26 | { } |
26 | }; | 27 | }; |
27 | 28 | ||
29 | struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = { | ||
30 | OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL), | ||
31 | OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0", | ||
32 | NULL), | ||
33 | OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL), | ||
34 | OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL), | ||
35 | OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL), | ||
36 | {}, | ||
37 | }; | ||
38 | |||
28 | static void __init kirkwood_dt_init(void) | 39 | static void __init kirkwood_dt_init(void) |
29 | { | 40 | { |
30 | pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); | 41 | pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); |
@@ -47,7 +58,6 @@ static void __init kirkwood_dt_init(void) | |||
47 | kirkwood_clk_init(); | 58 | kirkwood_clk_init(); |
48 | 59 | ||
49 | /* internal devices that every board has */ | 60 | /* internal devices that every board has */ |
50 | kirkwood_wdt_init(); | ||
51 | kirkwood_xor0_init(); | 61 | kirkwood_xor0_init(); |
52 | kirkwood_xor1_init(); | 62 | kirkwood_xor1_init(); |
53 | kirkwood_crypto_init(); | 63 | kirkwood_crypto_init(); |
@@ -68,7 +78,17 @@ static void __init kirkwood_dt_init(void) | |||
68 | if (of_machine_is_compatible("raidsonic,ib-nas62x0")) | 78 | if (of_machine_is_compatible("raidsonic,ib-nas62x0")) |
69 | ib62x0_init(); | 79 | ib62x0_init(); |
70 | 80 | ||
71 | of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL); | 81 | if (of_machine_is_compatible("qnap,ts219")) |
82 | qnap_dt_ts219_init(); | ||
83 | |||
84 | if (of_machine_is_compatible("seagate,goflexnet")) | ||
85 | goflexnet_init(); | ||
86 | |||
87 | if (of_machine_is_compatible("buffalo,lsxl")) | ||
88 | lsxl_init(); | ||
89 | |||
90 | of_platform_populate(NULL, kirkwood_dt_match_table, | ||
91 | kirkwood_auxdata_lookup, NULL); | ||
72 | } | 92 | } |
73 | 93 | ||
74 | static const char *kirkwood_dt_board_compat[] = { | 94 | static const char *kirkwood_dt_board_compat[] = { |
@@ -77,6 +97,9 @@ static const char *kirkwood_dt_board_compat[] = { | |||
77 | "dlink,dns-325", | 97 | "dlink,dns-325", |
78 | "iom,iconnect", | 98 | "iom,iconnect", |
79 | "raidsonic,ib-nas62x0", | 99 | "raidsonic,ib-nas62x0", |
100 | "qnap,ts219", | ||
101 | "seagate,goflexnet", | ||
102 | "buffalo,lsxl", | ||
80 | NULL | 103 | NULL |
81 | }; | 104 | }; |
82 | 105 | ||
@@ -84,7 +107,7 @@ DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") | |||
84 | /* Maintainer: Jason Cooper <jason@lakedaemon.net> */ | 107 | /* Maintainer: Jason Cooper <jason@lakedaemon.net> */ |
85 | .map_io = kirkwood_map_io, | 108 | .map_io = kirkwood_map_io, |
86 | .init_early = kirkwood_init_early, | 109 | .init_early = kirkwood_init_early, |
87 | .init_irq = kirkwood_init_irq, | 110 | .init_irq = orion_dt_init_irq, |
88 | .timer = &kirkwood_timer, | 111 | .timer = &kirkwood_timer, |
89 | .init_machine = kirkwood_dt_init, | 112 | .init_machine = kirkwood_dt_init, |
90 | .restart = kirkwood_restart, | 113 | .restart = kirkwood_restart, |
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c new file mode 100644 index 000000000000..413e2c8ef5fe --- /dev/null +++ b/arch/arm/mach-kirkwood/board-goflexnet.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net> | ||
3 | * | ||
4 | * arch/arm/mach-kirkwood/board-goflexnet.c | ||
5 | * | ||
6 | * Seagate GoFlext Net Board Init for drivers not converted to | ||
7 | * flattened device tree yet. | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | * | ||
13 | * Copied and modified for Seagate GoFlex Net support by | ||
14 | * Joshua Coombs <josh.coombs@gmail.com> based on ArchLinux ARM's | ||
15 | * GoFlex kernel patches. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/ata_platform.h> | ||
23 | #include <linux/mv643xx_eth.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/of_address.h> | ||
26 | #include <linux/of_fdt.h> | ||
27 | #include <linux/of_irq.h> | ||
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/mach/arch.h> | ||
32 | #include <asm/mach/map.h> | ||
33 | #include <mach/kirkwood.h> | ||
34 | #include <mach/bridge-regs.h> | ||
35 | #include <plat/mvsdio.h> | ||
36 | #include "common.h" | ||
37 | #include "mpp.h" | ||
38 | |||
39 | static struct mv643xx_eth_platform_data goflexnet_ge00_data = { | ||
40 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), | ||
41 | }; | ||
42 | |||
43 | static unsigned int goflexnet_mpp_config[] __initdata = { | ||
44 | MPP29_GPIO, /* USB Power Enable */ | ||
45 | MPP47_GPIO, /* LED Orange */ | ||
46 | MPP46_GPIO, /* LED Green */ | ||
47 | MPP45_GPIO, /* LED Left Capacity 3 */ | ||
48 | MPP44_GPIO, /* LED Left Capacity 2 */ | ||
49 | MPP43_GPIO, /* LED Left Capacity 1 */ | ||
50 | MPP42_GPIO, /* LED Left Capacity 0 */ | ||
51 | MPP41_GPIO, /* LED Right Capacity 3 */ | ||
52 | MPP40_GPIO, /* LED Right Capacity 2 */ | ||
53 | MPP39_GPIO, /* LED Right Capacity 1 */ | ||
54 | MPP38_GPIO, /* LED Right Capacity 0 */ | ||
55 | 0 | ||
56 | }; | ||
57 | |||
58 | void __init goflexnet_init(void) | ||
59 | { | ||
60 | /* | ||
61 | * Basic setup. Needs to be called early. | ||
62 | */ | ||
63 | kirkwood_mpp_conf(goflexnet_mpp_config); | ||
64 | |||
65 | if (gpio_request(29, "USB Power Enable") != 0 || | ||
66 | gpio_direction_output(29, 1) != 0) | ||
67 | pr_err("can't setup GPIO 29 (USB Power Enable)\n"); | ||
68 | kirkwood_ehci_init(); | ||
69 | |||
70 | kirkwood_ge00_init(&goflexnet_ge00_data); | ||
71 | } | ||
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c index eddf1df8891f..cfc47f80e734 100644 --- a/arch/arm/mach-kirkwood/board-ib62x0.c +++ b/arch/arm/mach-kirkwood/board-ib62x0.c | |||
@@ -18,9 +18,7 @@ | |||
18 | #include <linux/ata_platform.h> | 18 | #include <linux/ata_platform.h> |
19 | #include <linux/mv643xx_eth.h> | 19 | #include <linux/mv643xx_eth.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/gpio_keys.h> | ||
22 | #include <linux/input.h> | 21 | #include <linux/input.h> |
23 | #include <linux/leds.h> | ||
24 | #include <asm/mach-types.h> | 22 | #include <asm/mach-types.h> |
25 | #include <asm/mach/arch.h> | 23 | #include <asm/mach/arch.h> |
26 | #include <mach/kirkwood.h> | 24 | #include <mach/kirkwood.h> |
@@ -33,10 +31,6 @@ static struct mv643xx_eth_platform_data ib62x0_ge00_data = { | |||
33 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | 31 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), |
34 | }; | 32 | }; |
35 | 33 | ||
36 | static struct mv_sata_platform_data ib62x0_sata_data = { | ||
37 | .n_ports = 2, | ||
38 | }; | ||
39 | |||
40 | static unsigned int ib62x0_mpp_config[] __initdata = { | 34 | static unsigned int ib62x0_mpp_config[] __initdata = { |
41 | MPP0_NF_IO2, | 35 | MPP0_NF_IO2, |
42 | MPP1_NF_IO3, | 36 | MPP1_NF_IO3, |
@@ -55,69 +49,6 @@ static unsigned int ib62x0_mpp_config[] __initdata = { | |||
55 | 0 | 49 | 0 |
56 | }; | 50 | }; |
57 | 51 | ||
58 | static struct gpio_led ib62x0_led_pins[] = { | ||
59 | { | ||
60 | .name = "ib62x0:green:os", | ||
61 | .default_trigger = "default-on", | ||
62 | .gpio = 25, | ||
63 | .active_low = 0, | ||
64 | }, | ||
65 | { | ||
66 | .name = "ib62x0:red:os", | ||
67 | .default_trigger = "none", | ||
68 | .gpio = 22, | ||
69 | .active_low = 0, | ||
70 | }, | ||
71 | { | ||
72 | .name = "ib62x0:red:usb_copy", | ||
73 | .default_trigger = "none", | ||
74 | .gpio = 27, | ||
75 | .active_low = 0, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | static struct gpio_led_platform_data ib62x0_led_data = { | ||
80 | .leds = ib62x0_led_pins, | ||
81 | .num_leds = ARRAY_SIZE(ib62x0_led_pins), | ||
82 | }; | ||
83 | |||
84 | static struct platform_device ib62x0_led_device = { | ||
85 | .name = "leds-gpio", | ||
86 | .id = -1, | ||
87 | .dev = { | ||
88 | .platform_data = &ib62x0_led_data, | ||
89 | } | ||
90 | }; | ||
91 | |||
92 | static struct gpio_keys_button ib62x0_button_pins[] = { | ||
93 | { | ||
94 | .code = KEY_COPY, | ||
95 | .gpio = 29, | ||
96 | .desc = "USB Copy", | ||
97 | .active_low = 1, | ||
98 | }, | ||
99 | { | ||
100 | .code = KEY_RESTART, | ||
101 | .gpio = 28, | ||
102 | .desc = "Reset", | ||
103 | .active_low = 1, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | static struct gpio_keys_platform_data ib62x0_button_data = { | ||
108 | .buttons = ib62x0_button_pins, | ||
109 | .nbuttons = ARRAY_SIZE(ib62x0_button_pins), | ||
110 | }; | ||
111 | |||
112 | static struct platform_device ib62x0_button_device = { | ||
113 | .name = "gpio-keys", | ||
114 | .id = -1, | ||
115 | .num_resources = 0, | ||
116 | .dev = { | ||
117 | .platform_data = &ib62x0_button_data, | ||
118 | } | ||
119 | }; | ||
120 | |||
121 | static void ib62x0_power_off(void) | 52 | static void ib62x0_power_off(void) |
122 | { | 53 | { |
123 | gpio_set_value(IB62X0_GPIO_POWER_OFF, 1); | 54 | gpio_set_value(IB62X0_GPIO_POWER_OFF, 1); |
@@ -132,9 +63,6 @@ void __init ib62x0_init(void) | |||
132 | 63 | ||
133 | kirkwood_ehci_init(); | 64 | kirkwood_ehci_init(); |
134 | kirkwood_ge00_init(&ib62x0_ge00_data); | 65 | kirkwood_ge00_init(&ib62x0_ge00_data); |
135 | kirkwood_sata_init(&ib62x0_sata_data); | ||
136 | platform_device_register(&ib62x0_led_device); | ||
137 | platform_device_register(&ib62x0_button_device); | ||
138 | if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 && | 66 | if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 && |
139 | gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0) | 67 | gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0) |
140 | pm_power_off = ib62x0_power_off; | 68 | pm_power_off = ib62x0_power_off; |
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c index b0d3cc49269d..d7a9198ed300 100644 --- a/arch/arm/mach-kirkwood/board-iconnect.c +++ b/arch/arm/mach-kirkwood/board-iconnect.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | #include <linux/mv643xx_eth.h> | 20 | #include <linux/mv643xx_eth.h> |
21 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
22 | #include <linux/leds.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/input.h> | 22 | #include <linux/input.h> |
25 | #include <linux/gpio_keys.h> | 23 | #include <linux/gpio_keys.h> |
26 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
@@ -32,50 +30,6 @@ static struct mv643xx_eth_platform_data iconnect_ge00_data = { | |||
32 | .phy_addr = MV643XX_ETH_PHY_ADDR(11), | 30 | .phy_addr = MV643XX_ETH_PHY_ADDR(11), |
33 | }; | 31 | }; |
34 | 32 | ||
35 | static struct gpio_led iconnect_led_pins[] = { | ||
36 | { | ||
37 | .name = "led_level", | ||
38 | .gpio = 41, | ||
39 | .default_trigger = "default-on", | ||
40 | }, { | ||
41 | .name = "power:blue", | ||
42 | .gpio = 42, | ||
43 | .default_trigger = "timer", | ||
44 | }, { | ||
45 | .name = "power:red", | ||
46 | .gpio = 43, | ||
47 | }, { | ||
48 | .name = "usb1:blue", | ||
49 | .gpio = 44, | ||
50 | }, { | ||
51 | .name = "usb2:blue", | ||
52 | .gpio = 45, | ||
53 | }, { | ||
54 | .name = "usb3:blue", | ||
55 | .gpio = 46, | ||
56 | }, { | ||
57 | .name = "usb4:blue", | ||
58 | .gpio = 47, | ||
59 | }, { | ||
60 | .name = "otb:blue", | ||
61 | .gpio = 48, | ||
62 | }, | ||
63 | }; | ||
64 | |||
65 | static struct gpio_led_platform_data iconnect_led_data = { | ||
66 | .leds = iconnect_led_pins, | ||
67 | .num_leds = ARRAY_SIZE(iconnect_led_pins), | ||
68 | .gpio_blink_set = orion_gpio_led_blink_set, | ||
69 | }; | ||
70 | |||
71 | static struct platform_device iconnect_leds = { | ||
72 | .name = "leds-gpio", | ||
73 | .id = -1, | ||
74 | .dev = { | ||
75 | .platform_data = &iconnect_led_data, | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | static unsigned int iconnect_mpp_config[] __initdata = { | 33 | static unsigned int iconnect_mpp_config[] __initdata = { |
80 | MPP12_GPIO, | 34 | MPP12_GPIO, |
81 | MPP35_GPIO, | 35 | MPP35_GPIO, |
@@ -90,12 +44,6 @@ static unsigned int iconnect_mpp_config[] __initdata = { | |||
90 | 0 | 44 | 0 |
91 | }; | 45 | }; |
92 | 46 | ||
93 | static struct i2c_board_info __initdata iconnect_board_info[] = { | ||
94 | { | ||
95 | I2C_BOARD_INFO("lm63", 0x4c), | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | static struct mtd_partition iconnect_nand_parts[] = { | 47 | static struct mtd_partition iconnect_nand_parts[] = { |
100 | { | 48 | { |
101 | .name = "flash", | 49 | .name = "flash", |
@@ -142,15 +90,11 @@ void __init iconnect_init(void) | |||
142 | { | 90 | { |
143 | kirkwood_mpp_conf(iconnect_mpp_config); | 91 | kirkwood_mpp_conf(iconnect_mpp_config); |
144 | kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25); | 92 | kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25); |
145 | kirkwood_i2c_init(); | ||
146 | i2c_register_board_info(0, iconnect_board_info, | ||
147 | ARRAY_SIZE(iconnect_board_info)); | ||
148 | 93 | ||
149 | kirkwood_ehci_init(); | 94 | kirkwood_ehci_init(); |
150 | kirkwood_ge00_init(&iconnect_ge00_data); | 95 | kirkwood_ge00_init(&iconnect_ge00_data); |
151 | 96 | ||
152 | platform_device_register(&iconnect_button_device); | 97 | platform_device_register(&iconnect_button_device); |
153 | platform_device_register(&iconnect_leds); | ||
154 | } | 98 | } |
155 | 99 | ||
156 | static int __init iconnect_pci_init(void) | 100 | static int __init iconnect_pci_init(void) |
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c new file mode 100644 index 000000000000..83d8975592f8 --- /dev/null +++ b/arch/arm/mach-kirkwood/board-lsxl.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright 2012 (C), Michael Walle <michael@walle.cc> | ||
3 | * | ||
4 | * arch/arm/mach-kirkwood/board-lsxl.c | ||
5 | * | ||
6 | * Buffalo Linkstation LS-XHL and LS-CHLv2 init for drivers not | ||
7 | * converted to flattened device tree yet. | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/mtd/partitions.h> | ||
18 | #include <linux/ata_platform.h> | ||
19 | #include <linux/spi/flash.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <linux/mv643xx_eth.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/gpio-fan.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <asm/mach-types.h> | ||
26 | #include <asm/mach/arch.h> | ||
27 | #include <mach/kirkwood.h> | ||
28 | #include "common.h" | ||
29 | #include "mpp.h" | ||
30 | |||
31 | static struct mv643xx_eth_platform_data lsxl_ge00_data = { | ||
32 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), | ||
33 | }; | ||
34 | |||
35 | static struct mv643xx_eth_platform_data lsxl_ge01_data = { | ||
36 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
37 | }; | ||
38 | |||
39 | static unsigned int lsxl_mpp_config[] __initdata = { | ||
40 | MPP10_GPO, /* HDD Power Enable */ | ||
41 | MPP11_GPIO, /* USB Vbus Enable */ | ||
42 | MPP18_GPO, /* FAN High Enable# */ | ||
43 | MPP19_GPO, /* FAN Low Enable# */ | ||
44 | MPP36_GPIO, /* Function Blue LED */ | ||
45 | MPP37_GPIO, /* Alarm LED */ | ||
46 | MPP38_GPIO, /* Info LED */ | ||
47 | MPP39_GPIO, /* Power LED */ | ||
48 | MPP40_GPIO, /* Fan Lock */ | ||
49 | MPP41_GPIO, /* Function Button */ | ||
50 | MPP42_GPIO, /* Power Switch */ | ||
51 | MPP43_GPIO, /* Power Auto Switch */ | ||
52 | MPP48_GPIO, /* Function Red LED */ | ||
53 | 0 | ||
54 | }; | ||
55 | |||
56 | #define LSXL_GPIO_FAN_HIGH 18 | ||
57 | #define LSXL_GPIO_FAN_LOW 19 | ||
58 | #define LSXL_GPIO_FAN_LOCK 40 | ||
59 | |||
60 | static struct gpio_fan_alarm lsxl_alarm = { | ||
61 | .gpio = LSXL_GPIO_FAN_LOCK, | ||
62 | }; | ||
63 | |||
64 | static struct gpio_fan_speed lsxl_speeds[] = { | ||
65 | { | ||
66 | .rpm = 0, | ||
67 | .ctrl_val = 3, | ||
68 | }, { | ||
69 | .rpm = 1500, | ||
70 | .ctrl_val = 1, | ||
71 | }, { | ||
72 | .rpm = 3250, | ||
73 | .ctrl_val = 2, | ||
74 | }, { | ||
75 | .rpm = 5000, | ||
76 | .ctrl_val = 0, | ||
77 | } | ||
78 | }; | ||
79 | |||
80 | static int lsxl_gpio_list[] = { | ||
81 | LSXL_GPIO_FAN_HIGH, LSXL_GPIO_FAN_LOW, | ||
82 | }; | ||
83 | |||
84 | static struct gpio_fan_platform_data lsxl_fan_data = { | ||
85 | .num_ctrl = ARRAY_SIZE(lsxl_gpio_list), | ||
86 | .ctrl = lsxl_gpio_list, | ||
87 | .alarm = &lsxl_alarm, | ||
88 | .num_speed = ARRAY_SIZE(lsxl_speeds), | ||
89 | .speed = lsxl_speeds, | ||
90 | }; | ||
91 | |||
92 | static struct platform_device lsxl_fan_device = { | ||
93 | .name = "gpio-fan", | ||
94 | .id = -1, | ||
95 | .num_resources = 0, | ||
96 | .dev = { | ||
97 | .platform_data = &lsxl_fan_data, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | /* | ||
102 | * On the LS-XHL/LS-CHLv2, the shutdown process is following: | ||
103 | * - Userland monitors key events until the power switch goes to off position | ||
104 | * - The board reboots | ||
105 | * - U-boot starts and goes into an idle mode waiting for the user | ||
106 | * to move the switch to ON position | ||
107 | * | ||
108 | */ | ||
109 | static void lsxl_power_off(void) | ||
110 | { | ||
111 | kirkwood_restart('h', NULL); | ||
112 | } | ||
113 | |||
114 | #define LSXL_GPIO_HDD_POWER 10 | ||
115 | #define LSXL_GPIO_USB_POWER 11 | ||
116 | |||
117 | void __init lsxl_init(void) | ||
118 | { | ||
119 | /* | ||
120 | * Basic setup. Needs to be called early. | ||
121 | */ | ||
122 | kirkwood_mpp_conf(lsxl_mpp_config); | ||
123 | |||
124 | /* usb and sata power on */ | ||
125 | gpio_set_value(LSXL_GPIO_USB_POWER, 1); | ||
126 | gpio_set_value(LSXL_GPIO_HDD_POWER, 1); | ||
127 | |||
128 | kirkwood_ehci_init(); | ||
129 | kirkwood_ge00_init(&lsxl_ge00_data); | ||
130 | kirkwood_ge01_init(&lsxl_ge01_data); | ||
131 | platform_device_register(&lsxl_fan_device); | ||
132 | |||
133 | /* register power-off method */ | ||
134 | pm_power_off = lsxl_power_off; | ||
135 | } | ||
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c new file mode 100644 index 000000000000..1750e68506c1 --- /dev/null +++ b/arch/arm/mach-kirkwood/board-ts219.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * | ||
3 | * QNAP TS-11x/TS-21x Turbo NAS Board Setup via DT | ||
4 | * | ||
5 | * Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch> | ||
6 | * | ||
7 | * Based on the board file ts219-setup.c: | ||
8 | * | ||
9 | * Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com> | ||
10 | * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version | ||
15 | * 2 of the License, or (at your option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mv643xx_eth.h> | ||
22 | #include <linux/ata_platform.h> | ||
23 | #include <linux/gpio_keys.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <asm/mach-types.h> | ||
26 | #include <asm/mach/arch.h> | ||
27 | #include <mach/kirkwood.h> | ||
28 | #include "common.h" | ||
29 | #include "mpp.h" | ||
30 | #include "tsx1x-common.h" | ||
31 | |||
32 | static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = { | ||
33 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
34 | }; | ||
35 | |||
36 | static unsigned int qnap_ts219_mpp_config[] __initdata = { | ||
37 | MPP0_SPI_SCn, | ||
38 | MPP1_SPI_MOSI, | ||
39 | MPP2_SPI_SCK, | ||
40 | MPP3_SPI_MISO, | ||
41 | MPP4_SATA1_ACTn, | ||
42 | MPP5_SATA0_ACTn, | ||
43 | MPP8_TW0_SDA, | ||
44 | MPP9_TW0_SCK, | ||
45 | MPP10_UART0_TXD, | ||
46 | MPP11_UART0_RXD, | ||
47 | MPP13_UART1_TXD, /* PIC controller */ | ||
48 | MPP14_UART1_RXD, /* PIC controller */ | ||
49 | MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */ | ||
50 | MPP16_GPIO, /* Reset button (on devices with 88F6281) */ | ||
51 | MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ | ||
52 | MPP37_GPIO, /* Reset button (on devices with 88F6282) */ | ||
53 | MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */ | ||
54 | MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */ | ||
55 | 0 | ||
56 | }; | ||
57 | |||
58 | void __init qnap_dt_ts219_init(void) | ||
59 | { | ||
60 | u32 dev, rev; | ||
61 | |||
62 | kirkwood_mpp_conf(qnap_ts219_mpp_config); | ||
63 | |||
64 | kirkwood_pcie_id(&dev, &rev); | ||
65 | if (dev == MV88F6282_DEV_ID) | ||
66 | qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); | ||
67 | |||
68 | kirkwood_ge00_init(&qnap_ts219_ge00_data); | ||
69 | kirkwood_ehci_init(); | ||
70 | |||
71 | pm_power_off = qnap_tsx1x_power_off; | ||
72 | } | ||
73 | |||
74 | /* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */ | ||
75 | static int __init ts219_pci_init(void) | ||
76 | { | ||
77 | if (machine_is_ts219()) | ||
78 | kirkwood_pcie_init(KW_PCIE0); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | subsys_initcall(ts219_pci_init); | ||
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c9201539ffbd..c4b64adcbfce 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/clk-provider.h> | 18 | #include <linux/clk-provider.h> |
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <linux/mv643xx_i2c.h> | ||
20 | #include <net/dsa.h> | 21 | #include <net/dsa.h> |
21 | #include <asm/page.h> | 22 | #include <asm/page.h> |
22 | #include <asm/timex.h> | 23 | #include <asm/timex.h> |
@@ -276,6 +277,7 @@ void __init kirkwood_clk_init(void) | |||
276 | orion_clkdev_add("0", "pcie", pex0); | 277 | orion_clkdev_add("0", "pcie", pex0); |
277 | orion_clkdev_add("1", "pcie", pex1); | 278 | orion_clkdev_add("1", "pcie", pex1); |
278 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); | 279 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); |
280 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit); | ||
279 | 281 | ||
280 | /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., | 282 | /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., |
281 | * so should never be gated. | 283 | * so should never be gated. |
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 9248fa2c165b..304dd1abfdca 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h | |||
@@ -58,6 +58,11 @@ void dreamplug_init(void); | |||
58 | #else | 58 | #else |
59 | static inline void dreamplug_init(void) {}; | 59 | static inline void dreamplug_init(void) {}; |
60 | #endif | 60 | #endif |
61 | #ifdef CONFIG_MACH_TS219_DT | ||
62 | void qnap_dt_ts219_init(void); | ||
63 | #else | ||
64 | static inline void qnap_dt_ts219_init(void) {}; | ||
65 | #endif | ||
61 | 66 | ||
62 | #ifdef CONFIG_MACH_DLINK_KIRKWOOD_DT | 67 | #ifdef CONFIG_MACH_DLINK_KIRKWOOD_DT |
63 | void dnskw_init(void); | 68 | void dnskw_init(void); |
@@ -77,6 +82,18 @@ void ib62x0_init(void); | |||
77 | static inline void ib62x0_init(void) {}; | 82 | static inline void ib62x0_init(void) {}; |
78 | #endif | 83 | #endif |
79 | 84 | ||
85 | #ifdef CONFIG_MACH_GOFLEXNET_DT | ||
86 | void goflexnet_init(void); | ||
87 | #else | ||
88 | static inline void goflexnet_init(void) {}; | ||
89 | #endif | ||
90 | |||
91 | #ifdef CONFIG_MACH_LSXL_DT | ||
92 | void lsxl_init(void); | ||
93 | #else | ||
94 | static inline void lsxl_init(void) {}; | ||
95 | #endif | ||
96 | |||
80 | /* early init functions not converted to fdt yet */ | 97 | /* early init functions not converted to fdt yet */ |
81 | char *kirkwood_id(void); | 98 | char *kirkwood_id(void); |
82 | void kirkwood_l2_init(void); | 99 | void kirkwood_l2_init(void); |
diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c index c4c68e5b94f1..720063ffa19d 100644 --- a/arch/arm/mach-kirkwood/irq.c +++ b/arch/arm/mach-kirkwood/irq.c | |||
@@ -9,20 +9,23 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/gpio.h> | 10 | #include <linux/gpio.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | ||
13 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
14 | #include <linux/io.h> | ||
15 | #include <mach/bridge-regs.h> | 13 | #include <mach/bridge-regs.h> |
16 | #include <plat/irq.h> | 14 | #include <plat/irq.h> |
17 | #include "common.h" | ||
18 | 15 | ||
19 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 16 | static int __initdata gpio0_irqs[4] = { |
20 | { | 17 | IRQ_KIRKWOOD_GPIO_LOW_0_7, |
21 | BUG_ON(irq < IRQ_KIRKWOOD_GPIO_LOW_0_7); | 18 | IRQ_KIRKWOOD_GPIO_LOW_8_15, |
22 | BUG_ON(irq > IRQ_KIRKWOOD_GPIO_HIGH_16_23); | 19 | IRQ_KIRKWOOD_GPIO_LOW_16_23, |
20 | IRQ_KIRKWOOD_GPIO_LOW_24_31, | ||
21 | }; | ||
23 | 22 | ||
24 | orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3); | 23 | static int __initdata gpio1_irqs[4] = { |
25 | } | 24 | IRQ_KIRKWOOD_GPIO_HIGH_0_7, |
25 | IRQ_KIRKWOOD_GPIO_HIGH_8_15, | ||
26 | IRQ_KIRKWOOD_GPIO_HIGH_16_23, | ||
27 | 0, | ||
28 | }; | ||
26 | 29 | ||
27 | void __init kirkwood_init_irq(void) | 30 | void __init kirkwood_init_irq(void) |
28 | { | 31 | { |
@@ -32,17 +35,8 @@ void __init kirkwood_init_irq(void) | |||
32 | /* | 35 | /* |
33 | * Initialize gpiolib for GPIOs 0-49. | 36 | * Initialize gpiolib for GPIOs 0-49. |
34 | */ | 37 | */ |
35 | orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0, | 38 | orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_LOW_VIRT_BASE, 0, |
36 | IRQ_KIRKWOOD_GPIO_START); | 39 | IRQ_KIRKWOOD_GPIO_START, gpio0_irqs); |
37 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); | 40 | orion_gpio_init(NULL, 32, 18, (void __iomem *)GPIO_HIGH_VIRT_BASE, 0, |
38 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); | 41 | IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs); |
39 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); | ||
40 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); | ||
41 | |||
42 | orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0, | ||
43 | IRQ_KIRKWOOD_GPIO_START + 32); | ||
44 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); | ||
45 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); | ||
46 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, | ||
47 | gpio_irq_handler); | ||
48 | } | 42 | } |
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c index f516e74ce0d5..5c3d61ee729a 100644 --- a/arch/arm/mach-mmp/gplugd.c +++ b/arch/arm/mach-mmp/gplugd.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/mach/arch.h> | 14 | #include <asm/mach/arch.h> |
15 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
16 | 16 | ||
17 | #include <mach/irqs.h> | ||
17 | #include <mach/pxa168.h> | 18 | #include <mach/pxa168.h> |
18 | #include <mach/mfp-pxa168.h> | 19 | #include <mach/mfp-pxa168.h> |
19 | 20 | ||
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c index e421b701663b..eff9a750bbe2 100644 --- a/arch/arm/mach-mv78xx0/irq.c +++ b/arch/arm/mach-mv78xx0/irq.c | |||
@@ -9,19 +9,17 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/gpio.h> | 10 | #include <linux/gpio.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
15 | #include <mach/bridge-regs.h> | 13 | #include <mach/bridge-regs.h> |
16 | #include <plat/irq.h> | 14 | #include <plat/irq.h> |
17 | #include "common.h" | 15 | #include "common.h" |
18 | 16 | ||
19 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 17 | static int __initdata gpio0_irqs[4] = { |
20 | { | 18 | IRQ_MV78XX0_GPIO_0_7, |
21 | BUG_ON(irq < IRQ_MV78XX0_GPIO_0_7 || irq > IRQ_MV78XX0_GPIO_24_31); | 19 | IRQ_MV78XX0_GPIO_8_15, |
22 | 20 | IRQ_MV78XX0_GPIO_16_23, | |
23 | orion_gpio_irq_handler((irq - IRQ_MV78XX0_GPIO_0_7) << 3); | 21 | IRQ_MV78XX0_GPIO_24_31, |
24 | } | 22 | }; |
25 | 23 | ||
26 | void __init mv78xx0_init_irq(void) | 24 | void __init mv78xx0_init_irq(void) |
27 | { | 25 | { |
@@ -34,11 +32,7 @@ void __init mv78xx0_init_irq(void) | |||
34 | * registers for core #1 are at an offset of 0x18 from those of | 32 | * registers for core #1 are at an offset of 0x18 from those of |
35 | * core #0.) | 33 | * core #0.) |
36 | */ | 34 | */ |
37 | orion_gpio_init(0, 32, GPIO_VIRT_BASE, | 35 | orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, |
38 | mv78xx0_core_index() ? 0x18 : 0, | 36 | mv78xx0_core_index() ? 0x18 : 0, |
39 | IRQ_MV78XX0_GPIO_START); | 37 | IRQ_MV78XX0_GPIO_START, gpio0_irqs); |
40 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler); | ||
41 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler); | ||
42 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler); | ||
43 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler); | ||
44 | } | 38 | } |
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c index da0e37d40823..e1362ce48497 100644 --- a/arch/arm/mach-omap1/board-h2-mmc.c +++ b/arch/arm/mach-omap1/board-h2-mmc.c | |||
@@ -54,7 +54,6 @@ static struct omap_mmc_platform_data mmc1_data = { | |||
54 | .nr_slots = 1, | 54 | .nr_slots = 1, |
55 | .init = mmc_late_init, | 55 | .init = mmc_late_init, |
56 | .cleanup = mmc_cleanup, | 56 | .cleanup = mmc_cleanup, |
57 | .dma_mask = 0xffffffff, | ||
58 | .slots[0] = { | 57 | .slots[0] = { |
59 | .set_power = mmc_set_power, | 58 | .set_power = mmc_set_power, |
60 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 59 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c index f8242aa9b763..c74daace8cd6 100644 --- a/arch/arm/mach-omap1/board-h3-mmc.c +++ b/arch/arm/mach-omap1/board-h3-mmc.c | |||
@@ -36,7 +36,6 @@ static int mmc_set_power(struct device *dev, int slot, int power_on, | |||
36 | */ | 36 | */ |
37 | static struct omap_mmc_platform_data mmc1_data = { | 37 | static struct omap_mmc_platform_data mmc1_data = { |
38 | .nr_slots = 1, | 38 | .nr_slots = 1, |
39 | .dma_mask = 0xffffffff, | ||
40 | .slots[0] = { | 39 | .slots[0] = { |
41 | .set_power = mmc_set_power, | 40 | .set_power = mmc_set_power, |
42 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 41 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 4007a372481b..2c0ca8fc3380 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c | |||
@@ -185,7 +185,6 @@ static int nokia770_mmc_get_cover_state(struct device *dev, int slot) | |||
185 | 185 | ||
186 | static struct omap_mmc_platform_data nokia770_mmc2_data = { | 186 | static struct omap_mmc_platform_data nokia770_mmc2_data = { |
187 | .nr_slots = 1, | 187 | .nr_slots = 1, |
188 | .dma_mask = 0xffffffff, | ||
189 | .max_freq = 12000000, | 188 | .max_freq = 12000000, |
190 | .slots[0] = { | 189 | .slots[0] = { |
191 | .set_power = nokia770_mmc_set_power, | 190 | .set_power = nokia770_mmc_set_power, |
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index cc71a26723ef..355980321c2d 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c | |||
@@ -288,8 +288,7 @@ palmz71_gpio_setup(int early) | |||
288 | } | 288 | } |
289 | gpio_direction_input(PALMZ71_USBDETECT_GPIO); | 289 | gpio_direction_input(PALMZ71_USBDETECT_GPIO); |
290 | if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), | 290 | if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), |
291 | palmz71_powercable, IRQF_SAMPLE_RANDOM, | 291 | palmz71_powercable, 0, "palmz71-cable", NULL)) |
292 | "palmz71-cable", NULL)) | ||
293 | printk(KERN_ERR | 292 | printk(KERN_ERR |
294 | "IRQ request for power cable failed!\n"); | 293 | "IRQ request for power cable failed!\n"); |
295 | palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL); | 294 | palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL); |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index dd0fbf76ac79..dd2db025f778 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -62,6 +62,7 @@ config ARCH_OMAP4 | |||
62 | select PM_OPP if PM | 62 | select PM_OPP if PM |
63 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | 63 | select USB_ARCH_HAS_EHCI if USB_SUPPORT |
64 | select ARM_CPU_SUSPEND if PM | 64 | select ARM_CPU_SUSPEND if PM |
65 | select ARCH_NEEDS_CPU_IDLE_COUPLED | ||
65 | 66 | ||
66 | config SOC_OMAP5 | 67 | config SOC_OMAP5 |
67 | bool "TI OMAP5" | 68 | bool "TI OMAP5" |
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 2c5d0ed75285..677357ff61ac 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c | |||
@@ -468,7 +468,6 @@ static struct omap_mmc_platform_data mmc1_data = { | |||
468 | .cleanup = n8x0_mmc_cleanup, | 468 | .cleanup = n8x0_mmc_cleanup, |
469 | .shutdown = n8x0_mmc_shutdown, | 469 | .shutdown = n8x0_mmc_shutdown, |
470 | .max_freq = 24000000, | 470 | .max_freq = 24000000, |
471 | .dma_mask = 0xffffffff, | ||
472 | .slots[0] = { | 471 | .slots[0] = { |
473 | .wires = 4, | 472 | .wires = 4, |
474 | .set_power = n8x0_mmc_set_power, | 473 | .set_power = n8x0_mmc_set_power, |
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 02d15bbd4e35..ee05e193fc61 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "common.h" | 21 | #include "common.h" |
22 | #include "pm.h" | 22 | #include "pm.h" |
23 | #include "prm.h" | 23 | #include "prm.h" |
24 | #include "clockdomain.h" | ||
24 | 25 | ||
25 | /* Machine specific information */ | 26 | /* Machine specific information */ |
26 | struct omap4_idle_statedata { | 27 | struct omap4_idle_statedata { |
@@ -47,10 +48,14 @@ static struct omap4_idle_statedata omap4_idle_data[] = { | |||
47 | }, | 48 | }, |
48 | }; | 49 | }; |
49 | 50 | ||
50 | static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; | 51 | static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS]; |
52 | static struct clockdomain *cpu_clkdm[NR_CPUS]; | ||
53 | |||
54 | static atomic_t abort_barrier; | ||
55 | static bool cpu_done[NR_CPUS]; | ||
51 | 56 | ||
52 | /** | 57 | /** |
53 | * omap4_enter_idle - Programs OMAP4 to enter the specified state | 58 | * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions |
54 | * @dev: cpuidle device | 59 | * @dev: cpuidle device |
55 | * @drv: cpuidle driver | 60 | * @drv: cpuidle driver |
56 | * @index: the index of state to be entered | 61 | * @index: the index of state to be entered |
@@ -59,60 +64,84 @@ static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; | |||
59 | * specified low power state selected by the governor. | 64 | * specified low power state selected by the governor. |
60 | * Returns the amount of time spent in the low power state. | 65 | * Returns the amount of time spent in the low power state. |
61 | */ | 66 | */ |
62 | static int omap4_enter_idle(struct cpuidle_device *dev, | 67 | static int omap4_enter_idle_simple(struct cpuidle_device *dev, |
68 | struct cpuidle_driver *drv, | ||
69 | int index) | ||
70 | { | ||
71 | local_fiq_disable(); | ||
72 | omap_do_wfi(); | ||
73 | local_fiq_enable(); | ||
74 | |||
75 | return index; | ||
76 | } | ||
77 | |||
78 | static int omap4_enter_idle_coupled(struct cpuidle_device *dev, | ||
63 | struct cpuidle_driver *drv, | 79 | struct cpuidle_driver *drv, |
64 | int index) | 80 | int index) |
65 | { | 81 | { |
66 | struct omap4_idle_statedata *cx = &omap4_idle_data[index]; | 82 | struct omap4_idle_statedata *cx = &omap4_idle_data[index]; |
67 | u32 cpu1_state; | ||
68 | int cpu_id = smp_processor_id(); | 83 | int cpu_id = smp_processor_id(); |
69 | 84 | ||
70 | local_fiq_disable(); | 85 | local_fiq_disable(); |
71 | 86 | ||
72 | /* | 87 | /* |
73 | * CPU0 has to stay ON (i.e in C1) until CPU1 is OFF state. | 88 | * CPU0 has to wait and stay ON until CPU1 is OFF state. |
74 | * This is necessary to honour hardware recommondation | 89 | * This is necessary to honour hardware recommondation |
75 | * of triggeing all the possible low power modes once CPU1 is | 90 | * of triggeing all the possible low power modes once CPU1 is |
76 | * out of coherency and in OFF mode. | 91 | * out of coherency and in OFF mode. |
77 | * Update dev->last_state so that governor stats reflects right | ||
78 | * data. | ||
79 | */ | 92 | */ |
80 | cpu1_state = pwrdm_read_pwrst(cpu1_pd); | 93 | if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { |
81 | if (cpu1_state != PWRDM_POWER_OFF) { | 94 | while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) { |
82 | index = drv->safe_state_index; | 95 | cpu_relax(); |
83 | cx = &omap4_idle_data[index]; | 96 | |
97 | /* | ||
98 | * CPU1 could have already entered & exited idle | ||
99 | * without hitting off because of a wakeup | ||
100 | * or a failed attempt to hit off mode. Check for | ||
101 | * that here, otherwise we could spin forever | ||
102 | * waiting for CPU1 off. | ||
103 | */ | ||
104 | if (cpu_done[1]) | ||
105 | goto fail; | ||
106 | |||
107 | } | ||
84 | } | 108 | } |
85 | 109 | ||
86 | if (index > 0) | 110 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); |
87 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); | ||
88 | 111 | ||
89 | /* | 112 | /* |
90 | * Call idle CPU PM enter notifier chain so that | 113 | * Call idle CPU PM enter notifier chain so that |
91 | * VFP and per CPU interrupt context is saved. | 114 | * VFP and per CPU interrupt context is saved. |
92 | */ | 115 | */ |
93 | if (cx->cpu_state == PWRDM_POWER_OFF) | 116 | cpu_pm_enter(); |
94 | cpu_pm_enter(); | 117 | |
95 | 118 | if (dev->cpu == 0) { | |
96 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); | 119 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); |
97 | omap_set_pwrdm_state(mpu_pd, cx->mpu_state); | 120 | omap_set_pwrdm_state(mpu_pd, cx->mpu_state); |
98 | 121 | ||
99 | /* | 122 | /* |
100 | * Call idle CPU cluster PM enter notifier chain | 123 | * Call idle CPU cluster PM enter notifier chain |
101 | * to save GIC and wakeupgen context. | 124 | * to save GIC and wakeupgen context. |
102 | */ | 125 | */ |
103 | if ((cx->mpu_state == PWRDM_POWER_RET) && | 126 | if ((cx->mpu_state == PWRDM_POWER_RET) && |
104 | (cx->mpu_logic_state == PWRDM_POWER_OFF)) | 127 | (cx->mpu_logic_state == PWRDM_POWER_OFF)) |
105 | cpu_cluster_pm_enter(); | 128 | cpu_cluster_pm_enter(); |
129 | } | ||
106 | 130 | ||
107 | omap4_enter_lowpower(dev->cpu, cx->cpu_state); | 131 | omap4_enter_lowpower(dev->cpu, cx->cpu_state); |
132 | cpu_done[dev->cpu] = true; | ||
133 | |||
134 | /* Wakeup CPU1 only if it is not offlined */ | ||
135 | if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { | ||
136 | clkdm_wakeup(cpu_clkdm[1]); | ||
137 | clkdm_allow_idle(cpu_clkdm[1]); | ||
138 | } | ||
108 | 139 | ||
109 | /* | 140 | /* |
110 | * Call idle CPU PM exit notifier chain to restore | 141 | * Call idle CPU PM exit notifier chain to restore |
111 | * VFP and per CPU IRQ context. Only CPU0 state is | 142 | * VFP and per CPU IRQ context. |
112 | * considered since CPU1 is managed by CPU hotplug. | ||
113 | */ | 143 | */ |
114 | if (pwrdm_read_prev_pwrst(cpu0_pd) == PWRDM_POWER_OFF) | 144 | cpu_pm_exit(); |
115 | cpu_pm_exit(); | ||
116 | 145 | ||
117 | /* | 146 | /* |
118 | * Call idle CPU cluster PM exit notifier chain | 147 | * Call idle CPU cluster PM exit notifier chain |
@@ -121,8 +150,11 @@ static int omap4_enter_idle(struct cpuidle_device *dev, | |||
121 | if (omap4_mpuss_read_prev_context_state()) | 150 | if (omap4_mpuss_read_prev_context_state()) |
122 | cpu_cluster_pm_exit(); | 151 | cpu_cluster_pm_exit(); |
123 | 152 | ||
124 | if (index > 0) | 153 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); |
125 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); | 154 | |
155 | fail: | ||
156 | cpuidle_coupled_parallel_barrier(dev, &abort_barrier); | ||
157 | cpu_done[dev->cpu] = false; | ||
126 | 158 | ||
127 | local_fiq_enable(); | 159 | local_fiq_enable(); |
128 | 160 | ||
@@ -141,7 +173,7 @@ struct cpuidle_driver omap4_idle_driver = { | |||
141 | .exit_latency = 2 + 2, | 173 | .exit_latency = 2 + 2, |
142 | .target_residency = 5, | 174 | .target_residency = 5, |
143 | .flags = CPUIDLE_FLAG_TIME_VALID, | 175 | .flags = CPUIDLE_FLAG_TIME_VALID, |
144 | .enter = omap4_enter_idle, | 176 | .enter = omap4_enter_idle_simple, |
145 | .name = "C1", | 177 | .name = "C1", |
146 | .desc = "MPUSS ON" | 178 | .desc = "MPUSS ON" |
147 | }, | 179 | }, |
@@ -149,8 +181,8 @@ struct cpuidle_driver omap4_idle_driver = { | |||
149 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ | 181 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ |
150 | .exit_latency = 328 + 440, | 182 | .exit_latency = 328 + 440, |
151 | .target_residency = 960, | 183 | .target_residency = 960, |
152 | .flags = CPUIDLE_FLAG_TIME_VALID, | 184 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, |
153 | .enter = omap4_enter_idle, | 185 | .enter = omap4_enter_idle_coupled, |
154 | .name = "C2", | 186 | .name = "C2", |
155 | .desc = "MPUSS CSWR", | 187 | .desc = "MPUSS CSWR", |
156 | }, | 188 | }, |
@@ -158,8 +190,8 @@ struct cpuidle_driver omap4_idle_driver = { | |||
158 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | 190 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ |
159 | .exit_latency = 460 + 518, | 191 | .exit_latency = 460 + 518, |
160 | .target_residency = 1100, | 192 | .target_residency = 1100, |
161 | .flags = CPUIDLE_FLAG_TIME_VALID, | 193 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, |
162 | .enter = omap4_enter_idle, | 194 | .enter = omap4_enter_idle_coupled, |
163 | .name = "C3", | 195 | .name = "C3", |
164 | .desc = "MPUSS OSWR", | 196 | .desc = "MPUSS OSWR", |
165 | }, | 197 | }, |
@@ -168,6 +200,16 @@ struct cpuidle_driver omap4_idle_driver = { | |||
168 | .safe_state_index = 0, | 200 | .safe_state_index = 0, |
169 | }; | 201 | }; |
170 | 202 | ||
203 | /* | ||
204 | * For each cpu, setup the broadcast timer because local timers | ||
205 | * stops for the states above C1. | ||
206 | */ | ||
207 | static void omap_setup_broadcast_timer(void *arg) | ||
208 | { | ||
209 | int cpu = smp_processor_id(); | ||
210 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); | ||
211 | } | ||
212 | |||
171 | /** | 213 | /** |
172 | * omap4_idle_init - Init routine for OMAP4 idle | 214 | * omap4_idle_init - Init routine for OMAP4 idle |
173 | * | 215 | * |
@@ -180,19 +222,30 @@ int __init omap4_idle_init(void) | |||
180 | unsigned int cpu_id = 0; | 222 | unsigned int cpu_id = 0; |
181 | 223 | ||
182 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); | 224 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); |
183 | cpu0_pd = pwrdm_lookup("cpu0_pwrdm"); | 225 | cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); |
184 | cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); | 226 | cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); |
185 | if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) | 227 | if ((!mpu_pd) || (!cpu_pd[0]) || (!cpu_pd[1])) |
186 | return -ENODEV; | 228 | return -ENODEV; |
187 | 229 | ||
188 | dev = &per_cpu(omap4_idle_dev, cpu_id); | 230 | cpu_clkdm[0] = clkdm_lookup("mpu0_clkdm"); |
189 | dev->cpu = cpu_id; | 231 | cpu_clkdm[1] = clkdm_lookup("mpu1_clkdm"); |
232 | if (!cpu_clkdm[0] || !cpu_clkdm[1]) | ||
233 | return -ENODEV; | ||
234 | |||
235 | /* Configure the broadcast timer on each cpu */ | ||
236 | on_each_cpu(omap_setup_broadcast_timer, NULL, 1); | ||
237 | |||
238 | for_each_cpu(cpu_id, cpu_online_mask) { | ||
239 | dev = &per_cpu(omap4_idle_dev, cpu_id); | ||
240 | dev->cpu = cpu_id; | ||
241 | dev->coupled_cpus = *cpu_online_mask; | ||
190 | 242 | ||
191 | cpuidle_register_driver(&omap4_idle_driver); | 243 | cpuidle_register_driver(&omap4_idle_driver); |
192 | 244 | ||
193 | if (cpuidle_register_device(dev)) { | 245 | if (cpuidle_register_device(dev)) { |
194 | pr_err("%s: CPUidle register device failed\n", __func__); | 246 | pr_err("%s: CPUidle register failed\n", __func__); |
195 | return -EIO; | 247 | return -EIO; |
248 | } | ||
196 | } | 249 | } |
197 | 250 | ||
198 | return 0; | 251 | return 0; |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 5fb47a14f4ba..af1ed7d24a1f 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #define DISPC_CONTROL 0x0040 | 38 | #define DISPC_CONTROL 0x0040 |
39 | #define DISPC_CONTROL2 0x0238 | 39 | #define DISPC_CONTROL2 0x0238 |
40 | #define DISPC_CONTROL3 0x0848 | ||
40 | #define DISPC_IRQSTATUS 0x0018 | 41 | #define DISPC_IRQSTATUS 0x0018 |
41 | 42 | ||
42 | #define DSS_SYSCONFIG 0x10 | 43 | #define DSS_SYSCONFIG 0x10 |
@@ -52,6 +53,7 @@ | |||
52 | #define EVSYNC_EVEN_IRQ_SHIFT 2 | 53 | #define EVSYNC_EVEN_IRQ_SHIFT 2 |
53 | #define EVSYNC_ODD_IRQ_SHIFT 3 | 54 | #define EVSYNC_ODD_IRQ_SHIFT 3 |
54 | #define FRAMEDONE2_IRQ_SHIFT 22 | 55 | #define FRAMEDONE2_IRQ_SHIFT 22 |
56 | #define FRAMEDONE3_IRQ_SHIFT 30 | ||
55 | #define FRAMEDONETV_IRQ_SHIFT 24 | 57 | #define FRAMEDONETV_IRQ_SHIFT 24 |
56 | 58 | ||
57 | /* | 59 | /* |
@@ -376,7 +378,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) | |||
376 | static void dispc_disable_outputs(void) | 378 | static void dispc_disable_outputs(void) |
377 | { | 379 | { |
378 | u32 v, irq_mask = 0; | 380 | u32 v, irq_mask = 0; |
379 | bool lcd_en, digit_en, lcd2_en = false; | 381 | bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false; |
380 | int i; | 382 | int i; |
381 | struct omap_dss_dispc_dev_attr *da; | 383 | struct omap_dss_dispc_dev_attr *da; |
382 | struct omap_hwmod *oh; | 384 | struct omap_hwmod *oh; |
@@ -405,7 +407,13 @@ static void dispc_disable_outputs(void) | |||
405 | lcd2_en = v & LCD_EN_MASK; | 407 | lcd2_en = v & LCD_EN_MASK; |
406 | } | 408 | } |
407 | 409 | ||
408 | if (!(lcd_en | digit_en | lcd2_en)) | 410 | /* store value of LCDENABLE for LCD3 */ |
411 | if (da->manager_count > 3) { | ||
412 | v = omap_hwmod_read(oh, DISPC_CONTROL3); | ||
413 | lcd3_en = v & LCD_EN_MASK; | ||
414 | } | ||
415 | |||
416 | if (!(lcd_en | digit_en | lcd2_en | lcd3_en)) | ||
409 | return; /* no managers currently enabled */ | 417 | return; /* no managers currently enabled */ |
410 | 418 | ||
411 | /* | 419 | /* |
@@ -426,10 +434,12 @@ static void dispc_disable_outputs(void) | |||
426 | 434 | ||
427 | if (lcd2_en) | 435 | if (lcd2_en) |
428 | irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT; | 436 | irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT; |
437 | if (lcd3_en) | ||
438 | irq_mask |= 1 << FRAMEDONE3_IRQ_SHIFT; | ||
429 | 439 | ||
430 | /* | 440 | /* |
431 | * clear any previous FRAMEDONE, FRAMEDONETV, | 441 | * clear any previous FRAMEDONE, FRAMEDONETV, |
432 | * EVSYNC_EVEN/ODD or FRAMEDONE2 interrupts | 442 | * EVSYNC_EVEN/ODD, FRAMEDONE2 or FRAMEDONE3 interrupts |
433 | */ | 443 | */ |
434 | omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); | 444 | omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); |
435 | 445 | ||
@@ -445,12 +455,19 @@ static void dispc_disable_outputs(void) | |||
445 | omap_hwmod_write(v, oh, DISPC_CONTROL2); | 455 | omap_hwmod_write(v, oh, DISPC_CONTROL2); |
446 | } | 456 | } |
447 | 457 | ||
458 | /* disable LCD3 manager */ | ||
459 | if (da->manager_count > 3) { | ||
460 | v = omap_hwmod_read(oh, DISPC_CONTROL3); | ||
461 | v &= ~LCD_EN_MASK; | ||
462 | omap_hwmod_write(v, oh, DISPC_CONTROL3); | ||
463 | } | ||
464 | |||
448 | i = 0; | 465 | i = 0; |
449 | while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) != | 466 | while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) != |
450 | irq_mask) { | 467 | irq_mask) { |
451 | i++; | 468 | i++; |
452 | if (i > FRAMEDONE_IRQ_TIMEOUT) { | 469 | if (i > FRAMEDONE_IRQ_TIMEOUT) { |
453 | pr_err("didn't get FRAMEDONE1/2 or TV interrupt\n"); | 470 | pr_err("didn't get FRAMEDONE1/2/3 or TV interrupt\n"); |
454 | break; | 471 | break; |
455 | } | 472 | } |
456 | mdelay(1); | 473 | mdelay(1); |
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index be697d4e0843..a9675d8d1822 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c | |||
@@ -315,7 +315,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, | |||
315 | mmc->slots[0].caps = c->caps; | 315 | mmc->slots[0].caps = c->caps; |
316 | mmc->slots[0].pm_caps = c->pm_caps; | 316 | mmc->slots[0].pm_caps = c->pm_caps; |
317 | mmc->slots[0].internal_clock = !c->ext_clock; | 317 | mmc->slots[0].internal_clock = !c->ext_clock; |
318 | mmc->dma_mask = 0xffffffff; | ||
319 | mmc->max_freq = c->max_freq; | 318 | mmc->max_freq = c->max_freq; |
320 | if (cpu_is_omap44xx()) | 319 | if (cpu_is_omap44xx()) |
321 | mmc->reg_offset = OMAP4_MMC_REG_OFFSET; | 320 | mmc->reg_offset = OMAP4_MMC_REG_OFFSET; |
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 13d20c8a283d..2ff6d41ec6c6 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -130,6 +130,7 @@ static struct clock_event_device clockevent_gpt = { | |||
130 | .name = "gp_timer", | 130 | .name = "gp_timer", |
131 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 131 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
132 | .shift = 32, | 132 | .shift = 32, |
133 | .rating = 300, | ||
133 | .set_next_event = omap2_gp_timer_set_next_event, | 134 | .set_next_event = omap2_gp_timer_set_next_event, |
134 | .set_mode = omap2_gp_timer_set_mode, | 135 | .set_mode = omap2_gp_timer_set_mode, |
135 | }; | 136 | }; |
@@ -223,7 +224,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
223 | clockevent_delta2ns(3, &clockevent_gpt); | 224 | clockevent_delta2ns(3, &clockevent_gpt); |
224 | /* Timer internal resynch latency. */ | 225 | /* Timer internal resynch latency. */ |
225 | 226 | ||
226 | clockevent_gpt.cpumask = cpumask_of(0); | 227 | clockevent_gpt.cpumask = cpu_possible_mask; |
228 | clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); | ||
227 | clockevents_register_device(&clockevent_gpt); | 229 | clockevents_register_device(&clockevent_gpt); |
228 | 230 | ||
229 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", | 231 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", |
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c index b1b45fff776e..17da7091d310 100644 --- a/arch/arm/mach-orion5x/irq.c +++ b/arch/arm/mach-orion5x/irq.c | |||
@@ -11,19 +11,16 @@ | |||
11 | */ | 11 | */ |
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | ||
15 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
16 | #include <linux/io.h> | ||
17 | #include <mach/bridge-regs.h> | 15 | #include <mach/bridge-regs.h> |
18 | #include <plat/irq.h> | 16 | #include <plat/irq.h> |
19 | #include "common.h" | ||
20 | 17 | ||
21 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 18 | static int __initdata gpio0_irqs[4] = { |
22 | { | 19 | IRQ_ORION5X_GPIO_0_7, |
23 | BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); | 20 | IRQ_ORION5X_GPIO_8_15, |
24 | 21 | IRQ_ORION5X_GPIO_16_23, | |
25 | orion_gpio_irq_handler((irq - IRQ_ORION5X_GPIO_0_7) << 3); | 22 | IRQ_ORION5X_GPIO_24_31, |
26 | } | 23 | }; |
27 | 24 | ||
28 | void __init orion5x_init_irq(void) | 25 | void __init orion5x_init_irq(void) |
29 | { | 26 | { |
@@ -32,9 +29,6 @@ void __init orion5x_init_irq(void) | |||
32 | /* | 29 | /* |
33 | * Initialize gpiolib for GPIOs 0-31. | 30 | * Initialize gpiolib for GPIOs 0-31. |
34 | */ | 31 | */ |
35 | orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START); | 32 | orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, 0, |
36 | irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler); | 33 | IRQ_ORION5X_GPIO_START, gpio0_irqs); |
37 | irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler); | ||
38 | irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler); | ||
39 | irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler); | ||
40 | } | 34 | } |
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c index 0d024b1e916d..f224107de7bc 100644 --- a/arch/arm/mach-prima2/timer.c +++ b/arch/arm/mach-prima2/timer.c | |||
@@ -132,11 +132,11 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) | |||
132 | { | 132 | { |
133 | int i; | 133 | int i; |
134 | 134 | ||
135 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) | 135 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) |
136 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | 136 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); |
137 | 137 | ||
138 | writel_relaxed(sirfsoc_timer_reg_val[i - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); | 138 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); |
139 | writel_relaxed(sirfsoc_timer_reg_val[i - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 139 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); |
140 | } | 140 | } |
141 | 141 | ||
142 | static struct clock_event_device sirfsoc_clockevent = { | 142 | static struct clock_event_device sirfsoc_clockevent = { |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6bb3f47b1f14..0ca0db787903 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
@@ -456,7 +456,7 @@ static int lubbock_mci_init(struct device *dev, | |||
456 | init_timer(&mmc_timer); | 456 | init_timer(&mmc_timer); |
457 | mmc_timer.data = (unsigned long) data; | 457 | mmc_timer.data = (unsigned long) data; |
458 | return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, | 458 | return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, |
459 | IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data); | 459 | 0, "lubbock-sd-detect", data); |
460 | } | 460 | } |
461 | 461 | ||
462 | static int lubbock_mci_get_ro(struct device *dev) | 462 | static int lubbock_mci_get_ro(struct device *dev) |
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 2db697cd2b4e..39561dcf65f2 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c | |||
@@ -633,9 +633,8 @@ static struct platform_device bq24022 = { | |||
633 | static int magician_mci_init(struct device *dev, | 633 | static int magician_mci_init(struct device *dev, |
634 | irq_handler_t detect_irq, void *data) | 634 | irq_handler_t detect_irq, void *data) |
635 | { | 635 | { |
636 | return request_irq(IRQ_MAGICIAN_SD, detect_irq, | 636 | return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED, |
637 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 637 | "mmc card detect", data); |
638 | "mmc card detect", data); | ||
639 | } | 638 | } |
640 | 639 | ||
641 | static void magician_mci_exit(struct device *dev, void *data) | 640 | static void magician_mci_exit(struct device *dev, void *data) |
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 2b6ac00b2cd9..166dd32cc1d3 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c | |||
@@ -332,8 +332,8 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, | |||
332 | int err; | 332 | int err; |
333 | 333 | ||
334 | err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, | 334 | err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, |
335 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM, | 335 | IRQF_DISABLED | IRQF_TRIGGER_RISING, |
336 | "MMC card detect", data); | 336 | "MMC card detect", data); |
337 | if (err) { | 337 | if (err) { |
338 | printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" | 338 | printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" |
339 | "MMC card detect IRQ\n"); | 339 | "MMC card detect IRQ\n"); |
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 0f882ecb7d81..6ec300549960 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c | |||
@@ -120,182 +120,156 @@ struct pl08x_channel_data spear300_dma_info[] = { | |||
120 | .min_signal = 2, | 120 | .min_signal = 2, |
121 | .max_signal = 2, | 121 | .max_signal = 2, |
122 | .muxval = 0, | 122 | .muxval = 0, |
123 | .cctl = 0, | ||
124 | .periph_buses = PL08X_AHB1, | 123 | .periph_buses = PL08X_AHB1, |
125 | }, { | 124 | }, { |
126 | .bus_id = "uart0_tx", | 125 | .bus_id = "uart0_tx", |
127 | .min_signal = 3, | 126 | .min_signal = 3, |
128 | .max_signal = 3, | 127 | .max_signal = 3, |
129 | .muxval = 0, | 128 | .muxval = 0, |
130 | .cctl = 0, | ||
131 | .periph_buses = PL08X_AHB1, | 129 | .periph_buses = PL08X_AHB1, |
132 | }, { | 130 | }, { |
133 | .bus_id = "ssp0_rx", | 131 | .bus_id = "ssp0_rx", |
134 | .min_signal = 8, | 132 | .min_signal = 8, |
135 | .max_signal = 8, | 133 | .max_signal = 8, |
136 | .muxval = 0, | 134 | .muxval = 0, |
137 | .cctl = 0, | ||
138 | .periph_buses = PL08X_AHB1, | 135 | .periph_buses = PL08X_AHB1, |
139 | }, { | 136 | }, { |
140 | .bus_id = "ssp0_tx", | 137 | .bus_id = "ssp0_tx", |
141 | .min_signal = 9, | 138 | .min_signal = 9, |
142 | .max_signal = 9, | 139 | .max_signal = 9, |
143 | .muxval = 0, | 140 | .muxval = 0, |
144 | .cctl = 0, | ||
145 | .periph_buses = PL08X_AHB1, | 141 | .periph_buses = PL08X_AHB1, |
146 | }, { | 142 | }, { |
147 | .bus_id = "i2c_rx", | 143 | .bus_id = "i2c_rx", |
148 | .min_signal = 10, | 144 | .min_signal = 10, |
149 | .max_signal = 10, | 145 | .max_signal = 10, |
150 | .muxval = 0, | 146 | .muxval = 0, |
151 | .cctl = 0, | ||
152 | .periph_buses = PL08X_AHB1, | 147 | .periph_buses = PL08X_AHB1, |
153 | }, { | 148 | }, { |
154 | .bus_id = "i2c_tx", | 149 | .bus_id = "i2c_tx", |
155 | .min_signal = 11, | 150 | .min_signal = 11, |
156 | .max_signal = 11, | 151 | .max_signal = 11, |
157 | .muxval = 0, | 152 | .muxval = 0, |
158 | .cctl = 0, | ||
159 | .periph_buses = PL08X_AHB1, | 153 | .periph_buses = PL08X_AHB1, |
160 | }, { | 154 | }, { |
161 | .bus_id = "irda", | 155 | .bus_id = "irda", |
162 | .min_signal = 12, | 156 | .min_signal = 12, |
163 | .max_signal = 12, | 157 | .max_signal = 12, |
164 | .muxval = 0, | 158 | .muxval = 0, |
165 | .cctl = 0, | ||
166 | .periph_buses = PL08X_AHB1, | 159 | .periph_buses = PL08X_AHB1, |
167 | }, { | 160 | }, { |
168 | .bus_id = "adc", | 161 | .bus_id = "adc", |
169 | .min_signal = 13, | 162 | .min_signal = 13, |
170 | .max_signal = 13, | 163 | .max_signal = 13, |
171 | .muxval = 0, | 164 | .muxval = 0, |
172 | .cctl = 0, | ||
173 | .periph_buses = PL08X_AHB1, | 165 | .periph_buses = PL08X_AHB1, |
174 | }, { | 166 | }, { |
175 | .bus_id = "to_jpeg", | 167 | .bus_id = "to_jpeg", |
176 | .min_signal = 14, | 168 | .min_signal = 14, |
177 | .max_signal = 14, | 169 | .max_signal = 14, |
178 | .muxval = 0, | 170 | .muxval = 0, |
179 | .cctl = 0, | ||
180 | .periph_buses = PL08X_AHB1, | 171 | .periph_buses = PL08X_AHB1, |
181 | }, { | 172 | }, { |
182 | .bus_id = "from_jpeg", | 173 | .bus_id = "from_jpeg", |
183 | .min_signal = 15, | 174 | .min_signal = 15, |
184 | .max_signal = 15, | 175 | .max_signal = 15, |
185 | .muxval = 0, | 176 | .muxval = 0, |
186 | .cctl = 0, | ||
187 | .periph_buses = PL08X_AHB1, | 177 | .periph_buses = PL08X_AHB1, |
188 | }, { | 178 | }, { |
189 | .bus_id = "ras0_rx", | 179 | .bus_id = "ras0_rx", |
190 | .min_signal = 0, | 180 | .min_signal = 0, |
191 | .max_signal = 0, | 181 | .max_signal = 0, |
192 | .muxval = 1, | 182 | .muxval = 1, |
193 | .cctl = 0, | ||
194 | .periph_buses = PL08X_AHB1, | 183 | .periph_buses = PL08X_AHB1, |
195 | }, { | 184 | }, { |
196 | .bus_id = "ras0_tx", | 185 | .bus_id = "ras0_tx", |
197 | .min_signal = 1, | 186 | .min_signal = 1, |
198 | .max_signal = 1, | 187 | .max_signal = 1, |
199 | .muxval = 1, | 188 | .muxval = 1, |
200 | .cctl = 0, | ||
201 | .periph_buses = PL08X_AHB1, | 189 | .periph_buses = PL08X_AHB1, |
202 | }, { | 190 | }, { |
203 | .bus_id = "ras1_rx", | 191 | .bus_id = "ras1_rx", |
204 | .min_signal = 2, | 192 | .min_signal = 2, |
205 | .max_signal = 2, | 193 | .max_signal = 2, |
206 | .muxval = 1, | 194 | .muxval = 1, |
207 | .cctl = 0, | ||
208 | .periph_buses = PL08X_AHB1, | 195 | .periph_buses = PL08X_AHB1, |
209 | }, { | 196 | }, { |
210 | .bus_id = "ras1_tx", | 197 | .bus_id = "ras1_tx", |
211 | .min_signal = 3, | 198 | .min_signal = 3, |
212 | .max_signal = 3, | 199 | .max_signal = 3, |
213 | .muxval = 1, | 200 | .muxval = 1, |
214 | .cctl = 0, | ||
215 | .periph_buses = PL08X_AHB1, | 201 | .periph_buses = PL08X_AHB1, |
216 | }, { | 202 | }, { |
217 | .bus_id = "ras2_rx", | 203 | .bus_id = "ras2_rx", |
218 | .min_signal = 4, | 204 | .min_signal = 4, |
219 | .max_signal = 4, | 205 | .max_signal = 4, |
220 | .muxval = 1, | 206 | .muxval = 1, |
221 | .cctl = 0, | ||
222 | .periph_buses = PL08X_AHB1, | 207 | .periph_buses = PL08X_AHB1, |
223 | }, { | 208 | }, { |
224 | .bus_id = "ras2_tx", | 209 | .bus_id = "ras2_tx", |
225 | .min_signal = 5, | 210 | .min_signal = 5, |
226 | .max_signal = 5, | 211 | .max_signal = 5, |
227 | .muxval = 1, | 212 | .muxval = 1, |
228 | .cctl = 0, | ||
229 | .periph_buses = PL08X_AHB1, | 213 | .periph_buses = PL08X_AHB1, |
230 | }, { | 214 | }, { |
231 | .bus_id = "ras3_rx", | 215 | .bus_id = "ras3_rx", |
232 | .min_signal = 6, | 216 | .min_signal = 6, |
233 | .max_signal = 6, | 217 | .max_signal = 6, |
234 | .muxval = 1, | 218 | .muxval = 1, |
235 | .cctl = 0, | ||
236 | .periph_buses = PL08X_AHB1, | 219 | .periph_buses = PL08X_AHB1, |
237 | }, { | 220 | }, { |
238 | .bus_id = "ras3_tx", | 221 | .bus_id = "ras3_tx", |
239 | .min_signal = 7, | 222 | .min_signal = 7, |
240 | .max_signal = 7, | 223 | .max_signal = 7, |
241 | .muxval = 1, | 224 | .muxval = 1, |
242 | .cctl = 0, | ||
243 | .periph_buses = PL08X_AHB1, | 225 | .periph_buses = PL08X_AHB1, |
244 | }, { | 226 | }, { |
245 | .bus_id = "ras4_rx", | 227 | .bus_id = "ras4_rx", |
246 | .min_signal = 8, | 228 | .min_signal = 8, |
247 | .max_signal = 8, | 229 | .max_signal = 8, |
248 | .muxval = 1, | 230 | .muxval = 1, |
249 | .cctl = 0, | ||
250 | .periph_buses = PL08X_AHB1, | 231 | .periph_buses = PL08X_AHB1, |
251 | }, { | 232 | }, { |
252 | .bus_id = "ras4_tx", | 233 | .bus_id = "ras4_tx", |
253 | .min_signal = 9, | 234 | .min_signal = 9, |
254 | .max_signal = 9, | 235 | .max_signal = 9, |
255 | .muxval = 1, | 236 | .muxval = 1, |
256 | .cctl = 0, | ||
257 | .periph_buses = PL08X_AHB1, | 237 | .periph_buses = PL08X_AHB1, |
258 | }, { | 238 | }, { |
259 | .bus_id = "ras5_rx", | 239 | .bus_id = "ras5_rx", |
260 | .min_signal = 10, | 240 | .min_signal = 10, |
261 | .max_signal = 10, | 241 | .max_signal = 10, |
262 | .muxval = 1, | 242 | .muxval = 1, |
263 | .cctl = 0, | ||
264 | .periph_buses = PL08X_AHB1, | 243 | .periph_buses = PL08X_AHB1, |
265 | }, { | 244 | }, { |
266 | .bus_id = "ras5_tx", | 245 | .bus_id = "ras5_tx", |
267 | .min_signal = 11, | 246 | .min_signal = 11, |
268 | .max_signal = 11, | 247 | .max_signal = 11, |
269 | .muxval = 1, | 248 | .muxval = 1, |
270 | .cctl = 0, | ||
271 | .periph_buses = PL08X_AHB1, | 249 | .periph_buses = PL08X_AHB1, |
272 | }, { | 250 | }, { |
273 | .bus_id = "ras6_rx", | 251 | .bus_id = "ras6_rx", |
274 | .min_signal = 12, | 252 | .min_signal = 12, |
275 | .max_signal = 12, | 253 | .max_signal = 12, |
276 | .muxval = 1, | 254 | .muxval = 1, |
277 | .cctl = 0, | ||
278 | .periph_buses = PL08X_AHB1, | 255 | .periph_buses = PL08X_AHB1, |
279 | }, { | 256 | }, { |
280 | .bus_id = "ras6_tx", | 257 | .bus_id = "ras6_tx", |
281 | .min_signal = 13, | 258 | .min_signal = 13, |
282 | .max_signal = 13, | 259 | .max_signal = 13, |
283 | .muxval = 1, | 260 | .muxval = 1, |
284 | .cctl = 0, | ||
285 | .periph_buses = PL08X_AHB1, | 261 | .periph_buses = PL08X_AHB1, |
286 | }, { | 262 | }, { |
287 | .bus_id = "ras7_rx", | 263 | .bus_id = "ras7_rx", |
288 | .min_signal = 14, | 264 | .min_signal = 14, |
289 | .max_signal = 14, | 265 | .max_signal = 14, |
290 | .muxval = 1, | 266 | .muxval = 1, |
291 | .cctl = 0, | ||
292 | .periph_buses = PL08X_AHB1, | 267 | .periph_buses = PL08X_AHB1, |
293 | }, { | 268 | }, { |
294 | .bus_id = "ras7_tx", | 269 | .bus_id = "ras7_tx", |
295 | .min_signal = 15, | 270 | .min_signal = 15, |
296 | .max_signal = 15, | 271 | .max_signal = 15, |
297 | .muxval = 1, | 272 | .muxval = 1, |
298 | .cctl = 0, | ||
299 | .periph_buses = PL08X_AHB1, | 273 | .periph_buses = PL08X_AHB1, |
300 | }, | 274 | }, |
301 | }; | 275 | }; |
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index bbcf4571d361..1d0e435b9045 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c | |||
@@ -205,182 +205,156 @@ struct pl08x_channel_data spear310_dma_info[] = { | |||
205 | .min_signal = 2, | 205 | .min_signal = 2, |
206 | .max_signal = 2, | 206 | .max_signal = 2, |
207 | .muxval = 0, | 207 | .muxval = 0, |
208 | .cctl = 0, | ||
209 | .periph_buses = PL08X_AHB1, | 208 | .periph_buses = PL08X_AHB1, |
210 | }, { | 209 | }, { |
211 | .bus_id = "uart0_tx", | 210 | .bus_id = "uart0_tx", |
212 | .min_signal = 3, | 211 | .min_signal = 3, |
213 | .max_signal = 3, | 212 | .max_signal = 3, |
214 | .muxval = 0, | 213 | .muxval = 0, |
215 | .cctl = 0, | ||
216 | .periph_buses = PL08X_AHB1, | 214 | .periph_buses = PL08X_AHB1, |
217 | }, { | 215 | }, { |
218 | .bus_id = "ssp0_rx", | 216 | .bus_id = "ssp0_rx", |
219 | .min_signal = 8, | 217 | .min_signal = 8, |
220 | .max_signal = 8, | 218 | .max_signal = 8, |
221 | .muxval = 0, | 219 | .muxval = 0, |
222 | .cctl = 0, | ||
223 | .periph_buses = PL08X_AHB1, | 220 | .periph_buses = PL08X_AHB1, |
224 | }, { | 221 | }, { |
225 | .bus_id = "ssp0_tx", | 222 | .bus_id = "ssp0_tx", |
226 | .min_signal = 9, | 223 | .min_signal = 9, |
227 | .max_signal = 9, | 224 | .max_signal = 9, |
228 | .muxval = 0, | 225 | .muxval = 0, |
229 | .cctl = 0, | ||
230 | .periph_buses = PL08X_AHB1, | 226 | .periph_buses = PL08X_AHB1, |
231 | }, { | 227 | }, { |
232 | .bus_id = "i2c_rx", | 228 | .bus_id = "i2c_rx", |
233 | .min_signal = 10, | 229 | .min_signal = 10, |
234 | .max_signal = 10, | 230 | .max_signal = 10, |
235 | .muxval = 0, | 231 | .muxval = 0, |
236 | .cctl = 0, | ||
237 | .periph_buses = PL08X_AHB1, | 232 | .periph_buses = PL08X_AHB1, |
238 | }, { | 233 | }, { |
239 | .bus_id = "i2c_tx", | 234 | .bus_id = "i2c_tx", |
240 | .min_signal = 11, | 235 | .min_signal = 11, |
241 | .max_signal = 11, | 236 | .max_signal = 11, |
242 | .muxval = 0, | 237 | .muxval = 0, |
243 | .cctl = 0, | ||
244 | .periph_buses = PL08X_AHB1, | 238 | .periph_buses = PL08X_AHB1, |
245 | }, { | 239 | }, { |
246 | .bus_id = "irda", | 240 | .bus_id = "irda", |
247 | .min_signal = 12, | 241 | .min_signal = 12, |
248 | .max_signal = 12, | 242 | .max_signal = 12, |
249 | .muxval = 0, | 243 | .muxval = 0, |
250 | .cctl = 0, | ||
251 | .periph_buses = PL08X_AHB1, | 244 | .periph_buses = PL08X_AHB1, |
252 | }, { | 245 | }, { |
253 | .bus_id = "adc", | 246 | .bus_id = "adc", |
254 | .min_signal = 13, | 247 | .min_signal = 13, |
255 | .max_signal = 13, | 248 | .max_signal = 13, |
256 | .muxval = 0, | 249 | .muxval = 0, |
257 | .cctl = 0, | ||
258 | .periph_buses = PL08X_AHB1, | 250 | .periph_buses = PL08X_AHB1, |
259 | }, { | 251 | }, { |
260 | .bus_id = "to_jpeg", | 252 | .bus_id = "to_jpeg", |
261 | .min_signal = 14, | 253 | .min_signal = 14, |
262 | .max_signal = 14, | 254 | .max_signal = 14, |
263 | .muxval = 0, | 255 | .muxval = 0, |
264 | .cctl = 0, | ||
265 | .periph_buses = PL08X_AHB1, | 256 | .periph_buses = PL08X_AHB1, |
266 | }, { | 257 | }, { |
267 | .bus_id = "from_jpeg", | 258 | .bus_id = "from_jpeg", |
268 | .min_signal = 15, | 259 | .min_signal = 15, |
269 | .max_signal = 15, | 260 | .max_signal = 15, |
270 | .muxval = 0, | 261 | .muxval = 0, |
271 | .cctl = 0, | ||
272 | .periph_buses = PL08X_AHB1, | 262 | .periph_buses = PL08X_AHB1, |
273 | }, { | 263 | }, { |
274 | .bus_id = "uart1_rx", | 264 | .bus_id = "uart1_rx", |
275 | .min_signal = 0, | 265 | .min_signal = 0, |
276 | .max_signal = 0, | 266 | .max_signal = 0, |
277 | .muxval = 1, | 267 | .muxval = 1, |
278 | .cctl = 0, | ||
279 | .periph_buses = PL08X_AHB1, | 268 | .periph_buses = PL08X_AHB1, |
280 | }, { | 269 | }, { |
281 | .bus_id = "uart1_tx", | 270 | .bus_id = "uart1_tx", |
282 | .min_signal = 1, | 271 | .min_signal = 1, |
283 | .max_signal = 1, | 272 | .max_signal = 1, |
284 | .muxval = 1, | 273 | .muxval = 1, |
285 | .cctl = 0, | ||
286 | .periph_buses = PL08X_AHB1, | 274 | .periph_buses = PL08X_AHB1, |
287 | }, { | 275 | }, { |
288 | .bus_id = "uart2_rx", | 276 | .bus_id = "uart2_rx", |
289 | .min_signal = 2, | 277 | .min_signal = 2, |
290 | .max_signal = 2, | 278 | .max_signal = 2, |
291 | .muxval = 1, | 279 | .muxval = 1, |
292 | .cctl = 0, | ||
293 | .periph_buses = PL08X_AHB1, | 280 | .periph_buses = PL08X_AHB1, |
294 | }, { | 281 | }, { |
295 | .bus_id = "uart2_tx", | 282 | .bus_id = "uart2_tx", |
296 | .min_signal = 3, | 283 | .min_signal = 3, |
297 | .max_signal = 3, | 284 | .max_signal = 3, |
298 | .muxval = 1, | 285 | .muxval = 1, |
299 | .cctl = 0, | ||
300 | .periph_buses = PL08X_AHB1, | 286 | .periph_buses = PL08X_AHB1, |
301 | }, { | 287 | }, { |
302 | .bus_id = "uart3_rx", | 288 | .bus_id = "uart3_rx", |
303 | .min_signal = 4, | 289 | .min_signal = 4, |
304 | .max_signal = 4, | 290 | .max_signal = 4, |
305 | .muxval = 1, | 291 | .muxval = 1, |
306 | .cctl = 0, | ||
307 | .periph_buses = PL08X_AHB1, | 292 | .periph_buses = PL08X_AHB1, |
308 | }, { | 293 | }, { |
309 | .bus_id = "uart3_tx", | 294 | .bus_id = "uart3_tx", |
310 | .min_signal = 5, | 295 | .min_signal = 5, |
311 | .max_signal = 5, | 296 | .max_signal = 5, |
312 | .muxval = 1, | 297 | .muxval = 1, |
313 | .cctl = 0, | ||
314 | .periph_buses = PL08X_AHB1, | 298 | .periph_buses = PL08X_AHB1, |
315 | }, { | 299 | }, { |
316 | .bus_id = "uart4_rx", | 300 | .bus_id = "uart4_rx", |
317 | .min_signal = 6, | 301 | .min_signal = 6, |
318 | .max_signal = 6, | 302 | .max_signal = 6, |
319 | .muxval = 1, | 303 | .muxval = 1, |
320 | .cctl = 0, | ||
321 | .periph_buses = PL08X_AHB1, | 304 | .periph_buses = PL08X_AHB1, |
322 | }, { | 305 | }, { |
323 | .bus_id = "uart4_tx", | 306 | .bus_id = "uart4_tx", |
324 | .min_signal = 7, | 307 | .min_signal = 7, |
325 | .max_signal = 7, | 308 | .max_signal = 7, |
326 | .muxval = 1, | 309 | .muxval = 1, |
327 | .cctl = 0, | ||
328 | .periph_buses = PL08X_AHB1, | 310 | .periph_buses = PL08X_AHB1, |
329 | }, { | 311 | }, { |
330 | .bus_id = "uart5_rx", | 312 | .bus_id = "uart5_rx", |
331 | .min_signal = 8, | 313 | .min_signal = 8, |
332 | .max_signal = 8, | 314 | .max_signal = 8, |
333 | .muxval = 1, | 315 | .muxval = 1, |
334 | .cctl = 0, | ||
335 | .periph_buses = PL08X_AHB1, | 316 | .periph_buses = PL08X_AHB1, |
336 | }, { | 317 | }, { |
337 | .bus_id = "uart5_tx", | 318 | .bus_id = "uart5_tx", |
338 | .min_signal = 9, | 319 | .min_signal = 9, |
339 | .max_signal = 9, | 320 | .max_signal = 9, |
340 | .muxval = 1, | 321 | .muxval = 1, |
341 | .cctl = 0, | ||
342 | .periph_buses = PL08X_AHB1, | 322 | .periph_buses = PL08X_AHB1, |
343 | }, { | 323 | }, { |
344 | .bus_id = "ras5_rx", | 324 | .bus_id = "ras5_rx", |
345 | .min_signal = 10, | 325 | .min_signal = 10, |
346 | .max_signal = 10, | 326 | .max_signal = 10, |
347 | .muxval = 1, | 327 | .muxval = 1, |
348 | .cctl = 0, | ||
349 | .periph_buses = PL08X_AHB1, | 328 | .periph_buses = PL08X_AHB1, |
350 | }, { | 329 | }, { |
351 | .bus_id = "ras5_tx", | 330 | .bus_id = "ras5_tx", |
352 | .min_signal = 11, | 331 | .min_signal = 11, |
353 | .max_signal = 11, | 332 | .max_signal = 11, |
354 | .muxval = 1, | 333 | .muxval = 1, |
355 | .cctl = 0, | ||
356 | .periph_buses = PL08X_AHB1, | 334 | .periph_buses = PL08X_AHB1, |
357 | }, { | 335 | }, { |
358 | .bus_id = "ras6_rx", | 336 | .bus_id = "ras6_rx", |
359 | .min_signal = 12, | 337 | .min_signal = 12, |
360 | .max_signal = 12, | 338 | .max_signal = 12, |
361 | .muxval = 1, | 339 | .muxval = 1, |
362 | .cctl = 0, | ||
363 | .periph_buses = PL08X_AHB1, | 340 | .periph_buses = PL08X_AHB1, |
364 | }, { | 341 | }, { |
365 | .bus_id = "ras6_tx", | 342 | .bus_id = "ras6_tx", |
366 | .min_signal = 13, | 343 | .min_signal = 13, |
367 | .max_signal = 13, | 344 | .max_signal = 13, |
368 | .muxval = 1, | 345 | .muxval = 1, |
369 | .cctl = 0, | ||
370 | .periph_buses = PL08X_AHB1, | 346 | .periph_buses = PL08X_AHB1, |
371 | }, { | 347 | }, { |
372 | .bus_id = "ras7_rx", | 348 | .bus_id = "ras7_rx", |
373 | .min_signal = 14, | 349 | .min_signal = 14, |
374 | .max_signal = 14, | 350 | .max_signal = 14, |
375 | .muxval = 1, | 351 | .muxval = 1, |
376 | .cctl = 0, | ||
377 | .periph_buses = PL08X_AHB1, | 352 | .periph_buses = PL08X_AHB1, |
378 | }, { | 353 | }, { |
379 | .bus_id = "ras7_tx", | 354 | .bus_id = "ras7_tx", |
380 | .min_signal = 15, | 355 | .min_signal = 15, |
381 | .max_signal = 15, | 356 | .max_signal = 15, |
382 | .muxval = 1, | 357 | .muxval = 1, |
383 | .cctl = 0, | ||
384 | .periph_buses = PL08X_AHB1, | 358 | .periph_buses = PL08X_AHB1, |
385 | }, | 359 | }, |
386 | }; | 360 | }; |
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index 88d483bcd66a..fd823c624575 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c | |||
@@ -213,182 +213,156 @@ struct pl08x_channel_data spear320_dma_info[] = { | |||
213 | .min_signal = 2, | 213 | .min_signal = 2, |
214 | .max_signal = 2, | 214 | .max_signal = 2, |
215 | .muxval = 0, | 215 | .muxval = 0, |
216 | .cctl = 0, | ||
217 | .periph_buses = PL08X_AHB1, | 216 | .periph_buses = PL08X_AHB1, |
218 | }, { | 217 | }, { |
219 | .bus_id = "uart0_tx", | 218 | .bus_id = "uart0_tx", |
220 | .min_signal = 3, | 219 | .min_signal = 3, |
221 | .max_signal = 3, | 220 | .max_signal = 3, |
222 | .muxval = 0, | 221 | .muxval = 0, |
223 | .cctl = 0, | ||
224 | .periph_buses = PL08X_AHB1, | 222 | .periph_buses = PL08X_AHB1, |
225 | }, { | 223 | }, { |
226 | .bus_id = "ssp0_rx", | 224 | .bus_id = "ssp0_rx", |
227 | .min_signal = 8, | 225 | .min_signal = 8, |
228 | .max_signal = 8, | 226 | .max_signal = 8, |
229 | .muxval = 0, | 227 | .muxval = 0, |
230 | .cctl = 0, | ||
231 | .periph_buses = PL08X_AHB1, | 228 | .periph_buses = PL08X_AHB1, |
232 | }, { | 229 | }, { |
233 | .bus_id = "ssp0_tx", | 230 | .bus_id = "ssp0_tx", |
234 | .min_signal = 9, | 231 | .min_signal = 9, |
235 | .max_signal = 9, | 232 | .max_signal = 9, |
236 | .muxval = 0, | 233 | .muxval = 0, |
237 | .cctl = 0, | ||
238 | .periph_buses = PL08X_AHB1, | 234 | .periph_buses = PL08X_AHB1, |
239 | }, { | 235 | }, { |
240 | .bus_id = "i2c0_rx", | 236 | .bus_id = "i2c0_rx", |
241 | .min_signal = 10, | 237 | .min_signal = 10, |
242 | .max_signal = 10, | 238 | .max_signal = 10, |
243 | .muxval = 0, | 239 | .muxval = 0, |
244 | .cctl = 0, | ||
245 | .periph_buses = PL08X_AHB1, | 240 | .periph_buses = PL08X_AHB1, |
246 | }, { | 241 | }, { |
247 | .bus_id = "i2c0_tx", | 242 | .bus_id = "i2c0_tx", |
248 | .min_signal = 11, | 243 | .min_signal = 11, |
249 | .max_signal = 11, | 244 | .max_signal = 11, |
250 | .muxval = 0, | 245 | .muxval = 0, |
251 | .cctl = 0, | ||
252 | .periph_buses = PL08X_AHB1, | 246 | .periph_buses = PL08X_AHB1, |
253 | }, { | 247 | }, { |
254 | .bus_id = "irda", | 248 | .bus_id = "irda", |
255 | .min_signal = 12, | 249 | .min_signal = 12, |
256 | .max_signal = 12, | 250 | .max_signal = 12, |
257 | .muxval = 0, | 251 | .muxval = 0, |
258 | .cctl = 0, | ||
259 | .periph_buses = PL08X_AHB1, | 252 | .periph_buses = PL08X_AHB1, |
260 | }, { | 253 | }, { |
261 | .bus_id = "adc", | 254 | .bus_id = "adc", |
262 | .min_signal = 13, | 255 | .min_signal = 13, |
263 | .max_signal = 13, | 256 | .max_signal = 13, |
264 | .muxval = 0, | 257 | .muxval = 0, |
265 | .cctl = 0, | ||
266 | .periph_buses = PL08X_AHB1, | 258 | .periph_buses = PL08X_AHB1, |
267 | }, { | 259 | }, { |
268 | .bus_id = "to_jpeg", | 260 | .bus_id = "to_jpeg", |
269 | .min_signal = 14, | 261 | .min_signal = 14, |
270 | .max_signal = 14, | 262 | .max_signal = 14, |
271 | .muxval = 0, | 263 | .muxval = 0, |
272 | .cctl = 0, | ||
273 | .periph_buses = PL08X_AHB1, | 264 | .periph_buses = PL08X_AHB1, |
274 | }, { | 265 | }, { |
275 | .bus_id = "from_jpeg", | 266 | .bus_id = "from_jpeg", |
276 | .min_signal = 15, | 267 | .min_signal = 15, |
277 | .max_signal = 15, | 268 | .max_signal = 15, |
278 | .muxval = 0, | 269 | .muxval = 0, |
279 | .cctl = 0, | ||
280 | .periph_buses = PL08X_AHB1, | 270 | .periph_buses = PL08X_AHB1, |
281 | }, { | 271 | }, { |
282 | .bus_id = "ssp1_rx", | 272 | .bus_id = "ssp1_rx", |
283 | .min_signal = 0, | 273 | .min_signal = 0, |
284 | .max_signal = 0, | 274 | .max_signal = 0, |
285 | .muxval = 1, | 275 | .muxval = 1, |
286 | .cctl = 0, | ||
287 | .periph_buses = PL08X_AHB2, | 276 | .periph_buses = PL08X_AHB2, |
288 | }, { | 277 | }, { |
289 | .bus_id = "ssp1_tx", | 278 | .bus_id = "ssp1_tx", |
290 | .min_signal = 1, | 279 | .min_signal = 1, |
291 | .max_signal = 1, | 280 | .max_signal = 1, |
292 | .muxval = 1, | 281 | .muxval = 1, |
293 | .cctl = 0, | ||
294 | .periph_buses = PL08X_AHB2, | 282 | .periph_buses = PL08X_AHB2, |
295 | }, { | 283 | }, { |
296 | .bus_id = "ssp2_rx", | 284 | .bus_id = "ssp2_rx", |
297 | .min_signal = 2, | 285 | .min_signal = 2, |
298 | .max_signal = 2, | 286 | .max_signal = 2, |
299 | .muxval = 1, | 287 | .muxval = 1, |
300 | .cctl = 0, | ||
301 | .periph_buses = PL08X_AHB2, | 288 | .periph_buses = PL08X_AHB2, |
302 | }, { | 289 | }, { |
303 | .bus_id = "ssp2_tx", | 290 | .bus_id = "ssp2_tx", |
304 | .min_signal = 3, | 291 | .min_signal = 3, |
305 | .max_signal = 3, | 292 | .max_signal = 3, |
306 | .muxval = 1, | 293 | .muxval = 1, |
307 | .cctl = 0, | ||
308 | .periph_buses = PL08X_AHB2, | 294 | .periph_buses = PL08X_AHB2, |
309 | }, { | 295 | }, { |
310 | .bus_id = "uart1_rx", | 296 | .bus_id = "uart1_rx", |
311 | .min_signal = 4, | 297 | .min_signal = 4, |
312 | .max_signal = 4, | 298 | .max_signal = 4, |
313 | .muxval = 1, | 299 | .muxval = 1, |
314 | .cctl = 0, | ||
315 | .periph_buses = PL08X_AHB2, | 300 | .periph_buses = PL08X_AHB2, |
316 | }, { | 301 | }, { |
317 | .bus_id = "uart1_tx", | 302 | .bus_id = "uart1_tx", |
318 | .min_signal = 5, | 303 | .min_signal = 5, |
319 | .max_signal = 5, | 304 | .max_signal = 5, |
320 | .muxval = 1, | 305 | .muxval = 1, |
321 | .cctl = 0, | ||
322 | .periph_buses = PL08X_AHB2, | 306 | .periph_buses = PL08X_AHB2, |
323 | }, { | 307 | }, { |
324 | .bus_id = "uart2_rx", | 308 | .bus_id = "uart2_rx", |
325 | .min_signal = 6, | 309 | .min_signal = 6, |
326 | .max_signal = 6, | 310 | .max_signal = 6, |
327 | .muxval = 1, | 311 | .muxval = 1, |
328 | .cctl = 0, | ||
329 | .periph_buses = PL08X_AHB2, | 312 | .periph_buses = PL08X_AHB2, |
330 | }, { | 313 | }, { |
331 | .bus_id = "uart2_tx", | 314 | .bus_id = "uart2_tx", |
332 | .min_signal = 7, | 315 | .min_signal = 7, |
333 | .max_signal = 7, | 316 | .max_signal = 7, |
334 | .muxval = 1, | 317 | .muxval = 1, |
335 | .cctl = 0, | ||
336 | .periph_buses = PL08X_AHB2, | 318 | .periph_buses = PL08X_AHB2, |
337 | }, { | 319 | }, { |
338 | .bus_id = "i2c1_rx", | 320 | .bus_id = "i2c1_rx", |
339 | .min_signal = 8, | 321 | .min_signal = 8, |
340 | .max_signal = 8, | 322 | .max_signal = 8, |
341 | .muxval = 1, | 323 | .muxval = 1, |
342 | .cctl = 0, | ||
343 | .periph_buses = PL08X_AHB2, | 324 | .periph_buses = PL08X_AHB2, |
344 | }, { | 325 | }, { |
345 | .bus_id = "i2c1_tx", | 326 | .bus_id = "i2c1_tx", |
346 | .min_signal = 9, | 327 | .min_signal = 9, |
347 | .max_signal = 9, | 328 | .max_signal = 9, |
348 | .muxval = 1, | 329 | .muxval = 1, |
349 | .cctl = 0, | ||
350 | .periph_buses = PL08X_AHB2, | 330 | .periph_buses = PL08X_AHB2, |
351 | }, { | 331 | }, { |
352 | .bus_id = "i2c2_rx", | 332 | .bus_id = "i2c2_rx", |
353 | .min_signal = 10, | 333 | .min_signal = 10, |
354 | .max_signal = 10, | 334 | .max_signal = 10, |
355 | .muxval = 1, | 335 | .muxval = 1, |
356 | .cctl = 0, | ||
357 | .periph_buses = PL08X_AHB2, | 336 | .periph_buses = PL08X_AHB2, |
358 | }, { | 337 | }, { |
359 | .bus_id = "i2c2_tx", | 338 | .bus_id = "i2c2_tx", |
360 | .min_signal = 11, | 339 | .min_signal = 11, |
361 | .max_signal = 11, | 340 | .max_signal = 11, |
362 | .muxval = 1, | 341 | .muxval = 1, |
363 | .cctl = 0, | ||
364 | .periph_buses = PL08X_AHB2, | 342 | .periph_buses = PL08X_AHB2, |
365 | }, { | 343 | }, { |
366 | .bus_id = "i2s_rx", | 344 | .bus_id = "i2s_rx", |
367 | .min_signal = 12, | 345 | .min_signal = 12, |
368 | .max_signal = 12, | 346 | .max_signal = 12, |
369 | .muxval = 1, | 347 | .muxval = 1, |
370 | .cctl = 0, | ||
371 | .periph_buses = PL08X_AHB2, | 348 | .periph_buses = PL08X_AHB2, |
372 | }, { | 349 | }, { |
373 | .bus_id = "i2s_tx", | 350 | .bus_id = "i2s_tx", |
374 | .min_signal = 13, | 351 | .min_signal = 13, |
375 | .max_signal = 13, | 352 | .max_signal = 13, |
376 | .muxval = 1, | 353 | .muxval = 1, |
377 | .cctl = 0, | ||
378 | .periph_buses = PL08X_AHB2, | 354 | .periph_buses = PL08X_AHB2, |
379 | }, { | 355 | }, { |
380 | .bus_id = "rs485_rx", | 356 | .bus_id = "rs485_rx", |
381 | .min_signal = 14, | 357 | .min_signal = 14, |
382 | .max_signal = 14, | 358 | .max_signal = 14, |
383 | .muxval = 1, | 359 | .muxval = 1, |
384 | .cctl = 0, | ||
385 | .periph_buses = PL08X_AHB2, | 360 | .periph_buses = PL08X_AHB2, |
386 | }, { | 361 | }, { |
387 | .bus_id = "rs485_tx", | 362 | .bus_id = "rs485_tx", |
388 | .min_signal = 15, | 363 | .min_signal = 15, |
389 | .max_signal = 15, | 364 | .max_signal = 15, |
390 | .muxval = 1, | 365 | .muxval = 1, |
391 | .cctl = 0, | ||
392 | .periph_buses = PL08X_AHB2, | 366 | .periph_buses = PL08X_AHB2, |
393 | }, | 367 | }, |
394 | }; | 368 | }; |
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 66db5f13af84..98144baf8883 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c | |||
@@ -46,7 +46,8 @@ struct pl022_ssp_controller pl022_plat_data = { | |||
46 | struct pl08x_platform_data pl080_plat_data = { | 46 | struct pl08x_platform_data pl080_plat_data = { |
47 | .memcpy_channel = { | 47 | .memcpy_channel = { |
48 | .bus_id = "memcpy", | 48 | .bus_id = "memcpy", |
49 | .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ | 49 | .cctl_memcpy = |
50 | (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ | ||
50 | PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ | 51 | PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ |
51 | PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ | 52 | PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ |
52 | PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ | 53 | PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ |
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c index 9af67d003c62..5a5a52db252b 100644 --- a/arch/arm/mach-spear6xx/spear6xx.c +++ b/arch/arm/mach-spear6xx/spear6xx.c | |||
@@ -36,336 +36,288 @@ static struct pl08x_channel_data spear600_dma_info[] = { | |||
36 | .min_signal = 0, | 36 | .min_signal = 0, |
37 | .max_signal = 0, | 37 | .max_signal = 0, |
38 | .muxval = 0, | 38 | .muxval = 0, |
39 | .cctl = 0, | ||
40 | .periph_buses = PL08X_AHB1, | 39 | .periph_buses = PL08X_AHB1, |
41 | }, { | 40 | }, { |
42 | .bus_id = "ssp1_tx", | 41 | .bus_id = "ssp1_tx", |
43 | .min_signal = 1, | 42 | .min_signal = 1, |
44 | .max_signal = 1, | 43 | .max_signal = 1, |
45 | .muxval = 0, | 44 | .muxval = 0, |
46 | .cctl = 0, | ||
47 | .periph_buses = PL08X_AHB1, | 45 | .periph_buses = PL08X_AHB1, |
48 | }, { | 46 | }, { |
49 | .bus_id = "uart0_rx", | 47 | .bus_id = "uart0_rx", |
50 | .min_signal = 2, | 48 | .min_signal = 2, |
51 | .max_signal = 2, | 49 | .max_signal = 2, |
52 | .muxval = 0, | 50 | .muxval = 0, |
53 | .cctl = 0, | ||
54 | .periph_buses = PL08X_AHB1, | 51 | .periph_buses = PL08X_AHB1, |
55 | }, { | 52 | }, { |
56 | .bus_id = "uart0_tx", | 53 | .bus_id = "uart0_tx", |
57 | .min_signal = 3, | 54 | .min_signal = 3, |
58 | .max_signal = 3, | 55 | .max_signal = 3, |
59 | .muxval = 0, | 56 | .muxval = 0, |
60 | .cctl = 0, | ||
61 | .periph_buses = PL08X_AHB1, | 57 | .periph_buses = PL08X_AHB1, |
62 | }, { | 58 | }, { |
63 | .bus_id = "uart1_rx", | 59 | .bus_id = "uart1_rx", |
64 | .min_signal = 4, | 60 | .min_signal = 4, |
65 | .max_signal = 4, | 61 | .max_signal = 4, |
66 | .muxval = 0, | 62 | .muxval = 0, |
67 | .cctl = 0, | ||
68 | .periph_buses = PL08X_AHB1, | 63 | .periph_buses = PL08X_AHB1, |
69 | }, { | 64 | }, { |
70 | .bus_id = "uart1_tx", | 65 | .bus_id = "uart1_tx", |
71 | .min_signal = 5, | 66 | .min_signal = 5, |
72 | .max_signal = 5, | 67 | .max_signal = 5, |
73 | .muxval = 0, | 68 | .muxval = 0, |
74 | .cctl = 0, | ||
75 | .periph_buses = PL08X_AHB1, | 69 | .periph_buses = PL08X_AHB1, |
76 | }, { | 70 | }, { |
77 | .bus_id = "ssp2_rx", | 71 | .bus_id = "ssp2_rx", |
78 | .min_signal = 6, | 72 | .min_signal = 6, |
79 | .max_signal = 6, | 73 | .max_signal = 6, |
80 | .muxval = 0, | 74 | .muxval = 0, |
81 | .cctl = 0, | ||
82 | .periph_buses = PL08X_AHB2, | 75 | .periph_buses = PL08X_AHB2, |
83 | }, { | 76 | }, { |
84 | .bus_id = "ssp2_tx", | 77 | .bus_id = "ssp2_tx", |
85 | .min_signal = 7, | 78 | .min_signal = 7, |
86 | .max_signal = 7, | 79 | .max_signal = 7, |
87 | .muxval = 0, | 80 | .muxval = 0, |
88 | .cctl = 0, | ||
89 | .periph_buses = PL08X_AHB2, | 81 | .periph_buses = PL08X_AHB2, |
90 | }, { | 82 | }, { |
91 | .bus_id = "ssp0_rx", | 83 | .bus_id = "ssp0_rx", |
92 | .min_signal = 8, | 84 | .min_signal = 8, |
93 | .max_signal = 8, | 85 | .max_signal = 8, |
94 | .muxval = 0, | 86 | .muxval = 0, |
95 | .cctl = 0, | ||
96 | .periph_buses = PL08X_AHB1, | 87 | .periph_buses = PL08X_AHB1, |
97 | }, { | 88 | }, { |
98 | .bus_id = "ssp0_tx", | 89 | .bus_id = "ssp0_tx", |
99 | .min_signal = 9, | 90 | .min_signal = 9, |
100 | .max_signal = 9, | 91 | .max_signal = 9, |
101 | .muxval = 0, | 92 | .muxval = 0, |
102 | .cctl = 0, | ||
103 | .periph_buses = PL08X_AHB1, | 93 | .periph_buses = PL08X_AHB1, |
104 | }, { | 94 | }, { |
105 | .bus_id = "i2c_rx", | 95 | .bus_id = "i2c_rx", |
106 | .min_signal = 10, | 96 | .min_signal = 10, |
107 | .max_signal = 10, | 97 | .max_signal = 10, |
108 | .muxval = 0, | 98 | .muxval = 0, |
109 | .cctl = 0, | ||
110 | .periph_buses = PL08X_AHB1, | 99 | .periph_buses = PL08X_AHB1, |
111 | }, { | 100 | }, { |
112 | .bus_id = "i2c_tx", | 101 | .bus_id = "i2c_tx", |
113 | .min_signal = 11, | 102 | .min_signal = 11, |
114 | .max_signal = 11, | 103 | .max_signal = 11, |
115 | .muxval = 0, | 104 | .muxval = 0, |
116 | .cctl = 0, | ||
117 | .periph_buses = PL08X_AHB1, | 105 | .periph_buses = PL08X_AHB1, |
118 | }, { | 106 | }, { |
119 | .bus_id = "irda", | 107 | .bus_id = "irda", |
120 | .min_signal = 12, | 108 | .min_signal = 12, |
121 | .max_signal = 12, | 109 | .max_signal = 12, |
122 | .muxval = 0, | 110 | .muxval = 0, |
123 | .cctl = 0, | ||
124 | .periph_buses = PL08X_AHB1, | 111 | .periph_buses = PL08X_AHB1, |
125 | }, { | 112 | }, { |
126 | .bus_id = "adc", | 113 | .bus_id = "adc", |
127 | .min_signal = 13, | 114 | .min_signal = 13, |
128 | .max_signal = 13, | 115 | .max_signal = 13, |
129 | .muxval = 0, | 116 | .muxval = 0, |
130 | .cctl = 0, | ||
131 | .periph_buses = PL08X_AHB2, | 117 | .periph_buses = PL08X_AHB2, |
132 | }, { | 118 | }, { |
133 | .bus_id = "to_jpeg", | 119 | .bus_id = "to_jpeg", |
134 | .min_signal = 14, | 120 | .min_signal = 14, |
135 | .max_signal = 14, | 121 | .max_signal = 14, |
136 | .muxval = 0, | 122 | .muxval = 0, |
137 | .cctl = 0, | ||
138 | .periph_buses = PL08X_AHB1, | 123 | .periph_buses = PL08X_AHB1, |
139 | }, { | 124 | }, { |
140 | .bus_id = "from_jpeg", | 125 | .bus_id = "from_jpeg", |
141 | .min_signal = 15, | 126 | .min_signal = 15, |
142 | .max_signal = 15, | 127 | .max_signal = 15, |
143 | .muxval = 0, | 128 | .muxval = 0, |
144 | .cctl = 0, | ||
145 | .periph_buses = PL08X_AHB1, | 129 | .periph_buses = PL08X_AHB1, |
146 | }, { | 130 | }, { |
147 | .bus_id = "ras0_rx", | 131 | .bus_id = "ras0_rx", |
148 | .min_signal = 0, | 132 | .min_signal = 0, |
149 | .max_signal = 0, | 133 | .max_signal = 0, |
150 | .muxval = 1, | 134 | .muxval = 1, |
151 | .cctl = 0, | ||
152 | .periph_buses = PL08X_AHB1, | 135 | .periph_buses = PL08X_AHB1, |
153 | }, { | 136 | }, { |
154 | .bus_id = "ras0_tx", | 137 | .bus_id = "ras0_tx", |
155 | .min_signal = 1, | 138 | .min_signal = 1, |
156 | .max_signal = 1, | 139 | .max_signal = 1, |
157 | .muxval = 1, | 140 | .muxval = 1, |
158 | .cctl = 0, | ||
159 | .periph_buses = PL08X_AHB1, | 141 | .periph_buses = PL08X_AHB1, |
160 | }, { | 142 | }, { |
161 | .bus_id = "ras1_rx", | 143 | .bus_id = "ras1_rx", |
162 | .min_signal = 2, | 144 | .min_signal = 2, |
163 | .max_signal = 2, | 145 | .max_signal = 2, |
164 | .muxval = 1, | 146 | .muxval = 1, |
165 | .cctl = 0, | ||
166 | .periph_buses = PL08X_AHB1, | 147 | .periph_buses = PL08X_AHB1, |
167 | }, { | 148 | }, { |
168 | .bus_id = "ras1_tx", | 149 | .bus_id = "ras1_tx", |
169 | .min_signal = 3, | 150 | .min_signal = 3, |
170 | .max_signal = 3, | 151 | .max_signal = 3, |
171 | .muxval = 1, | 152 | .muxval = 1, |
172 | .cctl = 0, | ||
173 | .periph_buses = PL08X_AHB1, | 153 | .periph_buses = PL08X_AHB1, |
174 | }, { | 154 | }, { |
175 | .bus_id = "ras2_rx", | 155 | .bus_id = "ras2_rx", |
176 | .min_signal = 4, | 156 | .min_signal = 4, |
177 | .max_signal = 4, | 157 | .max_signal = 4, |
178 | .muxval = 1, | 158 | .muxval = 1, |
179 | .cctl = 0, | ||
180 | .periph_buses = PL08X_AHB1, | 159 | .periph_buses = PL08X_AHB1, |
181 | }, { | 160 | }, { |
182 | .bus_id = "ras2_tx", | 161 | .bus_id = "ras2_tx", |
183 | .min_signal = 5, | 162 | .min_signal = 5, |
184 | .max_signal = 5, | 163 | .max_signal = 5, |
185 | .muxval = 1, | 164 | .muxval = 1, |
186 | .cctl = 0, | ||
187 | .periph_buses = PL08X_AHB1, | 165 | .periph_buses = PL08X_AHB1, |
188 | }, { | 166 | }, { |
189 | .bus_id = "ras3_rx", | 167 | .bus_id = "ras3_rx", |
190 | .min_signal = 6, | 168 | .min_signal = 6, |
191 | .max_signal = 6, | 169 | .max_signal = 6, |
192 | .muxval = 1, | 170 | .muxval = 1, |
193 | .cctl = 0, | ||
194 | .periph_buses = PL08X_AHB1, | 171 | .periph_buses = PL08X_AHB1, |
195 | }, { | 172 | }, { |
196 | .bus_id = "ras3_tx", | 173 | .bus_id = "ras3_tx", |
197 | .min_signal = 7, | 174 | .min_signal = 7, |
198 | .max_signal = 7, | 175 | .max_signal = 7, |
199 | .muxval = 1, | 176 | .muxval = 1, |
200 | .cctl = 0, | ||
201 | .periph_buses = PL08X_AHB1, | 177 | .periph_buses = PL08X_AHB1, |
202 | }, { | 178 | }, { |
203 | .bus_id = "ras4_rx", | 179 | .bus_id = "ras4_rx", |
204 | .min_signal = 8, | 180 | .min_signal = 8, |
205 | .max_signal = 8, | 181 | .max_signal = 8, |
206 | .muxval = 1, | 182 | .muxval = 1, |
207 | .cctl = 0, | ||
208 | .periph_buses = PL08X_AHB1, | 183 | .periph_buses = PL08X_AHB1, |
209 | }, { | 184 | }, { |
210 | .bus_id = "ras4_tx", | 185 | .bus_id = "ras4_tx", |
211 | .min_signal = 9, | 186 | .min_signal = 9, |
212 | .max_signal = 9, | 187 | .max_signal = 9, |
213 | .muxval = 1, | 188 | .muxval = 1, |
214 | .cctl = 0, | ||
215 | .periph_buses = PL08X_AHB1, | 189 | .periph_buses = PL08X_AHB1, |
216 | }, { | 190 | }, { |
217 | .bus_id = "ras5_rx", | 191 | .bus_id = "ras5_rx", |
218 | .min_signal = 10, | 192 | .min_signal = 10, |
219 | .max_signal = 10, | 193 | .max_signal = 10, |
220 | .muxval = 1, | 194 | .muxval = 1, |
221 | .cctl = 0, | ||
222 | .periph_buses = PL08X_AHB1, | 195 | .periph_buses = PL08X_AHB1, |
223 | }, { | 196 | }, { |
224 | .bus_id = "ras5_tx", | 197 | .bus_id = "ras5_tx", |
225 | .min_signal = 11, | 198 | .min_signal = 11, |
226 | .max_signal = 11, | 199 | .max_signal = 11, |
227 | .muxval = 1, | 200 | .muxval = 1, |
228 | .cctl = 0, | ||
229 | .periph_buses = PL08X_AHB1, | 201 | .periph_buses = PL08X_AHB1, |
230 | }, { | 202 | }, { |
231 | .bus_id = "ras6_rx", | 203 | .bus_id = "ras6_rx", |
232 | .min_signal = 12, | 204 | .min_signal = 12, |
233 | .max_signal = 12, | 205 | .max_signal = 12, |
234 | .muxval = 1, | 206 | .muxval = 1, |
235 | .cctl = 0, | ||
236 | .periph_buses = PL08X_AHB1, | 207 | .periph_buses = PL08X_AHB1, |
237 | }, { | 208 | }, { |
238 | .bus_id = "ras6_tx", | 209 | .bus_id = "ras6_tx", |
239 | .min_signal = 13, | 210 | .min_signal = 13, |
240 | .max_signal = 13, | 211 | .max_signal = 13, |
241 | .muxval = 1, | 212 | .muxval = 1, |
242 | .cctl = 0, | ||
243 | .periph_buses = PL08X_AHB1, | 213 | .periph_buses = PL08X_AHB1, |
244 | }, { | 214 | }, { |
245 | .bus_id = "ras7_rx", | 215 | .bus_id = "ras7_rx", |
246 | .min_signal = 14, | 216 | .min_signal = 14, |
247 | .max_signal = 14, | 217 | .max_signal = 14, |
248 | .muxval = 1, | 218 | .muxval = 1, |
249 | .cctl = 0, | ||
250 | .periph_buses = PL08X_AHB1, | 219 | .periph_buses = PL08X_AHB1, |
251 | }, { | 220 | }, { |
252 | .bus_id = "ras7_tx", | 221 | .bus_id = "ras7_tx", |
253 | .min_signal = 15, | 222 | .min_signal = 15, |
254 | .max_signal = 15, | 223 | .max_signal = 15, |
255 | .muxval = 1, | 224 | .muxval = 1, |
256 | .cctl = 0, | ||
257 | .periph_buses = PL08X_AHB1, | 225 | .periph_buses = PL08X_AHB1, |
258 | }, { | 226 | }, { |
259 | .bus_id = "ext0_rx", | 227 | .bus_id = "ext0_rx", |
260 | .min_signal = 0, | 228 | .min_signal = 0, |
261 | .max_signal = 0, | 229 | .max_signal = 0, |
262 | .muxval = 2, | 230 | .muxval = 2, |
263 | .cctl = 0, | ||
264 | .periph_buses = PL08X_AHB2, | 231 | .periph_buses = PL08X_AHB2, |
265 | }, { | 232 | }, { |
266 | .bus_id = "ext0_tx", | 233 | .bus_id = "ext0_tx", |
267 | .min_signal = 1, | 234 | .min_signal = 1, |
268 | .max_signal = 1, | 235 | .max_signal = 1, |
269 | .muxval = 2, | 236 | .muxval = 2, |
270 | .cctl = 0, | ||
271 | .periph_buses = PL08X_AHB2, | 237 | .periph_buses = PL08X_AHB2, |
272 | }, { | 238 | }, { |
273 | .bus_id = "ext1_rx", | 239 | .bus_id = "ext1_rx", |
274 | .min_signal = 2, | 240 | .min_signal = 2, |
275 | .max_signal = 2, | 241 | .max_signal = 2, |
276 | .muxval = 2, | 242 | .muxval = 2, |
277 | .cctl = 0, | ||
278 | .periph_buses = PL08X_AHB2, | 243 | .periph_buses = PL08X_AHB2, |
279 | }, { | 244 | }, { |
280 | .bus_id = "ext1_tx", | 245 | .bus_id = "ext1_tx", |
281 | .min_signal = 3, | 246 | .min_signal = 3, |
282 | .max_signal = 3, | 247 | .max_signal = 3, |
283 | .muxval = 2, | 248 | .muxval = 2, |
284 | .cctl = 0, | ||
285 | .periph_buses = PL08X_AHB2, | 249 | .periph_buses = PL08X_AHB2, |
286 | }, { | 250 | }, { |
287 | .bus_id = "ext2_rx", | 251 | .bus_id = "ext2_rx", |
288 | .min_signal = 4, | 252 | .min_signal = 4, |
289 | .max_signal = 4, | 253 | .max_signal = 4, |
290 | .muxval = 2, | 254 | .muxval = 2, |
291 | .cctl = 0, | ||
292 | .periph_buses = PL08X_AHB2, | 255 | .periph_buses = PL08X_AHB2, |
293 | }, { | 256 | }, { |
294 | .bus_id = "ext2_tx", | 257 | .bus_id = "ext2_tx", |
295 | .min_signal = 5, | 258 | .min_signal = 5, |
296 | .max_signal = 5, | 259 | .max_signal = 5, |
297 | .muxval = 2, | 260 | .muxval = 2, |
298 | .cctl = 0, | ||
299 | .periph_buses = PL08X_AHB2, | 261 | .periph_buses = PL08X_AHB2, |
300 | }, { | 262 | }, { |
301 | .bus_id = "ext3_rx", | 263 | .bus_id = "ext3_rx", |
302 | .min_signal = 6, | 264 | .min_signal = 6, |
303 | .max_signal = 6, | 265 | .max_signal = 6, |
304 | .muxval = 2, | 266 | .muxval = 2, |
305 | .cctl = 0, | ||
306 | .periph_buses = PL08X_AHB2, | 267 | .periph_buses = PL08X_AHB2, |
307 | }, { | 268 | }, { |
308 | .bus_id = "ext3_tx", | 269 | .bus_id = "ext3_tx", |
309 | .min_signal = 7, | 270 | .min_signal = 7, |
310 | .max_signal = 7, | 271 | .max_signal = 7, |
311 | .muxval = 2, | 272 | .muxval = 2, |
312 | .cctl = 0, | ||
313 | .periph_buses = PL08X_AHB2, | 273 | .periph_buses = PL08X_AHB2, |
314 | }, { | 274 | }, { |
315 | .bus_id = "ext4_rx", | 275 | .bus_id = "ext4_rx", |
316 | .min_signal = 8, | 276 | .min_signal = 8, |
317 | .max_signal = 8, | 277 | .max_signal = 8, |
318 | .muxval = 2, | 278 | .muxval = 2, |
319 | .cctl = 0, | ||
320 | .periph_buses = PL08X_AHB2, | 279 | .periph_buses = PL08X_AHB2, |
321 | }, { | 280 | }, { |
322 | .bus_id = "ext4_tx", | 281 | .bus_id = "ext4_tx", |
323 | .min_signal = 9, | 282 | .min_signal = 9, |
324 | .max_signal = 9, | 283 | .max_signal = 9, |
325 | .muxval = 2, | 284 | .muxval = 2, |
326 | .cctl = 0, | ||
327 | .periph_buses = PL08X_AHB2, | 285 | .periph_buses = PL08X_AHB2, |
328 | }, { | 286 | }, { |
329 | .bus_id = "ext5_rx", | 287 | .bus_id = "ext5_rx", |
330 | .min_signal = 10, | 288 | .min_signal = 10, |
331 | .max_signal = 10, | 289 | .max_signal = 10, |
332 | .muxval = 2, | 290 | .muxval = 2, |
333 | .cctl = 0, | ||
334 | .periph_buses = PL08X_AHB2, | 291 | .periph_buses = PL08X_AHB2, |
335 | }, { | 292 | }, { |
336 | .bus_id = "ext5_tx", | 293 | .bus_id = "ext5_tx", |
337 | .min_signal = 11, | 294 | .min_signal = 11, |
338 | .max_signal = 11, | 295 | .max_signal = 11, |
339 | .muxval = 2, | 296 | .muxval = 2, |
340 | .cctl = 0, | ||
341 | .periph_buses = PL08X_AHB2, | 297 | .periph_buses = PL08X_AHB2, |
342 | }, { | 298 | }, { |
343 | .bus_id = "ext6_rx", | 299 | .bus_id = "ext6_rx", |
344 | .min_signal = 12, | 300 | .min_signal = 12, |
345 | .max_signal = 12, | 301 | .max_signal = 12, |
346 | .muxval = 2, | 302 | .muxval = 2, |
347 | .cctl = 0, | ||
348 | .periph_buses = PL08X_AHB2, | 303 | .periph_buses = PL08X_AHB2, |
349 | }, { | 304 | }, { |
350 | .bus_id = "ext6_tx", | 305 | .bus_id = "ext6_tx", |
351 | .min_signal = 13, | 306 | .min_signal = 13, |
352 | .max_signal = 13, | 307 | .max_signal = 13, |
353 | .muxval = 2, | 308 | .muxval = 2, |
354 | .cctl = 0, | ||
355 | .periph_buses = PL08X_AHB2, | 309 | .periph_buses = PL08X_AHB2, |
356 | }, { | 310 | }, { |
357 | .bus_id = "ext7_rx", | 311 | .bus_id = "ext7_rx", |
358 | .min_signal = 14, | 312 | .min_signal = 14, |
359 | .max_signal = 14, | 313 | .max_signal = 14, |
360 | .muxval = 2, | 314 | .muxval = 2, |
361 | .cctl = 0, | ||
362 | .periph_buses = PL08X_AHB2, | 315 | .periph_buses = PL08X_AHB2, |
363 | }, { | 316 | }, { |
364 | .bus_id = "ext7_tx", | 317 | .bus_id = "ext7_tx", |
365 | .min_signal = 15, | 318 | .min_signal = 15, |
366 | .max_signal = 15, | 319 | .max_signal = 15, |
367 | .muxval = 2, | 320 | .muxval = 2, |
368 | .cctl = 0, | ||
369 | .periph_buses = PL08X_AHB2, | 321 | .periph_buses = PL08X_AHB2, |
370 | }, | 322 | }, |
371 | }; | 323 | }; |
@@ -373,7 +325,8 @@ static struct pl08x_channel_data spear600_dma_info[] = { | |||
373 | struct pl08x_platform_data pl080_plat_data = { | 325 | struct pl08x_platform_data pl080_plat_data = { |
374 | .memcpy_channel = { | 326 | .memcpy_channel = { |
375 | .bus_id = "memcpy", | 327 | .bus_id = "memcpy", |
376 | .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ | 328 | .cctl_memcpy = |
329 | (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ | ||
377 | PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ | 330 | PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ |
378 | PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ | 331 | PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ |
379 | PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ | 332 | PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index 845f461f8ec1..c2021139cb56 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
@@ -38,11 +38,19 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
38 | dsb | 38 | dsb |
39 | mov r0, r0, lsr #PAGE_SHIFT @ align address | 39 | mov r0, r0, lsr #PAGE_SHIFT @ align address |
40 | mov r1, r1, lsr #PAGE_SHIFT | 40 | mov r1, r1, lsr #PAGE_SHIFT |
41 | #ifdef CONFIG_ARM_ERRATA_720789 | ||
42 | mov r3, #0 | ||
43 | #else | ||
41 | asid r3, r3 @ mask ASID | 44 | asid r3, r3 @ mask ASID |
45 | #endif | ||
42 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA | 46 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA |
43 | mov r1, r1, lsl #PAGE_SHIFT | 47 | mov r1, r1, lsl #PAGE_SHIFT |
44 | 1: | 48 | 1: |
49 | #ifdef CONFIG_ARM_ERRATA_720789 | ||
50 | ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) | ||
51 | #else | ||
45 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) | 52 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
53 | #endif | ||
46 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA | 54 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
47 | 55 | ||
48 | add r0, r0, #PAGE_SZ | 56 | add r0, r0, #PAGE_SZ |
@@ -67,7 +75,11 @@ ENTRY(v7wbi_flush_kern_tlb_range) | |||
67 | mov r0, r0, lsl #PAGE_SHIFT | 75 | mov r0, r0, lsl #PAGE_SHIFT |
68 | mov r1, r1, lsl #PAGE_SHIFT | 76 | mov r1, r1, lsl #PAGE_SHIFT |
69 | 1: | 77 | 1: |
78 | #ifdef CONFIG_ARM_ERRATA_720789 | ||
79 | ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) | ||
80 | #else | ||
70 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) | 81 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
82 | #endif | ||
71 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA | 83 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
72 | add r0, r0, #PAGE_SZ | 84 | add r0, r0, #PAGE_SZ |
73 | cmp r0, r1 | 85 | cmp r0, r1 |
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index c2193178210b..3ed1adbc09f8 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
25 | #include <mach/common.h> | 25 | #include <mach/common.h> |
26 | #include <mach/irqs.h> | ||
26 | 27 | ||
27 | #include "irq-common.h" | 28 | #include "irq-common.h" |
28 | 29 | ||
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index 5493bd95da5e..eb3e4d555343 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h | |||
@@ -81,8 +81,6 @@ struct omap_mmc_platform_data { | |||
81 | /* Return context loss count due to PM states changing */ | 81 | /* Return context loss count due to PM states changing */ |
82 | int (*get_context_loss_count)(struct device *dev); | 82 | int (*get_context_loss_count)(struct device *dev); |
83 | 83 | ||
84 | u64 dma_mask; | ||
85 | |||
86 | /* Integrating attributes from the omap_hwmod layer */ | 84 | /* Integrating attributes from the omap_hwmod layer */ |
87 | u8 controller_flags; | 85 | u8 controller_flags; |
88 | 86 | ||
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index c1793786aea9..d245a87dc014 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c | |||
@@ -47,6 +47,7 @@ void __init orion_clkdev_init(struct clk *tclk) | |||
47 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk); | 47 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk); |
48 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk); | 48 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk); |
49 | orion_clkdev_add(NULL, "orion_wdt", tclk); | 49 | orion_clkdev_add(NULL, "orion_wdt", tclk); |
50 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", tclk); | ||
50 | } | 51 | } |
51 | 52 | ||
52 | /* Fill in the resources structure and link it into the platform | 53 | /* Fill in the resources structure and link it into the platform |
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index af95af257301..dfda74fae6f2 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c | |||
@@ -8,15 +8,22 @@ | |||
8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define DEBUG | ||
12 | |||
11 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 14 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/irqdomain.h> | ||
14 | #include <linux/module.h> | 17 | #include <linux/module.h> |
15 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
16 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
17 | #include <linux/io.h> | 20 | #include <linux/io.h> |
18 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
19 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_irq.h> | ||
25 | #include <linux/of_address.h> | ||
26 | #include <plat/gpio.h> | ||
20 | 27 | ||
21 | /* | 28 | /* |
22 | * GPIO unit register offsets. | 29 | * GPIO unit register offsets. |
@@ -38,6 +45,7 @@ struct orion_gpio_chip { | |||
38 | unsigned long valid_output; | 45 | unsigned long valid_output; |
39 | int mask_offset; | 46 | int mask_offset; |
40 | int secondary_irq_base; | 47 | int secondary_irq_base; |
48 | struct irq_domain *domain; | ||
41 | }; | 49 | }; |
42 | 50 | ||
43 | static void __iomem *GPIO_OUT(struct orion_gpio_chip *ochip) | 51 | static void __iomem *GPIO_OUT(struct orion_gpio_chip *ochip) |
@@ -222,10 +230,10 @@ static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin) | |||
222 | struct orion_gpio_chip *ochip = | 230 | struct orion_gpio_chip *ochip = |
223 | container_of(chip, struct orion_gpio_chip, chip); | 231 | container_of(chip, struct orion_gpio_chip, chip); |
224 | 232 | ||
225 | return ochip->secondary_irq_base + pin; | 233 | return irq_create_mapping(ochip->domain, |
234 | ochip->secondary_irq_base + pin); | ||
226 | } | 235 | } |
227 | 236 | ||
228 | |||
229 | /* | 237 | /* |
230 | * Orion-specific GPIO API extensions. | 238 | * Orion-specific GPIO API extensions. |
231 | */ | 239 | */ |
@@ -353,12 +361,10 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) | |||
353 | int pin; | 361 | int pin; |
354 | u32 u; | 362 | u32 u; |
355 | 363 | ||
356 | pin = d->irq - gc->irq_base; | 364 | pin = d->hwirq - ochip->secondary_irq_base; |
357 | 365 | ||
358 | u = readl(GPIO_IO_CONF(ochip)) & (1 << pin); | 366 | u = readl(GPIO_IO_CONF(ochip)) & (1 << pin); |
359 | if (!u) { | 367 | if (!u) { |
360 | printk(KERN_ERR "orion gpio_irq_set_type failed " | ||
361 | "(irq %d, pin %d).\n", d->irq, pin); | ||
362 | return -EINVAL; | 368 | return -EINVAL; |
363 | } | 369 | } |
364 | 370 | ||
@@ -397,17 +403,53 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) | |||
397 | u &= ~(1 << pin); /* rising */ | 403 | u &= ~(1 << pin); /* rising */ |
398 | writel(u, GPIO_IN_POL(ochip)); | 404 | writel(u, GPIO_IN_POL(ochip)); |
399 | } | 405 | } |
400 | |||
401 | return 0; | 406 | return 0; |
402 | } | 407 | } |
403 | 408 | ||
404 | void __init orion_gpio_init(int gpio_base, int ngpio, | 409 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) |
405 | u32 base, int mask_offset, int secondary_irq_base) | 410 | { |
411 | struct orion_gpio_chip *ochip = irq_get_handler_data(irq); | ||
412 | u32 cause, type; | ||
413 | int i; | ||
414 | |||
415 | if (ochip == NULL) | ||
416 | return; | ||
417 | |||
418 | cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip)); | ||
419 | cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip)); | ||
420 | |||
421 | for (i = 0; i < ochip->chip.ngpio; i++) { | ||
422 | int irq; | ||
423 | |||
424 | irq = ochip->secondary_irq_base + i; | ||
425 | |||
426 | if (!(cause & (1 << i))) | ||
427 | continue; | ||
428 | |||
429 | type = irqd_get_trigger_type(irq_get_irq_data(irq)); | ||
430 | if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { | ||
431 | /* Swap polarity (race with GPIO line) */ | ||
432 | u32 polarity; | ||
433 | |||
434 | polarity = readl(GPIO_IN_POL(ochip)); | ||
435 | polarity ^= 1 << i; | ||
436 | writel(polarity, GPIO_IN_POL(ochip)); | ||
437 | } | ||
438 | generic_handle_irq(irq); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | void __init orion_gpio_init(struct device_node *np, | ||
443 | int gpio_base, int ngpio, | ||
444 | void __iomem *base, int mask_offset, | ||
445 | int secondary_irq_base, | ||
446 | int irqs[4]) | ||
406 | { | 447 | { |
407 | struct orion_gpio_chip *ochip; | 448 | struct orion_gpio_chip *ochip; |
408 | struct irq_chip_generic *gc; | 449 | struct irq_chip_generic *gc; |
409 | struct irq_chip_type *ct; | 450 | struct irq_chip_type *ct; |
410 | char gc_label[16]; | 451 | char gc_label[16]; |
452 | int i; | ||
411 | 453 | ||
412 | if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips)) | 454 | if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips)) |
413 | return; | 455 | return; |
@@ -426,6 +468,10 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
426 | ochip->chip.base = gpio_base; | 468 | ochip->chip.base = gpio_base; |
427 | ochip->chip.ngpio = ngpio; | 469 | ochip->chip.ngpio = ngpio; |
428 | ochip->chip.can_sleep = 0; | 470 | ochip->chip.can_sleep = 0; |
471 | #ifdef CONFIG_OF | ||
472 | ochip->chip.of_node = np; | ||
473 | #endif | ||
474 | |||
429 | spin_lock_init(&ochip->lock); | 475 | spin_lock_init(&ochip->lock); |
430 | ochip->base = (void __iomem *)base; | 476 | ochip->base = (void __iomem *)base; |
431 | ochip->valid_input = 0; | 477 | ochip->valid_input = 0; |
@@ -435,8 +481,6 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
435 | 481 | ||
436 | gpiochip_add(&ochip->chip); | 482 | gpiochip_add(&ochip->chip); |
437 | 483 | ||
438 | orion_gpio_chip_count++; | ||
439 | |||
440 | /* | 484 | /* |
441 | * Mask and clear GPIO interrupts. | 485 | * Mask and clear GPIO interrupts. |
442 | */ | 486 | */ |
@@ -444,16 +488,28 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
444 | writel(0, GPIO_EDGE_MASK(ochip)); | 488 | writel(0, GPIO_EDGE_MASK(ochip)); |
445 | writel(0, GPIO_LEVEL_MASK(ochip)); | 489 | writel(0, GPIO_LEVEL_MASK(ochip)); |
446 | 490 | ||
447 | gc = irq_alloc_generic_chip("orion_gpio_irq", 2, secondary_irq_base, | 491 | /* Setup the interrupt handlers. Each chip can have up to 4 |
492 | * interrupt handlers, with each handler dealing with 8 GPIO | ||
493 | * pins. */ | ||
494 | |||
495 | for (i = 0; i < 4; i++) { | ||
496 | if (irqs[i]) { | ||
497 | irq_set_handler_data(irqs[i], ochip); | ||
498 | irq_set_chained_handler(irqs[i], gpio_irq_handler); | ||
499 | } | ||
500 | } | ||
501 | |||
502 | gc = irq_alloc_generic_chip("orion_gpio_irq", 2, | ||
503 | secondary_irq_base, | ||
448 | ochip->base, handle_level_irq); | 504 | ochip->base, handle_level_irq); |
449 | gc->private = ochip; | 505 | gc->private = ochip; |
450 | |||
451 | ct = gc->chip_types; | 506 | ct = gc->chip_types; |
452 | ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF; | 507 | ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF; |
453 | ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; | 508 | ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; |
454 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | 509 | ct->chip.irq_mask = irq_gc_mask_clr_bit; |
455 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 510 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
456 | ct->chip.irq_set_type = gpio_irq_set_type; | 511 | ct->chip.irq_set_type = gpio_irq_set_type; |
512 | ct->chip.name = ochip->chip.label; | ||
457 | 513 | ||
458 | ct++; | 514 | ct++; |
459 | ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF; | 515 | ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF; |
@@ -464,41 +520,69 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
464 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 520 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
465 | ct->chip.irq_set_type = gpio_irq_set_type; | 521 | ct->chip.irq_set_type = gpio_irq_set_type; |
466 | ct->handler = handle_edge_irq; | 522 | ct->handler = handle_edge_irq; |
523 | ct->chip.name = ochip->chip.label; | ||
467 | 524 | ||
468 | irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE, | 525 | irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE, |
469 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 526 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
470 | } | ||
471 | 527 | ||
472 | void orion_gpio_irq_handler(int pinoff) | 528 | /* Setup irq domain on top of the generic chip. */ |
473 | { | 529 | ochip->domain = irq_domain_add_legacy(np, |
474 | struct orion_gpio_chip *ochip; | 530 | ochip->chip.ngpio, |
475 | u32 cause, type; | 531 | ochip->secondary_irq_base, |
476 | int i; | 532 | ochip->secondary_irq_base, |
477 | 533 | &irq_domain_simple_ops, | |
478 | ochip = orion_gpio_chip_find(pinoff); | 534 | ochip); |
479 | if (ochip == NULL) | 535 | if (!ochip->domain) |
480 | return; | 536 | panic("%s: couldn't allocate irq domain (DT).\n", |
481 | 537 | ochip->chip.label); | |
482 | cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip)); | ||
483 | cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip)); | ||
484 | |||
485 | for (i = 0; i < ochip->chip.ngpio; i++) { | ||
486 | int irq; | ||
487 | 538 | ||
488 | irq = ochip->secondary_irq_base + i; | 539 | orion_gpio_chip_count++; |
540 | } | ||
489 | 541 | ||
490 | if (!(cause & (1 << i))) | 542 | #ifdef CONFIG_OF |
491 | continue; | 543 | static void __init orion_gpio_of_init_one(struct device_node *np, |
544 | int irq_gpio_base) | ||
545 | { | ||
546 | int ngpio, gpio_base, mask_offset; | ||
547 | void __iomem *base; | ||
548 | int ret, i; | ||
549 | int irqs[4]; | ||
550 | int secondary_irq_base; | ||
551 | |||
552 | ret = of_property_read_u32(np, "ngpio", &ngpio); | ||
553 | if (ret) | ||
554 | goto out; | ||
555 | ret = of_property_read_u32(np, "mask-offset", &mask_offset); | ||
556 | if (ret == -EINVAL) | ||
557 | mask_offset = 0; | ||
558 | else | ||
559 | goto out; | ||
560 | base = of_iomap(np, 0); | ||
561 | if (!base) | ||
562 | goto out; | ||
563 | |||
564 | secondary_irq_base = irq_gpio_base + (32 * orion_gpio_chip_count); | ||
565 | gpio_base = 32 * orion_gpio_chip_count; | ||
566 | |||
567 | /* Get the interrupt numbers. Each chip can have up to 4 | ||
568 | * interrupt handlers, with each handler dealing with 8 GPIO | ||
569 | * pins. */ | ||
570 | |||
571 | for (i = 0; i < 4; i++) | ||
572 | irqs[i] = irq_of_parse_and_map(np, i); | ||
573 | |||
574 | orion_gpio_init(np, gpio_base, ngpio, base, mask_offset, | ||
575 | secondary_irq_base, irqs); | ||
576 | return; | ||
577 | out: | ||
578 | pr_err("%s: %s: missing mandatory property\n", __func__, np->name); | ||
579 | } | ||
492 | 580 | ||
493 | type = irqd_get_trigger_type(irq_get_irq_data(irq)); | 581 | void __init orion_gpio_of_init(int irq_gpio_base) |
494 | if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { | 582 | { |
495 | /* Swap polarity (race with GPIO line) */ | 583 | struct device_node *np; |
496 | u32 polarity; | ||
497 | 584 | ||
498 | polarity = readl(GPIO_IN_POL(ochip)); | 585 | for_each_compatible_node(np, NULL, "marvell,orion-gpio") |
499 | polarity ^= 1 << i; | 586 | orion_gpio_of_init_one(np, irq_gpio_base); |
500 | writel(polarity, GPIO_IN_POL(ochip)); | ||
501 | } | ||
502 | generic_handle_irq(irq); | ||
503 | } | ||
504 | } | 587 | } |
588 | #endif | ||
diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h index bec0c98ce41f..81c6fc8a7b28 100644 --- a/arch/arm/plat-orion/include/plat/gpio.h +++ b/arch/arm/plat-orion/include/plat/gpio.h | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | 16 | #include <linux/irqdomain.h> | |
17 | /* | 17 | /* |
18 | * Orion-specific GPIO API extensions. | 18 | * Orion-specific GPIO API extensions. |
19 | */ | 19 | */ |
@@ -27,13 +27,11 @@ int orion_gpio_led_blink_set(unsigned gpio, int state, | |||
27 | void orion_gpio_set_valid(unsigned pin, int mode); | 27 | void orion_gpio_set_valid(unsigned pin, int mode); |
28 | 28 | ||
29 | /* Initialize gpiolib. */ | 29 | /* Initialize gpiolib. */ |
30 | void __init orion_gpio_init(int gpio_base, int ngpio, | 30 | void __init orion_gpio_init(struct device_node *np, |
31 | u32 base, int mask_offset, int secondary_irq_base); | 31 | int gpio_base, int ngpio, |
32 | 32 | void __iomem *base, int mask_offset, | |
33 | /* | 33 | int secondary_irq_base, |
34 | * GPIO interrupt handling. | 34 | int irq[4]); |
35 | */ | ||
36 | void orion_gpio_irq_handler(int irqoff); | ||
37 | |||
38 | 35 | ||
36 | void __init orion_gpio_of_init(int irq_gpio_base); | ||
39 | #endif | 37 | #endif |
diff --git a/arch/arm/plat-orion/include/plat/irq.h b/arch/arm/plat-orion/include/plat/irq.h index f05eeab94968..50547e417936 100644 --- a/arch/arm/plat-orion/include/plat/irq.h +++ b/arch/arm/plat-orion/include/plat/irq.h | |||
@@ -12,6 +12,5 @@ | |||
12 | #define __PLAT_IRQ_H | 12 | #define __PLAT_IRQ_H |
13 | 13 | ||
14 | void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr); | 14 | void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr); |
15 | 15 | void __init orion_dt_init_irq(void); | |
16 | |||
17 | #endif | 16 | #endif |
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c index 2d5b9c1ef389..d751964def4c 100644 --- a/arch/arm/plat-orion/irq.c +++ b/arch/arm/plat-orion/irq.c | |||
@@ -11,8 +11,12 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqdomain.h> | ||
14 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_irq.h> | ||
15 | #include <plat/irq.h> | 18 | #include <plat/irq.h> |
19 | #include <plat/gpio.h> | ||
16 | 20 | ||
17 | void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) | 21 | void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) |
18 | { | 22 | { |
@@ -32,3 +36,39 @@ void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) | |||
32 | irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE, | 36 | irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE, |
33 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 37 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
34 | } | 38 | } |
39 | |||
40 | #ifdef CONFIG_OF | ||
41 | static int __init orion_add_irq_domain(struct device_node *np, | ||
42 | struct device_node *interrupt_parent) | ||
43 | { | ||
44 | int i = 0, irq_gpio; | ||
45 | void __iomem *base; | ||
46 | |||
47 | do { | ||
48 | base = of_iomap(np, i); | ||
49 | if (base) { | ||
50 | orion_irq_init(i * 32, base); | ||
51 | i++; | ||
52 | } | ||
53 | } while (base); | ||
54 | |||
55 | irq_domain_add_legacy(np, i * 32, 0, 0, | ||
56 | &irq_domain_simple_ops, NULL); | ||
57 | |||
58 | irq_gpio = i * 32; | ||
59 | orion_gpio_of_init(irq_gpio); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static const struct of_device_id orion_irq_match[] = { | ||
65 | { .compatible = "marvell,orion-intc", | ||
66 | .data = orion_add_irq_domain, }, | ||
67 | {}, | ||
68 | }; | ||
69 | |||
70 | void __init orion_dt_init_irq(void) | ||
71 | { | ||
72 | of_irq_init(orion_irq_match); | ||
73 | } | ||
74 | #endif | ||
diff --git a/arch/arm/plat-spear/include/plat/pl080.h b/arch/arm/plat-spear/include/plat/pl080.h index 2bc6b54460a8..eb6590ded40d 100644 --- a/arch/arm/plat-spear/include/plat/pl080.h +++ b/arch/arm/plat-spear/include/plat/pl080.h | |||
@@ -14,8 +14,8 @@ | |||
14 | #ifndef __PLAT_PL080_H | 14 | #ifndef __PLAT_PL080_H |
15 | #define __PLAT_PL080_H | 15 | #define __PLAT_PL080_H |
16 | 16 | ||
17 | struct pl08x_dma_chan; | 17 | struct pl08x_channel_data; |
18 | int pl080_get_signal(struct pl08x_dma_chan *ch); | 18 | int pl080_get_signal(const struct pl08x_channel_data *cd); |
19 | void pl080_put_signal(struct pl08x_dma_chan *ch); | 19 | void pl080_put_signal(const struct pl08x_channel_data *cd, int signal); |
20 | 20 | ||
21 | #endif /* __PLAT_PL080_H */ | 21 | #endif /* __PLAT_PL080_H */ |
diff --git a/arch/arm/plat-spear/pl080.c b/arch/arm/plat-spear/pl080.c index 12cf27f935f9..cfa1199d0f4a 100644 --- a/arch/arm/plat-spear/pl080.c +++ b/arch/arm/plat-spear/pl080.c | |||
@@ -27,9 +27,8 @@ struct { | |||
27 | unsigned char val; | 27 | unsigned char val; |
28 | } signals[16] = {{0, 0}, }; | 28 | } signals[16] = {{0, 0}, }; |
29 | 29 | ||
30 | int pl080_get_signal(struct pl08x_dma_chan *ch) | 30 | int pl080_get_signal(const struct pl08x_channel_data *cd) |
31 | { | 31 | { |
32 | const struct pl08x_channel_data *cd = ch->cd; | ||
33 | unsigned int signal = cd->min_signal, val; | 32 | unsigned int signal = cd->min_signal, val; |
34 | unsigned long flags; | 33 | unsigned long flags; |
35 | 34 | ||
@@ -63,18 +62,17 @@ int pl080_get_signal(struct pl08x_dma_chan *ch) | |||
63 | return signal; | 62 | return signal; |
64 | } | 63 | } |
65 | 64 | ||
66 | void pl080_put_signal(struct pl08x_dma_chan *ch) | 65 | void pl080_put_signal(const struct pl08x_channel_data *cd, int signal) |
67 | { | 66 | { |
68 | const struct pl08x_channel_data *cd = ch->cd; | ||
69 | unsigned long flags; | 67 | unsigned long flags; |
70 | 68 | ||
71 | spin_lock_irqsave(&lock, flags); | 69 | spin_lock_irqsave(&lock, flags); |
72 | 70 | ||
73 | /* if signal is not used */ | 71 | /* if signal is not used */ |
74 | if (!signals[cd->min_signal].busy) | 72 | if (!signals[signal].busy) |
75 | BUG(); | 73 | BUG(); |
76 | 74 | ||
77 | signals[cd->min_signal].busy--; | 75 | signals[signal].busy--; |
78 | 76 | ||
79 | spin_unlock_irqrestore(&lock, flags); | 77 | spin_unlock_irqrestore(&lock, flags); |
80 | } | 78 | } |
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 4fa9903b83cf..cc926c985981 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S | |||
@@ -7,18 +7,20 @@ | |||
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | ||
11 | * Basic entry code, called from the kernel's undefined instruction trap. | ||
12 | * r0 = faulted instruction | ||
13 | * r5 = faulted PC+4 | ||
14 | * r9 = successful return | ||
15 | * r10 = thread_info structure | ||
16 | * lr = failure return | ||
17 | */ | 10 | */ |
18 | #include <asm/thread_info.h> | 11 | #include <asm/thread_info.h> |
19 | #include <asm/vfpmacros.h> | 12 | #include <asm/vfpmacros.h> |
20 | #include "../kernel/entry-header.S" | 13 | #include "../kernel/entry-header.S" |
21 | 14 | ||
15 | @ VFP entry point. | ||
16 | @ | ||
17 | @ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb) | ||
18 | @ r2 = PC value to resume execution after successful emulation | ||
19 | @ r9 = normal "successful" return address | ||
20 | @ r10 = this threads thread_info structure | ||
21 | @ lr = unrecognised instruction return address | ||
22 | @ IRQs disabled. | ||
23 | @ | ||
22 | ENTRY(do_vfp) | 24 | ENTRY(do_vfp) |
23 | #ifdef CONFIG_PREEMPT | 25 | #ifdef CONFIG_PREEMPT |
24 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count | 26 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count |
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index d50f0e486cf2..ea0349f63586 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -62,13 +62,13 @@ | |||
62 | 62 | ||
63 | @ VFP hardware support entry point. | 63 | @ VFP hardware support entry point. |
64 | @ | 64 | @ |
65 | @ r0 = faulted instruction | 65 | @ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb) |
66 | @ r2 = faulted PC+4 | 66 | @ r2 = PC value to resume execution after successful emulation |
67 | @ r9 = successful return | 67 | @ r9 = normal "successful" return address |
68 | @ r10 = vfp_state union | 68 | @ r10 = vfp_state union |
69 | @ r11 = CPU number | 69 | @ r11 = CPU number |
70 | @ lr = failure return | 70 | @ lr = unrecognised instruction return address |
71 | 71 | @ IRQs enabled. | |
72 | ENTRY(vfp_support_entry) | 72 | ENTRY(vfp_support_entry) |
73 | DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 | 73 | DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 |
74 | 74 | ||
@@ -162,9 +162,12 @@ vfp_hw_state_valid: | |||
162 | @ exception before retrying branch | 162 | @ exception before retrying branch |
163 | @ out before setting an FPEXC that | 163 | @ out before setting an FPEXC that |
164 | @ stops us reading stuff | 164 | @ stops us reading stuff |
165 | VFPFMXR FPEXC, r1 @ restore FPEXC last | 165 | VFPFMXR FPEXC, r1 @ Restore FPEXC last |
166 | sub r2, r2, #4 | 166 | sub r2, r2, #4 @ Retry current instruction - if Thumb |
167 | str r2, [sp, #S_PC] @ retry the instruction | 167 | str r2, [sp, #S_PC] @ mode it's two 16-bit instructions, |
168 | @ else it's one 32-bit instruction, so | ||
169 | @ always subtract 4 from the following | ||
170 | @ instruction address. | ||
168 | #ifdef CONFIG_PREEMPT | 171 | #ifdef CONFIG_PREEMPT |
169 | get_thread_info r10 | 172 | get_thread_info r10 |
170 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count | 173 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 586961929e96..fb849d044bde 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -457,10 +457,16 @@ static int vfp_pm_suspend(void) | |||
457 | 457 | ||
458 | /* disable, just in case */ | 458 | /* disable, just in case */ |
459 | fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); | 459 | fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); |
460 | } else if (vfp_current_hw_state[ti->cpu]) { | ||
461 | #ifndef CONFIG_SMP | ||
462 | fmxr(FPEXC, fpexc | FPEXC_EN); | ||
463 | vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc); | ||
464 | fmxr(FPEXC, fpexc); | ||
465 | #endif | ||
460 | } | 466 | } |
461 | 467 | ||
462 | /* clear any information we had about last context state */ | 468 | /* clear any information we had about last context state */ |
463 | memset(vfp_current_hw_state, 0, sizeof(vfp_current_hw_state)); | 469 | vfp_current_hw_state[ti->cpu] = NULL; |
464 | 470 | ||
465 | return 0; | 471 | return 0; |
466 | } | 472 | } |
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 5c3e0888265a..1034884b77da 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/ioport.h> | 23 | #include <linux/ioport.h> |
24 | #include <linux/kernel_stat.h> | 24 | #include <linux/kernel_stat.h> |
25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
26 | #include <linux/random.h> /* for rand_initialize_irq() */ | ||
27 | #include <linux/signal.h> | 26 | #include <linux/signal.h> |
28 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
29 | #include <linux/threads.h> | 28 | #include <linux/threads.h> |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index d7f558c1e711..3fa4bc536953 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -2353,7 +2353,6 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t | |||
2353 | */ | 2353 | */ |
2354 | insert_vm_struct(mm, vma); | 2354 | insert_vm_struct(mm, vma); |
2355 | 2355 | ||
2356 | mm->total_vm += size >> PAGE_SHIFT; | ||
2357 | vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, | 2356 | vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, |
2358 | vma_pages(vma)); | 2357 | vma_pages(vma)); |
2359 | up_write(&task->mm->mmap_sem); | 2358 | up_write(&task->mm->mmap_sem); |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e3efc06e6409..331d574df99c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -77,6 +77,7 @@ config AR7 | |||
77 | select SYS_SUPPORTS_ZBOOT_UART16550 | 77 | select SYS_SUPPORTS_ZBOOT_UART16550 |
78 | select ARCH_REQUIRE_GPIOLIB | 78 | select ARCH_REQUIRE_GPIOLIB |
79 | select VLYNQ | 79 | select VLYNQ |
80 | select HAVE_CLK | ||
80 | help | 81 | help |
81 | Support for the Texas Instruments AR7 System-on-a-Chip | 82 | Support for the Texas Instruments AR7 System-on-a-Chip |
82 | family: TNETD7100, 7200 and 7300. | 83 | family: TNETD7100, 7200 and 7300. |
@@ -124,6 +125,7 @@ config BCM63XX | |||
124 | select SYS_HAS_EARLY_PRINTK | 125 | select SYS_HAS_EARLY_PRINTK |
125 | select SWAP_IO_SPACE | 126 | select SWAP_IO_SPACE |
126 | select ARCH_REQUIRE_GPIOLIB | 127 | select ARCH_REQUIRE_GPIOLIB |
128 | select HAVE_CLK | ||
127 | help | 129 | help |
128 | Support for BCM63XX based boards | 130 | Support for BCM63XX based boards |
129 | 131 | ||
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h index 83894aa7932c..c9456e7a7283 100644 --- a/arch/mips/include/asm/clock.h +++ b/arch/mips/include/asm/clock.h | |||
@@ -50,15 +50,4 @@ void clk_recalc_rate(struct clk *); | |||
50 | int clk_register(struct clk *); | 50 | int clk_register(struct clk *); |
51 | void clk_unregister(struct clk *); | 51 | void clk_unregister(struct clk *); |
52 | 52 | ||
53 | /* the exported API, in addition to clk_set_rate */ | ||
54 | /** | ||
55 | * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter | ||
56 | * @clk: clock source | ||
57 | * @rate: desired clock rate in Hz | ||
58 | * @algo_id: algorithm id to be passed down to ops->set_rate | ||
59 | * | ||
60 | * Returns success (0) or negative errno. | ||
61 | */ | ||
62 | int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); | ||
63 | |||
64 | #endif /* __ASM_MIPS_CLOCK_H */ | 53 | #endif /* __ASM_MIPS_CLOCK_H */ |
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 06367c37e1b2..5222a007bc21 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h | |||
@@ -245,7 +245,6 @@ static inline void do_perfcnt_IRQ(void) | |||
245 | 245 | ||
246 | #ifdef CONFIG_CPU_SUPPORTS_CPUFREQ | 246 | #ifdef CONFIG_CPU_SUPPORTS_CPUFREQ |
247 | #include <linux/cpufreq.h> | 247 | #include <linux/cpufreq.h> |
248 | extern void loongson2_cpu_wait(void); | ||
249 | extern struct cpufreq_frequency_table loongson2_clockmod_table[]; | 248 | extern struct cpufreq_frequency_table loongson2_clockmod_table[]; |
250 | 249 | ||
251 | /* Chip Config */ | 250 | /* Chip Config */ |
diff --git a/arch/mips/kernel/cpufreq/Makefile b/arch/mips/kernel/cpufreq/Makefile index c3479a432efe..05a5715ee38c 100644 --- a/arch/mips/kernel/cpufreq/Makefile +++ b/arch/mips/kernel/cpufreq/Makefile | |||
@@ -2,4 +2,4 @@ | |||
2 | # Makefile for the Linux/MIPS cpufreq. | 2 | # Makefile for the Linux/MIPS cpufreq. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o loongson2_clock.o | 5 | obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o |
diff --git a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c index ae5db206347c..e7c98e2b78b6 100644 --- a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c +++ b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #include <asm/clock.h> | 20 | #include <asm/clock.h> |
21 | 21 | ||
22 | #include <loongson.h> | 22 | #include <asm/mach-loongson/loongson.h> |
23 | 23 | ||
24 | static uint nowait; | 24 | static uint nowait; |
25 | 25 | ||
@@ -181,6 +181,25 @@ static struct platform_driver platform_driver = { | |||
181 | .id_table = platform_device_ids, | 181 | .id_table = platform_device_ids, |
182 | }; | 182 | }; |
183 | 183 | ||
184 | /* | ||
185 | * This is the simple version of Loongson-2 wait, Maybe we need do this in | ||
186 | * interrupt disabled context. | ||
187 | */ | ||
188 | |||
189 | static DEFINE_SPINLOCK(loongson2_wait_lock); | ||
190 | |||
191 | static void loongson2_cpu_wait(void) | ||
192 | { | ||
193 | unsigned long flags; | ||
194 | u32 cpu_freq; | ||
195 | |||
196 | spin_lock_irqsave(&loongson2_wait_lock, flags); | ||
197 | cpu_freq = LOONGSON_CHIPCFG0; | ||
198 | LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ | ||
199 | LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */ | ||
200 | spin_unlock_irqrestore(&loongson2_wait_lock, flags); | ||
201 | } | ||
202 | |||
184 | static int __init cpufreq_init(void) | 203 | static int __init cpufreq_init(void) |
185 | { | 204 | { |
186 | int ret; | 205 | int ret; |
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index d3bcc33f4699..ce2f129b081f 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c | |||
@@ -135,6 +135,11 @@ void clk_deactivate(struct clk *clk) | |||
135 | } | 135 | } |
136 | EXPORT_SYMBOL(clk_deactivate); | 136 | EXPORT_SYMBOL(clk_deactivate); |
137 | 137 | ||
138 | struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) | ||
139 | { | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
138 | static inline u32 get_counter_resolution(void) | 143 | static inline u32 get_counter_resolution(void) |
139 | { | 144 | { |
140 | u32 res; | 145 | u32 res; |
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index d185e8477fdf..6cfd6117fbfd 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c | |||
@@ -8,7 +8,10 @@ | |||
8 | 8 | ||
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/bootmem.h> | ||
11 | #include <linux/of_platform.h> | 12 | #include <linux/of_platform.h> |
13 | #include <linux/of_fdt.h> | ||
14 | |||
12 | #include <asm/bootinfo.h> | 15 | #include <asm/bootinfo.h> |
13 | #include <asm/time.h> | 16 | #include <asm/time.h> |
14 | 17 | ||
@@ -70,6 +73,25 @@ void __init plat_mem_setup(void) | |||
70 | __dt_setup_arch(&__dtb_start); | 73 | __dt_setup_arch(&__dtb_start); |
71 | } | 74 | } |
72 | 75 | ||
76 | void __init device_tree_init(void) | ||
77 | { | ||
78 | unsigned long base, size; | ||
79 | |||
80 | if (!initial_boot_params) | ||
81 | return; | ||
82 | |||
83 | base = virt_to_phys((void *)initial_boot_params); | ||
84 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
85 | |||
86 | /* Before we do anything, lets reserve the dt blob */ | ||
87 | reserve_bootmem(base, size, BOOTMEM_DEFAULT); | ||
88 | |||
89 | unflatten_device_tree(); | ||
90 | |||
91 | /* free the space reserved for the dt blob */ | ||
92 | free_bootmem(base, size); | ||
93 | } | ||
94 | |||
73 | void __init prom_init(void) | 95 | void __init prom_init(void) |
74 | { | 96 | { |
75 | /* call the soc specific detetcion code and get it to fill soc_info */ | 97 | /* call the soc specific detetcion code and get it to fill soc_info */ |
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 83780f7c842b..befbb760ab76 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c | |||
@@ -20,10 +20,12 @@ | |||
20 | 20 | ||
21 | /* clock control register */ | 21 | /* clock control register */ |
22 | #define CGU_IFCCR 0x0018 | 22 | #define CGU_IFCCR 0x0018 |
23 | #define CGU_IFCCR_VR9 0x0024 | ||
23 | /* system clock register */ | 24 | /* system clock register */ |
24 | #define CGU_SYS 0x0010 | 25 | #define CGU_SYS 0x0010 |
25 | /* pci control register */ | 26 | /* pci control register */ |
26 | #define CGU_PCICR 0x0034 | 27 | #define CGU_PCICR 0x0034 |
28 | #define CGU_PCICR_VR9 0x0038 | ||
27 | /* ephy configuration register */ | 29 | /* ephy configuration register */ |
28 | #define CGU_EPHY 0x10 | 30 | #define CGU_EPHY 0x10 |
29 | /* power control register */ | 31 | /* power control register */ |
@@ -80,6 +82,9 @@ static void __iomem *pmu_membase; | |||
80 | void __iomem *ltq_cgu_membase; | 82 | void __iomem *ltq_cgu_membase; |
81 | void __iomem *ltq_ebu_membase; | 83 | void __iomem *ltq_ebu_membase; |
82 | 84 | ||
85 | static u32 ifccr = CGU_IFCCR; | ||
86 | static u32 pcicr = CGU_PCICR; | ||
87 | |||
83 | /* legacy function kept alive to ease clkdev transition */ | 88 | /* legacy function kept alive to ease clkdev transition */ |
84 | void ltq_pmu_enable(unsigned int module) | 89 | void ltq_pmu_enable(unsigned int module) |
85 | { | 90 | { |
@@ -103,14 +108,14 @@ EXPORT_SYMBOL(ltq_pmu_disable); | |||
103 | /* enable a hw clock */ | 108 | /* enable a hw clock */ |
104 | static int cgu_enable(struct clk *clk) | 109 | static int cgu_enable(struct clk *clk) |
105 | { | 110 | { |
106 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR); | 111 | ltq_cgu_w32(ltq_cgu_r32(ifccr) | clk->bits, ifccr); |
107 | return 0; | 112 | return 0; |
108 | } | 113 | } |
109 | 114 | ||
110 | /* disable a hw clock */ | 115 | /* disable a hw clock */ |
111 | static void cgu_disable(struct clk *clk) | 116 | static void cgu_disable(struct clk *clk) |
112 | { | 117 | { |
113 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR); | 118 | ltq_cgu_w32(ltq_cgu_r32(ifccr) & ~clk->bits, ifccr); |
114 | } | 119 | } |
115 | 120 | ||
116 | /* enable a clock gate */ | 121 | /* enable a clock gate */ |
@@ -138,22 +143,22 @@ static void pmu_disable(struct clk *clk) | |||
138 | /* the pci enable helper */ | 143 | /* the pci enable helper */ |
139 | static int pci_enable(struct clk *clk) | 144 | static int pci_enable(struct clk *clk) |
140 | { | 145 | { |
141 | unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR); | 146 | unsigned int val = ltq_cgu_r32(ifccr); |
142 | /* set bus clock speed */ | 147 | /* set bus clock speed */ |
143 | if (of_machine_is_compatible("lantiq,ar9")) { | 148 | if (of_machine_is_compatible("lantiq,ar9")) { |
144 | ifccr &= ~0x1f00000; | 149 | val &= ~0x1f00000; |
145 | if (clk->rate == CLOCK_33M) | 150 | if (clk->rate == CLOCK_33M) |
146 | ifccr |= 0xe00000; | 151 | val |= 0xe00000; |
147 | else | 152 | else |
148 | ifccr |= 0x700000; /* 62.5M */ | 153 | val |= 0x700000; /* 62.5M */ |
149 | } else { | 154 | } else { |
150 | ifccr &= ~0xf00000; | 155 | val &= ~0xf00000; |
151 | if (clk->rate == CLOCK_33M) | 156 | if (clk->rate == CLOCK_33M) |
152 | ifccr |= 0x800000; | 157 | val |= 0x800000; |
153 | else | 158 | else |
154 | ifccr |= 0x400000; /* 62.5M */ | 159 | val |= 0x400000; /* 62.5M */ |
155 | } | 160 | } |
156 | ltq_cgu_w32(ifccr, CGU_IFCCR); | 161 | ltq_cgu_w32(val, ifccr); |
157 | pmu_enable(clk); | 162 | pmu_enable(clk); |
158 | return 0; | 163 | return 0; |
159 | } | 164 | } |
@@ -161,18 +166,16 @@ static int pci_enable(struct clk *clk) | |||
161 | /* enable the external clock as a source */ | 166 | /* enable the external clock as a source */ |
162 | static int pci_ext_enable(struct clk *clk) | 167 | static int pci_ext_enable(struct clk *clk) |
163 | { | 168 | { |
164 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16), | 169 | ltq_cgu_w32(ltq_cgu_r32(ifccr) & ~(1 << 16), ifccr); |
165 | CGU_IFCCR); | 170 | ltq_cgu_w32((1 << 30), pcicr); |
166 | ltq_cgu_w32((1 << 30), CGU_PCICR); | ||
167 | return 0; | 171 | return 0; |
168 | } | 172 | } |
169 | 173 | ||
170 | /* disable the external clock as a source */ | 174 | /* disable the external clock as a source */ |
171 | static void pci_ext_disable(struct clk *clk) | 175 | static void pci_ext_disable(struct clk *clk) |
172 | { | 176 | { |
173 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16), | 177 | ltq_cgu_w32(ltq_cgu_r32(ifccr) | (1 << 16), ifccr); |
174 | CGU_IFCCR); | 178 | ltq_cgu_w32((1 << 31) | (1 << 30), pcicr); |
175 | ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR); | ||
176 | } | 179 | } |
177 | 180 | ||
178 | /* enable a clockout source */ | 181 | /* enable a clockout source */ |
@@ -184,11 +187,11 @@ static int clkout_enable(struct clk *clk) | |||
184 | for (i = 0; i < 4; i++) { | 187 | for (i = 0; i < 4; i++) { |
185 | if (clk->rates[i] == clk->rate) { | 188 | if (clk->rates[i] == clk->rate) { |
186 | int shift = 14 - (2 * clk->module); | 189 | int shift = 14 - (2 * clk->module); |
187 | unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR); | 190 | unsigned int val = ltq_cgu_r32(ifccr); |
188 | 191 | ||
189 | ifccr &= ~(3 << shift); | 192 | val &= ~(3 << shift); |
190 | ifccr |= i << shift; | 193 | val |= i << shift; |
191 | ltq_cgu_w32(ifccr, CGU_IFCCR); | 194 | ltq_cgu_w32(val, ifccr); |
192 | return 0; | 195 | return 0; |
193 | } | 196 | } |
194 | } | 197 | } |
@@ -336,8 +339,12 @@ void __init ltq_soc_init(void) | |||
336 | clkdev_add_clkout(); | 339 | clkdev_add_clkout(); |
337 | 340 | ||
338 | /* add the soc dependent clocks */ | 341 | /* add the soc dependent clocks */ |
339 | if (!of_machine_is_compatible("lantiq,vr9")) | 342 | if (of_machine_is_compatible("lantiq,vr9")) { |
343 | ifccr = CGU_IFCCR_VR9; | ||
344 | pcicr = CGU_PCICR_VR9; | ||
345 | } else { | ||
340 | clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE); | 346 | clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE); |
347 | } | ||
341 | 348 | ||
342 | if (!of_machine_is_compatible("lantiq,ase")) { | 349 | if (!of_machine_is_compatible("lantiq,ase")) { |
343 | clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1); | 350 | clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1); |
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index aca93eed8779..263beb9322a8 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig | |||
@@ -41,6 +41,7 @@ config LEMOTE_MACH2F | |||
41 | select CSRC_R4K if ! MIPS_EXTERNAL_TIMER | 41 | select CSRC_R4K if ! MIPS_EXTERNAL_TIMER |
42 | select DMA_NONCOHERENT | 42 | select DMA_NONCOHERENT |
43 | select GENERIC_ISA_DMA_SUPPORT_BROKEN | 43 | select GENERIC_ISA_DMA_SUPPORT_BROKEN |
44 | select HAVE_CLK | ||
44 | select HW_HAS_PCI | 45 | select HW_HAS_PCI |
45 | select I8259 | 46 | select I8259 |
46 | select IRQ_CPU | 47 | select IRQ_CPU |
diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile index 8699a53f0477..4f9eaa328a16 100644 --- a/arch/mips/loongson/lemote-2f/Makefile +++ b/arch/mips/loongson/lemote-2f/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for lemote loongson2f family machines | 2 | # Makefile for lemote loongson2f family machines |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += machtype.o irq.o reset.o ec_kb3310b.o | 5 | obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o |
6 | 6 | ||
7 | # | 7 | # |
8 | # Suspend Support | 8 | # Suspend Support |
diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/loongson/lemote-2f/clock.c index 5426779d9fdb..bc739d4bab2e 100644 --- a/arch/mips/kernel/cpufreq/loongson2_clock.c +++ b/arch/mips/loongson/lemote-2f/clock.c | |||
@@ -6,14 +6,17 @@ | |||
6 | * License. See the file "COPYING" in the main directory of this archive | 6 | * License. See the file "COPYING" in the main directory of this archive |
7 | * for more details. | 7 | * for more details. |
8 | */ | 8 | */ |
9 | 9 | #include <linux/clk.h> | |
10 | #include <linux/module.h> | ||
11 | #include <linux/cpufreq.h> | 10 | #include <linux/cpufreq.h> |
12 | #include <linux/platform_device.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/export.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/list.h> | ||
15 | #include <linux/mutex.h> | ||
16 | #include <linux/spinlock.h> | ||
13 | 17 | ||
14 | #include <asm/clock.h> | 18 | #include <asm/clock.h> |
15 | 19 | #include <asm/mach-loongson/loongson.h> | |
16 | #include <loongson.h> | ||
17 | 20 | ||
18 | static LIST_HEAD(clock_list); | 21 | static LIST_HEAD(clock_list); |
19 | static DEFINE_SPINLOCK(clock_lock); | 22 | static DEFINE_SPINLOCK(clock_lock); |
@@ -89,12 +92,6 @@ EXPORT_SYMBOL(clk_put); | |||
89 | 92 | ||
90 | int clk_set_rate(struct clk *clk, unsigned long rate) | 93 | int clk_set_rate(struct clk *clk, unsigned long rate) |
91 | { | 94 | { |
92 | return clk_set_rate_ex(clk, rate, 0); | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(clk_set_rate); | ||
95 | |||
96 | int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) | ||
97 | { | ||
98 | int ret = 0; | 95 | int ret = 0; |
99 | int regval; | 96 | int regval; |
100 | int i; | 97 | int i; |
@@ -103,7 +100,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) | |||
103 | unsigned long flags; | 100 | unsigned long flags; |
104 | 101 | ||
105 | spin_lock_irqsave(&clock_lock, flags); | 102 | spin_lock_irqsave(&clock_lock, flags); |
106 | ret = clk->ops->set_rate(clk, rate, algo_id); | 103 | ret = clk->ops->set_rate(clk, rate, 0); |
107 | spin_unlock_irqrestore(&clock_lock, flags); | 104 | spin_unlock_irqrestore(&clock_lock, flags); |
108 | } | 105 | } |
109 | 106 | ||
@@ -129,7 +126,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) | |||
129 | 126 | ||
130 | return ret; | 127 | return ret; |
131 | } | 128 | } |
132 | EXPORT_SYMBOL_GPL(clk_set_rate_ex); | 129 | EXPORT_SYMBOL_GPL(clk_set_rate); |
133 | 130 | ||
134 | long clk_round_rate(struct clk *clk, unsigned long rate) | 131 | long clk_round_rate(struct clk *clk, unsigned long rate) |
135 | { | 132 | { |
@@ -146,26 +143,3 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
146 | return rate; | 143 | return rate; |
147 | } | 144 | } |
148 | EXPORT_SYMBOL_GPL(clk_round_rate); | 145 | EXPORT_SYMBOL_GPL(clk_round_rate); |
149 | |||
150 | /* | ||
151 | * This is the simple version of Loongson-2 wait, Maybe we need do this in | ||
152 | * interrupt disabled content | ||
153 | */ | ||
154 | |||
155 | DEFINE_SPINLOCK(loongson2_wait_lock); | ||
156 | void loongson2_cpu_wait(void) | ||
157 | { | ||
158 | u32 cpu_freq; | ||
159 | unsigned long flags; | ||
160 | |||
161 | spin_lock_irqsave(&loongson2_wait_lock, flags); | ||
162 | cpu_freq = LOONGSON_CHIPCFG0; | ||
163 | LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ | ||
164 | LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */ | ||
165 | spin_unlock_irqrestore(&loongson2_wait_lock, flags); | ||
166 | } | ||
167 | EXPORT_SYMBOL_GPL(loongson2_cpu_wait); | ||
168 | |||
169 | MODULE_AUTHOR("Yanhua <yanh@lemote.com>"); | ||
170 | MODULE_DESCRIPTION("cpufreq driver for Loongson 2F"); | ||
171 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig index 237fa214de9f..a9a14d6e81af 100644 --- a/arch/mips/loongson1/Kconfig +++ b/arch/mips/loongson1/Kconfig | |||
@@ -15,6 +15,7 @@ config LOONGSON1_LS1B | |||
15 | select SYS_SUPPORTS_LITTLE_ENDIAN | 15 | select SYS_SUPPORTS_LITTLE_ENDIAN |
16 | select SYS_SUPPORTS_HIGHMEM | 16 | select SYS_SUPPORTS_HIGHMEM |
17 | select SYS_HAS_EARLY_PRINTK | 17 | select SYS_HAS_EARLY_PRINTK |
18 | select HAVE_CLK | ||
18 | 19 | ||
19 | endchoice | 20 | endchoice |
20 | 21 | ||
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c index 2d98fb030596..1bbbbec12085 100644 --- a/arch/mips/loongson1/common/clock.c +++ b/arch/mips/loongson1/common/clock.c | |||
@@ -38,12 +38,28 @@ struct clk *clk_get(struct device *dev, const char *name) | |||
38 | } | 38 | } |
39 | EXPORT_SYMBOL(clk_get); | 39 | EXPORT_SYMBOL(clk_get); |
40 | 40 | ||
41 | int clk_enable(struct clk *clk) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | EXPORT_SYMBOL(clk_enable); | ||
46 | |||
47 | void clk_disable(struct clk *clk) | ||
48 | { | ||
49 | } | ||
50 | EXPORT_SYMBOL(clk_disable); | ||
51 | |||
41 | unsigned long clk_get_rate(struct clk *clk) | 52 | unsigned long clk_get_rate(struct clk *clk) |
42 | { | 53 | { |
43 | return clk->rate; | 54 | return clk->rate; |
44 | } | 55 | } |
45 | EXPORT_SYMBOL(clk_get_rate); | 56 | EXPORT_SYMBOL(clk_get_rate); |
46 | 57 | ||
58 | void clk_put(struct clk *clk) | ||
59 | { | ||
60 | } | ||
61 | EXPORT_SYMBOL(clk_put); | ||
62 | |||
47 | static void pll_clk_init(struct clk *clk) | 63 | static void pll_clk_init(struct clk *clk) |
48 | { | 64 | { |
49 | u32 pll; | 65 | u32 pll; |
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index b105eca3c020..cd8fcab6b054 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
@@ -401,6 +401,7 @@ static void __init node_mem_init(cnodeid_t node) | |||
401 | * Allocate the node data structures on the node first. | 401 | * Allocate the node data structures on the node first. |
402 | */ | 402 | */ |
403 | __node_data[node] = __va(slot_freepfn << PAGE_SHIFT); | 403 | __node_data[node] = __va(slot_freepfn << PAGE_SHIFT); |
404 | memset(__node_data[node], 0, PAGE_SIZE); | ||
404 | 405 | ||
405 | NODE_DATA(node)->bdata = &bootmem_node_data[node]; | 406 | NODE_DATA(node)->bdata = &bootmem_node_data[node]; |
406 | NODE_DATA(node)->node_start_pfn = start_pfn; | 407 | NODE_DATA(node)->node_start_pfn = start_pfn; |
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 852ae4bb7a85..6d40bc783459 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig | |||
@@ -20,6 +20,7 @@ config MACH_TXX9 | |||
20 | select SYS_SUPPORTS_32BIT_KERNEL | 20 | select SYS_SUPPORTS_32BIT_KERNEL |
21 | select SYS_SUPPORTS_LITTLE_ENDIAN | 21 | select SYS_SUPPORTS_LITTLE_ENDIAN |
22 | select SYS_SUPPORTS_BIG_ENDIAN | 22 | select SYS_SUPPORTS_BIG_ENDIAN |
23 | select HAVE_CLK | ||
23 | 24 | ||
24 | config TOSHIBA_JMR3927 | 25 | config TOSHIBA_JMR3927 |
25 | bool "Toshiba JMR-TX3927 board" | 26 | bool "Toshiba JMR-TX3927 board" |
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts index 852e5b27485d..57573bd52caa 100644 --- a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts +++ b/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts | |||
@@ -56,7 +56,7 @@ | |||
56 | ranges = <0x0 0x0 0xffe00000 0x100000>; | 56 | ranges = <0x0 0x0 0xffe00000 0x100000>; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | pci0: pcie@ffe08000 { | 59 | pci2: pcie@ffe08000 { |
60 | reg = <0 0xffe08000 0 0x1000>; | 60 | reg = <0 0xffe08000 0 0x1000>; |
61 | status = "disabled"; | 61 | status = "disabled"; |
62 | }; | 62 | }; |
@@ -76,7 +76,7 @@ | |||
76 | }; | 76 | }; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | pci2: pcie@ffe0a000 { | 79 | pci0: pcie@ffe0a000 { |
80 | reg = <0 0xffe0a000 0 0x1000>; | 80 | reg = <0 0xffe0a000 0 0x1000>; |
81 | ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000 | 81 | ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000 |
82 | 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; | 82 | 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; |
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts index b5a56ca51cf7..470247ea68b4 100644 --- a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts +++ b/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts | |||
@@ -56,7 +56,7 @@ | |||
56 | ranges = <0x0 0xf 0xffe00000 0x100000>; | 56 | ranges = <0x0 0xf 0xffe00000 0x100000>; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | pci0: pcie@fffe08000 { | 59 | pci2: pcie@fffe08000 { |
60 | reg = <0xf 0xffe08000 0 0x1000>; | 60 | reg = <0xf 0xffe08000 0 0x1000>; |
61 | status = "disabled"; | 61 | status = "disabled"; |
62 | }; | 62 | }; |
@@ -76,7 +76,7 @@ | |||
76 | }; | 76 | }; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | pci2: pcie@fffe0a000 { | 79 | pci0: pcie@fffe0a000 { |
80 | reg = <0xf 0xffe0a000 0 0x1000>; | 80 | reg = <0xf 0xffe0a000 0 0x1000>; |
81 | ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000 | 81 | ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000 |
82 | 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; | 82 | 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; |
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts index 22a215e94162..6cdcadc80c30 100644 --- a/arch/powerpc/boot/dts/p3041ds.dts +++ b/arch/powerpc/boot/dts/p3041ds.dts | |||
@@ -58,7 +58,7 @@ | |||
58 | #size-cells = <1>; | 58 | #size-cells = <1>; |
59 | compatible = "spansion,s25sl12801"; | 59 | compatible = "spansion,s25sl12801"; |
60 | reg = <0>; | 60 | reg = <0>; |
61 | spi-max-frequency = <40000000>; /* input clock */ | 61 | spi-max-frequency = <35000000>; /* input clock */ |
62 | partition@u-boot { | 62 | partition@u-boot { |
63 | label = "u-boot"; | 63 | label = "u-boot"; |
64 | reg = <0x00000000 0x00100000>; | 64 | reg = <0x00000000 0x00100000>; |
diff --git a/arch/powerpc/configs/chroma_defconfig b/arch/powerpc/configs/chroma_defconfig index b1f9597fe312..29bb11ec6c64 100644 --- a/arch/powerpc/configs/chroma_defconfig +++ b/arch/powerpc/configs/chroma_defconfig | |||
@@ -21,8 +21,8 @@ CONFIG_CGROUP_DEVICE=y | |||
21 | CONFIG_CPUSETS=y | 21 | CONFIG_CPUSETS=y |
22 | CONFIG_CGROUP_CPUACCT=y | 22 | CONFIG_CGROUP_CPUACCT=y |
23 | CONFIG_RESOURCE_COUNTERS=y | 23 | CONFIG_RESOURCE_COUNTERS=y |
24 | CONFIG_CGROUP_MEM_RES_CTLR=y | 24 | CONFIG_CGROUP_MEMCG=y |
25 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 25 | CONFIG_CGROUP_MEMCG_SWAP=y |
26 | CONFIG_NAMESPACES=y | 26 | CONFIG_NAMESPACES=y |
27 | CONFIG_RELAY=y | 27 | CONFIG_RELAY=y |
28 | CONFIG_BLK_DEV_INITRD=y | 28 | CONFIG_BLK_DEV_INITRD=y |
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index ab523f3c1731..9ecf6e35cd8d 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S | |||
@@ -67,7 +67,6 @@ kvmppc_skip_Hinterrupt: | |||
67 | #elif defined(CONFIG_PPC_BOOK3S_32) | 67 | #elif defined(CONFIG_PPC_BOOK3S_32) |
68 | 68 | ||
69 | #define FUNC(name) name | 69 | #define FUNC(name) name |
70 | #define MTMSR_EERI(reg) mtmsr (reg) | ||
71 | 70 | ||
72 | .macro INTERRUPT_TRAMPOLINE intno | 71 | .macro INTERRUPT_TRAMPOLINE intno |
73 | 72 | ||
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 89ee02c54561..3c732acf331d 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
@@ -208,6 +208,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) | |||
208 | u8 __iomem *lbc_lcs0_ba = NULL; | 208 | u8 __iomem *lbc_lcs0_ba = NULL; |
209 | u8 __iomem *lbc_lcs1_ba = NULL; | 209 | u8 __iomem *lbc_lcs1_ba = NULL; |
210 | phys_addr_t cs0_addr, cs1_addr; | 210 | phys_addr_t cs0_addr, cs1_addr; |
211 | u32 br0, or0, br1, or1; | ||
211 | const __be32 *iprop; | 212 | const __be32 *iprop; |
212 | unsigned int num_laws; | 213 | unsigned int num_laws; |
213 | u8 b; | 214 | u8 b; |
@@ -256,11 +257,70 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) | |||
256 | } | 257 | } |
257 | num_laws = be32_to_cpup(iprop); | 258 | num_laws = be32_to_cpup(iprop); |
258 | 259 | ||
259 | cs0_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[0].br)); | 260 | /* |
260 | cs1_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[1].br)); | 261 | * Indirect mode requires both BR0 and BR1 to be set to "GPCM", |
262 | * otherwise writes to these addresses won't actually appear on the | ||
263 | * local bus, and so the PIXIS won't see them. | ||
264 | * | ||
265 | * In FCM mode, writes go to the NAND controller, which does not pass | ||
266 | * them to the localbus directly. So we force BR0 and BR1 into GPCM | ||
267 | * mode, since we don't care about what's behind the localbus any | ||
268 | * more. | ||
269 | */ | ||
270 | br0 = in_be32(&lbc->bank[0].br); | ||
271 | br1 = in_be32(&lbc->bank[1].br); | ||
272 | or0 = in_be32(&lbc->bank[0].or); | ||
273 | or1 = in_be32(&lbc->bank[1].or); | ||
274 | |||
275 | /* Make sure CS0 and CS1 are programmed */ | ||
276 | if (!(br0 & BR_V) || !(br1 & BR_V)) { | ||
277 | pr_err("p1022ds: CS0 and/or CS1 is not programmed\n"); | ||
278 | goto exit; | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Use the existing BRx/ORx values if it's already GPCM. Otherwise, | ||
283 | * force the values to simple 32KB GPCM windows with the most | ||
284 | * conservative timing. | ||
285 | */ | ||
286 | if ((br0 & BR_MSEL) != BR_MS_GPCM) { | ||
287 | br0 = (br0 & BR_BA) | BR_V; | ||
288 | or0 = 0xFFFF8000 | 0xFF7; | ||
289 | out_be32(&lbc->bank[0].br, br0); | ||
290 | out_be32(&lbc->bank[0].or, or0); | ||
291 | } | ||
292 | if ((br1 & BR_MSEL) != BR_MS_GPCM) { | ||
293 | br1 = (br1 & BR_BA) | BR_V; | ||
294 | or1 = 0xFFFF8000 | 0xFF7; | ||
295 | out_be32(&lbc->bank[1].br, br1); | ||
296 | out_be32(&lbc->bank[1].or, or1); | ||
297 | } | ||
298 | |||
299 | cs0_addr = lbc_br_to_phys(ecm, num_laws, br0); | ||
300 | if (!cs0_addr) { | ||
301 | pr_err("p1022ds: could not determine physical address for CS0" | ||
302 | " (BR0=%08x)\n", br0); | ||
303 | goto exit; | ||
304 | } | ||
305 | cs1_addr = lbc_br_to_phys(ecm, num_laws, br1); | ||
306 | if (!cs0_addr) { | ||
307 | pr_err("p1022ds: could not determine physical address for CS1" | ||
308 | " (BR1=%08x)\n", br1); | ||
309 | goto exit; | ||
310 | } | ||
261 | 311 | ||
262 | lbc_lcs0_ba = ioremap(cs0_addr, 1); | 312 | lbc_lcs0_ba = ioremap(cs0_addr, 1); |
313 | if (!lbc_lcs0_ba) { | ||
314 | pr_err("p1022ds: could not ioremap CS0 address %llx\n", | ||
315 | (unsigned long long)cs0_addr); | ||
316 | goto exit; | ||
317 | } | ||
263 | lbc_lcs1_ba = ioremap(cs1_addr, 1); | 318 | lbc_lcs1_ba = ioremap(cs1_addr, 1); |
319 | if (!lbc_lcs1_ba) { | ||
320 | pr_err("p1022ds: could not ioremap CS1 address %llx\n", | ||
321 | (unsigned long long)cs1_addr); | ||
322 | goto exit; | ||
323 | } | ||
264 | 324 | ||
265 | /* Make sure we're in indirect mode first. */ | 325 | /* Make sure we're in indirect mode first. */ |
266 | if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != | 326 | if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != |
@@ -419,18 +479,6 @@ void __init p1022_ds_pic_init(void) | |||
419 | 479 | ||
420 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) | 480 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) |
421 | 481 | ||
422 | /* | ||
423 | * Disables a node in the device tree. | ||
424 | * | ||
425 | * This function is called before kmalloc() is available, so the 'new' object | ||
426 | * should be allocated in the global area. The easiest way is to do that is | ||
427 | * to allocate one static local variable for each call to this function. | ||
428 | */ | ||
429 | static void __init disable_one_node(struct device_node *np, struct property *new) | ||
430 | { | ||
431 | prom_update_property(np, new); | ||
432 | } | ||
433 | |||
434 | /* TRUE if there is a "video=fslfb" command-line parameter. */ | 482 | /* TRUE if there is a "video=fslfb" command-line parameter. */ |
435 | static bool fslfb; | 483 | static bool fslfb; |
436 | 484 | ||
@@ -493,28 +541,58 @@ static void __init p1022_ds_setup_arch(void) | |||
493 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; | 541 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; |
494 | 542 | ||
495 | /* | 543 | /* |
496 | * Disable the NOR flash node if there is video=fslfb... command-line | 544 | * Disable the NOR and NAND flash nodes if there is video=fslfb... |
497 | * parameter. When the DIU is active, NOR flash is unavailable, so we | 545 | * command-line parameter. When the DIU is active, the localbus is |
498 | * have to disable the node before the MTD driver loads. | 546 | * unavailable, so we have to disable these nodes before the MTD |
547 | * driver loads. | ||
499 | */ | 548 | */ |
500 | if (fslfb) { | 549 | if (fslfb) { |
501 | struct device_node *np = | 550 | struct device_node *np = |
502 | of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); | 551 | of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); |
503 | 552 | ||
504 | if (np) { | 553 | if (np) { |
505 | np = of_find_compatible_node(np, NULL, "cfi-flash"); | 554 | struct device_node *np2; |
506 | if (np) { | 555 | |
556 | of_node_get(np); | ||
557 | np2 = of_find_compatible_node(np, NULL, "cfi-flash"); | ||
558 | if (np2) { | ||
507 | static struct property nor_status = { | 559 | static struct property nor_status = { |
508 | .name = "status", | 560 | .name = "status", |
509 | .value = "disabled", | 561 | .value = "disabled", |
510 | .length = sizeof("disabled"), | 562 | .length = sizeof("disabled"), |
511 | }; | 563 | }; |
512 | 564 | ||
565 | /* | ||
566 | * prom_update_property() is called before | ||
567 | * kmalloc() is available, so the 'new' object | ||
568 | * should be allocated in the global area. | ||
569 | * The easiest way is to do that is to | ||
570 | * allocate one static local variable for each | ||
571 | * call to this function. | ||
572 | */ | ||
513 | pr_info("p1022ds: disabling %s node", | 573 | pr_info("p1022ds: disabling %s node", |
514 | np->full_name); | 574 | np2->full_name); |
515 | disable_one_node(np, &nor_status); | 575 | prom_update_property(np2, &nor_status); |
516 | of_node_put(np); | 576 | of_node_put(np2); |
517 | } | 577 | } |
578 | |||
579 | of_node_get(np); | ||
580 | np2 = of_find_compatible_node(np, NULL, | ||
581 | "fsl,elbc-fcm-nand"); | ||
582 | if (np2) { | ||
583 | static struct property nand_status = { | ||
584 | .name = "status", | ||
585 | .value = "disabled", | ||
586 | .length = sizeof("disabled"), | ||
587 | }; | ||
588 | |||
589 | pr_info("p1022ds: disabling %s node", | ||
590 | np2->full_name); | ||
591 | prom_update_property(np2, &nand_status); | ||
592 | of_node_put(np2); | ||
593 | } | ||
594 | |||
595 | of_node_put(np); | ||
518 | } | 596 | } |
519 | 597 | ||
520 | } | 598 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index d544d7816df3..dba1ce235da5 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -186,10 +186,13 @@ static void spufs_prune_dir(struct dentry *dir) | |||
186 | static int spufs_rmdir(struct inode *parent, struct dentry *dir) | 186 | static int spufs_rmdir(struct inode *parent, struct dentry *dir) |
187 | { | 187 | { |
188 | /* remove all entries */ | 188 | /* remove all entries */ |
189 | int res; | ||
189 | spufs_prune_dir(dir); | 190 | spufs_prune_dir(dir); |
190 | d_drop(dir); | 191 | d_drop(dir); |
191 | 192 | res = simple_rmdir(parent, dir); | |
192 | return simple_rmdir(parent, dir); | 193 | /* We have to give up the mm_struct */ |
194 | spu_forget(SPUFS_I(dir->d_inode)->i_ctx); | ||
195 | return res; | ||
193 | } | 196 | } |
194 | 197 | ||
195 | static int spufs_fill_dir(struct dentry *dir, | 198 | static int spufs_fill_dir(struct dentry *dir, |
@@ -245,9 +248,6 @@ static int spufs_dir_close(struct inode *inode, struct file *file) | |||
245 | mutex_unlock(&parent->i_mutex); | 248 | mutex_unlock(&parent->i_mutex); |
246 | WARN_ON(ret); | 249 | WARN_ON(ret); |
247 | 250 | ||
248 | /* We have to give up the mm_struct */ | ||
249 | spu_forget(ctx); | ||
250 | |||
251 | return dcache_dir_close(inode, file); | 251 | return dcache_dir_close(inode, file); |
252 | } | 252 | } |
253 | 253 | ||
@@ -450,28 +450,24 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, | |||
450 | struct spu_context *neighbor; | 450 | struct spu_context *neighbor; |
451 | struct path path = {.mnt = mnt, .dentry = dentry}; | 451 | struct path path = {.mnt = mnt, .dentry = dentry}; |
452 | 452 | ||
453 | ret = -EPERM; | ||
454 | if ((flags & SPU_CREATE_NOSCHED) && | 453 | if ((flags & SPU_CREATE_NOSCHED) && |
455 | !capable(CAP_SYS_NICE)) | 454 | !capable(CAP_SYS_NICE)) |
456 | goto out_unlock; | 455 | return -EPERM; |
457 | 456 | ||
458 | ret = -EINVAL; | ||
459 | if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE)) | 457 | if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE)) |
460 | == SPU_CREATE_ISOLATE) | 458 | == SPU_CREATE_ISOLATE) |
461 | goto out_unlock; | 459 | return -EINVAL; |
462 | 460 | ||
463 | ret = -ENODEV; | ||
464 | if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader) | 461 | if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader) |
465 | goto out_unlock; | 462 | return -ENODEV; |
466 | 463 | ||
467 | gang = NULL; | 464 | gang = NULL; |
468 | neighbor = NULL; | 465 | neighbor = NULL; |
469 | affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU); | 466 | affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU); |
470 | if (affinity) { | 467 | if (affinity) { |
471 | gang = SPUFS_I(inode)->i_gang; | 468 | gang = SPUFS_I(inode)->i_gang; |
472 | ret = -EINVAL; | ||
473 | if (!gang) | 469 | if (!gang) |
474 | goto out_unlock; | 470 | return -EINVAL; |
475 | mutex_lock(&gang->aff_mutex); | 471 | mutex_lock(&gang->aff_mutex); |
476 | neighbor = spufs_assert_affinity(flags, gang, aff_filp); | 472 | neighbor = spufs_assert_affinity(flags, gang, aff_filp); |
477 | if (IS_ERR(neighbor)) { | 473 | if (IS_ERR(neighbor)) { |
@@ -492,22 +488,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, | |||
492 | } | 488 | } |
493 | 489 | ||
494 | ret = spufs_context_open(&path); | 490 | ret = spufs_context_open(&path); |
495 | if (ret < 0) { | 491 | if (ret < 0) |
496 | WARN_ON(spufs_rmdir(inode, dentry)); | 492 | WARN_ON(spufs_rmdir(inode, dentry)); |
497 | if (affinity) | ||
498 | mutex_unlock(&gang->aff_mutex); | ||
499 | mutex_unlock(&inode->i_mutex); | ||
500 | spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); | ||
501 | goto out; | ||
502 | } | ||
503 | 493 | ||
504 | out_aff_unlock: | 494 | out_aff_unlock: |
505 | if (affinity) | 495 | if (affinity) |
506 | mutex_unlock(&gang->aff_mutex); | 496 | mutex_unlock(&gang->aff_mutex); |
507 | out_unlock: | ||
508 | mutex_unlock(&inode->i_mutex); | ||
509 | out: | ||
510 | dput(dentry); | ||
511 | return ret; | 497 | return ret; |
512 | } | 498 | } |
513 | 499 | ||
@@ -580,18 +566,13 @@ static int spufs_create_gang(struct inode *inode, | |||
580 | int ret; | 566 | int ret; |
581 | 567 | ||
582 | ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); | 568 | ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); |
583 | if (ret) | 569 | if (!ret) { |
584 | goto out; | 570 | ret = spufs_gang_open(&path); |
585 | 571 | if (ret < 0) { | |
586 | ret = spufs_gang_open(&path); | 572 | int err = simple_rmdir(inode, dentry); |
587 | if (ret < 0) { | 573 | WARN_ON(err); |
588 | int err = simple_rmdir(inode, dentry); | 574 | } |
589 | WARN_ON(err); | ||
590 | } | 575 | } |
591 | |||
592 | out: | ||
593 | mutex_unlock(&inode->i_mutex); | ||
594 | dput(dentry); | ||
595 | return ret; | 576 | return ret; |
596 | } | 577 | } |
597 | 578 | ||
@@ -601,40 +582,32 @@ static struct file_system_type spufs_type; | |||
601 | long spufs_create(struct path *path, struct dentry *dentry, | 582 | long spufs_create(struct path *path, struct dentry *dentry, |
602 | unsigned int flags, umode_t mode, struct file *filp) | 583 | unsigned int flags, umode_t mode, struct file *filp) |
603 | { | 584 | { |
585 | struct inode *dir = path->dentry->d_inode; | ||
604 | int ret; | 586 | int ret; |
605 | 587 | ||
606 | ret = -EINVAL; | ||
607 | /* check if we are on spufs */ | 588 | /* check if we are on spufs */ |
608 | if (path->dentry->d_sb->s_type != &spufs_type) | 589 | if (path->dentry->d_sb->s_type != &spufs_type) |
609 | goto out; | 590 | return -EINVAL; |
610 | 591 | ||
611 | /* don't accept undefined flags */ | 592 | /* don't accept undefined flags */ |
612 | if (flags & (~SPU_CREATE_FLAG_ALL)) | 593 | if (flags & (~SPU_CREATE_FLAG_ALL)) |
613 | goto out; | 594 | return -EINVAL; |
614 | 595 | ||
615 | /* only threads can be underneath a gang */ | 596 | /* only threads can be underneath a gang */ |
616 | if (path->dentry != path->dentry->d_sb->s_root) { | 597 | if (path->dentry != path->dentry->d_sb->s_root) |
617 | if ((flags & SPU_CREATE_GANG) || | 598 | if ((flags & SPU_CREATE_GANG) || !SPUFS_I(dir)->i_gang) |
618 | !SPUFS_I(path->dentry->d_inode)->i_gang) | 599 | return -EINVAL; |
619 | goto out; | ||
620 | } | ||
621 | 600 | ||
622 | mode &= ~current_umask(); | 601 | mode &= ~current_umask(); |
623 | 602 | ||
624 | if (flags & SPU_CREATE_GANG) | 603 | if (flags & SPU_CREATE_GANG) |
625 | ret = spufs_create_gang(path->dentry->d_inode, | 604 | ret = spufs_create_gang(dir, dentry, path->mnt, mode); |
626 | dentry, path->mnt, mode); | ||
627 | else | 605 | else |
628 | ret = spufs_create_context(path->dentry->d_inode, | 606 | ret = spufs_create_context(dir, dentry, path->mnt, flags, mode, |
629 | dentry, path->mnt, flags, mode, | ||
630 | filp); | 607 | filp); |
631 | if (ret >= 0) | 608 | if (ret >= 0) |
632 | fsnotify_mkdir(path->dentry->d_inode, dentry); | 609 | fsnotify_mkdir(dir, dentry); |
633 | return ret; | ||
634 | 610 | ||
635 | out: | ||
636 | mutex_unlock(&path->dentry->d_inode->i_mutex); | ||
637 | dput(dentry); | ||
638 | return ret; | 611 | return ret; |
639 | } | 612 | } |
640 | 613 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index 5665dcc382c7..5b7d8ffbf890 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c | |||
@@ -70,7 +70,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags, | |||
70 | ret = PTR_ERR(dentry); | 70 | ret = PTR_ERR(dentry); |
71 | if (!IS_ERR(dentry)) { | 71 | if (!IS_ERR(dentry)) { |
72 | ret = spufs_create(&path, dentry, flags, mode, neighbor); | 72 | ret = spufs_create(&path, dentry, flags, mode, neighbor); |
73 | path_put(&path); | 73 | done_path_create(&path, dentry); |
74 | } | 74 | } |
75 | 75 | ||
76 | return ret; | 76 | return ret; |
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h index 60c9c0bd5ba2..2aa97ddb7b78 100644 --- a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h +++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2009-2010 Freescale Semiconductor, Inc | 2 | * Copyright 2009-2010, 2012 Freescale Semiconductor, Inc |
3 | * | 3 | * |
4 | * QorIQ based Cache Controller Memory Mapped Registers | 4 | * QorIQ based Cache Controller Memory Mapped Registers |
5 | * | 5 | * |
@@ -91,7 +91,7 @@ struct mpc85xx_l2ctlr { | |||
91 | 91 | ||
92 | struct sram_parameters { | 92 | struct sram_parameters { |
93 | unsigned int sram_size; | 93 | unsigned int sram_size; |
94 | uint64_t sram_offset; | 94 | phys_addr_t sram_offset; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | extern int instantiate_cache_sram(struct platform_device *dev, | 97 | extern int instantiate_cache_sram(struct platform_device *dev, |
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c index cedabd0f4bfe..68ac3aacb191 100644 --- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c +++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2009-2010 Freescale Semiconductor, Inc. | 2 | * Copyright 2009-2010, 2012 Freescale Semiconductor, Inc. |
3 | * | 3 | * |
4 | * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation | 4 | * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation |
5 | * | 5 | * |
@@ -31,24 +31,21 @@ static char *sram_size; | |||
31 | static char *sram_offset; | 31 | static char *sram_offset; |
32 | struct mpc85xx_l2ctlr __iomem *l2ctlr; | 32 | struct mpc85xx_l2ctlr __iomem *l2ctlr; |
33 | 33 | ||
34 | static long get_cache_sram_size(void) | 34 | static int get_cache_sram_params(struct sram_parameters *sram_params) |
35 | { | 35 | { |
36 | unsigned long val; | 36 | unsigned long long addr; |
37 | unsigned int size; | ||
37 | 38 | ||
38 | if (!sram_size || (strict_strtoul(sram_size, 0, &val) < 0)) | 39 | if (!sram_size || (kstrtouint(sram_size, 0, &size) < 0)) |
39 | return -EINVAL; | 40 | return -EINVAL; |
40 | 41 | ||
41 | return val; | 42 | if (!sram_offset || (kstrtoull(sram_offset, 0, &addr) < 0)) |
42 | } | ||
43 | |||
44 | static long get_cache_sram_offset(void) | ||
45 | { | ||
46 | unsigned long val; | ||
47 | |||
48 | if (!sram_offset || (strict_strtoul(sram_offset, 0, &val) < 0)) | ||
49 | return -EINVAL; | 43 | return -EINVAL; |
50 | 44 | ||
51 | return val; | 45 | sram_params->sram_offset = addr; |
46 | sram_params->sram_size = size; | ||
47 | |||
48 | return 0; | ||
52 | } | 49 | } |
53 | 50 | ||
54 | static int __init get_size_from_cmdline(char *str) | 51 | static int __init get_size_from_cmdline(char *str) |
@@ -93,17 +90,9 @@ static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev) | |||
93 | } | 90 | } |
94 | l2cache_size = *prop; | 91 | l2cache_size = *prop; |
95 | 92 | ||
96 | sram_params.sram_size = get_cache_sram_size(); | 93 | if (get_cache_sram_params(&sram_params)) { |
97 | if ((int)sram_params.sram_size <= 0) { | ||
98 | dev_err(&dev->dev, | ||
99 | "Entire L2 as cache, Aborting Cache-SRAM stuff\n"); | ||
100 | return -EINVAL; | ||
101 | } | ||
102 | |||
103 | sram_params.sram_offset = get_cache_sram_offset(); | ||
104 | if ((int64_t)sram_params.sram_offset <= 0) { | ||
105 | dev_err(&dev->dev, | 94 | dev_err(&dev->dev, |
106 | "Entire L2 as cache, provide a valid sram offset\n"); | 95 | "Entire L2 as cache, provide valid sram offset and size\n"); |
107 | return -EINVAL; | 96 | return -EINVAL; |
108 | } | 97 | } |
109 | 98 | ||
@@ -125,14 +114,14 @@ static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev) | |||
125 | * Write bits[0-17] to srbar0 | 114 | * Write bits[0-17] to srbar0 |
126 | */ | 115 | */ |
127 | out_be32(&l2ctlr->srbar0, | 116 | out_be32(&l2ctlr->srbar0, |
128 | sram_params.sram_offset & L2SRAM_BAR_MSK_LO18); | 117 | lower_32_bits(sram_params.sram_offset) & L2SRAM_BAR_MSK_LO18); |
129 | 118 | ||
130 | /* | 119 | /* |
131 | * Write bits[18-21] to srbare0 | 120 | * Write bits[18-21] to srbare0 |
132 | */ | 121 | */ |
133 | #ifdef CONFIG_PHYS_64BIT | 122 | #ifdef CONFIG_PHYS_64BIT |
134 | out_be32(&l2ctlr->srbarea0, | 123 | out_be32(&l2ctlr->srbarea0, |
135 | (sram_params.sram_offset >> 32) & L2SRAM_BARE_MSK_HI4); | 124 | upper_32_bits(sram_params.sram_offset) & L2SRAM_BARE_MSK_HI4); |
136 | #endif | 125 | #endif |
137 | 126 | ||
138 | clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI); | 127 | clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI); |
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c index 253dce98c16e..14469cf9df68 100644 --- a/arch/powerpc/sysdev/xics/icp-hv.c +++ b/arch/powerpc/sysdev/xics/icp-hv.c | |||
@@ -111,7 +111,7 @@ static unsigned int icp_hv_get_irq(void) | |||
111 | if (vec == XICS_IRQ_SPURIOUS) | 111 | if (vec == XICS_IRQ_SPURIOUS) |
112 | return NO_IRQ; | 112 | return NO_IRQ; |
113 | 113 | ||
114 | irq = irq_radix_revmap_lookup(xics_host, vec); | 114 | irq = irq_find_mapping(xics_host, vec); |
115 | if (likely(irq != NO_IRQ)) { | 115 | if (likely(irq != NO_IRQ)) { |
116 | xics_push_cppr(vec); | 116 | xics_push_cppr(vec); |
117 | return irq; | 117 | return irq; |
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index 4c79b6fbee1c..48861d3fcd07 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c | |||
@@ -119,7 +119,7 @@ static unsigned int icp_native_get_irq(void) | |||
119 | if (vec == XICS_IRQ_SPURIOUS) | 119 | if (vec == XICS_IRQ_SPURIOUS) |
120 | return NO_IRQ; | 120 | return NO_IRQ; |
121 | 121 | ||
122 | irq = irq_radix_revmap_lookup(xics_host, vec); | 122 | irq = irq_find_mapping(xics_host, vec); |
123 | if (likely(irq != NO_IRQ)) { | 123 | if (likely(irq != NO_IRQ)) { |
124 | xics_push_cppr(vec); | 124 | xics_push_cppr(vec); |
125 | return irq; | 125 | return irq; |
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index cd1d18db92c6..9049d9f44485 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c | |||
@@ -329,9 +329,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq, | |||
329 | 329 | ||
330 | pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw); | 330 | pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw); |
331 | 331 | ||
332 | /* Insert the interrupt mapping into the radix tree for fast lookup */ | ||
333 | irq_radix_revmap_insert(xics_host, virq, hw); | ||
334 | |||
335 | /* They aren't all level sensitive but we just don't really know */ | 332 | /* They aren't all level sensitive but we just don't really know */ |
336 | irq_set_status_flags(virq, IRQ_LEVEL); | 333 | irq_set_status_flags(virq, IRQ_LEVEL); |
337 | 334 | ||
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 296cd32466df..76de6b68487c 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -90,6 +90,7 @@ config S390 | |||
90 | select HAVE_MEMBLOCK_NODE_MAP | 90 | select HAVE_MEMBLOCK_NODE_MAP |
91 | select HAVE_CMPXCHG_LOCAL | 91 | select HAVE_CMPXCHG_LOCAL |
92 | select ARCH_DISCARD_MEMBLOCK | 92 | select ARCH_DISCARD_MEMBLOCK |
93 | select BUILDTIME_EXTABLE_SORT | ||
93 | select ARCH_INLINE_SPIN_TRYLOCK | 94 | select ARCH_INLINE_SPIN_TRYLOCK |
94 | select ARCH_INLINE_SPIN_TRYLOCK_BH | 95 | select ARCH_INLINE_SPIN_TRYLOCK_BH |
95 | select ARCH_INLINE_SPIN_LOCK | 96 | select ARCH_INLINE_SPIN_LOCK |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 37d2bf267964..f39cd710980b 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -7,13 +7,16 @@ CONFIG_TASK_DELAY_ACCT=y | |||
7 | CONFIG_TASK_XACCT=y | 7 | CONFIG_TASK_XACCT=y |
8 | CONFIG_TASK_IO_ACCOUNTING=y | 8 | CONFIG_TASK_IO_ACCOUNTING=y |
9 | CONFIG_AUDIT=y | 9 | CONFIG_AUDIT=y |
10 | CONFIG_NO_HZ=y | ||
11 | CONFIG_HIGH_RES_TIMERS=y | ||
12 | CONFIG_RCU_FAST_NO_HZ=y | ||
10 | CONFIG_IKCONFIG=y | 13 | CONFIG_IKCONFIG=y |
11 | CONFIG_IKCONFIG_PROC=y | 14 | CONFIG_IKCONFIG_PROC=y |
12 | CONFIG_CGROUPS=y | 15 | CONFIG_CGROUPS=y |
13 | CONFIG_CPUSETS=y | 16 | CONFIG_CPUSETS=y |
14 | CONFIG_CGROUP_CPUACCT=y | 17 | CONFIG_CGROUP_CPUACCT=y |
15 | CONFIG_RESOURCE_COUNTERS=y | 18 | CONFIG_RESOURCE_COUNTERS=y |
16 | CONFIG_CGROUP_MEM_RES_CTLR=y | 19 | CONFIG_CGROUP_MEMCG=y |
17 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 20 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y |
18 | CONFIG_CGROUP_SCHED=y | 21 | CONFIG_CGROUP_SCHED=y |
19 | CONFIG_RT_GROUP_SCHED=y | 22 | CONFIG_RT_GROUP_SCHED=y |
@@ -35,8 +38,6 @@ CONFIG_MODVERSIONS=y | |||
35 | CONFIG_PARTITION_ADVANCED=y | 38 | CONFIG_PARTITION_ADVANCED=y |
36 | CONFIG_IBM_PARTITION=y | 39 | CONFIG_IBM_PARTITION=y |
37 | CONFIG_DEFAULT_DEADLINE=y | 40 | CONFIG_DEFAULT_DEADLINE=y |
38 | CONFIG_NO_HZ=y | ||
39 | CONFIG_HIGH_RES_TIMERS=y | ||
40 | CONFIG_PREEMPT=y | 41 | CONFIG_PREEMPT=y |
41 | CONFIG_MEMORY_HOTPLUG=y | 42 | CONFIG_MEMORY_HOTPLUG=y |
42 | CONFIG_MEMORY_HOTREMOVE=y | 43 | CONFIG_MEMORY_HOTREMOVE=y |
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 5c63615f1349..b749c5733657 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
12 | #include <asm/tlbflush.h> | 12 | #include <asm/tlbflush.h> |
13 | #include <asm/ctl_reg.h> | 13 | #include <asm/ctl_reg.h> |
14 | #include <asm-generic/mm_hooks.h> | ||
15 | 14 | ||
16 | static inline int init_new_context(struct task_struct *tsk, | 15 | static inline int init_new_context(struct task_struct *tsk, |
17 | struct mm_struct *mm) | 16 | struct mm_struct *mm) |
@@ -58,7 +57,7 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) | |||
58 | pgd_t *pgd = mm->pgd; | 57 | pgd_t *pgd = mm->pgd; |
59 | 58 | ||
60 | S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); | 59 | S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); |
61 | if (user_mode != HOME_SPACE_MODE) { | 60 | if (addressing_mode != HOME_SPACE_MODE) { |
62 | /* Load primary space page table origin. */ | 61 | /* Load primary space page table origin. */ |
63 | asm volatile(LCTL_OPCODE" 1,1,%0\n" | 62 | asm volatile(LCTL_OPCODE" 1,1,%0\n" |
64 | : : "m" (S390_lowcore.user_asce) ); | 63 | : : "m" (S390_lowcore.user_asce) ); |
@@ -91,4 +90,17 @@ static inline void activate_mm(struct mm_struct *prev, | |||
91 | switch_mm(prev, next, current); | 90 | switch_mm(prev, next, current); |
92 | } | 91 | } |
93 | 92 | ||
93 | static inline void arch_dup_mmap(struct mm_struct *oldmm, | ||
94 | struct mm_struct *mm) | ||
95 | { | ||
96 | #ifdef CONFIG_64BIT | ||
97 | if (oldmm->context.asce_limit < mm->context.asce_limit) | ||
98 | crst_table_downgrade(mm, oldmm->context.asce_limit); | ||
99 | #endif | ||
100 | } | ||
101 | |||
102 | static inline void arch_exit_mmap(struct mm_struct *mm) | ||
103 | { | ||
104 | } | ||
105 | |||
94 | #endif /* __S390_MMU_CONTEXT_H */ | 106 | #endif /* __S390_MMU_CONTEXT_H */ |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index c40fa91e38a8..11e4e3236937 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -120,7 +120,9 @@ struct stack_frame { | |||
120 | regs->psw.mask = psw_user_bits | PSW_MASK_BA; \ | 120 | regs->psw.mask = psw_user_bits | PSW_MASK_BA; \ |
121 | regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ | 121 | regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ |
122 | regs->gprs[15] = new_stackp; \ | 122 | regs->gprs[15] = new_stackp; \ |
123 | __tlb_flush_mm(current->mm); \ | ||
123 | crst_table_downgrade(current->mm, 1UL << 31); \ | 124 | crst_table_downgrade(current->mm, 1UL << 31); \ |
125 | update_mm(current->mm, current); \ | ||
124 | } while (0) | 126 | } while (0) |
125 | 127 | ||
126 | /* Forward declaration, a strange C thing */ | 128 | /* Forward declaration, a strange C thing */ |
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 57e80534375a..e6859d16ee2d 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
@@ -60,7 +60,7 @@ void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr, | |||
60 | #define SECONDARY_SPACE_MODE 2 | 60 | #define SECONDARY_SPACE_MODE 2 |
61 | #define HOME_SPACE_MODE 3 | 61 | #define HOME_SPACE_MODE 3 |
62 | 62 | ||
63 | extern unsigned int user_mode; | 63 | extern unsigned int addressing_mode; |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Machine features detected in head.S | 66 | * Machine features detected in head.S |
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 21be961e8a43..ba500d8dc392 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
@@ -110,6 +110,7 @@ struct debug_view debug_raw_view = { | |||
110 | NULL, | 110 | NULL, |
111 | NULL | 111 | NULL |
112 | }; | 112 | }; |
113 | EXPORT_SYMBOL(debug_raw_view); | ||
113 | 114 | ||
114 | struct debug_view debug_hex_ascii_view = { | 115 | struct debug_view debug_hex_ascii_view = { |
115 | "hex_ascii", | 116 | "hex_ascii", |
@@ -119,6 +120,7 @@ struct debug_view debug_hex_ascii_view = { | |||
119 | NULL, | 120 | NULL, |
120 | NULL | 121 | NULL |
121 | }; | 122 | }; |
123 | EXPORT_SYMBOL(debug_hex_ascii_view); | ||
122 | 124 | ||
123 | static struct debug_view debug_level_view = { | 125 | static struct debug_view debug_level_view = { |
124 | "level", | 126 | "level", |
@@ -155,6 +157,7 @@ struct debug_view debug_sprintf_view = { | |||
155 | NULL, | 157 | NULL, |
156 | NULL | 158 | NULL |
157 | }; | 159 | }; |
160 | EXPORT_SYMBOL(debug_sprintf_view); | ||
158 | 161 | ||
159 | /* used by dump analysis tools to determine version of debug feature */ | 162 | /* used by dump analysis tools to determine version of debug feature */ |
160 | static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION; | 163 | static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION; |
@@ -730,6 +733,7 @@ debug_info_t *debug_register(const char *name, int pages_per_area, | |||
730 | return debug_register_mode(name, pages_per_area, nr_areas, buf_size, | 733 | return debug_register_mode(name, pages_per_area, nr_areas, buf_size, |
731 | S_IRUSR | S_IWUSR, 0, 0); | 734 | S_IRUSR | S_IWUSR, 0, 0); |
732 | } | 735 | } |
736 | EXPORT_SYMBOL(debug_register); | ||
733 | 737 | ||
734 | /* | 738 | /* |
735 | * debug_unregister: | 739 | * debug_unregister: |
@@ -748,6 +752,7 @@ debug_unregister(debug_info_t * id) | |||
748 | out: | 752 | out: |
749 | return; | 753 | return; |
750 | } | 754 | } |
755 | EXPORT_SYMBOL(debug_unregister); | ||
751 | 756 | ||
752 | /* | 757 | /* |
753 | * debug_set_size: | 758 | * debug_set_size: |
@@ -810,7 +815,7 @@ debug_set_level(debug_info_t* id, int new_level) | |||
810 | } | 815 | } |
811 | spin_unlock_irqrestore(&id->lock,flags); | 816 | spin_unlock_irqrestore(&id->lock,flags); |
812 | } | 817 | } |
813 | 818 | EXPORT_SYMBOL(debug_set_level); | |
814 | 819 | ||
815 | /* | 820 | /* |
816 | * proceed_active_entry: | 821 | * proceed_active_entry: |
@@ -930,7 +935,7 @@ debug_stop_all(void) | |||
930 | if (debug_stoppable) | 935 | if (debug_stoppable) |
931 | debug_active = 0; | 936 | debug_active = 0; |
932 | } | 937 | } |
933 | 938 | EXPORT_SYMBOL(debug_stop_all); | |
934 | 939 | ||
935 | void debug_set_critical(void) | 940 | void debug_set_critical(void) |
936 | { | 941 | { |
@@ -963,6 +968,7 @@ debug_event_common(debug_info_t * id, int level, const void *buf, int len) | |||
963 | 968 | ||
964 | return active; | 969 | return active; |
965 | } | 970 | } |
971 | EXPORT_SYMBOL(debug_event_common); | ||
966 | 972 | ||
967 | /* | 973 | /* |
968 | * debug_exception_common: | 974 | * debug_exception_common: |
@@ -990,6 +996,7 @@ debug_entry_t | |||
990 | 996 | ||
991 | return active; | 997 | return active; |
992 | } | 998 | } |
999 | EXPORT_SYMBOL(debug_exception_common); | ||
993 | 1000 | ||
994 | /* | 1001 | /* |
995 | * counts arguments in format string for sprintf view | 1002 | * counts arguments in format string for sprintf view |
@@ -1043,6 +1050,7 @@ debug_sprintf_event(debug_info_t* id, int level,char *string,...) | |||
1043 | 1050 | ||
1044 | return active; | 1051 | return active; |
1045 | } | 1052 | } |
1053 | EXPORT_SYMBOL(debug_sprintf_event); | ||
1046 | 1054 | ||
1047 | /* | 1055 | /* |
1048 | * debug_sprintf_exception: | 1056 | * debug_sprintf_exception: |
@@ -1081,25 +1089,7 @@ debug_sprintf_exception(debug_info_t* id, int level,char *string,...) | |||
1081 | 1089 | ||
1082 | return active; | 1090 | return active; |
1083 | } | 1091 | } |
1084 | 1092 | EXPORT_SYMBOL(debug_sprintf_exception); | |
1085 | /* | ||
1086 | * debug_init: | ||
1087 | * - is called exactly once to initialize the debug feature | ||
1088 | */ | ||
1089 | |||
1090 | static int | ||
1091 | __init debug_init(void) | ||
1092 | { | ||
1093 | int rc = 0; | ||
1094 | |||
1095 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); | ||
1096 | mutex_lock(&debug_mutex); | ||
1097 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); | ||
1098 | initialized = 1; | ||
1099 | mutex_unlock(&debug_mutex); | ||
1100 | |||
1101 | return rc; | ||
1102 | } | ||
1103 | 1093 | ||
1104 | /* | 1094 | /* |
1105 | * debug_register_view: | 1095 | * debug_register_view: |
@@ -1147,6 +1137,7 @@ debug_register_view(debug_info_t * id, struct debug_view *view) | |||
1147 | out: | 1137 | out: |
1148 | return rc; | 1138 | return rc; |
1149 | } | 1139 | } |
1140 | EXPORT_SYMBOL(debug_register_view); | ||
1150 | 1141 | ||
1151 | /* | 1142 | /* |
1152 | * debug_unregister_view: | 1143 | * debug_unregister_view: |
@@ -1176,6 +1167,7 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view) | |||
1176 | out: | 1167 | out: |
1177 | return rc; | 1168 | return rc; |
1178 | } | 1169 | } |
1170 | EXPORT_SYMBOL(debug_unregister_view); | ||
1179 | 1171 | ||
1180 | static inline char * | 1172 | static inline char * |
1181 | debug_get_user_string(const char __user *user_buf, size_t user_len) | 1173 | debug_get_user_string(const char __user *user_buf, size_t user_len) |
@@ -1485,6 +1477,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | |||
1485 | except_str, entry->id.fields.cpuid, (void *) caller); | 1477 | except_str, entry->id.fields.cpuid, (void *) caller); |
1486 | return rc; | 1478 | return rc; |
1487 | } | 1479 | } |
1480 | EXPORT_SYMBOL(debug_dflt_header_fn); | ||
1488 | 1481 | ||
1489 | /* | 1482 | /* |
1490 | * prints debug data sprintf-formated: | 1483 | * prints debug data sprintf-formated: |
@@ -1533,33 +1526,16 @@ out: | |||
1533 | } | 1526 | } |
1534 | 1527 | ||
1535 | /* | 1528 | /* |
1536 | * clean up module | 1529 | * debug_init: |
1530 | * - is called exactly once to initialize the debug feature | ||
1537 | */ | 1531 | */ |
1538 | static void __exit debug_exit(void) | 1532 | static int __init debug_init(void) |
1539 | { | 1533 | { |
1540 | debugfs_remove(debug_debugfs_root_entry); | 1534 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); |
1541 | unregister_sysctl_table(s390dbf_sysctl_header); | 1535 | mutex_lock(&debug_mutex); |
1542 | return; | 1536 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT, NULL); |
1537 | initialized = 1; | ||
1538 | mutex_unlock(&debug_mutex); | ||
1539 | return 0; | ||
1543 | } | 1540 | } |
1544 | |||
1545 | /* | ||
1546 | * module definitions | ||
1547 | */ | ||
1548 | postcore_initcall(debug_init); | 1541 | postcore_initcall(debug_init); |
1549 | module_exit(debug_exit); | ||
1550 | MODULE_LICENSE("GPL"); | ||
1551 | |||
1552 | EXPORT_SYMBOL(debug_register); | ||
1553 | EXPORT_SYMBOL(debug_unregister); | ||
1554 | EXPORT_SYMBOL(debug_set_level); | ||
1555 | EXPORT_SYMBOL(debug_stop_all); | ||
1556 | EXPORT_SYMBOL(debug_register_view); | ||
1557 | EXPORT_SYMBOL(debug_unregister_view); | ||
1558 | EXPORT_SYMBOL(debug_event_common); | ||
1559 | EXPORT_SYMBOL(debug_exception_common); | ||
1560 | EXPORT_SYMBOL(debug_hex_ascii_view); | ||
1561 | EXPORT_SYMBOL(debug_raw_view); | ||
1562 | EXPORT_SYMBOL(debug_dflt_header_fn); | ||
1563 | EXPORT_SYMBOL(debug_sprintf_view); | ||
1564 | EXPORT_SYMBOL(debug_sprintf_exception); | ||
1565 | EXPORT_SYMBOL(debug_sprintf_event); | ||
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 1f6b428e2762..619c5d350726 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
@@ -1531,7 +1531,7 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr) | |||
1531 | 1531 | ||
1532 | void show_code(struct pt_regs *regs) | 1532 | void show_code(struct pt_regs *regs) |
1533 | { | 1533 | { |
1534 | char *mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; | 1534 | char *mode = user_mode(regs) ? "User" : "Krnl"; |
1535 | unsigned char code[64]; | 1535 | unsigned char code[64]; |
1536 | char buffer[64], *ptr; | 1536 | char buffer[64], *ptr; |
1537 | mm_segment_t old_fs; | 1537 | mm_segment_t old_fs; |
@@ -1540,7 +1540,7 @@ void show_code(struct pt_regs *regs) | |||
1540 | 1540 | ||
1541 | /* Get a snapshot of the 64 bytes surrounding the fault address. */ | 1541 | /* Get a snapshot of the 64 bytes surrounding the fault address. */ |
1542 | old_fs = get_fs(); | 1542 | old_fs = get_fs(); |
1543 | set_fs((regs->psw.mask & PSW_MASK_PSTATE) ? USER_DS : KERNEL_DS); | 1543 | set_fs(user_mode(regs) ? USER_DS : KERNEL_DS); |
1544 | for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { | 1544 | for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { |
1545 | addr = regs->psw.addr - 34 + start; | 1545 | addr = regs->psw.addr - 34 + start; |
1546 | if (__copy_from_user(code + start - 2, | 1546 | if (__copy_from_user(code + start - 2, |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index bc95a8ebd9cc..83c3271c442b 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -455,7 +455,6 @@ void __init startup_init(void) | |||
455 | init_kernel_storage_key(); | 455 | init_kernel_storage_key(); |
456 | lockdep_init(); | 456 | lockdep_init(); |
457 | lockdep_off(); | 457 | lockdep_off(); |
458 | sort_main_extable(); | ||
459 | setup_lowcore_early(); | 458 | setup_lowcore_early(); |
460 | setup_facility_list(); | 459 | setup_facility_list(); |
461 | detect_machine_type(); | 460 | detect_machine_type(); |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index e64d141555ce..6ffcd3203215 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -1583,7 +1583,7 @@ static struct kset *vmcmd_kset; | |||
1583 | 1583 | ||
1584 | static void vmcmd_run(struct shutdown_trigger *trigger) | 1584 | static void vmcmd_run(struct shutdown_trigger *trigger) |
1585 | { | 1585 | { |
1586 | char *cmd, *next_cmd; | 1586 | char *cmd; |
1587 | 1587 | ||
1588 | if (strcmp(trigger->name, ON_REIPL_STR) == 0) | 1588 | if (strcmp(trigger->name, ON_REIPL_STR) == 0) |
1589 | cmd = vmcmd_on_reboot; | 1589 | cmd = vmcmd_on_reboot; |
@@ -1600,15 +1600,7 @@ static void vmcmd_run(struct shutdown_trigger *trigger) | |||
1600 | 1600 | ||
1601 | if (strlen(cmd) == 0) | 1601 | if (strlen(cmd) == 0) |
1602 | return; | 1602 | return; |
1603 | do { | 1603 | __cpcmd(cmd, NULL, 0, NULL); |
1604 | next_cmd = strchr(cmd, '\n'); | ||
1605 | if (next_cmd) { | ||
1606 | next_cmd[0] = 0; | ||
1607 | next_cmd += 1; | ||
1608 | } | ||
1609 | __cpcmd(cmd, NULL, 0, NULL); | ||
1610 | cmd = next_cmd; | ||
1611 | } while (cmd != NULL); | ||
1612 | } | 1604 | } |
1613 | 1605 | ||
1614 | static int vmcmd_init(void) | 1606 | static int vmcmd_init(void) |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 743c0f32fe3b..f86c81e13c37 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -302,8 +302,8 @@ static int __init parse_vmalloc(char *arg) | |||
302 | } | 302 | } |
303 | early_param("vmalloc", parse_vmalloc); | 303 | early_param("vmalloc", parse_vmalloc); |
304 | 304 | ||
305 | unsigned int user_mode = HOME_SPACE_MODE; | 305 | unsigned int addressing_mode = HOME_SPACE_MODE; |
306 | EXPORT_SYMBOL_GPL(user_mode); | 306 | EXPORT_SYMBOL_GPL(addressing_mode); |
307 | 307 | ||
308 | static int set_amode_primary(void) | 308 | static int set_amode_primary(void) |
309 | { | 309 | { |
@@ -328,7 +328,7 @@ static int set_amode_primary(void) | |||
328 | */ | 328 | */ |
329 | static int __init early_parse_switch_amode(char *p) | 329 | static int __init early_parse_switch_amode(char *p) |
330 | { | 330 | { |
331 | user_mode = PRIMARY_SPACE_MODE; | 331 | addressing_mode = PRIMARY_SPACE_MODE; |
332 | return 0; | 332 | return 0; |
333 | } | 333 | } |
334 | early_param("switch_amode", early_parse_switch_amode); | 334 | early_param("switch_amode", early_parse_switch_amode); |
@@ -336,9 +336,9 @@ early_param("switch_amode", early_parse_switch_amode); | |||
336 | static int __init early_parse_user_mode(char *p) | 336 | static int __init early_parse_user_mode(char *p) |
337 | { | 337 | { |
338 | if (p && strcmp(p, "primary") == 0) | 338 | if (p && strcmp(p, "primary") == 0) |
339 | user_mode = PRIMARY_SPACE_MODE; | 339 | addressing_mode = PRIMARY_SPACE_MODE; |
340 | else if (!p || strcmp(p, "home") == 0) | 340 | else if (!p || strcmp(p, "home") == 0) |
341 | user_mode = HOME_SPACE_MODE; | 341 | addressing_mode = HOME_SPACE_MODE; |
342 | else | 342 | else |
343 | return 1; | 343 | return 1; |
344 | return 0; | 344 | return 0; |
@@ -347,7 +347,7 @@ early_param("user_mode", early_parse_user_mode); | |||
347 | 347 | ||
348 | static void setup_addressing_mode(void) | 348 | static void setup_addressing_mode(void) |
349 | { | 349 | { |
350 | if (user_mode == PRIMARY_SPACE_MODE) { | 350 | if (addressing_mode == PRIMARY_SPACE_MODE) { |
351 | if (set_amode_primary()) | 351 | if (set_amode_primary()) |
352 | pr_info("Address spaces switched, " | 352 | pr_info("Address spaces switched, " |
353 | "mvcos available\n"); | 353 | "mvcos available\n"); |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index af2421a0f315..01775c04a90e 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -185,7 +185,7 @@ void show_registers(struct pt_regs *regs) | |||
185 | { | 185 | { |
186 | char *mode; | 186 | char *mode; |
187 | 187 | ||
188 | mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; | 188 | mode = user_mode(regs) ? "User" : "Krnl"; |
189 | printk("%s PSW : %p %p", | 189 | printk("%s PSW : %p %p", |
190 | mode, (void *) regs->psw.mask, | 190 | mode, (void *) regs->psw.mask, |
191 | (void *) regs->psw.addr); | 191 | (void *) regs->psw.addr); |
@@ -225,7 +225,7 @@ void show_regs(struct pt_regs *regs) | |||
225 | (void *) current->thread.ksp); | 225 | (void *) current->thread.ksp); |
226 | show_registers(regs); | 226 | show_registers(regs); |
227 | /* Show stack backtrace if pt_regs is from kernel mode */ | 227 | /* Show stack backtrace if pt_regs is from kernel mode */ |
228 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) | 228 | if (!user_mode(regs)) |
229 | show_trace(NULL, (unsigned long *) regs->gprs[15]); | 229 | show_trace(NULL, (unsigned long *) regs->gprs[15]); |
230 | show_last_breaking_event(regs); | 230 | show_last_breaking_event(regs); |
231 | } | 231 | } |
@@ -300,7 +300,7 @@ static void __kprobes do_trap(struct pt_regs *regs, | |||
300 | regs->int_code, si_signo) == NOTIFY_STOP) | 300 | regs->int_code, si_signo) == NOTIFY_STOP) |
301 | return; | 301 | return; |
302 | 302 | ||
303 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 303 | if (user_mode(regs)) { |
304 | info.si_signo = si_signo; | 304 | info.si_signo = si_signo; |
305 | info.si_errno = 0; | 305 | info.si_errno = 0; |
306 | info.si_code = si_code; | 306 | info.si_code = si_code; |
@@ -341,7 +341,7 @@ void __kprobes do_per_trap(struct pt_regs *regs) | |||
341 | 341 | ||
342 | static void default_trap_handler(struct pt_regs *regs) | 342 | static void default_trap_handler(struct pt_regs *regs) |
343 | { | 343 | { |
344 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 344 | if (user_mode(regs)) { |
345 | report_user_fault(regs, SIGSEGV); | 345 | report_user_fault(regs, SIGSEGV); |
346 | do_exit(SIGSEGV); | 346 | do_exit(SIGSEGV); |
347 | } else | 347 | } else |
@@ -410,7 +410,7 @@ static void __kprobes illegal_op(struct pt_regs *regs) | |||
410 | 410 | ||
411 | location = get_psw_address(regs); | 411 | location = get_psw_address(regs); |
412 | 412 | ||
413 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 413 | if (user_mode(regs)) { |
414 | if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) | 414 | if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) |
415 | return; | 415 | return; |
416 | if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { | 416 | if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { |
@@ -478,7 +478,7 @@ void specification_exception(struct pt_regs *regs) | |||
478 | 478 | ||
479 | location = (__u16 __user *) get_psw_address(regs); | 479 | location = (__u16 __user *) get_psw_address(regs); |
480 | 480 | ||
481 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 481 | if (user_mode(regs)) { |
482 | get_user(*((__u16 *) opcode), location); | 482 | get_user(*((__u16 *) opcode), location); |
483 | switch (opcode[0]) { | 483 | switch (opcode[0]) { |
484 | case 0x28: /* LDR Rx,Ry */ | 484 | case 0x28: /* LDR Rx,Ry */ |
@@ -531,7 +531,7 @@ static void data_exception(struct pt_regs *regs) | |||
531 | asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); | 531 | asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); |
532 | 532 | ||
533 | #ifdef CONFIG_MATHEMU | 533 | #ifdef CONFIG_MATHEMU |
534 | else if (regs->psw.mask & PSW_MASK_PSTATE) { | 534 | else if (user_mode(regs)) { |
535 | __u8 opcode[6]; | 535 | __u8 opcode[6]; |
536 | get_user(*((__u16 *) opcode), location); | 536 | get_user(*((__u16 *) opcode), location); |
537 | switch (opcode[0]) { | 537 | switch (opcode[0]) { |
@@ -598,7 +598,7 @@ static void data_exception(struct pt_regs *regs) | |||
598 | static void space_switch_exception(struct pt_regs *regs) | 598 | static void space_switch_exception(struct pt_regs *regs) |
599 | { | 599 | { |
600 | /* Set user psw back to home space mode. */ | 600 | /* Set user psw back to home space mode. */ |
601 | if (regs->psw.mask & PSW_MASK_PSTATE) | 601 | if (user_mode(regs)) |
602 | regs->psw.mask |= PSW_ASC_HOME; | 602 | regs->psw.mask |= PSW_ASC_HOME; |
603 | /* Send SIGILL. */ | 603 | /* Send SIGILL. */ |
604 | do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); | 604 | do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index ea5590fdca3b..9a19ca367c17 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -84,7 +84,8 @@ struct vdso_data *vdso_data = &vdso_data_store.data; | |||
84 | */ | 84 | */ |
85 | static void vdso_init_data(struct vdso_data *vd) | 85 | static void vdso_init_data(struct vdso_data *vd) |
86 | { | 86 | { |
87 | vd->ectg_available = user_mode != HOME_SPACE_MODE && test_facility(31); | 87 | vd->ectg_available = |
88 | addressing_mode != HOME_SPACE_MODE && test_facility(31); | ||
88 | } | 89 | } |
89 | 90 | ||
90 | #ifdef CONFIG_64BIT | 91 | #ifdef CONFIG_64BIT |
@@ -101,7 +102,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore) | |||
101 | 102 | ||
102 | lowcore->vdso_per_cpu_data = __LC_PASTE; | 103 | lowcore->vdso_per_cpu_data = __LC_PASTE; |
103 | 104 | ||
104 | if (user_mode == HOME_SPACE_MODE || !vdso_enabled) | 105 | if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) |
105 | return 0; | 106 | return 0; |
106 | 107 | ||
107 | segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); | 108 | segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); |
@@ -146,7 +147,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore) | |||
146 | unsigned long segment_table, page_table, page_frame; | 147 | unsigned long segment_table, page_table, page_frame; |
147 | u32 *psal, *aste; | 148 | u32 *psal, *aste; |
148 | 149 | ||
149 | if (user_mode == HOME_SPACE_MODE || !vdso_enabled) | 150 | if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) |
150 | return; | 151 | return; |
151 | 152 | ||
152 | psal = (u32 *)(addr_t) lowcore->paste[4]; | 153 | psal = (u32 *)(addr_t) lowcore->paste[4]; |
@@ -164,7 +165,7 @@ static void vdso_init_cr5(void) | |||
164 | { | 165 | { |
165 | unsigned long cr5; | 166 | unsigned long cr5; |
166 | 167 | ||
167 | if (user_mode == HOME_SPACE_MODE || !vdso_enabled) | 168 | if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) |
168 | return; | 169 | return; |
169 | cr5 = offsetof(struct _lowcore, paste); | 170 | cr5 = offsetof(struct _lowcore, paste); |
170 | __ctl_load(cr5, 5, 5); | 171 | __ctl_load(cr5, 5, 5); |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 21109c63eb12..de8fa9bbd35e 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
@@ -45,7 +45,7 @@ SECTIONS | |||
45 | 45 | ||
46 | .dummy : { *(.dummy) } :data | 46 | .dummy : { *(.dummy) } :data |
47 | 47 | ||
48 | RODATA | 48 | RO_DATA_SECTION(PAGE_SIZE) |
49 | 49 | ||
50 | #ifdef CONFIG_SHARED_KERNEL | 50 | #ifdef CONFIG_SHARED_KERNEL |
51 | . = ALIGN(0x100000); /* VM shared segments are 1MB aligned */ | 51 | . = ALIGN(0x100000); /* VM shared segments are 1MB aligned */ |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 6a12d1bb6e09..6c013f544146 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #define VM_FAULT_BADCONTEXT 0x010000 | 49 | #define VM_FAULT_BADCONTEXT 0x010000 |
50 | #define VM_FAULT_BADMAP 0x020000 | 50 | #define VM_FAULT_BADMAP 0x020000 |
51 | #define VM_FAULT_BADACCESS 0x040000 | 51 | #define VM_FAULT_BADACCESS 0x040000 |
52 | #define VM_FAULT_SIGNAL 0x080000 | ||
52 | 53 | ||
53 | static unsigned long store_indication; | 54 | static unsigned long store_indication; |
54 | 55 | ||
@@ -110,7 +111,7 @@ static inline int user_space_fault(unsigned long trans_exc_code) | |||
110 | if (trans_exc_code == 2) | 111 | if (trans_exc_code == 2) |
111 | /* Access via secondary space, set_fs setting decides */ | 112 | /* Access via secondary space, set_fs setting decides */ |
112 | return current->thread.mm_segment.ar4; | 113 | return current->thread.mm_segment.ar4; |
113 | if (user_mode == HOME_SPACE_MODE) | 114 | if (addressing_mode == HOME_SPACE_MODE) |
114 | /* User space if the access has been done via home space. */ | 115 | /* User space if the access has been done via home space. */ |
115 | return trans_exc_code == 3; | 116 | return trans_exc_code == 3; |
116 | /* | 117 | /* |
@@ -219,7 +220,7 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault) | |||
219 | case VM_FAULT_BADACCESS: | 220 | case VM_FAULT_BADACCESS: |
220 | case VM_FAULT_BADMAP: | 221 | case VM_FAULT_BADMAP: |
221 | /* Bad memory access. Check if it is kernel or user space. */ | 222 | /* Bad memory access. Check if it is kernel or user space. */ |
222 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 223 | if (user_mode(regs)) { |
223 | /* User mode accesses just cause a SIGSEGV */ | 224 | /* User mode accesses just cause a SIGSEGV */ |
224 | si_code = (fault == VM_FAULT_BADMAP) ? | 225 | si_code = (fault == VM_FAULT_BADMAP) ? |
225 | SEGV_MAPERR : SEGV_ACCERR; | 226 | SEGV_MAPERR : SEGV_ACCERR; |
@@ -229,15 +230,19 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault) | |||
229 | case VM_FAULT_BADCONTEXT: | 230 | case VM_FAULT_BADCONTEXT: |
230 | do_no_context(regs); | 231 | do_no_context(regs); |
231 | break; | 232 | break; |
233 | case VM_FAULT_SIGNAL: | ||
234 | if (!user_mode(regs)) | ||
235 | do_no_context(regs); | ||
236 | break; | ||
232 | default: /* fault & VM_FAULT_ERROR */ | 237 | default: /* fault & VM_FAULT_ERROR */ |
233 | if (fault & VM_FAULT_OOM) { | 238 | if (fault & VM_FAULT_OOM) { |
234 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) | 239 | if (!user_mode(regs)) |
235 | do_no_context(regs); | 240 | do_no_context(regs); |
236 | else | 241 | else |
237 | pagefault_out_of_memory(); | 242 | pagefault_out_of_memory(); |
238 | } else if (fault & VM_FAULT_SIGBUS) { | 243 | } else if (fault & VM_FAULT_SIGBUS) { |
239 | /* Kernel mode? Handle exceptions or die */ | 244 | /* Kernel mode? Handle exceptions or die */ |
240 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) | 245 | if (!user_mode(regs)) |
241 | do_no_context(regs); | 246 | do_no_context(regs); |
242 | else | 247 | else |
243 | do_sigbus(regs); | 248 | do_sigbus(regs); |
@@ -286,7 +291,7 @@ static inline int do_exception(struct pt_regs *regs, int access) | |||
286 | 291 | ||
287 | address = trans_exc_code & __FAIL_ADDR_MASK; | 292 | address = trans_exc_code & __FAIL_ADDR_MASK; |
288 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); | 293 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); |
289 | flags = FAULT_FLAG_ALLOW_RETRY; | 294 | flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
290 | if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400) | 295 | if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400) |
291 | flags |= FAULT_FLAG_WRITE; | 296 | flags |= FAULT_FLAG_WRITE; |
292 | down_read(&mm->mmap_sem); | 297 | down_read(&mm->mmap_sem); |
@@ -335,6 +340,11 @@ retry: | |||
335 | * the fault. | 340 | * the fault. |
336 | */ | 341 | */ |
337 | fault = handle_mm_fault(mm, vma, address, flags); | 342 | fault = handle_mm_fault(mm, vma, address, flags); |
343 | /* No reason to continue if interrupted by SIGKILL. */ | ||
344 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { | ||
345 | fault = VM_FAULT_SIGNAL; | ||
346 | goto out; | ||
347 | } | ||
338 | if (unlikely(fault & VM_FAULT_ERROR)) | 348 | if (unlikely(fault & VM_FAULT_ERROR)) |
339 | goto out_up; | 349 | goto out_up; |
340 | 350 | ||
@@ -426,7 +436,7 @@ void __kprobes do_asce_exception(struct pt_regs *regs) | |||
426 | } | 436 | } |
427 | 437 | ||
428 | /* User mode accesses just cause a SIGSEGV */ | 438 | /* User mode accesses just cause a SIGSEGV */ |
429 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 439 | if (user_mode(regs)) { |
430 | do_sigsegv(regs, SEGV_MAPERR); | 440 | do_sigsegv(regs, SEGV_MAPERR); |
431 | return; | 441 | return; |
432 | } | 442 | } |
@@ -441,6 +451,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) | |||
441 | struct pt_regs regs; | 451 | struct pt_regs regs; |
442 | int access, fault; | 452 | int access, fault; |
443 | 453 | ||
454 | /* Emulate a uaccess fault from kernel mode. */ | ||
444 | regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK; | 455 | regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK; |
445 | if (!irqs_disabled()) | 456 | if (!irqs_disabled()) |
446 | regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; | 457 | regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; |
@@ -450,12 +461,12 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) | |||
450 | regs.int_parm_long = (uaddr & PAGE_MASK) | 2; | 461 | regs.int_parm_long = (uaddr & PAGE_MASK) | 2; |
451 | access = write ? VM_WRITE : VM_READ; | 462 | access = write ? VM_WRITE : VM_READ; |
452 | fault = do_exception(®s, access); | 463 | fault = do_exception(®s, access); |
453 | if (unlikely(fault)) { | 464 | /* |
454 | if (fault & VM_FAULT_OOM) | 465 | * Since the fault happened in kernel mode while performing a uaccess |
455 | return -EFAULT; | 466 | * all we need to do now is emulating a fixup in case "fault" is not |
456 | else if (fault & VM_FAULT_SIGBUS) | 467 | * zero. |
457 | do_sigbus(®s); | 468 | * For the calling uaccess functions this results always in -EFAULT. |
458 | } | 469 | */ |
459 | return fault ? -EFAULT : 0; | 470 | return fault ? -EFAULT : 0; |
460 | } | 471 | } |
461 | 472 | ||
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 573384256c5c..c59a5efa58b1 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
@@ -103,9 +103,15 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
103 | 103 | ||
104 | int s390_mmap_check(unsigned long addr, unsigned long len) | 104 | int s390_mmap_check(unsigned long addr, unsigned long len) |
105 | { | 105 | { |
106 | int rc; | ||
107 | |||
106 | if (!is_compat_task() && | 108 | if (!is_compat_task() && |
107 | len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) | 109 | len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) { |
108 | return crst_table_upgrade(current->mm, 1UL << 53); | 110 | rc = crst_table_upgrade(current->mm, 1UL << 53); |
111 | if (rc) | ||
112 | return rc; | ||
113 | update_mm(current->mm, current); | ||
114 | } | ||
109 | return 0; | 115 | return 0; |
110 | } | 116 | } |
111 | 117 | ||
@@ -125,6 +131,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, | |||
125 | rc = crst_table_upgrade(mm, 1UL << 53); | 131 | rc = crst_table_upgrade(mm, 1UL << 53); |
126 | if (rc) | 132 | if (rc) |
127 | return (unsigned long) rc; | 133 | return (unsigned long) rc; |
134 | update_mm(mm, current); | ||
128 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); | 135 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); |
129 | } | 136 | } |
130 | return area; | 137 | return area; |
@@ -147,6 +154,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, | |||
147 | rc = crst_table_upgrade(mm, 1UL << 53); | 154 | rc = crst_table_upgrade(mm, 1UL << 53); |
148 | if (rc) | 155 | if (rc) |
149 | return (unsigned long) rc; | 156 | return (unsigned long) rc; |
157 | update_mm(mm, current); | ||
150 | area = arch_get_unmapped_area_topdown(filp, addr, len, | 158 | area = arch_get_unmapped_area_topdown(filp, addr, len, |
151 | pgoff, flags); | 159 | pgoff, flags); |
152 | } | 160 | } |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 1cab221077cc..18df31d1f2c9 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -85,7 +85,6 @@ repeat: | |||
85 | crst_table_free(mm, table); | 85 | crst_table_free(mm, table); |
86 | if (mm->context.asce_limit < limit) | 86 | if (mm->context.asce_limit < limit) |
87 | goto repeat; | 87 | goto repeat; |
88 | update_mm(mm, current); | ||
89 | return 0; | 88 | return 0; |
90 | } | 89 | } |
91 | 90 | ||
@@ -93,9 +92,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) | |||
93 | { | 92 | { |
94 | pgd_t *pgd; | 93 | pgd_t *pgd; |
95 | 94 | ||
96 | if (mm->context.asce_limit <= limit) | ||
97 | return; | ||
98 | __tlb_flush_mm(mm); | ||
99 | while (mm->context.asce_limit > limit) { | 95 | while (mm->context.asce_limit > limit) { |
100 | pgd = mm->pgd; | 96 | pgd = mm->pgd; |
101 | switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { | 97 | switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { |
@@ -118,7 +114,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) | |||
118 | mm->task_size = mm->context.asce_limit; | 114 | mm->task_size = mm->context.asce_limit; |
119 | crst_table_free(mm, (unsigned long *) pgd); | 115 | crst_table_free(mm, (unsigned long *) pgd); |
120 | } | 116 | } |
121 | update_mm(mm, current); | ||
122 | } | 117 | } |
123 | #endif | 118 | #endif |
124 | 119 | ||
@@ -801,7 +796,7 @@ int s390_enable_sie(void) | |||
801 | struct mm_struct *mm, *old_mm; | 796 | struct mm_struct *mm, *old_mm; |
802 | 797 | ||
803 | /* Do we have switched amode? If no, we cannot do sie */ | 798 | /* Do we have switched amode? If no, we cannot do sie */ |
804 | if (user_mode == HOME_SPACE_MODE) | 799 | if (addressing_mode == HOME_SPACE_MODE) |
805 | return -EINVAL; | 800 | return -EINVAL; |
806 | 801 | ||
807 | /* Do we have pgstes? if yes, we are done */ | 802 | /* Do we have pgstes? if yes, we are done */ |
diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c index c82f62fb9c28..8a6811b2cdb9 100644 --- a/arch/s390/oprofile/backtrace.c +++ b/arch/s390/oprofile/backtrace.c | |||
@@ -58,7 +58,7 @@ void s390_backtrace(struct pt_regs * const regs, unsigned int depth) | |||
58 | unsigned long head; | 58 | unsigned long head; |
59 | struct stack_frame* head_sf; | 59 | struct stack_frame* head_sf; |
60 | 60 | ||
61 | if (user_mode (regs)) | 61 | if (user_mode(regs)) |
62 | return; | 62 | return; |
63 | 63 | ||
64 | head = regs->gprs[15]; | 64 | head = regs->gprs[15]; |
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 7048c03490d9..fb5805745ace 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig | |||
@@ -57,6 +57,7 @@ config SH_7724_SOLUTION_ENGINE | |||
57 | depends on CPU_SUBTYPE_SH7724 | 57 | depends on CPU_SUBTYPE_SH7724 |
58 | select ARCH_REQUIRE_GPIOLIB | 58 | select ARCH_REQUIRE_GPIOLIB |
59 | select SND_SOC_AK4642 if SND_SIMPLE_CARD | 59 | select SND_SOC_AK4642 if SND_SIMPLE_CARD |
60 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
60 | help | 61 | help |
61 | Select 7724 SolutionEngine if configuring for a Hitachi SH7724 | 62 | Select 7724 SolutionEngine if configuring for a Hitachi SH7724 |
62 | evaluation board. | 63 | evaluation board. |
@@ -140,6 +141,7 @@ config SH_RSK | |||
140 | bool "Renesas Starter Kit" | 141 | bool "Renesas Starter Kit" |
141 | depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203 || \ | 142 | depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203 || \ |
142 | CPU_SUBTYPE_SH7264 || CPU_SUBTYPE_SH7269 | 143 | CPU_SUBTYPE_SH7264 || CPU_SUBTYPE_SH7269 |
144 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
143 | help | 145 | help |
144 | Select this option if configuring for any of the RSK+ MCU | 146 | Select this option if configuring for any of the RSK+ MCU |
145 | evaluation platforms. | 147 | evaluation platforms. |
@@ -159,6 +161,7 @@ config SH_SDK7786 | |||
159 | select NO_IOPORT if !PCI | 161 | select NO_IOPORT if !PCI |
160 | select ARCH_WANT_OPTIONAL_GPIOLIB | 162 | select ARCH_WANT_OPTIONAL_GPIOLIB |
161 | select HAVE_SRAM_POOL | 163 | select HAVE_SRAM_POOL |
164 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
162 | help | 165 | help |
163 | Select SDK7786 if configuring for a Renesas Technology Europe | 166 | Select SDK7786 if configuring for a Renesas Technology Europe |
164 | SH7786-65nm board. | 167 | SH7786-65nm board. |
@@ -173,6 +176,7 @@ config SH_SH7757LCR | |||
173 | bool "SH7757LCR" | 176 | bool "SH7757LCR" |
174 | depends on CPU_SUBTYPE_SH7757 | 177 | depends on CPU_SUBTYPE_SH7757 |
175 | select ARCH_REQUIRE_GPIOLIB | 178 | select ARCH_REQUIRE_GPIOLIB |
179 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
176 | 180 | ||
177 | config SH_SH7785LCR | 181 | config SH_SH7785LCR |
178 | bool "SH7785LCR" | 182 | bool "SH7785LCR" |
@@ -206,6 +210,7 @@ config SH_MIGOR | |||
206 | bool "Migo-R" | 210 | bool "Migo-R" |
207 | depends on CPU_SUBTYPE_SH7722 | 211 | depends on CPU_SUBTYPE_SH7722 |
208 | select ARCH_REQUIRE_GPIOLIB | 212 | select ARCH_REQUIRE_GPIOLIB |
213 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
209 | help | 214 | help |
210 | Select Migo-R if configuring for the SH7722 Migo-R platform | 215 | Select Migo-R if configuring for the SH7722 Migo-R platform |
211 | by Renesas System Solutions Asia Pte. Ltd. | 216 | by Renesas System Solutions Asia Pte. Ltd. |
@@ -214,6 +219,7 @@ config SH_AP325RXA | |||
214 | bool "AP-325RXA" | 219 | bool "AP-325RXA" |
215 | depends on CPU_SUBTYPE_SH7723 | 220 | depends on CPU_SUBTYPE_SH7723 |
216 | select ARCH_REQUIRE_GPIOLIB | 221 | select ARCH_REQUIRE_GPIOLIB |
222 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
217 | help | 223 | help |
218 | Renesas "AP-325RXA" support. | 224 | Renesas "AP-325RXA" support. |
219 | Compatible with ALGO SYSTEM CO.,LTD. "AP-320A" | 225 | Compatible with ALGO SYSTEM CO.,LTD. "AP-320A" |
@@ -222,6 +228,7 @@ config SH_KFR2R09 | |||
222 | bool "KFR2R09" | 228 | bool "KFR2R09" |
223 | depends on CPU_SUBTYPE_SH7724 | 229 | depends on CPU_SUBTYPE_SH7724 |
224 | select ARCH_REQUIRE_GPIOLIB | 230 | select ARCH_REQUIRE_GPIOLIB |
231 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
225 | help | 232 | help |
226 | "Kit For R2R for 2009" support. | 233 | "Kit For R2R for 2009" support. |
227 | 234 | ||
@@ -230,6 +237,7 @@ config SH_ECOVEC | |||
230 | depends on CPU_SUBTYPE_SH7724 | 237 | depends on CPU_SUBTYPE_SH7724 |
231 | select ARCH_REQUIRE_GPIOLIB | 238 | select ARCH_REQUIRE_GPIOLIB |
232 | select SND_SOC_DA7210 if SND_SIMPLE_CARD | 239 | select SND_SOC_DA7210 if SND_SIMPLE_CARD |
240 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
233 | help | 241 | help |
234 | Renesas "R0P7724LC0011/21RL (EcoVec)" support. | 242 | Renesas "R0P7724LC0011/21RL (EcoVec)" support. |
235 | 243 | ||
@@ -305,6 +313,7 @@ config SH_MAGIC_PANEL_R2 | |||
305 | bool "Magic Panel R2" | 313 | bool "Magic Panel R2" |
306 | depends on CPU_SUBTYPE_SH7720 | 314 | depends on CPU_SUBTYPE_SH7720 |
307 | select ARCH_REQUIRE_GPIOLIB | 315 | select ARCH_REQUIRE_GPIOLIB |
316 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
308 | help | 317 | help |
309 | Select Magic Panel R2 if configuring for Magic Panel R2. | 318 | Select Magic Panel R2 if configuring for Magic Panel R2. |
310 | 319 | ||
@@ -316,6 +325,7 @@ config SH_CAYMAN | |||
316 | config SH_POLARIS | 325 | config SH_POLARIS |
317 | bool "SMSC Polaris" | 326 | bool "SMSC Polaris" |
318 | select CPU_HAS_IPR_IRQ | 327 | select CPU_HAS_IPR_IRQ |
328 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
319 | depends on CPU_SUBTYPE_SH7709 | 329 | depends on CPU_SUBTYPE_SH7709 |
320 | help | 330 | help |
321 | Select if configuring for an SMSC Polaris development board | 331 | Select if configuring for an SMSC Polaris development board |
@@ -323,6 +333,7 @@ config SH_POLARIS | |||
323 | config SH_SH2007 | 333 | config SH_SH2007 |
324 | bool "SH-2007 board" | 334 | bool "SH-2007 board" |
325 | select NO_IOPORT | 335 | select NO_IOPORT |
336 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
326 | depends on CPU_SUBTYPE_SH7780 | 337 | depends on CPU_SUBTYPE_SH7780 |
327 | help | 338 | help |
328 | SH-2007 is a single-board computer based around SH7780 chip | 339 | SH-2007 is a single-board computer based around SH7780 chip |
@@ -334,6 +345,7 @@ config SH_SH2007 | |||
334 | config SH_APSH4A3A | 345 | config SH_APSH4A3A |
335 | bool "AP-SH4A-3A" | 346 | bool "AP-SH4A-3A" |
336 | select SH_ALPHA_BOARD | 347 | select SH_ALPHA_BOARD |
348 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
337 | depends on CPU_SUBTYPE_SH7785 | 349 | depends on CPU_SUBTYPE_SH7785 |
338 | help | 350 | help |
339 | Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A. | 351 | Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A. |
@@ -342,6 +354,7 @@ config SH_APSH4AD0A | |||
342 | bool "AP-SH4AD-0A" | 354 | bool "AP-SH4AD-0A" |
343 | select SH_ALPHA_BOARD | 355 | select SH_ALPHA_BOARD |
344 | select SYS_SUPPORTS_PCI | 356 | select SYS_SUPPORTS_PCI |
357 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
345 | depends on CPU_SUBTYPE_SH7786 | 358 | depends on CPU_SUBTYPE_SH7786 |
346 | help | 359 | help |
347 | Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A. | 360 | Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A. |
diff --git a/arch/sh/boards/board-apsh4a3a.c b/arch/sh/boards/board-apsh4a3a.c index 2823619c6006..0a39c241628a 100644 --- a/arch/sh/boards/board-apsh4a3a.c +++ b/arch/sh/boards/board-apsh4a3a.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/mtd/physmap.h> | 15 | #include <linux/mtd/physmap.h> |
16 | #include <linux/regulator/fixed.h> | ||
17 | #include <linux/regulator/machine.h> | ||
16 | #include <linux/smsc911x.h> | 18 | #include <linux/smsc911x.h> |
17 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
18 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
@@ -66,6 +68,12 @@ static struct platform_device nor_flash_device = { | |||
66 | .resource = nor_flash_resources, | 68 | .resource = nor_flash_resources, |
67 | }; | 69 | }; |
68 | 70 | ||
71 | /* Dummy supplies, where voltage doesn't matter */ | ||
72 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
73 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
74 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
75 | }; | ||
76 | |||
69 | static struct resource smsc911x_resources[] = { | 77 | static struct resource smsc911x_resources[] = { |
70 | [0] = { | 78 | [0] = { |
71 | .name = "smsc911x-memory", | 79 | .name = "smsc911x-memory", |
@@ -105,6 +113,8 @@ static struct platform_device *apsh4a3a_devices[] __initdata = { | |||
105 | 113 | ||
106 | static int __init apsh4a3a_devices_setup(void) | 114 | static int __init apsh4a3a_devices_setup(void) |
107 | { | 115 | { |
116 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
117 | |||
108 | return platform_add_devices(apsh4a3a_devices, | 118 | return platform_add_devices(apsh4a3a_devices, |
109 | ARRAY_SIZE(apsh4a3a_devices)); | 119 | ARRAY_SIZE(apsh4a3a_devices)); |
110 | } | 120 | } |
diff --git a/arch/sh/boards/board-apsh4ad0a.c b/arch/sh/boards/board-apsh4ad0a.c index b4d6292a9247..92eac3a99187 100644 --- a/arch/sh/boards/board-apsh4ad0a.c +++ b/arch/sh/boards/board-apsh4ad0a.c | |||
@@ -12,12 +12,20 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/regulator/fixed.h> | ||
16 | #include <linux/regulator/machine.h> | ||
15 | #include <linux/smsc911x.h> | 17 | #include <linux/smsc911x.h> |
16 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
17 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
18 | #include <asm/machvec.h> | 20 | #include <asm/machvec.h> |
19 | #include <asm/sizes.h> | 21 | #include <asm/sizes.h> |
20 | 22 | ||
23 | /* Dummy supplies, where voltage doesn't matter */ | ||
24 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
25 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
26 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
27 | }; | ||
28 | |||
21 | static struct resource smsc911x_resources[] = { | 29 | static struct resource smsc911x_resources[] = { |
22 | [0] = { | 30 | [0] = { |
23 | .name = "smsc911x-memory", | 31 | .name = "smsc911x-memory", |
@@ -56,6 +64,8 @@ static struct platform_device *apsh4ad0a_devices[] __initdata = { | |||
56 | 64 | ||
57 | static int __init apsh4ad0a_devices_setup(void) | 65 | static int __init apsh4ad0a_devices_setup(void) |
58 | { | 66 | { |
67 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
68 | |||
59 | return platform_add_devices(apsh4ad0a_devices, | 69 | return platform_add_devices(apsh4ad0a_devices, |
60 | ARRAY_SIZE(apsh4ad0a_devices)); | 70 | ARRAY_SIZE(apsh4ad0a_devices)); |
61 | } | 71 | } |
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c index 90568f9de3a4..20500858b56c 100644 --- a/arch/sh/boards/board-magicpanelr2.c +++ b/arch/sh/boards/board-magicpanelr2.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/regulator/fixed.h> | ||
18 | #include <linux/regulator/machine.h> | ||
17 | #include <linux/smsc911x.h> | 19 | #include <linux/smsc911x.h> |
18 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
19 | #include <linux/mtd/partitions.h> | 21 | #include <linux/mtd/partitions.h> |
@@ -24,6 +26,12 @@ | |||
24 | #include <asm/heartbeat.h> | 26 | #include <asm/heartbeat.h> |
25 | #include <cpu/sh7720.h> | 27 | #include <cpu/sh7720.h> |
26 | 28 | ||
29 | /* Dummy supplies, where voltage doesn't matter */ | ||
30 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
31 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
32 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
33 | }; | ||
34 | |||
27 | #define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) | 35 | #define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) |
28 | 36 | ||
29 | /* Wait until reset finished. Timeout is 100ms. */ | 37 | /* Wait until reset finished. Timeout is 100ms. */ |
@@ -348,6 +356,8 @@ static struct platform_device *mpr2_devices[] __initdata = { | |||
348 | 356 | ||
349 | static int __init mpr2_devices_setup(void) | 357 | static int __init mpr2_devices_setup(void) |
350 | { | 358 | { |
359 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
360 | |||
351 | return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); | 361 | return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); |
352 | } | 362 | } |
353 | device_initcall(mpr2_devices_setup); | 363 | device_initcall(mpr2_devices_setup); |
diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c index 0978ae2e4847..37a08d094727 100644 --- a/arch/sh/boards/board-polaris.c +++ b/arch/sh/boards/board-polaris.c | |||
@@ -9,6 +9,8 @@ | |||
9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
10 | #include <linux/irq.h> | 10 | #include <linux/irq.h> |
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/regulator/fixed.h> | ||
13 | #include <linux/regulator/machine.h> | ||
12 | #include <linux/smsc911x.h> | 14 | #include <linux/smsc911x.h> |
13 | #include <linux/io.h> | 15 | #include <linux/io.h> |
14 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
@@ -22,6 +24,12 @@ | |||
22 | #define AREA5_WAIT_CTRL (0x1C00) | 24 | #define AREA5_WAIT_CTRL (0x1C00) |
23 | #define WAIT_STATES_10 (0x7) | 25 | #define WAIT_STATES_10 (0x7) |
24 | 26 | ||
27 | /* Dummy supplies, where voltage doesn't matter */ | ||
28 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
29 | REGULATOR_SUPPLY("vddvario", "smsc911x.0"), | ||
30 | REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), | ||
31 | }; | ||
32 | |||
25 | static struct resource smsc911x_resources[] = { | 33 | static struct resource smsc911x_resources[] = { |
26 | [0] = { | 34 | [0] = { |
27 | .name = "smsc911x-memory", | 35 | .name = "smsc911x-memory", |
@@ -88,6 +96,8 @@ static int __init polaris_initialise(void) | |||
88 | 96 | ||
89 | printk(KERN_INFO "Configuring Polaris external bus\n"); | 97 | printk(KERN_INFO "Configuring Polaris external bus\n"); |
90 | 98 | ||
99 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
100 | |||
91 | /* Configure area 5 with 2 wait states */ | 101 | /* Configure area 5 with 2 wait states */ |
92 | wcr = __raw_readw(WCR2); | 102 | wcr = __raw_readw(WCR2); |
93 | wcr &= (~AREA5_WAIT_CTRL); | 103 | wcr &= (~AREA5_WAIT_CTRL); |
diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c index b90b78f6a829..1980bb7e5780 100644 --- a/arch/sh/boards/board-sh2007.c +++ b/arch/sh/boards/board-sh2007.c | |||
@@ -6,6 +6,8 @@ | |||
6 | */ | 6 | */ |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
9 | #include <linux/regulator/fixed.h> | ||
10 | #include <linux/regulator/machine.h> | ||
9 | #include <linux/smsc911x.h> | 11 | #include <linux/smsc911x.h> |
10 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
11 | #include <linux/ata_platform.h> | 13 | #include <linux/ata_platform.h> |
@@ -13,6 +15,14 @@ | |||
13 | #include <asm/machvec.h> | 15 | #include <asm/machvec.h> |
14 | #include <mach/sh2007.h> | 16 | #include <mach/sh2007.h> |
15 | 17 | ||
18 | /* Dummy supplies, where voltage doesn't matter */ | ||
19 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
20 | REGULATOR_SUPPLY("vddvario", "smsc911x.0"), | ||
21 | REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), | ||
22 | REGULATOR_SUPPLY("vddvario", "smsc911x.1"), | ||
23 | REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), | ||
24 | }; | ||
25 | |||
16 | struct smsc911x_platform_config smc911x_info = { | 26 | struct smsc911x_platform_config smc911x_info = { |
17 | .flags = SMSC911X_USE_32BIT, | 27 | .flags = SMSC911X_USE_32BIT, |
18 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | 28 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, |
@@ -98,6 +108,8 @@ static struct platform_device *sh2007_devices[] __initdata = { | |||
98 | 108 | ||
99 | static int __init sh2007_io_init(void) | 109 | static int __init sh2007_io_init(void) |
100 | { | 110 | { |
111 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
112 | |||
101 | platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices)); | 113 | platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices)); |
102 | return 0; | 114 | return 0; |
103 | } | 115 | } |
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c index 5087f8bb4cff..41f86702eb9f 100644 --- a/arch/sh/boards/board-sh7757lcr.c +++ b/arch/sh/boards/board-sh7757lcr.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/regulator/fixed.h> | ||
16 | #include <linux/regulator/machine.h> | ||
15 | #include <linux/spi/spi.h> | 17 | #include <linux/spi/spi.h> |
16 | #include <linux/spi/flash.h> | 18 | #include <linux/spi/flash.h> |
17 | #include <linux/io.h> | 19 | #include <linux/io.h> |
@@ -199,6 +201,15 @@ static struct platform_device sh7757_eth_giga1_device = { | |||
199 | }, | 201 | }, |
200 | }; | 202 | }; |
201 | 203 | ||
204 | /* Fixed 3.3V regulator to be used by SDHI0, MMCIF */ | ||
205 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
206 | { | ||
207 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
208 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
209 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
210 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
211 | }; | ||
212 | |||
202 | /* SH_MMCIF */ | 213 | /* SH_MMCIF */ |
203 | static struct resource sh_mmcif_resources[] = { | 214 | static struct resource sh_mmcif_resources[] = { |
204 | [0] = { | 215 | [0] = { |
@@ -329,6 +340,9 @@ static struct spi_board_info spi_board_info[] = { | |||
329 | 340 | ||
330 | static int __init sh7757lcr_devices_setup(void) | 341 | static int __init sh7757lcr_devices_setup(void) |
331 | { | 342 | { |
343 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
344 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
345 | |||
332 | /* RGMII (PTA) */ | 346 | /* RGMII (PTA) */ |
333 | gpio_request(GPIO_FN_ET0_MDC, NULL); | 347 | gpio_request(GPIO_FN_ET0_MDC, NULL); |
334 | gpio_request(GPIO_FN_ET0_MDIO, NULL); | 348 | gpio_request(GPIO_FN_ET0_MDIO, NULL); |
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index f33ebf447073..9e963c1d1447 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/mtd/sh_flctl.h> | 20 | #include <linux/mtd/sh_flctl.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
23 | #include <linux/regulator/fixed.h> | ||
24 | #include <linux/regulator/machine.h> | ||
23 | #include <linux/smsc911x.h> | 25 | #include <linux/smsc911x.h> |
24 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
25 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
@@ -34,6 +36,12 @@ | |||
34 | #include <asm/suspend.h> | 36 | #include <asm/suspend.h> |
35 | #include <cpu/sh7723.h> | 37 | #include <cpu/sh7723.h> |
36 | 38 | ||
39 | /* Dummy supplies, where voltage doesn't matter */ | ||
40 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
41 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
42 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
43 | }; | ||
44 | |||
37 | static struct smsc911x_platform_config smsc911x_config = { | 45 | static struct smsc911x_platform_config smsc911x_config = { |
38 | .phy_interface = PHY_INTERFACE_MODE_MII, | 46 | .phy_interface = PHY_INTERFACE_MODE_MII, |
39 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | 47 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, |
@@ -423,6 +431,15 @@ static struct platform_device ceu_device = { | |||
423 | }, | 431 | }, |
424 | }; | 432 | }; |
425 | 433 | ||
434 | /* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */ | ||
435 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
436 | { | ||
437 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
438 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
439 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
440 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
441 | }; | ||
442 | |||
426 | static struct resource sdhi0_cn3_resources[] = { | 443 | static struct resource sdhi0_cn3_resources[] = { |
427 | [0] = { | 444 | [0] = { |
428 | .name = "SDHI0", | 445 | .name = "SDHI0", |
@@ -544,6 +561,10 @@ static int __init ap325rxa_devices_setup(void) | |||
544 | &ap325rxa_sdram_leave_start, | 561 | &ap325rxa_sdram_leave_start, |
545 | &ap325rxa_sdram_leave_end); | 562 | &ap325rxa_sdram_leave_end); |
546 | 563 | ||
564 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
565 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
566 | regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
567 | |||
547 | /* LD3 and LD4 LEDs */ | 568 | /* LD3 and LD4 LEDs */ |
548 | gpio_request(GPIO_PTX5, NULL); /* RUN */ | 569 | gpio_request(GPIO_PTX5, NULL); /* RUN */ |
549 | gpio_direction_output(GPIO_PTX5, 1); | 570 | gpio_direction_output(GPIO_PTX5, 1); |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 4158d70c0dea..64559e8af14b 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/regulator/fixed.h> | ||
23 | #include <linux/regulator/machine.h> | ||
22 | #include <linux/usb/r8a66597.h> | 24 | #include <linux/usb/r8a66597.h> |
23 | #include <linux/usb/renesas_usbhs.h> | 25 | #include <linux/usb/renesas_usbhs.h> |
24 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
@@ -242,9 +244,17 @@ static int usbhs_get_id(struct platform_device *pdev) | |||
242 | return gpio_get_value(GPIO_PTB3); | 244 | return gpio_get_value(GPIO_PTB3); |
243 | } | 245 | } |
244 | 246 | ||
247 | static void usbhs_phy_reset(struct platform_device *pdev) | ||
248 | { | ||
249 | /* enable vbus if HOST */ | ||
250 | if (!gpio_get_value(GPIO_PTB3)) | ||
251 | gpio_set_value(GPIO_PTB5, 1); | ||
252 | } | ||
253 | |||
245 | static struct renesas_usbhs_platform_info usbhs_info = { | 254 | static struct renesas_usbhs_platform_info usbhs_info = { |
246 | .platform_callback = { | 255 | .platform_callback = { |
247 | .get_id = usbhs_get_id, | 256 | .get_id = usbhs_get_id, |
257 | .phy_reset = usbhs_phy_reset, | ||
248 | }, | 258 | }, |
249 | .driver_param = { | 259 | .driver_param = { |
250 | .buswait_bwait = 4, | 260 | .buswait_bwait = 4, |
@@ -518,10 +528,86 @@ static struct i2c_board_info ts_i2c_clients = { | |||
518 | .irq = IRQ0, | 528 | .irq = IRQ0, |
519 | }; | 529 | }; |
520 | 530 | ||
531 | static struct regulator_consumer_supply cn12_power_consumers[] = | ||
532 | { | ||
533 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
534 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
535 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
536 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
537 | }; | ||
538 | |||
539 | static struct regulator_init_data cn12_power_init_data = { | ||
540 | .constraints = { | ||
541 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
542 | }, | ||
543 | .num_consumer_supplies = ARRAY_SIZE(cn12_power_consumers), | ||
544 | .consumer_supplies = cn12_power_consumers, | ||
545 | }; | ||
546 | |||
547 | static struct fixed_voltage_config cn12_power_info = { | ||
548 | .supply_name = "CN12 SD/MMC Vdd", | ||
549 | .microvolts = 3300000, | ||
550 | .gpio = GPIO_PTB7, | ||
551 | .enable_high = 1, | ||
552 | .init_data = &cn12_power_init_data, | ||
553 | }; | ||
554 | |||
555 | static struct platform_device cn12_power = { | ||
556 | .name = "reg-fixed-voltage", | ||
557 | .id = 0, | ||
558 | .dev = { | ||
559 | .platform_data = &cn12_power_info, | ||
560 | }, | ||
561 | }; | ||
562 | |||
521 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 563 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
522 | /* SDHI0 */ | 564 | /* SDHI0 */ |
565 | static struct regulator_consumer_supply sdhi0_power_consumers[] = | ||
566 | { | ||
567 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
568 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
569 | }; | ||
570 | |||
571 | static struct regulator_init_data sdhi0_power_init_data = { | ||
572 | .constraints = { | ||
573 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
574 | }, | ||
575 | .num_consumer_supplies = ARRAY_SIZE(sdhi0_power_consumers), | ||
576 | .consumer_supplies = sdhi0_power_consumers, | ||
577 | }; | ||
578 | |||
579 | static struct fixed_voltage_config sdhi0_power_info = { | ||
580 | .supply_name = "CN11 SD/MMC Vdd", | ||
581 | .microvolts = 3300000, | ||
582 | .gpio = GPIO_PTB6, | ||
583 | .enable_high = 1, | ||
584 | .init_data = &sdhi0_power_init_data, | ||
585 | }; | ||
586 | |||
587 | static struct platform_device sdhi0_power = { | ||
588 | .name = "reg-fixed-voltage", | ||
589 | .id = 1, | ||
590 | .dev = { | ||
591 | .platform_data = &sdhi0_power_info, | ||
592 | }, | ||
593 | }; | ||
594 | |||
523 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) | 595 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) |
524 | { | 596 | { |
597 | static int power_gpio = -EINVAL; | ||
598 | |||
599 | if (power_gpio < 0) { | ||
600 | int ret = gpio_request(GPIO_PTB6, NULL); | ||
601 | if (!ret) { | ||
602 | power_gpio = GPIO_PTB6; | ||
603 | gpio_direction_output(power_gpio, 0); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * Toggle the GPIO regardless, whether we managed to grab it above or | ||
609 | * the fixed regulator driver did. | ||
610 | */ | ||
525 | gpio_set_value(GPIO_PTB6, state); | 611 | gpio_set_value(GPIO_PTB6, state); |
526 | } | 612 | } |
527 | 613 | ||
@@ -562,13 +648,27 @@ static struct platform_device sdhi0_device = { | |||
562 | }, | 648 | }, |
563 | }; | 649 | }; |
564 | 650 | ||
565 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 651 | static void cn12_set_pwr(struct platform_device *pdev, int state) |
566 | /* SDHI1 */ | ||
567 | static void sdhi1_set_pwr(struct platform_device *pdev, int state) | ||
568 | { | 652 | { |
653 | static int power_gpio = -EINVAL; | ||
654 | |||
655 | if (power_gpio < 0) { | ||
656 | int ret = gpio_request(GPIO_PTB7, NULL); | ||
657 | if (!ret) { | ||
658 | power_gpio = GPIO_PTB7; | ||
659 | gpio_direction_output(power_gpio, 0); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | /* | ||
664 | * Toggle the GPIO regardless, whether we managed to grab it above or | ||
665 | * the fixed regulator driver did. | ||
666 | */ | ||
569 | gpio_set_value(GPIO_PTB7, state); | 667 | gpio_set_value(GPIO_PTB7, state); |
570 | } | 668 | } |
571 | 669 | ||
670 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | ||
671 | /* SDHI1 */ | ||
572 | static int sdhi1_get_cd(struct platform_device *pdev) | 672 | static int sdhi1_get_cd(struct platform_device *pdev) |
573 | { | 673 | { |
574 | return !gpio_get_value(GPIO_PTW7); | 674 | return !gpio_get_value(GPIO_PTW7); |
@@ -579,7 +679,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { | |||
579 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 679 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
580 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | | 680 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | |
581 | MMC_CAP_NEEDS_POLL, | 681 | MMC_CAP_NEEDS_POLL, |
582 | .set_pwr = sdhi1_set_pwr, | 682 | .set_pwr = cn12_set_pwr, |
583 | .get_cd = sdhi1_get_cd, | 683 | .get_cd = sdhi1_get_cd, |
584 | }; | 684 | }; |
585 | 685 | ||
@@ -899,14 +999,9 @@ static struct platform_device vou_device = { | |||
899 | 999 | ||
900 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) | 1000 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) |
901 | /* SH_MMCIF */ | 1001 | /* SH_MMCIF */ |
902 | static void mmcif_set_pwr(struct platform_device *pdev, int state) | ||
903 | { | ||
904 | gpio_set_value(GPIO_PTB7, state); | ||
905 | } | ||
906 | |||
907 | static void mmcif_down_pwr(struct platform_device *pdev) | 1002 | static void mmcif_down_pwr(struct platform_device *pdev) |
908 | { | 1003 | { |
909 | gpio_set_value(GPIO_PTB7, 0); | 1004 | cn12_set_pwr(pdev, 0); |
910 | } | 1005 | } |
911 | 1006 | ||
912 | static struct resource sh_mmcif_resources[] = { | 1007 | static struct resource sh_mmcif_resources[] = { |
@@ -929,7 +1024,7 @@ static struct resource sh_mmcif_resources[] = { | |||
929 | }; | 1024 | }; |
930 | 1025 | ||
931 | static struct sh_mmcif_plat_data sh_mmcif_plat = { | 1026 | static struct sh_mmcif_plat_data sh_mmcif_plat = { |
932 | .set_pwr = mmcif_set_pwr, | 1027 | .set_pwr = cn12_set_pwr, |
933 | .down_pwr = mmcif_down_pwr, | 1028 | .down_pwr = mmcif_down_pwr, |
934 | .sup_pclk = 0, /* SH7724: Max Pclk/2 */ | 1029 | .sup_pclk = 0, /* SH7724: Max Pclk/2 */ |
935 | .caps = MMC_CAP_4_BIT_DATA | | 1030 | .caps = MMC_CAP_4_BIT_DATA | |
@@ -960,7 +1055,9 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
960 | &ceu0_device, | 1055 | &ceu0_device, |
961 | &ceu1_device, | 1056 | &ceu1_device, |
962 | &keysc_device, | 1057 | &keysc_device, |
1058 | &cn12_power, | ||
963 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 1059 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
1060 | &sdhi0_power, | ||
964 | &sdhi0_device, | 1061 | &sdhi0_device, |
965 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 1062 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
966 | &sdhi1_device, | 1063 | &sdhi1_device, |
@@ -1258,8 +1355,6 @@ static int __init arch_setup(void) | |||
1258 | gpio_request(GPIO_FN_SDHI0D2, NULL); | 1355 | gpio_request(GPIO_FN_SDHI0D2, NULL); |
1259 | gpio_request(GPIO_FN_SDHI0D1, NULL); | 1356 | gpio_request(GPIO_FN_SDHI0D1, NULL); |
1260 | gpio_request(GPIO_FN_SDHI0D0, NULL); | 1357 | gpio_request(GPIO_FN_SDHI0D0, NULL); |
1261 | gpio_request(GPIO_PTB6, NULL); | ||
1262 | gpio_direction_output(GPIO_PTB6, 0); | ||
1263 | #else | 1358 | #else |
1264 | /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ | 1359 | /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ |
1265 | gpio_request(GPIO_FN_MSIOF0_TXD, NULL); | 1360 | gpio_request(GPIO_FN_MSIOF0_TXD, NULL); |
@@ -1288,8 +1383,6 @@ static int __init arch_setup(void) | |||
1288 | gpio_request(GPIO_FN_MMC_D0, NULL); | 1383 | gpio_request(GPIO_FN_MMC_D0, NULL); |
1289 | gpio_request(GPIO_FN_MMC_CLK, NULL); | 1384 | gpio_request(GPIO_FN_MMC_CLK, NULL); |
1290 | gpio_request(GPIO_FN_MMC_CMD, NULL); | 1385 | gpio_request(GPIO_FN_MMC_CMD, NULL); |
1291 | gpio_request(GPIO_PTB7, NULL); | ||
1292 | gpio_direction_output(GPIO_PTB7, 0); | ||
1293 | 1386 | ||
1294 | cn12_enabled = true; | 1387 | cn12_enabled = true; |
1295 | #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 1388 | #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
@@ -1301,8 +1394,6 @@ static int __init arch_setup(void) | |||
1301 | gpio_request(GPIO_FN_SDHI1D2, NULL); | 1394 | gpio_request(GPIO_FN_SDHI1D2, NULL); |
1302 | gpio_request(GPIO_FN_SDHI1D1, NULL); | 1395 | gpio_request(GPIO_FN_SDHI1D1, NULL); |
1303 | gpio_request(GPIO_FN_SDHI1D0, NULL); | 1396 | gpio_request(GPIO_FN_SDHI1D0, NULL); |
1304 | gpio_request(GPIO_PTB7, NULL); | ||
1305 | gpio_direction_output(GPIO_PTB7, 0); | ||
1306 | 1397 | ||
1307 | /* Card-detect, used on CN12 with SDHI1 */ | 1398 | /* Card-detect, used on CN12 with SDHI1 */ |
1308 | gpio_request(GPIO_PTW7, NULL); | 1399 | gpio_request(GPIO_PTW7, NULL); |
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 43a179ce9afc..f2a4304fbe23 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | #include <linux/input/sh_keysc.h> | 22 | #include <linux/input/sh_keysc.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/regulator/fixed.h> | ||
25 | #include <linux/regulator/machine.h> | ||
24 | #include <linux/usb/r8a66597.h> | 26 | #include <linux/usb/r8a66597.h> |
25 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
26 | #include <linux/sh_intc.h> | 28 | #include <linux/sh_intc.h> |
@@ -341,6 +343,13 @@ static struct platform_device kfr2r09_camera = { | |||
341 | }, | 343 | }, |
342 | }; | 344 | }; |
343 | 345 | ||
346 | /* Fixed 3.3V regulator to be used by SDHI0 */ | ||
347 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
348 | { | ||
349 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
350 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
351 | }; | ||
352 | |||
344 | static struct resource kfr2r09_sh_sdhi0_resources[] = { | 353 | static struct resource kfr2r09_sh_sdhi0_resources[] = { |
345 | [0] = { | 354 | [0] = { |
346 | .name = "SDHI0", | 355 | .name = "SDHI0", |
@@ -523,6 +532,9 @@ static int __init kfr2r09_devices_setup(void) | |||
523 | &kfr2r09_sdram_leave_start, | 532 | &kfr2r09_sdram_leave_start, |
524 | &kfr2r09_sdram_leave_end); | 533 | &kfr2r09_sdram_leave_end); |
525 | 534 | ||
535 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
536 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
537 | |||
526 | /* enable SCIF1 serial port for YC401 console support */ | 538 | /* enable SCIF1 serial port for YC401 console support */ |
527 | gpio_request(GPIO_FN_SCIF1_RXD, NULL); | 539 | gpio_request(GPIO_FN_SCIF1_RXD, NULL); |
528 | gpio_request(GPIO_FN_SCIF1_TXD, NULL); | 540 | gpio_request(GPIO_FN_SCIF1_TXD, NULL); |
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index a8a1ca741c85..8b73194ed2ce 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
18 | #include <linux/mtd/nand.h> | 18 | #include <linux/mtd/nand.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/regulator/fixed.h> | ||
21 | #include <linux/regulator/machine.h> | ||
20 | #include <linux/smc91x.h> | 22 | #include <linux/smc91x.h> |
21 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
22 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
@@ -386,6 +388,13 @@ static struct platform_device migor_ceu_device = { | |||
386 | }, | 388 | }, |
387 | }; | 389 | }; |
388 | 390 | ||
391 | /* Fixed 3.3V regulator to be used by SDHI0 */ | ||
392 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
393 | { | ||
394 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
395 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
396 | }; | ||
397 | |||
389 | static struct resource sdhi_cn9_resources[] = { | 398 | static struct resource sdhi_cn9_resources[] = { |
390 | [0] = { | 399 | [0] = { |
391 | .name = "SDHI", | 400 | .name = "SDHI", |
@@ -498,6 +507,10 @@ static int __init migor_devices_setup(void) | |||
498 | &migor_sdram_enter_end, | 507 | &migor_sdram_enter_end, |
499 | &migor_sdram_leave_start, | 508 | &migor_sdram_leave_start, |
500 | &migor_sdram_leave_end); | 509 | &migor_sdram_leave_end); |
510 | |||
511 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
512 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
513 | |||
501 | /* Let D11 LED show STATUS0 */ | 514 | /* Let D11 LED show STATUS0 */ |
502 | gpio_request(GPIO_FN_STATUS0, NULL); | 515 | gpio_request(GPIO_FN_STATUS0, NULL); |
503 | 516 | ||
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c index 895f030070d3..2685ea03b064 100644 --- a/arch/sh/boards/mach-rsk/setup.c +++ b/arch/sh/boards/mach-rsk/setup.c | |||
@@ -16,9 +16,17 @@ | |||
16 | #include <linux/mtd/partitions.h> | 16 | #include <linux/mtd/partitions.h> |
17 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
18 | #include <linux/mtd/map.h> | 18 | #include <linux/mtd/map.h> |
19 | #include <linux/regulator/fixed.h> | ||
20 | #include <linux/regulator/machine.h> | ||
19 | #include <asm/machvec.h> | 21 | #include <asm/machvec.h> |
20 | #include <asm/io.h> | 22 | #include <asm/io.h> |
21 | 23 | ||
24 | /* Dummy supplies, where voltage doesn't matter */ | ||
25 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
26 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
27 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
28 | }; | ||
29 | |||
22 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 30 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
23 | 31 | ||
24 | static struct mtd_partition rsk_partitions[] = { | 32 | static struct mtd_partition rsk_partitions[] = { |
@@ -67,6 +75,8 @@ static struct platform_device *rsk_devices[] __initdata = { | |||
67 | 75 | ||
68 | static int __init rsk_devices_setup(void) | 76 | static int __init rsk_devices_setup(void) |
69 | { | 77 | { |
78 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
79 | |||
70 | return platform_add_devices(rsk_devices, | 80 | return platform_add_devices(rsk_devices, |
71 | ARRAY_SIZE(rsk_devices)); | 81 | ARRAY_SIZE(rsk_devices)); |
72 | } | 82 | } |
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 27a2314f50ac..c29268bfd34a 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/regulator/fixed.h> | ||
15 | #include <linux/regulator/machine.h> | ||
14 | #include <linux/smsc911x.h> | 16 | #include <linux/smsc911x.h> |
15 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
16 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
@@ -38,6 +40,12 @@ static struct platform_device heartbeat_device = { | |||
38 | .resource = &heartbeat_resource, | 40 | .resource = &heartbeat_resource, |
39 | }; | 41 | }; |
40 | 42 | ||
43 | /* Dummy supplies, where voltage doesn't matter */ | ||
44 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
45 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
46 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
47 | }; | ||
48 | |||
41 | static struct resource smsc911x_resources[] = { | 49 | static struct resource smsc911x_resources[] = { |
42 | [0] = { | 50 | [0] = { |
43 | .name = "smsc911x-memory", | 51 | .name = "smsc911x-memory", |
@@ -236,6 +244,8 @@ static void __init sdk7786_setup(char **cmdline_p) | |||
236 | { | 244 | { |
237 | pr_info("Renesas Technology Europe SDK7786 support:\n"); | 245 | pr_info("Renesas Technology Europe SDK7786 support:\n"); |
238 | 246 | ||
247 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
248 | |||
239 | sdk7786_fpga_init(); | 249 | sdk7786_fpga_init(); |
240 | sdk7786_nmi_init(); | 250 | sdk7786_nmi_init(); |
241 | 251 | ||
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index ffbf5bc7366b..35f6efa3ac0e 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/mmc/sh_mobile_sdhi.h> | 18 | #include <linux/mmc/sh_mobile_sdhi.h> |
19 | #include <linux/mtd/physmap.h> | 19 | #include <linux/mtd/physmap.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/regulator/fixed.h> | ||
22 | #include <linux/regulator/machine.h> | ||
21 | #include <linux/smc91x.h> | 23 | #include <linux/smc91x.h> |
22 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
23 | #include <linux/input.h> | 25 | #include <linux/input.h> |
@@ -454,6 +456,15 @@ static struct platform_device sh7724_usb1_gadget_device = { | |||
454 | .resource = sh7724_usb1_gadget_resources, | 456 | .resource = sh7724_usb1_gadget_resources, |
455 | }; | 457 | }; |
456 | 458 | ||
459 | /* Fixed 3.3V regulator to be used by SDHI0, SDHI1 */ | ||
460 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
461 | { | ||
462 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
463 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
464 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
465 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
466 | }; | ||
467 | |||
457 | static struct resource sdhi0_cn7_resources[] = { | 468 | static struct resource sdhi0_cn7_resources[] = { |
458 | [0] = { | 469 | [0] = { |
459 | .name = "SDHI0", | 470 | .name = "SDHI0", |
@@ -684,6 +695,10 @@ static int __init devices_setup(void) | |||
684 | &ms7724se_sdram_enter_end, | 695 | &ms7724se_sdram_enter_end, |
685 | &ms7724se_sdram_leave_start, | 696 | &ms7724se_sdram_leave_start, |
686 | &ms7724se_sdram_leave_end); | 697 | &ms7724se_sdram_leave_end); |
698 | |||
699 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
700 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
701 | |||
687 | /* Reset Release */ | 702 | /* Reset Release */ |
688 | fpga_out = __raw_readw(FPGA_OUT); | 703 | fpga_out = __raw_readw(FPGA_OUT); |
689 | /* bit4: NTSC_PDN, bit5: NTSC_RESET */ | 704 | /* bit4: NTSC_PDN, bit5: NTSC_RESET */ |
diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig index e7583484cc07..95ae23fcfdd6 100644 --- a/arch/sh/configs/apsh4ad0a_defconfig +++ b/arch/sh/configs/apsh4ad0a_defconfig | |||
@@ -11,7 +11,7 @@ CONFIG_CGROUP_FREEZER=y | |||
11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
12 | CONFIG_CGROUP_CPUACCT=y | 12 | CONFIG_CGROUP_CPUACCT=y |
13 | CONFIG_RESOURCE_COUNTERS=y | 13 | CONFIG_RESOURCE_COUNTERS=y |
14 | CONFIG_CGROUP_MEM_RES_CTLR=y | 14 | CONFIG_CGROUP_MEMCG=y |
15 | CONFIG_BLK_CGROUP=y | 15 | CONFIG_BLK_CGROUP=y |
16 | CONFIG_NAMESPACES=y | 16 | CONFIG_NAMESPACES=y |
17 | CONFIG_BLK_DEV_INITRD=y | 17 | CONFIG_BLK_DEV_INITRD=y |
diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 8a7dd7b59c5c..76a76a295d74 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig | |||
@@ -18,8 +18,8 @@ CONFIG_CPUSETS=y | |||
18 | # CONFIG_PROC_PID_CPUSET is not set | 18 | # CONFIG_PROC_PID_CPUSET is not set |
19 | CONFIG_CGROUP_CPUACCT=y | 19 | CONFIG_CGROUP_CPUACCT=y |
20 | CONFIG_RESOURCE_COUNTERS=y | 20 | CONFIG_RESOURCE_COUNTERS=y |
21 | CONFIG_CGROUP_MEM_RES_CTLR=y | 21 | CONFIG_CGROUP_MEMCG=y |
22 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 22 | CONFIG_CGROUP_MEMCG_SWAP=y |
23 | CONFIG_CGROUP_SCHED=y | 23 | CONFIG_CGROUP_SCHED=y |
24 | CONFIG_RT_GROUP_SCHED=y | 24 | CONFIG_RT_GROUP_SCHED=y |
25 | CONFIG_BLK_CGROUP=y | 25 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 72c3fad7383f..6bc30ab9fd18 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig | |||
@@ -11,7 +11,7 @@ CONFIG_CGROUP_DEBUG=y | |||
11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
12 | CONFIG_CGROUP_CPUACCT=y | 12 | CONFIG_CGROUP_CPUACCT=y |
13 | CONFIG_RESOURCE_COUNTERS=y | 13 | CONFIG_RESOURCE_COUNTERS=y |
14 | CONFIG_CGROUP_MEM_RES_CTLR=y | 14 | CONFIG_CGROUP_MEMCG=y |
15 | CONFIG_RELAY=y | 15 | CONFIG_RELAY=y |
16 | CONFIG_NAMESPACES=y | 16 | CONFIG_NAMESPACES=y |
17 | CONFIG_UTS_NS=y | 17 | CONFIG_UTS_NS=y |
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index 6bb413036892..cd6c519f8fad 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig | |||
@@ -13,7 +13,7 @@ CONFIG_CGROUP_FREEZER=y | |||
13 | CONFIG_CGROUP_DEVICE=y | 13 | CONFIG_CGROUP_DEVICE=y |
14 | CONFIG_CGROUP_CPUACCT=y | 14 | CONFIG_CGROUP_CPUACCT=y |
15 | CONFIG_RESOURCE_COUNTERS=y | 15 | CONFIG_RESOURCE_COUNTERS=y |
16 | CONFIG_CGROUP_MEM_RES_CTLR=y | 16 | CONFIG_CGROUP_MEMCG=y |
17 | CONFIG_RELAY=y | 17 | CONFIG_RELAY=y |
18 | CONFIG_NAMESPACES=y | 18 | CONFIG_NAMESPACES=y |
19 | CONFIG_UTS_NS=y | 19 | CONFIG_UTS_NS=y |
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 8bfa4d056d7a..d7f89be9f474 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig | |||
@@ -15,8 +15,8 @@ CONFIG_CPUSETS=y | |||
15 | # CONFIG_PROC_PID_CPUSET is not set | 15 | # CONFIG_PROC_PID_CPUSET is not set |
16 | CONFIG_CGROUP_CPUACCT=y | 16 | CONFIG_CGROUP_CPUACCT=y |
17 | CONFIG_RESOURCE_COUNTERS=y | 17 | CONFIG_RESOURCE_COUNTERS=y |
18 | CONFIG_CGROUP_MEM_RES_CTLR=y | 18 | CONFIG_CGROUP_MEMCG=y |
19 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 19 | CONFIG_CGROUP_MEMCG_SWAP=y |
20 | CONFIG_CGROUP_SCHED=y | 20 | CONFIG_CGROUP_SCHED=y |
21 | CONFIG_RT_GROUP_SCHED=y | 21 | CONFIG_RT_GROUP_SCHED=y |
22 | CONFIG_BLK_DEV_INITRD=y | 22 | CONFIG_BLK_DEV_INITRD=y |
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h index 41f9f8b9db73..5340f3bc1863 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h | |||
@@ -283,5 +283,7 @@ enum { | |||
283 | SHDMA_SLAVE_RIIC8_RX, | 283 | SHDMA_SLAVE_RIIC8_RX, |
284 | SHDMA_SLAVE_RIIC9_TX, | 284 | SHDMA_SLAVE_RIIC9_TX, |
285 | SHDMA_SLAVE_RIIC9_RX, | 285 | SHDMA_SLAVE_RIIC9_RX, |
286 | SHDMA_SLAVE_RSPI_TX, | ||
287 | SHDMA_SLAVE_RSPI_RX, | ||
286 | }; | 288 | }; |
287 | #endif /* __ASM_SH7757_H__ */ | 289 | #endif /* __ASM_SH7757_H__ */ |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index c87e78f73234..5f30f805d2f2 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c | |||
@@ -334,8 +334,8 @@ static struct clk_lookup lookups[] = { | |||
334 | CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]), | 334 | CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]), |
335 | CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]), | 335 | CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]), |
336 | CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]), | 336 | CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]), |
337 | CLKDEV_CON_ID("usb1", &mstp_clks[HWBLK_USB1]), | 337 | CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[HWBLK_USB1]), |
338 | CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB0]), | 338 | CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[HWBLK_USB0]), |
339 | CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), | 339 | CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), |
340 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]), | 340 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]), |
341 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]), | 341 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]), |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 65786c7f5ded..6a868b091c2d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/serial.h> | 13 | #include <linux/serial.h> |
14 | #include <linux/serial_sci.h> | 14 | #include <linux/serial_sci.h> |
15 | #include <linux/sh_dma.h> | ||
15 | #include <linux/sh_timer.h> | 16 | #include <linux/sh_timer.h> |
16 | #include <linux/sh_intc.h> | 17 | #include <linux/sh_intc.h> |
17 | #include <linux/uio_driver.h> | 18 | #include <linux/uio_driver.h> |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index a7708425afa9..4a2f357f4df8 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c | |||
@@ -216,6 +216,20 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { | |||
216 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 216 | TS_INDEX2VAL(XMIT_SZ_8BIT), |
217 | .mid_rid = 0x42, | 217 | .mid_rid = 0x42, |
218 | }, | 218 | }, |
219 | { | ||
220 | .slave_id = SHDMA_SLAVE_RSPI_TX, | ||
221 | .addr = 0xfe480004, | ||
222 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
223 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
224 | .mid_rid = 0xc1, | ||
225 | }, | ||
226 | { | ||
227 | .slave_id = SHDMA_SLAVE_RSPI_RX, | ||
228 | .addr = 0xfe480004, | ||
229 | .chcr = DM_INC | 0x800 | 0x40000000 | | ||
230 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
231 | .mid_rid = 0xc2, | ||
232 | }, | ||
219 | }; | 233 | }; |
220 | 234 | ||
221 | static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { | 235 | static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { |
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 1fc25d85e515..3bdc1ad9a341 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c | |||
@@ -58,11 +58,15 @@ static void show_pte(struct mm_struct *mm, unsigned long addr) | |||
58 | { | 58 | { |
59 | pgd_t *pgd; | 59 | pgd_t *pgd; |
60 | 60 | ||
61 | if (mm) | 61 | if (mm) { |
62 | pgd = mm->pgd; | 62 | pgd = mm->pgd; |
63 | else | 63 | } else { |
64 | pgd = get_TTB(); | 64 | pgd = get_TTB(); |
65 | 65 | ||
66 | if (unlikely(!pgd)) | ||
67 | pgd = swapper_pg_dir; | ||
68 | } | ||
69 | |||
66 | printk(KERN_ALERT "pgd = %p\n", pgd); | 70 | printk(KERN_ALERT "pgd = %p\n", pgd); |
67 | pgd += pgd_index(addr); | 71 | pgd += pgd_index(addr); |
68 | printk(KERN_ALERT "[%08lx] *pgd=%0*Lx", addr, | 72 | printk(KERN_ALERT "[%08lx] *pgd=%0*Lx", addr, |
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 435e406fdec3..81d92fc9983b 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
@@ -1250,14 +1250,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name) | |||
1250 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); | 1250 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); |
1251 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | 1251 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); |
1252 | 1252 | ||
1253 | err = request_irq(lp->cfg.rx_irq, ldc_rx, | 1253 | err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED, |
1254 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
1255 | lp->rx_irq_name, lp); | 1254 | lp->rx_irq_name, lp); |
1256 | if (err) | 1255 | if (err) |
1257 | return err; | 1256 | return err; |
1258 | 1257 | ||
1259 | err = request_irq(lp->cfg.tx_irq, ldc_tx, | 1258 | err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED, |
1260 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
1261 | lp->tx_irq_name, lp); | 1259 | lp->tx_irq_name, lp); |
1262 | if (err) { | 1260 | if (err) { |
1263 | free_irq(lp->cfg.rx_irq, lp); | 1261 | free_irq(lp->cfg.rx_irq, lp); |
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index b8d99aca5431..0270620a1692 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig | |||
@@ -18,8 +18,8 @@ CONFIG_CGROUP_DEVICE=y | |||
18 | CONFIG_CPUSETS=y | 18 | CONFIG_CPUSETS=y |
19 | CONFIG_CGROUP_CPUACCT=y | 19 | CONFIG_CGROUP_CPUACCT=y |
20 | CONFIG_RESOURCE_COUNTERS=y | 20 | CONFIG_RESOURCE_COUNTERS=y |
21 | CONFIG_CGROUP_MEM_RES_CTLR=y | 21 | CONFIG_CGROUP_MEMCG=y |
22 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 22 | CONFIG_CGROUP_MEMCG_SWAP=y |
23 | CONFIG_CGROUP_SCHED=y | 23 | CONFIG_CGROUP_SCHED=y |
24 | CONFIG_RT_GROUP_SCHED=y | 24 | CONFIG_RT_GROUP_SCHED=y |
25 | CONFIG_BLK_CGROUP=y | 25 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 2b1fd31894f1..c11de27a9bcb 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig | |||
@@ -17,8 +17,8 @@ CONFIG_CGROUP_DEVICE=y | |||
17 | CONFIG_CPUSETS=y | 17 | CONFIG_CPUSETS=y |
18 | CONFIG_CGROUP_CPUACCT=y | 18 | CONFIG_CGROUP_CPUACCT=y |
19 | CONFIG_RESOURCE_COUNTERS=y | 19 | CONFIG_RESOURCE_COUNTERS=y |
20 | CONFIG_CGROUP_MEM_RES_CTLR=y | 20 | CONFIG_CGROUP_MEMCG=y |
21 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 21 | CONFIG_CGROUP_MEMCG_SWAP=y |
22 | CONFIG_CGROUP_SCHED=y | 22 | CONFIG_CGROUP_SCHED=y |
23 | CONFIG_RT_GROUP_SCHED=y | 23 | CONFIG_RT_GROUP_SCHED=y |
24 | CONFIG_BLK_CGROUP=y | 24 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/um/defconfig b/arch/um/defconfig index 7823ab12e6a4..08107a795062 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig | |||
@@ -155,15 +155,15 @@ CONFIG_CPUSETS=y | |||
155 | CONFIG_PROC_PID_CPUSET=y | 155 | CONFIG_PROC_PID_CPUSET=y |
156 | CONFIG_CGROUP_CPUACCT=y | 156 | CONFIG_CGROUP_CPUACCT=y |
157 | CONFIG_RESOURCE_COUNTERS=y | 157 | CONFIG_RESOURCE_COUNTERS=y |
158 | CONFIG_CGROUP_MEM_RES_CTLR=y | 158 | CONFIG_CGROUP_MEMCG=y |
159 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 159 | CONFIG_CGROUP_MEMCG_SWAP=y |
160 | # CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set | 160 | # CONFIG_CGROUP_MEMCG_SWAP_ENABLED is not set |
161 | # CONFIG_CGROUP_MEM_RES_CTLR_KMEM is not set | 161 | # CONFIG_CGROUP_MEMCG_KMEM is not set |
162 | CONFIG_CGROUP_SCHED=y | 162 | CONFIG_CGROUP_SCHED=y |
163 | CONFIG_FAIR_GROUP_SCHED=y | 163 | CONFIG_FAIR_GROUP_SCHED=y |
164 | # CONFIG_CFS_BANDWIDTH is not set | 164 | # CONFIG_CFS_BANDWIDTH is not set |
165 | # CONFIG_RT_GROUP_SCHED is not set | 165 | # CONFIG_RT_GROUP_SCHED is not set |
166 | CONFIG_BLK_CGROUP=m | 166 | CONFIG_BLK_CGROUP=y |
167 | # CONFIG_DEBUG_BLK_CGROUP is not set | 167 | # CONFIG_DEBUG_BLK_CGROUP is not set |
168 | # CONFIG_CHECKPOINT_RESTORE is not set | 168 | # CONFIG_CHECKPOINT_RESTORE is not set |
169 | CONFIG_NAMESPACES=y | 169 | CONFIG_NAMESPACES=y |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 45e248c2f43c..87eebfe03c61 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -150,9 +150,11 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty) | |||
150 | static void line_timer_cb(struct work_struct *work) | 150 | static void line_timer_cb(struct work_struct *work) |
151 | { | 151 | { |
152 | struct line *line = container_of(work, struct line, task.work); | 152 | struct line *line = container_of(work, struct line, task.work); |
153 | struct tty_struct *tty = tty_port_tty_get(&line->port); | ||
153 | 154 | ||
154 | if (!line->throttled) | 155 | if (!line->throttled) |
155 | chan_interrupt(line, line->tty, line->driver->read_irq); | 156 | chan_interrupt(line, tty, line->driver->read_irq); |
157 | tty_kref_put(tty); | ||
156 | } | 158 | } |
157 | 159 | ||
158 | int enable_chan(struct line *line) | 160 | int enable_chan(struct line *line) |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index acfd0e0fd0c9..bbaf2c59830a 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data) | |||
19 | { | 19 | { |
20 | struct chan *chan = data; | 20 | struct chan *chan = data; |
21 | struct line *line = chan->line; | 21 | struct line *line = chan->line; |
22 | struct tty_struct *tty = tty_port_tty_get(&line->port); | ||
22 | 23 | ||
23 | if (line) | 24 | if (line) |
24 | chan_interrupt(line, line->tty, irq); | 25 | chan_interrupt(line, tty, irq); |
26 | tty_kref_put(tty); | ||
25 | return IRQ_HANDLED; | 27 | return IRQ_HANDLED; |
26 | } | 28 | } |
27 | 29 | ||
@@ -219,92 +221,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old) | |||
219 | /* nothing */ | 221 | /* nothing */ |
220 | } | 222 | } |
221 | 223 | ||
222 | static const struct { | ||
223 | int cmd; | ||
224 | char *level; | ||
225 | char *name; | ||
226 | } tty_ioctls[] = { | ||
227 | /* don't print these, they flood the log ... */ | ||
228 | { TCGETS, NULL, "TCGETS" }, | ||
229 | { TCSETS, NULL, "TCSETS" }, | ||
230 | { TCSETSW, NULL, "TCSETSW" }, | ||
231 | { TCFLSH, NULL, "TCFLSH" }, | ||
232 | { TCSBRK, NULL, "TCSBRK" }, | ||
233 | |||
234 | /* general tty stuff */ | ||
235 | { TCSETSF, KERN_DEBUG, "TCSETSF" }, | ||
236 | { TCGETA, KERN_DEBUG, "TCGETA" }, | ||
237 | { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, | ||
238 | { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, | ||
239 | { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, | ||
240 | |||
241 | /* linux-specific ones */ | ||
242 | { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, | ||
243 | { KDGKBMODE, KERN_INFO, "KDGKBMODE" }, | ||
244 | { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" }, | ||
245 | { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, | ||
246 | }; | ||
247 | |||
248 | int line_ioctl(struct tty_struct *tty, unsigned int cmd, | ||
249 | unsigned long arg) | ||
250 | { | ||
251 | int ret; | ||
252 | int i; | ||
253 | |||
254 | ret = 0; | ||
255 | switch(cmd) { | ||
256 | #ifdef TIOCGETP | ||
257 | case TIOCGETP: | ||
258 | case TIOCSETP: | ||
259 | case TIOCSETN: | ||
260 | #endif | ||
261 | #ifdef TIOCGETC | ||
262 | case TIOCGETC: | ||
263 | case TIOCSETC: | ||
264 | #endif | ||
265 | #ifdef TIOCGLTC | ||
266 | case TIOCGLTC: | ||
267 | case TIOCSLTC: | ||
268 | #endif | ||
269 | /* Note: these are out of date as we now have TCGETS2 etc but this | ||
270 | whole lot should probably go away */ | ||
271 | case TCGETS: | ||
272 | case TCSETSF: | ||
273 | case TCSETSW: | ||
274 | case TCSETS: | ||
275 | case TCGETA: | ||
276 | case TCSETAF: | ||
277 | case TCSETAW: | ||
278 | case TCSETA: | ||
279 | case TCXONC: | ||
280 | case TCFLSH: | ||
281 | case TIOCOUTQ: | ||
282 | case TIOCINQ: | ||
283 | case TIOCGLCKTRMIOS: | ||
284 | case TIOCSLCKTRMIOS: | ||
285 | case TIOCPKT: | ||
286 | case TIOCGSOFTCAR: | ||
287 | case TIOCSSOFTCAR: | ||
288 | return -ENOIOCTLCMD; | ||
289 | #if 0 | ||
290 | case TCwhatever: | ||
291 | /* do something */ | ||
292 | break; | ||
293 | #endif | ||
294 | default: | ||
295 | for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) | ||
296 | if (cmd == tty_ioctls[i].cmd) | ||
297 | break; | ||
298 | if (i == ARRAY_SIZE(tty_ioctls)) { | ||
299 | printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", | ||
300 | __func__, tty->name, cmd); | ||
301 | } | ||
302 | ret = -ENOIOCTLCMD; | ||
303 | break; | ||
304 | } | ||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | void line_throttle(struct tty_struct *tty) | 224 | void line_throttle(struct tty_struct *tty) |
309 | { | 225 | { |
310 | struct line *line = tty->driver_data; | 226 | struct line *line = tty->driver_data; |
@@ -333,7 +249,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
333 | { | 249 | { |
334 | struct chan *chan = data; | 250 | struct chan *chan = data; |
335 | struct line *line = chan->line; | 251 | struct line *line = chan->line; |
336 | struct tty_struct *tty = line->tty; | 252 | struct tty_struct *tty; |
337 | int err; | 253 | int err; |
338 | 254 | ||
339 | /* | 255 | /* |
@@ -352,68 +268,42 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
352 | } | 268 | } |
353 | spin_unlock(&line->lock); | 269 | spin_unlock(&line->lock); |
354 | 270 | ||
271 | tty = tty_port_tty_get(&line->port); | ||
355 | if (tty == NULL) | 272 | if (tty == NULL) |
356 | return IRQ_NONE; | 273 | return IRQ_NONE; |
357 | 274 | ||
358 | tty_wakeup(tty); | 275 | tty_wakeup(tty); |
276 | tty_kref_put(tty); | ||
277 | |||
359 | return IRQ_HANDLED; | 278 | return IRQ_HANDLED; |
360 | } | 279 | } |
361 | 280 | ||
362 | int line_setup_irq(int fd, int input, int output, struct line *line, void *data) | 281 | int line_setup_irq(int fd, int input, int output, struct line *line, void *data) |
363 | { | 282 | { |
364 | const struct line_driver *driver = line->driver; | 283 | const struct line_driver *driver = line->driver; |
365 | int err = 0, flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM; | 284 | int err = 0; |
366 | 285 | ||
367 | if (input) | 286 | if (input) |
368 | err = um_request_irq(driver->read_irq, fd, IRQ_READ, | 287 | err = um_request_irq(driver->read_irq, fd, IRQ_READ, |
369 | line_interrupt, flags, | 288 | line_interrupt, IRQF_SHARED, |
370 | driver->read_irq_name, data); | 289 | driver->read_irq_name, data); |
371 | if (err) | 290 | if (err) |
372 | return err; | 291 | return err; |
373 | if (output) | 292 | if (output) |
374 | err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, | 293 | err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, |
375 | line_write_interrupt, flags, | 294 | line_write_interrupt, IRQF_SHARED, |
376 | driver->write_irq_name, data); | 295 | driver->write_irq_name, data); |
377 | return err; | 296 | return err; |
378 | } | 297 | } |
379 | 298 | ||
380 | /* | 299 | static int line_activate(struct tty_port *port, struct tty_struct *tty) |
381 | * Normally, a driver like this can rely mostly on the tty layer | ||
382 | * locking, particularly when it comes to the driver structure. | ||
383 | * However, in this case, mconsole requests can come in "from the | ||
384 | * side", and race with opens and closes. | ||
385 | * | ||
386 | * mconsole config requests will want to be sure the device isn't in | ||
387 | * use, and get_config, open, and close will want a stable | ||
388 | * configuration. The checking and modification of the configuration | ||
389 | * is done under a spinlock. Checking whether the device is in use is | ||
390 | * line->tty->count > 1, also under the spinlock. | ||
391 | * | ||
392 | * line->count serves to decide whether the device should be enabled or | ||
393 | * disabled on the host. If it's equal to 0, then we are doing the | ||
394 | * first open or last close. Otherwise, open and close just return. | ||
395 | */ | ||
396 | |||
397 | int line_open(struct line *lines, struct tty_struct *tty) | ||
398 | { | 300 | { |
399 | struct line *line = &lines[tty->index]; | 301 | int ret; |
400 | int err = -ENODEV; | 302 | struct line *line = tty->driver_data; |
401 | |||
402 | mutex_lock(&line->count_lock); | ||
403 | if (!line->valid) | ||
404 | goto out_unlock; | ||
405 | |||
406 | err = 0; | ||
407 | if (line->count++) | ||
408 | goto out_unlock; | ||
409 | |||
410 | BUG_ON(tty->driver_data); | ||
411 | tty->driver_data = line; | ||
412 | line->tty = tty; | ||
413 | 303 | ||
414 | err = enable_chan(line); | 304 | ret = enable_chan(line); |
415 | if (err) /* line_close() will be called by our caller */ | 305 | if (ret) |
416 | goto out_unlock; | 306 | return ret; |
417 | 307 | ||
418 | if (!line->sigio) { | 308 | if (!line->sigio) { |
419 | chan_enable_winch(line->chan_out, tty); | 309 | chan_enable_winch(line->chan_out, tty); |
@@ -421,44 +311,60 @@ int line_open(struct line *lines, struct tty_struct *tty) | |||
421 | } | 311 | } |
422 | 312 | ||
423 | chan_window_size(line, &tty->winsize.ws_row, | 313 | chan_window_size(line, &tty->winsize.ws_row, |
424 | &tty->winsize.ws_col); | 314 | &tty->winsize.ws_col); |
425 | out_unlock: | 315 | |
426 | mutex_unlock(&line->count_lock); | 316 | return 0; |
427 | return err; | ||
428 | } | 317 | } |
429 | 318 | ||
430 | static void unregister_winch(struct tty_struct *tty); | 319 | static const struct tty_port_operations line_port_ops = { |
320 | .activate = line_activate, | ||
321 | }; | ||
431 | 322 | ||
432 | void line_close(struct tty_struct *tty, struct file * filp) | 323 | int line_open(struct tty_struct *tty, struct file *filp) |
433 | { | 324 | { |
434 | struct line *line = tty->driver_data; | 325 | struct line *line = tty->driver_data; |
435 | 326 | ||
436 | /* | 327 | return tty_port_open(&line->port, tty, filp); |
437 | * If line_open fails (and tty->driver_data is never set), | 328 | } |
438 | * tty_open will call line_close. So just return in this case. | ||
439 | */ | ||
440 | if (line == NULL) | ||
441 | return; | ||
442 | 329 | ||
443 | /* We ignore the error anyway! */ | 330 | int line_install(struct tty_driver *driver, struct tty_struct *tty, |
444 | flush_buffer(line); | 331 | struct line *line) |
332 | { | ||
333 | int ret; | ||
445 | 334 | ||
446 | mutex_lock(&line->count_lock); | 335 | ret = tty_standard_install(driver, tty); |
447 | BUG_ON(!line->valid); | 336 | if (ret) |
337 | return ret; | ||
448 | 338 | ||
449 | if (--line->count) | 339 | tty->driver_data = line; |
450 | goto out_unlock; | ||
451 | 340 | ||
452 | line->tty = NULL; | 341 | return 0; |
453 | tty->driver_data = NULL; | 342 | } |
343 | |||
344 | static void unregister_winch(struct tty_struct *tty); | ||
345 | |||
346 | void line_cleanup(struct tty_struct *tty) | ||
347 | { | ||
348 | struct line *line = tty->driver_data; | ||
454 | 349 | ||
455 | if (line->sigio) { | 350 | if (line->sigio) { |
456 | unregister_winch(tty); | 351 | unregister_winch(tty); |
457 | line->sigio = 0; | 352 | line->sigio = 0; |
458 | } | 353 | } |
354 | } | ||
355 | |||
356 | void line_close(struct tty_struct *tty, struct file * filp) | ||
357 | { | ||
358 | struct line *line = tty->driver_data; | ||
459 | 359 | ||
460 | out_unlock: | 360 | tty_port_close(&line->port, tty, filp); |
461 | mutex_unlock(&line->count_lock); | 361 | } |
362 | |||
363 | void line_hangup(struct tty_struct *tty) | ||
364 | { | ||
365 | struct line *line = tty->driver_data; | ||
366 | |||
367 | tty_port_hangup(&line->port); | ||
462 | } | 368 | } |
463 | 369 | ||
464 | void close_lines(struct line *lines, int nlines) | 370 | void close_lines(struct line *lines, int nlines) |
@@ -476,9 +382,7 @@ int setup_one_line(struct line *lines, int n, char *init, | |||
476 | struct tty_driver *driver = line->driver->driver; | 382 | struct tty_driver *driver = line->driver->driver; |
477 | int err = -EINVAL; | 383 | int err = -EINVAL; |
478 | 384 | ||
479 | mutex_lock(&line->count_lock); | 385 | if (line->port.count) { |
480 | |||
481 | if (line->count) { | ||
482 | *error_out = "Device is already open"; | 386 | *error_out = "Device is already open"; |
483 | goto out; | 387 | goto out; |
484 | } | 388 | } |
@@ -519,7 +423,6 @@ int setup_one_line(struct line *lines, int n, char *init, | |||
519 | } | 423 | } |
520 | } | 424 | } |
521 | out: | 425 | out: |
522 | mutex_unlock(&line->count_lock); | ||
523 | return err; | 426 | return err; |
524 | } | 427 | } |
525 | 428 | ||
@@ -607,13 +510,17 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, | |||
607 | 510 | ||
608 | line = &lines[dev]; | 511 | line = &lines[dev]; |
609 | 512 | ||
610 | mutex_lock(&line->count_lock); | ||
611 | if (!line->valid) | 513 | if (!line->valid) |
612 | CONFIG_CHUNK(str, size, n, "none", 1); | 514 | CONFIG_CHUNK(str, size, n, "none", 1); |
613 | else if (line->tty == NULL) | 515 | else { |
614 | CONFIG_CHUNK(str, size, n, line->init_str, 1); | 516 | struct tty_struct *tty = tty_port_tty_get(&line->port); |
615 | else n = chan_config_string(line, str, size, error_out); | 517 | if (tty == NULL) { |
616 | mutex_unlock(&line->count_lock); | 518 | CONFIG_CHUNK(str, size, n, line->init_str, 1); |
519 | } else { | ||
520 | n = chan_config_string(line, str, size, error_out); | ||
521 | tty_kref_put(tty); | ||
522 | } | ||
523 | } | ||
617 | 524 | ||
618 | return n; | 525 | return n; |
619 | } | 526 | } |
@@ -663,8 +570,9 @@ int register_lines(struct line_driver *line_driver, | |||
663 | driver->init_termios = tty_std_termios; | 570 | driver->init_termios = tty_std_termios; |
664 | 571 | ||
665 | for (i = 0; i < nlines; i++) { | 572 | for (i = 0; i < nlines; i++) { |
573 | tty_port_init(&lines[i].port); | ||
574 | lines[i].port.ops = &line_port_ops; | ||
666 | spin_lock_init(&lines[i].lock); | 575 | spin_lock_init(&lines[i].lock); |
667 | mutex_init(&lines[i].count_lock); | ||
668 | lines[i].driver = line_driver; | 576 | lines[i].driver = line_driver; |
669 | INIT_LIST_HEAD(&lines[i].chan_list); | 577 | INIT_LIST_HEAD(&lines[i].chan_list); |
670 | } | 578 | } |
@@ -779,8 +687,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | |||
779 | .stack = stack }); | 687 | .stack = stack }); |
780 | 688 | ||
781 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, | 689 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, |
782 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 690 | IRQF_SHARED, "winch", winch) < 0) { |
783 | "winch", winch) < 0) { | ||
784 | printk(KERN_ERR "register_winch_irq - failed to register " | 691 | printk(KERN_ERR "register_winch_irq - failed to register " |
785 | "IRQ\n"); | 692 | "IRQ\n"); |
786 | goto out_free; | 693 | goto out_free; |
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 0a1834719dba..bae95611e7ab 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h | |||
@@ -32,9 +32,7 @@ struct line_driver { | |||
32 | }; | 32 | }; |
33 | 33 | ||
34 | struct line { | 34 | struct line { |
35 | struct tty_struct *tty; | 35 | struct tty_port port; |
36 | struct mutex count_lock; | ||
37 | unsigned long count; | ||
38 | int valid; | 36 | int valid; |
39 | 37 | ||
40 | char *init_str; | 38 | char *init_str; |
@@ -59,7 +57,11 @@ struct line { | |||
59 | }; | 57 | }; |
60 | 58 | ||
61 | extern void line_close(struct tty_struct *tty, struct file * filp); | 59 | extern void line_close(struct tty_struct *tty, struct file * filp); |
62 | extern int line_open(struct line *lines, struct tty_struct *tty); | 60 | extern int line_open(struct tty_struct *tty, struct file *filp); |
61 | extern int line_install(struct tty_driver *driver, struct tty_struct *tty, | ||
62 | struct line *line); | ||
63 | extern void line_cleanup(struct tty_struct *tty); | ||
64 | extern void line_hangup(struct tty_struct *tty); | ||
63 | extern int line_setup(char **conf, unsigned nlines, char **def, | 65 | extern int line_setup(char **conf, unsigned nlines, char **def, |
64 | char *init, char *name); | 66 | char *init, char *name); |
65 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, | 67 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, |
@@ -70,8 +72,6 @@ extern int line_chars_in_buffer(struct tty_struct *tty); | |||
70 | extern void line_flush_buffer(struct tty_struct *tty); | 72 | extern void line_flush_buffer(struct tty_struct *tty); |
71 | extern void line_flush_chars(struct tty_struct *tty); | 73 | extern void line_flush_chars(struct tty_struct *tty); |
72 | extern int line_write_room(struct tty_struct *tty); | 74 | extern int line_write_room(struct tty_struct *tty); |
73 | extern int line_ioctl(struct tty_struct *tty, unsigned int cmd, | ||
74 | unsigned long arg); | ||
75 | extern void line_throttle(struct tty_struct *tty); | 75 | extern void line_throttle(struct tty_struct *tty); |
76 | extern void line_unthrottle(struct tty_struct *tty); | 76 | extern void line_unthrottle(struct tty_struct *tty); |
77 | 77 | ||
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 43b39d61b538..664a60e8dfb4 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -774,8 +774,7 @@ static int __init mconsole_init(void) | |||
774 | register_reboot_notifier(&reboot_notifier); | 774 | register_reboot_notifier(&reboot_notifier); |
775 | 775 | ||
776 | err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, | 776 | err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, |
777 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 777 | IRQF_SHARED, "mconsole", (void *)sock); |
778 | "mconsole", (void *)sock); | ||
779 | if (err) { | 778 | if (err) { |
780 | printk(KERN_ERR "Failed to get IRQ for management console\n"); | 779 | printk(KERN_ERR "Failed to get IRQ for management console\n"); |
781 | goto out; | 780 | goto out; |
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 11866ffd45a9..1d83d50236e1 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c | |||
@@ -100,8 +100,7 @@ static int port_accept(struct port_list *port) | |||
100 | .port = port }); | 100 | .port = port }); |
101 | 101 | ||
102 | if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, | 102 | if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, |
103 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 103 | IRQF_SHARED, "telnetd", conn)) { |
104 | "telnetd", conn)) { | ||
105 | printk(KERN_ERR "port_accept : failed to get IRQ for " | 104 | printk(KERN_ERR "port_accept : failed to get IRQ for " |
106 | "telnetd\n"); | 105 | "telnetd\n"); |
107 | goto out_free; | 106 | goto out_free; |
@@ -184,8 +183,7 @@ void *port_data(int port_num) | |||
184 | } | 183 | } |
185 | 184 | ||
186 | if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, | 185 | if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, |
187 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 186 | IRQF_SHARED, "port", port)) { |
188 | "port", port)) { | ||
189 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); | 187 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); |
190 | goto out_close; | 188 | goto out_close; |
191 | } | 189 | } |
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index b25296e6218a..e32c6aa6396f 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c | |||
@@ -131,8 +131,7 @@ static int __init rng_init (void) | |||
131 | random_fd = err; | 131 | random_fd = err; |
132 | 132 | ||
133 | err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, | 133 | err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, |
134 | IRQF_SAMPLE_RANDOM, "random", | 134 | 0, "random", NULL); |
135 | NULL); | ||
136 | if (err) | 135 | if (err) |
137 | goto err_out_cleanup_hw; | 136 | goto err_out_cleanup_hw; |
138 | 137 | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index e09801a1327b..7e86f0070123 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -87,40 +87,13 @@ static int ssl_remove(int n, char **error_out) | |||
87 | error_out); | 87 | error_out); |
88 | } | 88 | } |
89 | 89 | ||
90 | static int ssl_open(struct tty_struct *tty, struct file *filp) | 90 | static int ssl_install(struct tty_driver *driver, struct tty_struct *tty) |
91 | { | ||
92 | int err = line_open(serial_lines, tty); | ||
93 | |||
94 | if (err) | ||
95 | printk(KERN_ERR "Failed to open serial line %d, err = %d\n", | ||
96 | tty->index, err); | ||
97 | |||
98 | return err; | ||
99 | } | ||
100 | |||
101 | #if 0 | ||
102 | static void ssl_flush_buffer(struct tty_struct *tty) | ||
103 | { | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | static void ssl_stop(struct tty_struct *tty) | ||
108 | { | ||
109 | printk(KERN_ERR "Someone should implement ssl_stop\n"); | ||
110 | } | ||
111 | |||
112 | static void ssl_start(struct tty_struct *tty) | ||
113 | { | ||
114 | printk(KERN_ERR "Someone should implement ssl_start\n"); | ||
115 | } | ||
116 | |||
117 | void ssl_hangup(struct tty_struct *tty) | ||
118 | { | 91 | { |
92 | return line_install(driver, tty, &serial_lines[tty->index]); | ||
119 | } | 93 | } |
120 | #endif | ||
121 | 94 | ||
122 | static const struct tty_operations ssl_ops = { | 95 | static const struct tty_operations ssl_ops = { |
123 | .open = ssl_open, | 96 | .open = line_open, |
124 | .close = line_close, | 97 | .close = line_close, |
125 | .write = line_write, | 98 | .write = line_write, |
126 | .put_char = line_put_char, | 99 | .put_char = line_put_char, |
@@ -129,14 +102,11 @@ static const struct tty_operations ssl_ops = { | |||
129 | .flush_buffer = line_flush_buffer, | 102 | .flush_buffer = line_flush_buffer, |
130 | .flush_chars = line_flush_chars, | 103 | .flush_chars = line_flush_chars, |
131 | .set_termios = line_set_termios, | 104 | .set_termios = line_set_termios, |
132 | .ioctl = line_ioctl, | ||
133 | .throttle = line_throttle, | 105 | .throttle = line_throttle, |
134 | .unthrottle = line_unthrottle, | 106 | .unthrottle = line_unthrottle, |
135 | #if 0 | 107 | .install = ssl_install, |
136 | .stop = ssl_stop, | 108 | .cleanup = line_cleanup, |
137 | .start = ssl_start, | 109 | .hangup = line_hangup, |
138 | .hangup = ssl_hangup, | ||
139 | #endif | ||
140 | }; | 110 | }; |
141 | 111 | ||
142 | /* Changed by ssl_init and referenced by ssl_exit, which are both serialized | 112 | /* Changed by ssl_init and referenced by ssl_exit, which are both serialized |
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 7663541c372e..929b99a261f3 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -89,21 +89,17 @@ static int con_remove(int n, char **error_out) | |||
89 | return line_remove(vts, ARRAY_SIZE(vts), n, error_out); | 89 | return line_remove(vts, ARRAY_SIZE(vts), n, error_out); |
90 | } | 90 | } |
91 | 91 | ||
92 | static int con_open(struct tty_struct *tty, struct file *filp) | ||
93 | { | ||
94 | int err = line_open(vts, tty); | ||
95 | if (err) | ||
96 | printk(KERN_ERR "Failed to open console %d, err = %d\n", | ||
97 | tty->index, err); | ||
98 | |||
99 | return err; | ||
100 | } | ||
101 | |||
102 | /* Set in an initcall, checked in an exitcall */ | 92 | /* Set in an initcall, checked in an exitcall */ |
103 | static int con_init_done = 0; | 93 | static int con_init_done = 0; |
104 | 94 | ||
95 | static int con_install(struct tty_driver *driver, struct tty_struct *tty) | ||
96 | { | ||
97 | return line_install(driver, tty, &vts[tty->index]); | ||
98 | } | ||
99 | |||
105 | static const struct tty_operations console_ops = { | 100 | static const struct tty_operations console_ops = { |
106 | .open = con_open, | 101 | .open = line_open, |
102 | .install = con_install, | ||
107 | .close = line_close, | 103 | .close = line_close, |
108 | .write = line_write, | 104 | .write = line_write, |
109 | .put_char = line_put_char, | 105 | .put_char = line_put_char, |
@@ -112,9 +108,10 @@ static const struct tty_operations console_ops = { | |||
112 | .flush_buffer = line_flush_buffer, | 108 | .flush_buffer = line_flush_buffer, |
113 | .flush_chars = line_flush_chars, | 109 | .flush_chars = line_flush_chars, |
114 | .set_termios = line_set_termios, | 110 | .set_termios = line_set_termios, |
115 | .ioctl = line_ioctl, | ||
116 | .throttle = line_throttle, | 111 | .throttle = line_throttle, |
117 | .unthrottle = line_unthrottle, | 112 | .unthrottle = line_unthrottle, |
113 | .cleanup = line_cleanup, | ||
114 | .hangup = line_hangup, | ||
118 | }; | 115 | }; |
119 | 116 | ||
120 | static void uml_console_write(struct console *console, const char *string, | 117 | static void uml_console_write(struct console *console, const char *string, |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 20505cafa299..0643e5bc9f41 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -514,7 +514,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) | |||
514 | goto out; | 514 | goto out; |
515 | } | 515 | } |
516 | 516 | ||
517 | fd = os_open_file(ubd_dev->file, global_openflags, 0); | 517 | fd = os_open_file(ubd_dev->file, of_read(OPENFLAGS()), 0); |
518 | if (fd < 0) | 518 | if (fd < 0) |
519 | return fd; | 519 | return fd; |
520 | 520 | ||
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index b68bbe269e01..e3031e69445d 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c | |||
@@ -50,8 +50,7 @@ int xterm_fd(int socket, int *pid_out) | |||
50 | init_completion(&data->ready); | 50 | init_completion(&data->ready); |
51 | 51 | ||
52 | err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, | 52 | err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, |
53 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 53 | IRQF_SHARED, "xterm", data); |
54 | "xterm", data); | ||
55 | if (err) { | 54 | if (err) { |
56 | printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " | 55 | printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " |
57 | "err = %d\n", err); | 56 | "err = %d\n", err); |
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index e786a6a3ec5e..442f1d025dc2 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h | |||
@@ -37,6 +37,8 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value); | |||
37 | 37 | ||
38 | extern int arch_copy_tls(struct task_struct *new); | 38 | extern int arch_copy_tls(struct task_struct *new); |
39 | extern void clear_flushed_tls(struct task_struct *task); | 39 | extern void clear_flushed_tls(struct task_struct *task); |
40 | extern void syscall_trace_enter(struct pt_regs *regs); | ||
41 | extern void syscall_trace_leave(struct pt_regs *regs); | ||
40 | 42 | ||
41 | #endif | 43 | #endif |
42 | 44 | ||
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 896e16602176..86daa5461815 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h | |||
@@ -60,7 +60,8 @@ extern unsigned long host_task_size; | |||
60 | 60 | ||
61 | extern int linux_main(int argc, char **argv); | 61 | extern int linux_main(int argc, char **argv); |
62 | 62 | ||
63 | extern void (*sig_info[])(int, struct uml_pt_regs *); | 63 | struct siginfo; |
64 | extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *); | ||
64 | 65 | ||
65 | #endif | 66 | #endif |
66 | 67 | ||
diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h index c6c784df2673..2b6d703925b5 100644 --- a/arch/um/include/shared/irq_user.h +++ b/arch/um/include/shared/irq_user.h | |||
@@ -20,7 +20,8 @@ struct irq_fd { | |||
20 | 20 | ||
21 | enum { IRQ_READ, IRQ_WRITE }; | 21 | enum { IRQ_READ, IRQ_WRITE }; |
22 | 22 | ||
23 | extern void sigio_handler(int sig, struct uml_pt_regs *regs); | 23 | struct siginfo; |
24 | extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); | ||
24 | extern void free_irq_by_fd(int fd); | 25 | extern void free_irq_by_fd(int fd); |
25 | extern void reactivate_fd(int fd, int irqnum); | 26 | extern void reactivate_fd(int fd, int irqnum); |
26 | extern void deactivate_fd(int fd, int irqnum); | 27 | extern void deactivate_fd(int fd, int irqnum); |
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 00965d06d2ca..af6b6dc868ba 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #include "sysdep/ptrace.h" | 9 | #include "sysdep/ptrace.h" |
10 | #include "sysdep/faultinfo.h" | 10 | #include "sysdep/faultinfo.h" |
11 | 11 | ||
12 | struct siginfo; | ||
13 | |||
12 | extern int uml_exitcode; | 14 | extern int uml_exitcode; |
13 | 15 | ||
14 | extern int ncpus; | 16 | extern int ncpus; |
@@ -22,7 +24,7 @@ extern void free_stack(unsigned long stack, int order); | |||
22 | 24 | ||
23 | extern int do_signal(void); | 25 | extern int do_signal(void); |
24 | extern void interrupt_end(void); | 26 | extern void interrupt_end(void); |
25 | extern void relay_signal(int sig, struct uml_pt_regs *regs); | 27 | extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs); |
26 | 28 | ||
27 | extern unsigned long segv(struct faultinfo fi, unsigned long ip, | 29 | extern unsigned long segv(struct faultinfo fi, unsigned long ip, |
28 | int is_user, struct uml_pt_regs *regs); | 30 | int is_user, struct uml_pt_regs *regs); |
@@ -33,9 +35,8 @@ extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); | |||
33 | extern int smp_sigio_handler(void); | 35 | extern int smp_sigio_handler(void); |
34 | extern void initial_thread_cb(void (*proc)(void *), void *arg); | 36 | extern void initial_thread_cb(void (*proc)(void *), void *arg); |
35 | extern int is_syscall(unsigned long addr); | 37 | extern int is_syscall(unsigned long addr); |
36 | extern void timer_handler(int sig, struct uml_pt_regs *regs); | ||
37 | 38 | ||
38 | extern void timer_handler(int sig, struct uml_pt_regs *regs); | 39 | extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); |
39 | 40 | ||
40 | extern int start_uml(void); | 41 | extern int start_uml(void); |
41 | extern void paging_init(void); | 42 | extern void paging_init(void); |
@@ -59,9 +60,9 @@ extern unsigned long from_irq_stack(int nested); | |||
59 | extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); | 60 | extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); |
60 | extern int singlestepping(void *t); | 61 | extern int singlestepping(void *t); |
61 | 62 | ||
62 | extern void segv_handler(int sig, struct uml_pt_regs *regs); | 63 | extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); |
63 | extern void bus_handler(int sig, struct uml_pt_regs *regs); | 64 | extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs); |
64 | extern void winch(int sig, struct uml_pt_regs *regs); | 65 | extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); |
65 | extern void fatal_sigsegv(void) __attribute__ ((noreturn)); | 66 | extern void fatal_sigsegv(void) __attribute__ ((noreturn)); |
66 | 67 | ||
67 | 68 | ||
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 00506c3d5d6e..9883026f0730 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -30,7 +30,7 @@ static struct irq_fd **last_irq_ptr = &active_fds; | |||
30 | 30 | ||
31 | extern void free_irqs(void); | 31 | extern void free_irqs(void); |
32 | 32 | ||
33 | void sigio_handler(int sig, struct uml_pt_regs *regs) | 33 | void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
34 | { | 34 | { |
35 | struct irq_fd *irq_fd; | 35 | struct irq_fd *irq_fd; |
36 | int n; | 36 | int n; |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index ccb9a9d283f1..57fc7028714a 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -151,12 +151,10 @@ void new_thread_handler(void) | |||
151 | * 0 if it just exits | 151 | * 0 if it just exits |
152 | */ | 152 | */ |
153 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); | 153 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); |
154 | if (n == 1) { | 154 | if (n == 1) |
155 | /* Handle any immediate reschedules or signals */ | ||
156 | interrupt_end(); | ||
157 | userspace(¤t->thread.regs.regs); | 155 | userspace(¤t->thread.regs.regs); |
158 | } | 156 | else |
159 | else do_exit(0); | 157 | do_exit(0); |
160 | } | 158 | } |
161 | 159 | ||
162 | /* Called magically, see new_thread_handler above */ | 160 | /* Called magically, see new_thread_handler above */ |
@@ -175,9 +173,6 @@ void fork_handler(void) | |||
175 | 173 | ||
176 | current->thread.prev_sched = NULL; | 174 | current->thread.prev_sched = NULL; |
177 | 175 | ||
178 | /* Handle any immediate reschedules or signals */ | ||
179 | interrupt_end(); | ||
180 | |||
181 | userspace(¤t->thread.regs.regs); | 176 | userspace(¤t->thread.regs.regs); |
182 | } | 177 | } |
183 | 178 | ||
@@ -193,7 +188,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
193 | if (current->thread.forking) { | 188 | if (current->thread.forking) { |
194 | memcpy(&p->thread.regs.regs, ®s->regs, | 189 | memcpy(&p->thread.regs.regs, ®s->regs, |
195 | sizeof(p->thread.regs.regs)); | 190 | sizeof(p->thread.regs.regs)); |
196 | UPT_SET_SYSCALL_RETURN(&p->thread.regs.regs, 0); | 191 | PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); |
197 | if (sp != 0) | 192 | if (sp != 0) |
198 | REGS_SP(p->thread.regs.regs.gp) = sp; | 193 | REGS_SP(p->thread.regs.regs.gp) = sp; |
199 | 194 | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 06b190390505..694d551c8899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -3,11 +3,12 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/audit.h" | 6 | #include <linux/audit.h> |
7 | #include "linux/ptrace.h" | 7 | #include <linux/ptrace.h> |
8 | #include "linux/sched.h" | 8 | #include <linux/sched.h> |
9 | #include "asm/uaccess.h" | 9 | #include <linux/tracehook.h> |
10 | #include "skas_ptrace.h" | 10 | #include <asm/uaccess.h> |
11 | #include <skas_ptrace.h> | ||
11 | 12 | ||
12 | 13 | ||
13 | 14 | ||
@@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, | |||
162 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and | 163 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and |
163 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check | 164 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check |
164 | */ | 165 | */ |
165 | void syscall_trace(struct uml_pt_regs *regs, int entryexit) | 166 | void syscall_trace_enter(struct pt_regs *regs) |
166 | { | 167 | { |
167 | int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; | 168 | audit_syscall_entry(HOST_AUDIT_ARCH, |
168 | int tracesysgood; | 169 | UPT_SYSCALL_NR(®s->regs), |
169 | 170 | UPT_SYSCALL_ARG1(®s->regs), | |
170 | if (!entryexit) | 171 | UPT_SYSCALL_ARG2(®s->regs), |
171 | audit_syscall_entry(HOST_AUDIT_ARCH, | 172 | UPT_SYSCALL_ARG3(®s->regs), |
172 | UPT_SYSCALL_NR(regs), | 173 | UPT_SYSCALL_ARG4(®s->regs)); |
173 | UPT_SYSCALL_ARG1(regs), | ||
174 | UPT_SYSCALL_ARG2(regs), | ||
175 | UPT_SYSCALL_ARG3(regs), | ||
176 | UPT_SYSCALL_ARG4(regs)); | ||
177 | else | ||
178 | audit_syscall_exit(regs); | ||
179 | |||
180 | /* Fake a debug trap */ | ||
181 | if (is_singlestep) | ||
182 | send_sigtrap(current, regs, 0); | ||
183 | 174 | ||
184 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 175 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
185 | return; | 176 | return; |
186 | 177 | ||
187 | if (!(current->ptrace & PT_PTRACED)) | 178 | tracehook_report_syscall_entry(regs); |
188 | return; | 179 | } |
189 | 180 | ||
190 | /* | 181 | void syscall_trace_leave(struct pt_regs *regs) |
191 | * the 0x80 provides a way for the tracing parent to distinguish | 182 | { |
192 | * between a syscall stop and SIGTRAP delivery | 183 | int ptraced = current->ptrace; |
193 | */ | ||
194 | tracesysgood = (current->ptrace & PT_TRACESYSGOOD); | ||
195 | ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); | ||
196 | 184 | ||
197 | if (entryexit) /* force do_signal() --> is_syscall() */ | 185 | audit_syscall_exit(regs); |
198 | set_thread_flag(TIF_SIGPENDING); | ||
199 | 186 | ||
200 | /* | 187 | /* Fake a debug trap */ |
201 | * this isn't the same as continuing with a signal, but it will do | 188 | if (ptraced & PT_DTRACE) |
202 | * for normal use. strace only continues with a signal if the | 189 | send_sigtrap(current, ®s->regs, 0); |
203 | * stopping signal is not SIGTRAP. -brl | 190 | |
204 | */ | 191 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
205 | if (current->exit_code) { | 192 | return; |
206 | send_sig(current->exit_code, current, 1); | 193 | |
207 | current->exit_code = 0; | 194 | tracehook_report_syscall_exit(regs, 0); |
208 | } | 195 | /* force do_signal() --> is_syscall() */ |
196 | if (ptraced & PT_PTRACED) | ||
197 | set_thread_flag(TIF_SIGPENDING); | ||
209 | } | 198 | } |
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index 2a1639255763..c88211139a51 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c | |||
@@ -25,8 +25,7 @@ int write_sigio_irq(int fd) | |||
25 | int err; | 25 | int err; |
26 | 26 | ||
27 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, | 27 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, |
28 | IRQF_SAMPLE_RANDOM, "write sigio", | 28 | 0, "write sigio", NULL); |
29 | NULL); | ||
30 | if (err) { | 29 | if (err) { |
31 | printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " | 30 | printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " |
32 | "err = %d\n", err); | 31 | "err = %d\n", err); |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 05fbeb480e0b..86368a025a96 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
18 | long result; | 18 | long result; |
19 | int syscall; | 19 | int syscall; |
20 | 20 | ||
21 | syscall_trace(r, 0); | 21 | syscall_trace_enter(regs); |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * This should go in the declaration of syscall, but when I do that, | 24 | * This should go in the declaration of syscall, but when I do that, |
@@ -34,7 +34,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
34 | result = -ENOSYS; | 34 | result = -ENOSYS; |
35 | else result = EXECUTE_SYSCALL(syscall, regs); | 35 | else result = EXECUTE_SYSCALL(syscall, regs); |
36 | 36 | ||
37 | UPT_SET_SYSCALL_RETURN(r, result); | 37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); |
38 | 38 | ||
39 | syscall_trace(r, 1); | 39 | syscall_trace_leave(regs); |
40 | } | 40 | } |
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index d1a23fb3190d..5f76d4ba151c 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "kern_util.h" | 13 | #include "kern_util.h" |
14 | #include "os.h" | 14 | #include "os.h" |
15 | 15 | ||
16 | void timer_handler(int sig, struct uml_pt_regs *regs) | 16 | void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
17 | { | 17 | { |
18 | unsigned long flags; | 18 | unsigned long flags; |
19 | 19 | ||
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 3be60765c0e2..0353b98ae35a 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -172,7 +172,7 @@ void fatal_sigsegv(void) | |||
172 | os_dump_core(); | 172 | os_dump_core(); |
173 | } | 173 | } |
174 | 174 | ||
175 | void segv_handler(int sig, struct uml_pt_regs *regs) | 175 | void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
176 | { | 176 | { |
177 | struct faultinfo * fi = UPT_FAULTINFO(regs); | 177 | struct faultinfo * fi = UPT_FAULTINFO(regs); |
178 | 178 | ||
@@ -258,8 +258,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | void relay_signal(int sig, struct uml_pt_regs *regs) | 261 | void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs) |
262 | { | 262 | { |
263 | struct faultinfo *fi; | ||
264 | struct siginfo clean_si; | ||
265 | |||
263 | if (!UPT_IS_USER(regs)) { | 266 | if (!UPT_IS_USER(regs)) { |
264 | if (sig == SIGBUS) | 267 | if (sig == SIGBUS) |
265 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " | 268 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " |
@@ -269,18 +272,40 @@ void relay_signal(int sig, struct uml_pt_regs *regs) | |||
269 | 272 | ||
270 | arch_examine_signal(sig, regs); | 273 | arch_examine_signal(sig, regs); |
271 | 274 | ||
272 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); | 275 | memset(&clean_si, 0, sizeof(clean_si)); |
273 | force_sig(sig, current); | 276 | clean_si.si_signo = si->si_signo; |
277 | clean_si.si_errno = si->si_errno; | ||
278 | clean_si.si_code = si->si_code; | ||
279 | switch (sig) { | ||
280 | case SIGILL: | ||
281 | case SIGFPE: | ||
282 | case SIGSEGV: | ||
283 | case SIGBUS: | ||
284 | case SIGTRAP: | ||
285 | fi = UPT_FAULTINFO(regs); | ||
286 | clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi); | ||
287 | current->thread.arch.faultinfo = *fi; | ||
288 | #ifdef __ARCH_SI_TRAPNO | ||
289 | clean_si.si_trapno = si->si_trapno; | ||
290 | #endif | ||
291 | break; | ||
292 | default: | ||
293 | printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n", | ||
294 | sig, si->si_code); | ||
295 | } | ||
296 | |||
297 | force_sig_info(sig, &clean_si, current); | ||
274 | } | 298 | } |
275 | 299 | ||
276 | void bus_handler(int sig, struct uml_pt_regs *regs) | 300 | void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs) |
277 | { | 301 | { |
278 | if (current->thread.fault_catcher != NULL) | 302 | if (current->thread.fault_catcher != NULL) |
279 | UML_LONGJMP(current->thread.fault_catcher, 1); | 303 | UML_LONGJMP(current->thread.fault_catcher, 1); |
280 | else relay_signal(sig, regs); | 304 | else |
305 | relay_signal(sig, si, regs); | ||
281 | } | 306 | } |
282 | 307 | ||
283 | void winch(int sig, struct uml_pt_regs *regs) | 308 | void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
284 | { | 309 | { |
285 | do_IRQ(WINCH_IRQ, regs); | 310 | do_IRQ(WINCH_IRQ, regs); |
286 | } | 311 | } |
diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h index 2c3c3ecd8c01..0dc2c9f135f6 100644 --- a/arch/um/os-Linux/internal.h +++ b/arch/um/os-Linux/internal.h | |||
@@ -1 +1 @@ | |||
void alarm_handler(int, mcontext_t *); | void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc); | ||
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 2d22f1fcd8e2..6366ce904b9b 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -13,8 +13,9 @@ | |||
13 | #include "kern_util.h" | 13 | #include "kern_util.h" |
14 | #include "os.h" | 14 | #include "os.h" |
15 | #include "sysdep/mcontext.h" | 15 | #include "sysdep/mcontext.h" |
16 | #include "internal.h" | ||
16 | 17 | ||
17 | void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { | 18 | void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = { |
18 | [SIGTRAP] = relay_signal, | 19 | [SIGTRAP] = relay_signal, |
19 | [SIGFPE] = relay_signal, | 20 | [SIGFPE] = relay_signal, |
20 | [SIGILL] = relay_signal, | 21 | [SIGILL] = relay_signal, |
@@ -24,7 +25,7 @@ void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { | |||
24 | [SIGIO] = sigio_handler, | 25 | [SIGIO] = sigio_handler, |
25 | [SIGVTALRM] = timer_handler }; | 26 | [SIGVTALRM] = timer_handler }; |
26 | 27 | ||
27 | static void sig_handler_common(int sig, mcontext_t *mc) | 28 | static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc) |
28 | { | 29 | { |
29 | struct uml_pt_regs r; | 30 | struct uml_pt_regs r; |
30 | int save_errno = errno; | 31 | int save_errno = errno; |
@@ -40,7 +41,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) | |||
40 | if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) | 41 | if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) |
41 | unblock_signals(); | 42 | unblock_signals(); |
42 | 43 | ||
43 | (*sig_info[sig])(sig, &r); | 44 | (*sig_info[sig])(sig, si, &r); |
44 | 45 | ||
45 | errno = save_errno; | 46 | errno = save_errno; |
46 | } | 47 | } |
@@ -60,7 +61,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) | |||
60 | static int signals_enabled; | 61 | static int signals_enabled; |
61 | static unsigned int signals_pending; | 62 | static unsigned int signals_pending; |
62 | 63 | ||
63 | void sig_handler(int sig, mcontext_t *mc) | 64 | void sig_handler(int sig, siginfo_t *si, mcontext_t *mc) |
64 | { | 65 | { |
65 | int enabled; | 66 | int enabled; |
66 | 67 | ||
@@ -72,7 +73,7 @@ void sig_handler(int sig, mcontext_t *mc) | |||
72 | 73 | ||
73 | block_signals(); | 74 | block_signals(); |
74 | 75 | ||
75 | sig_handler_common(sig, mc); | 76 | sig_handler_common(sig, si, mc); |
76 | 77 | ||
77 | set_signals(enabled); | 78 | set_signals(enabled); |
78 | } | 79 | } |
@@ -85,10 +86,10 @@ static void real_alarm_handler(mcontext_t *mc) | |||
85 | get_regs_from_mc(®s, mc); | 86 | get_regs_from_mc(®s, mc); |
86 | regs.is_user = 0; | 87 | regs.is_user = 0; |
87 | unblock_signals(); | 88 | unblock_signals(); |
88 | timer_handler(SIGVTALRM, ®s); | 89 | timer_handler(SIGVTALRM, NULL, ®s); |
89 | } | 90 | } |
90 | 91 | ||
91 | void alarm_handler(int sig, mcontext_t *mc) | 92 | void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) |
92 | { | 93 | { |
93 | int enabled; | 94 | int enabled; |
94 | 95 | ||
@@ -119,7 +120,7 @@ void set_sigstack(void *sig_stack, int size) | |||
119 | panic("enabling signal stack failed, errno = %d\n", errno); | 120 | panic("enabling signal stack failed, errno = %d\n", errno); |
120 | } | 121 | } |
121 | 122 | ||
122 | static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { | 123 | static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = { |
123 | [SIGSEGV] = sig_handler, | 124 | [SIGSEGV] = sig_handler, |
124 | [SIGBUS] = sig_handler, | 125 | [SIGBUS] = sig_handler, |
125 | [SIGILL] = sig_handler, | 126 | [SIGILL] = sig_handler, |
@@ -132,7 +133,7 @@ static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { | |||
132 | }; | 133 | }; |
133 | 134 | ||
134 | 135 | ||
135 | static void hard_handler(int sig, siginfo_t *info, void *p) | 136 | static void hard_handler(int sig, siginfo_t *si, void *p) |
136 | { | 137 | { |
137 | struct ucontext *uc = p; | 138 | struct ucontext *uc = p; |
138 | mcontext_t *mc = &uc->uc_mcontext; | 139 | mcontext_t *mc = &uc->uc_mcontext; |
@@ -161,7 +162,7 @@ static void hard_handler(int sig, siginfo_t *info, void *p) | |||
161 | while ((sig = ffs(pending)) != 0){ | 162 | while ((sig = ffs(pending)) != 0){ |
162 | sig--; | 163 | sig--; |
163 | pending &= ~(1 << sig); | 164 | pending &= ~(1 << sig); |
164 | (*handlers[sig])(sig, mc); | 165 | (*handlers[sig])(sig, si, mc); |
165 | } | 166 | } |
166 | 167 | ||
167 | /* | 168 | /* |
@@ -273,9 +274,12 @@ void unblock_signals(void) | |||
273 | * Deal with SIGIO first because the alarm handler might | 274 | * Deal with SIGIO first because the alarm handler might |
274 | * schedule, leaving the pending SIGIO stranded until we come | 275 | * schedule, leaving the pending SIGIO stranded until we come |
275 | * back here. | 276 | * back here. |
277 | * | ||
278 | * SIGIO's handler doesn't use siginfo or mcontext, | ||
279 | * so they can be NULL. | ||
276 | */ | 280 | */ |
277 | if (save_pending & SIGIO_MASK) | 281 | if (save_pending & SIGIO_MASK) |
278 | sig_handler_common(SIGIO, NULL); | 282 | sig_handler_common(SIGIO, NULL, NULL); |
279 | 283 | ||
280 | if (save_pending & SIGVTALRM_MASK) | 284 | if (save_pending & SIGVTALRM_MASK) |
281 | real_alarm_handler(NULL); | 285 | real_alarm_handler(NULL); |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index cd65727854eb..d93bb40499f7 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -346,6 +346,10 @@ void userspace(struct uml_pt_regs *regs) | |||
346 | int err, status, op, pid = userspace_pid[0]; | 346 | int err, status, op, pid = userspace_pid[0]; |
347 | /* To prevent races if using_sysemu changes under us.*/ | 347 | /* To prevent races if using_sysemu changes under us.*/ |
348 | int local_using_sysemu; | 348 | int local_using_sysemu; |
349 | siginfo_t si; | ||
350 | |||
351 | /* Handle any immediate reschedules or signals */ | ||
352 | interrupt_end(); | ||
349 | 353 | ||
350 | if (getitimer(ITIMER_VIRTUAL, &timer)) | 354 | if (getitimer(ITIMER_VIRTUAL, &timer)) |
351 | printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); | 355 | printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); |
@@ -404,13 +408,17 @@ void userspace(struct uml_pt_regs *regs) | |||
404 | 408 | ||
405 | if (WIFSTOPPED(status)) { | 409 | if (WIFSTOPPED(status)) { |
406 | int sig = WSTOPSIG(status); | 410 | int sig = WSTOPSIG(status); |
411 | |||
412 | ptrace(PTRACE_GETSIGINFO, pid, 0, &si); | ||
413 | |||
407 | switch (sig) { | 414 | switch (sig) { |
408 | case SIGSEGV: | 415 | case SIGSEGV: |
409 | if (PTRACE_FULL_FAULTINFO || | 416 | if (PTRACE_FULL_FAULTINFO || |
410 | !ptrace_faultinfo) { | 417 | !ptrace_faultinfo) { |
411 | get_skas_faultinfo(pid, | 418 | get_skas_faultinfo(pid, |
412 | ®s->faultinfo); | 419 | ®s->faultinfo); |
413 | (*sig_info[SIGSEGV])(SIGSEGV, regs); | 420 | (*sig_info[SIGSEGV])(SIGSEGV, &si, |
421 | regs); | ||
414 | } | 422 | } |
415 | else handle_segv(pid, regs); | 423 | else handle_segv(pid, regs); |
416 | break; | 424 | break; |
@@ -418,14 +426,14 @@ void userspace(struct uml_pt_regs *regs) | |||
418 | handle_trap(pid, regs, local_using_sysemu); | 426 | handle_trap(pid, regs, local_using_sysemu); |
419 | break; | 427 | break; |
420 | case SIGTRAP: | 428 | case SIGTRAP: |
421 | relay_signal(SIGTRAP, regs); | 429 | relay_signal(SIGTRAP, &si, regs); |
422 | break; | 430 | break; |
423 | case SIGVTALRM: | 431 | case SIGVTALRM: |
424 | now = os_nsecs(); | 432 | now = os_nsecs(); |
425 | if (now < nsecs) | 433 | if (now < nsecs) |
426 | break; | 434 | break; |
427 | block_signals(); | 435 | block_signals(); |
428 | (*sig_info[sig])(sig, regs); | 436 | (*sig_info[sig])(sig, &si, regs); |
429 | unblock_signals(); | 437 | unblock_signals(); |
430 | nsecs = timer.it_value.tv_sec * | 438 | nsecs = timer.it_value.tv_sec * |
431 | UM_NSEC_PER_SEC + | 439 | UM_NSEC_PER_SEC + |
@@ -439,7 +447,7 @@ void userspace(struct uml_pt_regs *regs) | |||
439 | case SIGFPE: | 447 | case SIGFPE: |
440 | case SIGWINCH: | 448 | case SIGWINCH: |
441 | block_signals(); | 449 | block_signals(); |
442 | (*sig_info[sig])(sig, regs); | 450 | (*sig_info[sig])(sig, &si, regs); |
443 | unblock_signals(); | 451 | unblock_signals(); |
444 | break; | 452 | break; |
445 | default: | 453 | default: |
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 910499d76a67..f60238559af3 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
@@ -87,7 +87,7 @@ static int after_sleep_interval(struct timespec *ts) | |||
87 | 87 | ||
88 | static void deliver_alarm(void) | 88 | static void deliver_alarm(void) |
89 | { | 89 | { |
90 | alarm_handler(SIGVTALRM, NULL); | 90 | alarm_handler(SIGVTALRM, NULL, NULL); |
91 | } | 91 | } |
92 | 92 | ||
93 | static unsigned long long sleep_time(unsigned long long nsecs) | 93 | static unsigned long long sleep_time(unsigned long long nsecs) |
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index c78f14a0df00..dab39350e51e 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
@@ -234,7 +234,7 @@ extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); | |||
234 | extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); | 234 | extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); |
235 | extern void perf_check_microcode(void); | 235 | extern void perf_check_microcode(void); |
236 | #else | 236 | #else |
237 | static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr) | 237 | static inline struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr) |
238 | { | 238 | { |
239 | *nr = 0; | 239 | *nr = 0; |
240 | return NULL; | 240 | return NULL; |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index a15df4be151f..821d53b696d1 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -374,7 +374,7 @@ struct x86_pmu { | |||
374 | /* | 374 | /* |
375 | * Intel DebugStore bits | 375 | * Intel DebugStore bits |
376 | */ | 376 | */ |
377 | int bts :1, | 377 | unsigned int bts :1, |
378 | bts_active :1, | 378 | bts_active :1, |
379 | pebs :1, | 379 | pebs :1, |
380 | pebs_active :1, | 380 | pebs_active :1, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 7a8b9d0abcaa..382366977d4c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -138,6 +138,84 @@ static u64 intel_pmu_event_map(int hw_event) | |||
138 | return intel_perfmon_event_map[hw_event]; | 138 | return intel_perfmon_event_map[hw_event]; |
139 | } | 139 | } |
140 | 140 | ||
141 | #define SNB_DMND_DATA_RD (1ULL << 0) | ||
142 | #define SNB_DMND_RFO (1ULL << 1) | ||
143 | #define SNB_DMND_IFETCH (1ULL << 2) | ||
144 | #define SNB_DMND_WB (1ULL << 3) | ||
145 | #define SNB_PF_DATA_RD (1ULL << 4) | ||
146 | #define SNB_PF_RFO (1ULL << 5) | ||
147 | #define SNB_PF_IFETCH (1ULL << 6) | ||
148 | #define SNB_LLC_DATA_RD (1ULL << 7) | ||
149 | #define SNB_LLC_RFO (1ULL << 8) | ||
150 | #define SNB_LLC_IFETCH (1ULL << 9) | ||
151 | #define SNB_BUS_LOCKS (1ULL << 10) | ||
152 | #define SNB_STRM_ST (1ULL << 11) | ||
153 | #define SNB_OTHER (1ULL << 15) | ||
154 | #define SNB_RESP_ANY (1ULL << 16) | ||
155 | #define SNB_NO_SUPP (1ULL << 17) | ||
156 | #define SNB_LLC_HITM (1ULL << 18) | ||
157 | #define SNB_LLC_HITE (1ULL << 19) | ||
158 | #define SNB_LLC_HITS (1ULL << 20) | ||
159 | #define SNB_LLC_HITF (1ULL << 21) | ||
160 | #define SNB_LOCAL (1ULL << 22) | ||
161 | #define SNB_REMOTE (0xffULL << 23) | ||
162 | #define SNB_SNP_NONE (1ULL << 31) | ||
163 | #define SNB_SNP_NOT_NEEDED (1ULL << 32) | ||
164 | #define SNB_SNP_MISS (1ULL << 33) | ||
165 | #define SNB_NO_FWD (1ULL << 34) | ||
166 | #define SNB_SNP_FWD (1ULL << 35) | ||
167 | #define SNB_HITM (1ULL << 36) | ||
168 | #define SNB_NON_DRAM (1ULL << 37) | ||
169 | |||
170 | #define SNB_DMND_READ (SNB_DMND_DATA_RD|SNB_LLC_DATA_RD) | ||
171 | #define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO) | ||
172 | #define SNB_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO) | ||
173 | |||
174 | #define SNB_SNP_ANY (SNB_SNP_NONE|SNB_SNP_NOT_NEEDED| \ | ||
175 | SNB_SNP_MISS|SNB_NO_FWD|SNB_SNP_FWD| \ | ||
176 | SNB_HITM) | ||
177 | |||
178 | #define SNB_DRAM_ANY (SNB_LOCAL|SNB_REMOTE|SNB_SNP_ANY) | ||
179 | #define SNB_DRAM_REMOTE (SNB_REMOTE|SNB_SNP_ANY) | ||
180 | |||
181 | #define SNB_L3_ACCESS SNB_RESP_ANY | ||
182 | #define SNB_L3_MISS (SNB_DRAM_ANY|SNB_NON_DRAM) | ||
183 | |||
184 | static __initconst const u64 snb_hw_cache_extra_regs | ||
185 | [PERF_COUNT_HW_CACHE_MAX] | ||
186 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
187 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = | ||
188 | { | ||
189 | [ C(LL ) ] = { | ||
190 | [ C(OP_READ) ] = { | ||
191 | [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_L3_ACCESS, | ||
192 | [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_L3_MISS, | ||
193 | }, | ||
194 | [ C(OP_WRITE) ] = { | ||
195 | [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_L3_ACCESS, | ||
196 | [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_L3_MISS, | ||
197 | }, | ||
198 | [ C(OP_PREFETCH) ] = { | ||
199 | [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS, | ||
200 | [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_L3_MISS, | ||
201 | }, | ||
202 | }, | ||
203 | [ C(NODE) ] = { | ||
204 | [ C(OP_READ) ] = { | ||
205 | [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_DRAM_ANY, | ||
206 | [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_DRAM_REMOTE, | ||
207 | }, | ||
208 | [ C(OP_WRITE) ] = { | ||
209 | [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_DRAM_ANY, | ||
210 | [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_DRAM_REMOTE, | ||
211 | }, | ||
212 | [ C(OP_PREFETCH) ] = { | ||
213 | [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_DRAM_ANY, | ||
214 | [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_DRAM_REMOTE, | ||
215 | }, | ||
216 | }, | ||
217 | }; | ||
218 | |||
141 | static __initconst const u64 snb_hw_cache_event_ids | 219 | static __initconst const u64 snb_hw_cache_event_ids |
142 | [PERF_COUNT_HW_CACHE_MAX] | 220 | [PERF_COUNT_HW_CACHE_MAX] |
143 | [PERF_COUNT_HW_CACHE_OP_MAX] | 221 | [PERF_COUNT_HW_CACHE_OP_MAX] |
@@ -235,16 +313,16 @@ static __initconst const u64 snb_hw_cache_event_ids | |||
235 | }, | 313 | }, |
236 | [ C(NODE) ] = { | 314 | [ C(NODE) ] = { |
237 | [ C(OP_READ) ] = { | 315 | [ C(OP_READ) ] = { |
238 | [ C(RESULT_ACCESS) ] = -1, | 316 | [ C(RESULT_ACCESS) ] = 0x01b7, |
239 | [ C(RESULT_MISS) ] = -1, | 317 | [ C(RESULT_MISS) ] = 0x01b7, |
240 | }, | 318 | }, |
241 | [ C(OP_WRITE) ] = { | 319 | [ C(OP_WRITE) ] = { |
242 | [ C(RESULT_ACCESS) ] = -1, | 320 | [ C(RESULT_ACCESS) ] = 0x01b7, |
243 | [ C(RESULT_MISS) ] = -1, | 321 | [ C(RESULT_MISS) ] = 0x01b7, |
244 | }, | 322 | }, |
245 | [ C(OP_PREFETCH) ] = { | 323 | [ C(OP_PREFETCH) ] = { |
246 | [ C(RESULT_ACCESS) ] = -1, | 324 | [ C(RESULT_ACCESS) ] = 0x01b7, |
247 | [ C(RESULT_MISS) ] = -1, | 325 | [ C(RESULT_MISS) ] = 0x01b7, |
248 | }, | 326 | }, |
249 | }, | 327 | }, |
250 | 328 | ||
@@ -1964,6 +2042,8 @@ __init int intel_pmu_init(void) | |||
1964 | case 58: /* IvyBridge */ | 2042 | case 58: /* IvyBridge */ |
1965 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, | 2043 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, |
1966 | sizeof(hw_cache_event_ids)); | 2044 | sizeof(hw_cache_event_ids)); |
2045 | memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, | ||
2046 | sizeof(hw_cache_extra_regs)); | ||
1967 | 2047 | ||
1968 | intel_pmu_lbr_init_snb(); | 2048 | intel_pmu_lbr_init_snb(); |
1969 | 2049 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 19faffc60886..7563fda9f033 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -18,6 +18,7 @@ static struct event_constraint constraint_empty = | |||
18 | EVENT_CONSTRAINT(0, 0, 0); | 18 | EVENT_CONSTRAINT(0, 0, 0); |
19 | 19 | ||
20 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); | 20 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); |
21 | DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); | ||
21 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); | 22 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); |
22 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); | 23 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); |
23 | DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); | 24 | DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); |
@@ -33,10 +34,81 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); | |||
33 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); | 34 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); |
34 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); | 35 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); |
35 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); | 36 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); |
36 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand0, filter_brand0, "config1:0-7"); | 37 | DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); |
37 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand1, filter_brand1, "config1:8-15"); | 38 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); |
38 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand2, filter_brand2, "config1:16-23"); | 39 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); |
39 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand3, filter_brand3, "config1:24-31"); | 40 | DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); |
41 | |||
42 | static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) | ||
43 | { | ||
44 | u64 count; | ||
45 | |||
46 | rdmsrl(event->hw.event_base, count); | ||
47 | |||
48 | return count; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * generic get constraint function for shared match/mask registers. | ||
53 | */ | ||
54 | static struct event_constraint * | ||
55 | uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
56 | { | ||
57 | struct intel_uncore_extra_reg *er; | ||
58 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
59 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
60 | unsigned long flags; | ||
61 | bool ok = false; | ||
62 | |||
63 | /* | ||
64 | * reg->alloc can be set due to existing state, so for fake box we | ||
65 | * need to ignore this, otherwise we might fail to allocate proper | ||
66 | * fake state for this extra reg constraint. | ||
67 | */ | ||
68 | if (reg1->idx == EXTRA_REG_NONE || | ||
69 | (!uncore_box_is_fake(box) && reg1->alloc)) | ||
70 | return NULL; | ||
71 | |||
72 | er = &box->shared_regs[reg1->idx]; | ||
73 | raw_spin_lock_irqsave(&er->lock, flags); | ||
74 | if (!atomic_read(&er->ref) || | ||
75 | (er->config1 == reg1->config && er->config2 == reg2->config)) { | ||
76 | atomic_inc(&er->ref); | ||
77 | er->config1 = reg1->config; | ||
78 | er->config2 = reg2->config; | ||
79 | ok = true; | ||
80 | } | ||
81 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
82 | |||
83 | if (ok) { | ||
84 | if (!uncore_box_is_fake(box)) | ||
85 | reg1->alloc = 1; | ||
86 | return NULL; | ||
87 | } | ||
88 | |||
89 | return &constraint_empty; | ||
90 | } | ||
91 | |||
92 | static void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
93 | { | ||
94 | struct intel_uncore_extra_reg *er; | ||
95 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
96 | |||
97 | /* | ||
98 | * Only put constraint if extra reg was actually allocated. Also | ||
99 | * takes care of event which do not use an extra shared reg. | ||
100 | * | ||
101 | * Also, if this is a fake box we shouldn't touch any event state | ||
102 | * (reg->alloc) and we don't care about leaving inconsistent box | ||
103 | * state either since it will be thrown out. | ||
104 | */ | ||
105 | if (uncore_box_is_fake(box) || !reg1->alloc) | ||
106 | return; | ||
107 | |||
108 | er = &box->shared_regs[reg1->idx]; | ||
109 | atomic_dec(&er->ref); | ||
110 | reg1->alloc = 0; | ||
111 | } | ||
40 | 112 | ||
41 | /* Sandy Bridge-EP uncore support */ | 113 | /* Sandy Bridge-EP uncore support */ |
42 | static struct intel_uncore_type snbep_uncore_cbox; | 114 | static struct intel_uncore_type snbep_uncore_cbox; |
@@ -64,18 +136,15 @@ static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) | |||
64 | pci_write_config_dword(pdev, box_ctl, config); | 136 | pci_write_config_dword(pdev, box_ctl, config); |
65 | } | 137 | } |
66 | 138 | ||
67 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, | 139 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
68 | struct perf_event *event) | ||
69 | { | 140 | { |
70 | struct pci_dev *pdev = box->pci_dev; | 141 | struct pci_dev *pdev = box->pci_dev; |
71 | struct hw_perf_event *hwc = &event->hw; | 142 | struct hw_perf_event *hwc = &event->hw; |
72 | 143 | ||
73 | pci_write_config_dword(pdev, hwc->config_base, hwc->config | | 144 | pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); |
74 | SNBEP_PMON_CTL_EN); | ||
75 | } | 145 | } |
76 | 146 | ||
77 | static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, | 147 | static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event) |
78 | struct perf_event *event) | ||
79 | { | 148 | { |
80 | struct pci_dev *pdev = box->pci_dev; | 149 | struct pci_dev *pdev = box->pci_dev; |
81 | struct hw_perf_event *hwc = &event->hw; | 150 | struct hw_perf_event *hwc = &event->hw; |
@@ -83,8 +152,7 @@ static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, | |||
83 | pci_write_config_dword(pdev, hwc->config_base, hwc->config); | 152 | pci_write_config_dword(pdev, hwc->config_base, hwc->config); |
84 | } | 153 | } |
85 | 154 | ||
86 | static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, | 155 | static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event) |
87 | struct perf_event *event) | ||
88 | { | 156 | { |
89 | struct pci_dev *pdev = box->pci_dev; | 157 | struct pci_dev *pdev = box->pci_dev; |
90 | struct hw_perf_event *hwc = &event->hw; | 158 | struct hw_perf_event *hwc = &event->hw; |
@@ -92,14 +160,15 @@ static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, | |||
92 | 160 | ||
93 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); | 161 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); |
94 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); | 162 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); |
163 | |||
95 | return count; | 164 | return count; |
96 | } | 165 | } |
97 | 166 | ||
98 | static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) | 167 | static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) |
99 | { | 168 | { |
100 | struct pci_dev *pdev = box->pci_dev; | 169 | struct pci_dev *pdev = box->pci_dev; |
101 | pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, | 170 | |
102 | SNBEP_PMON_BOX_CTL_INT); | 171 | pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, SNBEP_PMON_BOX_CTL_INT); |
103 | } | 172 | } |
104 | 173 | ||
105 | static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) | 174 | static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) |
@@ -112,7 +181,6 @@ static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) | |||
112 | rdmsrl(msr, config); | 181 | rdmsrl(msr, config); |
113 | config |= SNBEP_PMON_BOX_CTL_FRZ; | 182 | config |= SNBEP_PMON_BOX_CTL_FRZ; |
114 | wrmsrl(msr, config); | 183 | wrmsrl(msr, config); |
115 | return; | ||
116 | } | 184 | } |
117 | } | 185 | } |
118 | 186 | ||
@@ -126,12 +194,10 @@ static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) | |||
126 | rdmsrl(msr, config); | 194 | rdmsrl(msr, config); |
127 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; | 195 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; |
128 | wrmsrl(msr, config); | 196 | wrmsrl(msr, config); |
129 | return; | ||
130 | } | 197 | } |
131 | } | 198 | } |
132 | 199 | ||
133 | static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, | 200 | static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
134 | struct perf_event *event) | ||
135 | { | 201 | { |
136 | struct hw_perf_event *hwc = &event->hw; | 202 | struct hw_perf_event *hwc = &event->hw; |
137 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 203 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
@@ -150,68 +216,15 @@ static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, | |||
150 | wrmsrl(hwc->config_base, hwc->config); | 216 | wrmsrl(hwc->config_base, hwc->config); |
151 | } | 217 | } |
152 | 218 | ||
153 | static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box, | ||
154 | struct perf_event *event) | ||
155 | { | ||
156 | struct hw_perf_event *hwc = &event->hw; | ||
157 | u64 count; | ||
158 | |||
159 | rdmsrl(hwc->event_base, count); | ||
160 | return count; | ||
161 | } | ||
162 | |||
163 | static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) | 219 | static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) |
164 | { | 220 | { |
165 | unsigned msr = uncore_msr_box_ctl(box); | 221 | unsigned msr = uncore_msr_box_ctl(box); |
222 | |||
166 | if (msr) | 223 | if (msr) |
167 | wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); | 224 | wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); |
168 | } | 225 | } |
169 | 226 | ||
170 | static struct event_constraint * | 227 | static int snbep_uncore_hw_config(struct intel_uncore_box *box, struct perf_event *event) |
171 | snbep_uncore_get_constraint(struct intel_uncore_box *box, | ||
172 | struct perf_event *event) | ||
173 | { | ||
174 | struct intel_uncore_extra_reg *er; | ||
175 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
176 | unsigned long flags; | ||
177 | bool ok = false; | ||
178 | |||
179 | if (reg1->idx == EXTRA_REG_NONE || (box->phys_id >= 0 && reg1->alloc)) | ||
180 | return NULL; | ||
181 | |||
182 | er = &box->shared_regs[reg1->idx]; | ||
183 | raw_spin_lock_irqsave(&er->lock, flags); | ||
184 | if (!atomic_read(&er->ref) || er->config1 == reg1->config) { | ||
185 | atomic_inc(&er->ref); | ||
186 | er->config1 = reg1->config; | ||
187 | ok = true; | ||
188 | } | ||
189 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
190 | |||
191 | if (ok) { | ||
192 | if (box->phys_id >= 0) | ||
193 | reg1->alloc = 1; | ||
194 | return NULL; | ||
195 | } | ||
196 | return &constraint_empty; | ||
197 | } | ||
198 | |||
199 | static void snbep_uncore_put_constraint(struct intel_uncore_box *box, | ||
200 | struct perf_event *event) | ||
201 | { | ||
202 | struct intel_uncore_extra_reg *er; | ||
203 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
204 | |||
205 | if (box->phys_id < 0 || !reg1->alloc) | ||
206 | return; | ||
207 | |||
208 | er = &box->shared_regs[reg1->idx]; | ||
209 | atomic_dec(&er->ref); | ||
210 | reg1->alloc = 0; | ||
211 | } | ||
212 | |||
213 | static int snbep_uncore_hw_config(struct intel_uncore_box *box, | ||
214 | struct perf_event *event) | ||
215 | { | 228 | { |
216 | struct hw_perf_event *hwc = &event->hw; | 229 | struct hw_perf_event *hwc = &event->hw; |
217 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 230 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
@@ -221,14 +234,16 @@ static int snbep_uncore_hw_config(struct intel_uncore_box *box, | |||
221 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; | 234 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; |
222 | reg1->config = event->attr.config1 & | 235 | reg1->config = event->attr.config1 & |
223 | SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK; | 236 | SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK; |
224 | } else if (box->pmu->type == &snbep_uncore_pcu) { | ||
225 | reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; | ||
226 | reg1->config = event->attr.config1 & | ||
227 | SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK; | ||
228 | } else { | 237 | } else { |
229 | return 0; | 238 | if (box->pmu->type == &snbep_uncore_pcu) { |
239 | reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; | ||
240 | reg1->config = event->attr.config1 & SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK; | ||
241 | } else { | ||
242 | return 0; | ||
243 | } | ||
230 | } | 244 | } |
231 | reg1->idx = 0; | 245 | reg1->idx = 0; |
246 | |||
232 | return 0; | 247 | return 0; |
233 | } | 248 | } |
234 | 249 | ||
@@ -272,10 +287,19 @@ static struct attribute *snbep_uncore_pcu_formats_attr[] = { | |||
272 | &format_attr_thresh5.attr, | 287 | &format_attr_thresh5.attr, |
273 | &format_attr_occ_invert.attr, | 288 | &format_attr_occ_invert.attr, |
274 | &format_attr_occ_edge.attr, | 289 | &format_attr_occ_edge.attr, |
275 | &format_attr_filter_brand0.attr, | 290 | &format_attr_filter_band0.attr, |
276 | &format_attr_filter_brand1.attr, | 291 | &format_attr_filter_band1.attr, |
277 | &format_attr_filter_brand2.attr, | 292 | &format_attr_filter_band2.attr, |
278 | &format_attr_filter_brand3.attr, | 293 | &format_attr_filter_band3.attr, |
294 | NULL, | ||
295 | }; | ||
296 | |||
297 | static struct attribute *snbep_uncore_qpi_formats_attr[] = { | ||
298 | &format_attr_event_ext.attr, | ||
299 | &format_attr_umask.attr, | ||
300 | &format_attr_edge.attr, | ||
301 | &format_attr_inv.attr, | ||
302 | &format_attr_thresh8.attr, | ||
279 | NULL, | 303 | NULL, |
280 | }; | 304 | }; |
281 | 305 | ||
@@ -314,15 +338,20 @@ static struct attribute_group snbep_uncore_pcu_format_group = { | |||
314 | .attrs = snbep_uncore_pcu_formats_attr, | 338 | .attrs = snbep_uncore_pcu_formats_attr, |
315 | }; | 339 | }; |
316 | 340 | ||
341 | static struct attribute_group snbep_uncore_qpi_format_group = { | ||
342 | .name = "format", | ||
343 | .attrs = snbep_uncore_qpi_formats_attr, | ||
344 | }; | ||
345 | |||
317 | static struct intel_uncore_ops snbep_uncore_msr_ops = { | 346 | static struct intel_uncore_ops snbep_uncore_msr_ops = { |
318 | .init_box = snbep_uncore_msr_init_box, | 347 | .init_box = snbep_uncore_msr_init_box, |
319 | .disable_box = snbep_uncore_msr_disable_box, | 348 | .disable_box = snbep_uncore_msr_disable_box, |
320 | .enable_box = snbep_uncore_msr_enable_box, | 349 | .enable_box = snbep_uncore_msr_enable_box, |
321 | .disable_event = snbep_uncore_msr_disable_event, | 350 | .disable_event = snbep_uncore_msr_disable_event, |
322 | .enable_event = snbep_uncore_msr_enable_event, | 351 | .enable_event = snbep_uncore_msr_enable_event, |
323 | .read_counter = snbep_uncore_msr_read_counter, | 352 | .read_counter = uncore_msr_read_counter, |
324 | .get_constraint = snbep_uncore_get_constraint, | 353 | .get_constraint = uncore_get_constraint, |
325 | .put_constraint = snbep_uncore_put_constraint, | 354 | .put_constraint = uncore_put_constraint, |
326 | .hw_config = snbep_uncore_hw_config, | 355 | .hw_config = snbep_uncore_hw_config, |
327 | }; | 356 | }; |
328 | 357 | ||
@@ -485,8 +514,13 @@ static struct intel_uncore_type snbep_uncore_qpi = { | |||
485 | .num_counters = 4, | 514 | .num_counters = 4, |
486 | .num_boxes = 2, | 515 | .num_boxes = 2, |
487 | .perf_ctr_bits = 48, | 516 | .perf_ctr_bits = 48, |
517 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | ||
518 | .event_ctl = SNBEP_PCI_PMON_CTL0, | ||
519 | .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, | ||
520 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | ||
521 | .ops = &snbep_uncore_pci_ops, | ||
488 | .event_descs = snbep_uncore_qpi_events, | 522 | .event_descs = snbep_uncore_qpi_events, |
489 | SNBEP_UNCORE_PCI_COMMON_INIT(), | 523 | .format_group = &snbep_uncore_qpi_format_group, |
490 | }; | 524 | }; |
491 | 525 | ||
492 | 526 | ||
@@ -603,10 +637,8 @@ static void snbep_pci2phy_map_init(void) | |||
603 | } | 637 | } |
604 | /* end of Sandy Bridge-EP uncore support */ | 638 | /* end of Sandy Bridge-EP uncore support */ |
605 | 639 | ||
606 | |||
607 | /* Sandy Bridge uncore support */ | 640 | /* Sandy Bridge uncore support */ |
608 | static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, | 641 | static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
609 | struct perf_event *event) | ||
610 | { | 642 | { |
611 | struct hw_perf_event *hwc = &event->hw; | 643 | struct hw_perf_event *hwc = &event->hw; |
612 | 644 | ||
@@ -616,20 +648,11 @@ static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, | |||
616 | wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); | 648 | wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); |
617 | } | 649 | } |
618 | 650 | ||
619 | static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, | 651 | static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) |
620 | struct perf_event *event) | ||
621 | { | 652 | { |
622 | wrmsrl(event->hw.config_base, 0); | 653 | wrmsrl(event->hw.config_base, 0); |
623 | } | 654 | } |
624 | 655 | ||
625 | static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box, | ||
626 | struct perf_event *event) | ||
627 | { | ||
628 | u64 count; | ||
629 | rdmsrl(event->hw.event_base, count); | ||
630 | return count; | ||
631 | } | ||
632 | |||
633 | static void snb_uncore_msr_init_box(struct intel_uncore_box *box) | 656 | static void snb_uncore_msr_init_box(struct intel_uncore_box *box) |
634 | { | 657 | { |
635 | if (box->pmu->pmu_idx == 0) { | 658 | if (box->pmu->pmu_idx == 0) { |
@@ -648,15 +671,15 @@ static struct attribute *snb_uncore_formats_attr[] = { | |||
648 | }; | 671 | }; |
649 | 672 | ||
650 | static struct attribute_group snb_uncore_format_group = { | 673 | static struct attribute_group snb_uncore_format_group = { |
651 | .name = "format", | 674 | .name = "format", |
652 | .attrs = snb_uncore_formats_attr, | 675 | .attrs = snb_uncore_formats_attr, |
653 | }; | 676 | }; |
654 | 677 | ||
655 | static struct intel_uncore_ops snb_uncore_msr_ops = { | 678 | static struct intel_uncore_ops snb_uncore_msr_ops = { |
656 | .init_box = snb_uncore_msr_init_box, | 679 | .init_box = snb_uncore_msr_init_box, |
657 | .disable_event = snb_uncore_msr_disable_event, | 680 | .disable_event = snb_uncore_msr_disable_event, |
658 | .enable_event = snb_uncore_msr_enable_event, | 681 | .enable_event = snb_uncore_msr_enable_event, |
659 | .read_counter = snb_uncore_msr_read_counter, | 682 | .read_counter = uncore_msr_read_counter, |
660 | }; | 683 | }; |
661 | 684 | ||
662 | static struct event_constraint snb_uncore_cbox_constraints[] = { | 685 | static struct event_constraint snb_uncore_cbox_constraints[] = { |
@@ -697,12 +720,10 @@ static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) | |||
697 | 720 | ||
698 | static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) | 721 | static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) |
699 | { | 722 | { |
700 | wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, | 723 | wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); |
701 | NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); | ||
702 | } | 724 | } |
703 | 725 | ||
704 | static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, | 726 | static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
705 | struct perf_event *event) | ||
706 | { | 727 | { |
707 | struct hw_perf_event *hwc = &event->hw; | 728 | struct hw_perf_event *hwc = &event->hw; |
708 | 729 | ||
@@ -744,7 +765,7 @@ static struct intel_uncore_ops nhm_uncore_msr_ops = { | |||
744 | .enable_box = nhm_uncore_msr_enable_box, | 765 | .enable_box = nhm_uncore_msr_enable_box, |
745 | .disable_event = snb_uncore_msr_disable_event, | 766 | .disable_event = snb_uncore_msr_disable_event, |
746 | .enable_event = nhm_uncore_msr_enable_event, | 767 | .enable_event = nhm_uncore_msr_enable_event, |
747 | .read_counter = snb_uncore_msr_read_counter, | 768 | .read_counter = uncore_msr_read_counter, |
748 | }; | 769 | }; |
749 | 770 | ||
750 | static struct intel_uncore_type nhm_uncore = { | 771 | static struct intel_uncore_type nhm_uncore = { |
@@ -769,8 +790,1041 @@ static struct intel_uncore_type *nhm_msr_uncores[] = { | |||
769 | }; | 790 | }; |
770 | /* end of Nehalem uncore support */ | 791 | /* end of Nehalem uncore support */ |
771 | 792 | ||
772 | static void uncore_assign_hw_event(struct intel_uncore_box *box, | 793 | /* Nehalem-EX uncore support */ |
773 | struct perf_event *event, int idx) | 794 | #define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ |
795 | ((1ULL << (n)) - 1))) | ||
796 | |||
797 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); | ||
798 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); | ||
799 | DEFINE_UNCORE_FORMAT_ATTR(mm_cfg, mm_cfg, "config:63"); | ||
800 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); | ||
801 | DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); | ||
802 | |||
803 | static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box) | ||
804 | { | ||
805 | wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL); | ||
806 | } | ||
807 | |||
808 | static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box) | ||
809 | { | ||
810 | unsigned msr = uncore_msr_box_ctl(box); | ||
811 | u64 config; | ||
812 | |||
813 | if (msr) { | ||
814 | rdmsrl(msr, config); | ||
815 | config &= ~((1ULL << uncore_num_counters(box)) - 1); | ||
816 | /* WBox has a fixed counter */ | ||
817 | if (uncore_msr_fixed_ctl(box)) | ||
818 | config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN; | ||
819 | wrmsrl(msr, config); | ||
820 | } | ||
821 | } | ||
822 | |||
823 | static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box) | ||
824 | { | ||
825 | unsigned msr = uncore_msr_box_ctl(box); | ||
826 | u64 config; | ||
827 | |||
828 | if (msr) { | ||
829 | rdmsrl(msr, config); | ||
830 | config |= (1ULL << uncore_num_counters(box)) - 1; | ||
831 | /* WBox has a fixed counter */ | ||
832 | if (uncore_msr_fixed_ctl(box)) | ||
833 | config |= NHMEX_W_PMON_GLOBAL_FIXED_EN; | ||
834 | wrmsrl(msr, config); | ||
835 | } | ||
836 | } | ||
837 | |||
838 | static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
839 | { | ||
840 | wrmsrl(event->hw.config_base, 0); | ||
841 | } | ||
842 | |||
843 | static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
844 | { | ||
845 | struct hw_perf_event *hwc = &event->hw; | ||
846 | |||
847 | if (hwc->idx >= UNCORE_PMC_IDX_FIXED) | ||
848 | wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0); | ||
849 | else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0) | ||
850 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); | ||
851 | else | ||
852 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); | ||
853 | } | ||
854 | |||
855 | #define NHMEX_UNCORE_OPS_COMMON_INIT() \ | ||
856 | .init_box = nhmex_uncore_msr_init_box, \ | ||
857 | .disable_box = nhmex_uncore_msr_disable_box, \ | ||
858 | .enable_box = nhmex_uncore_msr_enable_box, \ | ||
859 | .disable_event = nhmex_uncore_msr_disable_event, \ | ||
860 | .read_counter = uncore_msr_read_counter | ||
861 | |||
862 | static struct intel_uncore_ops nhmex_uncore_ops = { | ||
863 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
864 | .enable_event = nhmex_uncore_msr_enable_event, | ||
865 | }; | ||
866 | |||
867 | static struct attribute *nhmex_uncore_ubox_formats_attr[] = { | ||
868 | &format_attr_event.attr, | ||
869 | &format_attr_edge.attr, | ||
870 | NULL, | ||
871 | }; | ||
872 | |||
873 | static struct attribute_group nhmex_uncore_ubox_format_group = { | ||
874 | .name = "format", | ||
875 | .attrs = nhmex_uncore_ubox_formats_attr, | ||
876 | }; | ||
877 | |||
878 | static struct intel_uncore_type nhmex_uncore_ubox = { | ||
879 | .name = "ubox", | ||
880 | .num_counters = 1, | ||
881 | .num_boxes = 1, | ||
882 | .perf_ctr_bits = 48, | ||
883 | .event_ctl = NHMEX_U_MSR_PMON_EV_SEL, | ||
884 | .perf_ctr = NHMEX_U_MSR_PMON_CTR, | ||
885 | .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK, | ||
886 | .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL, | ||
887 | .ops = &nhmex_uncore_ops, | ||
888 | .format_group = &nhmex_uncore_ubox_format_group | ||
889 | }; | ||
890 | |||
891 | static struct attribute *nhmex_uncore_cbox_formats_attr[] = { | ||
892 | &format_attr_event.attr, | ||
893 | &format_attr_umask.attr, | ||
894 | &format_attr_edge.attr, | ||
895 | &format_attr_inv.attr, | ||
896 | &format_attr_thresh8.attr, | ||
897 | NULL, | ||
898 | }; | ||
899 | |||
900 | static struct attribute_group nhmex_uncore_cbox_format_group = { | ||
901 | .name = "format", | ||
902 | .attrs = nhmex_uncore_cbox_formats_attr, | ||
903 | }; | ||
904 | |||
905 | static struct intel_uncore_type nhmex_uncore_cbox = { | ||
906 | .name = "cbox", | ||
907 | .num_counters = 6, | ||
908 | .num_boxes = 8, | ||
909 | .perf_ctr_bits = 48, | ||
910 | .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, | ||
911 | .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, | ||
912 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | ||
913 | .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, | ||
914 | .msr_offset = NHMEX_C_MSR_OFFSET, | ||
915 | .pair_ctr_ctl = 1, | ||
916 | .ops = &nhmex_uncore_ops, | ||
917 | .format_group = &nhmex_uncore_cbox_format_group | ||
918 | }; | ||
919 | |||
920 | static struct uncore_event_desc nhmex_uncore_wbox_events[] = { | ||
921 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"), | ||
922 | { /* end: all zeroes */ }, | ||
923 | }; | ||
924 | |||
925 | static struct intel_uncore_type nhmex_uncore_wbox = { | ||
926 | .name = "wbox", | ||
927 | .num_counters = 4, | ||
928 | .num_boxes = 1, | ||
929 | .perf_ctr_bits = 48, | ||
930 | .event_ctl = NHMEX_W_MSR_PMON_CNT0, | ||
931 | .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0, | ||
932 | .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR, | ||
933 | .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL, | ||
934 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | ||
935 | .box_ctl = NHMEX_W_MSR_GLOBAL_CTL, | ||
936 | .pair_ctr_ctl = 1, | ||
937 | .event_descs = nhmex_uncore_wbox_events, | ||
938 | .ops = &nhmex_uncore_ops, | ||
939 | .format_group = &nhmex_uncore_cbox_format_group | ||
940 | }; | ||
941 | |||
942 | static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
943 | { | ||
944 | struct hw_perf_event *hwc = &event->hw; | ||
945 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
946 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
947 | int ctr, ev_sel; | ||
948 | |||
949 | ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >> | ||
950 | NHMEX_B_PMON_CTR_SHIFT; | ||
951 | ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >> | ||
952 | NHMEX_B_PMON_CTL_EV_SEL_SHIFT; | ||
953 | |||
954 | /* events that do not use the match/mask registers */ | ||
955 | if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) || | ||
956 | (ctr == 2 && ev_sel != 0x4) || ctr == 3) | ||
957 | return 0; | ||
958 | |||
959 | if (box->pmu->pmu_idx == 0) | ||
960 | reg1->reg = NHMEX_B0_MSR_MATCH; | ||
961 | else | ||
962 | reg1->reg = NHMEX_B1_MSR_MATCH; | ||
963 | reg1->idx = 0; | ||
964 | reg1->config = event->attr.config1; | ||
965 | reg2->config = event->attr.config2; | ||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
970 | { | ||
971 | struct hw_perf_event *hwc = &event->hw; | ||
972 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
973 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
974 | |||
975 | if (reg1->idx != EXTRA_REG_NONE) { | ||
976 | wrmsrl(reg1->reg, reg1->config); | ||
977 | wrmsrl(reg1->reg + 1, reg2->config); | ||
978 | } | ||
979 | wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | | ||
980 | (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK)); | ||
981 | } | ||
982 | |||
983 | /* | ||
984 | * The Bbox has 4 counters, but each counter monitors different events. | ||
985 | * Use bits 6-7 in the event config to select counter. | ||
986 | */ | ||
987 | static struct event_constraint nhmex_uncore_bbox_constraints[] = { | ||
988 | EVENT_CONSTRAINT(0 , 1, 0xc0), | ||
989 | EVENT_CONSTRAINT(0x40, 2, 0xc0), | ||
990 | EVENT_CONSTRAINT(0x80, 4, 0xc0), | ||
991 | EVENT_CONSTRAINT(0xc0, 8, 0xc0), | ||
992 | EVENT_CONSTRAINT_END, | ||
993 | }; | ||
994 | |||
995 | static struct attribute *nhmex_uncore_bbox_formats_attr[] = { | ||
996 | &format_attr_event5.attr, | ||
997 | &format_attr_counter.attr, | ||
998 | &format_attr_match.attr, | ||
999 | &format_attr_mask.attr, | ||
1000 | NULL, | ||
1001 | }; | ||
1002 | |||
1003 | static struct attribute_group nhmex_uncore_bbox_format_group = { | ||
1004 | .name = "format", | ||
1005 | .attrs = nhmex_uncore_bbox_formats_attr, | ||
1006 | }; | ||
1007 | |||
1008 | static struct intel_uncore_ops nhmex_uncore_bbox_ops = { | ||
1009 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
1010 | .enable_event = nhmex_bbox_msr_enable_event, | ||
1011 | .hw_config = nhmex_bbox_hw_config, | ||
1012 | .get_constraint = uncore_get_constraint, | ||
1013 | .put_constraint = uncore_put_constraint, | ||
1014 | }; | ||
1015 | |||
1016 | static struct intel_uncore_type nhmex_uncore_bbox = { | ||
1017 | .name = "bbox", | ||
1018 | .num_counters = 4, | ||
1019 | .num_boxes = 2, | ||
1020 | .perf_ctr_bits = 48, | ||
1021 | .event_ctl = NHMEX_B0_MSR_PMON_CTL0, | ||
1022 | .perf_ctr = NHMEX_B0_MSR_PMON_CTR0, | ||
1023 | .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK, | ||
1024 | .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL, | ||
1025 | .msr_offset = NHMEX_B_MSR_OFFSET, | ||
1026 | .pair_ctr_ctl = 1, | ||
1027 | .num_shared_regs = 1, | ||
1028 | .constraints = nhmex_uncore_bbox_constraints, | ||
1029 | .ops = &nhmex_uncore_bbox_ops, | ||
1030 | .format_group = &nhmex_uncore_bbox_format_group | ||
1031 | }; | ||
1032 | |||
1033 | static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
1034 | { | ||
1035 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
1036 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
1037 | |||
1038 | if (event->attr.config & NHMEX_S_PMON_MM_CFG_EN) { | ||
1039 | reg1->config = event->attr.config1; | ||
1040 | reg2->config = event->attr.config2; | ||
1041 | } else { | ||
1042 | reg1->config = ~0ULL; | ||
1043 | reg2->config = ~0ULL; | ||
1044 | } | ||
1045 | |||
1046 | if (box->pmu->pmu_idx == 0) | ||
1047 | reg1->reg = NHMEX_S0_MSR_MM_CFG; | ||
1048 | else | ||
1049 | reg1->reg = NHMEX_S1_MSR_MM_CFG; | ||
1050 | |||
1051 | reg1->idx = 0; | ||
1052 | |||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
1057 | { | ||
1058 | struct hw_perf_event *hwc = &event->hw; | ||
1059 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
1060 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
1061 | |||
1062 | wrmsrl(reg1->reg, 0); | ||
1063 | if (reg1->config != ~0ULL || reg2->config != ~0ULL) { | ||
1064 | wrmsrl(reg1->reg + 1, reg1->config); | ||
1065 | wrmsrl(reg1->reg + 2, reg2->config); | ||
1066 | wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); | ||
1067 | } | ||
1068 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); | ||
1069 | } | ||
1070 | |||
1071 | static struct attribute *nhmex_uncore_sbox_formats_attr[] = { | ||
1072 | &format_attr_event.attr, | ||
1073 | &format_attr_umask.attr, | ||
1074 | &format_attr_edge.attr, | ||
1075 | &format_attr_inv.attr, | ||
1076 | &format_attr_thresh8.attr, | ||
1077 | &format_attr_mm_cfg.attr, | ||
1078 | &format_attr_match.attr, | ||
1079 | &format_attr_mask.attr, | ||
1080 | NULL, | ||
1081 | }; | ||
1082 | |||
1083 | static struct attribute_group nhmex_uncore_sbox_format_group = { | ||
1084 | .name = "format", | ||
1085 | .attrs = nhmex_uncore_sbox_formats_attr, | ||
1086 | }; | ||
1087 | |||
1088 | static struct intel_uncore_ops nhmex_uncore_sbox_ops = { | ||
1089 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
1090 | .enable_event = nhmex_sbox_msr_enable_event, | ||
1091 | .hw_config = nhmex_sbox_hw_config, | ||
1092 | .get_constraint = uncore_get_constraint, | ||
1093 | .put_constraint = uncore_put_constraint, | ||
1094 | }; | ||
1095 | |||
1096 | static struct intel_uncore_type nhmex_uncore_sbox = { | ||
1097 | .name = "sbox", | ||
1098 | .num_counters = 4, | ||
1099 | .num_boxes = 2, | ||
1100 | .perf_ctr_bits = 48, | ||
1101 | .event_ctl = NHMEX_S0_MSR_PMON_CTL0, | ||
1102 | .perf_ctr = NHMEX_S0_MSR_PMON_CTR0, | ||
1103 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | ||
1104 | .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL, | ||
1105 | .msr_offset = NHMEX_S_MSR_OFFSET, | ||
1106 | .pair_ctr_ctl = 1, | ||
1107 | .num_shared_regs = 1, | ||
1108 | .ops = &nhmex_uncore_sbox_ops, | ||
1109 | .format_group = &nhmex_uncore_sbox_format_group | ||
1110 | }; | ||
1111 | |||
1112 | enum { | ||
1113 | EXTRA_REG_NHMEX_M_FILTER, | ||
1114 | EXTRA_REG_NHMEX_M_DSP, | ||
1115 | EXTRA_REG_NHMEX_M_ISS, | ||
1116 | EXTRA_REG_NHMEX_M_MAP, | ||
1117 | EXTRA_REG_NHMEX_M_MSC_THR, | ||
1118 | EXTRA_REG_NHMEX_M_PGT, | ||
1119 | EXTRA_REG_NHMEX_M_PLD, | ||
1120 | EXTRA_REG_NHMEX_M_ZDP_CTL_FVC, | ||
1121 | }; | ||
1122 | |||
1123 | static struct extra_reg nhmex_uncore_mbox_extra_regs[] = { | ||
1124 | MBOX_INC_SEL_EXTAR_REG(0x0, DSP), | ||
1125 | MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR), | ||
1126 | MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR), | ||
1127 | MBOX_INC_SEL_EXTAR_REG(0x9, ISS), | ||
1128 | /* event 0xa uses two extra registers */ | ||
1129 | MBOX_INC_SEL_EXTAR_REG(0xa, ISS), | ||
1130 | MBOX_INC_SEL_EXTAR_REG(0xa, PLD), | ||
1131 | MBOX_INC_SEL_EXTAR_REG(0xb, PLD), | ||
1132 | /* events 0xd ~ 0x10 use the same extra register */ | ||
1133 | MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC), | ||
1134 | MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC), | ||
1135 | MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC), | ||
1136 | MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC), | ||
1137 | MBOX_INC_SEL_EXTAR_REG(0x16, PGT), | ||
1138 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP), | ||
1139 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS), | ||
1140 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT), | ||
1141 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP), | ||
1142 | EVENT_EXTRA_END | ||
1143 | }; | ||
1144 | |||
1145 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) | ||
1146 | { | ||
1147 | struct intel_uncore_extra_reg *er; | ||
1148 | unsigned long flags; | ||
1149 | bool ret = false; | ||
1150 | u64 mask; | ||
1151 | |||
1152 | if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { | ||
1153 | er = &box->shared_regs[idx]; | ||
1154 | raw_spin_lock_irqsave(&er->lock, flags); | ||
1155 | if (!atomic_read(&er->ref) || er->config == config) { | ||
1156 | atomic_inc(&er->ref); | ||
1157 | er->config = config; | ||
1158 | ret = true; | ||
1159 | } | ||
1160 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
1161 | |||
1162 | return ret; | ||
1163 | } | ||
1164 | /* | ||
1165 | * The ZDP_CTL_FVC MSR has 4 fields which are used to control | ||
1166 | * events 0xd ~ 0x10. Besides these 4 fields, there are additional | ||
1167 | * fields which are shared. | ||
1168 | */ | ||
1169 | idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
1170 | if (WARN_ON_ONCE(idx >= 4)) | ||
1171 | return false; | ||
1172 | |||
1173 | /* mask of the shared fields */ | ||
1174 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; | ||
1175 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | ||
1176 | |||
1177 | raw_spin_lock_irqsave(&er->lock, flags); | ||
1178 | /* add mask of the non-shared field if it's in use */ | ||
1179 | if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) | ||
1180 | mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1181 | |||
1182 | if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { | ||
1183 | atomic_add(1 << (idx * 8), &er->ref); | ||
1184 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | | ||
1185 | NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1186 | er->config &= ~mask; | ||
1187 | er->config |= (config & mask); | ||
1188 | ret = true; | ||
1189 | } | ||
1190 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
1191 | |||
1192 | return ret; | ||
1193 | } | ||
1194 | |||
1195 | static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx) | ||
1196 | { | ||
1197 | struct intel_uncore_extra_reg *er; | ||
1198 | |||
1199 | if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { | ||
1200 | er = &box->shared_regs[idx]; | ||
1201 | atomic_dec(&er->ref); | ||
1202 | return; | ||
1203 | } | ||
1204 | |||
1205 | idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
1206 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | ||
1207 | atomic_sub(1 << (idx * 8), &er->ref); | ||
1208 | } | ||
1209 | |||
1210 | u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) | ||
1211 | { | ||
1212 | struct hw_perf_event *hwc = &event->hw; | ||
1213 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
1214 | int idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8); | ||
1215 | u64 config = reg1->config; | ||
1216 | |||
1217 | /* get the non-shared control bits and shift them */ | ||
1218 | idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
1219 | config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1220 | if (new_idx > orig_idx) { | ||
1221 | idx = new_idx - orig_idx; | ||
1222 | config <<= 3 * idx; | ||
1223 | } else { | ||
1224 | idx = orig_idx - new_idx; | ||
1225 | config >>= 3 * idx; | ||
1226 | } | ||
1227 | |||
1228 | /* add the shared control bits back */ | ||
1229 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | ||
1230 | if (modify) { | ||
1231 | /* adjust the main event selector */ | ||
1232 | if (new_idx > orig_idx) | ||
1233 | hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; | ||
1234 | else | ||
1235 | hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; | ||
1236 | reg1->config = config; | ||
1237 | reg1->idx = ~0xff | new_idx; | ||
1238 | } | ||
1239 | return config; | ||
1240 | } | ||
1241 | |||
1242 | static struct event_constraint * | ||
1243 | nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
1244 | { | ||
1245 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
1246 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
1247 | int i, idx[2], alloc = 0; | ||
1248 | u64 config1 = reg1->config; | ||
1249 | |||
1250 | idx[0] = __BITS_VALUE(reg1->idx, 0, 8); | ||
1251 | idx[1] = __BITS_VALUE(reg1->idx, 1, 8); | ||
1252 | again: | ||
1253 | for (i = 0; i < 2; i++) { | ||
1254 | if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i))) | ||
1255 | idx[i] = 0xff; | ||
1256 | |||
1257 | if (idx[i] == 0xff) | ||
1258 | continue; | ||
1259 | |||
1260 | if (!nhmex_mbox_get_shared_reg(box, idx[i], | ||
1261 | __BITS_VALUE(config1, i, 32))) | ||
1262 | goto fail; | ||
1263 | alloc |= (0x1 << i); | ||
1264 | } | ||
1265 | |||
1266 | /* for the match/mask registers */ | ||
1267 | if ((uncore_box_is_fake(box) || !reg2->alloc) && | ||
1268 | !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) | ||
1269 | goto fail; | ||
1270 | |||
1271 | /* | ||
1272 | * If it's a fake box -- as per validate_{group,event}() we | ||
1273 | * shouldn't touch event state and we can avoid doing so | ||
1274 | * since both will only call get_event_constraints() once | ||
1275 | * on each event, this avoids the need for reg->alloc. | ||
1276 | */ | ||
1277 | if (!uncore_box_is_fake(box)) { | ||
1278 | if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) | ||
1279 | nhmex_mbox_alter_er(event, idx[0], true); | ||
1280 | reg1->alloc |= alloc; | ||
1281 | reg2->alloc = 1; | ||
1282 | } | ||
1283 | return NULL; | ||
1284 | fail: | ||
1285 | if (idx[0] != 0xff && !(alloc & 0x1) && | ||
1286 | idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { | ||
1287 | /* | ||
1288 | * events 0xd ~ 0x10 are functional identical, but are | ||
1289 | * controlled by different fields in the ZDP_CTL_FVC | ||
1290 | * register. If we failed to take one field, try the | ||
1291 | * rest 3 choices. | ||
1292 | */ | ||
1293 | BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff); | ||
1294 | idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
1295 | idx[0] = (idx[0] + 1) % 4; | ||
1296 | idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
1297 | if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) { | ||
1298 | config1 = nhmex_mbox_alter_er(event, idx[0], false); | ||
1299 | goto again; | ||
1300 | } | ||
1301 | } | ||
1302 | |||
1303 | if (alloc & 0x1) | ||
1304 | nhmex_mbox_put_shared_reg(box, idx[0]); | ||
1305 | if (alloc & 0x2) | ||
1306 | nhmex_mbox_put_shared_reg(box, idx[1]); | ||
1307 | return &constraint_empty; | ||
1308 | } | ||
1309 | |||
1310 | static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
1311 | { | ||
1312 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
1313 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
1314 | |||
1315 | if (uncore_box_is_fake(box)) | ||
1316 | return; | ||
1317 | |||
1318 | if (reg1->alloc & 0x1) | ||
1319 | nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8)); | ||
1320 | if (reg1->alloc & 0x2) | ||
1321 | nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8)); | ||
1322 | reg1->alloc = 0; | ||
1323 | |||
1324 | if (reg2->alloc) { | ||
1325 | nhmex_mbox_put_shared_reg(box, reg2->idx); | ||
1326 | reg2->alloc = 0; | ||
1327 | } | ||
1328 | } | ||
1329 | |||
1330 | static int nhmex_mbox_extra_reg_idx(struct extra_reg *er) | ||
1331 | { | ||
1332 | if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) | ||
1333 | return er->idx; | ||
1334 | return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd; | ||
1335 | } | ||
1336 | |||
1337 | static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
1338 | { | ||
1339 | struct intel_uncore_type *type = box->pmu->type; | ||
1340 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
1341 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
1342 | struct extra_reg *er; | ||
1343 | unsigned msr; | ||
1344 | int reg_idx = 0; | ||
1345 | |||
1346 | if (WARN_ON_ONCE(reg1->idx != -1)) | ||
1347 | return -EINVAL; | ||
1348 | /* | ||
1349 | * The mbox events may require 2 extra MSRs at the most. But only | ||
1350 | * the lower 32 bits in these MSRs are significant, so we can use | ||
1351 | * config1 to pass two MSRs' config. | ||
1352 | */ | ||
1353 | for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) { | ||
1354 | if (er->event != (event->hw.config & er->config_mask)) | ||
1355 | continue; | ||
1356 | if (event->attr.config1 & ~er->valid_mask) | ||
1357 | return -EINVAL; | ||
1358 | if (er->idx == __BITS_VALUE(reg1->idx, 0, 8) || | ||
1359 | er->idx == __BITS_VALUE(reg1->idx, 1, 8)) | ||
1360 | continue; | ||
1361 | if (WARN_ON_ONCE(reg_idx >= 2)) | ||
1362 | return -EINVAL; | ||
1363 | |||
1364 | msr = er->msr + type->msr_offset * box->pmu->pmu_idx; | ||
1365 | if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) | ||
1366 | return -EINVAL; | ||
1367 | |||
1368 | /* always use the 32~63 bits to pass the PLD config */ | ||
1369 | if (er->idx == EXTRA_REG_NHMEX_M_PLD) | ||
1370 | reg_idx = 1; | ||
1371 | |||
1372 | reg1->idx &= ~(0xff << (reg_idx * 8)); | ||
1373 | reg1->reg &= ~(0xffff << (reg_idx * 16)); | ||
1374 | reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8); | ||
1375 | reg1->reg |= msr << (reg_idx * 16); | ||
1376 | reg1->config = event->attr.config1; | ||
1377 | reg_idx++; | ||
1378 | } | ||
1379 | /* use config2 to pass the filter config */ | ||
1380 | reg2->idx = EXTRA_REG_NHMEX_M_FILTER; | ||
1381 | if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) | ||
1382 | reg2->config = event->attr.config2; | ||
1383 | else | ||
1384 | reg2->config = ~0ULL; | ||
1385 | if (box->pmu->pmu_idx == 0) | ||
1386 | reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; | ||
1387 | else | ||
1388 | reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; | ||
1389 | |||
1390 | return 0; | ||
1391 | } | ||
1392 | |||
1393 | static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx) | ||
1394 | { | ||
1395 | struct intel_uncore_extra_reg *er; | ||
1396 | unsigned long flags; | ||
1397 | u64 config; | ||
1398 | |||
1399 | if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) | ||
1400 | return box->shared_regs[idx].config; | ||
1401 | |||
1402 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | ||
1403 | raw_spin_lock_irqsave(&er->lock, flags); | ||
1404 | config = er->config; | ||
1405 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
1406 | return config; | ||
1407 | } | ||
1408 | |||
1409 | static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
1410 | { | ||
1411 | struct hw_perf_event *hwc = &event->hw; | ||
1412 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
1413 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
1414 | int idx; | ||
1415 | |||
1416 | idx = __BITS_VALUE(reg1->idx, 0, 8); | ||
1417 | if (idx != 0xff) | ||
1418 | wrmsrl(__BITS_VALUE(reg1->reg, 0, 16), | ||
1419 | nhmex_mbox_shared_reg_config(box, idx)); | ||
1420 | idx = __BITS_VALUE(reg1->idx, 1, 8); | ||
1421 | if (idx != 0xff) | ||
1422 | wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), | ||
1423 | nhmex_mbox_shared_reg_config(box, idx)); | ||
1424 | |||
1425 | wrmsrl(reg2->reg, 0); | ||
1426 | if (reg2->config != ~0ULL) { | ||
1427 | wrmsrl(reg2->reg + 1, | ||
1428 | reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); | ||
1429 | wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & | ||
1430 | (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); | ||
1431 | wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); | ||
1432 | } | ||
1433 | |||
1434 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); | ||
1435 | } | ||
1436 | |||
1437 | DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); | ||
1438 | DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); | ||
1439 | DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); | ||
1440 | DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); | ||
1441 | DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); | ||
1442 | DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); | ||
1443 | DEFINE_UNCORE_FORMAT_ATTR(filter_cfg, filter_cfg, "config2:63"); | ||
1444 | DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); | ||
1445 | DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); | ||
1446 | DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); | ||
1447 | DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); | ||
1448 | DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); | ||
1449 | DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); | ||
1450 | DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); | ||
1451 | DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); | ||
1452 | DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); | ||
1453 | |||
1454 | static struct attribute *nhmex_uncore_mbox_formats_attr[] = { | ||
1455 | &format_attr_count_mode.attr, | ||
1456 | &format_attr_storage_mode.attr, | ||
1457 | &format_attr_wrap_mode.attr, | ||
1458 | &format_attr_flag_mode.attr, | ||
1459 | &format_attr_inc_sel.attr, | ||
1460 | &format_attr_set_flag_sel.attr, | ||
1461 | &format_attr_filter_cfg.attr, | ||
1462 | &format_attr_filter_match.attr, | ||
1463 | &format_attr_filter_mask.attr, | ||
1464 | &format_attr_dsp.attr, | ||
1465 | &format_attr_thr.attr, | ||
1466 | &format_attr_fvc.attr, | ||
1467 | &format_attr_pgt.attr, | ||
1468 | &format_attr_map.attr, | ||
1469 | &format_attr_iss.attr, | ||
1470 | &format_attr_pld.attr, | ||
1471 | NULL, | ||
1472 | }; | ||
1473 | |||
1474 | static struct attribute_group nhmex_uncore_mbox_format_group = { | ||
1475 | .name = "format", | ||
1476 | .attrs = nhmex_uncore_mbox_formats_attr, | ||
1477 | }; | ||
1478 | |||
1479 | static struct uncore_event_desc nhmex_uncore_mbox_events[] = { | ||
1480 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"), | ||
1481 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"), | ||
1482 | { /* end: all zeroes */ }, | ||
1483 | }; | ||
1484 | |||
1485 | static struct intel_uncore_ops nhmex_uncore_mbox_ops = { | ||
1486 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
1487 | .enable_event = nhmex_mbox_msr_enable_event, | ||
1488 | .hw_config = nhmex_mbox_hw_config, | ||
1489 | .get_constraint = nhmex_mbox_get_constraint, | ||
1490 | .put_constraint = nhmex_mbox_put_constraint, | ||
1491 | }; | ||
1492 | |||
1493 | static struct intel_uncore_type nhmex_uncore_mbox = { | ||
1494 | .name = "mbox", | ||
1495 | .num_counters = 6, | ||
1496 | .num_boxes = 2, | ||
1497 | .perf_ctr_bits = 48, | ||
1498 | .event_ctl = NHMEX_M0_MSR_PMU_CTL0, | ||
1499 | .perf_ctr = NHMEX_M0_MSR_PMU_CNT0, | ||
1500 | .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK, | ||
1501 | .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL, | ||
1502 | .msr_offset = NHMEX_M_MSR_OFFSET, | ||
1503 | .pair_ctr_ctl = 1, | ||
1504 | .num_shared_regs = 8, | ||
1505 | .event_descs = nhmex_uncore_mbox_events, | ||
1506 | .ops = &nhmex_uncore_mbox_ops, | ||
1507 | .format_group = &nhmex_uncore_mbox_format_group, | ||
1508 | }; | ||
1509 | |||
1510 | void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | ||
1511 | { | ||
1512 | struct hw_perf_event *hwc = &event->hw; | ||
1513 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
1514 | int port; | ||
1515 | |||
1516 | /* adjust the main event selector */ | ||
1517 | if (reg1->idx % 2) { | ||
1518 | reg1->idx--; | ||
1519 | hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | ||
1520 | } else { | ||
1521 | reg1->idx++; | ||
1522 | hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | ||
1523 | } | ||
1524 | |||
1525 | /* adjust address or config of extra register */ | ||
1526 | port = reg1->idx / 6 + box->pmu->pmu_idx * 4; | ||
1527 | switch (reg1->idx % 6) { | ||
1528 | case 0: | ||
1529 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
1530 | break; | ||
1531 | case 1: | ||
1532 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
1533 | break; | ||
1534 | case 2: | ||
1535 | /* the 8~15 bits to the 0~7 bits */ | ||
1536 | reg1->config >>= 8; | ||
1537 | break; | ||
1538 | case 3: | ||
1539 | /* the 0~7 bits to the 8~15 bits */ | ||
1540 | reg1->config <<= 8; | ||
1541 | break; | ||
1542 | case 4: | ||
1543 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
1544 | break; | ||
1545 | case 5: | ||
1546 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
1547 | break; | ||
1548 | }; | ||
1549 | } | ||
1550 | |||
1551 | /* | ||
1552 | * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7. | ||
1553 | * An event set consists of 6 events, the 3rd and 4th events in | ||
1554 | * an event set use the same extra register. So an event set uses | ||
1555 | * 5 extra registers. | ||
1556 | */ | ||
1557 | static struct event_constraint * | ||
1558 | nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
1559 | { | ||
1560 | struct hw_perf_event *hwc = &event->hw; | ||
1561 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
1562 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
1563 | struct intel_uncore_extra_reg *er; | ||
1564 | unsigned long flags; | ||
1565 | int idx, er_idx; | ||
1566 | u64 config1; | ||
1567 | bool ok = false; | ||
1568 | |||
1569 | if (!uncore_box_is_fake(box) && reg1->alloc) | ||
1570 | return NULL; | ||
1571 | |||
1572 | idx = reg1->idx % 6; | ||
1573 | config1 = reg1->config; | ||
1574 | again: | ||
1575 | er_idx = idx; | ||
1576 | /* the 3rd and 4th events use the same extra register */ | ||
1577 | if (er_idx > 2) | ||
1578 | er_idx--; | ||
1579 | er_idx += (reg1->idx / 6) * 5; | ||
1580 | |||
1581 | er = &box->shared_regs[er_idx]; | ||
1582 | raw_spin_lock_irqsave(&er->lock, flags); | ||
1583 | if (idx < 2) { | ||
1584 | if (!atomic_read(&er->ref) || er->config == reg1->config) { | ||
1585 | atomic_inc(&er->ref); | ||
1586 | er->config = reg1->config; | ||
1587 | ok = true; | ||
1588 | } | ||
1589 | } else if (idx == 2 || idx == 3) { | ||
1590 | /* | ||
1591 | * these two events use different fields in a extra register, | ||
1592 | * the 0~7 bits and the 8~15 bits respectively. | ||
1593 | */ | ||
1594 | u64 mask = 0xff << ((idx - 2) * 8); | ||
1595 | if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) || | ||
1596 | !((er->config ^ config1) & mask)) { | ||
1597 | atomic_add(1 << ((idx - 2) * 8), &er->ref); | ||
1598 | er->config &= ~mask; | ||
1599 | er->config |= config1 & mask; | ||
1600 | ok = true; | ||
1601 | } | ||
1602 | } else { | ||
1603 | if (!atomic_read(&er->ref) || | ||
1604 | (er->config == (hwc->config >> 32) && | ||
1605 | er->config1 == reg1->config && | ||
1606 | er->config2 == reg2->config)) { | ||
1607 | atomic_inc(&er->ref); | ||
1608 | er->config = (hwc->config >> 32); | ||
1609 | er->config1 = reg1->config; | ||
1610 | er->config2 = reg2->config; | ||
1611 | ok = true; | ||
1612 | } | ||
1613 | } | ||
1614 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
1615 | |||
1616 | if (!ok) { | ||
1617 | /* | ||
1618 | * The Rbox events are always in pairs. The paired | ||
1619 | * events are functional identical, but use different | ||
1620 | * extra registers. If we failed to take an extra | ||
1621 | * register, try the alternative. | ||
1622 | */ | ||
1623 | if (idx % 2) | ||
1624 | idx--; | ||
1625 | else | ||
1626 | idx++; | ||
1627 | if (idx != reg1->idx % 6) { | ||
1628 | if (idx == 2) | ||
1629 | config1 >>= 8; | ||
1630 | else if (idx == 3) | ||
1631 | config1 <<= 8; | ||
1632 | goto again; | ||
1633 | } | ||
1634 | } else { | ||
1635 | if (!uncore_box_is_fake(box)) { | ||
1636 | if (idx != reg1->idx % 6) | ||
1637 | nhmex_rbox_alter_er(box, event); | ||
1638 | reg1->alloc = 1; | ||
1639 | } | ||
1640 | return NULL; | ||
1641 | } | ||
1642 | return &constraint_empty; | ||
1643 | } | ||
1644 | |||
1645 | static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
1646 | { | ||
1647 | struct intel_uncore_extra_reg *er; | ||
1648 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
1649 | int idx, er_idx; | ||
1650 | |||
1651 | if (uncore_box_is_fake(box) || !reg1->alloc) | ||
1652 | return; | ||
1653 | |||
1654 | idx = reg1->idx % 6; | ||
1655 | er_idx = idx; | ||
1656 | if (er_idx > 2) | ||
1657 | er_idx--; | ||
1658 | er_idx += (reg1->idx / 6) * 5; | ||
1659 | |||
1660 | er = &box->shared_regs[er_idx]; | ||
1661 | if (idx == 2 || idx == 3) | ||
1662 | atomic_sub(1 << ((idx - 2) * 8), &er->ref); | ||
1663 | else | ||
1664 | atomic_dec(&er->ref); | ||
1665 | |||
1666 | reg1->alloc = 0; | ||
1667 | } | ||
1668 | |||
1669 | static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
1670 | { | ||
1671 | struct hw_perf_event *hwc = &event->hw; | ||
1672 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
1673 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
1674 | int port, idx; | ||
1675 | |||
1676 | idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> | ||
1677 | NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | ||
1678 | if (idx >= 0x18) | ||
1679 | return -EINVAL; | ||
1680 | |||
1681 | reg1->idx = idx; | ||
1682 | reg1->config = event->attr.config1; | ||
1683 | |||
1684 | port = idx / 6 + box->pmu->pmu_idx * 4; | ||
1685 | idx %= 6; | ||
1686 | switch (idx) { | ||
1687 | case 0: | ||
1688 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
1689 | break; | ||
1690 | case 1: | ||
1691 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
1692 | break; | ||
1693 | case 2: | ||
1694 | case 3: | ||
1695 | reg1->reg = NHMEX_R_MSR_PORTN_QLX_CFG(port); | ||
1696 | break; | ||
1697 | case 4: | ||
1698 | case 5: | ||
1699 | if (idx == 4) | ||
1700 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
1701 | else | ||
1702 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
1703 | reg2->config = event->attr.config2; | ||
1704 | hwc->config |= event->attr.config & (~0ULL << 32); | ||
1705 | break; | ||
1706 | }; | ||
1707 | return 0; | ||
1708 | } | ||
1709 | |||
1710 | static u64 nhmex_rbox_shared_reg_config(struct intel_uncore_box *box, int idx) | ||
1711 | { | ||
1712 | struct intel_uncore_extra_reg *er; | ||
1713 | unsigned long flags; | ||
1714 | u64 config; | ||
1715 | |||
1716 | er = &box->shared_regs[idx]; | ||
1717 | |||
1718 | raw_spin_lock_irqsave(&er->lock, flags); | ||
1719 | config = er->config; | ||
1720 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
1721 | |||
1722 | return config; | ||
1723 | } | ||
1724 | |||
1725 | static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
1726 | { | ||
1727 | struct hw_perf_event *hwc = &event->hw; | ||
1728 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
1729 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
1730 | int idx, er_idx; | ||
1731 | |||
1732 | idx = reg1->idx % 6; | ||
1733 | er_idx = idx; | ||
1734 | if (er_idx > 2) | ||
1735 | er_idx--; | ||
1736 | er_idx += (reg1->idx / 6) * 5; | ||
1737 | |||
1738 | switch (idx) { | ||
1739 | case 0: | ||
1740 | case 1: | ||
1741 | wrmsrl(reg1->reg, reg1->config); | ||
1742 | break; | ||
1743 | case 2: | ||
1744 | case 3: | ||
1745 | wrmsrl(reg1->reg, nhmex_rbox_shared_reg_config(box, er_idx)); | ||
1746 | break; | ||
1747 | case 4: | ||
1748 | case 5: | ||
1749 | wrmsrl(reg1->reg, reg1->config); | ||
1750 | wrmsrl(reg1->reg + 1, hwc->config >> 32); | ||
1751 | wrmsrl(reg1->reg + 2, reg2->config); | ||
1752 | break; | ||
1753 | }; | ||
1754 | |||
1755 | wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | | ||
1756 | (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); | ||
1757 | } | ||
1758 | |||
1759 | DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config:32-63"); | ||
1760 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config1:0-63"); | ||
1761 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); | ||
1762 | DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); | ||
1763 | DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); | ||
1764 | |||
1765 | static struct attribute *nhmex_uncore_rbox_formats_attr[] = { | ||
1766 | &format_attr_event5.attr, | ||
1767 | &format_attr_xbr_mm_cfg.attr, | ||
1768 | &format_attr_xbr_match.attr, | ||
1769 | &format_attr_xbr_mask.attr, | ||
1770 | &format_attr_qlx_cfg.attr, | ||
1771 | &format_attr_iperf_cfg.attr, | ||
1772 | NULL, | ||
1773 | }; | ||
1774 | |||
1775 | static struct attribute_group nhmex_uncore_rbox_format_group = { | ||
1776 | .name = "format", | ||
1777 | .attrs = nhmex_uncore_rbox_formats_attr, | ||
1778 | }; | ||
1779 | |||
1780 | static struct uncore_event_desc nhmex_uncore_rbox_events[] = { | ||
1781 | INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"), | ||
1782 | INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"), | ||
1783 | INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"), | ||
1784 | INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"), | ||
1785 | INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"), | ||
1786 | INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"), | ||
1787 | { /* end: all zeroes */ }, | ||
1788 | }; | ||
1789 | |||
1790 | static struct intel_uncore_ops nhmex_uncore_rbox_ops = { | ||
1791 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
1792 | .enable_event = nhmex_rbox_msr_enable_event, | ||
1793 | .hw_config = nhmex_rbox_hw_config, | ||
1794 | .get_constraint = nhmex_rbox_get_constraint, | ||
1795 | .put_constraint = nhmex_rbox_put_constraint, | ||
1796 | }; | ||
1797 | |||
1798 | static struct intel_uncore_type nhmex_uncore_rbox = { | ||
1799 | .name = "rbox", | ||
1800 | .num_counters = 8, | ||
1801 | .num_boxes = 2, | ||
1802 | .perf_ctr_bits = 48, | ||
1803 | .event_ctl = NHMEX_R_MSR_PMON_CTL0, | ||
1804 | .perf_ctr = NHMEX_R_MSR_PMON_CNT0, | ||
1805 | .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK, | ||
1806 | .box_ctl = NHMEX_R_MSR_GLOBAL_CTL, | ||
1807 | .msr_offset = NHMEX_R_MSR_OFFSET, | ||
1808 | .pair_ctr_ctl = 1, | ||
1809 | .num_shared_regs = 20, | ||
1810 | .event_descs = nhmex_uncore_rbox_events, | ||
1811 | .ops = &nhmex_uncore_rbox_ops, | ||
1812 | .format_group = &nhmex_uncore_rbox_format_group | ||
1813 | }; | ||
1814 | |||
1815 | static struct intel_uncore_type *nhmex_msr_uncores[] = { | ||
1816 | &nhmex_uncore_ubox, | ||
1817 | &nhmex_uncore_cbox, | ||
1818 | &nhmex_uncore_bbox, | ||
1819 | &nhmex_uncore_sbox, | ||
1820 | &nhmex_uncore_mbox, | ||
1821 | &nhmex_uncore_rbox, | ||
1822 | &nhmex_uncore_wbox, | ||
1823 | NULL, | ||
1824 | }; | ||
1825 | /* end of Nehalem-EX uncore support */ | ||
1826 | |||
1827 | static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx) | ||
774 | { | 1828 | { |
775 | struct hw_perf_event *hwc = &event->hw; | 1829 | struct hw_perf_event *hwc = &event->hw; |
776 | 1830 | ||
@@ -787,8 +1841,7 @@ static void uncore_assign_hw_event(struct intel_uncore_box *box, | |||
787 | hwc->event_base = uncore_perf_ctr(box, hwc->idx); | 1841 | hwc->event_base = uncore_perf_ctr(box, hwc->idx); |
788 | } | 1842 | } |
789 | 1843 | ||
790 | static void uncore_perf_event_update(struct intel_uncore_box *box, | 1844 | static void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event) |
791 | struct perf_event *event) | ||
792 | { | 1845 | { |
793 | u64 prev_count, new_count, delta; | 1846 | u64 prev_count, new_count, delta; |
794 | int shift; | 1847 | int shift; |
@@ -858,14 +1911,12 @@ static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box) | |||
858 | box->hrtimer.function = uncore_pmu_hrtimer; | 1911 | box->hrtimer.function = uncore_pmu_hrtimer; |
859 | } | 1912 | } |
860 | 1913 | ||
861 | struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, | 1914 | struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cpu) |
862 | int cpu) | ||
863 | { | 1915 | { |
864 | struct intel_uncore_box *box; | 1916 | struct intel_uncore_box *box; |
865 | int i, size; | 1917 | int i, size; |
866 | 1918 | ||
867 | size = sizeof(*box) + type->num_shared_regs * | 1919 | size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg); |
868 | sizeof(struct intel_uncore_extra_reg); | ||
869 | 1920 | ||
870 | box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu)); | 1921 | box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu)); |
871 | if (!box) | 1922 | if (!box) |
@@ -915,12 +1966,11 @@ static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) | |||
915 | * perf core schedules event on the basis of cpu, uncore events are | 1966 | * perf core schedules event on the basis of cpu, uncore events are |
916 | * collected by one of the cpus inside a physical package. | 1967 | * collected by one of the cpus inside a physical package. |
917 | */ | 1968 | */ |
918 | return uncore_pmu_to_box(uncore_event_to_pmu(event), | 1969 | return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id()); |
919 | smp_processor_id()); | ||
920 | } | 1970 | } |
921 | 1971 | ||
922 | static int uncore_collect_events(struct intel_uncore_box *box, | 1972 | static int |
923 | struct perf_event *leader, bool dogrp) | 1973 | uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp) |
924 | { | 1974 | { |
925 | struct perf_event *event; | 1975 | struct perf_event *event; |
926 | int n, max_count; | 1976 | int n, max_count; |
@@ -952,8 +2002,7 @@ static int uncore_collect_events(struct intel_uncore_box *box, | |||
952 | } | 2002 | } |
953 | 2003 | ||
954 | static struct event_constraint * | 2004 | static struct event_constraint * |
955 | uncore_get_event_constraint(struct intel_uncore_box *box, | 2005 | uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event) |
956 | struct perf_event *event) | ||
957 | { | 2006 | { |
958 | struct intel_uncore_type *type = box->pmu->type; | 2007 | struct intel_uncore_type *type = box->pmu->type; |
959 | struct event_constraint *c; | 2008 | struct event_constraint *c; |
@@ -977,15 +2026,13 @@ uncore_get_event_constraint(struct intel_uncore_box *box, | |||
977 | return &type->unconstrainted; | 2026 | return &type->unconstrainted; |
978 | } | 2027 | } |
979 | 2028 | ||
980 | static void uncore_put_event_constraint(struct intel_uncore_box *box, | 2029 | static void uncore_put_event_constraint(struct intel_uncore_box *box, struct perf_event *event) |
981 | struct perf_event *event) | ||
982 | { | 2030 | { |
983 | if (box->pmu->type->ops->put_constraint) | 2031 | if (box->pmu->type->ops->put_constraint) |
984 | box->pmu->type->ops->put_constraint(box, event); | 2032 | box->pmu->type->ops->put_constraint(box, event); |
985 | } | 2033 | } |
986 | 2034 | ||
987 | static int uncore_assign_events(struct intel_uncore_box *box, | 2035 | static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n) |
988 | int assign[], int n) | ||
989 | { | 2036 | { |
990 | unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; | 2037 | unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; |
991 | struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; | 2038 | struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; |
@@ -1407,8 +2454,7 @@ static bool pcidrv_registered; | |||
1407 | /* | 2454 | /* |
1408 | * add a pci uncore device | 2455 | * add a pci uncore device |
1409 | */ | 2456 | */ |
1410 | static int __devinit uncore_pci_add(struct intel_uncore_type *type, | 2457 | static int __devinit uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) |
1411 | struct pci_dev *pdev) | ||
1412 | { | 2458 | { |
1413 | struct intel_uncore_pmu *pmu; | 2459 | struct intel_uncore_pmu *pmu; |
1414 | struct intel_uncore_box *box; | 2460 | struct intel_uncore_box *box; |
@@ -1485,6 +2531,7 @@ static int __devinit uncore_pci_probe(struct pci_dev *pdev, | |||
1485 | struct intel_uncore_type *type; | 2531 | struct intel_uncore_type *type; |
1486 | 2532 | ||
1487 | type = (struct intel_uncore_type *)id->driver_data; | 2533 | type = (struct intel_uncore_type *)id->driver_data; |
2534 | |||
1488 | return uncore_pci_add(type, pdev); | 2535 | return uncore_pci_add(type, pdev); |
1489 | } | 2536 | } |
1490 | 2537 | ||
@@ -1612,8 +2659,8 @@ static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id) | |||
1612 | return 0; | 2659 | return 0; |
1613 | } | 2660 | } |
1614 | 2661 | ||
1615 | static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores, | 2662 | static void __cpuinit |
1616 | int old_cpu, int new_cpu) | 2663 | uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu) |
1617 | { | 2664 | { |
1618 | struct intel_uncore_type *type; | 2665 | struct intel_uncore_type *type; |
1619 | struct intel_uncore_pmu *pmu; | 2666 | struct intel_uncore_pmu *pmu; |
@@ -1694,8 +2741,8 @@ static void __cpuinit uncore_event_init_cpu(int cpu) | |||
1694 | uncore_change_context(pci_uncores, -1, cpu); | 2741 | uncore_change_context(pci_uncores, -1, cpu); |
1695 | } | 2742 | } |
1696 | 2743 | ||
1697 | static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, | 2744 | static int |
1698 | unsigned long action, void *hcpu) | 2745 | __cpuinit uncore_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) |
1699 | { | 2746 | { |
1700 | unsigned int cpu = (long)hcpu; | 2747 | unsigned int cpu = (long)hcpu; |
1701 | 2748 | ||
@@ -1732,12 +2779,12 @@ static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, | |||
1732 | } | 2779 | } |
1733 | 2780 | ||
1734 | static struct notifier_block uncore_cpu_nb __cpuinitdata = { | 2781 | static struct notifier_block uncore_cpu_nb __cpuinitdata = { |
1735 | .notifier_call = uncore_cpu_notifier, | 2782 | .notifier_call = uncore_cpu_notifier, |
1736 | /* | 2783 | /* |
1737 | * to migrate uncore events, our notifier should be executed | 2784 | * to migrate uncore events, our notifier should be executed |
1738 | * before perf core's notifier. | 2785 | * before perf core's notifier. |
1739 | */ | 2786 | */ |
1740 | .priority = CPU_PRI_PERF + 1, | 2787 | .priority = CPU_PRI_PERF + 1, |
1741 | }; | 2788 | }; |
1742 | 2789 | ||
1743 | static void __init uncore_cpu_setup(void *dummy) | 2790 | static void __init uncore_cpu_setup(void *dummy) |
@@ -1767,6 +2814,9 @@ static int __init uncore_cpu_init(void) | |||
1767 | snbep_uncore_cbox.num_boxes = max_cores; | 2814 | snbep_uncore_cbox.num_boxes = max_cores; |
1768 | msr_uncores = snbep_msr_uncores; | 2815 | msr_uncores = snbep_msr_uncores; |
1769 | break; | 2816 | break; |
2817 | case 46: | ||
2818 | msr_uncores = nhmex_msr_uncores; | ||
2819 | break; | ||
1770 | default: | 2820 | default: |
1771 | return 0; | 2821 | return 0; |
1772 | } | 2822 | } |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index b13e9ea81def..f3851892e077 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
@@ -5,8 +5,6 @@ | |||
5 | #include "perf_event.h" | 5 | #include "perf_event.h" |
6 | 6 | ||
7 | #define UNCORE_PMU_NAME_LEN 32 | 7 | #define UNCORE_PMU_NAME_LEN 32 |
8 | #define UNCORE_BOX_HASH_SIZE 8 | ||
9 | |||
10 | #define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) | 8 | #define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) |
11 | 9 | ||
12 | #define UNCORE_FIXED_EVENT 0xff | 10 | #define UNCORE_FIXED_EVENT 0xff |
@@ -115,6 +113,10 @@ | |||
115 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ | 113 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ |
116 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) | 114 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) |
117 | 115 | ||
116 | #define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK \ | ||
117 | (SNBEP_PMON_RAW_EVENT_MASK | \ | ||
118 | SNBEP_PMON_CTL_EV_SEL_EXT) | ||
119 | |||
118 | /* SNB-EP pci control register */ | 120 | /* SNB-EP pci control register */ |
119 | #define SNBEP_PCI_PMON_BOX_CTL 0xf4 | 121 | #define SNBEP_PCI_PMON_BOX_CTL 0xf4 |
120 | #define SNBEP_PCI_PMON_CTL0 0xd8 | 122 | #define SNBEP_PCI_PMON_CTL0 0xd8 |
@@ -158,6 +160,193 @@ | |||
158 | #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc | 160 | #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc |
159 | #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd | 161 | #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd |
160 | 162 | ||
163 | /* NHM-EX event control */ | ||
164 | #define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff | ||
165 | #define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00 | ||
166 | #define NHMEX_PMON_CTL_EN_BIT0 (1 << 0) | ||
167 | #define NHMEX_PMON_CTL_EDGE_DET (1 << 18) | ||
168 | #define NHMEX_PMON_CTL_PMI_EN (1 << 20) | ||
169 | #define NHMEX_PMON_CTL_EN_BIT22 (1 << 22) | ||
170 | #define NHMEX_PMON_CTL_INVERT (1 << 23) | ||
171 | #define NHMEX_PMON_CTL_TRESH_MASK 0xff000000 | ||
172 | #define NHMEX_PMON_RAW_EVENT_MASK (NHMEX_PMON_CTL_EV_SEL_MASK | \ | ||
173 | NHMEX_PMON_CTL_UMASK_MASK | \ | ||
174 | NHMEX_PMON_CTL_EDGE_DET | \ | ||
175 | NHMEX_PMON_CTL_INVERT | \ | ||
176 | NHMEX_PMON_CTL_TRESH_MASK) | ||
177 | |||
178 | /* NHM-EX Ubox */ | ||
179 | #define NHMEX_U_MSR_PMON_GLOBAL_CTL 0xc00 | ||
180 | #define NHMEX_U_MSR_PMON_CTR 0xc11 | ||
181 | #define NHMEX_U_MSR_PMON_EV_SEL 0xc10 | ||
182 | |||
183 | #define NHMEX_U_PMON_GLOBAL_EN (1 << 0) | ||
184 | #define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL 0x0000001e | ||
185 | #define NHMEX_U_PMON_GLOBAL_EN_ALL (1 << 28) | ||
186 | #define NHMEX_U_PMON_GLOBAL_RST_ALL (1 << 29) | ||
187 | #define NHMEX_U_PMON_GLOBAL_FRZ_ALL (1 << 31) | ||
188 | |||
189 | #define NHMEX_U_PMON_RAW_EVENT_MASK \ | ||
190 | (NHMEX_PMON_CTL_EV_SEL_MASK | \ | ||
191 | NHMEX_PMON_CTL_EDGE_DET) | ||
192 | |||
193 | /* NHM-EX Cbox */ | ||
194 | #define NHMEX_C0_MSR_PMON_GLOBAL_CTL 0xd00 | ||
195 | #define NHMEX_C0_MSR_PMON_CTR0 0xd11 | ||
196 | #define NHMEX_C0_MSR_PMON_EV_SEL0 0xd10 | ||
197 | #define NHMEX_C_MSR_OFFSET 0x20 | ||
198 | |||
199 | /* NHM-EX Bbox */ | ||
200 | #define NHMEX_B0_MSR_PMON_GLOBAL_CTL 0xc20 | ||
201 | #define NHMEX_B0_MSR_PMON_CTR0 0xc31 | ||
202 | #define NHMEX_B0_MSR_PMON_CTL0 0xc30 | ||
203 | #define NHMEX_B_MSR_OFFSET 0x40 | ||
204 | #define NHMEX_B0_MSR_MATCH 0xe45 | ||
205 | #define NHMEX_B0_MSR_MASK 0xe46 | ||
206 | #define NHMEX_B1_MSR_MATCH 0xe4d | ||
207 | #define NHMEX_B1_MSR_MASK 0xe4e | ||
208 | |||
209 | #define NHMEX_B_PMON_CTL_EN (1 << 0) | ||
210 | #define NHMEX_B_PMON_CTL_EV_SEL_SHIFT 1 | ||
211 | #define NHMEX_B_PMON_CTL_EV_SEL_MASK \ | ||
212 | (0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT) | ||
213 | #define NHMEX_B_PMON_CTR_SHIFT 6 | ||
214 | #define NHMEX_B_PMON_CTR_MASK \ | ||
215 | (0x3 << NHMEX_B_PMON_CTR_SHIFT) | ||
216 | #define NHMEX_B_PMON_RAW_EVENT_MASK \ | ||
217 | (NHMEX_B_PMON_CTL_EV_SEL_MASK | \ | ||
218 | NHMEX_B_PMON_CTR_MASK) | ||
219 | |||
220 | /* NHM-EX Sbox */ | ||
221 | #define NHMEX_S0_MSR_PMON_GLOBAL_CTL 0xc40 | ||
222 | #define NHMEX_S0_MSR_PMON_CTR0 0xc51 | ||
223 | #define NHMEX_S0_MSR_PMON_CTL0 0xc50 | ||
224 | #define NHMEX_S_MSR_OFFSET 0x80 | ||
225 | #define NHMEX_S0_MSR_MM_CFG 0xe48 | ||
226 | #define NHMEX_S0_MSR_MATCH 0xe49 | ||
227 | #define NHMEX_S0_MSR_MASK 0xe4a | ||
228 | #define NHMEX_S1_MSR_MM_CFG 0xe58 | ||
229 | #define NHMEX_S1_MSR_MATCH 0xe59 | ||
230 | #define NHMEX_S1_MSR_MASK 0xe5a | ||
231 | |||
232 | #define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) | ||
233 | |||
234 | /* NHM-EX Mbox */ | ||
235 | #define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 | ||
236 | #define NHMEX_M0_MSR_PMU_DSP 0xca5 | ||
237 | #define NHMEX_M0_MSR_PMU_ISS 0xca6 | ||
238 | #define NHMEX_M0_MSR_PMU_MAP 0xca7 | ||
239 | #define NHMEX_M0_MSR_PMU_MSC_THR 0xca8 | ||
240 | #define NHMEX_M0_MSR_PMU_PGT 0xca9 | ||
241 | #define NHMEX_M0_MSR_PMU_PLD 0xcaa | ||
242 | #define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC 0xcab | ||
243 | #define NHMEX_M0_MSR_PMU_CTL0 0xcb0 | ||
244 | #define NHMEX_M0_MSR_PMU_CNT0 0xcb1 | ||
245 | #define NHMEX_M_MSR_OFFSET 0x40 | ||
246 | #define NHMEX_M0_MSR_PMU_MM_CFG 0xe54 | ||
247 | #define NHMEX_M1_MSR_PMU_MM_CFG 0xe5c | ||
248 | |||
249 | #define NHMEX_M_PMON_MM_CFG_EN (1ULL << 63) | ||
250 | #define NHMEX_M_PMON_ADDR_MATCH_MASK 0x3ffffffffULL | ||
251 | #define NHMEX_M_PMON_ADDR_MASK_MASK 0x7ffffffULL | ||
252 | #define NHMEX_M_PMON_ADDR_MASK_SHIFT 34 | ||
253 | |||
254 | #define NHMEX_M_PMON_CTL_EN (1 << 0) | ||
255 | #define NHMEX_M_PMON_CTL_PMI_EN (1 << 1) | ||
256 | #define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT 2 | ||
257 | #define NHMEX_M_PMON_CTL_COUNT_MODE_MASK \ | ||
258 | (0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT) | ||
259 | #define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT 4 | ||
260 | #define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK \ | ||
261 | (0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT) | ||
262 | #define NHMEX_M_PMON_CTL_WRAP_MODE (1 << 6) | ||
263 | #define NHMEX_M_PMON_CTL_FLAG_MODE (1 << 7) | ||
264 | #define NHMEX_M_PMON_CTL_INC_SEL_SHIFT 9 | ||
265 | #define NHMEX_M_PMON_CTL_INC_SEL_MASK \ | ||
266 | (0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) | ||
267 | #define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT 19 | ||
268 | #define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK \ | ||
269 | (0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | ||
270 | #define NHMEX_M_PMON_RAW_EVENT_MASK \ | ||
271 | (NHMEX_M_PMON_CTL_COUNT_MODE_MASK | \ | ||
272 | NHMEX_M_PMON_CTL_STORAGE_MODE_MASK | \ | ||
273 | NHMEX_M_PMON_CTL_WRAP_MODE | \ | ||
274 | NHMEX_M_PMON_CTL_FLAG_MODE | \ | ||
275 | NHMEX_M_PMON_CTL_INC_SEL_MASK | \ | ||
276 | NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) | ||
277 | |||
278 | |||
279 | #define NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK 0x1f | ||
280 | #define NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK (0x7 << 5) | ||
281 | #define NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK (0x7 << 8) | ||
282 | #define NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR (1 << 23) | ||
283 | #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK \ | ||
284 | (NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK | \ | ||
285 | NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK | \ | ||
286 | NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK | \ | ||
287 | NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR) | ||
288 | #define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n))) | ||
289 | |||
290 | /* | ||
291 | * use the 9~13 bits to select event If the 7th bit is not set, | ||
292 | * otherwise use the 19~21 bits to select event. | ||
293 | */ | ||
294 | #define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) | ||
295 | #define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \ | ||
296 | NHMEX_M_PMON_CTL_FLAG_MODE) | ||
297 | #define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \ | ||
298 | NHMEX_M_PMON_CTL_FLAG_MODE) | ||
299 | #define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \ | ||
300 | NHMEX_M_PMON_CTL_FLAG_MODE) | ||
301 | #define MBOX_INC_SEL_EXTAR_REG(c, r) \ | ||
302 | EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \ | ||
303 | MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r) | ||
304 | #define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \ | ||
305 | EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \ | ||
306 | MBOX_SET_FLAG_SEL_MASK, \ | ||
307 | (u64)-1, NHMEX_M_##r) | ||
308 | |||
309 | /* NHM-EX Rbox */ | ||
310 | #define NHMEX_R_MSR_GLOBAL_CTL 0xe00 | ||
311 | #define NHMEX_R_MSR_PMON_CTL0 0xe10 | ||
312 | #define NHMEX_R_MSR_PMON_CNT0 0xe11 | ||
313 | #define NHMEX_R_MSR_OFFSET 0x20 | ||
314 | |||
315 | #define NHMEX_R_MSR_PORTN_QLX_CFG(n) \ | ||
316 | ((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4)) | ||
317 | #define NHMEX_R_MSR_PORTN_IPERF_CFG0(n) (0xe04 + (n)) | ||
318 | #define NHMEX_R_MSR_PORTN_IPERF_CFG1(n) (0xe24 + (n)) | ||
319 | #define NHMEX_R_MSR_PORTN_XBR_OFFSET(n) \ | ||
320 | (((n) < 4 ? 0 : 0x10) + (n) * 4) | ||
321 | #define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) \ | ||
322 | (0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) | ||
323 | #define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n) \ | ||
324 | (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1) | ||
325 | #define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n) \ | ||
326 | (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2) | ||
327 | #define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) \ | ||
328 | (0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) | ||
329 | #define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n) \ | ||
330 | (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1) | ||
331 | #define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n) \ | ||
332 | (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2) | ||
333 | |||
334 | #define NHMEX_R_PMON_CTL_EN (1 << 0) | ||
335 | #define NHMEX_R_PMON_CTL_EV_SEL_SHIFT 1 | ||
336 | #define NHMEX_R_PMON_CTL_EV_SEL_MASK \ | ||
337 | (0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT) | ||
338 | #define NHMEX_R_PMON_CTL_PMI_EN (1 << 6) | ||
339 | #define NHMEX_R_PMON_RAW_EVENT_MASK NHMEX_R_PMON_CTL_EV_SEL_MASK | ||
340 | |||
341 | /* NHM-EX Wbox */ | ||
342 | #define NHMEX_W_MSR_GLOBAL_CTL 0xc80 | ||
343 | #define NHMEX_W_MSR_PMON_CNT0 0xc90 | ||
344 | #define NHMEX_W_MSR_PMON_EVT_SEL0 0xc91 | ||
345 | #define NHMEX_W_MSR_PMON_FIXED_CTR 0x394 | ||
346 | #define NHMEX_W_MSR_PMON_FIXED_CTL 0x395 | ||
347 | |||
348 | #define NHMEX_W_PMON_GLOBAL_FIXED_EN (1ULL << 31) | ||
349 | |||
161 | struct intel_uncore_ops; | 350 | struct intel_uncore_ops; |
162 | struct intel_uncore_pmu; | 351 | struct intel_uncore_pmu; |
163 | struct intel_uncore_box; | 352 | struct intel_uncore_box; |
@@ -178,6 +367,7 @@ struct intel_uncore_type { | |||
178 | unsigned msr_offset; | 367 | unsigned msr_offset; |
179 | unsigned num_shared_regs:8; | 368 | unsigned num_shared_regs:8; |
180 | unsigned single_fixed:1; | 369 | unsigned single_fixed:1; |
370 | unsigned pair_ctr_ctl:1; | ||
181 | struct event_constraint unconstrainted; | 371 | struct event_constraint unconstrainted; |
182 | struct event_constraint *constraints; | 372 | struct event_constraint *constraints; |
183 | struct intel_uncore_pmu *pmus; | 373 | struct intel_uncore_pmu *pmus; |
@@ -213,7 +403,7 @@ struct intel_uncore_pmu { | |||
213 | 403 | ||
214 | struct intel_uncore_extra_reg { | 404 | struct intel_uncore_extra_reg { |
215 | raw_spinlock_t lock; | 405 | raw_spinlock_t lock; |
216 | u64 config1; | 406 | u64 config, config1, config2; |
217 | atomic_t ref; | 407 | atomic_t ref; |
218 | }; | 408 | }; |
219 | 409 | ||
@@ -323,14 +513,16 @@ unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) | |||
323 | static inline | 513 | static inline |
324 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) | 514 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) |
325 | { | 515 | { |
326 | return idx + box->pmu->type->event_ctl + | 516 | return box->pmu->type->event_ctl + |
517 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | ||
327 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 518 | box->pmu->type->msr_offset * box->pmu->pmu_idx; |
328 | } | 519 | } |
329 | 520 | ||
330 | static inline | 521 | static inline |
331 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) | 522 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) |
332 | { | 523 | { |
333 | return idx + box->pmu->type->perf_ctr + | 524 | return box->pmu->type->perf_ctr + |
525 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | ||
334 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 526 | box->pmu->type->msr_offset * box->pmu->pmu_idx; |
335 | } | 527 | } |
336 | 528 | ||
@@ -422,3 +614,8 @@ static inline void uncore_box_init(struct intel_uncore_box *box) | |||
422 | box->pmu->type->ops->init_box(box); | 614 | box->pmu->type->ops->init_box(box); |
423 | } | 615 | } |
424 | } | 616 | } |
617 | |||
618 | static inline bool uncore_box_is_fake(struct intel_uncore_box *box) | ||
619 | { | ||
620 | return (box->phys_id < 0); | ||
621 | } | ||
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h index 950dfb7b8417..e72cd0df5ba3 100644 --- a/arch/x86/um/asm/ptrace.h +++ b/arch/x86/um/asm/ptrace.h | |||
@@ -30,10 +30,10 @@ | |||
30 | #define profile_pc(regs) PT_REGS_IP(regs) | 30 | #define profile_pc(regs) PT_REGS_IP(regs) |
31 | 31 | ||
32 | #define UPT_RESTART_SYSCALL(r) (UPT_IP(r) -= 2) | 32 | #define UPT_RESTART_SYSCALL(r) (UPT_IP(r) -= 2) |
33 | #define UPT_SET_SYSCALL_RETURN(r, res) (UPT_AX(r) = (res)) | 33 | #define PT_REGS_SET_SYSCALL_RETURN(r, res) (PT_REGS_AX(r) = (res)) |
34 | 34 | ||
35 | static inline long regs_return_value(struct uml_pt_regs *regs) | 35 | static inline long regs_return_value(struct pt_regs *regs) |
36 | { | 36 | { |
37 | return UPT_AX(regs); | 37 | return PT_REGS_AX(regs); |
38 | } | 38 | } |
39 | #endif /* __UM_X86_PTRACE_H */ | 39 | #endif /* __UM_X86_PTRACE_H */ |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 8a3f8351f438..8ed64cfae4ff 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -7,6 +7,7 @@ config ZONE_DMA | |||
7 | config XTENSA | 7 | config XTENSA |
8 | def_bool y | 8 | def_bool y |
9 | select HAVE_IDE | 9 | select HAVE_IDE |
10 | select GENERIC_ATOMIC64 | ||
10 | select HAVE_GENERIC_HARDIRQS | 11 | select HAVE_GENERIC_HARDIRQS |
11 | select GENERIC_IRQ_SHOW | 12 | select GENERIC_IRQ_SHOW |
12 | select GENERIC_CPU_DEVICES | 13 | select GENERIC_CPU_DEVICES |