[RFC 09/14] MV SATA: Add per channel clk/clkdev support.
From: Jason <hidden>
Date: 2012-03-06 19:01:39
On Tue, Mar 06, 2012 at 07:31:05AM +0100, Andrew Lunn wrote:
quoted hunk
The Orion kirkwood chips have a gatable clock per SATA channel. Add code to get and enable this clk if it exists. Signed-of-by: Andrew Lunn [off-list ref] --- arch/arm/mach-kirkwood/common.c | 3 ++ arch/arm/plat-orion/common.c | 4 +- arch/arm/plat-orion/include/plat/common.h | 3 ++ drivers/ata/sata_mv.c | 43 +++++++++++++++++++++++++--- 4 files changed, 46 insertions(+), 7 deletions(-)diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 7588812..855540a 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c@@ -244,6 +244,9 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) if (sata_data->n_ports > 1) kirkwood_clk_ctrl |= CGC_SATA1; + orion_clkdev_add("0", "sata_mv.0", &clk_sata0); + orion_clkdev_add("1", "sata_mv.0", &clk_sata1); +
This is a problem for devicetree. With devicetree, neither kirkwood_sata_init(), nor orion_sata_init() are ever called. The same is true for all the other drivers as well. Could this be moved into the driver's _probe() function? thx, Jason.
quoted hunk
orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); }diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 05f078a..06f1e7a 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c@@ -23,8 +23,8 @@ #include <plat/ehci-orion.h> /* Create a clkdev entry for a given device/clk */ -static void orion_clkdev_add(const char *con_id, const char *dev_id, - struct clk *clk) +void orion_clkdev_add(const char *con_id, const char *dev_id, + struct clk *clk) { struct clk_lookup *cl;diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index a70976e..b739343 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h@@ -107,4 +107,7 @@ void __init orion_crypto_init(unsigned long mapbase, unsigned long srambase, unsigned long sram_size, unsigned long irq); + +void orion_clkdev_add(const char *con_id, const char *dev_id, + struct clk *clk); #endifdiff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 38950ea..0f4a7e9 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@@ -4026,6 +4027,9 @@ static int mv_platform_probe(struct platform_device *pdev) struct mv_host_priv *hpriv; struct resource *res; int n_ports, rc; +#if defined(CONFIG_HAVE_CLK) + int port; +#endif ata_print_version_once(&pdev->dev, DRV_VERSION);@@ -4053,6 +4057,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;@@ -4065,9 +4076,18 @@ 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"); - else - clk_enable(hpriv->clk); + dev_notice(&pdev->dev, "cannot get optional clkdev\n"); + else { + 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 /*@@ -4097,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;@@ -4118,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; }-- 1.7.9.1