diff options
Diffstat (limited to 'drivers/devfreq')
-rw-r--r-- | drivers/devfreq/devfreq.c | 42 | ||||
-rw-r--r-- | drivers/devfreq/exynos4_bus.c | 14 |
2 files changed, 48 insertions, 8 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index a129a7b6bfd1..70c31d43fff3 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
@@ -83,6 +83,7 @@ int update_devfreq(struct devfreq *devfreq) | |||
83 | { | 83 | { |
84 | unsigned long freq; | 84 | unsigned long freq; |
85 | int err = 0; | 85 | int err = 0; |
86 | u32 flags = 0; | ||
86 | 87 | ||
87 | if (!mutex_is_locked(&devfreq->lock)) { | 88 | if (!mutex_is_locked(&devfreq->lock)) { |
88 | WARN(true, "devfreq->lock must be locked by the caller.\n"); | 89 | WARN(true, "devfreq->lock must be locked by the caller.\n"); |
@@ -94,7 +95,24 @@ int update_devfreq(struct devfreq *devfreq) | |||
94 | if (err) | 95 | if (err) |
95 | return err; | 96 | return err; |
96 | 97 | ||
97 | err = devfreq->profile->target(devfreq->dev.parent, &freq); | 98 | /* |
99 | * Adjust the freuqency with user freq and QoS. | ||
100 | * | ||
101 | * List from the highest proiority | ||
102 | * max_freq (probably called by thermal when it's too hot) | ||
103 | * min_freq | ||
104 | */ | ||
105 | |||
106 | if (devfreq->min_freq && freq < devfreq->min_freq) { | ||
107 | freq = devfreq->min_freq; | ||
108 | flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */ | ||
109 | } | ||
110 | if (devfreq->max_freq && freq > devfreq->max_freq) { | ||
111 | freq = devfreq->max_freq; | ||
112 | flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ | ||
113 | } | ||
114 | |||
115 | err = devfreq->profile->target(devfreq->dev.parent, &freq, flags); | ||
98 | if (err) | 116 | if (err) |
99 | return err; | 117 | return err; |
100 | 118 | ||
@@ -625,14 +643,30 @@ module_exit(devfreq_exit); | |||
625 | * freq value given to target callback. | 643 | * freq value given to target callback. |
626 | * @dev The devfreq user device. (parent of devfreq) | 644 | * @dev The devfreq user device. (parent of devfreq) |
627 | * @freq The frequency given to target function | 645 | * @freq The frequency given to target function |
646 | * @flags Flags handed from devfreq framework. | ||
628 | * | 647 | * |
629 | */ | 648 | */ |
630 | struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq) | 649 | struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, |
650 | u32 flags) | ||
631 | { | 651 | { |
632 | struct opp *opp = opp_find_freq_ceil(dev, freq); | 652 | struct opp *opp; |
633 | 653 | ||
634 | if (opp == ERR_PTR(-ENODEV)) | 654 | if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { |
655 | /* The freq is an upper bound. opp should be lower */ | ||
635 | opp = opp_find_freq_floor(dev, freq); | 656 | opp = opp_find_freq_floor(dev, freq); |
657 | |||
658 | /* If not available, use the closest opp */ | ||
659 | if (opp == ERR_PTR(-ENODEV)) | ||
660 | opp = opp_find_freq_ceil(dev, freq); | ||
661 | } else { | ||
662 | /* The freq is an lower bound. opp should be higher */ | ||
663 | opp = opp_find_freq_ceil(dev, freq); | ||
664 | |||
665 | /* If not available, use the closest opp */ | ||
666 | if (opp == ERR_PTR(-ENODEV)) | ||
667 | opp = opp_find_freq_floor(dev, freq); | ||
668 | } | ||
669 | |||
636 | return opp; | 670 | return opp; |
637 | } | 671 | } |
638 | 672 | ||
diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 590d6865e388..1a361e99965a 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c | |||
@@ -619,13 +619,19 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, | |||
619 | return err; | 619 | return err; |
620 | } | 620 | } |
621 | 621 | ||
622 | static int exynos4_bus_target(struct device *dev, unsigned long *_freq) | 622 | static int exynos4_bus_target(struct device *dev, unsigned long *_freq, |
623 | u32 flags) | ||
623 | { | 624 | { |
624 | int err = 0; | 625 | int err = 0; |
625 | struct busfreq_data *data = dev_get_drvdata(dev); | 626 | struct platform_device *pdev = container_of(dev, struct platform_device, |
626 | struct opp *opp = devfreq_recommended_opp(dev, _freq); | 627 | dev); |
627 | unsigned long old_freq = opp_get_freq(data->curr_opp); | 628 | struct busfreq_data *data = platform_get_drvdata(pdev); |
629 | struct opp *opp = devfreq_recommended_opp(dev, _freq, flags); | ||
628 | unsigned long freq = opp_get_freq(opp); | 630 | unsigned long freq = opp_get_freq(opp); |
631 | unsigned long old_freq = opp_get_freq(data->curr_opp); | ||
632 | |||
633 | if (IS_ERR(opp)) | ||
634 | return PTR_ERR(opp); | ||
629 | 635 | ||
630 | if (old_freq == freq) | 636 | if (old_freq == freq) |
631 | return 0; | 637 | return 0; |