[RFC 09/14] MV SATA: Add per channel clk/clkdev support.
Jason
jason at lakedaemon.net
Tue Mar 6 14:01:39 EST 2012
On Tue, Mar 06, 2012 at 07:31:05AM +0100, Andrew Lunn wrote:
> 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 <andrew at lunn.ch>
> ---
> 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.
> 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);
> #endif
> diff --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
>
More information about the linux-arm-kernel
mailing list