9
0
Fork 0

Merge branch 'for-next/ioresource'

This commit is contained in:
Sascha Hauer 2014-05-05 11:05:51 +02:00
commit f8327af20c
43 changed files with 534 additions and 254 deletions

View File

@ -223,7 +223,8 @@ static int eukrea_cpuimx27_console_init(void)
imx27_setup_weimcs(3, 0x0000D603, 0x0D1D0D01, 0x00D20000);
#ifdef CONFIG_DRIVER_SERIAL_NS16550
add_ns16550_device(DEVICE_ID_DYNAMIC, MX27_CS3_BASE_ADDR + QUART_OFFSET, 0xf,
IORESOURCE_MEM_16BIT, &quad_uart_serial_plat);
IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
&quad_uart_serial_plat);
#endif
return 0;
}

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

@ -60,7 +60,8 @@ static int armada_370_xp_add_uart(void)
uart_plat.clock = clk_get_rate(tclk);
if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
(unsigned int)CONSOLE_UART_BASE, 32,
IORESOURCE_MEM_32BIT, &uart_plat))
IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
&uart_plat))
return -ENODEV;
return 0;
}

View File

@ -58,7 +58,8 @@ static int kirkwood_add_uart(void)
uart_plat.clock = clk_get_rate(tclk);
if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
(unsigned int)CONSOLE_UART_BASE, 32,
IORESOURCE_MEM_32BIT, &uart_plat))
IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
&uart_plat))
return -ENODEV;
return 0;
}

View File

@ -45,8 +45,8 @@ static void socfpga_uart_init(void)
clks[uart] = clk_fixed("uart", 100000000);
clkdev_add_physbase(clks[uart], CYCLONE5_UART0_ADDRESS, NULL);
clkdev_add_physbase(clks[uart], CYCLONE5_UART1_ADDRESS, NULL);
add_ns16550_device(0, 0xffc02000, 1024, IORESOURCE_MEM_8BIT,
&uart_pdata);
add_ns16550_device(0, 0xffc02000, 1024, IORESOURCE_MEM |
IORESOURCE_MEM_8BIT, &uart_pdata);
}
static void socfpga_timer_init(void)

View File

@ -50,7 +50,7 @@ static int tegra20_add_debug_console(void)
return -ENODEV;
add_ns16550_device(DEVICE_ID_DYNAMIC, base, 8 << debug_uart.shift,
IORESOURCE_MEM_8BIT, &debug_uart);
IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &debug_uart);
return 0;
}

View File

@ -36,7 +36,7 @@ static int dir320_console_init(void)
/* Register the serial port */
add_ns16550_device(DEVICE_ID_DYNAMIC, DEBUG_LL_UART_ADDR, 8,
IORESOURCE_MEM_8BIT, &serial_plat);
IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &serial_plat);
return 0;
}

View File

@ -15,7 +15,7 @@ static int console_init(void)
barebox_set_hostname("ls1b");
add_ns16550_device(DEVICE_ID_DYNAMIC, KSEG1ADDR(LS1X_UART2_BASE),
8, IORESOURCE_MEM_8BIT, &serial_plat);
8, IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &serial_plat);
return 0;
}

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
@ -76,4 +78,6 @@ static inline void __raw_writel(u32 b, volatile void __iomem *addr)
#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
#include <asm-generic/io.h>
#endif /* __ASM_MIPS_IO_H */

View File

@ -189,7 +189,9 @@ static int ar2312_console_init(void)
/* Register the serial port */
serial_plat.clock = ar2312_sys_frequency();
add_ns16550_device(DEVICE_ID_DYNAMIC, KSEG1ADDR(AR2312_UART0),
8 << AR2312_UART_SHIFT, IORESOURCE_MEM_8BIT, &serial_plat);
8 << AR2312_UART_SHIFT,
IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
&serial_plat);
return 0;
}
console_initcall(ar2312_console_init);

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

