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 { 20*9f4629beSSimon Glass struct syscon_uc_info *priv; 2157251285SSimon Glass 22*9f4629beSSimon Glass if (device_get_uclass_id(dev) != UCLASS_SYSCON) 23*9f4629beSSimon Glass return ERR_PTR(-ENOEXEC); 24*9f4629beSSimon 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 3557251285SSimon Glass struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) 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) 4357251285SSimon Glass return ERR_PTR(ret); 4457251285SSimon Glass uclass_foreach_dev(dev, uc) { 4557251285SSimon Glass if (dev->driver_data == driver_data) { 4657251285SSimon Glass struct syscon_uc_info *priv; 4757251285SSimon Glass int ret; 4857251285SSimon Glass 4957251285SSimon Glass ret = device_probe(dev); 5057251285SSimon Glass if (ret) 5157251285SSimon Glass return ERR_PTR(ret); 5257251285SSimon Glass priv = dev_get_uclass_priv(dev); 5357251285SSimon Glass 5457251285SSimon Glass return priv->regmap; 5557251285SSimon Glass } 5657251285SSimon Glass } 5757251285SSimon Glass 58*9f4629beSSimon Glass return ERR_PTR(-ENODEV); 5957251285SSimon Glass } 6057251285SSimon Glass 6157251285SSimon Glass void *syscon_get_first_range(ulong driver_data) 6257251285SSimon Glass { 6357251285SSimon Glass struct regmap *map; 6457251285SSimon Glass 6557251285SSimon Glass map = syscon_get_regmap_by_driver_data(driver_data); 6657251285SSimon Glass if (IS_ERR(map)) 6757251285SSimon Glass return map; 6857251285SSimon Glass return regmap_get_range(map, 0); 6957251285SSimon Glass } 7057251285SSimon Glass 7157251285SSimon Glass UCLASS_DRIVER(syscon) = { 7257251285SSimon Glass .id = UCLASS_SYSCON, 7357251285SSimon Glass .name = "syscon", 7457251285SSimon Glass .per_device_auto_alloc_size = sizeof(struct syscon_uc_info), 7557251285SSimon Glass .pre_probe = syscon_pre_probe, 7657251285SSimon Glass }; 77