[PATCH] atmel_serial: Pass fixed register mappings through platform_data
authorHaavard Skinnemoen <hskinnemoen@atmel.com>
Wed, 4 Oct 2006 14:02:08 +0000 (16:02 +0200)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 4 Oct 2006 17:25:05 +0000 (10:25 -0700)
In order to initialize the serial console early, the atmel_serial
driver had to do a hack where it compared the physical address of the
port with an address known to be permanently mapped, and used it as a
virtual address. This got around the limitation that ioremap() isn't
always available when the console is being initalized.

This patch removes that hack and replaces it with a new "regs" field
in struct atmel_uart_data that the board-specific code can initialize
to a fixed virtual mapping for platform devices where this is possible.
It also initializes the DBGU's regs field with the address the driver
used to check against.

On AVR32, the "regs" field is initialized from the physical base
address when this it can be accessed through a permanently 1:1 mapped
segment, i.e. the P4 segment.

If regs is NULL, the console initialization is delayed until the "real"
driver is up and running and ioremap() can be used.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Acked-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/arm/mach-at91rm9200/devices.c
arch/avr32/mach-at32ap/at32ap7000.c
drivers/serial/atmel_serial.c
include/asm-arm/arch-at91rm9200/board.h
include/asm-avr32/arch-at32ap/board.h

index 5a3919f09d4d784e6166136da9cffa3b8e92b113..059824376629db538a6306e56bee80b9dbaeeb69 100644 (file)
@@ -561,6 +561,7 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
+       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static struct platform_device at91rm9200_dbgu_device = {
index 05d1296bd7b23383a877e33cdc7a0ff87b0ee98c..3dd3058750878cf0fedc2895bc0b1442a49b2438 100644 (file)
@@ -523,32 +523,48 @@ void __init at32_add_system_devices(void)
  *  USART
  * -------------------------------------------------------------------- */
 
+static struct atmel_uart_data atmel_usart0_data = {
+       .use_dma_tx     = 1,
+       .use_dma_rx     = 1,
+};
 static struct resource atmel_usart0_resource[] = {
        PBMEM(0xffe00c00),
        IRQ(7),
 };
-DEFINE_DEV(atmel_usart, 0);
+DEFINE_DEV_DATA(atmel_usart, 0);
 DEV_CLK(usart, atmel_usart0, pba, 4);
 
+static struct atmel_uart_data atmel_usart1_data = {
+       .use_dma_tx     = 1,
+       .use_dma_rx     = 1,
+};
 static struct resource atmel_usart1_resource[] = {
        PBMEM(0xffe01000),
        IRQ(7),
 };
-DEFINE_DEV(atmel_usart, 1);
+DEFINE_DEV_DATA(atmel_usart, 1);
 DEV_CLK(usart, atmel_usart1, pba, 4);
 
+static struct atmel_uart_data atmel_usart2_data = {
+       .use_dma_tx     = 1,
+       .use_dma_rx     = 1,
+};
 static struct resource atmel_usart2_resource[] = {
        PBMEM(0xffe01400),
        IRQ(8),
 };
-DEFINE_DEV(atmel_usart, 2);
+DEFINE_DEV_DATA(atmel_usart, 2);
 DEV_CLK(usart, atmel_usart2, pba, 5);
 
+static struct atmel_uart_data atmel_usart3_data = {
+       .use_dma_tx     = 1,
+       .use_dma_rx     = 1,
+};
 static struct resource atmel_usart3_resource[] = {
        PBMEM(0xffe01800),
        IRQ(9),
 };
-DEFINE_DEV(atmel_usart, 3);
+DEFINE_DEV_DATA(atmel_usart, 3);
 DEV_CLK(usart, atmel_usart3, pba, 6);
 
 static inline void configure_usart0_pins(void)
@@ -597,8 +613,13 @@ static struct platform_device *setup_usart(unsigned int id)
                configure_usart3_pins();
                break;
        default:
-               pdev = NULL;
-               break;
+               return NULL;
+       }
+
+       if (PXSEG(pdev->resource[0].start) == P4SEG) {
+               /* Addresses in the P4 segment are permanently mapped 1:1 */
+               struct atmel_uart_data *data = pdev->dev.platform_data;
+               data->regs = (void __iomem *)pdev->resource[0].start;
        }
 
        return pdev;
index 2f9d99bb9587ab1217b3a05ed8cad389e58481bf..34212df3980013c7013dcd33dcd78ddfefb8c336 100644 (file)
@@ -694,8 +694,9 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, struct
        port->mapbase   = pdev->resource[0].start;
        port->irq       = pdev->resource[1].start;
 
-       if (port->mapbase == AT91_VA_BASE_SYS + AT91_DBGU)              /* Part of system perpherals - already mapped */
-               port->membase = (void __iomem *) port->mapbase;
+       if (data->regs)
+               /* Already mapped by setup code */
+               port->membase = data->regs;
        else {
                port->flags     |= UPF_IOREMAP;
                port->membase   = NULL;
index d56527055c9d6dcb9377b037466db19a97855c54..3cc9aec80f9d50320dc2231f314d243a4040287f 100644 (file)
@@ -103,6 +103,7 @@ extern void __init at91_init_serial(struct at91_uart_config *config);
 struct atmel_uart_data {
        short           use_dma_tx;     /* use transmit DMA? */
        short           use_dma_rx;     /* use receive DMA? */
+       void __iomem    *regs;          /* virtual base address, if any */
 };
 extern void __init at91_add_device_serial(void);
 
index 82e5404d2f48e53307730e88463e0f7de6677a5f..435507281f8958d86527e8a4c269bd65fdb47751 100644 (file)
@@ -12,6 +12,11 @@ void at32_add_system_devices(void);
 #define ATMEL_MAX_UART 4
 extern struct platform_device *atmel_default_console_device;
 
+struct atmel_uart_data {
+       short           use_dma_tx;     /* use transmit DMA? */
+       short           use_dma_rx;     /* use receive DMA? */
+       void __iomem    *regs;          /* virtual base address, if any */
+};
 struct platform_device *at32_add_device_usart(unsigned int id);
 
 struct eth_platform_data {