@ -15,7 +15,8 @@ static int openrisc_console_init(void)
barebox_set_hostname("or1k");
/* Register the serial port */
add_ns16550_device(DEVICE_ID_DYNAMIC, OPENRISC_SOPC_UART_BASE, 1024, IORESOURCE_MEM_8BIT, &serial_plat);
add_ns16550_device(DEVICE_ID_DYNAMIC, OPENRISC_SOPC_UART_BASE, 1024,
IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &serial_plat);
#ifdef CONFIG_DRIVER_NET_ETHOC
add_generic_device("ethoc", DEVICE_ID_DYNAMIC, NULL,

View File

@ -16,104 +16,9 @@
#ifndef __ASM_OPENRISC_IO_H
#define __ASM_OPENRISC_IO_H
#define IO_SPACE_LIMIT 0x0
#include <asm/byteorder.h>
/*
* Given a physical address and a length, return a virtual address
* that can be used to access the memory range with the caching
* properties specified by "flags".
*/
#define MAP_NOCACHE (0)
#define MAP_WRCOMBINE (0)
#define MAP_WRBACK (0)
#define MAP_WRTHROUGH (0)
static inline void *
map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
return (void *)paddr;
}
/*
* Take down a mapping set up by map_physmem().
*/
static inline void unmap_physmem(void *vaddr, unsigned long flags)
{
}
/*
* Change virtual addresses to physical addresses
*/
static inline phys_addr_t virt_to_phys(void *vaddr)
{
return (phys_addr_t)(vaddr);
}
/*
* readX/writeX() are used to access memory mapped devices. On some
* architectures the memory mapped IO stuff needs to be accessed
* differently. On the openrisc architecture, we just read/write the
* memory location directly.
*/
#define readb(addr) (*(volatile unsigned char *) (addr))
#define readw(addr) (*(volatile unsigned short *) (addr))
#define readl(addr) (*(volatile unsigned int *) (addr))
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define writeb(b, addr) ((*(volatile unsigned char *) (addr)) = (b))
#define writew(b, addr) ((*(volatile unsigned short *) (addr)) = (b))
#define writel(b, addr) ((*(volatile unsigned int *) (addr)) = (b))
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
#define memset_io(a, b, c) memset((void *)(a), (b), (c))
#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
#define out_be32(a, v) __raw_writel((v), (void __iomem __force *)(a))
#define out_be16(a, v) __raw_writew((v), (a))
#define in_be32(a) __raw_readl((const void __iomem __force *)(a))
#define in_be16(a) __raw_readw(a)
#define writel_be(v, a) out_be32((__force unsigned *)a, v)
#define readl_be(a) in_be32((__force unsigned *)a)
/*
* Again, OpenRISC does not require mem IO specific function.
*/
#define IO_BASE 0x0
#define IO_SPACE_LIMIT 0xffffffff
#define inb(port) readb((port + IO_BASE))
#define outb(value, port) writeb((value), (port + IO_BASE))
#define inb_p(port) inb((port))
#define outb_p(value, port) outb((value), (port))
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
*/
#define xlate_dev_mem_ptr(p) __va(p)
/*
* Convert a virtual cached pointer to an uncached pointer
*/
#define xlate_dev_kmem_ptr(p) p
#define ioread8(addr) readb(addr)
#define ioread16(addr) readw(addr)
#define ioread32(addr) readl(addr)
#define iowrite8(v, addr) writeb((v), (addr))
#define iowrite16(v, addr) writew((v), (addr))
#define iowrite32(v, addr) writel((v), (addr))
#include <asm-generic/io.h>
#endif

View File

@ -130,7 +130,7 @@ static int p1022ds_console_init(void)
serial_plat.clock = fsl_get_bus_freq(0);
add_ns16550_device(DEVICE_ID_DYNAMIC, CFG_IMMR + 0x4500, 16,
IORESOURCE_MEM_8BIT, &serial_plat);
IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &serial_plat);
return 0;
}

View File

@ -112,7 +112,8 @@ static int p2020_console_init(void)
serial_plat.clock = fsl_get_bus_freq(0);
add_ns16550_device(DEVICE_ID_DYNAMIC, 0xffe04500, 16, IORESOURCE_MEM_8BIT,
add_ns16550_device(DEVICE_ID_DYNAMIC, 0xffe04500, 16,
IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
&serial_plat);
return 0;
}

View File

@ -115,7 +115,8 @@ static int da923rc_console_init(void)
barebox_set_model("unknown");
serial_plat.clock = fsl_get_bus_freq(0);
add_ns16550_device(1, CFG_CCSRBAR + 0x4600, 16, IORESOURCE_MEM_8BIT,
add_ns16550_device(1, CFG_CCSRBAR + 0x4600, 16,
IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
&serial_plat);
return 0;
}

View File

