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:
parent
0a5529d0ed
commit
4d94f56c6c
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <asm-generic/io.h>
|
#include <asm-generic/io.h>
|
||||||
|
|
||||||
|
#define IO_SPACE_LIMIT 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* String version of IO memory access ops:
|
* String version of IO memory access ops:
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
#define IO_SPACE_LIMIT 0
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* readX/writeX() are used to access memory mapped devices. On some
|
* readX/writeX() are used to access memory mapped devices. On some
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
#define IO_SPACE_LIMIT 0
|
||||||
|
|
||||||
#define __raw_writeb(v, a) (*(volatile unsigned char *)(a) = (v))
|
#define __raw_writeb(v, a) (*(volatile unsigned char *)(a) = (v))
|
||||||
#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v))
|
#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v))
|
||||||
#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v))
|
#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v))
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
#define __ASM_SANDBOX_IO_H
|
#define __ASM_SANDBOX_IO_H
|
||||||
|
|
||||||
#include <asm-generic/io.h>
|
#include <asm-generic/io.h>
|
||||||
|
#define IO_SPACE_LIMIT 0
|
||||||
|
|
||||||
#endif /* __ASM_SANDBOX_IO_H */
|
#endif /* __ASM_SANDBOX_IO_H */
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
#define IO_SPACE_LIMIT 0xffff
|
||||||
|
|
||||||
static inline void outb(unsigned char value, int port)
|
static inline void outb(unsigned char value, int port)
|
||||||
{
|
{
|
||||||
asm volatile("outb %b0, %w1" : : "a"(value), "Nd"(port));
|
asm volatile("outb %b0, %w1" : : "a"(value), "Nd"(port));
|
||||||
|
|
|
@ -309,10 +309,10 @@ config CMD_MEMINFO
|
||||||
|
|
||||||
config CMD_IOMEM
|
config CMD_IOMEM
|
||||||
tristate
|
tristate
|
||||||
prompt "iomem"
|
prompt "iomem/ioport"
|
||||||
help
|
help
|
||||||
Show information about iomem usage. Pendant to 'cat /proc/iomem'
|
Show information about iomem/ioport usage. Pendant to
|
||||||
under Linux.
|
'cat /proc/iomem' and 'cat /proc/ioports' under Linux.
|
||||||
|
|
||||||
config CMD_MEMORY
|
config CMD_MEMORY
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -76,7 +76,7 @@ obj-$(CONFIG_CMD_OFTREE) += oftree.o
|
||||||
obj-$(CONFIG_CMD_OF_PROPERTY) += of_property.o
|
obj-$(CONFIG_CMD_OF_PROPERTY) += of_property.o
|
||||||
obj-$(CONFIG_CMD_OF_NODE) += of_node.o
|
obj-$(CONFIG_CMD_OF_NODE) += of_node.o
|
||||||
obj-$(CONFIG_CMD_MAGICVAR) += magicvar.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_LINUX_EXEC) += linux_exec.o
|
||||||
obj-$(CONFIG_CMD_AUTOMOUNT) += automount.o
|
obj-$(CONFIG_CMD_AUTOMOUNT) += automount.o
|
||||||
obj-$(CONFIG_CMD_GLOBAL) += global.o
|
obj-$(CONFIG_CMD_GLOBAL) += global.o
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
#include <asm/io.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
|
|
||||||
|
@ -27,8 +28,8 @@ static void __print_resources(struct resource *res, int indent)
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
|
||||||
printf(PRINTF_CONVERSION_RESOURCE " - " PRINTF_CONVERSION_RESOURCE
|
printf(PRINTF_CONVERSION_RESOURCE " - " PRINTF_CONVERSION_RESOURCE
|
||||||
" (size " PRINTF_CONVERSION_RESOURCE ") %s\n", res->start,
|
" (size " PRINTF_CONVERSION_RESOURCE ") %s\n",
|
||||||
res->end, resource_size(res), res->name);
|
res->start, res->end, resource_size(res), res->name);
|
||||||
|
|
||||||
list_for_each_entry(r, &res->children, sibling)
|
list_for_each_entry(r, &res->children, sibling)
|
||||||
__print_resources(r, indent + 1);
|
__print_resources(r, indent + 1);
|
||||||
|
@ -50,3 +51,17 @@ BAREBOX_CMD_START(iomem)
|
||||||
.cmd = do_iomem,
|
.cmd = do_iomem,
|
||||||
.usage = "show iomem usage",
|
.usage = "show iomem usage",
|
||||||
BAREBOX_CMD_END
|
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
|
|
@ -148,7 +148,8 @@ struct resource *request_sdram_region(const char *name, resource_size_t start,
|
||||||
for_each_memory_bank(bank) {
|
for_each_memory_bank(bank) {
|
||||||
struct resource *res;
|
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)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
static int init_resource(struct resource *res, const char *name)
|
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
|
* the parent resource and does not conflict with any of the child
|
||||||
* resources.
|
* resources.
|
||||||
*/
|
*/
|
||||||
struct resource *request_region(struct resource *parent,
|
struct resource *__request_region(struct resource *parent,
|
||||||
const char *name, resource_size_t start,
|
const char *name, resource_size_t start,
|
||||||
resource_size_t end)
|
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)
|
int release_region(struct resource *res)
|
||||||
{
|
{
|
||||||
|
@ -109,7 +110,7 @@ int release_region(struct resource *res)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The root resource for the whole io space */
|
/* The root resource for the whole memory-mapped io space */
|
||||||
struct resource iomem_resource = {
|
struct resource iomem_resource = {
|
||||||
.start = 0,
|
.start = 0,
|
||||||
.end = 0xffffffff,
|
.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,
|
struct resource *request_iomem_region(const char *name,
|
||||||
resource_size_t start, resource_size_t end)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,13 +241,14 @@ int register_driver(struct driver_d *drv)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(register_driver);
|
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;
|
int i, n = 0;
|
||||||
|
|
||||||
for (i = 0; i < dev->num_resources; i++) {
|
for (i = 0; i < dev->num_resources; i++) {
|
||||||
struct resource *res = &dev->resource[i];
|
struct resource *res = &dev->resource[i];
|
||||||
if (resource_type(res) == IORESOURCE_MEM) {
|
if (resource_type(res) == type) {
|
||||||
if (n == num)
|
if (n == num)
|
||||||
return res;
|
return res;
|
||||||
n++;
|
n++;
|
||||||
|
@ -261,7 +262,7 @@ void *dev_get_mem_region(struct device_d *dev, int num)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
res = dev_get_resource(dev, num);
|
res = dev_get_resource(dev, IORESOURCE_MEM, num);
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -270,13 +271,14 @@ void *dev_get_mem_region(struct device_d *dev, int num)
|
||||||
EXPORT_SYMBOL(dev_get_mem_region);
|
EXPORT_SYMBOL(dev_get_mem_region);
|
||||||
|
|
||||||
struct resource *dev_get_resource_by_name(struct device_d *dev,
|
struct resource *dev_get_resource_by_name(struct device_d *dev,
|
||||||
|
unsigned long type,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < dev->num_resources; i++) {
|
for (i = 0; i < dev->num_resources; i++) {
|
||||||
struct resource *res = &dev->resource[i];
|
struct resource *res = &dev->resource[i];
|
||||||
if (resource_type(res) != IORESOURCE_MEM)
|
if (resource_type(res) != type)
|
||||||
continue;
|
continue;
|
||||||
if (!res->name)
|
if (!res->name)
|
||||||
continue;
|
continue;
|
||||||
|
@ -291,7 +293,7 @@ void *dev_get_mem_region_by_name(struct device_d *dev, const char *name)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
res = dev_get_resource_by_name(dev, name);
|
res = dev_get_resource_by_name(dev, IORESOURCE_MEM, name);
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ void __iomem *dev_request_mem_region_by_name(struct device_d *dev, const char *n
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
res = dev_get_resource_by_name(dev, name);
|
res = dev_get_resource_by_name(dev, IORESOURCE_MEM, name);
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -319,7 +321,7 @@ void __iomem *dev_request_mem_region(struct device_d *dev, int num)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
res = dev_get_resource(dev, num);
|
res = dev_get_resource(dev, IORESOURCE_MEM, num);
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ static void __iomem *bgpio_map(struct device_d *dev, const char *name,
|
||||||
|
|
||||||
*err = 0;
|
*err = 0;
|
||||||
|
|
||||||
r = dev_get_resource_by_name(dev, name);
|
r = dev_get_resource_by_name(dev, IORESOURCE_MEM, name);
|
||||||
if (!r)
|
if (!r)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ static int bgpio_dev_probe(struct device_d *dev)
|
||||||
struct bgpio_chip *bgc;
|
struct bgpio_chip *bgc;
|
||||||
struct bgpio_pdata *pdata = dev->platform_data;
|
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)
|
if (!r)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ static int syscon_probe(struct device_d *dev)
|
||||||
if (!syscon)
|
if (!syscon)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
res = dev_get_resource(dev, 0);
|
res = dev_get_resource(dev, IORESOURCE_MEM, 0);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
free(syscon);
|
free(syscon);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
|
@ -47,7 +47,7 @@ static int sram_probe(struct device_d *dev)
|
||||||
sram->cdev.name = asprintf("sram%d",
|
sram->cdev.name = asprintf("sram%d",
|
||||||
cdev_find_free_index("sram"));
|
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.size = (unsigned long)resource_size(res);
|
||||||
sram->cdev.ops = &memops;
|
sram->cdev.ops = &memops;
|
||||||
|
|
|
@ -203,11 +203,13 @@ static inline const char *dev_name(const struct device_d *dev)
|
||||||
/*
|
/*
|
||||||
* get resource 'num' for a device
|
* 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
|
* get resource base 'name' for a device
|
||||||
*/
|
*/
|
||||||
struct resource *dev_get_resource_by_name(struct device_d *dev,
|
struct resource *dev_get_resource_by_name(struct device_d *dev,
|
||||||
|
unsigned long type,
|
||||||
const char *name);
|
const char *name);
|
||||||
/*
|
/*
|
||||||
* get register base 'name' for a device
|
* 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,
|
void __iomem *dev_request_mem_region_by_name(struct device_d *dev,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get register base 'num' for a device
|
* get register base 'num' for a device
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -137,14 +137,17 @@ static inline unsigned long resource_type(const struct resource *res)
|
||||||
|
|
||||||
struct resource *request_iomem_region(const char *name,
|
struct resource *request_iomem_region(const char *name,
|
||||||
resource_size_t start, resource_size_t end);
|
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,
|
const char *name, resource_size_t end,
|
||||||
resource_size_t size);
|
resource_size_t size);
|
||||||
|
|
||||||
int release_region(struct resource *res);
|
int release_region(struct resource *res);
|
||||||
|
|
||||||
extern struct resource iomem_resource;
|
extern struct resource iomem_resource;
|
||||||
|
extern struct resource ioport_resource;
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
#endif /* _LINUX_IOPORT_H */
|
#endif /* _LINUX_IOPORT_H */
|
||||||
|
|
Loading…
Reference in New Issue