1 /* 2 * Copyright (C) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <syscon.h> 10 #include <dm.h> 11 #include <errno.h> 12 #include <regmap.h> 13 #include <dm/device-internal.h> 14 #include <dm/lists.h> 15 #include <dm/root.h> 16 #include <linux/err.h> 17 18 struct regmap *syscon_get_regmap(struct udevice *dev) 19 { 20 struct syscon_uc_info *priv = dev_get_uclass_priv(dev); 21 22 return priv->regmap; 23 } 24 25 static int syscon_pre_probe(struct udevice *dev) 26 { 27 struct syscon_uc_info *priv = dev_get_uclass_priv(dev); 28 29 return regmap_init_mem(dev, &priv->regmap); 30 } 31 32 struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) 33 { 34 struct udevice *dev; 35 struct uclass *uc; 36 int ret; 37 38 ret = uclass_get(UCLASS_SYSCON, &uc); 39 if (ret) 40 return ERR_PTR(ret); 41 uclass_foreach_dev(dev, uc) { 42 if (dev->driver_data == driver_data) { 43 struct syscon_uc_info *priv; 44 int ret; 45 46 ret = device_probe(dev); 47 if (ret) 48 return ERR_PTR(ret); 49 priv = dev_get_uclass_priv(dev); 50 51 return priv->regmap; 52 } 53 } 54 55 return ERR_PTR(-ENOENT); 56 } 57 58 void *syscon_get_first_range(ulong driver_data) 59 { 60 struct regmap *map; 61 62 map = syscon_get_regmap_by_driver_data(driver_data); 63 if (IS_ERR(map)) 64 return map; 65 return regmap_get_range(map, 0); 66 } 67 68 UCLASS_DRIVER(syscon) = { 69 .id = UCLASS_SYSCON, 70 .name = "syscon", 71 .per_device_auto_alloc_size = sizeof(struct syscon_uc_info), 72 .pre_probe = syscon_pre_probe, 73 }; 74