diff options
author | Andrew Lunn <andrew@lunn.ch> | 2012-02-18 16:26:42 -0500 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2012-05-08 19:33:58 -0400 |
commit | eee989902aab45f0ca2739727ef615420802649c (patch) | |
tree | 062debde96c0ffb0d13c151e81f9d41561cd20d0 /drivers/ata/sata_mv.c | |
parent | 74c335761acdfd94736d28ba0b941a2efb9c81f0 (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.c | 40 |
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) | |||
4098 | err: | 4117 | err: |
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 | } |