@ -12,6 +12,7 @@
#define SIO_CONFIG_RA 0x398
#define SIO_CONFIG_RD 0x399
#define _IO_BASE 0
#define readb(addr) in_8((volatile u8 *)(addr))
#define writeb(b,addr) out_8((volatile u8 *)(addr), (b))

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

@ -1 +1,4 @@
obj-y += generic_pc.o
obj-$(CONFIG_DISK_INTF_PLATFORM_IDE) += intf_platform_ide.o
obj-$(CONFIG_DISK_BIOS) += disk_bios_drive.o
obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial_ns16550.o

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2009 Juergen Beisert, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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.
*
*
*/
/**
* @file
* @brief Generic PC support for the BIOS disk interface
*/
#include <common.h>
#include <driver.h>
#include <init.h>
#include <linux/err.h>
#include "envsector.h"
static int bios_disk_init(void)
{
struct cdev *cdev;
add_generic_device("biosdrive", DEVICE_ID_DYNAMIC, NULL, 0, 0,
IORESOURCE_MEM, NULL);
if (pers_env_size != PATCH_AREA_PERS_SIZE_UNUSED) {
cdev = devfs_add_partition("biosdisk0",
pers_env_storage * 512,
(unsigned)pers_env_size * 512,
DEVFS_PARTITION_FIXED, "env0");
printf("Partition: %ld\n", IS_ERR(cdev) ? PTR_ERR(cdev) : 0);
} else
printf("No persistent storage defined\n");
return 0;
}
device_initcall(bios_disk_init);

View File

@ -1,6 +1,4 @@
/*
* Copyright (C) 2009 Juergen Beisert, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
@ -16,19 +14,23 @@
/**
* @file
* @brief x86 Architecture Initialization routines
* @brief x86 Generic PC common definitions
*/
#ifndef __X86_ENVSECTOR_H
#define __ENVSECTOR_H
#include <io.h>
/*
* These datas are from the MBR, created by the linker and filled by the
* setup tool while installing barebox on the disk drive
*/
extern uint64_t pers_env_storage;
extern uint16_t pers_env_size;
extern uint8_t pers_env_drive;
/** to work with the 8250 UART driver implementation we need this function */
unsigned int x86_uart_read(unsigned long base, unsigned char reg_idx)
{
return inb(base + reg_idx);
}
/**
* Persistent environment "not used" marker.
* Note: Must be in accordance to the value the tool "setup_mbr" writes.
*/
#define PATCH_AREA_PERS_SIZE_UNUSED 0x000
/** to work with the 8250 UART driver implementation we need this function */
void x86_uart_write(unsigned int val, unsigned long base, unsigned char reg_idx)
{
outb(val, base + reg_idx);
}
#endif

View File

