.. | .. |
---|
26 | 26 | bool enable_cmd_dat_delay; |
---|
27 | 27 | }; |
---|
28 | 28 | |
---|
| 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 | + |
---|
29 | 36 | static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host) |
---|
30 | 37 | { |
---|
31 | | - struct f_sdhost_priv *priv = sdhci_priv(host); |
---|
| 38 | + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); |
---|
32 | 39 | u32 ctrl = 0; |
---|
33 | 40 | |
---|
34 | 41 | usleep_range(2500, 3000); |
---|
.. | .. |
---|
61 | 68 | |
---|
62 | 69 | static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask) |
---|
63 | 70 | { |
---|
64 | | - struct f_sdhost_priv *priv = sdhci_priv(host); |
---|
| 71 | + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); |
---|
65 | 72 | u32 ctl; |
---|
66 | 73 | |
---|
67 | 74 | if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0) |
---|
.. | .. |
---|
85 | 92 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
---|
86 | 93 | }; |
---|
87 | 94 | |
---|
| 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 | + |
---|
88 | 103 | static int sdhci_f_sdh30_probe(struct platform_device *pdev) |
---|
89 | 104 | { |
---|
90 | 105 | struct sdhci_host *host; |
---|
91 | 106 | struct device *dev = &pdev->dev; |
---|
92 | | - int irq, ctrl = 0, ret = 0; |
---|
| 107 | + int ctrl = 0, ret = 0; |
---|
93 | 108 | struct f_sdhost_priv *priv; |
---|
| 109 | + struct sdhci_pltfm_host *pltfm_host; |
---|
94 | 110 | u32 reg = 0; |
---|
95 | 111 | |
---|
96 | | - irq = platform_get_irq(pdev, 0); |
---|
97 | | - if (irq < 0) |
---|
98 | | - return irq; |
---|
99 | | - |
---|
100 | | - 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)); |
---|
101 | 114 | if (IS_ERR(host)) |
---|
102 | 115 | return PTR_ERR(host); |
---|
103 | 116 | |
---|
104 | | - priv = sdhci_priv(host); |
---|
| 117 | + pltfm_host = sdhci_priv(host); |
---|
| 118 | + priv = sdhci_pltfm_priv(pltfm_host); |
---|
105 | 119 | priv->dev = dev; |
---|
106 | | - |
---|
107 | | - host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
---|
108 | | - SDHCI_QUIRK_INVERTED_WRITE_PROTECT; |
---|
109 | | - host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | |
---|
110 | | - SDHCI_QUIRK2_TUNING_WORK_AROUND; |
---|
111 | 120 | |
---|
112 | 121 | priv->enable_cmd_dat_delay = device_property_read_bool(dev, |
---|
113 | 122 | "fujitsu,cmd-dat-delay-select"); |
---|
.. | .. |
---|
115 | 124 | ret = mmc_of_parse(host->mmc); |
---|
116 | 125 | if (ret) |
---|
117 | 126 | goto err; |
---|
118 | | - |
---|
119 | | - platform_set_drvdata(pdev, host); |
---|
120 | | - |
---|
121 | | - host->hw_name = "f_sdh30"; |
---|
122 | | - host->ops = &sdhci_f_sdh30_ops; |
---|
123 | | - host->irq = irq; |
---|
124 | | - |
---|
125 | | - host->ioaddr = devm_platform_ioremap_resource(pdev, 0); |
---|
126 | | - if (IS_ERR(host->ioaddr)) { |
---|
127 | | - ret = PTR_ERR(host->ioaddr); |
---|
128 | | - goto err; |
---|
129 | | - } |
---|
130 | 127 | |
---|
131 | 128 | if (dev_of_node(dev)) { |
---|
132 | 129 | sdhci_get_of_property(pdev); |
---|
.. | .. |
---|
168 | 165 | if (reg & SDHCI_CAN_DO_8BIT) |
---|
169 | 166 | priv->vendor_hs200 = F_SDH30_EMMC_HS200; |
---|
170 | 167 | |
---|
| 168 | + if (!(reg & SDHCI_TIMEOUT_CLK_MASK)) |
---|
| 169 | + host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; |
---|
| 170 | + |
---|
171 | 171 | ret = sdhci_add_host(host); |
---|
172 | 172 | if (ret) |
---|
173 | 173 | goto err_add_host; |
---|
.. | .. |
---|
179 | 179 | err_clk: |
---|
180 | 180 | clk_disable_unprepare(priv->clk_iface); |
---|
181 | 181 | err: |
---|
182 | | - sdhci_free_host(host); |
---|
| 182 | + sdhci_pltfm_free(pdev); |
---|
| 183 | + |
---|
183 | 184 | return ret; |
---|
184 | 185 | } |
---|
185 | 186 | |
---|
186 | 187 | static int sdhci_f_sdh30_remove(struct platform_device *pdev) |
---|
187 | 188 | { |
---|
188 | 189 | struct sdhci_host *host = platform_get_drvdata(pdev); |
---|
189 | | - 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; |
---|
190 | 193 | |
---|
191 | | - sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) == |
---|
192 | | - 0xffffffff); |
---|
| 194 | + sdhci_pltfm_unregister(pdev); |
---|
193 | 195 | |
---|
194 | | - clk_disable_unprepare(priv->clk_iface); |
---|
195 | | - clk_disable_unprepare(priv->clk); |
---|
196 | | - |
---|
197 | | - sdhci_free_host(host); |
---|
198 | | - platform_set_drvdata(pdev, NULL); |
---|
| 196 | + clk_disable_unprepare(clk_iface); |
---|
| 197 | + clk_disable_unprepare(clk); |
---|
199 | 198 | |
---|
200 | 199 | return 0; |
---|
201 | 200 | } |
---|