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 *devp = NULL; 42 ret = uclass_get(UCLASS_SYSCON, &uc); 43 if (ret) 44 return ret; 45 uclass_foreach_dev(dev, uc) { 46 if (dev->driver_data == driver_data) { 47 *devp = dev; 48 return device_probe(dev); 49 } 50 } 51 52 return -ENODEV; 53 } 54 55 struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) 56 { 57 struct syscon_uc_info *priv; 58 struct udevice *dev; 59 int ret; 60 61 ret = syscon_get_by_driver_data(driver_data, &dev); 62 if (ret) 63 return ERR_PTR(ret); 64 priv = dev_get_uclass_priv(dev); 65 66 return priv->regmap; 67 } 68 69 void *syscon_get_first_range(ulong driver_data) 70 { 71 struct regmap *map; 72 73 map = syscon_get_regmap_by_driver_data(driver_data); 74 if (IS_ERR(map)) 75 return map; 76 return regmap_get_range(map, 0); 77 } 78 79 UCLASS_DRIVER(syscon) = { 80 .id = UCLASS_SYSCON, 81 .name = "syscon", 82 .per_device_auto_alloc_size = sizeof(struct syscon_uc_info), 83 .pre_probe = syscon_pre_probe, 84 }; 85