Commit 409dc360 authored by Russell King's avatar Russell King Committed by Russell King

[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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 02e0746e
...@@ -24,6 +24,15 @@ ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment