From: Simon Glass Date: Sun, 17 Jan 2016 23:11:08 +0000 (-0700) Subject: dm: syscon: Allow finding devices by driver data X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=ac94b7bcbed9a5ee71f6fb9a507c72abf601cb8a;p=u-boot.git 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 Reviewed-by: Bin Meng --- diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index 686c32056e..a0666d0bac 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 c62ccd61b3..4593b6e3eb 100644 --- a/include/syscon.h +++ b/include/syscon.h @@ -32,6 +32,20 @@ struct syscon_ops { */ struct regmap *syscon_get_regmap(struct udevice *dev); +/** + * 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 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 * diff --git a/test/dm/syscon.c b/test/dm/syscon.c index 36424816b8..c40f5fc09d 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);