diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 18:27:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 18:27:37 -0400 |
commit | 01d5f3b598b18a5035426c30801adf65822dbd0c (patch) | |
tree | 156c85882676ff9fb1759505ef9eee89814c8629 | |
parent | 9d919e8d5b04e987b0378cfd73df6cdd2b19e9db (diff) | |
parent | 03803ef66d22702af124d21552f90ac32da9fef5 (diff) |
Merge branch 'for-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata updates from Tejun Heo:
"A lot of activities on libata side this time.
- A lot of changes around ahci. Various embedded platforms are
implementing ahci controllers. Some were built atop ahci_platform,
others were doing their own things. Hans made some structural
changes to libahci and librarized ahci_platform so that ahci
platform drivers can share more common code. A couple platform
drivers are added on top of that and several are added to replace
older drivers which were doing their own things (older ones are
scheduled to be removed).
- Dan finishes the patchset to make libata PM operations
asynchronous. Combined with one patch being routed through scsi,
this should speed resume measurably.
- Various fixes and cleanups from Bartlomiej and others"
* 'for-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: (61 commits)
ata: fix Marvell SATA driver dependencies
ata: fix ARASAN CompactFlash PATA driver dependencies
ata: remove superfluous casts
ata: sata_highbank: remove superfluous cast
ata: fix Calxeda Highbank SATA driver dependencies
ata: fix R-Car SATA driver dependencies
ARM: davinci: da850: update SATA AHCI support
ata: add new-style AHCI platform driver for DaVinci DA850 AHCI controller
ata: move library code from ahci_platform.c to libahci_platform.c
ata: ahci_platform: fix ahci_platform_data->suspend method handling
libata: remove unused ata_sas_port_async_resume() stub
libata.h: add stub for ata_sas_port_resume
libata: async resume
libata, libsas: kill pm_result and related cleanup
ata: Fix compiler warning with APM X-Gene host controller driver
arm64: Add APM X-Gene SoC AHCI SATA host controller DTS entries
ata: Add APM X-Gene SoC AHCI SATA host controller driver
Documentation: Add documentation for the APM X-Gene SoC SATA host controller DTS binding
arm64: Add APM X-Gene SoC 15Gbps Multi-purpose PHY DTS entries
ata: ahci_sunxi: fix code formatting
...
92 files changed, 2249 insertions, 836 deletions
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index 89de1564950c..48b285ffa3a6 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt | |||
@@ -4,17 +4,33 @@ SATA nodes are defined to describe on-chip Serial ATA controllers. | |||
4 | Each SATA controller should have its own node. | 4 | Each SATA controller should have its own node. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible : compatible list, contains "snps,spear-ahci" | 7 | - compatible : compatible list, one of "snps,spear-ahci", |
8 | "snps,exynos5440-ahci", "ibm,476gtr-ahci", | ||
9 | "allwinner,sun4i-a10-ahci", "fsl,imx53-ahci" | ||
10 | "fsl,imx6q-ahci" or "snps,dwc-ahci" | ||
8 | - interrupts : <interrupt mapping for SATA IRQ> | 11 | - interrupts : <interrupt mapping for SATA IRQ> |
9 | - reg : <registers mapping> | 12 | - reg : <registers mapping> |
10 | 13 | ||
11 | Optional properties: | 14 | Optional properties: |
12 | - dma-coherent : Present if dma operations are coherent | 15 | - dma-coherent : Present if dma operations are coherent |
16 | - clocks : a list of phandle + clock specifier pairs | ||
17 | - target-supply : regulator for SATA target power | ||
13 | 18 | ||
14 | Example: | 19 | "fsl,imx53-ahci", "fsl,imx6q-ahci" required properties: |
20 | - clocks : must contain the sata, sata_ref and ahb clocks | ||
21 | - clock-names : must contain "ahb" for the ahb clock | ||
22 | |||
23 | Examples: | ||
15 | sata@ffe08000 { | 24 | sata@ffe08000 { |
16 | compatible = "snps,spear-ahci"; | 25 | compatible = "snps,spear-ahci"; |
17 | reg = <0xffe08000 0x1000>; | 26 | reg = <0xffe08000 0x1000>; |
18 | interrupts = <115>; | 27 | interrupts = <115>; |
19 | |||
20 | }; | 28 | }; |
29 | |||
30 | ahci: sata@01c18000 { | ||
31 | compatible = "allwinner,sun4i-a10-ahci"; | ||
32 | reg = <0x01c18000 0x1000>; | ||
33 | interrupts = <56>; | ||
34 | clocks = <&pll6 0>, <&ahb_gates 25>; | ||
35 | target-supply = <®_ahci_5v>; | ||
36 | }; | ||
diff --git a/Documentation/devicetree/bindings/ata/apm-xgene.txt b/Documentation/devicetree/bindings/ata/apm-xgene.txt new file mode 100644 index 000000000000..7bcfbf59810e --- /dev/null +++ b/Documentation/devicetree/bindings/ata/apm-xgene.txt | |||
@@ -0,0 +1,76 @@ | |||
1 | * APM X-Gene 6.0 Gb/s SATA host controller nodes | ||
2 | |||
3 | SATA host controller nodes are defined to describe on-chip Serial ATA | ||
4 | controllers. Each SATA controller (pair of ports) have its own node. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible : Shall contain: | ||
8 | * "apm,xgene-ahci" | ||
9 | - reg : First memory resource shall be the AHCI memory | ||
10 | resource. | ||
11 | Second memory resource shall be the host controller | ||
12 | core memory resource. | ||
13 | Third memory resource shall be the host controller | ||
14 | diagnostic memory resource. | ||
15 | 4th memory resource shall be the host controller | ||
16 | AXI memory resource. | ||
17 | 5th optional memory resource shall be the host | ||
18 | controller MUX memory resource if required. | ||
19 | - interrupts : Interrupt-specifier for SATA host controller IRQ. | ||
20 | - clocks : Reference to the clock entry. | ||
21 | - phys : A list of phandles + phy-specifiers, one for each | ||
22 | entry in phy-names. | ||
23 | - phy-names : Should contain: | ||
24 | * "sata-phy" for the SATA 6.0Gbps PHY | ||
25 | |||
26 | Optional properties: | ||
27 | - status : Shall be "ok" if enabled or "disabled" if disabled. | ||
28 | Default is "ok". | ||
29 | |||
30 | Example: | ||
31 | sataclk: sataclk { | ||
32 | compatible = "fixed-clock"; | ||
33 | #clock-cells = <1>; | ||
34 | clock-frequency = <100000000>; | ||
35 | clock-output-names = "sataclk"; | ||
36 | }; | ||
37 | |||
38 | phy2: phy@1f22a000 { | ||
39 | compatible = "apm,xgene-phy"; | ||
40 | reg = <0x0 0x1f22a000 0x0 0x100>; | ||
41 | #phy-cells = <1>; | ||
42 | }; | ||
43 | |||
44 | phy3: phy@1f23a000 { | ||
45 | compatible = "apm,xgene-phy"; | ||
46 | reg = <0x0 0x1f23a000 0x0 0x100>; | ||
47 | #phy-cells = <1>; | ||
48 | }; | ||
49 | |||
50 | sata2: sata@1a400000 { | ||
51 | compatible = "apm,xgene-ahci"; | ||
52 | reg = <0x0 0x1a400000 0x0 0x1000>, | ||
53 | <0x0 0x1f220000 0x0 0x1000>, | ||
54 | <0x0 0x1f22d000 0x0 0x1000>, | ||
55 | <0x0 0x1f22e000 0x0 0x1000>, | ||
56 | <0x0 0x1f227000 0x0 0x1000>; | ||
57 | interrupts = <0x0 0x87 0x4>; | ||
58 | status = "ok"; | ||
59 | clocks = <&sataclk 0>; | ||
60 | phys = <&phy2 0>; | ||
61 | phy-names = "sata-phy"; | ||
62 | }; | ||
63 | |||
64 | sata3: sata@1a800000 { | ||
65 | compatible = "apm,xgene-ahci-pcie"; | ||
66 | reg = <0x0 0x1a800000 0x0 0x1000>, | ||
67 | <0x0 0x1f230000 0x0 0x1000>, | ||
68 | <0x0 0x1f23d000 0x0 0x1000>, | ||
69 | <0x0 0x1f23e000 0x0 0x1000>, | ||
70 | <0x0 0x1f237000 0x0 0x1000>; | ||
71 | interrupts = <0x0 0x88 0x4>; | ||
72 | status = "ok"; | ||
73 | clocks = <&sataclk 0>; | ||
74 | phys = <&phy3 0>; | ||
75 | phy-names = "sata-phy"; | ||
76 | }; | ||
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 2ab00434b2eb..85399c98f84a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c | |||
@@ -472,7 +472,7 @@ static struct clk_lookup da850_clks[] = { | |||
472 | CLK("spi_davinci.0", NULL, &spi0_clk), | 472 | CLK("spi_davinci.0", NULL, &spi0_clk), |
473 | CLK("spi_davinci.1", NULL, &spi1_clk), | 473 | CLK("spi_davinci.1", NULL, &spi1_clk), |
474 | CLK("vpif", NULL, &vpif_clk), | 474 | CLK("vpif", NULL, &vpif_clk), |
475 | CLK("ahci", NULL, &sata_clk), | 475 | CLK("ahci_da850", NULL, &sata_clk), |
476 | CLK("davinci-rproc.0", NULL, &dsp_clk), | 476 | CLK("davinci-rproc.0", NULL, &dsp_clk), |
477 | CLK("ehrpwm", "fck", &ehrpwm_clk), | 477 | CLK("ehrpwm", "fck", &ehrpwm_clk), |
478 | CLK("ehrpwm", "tbclk", &ehrpwm_tbclk), | 478 | CLK("ehrpwm", "tbclk", &ehrpwm_tbclk), |
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 0486cdf28c8d..56ea41d5f849 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c | |||
@@ -1020,7 +1020,6 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect) | |||
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | #ifdef CONFIG_ARCH_DAVINCI_DA850 | 1022 | #ifdef CONFIG_ARCH_DAVINCI_DA850 |
1023 | |||
1024 | static struct resource da850_sata_resources[] = { | 1023 | static struct resource da850_sata_resources[] = { |
1025 | { | 1024 | { |
1026 | .start = DA850_SATA_BASE, | 1025 | .start = DA850_SATA_BASE, |
@@ -1028,103 +1027,22 @@ static struct resource da850_sata_resources[] = { | |||
1028 | .flags = IORESOURCE_MEM, | 1027 | .flags = IORESOURCE_MEM, |
1029 | }, | 1028 | }, |
1030 | { | 1029 | { |
1030 | .start = DA8XX_SYSCFG1_BASE + DA8XX_PWRDN_REG, | ||
1031 | .end = DA8XX_SYSCFG1_BASE + DA8XX_PWRDN_REG + 0x3, | ||
1032 | .flags = IORESOURCE_MEM, | ||
1033 | }, | ||
1034 | { | ||
1031 | .start = IRQ_DA850_SATAINT, | 1035 | .start = IRQ_DA850_SATAINT, |
1032 | .flags = IORESOURCE_IRQ, | 1036 | .flags = IORESOURCE_IRQ, |
1033 | }, | 1037 | }, |
1034 | }; | 1038 | }; |
1035 | 1039 | ||
1036 | /* SATA PHY Control Register offset from AHCI base */ | ||
1037 | #define SATA_P0PHYCR_REG 0x178 | ||
1038 | |||
1039 | #define SATA_PHY_MPY(x) ((x) << 0) | ||
1040 | #define SATA_PHY_LOS(x) ((x) << 6) | ||
1041 | #define SATA_PHY_RXCDR(x) ((x) << 10) | ||
1042 | #define SATA_PHY_RXEQ(x) ((x) << 13) | ||
1043 | #define SATA_PHY_TXSWING(x) ((x) << 19) | ||
1044 | #define SATA_PHY_ENPLL(x) ((x) << 31) | ||
1045 | |||
1046 | static struct clk *da850_sata_clk; | ||
1047 | static unsigned long da850_sata_refclkpn; | ||
1048 | |||
1049 | /* Supported DA850 SATA crystal frequencies */ | ||
1050 | #define KHZ_TO_HZ(freq) ((freq) * 1000) | ||
1051 | static unsigned long da850_sata_xtal[] = { | ||
1052 | KHZ_TO_HZ(300000), | ||
1053 | KHZ_TO_HZ(250000), | ||
1054 | 0, /* Reserved */ | ||
1055 | KHZ_TO_HZ(187500), | ||
1056 | KHZ_TO_HZ(150000), | ||
1057 | KHZ_TO_HZ(125000), | ||
1058 | KHZ_TO_HZ(120000), | ||
1059 | KHZ_TO_HZ(100000), | ||
1060 | KHZ_TO_HZ(75000), | ||
1061 | KHZ_TO_HZ(60000), | ||
1062 | }; | ||
1063 | |||
1064 | static int da850_sata_init(struct device *dev, void __iomem *addr) | ||
1065 | { | ||
1066 | int i, ret; | ||
1067 | unsigned int val; | ||
1068 | |||
1069 | da850_sata_clk = clk_get(dev, NULL); | ||
1070 | if (IS_ERR(da850_sata_clk)) | ||
1071 | return PTR_ERR(da850_sata_clk); | ||
1072 | |||
1073 | ret = clk_prepare_enable(da850_sata_clk); | ||
1074 | if (ret) | ||
1075 | goto err0; | ||
1076 | |||
1077 | /* Enable SATA clock receiver */ | ||
1078 | val = __raw_readl(DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); | ||
1079 | val &= ~BIT(0); | ||
1080 | __raw_writel(val, DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); | ||
1081 | |||
1082 | /* Get the multiplier needed for 1.5GHz PLL output */ | ||
1083 | for (i = 0; i < ARRAY_SIZE(da850_sata_xtal); i++) | ||
1084 | if (da850_sata_xtal[i] == da850_sata_refclkpn) | ||
1085 | break; | ||
1086 | |||
1087 | if (i == ARRAY_SIZE(da850_sata_xtal)) { | ||
1088 | ret = -EINVAL; | ||
1089 | goto err1; | ||
1090 | } | ||
1091 | |||
1092 | val = SATA_PHY_MPY(i + 1) | | ||
1093 | SATA_PHY_LOS(1) | | ||
1094 | SATA_PHY_RXCDR(4) | | ||
1095 | SATA_PHY_RXEQ(1) | | ||
1096 | SATA_PHY_TXSWING(3) | | ||
1097 | SATA_PHY_ENPLL(1); | ||
1098 | |||
1099 | __raw_writel(val, addr + SATA_P0PHYCR_REG); | ||
1100 | |||
1101 | return 0; | ||
1102 | |||
1103 | err1: | ||
1104 | clk_disable_unprepare(da850_sata_clk); | ||
1105 | err0: | ||
1106 | clk_put(da850_sata_clk); | ||
1107 | return ret; | ||
1108 | } | ||
1109 | |||
1110 | static void da850_sata_exit(struct device *dev) | ||
1111 | { | ||
1112 | clk_disable_unprepare(da850_sata_clk); | ||
1113 | clk_put(da850_sata_clk); | ||
1114 | } | ||
1115 | |||
1116 | static struct ahci_platform_data da850_sata_pdata = { | ||
1117 | .init = da850_sata_init, | ||
1118 | .exit = da850_sata_exit, | ||
1119 | }; | ||
1120 | |||
1121 | static u64 da850_sata_dmamask = DMA_BIT_MASK(32); | 1040 | static u64 da850_sata_dmamask = DMA_BIT_MASK(32); |
1122 | 1041 | ||
1123 | static struct platform_device da850_sata_device = { | 1042 | static struct platform_device da850_sata_device = { |
1124 | .name = "ahci", | 1043 | .name = "ahci_da850", |
1125 | .id = -1, | 1044 | .id = -1, |
1126 | .dev = { | 1045 | .dev = { |
1127 | .platform_data = &da850_sata_pdata, | ||
1128 | .dma_mask = &da850_sata_dmamask, | 1046 | .dma_mask = &da850_sata_dmamask, |
1129 | .coherent_dma_mask = DMA_BIT_MASK(32), | 1047 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1130 | }, | 1048 | }, |
@@ -1134,9 +1052,8 @@ static struct platform_device da850_sata_device = { | |||
1134 | 1052 | ||
1135 | int __init da850_register_sata(unsigned long refclkpn) | 1053 | int __init da850_register_sata(unsigned long refclkpn) |
1136 | { | 1054 | { |
1137 | da850_sata_refclkpn = refclkpn; | 1055 | /* please see comment in drivers/ata/ahci_da850.c */ |
1138 | if (!da850_sata_refclkpn) | 1056 | BUG_ON(refclkpn != 100 * 1000 * 1000); |
1139 | return -EINVAL; | ||
1140 | 1057 | ||
1141 | return platform_device_register(&da850_sata_device); | 1058 | return platform_device_register(&da850_sata_device); |
1142 | } | 1059 | } |
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index d37d7369e260..93f4b2dd9248 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi | |||
@@ -176,6 +176,87 @@ | |||
176 | reg-names = "csr-reg"; | 176 | reg-names = "csr-reg"; |
177 | clock-output-names = "eth8clk"; | 177 | clock-output-names = "eth8clk"; |
178 | }; | 178 | }; |
179 | |||
180 | sataphy1clk: sataphy1clk@1f21c000 { | ||
181 | compatible = "apm,xgene-device-clock"; | ||
182 | #clock-cells = <1>; | ||
183 | clocks = <&socplldiv2 0>; | ||
184 | reg = <0x0 0x1f21c000 0x0 0x1000>; | ||
185 | reg-names = "csr-reg"; | ||
186 | clock-output-names = "sataphy1clk"; | ||
187 | status = "disabled"; | ||
188 | csr-offset = <0x4>; | ||
189 | csr-mask = <0x00>; | ||
190 | enable-offset = <0x0>; | ||
191 | enable-mask = <0x06>; | ||
192 | }; | ||
193 | |||
194 | sataphy2clk: sataphy1clk@1f22c000 { | ||
195 | compatible = "apm,xgene-device-clock"; | ||
196 | #clock-cells = <1>; | ||
197 | clocks = <&socplldiv2 0>; | ||
198 | reg = <0x0 0x1f22c000 0x0 0x1000>; | ||
199 | reg-names = "csr-reg"; | ||
200 | clock-output-names = "sataphy2clk"; | ||
201 | status = "ok"; | ||
202 | csr-offset = <0x4>; | ||
203 | csr-mask = <0x3a>; | ||
204 | enable-offset = <0x0>; | ||
205 | enable-mask = <0x06>; | ||
206 | }; | ||
207 | |||
208 | sataphy3clk: sataphy1clk@1f23c000 { | ||
209 | compatible = "apm,xgene-device-clock"; | ||
210 | #clock-cells = <1>; | ||
211 | clocks = <&socplldiv2 0>; | ||
212 | reg = <0x0 0x1f23c000 0x0 0x1000>; | ||
213 | reg-names = "csr-reg"; | ||
214 | clock-output-names = "sataphy3clk"; | ||
215 | status = "ok"; | ||
216 | csr-offset = <0x4>; | ||
217 | csr-mask = <0x3a>; | ||
218 | enable-offset = <0x0>; | ||
219 | enable-mask = <0x06>; | ||
220 | }; | ||
221 | |||
222 | sata01clk: sata01clk@1f21c000 { | ||
223 | compatible = "apm,xgene-device-clock"; | ||
224 | #clock-cells = <1>; | ||
225 | clocks = <&socplldiv2 0>; | ||
226 | reg = <0x0 0x1f21c000 0x0 0x1000>; | ||
227 | reg-names = "csr-reg"; | ||
228 | clock-output-names = "sata01clk"; | ||
229 | csr-offset = <0x4>; | ||
230 | csr-mask = <0x05>; | ||
231 | enable-offset = <0x0>; | ||
232 | enable-mask = <0x39>; | ||
233 | }; | ||
234 | |||
235 | sata23clk: sata23clk@1f22c000 { | ||
236 | compatible = "apm,xgene-device-clock"; | ||
237 | #clock-cells = <1>; | ||
238 | clocks = <&socplldiv2 0>; | ||
239 | reg = <0x0 0x1f22c000 0x0 0x1000>; | ||
240 | reg-names = "csr-reg"; | ||
241 | clock-output-names = "sata23clk"; | ||
242 | csr-offset = <0x4>; | ||
243 | csr-mask = <0x05>; | ||
244 | enable-offset = <0x0>; | ||
245 | enable-mask = <0x39>; | ||
246 | }; | ||
247 | |||
248 | sata45clk: sata45clk@1f23c000 { | ||
249 | compatible = "apm,xgene-device-clock"; | ||
250 | #clock-cells = <1>; | ||
251 | clocks = <&socplldiv2 0>; | ||
252 | reg = <0x0 0x1f23c000 0x0 0x1000>; | ||
253 | reg-names = "csr-reg"; | ||
254 | clock-output-names = "sata45clk"; | ||
255 | csr-offset = <0x4>; | ||
256 | csr-mask = <0x05>; | ||
257 | enable-offset = <0x0>; | ||
258 | enable-mask = <0x39>; | ||
259 | }; | ||
179 | }; | 260 | }; |
180 | 261 | ||
181 | serial0: serial@1c020000 { | 262 | serial0: serial@1c020000 { |
@@ -187,5 +268,76 @@ | |||
187 | interrupt-parent = <&gic>; | 268 | interrupt-parent = <&gic>; |
188 | interrupts = <0x0 0x4c 0x4>; | 269 | interrupts = <0x0 0x4c 0x4>; |
189 | }; | 270 | }; |
271 | |||
272 | phy1: phy@1f21a000 { | ||
273 | compatible = "apm,xgene-phy"; | ||
274 | reg = <0x0 0x1f21a000 0x0 0x100>; | ||
275 | #phy-cells = <1>; | ||
276 | clocks = <&sataphy1clk 0>; | ||
277 | status = "disabled"; | ||
278 | apm,tx-boost-gain = <30 30 30 30 30 30>; | ||
279 | apm,tx-eye-tuning = <2 10 10 2 10 10>; | ||
280 | }; | ||
281 | |||
282 | phy2: phy@1f22a000 { | ||
283 | compatible = "apm,xgene-phy"; | ||
284 | reg = <0x0 0x1f22a000 0x0 0x100>; | ||
285 | #phy-cells = <1>; | ||
286 | clocks = <&sataphy2clk 0>; | ||
287 | status = "ok"; | ||
288 | apm,tx-boost-gain = <30 30 30 30 30 30>; | ||
289 | apm,tx-eye-tuning = <1 10 10 2 10 10>; | ||
290 | }; | ||
291 | |||
292 | phy3: phy@1f23a000 { | ||
293 | compatible = "apm,xgene-phy"; | ||
294 | reg = <0x0 0x1f23a000 0x0 0x100>; | ||
295 | #phy-cells = <1>; | ||
296 | clocks = <&sataphy3clk 0>; | ||
297 | status = "ok"; | ||
298 | apm,tx-boost-gain = <31 31 31 31 31 31>; | ||
299 | apm,tx-eye-tuning = <2 10 10 2 10 10>; | ||
300 | }; | ||
301 | |||
302 | sata1: sata@1a000000 { | ||
303 | compatible = "apm,xgene-ahci"; | ||
304 | reg = <0x0 0x1a000000 0x0 0x1000>, | ||
305 | <0x0 0x1f210000 0x0 0x1000>, | ||
306 | <0x0 0x1f21d000 0x0 0x1000>, | ||
307 | <0x0 0x1f21e000 0x0 0x1000>, | ||
308 | <0x0 0x1f217000 0x0 0x1000>; | ||
309 | interrupts = <0x0 0x86 0x4>; | ||
310 | status = "disabled"; | ||
311 | clocks = <&sata01clk 0>; | ||
312 | phys = <&phy1 0>; | ||
313 | phy-names = "sata-phy"; | ||
314 | }; | ||
315 | |||
316 | sata2: sata@1a400000 { | ||
317 | compatible = "apm,xgene-ahci"; | ||
318 | reg = <0x0 0x1a400000 0x0 0x1000>, | ||
319 | <0x0 0x1f220000 0x0 0x1000>, | ||
320 | <0x0 0x1f22d000 0x0 0x1000>, | ||
321 | <0x0 0x1f22e000 0x0 0x1000>, | ||
322 | <0x0 0x1f227000 0x0 0x1000>; | ||
323 | interrupts = <0x0 0x87 0x4>; | ||
324 | status = "ok"; | ||
325 | clocks = <&sata23clk 0>; | ||
326 | phys = <&phy2 0>; | ||
327 | phy-names = "sata-phy"; | ||
328 | }; | ||
329 | |||
330 | sata3: sata@1a800000 { | ||
331 | compatible = "apm,xgene-ahci"; | ||
332 | reg = <0x0 0x1a800000 0x0 0x1000>, | ||
333 | <0x0 0x1f230000 0x0 0x1000>, | ||
334 | <0x0 0x1f23d000 0x0 0x1000>, | ||
335 | <0x0 0x1f23e000 0x0 0x1000>; | ||
336 | interrupts = <0x0 0x88 0x4>; | ||
337 | status = "ok"; | ||
338 | clocks = <&sata45clk 0>; | ||
339 | phys = <&phy3 0>; | ||
340 | phy-names = "sata-phy"; | ||
341 | }; | ||
190 | }; | 342 | }; |
191 | }; | 343 | }; |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 868429a47be4..20e03a7eb8b4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -11,13 +11,13 @@ config HAVE_PATA_PLATFORM | |||
11 | to update the PATA_PLATFORM entry. | 11 | to update the PATA_PLATFORM entry. |
12 | 12 | ||
13 | menuconfig ATA | 13 | menuconfig ATA |
14 | tristate "Serial ATA and Parallel ATA drivers" | 14 | tristate "Serial ATA and Parallel ATA drivers (libata)" |
15 | depends on HAS_IOMEM | 15 | depends on HAS_IOMEM |
16 | depends on BLOCK | 16 | depends on BLOCK |
17 | depends on !(M32R || M68K || S390) || BROKEN | 17 | depends on !(M32R || M68K || S390) || BROKEN |
18 | select SCSI | 18 | select SCSI |
19 | ---help--- | 19 | ---help--- |
20 | If you want to use a ATA hard disk, ATA tape drive, ATA CD-ROM or | 20 | If you want to use an ATA hard disk, ATA tape drive, ATA CD-ROM or |
21 | any other ATA device under Linux, say Y and make sure that you know | 21 | any other ATA device under Linux, say Y and make sure that you know |
22 | the name of your ATA host adapter (the card inside your computer | 22 | the name of your ATA host adapter (the card inside your computer |
23 | that "speaks" the ATA protocol, also called ATA controller), | 23 | that "speaks" the ATA protocol, also called ATA controller), |
@@ -60,7 +60,7 @@ config ATA_ACPI | |||
60 | 60 | ||
61 | config SATA_ZPODD | 61 | config SATA_ZPODD |
62 | bool "SATA Zero Power Optical Disc Drive (ZPODD) support" | 62 | bool "SATA Zero Power Optical Disc Drive (ZPODD) support" |
63 | depends on ATA_ACPI | 63 | depends on ATA_ACPI && PM_RUNTIME |
64 | default n | 64 | default n |
65 | help | 65 | help |
66 | This option adds support for SATA Zero Power Optical Disc | 66 | This option adds support for SATA Zero Power Optical Disc |
@@ -97,15 +97,48 @@ config SATA_AHCI_PLATFORM | |||
97 | 97 | ||
98 | If unsure, say N. | 98 | If unsure, say N. |
99 | 99 | ||
100 | config AHCI_DA850 | ||
101 | tristate "DaVinci DA850 AHCI SATA support" | ||
102 | depends on ARCH_DAVINCI_DA850 | ||
103 | help | ||
104 | This option enables support for the DaVinci DA850 SoC's | ||
105 | onboard AHCI SATA. | ||
106 | |||
107 | If unsure, say N. | ||
108 | |||
109 | config AHCI_ST | ||
110 | tristate "ST AHCI SATA support" | ||
111 | depends on ARCH_STI | ||
112 | help | ||
113 | This option enables support for ST AHCI SATA controller. | ||
114 | |||
115 | If unsure, say N. | ||
116 | |||
100 | config AHCI_IMX | 117 | config AHCI_IMX |
101 | tristate "Freescale i.MX AHCI SATA support" | 118 | tristate "Freescale i.MX AHCI SATA support" |
102 | depends on SATA_AHCI_PLATFORM && MFD_SYSCON | 119 | depends on MFD_SYSCON |
103 | help | 120 | help |
104 | This option enables support for the Freescale i.MX SoC's | 121 | This option enables support for the Freescale i.MX SoC's |
105 | onboard AHCI SATA. | 122 | onboard AHCI SATA. |
106 | 123 | ||
107 | If unsure, say N. | 124 | If unsure, say N. |
108 | 125 | ||
126 | config AHCI_SUNXI | ||
127 | tristate "Allwinner sunxi AHCI SATA support" | ||
128 | depends on ARCH_SUNXI | ||
129 | help | ||
130 | This option enables support for the Allwinner sunxi SoC's | ||
131 | onboard AHCI SATA. | ||
132 | |||
133 | If unsure, say N. | ||
134 | |||
135 | config AHCI_XGENE | ||
136 | tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" | ||
137 | depends on ARM64 || COMPILE_TEST | ||
138 | select PHY_XGENE | ||
139 | help | ||
140 | This option enables support for APM X-Gene SoC SATA host controller. | ||
141 | |||
109 | config SATA_FSL | 142 | config SATA_FSL |
110 | tristate "Freescale 3.0Gbps SATA support" | 143 | tristate "Freescale 3.0Gbps SATA support" |
111 | depends on FSL_SOC | 144 | depends on FSL_SOC |
@@ -239,6 +272,7 @@ config SATA_DWC_VDEBUG | |||
239 | 272 | ||
240 | config SATA_HIGHBANK | 273 | config SATA_HIGHBANK |
241 | tristate "Calxeda Highbank SATA support" | 274 | tristate "Calxeda Highbank SATA support" |
275 | depends on ARCH_HIGHBANK || COMPILE_TEST | ||
242 | help | 276 | help |
243 | This option enables support for the Calxeda Highbank SoC's | 277 | This option enables support for the Calxeda Highbank SoC's |
244 | onboard SATA. | 278 | onboard SATA. |
@@ -247,6 +281,8 @@ config SATA_HIGHBANK | |||
247 | 281 | ||
248 | config SATA_MV | 282 | config SATA_MV |
249 | tristate "Marvell SATA support" | 283 | tristate "Marvell SATA support" |
284 | depends on PCI || ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \ | ||
285 | ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST | ||
250 | select GENERIC_PHY | 286 | select GENERIC_PHY |
251 | help | 287 | help |
252 | This option enables support for the Marvell Serial ATA family. | 288 | This option enables support for the Marvell Serial ATA family. |
@@ -273,6 +309,7 @@ config SATA_PROMISE | |||
273 | 309 | ||
274 | config SATA_RCAR | 310 | config SATA_RCAR |
275 | tristate "Renesas R-Car SATA support" | 311 | tristate "Renesas R-Car SATA support" |
312 | depends on ARCH_SHMOBILE || COMPILE_TEST | ||
276 | help | 313 | help |
277 | This option enables support for Renesas R-Car Serial ATA. | 314 | This option enables support for Renesas R-Car Serial ATA. |
278 | 315 | ||
@@ -352,6 +389,7 @@ config PATA_AMD | |||
352 | 389 | ||
353 | config PATA_ARASAN_CF | 390 | config PATA_ARASAN_CF |
354 | tristate "ARASAN CompactFlash PATA Controller Support" | 391 | tristate "ARASAN CompactFlash PATA Controller Support" |
392 | depends on ARCH_SPEAR13XX || COMPILE_TEST | ||
355 | depends on DMADEVICES | 393 | depends on DMADEVICES |
356 | select DMA_ENGINE | 394 | select DMA_ENGINE |
357 | help | 395 | help |
@@ -403,7 +441,7 @@ config PATA_CMD64X | |||
403 | 441 | ||
404 | config PATA_CS5520 | 442 | config PATA_CS5520 |
405 | tristate "CS5510/5520 PATA support" | 443 | tristate "CS5510/5520 PATA support" |
406 | depends on PCI | 444 | depends on PCI && (X86_32 || COMPILE_TEST) |
407 | help | 445 | help |
408 | This option enables support for the Cyrix 5510/5520 | 446 | This option enables support for the Cyrix 5510/5520 |
409 | companion chip used with the MediaGX/Geode processor family. | 447 | companion chip used with the MediaGX/Geode processor family. |
@@ -412,7 +450,7 @@ config PATA_CS5520 | |||
412 | 450 | ||
413 | config PATA_CS5530 | 451 | config PATA_CS5530 |
414 | tristate "CS5530 PATA support" | 452 | tristate "CS5530 PATA support" |
415 | depends on PCI | 453 | depends on PCI && (X86_32 || COMPILE_TEST) |
416 | help | 454 | help |
417 | This option enables support for the Cyrix/NatSemi/AMD CS5530 | 455 | This option enables support for the Cyrix/NatSemi/AMD CS5530 |
418 | companion chip used with the MediaGX/Geode processor family. | 456 | companion chip used with the MediaGX/Geode processor family. |
@@ -421,7 +459,7 @@ config PATA_CS5530 | |||
421 | 459 | ||
422 | config PATA_CS5535 | 460 | config PATA_CS5535 |
423 | tristate "CS5535 PATA support (Experimental)" | 461 | tristate "CS5535 PATA support (Experimental)" |
424 | depends on PCI && X86 && !X86_64 | 462 | depends on PCI && X86_32 |
425 | help | 463 | help |
426 | This option enables support for the NatSemi/AMD CS5535 | 464 | This option enables support for the NatSemi/AMD CS5535 |
427 | companion chip used with the Geode processor family. | 465 | companion chip used with the Geode processor family. |
@@ -430,7 +468,7 @@ config PATA_CS5535 | |||
430 | 468 | ||
431 | config PATA_CS5536 | 469 | config PATA_CS5536 |
432 | tristate "CS5536 PATA support" | 470 | tristate "CS5536 PATA support" |
433 | depends on PCI | 471 | depends on PCI && (X86_32 || MIPS || COMPILE_TEST) |
434 | help | 472 | help |
435 | This option enables support for the AMD CS5536 | 473 | This option enables support for the AMD CS5536 |
436 | companion chip used with the Geode LX processor family. | 474 | companion chip used with the Geode LX processor family. |
@@ -666,7 +704,7 @@ config PATA_RDC | |||
666 | 704 | ||
667 | config PATA_SC1200 | 705 | config PATA_SC1200 |
668 | tristate "SC1200 PATA support" | 706 | tristate "SC1200 PATA support" |
669 | depends on PCI | 707 | depends on PCI && (X86_32 || COMPILE_TEST) |
670 | help | 708 | help |
671 | This option enables support for the NatSemi/AMD SC1200 SoC | 709 | This option enables support for the NatSemi/AMD SC1200 SoC |
672 | companion chip used with the Geode processor family. | 710 | companion chip used with the Geode processor family. |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 46518c622460..44c8016e565c 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -4,13 +4,17 @@ obj-$(CONFIG_ATA) += libata.o | |||
4 | # non-SFF interface | 4 | # non-SFF interface |
5 | obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o | 5 | obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o |
6 | obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o | 6 | obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o |
7 | obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o | 7 | obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o |
8 | obj-$(CONFIG_SATA_FSL) += sata_fsl.o | 8 | obj-$(CONFIG_SATA_FSL) += sata_fsl.o |
9 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o | 9 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o |
10 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o | 10 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o |
11 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o | 11 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o |
12 | obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o | 12 | obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o |
13 | obj-$(CONFIG_AHCI_IMX) += ahci_imx.o | 13 | obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o |
14 | obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o | ||
15 | obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o | ||
16 | obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o | ||
17 | obj-$(CONFIG_AHCI_XGENE) += ahci_xgene.o libahci.o libahci_platform.o | ||
14 | 18 | ||
15 | # SFF w/ custom DMA | 19 | # SFF w/ custom DMA |
16 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o | 20 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o |
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index fd665d919df2..b51605ac5974 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/init.h> | ||
40 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
42 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c81d809c111b..a52a5b662f35 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/init.h> | ||
39 | #include <linux/blkdev.h> | 38 | #include <linux/blkdev.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
@@ -578,6 +577,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
578 | unsigned long deadline) | 577 | unsigned long deadline) |
579 | { | 578 | { |
580 | struct ata_port *ap = link->ap; | 579 | struct ata_port *ap = link->ap; |
580 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
581 | bool online; | 581 | bool online; |
582 | int rc; | 582 | int rc; |
583 | 583 | ||
@@ -588,7 +588,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
588 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), | 588 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), |
589 | deadline, &online, NULL); | 589 | deadline, &online, NULL); |
590 | 590 | ||
591 | ahci_start_engine(ap); | 591 | hpriv->start_engine(ap); |
592 | 592 | ||
593 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); | 593 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); |
594 | 594 | ||
@@ -603,6 +603,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
603 | { | 603 | { |
604 | struct ata_port *ap = link->ap; | 604 | struct ata_port *ap = link->ap; |
605 | struct ahci_port_priv *pp = ap->private_data; | 605 | struct ahci_port_priv *pp = ap->private_data; |
606 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
606 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 607 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
607 | struct ata_taskfile tf; | 608 | struct ata_taskfile tf; |
608 | bool online; | 609 | bool online; |
@@ -618,7 +619,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
618 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), | 619 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), |
619 | deadline, &online, NULL); | 620 | deadline, &online, NULL); |
620 | 621 | ||
621 | ahci_start_engine(ap); | 622 | hpriv->start_engine(ap); |
622 | 623 | ||
623 | /* The pseudo configuration device on SIMG4726 attached to | 624 | /* The pseudo configuration device on SIMG4726 attached to |
624 | * ASUS P5W-DH Deluxe doesn't send signature FIS after | 625 | * ASUS P5W-DH Deluxe doesn't send signature FIS after |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 2289efdf8203..51af275b3388 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/libata.h> | 39 | #include <linux/libata.h> |
40 | #include <linux/phy/phy.h> | ||
41 | #include <linux/regulator/consumer.h> | ||
40 | 42 | ||
41 | /* Enclosure Management Control */ | 43 | /* Enclosure Management Control */ |
42 | #define EM_CTRL_MSG_TYPE 0x000f0000 | 44 | #define EM_CTRL_MSG_TYPE 0x000f0000 |
@@ -51,6 +53,7 @@ | |||
51 | 53 | ||
52 | enum { | 54 | enum { |
53 | AHCI_MAX_PORTS = 32, | 55 | AHCI_MAX_PORTS = 32, |
56 | AHCI_MAX_CLKS = 3, | ||
54 | AHCI_MAX_SG = 168, /* hardware max is 64K */ | 57 | AHCI_MAX_SG = 168, /* hardware max is 64K */ |
55 | AHCI_DMA_BOUNDARY = 0xffffffff, | 58 | AHCI_DMA_BOUNDARY = 0xffffffff, |
56 | AHCI_MAX_CMDS = 32, | 59 | AHCI_MAX_CMDS = 32, |
@@ -321,8 +324,17 @@ struct ahci_host_priv { | |||
321 | u32 em_loc; /* enclosure management location */ | 324 | u32 em_loc; /* enclosure management location */ |
322 | u32 em_buf_sz; /* EM buffer size in byte */ | 325 | u32 em_buf_sz; /* EM buffer size in byte */ |
323 | u32 em_msg_type; /* EM message type */ | 326 | u32 em_msg_type; /* EM message type */ |
324 | struct clk *clk; /* Only for platforms supporting clk */ | 327 | bool got_runtime_pm; /* Did we do pm_runtime_get? */ |
328 | struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ | ||
329 | struct regulator *target_pwr; /* Optional */ | ||
330 | struct phy *phy; /* If platform uses phy */ | ||
325 | void *plat_data; /* Other platform data */ | 331 | void *plat_data; /* Other platform data */ |
332 | /* | ||
333 | * Optional ahci_start_engine override, if not set this gets set to the | ||
334 | * default ahci_start_engine during ahci_save_initial_config, this can | ||
335 | * be overridden anytime before the host is activated. | ||
336 | */ | ||
337 | void (*start_engine)(struct ata_port *ap); | ||
326 | }; | 338 | }; |
327 | 339 | ||
328 | extern int ahci_ignore_sss; | 340 | extern int ahci_ignore_sss; |
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c new file mode 100644 index 000000000000..2c83613ce2db --- /dev/null +++ b/drivers/ata/ahci_da850.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * DaVinci DA850 AHCI SATA platform driver | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2, or (at your option) | ||
7 | * any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/pm.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/libata.h> | ||
16 | #include <linux/ahci_platform.h> | ||
17 | #include "ahci.h" | ||
18 | |||
19 | /* SATA PHY Control Register offset from AHCI base */ | ||
20 | #define SATA_P0PHYCR_REG 0x178 | ||
21 | |||
22 | #define SATA_PHY_MPY(x) ((x) << 0) | ||
23 | #define SATA_PHY_LOS(x) ((x) << 6) | ||
24 | #define SATA_PHY_RXCDR(x) ((x) << 10) | ||
25 | #define SATA_PHY_RXEQ(x) ((x) << 13) | ||
26 | #define SATA_PHY_TXSWING(x) ((x) << 19) | ||
27 | #define SATA_PHY_ENPLL(x) ((x) << 31) | ||
28 | |||
29 | /* | ||
30 | * The multiplier needed for 1.5GHz PLL output. | ||
31 | * | ||
32 | * NOTE: This is currently hardcoded to be suitable for 100MHz crystal | ||
33 | * frequency (which is used by DA850 EVM board) and may need to be changed | ||
34 | * if you would like to use this driver on some other board. | ||
35 | */ | ||
36 | #define DA850_SATA_CLK_MULTIPLIER 7 | ||
37 | |||
38 | static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, | ||
39 | void __iomem *ahci_base) | ||
40 | { | ||
41 | unsigned int val; | ||
42 | |||
43 | /* Enable SATA clock receiver */ | ||
44 | val = readl(pwrdn_reg); | ||
45 | val &= ~BIT(0); | ||
46 | writel(val, pwrdn_reg); | ||
47 | |||
48 | val = SATA_PHY_MPY(DA850_SATA_CLK_MULTIPLIER + 1) | SATA_PHY_LOS(1) | | ||
49 | SATA_PHY_RXCDR(4) | SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | | ||
50 | SATA_PHY_ENPLL(1); | ||
51 | |||
52 | writel(val, ahci_base + SATA_P0PHYCR_REG); | ||
53 | } | ||
54 | |||
55 | static const struct ata_port_info ahci_da850_port_info = { | ||
56 | .flags = AHCI_FLAG_COMMON, | ||
57 | .pio_mask = ATA_PIO4, | ||
58 | .udma_mask = ATA_UDMA6, | ||
59 | .port_ops = &ahci_platform_ops, | ||
60 | }; | ||
61 | |||
62 | static int ahci_da850_probe(struct platform_device *pdev) | ||
63 | { | ||
64 | struct device *dev = &pdev->dev; | ||
65 | struct ahci_host_priv *hpriv; | ||
66 | struct resource *res; | ||
67 | void __iomem *pwrdn_reg; | ||
68 | int rc; | ||
69 | |||
70 | hpriv = ahci_platform_get_resources(pdev); | ||
71 | if (IS_ERR(hpriv)) | ||
72 | return PTR_ERR(hpriv); | ||
73 | |||
74 | rc = ahci_platform_enable_resources(hpriv); | ||
75 | if (rc) | ||
76 | return rc; | ||
77 | |||
78 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
79 | if (!res) | ||
80 | goto disable_resources; | ||
81 | |||
82 | pwrdn_reg = devm_ioremap(dev, res->start, resource_size(res)); | ||
83 | if (!pwrdn_reg) | ||
84 | goto disable_resources; | ||
85 | |||
86 | da850_sata_init(dev, pwrdn_reg, hpriv->mmio); | ||
87 | |||
88 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info, 0, 0); | ||
89 | if (rc) | ||
90 | goto disable_resources; | ||
91 | |||
92 | return 0; | ||
93 | disable_resources: | ||
94 | ahci_platform_disable_resources(hpriv); | ||
95 | return rc; | ||
96 | } | ||
97 | |||
98 | static SIMPLE_DEV_PM_OPS(ahci_da850_pm_ops, ahci_platform_suspend, | ||
99 | ahci_platform_resume); | ||
100 | |||
101 | static struct platform_driver ahci_da850_driver = { | ||
102 | .probe = ahci_da850_probe, | ||
103 | .remove = ata_platform_remove_one, | ||
104 | .driver = { | ||
105 | .name = "ahci_da850", | ||
106 | .owner = THIS_MODULE, | ||
107 | .pm = &ahci_da850_pm_ops, | ||
108 | }, | ||
109 | }; | ||
110 | module_platform_driver(ahci_da850_driver); | ||
111 | |||
112 | MODULE_DESCRIPTION("DaVinci DA850 AHCI SATA platform driver"); | ||
113 | MODULE_AUTHOR("Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>"); | ||
114 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index dd4d6f74d7bd..497c7abe1c7d 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c | |||
@@ -42,13 +42,7 @@ enum ahci_imx_type { | |||
42 | struct imx_ahci_priv { | 42 | struct imx_ahci_priv { |
43 | struct platform_device *ahci_pdev; | 43 | struct platform_device *ahci_pdev; |
44 | enum ahci_imx_type type; | 44 | enum ahci_imx_type type; |
45 | |||
46 | /* i.MX53 clock */ | ||
47 | struct clk *sata_gate_clk; | ||
48 | /* Common clock */ | ||
49 | struct clk *sata_ref_clk; | ||
50 | struct clk *ahb_clk; | 45 | struct clk *ahb_clk; |
51 | |||
52 | struct regmap *gpr; | 46 | struct regmap *gpr; |
53 | bool no_device; | 47 | bool no_device; |
54 | bool first_time; | 48 | bool first_time; |
@@ -58,28 +52,52 @@ static int ahci_imx_hotplug; | |||
58 | module_param_named(hotplug, ahci_imx_hotplug, int, 0644); | 52 | module_param_named(hotplug, ahci_imx_hotplug, int, 0644); |
59 | MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)"); | 53 | MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)"); |
60 | 54 | ||
61 | static int imx_sata_clock_enable(struct device *dev) | 55 | static void ahci_imx_host_stop(struct ata_host *host); |
56 | |||
57 | static int imx_sata_enable(struct ahci_host_priv *hpriv) | ||
62 | { | 58 | { |
63 | struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); | 59 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; |
64 | int ret; | 60 | int ret; |
65 | 61 | ||
66 | if (imxpriv->type == AHCI_IMX53) { | 62 | if (imxpriv->no_device) |
67 | ret = clk_prepare_enable(imxpriv->sata_gate_clk); | 63 | return 0; |
68 | if (ret < 0) { | 64 | |
69 | dev_err(dev, "prepare-enable sata_gate clock err:%d\n", | 65 | if (hpriv->target_pwr) { |
70 | ret); | 66 | ret = regulator_enable(hpriv->target_pwr); |
67 | if (ret) | ||
71 | return ret; | 68 | return ret; |
72 | } | ||
73 | } | 69 | } |
74 | 70 | ||
75 | ret = clk_prepare_enable(imxpriv->sata_ref_clk); | 71 | ret = ahci_platform_enable_clks(hpriv); |
76 | if (ret < 0) { | 72 | if (ret < 0) |
77 | dev_err(dev, "prepare-enable sata_ref clock err:%d\n", | 73 | goto disable_regulator; |
78 | ret); | ||
79 | goto clk_err; | ||
80 | } | ||
81 | 74 | ||
82 | if (imxpriv->type == AHCI_IMX6Q) { | 75 | if (imxpriv->type == AHCI_IMX6Q) { |
76 | /* | ||
77 | * set PHY Paremeters, two steps to configure the GPR13, | ||
78 | * one write for rest of parameters, mask of first write | ||
79 | * is 0x07ffffff, and the other one write for setting | ||
80 | * the mpll_clk_en. | ||
81 | */ | ||
82 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, | ||
83 | IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK | | ||
84 | IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK | | ||
85 | IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK | | ||
86 | IMX6Q_GPR13_SATA_SPD_MODE_MASK | | ||
87 | IMX6Q_GPR13_SATA_MPLL_SS_EN | | ||
88 | IMX6Q_GPR13_SATA_TX_ATTEN_MASK | | ||
89 | IMX6Q_GPR13_SATA_TX_BOOST_MASK | | ||
90 | IMX6Q_GPR13_SATA_TX_LVL_MASK | | ||
91 | IMX6Q_GPR13_SATA_MPLL_CLK_EN | | ||
92 | IMX6Q_GPR13_SATA_TX_EDGE_RATE, | ||
93 | IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB | | ||
94 | IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M | | ||
95 | IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F | | ||
96 | IMX6Q_GPR13_SATA_SPD_MODE_3P0G | | ||
97 | IMX6Q_GPR13_SATA_MPLL_SS_EN | | ||
98 | IMX6Q_GPR13_SATA_TX_ATTEN_9_16 | | ||
99 | IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB | | ||
100 | IMX6Q_GPR13_SATA_TX_LVL_1_025_V); | ||
83 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, | 101 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, |
84 | IMX6Q_GPR13_SATA_MPLL_CLK_EN, | 102 | IMX6Q_GPR13_SATA_MPLL_CLK_EN, |
85 | IMX6Q_GPR13_SATA_MPLL_CLK_EN); | 103 | IMX6Q_GPR13_SATA_MPLL_CLK_EN); |
@@ -89,15 +107,19 @@ static int imx_sata_clock_enable(struct device *dev) | |||
89 | 107 | ||
90 | return 0; | 108 | return 0; |
91 | 109 | ||
92 | clk_err: | 110 | disable_regulator: |
93 | if (imxpriv->type == AHCI_IMX53) | 111 | if (hpriv->target_pwr) |
94 | clk_disable_unprepare(imxpriv->sata_gate_clk); | 112 | regulator_disable(hpriv->target_pwr); |
113 | |||
95 | return ret; | 114 | return ret; |
96 | } | 115 | } |
97 | 116 | ||
98 | static void imx_sata_clock_disable(struct device *dev) | 117 | static void imx_sata_disable(struct ahci_host_priv *hpriv) |
99 | { | 118 | { |
100 | struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); | 119 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; |
120 | |||
121 | if (imxpriv->no_device) | ||
122 | return; | ||
101 | 123 | ||
102 | if (imxpriv->type == AHCI_IMX6Q) { | 124 | if (imxpriv->type == AHCI_IMX6Q) { |
103 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, | 125 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, |
@@ -105,10 +127,10 @@ static void imx_sata_clock_disable(struct device *dev) | |||
105 | !IMX6Q_GPR13_SATA_MPLL_CLK_EN); | 127 | !IMX6Q_GPR13_SATA_MPLL_CLK_EN); |
106 | } | 128 | } |
107 | 129 | ||
108 | clk_disable_unprepare(imxpriv->sata_ref_clk); | 130 | ahci_platform_disable_clks(hpriv); |
109 | 131 | ||
110 | if (imxpriv->type == AHCI_IMX53) | 132 | if (hpriv->target_pwr) |
111 | clk_disable_unprepare(imxpriv->sata_gate_clk); | 133 | regulator_disable(hpriv->target_pwr); |
112 | } | 134 | } |
113 | 135 | ||
114 | static void ahci_imx_error_handler(struct ata_port *ap) | 136 | static void ahci_imx_error_handler(struct ata_port *ap) |
@@ -118,7 +140,7 @@ static void ahci_imx_error_handler(struct ata_port *ap) | |||
118 | struct ata_host *host = dev_get_drvdata(ap->dev); | 140 | struct ata_host *host = dev_get_drvdata(ap->dev); |
119 | struct ahci_host_priv *hpriv = host->private_data; | 141 | struct ahci_host_priv *hpriv = host->private_data; |
120 | void __iomem *mmio = hpriv->mmio; | 142 | void __iomem *mmio = hpriv->mmio; |
121 | struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent); | 143 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; |
122 | 144 | ||
123 | ahci_error_handler(ap); | 145 | ahci_error_handler(ap); |
124 | 146 | ||
@@ -136,7 +158,7 @@ static void ahci_imx_error_handler(struct ata_port *ap) | |||
136 | */ | 158 | */ |
137 | reg_val = readl(mmio + PORT_PHY_CTL); | 159 | reg_val = readl(mmio + PORT_PHY_CTL); |
138 | writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL); | 160 | writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL); |
139 | imx_sata_clock_disable(ap->dev); | 161 | imx_sata_disable(hpriv); |
140 | imxpriv->no_device = true; | 162 | imxpriv->no_device = true; |
141 | } | 163 | } |
142 | 164 | ||
@@ -144,7 +166,9 @@ static int ahci_imx_softreset(struct ata_link *link, unsigned int *class, | |||
144 | unsigned long deadline) | 166 | unsigned long deadline) |
145 | { | 167 | { |
146 | struct ata_port *ap = link->ap; | 168 | struct ata_port *ap = link->ap; |
147 | struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent); | 169 | struct ata_host *host = dev_get_drvdata(ap->dev); |
170 | struct ahci_host_priv *hpriv = host->private_data; | ||
171 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; | ||
148 | int ret = -EIO; | 172 | int ret = -EIO; |
149 | 173 | ||
150 | if (imxpriv->type == AHCI_IMX53) | 174 | if (imxpriv->type == AHCI_IMX53) |
@@ -156,7 +180,8 @@ static int ahci_imx_softreset(struct ata_link *link, unsigned int *class, | |||
156 | } | 180 | } |
157 | 181 | ||
158 | static struct ata_port_operations ahci_imx_ops = { | 182 | static struct ata_port_operations ahci_imx_ops = { |
159 | .inherits = &ahci_platform_ops, | 183 | .inherits = &ahci_ops, |
184 | .host_stop = ahci_imx_host_stop, | ||
160 | .error_handler = ahci_imx_error_handler, | 185 | .error_handler = ahci_imx_error_handler, |
161 | .softreset = ahci_imx_softreset, | 186 | .softreset = ahci_imx_softreset, |
162 | }; | 187 | }; |
@@ -168,79 +193,6 @@ static const struct ata_port_info ahci_imx_port_info = { | |||
168 | .port_ops = &ahci_imx_ops, | 193 | .port_ops = &ahci_imx_ops, |
169 | }; | 194 | }; |
170 | 195 | ||
171 | static int imx_sata_init(struct device *dev, void __iomem *mmio) | ||
172 | { | ||
173 | int ret = 0; | ||
174 | unsigned int reg_val; | ||
175 | struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); | ||
176 | |||
177 | ret = imx_sata_clock_enable(dev); | ||
178 | if (ret < 0) | ||
179 | return ret; | ||
180 | |||
181 | /* | ||
182 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, | ||
183 | * and IP vendor specific register HOST_TIMER1MS. | ||
184 | * Configure CAP_SSS (support stagered spin up). | ||
185 | * Implement the port0. | ||
186 | * Get the ahb clock rate, and configure the TIMER1MS register. | ||
187 | */ | ||
188 | reg_val = readl(mmio + HOST_CAP); | ||
189 | if (!(reg_val & HOST_CAP_SSS)) { | ||
190 | reg_val |= HOST_CAP_SSS; | ||
191 | writel(reg_val, mmio + HOST_CAP); | ||
192 | } | ||
193 | reg_val = readl(mmio + HOST_PORTS_IMPL); | ||
194 | if (!(reg_val & 0x1)) { | ||
195 | reg_val |= 0x1; | ||
196 | writel(reg_val, mmio + HOST_PORTS_IMPL); | ||
197 | } | ||
198 | |||
199 | reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; | ||
200 | writel(reg_val, mmio + HOST_TIMER1MS); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static void imx_sata_exit(struct device *dev) | ||
206 | { | ||
207 | imx_sata_clock_disable(dev); | ||
208 | } | ||
209 | |||
210 | static int imx_ahci_suspend(struct device *dev) | ||
211 | { | ||
212 | struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); | ||
213 | |||
214 | /* | ||
215 | * If no_device is set, The CLKs had been gated off in the | ||
216 | * initialization so don't do it again here. | ||
217 | */ | ||
218 | if (!imxpriv->no_device) | ||
219 | imx_sata_clock_disable(dev); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int imx_ahci_resume(struct device *dev) | ||
225 | { | ||
226 | struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); | ||
227 | int ret = 0; | ||
228 | |||
229 | if (!imxpriv->no_device) | ||
230 | ret = imx_sata_clock_enable(dev); | ||
231 | |||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | static struct ahci_platform_data imx_sata_pdata = { | ||
236 | .init = imx_sata_init, | ||
237 | .exit = imx_sata_exit, | ||
238 | .ata_port_info = &ahci_imx_port_info, | ||
239 | .suspend = imx_ahci_suspend, | ||
240 | .resume = imx_ahci_resume, | ||
241 | |||
242 | }; | ||
243 | |||
244 | static const struct of_device_id imx_ahci_of_match[] = { | 196 | static const struct of_device_id imx_ahci_of_match[] = { |
245 | { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 }, | 197 | { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 }, |
246 | { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q }, | 198 | { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q }, |
@@ -251,151 +203,124 @@ MODULE_DEVICE_TABLE(of, imx_ahci_of_match); | |||
251 | static int imx_ahci_probe(struct platform_device *pdev) | 203 | static int imx_ahci_probe(struct platform_device *pdev) |
252 | { | 204 | { |
253 | struct device *dev = &pdev->dev; | 205 | struct device *dev = &pdev->dev; |
254 | struct resource *mem, *irq, res[2]; | ||
255 | const struct of_device_id *of_id; | 206 | const struct of_device_id *of_id; |
256 | enum ahci_imx_type type; | 207 | struct ahci_host_priv *hpriv; |
257 | const struct ahci_platform_data *pdata = NULL; | ||
258 | struct imx_ahci_priv *imxpriv; | 208 | struct imx_ahci_priv *imxpriv; |
259 | struct device *ahci_dev; | 209 | unsigned int reg_val; |
260 | struct platform_device *ahci_pdev; | ||
261 | int ret; | 210 | int ret; |
262 | 211 | ||
263 | of_id = of_match_device(imx_ahci_of_match, dev); | 212 | of_id = of_match_device(imx_ahci_of_match, dev); |
264 | if (!of_id) | 213 | if (!of_id) |
265 | return -EINVAL; | 214 | return -EINVAL; |
266 | 215 | ||
267 | type = (enum ahci_imx_type)of_id->data; | ||
268 | pdata = &imx_sata_pdata; | ||
269 | |||
270 | imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL); | 216 | imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL); |
271 | if (!imxpriv) { | 217 | if (!imxpriv) |
272 | dev_err(dev, "can't alloc ahci_host_priv\n"); | ||
273 | return -ENOMEM; | 218 | return -ENOMEM; |
274 | } | ||
275 | |||
276 | ahci_pdev = platform_device_alloc("ahci", -1); | ||
277 | if (!ahci_pdev) | ||
278 | return -ENODEV; | ||
279 | |||
280 | ahci_dev = &ahci_pdev->dev; | ||
281 | ahci_dev->parent = dev; | ||
282 | 219 | ||
283 | imxpriv->no_device = false; | 220 | imxpriv->no_device = false; |
284 | imxpriv->first_time = true; | 221 | imxpriv->first_time = true; |
285 | imxpriv->type = type; | 222 | imxpriv->type = (enum ahci_imx_type)of_id->data; |
286 | |||
287 | imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); | 223 | imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); |
288 | if (IS_ERR(imxpriv->ahb_clk)) { | 224 | if (IS_ERR(imxpriv->ahb_clk)) { |
289 | dev_err(dev, "can't get ahb clock.\n"); | 225 | dev_err(dev, "can't get ahb clock.\n"); |
290 | ret = PTR_ERR(imxpriv->ahb_clk); | 226 | return PTR_ERR(imxpriv->ahb_clk); |
291 | goto err_out; | ||
292 | } | 227 | } |
293 | 228 | ||
294 | if (type == AHCI_IMX53) { | 229 | if (imxpriv->type == AHCI_IMX6Q) { |
295 | imxpriv->sata_gate_clk = devm_clk_get(dev, "sata_gate"); | 230 | imxpriv->gpr = syscon_regmap_lookup_by_compatible( |
296 | if (IS_ERR(imxpriv->sata_gate_clk)) { | 231 | "fsl,imx6q-iomuxc-gpr"); |
297 | dev_err(dev, "can't get sata_gate clock.\n"); | 232 | if (IS_ERR(imxpriv->gpr)) { |
298 | ret = PTR_ERR(imxpriv->sata_gate_clk); | 233 | dev_err(dev, |
299 | goto err_out; | 234 | "failed to find fsl,imx6q-iomux-gpr regmap\n"); |
235 | return PTR_ERR(imxpriv->gpr); | ||
300 | } | 236 | } |
301 | } | 237 | } |
302 | 238 | ||
303 | imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref"); | 239 | hpriv = ahci_platform_get_resources(pdev); |
304 | if (IS_ERR(imxpriv->sata_ref_clk)) { | 240 | if (IS_ERR(hpriv)) |
305 | dev_err(dev, "can't get sata_ref clock.\n"); | 241 | return PTR_ERR(hpriv); |
306 | ret = PTR_ERR(imxpriv->sata_ref_clk); | 242 | |
307 | goto err_out; | 243 | hpriv->plat_data = imxpriv; |
308 | } | ||
309 | 244 | ||
310 | imxpriv->ahci_pdev = ahci_pdev; | 245 | ret = imx_sata_enable(hpriv); |
311 | platform_set_drvdata(pdev, imxpriv); | 246 | if (ret) |
247 | return ret; | ||
312 | 248 | ||
313 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 249 | /* |
314 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 250 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, |
315 | if (!mem || !irq) { | 251 | * and IP vendor specific register HOST_TIMER1MS. |
316 | dev_err(dev, "no mmio/irq resource\n"); | 252 | * Configure CAP_SSS (support stagered spin up). |
317 | ret = -ENOMEM; | 253 | * Implement the port0. |
318 | goto err_out; | 254 | * Get the ahb clock rate, and configure the TIMER1MS register. |
255 | */ | ||
256 | reg_val = readl(hpriv->mmio + HOST_CAP); | ||
257 | if (!(reg_val & HOST_CAP_SSS)) { | ||
258 | reg_val |= HOST_CAP_SSS; | ||
259 | writel(reg_val, hpriv->mmio + HOST_CAP); | ||
260 | } | ||
261 | reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL); | ||
262 | if (!(reg_val & 0x1)) { | ||
263 | reg_val |= 0x1; | ||
264 | writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL); | ||
319 | } | 265 | } |
320 | 266 | ||
321 | res[0] = *mem; | 267 | reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; |
322 | res[1] = *irq; | 268 | writel(reg_val, hpriv->mmio + HOST_TIMER1MS); |
323 | 269 | ||
324 | ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32); | 270 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0); |
325 | ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask; | 271 | if (ret) |
326 | ahci_dev->of_node = dev->of_node; | 272 | imx_sata_disable(hpriv); |
327 | 273 | ||
328 | if (type == AHCI_IMX6Q) { | 274 | return ret; |
329 | imxpriv->gpr = syscon_regmap_lookup_by_compatible( | 275 | } |
330 | "fsl,imx6q-iomuxc-gpr"); | ||
331 | if (IS_ERR(imxpriv->gpr)) { | ||
332 | dev_err(dev, | ||
333 | "failed to find fsl,imx6q-iomux-gpr regmap\n"); | ||
334 | ret = PTR_ERR(imxpriv->gpr); | ||
335 | goto err_out; | ||
336 | } | ||
337 | 276 | ||
338 | /* | 277 | static void ahci_imx_host_stop(struct ata_host *host) |
339 | * Set PHY Paremeters, two steps to configure the GPR13, | 278 | { |
340 | * one write for rest of parameters, mask of first write | 279 | struct ahci_host_priv *hpriv = host->private_data; |
341 | * is 0x07fffffe, and the other one write for setting | ||
342 | * the mpll_clk_en happens in imx_sata_clock_enable(). | ||
343 | */ | ||
344 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, | ||
345 | IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK | | ||
346 | IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK | | ||
347 | IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK | | ||
348 | IMX6Q_GPR13_SATA_SPD_MODE_MASK | | ||
349 | IMX6Q_GPR13_SATA_MPLL_SS_EN | | ||
350 | IMX6Q_GPR13_SATA_TX_ATTEN_MASK | | ||
351 | IMX6Q_GPR13_SATA_TX_BOOST_MASK | | ||
352 | IMX6Q_GPR13_SATA_TX_LVL_MASK | | ||
353 | IMX6Q_GPR13_SATA_MPLL_CLK_EN | | ||
354 | IMX6Q_GPR13_SATA_TX_EDGE_RATE, | ||
355 | IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB | | ||
356 | IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M | | ||
357 | IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F | | ||
358 | IMX6Q_GPR13_SATA_SPD_MODE_3P0G | | ||
359 | IMX6Q_GPR13_SATA_MPLL_SS_EN | | ||
360 | IMX6Q_GPR13_SATA_TX_ATTEN_9_16 | | ||
361 | IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB | | ||
362 | IMX6Q_GPR13_SATA_TX_LVL_1_025_V); | ||
363 | } | ||
364 | 280 | ||
365 | ret = platform_device_add_resources(ahci_pdev, res, 2); | 281 | imx_sata_disable(hpriv); |
366 | if (ret) | 282 | } |
367 | goto err_out; | ||
368 | 283 | ||
369 | ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata)); | 284 | #ifdef CONFIG_PM_SLEEP |
370 | if (ret) | 285 | static int imx_ahci_suspend(struct device *dev) |
371 | goto err_out; | 286 | { |
287 | struct ata_host *host = dev_get_drvdata(dev); | ||
288 | struct ahci_host_priv *hpriv = host->private_data; | ||
289 | int ret; | ||
372 | 290 | ||
373 | ret = platform_device_add(ahci_pdev); | 291 | ret = ahci_platform_suspend_host(dev); |
374 | if (ret) { | 292 | if (ret) |
375 | err_out: | ||
376 | platform_device_put(ahci_pdev); | ||
377 | return ret; | 293 | return ret; |
378 | } | 294 | |
295 | imx_sata_disable(hpriv); | ||
379 | 296 | ||
380 | return 0; | 297 | return 0; |
381 | } | 298 | } |
382 | 299 | ||
383 | static int imx_ahci_remove(struct platform_device *pdev) | 300 | static int imx_ahci_resume(struct device *dev) |
384 | { | 301 | { |
385 | struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev); | 302 | struct ata_host *host = dev_get_drvdata(dev); |
386 | struct platform_device *ahci_pdev = imxpriv->ahci_pdev; | 303 | struct ahci_host_priv *hpriv = host->private_data; |
304 | int ret; | ||
387 | 305 | ||
388 | platform_device_unregister(ahci_pdev); | 306 | ret = imx_sata_enable(hpriv); |
389 | return 0; | 307 | if (ret) |
308 | return ret; | ||
309 | |||
310 | return ahci_platform_resume_host(dev); | ||
390 | } | 311 | } |
312 | #endif | ||
313 | |||
314 | static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume); | ||
391 | 315 | ||
392 | static struct platform_driver imx_ahci_driver = { | 316 | static struct platform_driver imx_ahci_driver = { |
393 | .probe = imx_ahci_probe, | 317 | .probe = imx_ahci_probe, |
394 | .remove = imx_ahci_remove, | 318 | .remove = ata_platform_remove_one, |
395 | .driver = { | 319 | .driver = { |
396 | .name = "ahci-imx", | 320 | .name = "ahci-imx", |
397 | .owner = THIS_MODULE, | 321 | .owner = THIS_MODULE, |
398 | .of_match_table = imx_ahci_of_match, | 322 | .of_match_table = imx_ahci_of_match, |
323 | .pm = &ahci_imx_pm_ops, | ||
399 | }, | 324 | }, |
400 | }; | 325 | }; |
401 | module_platform_driver(imx_ahci_driver); | 326 | module_platform_driver(imx_ahci_driver); |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 4b231baceb09..ef67e79944f9 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -12,135 +12,36 @@ | |||
12 | * any later version. | 12 | * any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/gfp.h> | ||
18 | #include <linux/module.h> | 16 | #include <linux/module.h> |
19 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
20 | #include <linux/init.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/device.h> | 18 | #include <linux/device.h> |
23 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
24 | #include <linux/libata.h> | 20 | #include <linux/libata.h> |
25 | #include <linux/ahci_platform.h> | 21 | #include <linux/ahci_platform.h> |
26 | #include "ahci.h" | 22 | #include "ahci.h" |
27 | 23 | ||
28 | static void ahci_host_stop(struct ata_host *host); | 24 | static const struct ata_port_info ahci_port_info = { |
29 | 25 | .flags = AHCI_FLAG_COMMON, | |
30 | enum ahci_type { | 26 | .pio_mask = ATA_PIO4, |
31 | AHCI, /* standard platform ahci */ | 27 | .udma_mask = ATA_UDMA6, |
32 | IMX53_AHCI, /* ahci on i.mx53 */ | 28 | .port_ops = &ahci_platform_ops, |
33 | STRICT_AHCI, /* delayed DMA engine start */ | ||
34 | }; | ||
35 | |||
36 | static struct platform_device_id ahci_devtype[] = { | ||
37 | { | ||
38 | .name = "ahci", | ||
39 | .driver_data = AHCI, | ||
40 | }, { | ||
41 | .name = "imx53-ahci", | ||
42 | .driver_data = IMX53_AHCI, | ||
43 | }, { | ||
44 | .name = "strict-ahci", | ||
45 | .driver_data = STRICT_AHCI, | ||
46 | }, { | ||
47 | /* sentinel */ | ||
48 | } | ||
49 | }; | ||
50 | MODULE_DEVICE_TABLE(platform, ahci_devtype); | ||
51 | |||
52 | struct ata_port_operations ahci_platform_ops = { | ||
53 | .inherits = &ahci_ops, | ||
54 | .host_stop = ahci_host_stop, | ||
55 | }; | ||
56 | EXPORT_SYMBOL_GPL(ahci_platform_ops); | ||
57 | |||
58 | static struct ata_port_operations ahci_platform_retry_srst_ops = { | ||
59 | .inherits = &ahci_pmp_retry_srst_ops, | ||
60 | .host_stop = ahci_host_stop, | ||
61 | }; | ||
62 | |||
63 | static const struct ata_port_info ahci_port_info[] = { | ||
64 | /* by features */ | ||
65 | [AHCI] = { | ||
66 | .flags = AHCI_FLAG_COMMON, | ||
67 | .pio_mask = ATA_PIO4, | ||
68 | .udma_mask = ATA_UDMA6, | ||
69 | .port_ops = &ahci_platform_ops, | ||
70 | }, | ||
71 | [IMX53_AHCI] = { | ||
72 | .flags = AHCI_FLAG_COMMON, | ||
73 | .pio_mask = ATA_PIO4, | ||
74 | .udma_mask = ATA_UDMA6, | ||
75 | .port_ops = &ahci_platform_retry_srst_ops, | ||
76 | }, | ||
77 | [STRICT_AHCI] = { | ||
78 | AHCI_HFLAGS (AHCI_HFLAG_DELAY_ENGINE), | ||
79 | .flags = AHCI_FLAG_COMMON, | ||
80 | .pio_mask = ATA_PIO4, | ||
81 | .udma_mask = ATA_UDMA6, | ||
82 | .port_ops = &ahci_platform_ops, | ||
83 | }, | ||
84 | }; | ||
85 | |||
86 | static struct scsi_host_template ahci_platform_sht = { | ||
87 | AHCI_SHT("ahci_platform"), | ||
88 | }; | 29 | }; |
89 | 30 | ||
90 | static int ahci_probe(struct platform_device *pdev) | 31 | static int ahci_probe(struct platform_device *pdev) |
91 | { | 32 | { |
92 | struct device *dev = &pdev->dev; | 33 | struct device *dev = &pdev->dev; |
93 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | 34 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
94 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
95 | struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0]; | ||
96 | const struct ata_port_info *ppi[] = { &pi, NULL }; | ||
97 | struct ahci_host_priv *hpriv; | 35 | struct ahci_host_priv *hpriv; |
98 | struct ata_host *host; | ||
99 | struct resource *mem; | ||
100 | int irq; | ||
101 | int n_ports; | ||
102 | int i; | ||
103 | int rc; | 36 | int rc; |
104 | 37 | ||
105 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 38 | hpriv = ahci_platform_get_resources(pdev); |
106 | if (!mem) { | 39 | if (IS_ERR(hpriv)) |
107 | dev_err(dev, "no mmio space\n"); | 40 | return PTR_ERR(hpriv); |
108 | return -EINVAL; | ||
109 | } | ||
110 | |||
111 | irq = platform_get_irq(pdev, 0); | ||
112 | if (irq <= 0) { | ||
113 | dev_err(dev, "no irq\n"); | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | |||
117 | if (pdata && pdata->ata_port_info) | ||
118 | pi = *pdata->ata_port_info; | ||
119 | |||
120 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); | ||
121 | if (!hpriv) { | ||
122 | dev_err(dev, "can't alloc ahci_host_priv\n"); | ||
123 | return -ENOMEM; | ||
124 | } | ||
125 | |||
126 | hpriv->flags |= (unsigned long)pi.private_data; | ||
127 | |||
128 | hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); | ||
129 | if (!hpriv->mmio) { | ||
130 | dev_err(dev, "can't map %pR\n", mem); | ||
131 | return -ENOMEM; | ||
132 | } | ||
133 | 41 | ||
134 | hpriv->clk = clk_get(dev, NULL); | 42 | rc = ahci_platform_enable_resources(hpriv); |
135 | if (IS_ERR(hpriv->clk)) { | 43 | if (rc) |
136 | dev_err(dev, "can't get clock\n"); | 44 | return rc; |
137 | } else { | ||
138 | rc = clk_prepare_enable(hpriv->clk); | ||
139 | if (rc) { | ||
140 | dev_err(dev, "clock prepare enable failed"); | ||
141 | goto free_clk; | ||
142 | } | ||
143 | } | ||
144 | 45 | ||
145 | /* | 46 | /* |
146 | * Some platforms might need to prepare for mmio region access, | 47 | * Some platforms might need to prepare for mmio region access, |
@@ -151,69 +52,10 @@ static int ahci_probe(struct platform_device *pdev) | |||
151 | if (pdata && pdata->init) { | 52 | if (pdata && pdata->init) { |
152 | rc = pdata->init(dev, hpriv->mmio); | 53 | rc = pdata->init(dev, hpriv->mmio); |
153 | if (rc) | 54 | if (rc) |
154 | goto disable_unprepare_clk; | 55 | goto disable_resources; |
155 | } | ||
156 | |||
157 | ahci_save_initial_config(dev, hpriv, | ||
158 | pdata ? pdata->force_port_map : 0, | ||
159 | pdata ? pdata->mask_port_map : 0); | ||
160 | |||
161 | /* prepare host */ | ||
162 | if (hpriv->cap & HOST_CAP_NCQ) | ||
163 | pi.flags |= ATA_FLAG_NCQ; | ||
164 | |||
165 | if (hpriv->cap & HOST_CAP_PMP) | ||
166 | pi.flags |= ATA_FLAG_PMP; | ||
167 | |||
168 | ahci_set_em_messages(hpriv, &pi); | ||
169 | |||
170 | /* CAP.NP sometimes indicate the index of the last enabled | ||
171 | * port, at other times, that of the last possible port, so | ||
172 | * determining the maximum port number requires looking at | ||
173 | * both CAP.NP and port_map. | ||
174 | */ | ||
175 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); | ||
176 | |||
177 | host = ata_host_alloc_pinfo(dev, ppi, n_ports); | ||
178 | if (!host) { | ||
179 | rc = -ENOMEM; | ||
180 | goto pdata_exit; | ||
181 | } | ||
182 | |||
183 | host->private_data = hpriv; | ||
184 | |||
185 | if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) | ||
186 | host->flags |= ATA_HOST_PARALLEL_SCAN; | ||
187 | else | ||
188 | dev_info(dev, "SSS flag set, parallel bus scan disabled\n"); | ||
189 | |||
190 | if (pi.flags & ATA_FLAG_EM) | ||
191 | ahci_reset_em(host); | ||
192 | |||
193 | for (i = 0; i < host->n_ports; i++) { | ||
194 | struct ata_port *ap = host->ports[i]; | ||
195 | |||
196 | ata_port_desc(ap, "mmio %pR", mem); | ||
197 | ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); | ||
198 | |||
199 | /* set enclosure management message type */ | ||
200 | if (ap->flags & ATA_FLAG_EM) | ||
201 | ap->em_message_type = hpriv->em_msg_type; | ||
202 | |||
203 | /* disabled/not-implemented port */ | ||
204 | if (!(hpriv->port_map & (1 << i))) | ||
205 | ap->ops = &ata_dummy_port_ops; | ||
206 | } | 56 | } |
207 | 57 | ||
208 | rc = ahci_reset_controller(host); | 58 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0); |
209 | if (rc) | ||
210 | goto pdata_exit; | ||
211 | |||
212 | ahci_init_controller(host); | ||
213 | ahci_print_info(host, "platform"); | ||
214 | |||
215 | rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, | ||
216 | &ahci_platform_sht); | ||
217 | if (rc) | 59 | if (rc) |
218 | goto pdata_exit; | 60 | goto pdata_exit; |
219 | 61 | ||
@@ -221,115 +63,19 @@ static int ahci_probe(struct platform_device *pdev) | |||
221 | pdata_exit: | 63 | pdata_exit: |
222 | if (pdata && pdata->exit) | 64 | if (pdata && pdata->exit) |
223 | pdata->exit(dev); | 65 | pdata->exit(dev); |
224 | disable_unprepare_clk: | 66 | disable_resources: |
225 | if (!IS_ERR(hpriv->clk)) | 67 | ahci_platform_disable_resources(hpriv); |
226 | clk_disable_unprepare(hpriv->clk); | ||
227 | free_clk: | ||
228 | if (!IS_ERR(hpriv->clk)) | ||
229 | clk_put(hpriv->clk); | ||
230 | return rc; | ||
231 | } | ||
232 | |||
233 | static void ahci_host_stop(struct ata_host *host) | ||
234 | { | ||
235 | struct device *dev = host->dev; | ||
236 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | ||
237 | struct ahci_host_priv *hpriv = host->private_data; | ||
238 | |||
239 | if (pdata && pdata->exit) | ||
240 | pdata->exit(dev); | ||
241 | |||
242 | if (!IS_ERR(hpriv->clk)) { | ||
243 | clk_disable_unprepare(hpriv->clk); | ||
244 | clk_put(hpriv->clk); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | #ifdef CONFIG_PM_SLEEP | ||
249 | static int ahci_suspend(struct device *dev) | ||
250 | { | ||
251 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | ||
252 | struct ata_host *host = dev_get_drvdata(dev); | ||
253 | struct ahci_host_priv *hpriv = host->private_data; | ||
254 | void __iomem *mmio = hpriv->mmio; | ||
255 | u32 ctl; | ||
256 | int rc; | ||
257 | |||
258 | if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { | ||
259 | dev_err(dev, "firmware update required for suspend/resume\n"); | ||
260 | return -EIO; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * AHCI spec rev1.1 section 8.3.3: | ||
265 | * Software must disable interrupts prior to requesting a | ||
266 | * transition of the HBA to D3 state. | ||
267 | */ | ||
268 | ctl = readl(mmio + HOST_CTL); | ||
269 | ctl &= ~HOST_IRQ_EN; | ||
270 | writel(ctl, mmio + HOST_CTL); | ||
271 | readl(mmio + HOST_CTL); /* flush */ | ||
272 | |||
273 | rc = ata_host_suspend(host, PMSG_SUSPEND); | ||
274 | if (rc) | ||
275 | return rc; | ||
276 | |||
277 | if (pdata && pdata->suspend) | ||
278 | return pdata->suspend(dev); | ||
279 | |||
280 | if (!IS_ERR(hpriv->clk)) | ||
281 | clk_disable_unprepare(hpriv->clk); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int ahci_resume(struct device *dev) | ||
287 | { | ||
288 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | ||
289 | struct ata_host *host = dev_get_drvdata(dev); | ||
290 | struct ahci_host_priv *hpriv = host->private_data; | ||
291 | int rc; | ||
292 | |||
293 | if (!IS_ERR(hpriv->clk)) { | ||
294 | rc = clk_prepare_enable(hpriv->clk); | ||
295 | if (rc) { | ||
296 | dev_err(dev, "clock prepare enable failed"); | ||
297 | return rc; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | if (pdata && pdata->resume) { | ||
302 | rc = pdata->resume(dev); | ||
303 | if (rc) | ||
304 | goto disable_unprepare_clk; | ||
305 | } | ||
306 | |||
307 | if (dev->power.power_state.event == PM_EVENT_SUSPEND) { | ||
308 | rc = ahci_reset_controller(host); | ||
309 | if (rc) | ||
310 | goto disable_unprepare_clk; | ||
311 | |||
312 | ahci_init_controller(host); | ||
313 | } | ||
314 | |||
315 | ata_host_resume(host); | ||
316 | |||
317 | return 0; | ||
318 | |||
319 | disable_unprepare_clk: | ||
320 | if (!IS_ERR(hpriv->clk)) | ||
321 | clk_disable_unprepare(hpriv->clk); | ||
322 | |||
323 | return rc; | 68 | return rc; |
324 | } | 69 | } |
325 | #endif | ||
326 | 70 | ||
327 | static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); | 71 | static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, |
72 | ahci_platform_resume); | ||
328 | 73 | ||
329 | static const struct of_device_id ahci_of_match[] = { | 74 | static const struct of_device_id ahci_of_match[] = { |
330 | { .compatible = "snps,spear-ahci", }, | 75 | { .compatible = "snps,spear-ahci", }, |
331 | { .compatible = "snps,exynos5440-ahci", }, | 76 | { .compatible = "snps,exynos5440-ahci", }, |
332 | { .compatible = "ibm,476gtr-ahci", }, | 77 | { .compatible = "ibm,476gtr-ahci", }, |
78 | { .compatible = "snps,dwc-ahci", }, | ||
333 | {}, | 79 | {}, |
334 | }; | 80 | }; |
335 | MODULE_DEVICE_TABLE(of, ahci_of_match); | 81 | MODULE_DEVICE_TABLE(of, ahci_of_match); |
@@ -343,7 +89,6 @@ static struct platform_driver ahci_driver = { | |||
343 | .of_match_table = ahci_of_match, | 89 | .of_match_table = ahci_of_match, |
344 | .pm = &ahci_pm_ops, | 90 | .pm = &ahci_pm_ops, |
345 | }, | 91 | }, |
346 | .id_table = ahci_devtype, | ||
347 | }; | 92 | }; |
348 | module_platform_driver(ahci_driver); | 93 | module_platform_driver(ahci_driver); |
349 | 94 | ||
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c new file mode 100644 index 000000000000..633222226c19 --- /dev/null +++ b/drivers/ata/ahci_st.c | |||
@@ -0,0 +1,245 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 STMicroelectronics Limited | ||
3 | * | ||
4 | * Authors: Francesco Virlinzi <francesco.virlinzi@st.com> | ||
5 | * Alexandre Torgue <alexandre.torgue@st.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/clk.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/ahci_platform.h> | ||
19 | #include <linux/libata.h> | ||
20 | #include <linux/reset.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/dma-mapping.h> | ||
23 | |||
24 | #include "ahci.h" | ||
25 | |||
26 | #define ST_AHCI_OOBR 0xbc | ||
27 | #define ST_AHCI_OOBR_WE BIT(31) | ||
28 | #define ST_AHCI_OOBR_CWMIN_SHIFT 24 | ||
29 | #define ST_AHCI_OOBR_CWMAX_SHIFT 16 | ||
30 | #define ST_AHCI_OOBR_CIMIN_SHIFT 8 | ||
31 | #define ST_AHCI_OOBR_CIMAX_SHIFT 0 | ||
32 | |||
33 | struct st_ahci_drv_data { | ||
34 | struct platform_device *ahci; | ||
35 | struct reset_control *pwr; | ||
36 | struct reset_control *sw_rst; | ||
37 | struct reset_control *pwr_rst; | ||
38 | struct ahci_host_priv *hpriv; | ||
39 | }; | ||
40 | |||
41 | static void st_ahci_configure_oob(void __iomem *mmio) | ||
42 | { | ||
43 | unsigned long old_val, new_val; | ||
44 | |||
45 | new_val = (0x02 << ST_AHCI_OOBR_CWMIN_SHIFT) | | ||
46 | (0x04 << ST_AHCI_OOBR_CWMAX_SHIFT) | | ||
47 | (0x08 << ST_AHCI_OOBR_CIMIN_SHIFT) | | ||
48 | (0x0C << ST_AHCI_OOBR_CIMAX_SHIFT); | ||
49 | |||
50 | old_val = readl(mmio + ST_AHCI_OOBR); | ||
51 | writel(old_val | ST_AHCI_OOBR_WE, mmio + ST_AHCI_OOBR); | ||
52 | writel(new_val | ST_AHCI_OOBR_WE, mmio + ST_AHCI_OOBR); | ||
53 | writel(new_val, mmio + ST_AHCI_OOBR); | ||
54 | } | ||
55 | |||
56 | static int st_ahci_deassert_resets(struct device *dev) | ||
57 | { | ||
58 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | ||
59 | int err; | ||
60 | |||
61 | if (drv_data->pwr) { | ||
62 | err = reset_control_deassert(drv_data->pwr); | ||
63 | if (err) { | ||
64 | dev_err(dev, "unable to bring out of pwrdwn\n"); | ||
65 | return err; | ||
66 | } | ||
67 | } | ||
68 | |||
69 | st_ahci_configure_oob(drv_data->hpriv->mmio); | ||
70 | |||
71 | if (drv_data->sw_rst) { | ||
72 | err = reset_control_deassert(drv_data->sw_rst); | ||
73 | if (err) { | ||
74 | dev_err(dev, "unable to bring out of sw-rst\n"); | ||
75 | return err; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | if (drv_data->pwr_rst) { | ||
80 | err = reset_control_deassert(drv_data->pwr_rst); | ||
81 | if (err) { | ||
82 | dev_err(dev, "unable to bring out of pwr-rst\n"); | ||
83 | return err; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static void st_ahci_host_stop(struct ata_host *host) | ||
91 | { | ||
92 | struct ahci_host_priv *hpriv = host->private_data; | ||
93 | struct device *dev = host->dev; | ||
94 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | ||
95 | int err; | ||
96 | |||
97 | if (drv_data->pwr) { | ||
98 | err = reset_control_assert(drv_data->pwr); | ||
99 | if (err) | ||
100 | dev_err(dev, "unable to pwrdwn\n"); | ||
101 | } | ||
102 | |||
103 | ahci_platform_disable_resources(hpriv); | ||
104 | } | ||
105 | |||
106 | static int st_ahci_probe_resets(struct platform_device *pdev) | ||
107 | { | ||
108 | struct st_ahci_drv_data *drv_data = platform_get_drvdata(pdev); | ||
109 | |||
110 | drv_data->pwr = devm_reset_control_get(&pdev->dev, "pwr-dwn"); | ||
111 | if (IS_ERR(drv_data->pwr)) { | ||
112 | dev_info(&pdev->dev, "power reset control not defined\n"); | ||
113 | drv_data->pwr = NULL; | ||
114 | } | ||
115 | |||
116 | drv_data->sw_rst = devm_reset_control_get(&pdev->dev, "sw-rst"); | ||
117 | if (IS_ERR(drv_data->sw_rst)) { | ||
118 | dev_info(&pdev->dev, "soft reset control not defined\n"); | ||
119 | drv_data->sw_rst = NULL; | ||
120 | } | ||
121 | |||
122 | drv_data->pwr_rst = devm_reset_control_get(&pdev->dev, "pwr-rst"); | ||
123 | if (IS_ERR(drv_data->pwr_rst)) { | ||
124 | dev_dbg(&pdev->dev, "power soft reset control not defined\n"); | ||
125 | drv_data->pwr_rst = NULL; | ||
126 | } | ||
127 | |||
128 | return st_ahci_deassert_resets(&pdev->dev); | ||
129 | } | ||
130 | |||
131 | static struct ata_port_operations st_ahci_port_ops = { | ||
132 | .inherits = &ahci_platform_ops, | ||
133 | .host_stop = st_ahci_host_stop, | ||
134 | }; | ||
135 | |||
136 | static const struct ata_port_info st_ahci_port_info = { | ||
137 | .flags = AHCI_FLAG_COMMON, | ||
138 | .pio_mask = ATA_PIO4, | ||
139 | .udma_mask = ATA_UDMA6, | ||
140 | .port_ops = &st_ahci_port_ops, | ||
141 | }; | ||
142 | |||
143 | static int st_ahci_probe(struct platform_device *pdev) | ||
144 | { | ||
145 | struct st_ahci_drv_data *drv_data; | ||
146 | struct ahci_host_priv *hpriv; | ||
147 | int err; | ||
148 | |||
149 | drv_data = devm_kzalloc(&pdev->dev, sizeof(*drv_data), GFP_KERNEL); | ||
150 | if (!drv_data) | ||
151 | return -ENOMEM; | ||
152 | |||
153 | platform_set_drvdata(pdev, drv_data); | ||
154 | |||
155 | hpriv = ahci_platform_get_resources(pdev); | ||
156 | if (IS_ERR(hpriv)) | ||
157 | return PTR_ERR(hpriv); | ||
158 | |||
159 | drv_data->hpriv = hpriv; | ||
160 | |||
161 | err = st_ahci_probe_resets(pdev); | ||
162 | if (err) | ||
163 | return err; | ||
164 | |||
165 | err = ahci_platform_enable_resources(hpriv); | ||
166 | if (err) | ||
167 | return err; | ||
168 | |||
169 | err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, 0, 0); | ||
170 | if (err) { | ||
171 | ahci_platform_disable_resources(hpriv); | ||
172 | return err; | ||
173 | } | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | #ifdef CONFIG_PM_SLEEP | ||
179 | static int st_ahci_suspend(struct device *dev) | ||
180 | { | ||
181 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | ||
182 | struct ahci_host_priv *hpriv = drv_data->hpriv; | ||
183 | int err; | ||
184 | |||
185 | err = ahci_platform_suspend_host(dev); | ||
186 | if (err) | ||
187 | return err; | ||
188 | |||
189 | if (drv_data->pwr) { | ||
190 | err = reset_control_assert(drv_data->pwr); | ||
191 | if (err) { | ||
192 | dev_err(dev, "unable to pwrdwn"); | ||
193 | return err; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | ahci_platform_disable_resources(hpriv); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int st_ahci_resume(struct device *dev) | ||
203 | { | ||
204 | struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); | ||
205 | struct ahci_host_priv *hpriv = drv_data->hpriv; | ||
206 | int err; | ||
207 | |||
208 | err = ahci_platform_enable_resources(hpriv); | ||
209 | if (err) | ||
210 | return err; | ||
211 | |||
212 | err = st_ahci_deassert_resets(dev); | ||
213 | if (err) { | ||
214 | ahci_platform_disable_resources(hpriv); | ||
215 | return err; | ||
216 | } | ||
217 | |||
218 | return ahci_platform_resume_host(dev); | ||
219 | } | ||
220 | #endif | ||
221 | |||
222 | static SIMPLE_DEV_PM_OPS(st_ahci_pm_ops, st_ahci_suspend, st_ahci_resume); | ||
223 | |||
224 | static struct of_device_id st_ahci_match[] = { | ||
225 | { .compatible = "st,ahci", }, | ||
226 | {}, | ||
227 | }; | ||
228 | MODULE_DEVICE_TABLE(of, st_ahci_match); | ||
229 | |||
230 | static struct platform_driver st_ahci_driver = { | ||
231 | .driver = { | ||
232 | .name = "st_ahci", | ||
233 | .owner = THIS_MODULE, | ||
234 | .pm = &st_ahci_pm_ops, | ||
235 | .of_match_table = of_match_ptr(st_ahci_match), | ||
236 | }, | ||
237 | .probe = st_ahci_probe, | ||
238 | .remove = ata_platform_remove_one, | ||
239 | }; | ||
240 | module_platform_driver(st_ahci_driver); | ||
241 | |||
242 | MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>"); | ||
243 | MODULE_AUTHOR("Francesco Virlinzi <francesco.virlinzi@st.com>"); | ||
244 | MODULE_DESCRIPTION("STMicroelectronics SATA AHCI Driver"); | ||
245 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c new file mode 100644 index 000000000000..42d3f64e74b3 --- /dev/null +++ b/drivers/ata/ahci_sunxi.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* | ||
2 | * Allwinner sunxi AHCI SATA platform driver | ||
3 | * Copyright 2013 Olliver Schinagl <oliver@schinagl.nl> | ||
4 | * Copyright 2014 Hans de Goede <hdegoede@redhat.com> | ||
5 | * | ||
6 | * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov | ||
7 | * Based on code from Allwinner Technology Co., Ltd. <www.allwinnertech.com>, | ||
8 | * Daniel Wang <danielwang@allwinnertech.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms and conditions of the GNU General Public License, | ||
12 | * version 2, as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/ahci_platform.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/of_device.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/regulator/consumer.h> | ||
28 | #include "ahci.h" | ||
29 | |||
30 | #define AHCI_BISTAFR 0x00a0 | ||
31 | #define AHCI_BISTCR 0x00a4 | ||
32 | #define AHCI_BISTFCTR 0x00a8 | ||
33 | #define AHCI_BISTSR 0x00ac | ||
34 | #define AHCI_BISTDECR 0x00b0 | ||
35 | #define AHCI_DIAGNR0 0x00b4 | ||
36 | #define AHCI_DIAGNR1 0x00b8 | ||
37 | #define AHCI_OOBR 0x00bc | ||
38 | #define AHCI_PHYCS0R 0x00c0 | ||
39 | #define AHCI_PHYCS1R 0x00c4 | ||
40 | #define AHCI_PHYCS2R 0x00c8 | ||
41 | #define AHCI_TIMER1MS 0x00e0 | ||
42 | #define AHCI_GPARAM1R 0x00e8 | ||
43 | #define AHCI_GPARAM2R 0x00ec | ||
44 | #define AHCI_PPARAMR 0x00f0 | ||
45 | #define AHCI_TESTR 0x00f4 | ||
46 | #define AHCI_VERSIONR 0x00f8 | ||
47 | #define AHCI_IDR 0x00fc | ||
48 | #define AHCI_RWCR 0x00fc | ||
49 | #define AHCI_P0DMACR 0x0170 | ||
50 | #define AHCI_P0PHYCR 0x0178 | ||
51 | #define AHCI_P0PHYSR 0x017c | ||
52 | |||
53 | static void sunxi_clrbits(void __iomem *reg, u32 clr_val) | ||
54 | { | ||
55 | u32 reg_val; | ||
56 | |||
57 | reg_val = readl(reg); | ||
58 | reg_val &= ~(clr_val); | ||
59 | writel(reg_val, reg); | ||
60 | } | ||
61 | |||
62 | static void sunxi_setbits(void __iomem *reg, u32 set_val) | ||
63 | { | ||
64 | u32 reg_val; | ||
65 | |||
66 | reg_val = readl(reg); | ||
67 | reg_val |= set_val; | ||
68 | writel(reg_val, reg); | ||
69 | } | ||
70 | |||
71 | static void sunxi_clrsetbits(void __iomem *reg, u32 clr_val, u32 set_val) | ||
72 | { | ||
73 | u32 reg_val; | ||
74 | |||
75 | reg_val = readl(reg); | ||
76 | reg_val &= ~(clr_val); | ||
77 | reg_val |= set_val; | ||
78 | writel(reg_val, reg); | ||
79 | } | ||
80 | |||
81 | static u32 sunxi_getbits(void __iomem *reg, u8 mask, u8 shift) | ||
82 | { | ||
83 | return (readl(reg) >> shift) & mask; | ||
84 | } | ||
85 | |||
86 | static int ahci_sunxi_phy_init(struct device *dev, void __iomem *reg_base) | ||
87 | { | ||
88 | u32 reg_val; | ||
89 | int timeout; | ||
90 | |||
91 | /* This magic is from the original code */ | ||
92 | writel(0, reg_base + AHCI_RWCR); | ||
93 | msleep(5); | ||
94 | |||
95 | sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19)); | ||
96 | sunxi_clrsetbits(reg_base + AHCI_PHYCS0R, | ||
97 | (0x7 << 24), | ||
98 | (0x5 << 24) | BIT(23) | BIT(18)); | ||
99 | sunxi_clrsetbits(reg_base + AHCI_PHYCS1R, | ||
100 | (0x3 << 16) | (0x1f << 8) | (0x3 << 6), | ||
101 | (0x2 << 16) | (0x6 << 8) | (0x2 << 6)); | ||
102 | sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15)); | ||
103 | sunxi_clrbits(reg_base + AHCI_PHYCS1R, BIT(19)); | ||
104 | sunxi_clrsetbits(reg_base + AHCI_PHYCS0R, | ||
105 | (0x7 << 20), (0x3 << 20)); | ||
106 | sunxi_clrsetbits(reg_base + AHCI_PHYCS2R, | ||
107 | (0x1f << 5), (0x19 << 5)); | ||
108 | msleep(5); | ||
109 | |||
110 | sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19)); | ||
111 | |||
112 | timeout = 250; /* Power up takes aprox 50 us */ | ||
113 | do { | ||
114 | reg_val = sunxi_getbits(reg_base + AHCI_PHYCS0R, 0x7, 28); | ||
115 | if (reg_val == 0x02) | ||
116 | break; | ||
117 | |||
118 | if (--timeout == 0) { | ||
119 | dev_err(dev, "PHY power up failed.\n"); | ||
120 | return -EIO; | ||
121 | } | ||
122 | udelay(1); | ||
123 | } while (1); | ||
124 | |||
125 | sunxi_setbits(reg_base + AHCI_PHYCS2R, (0x1 << 24)); | ||
126 | |||
127 | timeout = 100; /* Calibration takes aprox 10 us */ | ||
128 | do { | ||
129 | reg_val = sunxi_getbits(reg_base + AHCI_PHYCS2R, 0x1, 24); | ||
130 | if (reg_val == 0x00) | ||
131 | break; | ||
132 | |||
133 | if (--timeout == 0) { | ||
134 | dev_err(dev, "PHY calibration failed.\n"); | ||
135 | return -EIO; | ||
136 | } | ||
137 | udelay(1); | ||
138 | } while (1); | ||
139 | |||
140 | msleep(15); | ||
141 | |||
142 | writel(0x7, reg_base + AHCI_RWCR); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static void ahci_sunxi_start_engine(struct ata_port *ap) | ||
148 | { | ||
149 | void __iomem *port_mmio = ahci_port_base(ap); | ||
150 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
151 | |||
152 | /* Setup DMA before DMA start */ | ||
153 | sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400); | ||
154 | |||
155 | /* Start DMA */ | ||
156 | sunxi_setbits(port_mmio + PORT_CMD, PORT_CMD_START); | ||
157 | } | ||
158 | |||
159 | static const struct ata_port_info ahci_sunxi_port_info = { | ||
160 | AHCI_HFLAGS(AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | | ||
161 | AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ), | ||
162 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, | ||
163 | .pio_mask = ATA_PIO4, | ||
164 | .udma_mask = ATA_UDMA6, | ||
165 | .port_ops = &ahci_platform_ops, | ||
166 | }; | ||
167 | |||
168 | static int ahci_sunxi_probe(struct platform_device *pdev) | ||
169 | { | ||
170 | struct device *dev = &pdev->dev; | ||
171 | struct ahci_host_priv *hpriv; | ||
172 | int rc; | ||
173 | |||
174 | hpriv = ahci_platform_get_resources(pdev); | ||
175 | if (IS_ERR(hpriv)) | ||
176 | return PTR_ERR(hpriv); | ||
177 | |||
178 | hpriv->start_engine = ahci_sunxi_start_engine; | ||
179 | |||
180 | rc = ahci_platform_enable_resources(hpriv); | ||
181 | if (rc) | ||
182 | return rc; | ||
183 | |||
184 | rc = ahci_sunxi_phy_init(dev, hpriv->mmio); | ||
185 | if (rc) | ||
186 | goto disable_resources; | ||
187 | |||
188 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info, 0, 0); | ||
189 | if (rc) | ||
190 | goto disable_resources; | ||
191 | |||
192 | return 0; | ||
193 | |||
194 | disable_resources: | ||
195 | ahci_platform_disable_resources(hpriv); | ||
196 | return rc; | ||
197 | } | ||
198 | |||
199 | #ifdef CONFIG_PM_SLEEP | ||
200 | static int ahci_sunxi_resume(struct device *dev) | ||
201 | { | ||
202 | struct ata_host *host = dev_get_drvdata(dev); | ||
203 | struct ahci_host_priv *hpriv = host->private_data; | ||
204 | int rc; | ||
205 | |||
206 | rc = ahci_platform_enable_resources(hpriv); | ||
207 | if (rc) | ||
208 | return rc; | ||
209 | |||
210 | rc = ahci_sunxi_phy_init(dev, hpriv->mmio); | ||
211 | if (rc) | ||
212 | goto disable_resources; | ||
213 | |||
214 | rc = ahci_platform_resume_host(dev); | ||
215 | if (rc) | ||
216 | goto disable_resources; | ||
217 | |||
218 | return 0; | ||
219 | |||
220 | disable_resources: | ||
221 | ahci_platform_disable_resources(hpriv); | ||
222 | return rc; | ||
223 | } | ||
224 | #endif | ||
225 | |||
226 | static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend, | ||
227 | ahci_sunxi_resume); | ||
228 | |||
229 | static const struct of_device_id ahci_sunxi_of_match[] = { | ||
230 | { .compatible = "allwinner,sun4i-a10-ahci", }, | ||
231 | { }, | ||
232 | }; | ||
233 | MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match); | ||
234 | |||
235 | static struct platform_driver ahci_sunxi_driver = { | ||
236 | .probe = ahci_sunxi_probe, | ||
237 | .remove = ata_platform_remove_one, | ||
238 | .driver = { | ||
239 | .name = "ahci-sunxi", | ||
240 | .owner = THIS_MODULE, | ||
241 | .of_match_table = ahci_sunxi_of_match, | ||
242 | .pm = &ahci_sunxi_pm_ops, | ||
243 | }, | ||
244 | }; | ||
245 | module_platform_driver(ahci_sunxi_driver); | ||
246 | |||
247 | MODULE_DESCRIPTION("Allwinner sunxi AHCI SATA driver"); | ||
248 | MODULE_AUTHOR("Olliver Schinagl <oliver@schinagl.nl>"); | ||
249 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c new file mode 100644 index 000000000000..77c89bf171f1 --- /dev/null +++ b/drivers/ata/ahci_xgene.c | |||
@@ -0,0 +1,486 @@ | |||
1 | /* | ||
2 | * AppliedMicro X-Gene SoC SATA Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) 2014, Applied Micro Circuits Corporation | ||
5 | * Author: Loc Ho <lho@apm.com> | ||
6 | * Tuan Phan <tphan@apm.com> | ||
7 | * Suman Tripathi <stripathi@apm.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | * | ||
22 | * NOTE: PM support is not currently available. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/ahci_platform.h> | ||
28 | #include <linux/of_address.h> | ||
29 | #include <linux/of_irq.h> | ||
30 | #include <linux/phy/phy.h> | ||
31 | #include "ahci.h" | ||
32 | |||
33 | /* Max # of disk per a controller */ | ||
34 | #define MAX_AHCI_CHN_PERCTR 2 | ||
35 | |||
36 | /* MUX CSR */ | ||
37 | #define SATA_ENET_CONFIG_REG 0x00000000 | ||
38 | #define CFG_SATA_ENET_SELECT_MASK 0x00000001 | ||
39 | |||
40 | /* SATA core host controller CSR */ | ||
41 | #define SLVRDERRATTRIBUTES 0x00000000 | ||
42 | #define SLVWRERRATTRIBUTES 0x00000004 | ||
43 | #define MSTRDERRATTRIBUTES 0x00000008 | ||
44 | #define MSTWRERRATTRIBUTES 0x0000000c | ||
45 | #define BUSCTLREG 0x00000014 | ||
46 | #define IOFMSTRWAUX 0x00000018 | ||
47 | #define INTSTATUSMASK 0x0000002c | ||
48 | #define ERRINTSTATUS 0x00000030 | ||
49 | #define ERRINTSTATUSMASK 0x00000034 | ||
50 | |||
51 | /* SATA host AHCI CSR */ | ||
52 | #define PORTCFG 0x000000a4 | ||
53 | #define PORTADDR_SET(dst, src) \ | ||
54 | (((dst) & ~0x0000003f) | (((u32)(src)) & 0x0000003f)) | ||
55 | #define PORTPHY1CFG 0x000000a8 | ||
56 | #define PORTPHY1CFG_FRCPHYRDY_SET(dst, src) \ | ||
57 | (((dst) & ~0x00100000) | (((u32)(src) << 0x14) & 0x00100000)) | ||
58 | #define PORTPHY2CFG 0x000000ac | ||
59 | #define PORTPHY3CFG 0x000000b0 | ||
60 | #define PORTPHY4CFG 0x000000b4 | ||
61 | #define PORTPHY5CFG 0x000000b8 | ||
62 | #define SCTL0 0x0000012C | ||
63 | #define PORTPHY5CFG_RTCHG_SET(dst, src) \ | ||
64 | (((dst) & ~0xfff00000) | (((u32)(src) << 0x14) & 0xfff00000)) | ||
65 | #define PORTAXICFG_EN_CONTEXT_SET(dst, src) \ | ||
66 | (((dst) & ~0x01000000) | (((u32)(src) << 0x18) & 0x01000000)) | ||
67 | #define PORTAXICFG 0x000000bc | ||
68 | #define PORTAXICFG_OUTTRANS_SET(dst, src) \ | ||
69 | (((dst) & ~0x00f00000) | (((u32)(src) << 0x14) & 0x00f00000)) | ||
70 | |||
71 | /* SATA host controller AXI CSR */ | ||
72 | #define INT_SLV_TMOMASK 0x00000010 | ||
73 | |||
74 | /* SATA diagnostic CSR */ | ||
75 | #define CFG_MEM_RAM_SHUTDOWN 0x00000070 | ||
76 | #define BLOCK_MEM_RDY 0x00000074 | ||
77 | |||
78 | struct xgene_ahci_context { | ||
79 | struct ahci_host_priv *hpriv; | ||
80 | struct device *dev; | ||
81 | void __iomem *csr_core; /* Core CSR address of IP */ | ||
82 | void __iomem *csr_diag; /* Diag CSR address of IP */ | ||
83 | void __iomem *csr_axi; /* AXI CSR address of IP */ | ||
84 | void __iomem *csr_mux; /* MUX CSR address of IP */ | ||
85 | }; | ||
86 | |||
87 | static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx) | ||
88 | { | ||
89 | dev_dbg(ctx->dev, "Release memory from shutdown\n"); | ||
90 | writel(0x0, ctx->csr_diag + CFG_MEM_RAM_SHUTDOWN); | ||
91 | readl(ctx->csr_diag + CFG_MEM_RAM_SHUTDOWN); /* Force a barrier */ | ||
92 | msleep(1); /* reset may take up to 1ms */ | ||
93 | if (readl(ctx->csr_diag + BLOCK_MEM_RDY) != 0xFFFFFFFF) { | ||
94 | dev_err(ctx->dev, "failed to release memory from shutdown\n"); | ||
95 | return -ENODEV; | ||
96 | } | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * xgene_ahci_read_id - Read ID data from the specified device | ||
102 | * @dev: device | ||
103 | * @tf: proposed taskfile | ||
104 | * @id: data buffer | ||
105 | * | ||
106 | * This custom read ID function is required due to the fact that the HW | ||
107 | * does not support DEVSLP and the controller state machine may get stuck | ||
108 | * after processing the ID query command. | ||
109 | */ | ||
110 | static unsigned int xgene_ahci_read_id(struct ata_device *dev, | ||
111 | struct ata_taskfile *tf, u16 *id) | ||
112 | { | ||
113 | u32 err_mask; | ||
114 | void __iomem *port_mmio = ahci_port_base(dev->link->ap); | ||
115 | |||
116 | err_mask = ata_do_dev_read_id(dev, tf, id); | ||
117 | if (err_mask) | ||
118 | return err_mask; | ||
119 | |||
120 | /* | ||
121 | * Mask reserved area. Word78 spec of Link Power Management | ||
122 | * bit15-8: reserved | ||
123 | * bit7: NCQ autosence | ||
124 | * bit6: Software settings preservation supported | ||
125 | * bit5: reserved | ||
126 | * bit4: In-order sata delivery supported | ||
127 | * bit3: DIPM requests supported | ||
128 | * bit2: DMA Setup FIS Auto-Activate optimization supported | ||
129 | * bit1: DMA Setup FIX non-Zero buffer offsets supported | ||
130 | * bit0: Reserved | ||
131 | * | ||
132 | * Clear reserved bit 8 (DEVSLP bit) as we don't support DEVSLP | ||
133 | */ | ||
134 | id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); | ||
135 | |||
136 | /* | ||
137 | * Due to HW errata, restart the port if no other command active. | ||
138 | * Otherwise the controller may get stuck. | ||
139 | */ | ||
140 | if (!readl(port_mmio + PORT_CMD_ISSUE)) { | ||
141 | writel(PORT_CMD_FIS_RX, port_mmio + PORT_CMD); | ||
142 | readl(port_mmio + PORT_CMD); /* Force a barrier */ | ||
143 | writel(PORT_CMD_FIS_RX | PORT_CMD_START, port_mmio + PORT_CMD); | ||
144 | readl(port_mmio + PORT_CMD); /* Force a barrier */ | ||
145 | } | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel) | ||
150 | { | ||
151 | void __iomem *mmio = ctx->hpriv->mmio; | ||
152 | u32 val; | ||
153 | |||
154 | dev_dbg(ctx->dev, "port configure mmio 0x%p channel %d\n", | ||
155 | mmio, channel); | ||
156 | val = readl(mmio + PORTCFG); | ||
157 | val = PORTADDR_SET(val, channel == 0 ? 2 : 3); | ||
158 | writel(val, mmio + PORTCFG); | ||
159 | readl(mmio + PORTCFG); /* Force a barrier */ | ||
160 | /* Disable fix rate */ | ||
161 | writel(0x0001fffe, mmio + PORTPHY1CFG); | ||
162 | readl(mmio + PORTPHY1CFG); /* Force a barrier */ | ||
163 | writel(0x5018461c, mmio + PORTPHY2CFG); | ||
164 | readl(mmio + PORTPHY2CFG); /* Force a barrier */ | ||
165 | writel(0x1c081907, mmio + PORTPHY3CFG); | ||
166 | readl(mmio + PORTPHY3CFG); /* Force a barrier */ | ||
167 | writel(0x1c080815, mmio + PORTPHY4CFG); | ||
168 | readl(mmio + PORTPHY4CFG); /* Force a barrier */ | ||
169 | /* Set window negotiation */ | ||
170 | val = readl(mmio + PORTPHY5CFG); | ||
171 | val = PORTPHY5CFG_RTCHG_SET(val, 0x300); | ||
172 | writel(val, mmio + PORTPHY5CFG); | ||
173 | readl(mmio + PORTPHY5CFG); /* Force a barrier */ | ||
174 | val = readl(mmio + PORTAXICFG); | ||
175 | val = PORTAXICFG_EN_CONTEXT_SET(val, 0x1); /* Enable context mgmt */ | ||
176 | val = PORTAXICFG_OUTTRANS_SET(val, 0xe); /* Set outstanding */ | ||
177 | writel(val, mmio + PORTAXICFG); | ||
178 | readl(mmio + PORTAXICFG); /* Force a barrier */ | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * xgene_ahci_do_hardreset - Issue the actual COMRESET | ||
183 | * @link: link to reset | ||
184 | * @deadline: deadline jiffies for the operation | ||
185 | * @online: Return value to indicate if device online | ||
186 | * | ||
187 | * Due to the limitation of the hardware PHY, a difference set of setting is | ||
188 | * required for each supported disk speed - Gen3 (6.0Gbps), Gen2 (3.0Gbps), | ||
189 | * and Gen1 (1.5Gbps). Otherwise during long IO stress test, the PHY will | ||
190 | * report disparity error and etc. In addition, during COMRESET, there can | ||
191 | * be error reported in the register PORT_SCR_ERR. For SERR_DISPARITY and | ||
192 | * SERR_10B_8B_ERR, the PHY receiver line must be reseted. The following | ||
193 | * algorithm is followed to proper configure the hardware PHY during COMRESET: | ||
194 | * | ||
195 | * Alg Part 1: | ||
196 | * 1. Start the PHY at Gen3 speed (default setting) | ||
197 | * 2. Issue the COMRESET | ||
198 | * 3. If no link, go to Alg Part 3 | ||
199 | * 4. If link up, determine if the negotiated speed matches the PHY | ||
200 | * configured speed | ||
201 | * 5. If they matched, go to Alg Part 2 | ||
202 | * 6. If they do not matched and first time, configure the PHY for the linked | ||
203 | * up disk speed and repeat step 2 | ||
204 | * 7. Go to Alg Part 2 | ||
205 | * | ||
206 | * Alg Part 2: | ||
207 | * 1. On link up, if there are any SERR_DISPARITY and SERR_10B_8B_ERR error | ||
208 | * reported in the register PORT_SCR_ERR, then reset the PHY receiver line | ||
209 | * 2. Go to Alg Part 3 | ||
210 | * | ||
211 | * Alg Part 3: | ||
212 | * 1. Clear any pending from register PORT_SCR_ERR. | ||
213 | * | ||
214 | * NOTE: For the initial version, we will NOT support Gen1/Gen2. In addition | ||
215 | * and until the underlying PHY supports an method to reset the receiver | ||
216 | * line, on detection of SERR_DISPARITY or SERR_10B_8B_ERR errors, | ||
217 | * an warning message will be printed. | ||
218 | */ | ||
219 | static int xgene_ahci_do_hardreset(struct ata_link *link, | ||
220 | unsigned long deadline, bool *online) | ||
221 | { | ||
222 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | ||
223 | struct ata_port *ap = link->ap; | ||
224 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
225 | struct xgene_ahci_context *ctx = hpriv->plat_data; | ||
226 | struct ahci_port_priv *pp = ap->private_data; | ||
227 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | ||
228 | void __iomem *port_mmio = ahci_port_base(ap); | ||
229 | struct ata_taskfile tf; | ||
230 | int rc; | ||
231 | u32 val; | ||
232 | |||
233 | /* clear D2H reception area to properly wait for D2H FIS */ | ||
234 | ata_tf_init(link->device, &tf); | ||
235 | tf.command = ATA_BUSY; | ||
236 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | ||
237 | rc = sata_link_hardreset(link, timing, deadline, online, | ||
238 | ahci_check_ready); | ||
239 | |||
240 | val = readl(port_mmio + PORT_SCR_ERR); | ||
241 | if (val & (SERR_DISPARITY | SERR_10B_8B_ERR)) | ||
242 | dev_warn(ctx->dev, "link has error\n"); | ||
243 | |||
244 | /* clear all errors if any pending */ | ||
245 | val = readl(port_mmio + PORT_SCR_ERR); | ||
246 | writel(val, port_mmio + PORT_SCR_ERR); | ||
247 | |||
248 | return rc; | ||
249 | } | ||
250 | |||
251 | static int xgene_ahci_hardreset(struct ata_link *link, unsigned int *class, | ||
252 | unsigned long deadline) | ||
253 | { | ||
254 | struct ata_port *ap = link->ap; | ||
255 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
256 | void __iomem *port_mmio = ahci_port_base(ap); | ||
257 | bool online; | ||
258 | int rc; | ||
259 | u32 portcmd_saved; | ||
260 | u32 portclb_saved; | ||
261 | u32 portclbhi_saved; | ||
262 | u32 portrxfis_saved; | ||
263 | u32 portrxfishi_saved; | ||
264 | |||
265 | /* As hardreset resets these CSR, save it to restore later */ | ||
266 | portcmd_saved = readl(port_mmio + PORT_CMD); | ||
267 | portclb_saved = readl(port_mmio + PORT_LST_ADDR); | ||
268 | portclbhi_saved = readl(port_mmio + PORT_LST_ADDR_HI); | ||
269 | portrxfis_saved = readl(port_mmio + PORT_FIS_ADDR); | ||
270 | portrxfishi_saved = readl(port_mmio + PORT_FIS_ADDR_HI); | ||
271 | |||
272 | ahci_stop_engine(ap); | ||
273 | |||
274 | rc = xgene_ahci_do_hardreset(link, deadline, &online); | ||
275 | |||
276 | /* As controller hardreset clears them, restore them */ | ||
277 | writel(portcmd_saved, port_mmio + PORT_CMD); | ||
278 | writel(portclb_saved, port_mmio + PORT_LST_ADDR); | ||
279 | writel(portclbhi_saved, port_mmio + PORT_LST_ADDR_HI); | ||
280 | writel(portrxfis_saved, port_mmio + PORT_FIS_ADDR); | ||
281 | writel(portrxfishi_saved, port_mmio + PORT_FIS_ADDR_HI); | ||
282 | |||
283 | hpriv->start_engine(ap); | ||
284 | |||
285 | if (online) | ||
286 | *class = ahci_dev_classify(ap); | ||
287 | |||
288 | return rc; | ||
289 | } | ||
290 | |||
291 | static void xgene_ahci_host_stop(struct ata_host *host) | ||
292 | { | ||
293 | struct ahci_host_priv *hpriv = host->private_data; | ||
294 | |||
295 | ahci_platform_disable_resources(hpriv); | ||
296 | } | ||
297 | |||
298 | static struct ata_port_operations xgene_ahci_ops = { | ||
299 | .inherits = &ahci_ops, | ||
300 | .host_stop = xgene_ahci_host_stop, | ||
301 | .hardreset = xgene_ahci_hardreset, | ||
302 | .read_id = xgene_ahci_read_id, | ||
303 | }; | ||
304 | |||
305 | static const struct ata_port_info xgene_ahci_port_info = { | ||
306 | AHCI_HFLAGS(AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ), | ||
307 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, | ||
308 | .pio_mask = ATA_PIO4, | ||
309 | .udma_mask = ATA_UDMA6, | ||
310 | .port_ops = &xgene_ahci_ops, | ||
311 | }; | ||
312 | |||
313 | static int xgene_ahci_hw_init(struct ahci_host_priv *hpriv) | ||
314 | { | ||
315 | struct xgene_ahci_context *ctx = hpriv->plat_data; | ||
316 | int i; | ||
317 | int rc; | ||
318 | u32 val; | ||
319 | |||
320 | /* Remove IP RAM out of shutdown */ | ||
321 | rc = xgene_ahci_init_memram(ctx); | ||
322 | if (rc) | ||
323 | return rc; | ||
324 | |||
325 | for (i = 0; i < MAX_AHCI_CHN_PERCTR; i++) | ||
326 | xgene_ahci_set_phy_cfg(ctx, i); | ||
327 | |||
328 | /* AXI disable Mask */ | ||
329 | writel(0xffffffff, hpriv->mmio + HOST_IRQ_STAT); | ||
330 | readl(hpriv->mmio + HOST_IRQ_STAT); /* Force a barrier */ | ||
331 | writel(0, ctx->csr_core + INTSTATUSMASK); | ||
332 | val = readl(ctx->csr_core + INTSTATUSMASK); /* Force a barrier */ | ||
333 | dev_dbg(ctx->dev, "top level interrupt mask 0x%X value 0x%08X\n", | ||
334 | INTSTATUSMASK, val); | ||
335 | |||
336 | writel(0x0, ctx->csr_core + ERRINTSTATUSMASK); | ||
337 | readl(ctx->csr_core + ERRINTSTATUSMASK); /* Force a barrier */ | ||
338 | writel(0x0, ctx->csr_axi + INT_SLV_TMOMASK); | ||
339 | readl(ctx->csr_axi + INT_SLV_TMOMASK); | ||
340 | |||
341 | /* Enable AXI Interrupt */ | ||
342 | writel(0xffffffff, ctx->csr_core + SLVRDERRATTRIBUTES); | ||
343 | writel(0xffffffff, ctx->csr_core + SLVWRERRATTRIBUTES); | ||
344 | writel(0xffffffff, ctx->csr_core + MSTRDERRATTRIBUTES); | ||
345 | writel(0xffffffff, ctx->csr_core + MSTWRERRATTRIBUTES); | ||
346 | |||
347 | /* Enable coherency */ | ||
348 | val = readl(ctx->csr_core + BUSCTLREG); | ||
349 | val &= ~0x00000002; /* Enable write coherency */ | ||
350 | val &= ~0x00000001; /* Enable read coherency */ | ||
351 | writel(val, ctx->csr_core + BUSCTLREG); | ||
352 | |||
353 | val = readl(ctx->csr_core + IOFMSTRWAUX); | ||
354 | val |= (1 << 3); /* Enable read coherency */ | ||
355 | val |= (1 << 9); /* Enable write coherency */ | ||
356 | writel(val, ctx->csr_core + IOFMSTRWAUX); | ||
357 | val = readl(ctx->csr_core + IOFMSTRWAUX); | ||
358 | dev_dbg(ctx->dev, "coherency 0x%X value 0x%08X\n", | ||
359 | IOFMSTRWAUX, val); | ||
360 | |||
361 | return rc; | ||
362 | } | ||
363 | |||
364 | static int xgene_ahci_mux_select(struct xgene_ahci_context *ctx) | ||
365 | { | ||
366 | u32 val; | ||
367 | |||
368 | /* Check for optional MUX resource */ | ||
369 | if (IS_ERR(ctx->csr_mux)) | ||
370 | return 0; | ||
371 | |||
372 | val = readl(ctx->csr_mux + SATA_ENET_CONFIG_REG); | ||
373 | val &= ~CFG_SATA_ENET_SELECT_MASK; | ||
374 | writel(val, ctx->csr_mux + SATA_ENET_CONFIG_REG); | ||
375 | val = readl(ctx->csr_mux + SATA_ENET_CONFIG_REG); | ||
376 | return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0; | ||
377 | } | ||
378 | |||
379 | static int xgene_ahci_probe(struct platform_device *pdev) | ||
380 | { | ||
381 | struct device *dev = &pdev->dev; | ||
382 | struct ahci_host_priv *hpriv; | ||
383 | struct xgene_ahci_context *ctx; | ||
384 | struct resource *res; | ||
385 | int rc; | ||
386 | |||
387 | hpriv = ahci_platform_get_resources(pdev); | ||
388 | if (IS_ERR(hpriv)) | ||
389 | return PTR_ERR(hpriv); | ||
390 | |||
391 | ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); | ||
392 | if (!ctx) | ||
393 | return -ENOMEM; | ||
394 | |||
395 | hpriv->plat_data = ctx; | ||
396 | ctx->hpriv = hpriv; | ||
397 | ctx->dev = dev; | ||
398 | |||
399 | /* Retrieve the IP core resource */ | ||
400 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
401 | ctx->csr_core = devm_ioremap_resource(dev, res); | ||
402 | if (IS_ERR(ctx->csr_core)) | ||
403 | return PTR_ERR(ctx->csr_core); | ||
404 | |||
405 | /* Retrieve the IP diagnostic resource */ | ||
406 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
407 | ctx->csr_diag = devm_ioremap_resource(dev, res); | ||
408 | if (IS_ERR(ctx->csr_diag)) | ||
409 | return PTR_ERR(ctx->csr_diag); | ||
410 | |||
411 | /* Retrieve the IP AXI resource */ | ||
412 | res = platform_get_resource(pdev, IORESOURCE_MEM, 3); | ||
413 | ctx->csr_axi = devm_ioremap_resource(dev, res); | ||
414 | if (IS_ERR(ctx->csr_axi)) | ||
415 | return PTR_ERR(ctx->csr_axi); | ||
416 | |||
417 | /* Retrieve the optional IP mux resource */ | ||
418 | res = platform_get_resource(pdev, IORESOURCE_MEM, 4); | ||
419 | ctx->csr_mux = devm_ioremap_resource(dev, res); | ||
420 | |||
421 | dev_dbg(dev, "VAddr 0x%p Mmio VAddr 0x%p\n", ctx->csr_core, | ||
422 | hpriv->mmio); | ||
423 | |||
424 | /* Select ATA */ | ||
425 | if ((rc = xgene_ahci_mux_select(ctx))) { | ||
426 | dev_err(dev, "SATA mux selection failed error %d\n", rc); | ||
427 | return -ENODEV; | ||
428 | } | ||
429 | |||
430 | /* Due to errata, HW requires full toggle transition */ | ||
431 | rc = ahci_platform_enable_clks(hpriv); | ||
432 | if (rc) | ||
433 | goto disable_resources; | ||
434 | ahci_platform_disable_clks(hpriv); | ||
435 | |||
436 | rc = ahci_platform_enable_resources(hpriv); | ||
437 | if (rc) | ||
438 | goto disable_resources; | ||
439 | |||
440 | /* Configure the host controller */ | ||
441 | xgene_ahci_hw_init(hpriv); | ||
442 | |||
443 | /* | ||
444 | * Setup DMA mask. This is preliminary until the DMA range is sorted | ||
445 | * out. | ||
446 | */ | ||
447 | rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); | ||
448 | if (rc) { | ||
449 | dev_err(dev, "Unable to set dma mask\n"); | ||
450 | goto disable_resources; | ||
451 | } | ||
452 | |||
453 | rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info, 0, 0); | ||
454 | if (rc) | ||
455 | goto disable_resources; | ||
456 | |||
457 | dev_dbg(dev, "X-Gene SATA host controller initialized\n"); | ||
458 | return 0; | ||
459 | |||
460 | disable_resources: | ||
461 | ahci_platform_disable_resources(hpriv); | ||
462 | return rc; | ||
463 | } | ||
464 | |||
465 | static const struct of_device_id xgene_ahci_of_match[] = { | ||
466 | {.compatible = "apm,xgene-ahci"}, | ||
467 | {}, | ||
468 | }; | ||
469 | MODULE_DEVICE_TABLE(of, xgene_ahci_of_match); | ||
470 | |||
471 | static struct platform_driver xgene_ahci_driver = { | ||
472 | .probe = xgene_ahci_probe, | ||
473 | .remove = ata_platform_remove_one, | ||
474 | .driver = { | ||
475 | .name = "xgene-ahci", | ||
476 | .owner = THIS_MODULE, | ||
477 | .of_match_table = xgene_ahci_of_match, | ||
478 | }, | ||
479 | }; | ||
480 | |||
481 | module_platform_driver(xgene_ahci_driver); | ||
482 | |||
483 | MODULE_DESCRIPTION("APM X-Gene AHCI SATA driver"); | ||
484 | MODULE_AUTHOR("Loc Ho <lho@apm.com>"); | ||
485 | MODULE_LICENSE("GPL"); | ||
486 | MODULE_VERSION("0.4"); | ||
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 7d196656adb5..9498a7d3846f 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <scsi/scsi_host.h> | 24 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 36605abe5a67..6bd4f660b4e1 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/gfp.h> | 36 | #include <linux/gfp.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/init.h> | ||
39 | #include <linux/blkdev.h> | 38 | #include <linux/blkdev.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
@@ -394,6 +393,9 @@ static ssize_t ahci_show_em_supported(struct device *dev, | |||
394 | * | 393 | * |
395 | * If inconsistent, config values are fixed up by this function. | 394 | * If inconsistent, config values are fixed up by this function. |
396 | * | 395 | * |
396 | * If it is not set already this function sets hpriv->start_engine to | ||
397 | * ahci_start_engine. | ||
398 | * | ||
397 | * LOCKING: | 399 | * LOCKING: |
398 | * None. | 400 | * None. |
399 | */ | 401 | */ |
@@ -500,6 +502,9 @@ void ahci_save_initial_config(struct device *dev, | |||
500 | hpriv->cap = cap; | 502 | hpriv->cap = cap; |
501 | hpriv->cap2 = cap2; | 503 | hpriv->cap2 = cap2; |
502 | hpriv->port_map = port_map; | 504 | hpriv->port_map = port_map; |
505 | |||
506 | if (!hpriv->start_engine) | ||
507 | hpriv->start_engine = ahci_start_engine; | ||
503 | } | 508 | } |
504 | EXPORT_SYMBOL_GPL(ahci_save_initial_config); | 509 | EXPORT_SYMBOL_GPL(ahci_save_initial_config); |
505 | 510 | ||
@@ -766,7 +771,7 @@ static void ahci_start_port(struct ata_port *ap) | |||
766 | 771 | ||
767 | /* enable DMA */ | 772 | /* enable DMA */ |
768 | if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE)) | 773 | if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE)) |
769 | ahci_start_engine(ap); | 774 | hpriv->start_engine(ap); |
770 | 775 | ||
771 | /* turn on LEDs */ | 776 | /* turn on LEDs */ |
772 | if (ap->flags & ATA_FLAG_EM) { | 777 | if (ap->flags & ATA_FLAG_EM) { |
@@ -1032,12 +1037,13 @@ static ssize_t ahci_led_show(struct ata_port *ap, char *buf) | |||
1032 | static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, | 1037 | static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, |
1033 | size_t size) | 1038 | size_t size) |
1034 | { | 1039 | { |
1035 | int state; | 1040 | unsigned int state; |
1036 | int pmp; | 1041 | int pmp; |
1037 | struct ahci_port_priv *pp = ap->private_data; | 1042 | struct ahci_port_priv *pp = ap->private_data; |
1038 | struct ahci_em_priv *emp; | 1043 | struct ahci_em_priv *emp; |
1039 | 1044 | ||
1040 | state = simple_strtoul(buf, NULL, 0); | 1045 | if (kstrtouint(buf, 0, &state) < 0) |
1046 | return -EINVAL; | ||
1041 | 1047 | ||
1042 | /* get the slot number from the message */ | 1048 | /* get the slot number from the message */ |
1043 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; | 1049 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; |
@@ -1234,7 +1240,7 @@ int ahci_kick_engine(struct ata_port *ap) | |||
1234 | 1240 | ||
1235 | /* restart engine */ | 1241 | /* restart engine */ |
1236 | out_restart: | 1242 | out_restart: |
1237 | ahci_start_engine(ap); | 1243 | hpriv->start_engine(ap); |
1238 | return rc; | 1244 | return rc; |
1239 | } | 1245 | } |
1240 | EXPORT_SYMBOL_GPL(ahci_kick_engine); | 1246 | EXPORT_SYMBOL_GPL(ahci_kick_engine); |
@@ -1387,8 +1393,8 @@ static int ahci_bad_pmp_check_ready(struct ata_link *link) | |||
1387 | return ata_check_ready(status); | 1393 | return ata_check_ready(status); |
1388 | } | 1394 | } |
1389 | 1395 | ||
1390 | int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class, | 1396 | static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class, |
1391 | unsigned long deadline) | 1397 | unsigned long deadline) |
1392 | { | 1398 | { |
1393 | struct ata_port *ap = link->ap; | 1399 | struct ata_port *ap = link->ap; |
1394 | void __iomem *port_mmio = ahci_port_base(ap); | 1400 | void __iomem *port_mmio = ahci_port_base(ap); |
@@ -1426,6 +1432,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, | |||
1426 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | 1432 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); |
1427 | struct ata_port *ap = link->ap; | 1433 | struct ata_port *ap = link->ap; |
1428 | struct ahci_port_priv *pp = ap->private_data; | 1434 | struct ahci_port_priv *pp = ap->private_data; |
1435 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
1429 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 1436 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
1430 | struct ata_taskfile tf; | 1437 | struct ata_taskfile tf; |
1431 | bool online; | 1438 | bool online; |
@@ -1443,7 +1450,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, | |||
1443 | rc = sata_link_hardreset(link, timing, deadline, &online, | 1450 | rc = sata_link_hardreset(link, timing, deadline, &online, |
1444 | ahci_check_ready); | 1451 | ahci_check_ready); |
1445 | 1452 | ||
1446 | ahci_start_engine(ap); | 1453 | hpriv->start_engine(ap); |
1447 | 1454 | ||
1448 | if (online) | 1455 | if (online) |
1449 | *class = ahci_dev_classify(ap); | 1456 | *class = ahci_dev_classify(ap); |
@@ -1629,7 +1636,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
1629 | } | 1636 | } |
1630 | 1637 | ||
1631 | if (irq_stat & PORT_IRQ_UNK_FIS) { | 1638 | if (irq_stat & PORT_IRQ_UNK_FIS) { |
1632 | u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK); | 1639 | u32 *unk = pp->rx_fis + RX_FIS_UNK; |
1633 | 1640 | ||
1634 | active_ehi->err_mask |= AC_ERR_HSM; | 1641 | active_ehi->err_mask |= AC_ERR_HSM; |
1635 | active_ehi->action |= ATA_EH_RESET; | 1642 | active_ehi->action |= ATA_EH_RESET; |
@@ -2007,10 +2014,12 @@ static void ahci_thaw(struct ata_port *ap) | |||
2007 | 2014 | ||
2008 | void ahci_error_handler(struct ata_port *ap) | 2015 | void ahci_error_handler(struct ata_port *ap) |
2009 | { | 2016 | { |
2017 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
2018 | |||
2010 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { | 2019 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { |
2011 | /* restart engine */ | 2020 | /* restart engine */ |
2012 | ahci_stop_engine(ap); | 2021 | ahci_stop_engine(ap); |
2013 | ahci_start_engine(ap); | 2022 | hpriv->start_engine(ap); |
2014 | } | 2023 | } |
2015 | 2024 | ||
2016 | sata_pmp_error_handler(ap); | 2025 | sata_pmp_error_handler(ap); |
@@ -2031,6 +2040,7 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | |||
2031 | 2040 | ||
2032 | static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) | 2041 | static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) |
2033 | { | 2042 | { |
2043 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
2034 | void __iomem *port_mmio = ahci_port_base(ap); | 2044 | void __iomem *port_mmio = ahci_port_base(ap); |
2035 | struct ata_device *dev = ap->link.device; | 2045 | struct ata_device *dev = ap->link.device; |
2036 | u32 devslp, dm, dito, mdat, deto; | 2046 | u32 devslp, dm, dito, mdat, deto; |
@@ -2094,7 +2104,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) | |||
2094 | PORT_DEVSLP_ADSE); | 2104 | PORT_DEVSLP_ADSE); |
2095 | writel(devslp, port_mmio + PORT_DEVSLP); | 2105 | writel(devslp, port_mmio + PORT_DEVSLP); |
2096 | 2106 | ||
2097 | ahci_start_engine(ap); | 2107 | hpriv->start_engine(ap); |
2098 | 2108 | ||
2099 | /* enable device sleep feature for the drive */ | 2109 | /* enable device sleep feature for the drive */ |
2100 | err_mask = ata_dev_set_feature(dev, | 2110 | err_mask = ata_dev_set_feature(dev, |
@@ -2106,6 +2116,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) | |||
2106 | 2116 | ||
2107 | static void ahci_enable_fbs(struct ata_port *ap) | 2117 | static void ahci_enable_fbs(struct ata_port *ap) |
2108 | { | 2118 | { |
2119 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
2109 | struct ahci_port_priv *pp = ap->private_data; | 2120 | struct ahci_port_priv *pp = ap->private_data; |
2110 | void __iomem *port_mmio = ahci_port_base(ap); | 2121 | void __iomem *port_mmio = ahci_port_base(ap); |
2111 | u32 fbs; | 2122 | u32 fbs; |
@@ -2134,11 +2145,12 @@ static void ahci_enable_fbs(struct ata_port *ap) | |||
2134 | } else | 2145 | } else |
2135 | dev_err(ap->host->dev, "Failed to enable FBS\n"); | 2146 | dev_err(ap->host->dev, "Failed to enable FBS\n"); |
2136 | 2147 | ||
2137 | ahci_start_engine(ap); | 2148 | hpriv->start_engine(ap); |
2138 | } | 2149 | } |
2139 | 2150 | ||
2140 | static void ahci_disable_fbs(struct ata_port *ap) | 2151 | static void ahci_disable_fbs(struct ata_port *ap) |
2141 | { | 2152 | { |
2153 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
2142 | struct ahci_port_priv *pp = ap->private_data; | 2154 | struct ahci_port_priv *pp = ap->private_data; |
2143 | void __iomem *port_mmio = ahci_port_base(ap); | 2155 | void __iomem *port_mmio = ahci_port_base(ap); |
2144 | u32 fbs; | 2156 | u32 fbs; |
@@ -2166,7 +2178,7 @@ static void ahci_disable_fbs(struct ata_port *ap) | |||
2166 | pp->fbs_enabled = false; | 2178 | pp->fbs_enabled = false; |
2167 | } | 2179 | } |
2168 | 2180 | ||
2169 | ahci_start_engine(ap); | 2181 | hpriv->start_engine(ap); |
2170 | } | 2182 | } |
2171 | 2183 | ||
2172 | static void ahci_pmp_attach(struct ata_port *ap) | 2184 | static void ahci_pmp_attach(struct ata_port *ap) |
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c new file mode 100644 index 000000000000..7cb3a85719c0 --- /dev/null +++ b/drivers/ata/libahci_platform.c | |||
@@ -0,0 +1,541 @@ | |||
1 | /* | ||
2 | * AHCI SATA platform library | ||
3 | * | ||
4 | * Copyright 2004-2005 Red Hat, Inc. | ||
5 | * Jeff Garzik <jgarzik@pobox.com> | ||
6 | * Copyright 2010 MontaVista Software, LLC. | ||
7 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2, or (at your option) | ||
12 | * any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/gfp.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/pm.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/libata.h> | ||
24 | #include <linux/ahci_platform.h> | ||
25 | #include <linux/phy/phy.h> | ||
26 | #include <linux/pm_runtime.h> | ||
27 | #include "ahci.h" | ||
28 | |||
29 | static void ahci_host_stop(struct ata_host *host); | ||
30 | |||
31 | struct ata_port_operations ahci_platform_ops = { | ||
32 | .inherits = &ahci_ops, | ||
33 | .host_stop = ahci_host_stop, | ||
34 | }; | ||
35 | EXPORT_SYMBOL_GPL(ahci_platform_ops); | ||
36 | |||
37 | static struct scsi_host_template ahci_platform_sht = { | ||
38 | AHCI_SHT("ahci_platform"), | ||
39 | }; | ||
40 | |||
41 | /** | ||
42 | * ahci_platform_enable_clks - Enable platform clocks | ||
43 | * @hpriv: host private area to store config values | ||
44 | * | ||
45 | * This function enables all the clks found in hpriv->clks, starting at | ||
46 | * index 0. If any clk fails to enable it disables all the clks already | ||
47 | * enabled in reverse order, and then returns an error. | ||
48 | * | ||
49 | * RETURNS: | ||
50 | * 0 on success otherwise a negative error code | ||
51 | */ | ||
52 | int ahci_platform_enable_clks(struct ahci_host_priv *hpriv) | ||
53 | { | ||
54 | int c, rc; | ||
55 | |||
56 | for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) { | ||
57 | rc = clk_prepare_enable(hpriv->clks[c]); | ||
58 | if (rc) | ||
59 | goto disable_unprepare_clk; | ||
60 | } | ||
61 | return 0; | ||
62 | |||
63 | disable_unprepare_clk: | ||
64 | while (--c >= 0) | ||
65 | clk_disable_unprepare(hpriv->clks[c]); | ||
66 | return rc; | ||
67 | } | ||
68 | EXPORT_SYMBOL_GPL(ahci_platform_enable_clks); | ||
69 | |||
70 | /** | ||
71 | * ahci_platform_disable_clks - Disable platform clocks | ||
72 | * @hpriv: host private area to store config values | ||
73 | * | ||
74 | * This function disables all the clks found in hpriv->clks, in reverse | ||
75 | * order of ahci_platform_enable_clks (starting at the end of the array). | ||
76 | */ | ||
77 | void ahci_platform_disable_clks(struct ahci_host_priv *hpriv) | ||
78 | { | ||
79 | int c; | ||
80 | |||
81 | for (c = AHCI_MAX_CLKS - 1; c >= 0; c--) | ||
82 | if (hpriv->clks[c]) | ||
83 | clk_disable_unprepare(hpriv->clks[c]); | ||
84 | } | ||
85 | EXPORT_SYMBOL_GPL(ahci_platform_disable_clks); | ||
86 | |||
87 | /** | ||
88 | * ahci_platform_enable_resources - Enable platform resources | ||
89 | * @hpriv: host private area to store config values | ||
90 | * | ||
91 | * This function enables all ahci_platform managed resources in the | ||
92 | * following order: | ||
93 | * 1) Regulator | ||
94 | * 2) Clocks (through ahci_platform_enable_clks) | ||
95 | * 3) Phy | ||
96 | * | ||
97 | * If resource enabling fails at any point the previous enabled resources | ||
98 | * are disabled in reverse order. | ||
99 | * | ||
100 | * RETURNS: | ||
101 | * 0 on success otherwise a negative error code | ||
102 | */ | ||
103 | int ahci_platform_enable_resources(struct ahci_host_priv *hpriv) | ||
104 | { | ||
105 | int rc; | ||
106 | |||
107 | if (hpriv->target_pwr) { | ||
108 | rc = regulator_enable(hpriv->target_pwr); | ||
109 | if (rc) | ||
110 | return rc; | ||
111 | } | ||
112 | |||
113 | rc = ahci_platform_enable_clks(hpriv); | ||
114 | if (rc) | ||
115 | goto disable_regulator; | ||
116 | |||
117 | if (hpriv->phy) { | ||
118 | rc = phy_init(hpriv->phy); | ||
119 | if (rc) | ||
120 | goto disable_clks; | ||
121 | |||
122 | rc = phy_power_on(hpriv->phy); | ||
123 | if (rc) { | ||
124 | phy_exit(hpriv->phy); | ||
125 | goto disable_clks; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | return 0; | ||
130 | |||
131 | disable_clks: | ||
132 | ahci_platform_disable_clks(hpriv); | ||
133 | |||
134 | disable_regulator: | ||
135 | if (hpriv->target_pwr) | ||
136 | regulator_disable(hpriv->target_pwr); | ||
137 | return rc; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(ahci_platform_enable_resources); | ||
140 | |||
141 | /** | ||
142 | * ahci_platform_disable_resources - Disable platform resources | ||
143 | * @hpriv: host private area to store config values | ||
144 | * | ||
145 | * This function disables all ahci_platform managed resources in the | ||
146 | * following order: | ||
147 | * 1) Phy | ||
148 | * 2) Clocks (through ahci_platform_disable_clks) | ||
149 | * 3) Regulator | ||
150 | */ | ||
151 | void ahci_platform_disable_resources(struct ahci_host_priv *hpriv) | ||
152 | { | ||
153 | if (hpriv->phy) { | ||
154 | phy_power_off(hpriv->phy); | ||
155 | phy_exit(hpriv->phy); | ||
156 | } | ||
157 | |||
158 | ahci_platform_disable_clks(hpriv); | ||
159 | |||
160 | if (hpriv->target_pwr) | ||
161 | regulator_disable(hpriv->target_pwr); | ||
162 | } | ||
163 | EXPORT_SYMBOL_GPL(ahci_platform_disable_resources); | ||
164 | |||
165 | static void ahci_platform_put_resources(struct device *dev, void *res) | ||
166 | { | ||
167 | struct ahci_host_priv *hpriv = res; | ||
168 | int c; | ||
169 | |||
170 | if (hpriv->got_runtime_pm) { | ||
171 | pm_runtime_put_sync(dev); | ||
172 | pm_runtime_disable(dev); | ||
173 | } | ||
174 | |||
175 | for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) | ||
176 | clk_put(hpriv->clks[c]); | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * ahci_platform_get_resources - Get platform resources | ||
181 | * @pdev: platform device to get resources for | ||
182 | * | ||
183 | * This function allocates an ahci_host_priv struct, and gets the following | ||
184 | * resources, storing a reference to them inside the returned struct: | ||
185 | * | ||
186 | * 1) mmio registers (IORESOURCE_MEM 0, mandatory) | ||
187 | * 2) regulator for controlling the targets power (optional) | ||
188 | * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node, | ||
189 | * or for non devicetree enabled platforms a single clock | ||
190 | * 4) phy (optional) | ||
191 | * | ||
192 | * RETURNS: | ||
193 | * The allocated ahci_host_priv on success, otherwise an ERR_PTR value | ||
194 | */ | ||
195 | struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev) | ||
196 | { | ||
197 | struct device *dev = &pdev->dev; | ||
198 | struct ahci_host_priv *hpriv; | ||
199 | struct clk *clk; | ||
200 | int i, rc = -ENOMEM; | ||
201 | |||
202 | if (!devres_open_group(dev, NULL, GFP_KERNEL)) | ||
203 | return ERR_PTR(-ENOMEM); | ||
204 | |||
205 | hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv), | ||
206 | GFP_KERNEL); | ||
207 | if (!hpriv) | ||
208 | goto err_out; | ||
209 | |||
210 | devres_add(dev, hpriv); | ||
211 | |||
212 | hpriv->mmio = devm_ioremap_resource(dev, | ||
213 | platform_get_resource(pdev, IORESOURCE_MEM, 0)); | ||
214 | if (IS_ERR(hpriv->mmio)) { | ||
215 | dev_err(dev, "no mmio space\n"); | ||
216 | rc = PTR_ERR(hpriv->mmio); | ||
217 | goto err_out; | ||
218 | } | ||
219 | |||
220 | hpriv->target_pwr = devm_regulator_get_optional(dev, "target"); | ||
221 | if (IS_ERR(hpriv->target_pwr)) { | ||
222 | rc = PTR_ERR(hpriv->target_pwr); | ||
223 | if (rc == -EPROBE_DEFER) | ||
224 | goto err_out; | ||
225 | hpriv->target_pwr = NULL; | ||
226 | } | ||
227 | |||
228 | for (i = 0; i < AHCI_MAX_CLKS; i++) { | ||
229 | /* | ||
230 | * For now we must use clk_get(dev, NULL) for the first clock, | ||
231 | * because some platforms (da850, spear13xx) are not yet | ||
232 | * converted to use devicetree for clocks. For new platforms | ||
233 | * this is equivalent to of_clk_get(dev->of_node, 0). | ||
234 | */ | ||
235 | if (i == 0) | ||
236 | clk = clk_get(dev, NULL); | ||
237 | else | ||
238 | clk = of_clk_get(dev->of_node, i); | ||
239 | |||
240 | if (IS_ERR(clk)) { | ||
241 | rc = PTR_ERR(clk); | ||
242 | if (rc == -EPROBE_DEFER) | ||
243 | goto err_out; | ||
244 | break; | ||
245 | } | ||
246 | hpriv->clks[i] = clk; | ||
247 | } | ||
248 | |||
249 | hpriv->phy = devm_phy_get(dev, "sata-phy"); | ||
250 | if (IS_ERR(hpriv->phy)) { | ||
251 | rc = PTR_ERR(hpriv->phy); | ||
252 | switch (rc) { | ||
253 | case -ENODEV: | ||
254 | case -ENOSYS: | ||
255 | /* continue normally */ | ||
256 | hpriv->phy = NULL; | ||
257 | break; | ||
258 | |||
259 | case -EPROBE_DEFER: | ||
260 | goto err_out; | ||
261 | |||
262 | default: | ||
263 | dev_err(dev, "couldn't get sata-phy\n"); | ||
264 | goto err_out; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | pm_runtime_enable(dev); | ||
269 | pm_runtime_get_sync(dev); | ||
270 | hpriv->got_runtime_pm = true; | ||
271 | |||
272 | devres_remove_group(dev, NULL); | ||
273 | return hpriv; | ||
274 | |||
275 | err_out: | ||
276 | devres_release_group(dev, NULL); | ||
277 | return ERR_PTR(rc); | ||
278 | } | ||
279 | EXPORT_SYMBOL_GPL(ahci_platform_get_resources); | ||
280 | |||
281 | /** | ||
282 | * ahci_platform_init_host - Bring up an ahci-platform host | ||
283 | * @pdev: platform device pointer for the host | ||
284 | * @hpriv: ahci-host private data for the host | ||
285 | * @pi_template: template for the ata_port_info to use | ||
286 | * @force_port_map: param passed to ahci_save_initial_config | ||
287 | * @mask_port_map: param passed to ahci_save_initial_config | ||
288 | * | ||
289 | * This function does all the usual steps needed to bring up an | ||
290 | * ahci-platform host, note any necessary resources (ie clks, phy, etc.) | ||
291 | * must be initialized / enabled before calling this. | ||
292 | * | ||
293 | * RETURNS: | ||
294 | * 0 on success otherwise a negative error code | ||
295 | */ | ||
296 | int ahci_platform_init_host(struct platform_device *pdev, | ||
297 | struct ahci_host_priv *hpriv, | ||
298 | const struct ata_port_info *pi_template, | ||
299 | unsigned int force_port_map, | ||
300 | unsigned int mask_port_map) | ||
301 | { | ||
302 | struct device *dev = &pdev->dev; | ||
303 | struct ata_port_info pi = *pi_template; | ||
304 | const struct ata_port_info *ppi[] = { &pi, NULL }; | ||
305 | struct ata_host *host; | ||
306 | int i, irq, n_ports, rc; | ||
307 | |||
308 | irq = platform_get_irq(pdev, 0); | ||
309 | if (irq <= 0) { | ||
310 | dev_err(dev, "no irq\n"); | ||
311 | return -EINVAL; | ||
312 | } | ||
313 | |||
314 | /* prepare host */ | ||
315 | hpriv->flags |= (unsigned long)pi.private_data; | ||
316 | |||
317 | ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map); | ||
318 | |||
319 | if (hpriv->cap & HOST_CAP_NCQ) | ||
320 | pi.flags |= ATA_FLAG_NCQ; | ||
321 | |||
322 | if (hpriv->cap & HOST_CAP_PMP) | ||
323 | pi.flags |= ATA_FLAG_PMP; | ||
324 | |||
325 | ahci_set_em_messages(hpriv, &pi); | ||
326 | |||
327 | /* CAP.NP sometimes indicate the index of the last enabled | ||
328 | * port, at other times, that of the last possible port, so | ||
329 | * determining the maximum port number requires looking at | ||
330 | * both CAP.NP and port_map. | ||
331 | */ | ||
332 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); | ||
333 | |||
334 | host = ata_host_alloc_pinfo(dev, ppi, n_ports); | ||
335 | if (!host) | ||
336 | return -ENOMEM; | ||
337 | |||
338 | host->private_data = hpriv; | ||
339 | |||
340 | if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) | ||
341 | host->flags |= ATA_HOST_PARALLEL_SCAN; | ||
342 | else | ||
343 | dev_info(dev, "SSS flag set, parallel bus scan disabled\n"); | ||
344 | |||
345 | if (pi.flags & ATA_FLAG_EM) | ||
346 | ahci_reset_em(host); | ||
347 | |||
348 | for (i = 0; i < host->n_ports; i++) { | ||
349 | struct ata_port *ap = host->ports[i]; | ||
350 | |||
351 | ata_port_desc(ap, "mmio %pR", | ||
352 | platform_get_resource(pdev, IORESOURCE_MEM, 0)); | ||
353 | ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); | ||
354 | |||
355 | /* set enclosure management message type */ | ||
356 | if (ap->flags & ATA_FLAG_EM) | ||
357 | ap->em_message_type = hpriv->em_msg_type; | ||
358 | |||
359 | /* disabled/not-implemented port */ | ||
360 | if (!(hpriv->port_map & (1 << i))) | ||
361 | ap->ops = &ata_dummy_port_ops; | ||
362 | } | ||
363 | |||
364 | rc = ahci_reset_controller(host); | ||
365 | if (rc) | ||
366 | return rc; | ||
367 | |||
368 | ahci_init_controller(host); | ||
369 | ahci_print_info(host, "platform"); | ||
370 | |||
371 | return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, | ||
372 | &ahci_platform_sht); | ||
373 | } | ||
374 | EXPORT_SYMBOL_GPL(ahci_platform_init_host); | ||
375 | |||
376 | static void ahci_host_stop(struct ata_host *host) | ||
377 | { | ||
378 | struct device *dev = host->dev; | ||
379 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | ||
380 | struct ahci_host_priv *hpriv = host->private_data; | ||
381 | |||
382 | if (pdata && pdata->exit) | ||
383 | pdata->exit(dev); | ||
384 | |||
385 | ahci_platform_disable_resources(hpriv); | ||
386 | } | ||
387 | |||
388 | #ifdef CONFIG_PM_SLEEP | ||
389 | /** | ||
390 | * ahci_platform_suspend_host - Suspend an ahci-platform host | ||
391 | * @dev: device pointer for the host | ||
392 | * | ||
393 | * This function does all the usual steps needed to suspend an | ||
394 | * ahci-platform host, note any necessary resources (ie clks, phy, etc.) | ||
395 | * must be disabled after calling this. | ||
396 | * | ||
397 | * RETURNS: | ||
398 | * 0 on success otherwise a negative error code | ||
399 | */ | ||
400 | int ahci_platform_suspend_host(struct device *dev) | ||
401 | { | ||
402 | struct ata_host *host = dev_get_drvdata(dev); | ||
403 | struct ahci_host_priv *hpriv = host->private_data; | ||
404 | void __iomem *mmio = hpriv->mmio; | ||
405 | u32 ctl; | ||
406 | |||
407 | if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { | ||
408 | dev_err(dev, "firmware update required for suspend/resume\n"); | ||
409 | return -EIO; | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | * AHCI spec rev1.1 section 8.3.3: | ||
414 | * Software must disable interrupts prior to requesting a | ||
415 | * transition of the HBA to D3 state. | ||
416 | */ | ||
417 | ctl = readl(mmio + HOST_CTL); | ||
418 | ctl &= ~HOST_IRQ_EN; | ||
419 | writel(ctl, mmio + HOST_CTL); | ||
420 | readl(mmio + HOST_CTL); /* flush */ | ||
421 | |||
422 | return ata_host_suspend(host, PMSG_SUSPEND); | ||
423 | } | ||
424 | EXPORT_SYMBOL_GPL(ahci_platform_suspend_host); | ||
425 | |||
426 | /** | ||
427 | * ahci_platform_resume_host - Resume an ahci-platform host | ||
428 | * @dev: device pointer for the host | ||
429 | * | ||
430 | * This function does all the usual steps needed to resume an ahci-platform | ||
431 | * host, note any necessary resources (ie clks, phy, etc.) must be | ||
432 | * initialized / enabled before calling this. | ||
433 | * | ||
434 | * RETURNS: | ||
435 | * 0 on success otherwise a negative error code | ||
436 | */ | ||
437 | int ahci_platform_resume_host(struct device *dev) | ||
438 | { | ||
439 | struct ata_host *host = dev_get_drvdata(dev); | ||
440 | int rc; | ||
441 | |||
442 | if (dev->power.power_state.event == PM_EVENT_SUSPEND) { | ||
443 | rc = ahci_reset_controller(host); | ||
444 | if (rc) | ||
445 | return rc; | ||
446 | |||
447 | ahci_init_controller(host); | ||
448 | } | ||
449 | |||
450 | ata_host_resume(host); | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | EXPORT_SYMBOL_GPL(ahci_platform_resume_host); | ||
455 | |||
456 | /** | ||
457 | * ahci_platform_suspend - Suspend an ahci-platform device | ||
458 | * @dev: the platform device to suspend | ||
459 | * | ||
460 | * This function suspends the host associated with the device, followed by | ||
461 | * disabling all the resources of the device. | ||
462 | * | ||
463 | * RETURNS: | ||
464 | * 0 on success otherwise a negative error code | ||
465 | */ | ||
466 | int ahci_platform_suspend(struct device *dev) | ||
467 | { | ||
468 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | ||
469 | struct ata_host *host = dev_get_drvdata(dev); | ||
470 | struct ahci_host_priv *hpriv = host->private_data; | ||
471 | int rc; | ||
472 | |||
473 | rc = ahci_platform_suspend_host(dev); | ||
474 | if (rc) | ||
475 | return rc; | ||
476 | |||
477 | if (pdata && pdata->suspend) { | ||
478 | rc = pdata->suspend(dev); | ||
479 | if (rc) | ||
480 | goto resume_host; | ||
481 | } | ||
482 | |||
483 | ahci_platform_disable_resources(hpriv); | ||
484 | |||
485 | return 0; | ||
486 | |||
487 | resume_host: | ||
488 | ahci_platform_resume_host(dev); | ||
489 | return rc; | ||
490 | } | ||
491 | EXPORT_SYMBOL_GPL(ahci_platform_suspend); | ||
492 | |||
493 | /** | ||
494 | * ahci_platform_resume - Resume an ahci-platform device | ||
495 | * @dev: the platform device to resume | ||
496 | * | ||
497 | * This function enables all the resources of the device followed by | ||
498 | * resuming the host associated with the device. | ||
499 | * | ||
500 | * RETURNS: | ||
501 | * 0 on success otherwise a negative error code | ||
502 | */ | ||
503 | int ahci_platform_resume(struct device *dev) | ||
504 | { | ||
505 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | ||
506 | struct ata_host *host = dev_get_drvdata(dev); | ||
507 | struct ahci_host_priv *hpriv = host->private_data; | ||
508 | int rc; | ||
509 | |||
510 | rc = ahci_platform_enable_resources(hpriv); | ||
511 | if (rc) | ||
512 | return rc; | ||
513 | |||
514 | if (pdata && pdata->resume) { | ||
515 | rc = pdata->resume(dev); | ||
516 | if (rc) | ||
517 | goto disable_resources; | ||
518 | } | ||
519 | |||
520 | rc = ahci_platform_resume_host(dev); | ||
521 | if (rc) | ||
522 | goto disable_resources; | ||
523 | |||
524 | /* We resumed so update PM runtime state */ | ||
525 | pm_runtime_disable(dev); | ||
526 | pm_runtime_set_active(dev); | ||
527 | pm_runtime_enable(dev); | ||
528 | |||
529 | return 0; | ||
530 | |||
531 | disable_resources: | ||
532 | ahci_platform_disable_resources(hpriv); | ||
533 | |||
534 | return rc; | ||
535 | } | ||
536 | EXPORT_SYMBOL_GPL(ahci_platform_resume); | ||
537 | #endif | ||
538 | |||
539 | MODULE_DESCRIPTION("AHCI SATA platform library"); | ||
540 | MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>"); | ||
541 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 9e69a5308693..b4f7cc2522d9 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -835,6 +835,7 @@ void ata_acpi_on_resume(struct ata_port *ap) | |||
835 | ata_for_each_dev(dev, &ap->link, ALL) { | 835 | ata_for_each_dev(dev, &ap->link, ALL) { |
836 | ata_acpi_clear_gtf(dev); | 836 | ata_acpi_clear_gtf(dev); |
837 | if (ata_dev_enabled(dev) && | 837 | if (ata_dev_enabled(dev) && |
838 | ata_dev_acpi_handle(dev) && | ||
838 | ata_dev_get_GTF(dev, NULL) >= 0) | 839 | ata_dev_get_GTF(dev, NULL) >= 0) |
839 | dev->flags |= ATA_DFLAG_ACPI_PENDING; | 840 | dev->flags |= ATA_DFLAG_ACPI_PENDING; |
840 | } | 841 | } |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8cb2522d592a..34406f7fdd7a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5352,22 +5352,17 @@ bool ata_link_offline(struct ata_link *link) | |||
5352 | } | 5352 | } |
5353 | 5353 | ||
5354 | #ifdef CONFIG_PM | 5354 | #ifdef CONFIG_PM |
5355 | static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, | 5355 | static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, |
5356 | unsigned int action, unsigned int ehi_flags, | 5356 | unsigned int action, unsigned int ehi_flags, |
5357 | int *async) | 5357 | bool async) |
5358 | { | 5358 | { |
5359 | struct ata_link *link; | 5359 | struct ata_link *link; |
5360 | unsigned long flags; | 5360 | unsigned long flags; |
5361 | int rc = 0; | ||
5362 | 5361 | ||
5363 | /* Previous resume operation might still be in | 5362 | /* Previous resume operation might still be in |
5364 | * progress. Wait for PM_PENDING to clear. | 5363 | * progress. Wait for PM_PENDING to clear. |
5365 | */ | 5364 | */ |
5366 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { | 5365 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { |
5367 | if (async) { | ||
5368 | *async = -EAGAIN; | ||
5369 | return 0; | ||
5370 | } | ||
5371 | ata_port_wait_eh(ap); | 5366 | ata_port_wait_eh(ap); |
5372 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | 5367 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); |
5373 | } | 5368 | } |
@@ -5376,11 +5371,6 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, | |||
5376 | spin_lock_irqsave(ap->lock, flags); | 5371 | spin_lock_irqsave(ap->lock, flags); |
5377 | 5372 | ||
5378 | ap->pm_mesg = mesg; | 5373 | ap->pm_mesg = mesg; |
5379 | if (async) | ||
5380 | ap->pm_result = async; | ||
5381 | else | ||
5382 | ap->pm_result = &rc; | ||
5383 | |||
5384 | ap->pflags |= ATA_PFLAG_PM_PENDING; | 5374 | ap->pflags |= ATA_PFLAG_PM_PENDING; |
5385 | ata_for_each_link(link, ap, HOST_FIRST) { | 5375 | ata_for_each_link(link, ap, HOST_FIRST) { |
5386 | link->eh_info.action |= action; | 5376 | link->eh_info.action |= action; |
@@ -5391,87 +5381,81 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, | |||
5391 | 5381 | ||
5392 | spin_unlock_irqrestore(ap->lock, flags); | 5382 | spin_unlock_irqrestore(ap->lock, flags); |
5393 | 5383 | ||
5394 | /* wait and check result */ | ||
5395 | if (!async) { | 5384 | if (!async) { |
5396 | ata_port_wait_eh(ap); | 5385 | ata_port_wait_eh(ap); |
5397 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | 5386 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); |
5398 | } | 5387 | } |
5399 | |||
5400 | return rc; | ||
5401 | } | 5388 | } |
5402 | 5389 | ||
5403 | static int __ata_port_suspend_common(struct ata_port *ap, pm_message_t mesg, int *async) | 5390 | /* |
5391 | * On some hardware, device fails to respond after spun down for suspend. As | ||
5392 | * the device won't be used before being resumed, we don't need to touch the | ||
5393 | * device. Ask EH to skip the usual stuff and proceed directly to suspend. | ||
5394 | * | ||
5395 | * http://thread.gmane.org/gmane.linux.ide/46764 | ||
5396 | */ | ||
5397 | static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET | ||
5398 | | ATA_EHI_NO_AUTOPSY | ||
5399 | | ATA_EHI_NO_RECOVERY; | ||
5400 | |||
5401 | static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) | ||
5404 | { | 5402 | { |
5405 | /* | 5403 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); |
5406 | * On some hardware, device fails to respond after spun down | ||
5407 | * for suspend. As the device won't be used before being | ||
5408 | * resumed, we don't need to touch the device. Ask EH to skip | ||
5409 | * the usual stuff and proceed directly to suspend. | ||
5410 | * | ||
5411 | * http://thread.gmane.org/gmane.linux.ide/46764 | ||
5412 | */ | ||
5413 | unsigned int ehi_flags = ATA_EHI_QUIET | ATA_EHI_NO_AUTOPSY | | ||
5414 | ATA_EHI_NO_RECOVERY; | ||
5415 | return ata_port_request_pm(ap, mesg, 0, ehi_flags, async); | ||
5416 | } | 5404 | } |
5417 | 5405 | ||
5418 | static int ata_port_suspend_common(struct device *dev, pm_message_t mesg) | 5406 | static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) |
5419 | { | 5407 | { |
5420 | struct ata_port *ap = to_ata_port(dev); | 5408 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); |
5421 | |||
5422 | return __ata_port_suspend_common(ap, mesg, NULL); | ||
5423 | } | 5409 | } |
5424 | 5410 | ||
5425 | static int ata_port_suspend(struct device *dev) | 5411 | static int ata_port_pm_suspend(struct device *dev) |
5426 | { | 5412 | { |
5413 | struct ata_port *ap = to_ata_port(dev); | ||
5414 | |||
5427 | if (pm_runtime_suspended(dev)) | 5415 | if (pm_runtime_suspended(dev)) |
5428 | return 0; | 5416 | return 0; |
5429 | 5417 | ||
5430 | return ata_port_suspend_common(dev, PMSG_SUSPEND); | 5418 | ata_port_suspend(ap, PMSG_SUSPEND); |
5419 | return 0; | ||
5431 | } | 5420 | } |
5432 | 5421 | ||
5433 | static int ata_port_do_freeze(struct device *dev) | 5422 | static int ata_port_pm_freeze(struct device *dev) |
5434 | { | 5423 | { |
5424 | struct ata_port *ap = to_ata_port(dev); | ||
5425 | |||
5435 | if (pm_runtime_suspended(dev)) | 5426 | if (pm_runtime_suspended(dev)) |
5436 | return 0; | 5427 | return 0; |
5437 | 5428 | ||
5438 | return ata_port_suspend_common(dev, PMSG_FREEZE); | 5429 | ata_port_suspend(ap, PMSG_FREEZE); |
5430 | return 0; | ||
5439 | } | 5431 | } |
5440 | 5432 | ||
5441 | static int ata_port_poweroff(struct device *dev) | 5433 | static int ata_port_pm_poweroff(struct device *dev) |
5442 | { | 5434 | { |
5443 | return ata_port_suspend_common(dev, PMSG_HIBERNATE); | 5435 | ata_port_suspend(to_ata_port(dev), PMSG_HIBERNATE); |
5436 | return 0; | ||
5444 | } | 5437 | } |
5445 | 5438 | ||
5446 | static int __ata_port_resume_common(struct ata_port *ap, pm_message_t mesg, | 5439 | static const unsigned int ata_port_resume_ehi = ATA_EHI_NO_AUTOPSY |
5447 | int *async) | 5440 | | ATA_EHI_QUIET; |
5448 | { | ||
5449 | int rc; | ||
5450 | 5441 | ||
5451 | rc = ata_port_request_pm(ap, mesg, ATA_EH_RESET, | 5442 | static void ata_port_resume(struct ata_port *ap, pm_message_t mesg) |
5452 | ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async); | 5443 | { |
5453 | return rc; | 5444 | ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, false); |
5454 | } | 5445 | } |
5455 | 5446 | ||
5456 | static int ata_port_resume_common(struct device *dev, pm_message_t mesg) | 5447 | static void ata_port_resume_async(struct ata_port *ap, pm_message_t mesg) |
5457 | { | 5448 | { |
5458 | struct ata_port *ap = to_ata_port(dev); | 5449 | ata_port_request_pm(ap, mesg, ATA_EH_RESET, ata_port_resume_ehi, true); |
5459 | |||
5460 | return __ata_port_resume_common(ap, mesg, NULL); | ||
5461 | } | 5450 | } |
5462 | 5451 | ||
5463 | static int ata_port_resume(struct device *dev) | 5452 | static int ata_port_pm_resume(struct device *dev) |
5464 | { | 5453 | { |
5465 | int rc; | 5454 | ata_port_resume_async(to_ata_port(dev), PMSG_RESUME); |
5466 | 5455 | pm_runtime_disable(dev); | |
5467 | rc = ata_port_resume_common(dev, PMSG_RESUME); | 5456 | pm_runtime_set_active(dev); |
5468 | if (!rc) { | 5457 | pm_runtime_enable(dev); |
5469 | pm_runtime_disable(dev); | 5458 | return 0; |
5470 | pm_runtime_set_active(dev); | ||
5471 | pm_runtime_enable(dev); | ||
5472 | } | ||
5473 | |||
5474 | return rc; | ||
5475 | } | 5459 | } |
5476 | 5460 | ||
5477 | /* | 5461 | /* |
@@ -5500,21 +5484,23 @@ static int ata_port_runtime_idle(struct device *dev) | |||
5500 | 5484 | ||
5501 | static int ata_port_runtime_suspend(struct device *dev) | 5485 | static int ata_port_runtime_suspend(struct device *dev) |
5502 | { | 5486 | { |
5503 | return ata_port_suspend_common(dev, PMSG_AUTO_SUSPEND); | 5487 | ata_port_suspend(to_ata_port(dev), PMSG_AUTO_SUSPEND); |
5488 | return 0; | ||
5504 | } | 5489 | } |
5505 | 5490 | ||
5506 | static int ata_port_runtime_resume(struct device *dev) | 5491 | static int ata_port_runtime_resume(struct device *dev) |
5507 | { | 5492 | { |
5508 | return ata_port_resume_common(dev, PMSG_AUTO_RESUME); | 5493 | ata_port_resume(to_ata_port(dev), PMSG_AUTO_RESUME); |
5494 | return 0; | ||
5509 | } | 5495 | } |
5510 | 5496 | ||
5511 | static const struct dev_pm_ops ata_port_pm_ops = { | 5497 | static const struct dev_pm_ops ata_port_pm_ops = { |
5512 | .suspend = ata_port_suspend, | 5498 | .suspend = ata_port_pm_suspend, |
5513 | .resume = ata_port_resume, | 5499 | .resume = ata_port_pm_resume, |
5514 | .freeze = ata_port_do_freeze, | 5500 | .freeze = ata_port_pm_freeze, |
5515 | .thaw = ata_port_resume, | 5501 | .thaw = ata_port_pm_resume, |
5516 | .poweroff = ata_port_poweroff, | 5502 | .poweroff = ata_port_pm_poweroff, |
5517 | .restore = ata_port_resume, | 5503 | .restore = ata_port_pm_resume, |
5518 | 5504 | ||
5519 | .runtime_suspend = ata_port_runtime_suspend, | 5505 | .runtime_suspend = ata_port_runtime_suspend, |
5520 | .runtime_resume = ata_port_runtime_resume, | 5506 | .runtime_resume = ata_port_runtime_resume, |
@@ -5526,18 +5512,17 @@ static const struct dev_pm_ops ata_port_pm_ops = { | |||
5526 | * level. sas suspend/resume is async to allow parallel port recovery | 5512 | * level. sas suspend/resume is async to allow parallel port recovery |
5527 | * since sas has multiple ata_port instances per Scsi_Host. | 5513 | * since sas has multiple ata_port instances per Scsi_Host. |
5528 | */ | 5514 | */ |
5529 | int ata_sas_port_async_suspend(struct ata_port *ap, int *async) | 5515 | void ata_sas_port_suspend(struct ata_port *ap) |
5530 | { | 5516 | { |
5531 | return __ata_port_suspend_common(ap, PMSG_SUSPEND, async); | 5517 | ata_port_suspend_async(ap, PMSG_SUSPEND); |
5532 | } | 5518 | } |
5533 | EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend); | 5519 | EXPORT_SYMBOL_GPL(ata_sas_port_suspend); |
5534 | 5520 | ||
5535 | int ata_sas_port_async_resume(struct ata_port *ap, int *async) | 5521 | void ata_sas_port_resume(struct ata_port *ap) |
5536 | { | 5522 | { |
5537 | return __ata_port_resume_common(ap, PMSG_RESUME, async); | 5523 | ata_port_resume_async(ap, PMSG_RESUME); |
5538 | } | 5524 | } |
5539 | EXPORT_SYMBOL_GPL(ata_sas_port_async_resume); | 5525 | EXPORT_SYMBOL_GPL(ata_sas_port_resume); |
5540 | |||
5541 | 5526 | ||
5542 | /** | 5527 | /** |
5543 | * ata_host_suspend - suspend host | 5528 | * ata_host_suspend - suspend host |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 6d8757008318..6760fc4e85b8 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -95,12 +95,13 @@ enum { | |||
95 | * represents timeout for that try. The first try can be soft or | 95 | * represents timeout for that try. The first try can be soft or |
96 | * hardreset. All others are hardreset if available. In most cases | 96 | * hardreset. All others are hardreset if available. In most cases |
97 | * the first reset w/ 10sec timeout should succeed. Following entries | 97 | * the first reset w/ 10sec timeout should succeed. Following entries |
98 | * are mostly for error handling, hotplug and retarded devices. | 98 | * are mostly for error handling, hotplug and those outlier devices that |
99 | * take an exceptionally long time to recover from reset. | ||
99 | */ | 100 | */ |
100 | static const unsigned long ata_eh_reset_timeouts[] = { | 101 | static const unsigned long ata_eh_reset_timeouts[] = { |
101 | 10000, /* most drives spin up by 10sec */ | 102 | 10000, /* most drives spin up by 10sec */ |
102 | 10000, /* > 99% working drives spin up before 20sec */ | 103 | 10000, /* > 99% working drives spin up before 20sec */ |
103 | 35000, /* give > 30 secs of idleness for retarded devices */ | 104 | 35000, /* give > 30 secs of idleness for outlier devices */ |
104 | 5000, /* and sweet one last chance */ | 105 | 5000, /* and sweet one last chance */ |
105 | ULONG_MAX, /* > 1 min has elapsed, give up */ | 106 | ULONG_MAX, /* > 1 min has elapsed, give up */ |
106 | }; | 107 | }; |
@@ -4069,7 +4070,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) | |||
4069 | 4070 | ||
4070 | ata_acpi_set_state(ap, ap->pm_mesg); | 4071 | ata_acpi_set_state(ap, ap->pm_mesg); |
4071 | out: | 4072 | out: |
4072 | /* report result */ | 4073 | /* update the flags */ |
4073 | spin_lock_irqsave(ap->lock, flags); | 4074 | spin_lock_irqsave(ap->lock, flags); |
4074 | 4075 | ||
4075 | ap->pflags &= ~ATA_PFLAG_PM_PENDING; | 4076 | ap->pflags &= ~ATA_PFLAG_PM_PENDING; |
@@ -4078,11 +4079,6 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) | |||
4078 | else if (ap->pflags & ATA_PFLAG_FROZEN) | 4079 | else if (ap->pflags & ATA_PFLAG_FROZEN) |
4079 | ata_port_schedule_eh(ap); | 4080 | ata_port_schedule_eh(ap); |
4080 | 4081 | ||
4081 | if (ap->pm_result) { | ||
4082 | *ap->pm_result = rc; | ||
4083 | ap->pm_result = NULL; | ||
4084 | } | ||
4085 | |||
4086 | spin_unlock_irqrestore(ap->lock, flags); | 4082 | spin_unlock_irqrestore(ap->lock, flags); |
4087 | 4083 | ||
4088 | return; | 4084 | return; |
@@ -4134,13 +4130,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) | |||
4134 | /* tell ACPI that we're resuming */ | 4130 | /* tell ACPI that we're resuming */ |
4135 | ata_acpi_on_resume(ap); | 4131 | ata_acpi_on_resume(ap); |
4136 | 4132 | ||
4137 | /* report result */ | 4133 | /* update the flags */ |
4138 | spin_lock_irqsave(ap->lock, flags); | 4134 | spin_lock_irqsave(ap->lock, flags); |
4139 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); | 4135 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); |
4140 | if (ap->pm_result) { | ||
4141 | *ap->pm_result = rc; | ||
4142 | ap->pm_result = NULL; | ||
4143 | } | ||
4144 | spin_unlock_irqrestore(ap->lock, flags); | 4136 | spin_unlock_irqrestore(ap->lock, flags); |
4145 | } | 4137 | } |
4146 | #endif /* CONFIG_PM */ | 4138 | #endif /* CONFIG_PM */ |
diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index 88949c6d55dd..f3a65a3140d3 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c | |||
@@ -85,21 +85,6 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) | |||
85 | return ODD_MECH_TYPE_UNSUPPORTED; | 85 | return ODD_MECH_TYPE_UNSUPPORTED; |
86 | } | 86 | } |
87 | 87 | ||
88 | static bool odd_can_poweroff(struct ata_device *ata_dev) | ||
89 | { | ||
90 | acpi_handle handle; | ||
91 | struct acpi_device *acpi_dev; | ||
92 | |||
93 | handle = ata_dev_acpi_handle(ata_dev); | ||
94 | if (!handle) | ||
95 | return false; | ||
96 | |||
97 | if (acpi_bus_get_device(handle, &acpi_dev)) | ||
98 | return false; | ||
99 | |||
100 | return acpi_device_can_poweroff(acpi_dev); | ||
101 | } | ||
102 | |||
103 | /* Test if ODD is zero power ready by sense code */ | 88 | /* Test if ODD is zero power ready by sense code */ |
104 | static bool zpready(struct ata_device *dev) | 89 | static bool zpready(struct ata_device *dev) |
105 | { | 90 | { |
@@ -267,13 +252,11 @@ static void ata_acpi_remove_pm_notifier(struct ata_device *dev) | |||
267 | 252 | ||
268 | void zpodd_init(struct ata_device *dev) | 253 | void zpodd_init(struct ata_device *dev) |
269 | { | 254 | { |
255 | struct acpi_device *adev = ACPI_COMPANION(&dev->tdev); | ||
270 | enum odd_mech_type mech_type; | 256 | enum odd_mech_type mech_type; |
271 | struct zpodd *zpodd; | 257 | struct zpodd *zpodd; |
272 | 258 | ||
273 | if (dev->zpodd) | 259 | if (dev->zpodd || !adev || !acpi_device_can_poweroff(adev)) |
274 | return; | ||
275 | |||
276 | if (!odd_can_poweroff(dev)) | ||
277 | return; | 260 | return; |
278 | 261 | ||
279 | mech_type = zpodd_get_mech_type(dev); | 262 | mech_type = zpodd_get_mech_type(dev); |
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 62c9ac80c6e9..5108b8744dce 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/pci.h> | 9 | #include <linux/pci.h> |
10 | #include <linux/init.h> | ||
11 | #include <linux/blkdev.h> | 10 | #include <linux/blkdev.h> |
12 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
13 | #include <linux/device.h> | 12 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index d23e2b3ca0b6..1206fa6b62ca 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/init.h> | ||
21 | #include <linux/blkdev.h> | 20 | #include <linux/blkdev.h> |
22 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
23 | #include <scsi/scsi_host.h> | 22 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 73492dd4a4bc..6fac524c2f50 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c | |||
@@ -356,7 +356,7 @@ static void cf_exit(struct arasan_cf_dev *acdev) | |||
356 | 356 | ||
357 | static void dma_callback(void *dev) | 357 | static void dma_callback(void *dev) |
358 | { | 358 | { |
359 | struct arasan_cf_dev *acdev = (struct arasan_cf_dev *) dev; | 359 | struct arasan_cf_dev *acdev = dev; |
360 | 360 | ||
361 | complete(&acdev->dma_completion); | 361 | complete(&acdev->dma_completion); |
362 | } | 362 | } |
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 1581dee2967a..3aa4e655e3c6 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index d63ee8f41a4f..e9c87274a781 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/init.h> | ||
22 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
23 | #include <linux/gfp.h> | 22 | #include <linux/gfp.h> |
24 | #include <scsi/scsi_host.h> | 23 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 24e51056ac26..30fa4ca4cef6 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/blkdev.h> | 18 | #include <linux/blkdev.h> |
20 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
21 | #include <scsi/scsi_host.h> | 20 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index 2ca5026f2c15..7e73a0f1e323 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/blkdev.h> | 32 | #include <linux/blkdev.h> |
34 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
35 | #include <linux/device.h> | 34 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 8fb69e5ca1b7..57f1be64dbf2 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/blkdev.h> | 18 | #include <linux/blkdev.h> |
20 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
21 | #include <linux/gfp.h> | 20 | #include <linux/gfp.h> |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 1275a8d4dedc..6bca3505b9e9 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/blkdev.h> | 29 | #include <linux/blkdev.h> |
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <scsi/scsi_host.h> | 31 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index f10baabbf5db..bcde4b786807 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/init.h> | ||
38 | #include <linux/blkdev.h> | 37 | #include <linux/blkdev.h> |
39 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
40 | #include <scsi/scsi_host.h> | 39 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index f07f2296acdc..8afe854a5a50 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/blkdev.h> | 29 | #include <linux/blkdev.h> |
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <scsi/scsi_host.h> | 31 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 997e16a3a63f..2c0986fa4bb2 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/init.h> | ||
35 | #include <linux/blkdev.h> | 34 | #include <linux/blkdev.h> |
36 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
37 | #include <scsi/scsi_host.h> | 36 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 0448860a2077..32ddcae5a360 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/init.h> | ||
37 | #include <linux/blkdev.h> | 36 | #include <linux/blkdev.h> |
38 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
39 | #include <linux/libata.h> | 38 | #include <linux/libata.h> |
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 810bc9964dde..3435bd6a5cc9 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/init.h> | ||
15 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
16 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
17 | #include <scsi/scsi_host.h> | 16 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 3c12fd7acd41..f440892225f4 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
17 | #include <linux/init.h> | ||
18 | #include <linux/blkdev.h> | 17 | #include <linux/blkdev.h> |
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
20 | #include <linux/device.h> | 19 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index 980b88e109fc..cad9d45749c4 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/err.h> | 34 | #include <linux/err.h> |
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/init.h> | ||
38 | #include <linux/blkdev.h> | 37 | #include <linux/blkdev.h> |
39 | #include <scsi/scsi_host.h> | 38 | #include <scsi/scsi_host.h> |
40 | #include <linux/ata.h> | 39 | #include <linux/ata.h> |
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 35b521348d31..8e76f79689d3 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <scsi/scsi_host.h> | 24 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index a9d74eff5fc4..3ba843f5cdc0 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <scsi/scsi_host.h> | 24 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 4be0398c153d..b93c0f0729e7 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/init.h> | ||
24 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
25 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
26 | #include <scsi/scsi_host.h> | 25 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 85cf2861e0b7..255c5aaff3a8 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/init.h> | ||
20 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
21 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
22 | #include <scsi/scsi_host.h> | 21 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c index b0b18ec5465f..e0872db913d6 100644 --- a/drivers/ata/pata_imx.c +++ b/drivers/ata/pata_imx.c | |||
@@ -15,7 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/blkdev.h> | 18 | #include <linux/blkdev.h> |
20 | #include <scsi/scsi_host.h> | 19 | #include <scsi/scsi_host.h> |
21 | #include <linux/ata.h> | 20 | #include <linux/ata.h> |
@@ -100,13 +99,9 @@ static int pata_imx_probe(struct platform_device *pdev) | |||
100 | struct resource *io_res; | 99 | struct resource *io_res; |
101 | int ret; | 100 | int ret; |
102 | 101 | ||
103 | io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
104 | if (io_res == NULL) | ||
105 | return -EINVAL; | ||
106 | |||
107 | irq = platform_get_irq(pdev, 0); | 102 | irq = platform_get_irq(pdev, 0); |
108 | if (irq <= 0) | 103 | if (irq < 0) |
109 | return -EINVAL; | 104 | return irq; |
110 | 105 | ||
111 | priv = devm_kzalloc(&pdev->dev, | 106 | priv = devm_kzalloc(&pdev->dev, |
112 | sizeof(struct pata_imx_priv), GFP_KERNEL); | 107 | sizeof(struct pata_imx_priv), GFP_KERNEL); |
@@ -136,11 +131,10 @@ static int pata_imx_probe(struct platform_device *pdev) | |||
136 | ap->pio_mask = ATA_PIO0; | 131 | ap->pio_mask = ATA_PIO0; |
137 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 132 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
138 | 133 | ||
139 | priv->host_regs = devm_ioremap(&pdev->dev, io_res->start, | 134 | io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
140 | resource_size(io_res)); | 135 | priv->host_regs = devm_ioremap_resource(&pdev->dev, io_res); |
141 | if (!priv->host_regs) { | 136 | if (IS_ERR(priv->host_regs)) { |
142 | dev_err(&pdev->dev, "failed to map IO/CTL base\n"); | 137 | ret = PTR_ERR(priv->host_regs); |
143 | ret = -EBUSY; | ||
144 | goto err; | 138 | goto err; |
145 | } | 139 | } |
146 | 140 | ||
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index 2a8dd9527ecc..81369d187a5c 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | ||
14 | #include <linux/blkdev.h> | 13 | #include <linux/blkdev.h> |
15 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
16 | #include <linux/device.h> | 15 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 581e04d80367..dc3d7877f29d 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -72,7 +72,6 @@ | |||
72 | #include <linux/kernel.h> | 72 | #include <linux/kernel.h> |
73 | #include <linux/module.h> | 73 | #include <linux/module.h> |
74 | #include <linux/pci.h> | 74 | #include <linux/pci.h> |
75 | #include <linux/init.h> | ||
76 | #include <linux/blkdev.h> | 75 | #include <linux/blkdev.h> |
77 | #include <linux/delay.h> | 76 | #include <linux/delay.h> |
78 | #include <linux/slab.h> | 77 | #include <linux/slab.h> |
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 76e739b031b6..b1cfa0258fd3 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | ||
14 | #include <linux/blkdev.h> | 13 | #include <linux/blkdev.h> |
15 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
16 | #include <linux/device.h> | 15 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index be816428b430..bce2a8ca4678 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -916,7 +916,6 @@ static __init int probe_chip_type(struct legacy_probe *probe) | |||
916 | local_irq_restore(flags); | 916 | local_irq_restore(flags); |
917 | return BIOS; | 917 | return BIOS; |
918 | } | 918 | } |
919 | local_irq_restore(flags); | ||
920 | } | 919 | } |
921 | 920 | ||
922 | if (ht6560a & mask) | 921 | if (ht6560a & mask) |
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index a4f5e781c8c2..6bad3df3a13c 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/init.h> | ||
15 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
16 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
17 | #include <linux/device.h> | 16 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c index 1f5f28bb0bb8..f39a5379e816 100644 --- a/drivers/ata/pata_mpiix.c +++ b/drivers/ata/pata_mpiix.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/init.h> | ||
32 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
33 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
34 | #include <scsi/scsi_host.h> | 33 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index ad1a0febd620..e3b97093ef9a 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/pci.h> | 9 | #include <linux/pci.h> |
10 | #include <linux/init.h> | ||
11 | #include <linux/blkdev.h> | 10 | #include <linux/blkdev.h> |
12 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
13 | #include <linux/device.h> | 12 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 9513e071040d..56201a69af12 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/init.h> | ||
41 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
42 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
43 | #include <scsi/scsi_host.h> | 42 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index 0c424dae56e7..6154c3ee11a5 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/init.h> | ||
24 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
25 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
26 | #include <scsi/scsi_host.h> | 25 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index 16dc3a63a23d..d44df7ccfe43 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
31 | #include <linux/device.h> | 30 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index d77b2e1054ef..319b64491b7b 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/init.h> | ||
20 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
21 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
22 | #include <linux/device.h> | 21 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index 4ea70cd22aee..fb042e0519d0 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/blkdev.h> | 29 | #include <linux/blkdev.h> |
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <scsi/scsi_host.h> | 31 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 78ede3fd1875..bb71ea214b99 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
31 | #include <scsi/scsi_host.h> | 30 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 40254f4df584..bcc4b968c049 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/blkdev.h> | 29 | #include <linux/blkdev.h> |
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 9d874c85d64d..1151f23177bb 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
31 | #include <linux/device.h> | 30 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index c34fc50070a6..defa050e1784 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/blkdev.h> | 18 | #include <linux/blkdev.h> |
20 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
21 | #include <scsi/scsi_host.h> | 20 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_piccolo.c b/drivers/ata/pata_piccolo.c index 2beb6b5045f8..0b46be117051 100644 --- a/drivers/ata/pata_piccolo.c +++ b/drivers/ata/pata_piccolo.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/init.h> | ||
22 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
23 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
24 | #include <scsi/scsi_host.h> | 23 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 02794885de10..a5579b55e332 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c | |||
@@ -13,7 +13,6 @@ | |||
13 | */ | 13 | */ |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | ||
17 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
18 | #include <scsi/scsi_host.h> | 17 | #include <scsi/scsi_host.h> |
19 | #include <linux/ata.h> | 18 | #include <linux/ata.h> |
diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index a6f05acad61e..73259bfda1e3 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/init.h> | ||
24 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
25 | #include <linux/ata.h> | 24 | #include <linux/ata.h> |
26 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index f582ba180a7d..be3f10240dca 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/blkdev.h> | 18 | #include <linux/blkdev.h> |
20 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
21 | #include <linux/device.h> | 20 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index 79a970f05a2e..521b2137ea3e 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
29 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
30 | #include <linux/device.h> | 29 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 040b093617a4..caedc90855b2 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
17 | #include <linux/init.h> | ||
18 | #include <linux/blkdev.h> | 17 | #include <linux/blkdev.h> |
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
20 | #include <scsi/scsi_host.h> | 19 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index ce2f828c17b3..96a232fffae6 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/init.h> | ||
36 | #include <linux/blkdev.h> | 35 | #include <linux/blkdev.h> |
37 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
38 | #include <scsi/scsi_host.h> | 37 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index f35f15f4d83e..f1f5b5ae3382 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/init.h> | ||
39 | #include <linux/blkdev.h> | 38 | #include <linux/blkdev.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/device.h> | 40 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c index d3830c45a369..5a1cde0ea360 100644 --- a/drivers/ata/pata_sch.c +++ b/drivers/ata/pata_sch.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/init.h> | ||
31 | #include <linux/blkdev.h> | 30 | #include <linux/blkdev.h> |
32 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
33 | #include <linux/device.h> | 32 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 96c6a79ef606..e27f31fe1b67 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/init.h> | ||
38 | #include <linux/blkdev.h> | 37 | #include <linux/blkdev.h> |
39 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
40 | #include <scsi/scsi_host.h> | 39 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index c4b0b073ba8e..73fe362d9716 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
31 | #include <scsi/scsi_host.h> | 30 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 1e8363640bf5..78d913aa93c8 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/blkdev.h> | 29 | #include <linux/blkdev.h> |
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <linux/device.h> | 31 | #include <linux/device.h> |
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 6816911ac422..900f0e4a1faf 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <scsi/scsi_host.h> | 24 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index 94473da68c02..7bc78e264f9e 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/init.h> | ||
40 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
42 | #include <scsi/scsi_host.h> | 41 | #include <scsi/scsi_host.h> |
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index c3ab9a6c3965..f6c9632bdff6 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -55,7 +55,6 @@ | |||
55 | #include <linux/kernel.h> | 55 | #include <linux/kernel.h> |
56 | #include <linux/module.h> | 56 | #include <linux/module.h> |
57 | #include <linux/pci.h> | 57 | #include <linux/pci.h> |
58 | #include <linux/init.h> | ||
59 | #include <linux/blkdev.h> | 58 | #include <linux/blkdev.h> |
60 | #include <linux/delay.h> | 59 | #include <linux/delay.h> |
61 | #include <linux/gfp.h> | 60 | #include <linux/gfp.h> |
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 8ea6e6afd041..f10631beffa8 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/gfp.h> | 37 | #include <linux/gfp.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/init.h> | ||
40 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
42 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 523524b68022..0bb2cabd2197 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/device.h> | 32 | #include <linux/device.h> |
34 | #include <linux/of_address.h> | 33 | #include <linux/of_address.h> |
35 | #include <linux/of_irq.h> | 34 | #include <linux/of_irq.h> |
@@ -462,8 +461,7 @@ static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance) | |||
462 | int chan; | 461 | int chan; |
463 | u32 tfr_reg, err_reg; | 462 | u32 tfr_reg, err_reg; |
464 | unsigned long flags; | 463 | unsigned long flags; |
465 | struct sata_dwc_device *hsdev = | 464 | struct sata_dwc_device *hsdev = hsdev_instance; |
466 | (struct sata_dwc_device *)hsdev_instance; | ||
467 | struct ata_host *host = (struct ata_host *)hsdev->host; | 465 | struct ata_host *host = (struct ata_host *)hsdev->host; |
468 | struct ata_port *ap; | 466 | struct ata_port *ap; |
469 | struct sata_dwc_device_port *hsdevp; | 467 | struct sata_dwc_device_port *hsdevp; |
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 870b11eadc6d..65965cf5af06 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/gfp.h> | 20 | #include <linux/gfp.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/types.h> | 22 | #include <linux/types.h> |
24 | #include <linux/err.h> | 23 | #include <linux/err.h> |
25 | #include <linux/io.h> | 24 | #include <linux/io.h> |
@@ -142,7 +141,7 @@ static ssize_t ecx_transmit_led_message(struct ata_port *ap, u32 state, | |||
142 | ssize_t size) | 141 | ssize_t size) |
143 | { | 142 | { |
144 | struct ahci_host_priv *hpriv = ap->host->private_data; | 143 | struct ahci_host_priv *hpriv = ap->host->private_data; |
145 | struct ecx_plat_data *pdata = (struct ecx_plat_data *) hpriv->plat_data; | 144 | struct ecx_plat_data *pdata = hpriv->plat_data; |
146 | struct ahci_port_priv *pp = ap->private_data; | 145 | struct ahci_port_priv *pp = ap->private_data; |
147 | unsigned long flags; | 146 | unsigned long flags; |
148 | int pmp, i; | 147 | int pmp, i; |
@@ -403,6 +402,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, | |||
403 | static const unsigned long timing[] = { 5, 100, 500}; | 402 | static const unsigned long timing[] = { 5, 100, 500}; |
404 | struct ata_port *ap = link->ap; | 403 | struct ata_port *ap = link->ap; |
405 | struct ahci_port_priv *pp = ap->private_data; | 404 | struct ahci_port_priv *pp = ap->private_data; |
405 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
406 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 406 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
407 | struct ata_taskfile tf; | 407 | struct ata_taskfile tf; |
408 | bool online; | 408 | bool online; |
@@ -431,7 +431,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, | |||
431 | break; | 431 | break; |
432 | } while (!online && retry--); | 432 | } while (!online && retry--); |
433 | 433 | ||
434 | ahci_start_engine(ap); | 434 | hpriv->start_engine(ap); |
435 | 435 | ||
436 | if (online) | 436 | if (online) |
437 | *class = ahci_dev_classify(ap); | 437 | *class = ahci_dev_classify(ap); |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index d74def823d3e..ba5f27120332 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include <linux/gfp.h> | 41 | #include <linux/gfp.h> |
42 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
43 | #include <linux/init.h> | ||
44 | #include <linux/blkdev.h> | 43 | #include <linux/blkdev.h> |
45 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
46 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 97f4acb54ad6..3638887476f6 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/gfp.h> | 36 | #include <linux/gfp.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/init.h> | ||
39 | #include <linux/blkdev.h> | 38 | #include <linux/blkdev.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 3b0dd57984e1..9a6bd4cd29a0 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/init.h> | ||
35 | #include <linux/blkdev.h> | 34 | #include <linux/blkdev.h> |
36 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
37 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index b7695e804635..3062f8605b29 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/init.h> | ||
41 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
42 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
43 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 1ad2f62d34b9..b513428171b3 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/init.h> | ||
37 | #include <linux/blkdev.h> | 36 | #include <linux/blkdev.h> |
38 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
39 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index dc4f70179e7d..c630fa812624 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
42 | #include <linux/init.h> | ||
43 | #include <linux/blkdev.h> | 42 | #include <linux/blkdev.h> |
44 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
45 | #include <linux/interrupt.h> | 44 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 9947010afc0f..39b5de60a1f9 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c | |||
@@ -82,7 +82,6 @@ | |||
82 | #include <linux/module.h> | 82 | #include <linux/module.h> |
83 | #include <linux/pci.h> | 83 | #include <linux/pci.h> |
84 | #include <linux/slab.h> | 84 | #include <linux/slab.h> |
85 | #include <linux/init.h> | ||
86 | #include <linux/blkdev.h> | 85 | #include <linux/blkdev.h> |
87 | #include <linux/delay.h> | 86 | #include <linux/delay.h> |
88 | #include <linux/interrupt.h> | 87 | #include <linux/interrupt.h> |
@@ -1021,8 +1020,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, | |||
1021 | idx++; | 1020 | idx++; |
1022 | dist = ((long) (window_size - (offset + size))) >= 0 ? size : | 1021 | dist = ((long) (window_size - (offset + size))) >= 0 ? size : |
1023 | (long) (window_size - offset); | 1022 | (long) (window_size - offset); |
1024 | memcpy_fromio((char *) psource, (char *) (dimm_mmio + offset / 4), | 1023 | memcpy_fromio(psource, dimm_mmio + offset / 4, dist); |
1025 | dist); | ||
1026 | 1024 | ||
1027 | psource += dist; | 1025 | psource += dist; |
1028 | size -= dist; | 1026 | size -= dist; |
@@ -1031,8 +1029,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, | |||
1031 | readl(mmio + PDC_GENERAL_CTLR); | 1029 | readl(mmio + PDC_GENERAL_CTLR); |
1032 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1030 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1033 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1031 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
1034 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), | 1032 | memcpy_fromio(psource, dimm_mmio, window_size / 4); |
1035 | window_size / 4); | ||
1036 | psource += window_size; | 1033 | psource += window_size; |
1037 | size -= window_size; | 1034 | size -= window_size; |
1038 | idx++; | 1035 | idx++; |
@@ -1043,8 +1040,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, | |||
1043 | readl(mmio + PDC_GENERAL_CTLR); | 1040 | readl(mmio + PDC_GENERAL_CTLR); |
1044 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1041 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1045 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1042 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
1046 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), | 1043 | memcpy_fromio(psource, dimm_mmio, size / 4); |
1047 | size / 4); | ||
1048 | } | 1044 | } |
1049 | } | 1045 | } |
1050 | #endif | 1046 | #endif |
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 6d6489118873..08f98c3ed5c8 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/gfp.h> | 29 | #include <linux/gfp.h> |
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/init.h> | ||
32 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
33 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
34 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 87f056e54a9d..f72e84228c5c 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/init.h> | ||
40 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
42 | #include <linux/device.h> | 41 | #include <linux/device.h> |
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 44f304b3de63..29e847aac34b 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/init.h> | ||
41 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
42 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
43 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index d2895836f9fa..766098af4eb7 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -700,46 +700,26 @@ void sas_probe_sata(struct asd_sas_port *port) | |||
700 | 700 | ||
701 | } | 701 | } |
702 | 702 | ||
703 | static bool sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func) | 703 | static void sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func) |
704 | { | 704 | { |
705 | struct domain_device *dev, *n; | 705 | struct domain_device *dev, *n; |
706 | bool retry = false; | ||
707 | 706 | ||
708 | list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { | 707 | list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { |
709 | int rc; | ||
710 | |||
711 | if (!dev_is_sata(dev)) | 708 | if (!dev_is_sata(dev)) |
712 | continue; | 709 | continue; |
713 | 710 | ||
714 | sas_ata_wait_eh(dev); | 711 | sas_ata_wait_eh(dev); |
715 | rc = dev->sata_dev.pm_result; | ||
716 | if (rc == -EAGAIN) | ||
717 | retry = true; | ||
718 | else if (rc) { | ||
719 | /* since we don't have a | ||
720 | * ->port_{suspend|resume} routine in our | ||
721 | * ata_port ops, and no entanglements with | ||
722 | * acpi, suspend should just be mechanical trip | ||
723 | * through eh, catch cases where these | ||
724 | * assumptions are invalidated | ||
725 | */ | ||
726 | WARN_ONCE(1, "failed %s %s error: %d\n", func, | ||
727 | dev_name(&dev->rphy->dev), rc); | ||
728 | } | ||
729 | 712 | ||
730 | /* if libata failed to power manage the device, tear it down */ | 713 | /* if libata failed to power manage the device, tear it down */ |
731 | if (ata_dev_disabled(sas_to_ata_dev(dev))) | 714 | if (ata_dev_disabled(sas_to_ata_dev(dev))) |
732 | sas_fail_probe(dev, func, -ENODEV); | 715 | sas_fail_probe(dev, func, -ENODEV); |
733 | } | 716 | } |
734 | |||
735 | return retry; | ||
736 | } | 717 | } |
737 | 718 | ||
738 | void sas_suspend_sata(struct asd_sas_port *port) | 719 | void sas_suspend_sata(struct asd_sas_port *port) |
739 | { | 720 | { |
740 | struct domain_device *dev; | 721 | struct domain_device *dev; |
741 | 722 | ||
742 | retry: | ||
743 | mutex_lock(&port->ha->disco_mutex); | 723 | mutex_lock(&port->ha->disco_mutex); |
744 | list_for_each_entry(dev, &port->dev_list, dev_list_node) { | 724 | list_for_each_entry(dev, &port->dev_list, dev_list_node) { |
745 | struct sata_device *sata; | 725 | struct sata_device *sata; |
@@ -751,20 +731,17 @@ void sas_suspend_sata(struct asd_sas_port *port) | |||
751 | if (sata->ap->pm_mesg.event == PM_EVENT_SUSPEND) | 731 | if (sata->ap->pm_mesg.event == PM_EVENT_SUSPEND) |
752 | continue; | 732 | continue; |
753 | 733 | ||
754 | sata->pm_result = -EIO; | 734 | ata_sas_port_suspend(sata->ap); |
755 | ata_sas_port_async_suspend(sata->ap, &sata->pm_result); | ||
756 | } | 735 | } |
757 | mutex_unlock(&port->ha->disco_mutex); | 736 | mutex_unlock(&port->ha->disco_mutex); |
758 | 737 | ||
759 | if (sas_ata_flush_pm_eh(port, __func__)) | 738 | sas_ata_flush_pm_eh(port, __func__); |
760 | goto retry; | ||
761 | } | 739 | } |
762 | 740 | ||
763 | void sas_resume_sata(struct asd_sas_port *port) | 741 | void sas_resume_sata(struct asd_sas_port *port) |
764 | { | 742 | { |
765 | struct domain_device *dev; | 743 | struct domain_device *dev; |
766 | 744 | ||
767 | retry: | ||
768 | mutex_lock(&port->ha->disco_mutex); | 745 | mutex_lock(&port->ha->disco_mutex); |
769 | list_for_each_entry(dev, &port->dev_list, dev_list_node) { | 746 | list_for_each_entry(dev, &port->dev_list, dev_list_node) { |
770 | struct sata_device *sata; | 747 | struct sata_device *sata; |
@@ -776,13 +753,11 @@ void sas_resume_sata(struct asd_sas_port *port) | |||
776 | if (sata->ap->pm_mesg.event == PM_EVENT_ON) | 753 | if (sata->ap->pm_mesg.event == PM_EVENT_ON) |
777 | continue; | 754 | continue; |
778 | 755 | ||
779 | sata->pm_result = -EIO; | 756 | ata_sas_port_resume(sata->ap); |
780 | ata_sas_port_async_resume(sata->ap, &sata->pm_result); | ||
781 | } | 757 | } |
782 | mutex_unlock(&port->ha->disco_mutex); | 758 | mutex_unlock(&port->ha->disco_mutex); |
783 | 759 | ||
784 | if (sas_ata_flush_pm_eh(port, __func__)) | 760 | sas_ata_flush_pm_eh(port, __func__); |
785 | goto retry; | ||
786 | } | 761 | } |
787 | 762 | ||
788 | /** | 763 | /** |
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index 73a25005d88a..1f16d502600c 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h | |||
@@ -19,15 +19,37 @@ | |||
19 | 19 | ||
20 | struct device; | 20 | struct device; |
21 | struct ata_port_info; | 21 | struct ata_port_info; |
22 | struct ahci_host_priv; | ||
23 | struct platform_device; | ||
22 | 24 | ||
25 | /* | ||
26 | * Note ahci_platform_data is deprecated, it is only kept around for use | ||
27 | * by the old da850 and spear13xx ahci code. | ||
28 | * New drivers should instead declare their own platform_driver struct, and | ||
29 | * use ahci_platform* functions in their own probe, suspend and resume methods. | ||
30 | */ | ||
23 | struct ahci_platform_data { | 31 | struct ahci_platform_data { |
24 | int (*init)(struct device *dev, void __iomem *addr); | 32 | int (*init)(struct device *dev, void __iomem *addr); |
25 | void (*exit)(struct device *dev); | 33 | void (*exit)(struct device *dev); |
26 | int (*suspend)(struct device *dev); | 34 | int (*suspend)(struct device *dev); |
27 | int (*resume)(struct device *dev); | 35 | int (*resume)(struct device *dev); |
28 | const struct ata_port_info *ata_port_info; | ||
29 | unsigned int force_port_map; | ||
30 | unsigned int mask_port_map; | ||
31 | }; | 36 | }; |
32 | 37 | ||
38 | int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); | ||
39 | void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); | ||
40 | int ahci_platform_enable_resources(struct ahci_host_priv *hpriv); | ||
41 | void ahci_platform_disable_resources(struct ahci_host_priv *hpriv); | ||
42 | struct ahci_host_priv *ahci_platform_get_resources( | ||
43 | struct platform_device *pdev); | ||
44 | int ahci_platform_init_host(struct platform_device *pdev, | ||
45 | struct ahci_host_priv *hpriv, | ||
46 | const struct ata_port_info *pi_template, | ||
47 | unsigned int force_port_map, | ||
48 | unsigned int mask_port_map); | ||
49 | |||
50 | int ahci_platform_suspend_host(struct device *dev); | ||
51 | int ahci_platform_resume_host(struct device *dev); | ||
52 | int ahci_platform_suspend(struct device *dev); | ||
53 | int ahci_platform_resume(struct device *dev); | ||
54 | |||
33 | #endif /* _AHCI_PLATFORM_H */ | 55 | #endif /* _AHCI_PLATFORM_H */ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index bec6dbe939a0..1de36be64df4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -848,7 +848,6 @@ struct ata_port { | |||
848 | struct completion park_req_pending; | 848 | struct completion park_req_pending; |
849 | 849 | ||
850 | pm_message_t pm_mesg; | 850 | pm_message_t pm_mesg; |
851 | int *pm_result; | ||
852 | enum ata_lpm_policy target_lpm_policy; | 851 | enum ata_lpm_policy target_lpm_policy; |
853 | 852 | ||
854 | struct timer_list fastdrain_timer; | 853 | struct timer_list fastdrain_timer; |
@@ -1140,16 +1139,14 @@ extern bool ata_link_offline(struct ata_link *link); | |||
1140 | #ifdef CONFIG_PM | 1139 | #ifdef CONFIG_PM |
1141 | extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); | 1140 | extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); |
1142 | extern void ata_host_resume(struct ata_host *host); | 1141 | extern void ata_host_resume(struct ata_host *host); |
1143 | extern int ata_sas_port_async_suspend(struct ata_port *ap, int *async); | 1142 | extern void ata_sas_port_suspend(struct ata_port *ap); |
1144 | extern int ata_sas_port_async_resume(struct ata_port *ap, int *async); | 1143 | extern void ata_sas_port_resume(struct ata_port *ap); |
1145 | #else | 1144 | #else |
1146 | static inline int ata_sas_port_async_suspend(struct ata_port *ap, int *async) | 1145 | static inline void ata_sas_port_suspend(struct ata_port *ap) |
1147 | { | 1146 | { |
1148 | return 0; | ||
1149 | } | 1147 | } |
1150 | static inline int ata_sas_port_async_resume(struct ata_port *ap, int *async) | 1148 | static inline void ata_sas_port_resume(struct ata_port *ap) |
1151 | { | 1149 | { |
1152 | return 0; | ||
1153 | } | 1150 | } |
1154 | #endif | 1151 | #endif |
1155 | extern int ata_ratelimit(void); | 1152 | extern int ata_ratelimit(void); |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index f843dd8722a9..ef7872c20da9 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -172,7 +172,6 @@ struct sata_device { | |||
172 | enum ata_command_set command_set; | 172 | enum ata_command_set command_set; |
173 | struct smp_resp rps_resp; /* report_phy_sata_resp */ | 173 | struct smp_resp rps_resp; /* report_phy_sata_resp */ |
174 | u8 port_no; /* port number, if this is a PM (Port) */ | 174 | u8 port_no; /* port number, if this is a PM (Port) */ |
175 | int pm_result; | ||
176 | 175 | ||
177 | struct ata_port *ap; | 176 | struct ata_port *ap; |
178 | struct ata_host ata_host; | 177 | struct ata_host ata_host; |