aboutsummaryrefslogtreecommitdiffstats
path: root/arch/unicore32
diff options
context:
space:
mode:
authorGuanXuetao <gxt@mprc.pku.edu.cn>2011-02-26 06:51:18 -0500
committerGuanXuetao <gxt@mprc.pku.edu.cn>2011-03-16 21:19:14 -0400
commitfa7499ef77db8d535e3c609c8064e9ee50c0693c (patch)
tree262a947a5800268a3992147b76baf920dff9beb0 /arch/unicore32
parent70fac51feaf2ca50c84e102e2a2699eb19ef24bd (diff)
unicore32 machine related files: core files
This patch adds machine related core files, also including build infrastructure. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/unicore32')
-rw-r--r--arch/unicore32/Kconfig25
-rw-r--r--arch/unicore32/kernel/puv3-core.c270
-rw-r--r--arch/unicore32/kernel/puv3-nb0916.c145
3 files changed, 440 insertions, 0 deletions
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index cc6a83215881..90835c959476 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -231,6 +231,31 @@ config PUV3_RTC
231 tristate "PKUnity v3 RTC Support" 231 tristate "PKUnity v3 RTC Support"
232 depends on !ARCH_FPGA 232 depends on !ARCH_FPGA
233 233
234if PUV3_NB0916
235
236menu "PKUnity NetBook-0916 Features"
237
238config I2C_BATTERY_BQ27200
239 tristate "I2C Battery BQ27200 Support"
240 select PUV3_I2C
241 select POWER_SUPPLY
242 select BATTERY_BQ27x00
243
244config I2C_EEPROM_AT24
245 tristate "I2C EEPROMs AT24 support"
246 select PUV3_I2C
247 select MISC_DEVICES
248 select EEPROM_AT24
249
250config LCD_BACKLIGHT
251 tristate "LCD Backlight support"
252 select BACKLIGHT_LCD_SUPPORT
253 select BACKLIGHT_PWM
254
255endmenu
256
257endif
258
234endif 259endif
235 260
236source "drivers/Kconfig" 261source "drivers/Kconfig"
diff --git a/arch/unicore32/kernel/puv3-core.c b/arch/unicore32/kernel/puv3-core.c
new file mode 100644
index 000000000000..26cc52b51e7b
--- /dev/null
+++ b/arch/unicore32/kernel/puv3-core.c
@@ -0,0 +1,270 @@
1/*
2 * linux/arch/unicore32/kernel/puv3-core.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
7 * Copyright (C) 2001-2010 Guan Xuetao
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/sysdev.h>
17#include <linux/amba/bus.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <linux/cnt32_to_63.h>
21#include <linux/usb/musb.h>
22
23#include <asm/irq.h>
24#include <mach/hardware.h>
25#include <mach/pm.h>
26
27/*
28 * This is the PKUnity sched_clock implementation. This has
29 * a resolution of 271ns, and a maximum value of 32025597s (370 days).
30 *
31 * The return value is guaranteed to be monotonic in that range as
32 * long as there is always less than 582 seconds between successive
33 * calls to this function.
34 *
35 * ( * 1E9 / CLOCK_TICK_RATE ) -> about 2235/32
36 */
37unsigned long long sched_clock(void)
38{
39 unsigned long long v = cnt32_to_63(OST_OSCR);
40
41 /* original conservative method, but overflow frequently
42 * v *= NSEC_PER_SEC >> 12;
43 * do_div(v, CLOCK_TICK_RATE >> 12);
44 */
45 v = ((v & 0x7fffffffffffffffULL) * 2235) >> 5;
46
47 return v;
48}
49
50static struct resource puv3_usb_resources[] = {
51 /* order is significant! */
52 {
53 .start = PKUNITY_USB_BASE,
54 .end = PKUNITY_USB_BASE + 0x3ff,
55 .flags = IORESOURCE_MEM,
56 }, {
57 .start = IRQ_USB,
58 .flags = IORESOURCE_IRQ,
59 }, {
60 .start = IRQ_USB,
61 .flags = IORESOURCE_IRQ,
62 },
63};
64
65static struct musb_hdrc_config puv3_usb_config[] = {
66 {
67 .num_eps = 16,
68 .multipoint = 1,
69#ifdef CONFIG_USB_INVENTRA_DMA
70 .dma = 1,
71 .dma_channels = 8,
72#endif
73 },
74};
75
76static struct musb_hdrc_platform_data puv3_usb_plat = {
77 .mode = MUSB_HOST,
78 .min_power = 100,
79 .clock = 0,
80 .config = puv3_usb_config,
81};
82
83static struct resource puv3_mmc_resources[] = {
84 [0] = {
85 .start = PKUNITY_SDC_BASE,
86 .end = PKUNITY_SDC_BASE + 0xfff,
87 .flags = IORESOURCE_MEM,
88 },
89 [1] = {
90 .start = IRQ_SDC,
91 .end = IRQ_SDC,
92 .flags = IORESOURCE_IRQ,
93 },
94};
95
96static struct resource puv3_rtc_resources[] = {
97 [0] = {
98 .start = PKUNITY_RTC_BASE,
99 .end = PKUNITY_RTC_BASE + 0xff,
100 .flags = IORESOURCE_MEM,
101 },
102 [1] = {
103 .start = IRQ_RTCAlarm,
104 .end = IRQ_RTCAlarm,
105 .flags = IORESOURCE_IRQ,
106 },
107 [2] = {
108 .start = IRQ_RTC,
109 .end = IRQ_RTC,
110 .flags = IORESOURCE_IRQ
111 }
112};
113
114static struct resource puv3_pwm_resources[] = {
115 [0] = {
116 .start = PKUNITY_OST_BASE + 0x80,
117 .end = PKUNITY_OST_BASE + 0xff,
118 .flags = IORESOURCE_MEM,
119 },
120};
121
122static struct resource puv3_uart0_resources[] = {
123 [0] = {
124 .start = PKUNITY_UART0_BASE,
125 .end = PKUNITY_UART0_BASE + 0xff,
126 .flags = IORESOURCE_MEM,
127 },
128 [1] = {
129 .start = IRQ_UART0,
130 .end = IRQ_UART0,
131 .flags = IORESOURCE_IRQ
132 }
133};
134
135static struct resource puv3_uart1_resources[] = {
136 [0] = {
137 .start = PKUNITY_UART1_BASE,
138 .end = PKUNITY_UART1_BASE + 0xff,
139 .flags = IORESOURCE_MEM,
140 },
141 [1] = {
142 .start = IRQ_UART1,
143 .end = IRQ_UART1,
144 .flags = IORESOURCE_IRQ
145 }
146};
147
148static struct resource puv3_umal_resources[] = {
149 [0] = {
150 .start = PKUNITY_UMAL_BASE,
151 .end = PKUNITY_UMAL_BASE + 0x1fff,
152 .flags = IORESOURCE_MEM,
153 },
154 [1] = {
155 .start = IRQ_UMAL,
156 .end = IRQ_UMAL,
157 .flags = IORESOURCE_IRQ
158 }
159};
160
161#ifdef CONFIG_PUV3_PM
162
163#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
164#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
165
166/*
167 * List of global PXA peripheral registers to preserve.
168 * More ones like CP and general purpose register values are preserved
169 * with the stack pointer in sleep.S.
170 */
171enum {
172 SLEEP_SAVE_PM_PLLDDRCFG,
173 SLEEP_SAVE_COUNT
174};
175
176
177static void puv3_cpu_pm_save(unsigned long *sleep_save)
178{
179/* SAVE(PM_PLLDDRCFG); */
180}
181
182static void puv3_cpu_pm_restore(unsigned long *sleep_save)
183{
184/* RESTORE(PM_PLLDDRCFG); */
185}
186
187static int puv3_cpu_pm_prepare(void)
188{
189 /* set resume return address */
190 PM_DIVCFG = virt_to_phys(puv3_cpu_resume);
191 return 0;
192}
193
194static void puv3_cpu_pm_enter(suspend_state_t state)
195{
196 /* Clear reset status */
197 RESETC_RSSR = RESETC_RSSR_HWR | RESETC_RSSR_WDR
198 | RESETC_RSSR_SMR | RESETC_RSSR_SWR;
199
200 switch (state) {
201/* case PM_SUSPEND_ON:
202 puv3_cpu_idle();
203 break; */
204 case PM_SUSPEND_MEM:
205 puv3_cpu_pm_prepare();
206 puv3_cpu_suspend(PM_PMCR_SFB);
207 break;
208 }
209}
210
211static int puv3_cpu_pm_valid(suspend_state_t state)
212{
213 return state == PM_SUSPEND_MEM;
214}
215
216static void puv3_cpu_pm_finish(void)
217{
218 /* ensure not to come back here if it wasn't intended */
219 /* PSPR = 0; */
220}
221
222static struct puv3_cpu_pm_fns puv3_cpu_pm_fnss = {
223 .save_count = SLEEP_SAVE_COUNT,
224 .valid = puv3_cpu_pm_valid,
225 .save = puv3_cpu_pm_save,
226 .restore = puv3_cpu_pm_restore,
227 .enter = puv3_cpu_pm_enter,
228 .prepare = puv3_cpu_pm_prepare,
229 .finish = puv3_cpu_pm_finish,
230};
231
232static void __init puv3_init_pm(void)
233{
234 puv3_cpu_pm_fns = &puv3_cpu_pm_fnss;
235}
236#else
237static inline void puv3_init_pm(void) {}
238#endif
239
240void puv3_ps2_init(void)
241{
242 struct clk *bclk32;
243
244 bclk32 = clk_get(NULL, "BUS32_CLK");
245 PS2_CNT = clk_get_rate(bclk32) / 200000; /* should > 5us */
246}
247
248void __init puv3_core_init(void)
249{
250 puv3_init_pm();
251 puv3_ps2_init();
252
253 platform_device_register_simple("PKUnity-v3-RTC", -1,
254 puv3_rtc_resources, ARRAY_SIZE(puv3_rtc_resources));
255 platform_device_register_simple("PKUnity-v3-UMAL", -1,
256 puv3_umal_resources, ARRAY_SIZE(puv3_umal_resources));
257 platform_device_register_simple("PKUnity-v3-MMC", -1,
258 puv3_mmc_resources, ARRAY_SIZE(puv3_mmc_resources));
259 platform_device_register_simple("PKUnity-v3-PWM", -1,
260 puv3_pwm_resources, ARRAY_SIZE(puv3_pwm_resources));
261 platform_device_register_simple("PKUnity-v3-UART", 0,
262 puv3_uart0_resources, ARRAY_SIZE(puv3_uart0_resources));
263 platform_device_register_simple("PKUnity-v3-UART", 1,
264 puv3_uart1_resources, ARRAY_SIZE(puv3_uart1_resources));
265 platform_device_register_simple("PKUnity-v3-AC97", -1, NULL, 0);
266 platform_device_register_resndata(&platform_bus, "musb_hdrc", -1,
267 puv3_usb_resources, ARRAY_SIZE(puv3_usb_resources),
268 &puv3_usb_plat, sizeof(puv3_usb_plat));
269}
270
diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c
new file mode 100644
index 000000000000..a78e60420653
--- /dev/null
+++ b/arch/unicore32/kernel/puv3-nb0916.c
@@ -0,0 +1,145 @@
1/*
2 * linux/arch/unicore32/kernel/puv3-nb0916.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
7 * Copyright (C) 2001-2010 Guan Xuetao
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/sysdev.h>
17#include <linux/platform_device.h>
18#include <linux/mtd/physmap.h>
19#include <linux/io.h>
20#include <linux/reboot.h>
21#include <linux/interrupt.h>
22#include <linux/i2c.h>
23#include <linux/pwm_backlight.h>
24#include <linux/gpio.h>
25#include <linux/gpio_keys.h>
26#include <linux/input.h>
27
28#include <mach/hardware.h>
29
30static struct physmap_flash_data physmap_flash_data = {
31 .width = 1,
32};
33
34static struct resource physmap_flash_resource = {
35 .start = 0xFFF80000,
36 .end = 0xFFFFFFFF,
37 .flags = IORESOURCE_MEM,
38};
39
40static struct resource puv3_i2c_resources[] = {
41 [0] = {
42 .start = PKUNITY_I2C_BASE,
43 .end = PKUNITY_I2C_BASE + 0xff,
44 .flags = IORESOURCE_MEM,
45 },
46 [1] = {
47 .start = IRQ_I2C,
48 .end = IRQ_I2C,
49 .flags = IORESOURCE_IRQ,
50 }
51};
52
53static struct platform_pwm_backlight_data nb0916_backlight_data = {
54 .pwm_id = 0,
55 .max_brightness = 100,
56 .dft_brightness = 100,
57 .pwm_period_ns = 70 * 1024,
58};
59
60static struct gpio_keys_button nb0916_gpio_keys[] = {
61 {
62 .type = EV_KEY,
63 .code = KEY_POWER,
64 .gpio = GPI_SOFF_REQ,
65 .desc = "Power Button",
66 .wakeup = 1,
67 .active_low = 1,
68 },
69 {
70 .type = EV_KEY,
71 .code = BTN_TOUCH,
72 .gpio = GPI_BTN_TOUCH,
73 .desc = "Touchpad Button",
74 .wakeup = 1,
75 .active_low = 1,
76 },
77};
78
79static struct gpio_keys_platform_data nb0916_gpio_button_data = {
80 .buttons = nb0916_gpio_keys,
81 .nbuttons = ARRAY_SIZE(nb0916_gpio_keys),
82};
83
84static irqreturn_t nb0916_lcdcaseoff_handler(int irq, void *dev_id)
85{
86 if (gpio_get_value(GPI_LCD_CASE_OFF))
87 gpio_set_value(GPO_LCD_EN, 1);
88 else
89 gpio_set_value(GPO_LCD_EN, 0);
90
91 return IRQ_HANDLED;
92}
93
94static irqreturn_t nb0916_overheat_handler(int irq, void *dev_id)
95{
96 machine_halt();
97 /* SYSTEM HALT, NO RETURN */
98 return IRQ_HANDLED;
99}
100
101static struct i2c_board_info __initdata puv3_i2c_devices[] = {
102 { I2C_BOARD_INFO("lm75", I2C_TAR_THERMAL), },
103 { I2C_BOARD_INFO("bq27200", I2C_TAR_PWIC), },
104 { I2C_BOARD_INFO("24c02", I2C_TAR_EEPROM), },
105};
106
107int __init mach_nb0916_init(void)
108{
109 i2c_register_board_info(0, puv3_i2c_devices,
110 ARRAY_SIZE(puv3_i2c_devices));
111
112 platform_device_register_simple("PKUnity-v3-I2C", -1,
113 puv3_i2c_resources, ARRAY_SIZE(puv3_i2c_resources));
114
115 platform_device_register_data(&platform_bus, "pwm-backlight", -1,
116 &nb0916_backlight_data, sizeof(nb0916_backlight_data));
117
118 platform_device_register_data(&platform_bus, "gpio-keys", -1,
119 &nb0916_gpio_button_data, sizeof(nb0916_gpio_button_data));
120
121 platform_device_register_resndata(&platform_bus, "physmap-flash", -1,
122 &physmap_flash_resource, 1,
123 &physmap_flash_data, sizeof(physmap_flash_data));
124
125 if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF),
126 &nb0916_lcdcaseoff_handler,
127 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
128 "NB0916 lcd case off", NULL) < 0) {
129
130 printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n",
131 gpio_to_irq(GPI_LCD_CASE_OFF));
132 }
133
134 if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler,
135 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
136 "NB0916 overheating protection", NULL) < 0) {
137
138 printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n",
139 gpio_to_irq(GPI_OTP_INT));
140 }
141
142 return 0;
143}
144
145subsys_initcall_sync(mach_nb0916_init);