diff options
-rwxr-xr-x | drivers/mxc/mlb/mxc_mlb150.c | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/drivers/mxc/mlb/mxc_mlb150.c b/drivers/mxc/mlb/mxc_mlb150.c index f0701e52693d..daf578299601 100755 --- a/drivers/mxc/mlb/mxc_mlb150.c +++ b/drivers/mxc/mlb/mxc_mlb150.c | |||
@@ -1908,6 +1908,8 @@ static int mxc_mlb150_open(struct inode *inode, struct file *filp) | |||
1908 | return -EBUSY; | 1908 | return -EBUSY; |
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | clk_prepare_enable(drvdata->clk_mlb3p); | ||
1912 | |||
1911 | /* initial MLB module */ | 1913 | /* initial MLB module */ |
1912 | mlb150_dev_init(); | 1914 | mlb150_dev_init(); |
1913 | 1915 | ||
@@ -1978,15 +1980,23 @@ static int mxc_mlb150_release(struct inode *inode, struct file *filp) | |||
1978 | mlb150_dev_dump_ctr_tbl(0, pdevinfo->channels[TX_CHANNEL].cl + 1); | 1980 | mlb150_dev_dump_ctr_tbl(0, pdevinfo->channels[TX_CHANNEL].cl + 1); |
1979 | #endif | 1981 | #endif |
1980 | 1982 | ||
1981 | /* clear channel settings and info */ | ||
1982 | mlb_channel_enable(drvdata, minor, 0); | ||
1983 | |||
1984 | gen_pool_free(drvdata->iram_pool, | 1983 | gen_pool_free(drvdata->iram_pool, |
1985 | (ulong)pdevinfo->rbuf_base_virt, drvdata->iram_size); | 1984 | (ulong)pdevinfo->rbuf_base_virt, drvdata->iram_size); |
1986 | 1985 | ||
1986 | mlb150_dev_exit(); | ||
1987 | |||
1988 | if (pdevinfo && atomic_read(&pdevinfo->on) | ||
1989 | && (pdevinfo->fps >= CLK_2048FS)) | ||
1990 | clk_disable_unprepare(drvdata->clk_mlb6p); | ||
1991 | |||
1992 | atomic_set(&pdevinfo->on, 0); | ||
1993 | |||
1994 | clk_disable_unprepare(drvdata->clk_mlb3p); | ||
1987 | /* decrease the open count */ | 1995 | /* decrease the open count */ |
1988 | atomic_set(&pdevinfo->opencnt, 0); | 1996 | atomic_set(&pdevinfo->opencnt, 0); |
1989 | 1997 | ||
1998 | drvdata->devinfo = NULL; | ||
1999 | |||
1990 | return 0; | 2000 | return 0; |
1991 | } | 2001 | } |
1992 | 2002 | ||
@@ -2596,30 +2606,28 @@ static int mxc_mlb150_probe(struct platform_device *pdev) | |||
2596 | if (IS_ERR(drvdata->clk_mlb3p)) { | 2606 | if (IS_ERR(drvdata->clk_mlb3p)) { |
2597 | dev_err(&pdev->dev, "unable to get mlb clock\n"); | 2607 | dev_err(&pdev->dev, "unable to get mlb clock\n"); |
2598 | ret = PTR_ERR(drvdata->clk_mlb3p); | 2608 | ret = PTR_ERR(drvdata->clk_mlb3p); |
2599 | goto err_clk; | 2609 | goto err_dev; |
2600 | } | 2610 | } |
2601 | clk_prepare_enable(drvdata->clk_mlb3p); | ||
2602 | 2611 | ||
2603 | drvdata->clk_mlb6p = devm_clk_get(&pdev->dev, "pll8_mlb"); | 2612 | drvdata->clk_mlb6p = devm_clk_get(&pdev->dev, "pll8_mlb"); |
2604 | if (IS_ERR(drvdata->clk_mlb6p)) { | 2613 | if (IS_ERR(drvdata->clk_mlb6p)) { |
2605 | dev_err(&pdev->dev, "unable to get mlb pll clock\n"); | 2614 | dev_err(&pdev->dev, "unable to get mlb pll clock\n"); |
2606 | ret = PTR_ERR(drvdata->clk_mlb6p); | 2615 | ret = PTR_ERR(drvdata->clk_mlb6p); |
2607 | goto err_clk; | 2616 | goto err_dev; |
2608 | } | 2617 | } |
2609 | 2618 | ||
2619 | |||
2610 | drvdata->iram_pool = of_get_named_gen_pool(np, "iram", 0); | 2620 | drvdata->iram_pool = of_get_named_gen_pool(np, "iram", 0); |
2611 | if (!drvdata->iram_pool) { | 2621 | if (!drvdata->iram_pool) { |
2612 | dev_err(&pdev->dev, "iram pool not available\n"); | 2622 | dev_err(&pdev->dev, "iram pool not available\n"); |
2613 | ret = -ENOMEM; | 2623 | ret = -ENOMEM; |
2614 | goto err_clk; | 2624 | goto err_dev; |
2615 | } | 2625 | } |
2616 | 2626 | ||
2627 | drvdata->devinfo = NULL; | ||
2617 | platform_set_drvdata(pdev, drvdata); | 2628 | platform_set_drvdata(pdev, drvdata); |
2618 | return 0; | 2629 | return 0; |
2619 | 2630 | ||
2620 | err_clk: | ||
2621 | if (!IS_ERR(drvdata->clk_mlb3p)) | ||
2622 | clk_disable_unprepare(drvdata->clk_mlb3p); | ||
2623 | err_dev: | 2631 | err_dev: |
2624 | for (--i; i >= 0; i--) | 2632 | for (--i; i >= 0; i--) |
2625 | device_destroy(drvdata->class, MKDEV(mlb_major, i)); | 2633 | device_destroy(drvdata->class, MKDEV(mlb_major, i)); |
@@ -2637,11 +2645,13 @@ static int mxc_mlb150_remove(struct platform_device *pdev) | |||
2637 | { | 2645 | { |
2638 | int i; | 2646 | int i; |
2639 | struct mlb_data *drvdata = platform_get_drvdata(pdev); | 2647 | struct mlb_data *drvdata = platform_get_drvdata(pdev); |
2648 | struct mlb_dev_info *pdevinfo = drvdata->devinfo; | ||
2640 | 2649 | ||
2641 | mlb150_dev_exit(); | 2650 | if (pdevinfo && atomic_read(&pdevinfo->on) |
2651 | && (pdevinfo->fps >= CLK_2048FS)) | ||
2652 | clk_disable_unprepare(drvdata->clk_mlb6p); | ||
2642 | 2653 | ||
2643 | /* disable mlb clock */ | 2654 | if (pdevinfo && atomic_read(&pdevinfo->opencnt)) |
2644 | if (!IS_ERR(drvdata->clk_mlb3p)) | ||
2645 | clk_disable_unprepare(drvdata->clk_mlb3p); | 2655 | clk_disable_unprepare(drvdata->clk_mlb3p); |
2646 | 2656 | ||
2647 | /* disable mlb power */ | 2657 | /* disable mlb power */ |
@@ -2668,10 +2678,16 @@ static int mxc_mlb150_remove(struct platform_device *pdev) | |||
2668 | static int mxc_mlb150_suspend(struct platform_device *pdev, pm_message_t state) | 2678 | static int mxc_mlb150_suspend(struct platform_device *pdev, pm_message_t state) |
2669 | { | 2679 | { |
2670 | struct mlb_data *drvdata = platform_get_drvdata(pdev); | 2680 | struct mlb_data *drvdata = platform_get_drvdata(pdev); |
2681 | struct mlb_dev_info *pdevinfo = drvdata->devinfo; | ||
2671 | 2682 | ||
2672 | mlb150_dev_exit(); | 2683 | mlb150_dev_exit(); |
2673 | 2684 | ||
2674 | clk_disable_unprepare(drvdata->clk_mlb3p); | 2685 | if (pdevinfo && atomic_read(&pdevinfo->on) |
2686 | && (pdevinfo->fps >= CLK_2048FS)) | ||
2687 | clk_disable_unprepare(drvdata->clk_mlb6p); | ||
2688 | |||
2689 | if (pdevinfo && atomic_read(&pdevinfo->opencnt)) | ||
2690 | clk_disable_unprepare(drvdata->clk_mlb3p); | ||
2675 | 2691 | ||
2676 | return 0; | 2692 | return 0; |
2677 | } | 2693 | } |
@@ -2679,8 +2695,14 @@ static int mxc_mlb150_suspend(struct platform_device *pdev, pm_message_t state) | |||
2679 | static int mxc_mlb150_resume(struct platform_device *pdev) | 2695 | static int mxc_mlb150_resume(struct platform_device *pdev) |
2680 | { | 2696 | { |
2681 | struct mlb_data *drvdata = platform_get_drvdata(pdev); | 2697 | struct mlb_data *drvdata = platform_get_drvdata(pdev); |
2698 | struct mlb_dev_info *pdevinfo = drvdata->devinfo; | ||
2682 | 2699 | ||
2683 | clk_prepare_enable(drvdata->clk_mlb6p); | 2700 | if (pdevinfo && atomic_read(&pdevinfo->opencnt)) |
2701 | clk_prepare_enable(drvdata->clk_mlb3p); | ||
2702 | |||
2703 | if (pdevinfo && atomic_read(&pdevinfo->on) && | ||
2704 | (pdevinfo->fps >= CLK_2048FS)) | ||
2705 | clk_prepare_enable(drvdata->clk_mlb6p); | ||
2684 | 2706 | ||
2685 | mlb150_dev_init(); | 2707 | mlb150_dev_init(); |
2686 | 2708 | ||