xref: /linux/drivers/ata/libahci_platform.c (revision 3932b9ca55b0be314a36d3e84faff3e823c081f5)
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_phys - Enable PHYs
43  * @hpriv: host private area to store config values
44  *
45  * This function enables all the PHYs found in hpriv->phys, if any.
46  * If a PHY fails to be enabled, it disables all the PHYs already
47  * enabled in reverse order and returns an error.
48  *
49  * RETURNS:
50  * 0 on success otherwise a negative error code
51  */
52 int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
53 {
54 	int rc, i;
55 
56 	for (i = 0; i < hpriv->nports; i++) {
57 		if (!hpriv->phys[i])
58 			continue;
59 
60 		rc = phy_init(hpriv->phys[i]);
61 		if (rc)
62 			goto disable_phys;
63 
64 		rc = phy_power_on(hpriv->phys[i]);
65 		if (rc) {
66 			phy_exit(hpriv->phys[i]);
67 			goto disable_phys;
68 		}
69 	}
70 
71 	return 0;
72 
73 disable_phys:
74 	while (--i >= 0) {
75 		phy_power_off(hpriv->phys[i]);
76 		phy_exit(hpriv->phys[i]);
77 	}
78 	return rc;
79 }
80 EXPORT_SYMBOL_GPL(ahci_platform_enable_phys);
81 
82 /**
83  * ahci_platform_disable_phys - Disable PHYs
84  * @hpriv: host private area to store config values
85  *
86  * This function disables all PHYs found in hpriv->phys.
87  */
88 void ahci_platform_disable_phys(struct ahci_host_priv *hpriv)
89 {
90 	int i;
91 
92 	for (i = 0; i < hpriv->nports; i++) {
93 		if (!hpriv->phys[i])
94 			continue;
95 
96 		phy_power_off(hpriv->phys[i]);
97 		phy_exit(hpriv->phys[i]);
98 	}
99 }
100 EXPORT_SYMBOL_GPL(ahci_platform_disable_phys);
101 
102 /**
103  * ahci_platform_enable_clks - Enable platform clocks
104  * @hpriv: host private area to store config values
105  *
106  * This function enables all the clks found in hpriv->clks, starting at
107  * index 0. If any clk fails to enable it disables all the clks already
108  * enabled in reverse order, and then returns an error.
109  *
110  * RETURNS:
111  * 0 on success otherwise a negative error code
112  */
113 int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
114 {
115 	int c, rc;
116 
117 	for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
118 		rc = clk_prepare_enable(hpriv->clks[c]);
119 		if (rc)
120 			goto disable_unprepare_clk;
121 	}
122 	return 0;
123 
124 disable_unprepare_clk:
125 	while (--c >= 0)
126 		clk_disable_unprepare(hpriv->clks[c]);
127 	return rc;
128 }
129 EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
130 
131 /**
132  * ahci_platform_disable_clks - Disable platform clocks
133  * @hpriv: host private area to store config values
134  *
135  * This function disables all the clks found in hpriv->clks, in reverse
136  * order of ahci_platform_enable_clks (starting at the end of the array).
137  */
138 void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
139 {
140 	int c;
141 
142 	for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
143 		if (hpriv->clks[c])
144 			clk_disable_unprepare(hpriv->clks[c]);
145 }
146 EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
147 
148 /**
149  * ahci_platform_enable_resources - Enable platform resources
150  * @hpriv: host private area to store config values
151  *
152  * This function enables all ahci_platform managed resources in the
153  * following order:
154  * 1) Regulator
155  * 2) Clocks (through ahci_platform_enable_clks)
156  * 3) Phys
157  *
158  * If resource enabling fails at any point the previous enabled resources
159  * are disabled in reverse order.
160  *
161  * RETURNS:
162  * 0 on success otherwise a negative error code
163  */
164 int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
165 {
166 	int rc;
167 
168 	if (hpriv->target_pwr) {
169 		rc = regulator_enable(hpriv->target_pwr);
170 		if (rc)
171 			return rc;
172 	}
173 
174 	rc = ahci_platform_enable_clks(hpriv);
175 	if (rc)
176 		goto disable_regulator;
177 
178 	rc = ahci_platform_enable_phys(hpriv);
179 	if (rc)
180 		goto disable_clks;
181 
182 	return 0;
183 
184 disable_clks:
185 	ahci_platform_disable_clks(hpriv);
186 
187 disable_regulator:
188 	if (hpriv->target_pwr)
189 		regulator_disable(hpriv->target_pwr);
190 	return rc;
191 }
192 EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
193 
194 /**
195  * ahci_platform_disable_resources - Disable platform resources
196  * @hpriv: host private area to store config values
197  *
198  * This function disables all ahci_platform managed resources in the
199  * following order:
200  * 1) Phys
201  * 2) Clocks (through ahci_platform_disable_clks)
202  * 3) Regulator
203  */
204 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
205 {
206 	ahci_platform_disable_phys(hpriv);
207 
208 	ahci_platform_disable_clks(hpriv);
209 
210 	if (hpriv->target_pwr)
211 		regulator_disable(hpriv->target_pwr);
212 }
213 EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
214 
215 static void ahci_platform_put_resources(struct device *dev, void *res)
216 {
217 	struct ahci_host_priv *hpriv = res;
218 	int c;
219 
220 	if (hpriv->got_runtime_pm) {
221 		pm_runtime_put_sync(dev);
222 		pm_runtime_disable(dev);
223 	}
224 
225 	for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
226 		clk_put(hpriv->clks[c]);
227 }
228 
229 /**
230  * ahci_platform_get_resources - Get platform resources
231  * @pdev: platform device to get resources for
232  *
233  * This function allocates an ahci_host_priv struct, and gets the following
234  * resources, storing a reference to them inside the returned struct:
235  *
236  * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
237  * 2) regulator for controlling the targets power (optional)
238  * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
239  *    or for non devicetree enabled platforms a single clock
240  *	4) phys (optional)
241  *
242  * RETURNS:
243  * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
244  */
245 struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
246 {
247 	struct device *dev = &pdev->dev;
248 	struct ahci_host_priv *hpriv;
249 	struct clk *clk;
250 	struct device_node *child;
251 	int i, enabled_ports = 0, rc = -ENOMEM;
252 	u32 mask_port_map = 0;
253 
254 	if (!devres_open_group(dev, NULL, GFP_KERNEL))
255 		return ERR_PTR(-ENOMEM);
256 
257 	hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
258 			     GFP_KERNEL);
259 	if (!hpriv)
260 		goto err_out;
261 
262 	devres_add(dev, hpriv);
263 
264 	hpriv->mmio = devm_ioremap_resource(dev,
265 			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
266 	if (IS_ERR(hpriv->mmio)) {
267 		dev_err(dev, "no mmio space\n");
268 		rc = PTR_ERR(hpriv->mmio);
269 		goto err_out;
270 	}
271 
272 	hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
273 	if (IS_ERR(hpriv->target_pwr)) {
274 		rc = PTR_ERR(hpriv->target_pwr);
275 		if (rc == -EPROBE_DEFER)
276 			goto err_out;
277 		hpriv->target_pwr = NULL;
278 	}
279 
280 	for (i = 0; i < AHCI_MAX_CLKS; i++) {
281 		/*
282 		 * For now we must use clk_get(dev, NULL) for the first clock,
283 		 * because some platforms (da850, spear13xx) are not yet
284 		 * converted to use devicetree for clocks.  For new platforms
285 		 * this is equivalent to of_clk_get(dev->of_node, 0).
286 		 */
287 		if (i == 0)
288 			clk = clk_get(dev, NULL);
289 		else
290 			clk = of_clk_get(dev->of_node, i);
291 
292 		if (IS_ERR(clk)) {
293 			rc = PTR_ERR(clk);
294 			if (rc == -EPROBE_DEFER)
295 				goto err_out;
296 			break;
297 		}
298 		hpriv->clks[i] = clk;
299 	}
300 
301 	hpriv->nports = of_get_child_count(dev->of_node);
302 
303 	if (hpriv->nports) {
304 		hpriv->phys = devm_kzalloc(dev,
305 					   hpriv->nports * sizeof(*hpriv->phys),
306 					   GFP_KERNEL);
307 		if (!hpriv->phys) {
308 			rc = -ENOMEM;
309 			goto err_out;
310 		}
311 
312 		for_each_child_of_node(dev->of_node, child) {
313 			u32 port;
314 
315 			if (!of_device_is_available(child))
316 				continue;
317 
318 			if (of_property_read_u32(child, "reg", &port)) {
319 				rc = -EINVAL;
320 				goto err_out;
321 			}
322 
323 			if (port >= hpriv->nports) {
324 				dev_warn(dev, "invalid port number %d\n", port);
325 				continue;
326 			}
327 
328 			mask_port_map |= BIT(port);
329 
330 			hpriv->phys[port] = devm_of_phy_get(dev, child, NULL);
331 			if (IS_ERR(hpriv->phys[port])) {
332 				rc = PTR_ERR(hpriv->phys[port]);
333 				dev_err(dev,
334 					"couldn't get PHY in node %s: %d\n",
335 					child->name, rc);
336 				goto err_out;
337 			}
338 
339 			enabled_ports++;
340 		}
341 		if (!enabled_ports) {
342 			dev_warn(dev, "No port enabled\n");
343 			rc = -ENODEV;
344 			goto err_out;
345 		}
346 
347 		if (!hpriv->mask_port_map)
348 			hpriv->mask_port_map = mask_port_map;
349 	} else {
350 		/*
351 		 * If no sub-node was found, keep this for device tree
352 		 * compatibility
353 		 */
354 		struct phy *phy = devm_phy_get(dev, "sata-phy");
355 		if (!IS_ERR(phy)) {
356 			hpriv->phys = devm_kzalloc(dev, sizeof(*hpriv->phys),
357 						   GFP_KERNEL);
358 			if (!hpriv->phys) {
359 				rc = -ENOMEM;
360 				goto err_out;
361 			}
362 
363 			hpriv->phys[0] = phy;
364 			hpriv->nports = 1;
365 		} else {
366 			rc = PTR_ERR(phy);
367 			switch (rc) {
368 				case -ENOSYS:
369 					/* No PHY support. Check if PHY is required. */
370 					if (of_find_property(dev->of_node, "phys", NULL)) {
371 						dev_err(dev, "couldn't get sata-phy: ENOSYS\n");
372 						goto err_out;
373 					}
374 				case -ENODEV:
375 					/* continue normally */
376 					hpriv->phys = NULL;
377 					break;
378 
379 				default:
380 					goto err_out;
381 
382 			}
383 		}
384 	}
385 
386 	pm_runtime_enable(dev);
387 	pm_runtime_get_sync(dev);
388 	hpriv->got_runtime_pm = true;
389 
390 	devres_remove_group(dev, NULL);
391 	return hpriv;
392 
393 err_out:
394 	devres_release_group(dev, NULL);
395 	return ERR_PTR(rc);
396 }
397 EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
398 
399 /**
400  * ahci_platform_init_host - Bring up an ahci-platform host
401  * @pdev: platform device pointer for the host
402  * @hpriv: ahci-host private data for the host
403  * @pi_template: template for the ata_port_info to use
404  *
405  * This function does all the usual steps needed to bring up an
406  * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
407  * must be initialized / enabled before calling this.
408  *
409  * RETURNS:
410  * 0 on success otherwise a negative error code
411  */
412 int ahci_platform_init_host(struct platform_device *pdev,
413 			    struct ahci_host_priv *hpriv,
414 			    const struct ata_port_info *pi_template)
415 {
416 	struct device *dev = &pdev->dev;
417 	struct ata_port_info pi = *pi_template;
418 	const struct ata_port_info *ppi[] = { &pi, NULL };
419 	struct ata_host *host;
420 	int i, irq, n_ports, rc;
421 
422 	irq = platform_get_irq(pdev, 0);
423 	if (irq <= 0) {
424 		dev_err(dev, "no irq\n");
425 		return -EINVAL;
426 	}
427 
428 	/* prepare host */
429 	pi.private_data = (void *)(unsigned long)hpriv->flags;
430 
431 	ahci_save_initial_config(dev, hpriv);
432 
433 	if (hpriv->cap & HOST_CAP_NCQ)
434 		pi.flags |= ATA_FLAG_NCQ;
435 
436 	if (hpriv->cap & HOST_CAP_PMP)
437 		pi.flags |= ATA_FLAG_PMP;
438 
439 	ahci_set_em_messages(hpriv, &pi);
440 
441 	/* CAP.NP sometimes indicate the index of the last enabled
442 	 * port, at other times, that of the last possible port, so
443 	 * determining the maximum port number requires looking at
444 	 * both CAP.NP and port_map.
445 	 */
446 	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
447 
448 	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
449 	if (!host)
450 		return -ENOMEM;
451 
452 	host->private_data = hpriv;
453 
454 	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
455 		host->flags |= ATA_HOST_PARALLEL_SCAN;
456 	else
457 		dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
458 
459 	if (pi.flags & ATA_FLAG_EM)
460 		ahci_reset_em(host);
461 
462 	for (i = 0; i < host->n_ports; i++) {
463 		struct ata_port *ap = host->ports[i];
464 
465 		ata_port_desc(ap, "mmio %pR",
466 			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
467 		ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
468 
469 		/* set enclosure management message type */
470 		if (ap->flags & ATA_FLAG_EM)
471 			ap->em_message_type = hpriv->em_msg_type;
472 
473 		/* disabled/not-implemented port */
474 		if (!(hpriv->port_map & (1 << i)))
475 			ap->ops = &ata_dummy_port_ops;
476 	}
477 
478 	if (hpriv->cap & HOST_CAP_64) {
479 		rc = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
480 		if (rc) {
481 			rc = dma_coerce_mask_and_coherent(dev,
482 							  DMA_BIT_MASK(32));
483 			if (rc) {
484 				dev_err(dev, "Failed to enable 64-bit DMA.\n");
485 				return rc;
486 			}
487 			dev_warn(dev, "Enable 32-bit DMA instead of 64-bit.\n");
488 		}
489 	}
490 
491 	rc = ahci_reset_controller(host);
492 	if (rc)
493 		return rc;
494 
495 	ahci_init_controller(host);
496 	ahci_print_info(host, "platform");
497 
498 	return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
499 				 &ahci_platform_sht);
500 }
501 EXPORT_SYMBOL_GPL(ahci_platform_init_host);
502 
503 static void ahci_host_stop(struct ata_host *host)
504 {
505 	struct device *dev = host->dev;
506 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
507 	struct ahci_host_priv *hpriv = host->private_data;
508 
509 	if (pdata && pdata->exit)
510 		pdata->exit(dev);
511 
512 	ahci_platform_disable_resources(hpriv);
513 }
514 
515 #ifdef CONFIG_PM_SLEEP
516 /**
517  * ahci_platform_suspend_host - Suspend an ahci-platform host
518  * @dev: device pointer for the host
519  *
520  * This function does all the usual steps needed to suspend an
521  * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
522  * must be disabled after calling this.
523  *
524  * RETURNS:
525  * 0 on success otherwise a negative error code
526  */
527 int ahci_platform_suspend_host(struct device *dev)
528 {
529 	struct ata_host *host = dev_get_drvdata(dev);
530 	struct ahci_host_priv *hpriv = host->private_data;
531 	void __iomem *mmio = hpriv->mmio;
532 	u32 ctl;
533 
534 	if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
535 		dev_err(dev, "firmware update required for suspend/resume\n");
536 		return -EIO;
537 	}
538 
539 	/*
540 	 * AHCI spec rev1.1 section 8.3.3:
541 	 * Software must disable interrupts prior to requesting a
542 	 * transition of the HBA to D3 state.
543 	 */
544 	ctl = readl(mmio + HOST_CTL);
545 	ctl &= ~HOST_IRQ_EN;
546 	writel(ctl, mmio + HOST_CTL);
547 	readl(mmio + HOST_CTL); /* flush */
548 
549 	return ata_host_suspend(host, PMSG_SUSPEND);
550 }
551 EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
552 
553 /**
554  * ahci_platform_resume_host - Resume an ahci-platform host
555  * @dev: device pointer for the host
556  *
557  * This function does all the usual steps needed to resume an ahci-platform
558  * host, note any necessary resources (ie clks, phys, etc.)  must be
559  * initialized / enabled before calling this.
560  *
561  * RETURNS:
562  * 0 on success otherwise a negative error code
563  */
564 int ahci_platform_resume_host(struct device *dev)
565 {
566 	struct ata_host *host = dev_get_drvdata(dev);
567 	int rc;
568 
569 	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
570 		rc = ahci_reset_controller(host);
571 		if (rc)
572 			return rc;
573 
574 		ahci_init_controller(host);
575 	}
576 
577 	ata_host_resume(host);
578 
579 	return 0;
580 }
581 EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
582 
583 /**
584  * ahci_platform_suspend - Suspend an ahci-platform device
585  * @dev: the platform device to suspend
586  *
587  * This function suspends the host associated with the device, followed by
588  * disabling all the resources of the device.
589  *
590  * RETURNS:
591  * 0 on success otherwise a negative error code
592  */
593 int ahci_platform_suspend(struct device *dev)
594 {
595 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
596 	struct ata_host *host = dev_get_drvdata(dev);
597 	struct ahci_host_priv *hpriv = host->private_data;
598 	int rc;
599 
600 	rc = ahci_platform_suspend_host(dev);
601 	if (rc)
602 		return rc;
603 
604 	if (pdata && pdata->suspend) {
605 		rc = pdata->suspend(dev);
606 		if (rc)
607 			goto resume_host;
608 	}
609 
610 	ahci_platform_disable_resources(hpriv);
611 
612 	return 0;
613 
614 resume_host:
615 	ahci_platform_resume_host(dev);
616 	return rc;
617 }
618 EXPORT_SYMBOL_GPL(ahci_platform_suspend);
619 
620 /**
621  * ahci_platform_resume - Resume an ahci-platform device
622  * @dev: the platform device to resume
623  *
624  * This function enables all the resources of the device followed by
625  * resuming the host associated with the device.
626  *
627  * RETURNS:
628  * 0 on success otherwise a negative error code
629  */
630 int ahci_platform_resume(struct device *dev)
631 {
632 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
633 	struct ata_host *host = dev_get_drvdata(dev);
634 	struct ahci_host_priv *hpriv = host->private_data;
635 	int rc;
636 
637 	rc = ahci_platform_enable_resources(hpriv);
638 	if (rc)
639 		return rc;
640 
641 	if (pdata && pdata->resume) {
642 		rc = pdata->resume(dev);
643 		if (rc)
644 			goto disable_resources;
645 	}
646 
647 	rc = ahci_platform_resume_host(dev);
648 	if (rc)
649 		goto disable_resources;
650 
651 	/* We resumed so update PM runtime state */
652 	pm_runtime_disable(dev);
653 	pm_runtime_set_active(dev);
654 	pm_runtime_enable(dev);
655 
656 	return 0;
657 
658 disable_resources:
659 	ahci_platform_disable_resources(hpriv);
660 
661 	return rc;
662 }
663 EXPORT_SYMBOL_GPL(ahci_platform_resume);
664 #endif
665 
666 MODULE_DESCRIPTION("AHCI SATA platform library");
667 MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
668 MODULE_LICENSE("GPL");
669