diff options
author | Magnus Damm <damm@igel.co.jp> | 2008-10-31 07:23:26 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-12-22 04:42:52 -0500 |
commit | b51339fff240ff179730f8963a758147fd60f3ec (patch) | |
tree | 745058a3e57b019437c5df2ab3de8b4dd5dca958 /drivers/video/sh_mobile_lcdcfb.c | |
parent | 765786e0aead7faf6c333176d22948c6f155fff1 (diff) |
sh: sh_mobile lcdc clock framework support
Add clock framework support to the lcdc driver and
adjust the board specific code accordingly.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video/sh_mobile_lcdcfb.c')
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index efff672fd7b8..c81ee00c54d7 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -35,6 +35,7 @@ struct sh_mobile_lcdc_chan { | |||
35 | struct sh_mobile_lcdc_priv { | 35 | struct sh_mobile_lcdc_priv { |
36 | void __iomem *base; | 36 | void __iomem *base; |
37 | #ifdef CONFIG_HAVE_CLK | 37 | #ifdef CONFIG_HAVE_CLK |
38 | struct clk *dot_clk; | ||
38 | struct clk *clk; | 39 | struct clk *clk; |
39 | #endif | 40 | #endif |
40 | unsigned long lddckr; | 41 | unsigned long lddckr; |
@@ -207,6 +208,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
207 | int k, m; | 208 | int k, m; |
208 | int ret = 0; | 209 | int ret = 0; |
209 | 210 | ||
211 | #ifdef CONFIG_HAVE_CLK | ||
212 | clk_enable(priv->clk); | ||
213 | if (priv->dot_clk) | ||
214 | clk_enable(priv->dot_clk); | ||
215 | #endif | ||
210 | /* reset */ | 216 | /* reset */ |
211 | lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); | 217 | lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); |
212 | lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); | 218 | lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); |
@@ -371,6 +377,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
371 | 377 | ||
372 | /* stop the lcdc */ | 378 | /* stop the lcdc */ |
373 | sh_mobile_lcdc_start_stop(priv, 0); | 379 | sh_mobile_lcdc_start_stop(priv, 0); |
380 | |||
381 | #ifdef CONFIG_HAVE_CLK | ||
382 | if (priv->dot_clk) | ||
383 | clk_disable(priv->dot_clk); | ||
384 | clk_disable(priv->clk); | ||
385 | #endif | ||
374 | } | 386 | } |
375 | 387 | ||
376 | static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) | 388 | static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) |
@@ -413,9 +425,13 @@ static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) | |||
413 | return -EINVAL; | 425 | return -EINVAL; |
414 | } | 426 | } |
415 | 427 | ||
416 | static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, | 428 | static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, |
429 | int clock_source, | ||
417 | struct sh_mobile_lcdc_priv *priv) | 430 | struct sh_mobile_lcdc_priv *priv) |
418 | { | 431 | { |
432 | #ifdef CONFIG_HAVE_CLK | ||
433 | char clk_name[8]; | ||
434 | #endif | ||
419 | char *str; | 435 | char *str; |
420 | int icksel; | 436 | int icksel; |
421 | 437 | ||
@@ -430,14 +446,20 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, | |||
430 | priv->lddckr = icksel << 16; | 446 | priv->lddckr = icksel << 16; |
431 | 447 | ||
432 | #ifdef CONFIG_HAVE_CLK | 448 | #ifdef CONFIG_HAVE_CLK |
449 | snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id); | ||
450 | priv->clk = clk_get(&pdev->dev, clk_name); | ||
451 | if (IS_ERR(priv->clk)) { | ||
452 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | ||
453 | return PTR_ERR(priv->clk); | ||
454 | } | ||
455 | |||
433 | if (str) { | 456 | if (str) { |
434 | priv->clk = clk_get(dev, str); | 457 | priv->dot_clk = clk_get(&pdev->dev, str); |
435 | if (IS_ERR(priv->clk)) { | 458 | if (IS_ERR(priv->dot_clk)) { |
436 | dev_err(dev, "cannot get clock %s\n", str); | 459 | dev_err(&pdev->dev, "cannot get dot clock %s\n", str); |
437 | return PTR_ERR(priv->clk); | 460 | clk_put(priv->clk); |
461 | return PTR_ERR(priv->dot_clk); | ||
438 | } | 462 | } |
439 | |||
440 | clk_enable(priv->clk); | ||
441 | } | 463 | } |
442 | #endif | 464 | #endif |
443 | 465 | ||
@@ -587,8 +609,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
587 | goto err1; | 609 | goto err1; |
588 | } | 610 | } |
589 | 611 | ||
590 | error = sh_mobile_lcdc_setup_clocks(&pdev->dev, | 612 | error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); |
591 | pdata->clock_source, priv); | ||
592 | if (error) { | 613 | if (error) { |
593 | dev_err(&pdev->dev, "unable to setup clocks\n"); | 614 | dev_err(&pdev->dev, "unable to setup clocks\n"); |
594 | goto err1; | 615 | goto err1; |
@@ -697,10 +718,9 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
697 | } | 718 | } |
698 | 719 | ||
699 | #ifdef CONFIG_HAVE_CLK | 720 | #ifdef CONFIG_HAVE_CLK |
700 | if (priv->clk) { | 721 | if (priv->dot_clk) |
701 | clk_disable(priv->clk); | 722 | clk_put(priv->dot_clk); |
702 | clk_put(priv->clk); | 723 | clk_put(priv->clk); |
703 | } | ||
704 | #endif | 724 | #endif |
705 | 725 | ||
706 | if (priv->base) | 726 | if (priv->base) |