[ARM] clkdev: fix clock matching
The old matching algorithm was too fuzzy, causing false positives. For example, when asked for device D connection C1 and we only find device D connection C2, we return that as a valid match despite the connection names being different. Change the algorithm such that: An entry with a NULL ID is assumed to be a wildcard. If an entry has a device ID, it must match If an entry has a connection ID, it must match However, we maintain the order of precidence while still only doing a single pass over all entries: dev+con > dev only > con only. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
committed by
Russell King
parent
02e0746ecc
commit
409dc360b4
@@ -24,6 +24,15 @@
|
|||||||
static LIST_HEAD(clocks);
|
static LIST_HEAD(clocks);
|
||||||
static DEFINE_MUTEX(clocks_mutex);
|
static DEFINE_MUTEX(clocks_mutex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the correct struct clk for the device and connection ID.
|
||||||
|
* We do slightly fuzzy matching here:
|
||||||
|
* An entry with a NULL ID is assumed to be a wildcard.
|
||||||
|
* If an entry has a device ID, it must match
|
||||||
|
* If an entry has a connection ID, it must match
|
||||||
|
* Then we take the most specific entry - with the following
|
||||||
|
* order of precidence: dev+con > dev only > con only.
|
||||||
|
*/
|
||||||
static struct clk *clk_find(const char *dev_id, const char *con_id)
|
static struct clk *clk_find(const char *dev_id, const char *con_id)
|
||||||
{
|
{
|
||||||
struct clk_lookup *p;
|
struct clk_lookup *p;
|
||||||
@@ -31,13 +40,17 @@ static struct clk *clk_find(const char *dev_id, const char *con_id)
|
|||||||
int match, best = 0;
|
int match, best = 0;
|
||||||
|
|
||||||
list_for_each_entry(p, &clocks, node) {
|
list_for_each_entry(p, &clocks, node) {
|
||||||
if ((p->dev_id && !dev_id) || (p->con_id && !con_id))
|
|
||||||
continue;
|
|
||||||
match = 0;
|
match = 0;
|
||||||
if (p->dev_id)
|
if (p->dev_id) {
|
||||||
match += 2 * (strcmp(p->dev_id, dev_id) == 0);
|
if (!dev_id || strcmp(p->dev_id, dev_id))
|
||||||
if (p->con_id)
|
continue;
|
||||||
match += 1 * (strcmp(p->con_id, con_id) == 0);
|
match += 2;
|
||||||
|
}
|
||||||
|
if (p->con_id) {
|
||||||
|
if (!con_id || strcmp(p->con_id, con_id))
|
||||||
|
continue;
|
||||||
|
match += 1;
|
||||||
|
}
|
||||||
if (match == 0)
|
if (match == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user