Commit eee98990 authored by Andrew Lunn's avatar Andrew Lunn Committed by Mike Turquette

ARM: Orion: SATA: Add per channel clk/clkdev support.

The Orion kirkwood chips have a gatable clock per SATA channel. Add
code to get and enable this clk if it exists.
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Tested-by: default avatarJamie Lentin <jm@lentin.co.uk>
Signed-off-by: default avatarMike Turquette <mturquette@linaro.org>
parent 74c33576
...@@ -86,7 +86,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) ...@@ -86,7 +86,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)
void __init kirkwood_clk_init(void) void __init kirkwood_clk_init(void)
{ {
struct clk *runit, *ge0, *ge1; struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0;
tclk = clk_register_fixed_rate(NULL, "tclk", NULL, tclk = clk_register_fixed_rate(NULL, "tclk", NULL,
CLK_IS_ROOT, kirkwood_tclk); CLK_IS_ROOT, kirkwood_tclk);
...@@ -94,8 +94,8 @@ void __init kirkwood_clk_init(void) ...@@ -94,8 +94,8 @@ void __init kirkwood_clk_init(void)
runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT);
ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0);
ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1);
kirkwood_register_gate("sata0", CGC_BIT_SATA0); sata0 = kirkwood_register_gate("sata0", CGC_BIT_SATA0);
kirkwood_register_gate("sata1", CGC_BIT_SATA1); sata1 = kirkwood_register_gate("sata1", CGC_BIT_SATA1);
kirkwood_register_gate("usb0", CGC_BIT_USB0); kirkwood_register_gate("usb0", CGC_BIT_USB0);
kirkwood_register_gate("sdio", CGC_BIT_SDIO); kirkwood_register_gate("sdio", CGC_BIT_SDIO);
kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); kirkwood_register_gate("crypto", CGC_BIT_CRYPTO);
...@@ -113,6 +113,8 @@ void __init kirkwood_clk_init(void) ...@@ -113,6 +113,8 @@ void __init kirkwood_clk_init(void)
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0);
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1);
orion_clkdev_add(NULL, "orion_wdt", tclk); orion_clkdev_add(NULL, "orion_wdt", tclk);
orion_clkdev_add("0", "sata_mv.0", sata0);
orion_clkdev_add("1", "sata_mv.0", sata1);
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -553,6 +553,7 @@ struct mv_host_priv { ...@@ -553,6 +553,7 @@ struct mv_host_priv {
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
struct clk *clk; struct clk *clk;
struct clk **port_clks;
#endif #endif
/* /*
* These consistent DMA memory pools give us guaranteed * These consistent DMA memory pools give us guaranteed
...@@ -4027,6 +4028,9 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4027,6 +4028,9 @@ static int mv_platform_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int n_ports = 0; int n_ports = 0;
int rc; int rc;
#if defined(CONFIG_HAVE_CLK)
int port;
#endif
ata_print_version_once(&pdev->dev, DRV_VERSION); ata_print_version_once(&pdev->dev, DRV_VERSION);
...@@ -4054,6 +4058,13 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4054,6 +4058,13 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!host || !hpriv) if (!host || !hpriv)
return -ENOMEM; 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; host->private_data = hpriv;
hpriv->n_ports = n_ports; hpriv->n_ports = n_ports;
hpriv->board_idx = chip_soc; hpriv->board_idx = chip_soc;
...@@ -4066,9 +4077,17 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4066,9 +4077,17 @@ static int mv_platform_probe(struct platform_device *pdev)
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
hpriv->clk = clk_get(&pdev->dev, NULL); hpriv->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(hpriv->clk)) if (IS_ERR(hpriv->clk))
dev_notice(&pdev->dev, "cannot get clkdev\n"); dev_notice(&pdev->dev, "cannot get optional clkdev\n");
else 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 #endif
/* /*
...@@ -4098,9 +4117,15 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4098,9 +4117,15 @@ static int mv_platform_probe(struct platform_device *pdev)
err: err:
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) { if (!IS_ERR(hpriv->clk)) {
clk_disable(hpriv->clk); clk_disable_unprepare(hpriv->clk);
clk_put(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 #endif
return rc; return rc;
...@@ -4119,14 +4144,21 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) ...@@ -4119,14 +4144,21 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
struct ata_host *host = platform_get_drvdata(pdev); struct ata_host *host = platform_get_drvdata(pdev);
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
struct mv_host_priv *hpriv = host->private_data; struct mv_host_priv *hpriv = host->private_data;
int port;
#endif #endif
ata_host_detach(host); ata_host_detach(host);
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) { if (!IS_ERR(hpriv->clk)) {
clk_disable(hpriv->clk); clk_disable_unprepare(hpriv->clk);
clk_put(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 #endif
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment