Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
siu.c
Go to the documentation of this file.
1 /*
2  * NEC VR4100 series SIU platform device.
3  *
4  * Copyright (C) 2007-2008 Yoichi Yuasa <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 #include <linux/errno.h>
21 #include <linux/init.h>
22 #include <linux/ioport.h>
23 #include <linux/platform_device.h>
24 #include <linux/serial_core.h>
25 #include <linux/irq.h>
26 
27 #include <asm/cpu.h>
28 #include <asm/vr41xx/siu.h>
29 
30 static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
33 };
34 
35 static struct resource siu_type1_resource[] __initdata = {
36  {
37  .start = 0x0c000000,
38  .end = 0x0c00000a,
39  .flags = IORESOURCE_MEM,
40  },
41  {
42  .start = SIU_IRQ,
43  .end = SIU_IRQ,
44  .flags = IORESOURCE_IRQ,
45  },
46 };
47 
48 static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
51 };
52 
53 static struct resource siu_type2_resource[] __initdata = {
54  {
55  .start = 0x0f000800,
56  .end = 0x0f00080a,
57  .flags = IORESOURCE_MEM,
58  },
59  {
60  .start = 0x0f000820,
61  .end = 0x0f000829,
62  .flags = IORESOURCE_MEM,
63  },
64  {
65  .start = SIU_IRQ,
66  .end = SIU_IRQ,
67  .flags = IORESOURCE_IRQ,
68  },
69  {
70  .start = DSIU_IRQ,
71  .end = DSIU_IRQ,
72  .flags = IORESOURCE_IRQ,
73  },
74 };
75 
76 static int __init vr41xx_siu_add(void)
77 {
78  struct platform_device *pdev;
79  struct resource *res;
80  unsigned int num;
81  int retval;
82 
83  pdev = platform_device_alloc("SIU", -1);
84  if (!pdev)
85  return -ENOMEM;
86 
87  switch (current_cpu_type()) {
88  case CPU_VR4111:
89  case CPU_VR4121:
90  pdev->dev.platform_data = siu_type1_ports;
91  res = siu_type1_resource;
92  num = ARRAY_SIZE(siu_type1_resource);
93  break;
94  case CPU_VR4122:
95  case CPU_VR4131:
96  case CPU_VR4133:
97  pdev->dev.platform_data = siu_type2_ports;
98  res = siu_type2_resource;
99  num = ARRAY_SIZE(siu_type2_resource);
100  break;
101  default:
102  retval = -ENODEV;
103  goto err_free_device;
104  }
105 
106  retval = platform_device_add_resources(pdev, res, num);
107  if (retval)
108  goto err_free_device;
109 
110  retval = platform_device_add(pdev);
111  if (retval)
112  goto err_free_device;
113 
114  return 0;
115 
116 err_free_device:
117  platform_device_put(pdev);
118 
119  return retval;
120 }
121 device_initcall(vr41xx_siu_add);
122 
124 {
125  struct uart_port port;
126  struct resource *res;
127  unsigned int *type;
128  int i;
129 
130  switch (current_cpu_type()) {
131  case CPU_VR4111:
132  case CPU_VR4121:
133  type = siu_type1_ports;
134  res = siu_type1_resource;
135  break;
136  case CPU_VR4122:
137  case CPU_VR4131:
138  case CPU_VR4133:
139  type = siu_type2_ports;
140  res = siu_type2_resource;
141  break;
142  default:
143  return;
144  }
145 
146  for (i = 0; i < SIU_PORTS_MAX; i++) {
147  port.line = i;
148  port.type = type[i];
149  if (port.type == PORT_UNKNOWN)
150  break;
151  port.mapbase = res[i].start;
152  port.membase = (unsigned char __iomem *)KSEG1ADDR(res[i].start);
153  vr41xx_siu_early_setup(&port);
154  }
155 }