@ -24,67 +24,16 @@
#include <driver.h>
#include <init.h>
#include <asm/syslib.h>
#include <ns16550.h>
#include <linux/err.h>
/*
* These datas are from the MBR, created by the linker and filled by the
* setup tool while installing barebox on the disk drive
*/
extern uint64_t pers_env_storage;
extern uint16_t pers_env_size;
extern uint8_t pers_env_drive;
/**
* Persistent environment "not used" marker.
* Note: Must be in accordance to the value the tool "setup_mbr" writes.
*/
#define PATCH_AREA_PERS_SIZE_UNUSED 0x000
static int devices_init(void)
{
struct cdev *cdev;
/* extended memory only */
add_mem_device("ram0", 0x0, bios_get_memsize() << 10,
IORESOURCE_MEM_WRITEABLE);
add_generic_device("biosdrive", DEVICE_ID_DYNAMIC, NULL, 0, 0, IORESOURCE_MEM,
NULL);
if (pers_env_size != PATCH_AREA_PERS_SIZE_UNUSED) {
cdev = devfs_add_partition("biosdisk0",
pers_env_storage * 512,
(unsigned)pers_env_size * 512,
DEVFS_PARTITION_FIXED, "env0");
printf("Partition: %ld\n", IS_ERR(cdev) ? PTR_ERR(cdev) : 0);
} else
printf("No persistent storage defined\n");
return 0;
}
device_initcall(devices_init);
#ifdef CONFIG_DRIVER_SERIAL_NS16550
static struct NS16550_plat serial_plat = {
.clock = 1843200,
.reg_read = x86_uart_read,
.reg_write = x86_uart_write,
};
static int pc_console_init(void)
{
barebox_set_model("X86 generic barebox");
barebox_set_hostname("x86");
/* Register the serial port */
add_ns16550_device(DEVICE_ID_DYNAMIC, 0x3f8, 8, 0, &serial_plat);
return 0;
}
console_initcall(pc_console_init);
#endif
device_initcall(devices_init);
/** @page generic_pc Generic PC based bootloader

View File

@ -0,0 +1,93 @@
/*
* Copyright (C) 2014 Juergen Beisert, Pengutronix, Michel Stam,
* Fugro Intersite
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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.
*
*
*/
/**
* @file
* @brief Generic PC support for the IDE platform driver
*/
#include <common.h>
#include <driver.h>
#include <init.h>
#include <linux/err.h>
#include <platform_ide.h>
#include "envsector.h"
static struct ide_port_info ide_plat = {
.ioport_shift = 0,
.dataif_be = 0,
};
static struct resource primary_ide_resources[] = {
{
.name = "base",
.start = 0x1f0,
.end = 0x1f7,
.flags = IORESOURCE_IO
},
{
.name = "alt",
.start = 0x3f6,
.end = 0x3f7,
.flags = IORESOURCE_IO
}
};
static struct resource secondary_ide_resources[] = {
{
.name = "base",
.start = 0x170,
.end = 0x177,
.flags = IORESOURCE_IO
},
};
static struct device_d primary_ide_device = {
.name = "ide_intf",
.id = 0,
.platform_data = &ide_plat,
.resource = primary_ide_resources,
.num_resources = ARRAY_SIZE(primary_ide_resources),
};
static struct device_d secondary_ide_device = {
.name = "ide_intf",
.id = 1,
.platform_data = &ide_plat,
.resource = secondary_ide_resources,
.num_resources = ARRAY_SIZE(secondary_ide_resources),
};
static int platform_ide_init(void)
{
struct cdev *cdev;
platform_device_register(&primary_ide_device);
platform_device_register(&secondary_ide_device);
if (pers_env_size != PATCH_AREA_PERS_SIZE_UNUSED) {
cdev = devfs_add_partition("ata0",
pers_env_storage * 512,
(unsigned)pers_env_size * 512,
DEVFS_PARTITION_FIXED, "env0");
printf("Partition: %ld\n", IS_ERR(cdev) ? PTR_ERR(cdev) : 0);
} else
printf("No persistent storage defined\n");
return 0;
}
device_initcall(platform_ide_init);

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2009 Juergen Beisert, Pengutronix, Michel Stam,
* Fugro Intersite
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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.
*
*
*/
/**
* @file
* @brief Generic PC support to let barebox acting as a boot loader
*/
#include <common.h>
#include <types.h>
#include <driver.h>
#include <init.h>
#include <asm/syslib.h>
#include <ns16550.h>
#include <linux/err.h>
static struct NS16550_plat serial_plat = {
.clock = 1843200,
};
static int pc_console_init(void)
{
barebox_set_model("X86 generic barebox");
barebox_set_hostname("x86");
/* Register the serial port */
add_ns16550_device(DEVICE_ID_DYNAMIC, 0x3f8, 8, IORESOURCE_IO,
&serial_plat);
add_ns16550_device(DEVICE_ID_DYNAMIC, 0x2f8, 8, IORESOURCE_IO,
&serial_plat);
return 0;
}
console_initcall(pc_console_init);

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

@ -14,9 +14,6 @@
*
*/
extern unsigned int x86_uart_read(unsigned long, unsigned char);
extern void x86_uart_write(unsigned int, unsigned long, unsigned char);
#ifdef CONFIG_X86_BIOS_BRINGUP
extern int bios_disk_rw_int13_extensions(int, int, void*) __attribute__((regparm(3)));

View File

@ -1,4 +1,3 @@
obj-y += generic.o
obj-y += reset.o
# reference clocksource

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

@ -14,6 +14,67 @@
#define DISK_MASTER 0
#define DISK_SLAVE 1
/**
* Read a byte from the ATA controller
* @param ide IDE port structure
* @param addr Register adress
* @return Register's content
*/
static inline uint8_t ata_rd_byte(struct ide_port *ide, void __iomem *addr)
{
if (ide->io.mmio)
return readb(addr);
else
return (uint8_t) inb((int) addr);
}
/**
* Write a byte to the ATA controller
* @param ide IDE port structure
* @param value Value to write
* @param addr Register adress
* @return Register's content
*/
static inline void ata_wr_byte(struct ide_port *ide, uint8_t value,
void __iomem *addr)
{
if (ide->io.mmio)
writeb(value, addr);
else
outb(value, (int) addr);
}
/**
* Read a word from the ATA controller
* @param ide IDE port structure
* @param addr Register adress
* @return Register's content
*/
static inline uint16_t ata_rd_word(struct ide_port *ide,
void __iomem *addr)
{
if (ide->io.mmio)
return readw(addr);
else
return (uint16_t) inw((int) addr);
}
/**
* Write a word to the ATA controller
* @param ide IDE port structure
* @param value Value to write
* @param addr Register adress
* @return Register's content
*/
static inline void ata_wr_word(struct ide_port *ide, uint16_t value,
void __iomem *addr)
{
if (ide->io.mmio)
writew(value, addr);
else
outw(value, (int) addr);
}
/**
* Read the status register of the ATA drive
* @param io Register file
@ -21,7 +82,7 @@
*/
static uint8_t ata_rd_status(struct ide_port *ide)
{
return readb(ide->io.status_addr);
return ata_rd_byte(ide, ide->io.status_addr);
}
/**
@ -83,12 +144,13 @@ static int ata_set_lba_sector(struct ide_port *ide, unsigned drive, uint64_t num
if (num > 0x0FFFFFFF || drive > 1)
return -EINVAL;
writeb(0xA0 | LBA_FLAG | drive << 4 | num >> 24, ide->io.device_addr);
writeb(0x00, ide->io.error_addr);
writeb(0x01, ide->io.nsect_addr);
writeb(num, ide->io.lbal_addr); /* 0 ... 7 */
writeb(num >> 8, ide->io.lbam_addr); /* 8 ... 15 */
writeb(num >> 16, ide->io.lbah_addr); /* 16 ... 23 */
ata_wr_byte(ide, 0xA0 | LBA_FLAG | drive << 4 | num >> 24,
ide->io.device_addr);
ata_wr_byte(ide, 0x00, ide->io.error_addr);
ata_wr_byte(ide, 0x01, ide->io.nsect_addr);
ata_wr_byte(ide, num, ide->io.lbal_addr); /* 0 ... 7 */
ata_wr_byte(ide, num >> 8, ide->io.lbam_addr); /* 8 ... 15 */
ata_wr_byte(ide, num >> 16, ide->io.lbah_addr); /* 16 ... 23 */
return 0;
}
@ -107,7 +169,7 @@ static int ata_wr_cmd(struct ide_port *ide, uint8_t cmd)
if (rc != 0)
return rc;
writeb(cmd, ide->io.command_addr);
ata_wr_byte(ide, cmd, ide->io.command_addr);
return 0;
}
@ -118,7 +180,7 @@ static int ata_wr_cmd(struct ide_port *ide, uint8_t cmd)
*/
static void ata_wr_dev_ctrl(struct ide_port *ide, uint8_t val)
{
writeb(val, ide->io.ctl_addr);
ata_wr_byte(ide, val, ide->io.ctl_addr);
}
/**
@ -133,10 +195,10 @@ static void ata_rd_sector(struct ide_port *ide, void *buf)
if (ide->io.dataif_be) {
for (; u > 0; u--)
*b++ = be16_to_cpu(readw(ide->io.data_addr));
*b++ = be16_to_cpu(ata_rd_word(ide, ide->io.data_addr));
} else {
for (; u > 0; u--)
*b++ = le16_to_cpu(readw(ide->io.data_addr));
*b++ = le16_to_cpu(ata_rd_word(ide, ide->io.data_addr));
}
}
@ -152,10 +214,10 @@ static void ata_wr_sector(struct ide_port *ide, const void *buf)
if (ide->io.dataif_be) {
for (; u > 0; u--)
writew(cpu_to_be16(*b++), ide->io.data_addr);
ata_wr_word(ide, cpu_to_be16(*b++), ide->io.data_addr);
} else {
for (; u > 0; u--)
writew(cpu_to_le16(*b++), ide->io.data_addr);
ata_wr_word(ide, cpu_to_le16(*b++), ide->io.data_addr);
}
}
@ -169,10 +231,10 @@ static int ide_read_id(struct ata_port *port, void *buf)
struct ide_port *ide = to_ata_drive_access(port);
int rc;
writeb(0xA0, ide->io.device_addr); /* FIXME drive */
writeb(0x00, ide->io.lbal_addr);
writeb(0x00, ide->io.lbam_addr);
writeb(0x00, ide->io.lbah_addr);
ata_wr_byte(ide, 0xA0, ide->io.device_addr); /* FIXME drive */
ata_wr_byte(ide, 0x00, ide->io.lbal_addr);
ata_wr_byte(ide, 0x00, ide->io.lbam_addr);
ata_wr_byte(ide, 0x00, ide->io.lbah_addr);
rc = ata_wr_cmd(ide, ATA_CMD_ID_ATA);
if (rc != 0)
@ -327,6 +389,8 @@ int ide_port_register(struct ide_port *ide)
ide->port.ops = &ide_ops;
ret = ata_port_register(&ide->port);
if (!ret)
ata_port_detect(&ide->port);
if (ret)
free(ide);

View File

@ -82,15 +82,46 @@ static int platform_ide_probe(struct device_d *dev)
struct ide_port_info *pdata = dev->platform_data;
struct ide_port *ide;
void *reg_base, *alt_base;
struct resource *reg, *alt;
int mmio;
if (pdata == NULL) {
dev_err(dev, "No platform data. Cannot continue\n");
return -EINVAL;
}
alt = NULL;
reg = dev_get_resource(dev, IORESOURCE_MEM, 0);
mmio = (reg != NULL);
if (reg != NULL) {
reg = request_iomem_region(dev_name(dev), reg->start,
reg->end);
alt = dev_get_resource(dev, IORESOURCE_MEM, 1);
if (alt != NULL)
alt = request_iomem_region(dev_name(dev), alt->start,
alt->end);
} else {
reg = dev_get_resource(dev, IORESOURCE_IO, 0);
if (reg != NULL) {
reg = request_ioport_region(dev_name(dev), reg->start,
reg->end);
alt = dev_get_resource(dev, IORESOURCE_IO, 1);
if (alt != NULL)
alt = request_ioport_region(dev_name(dev),
alt->start,
alt->end);
}
}
reg_base = (reg != NULL ? (void __force __iomem *) reg->start : NULL);
alt_base = (alt != NULL ? (void __force __iomem *) alt->start : NULL);
if (!reg_base)
return -ENODEV;
ide = xzalloc(sizeof(*ide));
reg_base = dev_request_mem_region(dev, 0);
alt_base = dev_request_mem_region(dev, 1);
ide->io.mmio = mmio;
platform_ide_setup_port(reg_base, alt_base, &ide->io, pdata->ioport_shift);
ide->io.reset = pdata->reset;
ide->io.dataif_be = pdata->dataif_be;
@ -125,6 +156,4 @@ device_platform_driver(platform_ide_driver);
*
* This driver does not change any access timings due to the fact it has no idea
* how to do so. So, do not expect an impressive data throughput.
*
* @todo Support also the IO port access method, the x86 architecture is using
*/

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

