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: Andrew Lunn <andrew@lunn.ch> Tested-by: Jamie Lentin <jm@lentin.co.uk> Signed-off-by: Mike Turquette <mturquette@linaro.org>
This commit is contained in:
parent
74c335761a
commit
eee989902a
2 changed files with 41 additions and 7 deletions
|
@ -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)
|
||||||
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)
|
||||||
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 {
|
||||||
|
|
||||||
#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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
#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)
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue