diff options
author | GuanXuetao <gxt@mprc.pku.edu.cn> | 2011-02-26 06:51:18 -0500 |
---|---|---|
committer | GuanXuetao <gxt@mprc.pku.edu.cn> | 2011-03-16 21:19:14 -0400 |
commit | fa7499ef77db8d535e3c609c8064e9ee50c0693c (patch) | |
tree | 262a947a5800268a3992147b76baf920dff9beb0 /arch/unicore32 | |
parent | 70fac51feaf2ca50c84e102e2a2699eb19ef24bd (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/Kconfig | 25 | ||||
-rw-r--r-- | arch/unicore32/kernel/puv3-core.c | 270 | ||||
-rw-r--r-- | arch/unicore32/kernel/puv3-nb0916.c | 145 |
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 | ||
234 | if PUV3_NB0916 | ||
235 | |||
236 | menu "PKUnity NetBook-0916 Features" | ||
237 | |||
238 | config I2C_BATTERY_BQ27200 | ||
239 | tristate "I2C Battery BQ27200 Support" | ||
240 | select PUV3_I2C | ||
241 | select POWER_SUPPLY | ||
242 | select BATTERY_BQ27x00 | ||
243 | |||
244 | config I2C_EEPROM_AT24 | ||
245 | tristate "I2C EEPROMs AT24 support" | ||
246 | select PUV3_I2C | ||
247 | select MISC_DEVICES | ||
248 | select EEPROM_AT24 | ||
249 | |||
250 | config LCD_BACKLIGHT | ||
251 | tristate "LCD Backlight support" | ||
252 | select BACKLIGHT_LCD_SUPPORT | ||
253 | select BACKLIGHT_PWM | ||
254 | |||
255 | endmenu | ||
256 | |||
257 | endif | ||
258 | |||
234 | endif | 259 | endif |
235 | 260 | ||
236 | source "drivers/Kconfig" | 261 | source "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 | */ | ||
37 | unsigned 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 | |||
50 | static 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 | |||
65 | static 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 | |||
76 | static 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 | |||
83 | static 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 | |||
96 | static 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 | |||
114 | static 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 | |||
122 | static 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 | |||
135 | static 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 | |||
148 | static 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 | */ | ||
171 | enum { | ||
172 | SLEEP_SAVE_PM_PLLDDRCFG, | ||
173 | SLEEP_SAVE_COUNT | ||
174 | }; | ||
175 | |||
176 | |||
177 | static void puv3_cpu_pm_save(unsigned long *sleep_save) | ||
178 | { | ||
179 | /* SAVE(PM_PLLDDRCFG); */ | ||
180 | } | ||
181 | |||
182 | static void puv3_cpu_pm_restore(unsigned long *sleep_save) | ||
183 | { | ||
184 | /* RESTORE(PM_PLLDDRCFG); */ | ||
185 | } | ||
186 | |||
187 | static 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 | |||
194 | static 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 | |||
211 | static int puv3_cpu_pm_valid(suspend_state_t state) | ||
212 | { | ||
213 | return state == PM_SUSPEND_MEM; | ||
214 | } | ||
215 | |||
216 | static void puv3_cpu_pm_finish(void) | ||
217 | { | ||
218 | /* ensure not to come back here if it wasn't intended */ | ||
219 | /* PSPR = 0; */ | ||
220 | } | ||
221 | |||
222 | static 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 | |||
232 | static void __init puv3_init_pm(void) | ||
233 | { | ||
234 | puv3_cpu_pm_fns = &puv3_cpu_pm_fnss; | ||
235 | } | ||
236 | #else | ||
237 | static inline void puv3_init_pm(void) {} | ||
238 | #endif | ||
239 | |||
240 | void 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 | |||
248 | void __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 | |||
30 | static struct physmap_flash_data physmap_flash_data = { | ||
31 | .width = 1, | ||
32 | }; | ||
33 | |||
34 | static struct resource physmap_flash_resource = { | ||
35 | .start = 0xFFF80000, | ||
36 | .end = 0xFFFFFFFF, | ||
37 | .flags = IORESOURCE_MEM, | ||
38 | }; | ||
39 | |||
40 | static 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 | |||
53 | static 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 | |||
60 | static 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 | |||
79 | static struct gpio_keys_platform_data nb0916_gpio_button_data = { | ||
80 | .buttons = nb0916_gpio_keys, | ||
81 | .nbuttons = ARRAY_SIZE(nb0916_gpio_keys), | ||
82 | }; | ||
83 | |||
84 | static 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 | |||
94 | static 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 | |||
101 | static 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 | |||
107 | int __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 | |||
145 | subsys_initcall_sync(mach_nb0916_init); | ||