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 35*ac94b7bcSSimon 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 4157251285SSimon Glass ret = uclass_get(UCLASS_SYSCON, &uc); 4257251285SSimon Glass if (ret) 43*ac94b7bcSSimon Glass return ret; 4457251285SSimon Glass uclass_foreach_dev(dev, uc) { 4557251285SSimon Glass if (dev->driver_data == driver_data) { 46*ac94b7bcSSimon Glass *devp = dev; 47*ac94b7bcSSimon Glass return device_probe(dev); 48*ac94b7bcSSimon Glass } 49*ac94b7bcSSimon Glass } 50*ac94b7bcSSimon Glass 51*ac94b7bcSSimon Glass return -ENODEV; 52*ac94b7bcSSimon Glass } 53*ac94b7bcSSimon Glass 54*ac94b7bcSSimon Glass struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) 55*ac94b7bcSSimon Glass { 5657251285SSimon Glass struct syscon_uc_info *priv; 57*ac94b7bcSSimon Glass struct udevice *dev; 5857251285SSimon Glass int ret; 5957251285SSimon Glass 60*ac94b7bcSSimon Glass ret = syscon_get_by_driver_data(driver_data, &dev); 6157251285SSimon Glass if (ret) 6257251285SSimon Glass return ERR_PTR(ret); 6357251285SSimon Glass priv = dev_get_uclass_priv(dev); 6457251285SSimon Glass 6557251285SSimon Glass return priv->regmap; 6657251285SSimon Glass } 6757251285SSimon Glass 6857251285SSimon Glass void *syscon_get_first_range(ulong driver_data) 6957251285SSimon Glass { 7057251285SSimon Glass struct regmap *map; 7157251285SSimon Glass 7257251285SSimon Glass map = syscon_get_regmap_by_driver_data(driver_data); 7357251285SSimon Glass if (IS_ERR(map)) 7457251285SSimon Glass return map; 7557251285SSimon Glass return regmap_get_range(map, 0); 7657251285SSimon Glass } 7757251285SSimon Glass 7857251285SSimon Glass UCLASS_DRIVER(syscon) = { 7957251285SSimon Glass .id = UCLASS_SYSCON, 8057251285SSimon Glass .name = "syscon", 8157251285SSimon Glass .per_device_auto_alloc_size = sizeof(struct syscon_uc_info), 8257251285SSimon Glass .pre_probe = syscon_pre_probe, 8357251285SSimon Glass }; 84