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