diff options
Diffstat (limited to 'target/linux/sunxi/patches-3.13/160-7-ahci-platform-add-resource-helpers.patch')
-rw-r--r-- | target/linux/sunxi/patches-3.13/160-7-ahci-platform-add-resource-helpers.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/target/linux/sunxi/patches-3.13/160-7-ahci-platform-add-resource-helpers.patch b/target/linux/sunxi/patches-3.13/160-7-ahci-platform-add-resource-helpers.patch new file mode 100644 index 0000000..0fdc87d --- /dev/null +++ b/target/linux/sunxi/patches-3.13/160-7-ahci-platform-add-resource-helpers.patch @@ -0,0 +1,211 @@ +From 05d5a60ae336c122e478cc002afccc880d462b3b Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Mon, 20 Jan 2014 14:54:40 +0100 +Subject: [PATCH] ahci-platform: Add enable_ / disable_resources helper + functions + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- + drivers/ata/ahci_platform.c | 112 ++++++++++++++++++++++++++++-------------- + include/linux/ahci_platform.h | 2 + + 2 files changed, 77 insertions(+), 37 deletions(-) + +diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c +index 907c076..6ebbc17 100644 +--- a/drivers/ata/ahci_platform.c ++++ b/drivers/ata/ahci_platform.c +@@ -139,6 +139,68 @@ void ahci_platform_disable_clks(struct ahci_host_priv *hpriv) + } + EXPORT_SYMBOL_GPL(ahci_platform_disable_clks); + ++/** ++ * ahci_platform_enable_resources - Enable platform resources ++ * @hpriv: host private area to store config values ++ * ++ * This function enables all ahci_platform managed resources in ++ * the following order: ++ * 1) Regulator ++ * 2) Clocks (through ahci_platform_enable_clks) ++ * ++ * If resource enabling fails at any point the previous enabled ++ * resources are disabled in reverse order. ++ * ++ * LOCKING: ++ * None. ++ * ++ * RETURNS: ++ * 0 on success otherwise a negative error code ++ */ ++int ahci_platform_enable_resources(struct ahci_host_priv *hpriv) ++{ ++ int rc; ++ ++ if (hpriv->target_pwr) { ++ rc = regulator_enable(hpriv->target_pwr); ++ if (rc) ++ return rc; ++ } ++ ++ rc = ahci_platform_enable_clks(hpriv); ++ if (rc) ++ goto disable_regulator; ++ ++ return 0; ++ ++disable_regulator: ++ if (hpriv->target_pwr) ++ regulator_disable(hpriv->target_pwr); ++ return rc; ++} ++EXPORT_SYMBOL_GPL(ahci_platform_enable_resources); ++ ++/** ++ * ahci_platform_disable_resources - Disable platform resources ++ * @hpriv: host private area to store config values ++ * ++ * This function disables all ahci_platform managed resources in ++ * the following order: ++ * 1) Clocks (through ahci_platform_disable_clks) ++ * 2) Regulator ++ * ++ * LOCKING: ++ * None. ++ */ ++void ahci_platform_disable_resources(struct ahci_host_priv *hpriv) ++{ ++ ahci_platform_disable_clks(hpriv); ++ ++ if (hpriv->target_pwr) ++ regulator_disable(hpriv->target_pwr); ++} ++EXPORT_SYMBOL_GPL(ahci_platform_disable_resources); ++ + static void ahci_put_clks(struct ahci_host_priv *hpriv) + { + int c; +@@ -221,15 +283,9 @@ static int ahci_probe(struct platform_device *pdev) + hpriv->clks[i] = clk; + } + +- if (hpriv->target_pwr) { +- rc = regulator_enable(hpriv->target_pwr); +- if (rc) +- goto free_clk; +- } +- +- rc = ahci_enable_clks(dev, hpriv); ++ rc = ahci_platform_enable_resources(hpriv); + if (rc) +- goto disable_regulator; ++ goto free_clk; + + /* + * Some platforms might need to prepare for mmio region access, +@@ -240,7 +296,7 @@ static int ahci_probe(struct platform_device *pdev) + if (pdata && pdata->init) { + rc = pdata->init(dev, hpriv->mmio); + if (rc) +- goto disable_unprepare_clk; ++ goto disable_resources; + } + + ahci_save_initial_config(dev, hpriv, +@@ -310,11 +366,8 @@ static int ahci_probe(struct platform_device *pdev) + pdata_exit: + if (pdata && pdata->exit) + pdata->exit(dev); +-disable_unprepare_clk: +- ahci_disable_clks(hpriv); +-disable_regulator: +- if (hpriv->target_pwr) +- regulator_disable(hpriv->target_pwr); ++disable_resources: ++ ahci_platform_disable_resources(hpriv); + free_clk: + ahci_put_clks(hpriv); + return rc; +@@ -329,11 +382,8 @@ static void ahci_host_stop(struct ata_host *host) + if (pdata && pdata->exit) + pdata->exit(dev); + +- ahci_disable_clks(hpriv); ++ ahci_platform_disable_resources(hpriv); + ahci_put_clks(hpriv); +- +- if (hpriv->target_pwr) +- regulator_disable(hpriv->target_pwr); + } + + #ifdef CONFIG_PM_SLEEP +@@ -368,10 +418,7 @@ static int ahci_suspend(struct device *dev) + if (pdata && pdata->suspend) + return pdata->suspend(dev); + +- ahci_disable_clks(hpriv); +- +- if (hpriv->target_pwr) +- regulator_disable(hpriv->target_pwr); ++ ahci_platform_disable_resources(hpriv); + + return 0; + } +@@ -383,26 +430,20 @@ static int ahci_resume(struct device *dev) + struct ahci_host_priv *hpriv = host->private_data; + int rc; + +- if (hpriv->target_pwr) { +- rc = regulator_enable(hpriv->target_pwr); +- if (rc) +- return rc; +- } +- +- rc = ahci_enable_clks(dev, hpriv); ++ rc = ahci_platform_enable_resources(hpriv); + if (rc) +- goto disable_regulator; ++ return rc; + + if (pdata && pdata->resume) { + rc = pdata->resume(dev); + if (rc) +- goto disable_unprepare_clk; ++ goto disable_resources; + } + + if (dev->power.power_state.event == PM_EVENT_SUSPEND) { + rc = ahci_reset_controller(host); + if (rc) +- goto disable_unprepare_clk; ++ goto disable_resources; + + ahci_init_controller(host); + } +@@ -411,11 +452,8 @@ static int ahci_resume(struct device *dev) + + return 0; + +-disable_unprepare_clk: +- ahci_disable_clks(hpriv); +-disable_regulator: +- if (hpriv->target_pwr) +- regulator_disable(hpriv->target_pwr); ++disable_resources: ++ ahci_platform_disable_resources(hpriv); + + return rc; + } +diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h +index 769d065..b674b01 100644 +--- a/include/linux/ahci_platform.h ++++ b/include/linux/ahci_platform.h +@@ -33,5 +33,7 @@ struct ahci_platform_data { + + int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); + void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); ++int ahci_platform_enable_resources(struct ahci_host_priv *hpriv); ++void ahci_platform_disable_resources(struct ahci_host_priv *hpriv); + + #endif /* _AHCI_PLATFORM_H */ +-- +1.8.5.5 + |