From 4d94f56c6c5ba00d35d6b3e3a1862439b2ced3f0 Mon Sep 17 00:00:00 2001 From: Michel Stam Date: Mon, 7 Apr 2014 12:01:20 +0200 Subject: common: Allow for I/O mapped I/O Rework the current framework so that I/O mapped I/O resources are also possible. Signed-off-by: Michel Stam Signed-off-by: Sascha Hauer --- arch/arm/include/asm/io.h | 2 ++ arch/mips/include/asm/io.h | 2 ++ arch/nios2/include/asm/io.h | 2 ++ arch/sandbox/include/asm/io.h | 1 + arch/x86/include/asm/io.h | 2 ++ commands/Kconfig | 6 ++-- commands/Makefile | 2 +- commands/iomem.c | 52 --------------------------------- commands/iomemport.c | 67 +++++++++++++++++++++++++++++++++++++++++++ common/memory.c | 3 +- common/resource.c | 28 ++++++++++++++---- drivers/base/driver.c | 16 ++++++----- drivers/gpio/gpio-generic.c | 4 +-- drivers/mfd/syscon.c | 2 +- drivers/misc/sram.c | 2 +- include/driver.h | 5 +++- include/linux/ioport.h | 5 +++- 17 files changed, 126 insertions(+), 75 deletions(-) delete mode 100644 commands/iomem.c create mode 100644 commands/iomemport.c diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index e0630ebb7e..ccf1f59013 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -3,6 +3,8 @@ #include +#define IO_SPACE_LIMIT 0 + /* * String version of IO memory access ops: */ diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 4100e1e52d..1cc8a51460 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -14,6 +14,8 @@ #include #include +#define IO_SPACE_LIMIT 0 + /*****************************************************************************/ /* * readX/writeX() are used to access memory mapped devices. On some diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h index 8ee48e08d3..59eea73ac2 100644 --- a/arch/nios2/include/asm/io.h +++ b/arch/nios2/include/asm/io.h @@ -22,6 +22,8 @@ #include +#define IO_SPACE_LIMIT 0 + #define __raw_writeb(v, a) (*(volatile unsigned char *)(a) = (v)) #define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v)) #define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v)) diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index 8ca164f214..35b578454e 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -2,5 +2,6 @@ #define __ASM_SANDBOX_IO_H #include +#define IO_SPACE_LIMIT 0 #endif /* __ASM_SANDBOX_IO_H */ diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 9cb78e41ec..f020510569 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -12,6 +12,8 @@ #include +#define IO_SPACE_LIMIT 0xffff + static inline void outb(unsigned char value, int port) { asm volatile("outb %b0, %w1" : : "a"(value), "Nd"(port)); diff --git a/commands/Kconfig b/commands/Kconfig index cc014f30ac..ced2edb71b 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -309,10 +309,10 @@ config CMD_MEMINFO config CMD_IOMEM tristate - prompt "iomem" + prompt "iomem/ioport" help - Show information about iomem usage. Pendant to 'cat /proc/iomem' - under Linux. + Show information about iomem/ioport usage. Pendant to + 'cat /proc/iomem' and 'cat /proc/ioports' under Linux. config CMD_MEMORY bool diff --git a/commands/Makefile b/commands/Makefile index e463031455..dded48f915 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -76,7 +76,7 @@ obj-$(CONFIG_CMD_OFTREE) += oftree.o obj-$(CONFIG_CMD_OF_PROPERTY) += of_property.o obj-$(CONFIG_CMD_OF_NODE) += of_node.o obj-$(CONFIG_CMD_MAGICVAR) += magicvar.o -obj-$(CONFIG_CMD_IOMEM) += iomem.o +obj-$(CONFIG_CMD_IOMEM) += iomemport.o obj-$(CONFIG_CMD_LINUX_EXEC) += linux_exec.o obj-$(CONFIG_CMD_AUTOMOUNT) += automount.o obj-$(CONFIG_CMD_GLOBAL) += global.o diff --git a/commands/iomem.c b/commands/iomem.c deleted file mode 100644 index e117c2a9f6..0000000000 --- a/commands/iomem.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * iomem.c - barebox iomem command - * - * Copyright (c) 2011 Sascha Hauer , Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include - -static void __print_resources(struct resource *res, int indent) -{ - struct resource *r; - int i; - - for (i = 0; i < indent; i++) - printf(" "); - - printf(PRINTF_CONVERSION_RESOURCE " - " PRINTF_CONVERSION_RESOURCE - " (size " PRINTF_CONVERSION_RESOURCE ") %s\n", res->start, - res->end, resource_size(res), res->name); - - list_for_each_entry(r, &res->children, sibling) - __print_resources(r, indent + 1); -} - -static void print_resources(struct resource *res) -{ - __print_resources(res, 0); -} - -static int do_iomem(int argc, char *argv[]) -{ - print_resources(&iomem_resource); - - return 0; -} - -BAREBOX_CMD_START(iomem) - .cmd = do_iomem, - .usage = "show iomem usage", -BAREBOX_CMD_END diff --git a/commands/iomemport.c b/commands/iomemport.c new file mode 100644 index 0000000000..652708c9cd --- /dev/null +++ b/commands/iomemport.c @@ -0,0 +1,67 @@ +/* + * iomem.c - barebox iomem command + * + * Copyright (c) 2011 Sascha Hauer , Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include + +static void __print_resources(struct resource *res, int indent) +{ + struct resource *r; + int i; + + for (i = 0; i < indent; i++) + printf(" "); + + printf(PRINTF_CONVERSION_RESOURCE " - " PRINTF_CONVERSION_RESOURCE + " (size " PRINTF_CONVERSION_RESOURCE ") %s\n", + res->start, res->end, resource_size(res), res->name); + + list_for_each_entry(r, &res->children, sibling) + __print_resources(r, indent + 1); +} + +static void print_resources(struct resource *res) +{ + __print_resources(res, 0); +} + +static int do_iomem(int argc, char *argv[]) +{ + print_resources(&iomem_resource); + + return 0; +} + +BAREBOX_CMD_START(iomem) + .cmd = do_iomem, + .usage = "show iomem usage", +BAREBOX_CMD_END + +#if IO_SPACE_LIMIT > 0 +static int do_ioport(int argc, char *argv[]) +{ + print_resources(&ioport_resource); + + return 0; +} + +BAREBOX_CMD_START(ioport) + .cmd = do_ioport, + .usage = "show ioport usage", +BAREBOX_CMD_END +#endif diff --git a/common/memory.c b/common/memory.c index c82bbaaf4c..7dbd7f4399 100644 --- a/common/memory.c +++ b/common/memory.c @@ -148,7 +148,8 @@ struct resource *request_sdram_region(const char *name, resource_size_t start, for_each_memory_bank(bank) { struct resource *res; - res = request_region(bank->res, name, start, start + size - 1); + res = __request_region(bank->res, name, start, + start + size - 1); if (res) return res; } diff --git a/common/resource.c b/common/resource.c index 5795e79c6b..fe4680e3bd 100644 --- a/common/resource.c +++ b/common/resource.c @@ -20,6 +20,7 @@ #include #include #include +#include static int init_resource(struct resource *res, const char *name) { @@ -36,7 +37,7 @@ static int init_resource(struct resource *res, const char *name) * the parent resource and does not conflict with any of the child * resources. */ -struct resource *request_region(struct resource *parent, +struct resource *__request_region(struct resource *parent, const char *name, resource_size_t start, resource_size_t end) { @@ -95,7 +96,7 @@ ok: } /* - * release a region previously requested with request_region + * release a region previously requested with request_*_region */ int release_region(struct resource *res) { @@ -109,7 +110,7 @@ int release_region(struct resource *res) return 0; } -/* The root resource for the whole io space */ +/* The root resource for the whole memory-mapped io space */ struct resource iomem_resource = { .start = 0, .end = 0xffffffff, @@ -118,10 +119,27 @@ struct resource iomem_resource = { }; /* - * request a region inside the io space + * request a region inside the io space (memory) */ struct resource *request_iomem_region(const char *name, resource_size_t start, resource_size_t end) { - return request_region(&iomem_resource, name, start, end); + return __request_region(&iomem_resource, name, start, end); +} + +/* The root resource for the whole io-mapped io space */ +struct resource ioport_resource = { + .start = 0, + .end = IO_SPACE_LIMIT, + .name = "ioport", + .children = LIST_HEAD_INIT(ioport_resource.children), +}; + +/* + * request a region inside the io space (i/o port) + */ +struct resource *request_ioport_region(const char *name, + resource_size_t start, resource_size_t end) +{ + return __request_region(&ioport_resource, name, start, end); } diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 37560fd46f..2cf3ee6892 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -241,13 +241,14 @@ int register_driver(struct driver_d *drv) } EXPORT_SYMBOL(register_driver); -struct resource *dev_get_resource(struct device_d *dev, int num) +struct resource *dev_get_resource(struct device_d *dev, unsigned long type, + int num) { int i, n = 0; for (i = 0; i < dev->num_resources; i++) { struct resource *res = &dev->resource[i]; - if (resource_type(res) == IORESOURCE_MEM) { + if (resource_type(res) == type) { if (n == num) return res; n++; @@ -261,7 +262,7 @@ void *dev_get_mem_region(struct device_d *dev, int num) { struct resource *res; - res = dev_get_resource(dev, num); + res = dev_get_resource(dev, IORESOURCE_MEM, num); if (!res) return NULL; @@ -270,13 +271,14 @@ void *dev_get_mem_region(struct device_d *dev, int num) EXPORT_SYMBOL(dev_get_mem_region); struct resource *dev_get_resource_by_name(struct device_d *dev, + unsigned long type, const char *name) { int i; for (i = 0; i < dev->num_resources; i++) { struct resource *res = &dev->resource[i]; - if (resource_type(res) != IORESOURCE_MEM) + if (resource_type(res) != type) continue; if (!res->name) continue; @@ -291,7 +293,7 @@ void *dev_get_mem_region_by_name(struct device_d *dev, const char *name) { struct resource *res; - res = dev_get_resource_by_name(dev, name); + res = dev_get_resource_by_name(dev, IORESOURCE_MEM, name); if (!res) return NULL; @@ -303,7 +305,7 @@ void __iomem *dev_request_mem_region_by_name(struct device_d *dev, const char *n { struct resource *res; - res = dev_get_resource_by_name(dev, name); + res = dev_get_resource_by_name(dev, IORESOURCE_MEM, name); if (!res) return NULL; @@ -319,7 +321,7 @@ void __iomem *dev_request_mem_region(struct device_d *dev, int num) { struct resource *res; - res = dev_get_resource(dev, num); + res = dev_get_resource(dev, IORESOURCE_MEM, num); if (!res) return NULL; diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index a2fc400431..5c46282045 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -310,7 +310,7 @@ static void __iomem *bgpio_map(struct device_d *dev, const char *name, *err = 0; - r = dev_get_resource_by_name(dev, name); + r = dev_get_resource_by_name(dev, IORESOURCE_MEM, name); if (!r) return NULL; @@ -342,7 +342,7 @@ static int bgpio_dev_probe(struct device_d *dev) struct bgpio_chip *bgc; struct bgpio_pdata *pdata = dev->platform_data; - r = dev_get_resource_by_name(dev, "dat"); + r = dev_get_resource_by_name(dev, IORESOURCE_MEM, "dat"); if (!r) return -EINVAL; diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 8fc84c34d8..e6722e1916 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -70,7 +70,7 @@ static int syscon_probe(struct device_d *dev) if (!syscon) return -ENOMEM; - res = dev_get_resource(dev, 0); + res = dev_get_resource(dev, IORESOURCE_MEM, 0); if (!res) { free(syscon); return -ENOENT; diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 7ea23b7b0c..0466a15289 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -47,7 +47,7 @@ static int sram_probe(struct device_d *dev) sram->cdev.name = asprintf("sram%d", cdev_find_free_index("sram")); - res = dev_get_resource(dev, 0); + res = dev_get_resource(dev, IORESOURCE_MEM, 0); sram->cdev.size = (unsigned long)resource_size(res); sram->cdev.ops = &memops; diff --git a/include/driver.h b/include/driver.h index 01b181ddbd..7c7d38fc14 100644 --- a/include/driver.h +++ b/include/driver.h @@ -203,11 +203,13 @@ static inline const char *dev_name(const struct device_d *dev) /* * get resource 'num' for a device */ -struct resource *dev_get_resource(struct device_d *dev, int num); +struct resource *dev_get_resource(struct device_d *dev, unsigned long type, + int num); /* * get resource base 'name' for a device */ struct resource *dev_get_resource_by_name(struct device_d *dev, + unsigned long type, const char *name); /* * get register base 'name' for a device @@ -219,6 +221,7 @@ void *dev_get_mem_region_by_name(struct device_d *dev, const char *name); */ void __iomem *dev_request_mem_region_by_name(struct device_d *dev, const char *name); + /* * get register base 'num' for a device */ diff --git a/include/linux/ioport.h b/include/linux/ioport.h index ff0cba0707..d1b2f55c93 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -137,14 +137,17 @@ static inline unsigned long resource_type(const struct resource *res) struct resource *request_iomem_region(const char *name, resource_size_t start, resource_size_t end); +struct resource *request_ioport_region(const char *name, + resource_size_t start, resource_size_t end); -struct resource *request_region(struct resource *parent, +struct resource *__request_region(struct resource *parent, const char *name, resource_size_t end, resource_size_t size); int release_region(struct resource *res); extern struct resource iomem_resource; +extern struct resource ioport_resource; #endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ -- cgit v1.2.3