From: Simon Glass Date: Wed, 17 May 2017 23:18:04 +0000 (-0600) Subject: dm: core: Move dev_get_addr() etc. into a separate file X-Git-Url: http://git.dujemihanovic.xyz/img/static/git-logo.png?a=commitdiff_plain;h=d6ffb00a438ef8ba714feb2c72a7ddbdebad2b2e;p=u-boot.git dm: core: Move dev_get_addr() etc. into a separate file Move this group of address-related functions into a new file. These use the flat device tree. Future work will provide new versions of these which can support the live tree. Signed-off-by: Simon Glass --- diff --git a/drivers/core/Makefile b/drivers/core/Makefile index 07adb61c28..8261f14f45 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 09a115f753..483f8368f7 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 0000000000..a0578feb1b --- /dev/null +++ b/drivers/core/fdtaddr.c @@ -0,0 +1,143 @@ +/* + * Device addresses + * + * Copyright (c) 2017 Google, Inc + * + * (C) Copyright 2012 + * Pavel Herrmann + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +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); +} diff --git a/include/dm.h b/include/dm.h index a179c8a6e3..84f789d807 100644 --- a/include/dm.h +++ b/include/dm.h @@ -8,6 +8,7 @@ #define _DM_H_ #include +#include #include #include diff --git a/include/dm/device.h b/include/dm/device.h index df02e41df3..361cdaee48 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -498,77 +498,6 @@ int device_find_first_child(struct udevice *parent, struct udevice **devp); */ int device_find_next_child(struct udevice **devp); -/** - * dev_get_addr() - Get the reg property of a device - * - * @dev: Pointer to a device - * - * @return addr - */ -fdt_addr_t dev_get_addr(struct udevice *dev); - -/** - * dev_get_addr_ptr() - Return pointer to the address of the reg property - * of a device - * - * @dev: Pointer to a device - * - * @return Pointer to addr, or NULL if there is no such property - */ -void *dev_get_addr_ptr(struct udevice *dev); - -/** - * dev_map_physmem() - Read device address from reg property of the - * device node and map the address into CPU address - * space. - * - * @dev: Pointer to device - * @size: size of the memory to map - * - * @return mapped address, or NULL if the device does not have reg - * property. - */ -void *dev_map_physmem(struct udevice *dev, unsigned long size); - -/** - * dev_get_addr_index() - Get the indexed reg property of a device - * - * @dev: Pointer to a device - * @index: the 'reg' property can hold a list of pairs - * and @index is used to select which one is required - * - * @return addr - */ -fdt_addr_t dev_get_addr_index(struct udevice *dev, int index); - -/** - * dev_get_addr_size_index() - Get the indexed reg property of a device - * - * Returns the address and size specified in the 'reg' property of a device. - * - * @dev: Pointer to a device - * @index: the 'reg' property can hold a list of pairs - * and @index is used to select which one is required - * @size: Pointer to size varible - this function returns the size - * specified in the 'reg' property here - * - * @return addr - */ -fdt_addr_t dev_get_addr_size_index(struct udevice *dev, int index, - fdt_size_t *size); - -/** - * dev_get_addr_name() - Get the reg property of a device, indexed by name - * - * @dev: Pointer to a device - * @name: the 'reg' property can hold a list of pairs, with the - * 'reg-names' property providing named-based identification. @index - * indicates the value to search for in 'reg-names'. - * - * @return addr - */ -fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name); - /** * device_has_children() - check if a device has any children * @@ -944,25 +873,4 @@ static inline void devm_kfree(struct udevice *dev, void *ptr) #endif /* ! CONFIG_DEVRES */ -/** - * dm_set_translation_offset() - Set translation offset - * @offs: Translation offset - * - * Some platforms need a special address translation. Those - * platforms (e.g. mvebu in SPL) can configure a translation - * offset in the DM by calling this function. It will be - * added to all addresses returned in dev_get_addr(). - */ -void dm_set_translation_offset(fdt_addr_t offs); - -/** - * dm_get_translation_offset() - Get translation offset - * - * This function returns the translation offset that can - * be configured by calling dm_set_translation_offset(). - * - * @return translation offset for the device address (0 as default). - */ -fdt_addr_t dm_get_translation_offset(void); - #endif diff --git a/include/dm/fdtaddr.h b/include/dm/fdtaddr.h new file mode 100644 index 0000000000..fd05b6fe95 --- /dev/null +++ b/include/dm/fdtaddr.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017 Google, Inc + * + * (C) Copyright 2012 + * Pavel Herrmann + * Marek Vasut + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _DM_ADDR_H +#define _DM_ADDR_H + +#include + +struct udevice; + +/** + * dev_get_addr() - Get the reg property of a device + * + * @dev: Pointer to a device + * + * @return addr + */ +fdt_addr_t dev_get_addr(struct udevice *dev); + +/** + * dev_get_addr_ptr() - Return pointer to the address of the reg property + * of a device + * + * @dev: Pointer to a device + * + * @return Pointer to addr, or NULL if there is no such property + */ +void *dev_get_addr_ptr(struct udevice *dev); + +/** + * dev_map_physmem() - Read device address from reg property of the + * device node and map the address into CPU address + * space. + * + * @dev: Pointer to device + * @size: size of the memory to map + * + * @return mapped address, or NULL if the device does not have reg + * property. + */ +void *dev_map_physmem(struct udevice *dev, unsigned long size); + +/** + * dev_get_addr_index() - Get the indexed reg property of a device + * + * @dev: Pointer to a device + * @index: the 'reg' property can hold a list of pairs + * and @index is used to select which one is required + * + * @return addr + */ +fdt_addr_t dev_get_addr_index(struct udevice *dev, int index); + +/** + * dev_get_addr_size_index() - Get the indexed reg property of a device + * + * Returns the address and size specified in the 'reg' property of a device. + * + * @dev: Pointer to a device + * @index: the 'reg' property can hold a list of pairs + * and @index is used to select which one is required + * @size: Pointer to size varible - this function returns the size + * specified in the 'reg' property here + * + * @return addr + */ +fdt_addr_t dev_get_addr_size_index(struct udevice *dev, int index, + fdt_size_t *size); + +/** + * dev_get_addr_name() - Get the reg property of a device, indexed by name + * + * @dev: Pointer to a device + * @name: the 'reg' property can hold a list of pairs, with the + * 'reg-names' property providing named-based identification. @index + * indicates the value to search for in 'reg-names'. + * + * @return addr + */ +fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name); + +/** + * dm_set_translation_offset() - Set translation offset + * @offs: Translation offset + * + * Some platforms need a special address translation. Those + * platforms (e.g. mvebu in SPL) can configure a translation + * offset in the DM by calling this function. It will be + * added to all addresses returned in dev_get_addr(). + */ +void dm_set_translation_offset(fdt_addr_t offs); + +/** + * dm_get_translation_offset() - Get translation offset + * + * This function returns the translation offset that can + * be configured by calling dm_set_translation_offset(). + * + * @return translation offset for the device address (0 as default). + */ +fdt_addr_t dm_get_translation_offset(void); + +#endif