Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+440
+25
arch/unicore32/Kconfig
··· 231 231 tristate "PKUnity v3 RTC Support" 232 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 259 endif 235 260 236 261 source "drivers/Kconfig"
+270
arch/unicore32/kernel/puv3-core.c
··· 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 +
+145
arch/unicore32/kernel/puv3-nb0916.c
··· 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);