@ -47,6 +47,7 @@ struct ns16550_priv {
struct console_device cdev;
struct NS16550_plat plat;
int access_width;
int mmio;
struct clk *clk;
uint32_t fcrval;
};
@ -61,6 +62,90 @@ struct ns16550_drvdata {
const char *linux_console_name;
};
/**
* @brief read system i/o (byte)
* @param[in] addr address to read
* @param[in] mmio memory i/o space or i/o port space
*/
static inline uint8_t ns16550_sys_readb(void __iomem *addr, int mmio)
{
if (mmio)
return readb(addr);
else
return (uint8_t) inb((int) addr);
}
/**
* @brief read system i/o (word)
* @param[in] addr address to read
* @param[in] mmio memory i/o space or i/o port space
*/
static inline uint16_t ns16550_sys_readw(void __iomem *addr, int mmio)
{
if (mmio)
return readw(addr);
else
return (uint16_t) inw((int) addr);
}
/**
* @brief read system i/o (dword)
* @param[in] addr address to read
* @param[in] mmio memory i/o space or i/o port space
*/
static inline uint32_t ns16550_sys_readl(void __iomem *addr, int mmio)
{
if (mmio)
return readl(addr);
else
return (uint32_t) inl((int) addr);
}
/**
* @brief write system i/o (byte)
* @param[in] val data to write
* @param[in] addr address to write to
* @param[in] mmio memory i/o space or i/o port space
*/
static inline void ns16550_sys_writeb(uint8_t val, void __iomem *addr,
int mmio)
{
if (mmio)
writeb(val, addr);
else
outb(val, (int) addr);
}
/**
* @brief read system i/o (word)
* @param[in] val data to write
* @param[in] addr address to write to
* @param[in] mmio memory i/o space or i/o port space
*/
static inline void ns16550_sys_writew(uint16_t val, void __iomem *addr,
int mmio)
{
if (mmio)
writew(val, addr);
else
outw(val, (int) addr);
}
/**
* @brief read system i/o (dword)
* @param[in] val data to write
* @param[in] addr address to write to
* @param[in] mmio memory i/o space or i/o port space
*/
static inline void ns16550_sys_writel(uint32_t val, void __iomem *addr,
int mmio)
{
if (mmio)
writel(val, addr);
else
outl(val, (int) addr);
}
/**
* @brief read register
*
@ -78,16 +163,13 @@ static uint32_t ns16550_read(struct console_device *cdev, uint32_t off)
off <<= plat->shift;
if (plat->reg_read)
return plat->reg_read((unsigned long)dev->priv, off);
switch (width) {
case IORESOURCE_MEM_8BIT:
return readb(dev->priv + off);
return ns16550_sys_readb(dev->priv + off, priv->mmio);
case IORESOURCE_MEM_16BIT:
return readw(dev->priv + off);
return ns16550_sys_readw(dev->priv + off, priv->mmio);
case IORESOURCE_MEM_32BIT:
return readl(dev->priv + off);
return ns16550_sys_readl(dev->priv + off, priv->mmio);
}
return -1;
}
@ -109,20 +191,15 @@ static void ns16550_write(struct console_device *cdev, uint32_t val,
off <<= plat->shift;
if (plat->reg_write) {
plat->reg_write(val, (unsigned long)dev->priv, off);
return;
}
switch (width) {
case IORESOURCE_MEM_8BIT:
writeb(val & 0xff, dev->priv + off);
ns16550_sys_writeb(val & 0xff, dev->priv + off, priv->mmio);
break;
case IORESOURCE_MEM_16BIT:
writew(val & 0xffff, dev->priv + off);
ns16550_sys_writew(val & 0xffff, dev->priv + off, priv->mmio);
break;
case IORESOURCE_MEM_32BIT:
writel(val, dev->priv + off);
ns16550_sys_writel(val, dev->priv + off, priv->mmio);
break;
}
}
@ -297,16 +374,30 @@ static int ns16550_probe(struct device_d *dev)
struct console_device *cdev;
struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data;
struct ns16550_drvdata *devtype;
struct resource *res;
int ret;
ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
if (ret)
devtype = &ns16550_drvdata;
dev->priv = dev_request_mem_region(dev, 0);
priv = xzalloc(sizeof(*priv));
res = dev_get_resource(dev, IORESOURCE_MEM, 0);
priv->mmio = (res != NULL);
if (res) {
res = request_iomem_region(dev_name(dev), res->start, res->end);
} else {
res = dev_get_resource(dev, IORESOURCE_IO, 0);
if (res)
res = request_ioport_region(dev_name(dev), res->start,
res->end);
}
if (!res)
goto err;
dev->priv = (void __force __iomem *) res->start;
if (plat)
priv->plat = *plat;
else

View File

@ -119,6 +119,7 @@ struct ata_ioports {
/* hard reset line handling */
void (*reset)(int); /* true: assert reset, false: de-assert reset */
int dataif_be; /* true if 16 bit data register is big endian */
int mmio; /* true if memory-mapped io */
};
struct ata_port;

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
*/
@ -275,7 +278,7 @@ static inline struct device_d *add_ns16550_device(int id, resource_size_t start,
resource_size_t size, int flags, struct NS16550_plat *pdata)
{
return add_generic_device("ns16550_serial", id, NULL, start, size,
IORESOURCE_MEM | flags, pdata);
flags, pdata);
}
#ifdef CONFIG_DRIVER_NET_DM9K

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

View File

@ -33,18 +33,9 @@
struct NS16550_plat {
/** Clock speed */
unsigned int clock;
/**
* register read access capability
*/
unsigned int (*reg_read) (unsigned long base, unsigned char reg_offset);
/**
* register write access capability
*/
void (*reg_write) (unsigned int val, unsigned long base,
unsigned char reg_offset);
int shift;
unsigned int flags;
int mmio;
#define NS16650_FLAG_DISABLE_FIFO 1
};