aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 14:34:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 14:34:32 -0400
commit10c8e0562057b5d64ea170feab148e1550420030 (patch)
treecfd387208c85e893c93d24e324d147eb6e9abfc9
parentd4e1f5a14e17d4f0e8034c0967511884bcb12fba (diff)
parent3e528cb7bae00ba0d73def6645d0f2fa906ee3e8 (diff)
Merge tag 'drivers-for-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver changes from Olof Johansson: "A handful of driver-related changes. We've had a bunch of them going in through other branches as well, so it's only a part of what we really have this release. Larger pieces are: - Removal of a now unused PWM driver for atmel [ This includes AVR32 changes that have been appropriately acked ] - Performance counter support for the arm CCN interconnect - OMAP mailbox driver cleanups and consolidation - PCI and SATA PHY drivers for SPEAr 13xx platforms - Redefinition (with backwards compatibility!) of PCI DT bindings for Tegra to better model regulators/power" Note: this merge also fixes up the semantic conflict with the new calling convention for devm_phy_create(), see commit f0ed817638b5 ("phy: core: Let node ptr of PHY point to PHY and not of PHY provider") that came in through Greg's USB tree. Semantic merge patch by Stephen Rothwell <sfr@canb.auug.org.au> through the next tree. * tag 'drivers-for-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (38 commits) bus: arm-ccn: Fix error handling at event allocation mailbox/omap: add a parent structure for every IP instance mailbox/omap: remove the private mailbox structure mailbox/omap: consolidate OMAP mailbox driver mailbox/omap: simplify the fifo assignment by using macros mailbox/omap: remove omap_mbox_type_t from mailbox ops mailbox/omap: remove OMAP1 mailbox driver mailbox/omap: use devm_* interfaces bus: ARM CCN: add PERF_EVENTS dependency bus: ARM CCN PMU driver PCI: spear: Remove spear13xx_pcie_remove() PCI: spear: Fix Section mismatch compilation warning for probe() ARM: tegra: Remove legacy PCIe power supply properties PCI: tegra: Remove deprecated power supply properties PCI: tegra: Implement accurate power supply scheme ARM: SPEAr13xx: Update defconfigs ARM: SPEAr13xx: Add pcie and miphy DT nodes ARM: SPEAr13xx: Add bindings and dt node for misc block ARM: SPEAr13xx: Fix static mapping table phy: Add drivers for PCIe and SATA phy on SPEAr13xx ...
-rw-r--r--Documentation/arm/CCN.txt52
-rw-r--r--Documentation/devicetree/bindings/arm/ccn.txt21
-rw-r--r--Documentation/devicetree/bindings/arm/spear-misc.txt9
-rw-r--r--Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt30
-rw-r--r--Documentation/devicetree/bindings/pci/spear13xx-pcie.txt14
-rw-r--r--Documentation/devicetree/bindings/phy/st-spear-miphy.txt15
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/boot/dts/spear1310-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear1310.dtsi93
-rw-r--r--arch/arm/boot/dts/spear1340-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear1340.dtsi30
-rw-r--r--arch/arm/boot/dts/spear13xx.dtsi9
-rw-r--r--arch/arm/boot/dts/tegra20-harmony.dts8
-rw-r--r--arch/arm/boot/dts/tegra20-tamonten.dtsi7
-rw-r--r--arch/arm/boot/dts/tegra20-trimslice.dts8
-rw-r--r--arch/arm/boot/dts/tegra30-beaver.dts12
-rw-r--r--arch/arm/boot/dts/tegra30-cardhu.dtsi11
-rw-r--r--arch/arm/configs/omap1_defconfig2
-rw-r--r--arch/arm/configs/spear13xx_defconfig16
-rw-r--r--arch/arm/mach-at91/at91sam9263.c1
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c11
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c1
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c11
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c1
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c11
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c55
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c42
-rw-r--r--arch/arm/mach-at91/board.h1
-rw-r--r--arch/arm/mach-at91/leds.c37
-rw-r--r--arch/arm/mach-spear/Kconfig4
-rw-r--r--arch/arm/mach-spear/include/mach/spear.h4
-rw-r--r--arch/arm/mach-spear/spear1340.c125
-rw-r--r--arch/arm/mach-spear/spear13xx.c2
-rw-r--r--arch/avr32/boards/atngw100/mrmt.c34
-rw-r--r--arch/avr32/boards/favr-32/setup.c48
-rw-r--r--arch/avr32/boards/merisc/setup.c34
-rw-r--r--arch/avr32/configs/atngw100_mrmt_defconfig5
-rw-r--r--arch/avr32/configs/atstk1002_defconfig5
-rw-r--r--arch/avr32/configs/atstk1003_defconfig5
-rw-r--r--arch/avr32/configs/atstk1004_defconfig5
-rw-r--r--arch/avr32/configs/atstk1006_defconfig5
-rw-r--r--arch/avr32/configs/favr-32_defconfig6
-rw-r--r--arch/avr32/configs/merisc_defconfig5
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c7
-rw-r--r--drivers/bus/Kconfig8
-rw-r--r--drivers/bus/Makefile4
-rw-r--r--drivers/bus/arm-ccn.c1391
-rw-r--r--drivers/leds/Kconfig8
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-atmel-pwm.c149
-rw-r--r--drivers/mailbox/Kconfig19
-rw-r--r--drivers/mailbox/Makefile6
-rw-r--r--drivers/mailbox/mailbox-omap1.c203
-rw-r--r--drivers/mailbox/mailbox-omap2.c357
-rw-r--r--drivers/mailbox/omap-mailbox.c444
-rw-r--r--drivers/mailbox/omap-mbox.h67
-rw-r--r--drivers/misc/Kconfig10
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/atmel_pwm.c402
-rw-r--r--drivers/pci/host/Kconfig8
-rw-r--r--drivers/pci/host/Makefile1
-rw-r--r--drivers/pci/host/pci-tegra.c222
-rw-r--r--drivers/pci/host/pcie-spear13xx.c393
-rw-r--r--drivers/phy/Kconfig26
-rw-r--r--drivers/phy/Makefile4
-rw-r--r--drivers/phy/phy-spear1310-miphy.c274
-rw-r--r--drivers/phy/phy-spear1340-miphy.c307
-rw-r--r--drivers/pinctrl/pinctrl-tegra-xusb.c4
-rw-r--r--drivers/pwm/Kconfig2
-rw-r--r--drivers/video/backlight/Kconfig11
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c223
-rw-r--r--include/linux/atmel-pwm-bl.h43
-rw-r--r--include/linux/atmel_pwm.h70
74 files changed, 3452 insertions, 2023 deletions
diff --git a/Documentation/arm/CCN.txt b/Documentation/arm/CCN.txt
new file mode 100644
index 000000000000..0632b3aad83e
--- /dev/null
+++ b/Documentation/arm/CCN.txt
@@ -0,0 +1,52 @@
1ARM Cache Coherent Network
2==========================
3
4CCN-504 is a ring-bus interconnect consisting of 11 crosspoints
5(XPs), with each crosspoint supporting up to two device ports,
6so nodes (devices) 0 and 1 are connected to crosspoint 0,
7nodes 2 and 3 to crosspoint 1 etc.
8
9PMU (perf) driver
10-----------------
11
12The CCN driver registers a perf PMU driver, which provides
13description of available events and configuration options
14in sysfs, see /sys/bus/event_source/devices/ccn*.
15
16The "format" directory describes format of the config, config1
17and config2 fields of the perf_event_attr structure. The "events"
18directory provides configuration templates for all documented
19events, that can be used with perf tool. For example "xp_valid_flit"
20is an equivalent of "type=0x8,event=0x4". Other parameters must be
21explicitly specified. For events originating from device, "node"
22defines its index. All crosspoint events require "xp" (index),
23"port" (device port number) and "vc" (virtual channel ID) and
24"dir" (direction). Watchpoints (special "event" value 0xfe) also
25require comparator values ("cmp_l" and "cmp_h") and "mask", being
26index of the comparator mask.
27
28Masks are defined separately from the event description
29(due to limited number of the config values) in the "cmp_mask"
30directory, with first 8 configurable by user and additional
314 hardcoded for the most frequent use cases.
32
33Cycle counter is described by a "type" value 0xff and does
34not require any other settings.
35
36Example of perf tool use:
37
38/ # perf list | grep ccn
39 ccn/cycles/ [Kernel PMU event]
40<...>
41 ccn/xp_valid_flit/ [Kernel PMU event]
42<...>
43
44/ # perf stat -C 0 -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
45 sleep 1
46
47The driver does not support sampling, therefore "perf record" will
48not work. Also notice that only single cpu is being selected
49("-C 0") - this is because perf framework does not support
50"non-CPU related" counters (yet?) so system-wide session ("-a")
51would try (and in most cases fail) to set up the same event
52per each CPU.
diff --git a/Documentation/devicetree/bindings/arm/ccn.txt b/Documentation/devicetree/bindings/arm/ccn.txt
new file mode 100644
index 000000000000..b100d3847d88
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/ccn.txt
@@ -0,0 +1,21 @@
1* ARM CCN (Cache Coherent Network)
2
3Required properties:
4
5- compatible: (standard compatible string) should be one of:
6 "arm,ccn-504"
7 "arm,ccn-508"
8
9- reg: (standard registers property) physical address and size
10 (16MB) of the configuration registers block
11
12- interrupts: (standard interrupt property) single interrupt
13 generated by the control block
14
15Example:
16
17 ccn@0x2000000000 {
18 compatible = "arm,ccn-504";
19 reg = <0x20 0x00000000 0 0x1000000>;
20 interrupts = <0 181 4>;
21 };
diff --git a/Documentation/devicetree/bindings/arm/spear-misc.txt b/Documentation/devicetree/bindings/arm/spear-misc.txt
new file mode 100644
index 000000000000..cf649827ffcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/spear-misc.txt
@@ -0,0 +1,9 @@
1SPEAr Misc configuration
2===========================
3SPEAr SOCs have some miscellaneous registers which are used to configure
4few properties of different peripheral controllers.
5
6misc node required properties:
7
8- compatible Should be "st,spear1340-misc", "syscon".
9- reg: Address range of misc space upto 8K
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
index c300391e8d3e..0823362548dc 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
@@ -14,9 +14,6 @@ Required properties:
14- interrupt-names: Must include the following entries: 14- interrupt-names: Must include the following entries:
15 "intr": The Tegra interrupt that is asserted for controller interrupts 15 "intr": The Tegra interrupt that is asserted for controller interrupts
16 "msi": The Tegra interrupt that is asserted when an MSI is received 16 "msi": The Tegra interrupt that is asserted when an MSI is received
17- pex-clk-supply: Supply voltage for internal reference clock
18- vdd-supply: Power supply for controller (1.05V)
19- avdd-supply: Power supply for controller (1.05V) (not required for Tegra20)
20- bus-range: Range of bus numbers associated with this controller 17- bus-range: Range of bus numbers associated with this controller
21- #address-cells: Address representation for root ports (must be 3) 18- #address-cells: Address representation for root ports (must be 3)
22 - cell 0 specifies the bus and device numbers of the root port: 19 - cell 0 specifies the bus and device numbers of the root port:
@@ -60,6 +57,33 @@ Required properties:
60 - afi 57 - afi
61 - pcie_x 58 - pcie_x
62 59
60Power supplies for Tegra20:
61- avdd-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
62- vdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
63- avdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
64 supply 1.05 V.
65- avdd-plle-supply: Power supply for PLLE, which is shared with SATA. Must
66 supply 1.05 V.
67- vddio-pex-clk-supply: Power supply for PCIe clock. Must supply 3.3 V.
68
69Power supplies for Tegra30:
70- Required:
71 - avdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
72 supply 1.05 V.
73 - avdd-plle-supply: Power supply for PLLE, which is shared with SATA. Must
74 supply 1.05 V.
75 - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
76 supply 1.8 V.
77 - hvdd-pex-supply: High-voltage supply for PCIe I/O and PCIe output clocks.
78 Must supply 3.3 V.
79- Optional:
80 - If lanes 0 to 3 are used:
81 - avdd-pexa-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
82 - vdd-pexa-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
83 - If lanes 4 or 5 are used:
84 - avdd-pexb-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
85 - vdd-pexb-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
86
63Root ports are defined as subnodes of the PCIe controller node. 87Root ports are defined as subnodes of the PCIe controller node.
64 88
65Required properties: 89Required properties:
diff --git a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt
new file mode 100644
index 000000000000..49ea76da7718
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt
@@ -0,0 +1,14 @@
1SPEAr13XX PCIe DT detail:
2================================
3
4SPEAr13XX uses synopsis designware PCIe controller and ST MiPHY as phy
5controller.
6
7Required properties:
8- compatible : should be "st,spear1340-pcie", "snps,dw-pcie".
9- phys : phandle to phy node associated with pcie controller
10- phy-names : must be "pcie-phy"
11- All other definitions as per generic PCI bindings
12
13 Optional properties:
14- st,pcie-is-gen1 indicates that forced gen1 initialization is needed.
diff --git a/Documentation/devicetree/bindings/phy/st-spear-miphy.txt b/Documentation/devicetree/bindings/phy/st-spear-miphy.txt
new file mode 100644
index 000000000000..2a6bfdcc09b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/st-spear-miphy.txt
@@ -0,0 +1,15 @@
1ST SPEAr miphy DT details
2=========================
3
4ST Microelectronics SPEAr miphy is a phy controller supporting PCIe and SATA.
5
6Required properties:
7- compatible : should be "st,spear1310-miphy" or "st,spear1340-miphy"
8- reg : offset and length of the PHY register set.
9- misc: phandle for the syscon node to access misc registers
10- #phy-cells : from the generic PHY bindings, must be 1.
11 - cell[1]: 0 if phy used for SATA, 1 for PCIe.
12
13Optional properties:
14- phy-id: Instance id of the phy. Only required when there are multiple phys
15 present on a implementation.
diff --git a/MAINTAINERS b/MAINTAINERS
index 20cd746d1933..e065c3881626 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6902,6 +6902,12 @@ S: Maintained
6902F: Documentation/devicetree/bindings/pci/host-generic-pci.txt 6902F: Documentation/devicetree/bindings/pci/host-generic-pci.txt
6903F: drivers/pci/host/pci-host-generic.c 6903F: drivers/pci/host/pci-host-generic.c
6904 6904
6905PCIE DRIVER FOR ST SPEAR13XX
6906M: Mohit Kumar <mohit.kumar@st.com>
6907L: linux-pci@vger.kernel.org
6908S: Maintained
6909F: drivers/pci/host/*spear*
6910
6905PCMCIA SUBSYSTEM 6911PCMCIA SUBSYSTEM
6906P: Linux PCMCIA Team 6912P: Linux PCMCIA Team
6907L: linux-pcmcia@lists.infradead.org 6913L: linux-pcmcia@lists.infradead.org
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
index b56a801e42a2..d42c84b1df8d 100644
--- a/arch/arm/boot/dts/spear1310-evb.dts
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -106,6 +106,10 @@
106 status = "okay"; 106 status = "okay";
107 }; 107 };
108 108
109 miphy@eb800000 {
110 status = "okay";
111 };
112
109 cf@b2800000 { 113 cf@b2800000 {
110 status = "okay"; 114 status = "okay";
111 }; 115 };
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
index 122ae94076c8..fa5f2bb5f106 100644
--- a/arch/arm/boot/dts/spear1310.dtsi
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -29,24 +29,111 @@
29 #gpio-cells = <2>; 29 #gpio-cells = <2>;
30 }; 30 };
31 31
32 ahci@b1000000 { 32 miphy0: miphy@eb800000 {
33 compatible = "st,spear1310-miphy";
34 reg = <0xeb800000 0x4000>;
35 misc = <&misc>;
36 phy-id = <0>;
37 #phy-cells = <1>;
38 status = "disabled";
39 };
40
41 miphy1: miphy@eb804000 {
42 compatible = "st,spear1310-miphy";
43 reg = <0xeb804000 0x4000>;
44 misc = <&misc>;
45 phy-id = <1>;
46 #phy-cells = <1>;
47 status = "disabled";
48 };
49
50 miphy2: miphy@eb808000 {
51 compatible = "st,spear1310-miphy";
52 reg = <0xeb808000 0x4000>;
53 misc = <&misc>;
54 phy-id = <2>;
55 #phy-cells = <1>;
56 status = "disabled";
57 };
58
59 ahci0: ahci@b1000000 {
33 compatible = "snps,spear-ahci"; 60 compatible = "snps,spear-ahci";
34 reg = <0xb1000000 0x10000>; 61 reg = <0xb1000000 0x10000>;
35 interrupts = <0 68 0x4>; 62 interrupts = <0 68 0x4>;
63 phys = <&miphy0 0>;
64 phy-names = "sata-phy";
36 status = "disabled"; 65 status = "disabled";
37 }; 66 };
38 67
39 ahci@b1800000 { 68 ahci1: ahci@b1800000 {
40 compatible = "snps,spear-ahci"; 69 compatible = "snps,spear-ahci";
41 reg = <0xb1800000 0x10000>; 70 reg = <0xb1800000 0x10000>;
42 interrupts = <0 69 0x4>; 71 interrupts = <0 69 0x4>;
72 phys = <&miphy1 0>;
73 phy-names = "sata-phy";
43 status = "disabled"; 74 status = "disabled";
44 }; 75 };
45 76
46 ahci@b4000000 { 77 ahci2: ahci@b4000000 {
47 compatible = "snps,spear-ahci"; 78 compatible = "snps,spear-ahci";
48 reg = <0xb4000000 0x10000>; 79 reg = <0xb4000000 0x10000>;
49 interrupts = <0 70 0x4>; 80 interrupts = <0 70 0x4>;
81 phys = <&miphy2 0>;
82 phy-names = "sata-phy";
83 status = "disabled";
84 };
85
86 pcie0: pcie@b1000000 {
87 compatible = "st,spear1340-pcie", "snps,dw-pcie";
88 reg = <0xb1000000 0x4000>;
89 interrupts = <0 68 0x4>;
90 interrupt-map-mask = <0 0 0 0>;
91 interrupt-map = <0x0 0 &gic 0 68 0x4>;
92 num-lanes = <1>;
93 phys = <&miphy0 1>;
94 phy-names = "pcie-phy";
95 #address-cells = <3>;
96 #size-cells = <2>;
97 device_type = "pci";
98 ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000 /* configuration space */
99 0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */
100 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
101 status = "disabled";
102 };
103
104 pcie1: pcie@b1800000 {
105 compatible = "st,spear1340-pcie", "snps,dw-pcie";
106 reg = <0xb1800000 0x4000>;
107 interrupts = <0 69 0x4>;
108 interrupt-map-mask = <0 0 0 0>;
109 interrupt-map = <0x0 0 &gic 0 69 0x4>;
110 num-lanes = <1>;
111 phys = <&miphy1 1>;
112 phy-names = "pcie-phy";
113 #address-cells = <3>;
114 #size-cells = <2>;
115 device_type = "pci";
116 ranges = <0x00000800 0 0x90000000 0x90000000 0 0x00020000 /* configuration space */
117 0x81000000 0 0 0x90020000 0 0x00010000 /* downstream I/O */
118 0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */
119 status = "disabled";
120 };
121
122 pcie2: pcie@b4000000 {
123 compatible = "st,spear1340-pcie", "snps,dw-pcie";
124 reg = <0xb4000000 0x4000>;
125 interrupts = <0 70 0x4>;
126 interrupt-map-mask = <0 0 0 0>;
127 interrupt-map = <0x0 0 &gic 0 70 0x4>;
128 num-lanes = <1>;
129 phys = <&miphy2 1>;
130 phy-names = "pcie-phy";
131 #address-cells = <3>;
132 #size-cells = <2>;
133 device_type = "pci";
134 ranges = <0x00000800 0 0xc0000000 0xc0000000 0 0x00020000 /* configuration space */
135 0x81000000 0 0 0xc0020000 0 0x00010000 /* downstream I/O */
136 0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
50 status = "disabled"; 137 status = "disabled";
51 }; 138 };
52 139
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
index d6c30ae0a8d7..b23e05ed1d60 100644
--- a/arch/arm/boot/dts/spear1340-evb.dts
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -122,6 +122,10 @@
122 status = "okay"; 122 status = "okay";
123 }; 123 };
124 124
125 miphy@eb800000 {
126 status = "okay";
127 };
128
125 dma@ea800000 { 129 dma@ea800000 {
126 status = "okay"; 130 status = "okay";
127 }; 131 };
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index 54d128d35681..e71df0f2cb52 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -31,10 +31,38 @@
31 status = "disabled"; 31 status = "disabled";
32 }; 32 };
33 33
34 ahci@b1000000 { 34 miphy0: miphy@eb800000 {
35 compatible = "st,spear1340-miphy";
36 reg = <0xeb800000 0x4000>;
37 misc = <&misc>;
38 #phy-cells = <1>;
39 status = "disabled";
40 };
41
42 ahci0: ahci@b1000000 {
35 compatible = "snps,spear-ahci"; 43 compatible = "snps,spear-ahci";
36 reg = <0xb1000000 0x10000>; 44 reg = <0xb1000000 0x10000>;
37 interrupts = <0 72 0x4>; 45 interrupts = <0 72 0x4>;
46 phys = <&miphy0 0>;
47 phy-names = "sata-phy";
48 status = "disabled";
49 };
50
51 pcie0: pcie@b1000000 {
52 compatible = "st,spear1340-pcie", "snps,dw-pcie";
53 reg = <0xb1000000 0x4000>;
54 interrupts = <0 68 0x4>;
55 interrupt-map-mask = <0 0 0 0>;
56 interrupt-map = <0x0 0 &gic 0 68 0x4>;
57 num-lanes = <1>;
58 phys = <&miphy0 1>;
59 phy-names = "pcie-phy";
60 #address-cells = <3>;
61 #size-cells = <2>;
62 device_type = "pci";
63 ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000 /* configuration space */
64 0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */
65 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
38 status = "disabled"; 66 status = "disabled";
39 }; 67 };
40 68
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
index 4382547df58a..a6eb5436d26d 100644
--- a/arch/arm/boot/dts/spear13xx.dtsi
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -83,8 +83,8 @@
83 #size-cells = <1>; 83 #size-cells = <1>;
84 compatible = "simple-bus"; 84 compatible = "simple-bus";
85 ranges = <0x50000000 0x50000000 0x10000000 85 ranges = <0x50000000 0x50000000 0x10000000
86 0xb0000000 0xb0000000 0x10000000 86 0x80000000 0x80000000 0x20000000
87 0xd0000000 0xd0000000 0x02000000 87 0xb0000000 0xb0000000 0x22000000
88 0xd8000000 0xd8000000 0x01000000 88 0xd8000000 0xd8000000 0x01000000
89 0xe0000000 0xe0000000 0x10000000>; 89 0xe0000000 0xe0000000 0x10000000>;
90 90
@@ -220,6 +220,11 @@
220 0xd8000000 0xd8000000 0x01000000 220 0xd8000000 0xd8000000 0x01000000
221 0xe0000000 0xe0000000 0x10000000>; 221 0xe0000000 0xe0000000 0x10000000>;
222 222
223 misc: syscon@e0700000 {
224 compatible = "st,spear1340-misc", "syscon";
225 reg = <0xe0700000 0x1000>;
226 };
227
223 gpio0: gpio@e0600000 { 228 gpio0: gpio@e0600000 {
224 compatible = "arm,pl061", "arm,primecell"; 229 compatible = "arm,pl061", "arm,primecell";
225 reg = <0xe0600000 0x1000>; 230 reg = <0xe0600000 0x1000>;
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts
index f45aad688d9b..a37279af687c 100644
--- a/arch/arm/boot/dts/tegra20-harmony.dts
+++ b/arch/arm/boot/dts/tegra20-harmony.dts
@@ -562,10 +562,14 @@
562 }; 562 };
563 563
564 pcie-controller@80003000 { 564 pcie-controller@80003000 {
565 pex-clk-supply = <&pci_clk_reg>;
566 vdd-supply = <&pci_vdd_reg>;
567 status = "okay"; 565 status = "okay";
568 566
567 avdd-pex-supply = <&pci_vdd_reg>;
568 vdd-pex-supply = <&pci_vdd_reg>;
569 avdd-pex-pll-supply = <&pci_vdd_reg>;
570 avdd-plle-supply = <&pci_vdd_reg>;
571 vddio-pex-clk-supply = <&pci_clk_reg>;
572
569 pci@1,0 { 573 pci@1,0 {
570 status = "okay"; 574 status = "okay";
571 }; 575 };
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi
index 9c8318538a11..80e7d386ce34 100644
--- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
+++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
@@ -474,8 +474,11 @@
474 }; 474 };
475 475
476 pcie-controller@80003000 { 476 pcie-controller@80003000 {
477 pex-clk-supply = <&pci_clk_reg>; 477 avdd-pex-supply = <&pci_vdd_reg>;
478 vdd-supply = <&pci_vdd_reg>; 478 vdd-pex-supply = <&pci_vdd_reg>;
479 avdd-pex-pll-supply = <&pci_vdd_reg>;
480 avdd-plle-supply = <&pci_vdd_reg>;
481 vddio-pex-clk-supply = <&pci_clk_reg>;
479 }; 482 };
480 483
481 usb@c5008000 { 484 usb@c5008000 {
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts
index 216fa6d50c65..5ad87979ab13 100644
--- a/arch/arm/boot/dts/tegra20-trimslice.dts
+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
@@ -318,8 +318,12 @@
318 318
319 pcie-controller@80003000 { 319 pcie-controller@80003000 {
320 status = "okay"; 320 status = "okay";
321 pex-clk-supply = <&pci_clk_reg>; 321
322 vdd-supply = <&pci_vdd_reg>; 322 avdd-pex-supply = <&pci_vdd_reg>;
323 vdd-pex-supply = <&pci_vdd_reg>;
324 avdd-pex-pll-supply = <&pci_vdd_reg>;
325 avdd-plle-supply = <&pci_vdd_reg>;
326 vddio-pex-clk-supply = <&pci_clk_reg>;
323 327
324 pci@1,0 { 328 pci@1,0 {
325 status = "okay"; 329 status = "okay";
diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts
index 3189791a9289..cee8f2246fdb 100644
--- a/arch/arm/boot/dts/tegra30-beaver.dts
+++ b/arch/arm/boot/dts/tegra30-beaver.dts
@@ -17,9 +17,15 @@
17 17
18 pcie-controller@00003000 { 18 pcie-controller@00003000 {
19 status = "okay"; 19 status = "okay";
20 pex-clk-supply = <&sys_3v3_pexs_reg>; 20
21 vdd-supply = <&ldo1_reg>; 21 avdd-pexa-supply = <&ldo1_reg>;
22 avdd-supply = <&ldo2_reg>; 22 vdd-pexa-supply = <&ldo1_reg>;
23 avdd-pexb-supply = <&ldo1_reg>;
24 vdd-pexb-supply = <&ldo1_reg>;
25 avdd-pex-pll-supply = <&ldo1_reg>;
26 avdd-plle-supply = <&ldo1_reg>;
27 vddio-pex-ctl-supply = <&sys_3v3_reg>;
28 hvdd-pex-supply = <&sys_3v3_pexs_reg>;
23 29
24 pci@1,0 { 30 pci@1,0 {
25 status = "okay"; 31 status = "okay";
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index 0cf0848a82d8..206379546244 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -38,9 +38,14 @@
38 38
39 pcie-controller@00003000 { 39 pcie-controller@00003000 {
40 status = "okay"; 40 status = "okay";
41 pex-clk-supply = <&pex_hvdd_3v3_reg>; 41
42 vdd-supply = <&ldo1_reg>; 42 /* AVDD_PEXA and VDD_PEXA inputs are grounded on Cardhu. */
43 avdd-supply = <&ldo2_reg>; 43 avdd-pexb-supply = <&ldo1_reg>;
44 vdd-pexb-supply = <&ldo1_reg>;
45 avdd-pex-pll-supply = <&ldo1_reg>;
46 hvdd-pex-supply = <&pex_hvdd_3v3_reg>;
47 vddio-pex-ctl-supply = <&sys_3v3_reg>;
48 avdd-plle-supply = <&ldo2_reg>;
44 49
45 pci@1,0 { 50 pci@1,0 {
46 nvidia,num-lanes = <4>; 51 nvidia,num-lanes = <4>;
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index ce541bb3c2de..115cda9f3260 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -26,8 +26,6 @@ CONFIG_ARCH_OMAP=y
26CONFIG_ARCH_OMAP1=y 26CONFIG_ARCH_OMAP1=y
27CONFIG_OMAP_RESET_CLOCKS=y 27CONFIG_OMAP_RESET_CLOCKS=y
28# CONFIG_OMAP_MUX is not set 28# CONFIG_OMAP_MUX is not set
29CONFIG_MAILBOX=y
30CONFIG_OMAP1_MBOX=y
31CONFIG_OMAP_32K_TIMER=y 29CONFIG_OMAP_32K_TIMER=y
32CONFIG_OMAP_DM_TIMER=y 30CONFIG_OMAP_DM_TIMER=y
33CONFIG_ARCH_OMAP730=y 31CONFIG_ARCH_OMAP730=y
diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
index 82eaa552ed14..d271b263f35d 100644
--- a/arch/arm/configs/spear13xx_defconfig
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -11,13 +11,24 @@ CONFIG_ARCH_SPEAR13XX=y
11CONFIG_MACH_SPEAR1310=y 11CONFIG_MACH_SPEAR1310=y
12CONFIG_MACH_SPEAR1340=y 12CONFIG_MACH_SPEAR1340=y
13# CONFIG_SWP_EMULATE is not set 13# CONFIG_SWP_EMULATE is not set
14CONFIG_PCI=y
15CONFIG_PCI_MSI=y
16CONFIG_PCIE_SPEAR13XX=y
14CONFIG_SMP=y 17CONFIG_SMP=y
15# CONFIG_SMP_ON_UP is not set 18# CONFIG_SMP_ON_UP is not set
16# CONFIG_ARM_CPU_TOPOLOGY is not set 19# CONFIG_ARM_CPU_TOPOLOGY is not set
20CONFIG_AEABI=y
17CONFIG_ARM_APPENDED_DTB=y 21CONFIG_ARM_APPENDED_DTB=y
18CONFIG_ARM_ATAG_DTB_COMPAT=y 22CONFIG_ARM_ATAG_DTB_COMPAT=y
23CONFIG_VFP=y
19CONFIG_BINFMT_MISC=y 24CONFIG_BINFMT_MISC=y
20CONFIG_NET=y 25CONFIG_NET=y
26CONFIG_UNIX=y
27CONFIG_INET=y
28CONFIG_IP_PNP=y
29CONFIG_IP_PNP_DHCP=y
30CONFIG_IP_PNP_BOOTP=y
31CONFIG_NET_IPIP=y
21CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 32CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
22CONFIG_MTD=y 33CONFIG_MTD=y
23CONFIG_MTD_OF_PARTS=y 34CONFIG_MTD_OF_PARTS=y
@@ -27,6 +38,7 @@ CONFIG_MTD_NAND=y
27CONFIG_MTD_NAND_FSMC=y 38CONFIG_MTD_NAND_FSMC=y
28CONFIG_BLK_DEV_RAM=y 39CONFIG_BLK_DEV_RAM=y
29CONFIG_BLK_DEV_RAM_SIZE=16384 40CONFIG_BLK_DEV_RAM_SIZE=16384
41CONFIG_BLK_DEV_SD=y
30CONFIG_ATA=y 42CONFIG_ATA=y
31# CONFIG_SATA_PMP is not set 43# CONFIG_SATA_PMP is not set
32CONFIG_SATA_AHCI_PLATFORM=y 44CONFIG_SATA_AHCI_PLATFORM=y
@@ -66,6 +78,7 @@ CONFIG_USB=y
66# CONFIG_USB_DEVICE_CLASS is not set 78# CONFIG_USB_DEVICE_CLASS is not set
67CONFIG_USB_EHCI_HCD=y 79CONFIG_USB_EHCI_HCD=y
68CONFIG_USB_OHCI_HCD=y 80CONFIG_USB_OHCI_HCD=y
81CONFIG_USB_STORAGE=y
69CONFIG_MMC=y 82CONFIG_MMC=y
70CONFIG_MMC_SDHCI=y 83CONFIG_MMC_SDHCI=y
71CONFIG_MMC_SDHCI_SPEAR=y 84CONFIG_MMC_SDHCI_SPEAR=y
@@ -79,11 +92,14 @@ CONFIG_EXT2_FS_SECURITY=y
79CONFIG_EXT3_FS=y 92CONFIG_EXT3_FS=y
80CONFIG_EXT3_FS_SECURITY=y 93CONFIG_EXT3_FS_SECURITY=y
81CONFIG_AUTOFS4_FS=m 94CONFIG_AUTOFS4_FS=m
95CONFIG_FUSE_FS=y
82CONFIG_MSDOS_FS=m 96CONFIG_MSDOS_FS=m
83CONFIG_VFAT_FS=m 97CONFIG_VFAT_FS=m
84CONFIG_FAT_DEFAULT_IOCHARSET="ascii" 98CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
85CONFIG_TMPFS=y 99CONFIG_TMPFS=y
86CONFIG_JFFS2_FS=y 100CONFIG_JFFS2_FS=y
101CONFIG_NFS_FS=y
102CONFIG_ROOT_NFS=y
87CONFIG_NLS_DEFAULT="utf8" 103CONFIG_NLS_DEFAULT="utf8"
88CONFIG_NLS_CODEPAGE_437=y 104CONFIG_NLS_CODEPAGE_437=y
89CONFIG_NLS_ASCII=m 105CONFIG_NLS_ASCII=m
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index c07465361947..810fa5f15a51 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -200,6 +200,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
200 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), 200 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
201 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), 201 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
202 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), 202 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk),
203 CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
203 /* fake hclk clock */ 204 /* fake hclk clock */
204 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), 205 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
205 CLKDEV_CON_ID("pioA", &pioA_clk), 206 CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 309390d8e2f8..cef0e2f57068 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1131,9 +1131,7 @@ static void __init at91_add_device_watchdog(void) {}
1131 * PWM 1131 * PWM
1132 * --------------------------------------------------------------------*/ 1132 * --------------------------------------------------------------------*/
1133 1133
1134#if defined(CONFIG_ATMEL_PWM) 1134#if IS_ENABLED(CONFIG_PWM_ATMEL)
1135static u32 pwm_mask;
1136
1137static struct resource pwm_resources[] = { 1135static struct resource pwm_resources[] = {
1138 [0] = { 1136 [0] = {
1139 .start = AT91SAM9263_BASE_PWMC, 1137 .start = AT91SAM9263_BASE_PWMC,
@@ -1148,11 +1146,8 @@ static struct resource pwm_resources[] = {
1148}; 1146};
1149 1147
1150static struct platform_device at91sam9263_pwm0_device = { 1148static struct platform_device at91sam9263_pwm0_device = {
1151 .name = "atmel_pwm", 1149 .name = "at91sam9rl-pwm",
1152 .id = -1, 1150 .id = -1,
1153 .dev = {
1154 .platform_data = &pwm_mask,
1155 },
1156 .resource = pwm_resources, 1151 .resource = pwm_resources,
1157 .num_resources = ARRAY_SIZE(pwm_resources), 1152 .num_resources = ARRAY_SIZE(pwm_resources),
1158}; 1153};
@@ -1171,8 +1166,6 @@ void __init at91_add_device_pwm(u32 mask)
1171 if (mask & (1 << AT91_PWM3)) 1166 if (mask & (1 << AT91_PWM3))
1172 at91_set_B_periph(AT91_PIN_PB29, 1); /* enable PWM3 */ 1167 at91_set_B_periph(AT91_PIN_PB29, 1); /* enable PWM3 */
1173 1168
1174 pwm_mask = mask;
1175
1176 platform_device_register(&at91sam9263_pwm0_device); 1169 platform_device_register(&at91sam9263_pwm0_device);
1177} 1170}
1178#else 1171#else
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 0d5d85797cd6..9d45496e4932 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -252,6 +252,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
252 CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk), 252 CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk),
253 CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk), 253 CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk),
254 CLKDEV_CON_DEV_ID(NULL, "atmel_aes", &aestdessha_clk), 254 CLKDEV_CON_DEV_ID(NULL, "atmel_aes", &aestdessha_clk),
255 CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
255 /* more usart lookup table for DT entries */ 256 /* more usart lookup table for DT entries */
256 CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck), 257 CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck),
257 CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk), 258 CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk),
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 391ab6bb536a..21ab782cc8e9 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1334,9 +1334,7 @@ static void __init at91_add_device_watchdog(void) {}
1334 * PWM 1334 * PWM
1335 * --------------------------------------------------------------------*/ 1335 * --------------------------------------------------------------------*/
1336 1336
1337#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE) 1337#if IS_ENABLED(CONFIG_PWM_ATMEL)
1338static u32 pwm_mask;
1339
1340static struct resource pwm_resources[] = { 1338static struct resource pwm_resources[] = {
1341 [0] = { 1339 [0] = {
1342 .start = AT91SAM9G45_BASE_PWMC, 1340 .start = AT91SAM9G45_BASE_PWMC,
@@ -1351,11 +1349,8 @@ static struct resource pwm_resources[] = {
1351}; 1349};
1352 1350
1353static struct platform_device at91sam9g45_pwm0_device = { 1351static struct platform_device at91sam9g45_pwm0_device = {
1354 .name = "atmel_pwm", 1352 .name = "at91sam9rl-pwm",
1355 .id = -1, 1353 .id = -1,
1356 .dev = {
1357 .platform_data = &pwm_mask,
1358 },
1359 .resource = pwm_resources, 1354 .resource = pwm_resources,
1360 .num_resources = ARRAY_SIZE(pwm_resources), 1355 .num_resources = ARRAY_SIZE(pwm_resources),
1361}; 1356};
@@ -1374,8 +1369,6 @@ void __init at91_add_device_pwm(u32 mask)
1374 if (mask & (1 << AT91_PWM3)) 1369 if (mask & (1 << AT91_PWM3))
1375 at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */ 1370 at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */
1376 1371
1377 pwm_mask = mask;
1378
1379 platform_device_register(&at91sam9g45_pwm0_device); 1372 platform_device_register(&at91sam9g45_pwm0_device);
1380} 1373}
1381#else 1374#else
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index a79960f57e6a..878d5015daab 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -200,6 +200,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
200 CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk), 200 CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk),
201 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), 201 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk),
202 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), 202 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk),
203 CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
203 CLKDEV_CON_ID("pioA", &pioA_clk), 204 CLKDEV_CON_ID("pioA", &pioA_clk),
204 CLKDEV_CON_ID("pioB", &pioB_clk), 205 CLKDEV_CON_ID("pioB", &pioB_clk),
205 CLKDEV_CON_ID("pioC", &pioC_clk), 206 CLKDEV_CON_ID("pioC", &pioC_clk),
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 0b1d71a7d9bf..37d1c9ed4562 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -799,9 +799,7 @@ static void __init at91_add_device_watchdog(void) {}
799 * PWM 799 * PWM
800 * --------------------------------------------------------------------*/ 800 * --------------------------------------------------------------------*/
801 801
802#if defined(CONFIG_ATMEL_PWM) 802#if IS_ENABLED(CONFIG_PWM_ATMEL)
803static u32 pwm_mask;
804
805static struct resource pwm_resources[] = { 803static struct resource pwm_resources[] = {
806 [0] = { 804 [0] = {
807 .start = AT91SAM9RL_BASE_PWMC, 805 .start = AT91SAM9RL_BASE_PWMC,
@@ -816,11 +814,8 @@ static struct resource pwm_resources[] = {
816}; 814};
817 815
818static struct platform_device at91sam9rl_pwm0_device = { 816static struct platform_device at91sam9rl_pwm0_device = {
819 .name = "atmel_pwm", 817 .name = "at91sam9rl-pwm",
820 .id = -1, 818 .id = -1,
821 .dev = {
822 .platform_data = &pwm_mask,
823 },
824 .resource = pwm_resources, 819 .resource = pwm_resources,
825 .num_resources = ARRAY_SIZE(pwm_resources), 820 .num_resources = ARRAY_SIZE(pwm_resources),
826}; 821};
@@ -839,8 +834,6 @@ void __init at91_add_device_pwm(u32 mask)
839 if (mask & (1 << AT91_PWM3)) 834 if (mask & (1 << AT91_PWM3))
840 at91_set_B_periph(AT91_PIN_PD8, 1); /* enable PWM3 */ 835 at91_set_B_periph(AT91_PIN_PD8, 1); /* enable PWM3 */
841 836
842 pwm_mask = mask;
843
844 platform_device_register(&at91sam9rl_pwm0_device); 837 platform_device_register(&at91sam9rl_pwm0_device);
845} 838}
846#else 839#else
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index cd2726ee5add..fc446097f410 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -32,6 +32,8 @@
32#include <linux/gpio_keys.h> 32#include <linux/gpio_keys.h>
33#include <linux/input.h> 33#include <linux/input.h>
34#include <linux/leds.h> 34#include <linux/leds.h>
35#include <linux/pwm.h>
36#include <linux/leds_pwm.h>
35 37
36#include <video/atmel_lcdc.h> 38#include <video/atmel_lcdc.h>
37 39
@@ -369,21 +371,47 @@ static struct gpio_led ek_leds[] = {
369 .name = "ds3", 371 .name = "ds3",
370 .gpio = AT91_PIN_PB7, 372 .gpio = AT91_PIN_PB7,
371 .default_trigger = "heartbeat", 373 .default_trigger = "heartbeat",
374 },
375#if !IS_ENABLED(CONFIG_LEDS_PWM)
376 {
377 .name = "ds1",
378 .gpio = AT91_PIN_PB8,
379 .active_low = 1,
380 .default_trigger = "none",
372 } 381 }
382#endif
373}; 383};
374 384
375/* 385/*
376 * PWM Leds 386 * PWM Leds
377 */ 387 */
378static struct gpio_led ek_pwm_led[] = { 388static struct pwm_lookup pwm_lookup[] = {
379 /* For now only DS1 is PWM-driven (by pwm1) */ 389 PWM_LOOKUP("at91sam9rl-pwm", 1, "leds_pwm", "ds1",
390 5000, PWM_POLARITY_INVERSED),
391};
392
393#if IS_ENABLED(CONFIG_LEDS_PWM)
394static struct led_pwm pwm_leds[] = {
380 { 395 {
381 .name = "ds1", 396 .name = "ds1",
382 .gpio = 1, /* is PWM channel number */ 397 .max_brightness = 255,
383 .active_low = 1, 398 },
384 .default_trigger = "none", 399};
385 } 400
401static struct led_pwm_platform_data pwm_data = {
402 .num_leds = ARRAY_SIZE(pwm_leds),
403 .leds = pwm_leds,
404};
405
406static struct platform_device leds_pwm = {
407 .name = "leds_pwm",
408 .id = -1,
409 .dev = {
410 .platform_data = &pwm_data,
411 },
386}; 412};
413#endif
414
387 415
388/* 416/*
389 * CAN 417 * CAN
@@ -403,6 +431,12 @@ static struct at91_can_data ek_can_data = {
403 .transceiver_switch = sam9263ek_transceiver_switch, 431 .transceiver_switch = sam9263ek_transceiver_switch,
404}; 432};
405 433
434static struct platform_device *devices[] __initdata = {
435#if IS_ENABLED(CONFIG_LEDS_PWM)
436 &leds_pwm,
437#endif
438};
439
406static void __init ek_board_init(void) 440static void __init ek_board_init(void)
407{ 441{
408 /* Serial */ 442 /* Serial */
@@ -437,9 +471,14 @@ static void __init ek_board_init(void)
437 at91_add_device_ac97(&ek_ac97_data); 471 at91_add_device_ac97(&ek_ac97_data);
438 /* LEDs */ 472 /* LEDs */
439 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); 473 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
440 at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); 474 pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
475#if IS_ENABLED(CONFIG_LEDS_PWM)
476 at91_add_device_pwm(1 << AT91_PWM1);
477#endif
441 /* CAN */ 478 /* CAN */
442 at91_add_device_can(&ek_can_data); 479 at91_add_device_can(&ek_can_data);
480 /* Other platform devices */
481 platform_add_devices(devices, ARRAY_SIZE(devices));
443} 482}
444 483
445MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") 484MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index 1ea61328f30d..b227732b0c83 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -26,6 +26,8 @@
26#include <linux/leds.h> 26#include <linux/leds.h>
27#include <linux/atmel-mci.h> 27#include <linux/atmel-mci.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/pwm.h>
30#include <linux/leds_pwm.h>
29 31
30#include <linux/platform_data/at91_adc.h> 32#include <linux/platform_data/at91_adc.h>
31 33
@@ -416,7 +418,7 @@ static struct gpio_led ek_leds[] = {
416 .active_low = 1, 418 .active_low = 1,
417 .default_trigger = "nand-disk", 419 .default_trigger = "nand-disk",
418 }, 420 },
419#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)) 421#if !IS_ENABLED(CONFIG_LEDS_PWM)
420 { /* "right" led, green, userled1, pwm1 */ 422 { /* "right" led, green, userled1, pwm1 */
421 .name = "d7", 423 .name = "d7",
422 .gpio = AT91_PIN_PD31, 424 .gpio = AT91_PIN_PD31,
@@ -430,22 +432,41 @@ static struct gpio_led ek_leds[] = {
430/* 432/*
431 * PWM Leds 433 * PWM Leds
432 */ 434 */
433static struct gpio_led ek_pwm_led[] = { 435static struct pwm_lookup pwm_lookup[] = {
434#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE) 436 PWM_LOOKUP("at91sam9rl-pwm", 1, "leds_pwm", "d7",
437 5000, PWM_POLARITY_INVERSED),
438};
439
440#if IS_ENABLED(CONFIG_LEDS_PWM)
441static struct led_pwm pwm_leds[] = {
435 { /* "right" led, green, userled1, pwm1 */ 442 { /* "right" led, green, userled1, pwm1 */
436 .name = "d7", 443 .name = "d7",
437 .gpio = 1, /* is PWM channel number */ 444 .max_brightness = 255,
438 .active_low = 1,
439 .default_trigger = "none",
440 }, 445 },
441#endif
442}; 446};
443 447
448static struct led_pwm_platform_data pwm_data = {
449 .num_leds = ARRAY_SIZE(pwm_leds),
450 .leds = pwm_leds,
451};
452
453static struct platform_device leds_pwm = {
454 .name = "leds_pwm",
455 .id = -1,
456 .dev = {
457 .platform_data = &pwm_data,
458 },
459};
460#endif
461
444static struct platform_device *devices[] __initdata = { 462static struct platform_device *devices[] __initdata = {
445#if defined(CONFIG_SOC_CAMERA_OV2640) || \ 463#if defined(CONFIG_SOC_CAMERA_OV2640) || \
446 defined(CONFIG_SOC_CAMERA_OV2640_MODULE) 464 defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
447 &isi_ov2640, 465 &isi_ov2640,
448#endif 466#endif
467#if IS_ENABLED(CONFIG_LEDS_PWM)
468 &leds_pwm,
469#endif
449}; 470};
450 471
451static void __init ek_board_init(void) 472static void __init ek_board_init(void)
@@ -486,7 +507,10 @@ static void __init ek_board_init(void)
486 at91_add_device_ac97(&ek_ac97_data); 507 at91_add_device_ac97(&ek_ac97_data);
487 /* LEDs */ 508 /* LEDs */
488 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); 509 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
489 at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); 510 pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
511#if IS_ENABLED(CONFIG_LEDS_PWM)
512 at91_add_device_pwm(1 << AT91_PWM1);
513#endif
490 /* Other platform devices */ 514 /* Other platform devices */
491 platform_add_devices(devices, ARRAY_SIZE(devices)); 515 platform_add_devices(devices, ARRAY_SIZE(devices));
492} 516}
diff --git a/arch/arm/mach-at91/board.h b/arch/arm/mach-at91/board.h
index 4e773b55bc2d..836e9a537e0c 100644
--- a/arch/arm/mach-at91/board.h
+++ b/arch/arm/mach-at91/board.h
@@ -123,6 +123,5 @@ extern void __init at91_add_device_can(struct at91_can_data *data);
123 123
124 /* LEDs */ 124 /* LEDs */
125extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); 125extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
126extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
127 126
128#endif 127#endif
diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c
index 77c4d8fd03fd..eb22e3357e87 100644
--- a/arch/arm/mach-at91/leds.c
+++ b/arch/arm/mach-at91/leds.c
@@ -54,40 +54,3 @@ void __init at91_gpio_leds(struct gpio_led *leds, int nr)
54void __init at91_gpio_leds(struct gpio_led *leds, int nr) {} 54void __init at91_gpio_leds(struct gpio_led *leds, int nr) {}
55#endif 55#endif
56 56
57
58/* ------------------------------------------------------------------------- */
59
60#if defined (CONFIG_LEDS_ATMEL_PWM)
61
62/*
63 * PWM Leds
64 */
65
66static struct gpio_led_platform_data pwm_led_data;
67
68static struct platform_device at91_pwm_leds_device = {
69 .name = "leds-atmel-pwm",
70 .id = -1,
71 .dev.platform_data = &pwm_led_data,
72};
73
74void __init at91_pwm_leds(struct gpio_led *leds, int nr)
75{
76 int i;
77 u32 pwm_mask = 0;
78
79 if (!nr)
80 return;
81
82 for (i = 0; i < nr; i++)
83 pwm_mask |= (1 << leds[i].gpio);
84
85 pwm_led_data.leds = leds;
86 pwm_led_data.num_leds = nr;
87
88 at91_add_device_pwm(pwm_mask);
89 platform_device_register(&at91_pwm_leds_device);
90}
91#else
92void __init at91_pwm_leds(struct gpio_led *leds, int nr){}
93#endif
diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
index 90df2022276a..6fd4dc88160b 100644
--- a/arch/arm/mach-spear/Kconfig
+++ b/arch/arm/mach-spear/Kconfig
@@ -19,6 +19,8 @@ config ARCH_SPEAR13XX
19 select HAVE_ARM_SCU if SMP 19 select HAVE_ARM_SCU if SMP
20 select HAVE_ARM_TWD if SMP 20 select HAVE_ARM_TWD if SMP
21 select PINCTRL 21 select PINCTRL
22 select MFD_SYSCON
23 select MIGHT_HAVE_PCI
22 help 24 help
23 Supports for ARM's SPEAR13XX family 25 Supports for ARM's SPEAR13XX family
24 26
@@ -27,12 +29,14 @@ if ARCH_SPEAR13XX
27config MACH_SPEAR1310 29config MACH_SPEAR1310
28 bool "SPEAr1310 Machine support with Device Tree" 30 bool "SPEAr1310 Machine support with Device Tree"
29 select PINCTRL_SPEAR1310 31 select PINCTRL_SPEAR1310
32 select PHY_ST_SPEAR1310_MIPHY
30 help 33 help
31 Supports ST SPEAr1310 machine configured via the device-tree 34 Supports ST SPEAr1310 machine configured via the device-tree
32 35
33config MACH_SPEAR1340 36config MACH_SPEAR1340
34 bool "SPEAr1340 Machine support with Device Tree" 37 bool "SPEAr1340 Machine support with Device Tree"
35 select PINCTRL_SPEAR1340 38 select PINCTRL_SPEAR1340
39 select PHY_ST_SPEAR1340_MIPHY
36 help 40 help
37 Supports ST SPEAr1340 machine configured via the device-tree 41 Supports ST SPEAr1340 machine configured via the device-tree
38 42
diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h
index 5cdc53d9b653..f2d6a0176575 100644
--- a/arch/arm/mach-spear/include/mach/spear.h
+++ b/arch/arm/mach-spear/include/mach/spear.h
@@ -52,10 +52,10 @@
52#ifdef CONFIG_ARCH_SPEAR13XX 52#ifdef CONFIG_ARCH_SPEAR13XX
53 53
54#define PERIP_GRP2_BASE UL(0xB3000000) 54#define PERIP_GRP2_BASE UL(0xB3000000)
55#define VA_PERIP_GRP2_BASE IOMEM(0xFE000000) 55#define VA_PERIP_GRP2_BASE IOMEM(0xF9000000)
56#define MCIF_SDHCI_BASE UL(0xB3000000) 56#define MCIF_SDHCI_BASE UL(0xB3000000)
57#define SYSRAM0_BASE UL(0xB3800000) 57#define SYSRAM0_BASE UL(0xB3800000)
58#define VA_SYSRAM0_BASE IOMEM(0xFE800000) 58#define VA_SYSRAM0_BASE IOMEM(0xF9800000)
59#define SYS_LOCATION (VA_SYSRAM0_BASE + 0x600) 59#define SYS_LOCATION (VA_SYSRAM0_BASE + 0x600)
60 60
61#define PERIP_GRP1_BASE UL(0xE0000000) 61#define PERIP_GRP1_BASE UL(0xE0000000)
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
index c601799b4aea..3f3c0f124bd3 100644
--- a/arch/arm/mach-spear/spear1340.c
+++ b/arch/arm/mach-spear/spear1340.c
@@ -13,136 +13,13 @@
13 13
14#define pr_fmt(fmt) "SPEAr1340: " fmt 14#define pr_fmt(fmt) "SPEAr1340: " fmt
15 15
16#include <linux/ahci_platform.h>
17#include <linux/amba/serial.h>
18#include <linux/delay.h>
19#include <linux/of_platform.h> 16#include <linux/of_platform.h>
20#include <asm/mach/arch.h> 17#include <asm/mach/arch.h>
21#include "generic.h" 18#include "generic.h"
22#include <mach/spear.h>
23
24/* FIXME: Move SATA PHY code into a standalone driver */
25
26/* Base addresses */
27#define SPEAR1340_SATA_BASE UL(0xB1000000)
28
29/* Power Management Registers */
30#define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100)
31#define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104)
32#define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108)
33
34#define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318)
35#define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C)
36#define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320)
37
38/* PCIE - SATA configuration registers */
39#define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424)
40 /* PCIE CFG MASks */
41 #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11)
42 #define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10)
43 #define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9)
44 #define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8)
45 #define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4)
46 #define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3)
47 #define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2)
48 #define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1)
49 #define SPEAR1340_PCIE_SATA_SEL_PCIE (0)
50 #define SPEAR1340_PCIE_SATA_SEL_SATA (1)
51 #define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F
52 #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \
53 SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
54 SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
55 SPEAR1340_PCIE_CFG_POWERUP_RESET | \
56 SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
57 #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \
58 SPEAR1340_SATA_CFG_PM_CLK_EN | \
59 SPEAR1340_SATA_CFG_POWERUP_RESET | \
60 SPEAR1340_SATA_CFG_RX_CLK_EN | \
61 SPEAR1340_SATA_CFG_TX_CLK_EN)
62
63#define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428)
64 #define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31)
65 #define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27)
66 #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27)
67 #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27)
68 #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0)
69 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
70 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
71 SPEAR1340_MIPHY_CLK_REF_DIV2 | \
72 SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
73 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
74 (SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
75 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
76 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
77 SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
78
79/* SATA device registration */
80static int sata_miphy_init(struct device *dev, void __iomem *addr)
81{
82 writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
83 writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
84 SPEAR1340_PCIE_MIPHY_CFG);
85 /* Switch on sata power domain */
86 writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
87 msleep(20);
88 /* Disable PCIE SATA Controller reset */
89 writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
90 SPEAR1340_PERIP1_SW_RST);
91 msleep(20);
92
93 return 0;
94}
95
96static void sata_miphy_exit(struct device *dev)
97{
98 writel(0, SPEAR1340_PCIE_SATA_CFG);
99 writel(0, SPEAR1340_PCIE_MIPHY_CFG);
100
101 /* Enable PCIE SATA Controller reset */
102 writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
103 SPEAR1340_PERIP1_SW_RST);
104 msleep(20);
105 /* Switch off sata power domain */
106 writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
107 msleep(20);
108}
109
110static int sata_suspend(struct device *dev)
111{
112 if (dev->power.power_state.event == PM_EVENT_FREEZE)
113 return 0;
114
115 sata_miphy_exit(dev);
116
117 return 0;
118}
119
120static int sata_resume(struct device *dev)
121{
122 if (dev->power.power_state.event == PM_EVENT_THAW)
123 return 0;
124
125 return sata_miphy_init(dev, NULL);
126}
127
128static struct ahci_platform_data sata_pdata = {
129 .init = sata_miphy_init,
130 .exit = sata_miphy_exit,
131 .suspend = sata_suspend,
132 .resume = sata_resume,
133};
134
135/* Add SPEAr1340 auxdata to pass platform data */
136static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
137 OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
138 &sata_pdata),
139 {}
140};
141 19
142static void __init spear1340_dt_init(void) 20static void __init spear1340_dt_init(void)
143{ 21{
144 of_platform_populate(NULL, of_default_bus_match_table, 22 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
145 spear1340_auxdata_lookup, NULL);
146 platform_device_register_simple("spear-cpufreq", -1, NULL, 0); 23 platform_device_register_simple("spear-cpufreq", -1, NULL, 0);
147} 24}
148 25
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index 8b56fe61a492..2e463a93468d 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -52,7 +52,7 @@ void __init spear13xx_l2x0_init(void)
52/* 52/*
53 * Following will create 16MB static virtual/physical mappings 53 * Following will create 16MB static virtual/physical mappings
54 * PHYSICAL VIRTUAL 54 * PHYSICAL VIRTUAL
55 * 0xB3000000 0xFE000000 55 * 0xB3000000 0xF9000000
56 * 0xE0000000 0xFD000000 56 * 0xE0000000 0xFD000000
57 * 0xEC000000 0xFC000000 57 * 0xEC000000 0xFC000000
58 * 0xED000000 0xFB000000 58 * 0xED000000 0xFB000000
diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c
index 1ba09e4c02b1..91146b416cdb 100644
--- a/arch/avr32/boards/atngw100/mrmt.c
+++ b/arch/avr32/boards/atngw100/mrmt.c
@@ -17,6 +17,8 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/fb.h> 18#include <linux/fb.h>
19#include <linux/leds.h> 19#include <linux/leds.h>
20#include <linux/pwm.h>
21#include <linux/leds_pwm.h>
20#include <linux/input.h> 22#include <linux/input.h>
21#include <linux/gpio_keys.h> 23#include <linux/gpio_keys.h>
22#include <linux/atmel_serial.h> 24#include <linux/atmel_serial.h>
@@ -155,21 +157,28 @@ static struct platform_device rmt_ts_device = {
155 157
156#ifdef CONFIG_BOARD_MRMT_BL_PWM 158#ifdef CONFIG_BOARD_MRMT_BL_PWM
157/* PWM LEDs: LCD Backlight, etc */ 159/* PWM LEDs: LCD Backlight, etc */
158static struct gpio_led rmt_pwm_led[] = { 160static struct pwm_lookup pwm_lookup[] = {
159 /* here the "gpio" is actually a PWM channel */ 161 PWM_LOOKUP("at91sam9rl-pwm", PWM_CH_BL, "leds_pwm", "ds1",
160 { .name = "backlight", .gpio = PWM_CH_BL, }, 162 5000, PWM_POLARITY_INVERSED),
161}; 163};
162 164
163static struct gpio_led_platform_data rmt_pwm_led_data = { 165static struct led_pwm pwm_leds[] = {
164 .num_leds = ARRAY_SIZE(rmt_pwm_led), 166 {
165 .leds = rmt_pwm_led, 167 .name = "backlight",
168 .max_brightness = 255,
169 },
170};
171
172static struct led_pwm_platform_data pwm_data = {
173 .num_leds = ARRAY_SIZE(pwm_leds),
174 .leds = pwm_leds,
166}; 175};
167 176
168static struct platform_device rmt_pwm_led_dev = { 177static struct platform_device leds_pwm = {
169 .name = "leds-atmel-pwm", 178 .name = "leds_pwm",
170 .id = -1, 179 .id = -1,
171 .dev = { 180 .dev = {
172 .platform_data = &rmt_pwm_led_data, 181 .platform_data = &pwm_data,
173 }, 182 },
174}; 183};
175#endif 184#endif
@@ -325,7 +334,8 @@ static int __init mrmt1_init(void)
325#ifdef CONFIG_BOARD_MRMT_BL_PWM 334#ifdef CONFIG_BOARD_MRMT_BL_PWM
326 /* Use PWM for Backlight controls */ 335 /* Use PWM for Backlight controls */
327 at32_add_device_pwm(1 << PWM_CH_BL); 336 at32_add_device_pwm(1 << PWM_CH_BL);
328 platform_device_register(&rmt_pwm_led_dev); 337 pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
338 platform_device_register(&leds_pwm);
329#else 339#else
330 /* Backlight always on */ 340 /* Backlight always on */
331 udelay( 1 ); 341 udelay( 1 );
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
index 1f121497b517..234cb071c601 100644
--- a/arch/avr32/boards/favr-32/setup.c
+++ b/arch/avr32/boards/favr-32/setup.c
@@ -18,7 +18,10 @@
18#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <linux/leds.h> 19#include <linux/leds.h>
20#include <linux/atmel-mci.h> 20#include <linux/atmel-mci.h>
21#include <linux/atmel-pwm-bl.h> 21#include <linux/pwm.h>
22#include <linux/pwm_backlight.h>
23#include <linux/regulator/fixed.h>
24#include <linux/regulator/machine.h>
22#include <linux/spi/spi.h> 25#include <linux/spi/spi.h>
23#include <linux/spi/ads7846.h> 26#include <linux/spi/ads7846.h>
24 27
@@ -33,6 +36,8 @@
33#include <mach/board.h> 36#include <mach/board.h>
34#include <mach/portmux.h> 37#include <mach/portmux.h>
35 38
39#define PWM_BL_CH 2
40
36/* Oscillator frequencies. These are board-specific */ 41/* Oscillator frequencies. These are board-specific */
37unsigned long at32_board_osc_rates[3] = { 42unsigned long at32_board_osc_rates[3] = {
38 [0] = 32768, /* 32.768 kHz on RTC osc */ 43 [0] = 32768, /* 32.768 kHz on RTC osc */
@@ -227,29 +232,36 @@ void __init favr32_setup_leds(void)
227 platform_device_register(&favr32_led_dev); 232 platform_device_register(&favr32_led_dev);
228} 233}
229 234
230static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = { 235static struct pwm_lookup pwm_lookup[] = {
231 .pwm_channel = 2, 236 PWM_LOOKUP("at91sam9rl-pwm", PWM_BL_CH, "pwm-backlight.0", NULL,
232 .pwm_frequency = 200000, 237 5000, PWM_POLARITY_INVERSED),
233 .pwm_compare_max = 345,
234 .pwm_duty_max = 345,
235 .pwm_duty_min = 90,
236 .pwm_active_low = 1,
237 .gpio_on = GPIO_PIN_PA(28),
238 .on_active_low = 0,
239}; 238};
240 239
241static struct platform_device atmel_pwm_bl_dev = { 240static struct regulator_consumer_supply fixed_power_consumers[] = {
242 .name = "atmel-pwm-bl", 241 REGULATOR_SUPPLY("power", "pwm-backlight.0"),
243 .id = 0, 242};
244 .dev = { 243
245 .platform_data = &atmel_pwm_bl_pdata, 244static struct platform_pwm_backlight_data pwm_bl_data = {
245 .enable_gpio = GPIO_PIN_PA(28),
246 .max_brightness = 255,
247 .dft_brightness = 255,
248 .lth_brightness = 50,
249};
250
251static struct platform_device pwm_bl_device = {
252 .name = "pwm-backlight",
253 .dev = {
254 .platform_data = &pwm_bl_data,
246 }, 255 },
247}; 256};
248 257
249static void __init favr32_setup_atmel_pwm_bl(void) 258static void __init favr32_setup_atmel_pwm_bl(void)
250{ 259{
251 platform_device_register(&atmel_pwm_bl_dev); 260 pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
252 at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0); 261 regulator_register_always_on(0, "fixed", fixed_power_consumers,
262 ARRAY_SIZE(fixed_power_consumers), 3300000);
263 platform_device_register(&pwm_bl_device);
264 at32_select_gpio(pwm_bl_data.enable_gpio, 0);
253} 265}
254 266
255void __init setup_board(void) 267void __init setup_board(void)
@@ -339,7 +351,7 @@ static int __init favr32_init(void)
339 351
340 set_abdac_rate(at32_add_device_abdac(0, &abdac0_data)); 352 set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
341 353
342 at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel); 354 at32_add_device_pwm(1 << PWM_BL_CH);
343 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); 355 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
344 at32_add_device_mci(0, &mci0_data); 356 at32_add_device_mci(0, &mci0_data);
345 at32_add_device_usba(0, NULL); 357 at32_add_device_usba(0, NULL);
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
index ed137e335796..83d896cc2aed 100644
--- a/arch/avr32/boards/merisc/setup.c
+++ b/arch/avr32/boards/merisc/setup.c
@@ -22,6 +22,8 @@
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/fb.h> 23#include <linux/fb.h>
24#include <linux/atmel-mci.h> 24#include <linux/atmel-mci.h>
25#include <linux/pwm.h>
26#include <linux/leds_pwm.h>
25 27
26#include <asm/io.h> 28#include <asm/io.h>
27#include <asm/setup.h> 29#include <asm/setup.h>
@@ -167,24 +169,29 @@ static struct i2c_board_info __initdata i2c_info[] = {
167 }, 169 },
168}; 170};
169 171
170#ifdef CONFIG_LEDS_ATMEL_PWM 172#if IS_ENABLED(CONFIG_LEDS_PWM)
171static struct gpio_led stk_pwm_led[] = { 173static struct pwm_lookup pwm_lookup[] = {
174 PWM_LOOKUP("at91sam9rl-pwm", 0, "leds_pwm", "backlight",
175 5000, PWM_POLARITY_NORMAL),
176};
177
178static struct led_pwm pwm_leds[] = {
172 { 179 {
173 .name = "backlight", 180 .name = "backlight",
174 .gpio = 0, /* PWM channel 0 (LCD backlight) */ 181 .max_brightness = 255,
175 }, 182 },
176}; 183};
177 184
178static struct gpio_led_platform_data stk_pwm_led_data = { 185static struct led_pwm_platform_data pwm_data = {
179 .num_leds = ARRAY_SIZE(stk_pwm_led), 186 .num_leds = ARRAY_SIZE(pwm_leds),
180 .leds = stk_pwm_led, 187 .leds = pwm_leds,
181}; 188};
182 189
183static struct platform_device stk_pwm_led_dev = { 190static struct platform_device leds_pwm = {
184 .name = "leds-atmel-pwm", 191 .name = "leds_pwm",
185 .id = -1, 192 .id = -1,
186 .dev = { 193 .dev = {
187 .platform_data = &stk_pwm_led_data, 194 .platform_data = &pwm_data,
188 }, 195 },
189}; 196};
190#endif 197#endif
@@ -278,9 +285,10 @@ static int __init merisc_init(void)
278 285
279 at32_add_device_mci(0, &mci0_data); 286 at32_add_device_mci(0, &mci0_data);
280 287
281#ifdef CONFIG_LEDS_ATMEL_PWM 288#if IS_ENABLED(CONFIG_LEDS_PWM)
289 pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
282 at32_add_device_pwm((1 << 0) | (1 << 2)); 290 at32_add_device_pwm((1 << 0) | (1 << 2));
283 platform_device_register(&stk_pwm_led_dev); 291 platform_device_register(&leds_pwm);
284#else 292#else
285 at32_add_device_pwm((1 << 2)); 293 at32_add_device_pwm((1 << 2));
286#endif 294#endif
diff --git a/arch/avr32/configs/atngw100_mrmt_defconfig b/arch/avr32/configs/atngw100_mrmt_defconfig
index 9a57da44eb6f..6838781e966f 100644
--- a/arch/avr32/configs/atngw100_mrmt_defconfig
+++ b/arch/avr32/configs/atngw100_mrmt_defconfig
@@ -56,7 +56,6 @@ CONFIG_MTD_CFI_AMDSTD=y
56CONFIG_MTD_PHYSMAP=y 56CONFIG_MTD_PHYSMAP=y
57CONFIG_MTD_DATAFLASH=y 57CONFIG_MTD_DATAFLASH=y
58CONFIG_BLK_DEV_LOOP=y 58CONFIG_BLK_DEV_LOOP=y
59CONFIG_ATMEL_PWM=y
60CONFIG_NETDEVICES=y 59CONFIG_NETDEVICES=y
61CONFIG_NET_ETHERNET=y 60CONFIG_NET_ETHERNET=y
62CONFIG_MACB=y 61CONFIG_MACB=y
@@ -104,8 +103,8 @@ CONFIG_MMC=y
104CONFIG_MMC_ATMELMCI=y 103CONFIG_MMC_ATMELMCI=y
105CONFIG_NEW_LEDS=y 104CONFIG_NEW_LEDS=y
106CONFIG_LEDS_CLASS=y 105CONFIG_LEDS_CLASS=y
107CONFIG_LEDS_ATMEL_PWM=y
108CONFIG_LEDS_GPIO=y 106CONFIG_LEDS_GPIO=y
107CONFIG_LEDS_PWM=y
109CONFIG_LEDS_TRIGGERS=y 108CONFIG_LEDS_TRIGGERS=y
110CONFIG_LEDS_TRIGGER_TIMER=y 109CONFIG_LEDS_TRIGGER_TIMER=y
111CONFIG_LEDS_TRIGGER_HEARTBEAT=y 110CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -114,6 +113,8 @@ CONFIG_RTC_DRV_S35390A=m
114CONFIG_RTC_DRV_AT32AP700X=m 113CONFIG_RTC_DRV_AT32AP700X=m
115CONFIG_DMADEVICES=y 114CONFIG_DMADEVICES=y
116CONFIG_UIO=y 115CONFIG_UIO=y
116CONFIG_PWM=y
117CONFIG_PWM_ATMEL=y
117CONFIG_EXT2_FS=y 118CONFIG_EXT2_FS=y
118CONFIG_EXT2_FS_XATTR=y 119CONFIG_EXT2_FS_XATTR=y
119CONFIG_EXT3_FS=y 120CONFIG_EXT3_FS=y
diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig
index 2813dd2b9138..b056820eef33 100644
--- a/arch/avr32/configs/atstk1002_defconfig
+++ b/arch/avr32/configs/atstk1002_defconfig
@@ -64,7 +64,6 @@ CONFIG_BLK_DEV_LOOP=m
64CONFIG_BLK_DEV_NBD=m 64CONFIG_BLK_DEV_NBD=m
65CONFIG_BLK_DEV_RAM=m 65CONFIG_BLK_DEV_RAM=m
66CONFIG_MISC_DEVICES=y 66CONFIG_MISC_DEVICES=y
67CONFIG_ATMEL_PWM=m
68CONFIG_ATMEL_TCLIB=y 67CONFIG_ATMEL_TCLIB=y
69CONFIG_ATMEL_SSC=m 68CONFIG_ATMEL_SSC=m
70# CONFIG_SCSI_PROC_FS is not set 69# CONFIG_SCSI_PROC_FS is not set
@@ -133,14 +132,16 @@ CONFIG_MMC_TEST=m
133CONFIG_MMC_ATMELMCI=y 132CONFIG_MMC_ATMELMCI=y
134CONFIG_NEW_LEDS=y 133CONFIG_NEW_LEDS=y
135CONFIG_LEDS_CLASS=y 134CONFIG_LEDS_CLASS=y
136CONFIG_LEDS_ATMEL_PWM=m
137CONFIG_LEDS_GPIO=m 135CONFIG_LEDS_GPIO=m
136CONFIG_LEDS_PWM=m
138CONFIG_LEDS_TRIGGERS=y 137CONFIG_LEDS_TRIGGERS=y
139CONFIG_LEDS_TRIGGER_TIMER=m 138CONFIG_LEDS_TRIGGER_TIMER=m
140CONFIG_LEDS_TRIGGER_HEARTBEAT=m 139CONFIG_LEDS_TRIGGER_HEARTBEAT=m
141CONFIG_RTC_CLASS=y 140CONFIG_RTC_CLASS=y
142CONFIG_RTC_DRV_AT32AP700X=y 141CONFIG_RTC_DRV_AT32AP700X=y
143CONFIG_DMADEVICES=y 142CONFIG_DMADEVICES=y
143CONFIG_PWM=y
144CONFIG_PWM_ATMEL=m
144CONFIG_EXT2_FS=y 145CONFIG_EXT2_FS=y
145CONFIG_EXT3_FS=y 146CONFIG_EXT3_FS=y
146# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set 147# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
diff --git a/arch/avr32/configs/atstk1003_defconfig b/arch/avr32/configs/atstk1003_defconfig
index f8ff3a3baad4..0cd23a303da1 100644
--- a/arch/avr32/configs/atstk1003_defconfig
+++ b/arch/avr32/configs/atstk1003_defconfig
@@ -53,7 +53,6 @@ CONFIG_BLK_DEV_LOOP=m
53CONFIG_BLK_DEV_NBD=m 53CONFIG_BLK_DEV_NBD=m
54CONFIG_BLK_DEV_RAM=m 54CONFIG_BLK_DEV_RAM=m
55CONFIG_MISC_DEVICES=y 55CONFIG_MISC_DEVICES=y
56CONFIG_ATMEL_PWM=m
57CONFIG_ATMEL_TCLIB=y 56CONFIG_ATMEL_TCLIB=y
58CONFIG_ATMEL_SSC=m 57CONFIG_ATMEL_SSC=m
59# CONFIG_SCSI_PROC_FS is not set 58# CONFIG_SCSI_PROC_FS is not set
@@ -112,14 +111,16 @@ CONFIG_MMC_TEST=m
112CONFIG_MMC_ATMELMCI=y 111CONFIG_MMC_ATMELMCI=y
113CONFIG_NEW_LEDS=y 112CONFIG_NEW_LEDS=y
114CONFIG_LEDS_CLASS=y 113CONFIG_LEDS_CLASS=y
115CONFIG_LEDS_ATMEL_PWM=m
116CONFIG_LEDS_GPIO=m 114CONFIG_LEDS_GPIO=m
115CONFIG_LEDS_PWM=m
117CONFIG_LEDS_TRIGGERS=y 116CONFIG_LEDS_TRIGGERS=y
118CONFIG_LEDS_TRIGGER_TIMER=m 117CONFIG_LEDS_TRIGGER_TIMER=m
119CONFIG_LEDS_TRIGGER_HEARTBEAT=m 118CONFIG_LEDS_TRIGGER_HEARTBEAT=m
120CONFIG_RTC_CLASS=y 119CONFIG_RTC_CLASS=y
121CONFIG_RTC_DRV_AT32AP700X=y 120CONFIG_RTC_DRV_AT32AP700X=y
122CONFIG_DMADEVICES=y 121CONFIG_DMADEVICES=y
122CONFIG_PWM=y
123CONFIG_PWM_ATMEL=m
123CONFIG_EXT2_FS=y 124CONFIG_EXT2_FS=y
124CONFIG_EXT3_FS=y 125CONFIG_EXT3_FS=y
125# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set 126# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
diff --git a/arch/avr32/configs/atstk1004_defconfig b/arch/avr32/configs/atstk1004_defconfig
index 992228e54e38..ac1041f5f85a 100644
--- a/arch/avr32/configs/atstk1004_defconfig
+++ b/arch/avr32/configs/atstk1004_defconfig
@@ -53,7 +53,6 @@ CONFIG_BLK_DEV_LOOP=m
53CONFIG_BLK_DEV_NBD=m 53CONFIG_BLK_DEV_NBD=m
54CONFIG_BLK_DEV_RAM=m 54CONFIG_BLK_DEV_RAM=m
55CONFIG_MISC_DEVICES=y 55CONFIG_MISC_DEVICES=y
56CONFIG_ATMEL_PWM=m
57CONFIG_ATMEL_TCLIB=y 56CONFIG_ATMEL_TCLIB=y
58CONFIG_ATMEL_SSC=m 57CONFIG_ATMEL_SSC=m
59# CONFIG_SCSI_PROC_FS is not set 58# CONFIG_SCSI_PROC_FS is not set
@@ -111,14 +110,16 @@ CONFIG_MMC_TEST=m
111CONFIG_MMC_ATMELMCI=y 110CONFIG_MMC_ATMELMCI=y
112CONFIG_NEW_LEDS=y 111CONFIG_NEW_LEDS=y
113CONFIG_LEDS_CLASS=y 112CONFIG_LEDS_CLASS=y
114CONFIG_LEDS_ATMEL_PWM=m
115CONFIG_LEDS_GPIO=m 113CONFIG_LEDS_GPIO=m
114CONFIG_LEDS_PWM=m
116CONFIG_LEDS_TRIGGERS=y 115CONFIG_LEDS_TRIGGERS=y
117CONFIG_LEDS_TRIGGER_TIMER=m 116CONFIG_LEDS_TRIGGER_TIMER=m
118CONFIG_LEDS_TRIGGER_HEARTBEAT=m 117CONFIG_LEDS_TRIGGER_HEARTBEAT=m
119CONFIG_RTC_CLASS=y 118CONFIG_RTC_CLASS=y
120CONFIG_RTC_DRV_AT32AP700X=y 119CONFIG_RTC_DRV_AT32AP700X=y
121CONFIG_DMADEVICES=y 120CONFIG_DMADEVICES=y
121CONFIG_PWM=y
122CONFIG_PWM_ATMEL=m
122CONFIG_EXT2_FS=y 123CONFIG_EXT2_FS=y
123CONFIG_EXT3_FS=y 124CONFIG_EXT3_FS=y
124# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set 125# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
diff --git a/arch/avr32/configs/atstk1006_defconfig b/arch/avr32/configs/atstk1006_defconfig
index b8e698b0d1fa..ea4f670cb995 100644
--- a/arch/avr32/configs/atstk1006_defconfig
+++ b/arch/avr32/configs/atstk1006_defconfig
@@ -67,7 +67,6 @@ CONFIG_BLK_DEV_LOOP=m
67CONFIG_BLK_DEV_NBD=m 67CONFIG_BLK_DEV_NBD=m
68CONFIG_BLK_DEV_RAM=m 68CONFIG_BLK_DEV_RAM=m
69CONFIG_MISC_DEVICES=y 69CONFIG_MISC_DEVICES=y
70CONFIG_ATMEL_PWM=m
71CONFIG_ATMEL_TCLIB=y 70CONFIG_ATMEL_TCLIB=y
72CONFIG_ATMEL_SSC=m 71CONFIG_ATMEL_SSC=m
73# CONFIG_SCSI_PROC_FS is not set 72# CONFIG_SCSI_PROC_FS is not set
@@ -136,14 +135,16 @@ CONFIG_MMC_TEST=m
136CONFIG_MMC_ATMELMCI=y 135CONFIG_MMC_ATMELMCI=y
137CONFIG_NEW_LEDS=y 136CONFIG_NEW_LEDS=y
138CONFIG_LEDS_CLASS=y 137CONFIG_LEDS_CLASS=y
139CONFIG_LEDS_ATMEL_PWM=m
140CONFIG_LEDS_GPIO=m 138CONFIG_LEDS_GPIO=m
139CONFIG_LEDS_PWM=m
141CONFIG_LEDS_TRIGGERS=y 140CONFIG_LEDS_TRIGGERS=y
142CONFIG_LEDS_TRIGGER_TIMER=m 141CONFIG_LEDS_TRIGGER_TIMER=m
143CONFIG_LEDS_TRIGGER_HEARTBEAT=m 142CONFIG_LEDS_TRIGGER_HEARTBEAT=m
144CONFIG_RTC_CLASS=y 143CONFIG_RTC_CLASS=y
145CONFIG_RTC_DRV_AT32AP700X=y 144CONFIG_RTC_DRV_AT32AP700X=y
146CONFIG_DMADEVICES=y 145CONFIG_DMADEVICES=y
146CONFIG_PWM=y
147CONFIG_PWM_ATMEL=m
147CONFIG_EXT2_FS=y 148CONFIG_EXT2_FS=y
148CONFIG_EXT3_FS=y 149CONFIG_EXT3_FS=y
149# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set 150# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig
index 07bed3f7eb5e..b3eb67dc05ac 100644
--- a/arch/avr32/configs/favr-32_defconfig
+++ b/arch/avr32/configs/favr-32_defconfig
@@ -67,7 +67,6 @@ CONFIG_MTD_PHYSMAP=y
67CONFIG_BLK_DEV_LOOP=m 67CONFIG_BLK_DEV_LOOP=m
68CONFIG_BLK_DEV_NBD=m 68CONFIG_BLK_DEV_NBD=m
69CONFIG_BLK_DEV_RAM=m 69CONFIG_BLK_DEV_RAM=m
70CONFIG_ATMEL_PWM=m
71CONFIG_ATMEL_TCLIB=y 70CONFIG_ATMEL_TCLIB=y
72CONFIG_ATMEL_SSC=m 71CONFIG_ATMEL_SSC=m
73CONFIG_NETDEVICES=y 72CONFIG_NETDEVICES=y
@@ -108,7 +107,7 @@ CONFIG_FB=y
108CONFIG_FB_ATMEL=y 107CONFIG_FB_ATMEL=y
109CONFIG_BACKLIGHT_LCD_SUPPORT=y 108CONFIG_BACKLIGHT_LCD_SUPPORT=y
110# CONFIG_LCD_CLASS_DEVICE is not set 109# CONFIG_LCD_CLASS_DEVICE is not set
111CONFIG_BACKLIGHT_ATMEL_PWM=m 110CONFIG_BACKLIGHT_PWM=m
112CONFIG_SOUND=m 111CONFIG_SOUND=m
113CONFIG_SOUND_PRIME=m 112CONFIG_SOUND_PRIME=m
114# CONFIG_HID_SUPPORT is not set 113# CONFIG_HID_SUPPORT is not set
@@ -123,7 +122,6 @@ CONFIG_MMC=y
123CONFIG_MMC_ATMELMCI=y 122CONFIG_MMC_ATMELMCI=y
124CONFIG_NEW_LEDS=y 123CONFIG_NEW_LEDS=y
125CONFIG_LEDS_CLASS=y 124CONFIG_LEDS_CLASS=y
126CONFIG_LEDS_ATMEL_PWM=m
127CONFIG_LEDS_GPIO=y 125CONFIG_LEDS_GPIO=y
128CONFIG_LEDS_TRIGGERS=y 126CONFIG_LEDS_TRIGGERS=y
129CONFIG_LEDS_TRIGGER_TIMER=y 127CONFIG_LEDS_TRIGGER_TIMER=y
@@ -132,6 +130,8 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
132CONFIG_RTC_CLASS=y 130CONFIG_RTC_CLASS=y
133CONFIG_RTC_DRV_AT32AP700X=y 131CONFIG_RTC_DRV_AT32AP700X=y
134CONFIG_DMADEVICES=y 132CONFIG_DMADEVICES=y
133CONFIG_PWM=y
134CONFIG_PWM_ATMEL=y
135CONFIG_EXT2_FS=y 135CONFIG_EXT2_FS=y
136CONFIG_EXT3_FS=y 136CONFIG_EXT3_FS=y
137# CONFIG_EXT3_FS_XATTR is not set 137# CONFIG_EXT3_FS_XATTR is not set
diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig
index 91df6b2986be..b9ef4cc85d08 100644
--- a/arch/avr32/configs/merisc_defconfig
+++ b/arch/avr32/configs/merisc_defconfig
@@ -55,7 +55,6 @@ CONFIG_MTD_ABSENT=y
55CONFIG_MTD_PHYSMAP=y 55CONFIG_MTD_PHYSMAP=y
56CONFIG_MTD_BLOCK2MTD=y 56CONFIG_MTD_BLOCK2MTD=y
57CONFIG_BLK_DEV_LOOP=y 57CONFIG_BLK_DEV_LOOP=y
58CONFIG_ATMEL_PWM=y
59CONFIG_ATMEL_SSC=y 58CONFIG_ATMEL_SSC=y
60CONFIG_SCSI=y 59CONFIG_SCSI=y
61CONFIG_BLK_DEV_SD=y 60CONFIG_BLK_DEV_SD=y
@@ -103,12 +102,14 @@ CONFIG_MMC=y
103CONFIG_MMC_ATMELMCI=y 102CONFIG_MMC_ATMELMCI=y
104CONFIG_NEW_LEDS=y 103CONFIG_NEW_LEDS=y
105CONFIG_LEDS_CLASS=y 104CONFIG_LEDS_CLASS=y
106CONFIG_LEDS_ATMEL_PWM=y 105CONFIG_LEDS_PWM=y
107CONFIG_RTC_CLASS=y 106CONFIG_RTC_CLASS=y
108# CONFIG_RTC_HCTOSYS is not set 107# CONFIG_RTC_HCTOSYS is not set
109CONFIG_RTC_DRV_PCF8563=y 108CONFIG_RTC_DRV_PCF8563=y
110CONFIG_DMADEVICES=y 109CONFIG_DMADEVICES=y
111CONFIG_UIO=y 110CONFIG_UIO=y
111CONFIG_PWM=y
112CONFIG_PWM_ATMEL=m
112CONFIG_EXT2_FS=y 113CONFIG_EXT2_FS=y
113# CONFIG_DNOTIFY is not set 114# CONFIG_DNOTIFY is not set
114CONFIG_FUSE_FS=y 115CONFIG_FUSE_FS=y
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index a1f4d1e91b52..db85b5ec3351 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -1553,7 +1553,7 @@ static struct resource atmel_pwm0_resource[] __initdata = {
1553 IRQ(24), 1553 IRQ(24),
1554}; 1554};
1555static struct clk atmel_pwm0_mck = { 1555static struct clk atmel_pwm0_mck = {
1556 .name = "pwm_clk", 1556 .name = "at91sam9rl-pwm",
1557 .parent = &pbb_clk, 1557 .parent = &pbb_clk,
1558 .mode = pbb_clk_mode, 1558 .mode = pbb_clk_mode,
1559 .get_rate = pbb_clk_get_rate, 1559 .get_rate = pbb_clk_get_rate,
@@ -1568,7 +1568,7 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
1568 if (!mask) 1568 if (!mask)
1569 return NULL; 1569 return NULL;
1570 1570
1571 pdev = platform_device_alloc("atmel_pwm", 0); 1571 pdev = platform_device_alloc("at91sam9rl-pwm", 0);
1572 if (!pdev) 1572 if (!pdev)
1573 return NULL; 1573 return NULL;
1574 1574
@@ -1576,9 +1576,6 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
1576 ARRAY_SIZE(atmel_pwm0_resource))) 1576 ARRAY_SIZE(atmel_pwm0_resource)))
1577 goto out_free_pdev; 1577 goto out_free_pdev;
1578 1578
1579 if (platform_device_add_data(pdev, &mask, sizeof(mask)))
1580 goto out_free_pdev;
1581
1582 pin_mask = 0; 1579 pin_mask = 0;
1583 if (mask & (1 << 0)) 1580 if (mask & (1 << 0))
1584 pin_mask |= (1 << 28); 1581 pin_mask |= (1 << 28);
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 1f37d9870e7a..603eb1be4f6a 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -50,6 +50,14 @@ config ARM_CCI
50 Driver supporting the CCI cache coherent interconnect for ARM 50 Driver supporting the CCI cache coherent interconnect for ARM
51 platforms. 51 platforms.
52 52
53config ARM_CCN
54 bool "ARM CCN driver support"
55 depends on ARM || ARM64
56 depends on PERF_EVENTS
57 help
58 PMU (perf) driver supporting the ARM CCN (Cache Coherent Network)
59 interconnect.
60
53config VEXPRESS_CONFIG 61config VEXPRESS_CONFIG
54 bool "Versatile Express configuration bus" 62 bool "Versatile Express configuration bus"
55 default y if ARCH_VEXPRESS 63 default y if ARCH_VEXPRESS
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 6a4ea7e4af1a..2973c18cbcc2 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -9,7 +9,9 @@ obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
9 9
10# Interconnect bus driver for OMAP SoCs. 10# Interconnect bus driver for OMAP SoCs.
11obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o 11obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o
12# CCI cache coherent interconnect for ARM platforms 12
13# Interconnect bus drivers for ARM platforms
13obj-$(CONFIG_ARM_CCI) += arm-cci.o 14obj-$(CONFIG_ARM_CCI) += arm-cci.o
15obj-$(CONFIG_ARM_CCN) += arm-ccn.o
14 16
15obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o 17obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c
new file mode 100644
index 000000000000..3266f8ff9311
--- /dev/null
+++ b/drivers/bus/arm-ccn.c
@@ -0,0 +1,1391 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2014 ARM Limited
12 */
13
14#include <linux/ctype.h>
15#include <linux/hrtimer.h>
16#include <linux/idr.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/perf_event.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23
24#define CCN_NUM_XP_PORTS 2
25#define CCN_NUM_VCS 4
26#define CCN_NUM_REGIONS 256
27#define CCN_REGION_SIZE 0x10000
28
29#define CCN_ALL_OLY_ID 0xff00
30#define CCN_ALL_OLY_ID__OLY_ID__SHIFT 0
31#define CCN_ALL_OLY_ID__OLY_ID__MASK 0x1f
32#define CCN_ALL_OLY_ID__NODE_ID__SHIFT 8
33#define CCN_ALL_OLY_ID__NODE_ID__MASK 0x3f
34
35#define CCN_MN_ERRINT_STATUS 0x0008
36#define CCN_MN_ERRINT_STATUS__INTREQ__DESSERT 0x11
37#define CCN_MN_ERRINT_STATUS__ALL_ERRORS__ENABLE 0x02
38#define CCN_MN_ERRINT_STATUS__ALL_ERRORS__DISABLED 0x20
39#define CCN_MN_ERRINT_STATUS__ALL_ERRORS__DISABLE 0x22
40#define CCN_MN_ERRINT_STATUS__CORRECTED_ERRORS_ENABLE 0x04
41#define CCN_MN_ERRINT_STATUS__CORRECTED_ERRORS_DISABLED 0x40
42#define CCN_MN_ERRINT_STATUS__CORRECTED_ERRORS_DISABLE 0x44
43#define CCN_MN_ERRINT_STATUS__PMU_EVENTS__ENABLE 0x08
44#define CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLED 0x80
45#define CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE 0x88
46#define CCN_MN_OLY_COMP_LIST_63_0 0x01e0
47#define CCN_MN_ERR_SIG_VAL_63_0 0x0300
48#define CCN_MN_ERR_SIG_VAL_63_0__DT (1 << 1)
49
50#define CCN_DT_ACTIVE_DSM 0x0000
51#define CCN_DT_ACTIVE_DSM__DSM_ID__SHIFT(n) ((n) * 8)
52#define CCN_DT_ACTIVE_DSM__DSM_ID__MASK 0xff
53#define CCN_DT_CTL 0x0028
54#define CCN_DT_CTL__DT_EN (1 << 0)
55#define CCN_DT_PMEVCNT(n) (0x0100 + (n) * 0x8)
56#define CCN_DT_PMCCNTR 0x0140
57#define CCN_DT_PMCCNTRSR 0x0190
58#define CCN_DT_PMOVSR 0x0198
59#define CCN_DT_PMOVSR_CLR 0x01a0
60#define CCN_DT_PMCR 0x01a8
61#define CCN_DT_PMCR__OVFL_INTR_EN (1 << 6)
62#define CCN_DT_PMCR__PMU_EN (1 << 0)
63#define CCN_DT_PMSR 0x01b0
64#define CCN_DT_PMSR_REQ 0x01b8
65#define CCN_DT_PMSR_CLR 0x01c0
66
67#define CCN_HNF_PMU_EVENT_SEL 0x0600
68#define CCN_HNF_PMU_EVENT_SEL__ID__SHIFT(n) ((n) * 4)
69#define CCN_HNF_PMU_EVENT_SEL__ID__MASK 0xf
70
71#define CCN_XP_DT_CONFIG 0x0300
72#define CCN_XP_DT_CONFIG__DT_CFG__SHIFT(n) ((n) * 4)
73#define CCN_XP_DT_CONFIG__DT_CFG__MASK 0xf
74#define CCN_XP_DT_CONFIG__DT_CFG__PASS_THROUGH 0x0
75#define CCN_XP_DT_CONFIG__DT_CFG__WATCHPOINT_0_OR_1 0x1
76#define CCN_XP_DT_CONFIG__DT_CFG__WATCHPOINT(n) (0x2 + (n))
77#define CCN_XP_DT_CONFIG__DT_CFG__XP_PMU_EVENT(n) (0x4 + (n))
78#define CCN_XP_DT_CONFIG__DT_CFG__DEVICE_PMU_EVENT(d, n) (0x8 + (d) * 4 + (n))
79#define CCN_XP_DT_INTERFACE_SEL 0x0308
80#define CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__SHIFT(n) (0 + (n) * 8)
81#define CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__MASK 0x1
82#define CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__SHIFT(n) (1 + (n) * 8)
83#define CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__MASK 0x1
84#define CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__SHIFT(n) (2 + (n) * 8)
85#define CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__MASK 0x3
86#define CCN_XP_DT_CMP_VAL_L(n) (0x0310 + (n) * 0x40)
87#define CCN_XP_DT_CMP_VAL_H(n) (0x0318 + (n) * 0x40)
88#define CCN_XP_DT_CMP_MASK_L(n) (0x0320 + (n) * 0x40)
89#define CCN_XP_DT_CMP_MASK_H(n) (0x0328 + (n) * 0x40)
90#define CCN_XP_DT_CONTROL 0x0370
91#define CCN_XP_DT_CONTROL__DT_ENABLE (1 << 0)
92#define CCN_XP_DT_CONTROL__WP_ARM_SEL__SHIFT(n) (12 + (n) * 4)
93#define CCN_XP_DT_CONTROL__WP_ARM_SEL__MASK 0xf
94#define CCN_XP_DT_CONTROL__WP_ARM_SEL__ALWAYS 0xf
95#define CCN_XP_PMU_EVENT_SEL 0x0600
96#define CCN_XP_PMU_EVENT_SEL__ID__SHIFT(n) ((n) * 7)
97#define CCN_XP_PMU_EVENT_SEL__ID__MASK 0x3f
98
99#define CCN_SBAS_PMU_EVENT_SEL 0x0600
100#define CCN_SBAS_PMU_EVENT_SEL__ID__SHIFT(n) ((n) * 4)
101#define CCN_SBAS_PMU_EVENT_SEL__ID__MASK 0xf
102
103#define CCN_RNI_PMU_EVENT_SEL 0x0600
104#define CCN_RNI_PMU_EVENT_SEL__ID__SHIFT(n) ((n) * 4)
105#define CCN_RNI_PMU_EVENT_SEL__ID__MASK 0xf
106
107#define CCN_TYPE_MN 0x01
108#define CCN_TYPE_DT 0x02
109#define CCN_TYPE_HNF 0x04
110#define CCN_TYPE_HNI 0x05
111#define CCN_TYPE_XP 0x08
112#define CCN_TYPE_SBSX 0x0c
113#define CCN_TYPE_SBAS 0x10
114#define CCN_TYPE_RNI_1P 0x14
115#define CCN_TYPE_RNI_2P 0x15
116#define CCN_TYPE_RNI_3P 0x16
117#define CCN_TYPE_RND_1P 0x18 /* RN-D = RN-I + DVM */
118#define CCN_TYPE_RND_2P 0x19
119#define CCN_TYPE_RND_3P 0x1a
120#define CCN_TYPE_CYCLES 0xff /* Pseudotype */
121
122#define CCN_EVENT_WATCHPOINT 0xfe /* Pseudoevent */
123
124#define CCN_NUM_PMU_EVENTS 4
125#define CCN_NUM_XP_WATCHPOINTS 2 /* See DT.dbg_id.num_watchpoints */
126#define CCN_NUM_PMU_EVENT_COUNTERS 8 /* See DT.dbg_id.num_pmucntr */
127#define CCN_IDX_PMU_CYCLE_COUNTER CCN_NUM_PMU_EVENT_COUNTERS
128
129#define CCN_NUM_PREDEFINED_MASKS 4
130#define CCN_IDX_MASK_ANY (CCN_NUM_PMU_EVENT_COUNTERS + 0)
131#define CCN_IDX_MASK_EXACT (CCN_NUM_PMU_EVENT_COUNTERS + 1)
132#define CCN_IDX_MASK_ORDER (CCN_NUM_PMU_EVENT_COUNTERS + 2)
133#define CCN_IDX_MASK_OPCODE (CCN_NUM_PMU_EVENT_COUNTERS + 3)
134
135struct arm_ccn_component {
136 void __iomem *base;
137 u32 type;
138
139 DECLARE_BITMAP(pmu_events_mask, CCN_NUM_PMU_EVENTS);
140 union {
141 struct {
142 DECLARE_BITMAP(dt_cmp_mask, CCN_NUM_XP_WATCHPOINTS);
143 } xp;
144 };
145};
146
147#define pmu_to_arm_ccn(_pmu) container_of(container_of(_pmu, \
148 struct arm_ccn_dt, pmu), struct arm_ccn, dt)
149
150struct arm_ccn_dt {
151 int id;
152 void __iomem *base;
153
154 spinlock_t config_lock;
155
156 DECLARE_BITMAP(pmu_counters_mask, CCN_NUM_PMU_EVENT_COUNTERS + 1);
157 struct {
158 struct arm_ccn_component *source;
159 struct perf_event *event;
160 } pmu_counters[CCN_NUM_PMU_EVENT_COUNTERS + 1];
161
162 struct {
163 u64 l, h;
164 } cmp_mask[CCN_NUM_PMU_EVENT_COUNTERS + CCN_NUM_PREDEFINED_MASKS];
165
166 struct hrtimer hrtimer;
167
168 struct pmu pmu;
169};
170
171struct arm_ccn {
172 struct device *dev;
173 void __iomem *base;
174 unsigned irq_used:1;
175 unsigned sbas_present:1;
176 unsigned sbsx_present:1;
177
178 int num_nodes;
179 struct arm_ccn_component *node;
180
181 int num_xps;
182 struct arm_ccn_component *xp;
183
184 struct arm_ccn_dt dt;
185};
186
187
188static int arm_ccn_node_to_xp(int node)
189{
190 return node / CCN_NUM_XP_PORTS;
191}
192
193static int arm_ccn_node_to_xp_port(int node)
194{
195 return node % CCN_NUM_XP_PORTS;
196}
197
198
199/*
200 * Bit shifts and masks in these defines must be kept in sync with
201 * arm_ccn_pmu_config_set() and CCN_FORMAT_ATTRs below!
202 */
203#define CCN_CONFIG_NODE(_config) (((_config) >> 0) & 0xff)
204#define CCN_CONFIG_XP(_config) (((_config) >> 0) & 0xff)
205#define CCN_CONFIG_TYPE(_config) (((_config) >> 8) & 0xff)
206#define CCN_CONFIG_EVENT(_config) (((_config) >> 16) & 0xff)
207#define CCN_CONFIG_PORT(_config) (((_config) >> 24) & 0x3)
208#define CCN_CONFIG_VC(_config) (((_config) >> 26) & 0x7)
209#define CCN_CONFIG_DIR(_config) (((_config) >> 29) & 0x1)
210#define CCN_CONFIG_MASK(_config) (((_config) >> 30) & 0xf)
211
212static void arm_ccn_pmu_config_set(u64 *config, u32 node_xp, u32 type, u32 port)
213{
214 *config &= ~((0xff << 0) | (0xff << 8) | (0xff << 24));
215 *config |= (node_xp << 0) | (type << 8) | (port << 24);
216}
217
218static ssize_t arm_ccn_pmu_format_show(struct device *dev,
219 struct device_attribute *attr, char *buf)
220{
221 struct dev_ext_attribute *ea = container_of(attr,
222 struct dev_ext_attribute, attr);
223
224 return snprintf(buf, PAGE_SIZE, "%s\n", (char *)ea->var);
225}
226
227#define CCN_FORMAT_ATTR(_name, _config) \
228 struct dev_ext_attribute arm_ccn_pmu_format_attr_##_name = \
229 { __ATTR(_name, S_IRUGO, arm_ccn_pmu_format_show, \
230 NULL), _config }
231
232static CCN_FORMAT_ATTR(node, "config:0-7");
233static CCN_FORMAT_ATTR(xp, "config:0-7");
234static CCN_FORMAT_ATTR(type, "config:8-15");
235static CCN_FORMAT_ATTR(event, "config:16-23");
236static CCN_FORMAT_ATTR(port, "config:24-25");
237static CCN_FORMAT_ATTR(vc, "config:26-28");
238static CCN_FORMAT_ATTR(dir, "config:29-29");
239static CCN_FORMAT_ATTR(mask, "config:30-33");
240static CCN_FORMAT_ATTR(cmp_l, "config1:0-62");
241static CCN_FORMAT_ATTR(cmp_h, "config2:0-59");
242
243static struct attribute *arm_ccn_pmu_format_attrs[] = {
244 &arm_ccn_pmu_format_attr_node.attr.attr,
245 &arm_ccn_pmu_format_attr_xp.attr.attr,
246 &arm_ccn_pmu_format_attr_type.attr.attr,
247 &arm_ccn_pmu_format_attr_event.attr.attr,
248 &arm_ccn_pmu_format_attr_port.attr.attr,
249 &arm_ccn_pmu_format_attr_vc.attr.attr,
250 &arm_ccn_pmu_format_attr_dir.attr.attr,
251 &arm_ccn_pmu_format_attr_mask.attr.attr,
252 &arm_ccn_pmu_format_attr_cmp_l.attr.attr,
253 &arm_ccn_pmu_format_attr_cmp_h.attr.attr,
254 NULL
255};
256
257static struct attribute_group arm_ccn_pmu_format_attr_group = {
258 .name = "format",
259 .attrs = arm_ccn_pmu_format_attrs,
260};
261
262
263struct arm_ccn_pmu_event {
264 struct device_attribute attr;
265 u32 type;
266 u32 event;
267 int num_ports;
268 int num_vcs;
269 const char *def;
270 int mask;
271};
272
273#define CCN_EVENT_ATTR(_name) \
274 __ATTR(_name, S_IRUGO, arm_ccn_pmu_event_show, NULL)
275
276/*
277 * Events defined in TRM for MN, HN-I and SBSX are actually watchpoints set on
278 * their ports in XP they are connected to. For the sake of usability they are
279 * explicitly defined here (and translated into a relevant watchpoint in
280 * arm_ccn_pmu_event_init()) so the user can easily request them without deep
281 * knowledge of the flit format.
282 */
283
284#define CCN_EVENT_MN(_name, _def, _mask) { .attr = CCN_EVENT_ATTR(mn_##_name), \
285 .type = CCN_TYPE_MN, .event = CCN_EVENT_WATCHPOINT, \
286 .num_ports = CCN_NUM_XP_PORTS, .num_vcs = CCN_NUM_VCS, \
287 .def = _def, .mask = _mask, }
288
289#define CCN_EVENT_HNI(_name, _def, _mask) { \
290 .attr = CCN_EVENT_ATTR(hni_##_name), .type = CCN_TYPE_HNI, \
291 .event = CCN_EVENT_WATCHPOINT, .num_ports = CCN_NUM_XP_PORTS, \
292 .num_vcs = CCN_NUM_VCS, .def = _def, .mask = _mask, }
293
294#define CCN_EVENT_SBSX(_name, _def, _mask) { \
295 .attr = CCN_EVENT_ATTR(sbsx_##_name), .type = CCN_TYPE_SBSX, \
296 .event = CCN_EVENT_WATCHPOINT, .num_ports = CCN_NUM_XP_PORTS, \
297 .num_vcs = CCN_NUM_VCS, .def = _def, .mask = _mask, }
298
299#define CCN_EVENT_HNF(_name, _event) { .attr = CCN_EVENT_ATTR(hnf_##_name), \
300 .type = CCN_TYPE_HNF, .event = _event, }
301
302#define CCN_EVENT_XP(_name, _event) { .attr = CCN_EVENT_ATTR(xp_##_name), \
303 .type = CCN_TYPE_XP, .event = _event, \
304 .num_ports = CCN_NUM_XP_PORTS, .num_vcs = CCN_NUM_VCS, }
305
306/*
307 * RN-I & RN-D (RN-D = RN-I + DVM) nodes have different type ID depending
308 * on configuration. One of them is picked to represent the whole group,
309 * as they all share the same event types.
310 */
311#define CCN_EVENT_RNI(_name, _event) { .attr = CCN_EVENT_ATTR(rni_##_name), \
312 .type = CCN_TYPE_RNI_3P, .event = _event, }
313
314#define CCN_EVENT_SBAS(_name, _event) { .attr = CCN_EVENT_ATTR(sbas_##_name), \
315 .type = CCN_TYPE_SBAS, .event = _event, }
316
317#define CCN_EVENT_CYCLES(_name) { .attr = CCN_EVENT_ATTR(_name), \
318 .type = CCN_TYPE_CYCLES }
319
320
321static ssize_t arm_ccn_pmu_event_show(struct device *dev,
322 struct device_attribute *attr, char *buf)
323{
324 struct arm_ccn_pmu_event *event = container_of(attr,
325 struct arm_ccn_pmu_event, attr);
326 ssize_t res;
327
328 res = snprintf(buf, PAGE_SIZE, "type=0x%x", event->type);
329 if (event->event)
330 res += snprintf(buf + res, PAGE_SIZE - res, ",event=0x%x",
331 event->event);
332 if (event->def)
333 res += snprintf(buf + res, PAGE_SIZE - res, ",%s",
334 event->def);
335 if (event->mask)
336 res += snprintf(buf + res, PAGE_SIZE - res, ",mask=0x%x",
337 event->mask);
338 res += snprintf(buf + res, PAGE_SIZE - res, "\n");
339
340 return res;
341}
342
343static umode_t arm_ccn_pmu_events_is_visible(struct kobject *kobj,
344 struct attribute *attr, int index)
345{
346 struct device *dev = kobj_to_dev(kobj);
347 struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
348 struct device_attribute *dev_attr = container_of(attr,
349 struct device_attribute, attr);
350 struct arm_ccn_pmu_event *event = container_of(dev_attr,
351 struct arm_ccn_pmu_event, attr);
352
353 if (event->type == CCN_TYPE_SBAS && !ccn->sbas_present)
354 return 0;
355 if (event->type == CCN_TYPE_SBSX && !ccn->sbsx_present)
356 return 0;
357
358 return attr->mode;
359}
360
361static struct arm_ccn_pmu_event arm_ccn_pmu_events[] = {
362 CCN_EVENT_MN(eobarrier, "dir=0,vc=0,cmp_h=0x1c00", CCN_IDX_MASK_OPCODE),
363 CCN_EVENT_MN(ecbarrier, "dir=0,vc=0,cmp_h=0x1e00", CCN_IDX_MASK_OPCODE),
364 CCN_EVENT_MN(dvmop, "dir=0,vc=0,cmp_h=0x2800", CCN_IDX_MASK_OPCODE),
365 CCN_EVENT_HNI(txdatflits, "dir=1,vc=3", CCN_IDX_MASK_ANY),
366 CCN_EVENT_HNI(rxdatflits, "dir=0,vc=3", CCN_IDX_MASK_ANY),
367 CCN_EVENT_HNI(txreqflits, "dir=1,vc=0", CCN_IDX_MASK_ANY),
368 CCN_EVENT_HNI(rxreqflits, "dir=0,vc=0", CCN_IDX_MASK_ANY),
369 CCN_EVENT_HNI(rxreqflits_order, "dir=0,vc=0,cmp_h=0x8000",
370 CCN_IDX_MASK_ORDER),
371 CCN_EVENT_SBSX(txdatflits, "dir=1,vc=3", CCN_IDX_MASK_ANY),
372 CCN_EVENT_SBSX(rxdatflits, "dir=0,vc=3", CCN_IDX_MASK_ANY),
373 CCN_EVENT_SBSX(txreqflits, "dir=1,vc=0", CCN_IDX_MASK_ANY),
374 CCN_EVENT_SBSX(rxreqflits, "dir=0,vc=0", CCN_IDX_MASK_ANY),
375 CCN_EVENT_SBSX(rxreqflits_order, "dir=0,vc=0,cmp_h=0x8000",
376 CCN_IDX_MASK_ORDER),
377 CCN_EVENT_HNF(cache_miss, 0x1),
378 CCN_EVENT_HNF(l3_sf_cache_access, 0x02),
379 CCN_EVENT_HNF(cache_fill, 0x3),
380 CCN_EVENT_HNF(pocq_retry, 0x4),
381 CCN_EVENT_HNF(pocq_reqs_recvd, 0x5),
382 CCN_EVENT_HNF(sf_hit, 0x6),
383 CCN_EVENT_HNF(sf_evictions, 0x7),
384 CCN_EVENT_HNF(snoops_sent, 0x8),
385 CCN_EVENT_HNF(snoops_broadcast, 0x9),
386 CCN_EVENT_HNF(l3_eviction, 0xa),
387 CCN_EVENT_HNF(l3_fill_invalid_way, 0xb),
388 CCN_EVENT_HNF(mc_retries, 0xc),
389 CCN_EVENT_HNF(mc_reqs, 0xd),
390 CCN_EVENT_HNF(qos_hh_retry, 0xe),
391 CCN_EVENT_RNI(rdata_beats_p0, 0x1),
392 CCN_EVENT_RNI(rdata_beats_p1, 0x2),
393 CCN_EVENT_RNI(rdata_beats_p2, 0x3),
394 CCN_EVENT_RNI(rxdat_flits, 0x4),
395 CCN_EVENT_RNI(txdat_flits, 0x5),
396 CCN_EVENT_RNI(txreq_flits, 0x6),
397 CCN_EVENT_RNI(txreq_flits_retried, 0x7),
398 CCN_EVENT_RNI(rrt_full, 0x8),
399 CCN_EVENT_RNI(wrt_full, 0x9),
400 CCN_EVENT_RNI(txreq_flits_replayed, 0xa),
401 CCN_EVENT_XP(upload_starvation, 0x1),
402 CCN_EVENT_XP(download_starvation, 0x2),
403 CCN_EVENT_XP(respin, 0x3),
404 CCN_EVENT_XP(valid_flit, 0x4),
405 CCN_EVENT_XP(watchpoint, CCN_EVENT_WATCHPOINT),
406 CCN_EVENT_SBAS(rdata_beats_p0, 0x1),
407 CCN_EVENT_SBAS(rxdat_flits, 0x4),
408 CCN_EVENT_SBAS(txdat_flits, 0x5),
409 CCN_EVENT_SBAS(txreq_flits, 0x6),
410 CCN_EVENT_SBAS(txreq_flits_retried, 0x7),
411 CCN_EVENT_SBAS(rrt_full, 0x8),
412 CCN_EVENT_SBAS(wrt_full, 0x9),
413 CCN_EVENT_SBAS(txreq_flits_replayed, 0xa),
414 CCN_EVENT_CYCLES(cycles),
415};
416
417/* Populated in arm_ccn_init() */
418static struct attribute
419 *arm_ccn_pmu_events_attrs[ARRAY_SIZE(arm_ccn_pmu_events) + 1];
420
421static struct attribute_group arm_ccn_pmu_events_attr_group = {
422 .name = "events",
423 .is_visible = arm_ccn_pmu_events_is_visible,
424 .attrs = arm_ccn_pmu_events_attrs,
425};
426
427
428static u64 *arm_ccn_pmu_get_cmp_mask(struct arm_ccn *ccn, const char *name)
429{
430 unsigned long i;
431
432 if (WARN_ON(!name || !name[0] || !isxdigit(name[0]) || !name[1]))
433 return NULL;
434 i = isdigit(name[0]) ? name[0] - '0' : 0xa + tolower(name[0]) - 'a';
435
436 switch (name[1]) {
437 case 'l':
438 return &ccn->dt.cmp_mask[i].l;
439 case 'h':
440 return &ccn->dt.cmp_mask[i].h;
441 default:
442 return NULL;
443 }
444}
445
446static ssize_t arm_ccn_pmu_cmp_mask_show(struct device *dev,
447 struct device_attribute *attr, char *buf)
448{
449 struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
450 u64 *mask = arm_ccn_pmu_get_cmp_mask(ccn, attr->attr.name);
451
452 return mask ? snprintf(buf, PAGE_SIZE, "0x%016llx\n", *mask) : -EINVAL;
453}
454
455static ssize_t arm_ccn_pmu_cmp_mask_store(struct device *dev,
456 struct device_attribute *attr, const char *buf, size_t count)
457{
458 struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
459 u64 *mask = arm_ccn_pmu_get_cmp_mask(ccn, attr->attr.name);
460 int err = -EINVAL;
461
462 if (mask)
463 err = kstrtoull(buf, 0, mask);
464
465 return err ? err : count;
466}
467
468#define CCN_CMP_MASK_ATTR(_name) \
469 struct device_attribute arm_ccn_pmu_cmp_mask_attr_##_name = \
470 __ATTR(_name, S_IRUGO | S_IWUSR, \
471 arm_ccn_pmu_cmp_mask_show, arm_ccn_pmu_cmp_mask_store)
472
473#define CCN_CMP_MASK_ATTR_RO(_name) \
474 struct device_attribute arm_ccn_pmu_cmp_mask_attr_##_name = \
475 __ATTR(_name, S_IRUGO, arm_ccn_pmu_cmp_mask_show, NULL)
476
477static CCN_CMP_MASK_ATTR(0l);
478static CCN_CMP_MASK_ATTR(0h);
479static CCN_CMP_MASK_ATTR(1l);
480static CCN_CMP_MASK_ATTR(1h);
481static CCN_CMP_MASK_ATTR(2l);
482static CCN_CMP_MASK_ATTR(2h);
483static CCN_CMP_MASK_ATTR(3l);
484static CCN_CMP_MASK_ATTR(3h);
485static CCN_CMP_MASK_ATTR(4l);
486static CCN_CMP_MASK_ATTR(4h);
487static CCN_CMP_MASK_ATTR(5l);
488static CCN_CMP_MASK_ATTR(5h);
489static CCN_CMP_MASK_ATTR(6l);
490static CCN_CMP_MASK_ATTR(6h);
491static CCN_CMP_MASK_ATTR(7l);
492static CCN_CMP_MASK_ATTR(7h);
493static CCN_CMP_MASK_ATTR_RO(8l);
494static CCN_CMP_MASK_ATTR_RO(8h);
495static CCN_CMP_MASK_ATTR_RO(9l);
496static CCN_CMP_MASK_ATTR_RO(9h);
497static CCN_CMP_MASK_ATTR_RO(al);
498static CCN_CMP_MASK_ATTR_RO(ah);
499static CCN_CMP_MASK_ATTR_RO(bl);
500static CCN_CMP_MASK_ATTR_RO(bh);
501
502static struct attribute *arm_ccn_pmu_cmp_mask_attrs[] = {
503 &arm_ccn_pmu_cmp_mask_attr_0l.attr, &arm_ccn_pmu_cmp_mask_attr_0h.attr,
504 &arm_ccn_pmu_cmp_mask_attr_1l.attr, &arm_ccn_pmu_cmp_mask_attr_1h.attr,
505 &arm_ccn_pmu_cmp_mask_attr_2l.attr, &arm_ccn_pmu_cmp_mask_attr_2h.attr,
506 &arm_ccn_pmu_cmp_mask_attr_3l.attr, &arm_ccn_pmu_cmp_mask_attr_3h.attr,
507 &arm_ccn_pmu_cmp_mask_attr_4l.attr, &arm_ccn_pmu_cmp_mask_attr_4h.attr,
508 &arm_ccn_pmu_cmp_mask_attr_5l.attr, &arm_ccn_pmu_cmp_mask_attr_5h.attr,
509 &arm_ccn_pmu_cmp_mask_attr_6l.attr, &arm_ccn_pmu_cmp_mask_attr_6h.attr,
510 &arm_ccn_pmu_cmp_mask_attr_7l.attr, &arm_ccn_pmu_cmp_mask_attr_7h.attr,
511 &arm_ccn_pmu_cmp_mask_attr_8l.attr, &arm_ccn_pmu_cmp_mask_attr_8h.attr,
512 &arm_ccn_pmu_cmp_mask_attr_9l.attr, &arm_ccn_pmu_cmp_mask_attr_9h.attr,
513 &arm_ccn_pmu_cmp_mask_attr_al.attr, &arm_ccn_pmu_cmp_mask_attr_ah.attr,
514 &arm_ccn_pmu_cmp_mask_attr_bl.attr, &arm_ccn_pmu_cmp_mask_attr_bh.attr,
515 NULL
516};
517
518static struct attribute_group arm_ccn_pmu_cmp_mask_attr_group = {
519 .name = "cmp_mask",
520 .attrs = arm_ccn_pmu_cmp_mask_attrs,
521};
522
523
524/*
525 * Default poll period is 10ms, which is way over the top anyway,
526 * as in the worst case scenario (an event every cycle), with 1GHz
527 * clocked bus, the smallest, 32 bit counter will overflow in
528 * more than 4s.
529 */
530static unsigned int arm_ccn_pmu_poll_period_us = 10000;
531module_param_named(pmu_poll_period_us, arm_ccn_pmu_poll_period_us, uint,
532 S_IRUGO | S_IWUSR);
533
534static ktime_t arm_ccn_pmu_timer_period(void)
535{
536 return ns_to_ktime((u64)arm_ccn_pmu_poll_period_us * 1000);
537}
538
539
540static const struct attribute_group *arm_ccn_pmu_attr_groups[] = {
541 &arm_ccn_pmu_events_attr_group,
542 &arm_ccn_pmu_format_attr_group,
543 &arm_ccn_pmu_cmp_mask_attr_group,
544 NULL
545};
546
547
548static int arm_ccn_pmu_alloc_bit(unsigned long *bitmap, unsigned long size)
549{
550 int bit;
551
552 do {
553 bit = find_first_zero_bit(bitmap, size);
554 if (bit >= size)
555 return -EAGAIN;
556 } while (test_and_set_bit(bit, bitmap));
557
558 return bit;
559}
560
561/* All RN-I and RN-D nodes have identical PMUs */
562static int arm_ccn_pmu_type_eq(u32 a, u32 b)
563{
564 if (a == b)
565 return 1;
566
567 switch (a) {
568 case CCN_TYPE_RNI_1P:
569 case CCN_TYPE_RNI_2P:
570 case CCN_TYPE_RNI_3P:
571 case CCN_TYPE_RND_1P:
572 case CCN_TYPE_RND_2P:
573 case CCN_TYPE_RND_3P:
574 switch (b) {
575 case CCN_TYPE_RNI_1P:
576 case CCN_TYPE_RNI_2P:
577 case CCN_TYPE_RNI_3P:
578 case CCN_TYPE_RND_1P:
579 case CCN_TYPE_RND_2P:
580 case CCN_TYPE_RND_3P:
581 return 1;
582 }
583 break;
584 }
585
586 return 0;
587}
588
589static int arm_ccn_pmu_event_init(struct perf_event *event)
590{
591 struct arm_ccn *ccn;
592 struct hw_perf_event *hw = &event->hw;
593 u32 node_xp, type, event_id;
594 int valid, bit;
595 struct arm_ccn_component *source;
596 int i;
597
598 if (event->attr.type != event->pmu->type)
599 return -ENOENT;
600
601 ccn = pmu_to_arm_ccn(event->pmu);
602
603 if (hw->sample_period) {
604 dev_warn(ccn->dev, "Sampling not supported!\n");
605 return -EOPNOTSUPP;
606 }
607
608 if (has_branch_stack(event) || event->attr.exclude_user ||
609 event->attr.exclude_kernel || event->attr.exclude_hv ||
610 event->attr.exclude_idle) {
611 dev_warn(ccn->dev, "Can't exclude execution levels!\n");
612 return -EOPNOTSUPP;
613 }
614
615 if (event->cpu < 0) {
616 dev_warn(ccn->dev, "Can't provide per-task data!\n");
617 return -EOPNOTSUPP;
618 }
619
620 node_xp = CCN_CONFIG_NODE(event->attr.config);
621 type = CCN_CONFIG_TYPE(event->attr.config);
622 event_id = CCN_CONFIG_EVENT(event->attr.config);
623
624 /* Validate node/xp vs topology */
625 switch (type) {
626 case CCN_TYPE_XP:
627 if (node_xp >= ccn->num_xps) {
628 dev_warn(ccn->dev, "Invalid XP ID %d!\n", node_xp);
629 return -EINVAL;
630 }
631 break;
632 case CCN_TYPE_CYCLES:
633 break;
634 default:
635 if (node_xp >= ccn->num_nodes) {
636 dev_warn(ccn->dev, "Invalid node ID %d!\n", node_xp);
637 return -EINVAL;
638 }
639 if (!arm_ccn_pmu_type_eq(type, ccn->node[node_xp].type)) {
640 dev_warn(ccn->dev, "Invalid type 0x%x for node %d!\n",
641 type, node_xp);
642 return -EINVAL;
643 }
644 break;
645 }
646
647 /* Validate event ID vs available for the type */
648 for (i = 0, valid = 0; i < ARRAY_SIZE(arm_ccn_pmu_events) && !valid;
649 i++) {
650 struct arm_ccn_pmu_event *e = &arm_ccn_pmu_events[i];
651 u32 port = CCN_CONFIG_PORT(event->attr.config);
652 u32 vc = CCN_CONFIG_VC(event->attr.config);
653
654 if (!arm_ccn_pmu_type_eq(type, e->type))
655 continue;
656 if (event_id != e->event)
657 continue;
658 if (e->num_ports && port >= e->num_ports) {
659 dev_warn(ccn->dev, "Invalid port %d for node/XP %d!\n",
660 port, node_xp);
661 return -EINVAL;
662 }
663 if (e->num_vcs && vc >= e->num_vcs) {
664 dev_warn(ccn->dev, "Invalid vc %d for node/XP %d!\n",
665 port, node_xp);
666 return -EINVAL;
667 }
668 valid = 1;
669 }
670 if (!valid) {
671 dev_warn(ccn->dev, "Invalid event 0x%x for node/XP %d!\n",
672 event_id, node_xp);
673 return -EINVAL;
674 }
675
676 /* Watchpoint-based event for a node is actually set on XP */
677 if (event_id == CCN_EVENT_WATCHPOINT && type != CCN_TYPE_XP) {
678 u32 port;
679
680 type = CCN_TYPE_XP;
681 port = arm_ccn_node_to_xp_port(node_xp);
682 node_xp = arm_ccn_node_to_xp(node_xp);
683
684 arm_ccn_pmu_config_set(&event->attr.config,
685 node_xp, type, port);
686 }
687
688 /* Allocate the cycle counter */
689 if (type == CCN_TYPE_CYCLES) {
690 if (test_and_set_bit(CCN_IDX_PMU_CYCLE_COUNTER,
691 ccn->dt.pmu_counters_mask))
692 return -EAGAIN;
693
694 hw->idx = CCN_IDX_PMU_CYCLE_COUNTER;
695 ccn->dt.pmu_counters[CCN_IDX_PMU_CYCLE_COUNTER].event = event;
696
697 return 0;
698 }
699
700 /* Allocate an event counter */
701 hw->idx = arm_ccn_pmu_alloc_bit(ccn->dt.pmu_counters_mask,
702 CCN_NUM_PMU_EVENT_COUNTERS);
703 if (hw->idx < 0) {
704 dev_warn(ccn->dev, "No more counters available!\n");
705 return -EAGAIN;
706 }
707
708 if (type == CCN_TYPE_XP)
709 source = &ccn->xp[node_xp];
710 else
711 source = &ccn->node[node_xp];
712 ccn->dt.pmu_counters[hw->idx].source = source;
713
714 /* Allocate an event source or a watchpoint */
715 if (type == CCN_TYPE_XP && event_id == CCN_EVENT_WATCHPOINT)
716 bit = arm_ccn_pmu_alloc_bit(source->xp.dt_cmp_mask,
717 CCN_NUM_XP_WATCHPOINTS);
718 else
719 bit = arm_ccn_pmu_alloc_bit(source->pmu_events_mask,
720 CCN_NUM_PMU_EVENTS);
721 if (bit < 0) {
722 dev_warn(ccn->dev, "No more event sources/watchpoints on node/XP %d!\n",
723 node_xp);
724 clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
725 return -EAGAIN;
726 }
727 hw->config_base = bit;
728
729 ccn->dt.pmu_counters[hw->idx].event = event;
730
731 return 0;
732}
733
734static void arm_ccn_pmu_event_free(struct perf_event *event)
735{
736 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
737 struct hw_perf_event *hw = &event->hw;
738
739 if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) {
740 clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask);
741 } else {
742 struct arm_ccn_component *source =
743 ccn->dt.pmu_counters[hw->idx].source;
744
745 if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP &&
746 CCN_CONFIG_EVENT(event->attr.config) ==
747 CCN_EVENT_WATCHPOINT)
748 clear_bit(hw->config_base, source->xp.dt_cmp_mask);
749 else
750 clear_bit(hw->config_base, source->pmu_events_mask);
751 clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
752 }
753
754 ccn->dt.pmu_counters[hw->idx].source = NULL;
755 ccn->dt.pmu_counters[hw->idx].event = NULL;
756}
757
758static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx)
759{
760 u64 res;
761
762 if (idx == CCN_IDX_PMU_CYCLE_COUNTER) {
763#ifdef readq
764 res = readq(ccn->dt.base + CCN_DT_PMCCNTR);
765#else
766 /* 40 bit counter, can do snapshot and read in two parts */
767 writel(0x1, ccn->dt.base + CCN_DT_PMSR_REQ);
768 while (!(readl(ccn->dt.base + CCN_DT_PMSR) & 0x1))
769 ;
770 writel(0x1, ccn->dt.base + CCN_DT_PMSR_CLR);
771 res = readl(ccn->dt.base + CCN_DT_PMCCNTRSR + 4) & 0xff;
772 res <<= 32;
773 res |= readl(ccn->dt.base + CCN_DT_PMCCNTRSR);
774#endif
775 } else {
776 res = readl(ccn->dt.base + CCN_DT_PMEVCNT(idx));
777 }
778
779 return res;
780}
781
782static void arm_ccn_pmu_event_update(struct perf_event *event)
783{
784 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
785 struct hw_perf_event *hw = &event->hw;
786 u64 prev_count, new_count, mask;
787
788 do {
789 prev_count = local64_read(&hw->prev_count);
790 new_count = arm_ccn_pmu_read_counter(ccn, hw->idx);
791 } while (local64_xchg(&hw->prev_count, new_count) != prev_count);
792
793 mask = (1LLU << (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER ? 40 : 32)) - 1;
794
795 local64_add((new_count - prev_count) & mask, &event->count);
796}
797
798static void arm_ccn_pmu_xp_dt_config(struct perf_event *event, int enable)
799{
800 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
801 struct hw_perf_event *hw = &event->hw;
802 struct arm_ccn_component *xp;
803 u32 val, dt_cfg;
804
805 if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP)
806 xp = &ccn->xp[CCN_CONFIG_XP(event->attr.config)];
807 else
808 xp = &ccn->xp[arm_ccn_node_to_xp(
809 CCN_CONFIG_NODE(event->attr.config))];
810
811 if (enable)
812 dt_cfg = hw->event_base;
813 else
814 dt_cfg = CCN_XP_DT_CONFIG__DT_CFG__PASS_THROUGH;
815
816 spin_lock(&ccn->dt.config_lock);
817
818 val = readl(xp->base + CCN_XP_DT_CONFIG);
819 val &= ~(CCN_XP_DT_CONFIG__DT_CFG__MASK <<
820 CCN_XP_DT_CONFIG__DT_CFG__SHIFT(hw->idx));
821 val |= dt_cfg << CCN_XP_DT_CONFIG__DT_CFG__SHIFT(hw->idx);
822 writel(val, xp->base + CCN_XP_DT_CONFIG);
823
824 spin_unlock(&ccn->dt.config_lock);
825}
826
827static void arm_ccn_pmu_event_start(struct perf_event *event, int flags)
828{
829 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
830 struct hw_perf_event *hw = &event->hw;
831
832 local64_set(&event->hw.prev_count,
833 arm_ccn_pmu_read_counter(ccn, hw->idx));
834 hw->state = 0;
835
836 if (!ccn->irq_used)
837 hrtimer_start(&ccn->dt.hrtimer, arm_ccn_pmu_timer_period(),
838 HRTIMER_MODE_REL);
839
840 /* Set the DT bus input, engaging the counter */
841 arm_ccn_pmu_xp_dt_config(event, 1);
842}
843
844static void arm_ccn_pmu_event_stop(struct perf_event *event, int flags)
845{
846 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
847 struct hw_perf_event *hw = &event->hw;
848 u64 timeout;
849
850 /* Disable counting, setting the DT bus to pass-through mode */
851 arm_ccn_pmu_xp_dt_config(event, 0);
852
853 if (!ccn->irq_used)
854 hrtimer_cancel(&ccn->dt.hrtimer);
855
856 /* Let the DT bus drain */
857 timeout = arm_ccn_pmu_read_counter(ccn, CCN_IDX_PMU_CYCLE_COUNTER) +
858 ccn->num_xps;
859 while (arm_ccn_pmu_read_counter(ccn, CCN_IDX_PMU_CYCLE_COUNTER) <
860 timeout)
861 cpu_relax();
862
863 if (flags & PERF_EF_UPDATE)
864 arm_ccn_pmu_event_update(event);
865
866 hw->state |= PERF_HES_STOPPED;
867}
868
869static void arm_ccn_pmu_xp_watchpoint_config(struct perf_event *event)
870{
871 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
872 struct hw_perf_event *hw = &event->hw;
873 struct arm_ccn_component *source =
874 ccn->dt.pmu_counters[hw->idx].source;
875 unsigned long wp = hw->config_base;
876 u32 val;
877 u64 cmp_l = event->attr.config1;
878 u64 cmp_h = event->attr.config2;
879 u64 mask_l = ccn->dt.cmp_mask[CCN_CONFIG_MASK(event->attr.config)].l;
880 u64 mask_h = ccn->dt.cmp_mask[CCN_CONFIG_MASK(event->attr.config)].h;
881
882 hw->event_base = CCN_XP_DT_CONFIG__DT_CFG__WATCHPOINT(wp);
883
884 /* Direction (RX/TX), device (port) & virtual channel */
885 val = readl(source->base + CCN_XP_DT_INTERFACE_SEL);
886 val &= ~(CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__MASK <<
887 CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__SHIFT(wp));
888 val |= CCN_CONFIG_DIR(event->attr.config) <<
889 CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__SHIFT(wp);
890 val &= ~(CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__MASK <<
891 CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__SHIFT(wp));
892 val |= CCN_CONFIG_PORT(event->attr.config) <<
893 CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__SHIFT(wp);
894 val &= ~(CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__MASK <<
895 CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__SHIFT(wp));
896 val |= CCN_CONFIG_VC(event->attr.config) <<
897 CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__SHIFT(wp);
898 writel(val, source->base + CCN_XP_DT_INTERFACE_SEL);
899
900 /* Comparison values */
901 writel(cmp_l & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_L(wp));
902 writel((cmp_l >> 32) & 0xefffffff,
903 source->base + CCN_XP_DT_CMP_VAL_L(wp) + 4);
904 writel(cmp_h & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_H(wp));
905 writel((cmp_h >> 32) & 0x0fffffff,
906 source->base + CCN_XP_DT_CMP_VAL_H(wp) + 4);
907
908 /* Mask */
909 writel(mask_l & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_L(wp));
910 writel((mask_l >> 32) & 0xefffffff,
911 source->base + CCN_XP_DT_CMP_MASK_L(wp) + 4);
912 writel(mask_h & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_H(wp));
913 writel((mask_h >> 32) & 0x0fffffff,
914 source->base + CCN_XP_DT_CMP_MASK_H(wp) + 4);
915}
916
917static void arm_ccn_pmu_xp_event_config(struct perf_event *event)
918{
919 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
920 struct hw_perf_event *hw = &event->hw;
921 struct arm_ccn_component *source =
922 ccn->dt.pmu_counters[hw->idx].source;
923 u32 val, id;
924
925 hw->event_base = CCN_XP_DT_CONFIG__DT_CFG__XP_PMU_EVENT(hw->config_base);
926
927 id = (CCN_CONFIG_VC(event->attr.config) << 4) |
928 (CCN_CONFIG_PORT(event->attr.config) << 3) |
929 (CCN_CONFIG_EVENT(event->attr.config) << 0);
930
931 val = readl(source->base + CCN_XP_PMU_EVENT_SEL);
932 val &= ~(CCN_XP_PMU_EVENT_SEL__ID__MASK <<
933 CCN_XP_PMU_EVENT_SEL__ID__SHIFT(hw->config_base));
934 val |= id << CCN_XP_PMU_EVENT_SEL__ID__SHIFT(hw->config_base);
935 writel(val, source->base + CCN_XP_PMU_EVENT_SEL);
936}
937
938static void arm_ccn_pmu_node_event_config(struct perf_event *event)
939{
940 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
941 struct hw_perf_event *hw = &event->hw;
942 struct arm_ccn_component *source =
943 ccn->dt.pmu_counters[hw->idx].source;
944 u32 type = CCN_CONFIG_TYPE(event->attr.config);
945 u32 val, port;
946
947 port = arm_ccn_node_to_xp_port(CCN_CONFIG_NODE(event->attr.config));
948 hw->event_base = CCN_XP_DT_CONFIG__DT_CFG__DEVICE_PMU_EVENT(port,
949 hw->config_base);
950
951 /* These *_event_sel regs should be identical, but let's make sure... */
952 BUILD_BUG_ON(CCN_HNF_PMU_EVENT_SEL != CCN_SBAS_PMU_EVENT_SEL);
953 BUILD_BUG_ON(CCN_SBAS_PMU_EVENT_SEL != CCN_RNI_PMU_EVENT_SEL);
954 BUILD_BUG_ON(CCN_HNF_PMU_EVENT_SEL__ID__SHIFT(1) !=
955 CCN_SBAS_PMU_EVENT_SEL__ID__SHIFT(1));
956 BUILD_BUG_ON(CCN_SBAS_PMU_EVENT_SEL__ID__SHIFT(1) !=
957 CCN_RNI_PMU_EVENT_SEL__ID__SHIFT(1));
958 BUILD_BUG_ON(CCN_HNF_PMU_EVENT_SEL__ID__MASK !=
959 CCN_SBAS_PMU_EVENT_SEL__ID__MASK);
960 BUILD_BUG_ON(CCN_SBAS_PMU_EVENT_SEL__ID__MASK !=
961 CCN_RNI_PMU_EVENT_SEL__ID__MASK);
962 if (WARN_ON(type != CCN_TYPE_HNF && type != CCN_TYPE_SBAS &&
963 !arm_ccn_pmu_type_eq(type, CCN_TYPE_RNI_3P)))
964 return;
965
966 /* Set the event id for the pre-allocated counter */
967 val = readl(source->base + CCN_HNF_PMU_EVENT_SEL);
968 val &= ~(CCN_HNF_PMU_EVENT_SEL__ID__MASK <<
969 CCN_HNF_PMU_EVENT_SEL__ID__SHIFT(hw->config_base));
970 val |= CCN_CONFIG_EVENT(event->attr.config) <<
971 CCN_HNF_PMU_EVENT_SEL__ID__SHIFT(hw->config_base);
972 writel(val, source->base + CCN_HNF_PMU_EVENT_SEL);
973}
974
975static void arm_ccn_pmu_event_config(struct perf_event *event)
976{
977 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
978 struct hw_perf_event *hw = &event->hw;
979 u32 xp, offset, val;
980
981 /* Cycle counter requires no setup */
982 if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER)
983 return;
984
985 if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP)
986 xp = CCN_CONFIG_XP(event->attr.config);
987 else
988 xp = arm_ccn_node_to_xp(CCN_CONFIG_NODE(event->attr.config));
989
990 spin_lock(&ccn->dt.config_lock);
991
992 /* Set the DT bus "distance" register */
993 offset = (hw->idx / 4) * 4;
994 val = readl(ccn->dt.base + CCN_DT_ACTIVE_DSM + offset);
995 val &= ~(CCN_DT_ACTIVE_DSM__DSM_ID__MASK <<
996 CCN_DT_ACTIVE_DSM__DSM_ID__SHIFT(hw->idx % 4));
997 val |= xp << CCN_DT_ACTIVE_DSM__DSM_ID__SHIFT(hw->idx % 4);
998 writel(val, ccn->dt.base + CCN_DT_ACTIVE_DSM + offset);
999
1000 if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP) {
1001 if (CCN_CONFIG_EVENT(event->attr.config) ==
1002 CCN_EVENT_WATCHPOINT)
1003 arm_ccn_pmu_xp_watchpoint_config(event);
1004 else
1005 arm_ccn_pmu_xp_event_config(event);
1006 } else {
1007 arm_ccn_pmu_node_event_config(event);
1008 }
1009
1010 spin_unlock(&ccn->dt.config_lock);
1011}
1012
1013static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)
1014{
1015 struct hw_perf_event *hw = &event->hw;
1016
1017 arm_ccn_pmu_event_config(event);
1018
1019 hw->state = PERF_HES_STOPPED;
1020
1021 if (flags & PERF_EF_START)
1022 arm_ccn_pmu_event_start(event, PERF_EF_UPDATE);
1023
1024 return 0;
1025}
1026
1027static void arm_ccn_pmu_event_del(struct perf_event *event, int flags)
1028{
1029 arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE);
1030
1031 arm_ccn_pmu_event_free(event);
1032}
1033
1034static void arm_ccn_pmu_event_read(struct perf_event *event)
1035{
1036 arm_ccn_pmu_event_update(event);
1037}
1038
1039static irqreturn_t arm_ccn_pmu_overflow_handler(struct arm_ccn_dt *dt)
1040{
1041 u32 pmovsr = readl(dt->base + CCN_DT_PMOVSR);
1042 int idx;
1043
1044 if (!pmovsr)
1045 return IRQ_NONE;
1046
1047 writel(pmovsr, dt->base + CCN_DT_PMOVSR_CLR);
1048
1049 BUILD_BUG_ON(CCN_IDX_PMU_CYCLE_COUNTER != CCN_NUM_PMU_EVENT_COUNTERS);
1050
1051 for (idx = 0; idx < CCN_NUM_PMU_EVENT_COUNTERS + 1; idx++) {
1052 struct perf_event *event = dt->pmu_counters[idx].event;
1053 int overflowed = pmovsr & BIT(idx);
1054
1055 WARN_ON_ONCE(overflowed && !event);
1056
1057 if (!event || !overflowed)
1058 continue;
1059
1060 arm_ccn_pmu_event_update(event);
1061 }
1062
1063 return IRQ_HANDLED;
1064}
1065
1066static enum hrtimer_restart arm_ccn_pmu_timer_handler(struct hrtimer *hrtimer)
1067{
1068 struct arm_ccn_dt *dt = container_of(hrtimer, struct arm_ccn_dt,
1069 hrtimer);
1070 unsigned long flags;
1071
1072 local_irq_save(flags);
1073 arm_ccn_pmu_overflow_handler(dt);
1074 local_irq_restore(flags);
1075
1076 hrtimer_forward_now(hrtimer, arm_ccn_pmu_timer_period());
1077 return HRTIMER_RESTART;
1078}
1079
1080
1081static DEFINE_IDA(arm_ccn_pmu_ida);
1082
1083static int arm_ccn_pmu_init(struct arm_ccn *ccn)
1084{
1085 int i;
1086 char *name;
1087
1088 /* Initialize DT subsystem */
1089 ccn->dt.base = ccn->base + CCN_REGION_SIZE;
1090 spin_lock_init(&ccn->dt.config_lock);
1091 writel(CCN_DT_CTL__DT_EN, ccn->dt.base + CCN_DT_CTL);
1092 writel(CCN_DT_PMCR__OVFL_INTR_EN | CCN_DT_PMCR__PMU_EN,
1093 ccn->dt.base + CCN_DT_PMCR);
1094 writel(0x1, ccn->dt.base + CCN_DT_PMSR_CLR);
1095 for (i = 0; i < ccn->num_xps; i++) {
1096 writel(0, ccn->xp[i].base + CCN_XP_DT_CONFIG);
1097 writel((CCN_XP_DT_CONTROL__WP_ARM_SEL__ALWAYS <<
1098 CCN_XP_DT_CONTROL__WP_ARM_SEL__SHIFT(0)) |
1099 (CCN_XP_DT_CONTROL__WP_ARM_SEL__ALWAYS <<
1100 CCN_XP_DT_CONTROL__WP_ARM_SEL__SHIFT(1)) |
1101 CCN_XP_DT_CONTROL__DT_ENABLE,
1102 ccn->xp[i].base + CCN_XP_DT_CONTROL);
1103 }
1104 ccn->dt.cmp_mask[CCN_IDX_MASK_ANY].l = ~0;
1105 ccn->dt.cmp_mask[CCN_IDX_MASK_ANY].h = ~0;
1106 ccn->dt.cmp_mask[CCN_IDX_MASK_EXACT].l = 0;
1107 ccn->dt.cmp_mask[CCN_IDX_MASK_EXACT].h = 0;
1108 ccn->dt.cmp_mask[CCN_IDX_MASK_ORDER].l = ~0;
1109 ccn->dt.cmp_mask[CCN_IDX_MASK_ORDER].h = ~(0x1 << 15);
1110 ccn->dt.cmp_mask[CCN_IDX_MASK_OPCODE].l = ~0;
1111 ccn->dt.cmp_mask[CCN_IDX_MASK_OPCODE].h = ~(0x1f << 9);
1112
1113 /* Get a convenient /sys/event_source/devices/ name */
1114 ccn->dt.id = ida_simple_get(&arm_ccn_pmu_ida, 0, 0, GFP_KERNEL);
1115 if (ccn->dt.id == 0) {
1116 name = "ccn";
1117 } else {
1118 int len = snprintf(NULL, 0, "ccn_%d", ccn->dt.id);
1119
1120 name = devm_kzalloc(ccn->dev, len + 1, GFP_KERNEL);
1121 snprintf(name, len + 1, "ccn_%d", ccn->dt.id);
1122 }
1123
1124 /* Perf driver registration */
1125 ccn->dt.pmu = (struct pmu) {
1126 .attr_groups = arm_ccn_pmu_attr_groups,
1127 .task_ctx_nr = perf_invalid_context,
1128 .event_init = arm_ccn_pmu_event_init,
1129 .add = arm_ccn_pmu_event_add,
1130 .del = arm_ccn_pmu_event_del,
1131 .start = arm_ccn_pmu_event_start,
1132 .stop = arm_ccn_pmu_event_stop,
1133 .read = arm_ccn_pmu_event_read,
1134 };
1135
1136 /* No overflow interrupt? Have to use a timer instead. */
1137 if (!ccn->irq_used) {
1138 dev_info(ccn->dev, "No access to interrupts, using timer.\n");
1139 hrtimer_init(&ccn->dt.hrtimer, CLOCK_MONOTONIC,
1140 HRTIMER_MODE_REL);
1141 ccn->dt.hrtimer.function = arm_ccn_pmu_timer_handler;
1142 }
1143
1144 return perf_pmu_register(&ccn->dt.pmu, name, -1);
1145}
1146
1147static void arm_ccn_pmu_cleanup(struct arm_ccn *ccn)
1148{
1149 int i;
1150
1151 for (i = 0; i < ccn->num_xps; i++)
1152 writel(0, ccn->xp[i].base + CCN_XP_DT_CONTROL);
1153 writel(0, ccn->dt.base + CCN_DT_PMCR);
1154 perf_pmu_unregister(&ccn->dt.pmu);
1155 ida_simple_remove(&arm_ccn_pmu_ida, ccn->dt.id);
1156}
1157
1158
1159static int arm_ccn_for_each_valid_region(struct arm_ccn *ccn,
1160 int (*callback)(struct arm_ccn *ccn, int region,
1161 void __iomem *base, u32 type, u32 id))
1162{
1163 int region;
1164
1165 for (region = 0; region < CCN_NUM_REGIONS; region++) {
1166 u32 val, type, id;
1167 void __iomem *base;
1168 int err;
1169
1170 val = readl(ccn->base + CCN_MN_OLY_COMP_LIST_63_0 +
1171 4 * (region / 32));
1172 if (!(val & (1 << (region % 32))))
1173 continue;
1174
1175 base = ccn->base + region * CCN_REGION_SIZE;
1176 val = readl(base + CCN_ALL_OLY_ID);
1177 type = (val >> CCN_ALL_OLY_ID__OLY_ID__SHIFT) &
1178 CCN_ALL_OLY_ID__OLY_ID__MASK;
1179 id = (val >> CCN_ALL_OLY_ID__NODE_ID__SHIFT) &
1180 CCN_ALL_OLY_ID__NODE_ID__MASK;
1181
1182 err = callback(ccn, region, base, type, id);
1183 if (err)
1184 return err;
1185 }
1186
1187 return 0;
1188}
1189
1190static int arm_ccn_get_nodes_num(struct arm_ccn *ccn, int region,
1191 void __iomem *base, u32 type, u32 id)
1192{
1193
1194 if (type == CCN_TYPE_XP && id >= ccn->num_xps)
1195 ccn->num_xps = id + 1;
1196 else if (id >= ccn->num_nodes)
1197 ccn->num_nodes = id + 1;
1198
1199 return 0;
1200}
1201
1202static int arm_ccn_init_nodes(struct arm_ccn *ccn, int region,
1203 void __iomem *base, u32 type, u32 id)
1204{
1205 struct arm_ccn_component *component;
1206
1207 dev_dbg(ccn->dev, "Region %d: id=%u, type=0x%02x\n", region, id, type);
1208
1209 switch (type) {
1210 case CCN_TYPE_MN:
1211 case CCN_TYPE_DT:
1212 return 0;
1213 case CCN_TYPE_XP:
1214 component = &ccn->xp[id];
1215 break;
1216 case CCN_TYPE_SBSX:
1217 ccn->sbsx_present = 1;
1218 component = &ccn->node[id];
1219 break;
1220 case CCN_TYPE_SBAS:
1221 ccn->sbas_present = 1;
1222 /* Fall-through */
1223 default:
1224 component = &ccn->node[id];
1225 break;
1226 }
1227
1228 component->base = base;
1229 component->type = type;
1230
1231 return 0;
1232}
1233
1234
1235static irqreturn_t arm_ccn_error_handler(struct arm_ccn *ccn,
1236 const u32 *err_sig_val)
1237{
1238 /* This should be really handled by firmware... */
1239 dev_err(ccn->dev, "Error reported in %08x%08x%08x%08x%08x%08x.\n",
1240 err_sig_val[5], err_sig_val[4], err_sig_val[3],
1241 err_sig_val[2], err_sig_val[1], err_sig_val[0]);
1242 dev_err(ccn->dev, "Disabling interrupt generation for all errors.\n");
1243 writel(CCN_MN_ERRINT_STATUS__ALL_ERRORS__DISABLE,
1244 ccn->base + CCN_MN_ERRINT_STATUS);
1245
1246 return IRQ_HANDLED;
1247}
1248
1249
1250static irqreturn_t arm_ccn_irq_handler(int irq, void *dev_id)
1251{
1252 irqreturn_t res = IRQ_NONE;
1253 struct arm_ccn *ccn = dev_id;
1254 u32 err_sig_val[6];
1255 u32 err_or;
1256 int i;
1257
1258 /* PMU overflow is a special case */
1259 err_or = err_sig_val[0] = readl(ccn->base + CCN_MN_ERR_SIG_VAL_63_0);
1260 if (err_or & CCN_MN_ERR_SIG_VAL_63_0__DT) {
1261 err_or &= ~CCN_MN_ERR_SIG_VAL_63_0__DT;
1262 res = arm_ccn_pmu_overflow_handler(&ccn->dt);
1263 }
1264
1265 /* Have to read all err_sig_vals to clear them */
1266 for (i = 1; i < ARRAY_SIZE(err_sig_val); i++) {
1267 err_sig_val[i] = readl(ccn->base +
1268 CCN_MN_ERR_SIG_VAL_63_0 + i * 4);
1269 err_or |= err_sig_val[i];
1270 }
1271 if (err_or)
1272 res |= arm_ccn_error_handler(ccn, err_sig_val);
1273
1274 if (res != IRQ_NONE)
1275 writel(CCN_MN_ERRINT_STATUS__INTREQ__DESSERT,
1276 ccn->base + CCN_MN_ERRINT_STATUS);
1277
1278 return res;
1279}
1280
1281
1282static int arm_ccn_probe(struct platform_device *pdev)
1283{
1284 struct arm_ccn *ccn;
1285 struct resource *res;
1286 int err;
1287
1288 ccn = devm_kzalloc(&pdev->dev, sizeof(*ccn), GFP_KERNEL);
1289 if (!ccn)
1290 return -ENOMEM;
1291 ccn->dev = &pdev->dev;
1292 platform_set_drvdata(pdev, ccn);
1293
1294 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1295 if (!res)
1296 return -EINVAL;
1297
1298 if (!devm_request_mem_region(ccn->dev, res->start,
1299 resource_size(res), pdev->name))
1300 return -EBUSY;
1301
1302 ccn->base = devm_ioremap(ccn->dev, res->start,
1303 resource_size(res));
1304 if (!ccn->base)
1305 return -EFAULT;
1306
1307 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1308 if (!res)
1309 return -EINVAL;
1310
1311 /* Check if we can use the interrupt */
1312 writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE,
1313 ccn->base + CCN_MN_ERRINT_STATUS);
1314 if (readl(ccn->base + CCN_MN_ERRINT_STATUS) &
1315 CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLED) {
1316 /* Can set 'disable' bits, so can acknowledge interrupts */
1317 writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__ENABLE,
1318 ccn->base + CCN_MN_ERRINT_STATUS);
1319 err = devm_request_irq(ccn->dev, res->start,
1320 arm_ccn_irq_handler, 0, dev_name(ccn->dev),
1321 ccn);
1322 if (err)
1323 return err;
1324
1325 ccn->irq_used = 1;
1326 }
1327
1328
1329 /* Build topology */
1330
1331 err = arm_ccn_for_each_valid_region(ccn, arm_ccn_get_nodes_num);
1332 if (err)
1333 return err;
1334
1335 ccn->node = devm_kzalloc(ccn->dev, sizeof(*ccn->node) * ccn->num_nodes,
1336 GFP_KERNEL);
1337 ccn->xp = devm_kzalloc(ccn->dev, sizeof(*ccn->node) * ccn->num_xps,
1338 GFP_KERNEL);
1339 if (!ccn->node || !ccn->xp)
1340 return -ENOMEM;
1341
1342 err = arm_ccn_for_each_valid_region(ccn, arm_ccn_init_nodes);
1343 if (err)
1344 return err;
1345
1346 return arm_ccn_pmu_init(ccn);
1347}
1348
1349static int arm_ccn_remove(struct platform_device *pdev)
1350{
1351 struct arm_ccn *ccn = platform_get_drvdata(pdev);
1352
1353 arm_ccn_pmu_cleanup(ccn);
1354
1355 return 0;
1356}
1357
1358static const struct of_device_id arm_ccn_match[] = {
1359 { .compatible = "arm,ccn-504", },
1360 {},
1361};
1362
1363static struct platform_driver arm_ccn_driver = {
1364 .driver = {
1365 .name = "arm-ccn",
1366 .of_match_table = arm_ccn_match,
1367 },
1368 .probe = arm_ccn_probe,
1369 .remove = arm_ccn_remove,
1370};
1371
1372static int __init arm_ccn_init(void)
1373{
1374 int i;
1375
1376 for (i = 0; i < ARRAY_SIZE(arm_ccn_pmu_events); i++)
1377 arm_ccn_pmu_events_attrs[i] = &arm_ccn_pmu_events[i].attr.attr;
1378
1379 return platform_driver_register(&arm_ccn_driver);
1380}
1381
1382static void __exit arm_ccn_exit(void)
1383{
1384 platform_driver_unregister(&arm_ccn_driver);
1385}
1386
1387module_init(arm_ccn_init);
1388module_exit(arm_ccn_exit);
1389
1390MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
1391MODULE_LICENSE("GPL");
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 30e82860567a..8c96e2ddf43b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -32,14 +32,6 @@ config LEDS_88PM860X
32 This option enables support for on-chip LED drivers found on Marvell 32 This option enables support for on-chip LED drivers found on Marvell
33 Semiconductor 88PM8606 PMIC. 33 Semiconductor 88PM8606 PMIC.
34 34
35config LEDS_ATMEL_PWM
36 tristate "LED Support using Atmel PWM outputs"
37 depends on LEDS_CLASS
38 depends on ATMEL_PWM
39 help
40 This option enables support for LEDs driven using outputs
41 of the dedicated PWM controller found on newer Atmel SOCs.
42
43config LEDS_LM3530 35config LEDS_LM3530
44 tristate "LCD Backlight driver for LM3530" 36 tristate "LCD Backlight driver for LM3530"
45 depends on LEDS_CLASS 37 depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index b2a62959ff8f..d8cc5f2777de 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,7 +6,6 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
6 6
7# LED Platform Drivers 7# LED Platform Drivers
8obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o 8obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
9obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
10obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o 9obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
11obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o 10obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
12obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o 11obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
deleted file mode 100644
index 56cec8d6a2ac..000000000000
--- a/drivers/leds/leds-atmel-pwm.c
+++ /dev/null
@@ -1,149 +0,0 @@
1#include <linux/kernel.h>
2#include <linux/platform_device.h>
3#include <linux/leds.h>
4#include <linux/io.h>
5#include <linux/atmel_pwm.h>
6#include <linux/slab.h>
7#include <linux/module.h>
8
9
10struct pwmled {
11 struct led_classdev cdev;
12 struct pwm_channel pwmc;
13 struct gpio_led *desc;
14 u32 mult;
15 u8 active_low;
16};
17
18
19/*
20 * For simplicity, we use "brightness" as if it were a linear function
21 * of PWM duty cycle. However, a logarithmic function of duty cycle is
22 * probably a better match for perceived brightness: two is half as bright
23 * as four, four is half as bright as eight, etc
24 */
25static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
26{
27 struct pwmled *led;
28
29 /* update the duty cycle for the *next* period */
30 led = container_of(cdev, struct pwmled, cdev);
31 pwm_channel_writel(&led->pwmc, PWM_CUPD, led->mult * (unsigned) b);
32}
33
34/*
35 * NOTE: we reuse the platform_data structure of GPIO leds,
36 * but repurpose its "gpio" number as a PWM channel number.
37 */
38static int pwmled_probe(struct platform_device *pdev)
39{
40 const struct gpio_led_platform_data *pdata;
41 struct pwmled *leds;
42 int i;
43 int status;
44
45 pdata = dev_get_platdata(&pdev->dev);
46 if (!pdata || pdata->num_leds < 1)
47 return -ENODEV;
48
49 leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds),
50 GFP_KERNEL);
51 if (!leds)
52 return -ENOMEM;
53
54 for (i = 0; i < pdata->num_leds; i++) {
55 struct pwmled *led = leds + i;
56 const struct gpio_led *dat = pdata->leds + i;
57 u32 tmp;
58
59 led->cdev.name = dat->name;
60 led->cdev.brightness = LED_OFF;
61 led->cdev.brightness_set = pwmled_brightness;
62 led->cdev.default_trigger = dat->default_trigger;
63
64 led->active_low = dat->active_low;
65
66 status = pwm_channel_alloc(dat->gpio, &led->pwmc);
67 if (status < 0)
68 goto err;
69
70 /*
71 * Prescale clock by 2^x, so PWM counts in low MHz.
72 * Start each cycle with the LED active, so increasing
73 * the duty cycle gives us more time on (== brighter).
74 */
75 tmp = 5;
76 if (!led->active_low)
77 tmp |= PWM_CPR_CPOL;
78 pwm_channel_writel(&led->pwmc, PWM_CMR, tmp);
79
80 /*
81 * Pick a period so PWM cycles at 100+ Hz; and a multiplier
82 * for scaling duty cycle: brightness * mult.
83 */
84 tmp = (led->pwmc.mck / (1 << 5)) / 100;
85 tmp /= 255;
86 led->mult = tmp;
87 pwm_channel_writel(&led->pwmc, PWM_CDTY,
88 led->cdev.brightness * 255);
89 pwm_channel_writel(&led->pwmc, PWM_CPRD,
90 LED_FULL * tmp);
91
92 pwm_channel_enable(&led->pwmc);
93
94 /* Hand it over to the LED framework */
95 status = led_classdev_register(&pdev->dev, &led->cdev);
96 if (status < 0) {
97 pwm_channel_free(&led->pwmc);
98 goto err;
99 }
100 }
101
102 platform_set_drvdata(pdev, leds);
103 return 0;
104
105err:
106 if (i > 0) {
107 for (i = i - 1; i >= 0; i--) {
108 led_classdev_unregister(&leds[i].cdev);
109 pwm_channel_free(&leds[i].pwmc);
110 }
111 }
112
113 return status;
114}
115
116static int pwmled_remove(struct platform_device *pdev)
117{
118 const struct gpio_led_platform_data *pdata;
119 struct pwmled *leds;
120 unsigned i;
121
122 pdata = dev_get_platdata(&pdev->dev);
123 leds = platform_get_drvdata(pdev);
124
125 for (i = 0; i < pdata->num_leds; i++) {
126 struct pwmled *led = leds + i;
127
128 led_classdev_unregister(&led->cdev);
129 pwm_channel_free(&led->pwmc);
130 }
131
132 return 0;
133}
134
135static struct platform_driver pwmled_driver = {
136 .driver = {
137 .name = "leds-atmel-pwm",
138 .owner = THIS_MODULE,
139 },
140 /* REVISIT add suspend() and resume() methods */
141 .probe = pwmled_probe,
142 .remove = pwmled_remove,
143};
144
145module_platform_driver(pwmled_driver);
146
147MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");
148MODULE_LICENSE("GPL");
149MODULE_ALIAS("platform:leds-atmel-pwm");
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index c8b5c13bcd05..9fd9c6717e0c 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -16,26 +16,9 @@ config PL320_MBOX
16 Management Engine, primarily for cpufreq. Say Y here if you want 16 Management Engine, primarily for cpufreq. Say Y here if you want
17 to use the PL320 IPCM support. 17 to use the PL320 IPCM support.
18 18
19config OMAP_MBOX
20 tristate
21 help
22 This option is selected by any OMAP architecture specific mailbox
23 driver such as CONFIG_OMAP1_MBOX or CONFIG_OMAP2PLUS_MBOX. This
24 enables the common OMAP mailbox framework code.
25
26config OMAP1_MBOX
27 tristate "OMAP1 Mailbox framework support"
28 depends on ARCH_OMAP1
29 select OMAP_MBOX
30 help
31 Mailbox implementation for OMAP chips with hardware for
32 interprocessor communication involving DSP in OMAP1. Say Y here
33 if you want to use OMAP1 Mailbox framework support.
34
35config OMAP2PLUS_MBOX 19config OMAP2PLUS_MBOX
36 tristate "OMAP2+ Mailbox framework support" 20 tristate "OMAP2+ Mailbox framework support"
37 depends on ARCH_OMAP2PLUS 21 depends on ARCH_OMAP2PLUS
38 select OMAP_MBOX
39 help 22 help
40 Mailbox implementation for OMAP family chips with hardware for 23 Mailbox implementation for OMAP family chips with hardware for
41 interprocessor communication involving DSP, IVA1.0 and IVA2 in 24 interprocessor communication involving DSP, IVA1.0 and IVA2 in
@@ -44,7 +27,7 @@ config OMAP2PLUS_MBOX
44 27
45config OMAP_MBOX_KFIFO_SIZE 28config OMAP_MBOX_KFIFO_SIZE
46 int "Mailbox kfifo default buffer size (bytes)" 29 int "Mailbox kfifo default buffer size (bytes)"
47 depends on OMAP2PLUS_MBOX || OMAP1_MBOX 30 depends on OMAP2PLUS_MBOX
48 default 256 31 default 256
49 help 32 help
50 Specify the default size of mailbox's kfifo buffers (bytes). 33 Specify the default size of mailbox's kfifo buffers (bytes).
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index e0facb34084a..6d184dbcaca8 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -1,7 +1,3 @@
1obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o 1obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
2 2
3obj-$(CONFIG_OMAP_MBOX) += omap-mailbox.o 3obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o
4obj-$(CONFIG_OMAP1_MBOX) += mailbox_omap1.o
5mailbox_omap1-objs := mailbox-omap1.o
6obj-$(CONFIG_OMAP2PLUS_MBOX) += mailbox_omap2.o
7mailbox_omap2-objs := mailbox-omap2.o
diff --git a/drivers/mailbox/mailbox-omap1.c b/drivers/mailbox/mailbox-omap1.c
deleted file mode 100644
index 9001b7633f10..000000000000
--- a/drivers/mailbox/mailbox-omap1.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/*
2 * Mailbox reservation modules for OMAP1
3 *
4 * Copyright (C) 2006-2009 Nokia Corporation
5 * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/module.h>
13#include <linux/interrupt.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16
17#include "omap-mbox.h"
18
19#define MAILBOX_ARM2DSP1 0x00
20#define MAILBOX_ARM2DSP1b 0x04
21#define MAILBOX_DSP2ARM1 0x08
22#define MAILBOX_DSP2ARM1b 0x0c
23#define MAILBOX_DSP2ARM2 0x10
24#define MAILBOX_DSP2ARM2b 0x14
25#define MAILBOX_ARM2DSP1_Flag 0x18
26#define MAILBOX_DSP2ARM1_Flag 0x1c
27#define MAILBOX_DSP2ARM2_Flag 0x20
28
29static void __iomem *mbox_base;
30
31struct omap_mbox1_fifo {
32 unsigned long cmd;
33 unsigned long data;
34 unsigned long flag;
35};
36
37struct omap_mbox1_priv {
38 struct omap_mbox1_fifo tx_fifo;
39 struct omap_mbox1_fifo rx_fifo;
40};
41
42static inline int mbox_read_reg(size_t ofs)
43{
44 return __raw_readw(mbox_base + ofs);
45}
46
47static inline void mbox_write_reg(u32 val, size_t ofs)
48{
49 __raw_writew(val, mbox_base + ofs);
50}
51
52/* msg */
53static mbox_msg_t omap1_mbox_fifo_read(struct omap_mbox *mbox)
54{
55 struct omap_mbox1_fifo *fifo =
56 &((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
57 mbox_msg_t msg;
58
59 msg = mbox_read_reg(fifo->data);
60 msg |= ((mbox_msg_t) mbox_read_reg(fifo->cmd)) << 16;
61
62 return msg;
63}
64
65static void
66omap1_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
67{
68 struct omap_mbox1_fifo *fifo =
69 &((struct omap_mbox1_priv *)mbox->priv)->tx_fifo;
70
71 mbox_write_reg(msg & 0xffff, fifo->data);
72 mbox_write_reg(msg >> 16, fifo->cmd);
73}
74
75static int omap1_mbox_fifo_empty(struct omap_mbox *mbox)
76{
77 return 0;
78}
79
80static int omap1_mbox_fifo_full(struct omap_mbox *mbox)
81{
82 struct omap_mbox1_fifo *fifo =
83 &((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
84
85 return mbox_read_reg(fifo->flag);
86}
87
88/* irq */
89static void
90omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
91{
92 if (irq == IRQ_RX)
93 enable_irq(mbox->irq);
94}
95
96static void
97omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
98{
99 if (irq == IRQ_RX)
100 disable_irq(mbox->irq);
101}
102
103static int
104omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
105{
106 if (irq == IRQ_TX)
107 return 0;
108 return 1;
109}
110
111static struct omap_mbox_ops omap1_mbox_ops = {
112 .type = OMAP_MBOX_TYPE1,
113 .fifo_read = omap1_mbox_fifo_read,
114 .fifo_write = omap1_mbox_fifo_write,
115 .fifo_empty = omap1_mbox_fifo_empty,
116 .fifo_full = omap1_mbox_fifo_full,
117 .enable_irq = omap1_mbox_enable_irq,
118 .disable_irq = omap1_mbox_disable_irq,
119 .is_irq = omap1_mbox_is_irq,
120};
121
122/* FIXME: the following struct should be created automatically by the user id */
123
124/* DSP */
125static struct omap_mbox1_priv omap1_mbox_dsp_priv = {
126 .tx_fifo = {
127 .cmd = MAILBOX_ARM2DSP1b,
128 .data = MAILBOX_ARM2DSP1,
129 .flag = MAILBOX_ARM2DSP1_Flag,
130 },
131 .rx_fifo = {
132 .cmd = MAILBOX_DSP2ARM1b,
133 .data = MAILBOX_DSP2ARM1,
134 .flag = MAILBOX_DSP2ARM1_Flag,
135 },
136};
137
138static struct omap_mbox mbox_dsp_info = {
139 .name = "dsp",
140 .ops = &omap1_mbox_ops,
141 .priv = &omap1_mbox_dsp_priv,
142};
143
144static struct omap_mbox *omap1_mboxes[] = { &mbox_dsp_info, NULL };
145
146static int omap1_mbox_probe(struct platform_device *pdev)
147{
148 struct resource *mem;
149 int ret;
150 struct omap_mbox **list;
151
152 list = omap1_mboxes;
153 list[0]->irq = platform_get_irq_byname(pdev, "dsp");
154
155 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
156 if (!mem)
157 return -ENOENT;
158
159 mbox_base = ioremap(mem->start, resource_size(mem));
160 if (!mbox_base)
161 return -ENOMEM;
162
163 ret = omap_mbox_register(&pdev->dev, list);
164 if (ret) {
165 iounmap(mbox_base);
166 return ret;
167 }
168
169 return 0;
170}
171
172static int omap1_mbox_remove(struct platform_device *pdev)
173{
174 omap_mbox_unregister();
175 iounmap(mbox_base);
176 return 0;
177}
178
179static struct platform_driver omap1_mbox_driver = {
180 .probe = omap1_mbox_probe,
181 .remove = omap1_mbox_remove,
182 .driver = {
183 .name = "omap-mailbox",
184 },
185};
186
187static int __init omap1_mbox_init(void)
188{
189 return platform_driver_register(&omap1_mbox_driver);
190}
191
192static void __exit omap1_mbox_exit(void)
193{
194 platform_driver_unregister(&omap1_mbox_driver);
195}
196
197module_init(omap1_mbox_init);
198module_exit(omap1_mbox_exit);
199
200MODULE_LICENSE("GPL v2");
201MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions");
202MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
203MODULE_ALIAS("platform:omap1-mailbox");
diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
deleted file mode 100644
index 42d2b893ea67..000000000000
--- a/drivers/mailbox/mailbox-omap2.c
+++ /dev/null
@@ -1,357 +0,0 @@
1/*
2 * Mailbox reservation modules for OMAP2/3
3 *
4 * Copyright (C) 2006-2009 Nokia Corporation
5 * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
6 * and Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/clk.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/io.h>
19#include <linux/pm_runtime.h>
20#include <linux/platform_data/mailbox-omap.h>
21
22#include "omap-mbox.h"
23
24#define MAILBOX_REVISION 0x000
25#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
26#define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
27#define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
28#define MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
29#define MAILBOX_IRQENABLE(u) (0x104 + 8 * (u))
30
31#define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 0x10 * (u))
32#define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u))
33#define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 0x10 * (u))
34
35#define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m)))
36#define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1))
37
38#define MBOX_REG_SIZE 0x120
39
40#define OMAP4_MBOX_REG_SIZE 0x130
41
42#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32))
43#define OMAP4_MBOX_NR_REGS (OMAP4_MBOX_REG_SIZE / sizeof(u32))
44
45static void __iomem *mbox_base;
46
47struct omap_mbox2_fifo {
48 unsigned long msg;
49 unsigned long fifo_stat;
50 unsigned long msg_stat;
51};
52
53struct omap_mbox2_priv {
54 struct omap_mbox2_fifo tx_fifo;
55 struct omap_mbox2_fifo rx_fifo;
56 unsigned long irqenable;
57 unsigned long irqstatus;
58 u32 newmsg_bit;
59 u32 notfull_bit;
60 u32 ctx[OMAP4_MBOX_NR_REGS];
61 unsigned long irqdisable;
62 u32 intr_type;
63};
64
65static inline unsigned int mbox_read_reg(size_t ofs)
66{
67 return __raw_readl(mbox_base + ofs);
68}
69
70static inline void mbox_write_reg(u32 val, size_t ofs)
71{
72 __raw_writel(val, mbox_base + ofs);
73}
74
75/* Mailbox H/W preparations */
76static int omap2_mbox_startup(struct omap_mbox *mbox)
77{
78 u32 l;
79
80 pm_runtime_enable(mbox->dev->parent);
81 pm_runtime_get_sync(mbox->dev->parent);
82
83 l = mbox_read_reg(MAILBOX_REVISION);
84 pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
85
86 return 0;
87}
88
89static void omap2_mbox_shutdown(struct omap_mbox *mbox)
90{
91 pm_runtime_put_sync(mbox->dev->parent);
92 pm_runtime_disable(mbox->dev->parent);
93}
94
95/* Mailbox FIFO handle functions */
96static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
97{
98 struct omap_mbox2_fifo *fifo =
99 &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
100 return (mbox_msg_t) mbox_read_reg(fifo->msg);
101}
102
103static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
104{
105 struct omap_mbox2_fifo *fifo =
106 &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
107 mbox_write_reg(msg, fifo->msg);
108}
109
110static int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
111{
112 struct omap_mbox2_fifo *fifo =
113 &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
114 return (mbox_read_reg(fifo->msg_stat) == 0);
115}
116
117static int omap2_mbox_fifo_full(struct omap_mbox *mbox)
118{
119 struct omap_mbox2_fifo *fifo =
120 &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
121 return mbox_read_reg(fifo->fifo_stat);
122}
123
124/* Mailbox IRQ handle functions */
125static void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
126{
127 struct omap_mbox2_priv *p = mbox->priv;
128 u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
129
130 l = mbox_read_reg(p->irqenable);
131 l |= bit;
132 mbox_write_reg(l, p->irqenable);
133}
134
135static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
136{
137 struct omap_mbox2_priv *p = mbox->priv;
138 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
139
140 /*
141 * Read and update the interrupt configuration register for pre-OMAP4.
142 * OMAP4 and later SoCs have a dedicated interrupt disabling register.
143 */
144 if (!p->intr_type)
145 bit = mbox_read_reg(p->irqdisable) & ~bit;
146
147 mbox_write_reg(bit, p->irqdisable);
148}
149
150static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
151{
152 struct omap_mbox2_priv *p = mbox->priv;
153 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
154
155 mbox_write_reg(bit, p->irqstatus);
156
157 /* Flush posted write for irq status to avoid spurious interrupts */
158 mbox_read_reg(p->irqstatus);
159}
160
161static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
162{
163 struct omap_mbox2_priv *p = mbox->priv;
164 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
165 u32 enable = mbox_read_reg(p->irqenable);
166 u32 status = mbox_read_reg(p->irqstatus);
167
168 return (int)(enable & status & bit);
169}
170
171static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
172{
173 int i;
174 struct omap_mbox2_priv *p = mbox->priv;
175 int nr_regs;
176
177 if (p->intr_type)
178 nr_regs = OMAP4_MBOX_NR_REGS;
179 else
180 nr_regs = MBOX_NR_REGS;
181 for (i = 0; i < nr_regs; i++) {
182 p->ctx[i] = mbox_read_reg(i * sizeof(u32));
183
184 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
185 i, p->ctx[i]);
186 }
187}
188
189static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
190{
191 int i;
192 struct omap_mbox2_priv *p = mbox->priv;
193 int nr_regs;
194
195 if (p->intr_type)
196 nr_regs = OMAP4_MBOX_NR_REGS;
197 else
198 nr_regs = MBOX_NR_REGS;
199 for (i = 0; i < nr_regs; i++) {
200 mbox_write_reg(p->ctx[i], i * sizeof(u32));
201
202 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
203 i, p->ctx[i]);
204 }
205}
206
207static struct omap_mbox_ops omap2_mbox_ops = {
208 .type = OMAP_MBOX_TYPE2,
209 .startup = omap2_mbox_startup,
210 .shutdown = omap2_mbox_shutdown,
211 .fifo_read = omap2_mbox_fifo_read,
212 .fifo_write = omap2_mbox_fifo_write,
213 .fifo_empty = omap2_mbox_fifo_empty,
214 .fifo_full = omap2_mbox_fifo_full,
215 .enable_irq = omap2_mbox_enable_irq,
216 .disable_irq = omap2_mbox_disable_irq,
217 .ack_irq = omap2_mbox_ack_irq,
218 .is_irq = omap2_mbox_is_irq,
219 .save_ctx = omap2_mbox_save_ctx,
220 .restore_ctx = omap2_mbox_restore_ctx,
221};
222
223static int omap2_mbox_probe(struct platform_device *pdev)
224{
225 struct resource *mem;
226 int ret;
227 struct omap_mbox **list, *mbox, *mboxblk;
228 struct omap_mbox2_priv *priv, *privblk;
229 struct omap_mbox_pdata *pdata = pdev->dev.platform_data;
230 struct omap_mbox_dev_info *info;
231 int i;
232
233 if (!pdata || !pdata->info_cnt || !pdata->info) {
234 pr_err("%s: platform not supported\n", __func__);
235 return -ENODEV;
236 }
237
238 /* allocate one extra for marking end of list */
239 list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL);
240 if (!list)
241 return -ENOMEM;
242
243 mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL);
244 if (!mboxblk) {
245 ret = -ENOMEM;
246 goto free_list;
247 }
248
249 privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL);
250 if (!privblk) {
251 ret = -ENOMEM;
252 goto free_mboxblk;
253 }
254
255 info = pdata->info;
256 for (i = 0; i < pdata->info_cnt; i++, info++, priv++) {
257 priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id);
258 priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id);
259 priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id);
260 priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id);
261 priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id);
262 priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id);
263 if (pdata->intr_type) {
264 priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id);
265 priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id);
266 priv->irqdisable =
267 OMAP4_MAILBOX_IRQENABLE_CLR(info->usr_id);
268 } else {
269 priv->irqenable = MAILBOX_IRQENABLE(info->usr_id);
270 priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id);
271 priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id);
272 }
273 priv->intr_type = pdata->intr_type;
274
275 mbox->priv = priv;
276 mbox->name = info->name;
277 mbox->ops = &omap2_mbox_ops;
278 mbox->irq = platform_get_irq(pdev, info->irq_id);
279 if (mbox->irq < 0) {
280 ret = mbox->irq;
281 goto free_privblk;
282 }
283 list[i] = mbox++;
284 }
285
286 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
287 if (!mem) {
288 ret = -ENOENT;
289 goto free_privblk;
290 }
291
292 mbox_base = ioremap(mem->start, resource_size(mem));
293 if (!mbox_base) {
294 ret = -ENOMEM;
295 goto free_privblk;
296 }
297
298 ret = omap_mbox_register(&pdev->dev, list);
299 if (ret)
300 goto unmap_mbox;
301 platform_set_drvdata(pdev, list);
302
303 return 0;
304
305unmap_mbox:
306 iounmap(mbox_base);
307free_privblk:
308 kfree(privblk);
309free_mboxblk:
310 kfree(mboxblk);
311free_list:
312 kfree(list);
313 return ret;
314}
315
316static int omap2_mbox_remove(struct platform_device *pdev)
317{
318 struct omap_mbox2_priv *privblk;
319 struct omap_mbox **list = platform_get_drvdata(pdev);
320 struct omap_mbox *mboxblk = list[0];
321
322 privblk = mboxblk->priv;
323 omap_mbox_unregister();
324 iounmap(mbox_base);
325 kfree(privblk);
326 kfree(mboxblk);
327 kfree(list);
328
329 return 0;
330}
331
332static struct platform_driver omap2_mbox_driver = {
333 .probe = omap2_mbox_probe,
334 .remove = omap2_mbox_remove,
335 .driver = {
336 .name = "omap-mailbox",
337 },
338};
339
340static int __init omap2_mbox_init(void)
341{
342 return platform_driver_register(&omap2_mbox_driver);
343}
344
345static void __exit omap2_mbox_exit(void)
346{
347 platform_driver_unregister(&omap2_mbox_driver);
348}
349
350module_init(omap2_mbox_init);
351module_exit(omap2_mbox_exit);
352
353MODULE_LICENSE("GPL v2");
354MODULE_DESCRIPTION("omap mailbox: omap2/3/4 architecture specific functions");
355MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
356MODULE_AUTHOR("Paul Mundt");
357MODULE_ALIAS("platform:omap2-mailbox");
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index d79a646b9042..a27e00e63a8a 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -2,8 +2,10 @@
2 * OMAP mailbox driver 2 * OMAP mailbox driver
3 * 3 *
4 * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved. 4 * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
5 * Copyright (C) 2013-2014 Texas Instruments Inc.
5 * 6 *
6 * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> 7 * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
8 * Suman Anna <s-anna@ti.com>
7 * 9 *
8 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
@@ -24,70 +26,164 @@
24#include <linux/interrupt.h> 26#include <linux/interrupt.h>
25#include <linux/spinlock.h> 27#include <linux/spinlock.h>
26#include <linux/mutex.h> 28#include <linux/mutex.h>
27#include <linux/delay.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
29#include <linux/kfifo.h> 30#include <linux/kfifo.h>
30#include <linux/err.h> 31#include <linux/err.h>
31#include <linux/notifier.h> 32#include <linux/notifier.h>
32#include <linux/module.h> 33#include <linux/module.h>
33 34#include <linux/platform_device.h>
34#include "omap-mbox.h" 35#include <linux/pm_runtime.h>
35 36#include <linux/platform_data/mailbox-omap.h>
36static struct omap_mbox **mboxes; 37#include <linux/omap-mailbox.h>
37 38
38static int mbox_configured; 39#define MAILBOX_REVISION 0x000
39static DEFINE_MUTEX(mbox_configured_lock); 40#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
41#define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
42#define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
43
44#define OMAP2_MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
45#define OMAP2_MAILBOX_IRQENABLE(u) (0x104 + 8 * (u))
46
47#define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 0x10 * (u))
48#define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u))
49#define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 0x10 * (u))
50
51#define MAILBOX_IRQSTATUS(type, u) (type ? OMAP4_MAILBOX_IRQSTATUS(u) : \
52 OMAP2_MAILBOX_IRQSTATUS(u))
53#define MAILBOX_IRQENABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE(u) : \
54 OMAP2_MAILBOX_IRQENABLE(u))
55#define MAILBOX_IRQDISABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE_CLR(u) \
56 : OMAP2_MAILBOX_IRQENABLE(u))
57
58#define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m)))
59#define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1))
60
61#define MBOX_REG_SIZE 0x120
62
63#define OMAP4_MBOX_REG_SIZE 0x130
64
65#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32))
66#define OMAP4_MBOX_NR_REGS (OMAP4_MBOX_REG_SIZE / sizeof(u32))
67
68struct omap_mbox_fifo {
69 unsigned long msg;
70 unsigned long fifo_stat;
71 unsigned long msg_stat;
72 unsigned long irqenable;
73 unsigned long irqstatus;
74 unsigned long irqdisable;
75 u32 intr_bit;
76};
77
78struct omap_mbox_queue {
79 spinlock_t lock;
80 struct kfifo fifo;
81 struct work_struct work;
82 struct tasklet_struct tasklet;
83 struct omap_mbox *mbox;
84 bool full;
85};
86
87struct omap_mbox_device {
88 struct device *dev;
89 struct mutex cfg_lock;
90 void __iomem *mbox_base;
91 u32 num_users;
92 u32 num_fifos;
93 struct omap_mbox **mboxes;
94 struct list_head elem;
95};
96
97struct omap_mbox {
98 const char *name;
99 int irq;
100 struct omap_mbox_queue *txq, *rxq;
101 struct device *dev;
102 struct omap_mbox_device *parent;
103 struct omap_mbox_fifo tx_fifo;
104 struct omap_mbox_fifo rx_fifo;
105 u32 ctx[OMAP4_MBOX_NR_REGS];
106 u32 intr_type;
107 int use_count;
108 struct blocking_notifier_head notifier;
109};
110
111/* global variables for the mailbox devices */
112static DEFINE_MUTEX(omap_mbox_devices_lock);
113static LIST_HEAD(omap_mbox_devices);
40 114
41static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE; 115static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
42module_param(mbox_kfifo_size, uint, S_IRUGO); 116module_param(mbox_kfifo_size, uint, S_IRUGO);
43MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)"); 117MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
44 118
119static inline
120unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs)
121{
122 return __raw_readl(mdev->mbox_base + ofs);
123}
124
125static inline
126void mbox_write_reg(struct omap_mbox_device *mdev, u32 val, size_t ofs)
127{
128 __raw_writel(val, mdev->mbox_base + ofs);
129}
130
45/* Mailbox FIFO handle functions */ 131/* Mailbox FIFO handle functions */
46static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) 132static mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
47{ 133{
48 return mbox->ops->fifo_read(mbox); 134 struct omap_mbox_fifo *fifo = &mbox->rx_fifo;
135 return (mbox_msg_t) mbox_read_reg(mbox->parent, fifo->msg);
49} 136}
50static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) 137
138static void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
51{ 139{
52 mbox->ops->fifo_write(mbox, msg); 140 struct omap_mbox_fifo *fifo = &mbox->tx_fifo;
141 mbox_write_reg(mbox->parent, msg, fifo->msg);
53} 142}
54static inline int mbox_fifo_empty(struct omap_mbox *mbox) 143
144static int mbox_fifo_empty(struct omap_mbox *mbox)
55{ 145{
56 return mbox->ops->fifo_empty(mbox); 146 struct omap_mbox_fifo *fifo = &mbox->rx_fifo;
147 return (mbox_read_reg(mbox->parent, fifo->msg_stat) == 0);
57} 148}
58static inline int mbox_fifo_full(struct omap_mbox *mbox) 149
150static int mbox_fifo_full(struct omap_mbox *mbox)
59{ 151{
60 return mbox->ops->fifo_full(mbox); 152 struct omap_mbox_fifo *fifo = &mbox->tx_fifo;
153 return mbox_read_reg(mbox->parent, fifo->fifo_stat);
61} 154}
62 155
63/* Mailbox IRQ handle functions */ 156/* Mailbox IRQ handle functions */
64static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 157static void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
65{ 158{
66 if (mbox->ops->ack_irq) 159 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
67 mbox->ops->ack_irq(mbox, irq); 160 &mbox->tx_fifo : &mbox->rx_fifo;
161 u32 bit = fifo->intr_bit;
162 u32 irqstatus = fifo->irqstatus;
163
164 mbox_write_reg(mbox->parent, bit, irqstatus);
165
166 /* Flush posted write for irq status to avoid spurious interrupts */
167 mbox_read_reg(mbox->parent, irqstatus);
68} 168}
69static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 169
170static int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
70{ 171{
71 return mbox->ops->is_irq(mbox, irq); 172 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
173 &mbox->tx_fifo : &mbox->rx_fifo;
174 u32 bit = fifo->intr_bit;
175 u32 irqenable = fifo->irqenable;
176 u32 irqstatus = fifo->irqstatus;
177
178 u32 enable = mbox_read_reg(mbox->parent, irqenable);
179 u32 status = mbox_read_reg(mbox->parent, irqstatus);
180
181 return (int)(enable & status & bit);
72} 182}
73 183
74/* 184/*
75 * message sender 185 * message sender
76 */ 186 */
77static int __mbox_poll_for_space(struct omap_mbox *mbox)
78{
79 int ret = 0, i = 1000;
80
81 while (mbox_fifo_full(mbox)) {
82 if (mbox->ops->type == OMAP_MBOX_TYPE2)
83 return -1;
84 if (--i == 0)
85 return -1;
86 udelay(1);
87 }
88 return ret;
89}
90
91int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) 187int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
92{ 188{
93 struct omap_mbox_queue *mq = mbox->txq; 189 struct omap_mbox_queue *mq = mbox->txq;
@@ -100,7 +196,7 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
100 goto out; 196 goto out;
101 } 197 }
102 198
103 if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) { 199 if (kfifo_is_empty(&mq->fifo) && !mbox_fifo_full(mbox)) {
104 mbox_fifo_write(mbox, msg); 200 mbox_fifo_write(mbox, msg);
105 goto out; 201 goto out;
106 } 202 }
@@ -118,35 +214,69 @@ EXPORT_SYMBOL(omap_mbox_msg_send);
118 214
119void omap_mbox_save_ctx(struct omap_mbox *mbox) 215void omap_mbox_save_ctx(struct omap_mbox *mbox)
120{ 216{
121 if (!mbox->ops->save_ctx) { 217 int i;
122 dev_err(mbox->dev, "%s:\tno save\n", __func__); 218 int nr_regs;
123 return; 219
124 } 220 if (mbox->intr_type)
221 nr_regs = OMAP4_MBOX_NR_REGS;
222 else
223 nr_regs = MBOX_NR_REGS;
224 for (i = 0; i < nr_regs; i++) {
225 mbox->ctx[i] = mbox_read_reg(mbox->parent, i * sizeof(u32));
125 226
126 mbox->ops->save_ctx(mbox); 227 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
228 i, mbox->ctx[i]);
229 }
127} 230}
128EXPORT_SYMBOL(omap_mbox_save_ctx); 231EXPORT_SYMBOL(omap_mbox_save_ctx);
129 232
130void omap_mbox_restore_ctx(struct omap_mbox *mbox) 233void omap_mbox_restore_ctx(struct omap_mbox *mbox)
131{ 234{
132 if (!mbox->ops->restore_ctx) { 235 int i;
133 dev_err(mbox->dev, "%s:\tno restore\n", __func__); 236 int nr_regs;
134 return;
135 }
136 237
137 mbox->ops->restore_ctx(mbox); 238 if (mbox->intr_type)
239 nr_regs = OMAP4_MBOX_NR_REGS;
240 else
241 nr_regs = MBOX_NR_REGS;
242 for (i = 0; i < nr_regs; i++) {
243 mbox_write_reg(mbox->parent, mbox->ctx[i], i * sizeof(u32));
244
245 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
246 i, mbox->ctx[i]);
247 }
138} 248}
139EXPORT_SYMBOL(omap_mbox_restore_ctx); 249EXPORT_SYMBOL(omap_mbox_restore_ctx);
140 250
141void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 251void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
142{ 252{
143 mbox->ops->enable_irq(mbox, irq); 253 u32 l;
254 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
255 &mbox->tx_fifo : &mbox->rx_fifo;
256 u32 bit = fifo->intr_bit;
257 u32 irqenable = fifo->irqenable;
258
259 l = mbox_read_reg(mbox->parent, irqenable);
260 l |= bit;
261 mbox_write_reg(mbox->parent, l, irqenable);
144} 262}
145EXPORT_SYMBOL(omap_mbox_enable_irq); 263EXPORT_SYMBOL(omap_mbox_enable_irq);
146 264
147void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 265void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
148{ 266{
149 mbox->ops->disable_irq(mbox, irq); 267 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
268 &mbox->tx_fifo : &mbox->rx_fifo;
269 u32 bit = fifo->intr_bit;
270 u32 irqdisable = fifo->irqdisable;
271
272 /*
273 * Read and update the interrupt configuration register for pre-OMAP4.
274 * OMAP4 and later SoCs have a dedicated interrupt disabling register.
275 */
276 if (!mbox->intr_type)
277 bit = mbox_read_reg(mbox->parent, irqdisable) & ~bit;
278
279 mbox_write_reg(mbox->parent, bit, irqdisable);
150} 280}
151EXPORT_SYMBOL(omap_mbox_disable_irq); 281EXPORT_SYMBOL(omap_mbox_disable_irq);
152 282
@@ -158,7 +288,7 @@ static void mbox_tx_tasklet(unsigned long tx_data)
158 int ret; 288 int ret;
159 289
160 while (kfifo_len(&mq->fifo)) { 290 while (kfifo_len(&mq->fifo)) {
161 if (__mbox_poll_for_space(mbox)) { 291 if (mbox_fifo_full(mbox)) {
162 omap_mbox_enable_irq(mbox, IRQ_TX); 292 omap_mbox_enable_irq(mbox, IRQ_TX);
163 break; 293 break;
164 } 294 }
@@ -223,9 +353,6 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
223 353
224 len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); 354 len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
225 WARN_ON(len != sizeof(msg)); 355 WARN_ON(len != sizeof(msg));
226
227 if (mbox->ops->type == OMAP_MBOX_TYPE1)
228 break;
229 } 356 }
230 357
231 /* no more messages in the fifo. clear IRQ source. */ 358 /* no more messages in the fifo. clear IRQ source. */
@@ -283,16 +410,12 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
283{ 410{
284 int ret = 0; 411 int ret = 0;
285 struct omap_mbox_queue *mq; 412 struct omap_mbox_queue *mq;
413 struct omap_mbox_device *mdev = mbox->parent;
286 414
287 mutex_lock(&mbox_configured_lock); 415 mutex_lock(&mdev->cfg_lock);
288 if (!mbox_configured++) { 416 ret = pm_runtime_get_sync(mdev->dev);
289 if (likely(mbox->ops->startup)) { 417 if (unlikely(ret < 0))
290 ret = mbox->ops->startup(mbox); 418 goto fail_startup;
291 if (unlikely(ret))
292 goto fail_startup;
293 } else
294 goto fail_startup;
295 }
296 419
297 if (!mbox->use_count++) { 420 if (!mbox->use_count++) {
298 mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); 421 mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
@@ -319,7 +442,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
319 442
320 omap_mbox_enable_irq(mbox, IRQ_RX); 443 omap_mbox_enable_irq(mbox, IRQ_RX);
321 } 444 }
322 mutex_unlock(&mbox_configured_lock); 445 mutex_unlock(&mdev->cfg_lock);
323 return 0; 446 return 0;
324 447
325fail_request_irq: 448fail_request_irq:
@@ -327,18 +450,18 @@ fail_request_irq:
327fail_alloc_rxq: 450fail_alloc_rxq:
328 mbox_queue_free(mbox->txq); 451 mbox_queue_free(mbox->txq);
329fail_alloc_txq: 452fail_alloc_txq:
330 if (mbox->ops->shutdown) 453 pm_runtime_put_sync(mdev->dev);
331 mbox->ops->shutdown(mbox);
332 mbox->use_count--; 454 mbox->use_count--;
333fail_startup: 455fail_startup:
334 mbox_configured--; 456 mutex_unlock(&mdev->cfg_lock);
335 mutex_unlock(&mbox_configured_lock);
336 return ret; 457 return ret;
337} 458}
338 459
339static void omap_mbox_fini(struct omap_mbox *mbox) 460static void omap_mbox_fini(struct omap_mbox *mbox)
340{ 461{
341 mutex_lock(&mbox_configured_lock); 462 struct omap_mbox_device *mdev = mbox->parent;
463
464 mutex_lock(&mdev->cfg_lock);
342 465
343 if (!--mbox->use_count) { 466 if (!--mbox->use_count) {
344 omap_mbox_disable_irq(mbox, IRQ_RX); 467 omap_mbox_disable_irq(mbox, IRQ_RX);
@@ -349,28 +472,43 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
349 mbox_queue_free(mbox->rxq); 472 mbox_queue_free(mbox->rxq);
350 } 473 }
351 474
352 if (likely(mbox->ops->shutdown)) { 475 pm_runtime_put_sync(mdev->dev);
353 if (!--mbox_configured)
354 mbox->ops->shutdown(mbox);
355 }
356 476
357 mutex_unlock(&mbox_configured_lock); 477 mutex_unlock(&mdev->cfg_lock);
358} 478}
359 479
360struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb) 480static struct omap_mbox *omap_mbox_device_find(struct omap_mbox_device *mdev,
481 const char *mbox_name)
361{ 482{
362 struct omap_mbox *_mbox, *mbox = NULL; 483 struct omap_mbox *_mbox, *mbox = NULL;
363 int i, ret; 484 struct omap_mbox **mboxes = mdev->mboxes;
485 int i;
364 486
365 if (!mboxes) 487 if (!mboxes)
366 return ERR_PTR(-EINVAL); 488 return NULL;
367 489
368 for (i = 0; (_mbox = mboxes[i]); i++) { 490 for (i = 0; (_mbox = mboxes[i]); i++) {
369 if (!strcmp(_mbox->name, name)) { 491 if (!strcmp(_mbox->name, mbox_name)) {
370 mbox = _mbox; 492 mbox = _mbox;
371 break; 493 break;
372 } 494 }
373 } 495 }
496 return mbox;
497}
498
499struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
500{
501 struct omap_mbox *mbox = NULL;
502 struct omap_mbox_device *mdev;
503 int ret;
504
505 mutex_lock(&omap_mbox_devices_lock);
506 list_for_each_entry(mdev, &omap_mbox_devices, elem) {
507 mbox = omap_mbox_device_find(mdev, name);
508 if (mbox)
509 break;
510 }
511 mutex_unlock(&omap_mbox_devices_lock);
374 512
375 if (!mbox) 513 if (!mbox)
376 return ERR_PTR(-ENOENT); 514 return ERR_PTR(-ENOENT);
@@ -397,19 +535,20 @@ EXPORT_SYMBOL(omap_mbox_put);
397 535
398static struct class omap_mbox_class = { .name = "mbox", }; 536static struct class omap_mbox_class = { .name = "mbox", };
399 537
400int omap_mbox_register(struct device *parent, struct omap_mbox **list) 538static int omap_mbox_register(struct omap_mbox_device *mdev)
401{ 539{
402 int ret; 540 int ret;
403 int i; 541 int i;
542 struct omap_mbox **mboxes;
404 543
405 mboxes = list; 544 if (!mdev || !mdev->mboxes)
406 if (!mboxes)
407 return -EINVAL; 545 return -EINVAL;
408 546
547 mboxes = mdev->mboxes;
409 for (i = 0; mboxes[i]; i++) { 548 for (i = 0; mboxes[i]; i++) {
410 struct omap_mbox *mbox = mboxes[i]; 549 struct omap_mbox *mbox = mboxes[i];
411 mbox->dev = device_create(&omap_mbox_class, 550 mbox->dev = device_create(&omap_mbox_class,
412 parent, 0, mbox, "%s", mbox->name); 551 mdev->dev, 0, mbox, "%s", mbox->name);
413 if (IS_ERR(mbox->dev)) { 552 if (IS_ERR(mbox->dev)) {
414 ret = PTR_ERR(mbox->dev); 553 ret = PTR_ERR(mbox->dev);
415 goto err_out; 554 goto err_out;
@@ -417,6 +556,11 @@ int omap_mbox_register(struct device *parent, struct omap_mbox **list)
417 556
418 BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier); 557 BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
419 } 558 }
559
560 mutex_lock(&omap_mbox_devices_lock);
561 list_add(&mdev->elem, &omap_mbox_devices);
562 mutex_unlock(&omap_mbox_devices_lock);
563
420 return 0; 564 return 0;
421 565
422err_out: 566err_out:
@@ -424,21 +568,148 @@ err_out:
424 device_unregister(mboxes[i]->dev); 568 device_unregister(mboxes[i]->dev);
425 return ret; 569 return ret;
426} 570}
427EXPORT_SYMBOL(omap_mbox_register);
428 571
429int omap_mbox_unregister(void) 572static int omap_mbox_unregister(struct omap_mbox_device *mdev)
430{ 573{
431 int i; 574 int i;
575 struct omap_mbox **mboxes;
432 576
433 if (!mboxes) 577 if (!mdev || !mdev->mboxes)
434 return -EINVAL; 578 return -EINVAL;
435 579
580 mutex_lock(&omap_mbox_devices_lock);
581 list_del(&mdev->elem);
582 mutex_unlock(&omap_mbox_devices_lock);
583
584 mboxes = mdev->mboxes;
436 for (i = 0; mboxes[i]; i++) 585 for (i = 0; mboxes[i]; i++)
437 device_unregister(mboxes[i]->dev); 586 device_unregister(mboxes[i]->dev);
438 mboxes = NULL;
439 return 0; 587 return 0;
440} 588}
441EXPORT_SYMBOL(omap_mbox_unregister); 589
590static int omap_mbox_probe(struct platform_device *pdev)
591{
592 struct resource *mem;
593 int ret;
594 struct omap_mbox **list, *mbox, *mboxblk;
595 struct omap_mbox_pdata *pdata = pdev->dev.platform_data;
596 struct omap_mbox_dev_info *info;
597 struct omap_mbox_device *mdev;
598 struct omap_mbox_fifo *fifo;
599 u32 intr_type;
600 u32 l;
601 int i;
602
603 if (!pdata || !pdata->info_cnt || !pdata->info) {
604 pr_err("%s: platform not supported\n", __func__);
605 return -ENODEV;
606 }
607
608 mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
609 if (!mdev)
610 return -ENOMEM;
611
612 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
613 mdev->mbox_base = devm_ioremap_resource(&pdev->dev, mem);
614 if (IS_ERR(mdev->mbox_base))
615 return PTR_ERR(mdev->mbox_base);
616
617 /* allocate one extra for marking end of list */
618 list = devm_kzalloc(&pdev->dev, (pdata->info_cnt + 1) * sizeof(*list),
619 GFP_KERNEL);
620 if (!list)
621 return -ENOMEM;
622
623 mboxblk = devm_kzalloc(&pdev->dev, pdata->info_cnt * sizeof(*mbox),
624 GFP_KERNEL);
625 if (!mboxblk)
626 return -ENOMEM;
627
628 info = pdata->info;
629 intr_type = pdata->intr_type;
630 mbox = mboxblk;
631 for (i = 0; i < pdata->info_cnt; i++, info++) {
632 fifo = &mbox->tx_fifo;
633 fifo->msg = MAILBOX_MESSAGE(info->tx_id);
634 fifo->fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id);
635 fifo->intr_bit = MAILBOX_IRQ_NOTFULL(info->tx_id);
636 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id);
637 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id);
638 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id);
639
640 fifo = &mbox->rx_fifo;
641 fifo->msg = MAILBOX_MESSAGE(info->rx_id);
642 fifo->msg_stat = MAILBOX_MSGSTATUS(info->rx_id);
643 fifo->intr_bit = MAILBOX_IRQ_NEWMSG(info->rx_id);
644 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id);
645 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id);
646 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id);
647
648 mbox->intr_type = intr_type;
649
650 mbox->parent = mdev;
651 mbox->name = info->name;
652 mbox->irq = platform_get_irq(pdev, info->irq_id);
653 if (mbox->irq < 0)
654 return mbox->irq;
655 list[i] = mbox++;
656 }
657
658 mutex_init(&mdev->cfg_lock);
659 mdev->dev = &pdev->dev;
660 mdev->num_users = pdata->num_users;
661 mdev->num_fifos = pdata->num_fifos;
662 mdev->mboxes = list;
663 ret = omap_mbox_register(mdev);
664 if (ret)
665 return ret;
666
667 platform_set_drvdata(pdev, mdev);
668 pm_runtime_enable(mdev->dev);
669
670 ret = pm_runtime_get_sync(mdev->dev);
671 if (ret < 0) {
672 pm_runtime_put_noidle(mdev->dev);
673 goto unregister;
674 }
675
676 /*
677 * just print the raw revision register, the format is not
678 * uniform across all SoCs
679 */
680 l = mbox_read_reg(mdev, MAILBOX_REVISION);
681 dev_info(mdev->dev, "omap mailbox rev 0x%x\n", l);
682
683 ret = pm_runtime_put_sync(mdev->dev);
684 if (ret < 0)
685 goto unregister;
686
687 return 0;
688
689unregister:
690 pm_runtime_disable(mdev->dev);
691 omap_mbox_unregister(mdev);
692 return ret;
693}
694
695static int omap_mbox_remove(struct platform_device *pdev)
696{
697 struct omap_mbox_device *mdev = platform_get_drvdata(pdev);
698
699 pm_runtime_disable(mdev->dev);
700 omap_mbox_unregister(mdev);
701
702 return 0;
703}
704
705static struct platform_driver omap_mbox_driver = {
706 .probe = omap_mbox_probe,
707 .remove = omap_mbox_remove,
708 .driver = {
709 .name = "omap-mailbox",
710 .owner = THIS_MODULE,
711 },
712};
442 713
443static int __init omap_mbox_init(void) 714static int __init omap_mbox_init(void)
444{ 715{
@@ -453,12 +724,13 @@ static int __init omap_mbox_init(void)
453 mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, 724 mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
454 sizeof(mbox_msg_t)); 725 sizeof(mbox_msg_t));
455 726
456 return 0; 727 return platform_driver_register(&omap_mbox_driver);
457} 728}
458subsys_initcall(omap_mbox_init); 729subsys_initcall(omap_mbox_init);
459 730
460static void __exit omap_mbox_exit(void) 731static void __exit omap_mbox_exit(void)
461{ 732{
733 platform_driver_unregister(&omap_mbox_driver);
462 class_unregister(&omap_mbox_class); 734 class_unregister(&omap_mbox_class);
463} 735}
464module_exit(omap_mbox_exit); 736module_exit(omap_mbox_exit);
diff --git a/drivers/mailbox/omap-mbox.h b/drivers/mailbox/omap-mbox.h
deleted file mode 100644
index 86d7518cd13b..000000000000
--- a/drivers/mailbox/omap-mbox.h
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * omap-mbox.h: OMAP mailbox internal definitions
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef OMAP_MBOX_H
10#define OMAP_MBOX_H
11
12#include <linux/device.h>
13#include <linux/interrupt.h>
14#include <linux/kfifo.h>
15#include <linux/spinlock.h>
16#include <linux/workqueue.h>
17#include <linux/omap-mailbox.h>
18
19typedef int __bitwise omap_mbox_type_t;
20#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
21#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
22
23struct omap_mbox_ops {
24 omap_mbox_type_t type;
25 int (*startup)(struct omap_mbox *mbox);
26 void (*shutdown)(struct omap_mbox *mbox);
27 /* fifo */
28 mbox_msg_t (*fifo_read)(struct omap_mbox *mbox);
29 void (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
30 int (*fifo_empty)(struct omap_mbox *mbox);
31 int (*fifo_full)(struct omap_mbox *mbox);
32 /* irq */
33 void (*enable_irq)(struct omap_mbox *mbox,
34 omap_mbox_irq_t irq);
35 void (*disable_irq)(struct omap_mbox *mbox,
36 omap_mbox_irq_t irq);
37 void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
38 int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
39 /* ctx */
40 void (*save_ctx)(struct omap_mbox *mbox);
41 void (*restore_ctx)(struct omap_mbox *mbox);
42};
43
44struct omap_mbox_queue {
45 spinlock_t lock;
46 struct kfifo fifo;
47 struct work_struct work;
48 struct tasklet_struct tasklet;
49 struct omap_mbox *mbox;
50 bool full;
51};
52
53struct omap_mbox {
54 const char *name;
55 int irq;
56 struct omap_mbox_queue *txq, *rxq;
57 struct omap_mbox_ops *ops;
58 struct device *dev;
59 void *priv;
60 int use_count;
61 struct blocking_notifier_head notifier;
62};
63
64int omap_mbox_register(struct device *parent, struct omap_mbox **);
65int omap_mbox_unregister(void);
66
67#endif /* OMAP_MBOX_H */
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index ee9402324a23..b841180c7c74 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -51,16 +51,6 @@ config AD525X_DPOT_SPI
51 To compile this driver as a module, choose M here: the 51 To compile this driver as a module, choose M here: the
52 module will be called ad525x_dpot-spi. 52 module will be called ad525x_dpot-spi.
53 53
54config ATMEL_PWM
55 tristate "Atmel AT32/AT91 PWM support"
56 depends on HAVE_CLK
57 depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
58 help
59 This option enables device driver support for the PWM channels
60 on certain Atmel processors. Pulse Width Modulation is used for
61 purposes including software controlled power-efficient backlights
62 on LCD displays, motor control, and waveform generation.
63
64config ATMEL_TCLIB 54config ATMEL_TCLIB
65 bool "Atmel AT32/AT91 Timer/Counter Library" 55 bool "Atmel AT32/AT91 Timer/Counter Library"
66 depends on (AVR32 || ARCH_AT91) 56 depends on (AVR32 || ARCH_AT91)
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d59ce1261b38..5497d026e651 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
7obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o 7obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
8obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o 8obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
9obj-$(CONFIG_INTEL_MID_PTI) += pti.o 9obj-$(CONFIG_INTEL_MID_PTI) += pti.o
10obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
11obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o 10obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
12obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o 11obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
13obj-$(CONFIG_BMP085) += bmp085.o 12obj-$(CONFIG_BMP085) += bmp085.o
diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c
deleted file mode 100644
index a6dc56e1bc58..000000000000
--- a/drivers/misc/atmel_pwm.c
+++ /dev/null
@@ -1,402 +0,0 @@
1#include <linux/module.h>
2#include <linux/clk.h>
3#include <linux/err.h>
4#include <linux/slab.h>
5#include <linux/io.h>
6#include <linux/interrupt.h>
7#include <linux/platform_device.h>
8#include <linux/atmel_pwm.h>
9
10
11/*
12 * This is a simple driver for the PWM controller found in various newer
13 * Atmel SOCs, including the AVR32 series and the AT91sam9263.
14 *
15 * Chips with current Linux ports have only 4 PWM channels, out of max 32.
16 * AT32UC3A and AT32UC3B chips have 7 channels (but currently no Linux).
17 * Docs are inconsistent about the width of the channel counter registers;
18 * it's at least 16 bits, but several places say 20 bits.
19 */
20#define PWM_NCHAN 4 /* max 32 */
21
22struct pwm {
23 spinlock_t lock;
24 struct platform_device *pdev;
25 u32 mask;
26 int irq;
27 void __iomem *base;
28 struct clk *clk;
29 struct pwm_channel *channel[PWM_NCHAN];
30 void (*handler[PWM_NCHAN])(struct pwm_channel *);
31};
32
33
34/* global PWM controller registers */
35#define PWM_MR 0x00
36#define PWM_ENA 0x04
37#define PWM_DIS 0x08
38#define PWM_SR 0x0c
39#define PWM_IER 0x10
40#define PWM_IDR 0x14
41#define PWM_IMR 0x18
42#define PWM_ISR 0x1c
43
44static inline void pwm_writel(const struct pwm *p, unsigned offset, u32 val)
45{
46 __raw_writel(val, p->base + offset);
47}
48
49static inline u32 pwm_readl(const struct pwm *p, unsigned offset)
50{
51 return __raw_readl(p->base + offset);
52}
53
54static inline void __iomem *pwmc_regs(const struct pwm *p, int index)
55{
56 return p->base + 0x200 + index * 0x20;
57}
58
59static struct pwm *pwm;
60
61static void pwm_dumpregs(struct pwm_channel *ch, char *tag)
62{
63 struct device *dev = &pwm->pdev->dev;
64
65 dev_dbg(dev, "%s: mr %08x, sr %08x, imr %08x\n",
66 tag,
67 pwm_readl(pwm, PWM_MR),
68 pwm_readl(pwm, PWM_SR),
69 pwm_readl(pwm, PWM_IMR));
70 dev_dbg(dev,
71 "pwm ch%d - mr %08x, dty %u, prd %u, cnt %u\n",
72 ch->index,
73 pwm_channel_readl(ch, PWM_CMR),
74 pwm_channel_readl(ch, PWM_CDTY),
75 pwm_channel_readl(ch, PWM_CPRD),
76 pwm_channel_readl(ch, PWM_CCNT));
77}
78
79
80/**
81 * pwm_channel_alloc - allocate an unused PWM channel
82 * @index: identifies the channel
83 * @ch: structure to be initialized
84 *
85 * Drivers allocate PWM channels according to the board's wiring, and
86 * matching board-specific setup code. Returns zero or negative errno.
87 */
88int pwm_channel_alloc(int index, struct pwm_channel *ch)
89{
90 unsigned long flags;
91 int status = 0;
92
93 if (!pwm)
94 return -EPROBE_DEFER;
95
96 if (!(pwm->mask & 1 << index))
97 return -ENODEV;
98
99 if (index < 0 || index >= PWM_NCHAN || !ch)
100 return -EINVAL;
101 memset(ch, 0, sizeof *ch);
102
103 spin_lock_irqsave(&pwm->lock, flags);
104 if (pwm->channel[index])
105 status = -EBUSY;
106 else {
107 clk_enable(pwm->clk);
108
109 ch->regs = pwmc_regs(pwm, index);
110 ch->index = index;
111
112 /* REVISIT: ap7000 seems to go 2x as fast as we expect!! */
113 ch->mck = clk_get_rate(pwm->clk);
114
115 pwm->channel[index] = ch;
116 pwm->handler[index] = NULL;
117
118 /* channel and irq are always disabled when we return */
119 pwm_writel(pwm, PWM_DIS, 1 << index);
120 pwm_writel(pwm, PWM_IDR, 1 << index);
121 }
122 spin_unlock_irqrestore(&pwm->lock, flags);
123 return status;
124}
125EXPORT_SYMBOL(pwm_channel_alloc);
126
127static int pwmcheck(struct pwm_channel *ch)
128{
129 int index;
130
131 if (!pwm)
132 return -ENODEV;
133 if (!ch)
134 return -EINVAL;
135 index = ch->index;
136 if (index < 0 || index >= PWM_NCHAN || pwm->channel[index] != ch)
137 return -EINVAL;
138
139 return index;
140}
141
142/**
143 * pwm_channel_free - release a previously allocated channel
144 * @ch: the channel being released
145 *
146 * The channel is completely shut down (counter and IRQ disabled),
147 * and made available for re-use. Returns zero, or negative errno.
148 */
149int pwm_channel_free(struct pwm_channel *ch)
150{
151 unsigned long flags;
152 int t;
153
154 spin_lock_irqsave(&pwm->lock, flags);
155 t = pwmcheck(ch);
156 if (t >= 0) {
157 pwm->channel[t] = NULL;
158 pwm->handler[t] = NULL;
159
160 /* channel and irq are always disabled when we return */
161 pwm_writel(pwm, PWM_DIS, 1 << t);
162 pwm_writel(pwm, PWM_IDR, 1 << t);
163
164 clk_disable(pwm->clk);
165 t = 0;
166 }
167 spin_unlock_irqrestore(&pwm->lock, flags);
168 return t;
169}
170EXPORT_SYMBOL(pwm_channel_free);
171
172int __pwm_channel_onoff(struct pwm_channel *ch, int enabled)
173{
174 unsigned long flags;
175 int t;
176
177 /* OMITTED FUNCTIONALITY: starting several channels in synch */
178
179 spin_lock_irqsave(&pwm->lock, flags);
180 t = pwmcheck(ch);
181 if (t >= 0) {
182 pwm_writel(pwm, enabled ? PWM_ENA : PWM_DIS, 1 << t);
183 t = 0;
184 pwm_dumpregs(ch, enabled ? "enable" : "disable");
185 }
186 spin_unlock_irqrestore(&pwm->lock, flags);
187
188 return t;
189}
190EXPORT_SYMBOL(__pwm_channel_onoff);
191
192/**
193 * pwm_clk_alloc - allocate and configure CLKA or CLKB
194 * @prescale: from 0..10, the power of two used to divide MCK
195 * @div: from 1..255, the linear divisor to use
196 *
197 * Returns PWM_CPR_CLKA, PWM_CPR_CLKB, or negative errno. The allocated
198 * clock will run with a period of (2^prescale * div) / MCK, or twice as
199 * long if center aligned PWM output is used. The clock must later be
200 * deconfigured using pwm_clk_free().
201 */
202int pwm_clk_alloc(unsigned prescale, unsigned div)
203{
204 unsigned long flags;
205 u32 mr;
206 u32 val = (prescale << 8) | div;
207 int ret = -EBUSY;
208
209 if (prescale >= 10 || div == 0 || div > 255)
210 return -EINVAL;
211
212 spin_lock_irqsave(&pwm->lock, flags);
213 mr = pwm_readl(pwm, PWM_MR);
214 if ((mr & 0xffff) == 0) {
215 mr |= val;
216 ret = PWM_CPR_CLKA;
217 } else if ((mr & (0xffff << 16)) == 0) {
218 mr |= val << 16;
219 ret = PWM_CPR_CLKB;
220 }
221 if (ret > 0)
222 pwm_writel(pwm, PWM_MR, mr);
223 spin_unlock_irqrestore(&pwm->lock, flags);
224 return ret;
225}
226EXPORT_SYMBOL(pwm_clk_alloc);
227
228/**
229 * pwm_clk_free - deconfigure and release CLKA or CLKB
230 *
231 * Reverses the effect of pwm_clk_alloc().
232 */
233void pwm_clk_free(unsigned clk)
234{
235 unsigned long flags;
236 u32 mr;
237
238 spin_lock_irqsave(&pwm->lock, flags);
239 mr = pwm_readl(pwm, PWM_MR);
240 if (clk == PWM_CPR_CLKA)
241 pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 0));
242 if (clk == PWM_CPR_CLKB)
243 pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 16));
244 spin_unlock_irqrestore(&pwm->lock, flags);
245}
246EXPORT_SYMBOL(pwm_clk_free);
247
248/**
249 * pwm_channel_handler - manage channel's IRQ handler
250 * @ch: the channel
251 * @handler: the handler to use, possibly NULL
252 *
253 * If the handler is non-null, the handler will be called after every
254 * period of this PWM channel. If the handler is null, this channel
255 * won't generate an IRQ.
256 */
257int pwm_channel_handler(struct pwm_channel *ch,
258 void (*handler)(struct pwm_channel *ch))
259{
260 unsigned long flags;
261 int t;
262
263 spin_lock_irqsave(&pwm->lock, flags);
264 t = pwmcheck(ch);
265 if (t >= 0) {
266 pwm->handler[t] = handler;
267 pwm_writel(pwm, handler ? PWM_IER : PWM_IDR, 1 << t);
268 t = 0;
269 }
270 spin_unlock_irqrestore(&pwm->lock, flags);
271
272 return t;
273}
274EXPORT_SYMBOL(pwm_channel_handler);
275
276static irqreturn_t pwm_irq(int id, void *_pwm)
277{
278 struct pwm *p = _pwm;
279 irqreturn_t handled = IRQ_NONE;
280 u32 irqstat;
281 int index;
282
283 spin_lock(&p->lock);
284
285 /* ack irqs, then handle them */
286 irqstat = pwm_readl(pwm, PWM_ISR);
287
288 while (irqstat) {
289 struct pwm_channel *ch;
290 void (*handler)(struct pwm_channel *ch);
291
292 index = ffs(irqstat) - 1;
293 irqstat &= ~(1 << index);
294 ch = pwm->channel[index];
295 handler = pwm->handler[index];
296 if (handler && ch) {
297 spin_unlock(&p->lock);
298 handler(ch);
299 spin_lock(&p->lock);
300 handled = IRQ_HANDLED;
301 }
302 }
303
304 spin_unlock(&p->lock);
305 return handled;
306}
307
308static int __init pwm_probe(struct platform_device *pdev)
309{
310 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
311 int irq = platform_get_irq(pdev, 0);
312 u32 *mp = pdev->dev.platform_data;
313 struct pwm *p;
314 int status = -EIO;
315
316 if (pwm)
317 return -EBUSY;
318 if (!r || irq < 0 || !mp || !*mp)
319 return -ENODEV;
320 if (*mp & ~((1<<PWM_NCHAN)-1)) {
321 dev_warn(&pdev->dev, "mask 0x%x ... more than %d channels\n",
322 *mp, PWM_NCHAN);
323 return -EINVAL;
324 }
325
326 p = kzalloc(sizeof(*p), GFP_KERNEL);
327 if (!p)
328 return -ENOMEM;
329
330 spin_lock_init(&p->lock);
331 p->pdev = pdev;
332 p->mask = *mp;
333 p->irq = irq;
334 p->base = ioremap(r->start, resource_size(r));
335 if (!p->base)
336 goto fail;
337 p->clk = clk_get(&pdev->dev, "pwm_clk");
338 if (IS_ERR(p->clk)) {
339 status = PTR_ERR(p->clk);
340 p->clk = NULL;
341 goto fail;
342 }
343
344 status = request_irq(irq, pwm_irq, 0, pdev->name, p);
345 if (status < 0)
346 goto fail;
347
348 pwm = p;
349 platform_set_drvdata(pdev, p);
350
351 return 0;
352
353fail:
354 if (p->clk)
355 clk_put(p->clk);
356 if (p->base)
357 iounmap(p->base);
358
359 kfree(p);
360 return status;
361}
362
363static int __exit pwm_remove(struct platform_device *pdev)
364{
365 struct pwm *p = platform_get_drvdata(pdev);
366
367 if (p != pwm)
368 return -EINVAL;
369
370 clk_enable(pwm->clk);
371 pwm_writel(pwm, PWM_DIS, (1 << PWM_NCHAN) - 1);
372 pwm_writel(pwm, PWM_IDR, (1 << PWM_NCHAN) - 1);
373 clk_disable(pwm->clk);
374
375 pwm = NULL;
376
377 free_irq(p->irq, p);
378 clk_put(p->clk);
379 iounmap(p->base);
380 kfree(p);
381
382 return 0;
383}
384
385static struct platform_driver atmel_pwm_driver = {
386 .driver = {
387 .name = "atmel_pwm",
388 .owner = THIS_MODULE,
389 },
390 .remove = __exit_p(pwm_remove),
391
392 /* NOTE: PWM can keep running in AVR32 "idle" and "frozen" states;
393 * and all AT91sam9263 states, albeit at reduced clock rate if
394 * MCK becomes the slow clock (i.e. what Linux labels STR).
395 */
396};
397
398module_platform_driver_probe(atmel_pwm_driver, pwm_probe);
399
400MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module");
401MODULE_LICENSE("GPL");
402MODULE_ALIAS("platform:atmel_pwm");
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 21df477be0c8..2d8a4d05d78f 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -46,4 +46,12 @@ config PCI_HOST_GENERIC
46 Say Y here if you want to support a simple generic PCI host 46 Say Y here if you want to support a simple generic PCI host
47 controller, such as the one emulated by kvmtool. 47 controller, such as the one emulated by kvmtool.
48 48
49config PCIE_SPEAR13XX
50 tristate "STMicroelectronics SPEAr PCIe controller"
51 depends on ARCH_SPEAR13XX
52 select PCIEPORTBUS
53 select PCIE_DW
54 help
55 Say Y here if you want PCIe support on SPEAr13XX SoCs.
56
49endmenu 57endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 611ba4b48c94..0daec7941aba 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
6obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o 6obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
7obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o 7obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o
8obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o 8obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
9obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 60a7299e9632..abd65784618d 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -234,7 +234,6 @@ struct tegra_pcie_soc_data {
234 bool has_pex_clkreq_en; 234 bool has_pex_clkreq_en;
235 bool has_pex_bias_ctrl; 235 bool has_pex_bias_ctrl;
236 bool has_intr_prsnt_sense; 236 bool has_intr_prsnt_sense;
237 bool has_avdd_supply;
238 bool has_cml_clk; 237 bool has_cml_clk;
239}; 238};
240 239
@@ -273,9 +272,8 @@ struct tegra_pcie {
273 unsigned int num_ports; 272 unsigned int num_ports;
274 u32 xbar_config; 273 u32 xbar_config;
275 274
276 struct regulator *pex_clk_supply; 275 struct regulator_bulk_data *supplies;
277 struct regulator *vdd_supply; 276 unsigned int num_supplies;
278 struct regulator *avdd_supply;
279 277
280 const struct tegra_pcie_soc_data *soc_data; 278 const struct tegra_pcie_soc_data *soc_data;
281}; 279};
@@ -895,7 +893,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
895 893
896static void tegra_pcie_power_off(struct tegra_pcie *pcie) 894static void tegra_pcie_power_off(struct tegra_pcie *pcie)
897{ 895{
898 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
899 int err; 896 int err;
900 897
901 /* TODO: disable and unprepare clocks? */ 898 /* TODO: disable and unprepare clocks? */
@@ -906,23 +903,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
906 903
907 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 904 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
908 905
909 if (soc->has_avdd_supply) { 906 err = regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
910 err = regulator_disable(pcie->avdd_supply);
911 if (err < 0)
912 dev_warn(pcie->dev,
913 "failed to disable AVDD regulator: %d\n",
914 err);
915 }
916
917 err = regulator_disable(pcie->pex_clk_supply);
918 if (err < 0) 907 if (err < 0)
919 dev_warn(pcie->dev, "failed to disable pex-clk regulator: %d\n", 908 dev_warn(pcie->dev, "failed to disable regulators: %d\n", err);
920 err);
921
922 err = regulator_disable(pcie->vdd_supply);
923 if (err < 0)
924 dev_warn(pcie->dev, "failed to disable VDD regulator: %d\n",
925 err);
926} 909}
927 910
928static int tegra_pcie_power_on(struct tegra_pcie *pcie) 911static int tegra_pcie_power_on(struct tegra_pcie *pcie)
@@ -937,28 +920,9 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
937 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 920 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
938 921
939 /* enable regulators */ 922 /* enable regulators */
940 err = regulator_enable(pcie->vdd_supply); 923 err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
941 if (err < 0) { 924 if (err < 0)
942 dev_err(pcie->dev, "failed to enable VDD regulator: %d\n", err); 925 dev_err(pcie->dev, "failed to enable regulators: %d\n", err);
943 return err;
944 }
945
946 err = regulator_enable(pcie->pex_clk_supply);
947 if (err < 0) {
948 dev_err(pcie->dev, "failed to enable pex-clk regulator: %d\n",
949 err);
950 return err;
951 }
952
953 if (soc->has_avdd_supply) {
954 err = regulator_enable(pcie->avdd_supply);
955 if (err < 0) {
956 dev_err(pcie->dev,
957 "failed to enable AVDD regulator: %d\n",
958 err);
959 return err;
960 }
961 }
962 926
963 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, 927 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
964 pcie->pex_clk, 928 pcie->pex_clk,
@@ -1395,14 +1359,157 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
1395 return -EINVAL; 1359 return -EINVAL;
1396} 1360}
1397 1361
1362/*
1363 * Check whether a given set of supplies is available in a device tree node.
1364 * This is used to check whether the new or the legacy device tree bindings
1365 * should be used.
1366 */
1367static bool of_regulator_bulk_available(struct device_node *np,
1368 struct regulator_bulk_data *supplies,
1369 unsigned int num_supplies)
1370{
1371 char property[32];
1372 unsigned int i;
1373
1374 for (i = 0; i < num_supplies; i++) {
1375 snprintf(property, 32, "%s-supply", supplies[i].supply);
1376
1377 if (of_find_property(np, property, NULL) == NULL)
1378 return false;
1379 }
1380
1381 return true;
1382}
1383
1384/*
1385 * Old versions of the device tree binding for this device used a set of power
1386 * supplies that didn't match the hardware inputs. This happened to work for a
1387 * number of cases but is not future proof. However to preserve backwards-
1388 * compatibility with old device trees, this function will try to use the old
1389 * set of supplies.
1390 */
1391static int tegra_pcie_get_legacy_regulators(struct tegra_pcie *pcie)
1392{
1393 struct device_node *np = pcie->dev->of_node;
1394
1395 if (of_device_is_compatible(np, "nvidia,tegra30-pcie"))
1396 pcie->num_supplies = 3;
1397 else if (of_device_is_compatible(np, "nvidia,tegra20-pcie"))
1398 pcie->num_supplies = 2;
1399
1400 if (pcie->num_supplies == 0) {
1401 dev_err(pcie->dev, "device %s not supported in legacy mode\n",
1402 np->full_name);
1403 return -ENODEV;
1404 }
1405
1406 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
1407 sizeof(*pcie->supplies),
1408 GFP_KERNEL);
1409 if (!pcie->supplies)
1410 return -ENOMEM;
1411
1412 pcie->supplies[0].supply = "pex-clk";
1413 pcie->supplies[1].supply = "vdd";
1414
1415 if (pcie->num_supplies > 2)
1416 pcie->supplies[2].supply = "avdd";
1417
1418 return devm_regulator_bulk_get(pcie->dev, pcie->num_supplies,
1419 pcie->supplies);
1420}
1421
1422/*
1423 * Obtains the list of regulators required for a particular generation of the
1424 * IP block.
1425 *
1426 * This would've been nice to do simply by providing static tables for use
1427 * with the regulator_bulk_*() API, but unfortunately Tegra30 is a bit quirky
1428 * in that it has two pairs or AVDD_PEX and VDD_PEX supplies (PEXA and PEXB)
1429 * and either seems to be optional depending on which ports are being used.
1430 */
1431static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
1432{
1433 struct device_node *np = pcie->dev->of_node;
1434 unsigned int i = 0;
1435
1436 if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
1437 bool need_pexa = false, need_pexb = false;
1438
1439 /* VDD_PEXA and AVDD_PEXA supply lanes 0 to 3 */
1440 if (lane_mask & 0x0f)
1441 need_pexa = true;
1442
1443 /* VDD_PEXB and AVDD_PEXB supply lanes 4 to 5 */
1444 if (lane_mask & 0x30)
1445 need_pexb = true;
1446
1447 pcie->num_supplies = 4 + (need_pexa ? 2 : 0) +
1448 (need_pexb ? 2 : 0);
1449
1450 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
1451 sizeof(*pcie->supplies),
1452 GFP_KERNEL);
1453 if (!pcie->supplies)
1454 return -ENOMEM;
1455
1456 pcie->supplies[i++].supply = "avdd-pex-pll";
1457 pcie->supplies[i++].supply = "hvdd-pex";
1458 pcie->supplies[i++].supply = "vddio-pex-ctl";
1459 pcie->supplies[i++].supply = "avdd-plle";
1460
1461 if (need_pexa) {
1462 pcie->supplies[i++].supply = "avdd-pexa";
1463 pcie->supplies[i++].supply = "vdd-pexa";
1464 }
1465
1466 if (need_pexb) {
1467 pcie->supplies[i++].supply = "avdd-pexb";
1468 pcie->supplies[i++].supply = "vdd-pexb";
1469 }
1470 } else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
1471 pcie->num_supplies = 5;
1472
1473 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
1474 sizeof(*pcie->supplies),
1475 GFP_KERNEL);
1476 if (!pcie->supplies)
1477 return -ENOMEM;
1478
1479 pcie->supplies[0].supply = "avdd-pex";
1480 pcie->supplies[1].supply = "vdd-pex";
1481 pcie->supplies[2].supply = "avdd-pex-pll";
1482 pcie->supplies[3].supply = "avdd-plle";
1483 pcie->supplies[4].supply = "vddio-pex-clk";
1484 }
1485
1486 if (of_regulator_bulk_available(pcie->dev->of_node, pcie->supplies,
1487 pcie->num_supplies))
1488 return devm_regulator_bulk_get(pcie->dev, pcie->num_supplies,
1489 pcie->supplies);
1490
1491 /*
1492 * If not all regulators are available for this new scheme, assume
1493 * that the device tree complies with an older version of the device
1494 * tree binding.
1495 */
1496 dev_info(pcie->dev, "using legacy DT binding for power supplies\n");
1497
1498 devm_kfree(pcie->dev, pcie->supplies);
1499 pcie->num_supplies = 0;
1500
1501 return tegra_pcie_get_legacy_regulators(pcie);
1502}
1503
1398static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) 1504static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1399{ 1505{
1400 const struct tegra_pcie_soc_data *soc = pcie->soc_data; 1506 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
1401 struct device_node *np = pcie->dev->of_node, *port; 1507 struct device_node *np = pcie->dev->of_node, *port;
1402 struct of_pci_range_parser parser; 1508 struct of_pci_range_parser parser;
1403 struct of_pci_range range; 1509 struct of_pci_range range;
1510 u32 lanes = 0, mask = 0;
1511 unsigned int lane = 0;
1404 struct resource res; 1512 struct resource res;
1405 u32 lanes = 0;
1406 int err; 1513 int err;
1407 1514
1408 if (of_pci_range_parser_init(&parser, np)) { 1515 if (of_pci_range_parser_init(&parser, np)) {
@@ -1410,20 +1517,6 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1410 return -EINVAL; 1517 return -EINVAL;
1411 } 1518 }
1412 1519
1413 pcie->vdd_supply = devm_regulator_get(pcie->dev, "vdd");
1414 if (IS_ERR(pcie->vdd_supply))
1415 return PTR_ERR(pcie->vdd_supply);
1416
1417 pcie->pex_clk_supply = devm_regulator_get(pcie->dev, "pex-clk");
1418 if (IS_ERR(pcie->pex_clk_supply))
1419 return PTR_ERR(pcie->pex_clk_supply);
1420
1421 if (soc->has_avdd_supply) {
1422 pcie->avdd_supply = devm_regulator_get(pcie->dev, "avdd");
1423 if (IS_ERR(pcie->avdd_supply))
1424 return PTR_ERR(pcie->avdd_supply);
1425 }
1426
1427 for_each_of_pci_range(&parser, &range) { 1520 for_each_of_pci_range(&parser, &range) {
1428 of_pci_range_to_resource(&range, np, &res); 1521 of_pci_range_to_resource(&range, np, &res);
1429 1522
@@ -1491,8 +1584,13 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1491 1584
1492 lanes |= value << (index << 3); 1585 lanes |= value << (index << 3);
1493 1586
1494 if (!of_device_is_available(port)) 1587 if (!of_device_is_available(port)) {
1588 lane += value;
1495 continue; 1589 continue;
1590 }
1591
1592 mask |= ((1 << value) - 1) << lane;
1593 lane += value;
1496 1594
1497 rp = devm_kzalloc(pcie->dev, sizeof(*rp), GFP_KERNEL); 1595 rp = devm_kzalloc(pcie->dev, sizeof(*rp), GFP_KERNEL);
1498 if (!rp) 1596 if (!rp)
@@ -1523,6 +1621,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1523 return err; 1621 return err;
1524 } 1622 }
1525 1623
1624 err = tegra_pcie_get_regulators(pcie, mask);
1625 if (err < 0)
1626 return err;
1627
1526 return 0; 1628 return 0;
1527} 1629}
1528 1630
@@ -1616,7 +1718,6 @@ static const struct tegra_pcie_soc_data tegra20_pcie_data = {
1616 .has_pex_clkreq_en = false, 1718 .has_pex_clkreq_en = false,
1617 .has_pex_bias_ctrl = false, 1719 .has_pex_bias_ctrl = false,
1618 .has_intr_prsnt_sense = false, 1720 .has_intr_prsnt_sense = false,
1619 .has_avdd_supply = false,
1620 .has_cml_clk = false, 1721 .has_cml_clk = false,
1621}; 1722};
1622 1723
@@ -1628,7 +1729,6 @@ static const struct tegra_pcie_soc_data tegra30_pcie_data = {
1628 .has_pex_clkreq_en = true, 1729 .has_pex_clkreq_en = true,
1629 .has_pex_bias_ctrl = true, 1730 .has_pex_bias_ctrl = true,
1630 .has_intr_prsnt_sense = true, 1731 .has_intr_prsnt_sense = true,
1631 .has_avdd_supply = true,
1632 .has_cml_clk = true, 1732 .has_cml_clk = true,
1633}; 1733};
1634 1734
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
new file mode 100644
index 000000000000..6dea9e43a75c
--- /dev/null
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -0,0 +1,393 @@
1/*
2 * PCIe host controller driver for ST Microelectronics SPEAr13xx SoCs
3 *
4 * SPEAr13xx PCIe Glue Layer Source Code
5 *
6 * Copyright (C) 2010-2014 ST Microelectronics
7 * Pratyush Anand <pratyush.anand@st.com>
8 * Mohit Kumar <mohit.kumar@st.com>
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 */
14
15#include <linux/clk.h>
16#include <linux/delay.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/pci.h>
22#include <linux/phy/phy.h>
23#include <linux/platform_device.h>
24#include <linux/resource.h>
25
26#include "pcie-designware.h"
27
28struct spear13xx_pcie {
29 void __iomem *app_base;
30 struct phy *phy;
31 struct clk *clk;
32 struct pcie_port pp;
33 bool is_gen1;
34};
35
36struct pcie_app_reg {
37 u32 app_ctrl_0; /* cr0 */
38 u32 app_ctrl_1; /* cr1 */
39 u32 app_status_0; /* cr2 */
40 u32 app_status_1; /* cr3 */
41 u32 msg_status; /* cr4 */
42 u32 msg_payload; /* cr5 */
43 u32 int_sts; /* cr6 */
44 u32 int_clr; /* cr7 */
45 u32 int_mask; /* cr8 */
46 u32 mst_bmisc; /* cr9 */
47 u32 phy_ctrl; /* cr10 */
48 u32 phy_status; /* cr11 */
49 u32 cxpl_debug_info_0; /* cr12 */
50 u32 cxpl_debug_info_1; /* cr13 */
51 u32 ven_msg_ctrl_0; /* cr14 */
52 u32 ven_msg_ctrl_1; /* cr15 */
53 u32 ven_msg_data_0; /* cr16 */
54 u32 ven_msg_data_1; /* cr17 */
55 u32 ven_msi_0; /* cr18 */
56 u32 ven_msi_1; /* cr19 */
57 u32 mst_rmisc; /* cr20 */
58};
59
60/* CR0 ID */
61#define RX_LANE_FLIP_EN_ID 0
62#define TX_LANE_FLIP_EN_ID 1
63#define SYS_AUX_PWR_DET_ID 2
64#define APP_LTSSM_ENABLE_ID 3
65#define SYS_ATTEN_BUTTON_PRESSED_ID 4
66#define SYS_MRL_SENSOR_STATE_ID 5
67#define SYS_PWR_FAULT_DET_ID 6
68#define SYS_MRL_SENSOR_CHGED_ID 7
69#define SYS_PRE_DET_CHGED_ID 8
70#define SYS_CMD_CPLED_INT_ID 9
71#define APP_INIT_RST_0_ID 11
72#define APP_REQ_ENTR_L1_ID 12
73#define APP_READY_ENTR_L23_ID 13
74#define APP_REQ_EXIT_L1_ID 14
75#define DEVICE_TYPE_EP (0 << 25)
76#define DEVICE_TYPE_LEP (1 << 25)
77#define DEVICE_TYPE_RC (4 << 25)
78#define SYS_INT_ID 29
79#define MISCTRL_EN_ID 30
80#define REG_TRANSLATION_ENABLE 31
81
82/* CR1 ID */
83#define APPS_PM_XMT_TURNOFF_ID 2
84#define APPS_PM_XMT_PME_ID 5
85
86/* CR3 ID */
87#define XMLH_LTSSM_STATE_DETECT_QUIET 0x00
88#define XMLH_LTSSM_STATE_DETECT_ACT 0x01
89#define XMLH_LTSSM_STATE_POLL_ACTIVE 0x02
90#define XMLH_LTSSM_STATE_POLL_COMPLIANCE 0x03
91#define XMLH_LTSSM_STATE_POLL_CONFIG 0x04
92#define XMLH_LTSSM_STATE_PRE_DETECT_QUIET 0x05
93#define XMLH_LTSSM_STATE_DETECT_WAIT 0x06
94#define XMLH_LTSSM_STATE_CFG_LINKWD_START 0x07
95#define XMLH_LTSSM_STATE_CFG_LINKWD_ACEPT 0x08
96#define XMLH_LTSSM_STATE_CFG_LANENUM_WAIT 0x09
97#define XMLH_LTSSM_STATE_CFG_LANENUM_ACEPT 0x0A
98#define XMLH_LTSSM_STATE_CFG_COMPLETE 0x0B
99#define XMLH_LTSSM_STATE_CFG_IDLE 0x0C
100#define XMLH_LTSSM_STATE_RCVRY_LOCK 0x0D
101#define XMLH_LTSSM_STATE_RCVRY_SPEED 0x0E
102#define XMLH_LTSSM_STATE_RCVRY_RCVRCFG 0x0F
103#define XMLH_LTSSM_STATE_RCVRY_IDLE 0x10
104#define XMLH_LTSSM_STATE_L0 0x11
105#define XMLH_LTSSM_STATE_L0S 0x12
106#define XMLH_LTSSM_STATE_L123_SEND_EIDLE 0x13
107#define XMLH_LTSSM_STATE_L1_IDLE 0x14
108#define XMLH_LTSSM_STATE_L2_IDLE 0x15
109#define XMLH_LTSSM_STATE_L2_WAKE 0x16
110#define XMLH_LTSSM_STATE_DISABLED_ENTRY 0x17
111#define XMLH_LTSSM_STATE_DISABLED_IDLE 0x18
112#define XMLH_LTSSM_STATE_DISABLED 0x19
113#define XMLH_LTSSM_STATE_LPBK_ENTRY 0x1A
114#define XMLH_LTSSM_STATE_LPBK_ACTIVE 0x1B
115#define XMLH_LTSSM_STATE_LPBK_EXIT 0x1C
116#define XMLH_LTSSM_STATE_LPBK_EXIT_TIMEOUT 0x1D
117#define XMLH_LTSSM_STATE_HOT_RESET_ENTRY 0x1E
118#define XMLH_LTSSM_STATE_HOT_RESET 0x1F
119#define XMLH_LTSSM_STATE_MASK 0x3F
120#define XMLH_LINK_UP (1 << 6)
121
122/* CR4 ID */
123#define CFG_MSI_EN_ID 18
124
125/* CR6 */
126#define INTA_CTRL_INT (1 << 7)
127#define INTB_CTRL_INT (1 << 8)
128#define INTC_CTRL_INT (1 << 9)
129#define INTD_CTRL_INT (1 << 10)
130#define MSI_CTRL_INT (1 << 26)
131
132/* CR19 ID */
133#define VEN_MSI_REQ_ID 11
134#define VEN_MSI_FUN_NUM_ID 8
135#define VEN_MSI_TC_ID 5
136#define VEN_MSI_VECTOR_ID 0
137#define VEN_MSI_REQ_EN ((u32)0x1 << VEN_MSI_REQ_ID)
138#define VEN_MSI_FUN_NUM_MASK ((u32)0x7 << VEN_MSI_FUN_NUM_ID)
139#define VEN_MSI_TC_MASK ((u32)0x7 << VEN_MSI_TC_ID)
140#define VEN_MSI_VECTOR_MASK ((u32)0x1F << VEN_MSI_VECTOR_ID)
141
142#define EXP_CAP_ID_OFFSET 0x70
143
144#define to_spear13xx_pcie(x) container_of(x, struct spear13xx_pcie, pp)
145
146static int spear13xx_pcie_establish_link(struct pcie_port *pp)
147{
148 u32 val;
149 int count = 0;
150 struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
151 struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
152 u32 exp_cap_off = EXP_CAP_ID_OFFSET;
153
154 if (dw_pcie_link_up(pp)) {
155 dev_err(pp->dev, "link already up\n");
156 return 0;
157 }
158
159 dw_pcie_setup_rc(pp);
160
161 /*
162 * this controller support only 128 bytes read size, however its
163 * default value in capability register is 512 bytes. So force
164 * it to 128 here.
165 */
166 dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, &val);
167 val &= ~PCI_EXP_DEVCTL_READRQ;
168 dw_pcie_cfg_write(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, val);
169
170 dw_pcie_cfg_write(pp->dbi_base, PCI_VENDOR_ID, 2, 0x104A);
171 dw_pcie_cfg_write(pp->dbi_base, PCI_DEVICE_ID, 2, 0xCD80);
172
173 /*
174 * if is_gen1 is set then handle it, so that some buggy card
175 * also works
176 */
177 if (spear13xx_pcie->is_gen1) {
178 dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCAP, 4,
179 &val);
180 if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
181 val &= ~((u32)PCI_EXP_LNKCAP_SLS);
182 val |= PCI_EXP_LNKCAP_SLS_2_5GB;
183 dw_pcie_cfg_write(pp->dbi_base, exp_cap_off +
184 PCI_EXP_LNKCAP, 4, val);
185 }
186
187 dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCTL2, 4,
188 &val);
189 if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
190 val &= ~((u32)PCI_EXP_LNKCAP_SLS);
191 val |= PCI_EXP_LNKCAP_SLS_2_5GB;
192 dw_pcie_cfg_write(pp->dbi_base, exp_cap_off +
193 PCI_EXP_LNKCTL2, 4, val);
194 }
195 }
196
197 /* enable ltssm */
198 writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID)
199 | (1 << APP_LTSSM_ENABLE_ID)
200 | ((u32)1 << REG_TRANSLATION_ENABLE),
201 &app_reg->app_ctrl_0);
202
203 /* check if the link is up or not */
204 while (!dw_pcie_link_up(pp)) {
205 mdelay(100);
206 count++;
207 if (count == 10) {
208 dev_err(pp->dev, "link Fail\n");
209 return -EINVAL;
210 }
211 }
212 dev_info(pp->dev, "link up\n");
213
214 return 0;
215}
216
217static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)
218{
219 struct pcie_port *pp = arg;
220 struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
221 struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
222 unsigned int status;
223
224 status = readl(&app_reg->int_sts);
225
226 if (status & MSI_CTRL_INT) {
227 if (!IS_ENABLED(CONFIG_PCI_MSI))
228 BUG();
229 dw_handle_msi_irq(pp);
230 }
231
232 writel(status, &app_reg->int_clr);
233
234 return IRQ_HANDLED;
235}
236
237static void spear13xx_pcie_enable_interrupts(struct pcie_port *pp)
238{
239 struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
240 struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
241
242 /* Enable MSI interrupt */
243 if (IS_ENABLED(CONFIG_PCI_MSI)) {
244 dw_pcie_msi_init(pp);
245 writel(readl(&app_reg->int_mask) |
246 MSI_CTRL_INT, &app_reg->int_mask);
247 }
248}
249
250static int spear13xx_pcie_link_up(struct pcie_port *pp)
251{
252 struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
253 struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
254
255 if (readl(&app_reg->app_status_1) & XMLH_LINK_UP)
256 return 1;
257
258 return 0;
259}
260
261static void spear13xx_pcie_host_init(struct pcie_port *pp)
262{
263 spear13xx_pcie_establish_link(pp);
264 spear13xx_pcie_enable_interrupts(pp);
265}
266
267static struct pcie_host_ops spear13xx_pcie_host_ops = {
268 .link_up = spear13xx_pcie_link_up,
269 .host_init = spear13xx_pcie_host_init,
270};
271
272static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev)
273{
274 struct device *dev = &pdev->dev;
275 int ret;
276
277 pp->irq = platform_get_irq(pdev, 0);
278 if (!pp->irq) {
279 dev_err(dev, "failed to get irq\n");
280 return -ENODEV;
281 }
282 ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler,
283 IRQF_SHARED, "spear1340-pcie", pp);
284 if (ret) {
285 dev_err(dev, "failed to request irq %d\n", pp->irq);
286 return ret;
287 }
288
289 pp->root_bus_nr = -1;
290 pp->ops = &spear13xx_pcie_host_ops;
291
292 ret = dw_pcie_host_init(pp);
293 if (ret) {
294 dev_err(dev, "failed to initialize host\n");
295 return ret;
296 }
297
298 return 0;
299}
300
301static int __init spear13xx_pcie_probe(struct platform_device *pdev)
302{
303 struct spear13xx_pcie *spear13xx_pcie;
304 struct pcie_port *pp;
305 struct device *dev = &pdev->dev;
306 struct device_node *np = pdev->dev.of_node;
307 struct resource *dbi_base;
308 int ret;
309
310 spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL);
311 if (!spear13xx_pcie) {
312 dev_err(dev, "no memory for SPEAr13xx pcie\n");
313 return -ENOMEM;
314 }
315
316 spear13xx_pcie->phy = devm_phy_get(dev, "pcie-phy");
317 if (IS_ERR(spear13xx_pcie->phy)) {
318 ret = PTR_ERR(spear13xx_pcie->phy);
319 if (ret == -EPROBE_DEFER)
320 dev_info(dev, "probe deferred\n");
321 else
322 dev_err(dev, "couldn't get pcie-phy\n");
323 return ret;
324 }
325
326 phy_init(spear13xx_pcie->phy);
327
328 spear13xx_pcie->clk = devm_clk_get(dev, NULL);
329 if (IS_ERR(spear13xx_pcie->clk)) {
330 dev_err(dev, "couldn't get clk for pcie\n");
331 return PTR_ERR(spear13xx_pcie->clk);
332 }
333 ret = clk_prepare_enable(spear13xx_pcie->clk);
334 if (ret) {
335 dev_err(dev, "couldn't enable clk for pcie\n");
336 return ret;
337 }
338
339 pp = &spear13xx_pcie->pp;
340
341 pp->dev = dev;
342
343 dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
344 pp->dbi_base = devm_ioremap_resource(dev, dbi_base);
345 if (IS_ERR(pp->dbi_base)) {
346 dev_err(dev, "couldn't remap dbi base %p\n", dbi_base);
347 ret = PTR_ERR(pp->dbi_base);
348 goto fail_clk;
349 }
350 spear13xx_pcie->app_base = pp->dbi_base + 0x2000;
351
352 if (of_property_read_bool(np, "st,pcie-is-gen1"))
353 spear13xx_pcie->is_gen1 = true;
354
355 ret = add_pcie_port(pp, pdev);
356 if (ret < 0)
357 goto fail_clk;
358
359 platform_set_drvdata(pdev, spear13xx_pcie);
360 return 0;
361
362fail_clk:
363 clk_disable_unprepare(spear13xx_pcie->clk);
364
365 return ret;
366}
367
368static const struct of_device_id spear13xx_pcie_of_match[] = {
369 { .compatible = "st,spear1340-pcie", },
370 {},
371};
372MODULE_DEVICE_TABLE(of, spear13xx_pcie_of_match);
373
374static struct platform_driver spear13xx_pcie_driver __initdata = {
375 .probe = spear13xx_pcie_probe,
376 .driver = {
377 .name = "spear-pcie",
378 .owner = THIS_MODULE,
379 .of_match_table = of_match_ptr(spear13xx_pcie_of_match),
380 },
381};
382
383/* SPEAr13xx PCIe driver does not allow module unload */
384
385static int __init pcie_init(void)
386{
387 return platform_driver_register(&spear13xx_pcie_driver);
388}
389module_init(pcie_init);
390
391MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver");
392MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
393MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index d1f5fc924c93..0dd742719154 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -197,13 +197,6 @@ config PHY_EXYNOS5_USBDRD
197 This driver provides PHY interface for USB 3.0 DRD controller 197 This driver provides PHY interface for USB 3.0 DRD controller
198 present on Exynos5 SoC series. 198 present on Exynos5 SoC series.
199 199
200config PHY_XGENE
201 tristate "APM X-Gene 15Gbps PHY support"
202 depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)
203 select GENERIC_PHY
204 help
205 This option enables support for APM X-Gene SoC multi-purpose PHY.
206
207config PHY_QCOM_APQ8064_SATA 200config PHY_QCOM_APQ8064_SATA
208 tristate "Qualcomm APQ8064 SATA SerDes/PHY driver" 201 tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
209 depends on ARCH_QCOM 202 depends on ARCH_QCOM
@@ -218,4 +211,23 @@ config PHY_QCOM_IPQ806X_SATA
218 depends on OF 211 depends on OF
219 select GENERIC_PHY 212 select GENERIC_PHY
220 213
214config PHY_ST_SPEAR1310_MIPHY
215 tristate "ST SPEAR1310-MIPHY driver"
216 select GENERIC_PHY
217 help
218 Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA.
219
220config PHY_ST_SPEAR1340_MIPHY
221 tristate "ST SPEAR1340-MIPHY driver"
222 select GENERIC_PHY
223 help
224 Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA.
225
226config PHY_XGENE
227 tristate "APM X-Gene 15Gbps PHY support"
228 depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)
229 select GENERIC_PHY
230 help
231 This option enables support for APM X-Gene SoC multi-purpose PHY.
232
221endmenu 233endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index ec24e915349b..95c69ed5ed45 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -23,6 +23,8 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
23phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o 23phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
24phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o 24phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
25obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o 25obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
26obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
27obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o 26obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
28obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o 27obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
28obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
29obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
30obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c
new file mode 100644
index 000000000000..6dcbfcddb372
--- /dev/null
+++ b/drivers/phy/phy-spear1310-miphy.c
@@ -0,0 +1,274 @@
1/*
2 * ST SPEAr1310-miphy driver
3 *
4 * Copyright (C) 2014 ST Microelectronics
5 * Pratyush Anand <pratyush.anand@st.com>
6 * Mohit Kumar <mohit.kumar@st.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/bitops.h>
15#include <linux/delay.h>
16#include <linux/dma-mapping.h>
17#include <linux/kernel.h>
18#include <linux/mfd/syscon.h>
19#include <linux/module.h>
20#include <linux/of_device.h>
21#include <linux/phy/phy.h>
22#include <linux/regmap.h>
23
24/* SPEAr1310 Registers */
25#define SPEAR1310_PCIE_SATA_CFG 0x3A4
26 #define SPEAR1310_PCIE_SATA2_SEL_PCIE (0 << 31)
27 #define SPEAR1310_PCIE_SATA1_SEL_PCIE (0 << 30)
28 #define SPEAR1310_PCIE_SATA0_SEL_PCIE (0 << 29)
29 #define SPEAR1310_PCIE_SATA2_SEL_SATA BIT(31)
30 #define SPEAR1310_PCIE_SATA1_SEL_SATA BIT(30)
31 #define SPEAR1310_PCIE_SATA0_SEL_SATA BIT(29)
32 #define SPEAR1310_SATA2_CFG_TX_CLK_EN BIT(27)
33 #define SPEAR1310_SATA2_CFG_RX_CLK_EN BIT(26)
34 #define SPEAR1310_SATA2_CFG_POWERUP_RESET BIT(25)
35 #define SPEAR1310_SATA2_CFG_PM_CLK_EN BIT(24)
36 #define SPEAR1310_SATA1_CFG_TX_CLK_EN BIT(23)
37 #define SPEAR1310_SATA1_CFG_RX_CLK_EN BIT(22)
38 #define SPEAR1310_SATA1_CFG_POWERUP_RESET BIT(21)
39 #define SPEAR1310_SATA1_CFG_PM_CLK_EN BIT(20)
40 #define SPEAR1310_SATA0_CFG_TX_CLK_EN BIT(19)
41 #define SPEAR1310_SATA0_CFG_RX_CLK_EN BIT(18)
42 #define SPEAR1310_SATA0_CFG_POWERUP_RESET BIT(17)
43 #define SPEAR1310_SATA0_CFG_PM_CLK_EN BIT(16)
44 #define SPEAR1310_PCIE2_CFG_DEVICE_PRESENT BIT(11)
45 #define SPEAR1310_PCIE2_CFG_POWERUP_RESET BIT(10)
46 #define SPEAR1310_PCIE2_CFG_CORE_CLK_EN BIT(9)
47 #define SPEAR1310_PCIE2_CFG_AUX_CLK_EN BIT(8)
48 #define SPEAR1310_PCIE1_CFG_DEVICE_PRESENT BIT(7)
49 #define SPEAR1310_PCIE1_CFG_POWERUP_RESET BIT(6)
50 #define SPEAR1310_PCIE1_CFG_CORE_CLK_EN BIT(5)
51 #define SPEAR1310_PCIE1_CFG_AUX_CLK_EN BIT(4)
52 #define SPEAR1310_PCIE0_CFG_DEVICE_PRESENT BIT(3)
53 #define SPEAR1310_PCIE0_CFG_POWERUP_RESET BIT(2)
54 #define SPEAR1310_PCIE0_CFG_CORE_CLK_EN BIT(1)
55 #define SPEAR1310_PCIE0_CFG_AUX_CLK_EN BIT(0)
56
57 #define SPEAR1310_PCIE_CFG_MASK(x) ((0xF << (x * 4)) | BIT((x + 29)))
58 #define SPEAR1310_SATA_CFG_MASK(x) ((0xF << (x * 4 + 16)) | \
59 BIT((x + 29)))
60 #define SPEAR1310_PCIE_CFG_VAL(x) \
61 (SPEAR1310_PCIE_SATA##x##_SEL_PCIE | \
62 SPEAR1310_PCIE##x##_CFG_AUX_CLK_EN | \
63 SPEAR1310_PCIE##x##_CFG_CORE_CLK_EN | \
64 SPEAR1310_PCIE##x##_CFG_POWERUP_RESET | \
65 SPEAR1310_PCIE##x##_CFG_DEVICE_PRESENT)
66 #define SPEAR1310_SATA_CFG_VAL(x) \
67 (SPEAR1310_PCIE_SATA##x##_SEL_SATA | \
68 SPEAR1310_SATA##x##_CFG_PM_CLK_EN | \
69 SPEAR1310_SATA##x##_CFG_POWERUP_RESET | \
70 SPEAR1310_SATA##x##_CFG_RX_CLK_EN | \
71 SPEAR1310_SATA##x##_CFG_TX_CLK_EN)
72
73#define SPEAR1310_PCIE_MIPHY_CFG_1 0x3A8
74 #define SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT BIT(31)
75 #define SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 BIT(28)
76 #define SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(x) (x << 16)
77 #define SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT BIT(15)
78 #define SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 BIT(12)
79 #define SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(x) (x << 0)
80 #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_MASK (0xFFFF)
81 #define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK (0xFFFF << 16)
82 #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA \
83 (SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
84 SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 | \
85 SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(60) | \
86 SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
87 SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 | \
88 SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(60))
89 #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
90 (SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(120))
91 #define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE \
92 (SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
93 SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(25) | \
94 SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
95 SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(25))
96
97#define SPEAR1310_PCIE_MIPHY_CFG_2 0x3AC
98
99enum spear1310_miphy_mode {
100 SATA,
101 PCIE,
102};
103
104struct spear1310_miphy_priv {
105 /* instance id of this phy */
106 u32 id;
107 /* phy mode: 0 for SATA 1 for PCIe */
108 enum spear1310_miphy_mode mode;
109 /* regmap for any soc specific misc registers */
110 struct regmap *misc;
111 /* phy struct pointer */
112 struct phy *phy;
113};
114
115static int spear1310_miphy_pcie_init(struct spear1310_miphy_priv *priv)
116{
117 u32 val;
118
119 regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
120 SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK,
121 SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE);
122
123 switch (priv->id) {
124 case 0:
125 val = SPEAR1310_PCIE_CFG_VAL(0);
126 break;
127 case 1:
128 val = SPEAR1310_PCIE_CFG_VAL(1);
129 break;
130 case 2:
131 val = SPEAR1310_PCIE_CFG_VAL(2);
132 break;
133 default:
134 return -EINVAL;
135 }
136
137 regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
138 SPEAR1310_PCIE_CFG_MASK(priv->id), val);
139
140 return 0;
141}
142
143static int spear1310_miphy_pcie_exit(struct spear1310_miphy_priv *priv)
144{
145 regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
146 SPEAR1310_PCIE_CFG_MASK(priv->id), 0);
147
148 regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
149 SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK, 0);
150
151 return 0;
152}
153
154static int spear1310_miphy_init(struct phy *phy)
155{
156 struct spear1310_miphy_priv *priv = phy_get_drvdata(phy);
157 int ret = 0;
158
159 if (priv->mode == PCIE)
160 ret = spear1310_miphy_pcie_init(priv);
161
162 return ret;
163}
164
165static int spear1310_miphy_exit(struct phy *phy)
166{
167 struct spear1310_miphy_priv *priv = phy_get_drvdata(phy);
168 int ret = 0;
169
170 if (priv->mode == PCIE)
171 ret = spear1310_miphy_pcie_exit(priv);
172
173 return ret;
174}
175
176static const struct of_device_id spear1310_miphy_of_match[] = {
177 { .compatible = "st,spear1310-miphy" },
178 { },
179};
180MODULE_DEVICE_TABLE(of, spear1310_miphy_of_match);
181
182static struct phy_ops spear1310_miphy_ops = {
183 .init = spear1310_miphy_init,
184 .exit = spear1310_miphy_exit,
185 .owner = THIS_MODULE,
186};
187
188static struct phy *spear1310_miphy_xlate(struct device *dev,
189 struct of_phandle_args *args)
190{
191 struct spear1310_miphy_priv *priv = dev_get_drvdata(dev);
192
193 if (args->args_count < 1) {
194 dev_err(dev, "DT did not pass correct no of args\n");
195 return NULL;
196 }
197
198 priv->mode = args->args[0];
199
200 if (priv->mode != SATA && priv->mode != PCIE) {
201 dev_err(dev, "DT did not pass correct phy mode\n");
202 return NULL;
203 }
204
205 return priv->phy;
206}
207
208static int spear1310_miphy_probe(struct platform_device *pdev)
209{
210 struct device *dev = &pdev->dev;
211 struct spear1310_miphy_priv *priv;
212 struct phy_provider *phy_provider;
213
214 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
215 if (!priv) {
216 dev_err(dev, "can't alloc spear1310_miphy private date memory\n");
217 return -ENOMEM;
218 }
219
220 priv->misc =
221 syscon_regmap_lookup_by_phandle(dev->of_node, "misc");
222 if (IS_ERR(priv->misc)) {
223 dev_err(dev, "failed to find misc regmap\n");
224 return PTR_ERR(priv->misc);
225 }
226
227 if (of_property_read_u32(dev->of_node, "phy-id", &priv->id)) {
228 dev_err(dev, "failed to find phy id\n");
229 return -EINVAL;
230 }
231
232 priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops, NULL);
233 if (IS_ERR(priv->phy)) {
234 dev_err(dev, "failed to create SATA PCIe PHY\n");
235 return PTR_ERR(priv->phy);
236 }
237
238 dev_set_drvdata(dev, priv);
239 phy_set_drvdata(priv->phy, priv);
240
241 phy_provider =
242 devm_of_phy_provider_register(dev, spear1310_miphy_xlate);
243 if (IS_ERR(phy_provider)) {
244 dev_err(dev, "failed to register phy provider\n");
245 return PTR_ERR(phy_provider);
246 }
247
248 return 0;
249}
250
251static struct platform_driver spear1310_miphy_driver = {
252 .probe = spear1310_miphy_probe,
253 .driver = {
254 .name = "spear1310-miphy",
255 .owner = THIS_MODULE,
256 .of_match_table = of_match_ptr(spear1310_miphy_of_match),
257 },
258};
259
260static int __init spear1310_miphy_phy_init(void)
261{
262 return platform_driver_register(&spear1310_miphy_driver);
263}
264module_init(spear1310_miphy_phy_init);
265
266static void __exit spear1310_miphy_phy_exit(void)
267{
268 platform_driver_unregister(&spear1310_miphy_driver);
269}
270module_exit(spear1310_miphy_phy_exit);
271
272MODULE_DESCRIPTION("ST SPEAR1310-MIPHY driver");
273MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
274MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c
new file mode 100644
index 000000000000..7135ba2603b6
--- /dev/null
+++ b/drivers/phy/phy-spear1340-miphy.c
@@ -0,0 +1,307 @@
1/*
2 * ST spear1340-miphy driver
3 *
4 * Copyright (C) 2014 ST Microelectronics
5 * Pratyush Anand <pratyush.anand@st.com>
6 * Mohit Kumar <mohit.kumar@st.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/bitops.h>
15#include <linux/delay.h>
16#include <linux/dma-mapping.h>
17#include <linux/kernel.h>
18#include <linux/mfd/syscon.h>
19#include <linux/module.h>
20#include <linux/of_device.h>
21#include <linux/phy/phy.h>
22#include <linux/regmap.h>
23
24/* SPEAr1340 Registers */
25/* Power Management Registers */
26#define SPEAR1340_PCM_CFG 0x100
27 #define SPEAR1340_PCM_CFG_SATA_POWER_EN BIT(11)
28#define SPEAR1340_PCM_WKUP_CFG 0x104
29#define SPEAR1340_SWITCH_CTR 0x108
30
31#define SPEAR1340_PERIP1_SW_RST 0x318
32 #define SPEAR1340_PERIP1_SW_RSATA BIT(12)
33#define SPEAR1340_PERIP2_SW_RST 0x31C
34#define SPEAR1340_PERIP3_SW_RST 0x320
35
36/* PCIE - SATA configuration registers */
37#define SPEAR1340_PCIE_SATA_CFG 0x424
38 /* PCIE CFG MASks */
39 #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT BIT(11)
40 #define SPEAR1340_PCIE_CFG_POWERUP_RESET BIT(10)
41 #define SPEAR1340_PCIE_CFG_CORE_CLK_EN BIT(9)
42 #define SPEAR1340_PCIE_CFG_AUX_CLK_EN BIT(8)
43 #define SPEAR1340_SATA_CFG_TX_CLK_EN BIT(4)
44 #define SPEAR1340_SATA_CFG_RX_CLK_EN BIT(3)
45 #define SPEAR1340_SATA_CFG_POWERUP_RESET BIT(2)
46 #define SPEAR1340_SATA_CFG_PM_CLK_EN BIT(1)
47 #define SPEAR1340_PCIE_SATA_SEL_PCIE (0)
48 #define SPEAR1340_PCIE_SATA_SEL_SATA (1)
49 #define SPEAR1340_PCIE_SATA_CFG_MASK 0xF1F
50 #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \
51 SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
52 SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
53 SPEAR1340_PCIE_CFG_POWERUP_RESET | \
54 SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
55 #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \
56 SPEAR1340_SATA_CFG_PM_CLK_EN | \
57 SPEAR1340_SATA_CFG_POWERUP_RESET | \
58 SPEAR1340_SATA_CFG_RX_CLK_EN | \
59 SPEAR1340_SATA_CFG_TX_CLK_EN)
60
61#define SPEAR1340_PCIE_MIPHY_CFG 0x428
62 #define SPEAR1340_MIPHY_OSC_BYPASS_EXT BIT(31)
63 #define SPEAR1340_MIPHY_CLK_REF_DIV2 BIT(27)
64 #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27)
65 #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27)
66 #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0)
67 #define SPEAR1340_PCIE_MIPHY_CFG_MASK 0xF80000FF
68 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
69 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
70 SPEAR1340_MIPHY_CLK_REF_DIV2 | \
71 SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
72 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
73 (SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
74 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
75 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
76 SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
77
78enum spear1340_miphy_mode {
79 SATA,
80 PCIE,
81};
82
83struct spear1340_miphy_priv {
84 /* phy mode: 0 for SATA 1 for PCIe */
85 enum spear1340_miphy_mode mode;
86 /* regmap for any soc specific misc registers */
87 struct regmap *misc;
88 /* phy struct pointer */
89 struct phy *phy;
90};
91
92static int spear1340_miphy_sata_init(struct spear1340_miphy_priv *priv)
93{
94 regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
95 SPEAR1340_PCIE_SATA_CFG_MASK,
96 SPEAR1340_SATA_CFG_VAL);
97 regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
98 SPEAR1340_PCIE_MIPHY_CFG_MASK,
99 SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK);
100 /* Switch on sata power domain */
101 regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
102 SPEAR1340_PCM_CFG_SATA_POWER_EN,
103 SPEAR1340_PCM_CFG_SATA_POWER_EN);
104 /* Wait for SATA power domain on */
105 msleep(20);
106
107 /* Disable PCIE SATA Controller reset */
108 regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
109 SPEAR1340_PERIP1_SW_RSATA, 0);
110 /* Wait for SATA reset de-assert completion */
111 msleep(20);
112
113 return 0;
114}
115
116static int spear1340_miphy_sata_exit(struct spear1340_miphy_priv *priv)
117{
118 regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
119 SPEAR1340_PCIE_SATA_CFG_MASK, 0);
120 regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
121 SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
122
123 /* Enable PCIE SATA Controller reset */
124 regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
125 SPEAR1340_PERIP1_SW_RSATA,
126 SPEAR1340_PERIP1_SW_RSATA);
127 /* Wait for SATA power domain off */
128 msleep(20);
129 /* Switch off sata power domain */
130 regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
131 SPEAR1340_PCM_CFG_SATA_POWER_EN, 0);
132 /* Wait for SATA reset assert completion */
133 msleep(20);
134
135 return 0;
136}
137
138static int spear1340_miphy_pcie_init(struct spear1340_miphy_priv *priv)
139{
140 regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
141 SPEAR1340_PCIE_MIPHY_CFG_MASK,
142 SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE);
143 regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
144 SPEAR1340_PCIE_SATA_CFG_MASK,
145 SPEAR1340_PCIE_CFG_VAL);
146
147 return 0;
148}
149
150static int spear1340_miphy_pcie_exit(struct spear1340_miphy_priv *priv)
151{
152 regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
153 SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
154 regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
155 SPEAR1340_PCIE_SATA_CFG_MASK, 0);
156
157 return 0;
158}
159
160static int spear1340_miphy_init(struct phy *phy)
161{
162 struct spear1340_miphy_priv *priv = phy_get_drvdata(phy);
163 int ret = 0;
164
165 if (priv->mode == SATA)
166 ret = spear1340_miphy_sata_init(priv);
167 else if (priv->mode == PCIE)
168 ret = spear1340_miphy_pcie_init(priv);
169
170 return ret;
171}
172
173static int spear1340_miphy_exit(struct phy *phy)
174{
175 struct spear1340_miphy_priv *priv = phy_get_drvdata(phy);
176 int ret = 0;
177
178 if (priv->mode == SATA)
179 ret = spear1340_miphy_sata_exit(priv);
180 else if (priv->mode == PCIE)
181 ret = spear1340_miphy_pcie_exit(priv);
182
183 return ret;
184}
185
186static const struct of_device_id spear1340_miphy_of_match[] = {
187 { .compatible = "st,spear1340-miphy" },
188 { },
189};
190MODULE_DEVICE_TABLE(of, spear1340_miphy_of_match);
191
192static struct phy_ops spear1340_miphy_ops = {
193 .init = spear1340_miphy_init,
194 .exit = spear1340_miphy_exit,
195 .owner = THIS_MODULE,
196};
197
198#ifdef CONFIG_PM_SLEEP
199static int spear1340_miphy_suspend(struct device *dev)
200{
201 struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
202 int ret = 0;
203
204 if (priv->mode == SATA)
205 ret = spear1340_miphy_sata_exit(priv);
206
207 return ret;
208}
209
210static int spear1340_miphy_resume(struct device *dev)
211{
212 struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
213 int ret = 0;
214
215 if (priv->mode == SATA)
216 ret = spear1340_miphy_sata_init(priv);
217
218 return ret;
219}
220#endif
221
222static SIMPLE_DEV_PM_OPS(spear1340_miphy_pm_ops, spear1340_miphy_suspend,
223 spear1340_miphy_resume);
224
225static struct phy *spear1340_miphy_xlate(struct device *dev,
226 struct of_phandle_args *args)
227{
228 struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
229
230 if (args->args_count < 1) {
231 dev_err(dev, "DT did not pass correct no of args\n");
232 return NULL;
233 }
234
235 priv->mode = args->args[0];
236
237 if (priv->mode != SATA && priv->mode != PCIE) {
238 dev_err(dev, "DT did not pass correct phy mode\n");
239 return NULL;
240 }
241
242 return priv->phy;
243}
244
245static int spear1340_miphy_probe(struct platform_device *pdev)
246{
247 struct device *dev = &pdev->dev;
248 struct spear1340_miphy_priv *priv;
249 struct phy_provider *phy_provider;
250
251 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
252 if (!priv) {
253 dev_err(dev, "can't alloc spear1340_miphy private date memory\n");
254 return -ENOMEM;
255 }
256
257 priv->misc =
258 syscon_regmap_lookup_by_phandle(dev->of_node, "misc");
259 if (IS_ERR(priv->misc)) {
260 dev_err(dev, "failed to find misc regmap\n");
261 return PTR_ERR(priv->misc);
262 }
263
264 priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops, NULL);
265 if (IS_ERR(priv->phy)) {
266 dev_err(dev, "failed to create SATA PCIe PHY\n");
267 return PTR_ERR(priv->phy);
268 }
269
270 dev_set_drvdata(dev, priv);
271 phy_set_drvdata(priv->phy, priv);
272
273 phy_provider =
274 devm_of_phy_provider_register(dev, spear1340_miphy_xlate);
275 if (IS_ERR(phy_provider)) {
276 dev_err(dev, "failed to register phy provider\n");
277 return PTR_ERR(phy_provider);
278 }
279
280 return 0;
281}
282
283static struct platform_driver spear1340_miphy_driver = {
284 .probe = spear1340_miphy_probe,
285 .driver = {
286 .name = "spear1340-miphy",
287 .owner = THIS_MODULE,
288 .pm = &spear1340_miphy_pm_ops,
289 .of_match_table = of_match_ptr(spear1340_miphy_of_match),
290 },
291};
292
293static int __init spear1340_miphy_phy_init(void)
294{
295 return platform_driver_register(&spear1340_miphy_driver);
296}
297module_init(spear1340_miphy_phy_init);
298
299static void __exit spear1340_miphy_phy_exit(void)
300{
301 platform_driver_unregister(&spear1340_miphy_driver);
302}
303module_exit(spear1340_miphy_phy_exit);
304
305MODULE_DESCRIPTION("ST SPEAR1340-MIPHY driver");
306MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
307MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c
index 4a7daf577b49..a06620474845 100644
--- a/drivers/pinctrl/pinctrl-tegra-xusb.c
+++ b/drivers/pinctrl/pinctrl-tegra-xusb.c
@@ -910,7 +910,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
910 goto reset; 910 goto reset;
911 } 911 }
912 912
913 phy = devm_phy_create(&pdev->dev, &pcie_phy_ops, NULL); 913 phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops, NULL);
914 if (IS_ERR(phy)) { 914 if (IS_ERR(phy)) {
915 err = PTR_ERR(phy); 915 err = PTR_ERR(phy);
916 goto unregister; 916 goto unregister;
@@ -919,7 +919,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
919 padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy; 919 padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy;
920 phy_set_drvdata(phy, padctl); 920 phy_set_drvdata(phy, padctl);
921 921
922 phy = devm_phy_create(&pdev->dev, &sata_phy_ops, NULL); 922 phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops, NULL);
923 if (IS_ERR(phy)) { 923 if (IS_ERR(phy)) {
924 err = PTR_ERR(phy); 924 err = PTR_ERR(phy);
925 goto unregister; 925 goto unregister;
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 4ad7b89a4cb4..331dfca415c7 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -43,7 +43,7 @@ config PWM_AB8500
43 43
44config PWM_ATMEL 44config PWM_ATMEL
45 tristate "Atmel PWM support" 45 tristate "Atmel PWM support"
46 depends on ARCH_AT91 46 depends on ARCH_AT91 || AVR32
47 help 47 help
48 Generic PWM framework driver for Atmel SoC. 48 Generic PWM framework driver for Atmel SoC.
49 49
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index cc153f55d9f9..8d03924749b8 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -178,17 +178,6 @@ config BACKLIGHT_ATMEL_LCDC
178 If in doubt, it's safe to enable this option; it doesn't kick 178 If in doubt, it's safe to enable this option; it doesn't kick
179 in unless the board's description says it's wired that way. 179 in unless the board's description says it's wired that way.
180 180
181config BACKLIGHT_ATMEL_PWM
182 tristate "Atmel PWM backlight control"
183 depends on ATMEL_PWM
184 help
185 Say Y here if you want to use the PWM peripheral in Atmel AT91 and
186 AVR32 devices. This driver will need additional platform data to know
187 which PWM instance to use and how to configure it.
188
189 To compile this driver as a module, choose M here: the module will be
190 called atmel-pwm-bl.
191
192config BACKLIGHT_EP93XX 181config BACKLIGHT_EP93XX
193 tristate "Cirrus EP93xx Backlight Driver" 182 tristate "Cirrus EP93xx Backlight Driver"
194 depends on FB_EP93XX 183 depends on FB_EP93XX
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index a9ea34a39cad..fcd50b732165 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
25obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o 25obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
26obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o 26obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
27obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o 27obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o
28obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
29obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o 28obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o
30obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 29obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
31obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 30obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
deleted file mode 100644
index 261b1a4ec3d8..000000000000
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ /dev/null
@@ -1,223 +0,0 @@
1/*
2 * Copyright (C) 2008 Atmel Corporation
3 *
4 * Backlight driver using Atmel PWM peripheral.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 */
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/fb.h>
15#include <linux/gpio.h>
16#include <linux/backlight.h>
17#include <linux/atmel_pwm.h>
18#include <linux/atmel-pwm-bl.h>
19#include <linux/slab.h>
20
21struct atmel_pwm_bl {
22 const struct atmel_pwm_bl_platform_data *pdata;
23 struct backlight_device *bldev;
24 struct platform_device *pdev;
25 struct pwm_channel pwmc;
26 int gpio_on;
27};
28
29static void atmel_pwm_bl_set_gpio_on(struct atmel_pwm_bl *pwmbl, int on)
30{
31 if (!gpio_is_valid(pwmbl->gpio_on))
32 return;
33
34 gpio_set_value(pwmbl->gpio_on, on ^ pwmbl->pdata->on_active_low);
35}
36
37static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
38{
39 struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
40 int intensity = bd->props.brightness;
41 int pwm_duty;
42
43 if (bd->props.power != FB_BLANK_UNBLANK)
44 intensity = 0;
45 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
46 intensity = 0;
47
48 if (pwmbl->pdata->pwm_active_low)
49 pwm_duty = pwmbl->pdata->pwm_duty_min + intensity;
50 else
51 pwm_duty = pwmbl->pdata->pwm_duty_max - intensity;
52
53 if (pwm_duty > pwmbl->pdata->pwm_duty_max)
54 pwm_duty = pwmbl->pdata->pwm_duty_max;
55 if (pwm_duty < pwmbl->pdata->pwm_duty_min)
56 pwm_duty = pwmbl->pdata->pwm_duty_min;
57
58 if (!intensity) {
59 atmel_pwm_bl_set_gpio_on(pwmbl, 0);
60 pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
61 pwm_channel_disable(&pwmbl->pwmc);
62 } else {
63 pwm_channel_enable(&pwmbl->pwmc);
64 pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
65 atmel_pwm_bl_set_gpio_on(pwmbl, 1);
66 }
67
68 return 0;
69}
70
71static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
72{
73 struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
74 u32 cdty;
75 u32 intensity;
76
77 cdty = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
78 if (pwmbl->pdata->pwm_active_low)
79 intensity = cdty - pwmbl->pdata->pwm_duty_min;
80 else
81 intensity = pwmbl->pdata->pwm_duty_max - cdty;
82
83 return intensity & 0xffff;
84}
85
86static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
87{
88 unsigned long pwm_rate = pwmbl->pwmc.mck;
89 unsigned long prescale = DIV_ROUND_UP(pwm_rate,
90 (pwmbl->pdata->pwm_frequency *
91 pwmbl->pdata->pwm_compare_max)) - 1;
92
93 /*
94 * Prescale must be power of two and maximum 0xf in size because of
95 * hardware limit. PWM speed will be:
96 * PWM module clock speed / (2 ^ prescale).
97 */
98 prescale = fls(prescale);
99 if (prescale > 0xf)
100 prescale = 0xf;
101
102 pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale);
103 pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY,
104 pwmbl->pdata->pwm_duty_min +
105 pwmbl->bldev->props.brightness);
106 pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
107 pwmbl->pdata->pwm_compare_max);
108
109 dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver (%lu Hz)\n",
110 pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max /
111 (1 << prescale));
112
113 return pwm_channel_enable(&pwmbl->pwmc);
114}
115
116static const struct backlight_ops atmel_pwm_bl_ops = {
117 .get_brightness = atmel_pwm_bl_get_intensity,
118 .update_status = atmel_pwm_bl_set_intensity,
119};
120
121static int atmel_pwm_bl_probe(struct platform_device *pdev)
122{
123 struct backlight_properties props;
124 const struct atmel_pwm_bl_platform_data *pdata;
125 struct backlight_device *bldev;
126 struct atmel_pwm_bl *pwmbl;
127 unsigned long flags;
128 int retval;
129
130 pdata = dev_get_platdata(&pdev->dev);
131 if (!pdata)
132 return -ENODEV;
133
134 if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
135 pdata->pwm_duty_min > pdata->pwm_duty_max ||
136 pdata->pwm_frequency == 0)
137 return -EINVAL;
138
139 pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl),
140 GFP_KERNEL);
141 if (!pwmbl)
142 return -ENOMEM;
143
144 pwmbl->pdev = pdev;
145 pwmbl->pdata = pdata;
146 pwmbl->gpio_on = pdata->gpio_on;
147
148 retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
149 if (retval)
150 return retval;
151
152 if (gpio_is_valid(pwmbl->gpio_on)) {
153 /* Turn display off by default. */
154 if (pdata->on_active_low)
155 flags = GPIOF_OUT_INIT_HIGH;
156 else
157 flags = GPIOF_OUT_INIT_LOW;
158
159 retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on,
160 flags, "gpio_atmel_pwm_bl");
161 if (retval)
162 goto err_free_pwm;
163 }
164
165 memset(&props, 0, sizeof(struct backlight_properties));
166 props.type = BACKLIGHT_RAW;
167 props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
168 bldev = devm_backlight_device_register(&pdev->dev, "atmel-pwm-bl",
169 &pdev->dev, pwmbl, &atmel_pwm_bl_ops,
170 &props);
171 if (IS_ERR(bldev)) {
172 retval = PTR_ERR(bldev);
173 goto err_free_pwm;
174 }
175
176 pwmbl->bldev = bldev;
177
178 platform_set_drvdata(pdev, pwmbl);
179
180 /* Power up the backlight by default at middle intesity. */
181 bldev->props.power = FB_BLANK_UNBLANK;
182 bldev->props.brightness = bldev->props.max_brightness / 2;
183
184 retval = atmel_pwm_bl_init_pwm(pwmbl);
185 if (retval)
186 goto err_free_pwm;
187
188 atmel_pwm_bl_set_intensity(bldev);
189
190 return 0;
191
192err_free_pwm:
193 pwm_channel_free(&pwmbl->pwmc);
194
195 return retval;
196}
197
198static int atmel_pwm_bl_remove(struct platform_device *pdev)
199{
200 struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
201
202 atmel_pwm_bl_set_gpio_on(pwmbl, 0);
203 pwm_channel_disable(&pwmbl->pwmc);
204 pwm_channel_free(&pwmbl->pwmc);
205
206 return 0;
207}
208
209static struct platform_driver atmel_pwm_bl_driver = {
210 .driver = {
211 .name = "atmel-pwm-bl",
212 },
213 /* REVISIT add suspend() and resume() */
214 .probe = atmel_pwm_bl_probe,
215 .remove = atmel_pwm_bl_remove,
216};
217
218module_platform_driver(atmel_pwm_bl_driver);
219
220MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
221MODULE_DESCRIPTION("Atmel PWM backlight driver");
222MODULE_LICENSE("GPL");
223MODULE_ALIAS("platform:atmel-pwm-bl");
diff --git a/include/linux/atmel-pwm-bl.h b/include/linux/atmel-pwm-bl.h
deleted file mode 100644
index 0153a47806c2..000000000000
--- a/include/linux/atmel-pwm-bl.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * Copyright (C) 2007 Atmel Corporation
3 *
4 * Driver for the AT32AP700X PS/2 controller (PSIF).
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 */
10
11#ifndef __INCLUDE_ATMEL_PWM_BL_H
12#define __INCLUDE_ATMEL_PWM_BL_H
13
14/**
15 * struct atmel_pwm_bl_platform_data
16 * @pwm_channel: which PWM channel in the PWM module to use.
17 * @pwm_frequency: PWM frequency to generate, the driver will try to be as
18 * close as the prescaler allows.
19 * @pwm_compare_max: value to use in the PWM channel compare register.
20 * @pwm_duty_max: maximum duty cycle value, must be less than or equal to
21 * pwm_compare_max.
22 * @pwm_duty_min: minimum duty cycle value, must be less than pwm_duty_max.
23 * @pwm_active_low: set to one if the low part of the PWM signal increases the
24 * brightness of the backlight.
25 * @gpio_on: GPIO line to control the backlight on/off, set to -1 if not used.
26 * @on_active_low: set to one if the on/off signal is on when GPIO is low.
27 *
28 * This struct must be added to the platform device in the board code. It is
29 * used by the atmel-pwm-bl driver to setup the GPIO to control on/off and the
30 * PWM device.
31 */
32struct atmel_pwm_bl_platform_data {
33 unsigned int pwm_channel;
34 unsigned int pwm_frequency;
35 unsigned int pwm_compare_max;
36 unsigned int pwm_duty_max;
37 unsigned int pwm_duty_min;
38 unsigned int pwm_active_low;
39 int gpio_on;
40 unsigned int on_active_low;
41};
42
43#endif /* __INCLUDE_ATMEL_PWM_BL_H */
diff --git a/include/linux/atmel_pwm.h b/include/linux/atmel_pwm.h
deleted file mode 100644
index ea04abb3db8e..000000000000
--- a/include/linux/atmel_pwm.h
+++ /dev/null
@@ -1,70 +0,0 @@
1#ifndef __LINUX_ATMEL_PWM_H
2#define __LINUX_ATMEL_PWM_H
3
4/**
5 * struct pwm_channel - driver handle to a PWM channel
6 * @regs: base of this channel's registers
7 * @index: number of this channel (0..31)
8 * @mck: base clock rate, which can be prescaled and maybe subdivided
9 *
10 * Drivers initialize a pwm_channel structure using pwm_channel_alloc().
11 * Then they configure its clock rate (derived from MCK), alignment,
12 * polarity, and duty cycle by writing directly to the channel registers,
13 * before enabling the channel by calling pwm_channel_enable().
14 *
15 * After emitting a PWM signal for the desired length of time, drivers
16 * may then pwm_channel_disable() or pwm_channel_free(). Both of these
17 * disable the channel, but when it's freed the IRQ is deconfigured and
18 * the channel must later be re-allocated and reconfigured.
19 *
20 * Note that if the period or duty cycle need to be changed while the
21 * PWM channel is operating, drivers must use the PWM_CUPD double buffer
22 * mechanism, either polling until they change or getting implicitly
23 * notified through a once-per-period interrupt handler.
24 */
25struct pwm_channel {
26 void __iomem *regs;
27 unsigned index;
28 unsigned long mck;
29};
30
31extern int pwm_channel_alloc(int index, struct pwm_channel *ch);
32extern int pwm_channel_free(struct pwm_channel *ch);
33
34extern int pwm_clk_alloc(unsigned prescale, unsigned div);
35extern void pwm_clk_free(unsigned clk);
36
37extern int __pwm_channel_onoff(struct pwm_channel *ch, int enabled);
38
39#define pwm_channel_enable(ch) __pwm_channel_onoff((ch), 1)
40#define pwm_channel_disable(ch) __pwm_channel_onoff((ch), 0)
41
42/* periodic interrupts, mostly for CUPD changes to period or cycle */
43extern int pwm_channel_handler(struct pwm_channel *ch,
44 void (*handler)(struct pwm_channel *ch));
45
46/* per-channel registers (banked at pwm_channel->regs) */
47#define PWM_CMR 0x00 /* mode register */
48#define PWM_CPR_CPD (1 << 10) /* set: CUPD modifies period */
49#define PWM_CPR_CPOL (1 << 9) /* set: idle high */
50#define PWM_CPR_CALG (1 << 8) /* set: center align */
51#define PWM_CPR_CPRE (0xf << 0) /* mask: rate is mck/(2^pre) */
52#define PWM_CPR_CLKA (0xb << 0) /* rate CLKA */
53#define PWM_CPR_CLKB (0xc << 0) /* rate CLKB */
54#define PWM_CDTY 0x04 /* duty cycle (max of CPRD) */
55#define PWM_CPRD 0x08 /* period (count up from zero) */
56#define PWM_CCNT 0x0c /* counter (20 bits?) */
57#define PWM_CUPD 0x10 /* update CPRD (or CDTY) next period */
58
59static inline void
60pwm_channel_writel(struct pwm_channel *pwmc, unsigned offset, u32 val)
61{
62 __raw_writel(val, pwmc->regs + offset);
63}
64
65static inline u32 pwm_channel_readl(struct pwm_channel *pwmc, unsigned offset)
66{
67 return __raw_readl(pwmc->regs + offset);
68}
69
70#endif /* __LINUX_ATMEL_PWM_H */