diff options
Diffstat (limited to 'drivers/devfreq/devfreq.c')
-rw-r--r-- | drivers/devfreq/devfreq.c | 42 |
1 files changed, 38 insertions, 4 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 | ||