hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/drivers/ata/libahci_platform.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * AHCI SATA platform library
34 *
....@@ -5,11 +6,6 @@
56 * Jeff Garzik <jgarzik@pobox.com>
67 * Copyright 2010 MontaVista Software, LLC.
78 * 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.
139 */
1410
1511 #include <linux/clk.h>
....@@ -56,8 +52,14 @@
5652 if (rc)
5753 goto disable_phys;
5854
59
- rc = phy_power_on(hpriv->phys[i]);
55
+ rc = phy_set_mode(hpriv->phys[i], PHY_MODE_SATA);
6056 if (rc) {
57
+ phy_exit(hpriv->phys[i]);
58
+ goto disable_phys;
59
+ }
60
+
61
+ rc = phy_power_on(hpriv->phys[i]);
62
+ if (rc && !(rc == -EOPNOTSUPP && (hpriv->flags & AHCI_HFLAG_IGN_NOTSUPP_POWER_ON))) {
6163 phy_exit(hpriv->phys[i]);
6264 goto disable_phys;
6365 }
....@@ -141,7 +143,7 @@
141143 * ahci_platform_enable_regulators - Enable regulators
142144 * @hpriv: host private area to store config values
143145 *
144
- * This function enables all the regulators found in
146
+ * This function enables all the regulators found in controller and
145147 * hpriv->target_pwrs, if any. If a regulator fails to be enabled, it
146148 * disables all the regulators already enabled in reverse order and
147149 * returns an error.
....@@ -152,6 +154,14 @@
152154 int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv)
153155 {
154156 int rc, i;
157
+
158
+ rc = regulator_enable(hpriv->ahci_regulator);
159
+ if (rc)
160
+ return rc;
161
+
162
+ rc = regulator_enable(hpriv->phy_regulator);
163
+ if (rc)
164
+ goto disable_ahci_pwrs;
155165
156166 for (i = 0; i < hpriv->nports; i++) {
157167 if (!hpriv->target_pwrs[i])
....@@ -169,6 +179,9 @@
169179 if (hpriv->target_pwrs[i])
170180 regulator_disable(hpriv->target_pwrs[i]);
171181
182
+ regulator_disable(hpriv->phy_regulator);
183
+disable_ahci_pwrs:
184
+ regulator_disable(hpriv->ahci_regulator);
172185 return rc;
173186 }
174187 EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators);
....@@ -177,7 +190,8 @@
177190 * ahci_platform_disable_regulators - Disable regulators
178191 * @hpriv: host private area to store config values
179192 *
180
- * This function disables all regulators found in hpriv->target_pwrs.
193
+ * This function disables all regulators found in hpriv->target_pwrs and
194
+ * AHCI controller.
181195 */
182196 void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv)
183197 {
....@@ -188,6 +202,9 @@
188202 continue;
189203 regulator_disable(hpriv->target_pwrs[i]);
190204 }
205
+
206
+ regulator_disable(hpriv->ahci_regulator);
207
+ regulator_disable(hpriv->phy_regulator);
191208 }
192209 EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
193210 /**
....@@ -305,11 +322,11 @@
305322 /* No PHY support. Check if PHY is required. */
306323 if (of_find_property(node, "phys", NULL)) {
307324 dev_err(dev,
308
- "couldn't get PHY in node %s: ENOSYS\n",
309
- node->name);
325
+ "couldn't get PHY in node %pOFn: ENOSYS\n",
326
+ node);
310327 break;
311328 }
312
- /* fall through */
329
+ fallthrough;
313330 case -ENODEV:
314331 /* continue normally */
315332 hpriv->phys[port] = NULL;
....@@ -321,8 +338,8 @@
321338
322339 default:
323340 dev_err(dev,
324
- "couldn't get PHY in node %s: %d\n",
325
- node->name, rc);
341
+ "couldn't get PHY in node %pOFn: %d\n",
342
+ node, rc);
326343
327344 break;
328345 }
....@@ -336,7 +353,7 @@
336353 struct regulator *target_pwr;
337354 int rc = 0;
338355
339
- target_pwr = regulator_get_optional(dev, "target");
356
+ target_pwr = regulator_get(dev, "target");
340357
341358 if (!IS_ERR(target_pwr))
342359 hpriv->target_pwrs[port] = target_pwr;
....@@ -356,6 +373,7 @@
356373 *
357374 * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
358375 * 2) regulator for controlling the targets power (optional)
376
+ * regulator for controlling the AHCI controller (optional)
359377 * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
360378 * or for non devicetree enabled platforms a single clock
361379 * 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional)
....@@ -387,7 +405,6 @@
387405 hpriv->mmio = devm_ioremap_resource(dev,
388406 platform_get_resource(pdev, IORESOURCE_MEM, 0));
389407 if (IS_ERR(hpriv->mmio)) {
390
- dev_err(dev, "no mmio space\n");
391408 rc = PTR_ERR(hpriv->mmio);
392409 goto err_out;
393410 }
....@@ -413,6 +430,19 @@
413430 hpriv->clks[i] = clk;
414431 }
415432
433
+ hpriv->ahci_regulator = devm_regulator_get(dev, "ahci");
434
+ if (IS_ERR(hpriv->ahci_regulator)) {
435
+ rc = PTR_ERR(hpriv->ahci_regulator);
436
+ if (rc != 0)
437
+ goto err_out;
438
+ }
439
+
440
+ hpriv->phy_regulator = devm_regulator_get(dev, "phy");
441
+ if (IS_ERR(hpriv->phy_regulator)) {
442
+ rc = PTR_ERR(hpriv->phy_regulator);
443
+ goto err_out;
444
+ }
445
+
416446 if (flags & AHCI_PLATFORM_GET_RESETS) {
417447 hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
418448 if (IS_ERR(hpriv->rsts)) {
....@@ -421,14 +451,24 @@
421451 }
422452 }
423453
424
- hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
454
+ /*
455
+ * Too many sub-nodes most likely means having something wrong with
456
+ * the firmware.
457
+ */
458
+ child_nodes = of_get_child_count(dev->of_node);
459
+ if (child_nodes > AHCI_MAX_PORTS) {
460
+ rc = -EINVAL;
461
+ goto err_out;
462
+ }
425463
426464 /*
427465 * If no sub-node was found, we still need to set nports to
428466 * one in order to be able to use the
429467 * ahci_platform_[en|dis]able_[phys|regulators] functions.
430468 */
431
- if (!child_nodes)
469
+ if (child_nodes)
470
+ hpriv->nports = child_nodes;
471
+ else
432472 hpriv->nports = 1;
433473
434474 hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
....@@ -456,6 +496,7 @@
456496
457497 if (of_property_read_u32(child, "reg", &port)) {
458498 rc = -EINVAL;
499
+ of_node_put(child);
459500 goto err_out;
460501 }
461502
....@@ -473,14 +514,18 @@
473514 if (port_dev) {
474515 rc = ahci_platform_get_regulator(hpriv, port,
475516 &port_dev->dev);
476
- if (rc == -EPROBE_DEFER)
517
+ if (rc == -EPROBE_DEFER) {
518
+ of_node_put(child);
477519 goto err_out;
520
+ }
478521 }
479522 #endif
480523
481524 rc = ahci_platform_get_phy(hpriv, port, dev, child);
482
- if (rc)
525
+ if (rc) {
526
+ of_node_put(child);
483527 goto err_out;
528
+ }
484529
485530 enabled_ports++;
486531 }
....@@ -703,6 +748,9 @@
703748 writel(ctl, mmio + HOST_CTL);
704749 readl(mmio + HOST_CTL); /* flush */
705750
751
+ if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
752
+ ahci_platform_disable_phys(hpriv);
753
+
706754 return ata_host_suspend(host, PMSG_SUSPEND);
707755 }
708756 EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
....@@ -721,6 +769,7 @@
721769 int ahci_platform_resume_host(struct device *dev)
722770 {
723771 struct ata_host *host = dev_get_drvdata(dev);
772
+ struct ahci_host_priv *hpriv = host->private_data;
724773 int rc;
725774
726775 if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
....@@ -731,6 +780,9 @@
731780 ahci_init_controller(host);
732781 }
733782
783
+ if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
784
+ ahci_platform_enable_phys(hpriv);
785
+
734786 ata_host_resume(host);
735787
736788 return 0;