xtensa: s6105 specific configuration for s6gmac
[pandora-kernel.git] / arch / xtensa / platforms / s6105 / device.c
index 78b08be..963634a 100644 (file)
@@ -5,14 +5,27 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
 
 #include <variant/hardware.h>
+#include <variant/dmac.h>
 
+#include <platform/gpio.h>
+
+#define GPIO3_INTNUM           3
 #define UART_INTNUM            4
+#define GMAC_INTNUM            5
+
+static const signed char gpio3_irq_mappings[] = {
+       S6_INTC_GPIO(3),
+       -1
+};
 
 static const signed char uart_irq_mappings[] = {
        S6_INTC_UART(0),
@@ -20,8 +33,18 @@ static const signed char uart_irq_mappings[] = {
        -1,
 };
 
+static const signed char gmac_irq_mappings[] = {
+       S6_INTC_GMAC_STAT,
+       S6_INTC_GMAC_ERR,
+       S6_INTC_DMA_HOSTTERMCNT(0),
+       S6_INTC_DMA_HOSTTERMCNT(1),
+       -1
+};
+
 const signed char *platform_irq_mappings[NR_IRQS] = {
+       [GPIO3_INTNUM] = gpio3_irq_mappings,
        [UART_INTNUM] = uart_irq_mappings,
+       [GMAC_INTNUM] = gmac_irq_mappings,
 };
 
 static struct plat_serial8250_port serial_platform_data[] = {
@@ -46,6 +69,66 @@ static struct plat_serial8250_port serial_platform_data[] = {
        { },
 };
 
+static struct resource s6_gmac_resource[] = {
+       {
+               .name   = "mem",
+               .start  = (resource_size_t)S6_REG_GMAC,
+               .end    = (resource_size_t)S6_REG_GMAC + 0x10000 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = "dma",
+               .start  = (resource_size_t)
+                       DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX),
+               .end    = (resource_size_t)
+                       DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX) + 0x100 - 1,
+               .flags  = IORESOURCE_DMA,
+       },
+       {
+               .name   = "dma",
+               .start  = (resource_size_t)
+                       DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX),
+               .end    = (resource_size_t)
+                       DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX) + 0x100 - 1,
+               .flags  = IORESOURCE_DMA,
+       },
+       {
+               .name   = "io",
+               .start  = (resource_size_t)S6_MEM_GMAC,
+               .end    = (resource_size_t)S6_MEM_GMAC + 0x2000000 - 1,
+               .flags  = IORESOURCE_IO,
+       },
+       {
+               .name   = "irq",
+               .start  = (resource_size_t)GMAC_INTNUM,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .name   = "irq",
+               .start  = (resource_size_t)PHY_POLL,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static int __init prepare_phy_irq(int pin)
+{
+       int irq;
+       if (gpio_request(pin, "s6gmac_phy") < 0)
+               goto fail;
+       if (gpio_direction_input(pin) < 0)
+               goto free;
+       irq = gpio_to_irq(pin);
+       if (irq < 0)
+               goto free;
+       if (set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0)
+               goto free;
+       return irq;
+free:
+       gpio_free(pin);
+fail:
+       return PHY_POLL;
+}
+
 static struct platform_device platform_devices[] = {
        {
                .name = "serial8250",
@@ -54,12 +137,20 @@ static struct platform_device platform_devices[] = {
                        .platform_data = serial_platform_data,
                },
        },
+       {
+               .name = "s6gmac",
+               .id = 0,
+               .resource = s6_gmac_resource,
+               .num_resources = ARRAY_SIZE(s6_gmac_resource),
+       },
 };
 
 static int __init device_init(void)
 {
        int i;
 
+       s6_gmac_resource[5].start = prepare_phy_irq(GPIO_PHY_IRQ);
+
        for (i = 0; i < ARRAY_SIZE(platform_devices); i++)
                platform_device_register(&platform_devices[i]);
        return 0;