Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
board-og.c
Go to the documentation of this file.
1 /*
2  * board-og.c -- support for the OpenGear KS8695 based boards.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/interrupt.h>
12 #include <linux/init.h>
13 #include <linux/delay.h>
14 #include <linux/platform_device.h>
15 #include <linux/serial_8250.h>
16 #include <linux/gpio.h>
17 #include <linux/irq.h>
18 #include <asm/mach-types.h>
19 #include <asm/mach/arch.h>
20 #include <asm/mach/map.h>
21 #include <mach/devices.h>
22 #include <mach/regs-gpio.h>
23 #include <mach/gpio-ks8695.h>
24 #include "generic.h"
25 
26 static int og_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
27 {
28  if (machine_is_im4004() && (slot == 8))
29  return KS8695_IRQ_EXTERN1;
30  return KS8695_IRQ_EXTERN0;
31 }
32 
33 static struct ks8695_pci_cfg __initdata og_pci = {
34  .mode = KS8695_MODE_PCI,
35  .map_irq = og_pci_map_irq,
36 };
37 
38 static void __init og_register_pci(void)
39 {
40  /* Initialize the GPIO lines for interrupt mode */
42 
43  /* Cardbus Slot */
44  if (machine_is_im4004())
46 
47  ks8695_init_pci(&og_pci);
48 }
49 
50 /*
51  * The PCI bus reset is driven by a dedicated GPIO line. Toggle it here
52  * and bring the PCI bus out of reset.
53  */
54 static void __init og_pci_bus_reset(void)
55 {
56  unsigned int rstline = 1;
57 
58  /* Some boards use a different GPIO as the PCI reset line */
59  if (machine_is_im4004())
60  rstline = 2;
61  else if (machine_is_im42xx())
62  rstline = 0;
63 
64  gpio_request(rstline, "PCI reset");
65  gpio_direction_output(rstline, 0);
66 
67  /* Drive a reset on the PCI reset line */
68  gpio_set_value(rstline, 1);
69  gpio_set_value(rstline, 0);
70  mdelay(100);
71  gpio_set_value(rstline, 1);
72  mdelay(100);
73 }
74 
75 /*
76  * Direct connect serial ports (non-PCI that is).
77  */
78 #define S8250_PHYS 0x03800000
79 #define S8250_VIRT 0xf4000000
80 #define S8250_SIZE 0x00100000
81 
82 static struct __initdata map_desc og_io_desc[] = {
83  {
84  .virtual = S8250_VIRT,
85  .pfn = __phys_to_pfn(S8250_PHYS),
86  .length = S8250_SIZE,
87  .type = MT_DEVICE,
88  }
89 };
90 
91 static struct resource og_uart_resources[] = {
92  {
93  .start = S8250_VIRT,
94  .end = S8250_VIRT + S8250_SIZE,
95  .flags = IORESOURCE_MEM
96  },
97 };
98 
99 static struct plat_serial8250_port og_uart_data[] = {
100  {
101  .mapbase = S8250_VIRT,
102  .membase = (char *) S8250_VIRT,
103  .irq = 3,
105  .iotype = UPIO_MEM,
106  .regshift = 2,
107  .uartclk = 115200 * 16,
108  },
109  { },
110 };
111 
112 static struct platform_device og_uart = {
113  .name = "serial8250",
114  .id = 0,
115  .dev.platform_data = og_uart_data,
116  .num_resources = 1,
117  .resource = og_uart_resources
118 };
119 
120 static struct platform_device *og_devices[] __initdata = {
121  &og_uart
122 };
123 
124 static void __init og_init(void)
125 {
127 
128  if (machine_is_cm4002()) {
130  iotable_init(og_io_desc, ARRAY_SIZE(og_io_desc));
131  platform_add_devices(og_devices, ARRAY_SIZE(og_devices));
132  } else {
133  og_pci_bus_reset();
134  og_register_pci();
135  }
136 
139 }
140 
141 #ifdef CONFIG_MACH_CM4002
142 MACHINE_START(CM4002, "OpenGear/CM4002")
143  /* OpenGear Inc. */
144  .atag_offset = 0x100,
145  .map_io = ks8695_map_io,
146  .init_irq = ks8695_init_irq,
147  .init_machine = og_init,
148  .timer = &ks8695_timer,
149  .restart = ks8695_restart,
151 #endif
152 
153 #ifdef CONFIG_MACH_CM4008
154 MACHINE_START(CM4008, "OpenGear/CM4008")
155  /* OpenGear Inc. */
156  .atag_offset = 0x100,
157  .map_io = ks8695_map_io,
158  .init_irq = ks8695_init_irq,
159  .init_machine = og_init,
160  .timer = &ks8695_timer,
161  .restart = ks8695_restart,
163 #endif
164 
165 #ifdef CONFIG_MACH_CM41xx
166 MACHINE_START(CM41XX, "OpenGear/CM41xx")
167  /* OpenGear Inc. */
168  .atag_offset = 0x100,
169  .map_io = ks8695_map_io,
170  .init_irq = ks8695_init_irq,
171  .init_machine = og_init,
172  .timer = &ks8695_timer,
173  .restart = ks8695_restart,
175 #endif
176 
177 #ifdef CONFIG_MACH_IM4004
178 MACHINE_START(IM4004, "OpenGear/IM4004")
179  /* OpenGear Inc. */
180  .atag_offset = 0x100,
181  .map_io = ks8695_map_io,
182  .init_irq = ks8695_init_irq,
183  .init_machine = og_init,
184  .timer = &ks8695_timer,
185  .restart = ks8695_restart,
187 #endif
188 
189 #ifdef CONFIG_MACH_IM42xx
190 MACHINE_START(IM42XX, "OpenGear/IM42xx")
191  /* OpenGear Inc. */
192  .atag_offset = 0x100,
193  .map_io = ks8695_map_io,
194  .init_irq = ks8695_init_irq,
195  .init_machine = og_init,
196  .timer = &ks8695_timer,
197  .restart = ks8695_restart,
199 #endif