|
12 | 12 | #include <linux/module.h>
|
13 | 13 | #include <linux/of_device.h>
|
14 | 14 | #include <linux/platform_device.h>
|
| 15 | +#include <linux/reset.h> |
15 | 16 | #include "ahci.h"
|
16 | 17 |
|
17 | 18 | /* Vendor Specific Register Offsets */
|
@@ -87,6 +88,7 @@ struct ceva_ahci_priv {
|
87 | 88 | u32 axicc;
|
88 | 89 | bool is_cci_enabled;
|
89 | 90 | int flags;
|
| 91 | + struct reset_control *rst; |
90 | 92 | };
|
91 | 93 |
|
92 | 94 | static unsigned int ceva_ahci_read_id(struct ata_device *dev,
|
@@ -202,13 +204,48 @@ static int ceva_ahci_probe(struct platform_device *pdev)
|
202 | 204 |
|
203 | 205 | cevapriv->ahci_pdev = pdev;
|
204 | 206 |
|
| 207 | + cevapriv->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, |
| 208 | + NULL); |
| 209 | + if (IS_ERR(cevapriv->rst)) { |
| 210 | + if (PTR_ERR(cevapriv->rst) != -EPROBE_DEFER) |
| 211 | + dev_err(&pdev->dev, "failed to get reset: %ld\n", |
| 212 | + PTR_ERR(cevapriv->rst)); |
| 213 | + } |
| 214 | + |
205 | 215 | hpriv = ahci_platform_get_resources(pdev, 0);
|
206 | 216 | if (IS_ERR(hpriv))
|
207 | 217 | return PTR_ERR(hpriv);
|
208 | 218 |
|
209 |
| - rc = ahci_platform_enable_resources(hpriv); |
210 |
| - if (rc) |
211 |
| - return rc; |
| 219 | + if (!cevapriv->rst) { |
| 220 | + rc = ahci_platform_enable_resources(hpriv); |
| 221 | + if (rc) |
| 222 | + return rc; |
| 223 | + } else { |
| 224 | + int i; |
| 225 | + |
| 226 | + rc = ahci_platform_enable_clks(hpriv); |
| 227 | + if (rc) |
| 228 | + return rc; |
| 229 | + /* Assert the controller reset */ |
| 230 | + reset_control_assert(cevapriv->rst); |
| 231 | + |
| 232 | + for (i = 0; i < hpriv->nports; i++) { |
| 233 | + rc = phy_init(hpriv->phys[i]); |
| 234 | + if (rc) |
| 235 | + return rc; |
| 236 | + } |
| 237 | + |
| 238 | + /* De-assert the controller reset */ |
| 239 | + reset_control_deassert(cevapriv->rst); |
| 240 | + |
| 241 | + for (i = 0; i < hpriv->nports; i++) { |
| 242 | + rc = phy_power_on(hpriv->phys[i]); |
| 243 | + if (rc) { |
| 244 | + phy_exit(hpriv->phys[i]); |
| 245 | + return rc; |
| 246 | + } |
| 247 | + } |
| 248 | + } |
212 | 249 |
|
213 | 250 | if (of_property_read_bool(np, "ceva,broken-gen2"))
|
214 | 251 | cevapriv->flags = CEVA_FLAG_BROKEN_GEN2;
|
|
0 commit comments