Thread (1 message) 1 message, 1 author, 2012-03-06

[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);
 #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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help