diff options
author | Simon Glass <sjg@chromium.org> | 2016-01-17 16:11:08 -0700 |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2016-01-24 12:07:19 +0800 |
commit | ac94b7bcbed9a5ee71f6fb9a507c72abf601cb8a (patch) | |
tree | 8158f7f6868c310d114e0336413f75d239850a00 | |
parent | 907eed2ce36db8407d56edc305c32b0923934322 (diff) | |
download | u-boot-imx-ac94b7bcbed9a5ee71f6fb9a507c72abf601cb8a.zip u-boot-imx-ac94b7bcbed9a5ee71f6fb9a507c72abf601cb8a.tar.gz u-boot-imx-ac94b7bcbed9a5ee71f6fb9a507c72abf601cb8a.tar.bz2 |
dm: syscon: Allow finding devices by driver data
We have a way to find a regmap by its syscon driver data value. Add the same
for syscon itself.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r-- | drivers/core/syscon-uclass.c | 31 | ||||
-rw-r--r-- | include/syscon.h | 14 | ||||
-rw-r--r-- | test/dm/syscon.c | 17 |
3 files changed, 50 insertions, 12 deletions
diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index 686c320..a0666d0 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -32,7 +32,7 @@ static int syscon_pre_probe(struct udevice *dev) return regmap_init_mem(dev, &priv->regmap); } -struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) +int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp) { struct udevice *dev; struct uclass *uc; @@ -40,22 +40,29 @@ struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) ret = uclass_get(UCLASS_SYSCON, &uc); if (ret) - return ERR_PTR(ret); + return ret; uclass_foreach_dev(dev, uc) { if (dev->driver_data == driver_data) { - struct syscon_uc_info *priv; - int ret; - - ret = device_probe(dev); - if (ret) - return ERR_PTR(ret); - priv = dev_get_uclass_priv(dev); - - return priv->regmap; + *devp = dev; + return device_probe(dev); } } - return ERR_PTR(-ENODEV); + return -ENODEV; +} + +struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) +{ + struct syscon_uc_info *priv; + struct udevice *dev; + int ret; + + ret = syscon_get_by_driver_data(driver_data, &dev); + if (ret) + return ERR_PTR(ret); + priv = dev_get_uclass_priv(dev); + + return priv->regmap; } void *syscon_get_first_range(ulong driver_data) diff --git a/include/syscon.h b/include/syscon.h index c62ccd6..4593b6e 100644 --- a/include/syscon.h +++ b/include/syscon.h @@ -37,6 +37,20 @@ struct regmap *syscon_get_regmap(struct udevice *dev); * * Each system controller can be accessed by its driver data, which is * assumed to be unique through the scope of all system controllers that + * are in use. This function looks up the controller given this driver data. + * + * @driver_data: Driver data value to look up + * @devp: Returns the controller correponding to @driver_data + * @return 0 on success, -ENODEV if the ID was not found, or other -ve error + * code + */ +int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp); + +/** + * syscon_get_regmap_by_driver_data() - Look up a controller by its ID + * + * Each system controller can be accessed by its driver data, which is + * assumed to be unique through the scope of all system controllers that * are in use. This function looks up the regmap given this driver data. * * @driver_data: Driver data value to look up diff --git a/test/dm/syscon.c b/test/dm/syscon.c index 3642481..c40f5fc 100644 --- a/test/dm/syscon.c +++ b/test/dm/syscon.c @@ -29,3 +29,20 @@ static int dm_test_syscon_base(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_syscon_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test system controller finding */ +static int dm_test_syscon_by_driver_data(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(syscon_get_by_driver_data(SYSCON0, &dev)); + ut_asserteq(SYSCON0, dev->driver_data); + + ut_assertok(syscon_get_by_driver_data(SYSCON1, &dev)); + ut_asserteq(SYSCON1, dev->driver_data); + + ut_asserteq(-ENODEV, syscon_get_by_driver_data(2, &dev)); + + return 0; +} +DM_TEST(dm_test_syscon_by_driver_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |