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; 21 22 if (device_get_uclass_id(dev) != UCLASS_SYSCON) 23 return ERR_PTR(-ENOEXEC); 24 priv = dev_get_uclass_priv(dev); 25 return priv->regmap; 26 } 27 28 static int syscon_pre_probe(struct udevice *dev) 29 { 30 struct syscon_uc_info *priv = dev_get_uclass_priv(dev); 31 32 return regmap_init_mem(dev, &priv->regmap); 33 } 34 35 int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp) 36 { 37 struct udevice *dev; 38 struct uclass *uc; 39 int ret; 40 41 ret = uclass_get(UCLASS_SYSCON, &uc); 42 if (ret) 43 return ret; 44 uclass_foreach_dev(dev, uc) { 45 if (dev->driver_data == driver_data) { 46 *devp = dev; 47 return device_probe(dev); 48 } 49 } 50 51 return -ENODEV; 52 } 53 54 struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) 55 { 56 struct syscon_uc_info *priv; 57 struct udevice *dev; 58 int ret; 59 60 ret = syscon_get_by_driver_data(driver_data, &dev); 61 if (ret) 62 return ERR_PTR(ret); 63 priv = dev_get_uclass_priv(dev); 64 65 return priv->regmap; 66 } 67 68 void *syscon_get_first_range(ulong driver_data) 69 { 70 struct regmap *map; 71 72 map = syscon_get_regmap_by_driver_data(driver_data); 73 if (IS_ERR(map)) 74 return map; 75 return regmap_get_range(map, 0); 76 } 77 78 UCLASS_DRIVER(syscon) = { 79 .id = UCLASS_SYSCON, 80 .name = "syscon", 81 .per_device_auto_alloc_size = sizeof(struct syscon_uc_info), 82 .pre_probe = syscon_pre_probe, 83 }; 84