Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
device.c
Go to the documentation of this file.
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 
25 static const signed char gpio3_irq_mappings[] = {
26  S6_INTC_GPIO(3),
27  -1
28 };
29 
30 static const signed char uart_irq_mappings[] = {
31  S6_INTC_UART(0),
32  S6_INTC_UART(1),
33  -1,
34 };
35 
36 static const signed char gmac_irq_mappings[] = {
41  -1
42 };
43 
44 const 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 
50 static 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,
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,
68  },
69  { },
70 };
71 
72 static 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)
83  .end = (resource_size_t)
85  .flags = IORESOURCE_DMA,
86  },
87  {
88  .name = "dma",
89  .start = (resource_size_t)
91  .end = (resource_size_t)
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,
105  },
106  {
107  .name = "irq",
108  .start = (resource_size_t)PHY_POLL,
110  },
111 };
112 
113 static 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;
126 free:
127  gpio_free(pin);
128 fail:
129  return PHY_POLL;
130 }
131 
132 static 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 
151 static 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 }
161 arch_initcall_sync(device_init);