summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-05-16 16:35:25 +0200
committerArnd Bergmann <arnd@arndb.de>2012-05-16 16:35:25 +0200
commit3c0dec5f58b3c7b3627715126d1bf9b030a076f0 (patch)
tree4bf8f56fca3bf6be109209b116fc8e32cb2e0f9e /drivers/ata
parentfcd8d84a585f3578a9ebdd27e757495a27415322 (diff)
parent7e0fa1b5fa91d9aa456d102c273b2cf0f2e95d39 (diff)
downloadlinux-3c0dec5f58b3c7b3627715126d1bf9b030a076f0.tar.gz
linux-3c0dec5f58b3c7b3627715126d1bf9b030a076f0.tar.xz
linux-3c0dec5f58b3c7b3627715126d1bf9b030a076f0.zip
Merge branch 'clk-next' of git://git.linaro.org/people/mturquette/linux into next/clock
* 'clk-next' of git://git.linaro.org/people/mturquette/linux: clk: Fix CLK_SET_RATE_GATE flag validation in clk_set_rate(). clk: Provide dummy clk_unregister() ARM: Kirkwood: Replace clock gating ARM: Orion: Audio: Add clk/clkdev support ARM: Orion: PCIE: Add support for clk ARM: Orion: XOR: Add support for clk ARM: Orion: CESA: Add support for clk ARM: Orion: SDIO: Add support for clk. ARM: Orion: NAND: Add support for clk, if there is one. ARM: Orion: EHCI: Add support for enabling clocks ARM: Orion: SATA: Add per channel clk/clkdev support. ARM: Orion: UART: Get the clock rate via clk_get_rate(). ARM: Orion: WDT: Add clk/clkdev support ARM: Orion: Eth: Add clk/clkdev support. ARM: Orion: SPI: Add clk/clkdev support. ARM: Orion: Add clocks using the generic clk infrastructure. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_mv.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 7336d4a7ab31..24712adf69df 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -553,6 +553,7 @@ struct mv_host_priv {
#if defined(CONFIG_HAVE_CLK)
struct clk *clk;
+ struct clk **port_clks;
#endif
/*
* These consistent DMA memory pools give us guaranteed
@@ -4027,6 +4028,9 @@ static int mv_platform_probe(struct platform_device *pdev)
struct resource *res;
int n_ports = 0;
int rc;
+#if defined(CONFIG_HAVE_CLK)
+ int port;
+#endif
ata_print_version_once(&pdev->dev, DRV_VERSION);
@@ -4054,6 +4058,13 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!host || !hpriv)
return -ENOMEM;
+#if defined(CONFIG_HAVE_CLK)
+ hpriv->port_clks = devm_kzalloc(&pdev->dev,
+ sizeof(struct clk *) * n_ports,
+ GFP_KERNEL);
+ if (!hpriv->port_clks)
+ return -ENOMEM;
+#endif
host->private_data = hpriv;
hpriv->n_ports = n_ports;
hpriv->board_idx = chip_soc;
@@ -4066,9 +4077,17 @@ static int mv_platform_probe(struct platform_device *pdev)
#if defined(CONFIG_HAVE_CLK)
hpriv->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(hpriv->clk))
- dev_notice(&pdev->dev, "cannot get clkdev\n");
+ dev_notice(&pdev->dev, "cannot get optional clkdev\n");
else
- clk_enable(hpriv->clk);
+ clk_prepare_enable(hpriv->clk);
+
+ for (port = 0; port < n_ports; port++) {
+ char port_number[16];
+ sprintf(port_number, "%d", port);
+ hpriv->port_clks[port] = clk_get(&pdev->dev, port_number);
+ if (!IS_ERR(hpriv->port_clks[port]))
+ clk_prepare_enable(hpriv->port_clks[port]);
+ }
#endif
/*
@@ -4098,9 +4117,15 @@ static int mv_platform_probe(struct platform_device *pdev)
err:
#if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) {
- clk_disable(hpriv->clk);
+ clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
}
+ for (port = 0; port < n_ports; port++) {
+ if (!IS_ERR(hpriv->port_clks[port])) {
+ clk_disable_unprepare(hpriv->port_clks[port]);
+ clk_put(hpriv->port_clks[port]);
+ }
+ }
#endif
return rc;
@@ -4119,14 +4144,21 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
struct ata_host *host = platform_get_drvdata(pdev);
#if defined(CONFIG_HAVE_CLK)
struct mv_host_priv *hpriv = host->private_data;
+ int port;
#endif
ata_host_detach(host);
#if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) {
- clk_disable(hpriv->clk);
+ clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
}
+ for (port = 0; port < host->n_ports; port++) {
+ if (!IS_ERR(hpriv->port_clks[port])) {
+ clk_disable_unprepare(hpriv->port_clks[port]);
+ clk_put(hpriv->port_clks[port]);
+ }
+ }
#endif
return 0;
}