linux/arch/xtensa/platforms/s6105/device.c
<<
>>
Prefs
   1/*
   2 * s6105 platform devices
   3 *
   4 * Copyright (c) 2009 emlix GmbH
   5 */
   6
   7#include <linux/kernel.h>
   8#include <linux/gpio.h>
   9#include <linux/init.h>
  10#include <linux/irq.h>
  11#include <linux/phy.h>
  12#include <linux/platform_device.h>
  13#include <linux/serial.h>
  14#include <linux/serial_8250.h>
  15
  16#include <variant/hardware.h>
  17#include <variant/dmac.h>
  18
  19#include <platform/gpio.h>
  20
  21#define GPIO3_INTNUM            3
  22#define UART_INTNUM             4
  23#define GMAC_INTNUM             5
  24
  25static const signed char gpio3_irq_mappings[] = {
  26        S6_INTC_GPIO(3),
  27        -1
  28};
  29
  30static const signed char uart_irq_mappings[] = {
  31        S6_INTC_UART(0),
  32        S6_INTC_UART(1),
  33        -1,
  34};
  35
  36static const signed char gmac_irq_mappings[] = {
  37        S6_INTC_GMAC_STAT,
  38        S6_INTC_GMAC_ERR,
  39        S6_INTC_DMA_HOSTTERMCNT(0),
  40        S6_INTC_DMA_HOSTTERMCNT(1),
  41        -1
  42};
  43
  44const signed char *platform_irq_mappings[NR_IRQS] = {
  45        [GPIO3_INTNUM] = gpio3_irq_mappings,
  46        [UART_INTNUM] = uart_irq_mappings,
  47        [GMAC_INTNUM] = gmac_irq_mappings,
  48};
  49
  50static struct plat_serial8250_port serial_platform_data[] = {
  51        {
  52                .membase = (void *)S6_REG_UART + 0x0000,
  53                .mapbase = S6_REG_UART + 0x0000,
  54                .irq = UART_INTNUM,
  55                .uartclk = S6_SCLK,
  56                .regshift = 2,
  57                .iotype = SERIAL_IO_MEM,
  58                .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
  59        },
  60        {
  61                .membase = (void *)S6_REG_UART + 0x1000,
  62                .mapbase = S6_REG_UART + 0x1000,
  63                .irq = UART_INTNUM,
  64                .uartclk = S6_SCLK,
  65                .regshift = 2,
  66                .iotype = SERIAL_IO_MEM,
  67                .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
  68        },
  69        { },
  70};
  71
  72static struct resource s6_gmac_resource[] = {
  73        {
  74                .name   = "mem",
  75                .start  = (resource_size_t)S6_REG_GMAC,
  76                .end    = (resource_size_t)S6_REG_GMAC + 0x10000 - 1,
  77                .flags  = IORESOURCE_MEM,
  78        },
  79        {
  80                .name   = "dma",
  81                .start  = (resource_size_t)
  82                        DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX),
  83                .end    = (resource_size_t)
  84                        DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX) + 0x100 - 1,
  85                .flags  = IORESOURCE_DMA,
  86        },
  87        {
  88                .name   = "dma",
  89                .start  = (resource_size_t)
  90                        DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX),
  91                .end    = (resource_size_t)
  92                        DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX) + 0x100 - 1,
  93                .flags  = IORESOURCE_DMA,
  94        },
  95        {
  96                .name   = "io",
  97                .start  = (resource_size_t)S6_MEM_GMAC,
  98                .end    = (resource_size_t)S6_MEM_GMAC + 0x2000000 - 1,
  99                .flags  = IORESOURCE_IO,
 100        },
 101        {
 102                .name   = "irq",
 103                .start  = (resource_size_t)GMAC_INTNUM,
 104                .flags  = IORESOURCE_IRQ,
 105        },
 106        {
 107                .name   = "irq",
 108                .start  = (resource_size_t)PHY_POLL,
 109                .flags  = IORESOURCE_IRQ,
 110        },
 111};
 112
 113static int __init prepare_phy_irq(int pin)
 114{
 115        int irq;
 116        if (gpio_request(pin, "s6gmac_phy") < 0)
 117                goto fail;
 118        if (gpio_direction_input(pin) < 0)
 119                goto free;
 120        irq = gpio_to_irq(pin);
 121        if (irq < 0)
 122                goto free;
 123        if (irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0)
 124                goto free;
 125        return irq;
 126free:
 127        gpio_free(pin);
 128fail:
 129        return PHY_POLL;
 130}
 131
 132static struct platform_device platform_devices[] = {
 133        {
 134                .name = "serial8250",
 135                .id = PLAT8250_DEV_PLATFORM,
 136                .dev = {
 137                        .platform_data = serial_platform_data,
 138                },
 139        },
 140        {
 141                .name = "s6gmac",
 142                .id = 0,
 143                .resource = s6_gmac_resource,
 144                .num_resources = ARRAY_SIZE(s6_gmac_resource),
 145        },
 146        {
 147                I2C_BOARD_INFO("m41t62", S6I2C_ADDR_M41T62),
 148        },
 149};
 150
 151static int __init device_init(void)
 152{
 153        int i;
 154
 155        s6_gmac_resource[5].start = prepare_phy_irq(GPIO_PHY_IRQ);
 156
 157        for (i = 0; i < ARRAY_SIZE(platform_devices); i++)
 158                platform_device_register(&platform_devices[i]);
 159        return 0;
 160}
 161arch_initcall_sync(device_init);
 162