diff --git a/drivers/opp/core.c b/drivers/opp/core.c index d695f68fba8c..e732f97dc2f6 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -481,10 +481,15 @@ static struct dev_pm_opp *_opp_table_find_key(struct opp_table *opp_table, unsigned long *key, int index, bool available, unsigned long (*read)(struct dev_pm_opp *opp, int index), bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, - unsigned long opp_key, unsigned long key)) + unsigned long opp_key, unsigned long key), + bool (*assert)(struct opp_table *opp_table)) { struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); + /* Assert that the requirement is met */ + if (assert && !assert(opp_table)) + return ERR_PTR(-EINVAL); + mutex_lock(&opp_table->lock); list_for_each_entry(temp_opp, &opp_table->opp_list, node) { @@ -509,7 +514,8 @@ static struct dev_pm_opp * _find_key(struct device *dev, unsigned long *key, int index, bool available, unsigned long (*read)(struct dev_pm_opp *opp, int index), bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, - unsigned long opp_key, unsigned long key)) + unsigned long opp_key, unsigned long key), + bool (*assert)(struct opp_table *opp_table)) { struct opp_table *opp_table; struct dev_pm_opp *opp; @@ -522,7 +528,7 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available, } opp = _opp_table_find_key(opp_table, key, index, available, read, - compare); + compare, assert); dev_pm_opp_put_opp_table(opp_table); @@ -531,35 +537,42 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available, static struct dev_pm_opp *_find_key_exact(struct device *dev, unsigned long key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { /* * The value of key will be updated here, but will be ignored as the * caller doesn't need it. */ - return _find_key(dev, &key, index, available, read, _compare_exact); + return _find_key(dev, &key, index, available, read, _compare_exact, + assert); } static struct dev_pm_opp *_opp_table_find_key_ceil(struct opp_table *opp_table, unsigned long *key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { return _opp_table_find_key(opp_table, key, index, available, read, - _compare_ceil); + _compare_ceil, assert); } static struct dev_pm_opp *_find_key_ceil(struct device *dev, unsigned long *key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { - return _find_key(dev, key, index, available, read, _compare_ceil); + return _find_key(dev, key, index, available, read, _compare_ceil, + assert); } static struct dev_pm_opp *_find_key_floor(struct device *dev, unsigned long *key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { - return _find_key(dev, key, index, available, read, _compare_floor); + return _find_key(dev, key, index, available, read, _compare_floor, + assert); } /** @@ -588,14 +601,15 @@ static struct dev_pm_opp *_find_key_floor(struct device *dev, struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, bool available) { - return _find_key_exact(dev, freq, 0, available, _read_freq); + return _find_key_exact(dev, freq, 0, available, _read_freq, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table, unsigned long *freq) { - return _opp_table_find_key_ceil(opp_table, freq, 0, true, _read_freq); + return _opp_table_find_key_ceil(opp_table, freq, 0, true, _read_freq, + NULL); } /** @@ -619,7 +633,7 @@ static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table, struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) { - return _find_key_ceil(dev, freq, 0, true, _read_freq); + return _find_key_ceil(dev, freq, 0, true, _read_freq, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); @@ -644,7 +658,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq) { - return _find_key_floor(dev, freq, 0, true, _read_freq); + return _find_key_floor(dev, freq, 0, true, _read_freq, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); @@ -666,7 +680,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, unsigned int level) { - return _find_key_exact(dev, level, 0, true, _read_level); + return _find_key_exact(dev, level, 0, true, _read_level, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_exact); @@ -691,7 +705,7 @@ struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, unsigned long temp = *level; struct dev_pm_opp *opp; - opp = _find_key_ceil(dev, &temp, 0, true, _read_level); + opp = _find_key_ceil(dev, &temp, 0, true, _read_level, NULL); *level = temp; return opp; } @@ -722,7 +736,7 @@ struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, unsigned int *bw, unsigned long temp = *bw; struct dev_pm_opp *opp; - opp = _find_key_ceil(dev, &temp, index, true, _read_bw); + opp = _find_key_ceil(dev, &temp, index, true, _read_bw, NULL); *bw = temp; return opp; } @@ -753,7 +767,7 @@ struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, unsigned long temp = *bw; struct dev_pm_opp *opp; - opp = _find_key_floor(dev, &temp, index, true, _read_bw); + opp = _find_key_floor(dev, &temp, index, true, _read_bw, NULL); *bw = temp; return opp; }