File Index
Files and directories
Sign in
FILE

libahci_platform.c

File preview with syntax highlighting.

linux-6.19.14/drivers/ata/libahci_platform.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * AHCI SATA platform library
  4 *
  5 * Copyright 2004-2005  Red Hat, Inc.
  6 *   Jeff Garzik <jgarzik@pobox.com>
  7 * Copyright 2010  MontaVista Software, LLC.
  8 *   Anton Vorontsov <avorontsov@ru.mvista.com>
  9 */
 10
 11#include <linux/clk.h>
 12#include <linux/kernel.h>
 13#include <linux/gfp.h>
 14#include <linux/module.h>
 15#include <linux/pm.h>
 16#include <linux/interrupt.h>
 17#include <linux/device.h>
 18#include <linux/platform_device.h>
 19#include <linux/libata.h>
 20#include <linux/ahci_platform.h>
 21#include <linux/phy/phy.h>
 22#include <linux/pm_runtime.h>
 23#include <linux/of.h>
 24#include <linux/of_platform.h>
 25#include <linux/reset.h>
 26#include "ahci.h"
 27
 28static void ahci_host_stop(struct ata_host *host);
 29
 30struct ata_port_operations ahci_platform_ops = {
 31	.inherits	= &ahci_ops,
 32	.host_stop	= ahci_host_stop,
 33};
 34EXPORT_SYMBOL_GPL(ahci_platform_ops);
 35
 36/**
 37 * ahci_platform_enable_phys - Enable PHYs
 38 * @hpriv: host private area to store config values
 39 *
 40 * This function enables all the PHYs found in hpriv->phys, if any.
 41 * If a PHY fails to be enabled, it disables all the PHYs already
 42 * enabled in reverse order and returns an error.
 43 *
 44 * RETURNS:
 45 * 0 on success otherwise a negative error code
 46 */
 47int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
 48{
 49	int rc, i;
 50
 51	for (i = 0; i < hpriv->nports; i++) {
 52		if (ahci_ignore_port(hpriv, i))
 53			continue;
 54
 55		rc = phy_init(hpriv->phys[i]);
 56		if (rc)
 57			goto disable_phys;
 58
 59		rc = phy_set_mode(hpriv->phys[i], PHY_MODE_SATA);
 60		if (rc) {
 61			phy_exit(hpriv->phys[i]);
 62			goto disable_phys;
 63		}
 64
 65		rc = phy_power_on(hpriv->phys[i]);
 66		if (rc) {
 67			phy_exit(hpriv->phys[i]);
 68			goto disable_phys;
 69		}
 70	}
 71
 72	return 0;
 73
 74disable_phys:
 75	while (--i >= 0) {
 76		if (ahci_ignore_port(hpriv, i))
 77			continue;
 78
 79		phy_power_off(hpriv->phys[i]);
 80		phy_exit(hpriv->phys[i]);
 81	}
 82	return rc;
 83}
 84EXPORT_SYMBOL_GPL(ahci_platform_enable_phys);
 85
 86/**
 87 * ahci_platform_disable_phys - Disable PHYs
 88 * @hpriv: host private area to store config values
 89 *
 90 * This function disables all PHYs found in hpriv->phys.
 91 */
 92void ahci_platform_disable_phys(struct ahci_host_priv *hpriv)
 93{
 94	int i;
 95
 96	for (i = 0; i < hpriv->nports; i++) {
 97		if (ahci_ignore_port(hpriv, i))
 98			continue;
 99
100		phy_power_off(hpriv->phys[i]);
101		phy_exit(hpriv->phys[i]);
102	}
103}
104EXPORT_SYMBOL_GPL(ahci_platform_disable_phys);
105
106/**
107 * ahci_platform_find_clk - Find platform clock
108 * @hpriv: host private area to store config values
109 * @con_id: clock connection ID
110 *
111 * This function returns a pointer to the clock descriptor of the clock with
112 * the passed ID.
113 *
114 * RETURNS:
115 * Pointer to the clock descriptor on success otherwise NULL
116 */
117struct clk *ahci_platform_find_clk(struct ahci_host_priv *hpriv, const char *con_id)
118{
119	int i;
120
121	for (i = 0; i < hpriv->n_clks; i++) {
122		if (hpriv->clks[i].id && !strcmp(hpriv->clks[i].id, con_id))
123			return hpriv->clks[i].clk;
124	}
125
126	return NULL;
127}
128EXPORT_SYMBOL_GPL(ahci_platform_find_clk);
129
130/**
131 * ahci_platform_enable_clks - Enable platform clocks
132 * @hpriv: host private area to store config values
133 *
134 * This function enables all the clks found for the AHCI device.
135 *
136 * RETURNS:
137 * 0 on success otherwise a negative error code
138 */
139int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
140{
141	return clk_bulk_prepare_enable(hpriv->n_clks, hpriv->clks);
142}
143EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
144
145/**
146 * ahci_platform_disable_clks - Disable platform clocks
147 * @hpriv: host private area to store config values
148 *
149 * This function disables all the clocks enabled before
150 * (bulk-clocks-disable function is supposed to do that in reverse
151 * from the enabling procedure order).
152 */
153void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
154{
155	clk_bulk_disable_unprepare(hpriv->n_clks, hpriv->clks);
156}
157EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
158
159/**
160 * ahci_platform_deassert_rsts - Deassert/trigger platform resets
161 * @hpriv: host private area to store config values
162 *
163 * This function deasserts or triggers all the reset lines found for
164 * the AHCI device.
165 *
166 * RETURNS:
167 * 0 on success otherwise a negative error code
168 */
169int ahci_platform_deassert_rsts(struct ahci_host_priv *hpriv)
170{
171	if (hpriv->f_rsts & AHCI_PLATFORM_RST_TRIGGER)
172		return reset_control_reset(hpriv->rsts);
173
174	return reset_control_deassert(hpriv->rsts);
175}
176EXPORT_SYMBOL_GPL(ahci_platform_deassert_rsts);
177
178/**
179 * ahci_platform_assert_rsts - Assert/rearm platform resets
180 * @hpriv: host private area to store config values
181 *
182 * This function asserts or rearms (for self-deasserting resets) all
183 * the reset controls found for the AHCI device.
184 *
185 * RETURNS:
186 * 0 on success otherwise a negative error code
187 */
188int ahci_platform_assert_rsts(struct ahci_host_priv *hpriv)
189{
190	if (hpriv->f_rsts & AHCI_PLATFORM_RST_TRIGGER)
191		return reset_control_rearm(hpriv->rsts);
192
193	return reset_control_assert(hpriv->rsts);
194}
195EXPORT_SYMBOL_GPL(ahci_platform_assert_rsts);
196
197/**
198 * ahci_platform_enable_regulators - Enable regulators
199 * @hpriv: host private area to store config values
200 *
201 * This function enables all the regulators found in controller and
202 * hpriv->target_pwrs, if any.  If a regulator fails to be enabled, it
203 * disables all the regulators already enabled in reverse order and
204 * returns an error.
205 *
206 * RETURNS:
207 * 0 on success otherwise a negative error code
208 */
209int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv)
210{
211	int rc, i;
212
213	rc = regulator_enable(hpriv->ahci_regulator);
214	if (rc)
215		return rc;
216
217	rc = regulator_enable(hpriv->phy_regulator);
218	if (rc)
219		goto disable_ahci_pwrs;
220
221	for (i = 0; i < hpriv->nports; i++) {
222		if (!hpriv->target_pwrs[i])
223			continue;
224
225		rc = regulator_enable(hpriv->target_pwrs[i]);
226		if (rc)
227			goto disable_target_pwrs;
228	}
229
230	return 0;
231
232disable_target_pwrs:
233	while (--i >= 0)
234		if (hpriv->target_pwrs[i])
235			regulator_disable(hpriv->target_pwrs[i]);
236
237	regulator_disable(hpriv->phy_regulator);
238disable_ahci_pwrs:
239	regulator_disable(hpriv->ahci_regulator);
240	return rc;
241}
242EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators);
243
244/**
245 * ahci_platform_disable_regulators - Disable regulators
246 * @hpriv: host private area to store config values
247 *
248 * This function disables all regulators found in hpriv->target_pwrs and
249 * AHCI controller.
250 */
251void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv)
252{
253	int i;
254
255	for (i = 0; i < hpriv->nports; i++) {
256		if (!hpriv->target_pwrs[i])
257			continue;
258		regulator_disable(hpriv->target_pwrs[i]);
259	}
260
261	regulator_disable(hpriv->ahci_regulator);
262	regulator_disable(hpriv->phy_regulator);
263}
264EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
265/**
266 * ahci_platform_enable_resources - Enable platform resources
267 * @hpriv: host private area to store config values
268 *
269 * This function enables all ahci_platform managed resources in the
270 * following order:
271 * 1) Regulator
272 * 2) Clocks (through ahci_platform_enable_clks)
273 * 3) Resets
274 * 4) Phys
275 *
276 * If resource enabling fails at any point the previous enabled resources
277 * are disabled in reverse order.
278 *
279 * RETURNS:
280 * 0 on success otherwise a negative error code
281 */
282int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
283{
284	int rc;
285
286	rc = ahci_platform_enable_regulators(hpriv);
287	if (rc)
288		return rc;
289
290	rc = ahci_platform_enable_clks(hpriv);
291	if (rc)
292		goto disable_regulator;
293
294	rc = ahci_platform_deassert_rsts(hpriv);
295	if (rc)
296		goto disable_clks;
297
298	rc = ahci_platform_enable_phys(hpriv);
299	if (rc)
300		goto disable_rsts;
301
302	return 0;
303
304disable_rsts:
305	ahci_platform_assert_rsts(hpriv);
306
307disable_clks:
308	ahci_platform_disable_clks(hpriv);
309
310disable_regulator:
311	ahci_platform_disable_regulators(hpriv);
312
313	return rc;
314}
315EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
316
317/**
318 * ahci_platform_disable_resources - Disable platform resources
319 * @hpriv: host private area to store config values
320 *
321 * This function disables all ahci_platform managed resources in the
322 * following order:
323 * 1) Phys
324 * 2) Resets
325 * 3) Clocks (through ahci_platform_disable_clks)
326 * 4) Regulator
327 */
328void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
329{
330	ahci_platform_disable_phys(hpriv);
331
332	ahci_platform_assert_rsts(hpriv);
333
334	ahci_platform_disable_clks(hpriv);
335
336	ahci_platform_disable_regulators(hpriv);
337}
338EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
339
340static void ahci_platform_put_resources(struct device *dev, void *res)
341{
342	struct ahci_host_priv *hpriv = res;
343	int c;
344
345	if (hpriv->got_runtime_pm) {
346		pm_runtime_put_sync(dev);
347		pm_runtime_disable(dev);
348	}
349
350	/*
351	 * The regulators are tied to child node device and not to the
352	 * SATA device itself. So we can't use devm for automatically
353	 * releasing them. We have to do it manually here.
354	 */
355	for (c = 0; c < hpriv->nports; c++)
356		if (hpriv->target_pwrs && hpriv->target_pwrs[c])
357			regulator_put(hpriv->target_pwrs[c]);
358
359	kfree(hpriv->target_pwrs);
360}
361
362static int ahci_platform_get_phy(struct ahci_host_priv *hpriv, u32 port,
363				struct device *dev, struct device_node *node)
364{
365	int rc;
366
367	hpriv->phys[port] = devm_of_phy_get(dev, node, NULL);
368
369	if (!IS_ERR(hpriv->phys[port]))
370		return 0;
371
372	rc = PTR_ERR(hpriv->phys[port]);
373	switch (rc) {
374	case -ENOSYS:
375		/* No PHY support. Check if PHY is required. */
376		if (of_property_present(node, "phys")) {
377			dev_err(dev,
378				"couldn't get PHY in node %pOFn: ENOSYS\n",
379				node);
380			break;
381		}
382		fallthrough;
383	case -ENODEV:
384		/* continue normally */
385		hpriv->phys[port] = NULL;
386		rc = 0;
387		break;
388	case -EPROBE_DEFER:
389		/* Do not complain yet */
390		break;
391
392	default:
393		dev_err(dev,
394			"couldn't get PHY in node %pOFn: %d\n",
395			node, rc);
396
397		break;
398	}
399
400	return rc;
401}
402
403static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
404				struct device *dev)
405{
406	struct regulator *target_pwr;
407	int rc = 0;
408
409	target_pwr = regulator_get(dev, "target");
410
411	if (!IS_ERR(target_pwr))
412		hpriv->target_pwrs[port] = target_pwr;
413	else
414		rc = PTR_ERR(target_pwr);
415
416	return rc;
417}
418
419static int ahci_platform_get_firmware(struct ahci_host_priv *hpriv,
420				      struct device *dev)
421{
422	u32 port;
423
424	if (!of_property_read_u32(dev->of_node, "hba-cap", &hpriv->saved_cap))
425		hpriv->saved_cap &= (HOST_CAP_SSS | HOST_CAP_MPS);
426
427	of_property_read_u32(dev->of_node,
428			     "ports-implemented", &hpriv->saved_port_map);
429
430	for_each_child_of_node_scoped(dev->of_node, child) {
431		if (!of_device_is_available(child))
432			continue;
433
434		if (of_property_read_u32(child, "reg", &port))
435			return -EINVAL;
436
437		if (!of_property_read_u32(child, "hba-port-cap", &hpriv->saved_port_cap[port]))
438			hpriv->saved_port_cap[port] &= PORT_CMD_CAP;
439	}
440
441	return 0;
442}
443
444static u32 ahci_platform_find_max_port_id(struct device *dev)
445{
446	u32 max_port = 0;
447
448	for_each_child_of_node_scoped(dev->of_node, child) {
449		u32 port;
450
451		if (!of_property_read_u32(child, "reg", &port))
452			max_port = max(max_port, port);
453	}
454
455	return max_port;
456}
457
458/**
459 * ahci_platform_get_resources - Get platform resources
460 * @pdev: platform device to get resources for
461 * @flags: bitmap representing the resource to get
462 *
463 * This function allocates an ahci_host_priv struct, and gets the following
464 * resources, storing a reference to them inside the returned struct:
465 *
466 * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
467 * 2) regulator for controlling the targets power (optional)
468 *    regulator for controlling the AHCI controller (optional)
469 * 3) all clocks specified in the devicetree node, or a single
470 *    clock for non-OF platforms (optional)
471 * 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional)
472 * 5) phys (optional)
473 *
474 * RETURNS:
475 * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
476 */
477struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
478						   unsigned int flags)
479{
480	int child_nodes, rc = -ENOMEM, enabled_ports = 0;
481	struct device *dev = &pdev->dev;
482	struct ahci_host_priv *hpriv;
483	u32 mask_port_map = 0;
484	u32 max_port;
485
486	if (!devres_open_group(dev, NULL, GFP_KERNEL))
487		return ERR_PTR(-ENOMEM);
488
489	hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
490			     GFP_KERNEL);
491	if (!hpriv)
492		goto err_out;
493
494	devres_add(dev, hpriv);
495
496	/*
497	 * If the DT provided an "ahci" named resource, use it. Otherwise,
498	 * fallback to using the default first resource for the device node.
499	 */
500	if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci"))
501		hpriv->mmio = devm_platform_ioremap_resource_byname(pdev, "ahci");
502	else
503		hpriv->mmio = devm_platform_ioremap_resource(pdev, 0);
504	if (IS_ERR(hpriv->mmio)) {
505		rc = PTR_ERR(hpriv->mmio);
506		goto err_out;
507	}
508
509	/*
510	 * Bulk clocks getting procedure can fail to find any clock due to
511	 * running on a non-OF platform or due to the clocks being defined in
512	 * bypass of the DT firmware (like da850, spear13xx). In that case we
513	 * fallback to getting a single clock source right from the dev clocks
514	 * list.
515	 */
516	rc = devm_clk_bulk_get_all(dev, &hpriv->clks);
517	if (rc < 0)
518		goto err_out;
519
520	if (rc > 0) {
521		/* Got clocks in bulk */
522		hpriv->n_clks = rc;
523	} else {
524		/*
525		 * No clock bulk found: fallback to manually getting
526		 * the optional clock.
527		 */
528		hpriv->clks = devm_kzalloc(dev, sizeof(*hpriv->clks), GFP_KERNEL);
529		if (!hpriv->clks) {
530			rc = -ENOMEM;
531			goto err_out;
532		}
533		hpriv->clks->clk = devm_clk_get_optional(dev, NULL);
534		if (IS_ERR(hpriv->clks->clk)) {
535			rc = PTR_ERR(hpriv->clks->clk);
536			goto err_out;
537		} else if (hpriv->clks->clk) {
538			hpriv->clks->id = "ahci";
539			hpriv->n_clks = 1;
540		}
541	}
542
543	hpriv->ahci_regulator = devm_regulator_get(dev, "ahci");
544	if (IS_ERR(hpriv->ahci_regulator)) {
545		rc = PTR_ERR(hpriv->ahci_regulator);
546		if (rc != 0)
547			goto err_out;
548	}
549
550	hpriv->phy_regulator = devm_regulator_get(dev, "phy");
551	if (IS_ERR(hpriv->phy_regulator)) {
552		rc = PTR_ERR(hpriv->phy_regulator);
553		goto err_out;
554	}
555
556	if (flags & AHCI_PLATFORM_GET_RESETS) {
557		hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
558		if (IS_ERR(hpriv->rsts)) {
559			rc = PTR_ERR(hpriv->rsts);
560			goto err_out;
561		}
562
563		hpriv->f_rsts = flags & AHCI_PLATFORM_RST_TRIGGER;
564	}
565
566	/*
567	 * Too many sub-nodes most likely means having something wrong with
568	 * the firmware.
569	 */
570	child_nodes = of_get_child_count(dev->of_node);
571	if (child_nodes > AHCI_MAX_PORTS) {
572		rc = -EINVAL;
573		goto err_out;
574	}
575
576	/* find maximum port id for allocating structures */
577	max_port = ahci_platform_find_max_port_id(dev);
578	/*
579	 * Set nports according to maximum port id. Clamp at
580	 * AHCI_MAX_PORTS, warning message for invalid port id
581	 * is generated later.
582	 * When DT has no sub-nodes max_port is 0, nports is 1,
583	 * in order to be able to use the
584	 * ahci_platform_[en|dis]able_[phys|regulators] functions.
585	 */
586	hpriv->nports = min(AHCI_MAX_PORTS, max_port + 1);
587
588	hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
589	if (!hpriv->phys) {
590		rc = -ENOMEM;
591		goto err_out;
592	}
593	/*
594	 * We cannot use devm_ here, since ahci_platform_put_resources() uses
595	 * target_pwrs after devm_ have freed memory
596	 */
597	hpriv->target_pwrs = kcalloc(hpriv->nports, sizeof(*hpriv->target_pwrs), GFP_KERNEL);
598	if (!hpriv->target_pwrs) {
599		rc = -ENOMEM;
600		goto err_out;
601	}
602
603	if (child_nodes) {
604		for_each_child_of_node_scoped(dev->of_node, child) {
605			u32 port;
606			struct platform_device *port_dev __maybe_unused;
607
608			if (!of_device_is_available(child))
609				continue;
610
611			if (of_property_read_u32(child, "reg", &port)) {
612				rc = -EINVAL;
613				goto err_out;
614			}
615
616			if (port >= hpriv->nports) {
617				dev_warn(dev, "invalid port number %d\n", port);
618				continue;
619			}
620			mask_port_map |= BIT(port);
621
622#ifdef CONFIG_OF_ADDRESS
623			of_platform_device_create(child, NULL, NULL);
624
625			port_dev = of_find_device_by_node(child);
626
627			if (port_dev) {
628				rc = ahci_platform_get_regulator(hpriv, port,
629								&port_dev->dev);
630				if (rc == -EPROBE_DEFER)
631					goto err_out;
632			}
633#endif
634
635			rc = ahci_platform_get_phy(hpriv, port, dev, child);
636			if (rc)
637				goto err_out;
638
639			enabled_ports++;
640		}
641		if (!enabled_ports) {
642			dev_warn(dev, "No port enabled\n");
643			rc = -ENODEV;
644			goto err_out;
645		}
646
647		if (!hpriv->mask_port_map)
648			hpriv->mask_port_map = mask_port_map;
649	} else {
650		/*
651		 * If no sub-node was found, keep this for device tree
652		 * compatibility
653		 */
654		rc = ahci_platform_get_phy(hpriv, 0, dev, dev->of_node);
655		if (rc)
656			goto err_out;
657
658		rc = ahci_platform_get_regulator(hpriv, 0, dev);
659		if (rc == -EPROBE_DEFER)
660			goto err_out;
661	}
662
663	/*
664	 * Retrieve firmware-specific flags which then will be used to set
665	 * the HW-init fields of HBA and its ports
666	 */
667	rc = ahci_platform_get_firmware(hpriv, dev);
668	if (rc)
669		goto err_out;
670
671	pm_runtime_enable(dev);
672	pm_runtime_get_sync(dev);
673	hpriv->got_runtime_pm = true;
674
675	devres_remove_group(dev, NULL);
676	return hpriv;
677
678err_out:
679	devres_release_group(dev, NULL);
680	return ERR_PTR(rc);
681}
682EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
683
684/**
685 * ahci_platform_init_host - Bring up an ahci-platform host
686 * @pdev: platform device pointer for the host
687 * @hpriv: ahci-host private data for the host
688 * @pi_template: template for the ata_port_info to use
689 * @sht: scsi_host_template to use when registering
690 *
691 * This function does all the usual steps needed to bring up an
692 * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
693 * must be initialized / enabled before calling this.
694 *
695 * RETURNS:
696 * 0 on success otherwise a negative error code
697 */
698int ahci_platform_init_host(struct platform_device *pdev,
699			    struct ahci_host_priv *hpriv,
700			    const struct ata_port_info *pi_template,
701			    const struct scsi_host_template *sht)
702{
703	struct device *dev = &pdev->dev;
704	struct ata_port_info pi = *pi_template;
705	const struct ata_port_info *ppi[] = { &pi, NULL };
706	struct ata_host *host;
707	int i, irq, n_ports, rc;
708
709	irq = platform_get_irq(pdev, 0);
710	if (irq < 0)
711		return irq;
712	if (!irq)
713		return -EINVAL;
714
715	hpriv->irq = irq;
716
717	/* prepare host */
718	pi.private_data = (void *)(unsigned long)hpriv->flags;
719
720	ahci_save_initial_config(dev, hpriv);
721
722	if (hpriv->cap & HOST_CAP_NCQ)
723		pi.flags |= ATA_FLAG_NCQ;
724
725	if (hpriv->cap & HOST_CAP_PMP)
726		pi.flags |= ATA_FLAG_PMP;
727
728	ahci_set_em_messages(hpriv, &pi);
729
730	/* CAP.NP sometimes indicate the index of the last enabled
731	 * port, at other times, that of the last possible port, so
732	 * determining the maximum port number requires looking at
733	 * both CAP.NP and port_map.
734	 */
735	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
736
737	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
738	if (!host)
739		return -ENOMEM;
740
741	host->private_data = hpriv;
742
743	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
744		host->flags |= ATA_HOST_PARALLEL_SCAN;
745	else
746		dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
747
748	if (pi.flags & ATA_FLAG_EM)
749		ahci_reset_em(host);
750
751	for (i = 0; i < host->n_ports; i++) {
752		struct ata_port *ap = host->ports[i];
753
754		ata_port_desc(ap, "mmio %pR",
755			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
756		ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
757
758		/* set enclosure management message type */
759		if (ap->flags & ATA_FLAG_EM)
760			ap->em_message_type = hpriv->em_msg_type;
761
762		/* disabled/not-implemented port */
763		if (!(hpriv->port_map & (1 << i)))
764			ap->ops = &ata_dummy_port_ops;
765	}
766
767	if (hpriv->cap & HOST_CAP_64) {
768		rc = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
769		if (rc) {
770			dev_err(dev, "Failed to enable 64-bit DMA.\n");
771			return rc;
772		}
773	}
774
775	rc = ahci_reset_controller(host);
776	if (rc)
777		return rc;
778
779	ahci_init_controller(host);
780	ahci_print_info(host, "platform");
781
782	return ahci_host_activate(host, sht);
783}
784EXPORT_SYMBOL_GPL(ahci_platform_init_host);
785
786static void ahci_host_stop(struct ata_host *host)
787{
788	struct ahci_host_priv *hpriv = host->private_data;
789
790	ahci_platform_disable_resources(hpriv);
791}
792
793/**
794 * ahci_platform_shutdown - Disable interrupts and stop DMA for host ports
795 * @pdev: platform device pointer for the host
796 *
797 * This function is called during system shutdown and performs the minimal
798 * deconfiguration required to ensure that an ahci_platform host cannot
799 * corrupt or otherwise interfere with a new kernel being started with kexec.
800 */
801void ahci_platform_shutdown(struct platform_device *pdev)
802{
803	struct ata_host *host = platform_get_drvdata(pdev);
804	struct ahci_host_priv *hpriv = host->private_data;
805	void __iomem *mmio = hpriv->mmio;
806	int i;
807
808	for (i = 0; i < host->n_ports; i++) {
809		struct ata_port *ap = host->ports[i];
810
811		/* Disable port interrupts */
812		if (ap->ops->freeze)
813			ap->ops->freeze(ap);
814
815		/* Stop the port DMA engines */
816		if (ap->ops->port_stop)
817			ap->ops->port_stop(ap);
818	}
819
820	/* Disable and clear host interrupts */
821	writel(readl(mmio + HOST_CTL) & ~HOST_IRQ_EN, mmio + HOST_CTL);
822	readl(mmio + HOST_CTL); /* flush */
823	writel(GENMASK(host->n_ports, 0), mmio + HOST_IRQ_STAT);
824}
825EXPORT_SYMBOL_GPL(ahci_platform_shutdown);
826
827#ifdef CONFIG_PM_SLEEP
828/**
829 * ahci_platform_suspend_host - Suspend an ahci-platform host
830 * @dev: device pointer for the host
831 *
832 * This function does all the usual steps needed to suspend an
833 * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
834 * must be disabled after calling this.
835 *
836 * RETURNS:
837 * 0 on success otherwise a negative error code
838 */
839int ahci_platform_suspend_host(struct device *dev)
840{
841	struct ata_host *host = dev_get_drvdata(dev);
842	struct ahci_host_priv *hpriv = host->private_data;
843	void __iomem *mmio = hpriv->mmio;
844	u32 ctl;
845
846	if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
847		dev_err(dev, "firmware update required for suspend/resume\n");
848		return -EIO;
849	}
850
851	/*
852	 * AHCI spec rev1.1 section 8.3.3:
853	 * Software must disable interrupts prior to requesting a
854	 * transition of the HBA to D3 state.
855	 */
856	ctl = readl(mmio + HOST_CTL);
857	ctl &= ~HOST_IRQ_EN;
858	writel(ctl, mmio + HOST_CTL);
859	readl(mmio + HOST_CTL); /* flush */
860
861	if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
862		ahci_platform_disable_phys(hpriv);
863
864	ata_host_suspend(host, PMSG_SUSPEND);
865	return 0;
866}
867EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
868
869/**
870 * ahci_platform_resume_host - Resume an ahci-platform host
871 * @dev: device pointer for the host
872 *
873 * This function does all the usual steps needed to resume an ahci-platform
874 * host, note any necessary resources (ie clks, phys, etc.)  must be
875 * initialized / enabled before calling this.
876 *
877 * RETURNS:
878 * 0 on success otherwise a negative error code
879 */
880int ahci_platform_resume_host(struct device *dev)
881{
882	struct ata_host *host = dev_get_drvdata(dev);
883	struct ahci_host_priv *hpriv = host->private_data;
884	int rc;
885
886	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
887		rc = ahci_reset_controller(host);
888		if (rc)
889			return rc;
890
891		ahci_init_controller(host);
892	}
893
894	if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
895		ahci_platform_enable_phys(hpriv);
896
897	ata_host_resume(host);
898
899	return 0;
900}
901EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
902
903/**
904 * ahci_platform_suspend - Suspend an ahci-platform device
905 * @dev: the platform device to suspend
906 *
907 * This function suspends the host associated with the device, followed by
908 * disabling all the resources of the device.
909 *
910 * RETURNS:
911 * 0 on success otherwise a negative error code
912 */
913int ahci_platform_suspend(struct device *dev)
914{
915	struct ata_host *host = dev_get_drvdata(dev);
916	struct ahci_host_priv *hpriv = host->private_data;
917	int rc;
918
919	rc = ahci_platform_suspend_host(dev);
920	if (rc)
921		return rc;
922
923	ahci_platform_disable_resources(hpriv);
924
925	return 0;
926}
927EXPORT_SYMBOL_GPL(ahci_platform_suspend);
928
929/**
930 * ahci_platform_resume - Resume an ahci-platform device
931 * @dev: the platform device to resume
932 *
933 * This function enables all the resources of the device followed by
934 * resuming the host associated with the device.
935 *
936 * RETURNS:
937 * 0 on success otherwise a negative error code
938 */
939int ahci_platform_resume(struct device *dev)
940{
941	struct ata_host *host = dev_get_drvdata(dev);
942	struct ahci_host_priv *hpriv = host->private_data;
943	int rc;
944
945	rc = ahci_platform_enable_resources(hpriv);
946	if (rc)
947		return rc;
948
949	rc = ahci_platform_resume_host(dev);
950	if (rc)
951		goto disable_resources;
952
953	/* We resumed so update PM runtime state */
954	pm_runtime_disable(dev);
955	pm_runtime_set_active(dev);
956	pm_runtime_enable(dev);
957
958	return 0;
959
960disable_resources:
961	ahci_platform_disable_resources(hpriv);
962
963	return rc;
964}
965EXPORT_SYMBOL_GPL(ahci_platform_resume);
966#endif
967
968MODULE_DESCRIPTION("AHCI SATA platform library");
969MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
970MODULE_LICENSE("GPL");
~/ Read-only file preview.