aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2012-02-18 16:26:42 -0500
committerMike Turquette <mturquette@linaro.org>2012-05-08 19:33:58 -0400
commiteee989902aab45f0ca2739727ef615420802649c (patch)
tree062debde96c0ffb0d13c151e81f9d41561cd20d0 /drivers/ata/sata_mv.c
parent74c335761acdfd94736d28ba0b941a2efb9c81f0 (diff)
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>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r--drivers/ata/sata_mv.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 7336d4a7ab31..24712adf69df 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -553,6 +553,7 @@ struct mv_host_priv {
553 553
554#if defined(CONFIG_HAVE_CLK) 554#if defined(CONFIG_HAVE_CLK)
555 struct clk *clk; 555 struct clk *clk;
556 struct clk **port_clks;
556#endif 557#endif
557 /* 558 /*
558 * These consistent DMA memory pools give us guaranteed 559 * These consistent DMA memory pools give us guaranteed
@@ -4027,6 +4028,9 @@ static int mv_platform_probe(struct platform_device *pdev)
4027 struct resource *res; 4028 struct resource *res;
4028 int n_ports = 0; 4029 int n_ports = 0;
4029 int rc; 4030 int rc;
4031#if defined(CONFIG_HAVE_CLK)
4032 int port;
4033#endif
4030 4034
4031 ata_print_version_once(&pdev->dev, DRV_VERSION); 4035 ata_print_version_once(&pdev->dev, DRV_VERSION);
4032 4036
@@ -4054,6 +4058,13 @@ static int mv_platform_probe(struct platform_device *pdev)
4054 4058
4055 if (!host || !hpriv) 4059 if (!host || !hpriv)
4056 return -ENOMEM; 4060 return -ENOMEM;
4061#if defined(CONFIG_HAVE_CLK)
4062 hpriv->port_clks = devm_kzalloc(&pdev->dev,
4063 sizeof(struct clk *) * n_ports,
4064 GFP_KERNEL);
4065 if (!hpriv->port_clks)
4066 return -ENOMEM;
4067#endif
4057 host->private_data = hpriv; 4068 host->private_data = hpriv;
4058 hpriv->n_ports = n_ports; 4069 hpriv->n_ports = n_ports;
4059 hpriv->board_idx = chip_soc; 4070 hpriv->board_idx = chip_soc;
@@ -4066,9 +4077,17 @@ static int mv_platform_probe(struct platform_device *pdev)
4066#if defined(CONFIG_HAVE_CLK) 4077#if defined(CONFIG_HAVE_CLK)
4067 hpriv->clk = clk_get(&pdev->dev, NULL); 4078 hpriv->clk = clk_get(&pdev->dev, NULL);
4068 if (IS_ERR(hpriv->clk)) 4079 if (IS_ERR(hpriv->clk))
4069 dev_notice(&pdev->dev, "cannot get clkdev\n"); 4080 dev_notice(&pdev->dev, "cannot get optional clkdev\n");
4070 else 4081 else
4071 clk_enable(hpriv->clk); 4082 clk_prepare_enable(hpriv->clk);
4083
4084 for (port = 0; port < n_ports; port++) {
4085 char port_number[16];
4086 sprintf(port_number, "%d", port);
4087 hpriv->port_clks[port] = clk_get(&pdev->dev, port_number);
4088 if (!IS_ERR(hpriv->port_clks[port]))
4089 clk_prepare_enable(hpriv->port_clks[port]);
4090 }
4072#endif 4091#endif
4073 4092
4074 /* 4093 /*
@@ -4098,9 +4117,15 @@ static int mv_platform_probe(struct platform_device *pdev)
4098err: 4117err:
4099#if defined(CONFIG_HAVE_CLK) 4118#if defined(CONFIG_HAVE_CLK)
4100 if (!IS_ERR(hpriv->clk)) { 4119 if (!IS_ERR(hpriv->clk)) {
4101 clk_disable(hpriv->clk); 4120 clk_disable_unprepare(hpriv->clk);
4102 clk_put(hpriv->clk); 4121 clk_put(hpriv->clk);
4103 } 4122 }
4123 for (port = 0; port < n_ports; port++) {
4124 if (!IS_ERR(hpriv->port_clks[port])) {
4125 clk_disable_unprepare(hpriv->port_clks[port]);
4126 clk_put(hpriv->port_clks[port]);
4127 }
4128 }
4104#endif 4129#endif
4105 4130
4106 return rc; 4131 return rc;
@@ -4119,14 +4144,21 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
4119 struct ata_host *host = platform_get_drvdata(pdev); 4144 struct ata_host *host = platform_get_drvdata(pdev);
4120#if defined(CONFIG_HAVE_CLK) 4145#if defined(CONFIG_HAVE_CLK)
4121 struct mv_host_priv *hpriv = host->private_data; 4146 struct mv_host_priv *hpriv = host->private_data;
4147 int port;
4122#endif 4148#endif
4123 ata_host_detach(host); 4149 ata_host_detach(host);
4124 4150
4125#if defined(CONFIG_HAVE_CLK) 4151#if defined(CONFIG_HAVE_CLK)
4126 if (!IS_ERR(hpriv->clk)) { 4152 if (!IS_ERR(hpriv->clk)) {
4127 clk_disable(hpriv->clk); 4153 clk_disable_unprepare(hpriv->clk);
4128 clk_put(hpriv->clk); 4154 clk_put(hpriv->clk);
4129 } 4155 }
4156 for (port = 0; port < host->n_ports; port++) {
4157 if (!IS_ERR(hpriv->port_clks[port])) {
4158 clk_disable_unprepare(hpriv->port_clks[port]);
4159 clk_put(hpriv->port_clks[port]);
4160 }
4161 }
4130#endif 4162#endif
4131 return 0; 4163 return 0;
4132} 4164}