157251285SSimon Glass /* 257251285SSimon Glass * Copyright (C) 2015 Google, Inc 357251285SSimon Glass * Written by Simon Glass <sjg@chromium.org> 457251285SSimon Glass * 557251285SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 657251285SSimon Glass */ 757251285SSimon Glass 857251285SSimon Glass #include <common.h> 957251285SSimon Glass #include <syscon.h> 1057251285SSimon Glass #include <dm.h> 1157251285SSimon Glass #include <errno.h> 1257251285SSimon Glass #include <regmap.h> 1357251285SSimon Glass #include <dm/device-internal.h> 1457251285SSimon Glass #include <dm/lists.h> 1557251285SSimon Glass #include <dm/root.h> 1657251285SSimon Glass #include <linux/err.h> 1757251285SSimon Glass 1857251285SSimon Glass struct regmap *syscon_get_regmap(struct udevice *dev) 1957251285SSimon Glass { 209f4629beSSimon Glass struct syscon_uc_info *priv; 2157251285SSimon Glass 229f4629beSSimon Glass if (device_get_uclass_id(dev) != UCLASS_SYSCON) 239f4629beSSimon Glass return ERR_PTR(-ENOEXEC); 249f4629beSSimon Glass priv = dev_get_uclass_priv(dev); 2557251285SSimon Glass return priv->regmap; 2657251285SSimon Glass } 2757251285SSimon Glass 2857251285SSimon Glass static int syscon_pre_probe(struct udevice *dev) 2957251285SSimon Glass { 3057251285SSimon Glass struct syscon_uc_info *priv = dev_get_uclass_priv(dev); 3157251285SSimon Glass 3257251285SSimon Glass return regmap_init_mem(dev, &priv->regmap); 3357251285SSimon Glass } 3457251285SSimon Glass 35ac94b7bcSSimon Glass int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp) 3657251285SSimon Glass { 3757251285SSimon Glass struct udevice *dev; 3857251285SSimon Glass struct uclass *uc; 3957251285SSimon Glass int ret; 4057251285SSimon Glass 41*532f2435SSimon Glass *devp = NULL; 4257251285SSimon Glass ret = uclass_get(UCLASS_SYSCON, &uc); 4357251285SSimon Glass if (ret) 44ac94b7bcSSimon Glass return ret; 4557251285SSimon Glass uclass_foreach_dev(dev, uc) { 4657251285SSimon Glass if (dev->driver_data == driver_data) { 47ac94b7bcSSimon Glass *devp = dev; 48ac94b7bcSSimon Glass return device_probe(dev); 49ac94b7bcSSimon Glass } 50ac94b7bcSSimon Glass } 51ac94b7bcSSimon Glass 52ac94b7bcSSimon Glass return -ENODEV; 53ac94b7bcSSimon Glass } 54ac94b7bcSSimon Glass 55ac94b7bcSSimon Glass struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) 56ac94b7bcSSimon Glass { 5757251285SSimon Glass struct syscon_uc_info *priv; 58ac94b7bcSSimon Glass struct udevice *dev; 5957251285SSimon Glass int ret; 6057251285SSimon Glass 61ac94b7bcSSimon Glass ret = syscon_get_by_driver_data(driver_data, &dev); 6257251285SSimon Glass if (ret) 6357251285SSimon Glass return ERR_PTR(ret); 6457251285SSimon Glass priv = dev_get_uclass_priv(dev); 6557251285SSimon Glass 6657251285SSimon Glass return priv->regmap; 6757251285SSimon Glass } 6857251285SSimon Glass 6957251285SSimon Glass void *syscon_get_first_range(ulong driver_data) 7057251285SSimon Glass { 7157251285SSimon Glass struct regmap *map; 7257251285SSimon Glass 7357251285SSimon Glass map = syscon_get_regmap_by_driver_data(driver_data); 7457251285SSimon Glass if (IS_ERR(map)) 7557251285SSimon Glass return map; 7657251285SSimon Glass return regmap_get_range(map, 0); 7757251285SSimon Glass } 7857251285SSimon Glass 7957251285SSimon Glass UCLASS_DRIVER(syscon) = { 8057251285SSimon Glass .id = UCLASS_SYSCON, 8157251285SSimon Glass .name = "syscon", 8257251285SSimon Glass .per_device_auto_alloc_size = sizeof(struct syscon_uc_info), 8357251285SSimon Glass .pre_probe = syscon_pre_probe, 8457251285SSimon Glass }; 85