forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/mmc/host/sdhci_f_sdh30.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * linux/drivers/mmc/host/sdhci_f_sdh30.c
34 *
45 * Copyright (C) 2013 - 2015 Fujitsu Semiconductor, Ltd
56 * Vincent Yang <vincent.yang@tw.fujitsu.com>
67 * Copyright (C) 2015 Linaro Ltd Andy Green <andy.green@linaro.org>
7
- *
8
- * This program is free software: you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation, version 2 of the License.
118 */
129
1310 #include <linux/acpi.h>
....@@ -19,31 +16,7 @@
1916 #include <linux/clk.h>
2017
2118 #include "sdhci-pltfm.h"
22
-
23
-/* F_SDH30 extended Controller registers */
24
-#define F_SDH30_AHB_CONFIG 0x100
25
-#define F_SDH30_AHB_BIGED 0x00000040
26
-#define F_SDH30_BUSLOCK_DMA 0x00000020
27
-#define F_SDH30_BUSLOCK_EN 0x00000010
28
-#define F_SDH30_SIN 0x00000008
29
-#define F_SDH30_AHB_INCR_16 0x00000004
30
-#define F_SDH30_AHB_INCR_8 0x00000002
31
-#define F_SDH30_AHB_INCR_4 0x00000001
32
-
33
-#define F_SDH30_TUNING_SETTING 0x108
34
-#define F_SDH30_CMD_CHK_DIS 0x00010000
35
-
36
-#define F_SDH30_IO_CONTROL2 0x114
37
-#define F_SDH30_CRES_O_DN 0x00080000
38
-#define F_SDH30_MSEL_O_1_8 0x00040000
39
-
40
-#define F_SDH30_ESD_CONTROL 0x124
41
-#define F_SDH30_EMMC_RST 0x00000002
42
-#define F_SDH30_EMMC_HS200 0x01000000
43
-
44
-#define F_SDH30_CMD_DAT_DELAY 0x200
45
-
46
-#define F_SDH30_MIN_CLOCK 400000
19
+#include "sdhci_f_sdh30.h"
4720
4821 struct f_sdhost_priv {
4922 struct clk *clk_iface;
....@@ -53,9 +26,16 @@
5326 bool enable_cmd_dat_delay;
5427 };
5528
29
+static void *sdhci_f_sdhost_priv(struct sdhci_host *host)
30
+{
31
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
32
+
33
+ return sdhci_pltfm_priv(pltfm_host);
34
+}
35
+
5636 static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
5737 {
58
- struct f_sdhost_priv *priv = sdhci_priv(host);
38
+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
5939 u32 ctrl = 0;
6040
6141 usleep_range(2500, 3000);
....@@ -88,7 +68,7 @@
8868
8969 static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
9070 {
91
- struct f_sdhost_priv *priv = sdhci_priv(host);
71
+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
9272 u32 ctl;
9373
9474 if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
....@@ -112,32 +92,31 @@
11292 .set_uhs_signaling = sdhci_set_uhs_signaling,
11393 };
11494
95
+static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = {
96
+ .ops = &sdhci_f_sdh30_ops,
97
+ .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
98
+ | SDHCI_QUIRK_INVERTED_WRITE_PROTECT,
99
+ .quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE
100
+ | SDHCI_QUIRK2_TUNING_WORK_AROUND,
101
+};
102
+
115103 static int sdhci_f_sdh30_probe(struct platform_device *pdev)
116104 {
117105 struct sdhci_host *host;
118106 struct device *dev = &pdev->dev;
119
- struct resource *res;
120
- int irq, ctrl = 0, ret = 0;
107
+ int ctrl = 0, ret = 0;
121108 struct f_sdhost_priv *priv;
109
+ struct sdhci_pltfm_host *pltfm_host;
122110 u32 reg = 0;
123111
124
- irq = platform_get_irq(pdev, 0);
125
- if (irq < 0) {
126
- dev_err(dev, "%s: no irq specified\n", __func__);
127
- return irq;
128
- }
129
-
130
- host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv));
112
+ host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data,
113
+ sizeof(struct f_sdhost_priv));
131114 if (IS_ERR(host))
132115 return PTR_ERR(host);
133116
134
- priv = sdhci_priv(host);
117
+ pltfm_host = sdhci_priv(host);
118
+ priv = sdhci_pltfm_priv(pltfm_host);
135119 priv->dev = dev;
136
-
137
- host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
138
- SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
139
- host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
140
- SDHCI_QUIRK2_TUNING_WORK_AROUND;
141120
142121 priv->enable_cmd_dat_delay = device_property_read_bool(dev,
143122 "fujitsu,cmd-dat-delay-select");
....@@ -145,19 +124,6 @@
145124 ret = mmc_of_parse(host->mmc);
146125 if (ret)
147126 goto err;
148
-
149
- platform_set_drvdata(pdev, host);
150
-
151
- host->hw_name = "f_sdh30";
152
- host->ops = &sdhci_f_sdh30_ops;
153
- host->irq = irq;
154
-
155
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
156
- host->ioaddr = devm_ioremap_resource(&pdev->dev, res);
157
- if (IS_ERR(host->ioaddr)) {
158
- ret = PTR_ERR(host->ioaddr);
159
- goto err;
160
- }
161127
162128 if (dev_of_node(dev)) {
163129 sdhci_get_of_property(pdev);
....@@ -199,6 +165,9 @@
199165 if (reg & SDHCI_CAN_DO_8BIT)
200166 priv->vendor_hs200 = F_SDH30_EMMC_HS200;
201167
168
+ if (!(reg & SDHCI_TIMEOUT_CLK_MASK))
169
+ host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
170
+
202171 ret = sdhci_add_host(host);
203172 if (ret)
204173 goto err_add_host;
....@@ -210,23 +179,22 @@
210179 err_clk:
211180 clk_disable_unprepare(priv->clk_iface);
212181 err:
213
- sdhci_free_host(host);
182
+ sdhci_pltfm_free(pdev);
183
+
214184 return ret;
215185 }
216186
217187 static int sdhci_f_sdh30_remove(struct platform_device *pdev)
218188 {
219189 struct sdhci_host *host = platform_get_drvdata(pdev);
220
- struct f_sdhost_priv *priv = sdhci_priv(host);
190
+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
191
+ struct clk *clk_iface = priv->clk_iface;
192
+ struct clk *clk = priv->clk;
221193
222
- sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
223
- 0xffffffff);
194
+ sdhci_pltfm_unregister(pdev);
224195
225
- clk_disable_unprepare(priv->clk_iface);
226
- clk_disable_unprepare(priv->clk);
227
-
228
- sdhci_free_host(host);
229
- platform_set_drvdata(pdev, NULL);
196
+ clk_disable_unprepare(clk_iface);
197
+ clk_disable_unprepare(clk);
230198
231199 return 0;
232200 }