9
0
Fork 0

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 <michel@reverze.net>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Michel Stam 2014-04-07 12:01:20 +02:00 committed by Sascha Hauer
parent 0a5529d0ed
commit 4d94f56c6c
16 changed files with 76 additions and 25 deletions

View File

@ -3,6 +3,8 @@
#include <asm-generic/io.h>
#define IO_SPACE_LIMIT 0
/*
* String version of IO memory access ops:
*/

View File

@ -14,6 +14,8 @@
#include <asm/types.h>
#include <asm/byteorder.h>
#define IO_SPACE_LIMIT 0
/*****************************************************************************/
/*
* readX/writeX() are used to access memory mapped devices. On some

View File

@ -22,6 +22,8 @@
#include <asm/byteorder.h>
#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))

View File

@ -2,5 +2,6 @@
#define __ASM_SANDBOX_IO_H
#include <asm-generic/io.h>
#define IO_SPACE_LIMIT 0
#endif /* __ASM_SANDBOX_IO_H */

View File

@ -12,6 +12,8 @@
#include <asm/byteorder.h>
#define IO_SPACE_LIMIT 0xffff
static inline void outb(unsigned char value, int port)
{
asm volatile("outb %b0, %w1" : : "a"(value), "Nd"(port));

View File

@ -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

View File

@ -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

View File

@ -15,6 +15,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <asm/io.h>
#include <common.h>
#include <command.h>
@ -27,8 +28,8 @@ static void __print_resources(struct resource *res, int indent)
printf(" ");
printf(PRINTF_CONVERSION_RESOURCE " - " PRINTF_CONVERSION_RESOURCE
" (size " PRINTF_CONVERSION_RESOURCE ") %s\n", res->start,
res->end, resource_size(res), res->name);
" (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);
@ -50,3 +51,17 @@ 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

View File

@ -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;
}

View File

@ -20,6 +20,7 @@
#include <errno.h>
#include <init.h>
#include <linux/ioport.h>
#include <asm/io.h>
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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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
*/

View File

@ -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 */