diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/core/Makefile | 2 | ||||
-rw-r--r-- | drivers/core/device.c | 125 | ||||
-rw-r--r-- | drivers/core/fdtaddr.c | 143 |
3 files changed, 144 insertions, 126 deletions
diff --git a/drivers/core/Makefile b/drivers/core/Makefile index 07adb61..8261f14 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -4,7 +4,7 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += device.o lists.o root.o uclass.o util.o +obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o obj-$(CONFIG_DEVRES) += devres.o obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o diff --git a/drivers/core/device.c b/drivers/core/device.c index 09a115f..483f836 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -655,131 +655,6 @@ const char *dev_get_uclass_name(struct udevice *dev) return dev->uclass->uc_drv->name; } -fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) -{ -#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) - fdt_addr_t addr; - - if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { - const fdt32_t *reg; - int len = 0; - int na, ns; - - na = fdt_address_cells(gd->fdt_blob, - dev_of_offset(dev->parent)); - if (na < 1) { - debug("bad #address-cells\n"); - return FDT_ADDR_T_NONE; - } - - ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent)); - if (ns < 0) { - debug("bad #size-cells\n"); - return FDT_ADDR_T_NONE; - } - - reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg", - &len); - if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) { - debug("Req index out of range\n"); - return FDT_ADDR_T_NONE; - } - - reg += index * (na + ns); - - /* - * Use the full-fledged translate function for complex - * bus setups. - */ - addr = fdt_translate_address((void *)gd->fdt_blob, - dev_of_offset(dev), reg); - } else { - /* - * Use the "simple" translate function for less complex - * bus setups. - */ - addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, - dev_of_offset(dev->parent), dev_of_offset(dev), - "reg", index, NULL, false); - if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { - if (device_get_uclass_id(dev->parent) == - UCLASS_SIMPLE_BUS) - addr = simple_bus_translate(dev->parent, addr); - } - } - - /* - * Some platforms need a special address translation. Those - * platforms (e.g. mvebu in SPL) can configure a translation - * offset in the DM by calling dm_set_translation_offset() that - * will get added to all addresses returned by dev_get_addr(). - */ - addr += dm_get_translation_offset(); - - return addr; -#else - return FDT_ADDR_T_NONE; -#endif -} - -fdt_addr_t dev_get_addr_size_index(struct udevice *dev, int index, - fdt_size_t *size) -{ -#if CONFIG_IS_ENABLED(OF_CONTROL) - /* - * Only get the size in this first call. We'll get the addr in the - * next call to the exisiting dev_get_xxx function which handles - * all config options. - */ - fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev), - "reg", index, size, false); - - /* - * Get the base address via the existing function which handles - * all Kconfig cases - */ - return dev_get_addr_index(dev, index); -#else - return FDT_ADDR_T_NONE; -#endif -} - -fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name) -{ -#if CONFIG_IS_ENABLED(OF_CONTROL) - int index; - - index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev), - "reg-names", name); - if (index < 0) - return index; - - return dev_get_addr_index(dev, index); -#else - return FDT_ADDR_T_NONE; -#endif -} - -fdt_addr_t dev_get_addr(struct udevice *dev) -{ - return dev_get_addr_index(dev, 0); -} - -void *dev_get_addr_ptr(struct udevice *dev) -{ - return (void *)(uintptr_t)dev_get_addr_index(dev, 0); -} - -void *dev_map_physmem(struct udevice *dev, unsigned long size) -{ - fdt_addr_t addr = dev_get_addr(dev); - - if (addr == FDT_ADDR_T_NONE) - return NULL; - - return map_physmem(addr, size, MAP_NOCACHE); -} - bool device_has_children(struct udevice *dev) { return !list_empty(&dev->child_head); diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c new file mode 100644 index 0000000..a0578fe --- /dev/null +++ b/drivers/core/fdtaddr.c @@ -0,0 +1,143 @@ +/* + * Device addresses + * + * Copyright (c) 2017 Google, Inc + * + * (C) Copyright 2012 + * Pavel Herrmann <morpheus.ibis@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <fdt_support.h> +#include <asm/io.h> +#include <dm/device-internal.h> + +DECLARE_GLOBAL_DATA_PTR; + +fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) + fdt_addr_t addr; + + if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { + const fdt32_t *reg; + int len = 0; + int na, ns; + + na = fdt_address_cells(gd->fdt_blob, + dev_of_offset(dev->parent)); + if (na < 1) { + debug("bad #address-cells\n"); + return FDT_ADDR_T_NONE; + } + + ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent)); + if (ns < 0) { + debug("bad #size-cells\n"); + return FDT_ADDR_T_NONE; + } + + reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg", + &len); + if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) { + debug("Req index out of range\n"); + return FDT_ADDR_T_NONE; + } + + reg += index * (na + ns); + + /* + * Use the full-fledged translate function for complex + * bus setups. + */ + addr = fdt_translate_address((void *)gd->fdt_blob, + dev_of_offset(dev), reg); + } else { + /* + * Use the "simple" translate function for less complex + * bus setups. + */ + addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, + dev_of_offset(dev->parent), dev_of_offset(dev), + "reg", index, NULL, false); + if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { + if (device_get_uclass_id(dev->parent) == + UCLASS_SIMPLE_BUS) + addr = simple_bus_translate(dev->parent, addr); + } + } + + /* + * Some platforms need a special address translation. Those + * platforms (e.g. mvebu in SPL) can configure a translation + * offset in the DM by calling dm_set_translation_offset() that + * will get added to all addresses returned by dev_get_addr(). + */ + addr += dm_get_translation_offset(); + + return addr; +#else + return FDT_ADDR_T_NONE; +#endif +} + +fdt_addr_t dev_get_addr_size_index(struct udevice *dev, int index, + fdt_size_t *size) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL) + /* + * Only get the size in this first call. We'll get the addr in the + * next call to the exisiting dev_get_xxx function which handles + * all config options. + */ + fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev), + "reg", index, size, false); + + /* + * Get the base address via the existing function which handles + * all Kconfig cases + */ + return dev_get_addr_index(dev, index); +#else + return FDT_ADDR_T_NONE; +#endif +} + +fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL) + int index; + + index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev), + "reg-names", name); + if (index < 0) + return index; + + return dev_get_addr_index(dev, index); +#else + return FDT_ADDR_T_NONE; +#endif +} + +fdt_addr_t dev_get_addr(struct udevice *dev) +{ + return dev_get_addr_index(dev, 0); +} + +void *dev_get_addr_ptr(struct udevice *dev) +{ + return (void *)(uintptr_t)dev_get_addr_index(dev, 0); +} + +void *dev_map_physmem(struct udevice *dev, unsigned long size) +{ + fdt_addr_t addr = dev_get_addr(dev); + + if (addr == FDT_ADDR_T_NONE) + return NULL; + + return map_physmem(addr, size, MAP_NOCACHE); +} |