summaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2011-05-18 10:27:39 -0500
committerGrant Likely <grant.likely@secretlab.ca>2011-05-18 10:19:36 -0600
commit01294d82622d6d9d64bde8e4530c7e2c6dbb6ee6 (patch)
tree98707dfac7c9533dbfef30c4ff05c0dfdabc17a6 /include/linux
parent2e9521fd656f05a716b5294a7dbebd37ced05e43 (diff)
downloadlinux-01294d82622d6d9d64bde8e4530c7e2c6dbb6ee6.tar.gz
linux-01294d82622d6d9d64bde8e4530c7e2c6dbb6ee6.tar.bz2
linux-01294d82622d6d9d64bde8e4530c7e2c6dbb6ee6.zip
of: fix race when matching drivers
If two drivers are probing devices at the same time, both will write their match table result to the dev->of_match cache at the same time. Only write the result if the device matches. In a thread titled "SBus devices sometimes detected, sometimes not", Meelis reported his SBus hme was not detected about 50% of the time. From the debug suggested by Grant it was obvious another driver matched some devices between the call to match the hme and the hme discovery failling. Reported-by: Meelis Roos <mroos@linux.ee> Signed-off-by: Milton Miller <miltonm@bga.com> [grant.likely: modified to only call of_match_device() once] Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/of_device.h8
1 files changed, 6 insertions, 2 deletions
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 8bfe6c1d4365..b33d68814a73 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -21,8 +21,12 @@ extern void of_device_make_bus_id(struct device *dev);
static inline int of_driver_match_device(struct device *dev,
const struct device_driver *drv)
{
- dev->of_match = of_match_device(drv->of_match_table, dev);
- return dev->of_match != NULL;
+ const struct of_device_id *match;
+
+ match = of_match_device(drv->of_match_table, dev);
+ if (match)
+ dev->of_match = match;
+ return match != NULL;
}
extern struct platform_device *of_dev_get(struct platform_device *dev);