aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1')
-rw-r--r--drivers/w1/masters/ds1wm.c27
1 files changed, 7 insertions, 20 deletions
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index f1e6b3dd1e43..37f08c850608 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -16,7 +16,6 @@
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/clk.h>
20#include <linux/err.h> 19#include <linux/err.h>
21#include <linux/delay.h> 20#include <linux/delay.h>
22#include <linux/mfd/core.h> 21#include <linux/mfd/core.h>
@@ -93,7 +92,6 @@ struct ds1wm_data {
93 struct mfd_cell *cell; 92 struct mfd_cell *cell;
94 int irq; 93 int irq;
95 int active_high; 94 int active_high;
96 struct clk *clk;
97 int slave_present; 95 int slave_present;
98 void *reset_complete; 96 void *reset_complete;
99 void *read_complete; 97 void *read_complete;
@@ -216,17 +214,17 @@ static int ds1wm_find_divisor(int gclk)
216 214
217static void ds1wm_up(struct ds1wm_data *ds1wm_data) 215static void ds1wm_up(struct ds1wm_data *ds1wm_data)
218{ 216{
219 int gclk, divisor; 217 int divisor;
218 struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data;
220 219
221 if (ds1wm_data->cell->enable) 220 if (ds1wm_data->cell->enable)
222 ds1wm_data->cell->enable(ds1wm_data->pdev); 221 ds1wm_data->cell->enable(ds1wm_data->pdev);
223 222
224 gclk = clk_get_rate(ds1wm_data->clk); 223 divisor = ds1wm_find_divisor(plat->clock_rate);
225 clk_enable(ds1wm_data->clk);
226 divisor = ds1wm_find_divisor(gclk);
227 if (divisor == 0) { 224 if (divisor == 0) {
228 dev_err(&ds1wm_data->pdev->dev, 225 dev_err(&ds1wm_data->pdev->dev,
229 "no suitable divisor for %dHz clock\n", gclk); 226 "no suitable divisor for %dHz clock\n",
227 plat->clock_rate);
230 return; 228 return;
231 } 229 }
232 ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor); 230 ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
@@ -247,8 +245,6 @@ static void ds1wm_down(struct ds1wm_data *ds1wm_data)
247 245
248 if (ds1wm_data->cell->disable) 246 if (ds1wm_data->cell->disable)
249 ds1wm_data->cell->disable(ds1wm_data->pdev); 247 ds1wm_data->cell->disable(ds1wm_data->pdev);
250
251 clk_disable(ds1wm_data->clk);
252} 248}
253 249
254/* --------------------------------------------------------------------- */ 250/* --------------------------------------------------------------------- */
@@ -385,26 +381,18 @@ static int ds1wm_probe(struct platform_device *pdev)
385 if (ret) 381 if (ret)
386 goto err1; 382 goto err1;
387 383
388 ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
389 if (IS_ERR(ds1wm_data->clk)) {
390 ret = PTR_ERR(ds1wm_data->clk);
391 goto err2;
392 }
393
394 ds1wm_up(ds1wm_data); 384 ds1wm_up(ds1wm_data);
395 385
396 ds1wm_master.data = (void *)ds1wm_data; 386 ds1wm_master.data = (void *)ds1wm_data;
397 387
398 ret = w1_add_master_device(&ds1wm_master); 388 ret = w1_add_master_device(&ds1wm_master);
399 if (ret) 389 if (ret)
400 goto err3; 390 goto err2;
401 391
402 return 0; 392 return 0;
403 393
404err3:
405 ds1wm_down(ds1wm_data);
406 clk_put(ds1wm_data->clk);
407err2: 394err2:
395 ds1wm_down(ds1wm_data);
408 free_irq(ds1wm_data->irq, ds1wm_data); 396 free_irq(ds1wm_data->irq, ds1wm_data);
409err1: 397err1:
410 iounmap(ds1wm_data->map); 398 iounmap(ds1wm_data->map);
@@ -443,7 +431,6 @@ static int ds1wm_remove(struct platform_device *pdev)
443 431
444 w1_remove_master_device(&ds1wm_master); 432 w1_remove_master_device(&ds1wm_master);
445 ds1wm_down(ds1wm_data); 433 ds1wm_down(ds1wm_data);
446 clk_put(ds1wm_data->clk);
447 free_irq(ds1wm_data->irq, ds1wm_data); 434 free_irq(ds1wm_data->irq, ds1wm_data);
448 iounmap(ds1wm_data->map); 435 iounmap(ds1wm_data->map);
449 kfree(ds1wm_data); 436 kfree(ds1wm_data);