summaryrefslogtreecommitdiff
path: root/target/linux/patches/2.6.37/lemote.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/patches/2.6.37/lemote.patch')
-rw-r--r--target/linux/patches/2.6.37/lemote.patch4271
1 files changed, 0 insertions, 4271 deletions
diff --git a/target/linux/patches/2.6.37/lemote.patch b/target/linux/patches/2.6.37/lemote.patch
deleted file mode 100644
index 513292e96..000000000
--- a/target/linux/patches/2.6.37/lemote.patch
+++ /dev/null
@@ -1,4271 +0,0 @@
-diff -Nur linux-2.6.37.orig/arch/mips/Kconfig linux-2.6.37/arch/mips/Kconfig
---- linux-2.6.37.orig/arch/mips/Kconfig 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/Kconfig 2011-01-11 20:44:43.000000000 +0100
-@@ -210,7 +210,7 @@
-
- config MACH_LOONGSON
- bool "Loongson family of machines"
-- select SYS_SUPPORTS_ZBOOT
-+ select SYS_SUPPORTS_ZBOOT_UART16550
- help
- This enables the support of Loongson family of machines.
-
-@@ -1101,6 +1101,8 @@
- bool "Loongson 2E"
- depends on SYS_HAS_CPU_LOONGSON2E
- select CPU_LOONGSON2
-+ select GENERIC_GPIO
-+ select ARCH_REQUIRE_GPIOLIB
- help
- The Loongson 2E processor implements the MIPS III instruction set
- with many extensions.
-@@ -2099,6 +2101,18 @@
- source "kernel/time/Kconfig"
-
- #
-+# High Resolution sched_clock() Configuration
-+#
-+
-+config CPU_HAS_FIXED_C0_COUNT
-+ bool
-+
-+config CPU_SUPPORTS_HR_SCHED_CLOCK
-+ bool
-+ depends on CPU_HAS_FIXED_C0_COUNT || !CPU_FREQ
-+ default y
-+
-+#
- # Timer Interrupt Frequency Configuration
- #
-
-diff -Nur linux-2.6.37.orig/arch/mips/include/asm/dma-mapping.h linux-2.6.37/arch/mips/include/asm/dma-mapping.h
---- linux-2.6.37.orig/arch/mips/include/asm/dma-mapping.h 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/include/asm/dma-mapping.h 2011-01-11 20:44:43.000000000 +0100
-@@ -85,4 +85,8 @@
- void dma_free_noncoherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-
-+#define ARCH_HAS_DMA_MMAP_COHERENT
-+extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-+ void *cpu_addr, dma_addr_t handle, size_t size);
-+
- #endif /* _ASM_DMA_MAPPING_H */
-diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
---- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2011-01-11 20:44:43.000000000 +0100
-@@ -255,21 +255,12 @@
- * IDE STANDARD
- */
- #define IDE_CAP 0x00
--#define IDE_CONFIG 0x01
--#define IDE_SMI 0x02
--#define IDE_ERROR 0x03
--#define IDE_PM 0x04
--#define IDE_DIAG 0x05
--
--/*
-- * IDE SPEC.
-- */
- #define IDE_IO_BAR 0x08
- #define IDE_CFG 0x10
- #define IDE_DTC 0x12
- #define IDE_CAST 0x13
- #define IDE_ETC 0x14
--#define IDE_INTERNAL_PM 0x15
-+#define IDE_PM 0x15
-
- /*
- * ACC STANDARD
-@@ -301,5 +292,40 @@
- /* GPIO : I/O SPACE; REG : 32BITS */
- #define GPIOL_OUT_VAL 0x00
- #define GPIOL_OUT_EN 0x04
-+#define GPIOL_OUT_AUX1_SEL 0x10
-+/* SMB : I/O SPACE, REG : 8BITS WIDTH */
-+#define SMB_SDA 0x00
-+#define SMB_STS 0x01
-+#define SMB_STS_SLVSTP (1 << 7)
-+#define SMB_STS_SDAST (1 << 6)
-+#define SMB_STS_BER (1 << 5)
-+#define SMB_STS_NEGACK (1 << 4)
-+#define SMB_STS_STASTR (1 << 3)
-+#define SMB_STS_NMATCH (1 << 2)
-+#define SMB_STS_MASTER (1 << 1)
-+#define SMB_STS_XMIT (1 << 0)
-+#define SMB_CTRL_STS 0x02
-+#define SMB_CSTS_TGSTL (1 << 5)
-+#define SMB_CSTS_TSDA (1 << 4)
-+#define SMB_CSTS_GCMTCH (1 << 3)
-+#define SMB_CSTS_MATCH (1 << 2)
-+#define SMB_CSTS_BB (1 << 1)
-+#define SMB_CSTS_BUSY (1 << 0)
-+#define SMB_CTRL1 0x03
-+#define SMB_CTRL1_STASTRE (1 << 7)
-+#define SMB_CTRL1_NMINTE (1 << 6)
-+#define SMB_CTRL1_GCMEN (1 << 5)
-+#define SMB_CTRL1_ACK (1 << 4)
-+#define SMB_CTRL1_RSVD (1 << 3)
-+#define SMB_CTRL1_INTEN (1 << 2)
-+#define SMB_CTRL1_STOP (1 << 1)
-+#define SMB_CTRL1_START (1 << 0)
-+#define SMB_ADDR 0x04
-+#define SMB_ADDR_SAEN (1 << 7)
-+#define SMB_CONTROLLER_ADDR (0xef << 0)
-+#define SMB_CTRL2 0x05
-+#define SMB_FREQ (0x20 << 1)
-+#define SMB_ENABLE (0x01 << 0)
-+#define SMB_CTRL3 0x06
-
- #endif /* _CS5536_H */
-diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
---- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2011-01-11 20:44:43.000000000 +0100
-@@ -32,4 +32,9 @@
- #define MFGPT0_CNT (MFGPT_BASE + 4)
- #define MFGPT0_SETUP (MFGPT_BASE + 6)
-
-+#define MFGPT2_CMP1 (MFGPT_BASE + 0x10)
-+#define MFGPT2_CMP2 (MFGPT_BASE + 0x12)
-+#define MFGPT2_CNT (MFGPT_BASE + 0x14)
-+#define MFGPT2_SETUP (MFGPT_BASE + 0x16)
-+
- #endif /*!_CS5536_MFGPT_H */
-diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h linux-2.6.37/arch/mips/include/asm/mach-loongson/ec_kb3310b.h
---- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,191 @@
-+/*
-+ * KB3310B Embedded Controller
-+ *
-+ * Copyright (C) 2008 Lemote Inc.
-+ * Author: liujl <liujl@lemote.com>, 2008-03-14
-+ * Copyright (C) 2009 Lemote Inc.
-+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#ifndef _EC_KB3310B_H
-+#define _EC_KB3310B_H
-+
-+extern unsigned char ec_read(unsigned short addr);
-+extern void ec_write(unsigned short addr, unsigned char val);
-+extern int ec_query_seq(unsigned char cmd);
-+extern int ec_query_event_num(void);
-+extern int ec_get_event_num(void);
-+
-+typedef int (*sci_handler) (int status);
-+extern sci_handler yeeloong_report_lid_status;
-+
-+#define SCI_IRQ_NUM 0x0A
-+
-+/*
-+ * The following registers are determined by the EC index configuration.
-+ * 1, fill the PORT_HIGH as EC register high part.
-+ * 2, fill the PORT_LOW as EC register low part.
-+ * 3, fill the PORT_DATA as EC register write data or get the data from it.
-+ */
-+#define EC_IO_PORT_HIGH 0x0381
-+#define EC_IO_PORT_LOW 0x0382
-+#define EC_IO_PORT_DATA 0x0383
-+
-+/*
-+ * EC delay time is 500us for register and status access
-+ */
-+#define EC_REG_DELAY 500 /* unit : us */
-+#define EC_CMD_TIMEOUT 0x1000
-+
-+/*
-+ * EC access port for SCI communication
-+ */
-+#define EC_CMD_PORT 0x66
-+#define EC_STS_PORT 0x66
-+#define EC_DAT_PORT 0x62
-+#define CMD_INIT_IDLE_MODE 0xdd
-+#define CMD_EXIT_IDLE_MODE 0xdf
-+#define CMD_INIT_RESET_MODE 0xd8
-+#define CMD_REBOOT_SYSTEM 0x8c
-+#define CMD_GET_EVENT_NUM 0x84
-+#define CMD_PROGRAM_PIECE 0xda
-+
-+/* Temperature & Fan registers */
-+#define REG_TEMPERATURE_VALUE 0xF458
-+#define REG_FAN_AUTO_MAN_SWITCH 0xF459
-+#define BIT_FAN_AUTO 0
-+#define BIT_FAN_MANUAL 1
-+#define REG_FAN_CONTROL 0xF4D2
-+#define BIT_FAN_CONTROL_ON (1 << 0)
-+#define BIT_FAN_CONTROL_OFF (0 << 0)
-+#define REG_FAN_STATUS 0xF4DA
-+#define BIT_FAN_STATUS_ON (1 << 0)
-+#define BIT_FAN_STATUS_OFF (0 << 0)
-+#define REG_FAN_SPEED_HIGH 0xFE22
-+#define REG_FAN_SPEED_LOW 0xFE23
-+#define REG_FAN_SPEED_LEVEL 0xF4CC
-+/* Fan speed divider */
-+#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
-+
-+/* Battery registers */
-+#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
-+#define REG_BAT_DESIGN_CAP_LOW 0xF77E
-+#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
-+#define REG_BAT_FULLCHG_CAP_LOW 0xF781
-+#define REG_BAT_DESIGN_VOL_HIGH 0xF782
-+#define REG_BAT_DESIGN_VOL_LOW 0xF783
-+#define REG_BAT_CURRENT_HIGH 0xF784
-+#define REG_BAT_CURRENT_LOW 0xF785
-+#define REG_BAT_VOLTAGE_HIGH 0xF786
-+#define REG_BAT_VOLTAGE_LOW 0xF787
-+#define REG_BAT_TEMPERATURE_HIGH 0xF788
-+#define REG_BAT_TEMPERATURE_LOW 0xF789
-+#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
-+#define REG_BAT_RELATIVE_CAP_LOW 0xF493
-+#define REG_BAT_VENDOR 0xF4C4
-+#define FLAG_BAT_VENDOR_SANYO 0x01
-+#define FLAG_BAT_VENDOR_SIMPLO 0x02
-+#define REG_BAT_CELL_COUNT 0xF4C6
-+#define FLAG_BAT_CELL_3S1P 0x03
-+#define FLAG_BAT_CELL_3S2P 0x06
-+#define REG_BAT_CHARGE 0xF4A2
-+#define FLAG_BAT_CHARGE_DISCHARGE 0x01
-+#define FLAG_BAT_CHARGE_CHARGE 0x02
-+#define FLAG_BAT_CHARGE_ACPOWER 0x00
-+#define REG_BAT_STATUS 0xF4B0
-+#define BIT_BAT_STATUS_LOW (1 << 5)
-+#define BIT_BAT_STATUS_DESTROY (1 << 2)
-+#define BIT_BAT_STATUS_FULL (1 << 1)
-+#define BIT_BAT_STATUS_IN (1 << 0)
-+#define REG_BAT_CHARGE_STATUS 0xF4B1
-+#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
-+#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
-+#define REG_BAT_STATE 0xF482
-+#define BIT_BAT_STATE_CHARGING (1 << 1)
-+#define BIT_BAT_STATE_DISCHARGING (1 << 0)
-+#define REG_BAT_POWER 0xF440
-+#define BIT_BAT_POWER_S3 (1 << 2)
-+#define BIT_BAT_POWER_ON (1 << 1)
-+#define BIT_BAT_POWER_ACIN (1 << 0)
-+
-+/* Audio: rd/wr */
-+#define REG_AUDIO_VOLUME 0xF46C
-+#define REG_AUDIO_MUTE 0xF4E7
-+#define REG_AUDIO_BEEP 0xF4D0
-+/* USB port power or not: rd/wr */
-+#define REG_USB0_FLAG 0xF461
-+#define REG_USB1_FLAG 0xF462
-+#define REG_USB2_FLAG 0xF463
-+#define BIT_USB_FLAG_ON 1
-+#define BIT_USB_FLAG_OFF 0
-+/* LID */
-+#define REG_LID_DETECT 0xF4BD
-+#define BIT_LID_DETECT_ON 1
-+#define BIT_LID_DETECT_OFF 0
-+/* CRT */
-+#define REG_CRT_DETECT 0xF4AD
-+#define BIT_CRT_DETECT_PLUG 1
-+#define BIT_CRT_DETECT_UNPLUG 0
-+/* LCD backlight brightness adjust: 9 levels */
-+#define REG_DISPLAY_BRIGHTNESS 0xF4F5
-+/* Black screen Status */
-+#define BIT_DISPLAY_LCD_ON 1
-+#define BIT_DISPLAY_LCD_OFF 0
-+/* LCD backlight control: off/restore */
-+#define REG_BACKLIGHT_CTRL 0xF7BD
-+#define BIT_BACKLIGHT_ON 1
-+#define BIT_BACKLIGHT_OFF 0
-+/* Reset the machine auto-clear: rd/wr */
-+#define REG_RESET 0xF4EC
-+#define BIT_RESET_ON 1
-+/* Light the led: rd/wr */
-+#define REG_LED 0xF4C8
-+#define BIT_LED_RED_POWER (1 << 0)
-+#define BIT_LED_ORANGE_POWER (1 << 1)
-+#define BIT_LED_GREEN_CHARGE (1 << 2)
-+#define BIT_LED_RED_CHARGE (1 << 3)
-+#define BIT_LED_NUMLOCK (1 << 4)
-+/* Test led mode, all led on/off */
-+#define REG_LED_TEST 0xF4C2
-+#define BIT_LED_TEST_IN 1
-+#define BIT_LED_TEST_OUT 0
-+/* Camera on/off */
-+#define REG_CAMERA_STATUS 0xF46A
-+#define BIT_CAMERA_STATUS_ON 1
-+#define BIT_CAMERA_STATUS_OFF 0
-+#define REG_CAMERA_CONTROL 0xF7B7
-+#define BIT_CAMERA_CONTROL_OFF 0
-+#define BIT_CAMERA_CONTROL_ON 1
-+/* Wlan Status */
-+#define REG_WLAN 0xF4FA
-+#define BIT_WLAN_ON 1
-+#define BIT_WLAN_OFF 0
-+#define REG_DISPLAY_LCD 0xF79F
-+
-+/* SCI Event Number from EC */
-+enum {
-+ EVENT_LID = 0x23, /* Turn on/off LID */
-+ EVENT_SWITCHVIDEOMODE, /* Fn+F3 for display switch */
-+ EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
-+ EVENT_OVERTEMP, /* Over-temperature happened */
-+ EVENT_CRT_DETECT, /* CRT is connected */
-+ EVENT_CAMERA, /* Camera on/off */
-+ EVENT_USB_OC2, /* USB2 Over Current occurred */
-+ EVENT_USB_OC0, /* USB0 Over Current occurred */
-+ EVENT_DISPLAYTOGGLE, /* Fn+F2, Turn on/off backlight */
-+ EVENT_AUDIO_MUTE, /* Fn+F4, Mute on/off */
-+ EVENT_DISPLAY_BRIGHTNESS,/* Fn+^/V, LCD backlight brightness adjust */
-+ EVENT_AC_BAT, /* AC & Battery relative issue */
-+ EVENT_AUDIO_VOLUME, /* Fn+<|>, Volume adjust */
-+ EVENT_WLAN, /* Wlan on/off */
-+};
-+
-+#define EVENT_START EVENT_LID
-+#define EVENT_END EVENT_WLAN
-+
-+#endif /* !_EC_KB3310B_H */
-diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/loongson.h linux-2.6.37/arch/mips/include/asm/mach-loongson/loongson.h
---- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/loongson.h 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/loongson.h 2011-01-11 20:44:43.000000000 +0100
-@@ -43,6 +43,12 @@
- #endif
- }
-
-+/*
-+ * Copy kernel command line from arcs_cmdline
-+ */
-+#include <asm/setup.h>
-+extern char loongson_cmdline[COMMAND_LINE_SIZE];
-+
- /* irq operation functions */
- extern void bonito_irqdispatch(void);
- extern void __init bonito_irq_init(void);
-diff -Nur linux-2.6.37.orig/arch/mips/kernel/csrc-r4k.c linux-2.6.37/arch/mips/kernel/csrc-r4k.c
---- linux-2.6.37.orig/arch/mips/kernel/csrc-r4k.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/kernel/csrc-r4k.c 2011-01-11 20:44:43.000000000 +0100
-@@ -6,10 +6,66 @@
- * Copyright (C) 2007 by Ralf Baechle
- */
- #include <linux/clocksource.h>
-+#include <linux/cnt32_to_63.h>
- #include <linux/init.h>
-+#include <linux/timer.h>
-
- #include <asm/time.h>
-
-+#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
-+/*
-+ * MIPS sched_clock implementation.
-+ *
-+ * Because the hardware timer period is quite short and because cnt32_to_63()
-+ * needs to be called at least once per half period to work properly, a kernel
-+ * timer is set up to ensure this requirement is always met.
-+ *
-+ * Please refer to include/linux/cnt32_to_63.h and arch/arm/plat-orion/time.c
-+ */
-+#define CLOCK2NS_SCALE_FACTOR 8
-+
-+static unsigned long clock2ns_scale __read_mostly;
-+
-+unsigned long long notrace sched_clock(void)
-+{
-+ unsigned long long v = cnt32_to_63(read_c0_count());
-+ return (v * clock2ns_scale) >> CLOCK2NS_SCALE_FACTOR;
-+}
-+
-+static struct timer_list cnt32_to_63_keepwarm_timer;
-+
-+static void cnt32_to_63_keepwarm(unsigned long data)
-+{
-+ mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
-+ sched_clock();
-+}
-+#endif
-+
-+static inline void setup_hres_sched_clock(unsigned long clock)
-+{
-+#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
-+ unsigned long long v;
-+ unsigned long data;
-+
-+ v = NSEC_PER_SEC;
-+ v <<= CLOCK2NS_SCALE_FACTOR;
-+ v += clock/2;
-+ do_div(v, clock);
-+ /*
-+ * We want an even value to automatically clear the top bit
-+ * returned by cnt32_to_63() without an additional run time
-+ * instruction. So if the LSB is 1 then round it up.
-+ */
-+ if (v & 1)
-+ v++;
-+ clock2ns_scale = v;
-+
-+ data = 0x80000000UL / clock * HZ;
-+ setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
-+ mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
-+#endif
-+}
-+
- static cycle_t c0_hpt_read(struct clocksource *cs)
- {
- return read_c0_count();
-@@ -27,6 +83,8 @@
- if (!cpu_has_counter || !mips_hpt_frequency)
- return -ENXIO;
-
-+ setup_hres_sched_clock(mips_hpt_frequency);
-+
- /* Calculate a somewhat reasonable rating value */
- clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
-
-diff -Nur linux-2.6.37.orig/arch/mips/kernel/time.c linux-2.6.37/arch/mips/kernel/time.c
---- linux-2.6.37.orig/arch/mips/kernel/time.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/kernel/time.c 2011-01-11 20:44:43.000000000 +0100
-@@ -119,6 +119,11 @@
-
- void __init time_init(void)
- {
-+#ifdef CONFIG_HR_SCHED_CLOCK
-+ if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
-+ write_c0_count(0);
-+#endif
-+
- plat_time_init();
-
- if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cmdline.c linux-2.6.37/arch/mips/loongson/common/cmdline.c
---- linux-2.6.37.orig/arch/mips/loongson/common/cmdline.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/common/cmdline.c 2011-01-11 20:44:43.000000000 +0100
-@@ -17,10 +17,15 @@
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-+#include <linux/module.h>
- #include <asm/bootinfo.h>
-
- #include <loongson.h>
-
-+/* the kernel command line copied from arcs_cmdline */
-+char loongson_cmdline[COMMAND_LINE_SIZE];
-+EXPORT_SYMBOL(loongson_cmdline);
-+
- void __init prom_init_cmdline(void)
- {
- int prom_argc;
-@@ -50,4 +55,26 @@
- strcat(arcs_cmdline, " root=/dev/hda1");
-
- prom_init_machtype();
-+
-+ /* append machine specific command line */
-+ switch (mips_machtype) {
-+ case MACH_LEMOTE_LL2F:
-+ if ((strstr(arcs_cmdline, "video=")) == NULL)
-+ strcat(arcs_cmdline, " video=sisfb:1360x768-16@60");
-+ break;
-+ case MACH_LEMOTE_FL2F:
-+ if ((strstr(arcs_cmdline, "ide_core.ignore_cable=")) == NULL)
-+ strcat(arcs_cmdline, " ide_core.ignore_cable=0");
-+ break;
-+ case MACH_LEMOTE_ML2F7:
-+ /* Mengloong-2F has a 800x480 screen */
-+ if ((strstr(arcs_cmdline, "vga=")) == NULL)
-+ strcat(arcs_cmdline, " vga=0x313");
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* copy arcs_cmdline into loongson_cmdline */
-+ strncpy(loongson_cmdline, arcs_cmdline, COMMAND_LINE_SIZE);
- }
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_acc.c
---- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_acc.c 2011-01-11 20:44:43.000000000 +0100
-@@ -18,7 +18,7 @@
-
- void pci_acc_write_reg(int reg, u32 value)
- {
-- u32 hi = 0, lo = value;
-+ u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
-@@ -66,75 +66,73 @@
- u32 pci_acc_read_reg(int reg)
- {
- u32 hi, lo;
-- u32 conf_data = 0;
-+ u32 cfg = 0;
-
- switch (reg) {
- case PCI_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID,
-+ CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
- if (((lo & 0xfff00000) || (hi & 0x000000ff))
- && ((hi & 0xf0000000) == 0xa0000000))
-- conf_data |= PCI_COMMAND_IO;
-+ cfg |= PCI_COMMAND_IO;
- _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
- if ((lo & 0x300) == 0x300)
-- conf_data |= PCI_COMMAND_MASTER;
-+ cfg |= PCI_COMMAND_MASTER;
- break;
- case PCI_STATUS:
-- conf_data |= PCI_STATUS_66MHZ;
-- conf_data |= PCI_STATUS_FAST_BACK;
-+ cfg |= PCI_STATUS_66MHZ;
-+ cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
-- conf_data |= PCI_STATUS_PARITY;
-- conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
-+ cfg |= PCI_STATUS_PARITY;
-+ cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
-- conf_data = lo & 0x000000ff;
-- conf_data |= (CS5536_ACC_CLASS_CODE << 8);
-+ cfg = lo & 0x000000ff;
-+ cfg |= (CS5536_ACC_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
-- conf_data =
-- CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
-- PCI_NORMAL_LATENCY_TIMER);
-+ cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
-+ PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_ACC_FLAG) {
-- conf_data = CS5536_ACC_RANGE |
-+ cfg = CS5536_ACC_RANGE |
- PCI_BASE_ADDRESS_SPACE_IO;
- lo &= ~SOFT_BAR_ACC_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
-- conf_data = (hi & 0x000000ff) << 12;
-- conf_data |= (lo & 0xfff00000) >> 20;
-- conf_data |= 0x01;
-- conf_data &= ~0x02;
-+ cfg = (hi & 0x000000ff) << 12;
-+ cfg |= (lo & 0xfff00000) >> 20;
-+ cfg |= 0x01;
-+ cfg &= ~0x02;
- }
- break;
- case PCI_CARDBUS_CIS:
-- conf_data = PCI_CARDBUS_CIS_POINTER;
-+ cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID,
-+ CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
-- conf_data = PCI_EXPANSION_ROM_BAR;
-+ cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
-- conf_data = PCI_CAPLIST_USB_POINTER;
-+ cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
-- conf_data =
-- CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
-+ cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
- break;
- default:
- break;
- }
-
-- return conf_data;
-+ return cfg;
- }
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ehci.c
---- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2011-01-11 20:44:43.000000000 +0100
-@@ -18,7 +18,7 @@
-
- void pci_ehci_write_reg(int reg, u32 value)
- {
-- u32 hi = 0, lo = value;
-+ u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
-@@ -78,83 +78,81 @@
-
- u32 pci_ehci_read_reg(int reg)
- {
-- u32 conf_data = 0;
-+ u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID,
-+ CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- if (hi & PCI_COMMAND_MASTER)
-- conf_data |= PCI_COMMAND_MASTER;
-+ cfg |= PCI_COMMAND_MASTER;
- if (hi & PCI_COMMAND_MEMORY)
-- conf_data |= PCI_COMMAND_MEMORY;
-+ cfg |= PCI_COMMAND_MEMORY;
- break;
- case PCI_STATUS:
-- conf_data |= PCI_STATUS_66MHZ;
-- conf_data |= PCI_STATUS_FAST_BACK;
-+ cfg |= PCI_STATUS_66MHZ;
-+ cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
-- conf_data |= PCI_STATUS_PARITY;
-- conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
-+ cfg |= PCI_STATUS_PARITY;
-+ cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
-- conf_data = lo & 0x000000ff;
-- conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
-+ cfg = lo & 0x000000ff;
-+ cfg |= (CS5536_EHCI_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
-- conf_data =
-- CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
-- PCI_NORMAL_LATENCY_TIMER);
-+ cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
-+ PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_EHCI_FLAG) {
-- conf_data = CS5536_EHCI_RANGE |
-+ cfg = CS5536_EHCI_RANGE |
- PCI_BASE_ADDRESS_SPACE_MEMORY;
- lo &= ~SOFT_BAR_EHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
-- conf_data = lo & 0xfffff000;
-+ cfg = lo & 0xfffff000;
- }
- break;
- case PCI_CARDBUS_CIS:
-- conf_data = PCI_CARDBUS_CIS_POINTER;
-+ cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID,
-+ CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
-- conf_data = PCI_EXPANSION_ROM_BAR;
-+ cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
-- conf_data = PCI_CAPLIST_USB_POINTER;
-+ cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
-- conf_data =
-- CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
-+ cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- break;
- case PCI_EHCI_LEGSMIEN_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
-- conf_data = (hi & 0x003f0000) >> 16;
-+ cfg = (hi & 0x003f0000) >> 16;
- break;
- case PCI_EHCI_LEGSMISTS_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
-- conf_data = (hi & 0x3f000000) >> 24;
-+ cfg = (hi & 0x3f000000) >> 24;
- break;
- case PCI_EHCI_FLADJ_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
-- conf_data = hi & 0x00003f00;
-+ cfg = hi & 0x00003f00;
- break;
- default:
- break;
- }
-
-- return conf_data;
-+ return cfg;
- }
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ide.c
---- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ide.c 2011-01-11 20:44:43.000000000 +0100
-@@ -18,7 +18,7 @@
-
- void pci_ide_write_reg(int reg, u32 value)
- {
-- u32 hi = 0, lo = value;
-+ u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
-@@ -72,26 +72,16 @@
- _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
- }
- break;
-- case PCI_IDE_DTC_REG:
-- _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
-- lo = value;
-- _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
-- break;
-- case PCI_IDE_CAST_REG:
-- _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
-- lo = value;
-- _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
-- break;
-- case PCI_IDE_ETC_REG:
-- _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
-- lo = value;
-- _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
-- break;
-- case PCI_IDE_PM_REG:
-- _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
-- lo = value;
-- _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
-- break;
-+#define SET_PCI_IDE_REG(r) \
-+ case PCI_IDE_##r##_REG: \
-+ _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &lo); \
-+ lo = value; \
-+ _wrmsr(IDE_MSR_REG(IDE_##r), hi, lo); \
-+ break;
-+ SET_PCI_IDE_REG(DTC)
-+ SET_PCI_IDE_REG(CAST)
-+ SET_PCI_IDE_REG(ETC)
-+ SET_PCI_IDE_REG(PM)
- default:
- break;
- }
-@@ -99,94 +89,82 @@
-
- u32 pci_ide_read_reg(int reg)
- {
-- u32 conf_data = 0;
-+ u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID,
-+ CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
- if (lo & 0xfffffff0)
-- conf_data |= PCI_COMMAND_IO;
-+ cfg |= PCI_COMMAND_IO;
- _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
- if ((lo & 0x30) == 0x30)
-- conf_data |= PCI_COMMAND_MASTER;
-+ cfg |= PCI_COMMAND_MASTER;
- break;
- case PCI_STATUS:
-- conf_data |= PCI_STATUS_66MHZ;
-- conf_data |= PCI_STATUS_FAST_BACK;
-+ cfg |= PCI_STATUS_66MHZ;
-+ cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
-- conf_data |= PCI_STATUS_PARITY;
-- conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
-+ cfg |= PCI_STATUS_PARITY;
-+ cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
-- conf_data = lo & 0x000000ff;
-- conf_data |= (CS5536_IDE_CLASS_CODE << 8);
-+ cfg = lo & 0x000000ff;
-+ cfg |= (CS5536_IDE_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
- hi &= 0x000000f8;
-- conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
-+ cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
- break;
- case PCI_BAR4_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_IDE_FLAG) {
-- conf_data = CS5536_IDE_RANGE |
-+ cfg = CS5536_IDE_RANGE |
- PCI_BASE_ADDRESS_SPACE_IO;
- lo &= ~SOFT_BAR_IDE_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
-- conf_data = lo & 0xfffffff0;
-- conf_data |= 0x01;
-- conf_data &= ~0x02;
-+ cfg = lo & 0xfffffff0;
-+ cfg |= 0x01;
-+ cfg &= ~0x02;
- }
- break;
- case PCI_CARDBUS_CIS:
-- conf_data = PCI_CARDBUS_CIS_POINTER;
-+ cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID,
-+ CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
-- conf_data = PCI_EXPANSION_ROM_BAR;
-+ cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
-- conf_data = PCI_CAPLIST_POINTER;
-+ cfg = PCI_CAPLIST_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
-- conf_data =
-- CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
-- break;
-- case PCI_IDE_CFG_REG:
-- _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
-- conf_data = lo;
-- break;
-- case PCI_IDE_DTC_REG:
-- _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
-- conf_data = lo;
-- break;
-- case PCI_IDE_CAST_REG:
-- _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
-- conf_data = lo;
-- break;
-- case PCI_IDE_ETC_REG:
-- _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
-- conf_data = lo;
-- break;
-- case PCI_IDE_PM_REG:
-- _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
-- conf_data = lo;
-+ cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
- break;
-+#define GET_PCI_IDE_REG(r) \
-+ case PCI_IDE_##r##_REG: \
-+ _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &cfg); \
-+ break;
-+ GET_PCI_IDE_REG(CFG)
-+ GET_PCI_IDE_REG(DTC)
-+ GET_PCI_IDE_REG(CAST)
-+ GET_PCI_IDE_REG(ETC)
-+ GET_PCI_IDE_REG(PM)
- default:
- break;
- }
-
-- return conf_data;
-+ return cfg;
- }
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ohci.c
---- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2011-01-11 20:44:43.000000000 +0100
-@@ -18,7 +18,7 @@
-
- void pci_ohci_write_reg(int reg, u32 value)
- {
-- u32 hi = 0, lo = value;
-+ u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
-@@ -73,77 +73,75 @@
-
- u32 pci_ohci_read_reg(int reg)
- {
-- u32 conf_data = 0;
-+ u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID,
-+ CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
- if (hi & PCI_COMMAND_MASTER)
-- conf_data |= PCI_COMMAND_MASTER;
-+ cfg |= PCI_COMMAND_MASTER;
- if (hi & PCI_COMMAND_MEMORY)
-- conf_data |= PCI_COMMAND_MEMORY;
-+ cfg |= PCI_COMMAND_MEMORY;
- break;
- case PCI_STATUS:
-- conf_data |= PCI_STATUS_66MHZ;
-- conf_data |= PCI_STATUS_FAST_BACK;
-+ cfg |= PCI_STATUS_66MHZ;
-+ cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
-- conf_data |= PCI_STATUS_PARITY;
-- conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
-+ cfg |= PCI_STATUS_PARITY;
-+ cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
-- conf_data = lo & 0x000000ff;
-- conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
-+ cfg = lo & 0x000000ff;
-+ cfg |= (CS5536_OHCI_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
-- conf_data =
-- CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
-- PCI_NORMAL_LATENCY_TIMER);
-+ cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
-+ PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_OHCI_FLAG) {
-- conf_data = CS5536_OHCI_RANGE |
-+ cfg = CS5536_OHCI_RANGE |
- PCI_BASE_ADDRESS_SPACE_MEMORY;
- lo &= ~SOFT_BAR_OHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
-- conf_data = lo & 0xffffff00;
-- conf_data &= ~0x0000000f; /* 32bit mem */
-+ cfg = lo & 0xffffff00;
-+ cfg &= ~0x0000000f; /* 32bit mem */
- }
- break;
- case PCI_CARDBUS_CIS:
-- conf_data = PCI_CARDBUS_CIS_POINTER;
-+ cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
-- conf_data =
-- CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
-+ cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID,
-+ CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
-- conf_data = PCI_EXPANSION_ROM_BAR;
-+ cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
-- conf_data = PCI_CAPLIST_USB_POINTER;
-+ cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
-- conf_data =
-- CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
-+ cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- break;
- case PCI_OHCI_INT_REG:
- _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
- if ((lo & 0x00000f00) == CS5536_USB_INTR)
-- conf_data = 1;
-+ cfg = 1;
- break;
- default:
- break;
- }
-
-- return conf_data;
-+ return cfg;
- }
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/mtd.c linux-2.6.37/arch/mips/loongson/common/mtd.c
---- linux-2.6.37.orig/arch/mips/loongson/common/mtd.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/common/mtd.c 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,91 @@
-+/*
-+ * Driver for flushing/dumping ROM of PMON on loongson family machines
-+ *
-+ * Copyright (C) 2008-2009 Lemote Inc.
-+ * Author: Yan Hua <yanh@lemote.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/io.h>
-+
-+#include <loongson.h>
-+
-+#define FLASH_PHYS_ADDR LOONGSON_BOOT_BASE
-+#define FLASH_SIZE 0x080000
-+
-+#define FLASH_PARTITION0_ADDR 0x00000000
-+#define FLASH_PARTITION0_SIZE 0x00080000
-+
-+struct map_info flash_map = {
-+ .name = "flash device",
-+ .size = FLASH_SIZE,
-+ .bankwidth = 1,
-+};
-+
-+struct mtd_partition flash_parts[] = {
-+ {
-+ .name = "Bootloader",
-+ .offset = FLASH_PARTITION0_ADDR,
-+ .size = FLASH_PARTITION0_SIZE},
-+};
-+
-+#define PARTITION_COUNT ARRAY_SIZE(flash_parts)
-+
-+static struct mtd_info *mymtd;
-+
-+int __init init_flash(void)
-+{
-+ printk(KERN_NOTICE "flash device: %x at %x\n",
-+ FLASH_SIZE, FLASH_PHYS_ADDR);
-+
-+ flash_map.phys = FLASH_PHYS_ADDR;
-+ flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE);
-+
-+ if (!flash_map.virt) {
-+ printk(KERN_NOTICE "Failed to ioremap\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&flash_map);
-+
-+ mymtd = do_map_probe("cfi_probe", &flash_map);
-+ if (mymtd) {
-+ add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT);
-+ printk(KERN_NOTICE "pmon flash device initialized\n");
-+ return 0;
-+ }
-+
-+ iounmap((void *)flash_map.virt);
-+ return -ENXIO;
-+}
-+
-+static void __exit cleanup_flash(void)
-+{
-+ if (mymtd) {
-+ del_mtd_partitions(mymtd);
-+ map_destroy(mymtd);
-+ }
-+ if (flash_map.virt) {
-+ iounmap((void *)flash_map.virt);
-+ flash_map.virt = 0;
-+ }
-+}
-+
-+module_init(init_flash);
-+module_exit(cleanup_flash);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
-+MODULE_DESCRIPTION("MTD driver for pmon flushing/dumping");
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/Makefile linux-2.6.37/arch/mips/loongson/lemote-2f/Makefile
---- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/Makefile 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/lemote-2f/Makefile 2011-01-11 20:44:43.000000000 +0100
-@@ -2,7 +2,7 @@
- # Makefile for lemote loongson2f family machines
- #
-
--obj-y += machtype.o irq.o reset.o ec_kb3310b.o
-+obj-y += machtype.o irq.o reset.o ec_kb3310b.o platform.o
-
- #
- # Suspend Support
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.c
---- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2011-01-11 20:44:43.000000000 +0100
-@@ -14,7 +14,7 @@
- #include <linux/spinlock.h>
- #include <linux/delay.h>
-
--#include "ec_kb3310b.h"
-+#include <ec_kb3310b.h>
-
- static DEFINE_SPINLOCK(index_access_lock);
- static DEFINE_SPINLOCK(port_access_lock);
-@@ -78,12 +78,9 @@
- spin_unlock_irqrestore(&port_access_lock, flags);
-
- if (timeout <= 0) {
-- printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
-+ pr_err("%s: deadable error : timeout...\n", __func__);
- ret = -EINVAL;
-- } else
-- printk(KERN_INFO
-- "(%x/%d)ec issued command %d status : 0x%x\n",
-- timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
-+ }
-
- return ret;
- }
-@@ -118,8 +115,7 @@
- udelay(EC_REG_DELAY);
- }
- if (timeout <= 0) {
-- pr_info("%s: get event number timeout.\n", __func__);
--
-+ pr_err("%s: get event number timeout.\n", __func__);
- return -EINVAL;
- }
- value = inb(EC_DAT_PORT);
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.h
---- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,188 +0,0 @@
--/*
-- * KB3310B Embedded Controller
-- *
-- * Copyright (C) 2008 Lemote Inc.
-- * Author: liujl <liujl@lemote.com>, 2008-03-14
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- */
--
--#ifndef _EC_KB3310B_H
--#define _EC_KB3310B_H
--
--extern unsigned char ec_read(unsigned short addr);
--extern void ec_write(unsigned short addr, unsigned char val);
--extern int ec_query_seq(unsigned char cmd);
--extern int ec_query_event_num(void);
--extern int ec_get_event_num(void);
--
--typedef int (*sci_handler) (int status);
--extern sci_handler yeeloong_report_lid_status;
--
--#define SCI_IRQ_NUM 0x0A
--
--/*
-- * The following registers are determined by the EC index configuration.
-- * 1, fill the PORT_HIGH as EC register high part.
-- * 2, fill the PORT_LOW as EC register low part.
-- * 3, fill the PORT_DATA as EC register write data or get the data from it.
-- */
--#define EC_IO_PORT_HIGH 0x0381
--#define EC_IO_PORT_LOW 0x0382
--#define EC_IO_PORT_DATA 0x0383
--
--/*
-- * EC delay time is 500us for register and status access
-- */
--#define EC_REG_DELAY 500 /* unit : us */
--#define EC_CMD_TIMEOUT 0x1000
--
--/*
-- * EC access port for SCI communication
-- */
--#define EC_CMD_PORT 0x66
--#define EC_STS_PORT 0x66
--#define EC_DAT_PORT 0x62
--#define CMD_INIT_IDLE_MODE 0xdd
--#define CMD_EXIT_IDLE_MODE 0xdf
--#define CMD_INIT_RESET_MODE 0xd8
--#define CMD_REBOOT_SYSTEM 0x8c
--#define CMD_GET_EVENT_NUM 0x84
--#define CMD_PROGRAM_PIECE 0xda
--
--/* temperature & fan registers */
--#define REG_TEMPERATURE_VALUE 0xF458
--#define REG_FAN_AUTO_MAN_SWITCH 0xF459
--#define BIT_FAN_AUTO 0
--#define BIT_FAN_MANUAL 1
--#define REG_FAN_CONTROL 0xF4D2
--#define BIT_FAN_CONTROL_ON (1 << 0)
--#define BIT_FAN_CONTROL_OFF (0 << 0)
--#define REG_FAN_STATUS 0xF4DA
--#define BIT_FAN_STATUS_ON (1 << 0)
--#define BIT_FAN_STATUS_OFF (0 << 0)
--#define REG_FAN_SPEED_HIGH 0xFE22
--#define REG_FAN_SPEED_LOW 0xFE23
--#define REG_FAN_SPEED_LEVEL 0xF4CC
--/* fan speed divider */
--#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
--
--/* battery registers */
--#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
--#define REG_BAT_DESIGN_CAP_LOW 0xF77E
--#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
--#define REG_BAT_FULLCHG_CAP_LOW 0xF781
--#define REG_BAT_DESIGN_VOL_HIGH 0xF782
--#define REG_BAT_DESIGN_VOL_LOW 0xF783
--#define REG_BAT_CURRENT_HIGH 0xF784
--#define REG_BAT_CURRENT_LOW 0xF785
--#define REG_BAT_VOLTAGE_HIGH 0xF786
--#define REG_BAT_VOLTAGE_LOW 0xF787
--#define REG_BAT_TEMPERATURE_HIGH 0xF788
--#define REG_BAT_TEMPERATURE_LOW 0xF789
--#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
--#define REG_BAT_RELATIVE_CAP_LOW 0xF493
--#define REG_BAT_VENDOR 0xF4C4
--#define FLAG_BAT_VENDOR_SANYO 0x01
--#define FLAG_BAT_VENDOR_SIMPLO 0x02
--#define REG_BAT_CELL_COUNT 0xF4C6
--#define FLAG_BAT_CELL_3S1P 0x03
--#define FLAG_BAT_CELL_3S2P 0x06
--#define REG_BAT_CHARGE 0xF4A2
--#define FLAG_BAT_CHARGE_DISCHARGE 0x01
--#define FLAG_BAT_CHARGE_CHARGE 0x02
--#define FLAG_BAT_CHARGE_ACPOWER 0x00
--#define REG_BAT_STATUS 0xF4B0
--#define BIT_BAT_STATUS_LOW (1 << 5)
--#define BIT_BAT_STATUS_DESTROY (1 << 2)
--#define BIT_BAT_STATUS_FULL (1 << 1)
--#define BIT_BAT_STATUS_IN (1 << 0)
--#define REG_BAT_CHARGE_STATUS 0xF4B1
--#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
--#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
--#define REG_BAT_STATE 0xF482
--#define BIT_BAT_STATE_CHARGING (1 << 1)
--#define BIT_BAT_STATE_DISCHARGING (1 << 0)
--#define REG_BAT_POWER 0xF440
--#define BIT_BAT_POWER_S3 (1 << 2)
--#define BIT_BAT_POWER_ON (1 << 1)
--#define BIT_BAT_POWER_ACIN (1 << 0)
--
--/* other registers */
--/* Audio: rd/wr */
--#define REG_AUDIO_VOLUME 0xF46C
--#define REG_AUDIO_MUTE 0xF4E7
--#define REG_AUDIO_BEEP 0xF4D0
--/* USB port power or not: rd/wr */
--#define REG_USB0_FLAG 0xF461
--#define REG_USB1_FLAG 0xF462
--#define REG_USB2_FLAG 0xF463
--#define BIT_USB_FLAG_ON 1
--#define BIT_USB_FLAG_OFF 0
--/* LID */
--#define REG_LID_DETECT 0xF4BD
--#define BIT_LID_DETECT_ON 1
--#define BIT_LID_DETECT_OFF 0
--/* CRT */
--#define REG_CRT_DETECT 0xF4AD
--#define BIT_CRT_DETECT_PLUG 1
--#define BIT_CRT_DETECT_UNPLUG 0
--/* LCD backlight brightness adjust: 9 levels */
--#define REG_DISPLAY_BRIGHTNESS 0xF4F5
--/* Black screen Status */
--#define BIT_DISPLAY_LCD_ON 1
--#define BIT_DISPLAY_LCD_OFF 0
--/* LCD backlight control: off/restore */
--#define REG_BACKLIGHT_CTRL 0xF7BD
--#define BIT_BACKLIGHT_ON 1
--#define BIT_BACKLIGHT_OFF 0
--/* Reset the machine auto-clear: rd/wr */
--#define REG_RESET 0xF4EC
--#define BIT_RESET_ON 1
--/* Light the led: rd/wr */
--#define REG_LED 0xF4C8
--#define BIT_LED_RED_POWER (1 << 0)
--#define BIT_LED_ORANGE_POWER (1 << 1)
--#define BIT_LED_GREEN_CHARGE (1 << 2)
--#define BIT_LED_RED_CHARGE (1 << 3)
--#define BIT_LED_NUMLOCK (1 << 4)
--/* Test led mode, all led on/off */
--#define REG_LED_TEST 0xF4C2
--#define BIT_LED_TEST_IN 1
--#define BIT_LED_TEST_OUT 0
--/* Camera on/off */
--#define REG_CAMERA_STATUS 0xF46A
--#define BIT_CAMERA_STATUS_ON 1
--#define BIT_CAMERA_STATUS_OFF 0
--#define REG_CAMERA_CONTROL 0xF7B7
--#define BIT_CAMERA_CONTROL_OFF 0
--#define BIT_CAMERA_CONTROL_ON 1
--/* Wlan Status */
--#define REG_WLAN 0xF4FA
--#define BIT_WLAN_ON 1
--#define BIT_WLAN_OFF 0
--#define REG_DISPLAY_LCD 0xF79F
--
--/* SCI Event Number from EC */
--enum {
-- EVENT_LID = 0x23, /* LID open/close */
-- EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
-- EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
-- EVENT_OVERTEMP, /* Over-temperature happened */
-- EVENT_CRT_DETECT, /* CRT is connected */
-- EVENT_CAMERA, /* Camera on/off */
-- EVENT_USB_OC2, /* USB2 Over Current occurred */
-- EVENT_USB_OC0, /* USB0 Over Current occurred */
-- EVENT_BLACK_SCREEN, /* Turn on/off backlight */
-- EVENT_AUDIO_MUTE, /* Mute on/off */
-- EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
-- EVENT_AC_BAT, /* AC & Battery relative issue */
-- EVENT_AUDIO_VOLUME, /* Volume adjust */
-- EVENT_WLAN, /* Wlan on/off */
-- EVENT_END
--};
--
--#endif /* !_EC_KB3310B_H */
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/platform.c linux-2.6.37/arch/mips/loongson/lemote-2f/platform.c
---- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/platform.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/lemote-2f/platform.c 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright (C) 2009 Lemote Inc.
-+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/platform_device.h>
-+
-+#include <asm/bootinfo.h>
-+
-+static struct platform_device yeeloong_pdev = {
-+ .name = "yeeloong_laptop",
-+ .id = -1,
-+};
-+
-+static struct platform_device lynloong_pdev = {
-+ .name = "lynloong_pc",
-+ .id = -1,
-+};
-+
-+static int __init lemote2f_platform_init(void)
-+{
-+ struct platform_device *pdev = NULL;
-+
-+ switch (mips_machtype) {
-+ case MACH_LEMOTE_YL2F89:
-+ pdev = &yeeloong_pdev;
-+ break;
-+ case MACH_LEMOTE_LL2F:
-+ pdev = &lynloong_pdev;
-+ break;
-+ default:
-+ break;
-+
-+ }
-+
-+ if (pdev != NULL)
-+ return platform_device_register(pdev);
-+
-+ return -ENODEV;
-+}
-+
-+arch_initcall(lemote2f_platform_init);
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/pm.c linux-2.6.37/arch/mips/loongson/lemote-2f/pm.c
---- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/pm.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/lemote-2f/pm.c 2011-01-11 20:44:43.000000000 +0100
-@@ -23,7 +23,7 @@
- #include <loongson.h>
-
- #include <cs5536/cs5536_mfgpt.h>
--#include "ec_kb3310b.h"
-+#include <ec_kb3310b.h>
-
- #define I8042_KBD_IRQ 1
- #define I8042_CTR_KBDINT 0x01
-@@ -100,7 +100,7 @@
- if (irq < 0)
- return 0;
-
-- printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
-+ pr_info("%s: irq = %d\n", __func__, irq);
-
- if (irq == I8042_KBD_IRQ)
- return 1;
-diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/reset.c linux-2.6.37/arch/mips/loongson/lemote-2f/reset.c
---- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/reset.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/loongson/lemote-2f/reset.c 2011-01-11 20:44:43.000000000 +0100
-@@ -20,7 +20,7 @@
- #include <loongson.h>
-
- #include <cs5536/cs5536.h>
--#include "ec_kb3310b.h"
-+#include <ec_kb3310b.h>
-
- static void reset_cpu(void)
- {
-diff -Nur linux-2.6.37.orig/arch/mips/mm/dma-default.c linux-2.6.37/arch/mips/mm/dma-default.c
---- linux-2.6.37.orig/arch/mips/mm/dma-default.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/arch/mips/mm/dma-default.c 2011-01-11 20:46:19.000000000 +0100
-@@ -300,6 +300,20 @@
-
- EXPORT_SYMBOL(dma_cache_sync);
-
-+int __weak dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-+ void *cpu_addr, dma_addr_t handle, size_t size)
-+{
-+ struct page *pg;
-+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+ cpu_addr = (void *)dma_addr_to_virt(dev, handle);
-+ pg = virt_to_page(cpu_addr);
-+ return remap_pfn_range(vma, vma->vm_start,
-+ page_to_pfn(pg) + vma->vm_pgoff,
-+ size, vma->vm_page_prot);
-+}
-+EXPORT_SYMBOL(dma_mmap_coherent);
-+
-+
- static struct dma_map_ops mips_default_dma_map_ops = {
- .alloc_coherent = mips_dma_alloc_coherent,
- .free_coherent = mips_dma_free_coherent,
-diff -Nur linux-2.6.37.orig/drivers/ide/ide-iops.c linux-2.6.37/drivers/ide/ide-iops.c
---- linux-2.6.37.orig/drivers/ide/ide-iops.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/drivers/ide/ide-iops.c 2011-01-11 20:44:43.000000000 +0100
-@@ -27,6 +27,8 @@
- #include <asm/uaccess.h>
- #include <asm/io.h>
-
-+#include <asm/bootinfo.h>
-+
- void SELECT_MASK(ide_drive_t *drive, int mask)
- {
- const struct ide_port_ops *port_ops = drive->hwif->port_ops;
-@@ -300,6 +302,9 @@
- {
- const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
-
-+ if (mips_machtype != MACH_LEMOTE_YL2F89)
-+ return;
-+
- for (list = nien_quirk_list; *list != NULL; list++)
- if (strstr(m, *list) != NULL) {
- drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
-diff -Nur linux-2.6.37.orig/drivers/platform/Kconfig linux-2.6.37/drivers/platform/Kconfig
---- linux-2.6.37.orig/drivers/platform/Kconfig 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/drivers/platform/Kconfig 2011-01-11 20:44:43.000000000 +0100
-@@ -1,3 +1,7 @@
- if X86
- source "drivers/platform/x86/Kconfig"
- endif
-+
-+if MIPS
-+source "drivers/platform/mips/Kconfig"
-+endif
-diff -Nur linux-2.6.37.orig/drivers/platform/Makefile linux-2.6.37/drivers/platform/Makefile
---- linux-2.6.37.orig/drivers/platform/Makefile 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/drivers/platform/Makefile 2011-01-11 20:44:43.000000000 +0100
-@@ -3,3 +3,4 @@
- #
-
- obj-$(CONFIG_X86) += x86/
-+obj-$(CONFIG_MIPS) += mips/
-diff -Nur linux-2.6.37.orig/drivers/platform/mips/Kconfig linux-2.6.37/drivers/platform/mips/Kconfig
---- linux-2.6.37.orig/drivers/platform/mips/Kconfig 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/drivers/platform/mips/Kconfig 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,43 @@
-+#
-+# MIPS Platform Specific Drivers
-+#
-+
-+menuconfig MIPS_PLATFORM_DEVICES
-+ bool "MIPS Platform Specific Device Drivers"
-+ default y
-+ help
-+ Say Y here to get to see options for device drivers of various
-+ MIPS platforms, including vendor-specific netbook/laptop/pc extension
-+ drivers. This option alone does not add any kernel code.
-+
-+ If you say N, all options in this submenu will be skipped and disabled.
-+
-+if MIPS_PLATFORM_DEVICES
-+
-+config LEMOTE_YEELOONG2F
-+ tristate "Lemote YeeLoong Laptop"
-+ depends on LEMOTE_MACH2F
-+ select BACKLIGHT_CLASS_DEVICE
-+ select POWER_SUPPLY
-+ select HWMON
-+ select VIDEO_OUTPUT_CONTROL
-+ select INPUT_SPARSEKMAP
-+ depends on INPUT
-+ help
-+ YeeLoong netbook is a mini laptop made by Lemote, which is basically
-+ compatible to FuLoong2F mini PC, but it has an extra Embedded
-+ Controller(kb3310b) for battery, hotkey, backlight, temperature and
-+ fan management.
-+
-+config LEMOTE_LYNLOONG2F
-+ tristate "Lemote LynLoong PC"
-+ depends on LEMOTE_MACH2F
-+ select BACKLIGHT_CLASS_DEVICE
-+ select VIDEO_OUTPUT_CONTROL
-+ help
-+ LynLoong PC is an AllINONE machine made by Lemote, which is basically
-+ compatible to FuLoong2F Mini PC, the only difference is that it has a
-+ size-fixed screen: 1360x768 with sisfb video driver. and also, it has
-+ its own specific suspend support.
-+
-+endif # MIPS_PLATFORM_DEVICES
-diff -Nur linux-2.6.37.orig/drivers/platform/mips/Makefile linux-2.6.37/drivers/platform/mips/Makefile
---- linux-2.6.37.orig/drivers/platform/mips/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/drivers/platform/mips/Makefile 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,7 @@
-+#
-+# Makefile for MIPS Platform-Specific Drivers
-+#
-+
-+obj-$(CONFIG_LEMOTE_YEELOONG2F) += yeeloong_laptop.o
-+
-+obj-$(CONFIG_LEMOTE_LYNLOONG2F) += lynloong_pc.o
-diff -Nur linux-2.6.37.orig/drivers/platform/mips/lynloong_pc.c linux-2.6.37/drivers/platform/mips/lynloong_pc.c
---- linux-2.6.37.orig/drivers/platform/mips/lynloong_pc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/drivers/platform/mips/lynloong_pc.c 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,513 @@
-+/*
-+ * Driver for LynLoong PC extras
-+ *
-+ * Copyright (C) 2009 Lemote Inc.
-+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Xiang Yu <xiangy@lemote.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/platform_device.h>
-+#include <linux/backlight.h> /* for backlight subdriver */
-+#include <linux/fb.h>
-+#include <linux/video_output.h> /* for video output subdriver */
-+#include <linux/delay.h> /* for suspend support */
-+
-+#include <cs5536/cs5536.h>
-+#include <cs5536/cs5536_mfgpt.h>
-+
-+#include <loongson.h>
-+
-+static u32 gpio_base, mfgpt_base;
-+
-+static void set_gpio_reg_high(int gpio, int reg)
-+{
-+ u32 val;
-+
-+ val = inl(gpio_base + reg);
-+ val |= (1 << gpio);
-+ val &= ~(1 << (16 + gpio));
-+ outl(val, gpio_base + reg);
-+ mmiowb();
-+}
-+
-+static void set_gpio_reg_low(int gpio, int reg)
-+{
-+ u32 val;
-+
-+ val = inl(gpio_base + reg);
-+ val |= (1 << (16 + gpio));
-+ val &= ~(1 << gpio);
-+ outl(val, gpio_base + reg);
-+ mmiowb();
-+}
-+
-+static void set_gpio_output_low(int gpio)
-+{
-+ set_gpio_reg_high(gpio, GPIOL_OUT_EN);
-+ set_gpio_reg_low(gpio, GPIOL_OUT_VAL);
-+}
-+
-+static void set_gpio_output_high(int gpio)
-+{
-+ set_gpio_reg_high(gpio, GPIOL_OUT_EN);
-+ set_gpio_reg_high(gpio, GPIOL_OUT_VAL);
-+}
-+
-+/* backlight subdriver */
-+
-+#define MAX_BRIGHTNESS 100
-+#define DEFAULT_BRIGHTNESS 50
-+#define MIN_BRIGHTNESS 0
-+static unsigned int level;
-+
-+DEFINE_SPINLOCK(backlight_lock);
-+/* Tune the brightness */
-+static void setup_mfgpt2(void)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&backlight_lock, flags);
-+
-+ /* Set MFGPT2 comparator 1,2 */
-+ outw(MAX_BRIGHTNESS-level, MFGPT2_CMP1);
-+ outw(MAX_BRIGHTNESS, MFGPT2_CMP2);
-+ /* Clear MFGPT2 UP COUNTER */
-+ outw(0, MFGPT2_CNT);
-+ /* Enable counter, compare mode, 32k */
-+ outw(0x8280, MFGPT2_SETUP);
-+
-+ spin_unlock_irqrestore(&backlight_lock, flags);
-+}
-+
-+static int lynloong_set_brightness(struct backlight_device *bd)
-+{
-+ level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
-+ bd->props.power == FB_BLANK_UNBLANK) ?
-+ bd->props.brightness : 0;
-+
-+ if (level > MAX_BRIGHTNESS)
-+ level = MAX_BRIGHTNESS;
-+ else if (level < MIN_BRIGHTNESS)
-+ level = MIN_BRIGHTNESS;
-+
-+ setup_mfgpt2();
-+
-+ return 0;
-+}
-+
-+static int lynloong_get_brightness(struct backlight_device *bd)
-+{
-+ return level;
-+}
-+
-+static struct backlight_ops backlight_ops = {
-+ .get_brightness = lynloong_get_brightness,
-+ .update_status = lynloong_set_brightness,
-+};
-+
-+static struct backlight_device *lynloong_backlight_dev;
-+
-+static int lynloong_backlight_init(void)
-+{
-+ int ret;
-+ u32 hi;
-+ struct backlight_properties props;
-+
-+ /* Get gpio_base */
-+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
-+ /* Get mfgpt_base */
-+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base);
-+ /* Get gpio_base */
-+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
-+
-+ /* Select for mfgpt */
-+ set_gpio_reg_high(7, GPIOL_OUT_AUX1_SEL);
-+ /* Enable brightness controlling */
-+ set_gpio_output_high(7);
-+
-+ memset(&props, 0, sizeof(struct backlight_properties));
-+ props.max_brightness = MAX_BRIGHTNESS;
-+ lynloong_backlight_dev = backlight_device_register("backlight0", NULL,
-+ NULL, &backlight_ops, &props);
-+
-+ if (IS_ERR(lynloong_backlight_dev)) {
-+ ret = PTR_ERR(lynloong_backlight_dev);
-+ return ret;
-+ }
-+
-+ lynloong_backlight_dev->props.brightness = DEFAULT_BRIGHTNESS;
-+ backlight_update_status(lynloong_backlight_dev);
-+
-+ return 0;
-+}
-+
-+static void lynloong_backlight_exit(void)
-+{
-+ if (lynloong_backlight_dev) {
-+ backlight_device_unregister(lynloong_backlight_dev);
-+ lynloong_backlight_dev = NULL;
-+ }
-+ /* Disable brightness controlling */
-+ set_gpio_output_low(7);
-+}
-+
-+/* video output driver */
-+static int vo_status = 1;
-+
-+static int lcd_video_output_get(struct output_device *od)
-+{
-+ return vo_status;
-+}
-+
-+static int lcd_video_output_set(struct output_device *od)
-+{
-+ int i;
-+ unsigned long status;
-+
-+ status = !!od->request_state;
-+
-+ if (status == 0) {
-+ /* Set the current status as off */
-+ vo_status = 0;
-+ /* Turn off the backlight */
-+ set_gpio_output_low(11);
-+ for (i = 0; i < 0x500; i++)
-+ delay();
-+ /* Turn off the LCD */
-+ set_gpio_output_high(8);
-+ } else {
-+ /* Turn on the LCD */
-+ set_gpio_output_low(8);
-+ for (i = 0; i < 0x500; i++)
-+ delay();
-+ /* Turn on the backlight */
-+ set_gpio_output_high(11);
-+ /* Set the current status as on */
-+ vo_status = 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct output_properties lcd_output_properties = {
-+ .set_state = lcd_video_output_set,
-+ .get_status = lcd_video_output_get,
-+};
-+
-+static struct output_device *lcd_output_dev;
-+
-+static void lynloong_lcd_vo_set(int status)
-+{
-+ lcd_output_dev->request_state = status;
-+ lcd_video_output_set(lcd_output_dev);
-+}
-+
-+static int lynloong_vo_init(void)
-+{
-+ int ret;
-+
-+ /* Register video output device: lcd */
-+ lcd_output_dev = video_output_register("LCD", NULL, NULL,
-+ &lcd_output_properties);
-+
-+ if (IS_ERR(lcd_output_dev)) {
-+ ret = PTR_ERR(lcd_output_dev);
-+ lcd_output_dev = NULL;
-+ return ret;
-+ }
-+ /* Ensure LCD is on by default */
-+ lynloong_lcd_vo_set(1);
-+
-+ return 0;
-+}
-+
-+static void lynloong_vo_exit(void)
-+{
-+ if (lcd_output_dev) {
-+ video_output_unregister(lcd_output_dev);
-+ lcd_output_dev = NULL;
-+ }
-+}
-+
-+/* suspend support */
-+
-+#ifdef CONFIG_PM
-+
-+static u32 smb_base;
-+
-+/* I2C operations */
-+
-+static int i2c_wait(void)
-+{
-+ char c;
-+ int i;
-+
-+ udelay(1000);
-+ for (i = 0; i < 20; i++) {
-+ c = inb(smb_base | SMB_STS);
-+ if (c & (SMB_STS_BER | SMB_STS_NEGACK))
-+ return -1;
-+ if (c & SMB_STS_SDAST)
-+ return 0;
-+ udelay(100);
-+ }
-+ return -2;
-+}
-+
-+static void i2c_read_single(int addr, int regNo, char *value)
-+{
-+ unsigned char c;
-+
-+ /* Start condition */
-+ c = inb(smb_base | SMB_CTRL1);
-+ outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
-+ i2c_wait();
-+
-+ /* Send slave address */
-+ outb(addr & 0xfe, smb_base | SMB_SDA);
-+ i2c_wait();
-+
-+ /* Acknowledge smbus */
-+ c = inb(smb_base | SMB_CTRL1);
-+ outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
-+
-+ /* Send register index */
-+ outb(regNo, smb_base | SMB_SDA);
-+ i2c_wait();
-+
-+ /* Acknowledge smbus */
-+ c = inb(smb_base | SMB_CTRL1);
-+ outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
-+
-+ /* Start condition again */
-+ c = inb(smb_base | SMB_CTRL1);
-+ outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
-+ i2c_wait();
-+
-+ /* Send salve address again */
-+ outb(1 | addr, smb_base | SMB_SDA);
-+ i2c_wait();
-+
-+ /* Acknowledge smbus */
-+ c = inb(smb_base | SMB_CTRL1);
-+ outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
-+
-+ /* Read data */
-+ *value = inb(smb_base | SMB_SDA);
-+
-+ /* Stop condition */
-+ outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
-+ i2c_wait();
-+}
-+
-+static void i2c_write_single(int addr, int regNo, char value)
-+{
-+ unsigned char c;
-+
-+ /* Start condition */
-+ c = inb(smb_base | SMB_CTRL1);
-+ outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
-+ i2c_wait();
-+ /* Send slave address */
-+ outb(addr & 0xfe, smb_base | SMB_SDA);
-+ i2c_wait();;
-+
-+ /* Send register index */
-+ outb(regNo, smb_base | SMB_SDA);
-+ i2c_wait();
-+
-+ /* Write data */
-+ outb(value, smb_base | SMB_SDA);
-+ i2c_wait();
-+ /* Stop condition */
-+ outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
-+ i2c_wait();
-+}
-+
-+static void stop_clock(int clk_reg, int clk_sel)
-+{
-+ u8 value;
-+
-+ i2c_read_single(0xd3, clk_reg, &value);
-+ value &= ~(1 << clk_sel);
-+ i2c_write_single(0xd2, clk_reg, value);
-+}
-+
-+static void enable_clock(int clk_reg, int clk_sel)
-+{
-+ u8 value;
-+
-+ i2c_read_single(0xd3, clk_reg, &value);
-+ value |= (1 << clk_sel);
-+ i2c_write_single(0xd2, clk_reg, value);
-+}
-+
-+static char cached_clk_freq;
-+static char cached_pci_fixed_freq;
-+
-+static void decrease_clk_freq(void)
-+{
-+ char value;
-+
-+ i2c_read_single(0xd3, 1, &value);
-+ cached_clk_freq = value;
-+
-+ /* Select frequency by software */
-+ value |= (1 << 1);
-+ /* CPU, 3V66, PCI : 100, 66, 33(1) */
-+ value |= (1 << 2);
-+ i2c_write_single(0xd2, 1, value);
-+
-+ /* Cache the pci frequency */
-+ i2c_read_single(0xd3, 14, &value);
-+ cached_pci_fixed_freq = value;
-+
-+ /* Enable PCI fix mode */
-+ value |= (1 << 5);
-+ /* 3V66, PCI : 64MHz, 32MHz */
-+ value |= (1 << 3);
-+ i2c_write_single(0xd2, 14, value);
-+
-+}
-+
-+static void resume_clk_freq(void)
-+{
-+ i2c_write_single(0xd2, 1, cached_clk_freq);
-+ i2c_write_single(0xd2, 14, cached_pci_fixed_freq);
-+}
-+
-+static void stop_clocks(void)
-+{
-+ /* CPU Clock Register */
-+ stop_clock(2, 5); /* not used */
-+ stop_clock(2, 6); /* not used */
-+ stop_clock(2, 7); /* not used */
-+
-+ /* PCI Clock Register */
-+ stop_clock(3, 1); /* 8100 */
-+ stop_clock(3, 5); /* SIS */
-+ stop_clock(3, 0); /* not used */
-+ stop_clock(3, 6); /* not used */
-+
-+ /* PCI 48M Clock Register */
-+ stop_clock(4, 6); /* USB grounding */
-+ stop_clock(4, 5); /* REF(5536_14M) */
-+
-+ /* 3V66 Control Register */
-+ stop_clock(5, 0); /* VCH_CLK..., grounding */
-+}
-+
-+static void enable_clocks(void)
-+{
-+ enable_clock(3, 1); /* 8100 */
-+ enable_clock(3, 5); /* SIS */
-+
-+ enable_clock(4, 6);
-+ enable_clock(4, 5); /* REF(5536_14M) */
-+
-+ enable_clock(5, 0); /* VCH_CLOCK, grounding */
-+}
-+
-+static int lynloong_suspend(struct device *dev)
-+{
-+ /* Disable AMP */
-+ set_gpio_output_high(6);
-+ /* Turn off LCD */
-+ lynloong_lcd_vo_set(0);
-+
-+ /* Stop the clocks of some devices */
-+ stop_clocks();
-+
-+ /* Decrease the external clock frequency */
-+ decrease_clk_freq();
-+
-+ return 0;
-+}
-+
-+static int lynloong_resume(struct device *dev)
-+{
-+ /* Turn on the LCD */
-+ lynloong_lcd_vo_set(1);
-+
-+ /* Resume clock frequency, enable the relative clocks */
-+ resume_clk_freq();
-+ enable_clocks();
-+
-+ /* Enable AMP */
-+ set_gpio_output_low(6);
-+
-+ return 0;
-+}
-+
-+static const SIMPLE_DEV_PM_OPS(lynloong_pm_ops, lynloong_suspend,
-+ lynloong_resume);
-+#endif /* !CONFIG_PM */
-+
-+static struct platform_device_id platform_device_ids[] = {
-+ {
-+ .name = "lynloong_pc",
-+ },
-+ {}
-+};
-+
-+MODULE_DEVICE_TABLE(platform, platform_device_ids);
-+
-+static struct platform_driver platform_driver = {
-+ .driver = {
-+ .name = "lynloong_pc",
-+ .owner = THIS_MODULE,
-+#ifdef CONFIG_PM
-+ .pm = &lynloong_pm_ops,
-+#endif
-+ },
-+ .id_table = platform_device_ids,
-+};
-+
-+static int __init lynloong_init(void)
-+{
-+ int ret;
-+
-+ pr_info("Load LynLoong Platform Specific Driver.\n");
-+
-+ /* Register platform stuff */
-+ ret = platform_driver_register(&platform_driver);
-+ if (ret) {
-+ pr_err("Fail to register lynloong platform driver.\n");
-+ return ret;
-+ }
-+
-+ ret = lynloong_backlight_init();
-+ if (ret) {
-+ pr_err("Fail to register lynloong backlight driver.\n");
-+ return ret;
-+ }
-+
-+ ret = lynloong_vo_init();
-+ if (ret) {
-+ pr_err("Fail to register lynloong backlight driver.\n");
-+ lynloong_vo_exit();
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit lynloong_exit(void)
-+{
-+ lynloong_vo_exit();
-+ lynloong_backlight_exit();
-+ platform_driver_unregister(&platform_driver);
-+
-+ pr_info("Unload LynLoong Platform Specific Driver.\n");
-+}
-+
-+module_init(lynloong_init);
-+module_exit(lynloong_exit);
-+
-+MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Xiang Yu <xiangy@lemote.com>");
-+MODULE_DESCRIPTION("LynLoong PC driver");
-+MODULE_LICENSE("GPL");
-diff -Nur linux-2.6.37.orig/drivers/platform/mips/yeeloong_ecrom.c linux-2.6.37/drivers/platform/mips/yeeloong_ecrom.c
---- linux-2.6.37.orig/drivers/platform/mips/yeeloong_ecrom.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/drivers/platform/mips/yeeloong_ecrom.c 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,943 @@
-+/*
-+ * Driver for flushing/dumping ROM of EC on YeeLoong laptop
-+ *
-+ * Copyright (C) 2009 Lemote Inc.
-+ * Author: liujl <liujl@lemote.com>
-+ *
-+ * NOTE :
-+ * The EC resources accessing and programming are supported.
-+ */
-+
-+#include <linux/proc_fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <ec_kb3310b.h>
-+
-+#define EC_MISC_DEV "ec_misc"
-+#define EC_IOC_MAGIC 'E'
-+
-+/* ec registers range */
-+#define EC_MAX_REGADDR 0xFFFF
-+#define EC_MIN_REGADDR 0xF000
-+#define EC_RAM_ADDR 0xF800
-+
-+/* version burned address */
-+#define VER_ADDR 0xf7a1
-+#define VER_MAX_SIZE 7
-+#define EC_ROM_MAX_SIZE 0x10000
-+
-+/* ec internal register */
-+#define REG_POWER_MODE 0xF710
-+#define FLAG_NORMAL_MODE 0x00
-+#define FLAG_IDLE_MODE 0x01
-+#define FLAG_RESET_MODE 0x02
-+
-+/* ec update program flag */
-+#define PROGRAM_FLAG_NONE 0x00
-+#define PROGRAM_FLAG_IE 0x01
-+#define PROGRAM_FLAG_ROM 0x02
-+
-+/* XBI relative registers */
-+#define REG_XBISEG0 0xFEA0
-+#define REG_XBISEG1 0xFEA1
-+#define REG_XBIRSV2 0xFEA2
-+#define REG_XBIRSV3 0xFEA3
-+#define REG_XBIRSV4 0xFEA4
-+#define REG_XBICFG 0xFEA5
-+#define REG_XBICS 0xFEA6
-+#define REG_XBIWE 0xFEA7
-+#define REG_XBISPIA0 0xFEA8
-+#define REG_XBISPIA1 0xFEA9
-+#define REG_XBISPIA2 0xFEAA
-+#define REG_XBISPIDAT 0xFEAB
-+#define REG_XBISPICMD 0xFEAC
-+#define REG_XBISPICFG 0xFEAD
-+#define REG_XBISPIDATR 0xFEAE
-+#define REG_XBISPICFG2 0xFEAF
-+
-+/* commands definition for REG_XBISPICMD */
-+#define SPICMD_WRITE_STATUS 0x01
-+#define SPICMD_BYTE_PROGRAM 0x02
-+#define SPICMD_READ_BYTE 0x03
-+#define SPICMD_WRITE_DISABLE 0x04
-+#define SPICMD_READ_STATUS 0x05
-+#define SPICMD_WRITE_ENABLE 0x06
-+#define SPICMD_HIGH_SPEED_READ 0x0B
-+#define SPICMD_POWER_DOWN 0xB9
-+#define SPICMD_SST_EWSR 0x50
-+#define SPICMD_SST_SEC_ERASE 0x20
-+#define SPICMD_SST_BLK_ERASE 0x52
-+#define SPICMD_SST_CHIP_ERASE 0x60
-+#define SPICMD_FRDO 0x3B
-+#define SPICMD_SEC_ERASE 0xD7
-+#define SPICMD_BLK_ERASE 0xD8
-+#define SPICMD_CHIP_ERASE 0xC7
-+
-+/* bits definition for REG_XBISPICFG */
-+#define SPICFG_AUTO_CHECK 0x01
-+#define SPICFG_SPI_BUSY 0x02
-+#define SPICFG_DUMMY_READ 0x04
-+#define SPICFG_EN_SPICMD 0x08
-+#define SPICFG_LOW_SPICS 0x10
-+#define SPICFG_EN_SHORT_READ 0x20
-+#define SPICFG_EN_OFFSET_READ 0x40
-+#define SPICFG_EN_FAST_READ 0x80
-+
-+/* watchdog timer registers */
-+#define REG_WDTCFG 0xfe80
-+#define REG_WDTPF 0xfe81
-+#define REG_WDT 0xfe82
-+
-+/* lpc configure register */
-+#define REG_LPCCFG 0xfe95
-+
-+/* 8051 reg */
-+#define REG_PXCFG 0xff14
-+
-+/* Fan register in KB3310 */
-+#define REG_ECFAN_SPEED_LEVEL 0xf4e4
-+#define REG_ECFAN_SWITCH 0xf4d2
-+
-+/* the ec flash rom id number */
-+#define EC_ROM_PRODUCT_ID_SPANSION 0x01
-+#define EC_ROM_PRODUCT_ID_MXIC 0xC2
-+#define EC_ROM_PRODUCT_ID_AMIC 0x37
-+#define EC_ROM_PRODUCT_ID_EONIC 0x1C
-+
-+/* misc ioctl operations */
-+#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int)
-+#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int)
-+#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int)
-+#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int)
-+#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int)
-+
-+/* start address for programming of EC content or IE */
-+/* ec running code start address */
-+#define EC_START_ADDR 0x00000000
-+/* ec information element storing address */
-+#define IE_START_ADDR 0x00020000
-+
-+/* EC state */
-+#define EC_STATE_IDLE 0x00 /* ec in idle state */
-+#define EC_STATE_BUSY 0x01 /* ec in busy state */
-+
-+/* timeout value for programming */
-+#define EC_FLASH_TIMEOUT 0x1000 /* ec program timeout */
-+/* command checkout timeout including cmd to port or state flag check */
-+#define EC_CMD_TIMEOUT 0x1000
-+#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) /* unit : us */
-+#define EC_MAX_DELAY_UNIT (10) /* every time for polling */
-+#define SPI_FINISH_WAIT_TIME 10
-+/* EC content max size */
-+#define EC_CONTENT_MAX_SIZE (64 * 1024)
-+#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR)
-+
-+/* the register operation access struct */
-+struct ec_reg {
-+ u32 addr; /* the address of kb3310 registers */
-+ u8 val; /* the register value */
-+};
-+
-+struct ec_info {
-+ u32 start_addr;
-+ u32 size;
-+ u8 *buf;
-+};
-+
-+/* open for using rom protection action */
-+#define EC_ROM_PROTECTION
-+
-+/* enable the chip reset mode */
-+static int ec_init_reset_mode(void)
-+{
-+ int timeout;
-+ unsigned char status = 0;
-+ int ret = 0;
-+
-+ /* make chip goto reset mode */
-+ ret = ec_query_seq(CMD_INIT_RESET_MODE);
-+ if (ret < 0) {
-+ printk(KERN_ERR "ec init reset mode failed.\n");
-+ goto out;
-+ }
-+
-+ /* make the action take active */
-+ timeout = EC_CMD_TIMEOUT;
-+ status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
-+ while (timeout--) {
-+ if (status) {
-+ udelay(EC_REG_DELAY);
-+ break;
-+ }
-+ status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
-+ udelay(EC_REG_DELAY);
-+ }
-+ if (timeout <= 0) {
-+ printk(KERN_ERR "ec rom fixup : can't check reset status.\n");
-+ ret = -EINVAL;
-+ } else
-+ printk(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout,
-+ EC_CMD_TIMEOUT - timeout, status);
-+
-+ /* set MCU to reset mode */
-+ udelay(EC_REG_DELAY);
-+ status = ec_read(REG_PXCFG);
-+ status |= (1 << 0);
-+ ec_write(REG_PXCFG, status);
-+ udelay(EC_REG_DELAY);
-+
-+ /* disable FWH/LPC */
-+ udelay(EC_REG_DELAY);
-+ status = ec_read(REG_LPCCFG);
-+ status &= ~(1 << 7);
-+ ec_write(REG_LPCCFG, status);
-+ udelay(EC_REG_DELAY);
-+
-+ printk(KERN_INFO "entering reset mode ok..............\n");
-+
-+ out:
-+ return ret;
-+}
-+
-+/* make ec exit from reset mode */
-+static void ec_exit_reset_mode(void)
-+{
-+ unsigned char regval;
-+
-+ udelay(EC_REG_DELAY);
-+ regval = ec_read(REG_LPCCFG);
-+ regval |= (1 << 7);
-+ ec_write(REG_LPCCFG, regval);
-+ regval = ec_read(REG_PXCFG);
-+ regval &= ~(1 << 0);
-+ ec_write(REG_PXCFG, regval);
-+ printk(KERN_INFO "exit reset mode ok..................\n");
-+
-+ return;
-+}
-+
-+/* make ec disable WDD */
-+static void ec_disable_WDD(void)
-+{
-+ unsigned char status;
-+
-+ udelay(EC_REG_DELAY);
-+ status = ec_read(REG_WDTCFG);
-+ ec_write(REG_WDTPF, 0x03);
-+ ec_write(REG_WDTCFG, (status & 0x80) | 0x48);
-+ printk(KERN_INFO "Disable WDD ok..................\n");
-+
-+ return;
-+}
-+
-+/* make ec enable WDD */
-+static void ec_enable_WDD(void)
-+{
-+ unsigned char status;
-+
-+ udelay(EC_REG_DELAY);
-+ status = ec_read(REG_WDTCFG);
-+ ec_write(REG_WDT, 0x28); /* set WDT 5sec(0x28) */
-+ ec_write(REG_WDTCFG, (status & 0x80) | 0x03);
-+ printk(KERN_INFO "Enable WDD ok..................\n");
-+
-+ return;
-+}
-+
-+/* make ec goto idle mode */
-+static int ec_init_idle_mode(void)
-+{
-+ int timeout;
-+ unsigned char status = 0;
-+ int ret = 0;
-+
-+ ec_query_seq(CMD_INIT_IDLE_MODE);
-+
-+ /* make the action take active */
-+ timeout = EC_CMD_TIMEOUT;
-+ status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
-+ while (timeout--) {
-+ if (status) {
-+ udelay(EC_REG_DELAY);
-+ break;
-+ }
-+ status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
-+ udelay(EC_REG_DELAY);
-+ }
-+ if (timeout <= 0) {
-+ printk(KERN_ERR "ec rom fixup : can't check out the status.\n");
-+ ret = -EINVAL;
-+ } else
-+ printk(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout,
-+ EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE));
-+
-+ printk(KERN_INFO "entering idle mode ok...................\n");
-+
-+ return ret;
-+}
-+
-+/* make ec exit from idle mode */
-+static int ec_exit_idle_mode(void)
-+{
-+
-+ ec_query_seq(CMD_EXIT_IDLE_MODE);
-+
-+ printk(KERN_INFO "exit idle mode ok...................\n");
-+
-+ return 0;
-+}
-+
-+static int ec_instruction_cycle(void)
-+{
-+ unsigned long timeout;
-+ int ret = 0;
-+
-+ timeout = EC_FLASH_TIMEOUT;
-+ while (timeout-- >= 0) {
-+ if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY))
-+ break;
-+ }
-+ if (timeout <= 0) {
-+ printk(KERN_ERR
-+ "EC_INSTRUCTION_CYCLE : timeout for check flag.\n");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ out:
-+ return ret;
-+}
-+
-+/* To see if the ec is in busy state or not. */
-+static inline int ec_flash_busy(unsigned long timeout)
-+{
-+ /* assurance the first command be going to rom */
-+ if (ec_instruction_cycle() < 0)
-+ return EC_STATE_BUSY;
-+#if 1
-+ timeout = timeout / EC_MAX_DELAY_UNIT;
-+ while (timeout-- > 0) {
-+ /* check the rom's status of busy flag */
-+ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
-+ if (ec_instruction_cycle() < 0)
-+ return EC_STATE_BUSY;
-+ if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
-+ return EC_STATE_IDLE;
-+ udelay(EC_MAX_DELAY_UNIT);
-+ }
-+ if (timeout <= 0) {
-+ printk(KERN_ERR
-+ "EC_FLASH_BUSY : timeout for check rom flag.\n");
-+ return EC_STATE_BUSY;
-+ }
-+#else
-+ /* check the rom's status of busy flag */
-+ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
-+ if (ec_instruction_cycle() < 0)
-+ return EC_STATE_BUSY;
-+
-+ timeout = timeout / EC_MAX_DELAY_UNIT;
-+ while (timeout-- > 0) {
-+ if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
-+ return EC_STATE_IDLE;
-+ udelay(EC_MAX_DELAY_UNIT);
-+ }
-+ if (timeout <= 0) {
-+ printk(KERN_ERR
-+ "EC_FLASH_BUSY : timeout for check rom flag.\n");
-+ return EC_STATE_BUSY;
-+ }
-+#endif
-+
-+ return EC_STATE_IDLE;
-+}
-+
-+static int rom_instruction_cycle(unsigned char cmd)
-+{
-+ unsigned long timeout = 0;
-+
-+ switch (cmd) {
-+ case SPICMD_READ_STATUS:
-+ case SPICMD_WRITE_ENABLE:
-+ case SPICMD_WRITE_DISABLE:
-+ case SPICMD_READ_BYTE:
-+ case SPICMD_HIGH_SPEED_READ:
-+ timeout = 0;
-+ break;
-+ case SPICMD_WRITE_STATUS:
-+ timeout = 300 * 1000;
-+ break;
-+ case SPICMD_BYTE_PROGRAM:
-+ timeout = 5 * 1000;
-+ break;
-+ case SPICMD_SST_SEC_ERASE:
-+ case SPICMD_SEC_ERASE:
-+ timeout = 1000 * 1000;
-+ break;
-+ case SPICMD_SST_BLK_ERASE:
-+ case SPICMD_BLK_ERASE:
-+ timeout = 3 * 1000 * 1000;
-+ break;
-+ case SPICMD_SST_CHIP_ERASE:
-+ case SPICMD_CHIP_ERASE:
-+ timeout = 20 * 1000 * 1000;
-+ break;
-+ default:
-+ timeout = EC_SPICMD_STANDARD_TIMEOUT;
-+ }
-+ if (timeout == 0)
-+ return ec_instruction_cycle();
-+ if (timeout < EC_SPICMD_STANDARD_TIMEOUT)
-+ timeout = EC_SPICMD_STANDARD_TIMEOUT;
-+
-+ return ec_flash_busy(timeout);
-+}
-+
-+/* delay for start/stop action */
-+static void delay_spi(int n)
-+{
-+ while (n--)
-+ inb(EC_IO_PORT_HIGH);
-+}
-+
-+/* start the action to spi rom function */
-+static void ec_start_spi(void)
-+{
-+ unsigned char val;
-+
-+ delay_spi(SPI_FINISH_WAIT_TIME);
-+ val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK;
-+ ec_write(REG_XBISPICFG, val);
-+ delay_spi(SPI_FINISH_WAIT_TIME);
-+}
-+
-+/* stop the action to spi rom function */
-+static void ec_stop_spi(void)
-+{
-+ unsigned char val;
-+
-+ delay_spi(SPI_FINISH_WAIT_TIME);
-+ val =
-+ ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK));
-+ ec_write(REG_XBISPICFG, val);
-+ delay_spi(SPI_FINISH_WAIT_TIME);
-+}
-+
-+/* read one byte from xbi interface */
-+static int ec_read_byte(unsigned int addr, unsigned char *byte)
-+{
-+ int ret = 0;
-+
-+ /* enable spicmd writing. */
-+ ec_start_spi();
-+
-+ /* enable write spi flash */
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
-+ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
-+ printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ /* write the address */
-+ ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
-+ ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
-+ ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
-+ /* start action */
-+ ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ);
-+ if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ *byte = ec_read(REG_XBISPIDAT);
-+
-+ out:
-+ /* disable spicmd writing. */
-+ ec_stop_spi();
-+
-+ return ret;
-+}
-+
-+/* write one byte to ec rom */
-+static int ec_write_byte(unsigned int addr, unsigned char byte)
-+{
-+ int ret = 0;
-+
-+ /* enable spicmd writing. */
-+ ec_start_spi();
-+
-+ /* enable write spi flash */
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
-+ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ /* write the address */
-+ ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
-+ ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
-+ ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
-+ ec_write(REG_XBISPIDAT, byte);
-+ /* start action */
-+ ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM);
-+ if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ out:
-+ /* disable spicmd writing. */
-+ ec_stop_spi();
-+
-+ return ret;
-+}
-+
-+/* unprotect SPI ROM */
-+/* EC_ROM_unprotect function code */
-+static int EC_ROM_unprotect(void)
-+{
-+ unsigned char status;
-+
-+ /* enable write spi flash */
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
-+ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
-+ return 1;
-+ }
-+
-+ /* unprotect the status register of rom */
-+ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
-+ if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
-+ printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n");
-+ return 1;
-+ }
-+ status = ec_read(REG_XBISPIDAT);
-+ ec_write(REG_XBISPIDAT, status & 0x02);
-+ if (ec_instruction_cycle() < 0) {
-+ printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n");
-+ return 1;
-+ }
-+
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
-+ if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n");
-+ return 1;
-+ }
-+
-+ /* enable write spi flash */
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
-+ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/* erase one block or chip or sector as needed */
-+static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr)
-+{
-+ unsigned char status;
-+ int ret = 0, i = 0;
-+ int unprotect_count = 3;
-+ int check_flag = 0;
-+
-+ /* enable spicmd writing. */
-+ ec_start_spi();
-+
-+#ifdef EC_ROM_PROTECTION
-+ /* added for re-check SPICMD_READ_STATUS */
-+ while (unprotect_count-- > 0) {
-+ if (EC_ROM_unprotect()) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ /* first time:500ms --> 5.5sec -->10.5sec */
-+ for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++)
-+ udelay(50000);
-+ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
-+ if (rom_instruction_cycle(SPICMD_READ_STATUS)
-+ == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
-+ } else {
-+ status = ec_read(REG_XBISPIDAT);
-+ printk(KERN_INFO "Read unprotect status : 0x%x\n",
-+ status);
-+ if ((status & 0x1C) == 0x00) {
-+ printk(KERN_INFO
-+ "Read unprotect status OK1 : 0x%x\n",
-+ status & 0x1C);
-+ check_flag = 1;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (!check_flag) {
-+ printk(KERN_INFO "SPI ROM unprotect fail.\n");
-+ return 1;
-+ }
-+#endif
-+
-+ /* block address fill */
-+ if (erase_cmd == SPICMD_BLK_ERASE) {
-+ ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16);
-+ ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8);
-+ ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0);
-+ }
-+
-+ /* erase the whole chip first */
-+ ec_write(REG_XBISPICMD, erase_cmd);
-+ if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) {
-+ printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ out:
-+ /* disable spicmd writing. */
-+ ec_stop_spi();
-+
-+ return ret;
-+}
-+
-+/* update the whole rom content with H/W mode
-+ * PLEASE USING ec_unit_erase() FIRSTLY
-+ */
-+static int ec_program_rom(struct ec_info *info, int flag)
-+{
-+ unsigned int addr = 0;
-+ unsigned long size = 0;
-+ unsigned char *ptr = NULL;
-+ unsigned char data;
-+ unsigned char val = 0;
-+ int ret = 0;
-+ int i, j;
-+ unsigned char status;
-+
-+ /* modify for program serial No.
-+ * set IE_START_ADDR & use idle mode,
-+ * disable WDD
-+ */
-+ if (flag == PROGRAM_FLAG_ROM) {
-+ ret = ec_init_reset_mode();
-+ addr = info->start_addr + EC_START_ADDR;
-+ printk(KERN_INFO "PROGRAM_FLAG_ROM..............\n");
-+ } else if (flag == PROGRAM_FLAG_IE) {
-+ ret = ec_init_idle_mode();
-+ ec_disable_WDD();
-+ addr = info->start_addr + IE_START_ADDR;
-+ printk(KERN_INFO "PROGRAM_FLAG_IE..............\n");
-+ } else {
-+ return 0;
-+ }
-+
-+ if (ret < 0) {
-+ if (flag == PROGRAM_FLAG_IE)
-+ ec_enable_WDD();
-+ return ret;
-+ }
-+
-+ size = info->size;
-+ ptr = info->buf;
-+ printk(KERN_INFO "starting update ec ROM..............\n");
-+
-+ ret = ec_unit_erase(SPICMD_BLK_ERASE, addr);
-+ if (ret) {
-+ printk(KERN_ERR "program ec : erase block failed.\n");
-+ goto out;
-+ }
-+ printk(KERN_ERR "program ec : erase block OK.\n");
-+
-+ i = 0;
-+ while (i < size) {
-+ data = *(ptr + i);
-+ ec_write_byte(addr, data);
-+ ec_read_byte(addr, &val);
-+ if (val != data) {
-+ ec_write_byte(addr, data);
-+ ec_read_byte(addr, &val);
-+ if (val != data) {
-+ printk(KERN_INFO
-+ "EC : Second flash program failed at:\t");
-+ printk(KERN_INFO
-+ "addr : 0x%x, source : 0x%x, dest: 0x%x\n",
-+ addr, data, val);
-+ printk(KERN_INFO "This should not happen... STOP\n");
-+ break;
-+ }
-+ }
-+ i++;
-+ addr++;
-+ }
-+
-+#ifdef EC_ROM_PROTECTION
-+ /* we should start spi access firstly */
-+ ec_start_spi();
-+
-+ /* enable write spi flash */
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
-+ if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n");
-+ goto out1;
-+ }
-+
-+ /* protect the status register of rom */
-+ ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
-+ if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
-+ goto out1;
-+ }
-+ status = ec_read(REG_XBISPIDAT);
-+
-+ ec_write(REG_XBISPIDAT, status | 0x1C);
-+ if (ec_instruction_cycle() < 0) {
-+ printk(KERN_ERR
-+ "EC_PROGRAM_ROM : write status value failed.\n");
-+ goto out1;
-+ }
-+
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
-+ if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n");
-+ goto out1;
-+ }
-+#endif
-+
-+ /* disable the write action to spi rom */
-+ ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE);
-+ if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) {
-+ printk(KERN_ERR
-+ "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n");
-+ goto out1;
-+ }
-+
-+ out1:
-+ /* we should stop spi access firstly */
-+ ec_stop_spi();
-+ out:
-+ /* for security */
-+ for (j = 0; j < 2000; j++)
-+ udelay(1000);
-+
-+ /* modify for program serial No.
-+ * after program No exit idle mode
-+ * and enable WDD
-+ */
-+ if (flag == PROGRAM_FLAG_ROM) {
-+ /* exit from the reset mode */
-+ ec_exit_reset_mode();
-+ } else {
-+ /* ec exit from idle mode */
-+ ret = ec_exit_idle_mode();
-+ ec_enable_WDD();
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* ioctl */
-+static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd,
-+ u_long arg)
-+{
-+ struct ec_info ecinfo;
-+ void __user *ptr = (void __user *)arg;
-+ struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
-+ int ret = 0;
-+
-+ switch (cmd) {
-+ case IOCTL_RDREG:
-+ ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
-+ if (ret) {
-+ printk(KERN_ERR "reg read : copy from user error.\n");
-+ return -EFAULT;
-+ }
-+ if ((ecreg->addr > EC_MAX_REGADDR)
-+ || (ecreg->addr < EC_MIN_REGADDR)) {
-+ printk(KERN_ERR
-+ "reg read : out of register address range.\n");
-+ return -EINVAL;
-+ }
-+ ecreg->val = ec_read(ecreg->addr);
-+ ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
-+ if (ret) {
-+ printk(KERN_ERR "reg read : copy to user error.\n");
-+ return -EFAULT;
-+ }
-+ break;
-+ case IOCTL_WRREG:
-+ ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
-+ if (ret) {
-+ printk(KERN_ERR "reg write : copy from user error.\n");
-+ return -EFAULT;
-+ }
-+ if ((ecreg->addr > EC_MAX_REGADDR)
-+ || (ecreg->addr < EC_MIN_REGADDR)) {
-+ printk(KERN_ERR
-+ "reg write : out of register address range.\n");
-+ return -EINVAL;
-+ }
-+ ec_write(ecreg->addr, ecreg->val);
-+ break;
-+ case IOCTL_READ_EC:
-+ ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
-+ if (ret) {
-+ printk(KERN_ERR "spi read : copy from user error.\n");
-+ return -EFAULT;
-+ }
-+ if ((ecreg->addr > EC_RAM_ADDR)
-+ && (ecreg->addr < EC_MAX_REGADDR)) {
-+ printk(KERN_ERR
-+ "spi read : out of register address range.\n");
-+ return -EINVAL;
-+ }
-+ ec_read_byte(ecreg->addr, &(ecreg->val));
-+ ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
-+ if (ret) {
-+ printk(KERN_ERR "spi read : copy to user error.\n");
-+ return -EFAULT;
-+ }
-+ break;
-+ case IOCTL_PROGRAM_IE:
-+ ecinfo.start_addr = EC_START_ADDR;
-+ ecinfo.size = EC_CONTENT_MAX_SIZE;
-+ ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
-+ if (ecinfo.buf == NULL) {
-+ printk(KERN_ERR "program ie : kmalloc failed.\n");
-+ return -ENOMEM;
-+ }
-+ ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size);
-+ if (ret) {
-+ printk(KERN_ERR "program ie : copy from user error.\n");
-+ kfree(ecinfo.buf);
-+ ecinfo.buf = NULL;
-+ return -EFAULT;
-+ }
-+
-+ /* use ec_program_rom to write serial No */
-+ ec_program_rom(&ecinfo, PROGRAM_FLAG_IE);
-+
-+ kfree(ecinfo.buf);
-+ ecinfo.buf = NULL;
-+ break;
-+ case IOCTL_PROGRAM_EC:
-+ ecinfo.start_addr = EC_START_ADDR;
-+ if (get_user((ecinfo.size), (u32 *) ptr)) {
-+ printk(KERN_ERR "program ec : get user error.\n");
-+ return -EFAULT;
-+ }
-+ if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) {
-+ printk(KERN_ERR "program ec : size out of limited.\n");
-+ return -EINVAL;
-+ }
-+ ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
-+ if (ecinfo.buf == NULL) {
-+ printk(KERN_ERR "program ec : kmalloc failed.\n");
-+ return -ENOMEM;
-+ }
-+ ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size);
-+ if (ret) {
-+ printk(KERN_ERR "program ec : copy from user error.\n");
-+ kfree(ecinfo.buf);
-+ ecinfo.buf = NULL;
-+ return -EFAULT;
-+ }
-+
-+ ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM);
-+
-+ kfree(ecinfo.buf);
-+ ecinfo.buf = NULL;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+static long misc_compat_ioctl(struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
-+}
-+
-+static int misc_open(struct inode *inode, struct file *filp)
-+{
-+ struct ec_reg *ecreg = NULL;
-+ ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL);
-+ if (ecreg)
-+ filp->private_data = ecreg;
-+
-+ return ecreg ? 0 : -ENOMEM;
-+}
-+
-+static int misc_release(struct inode *inode, struct file *filp)
-+{
-+ struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
-+
-+ filp->private_data = NULL;
-+ kfree(ecreg);
-+
-+ return 0;
-+}
-+
-+static const struct file_operations ecmisc_fops = {
-+ .open = misc_open,
-+ .release = misc_release,
-+ .read = NULL,
-+ .write = NULL,
-+#ifdef CONFIG_64BIT
-+ .compat_ioctl = misc_compat_ioctl,
-+#else
-+ .ioctl = misc_ioctl,
-+#endif
-+};
-+
-+static struct miscdevice ecmisc_device = {
-+ .minor = MISC_DYNAMIC_MINOR,
-+ .name = EC_MISC_DEV,
-+ .fops = &ecmisc_fops
-+};
-+
-+static int __init ecmisc_init(void)
-+{
-+ int ret;
-+
-+ printk(KERN_INFO "EC misc device init.\n");
-+ ret = misc_register(&ecmisc_device);
-+
-+ return ret;
-+}
-+
-+static void __exit ecmisc_exit(void)
-+{
-+ printk(KERN_INFO "EC misc device exit.\n");
-+ misc_deregister(&ecmisc_device);
-+}
-+
-+module_init(ecmisc_init);
-+module_exit(ecmisc_exit);
-+
-+MODULE_AUTHOR("liujl <liujl@lemote.com>");
-+MODULE_DESCRIPTION("Driver for flushing/dumping ROM of EC on YeeLoong laptop");
-+MODULE_LICENSE("GPL");
-diff -Nur linux-2.6.37.orig/drivers/platform/mips/yeeloong_laptop.c linux-2.6.37/drivers/platform/mips/yeeloong_laptop.c
---- linux-2.6.37.orig/drivers/platform/mips/yeeloong_laptop.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.37/drivers/platform/mips/yeeloong_laptop.c 2011-01-11 20:44:43.000000000 +0100
-@@ -0,0 +1,1200 @@
-+/*
-+ * Driver for YeeLoong laptop extras
-+ *
-+ * Copyright (C) 2009 Lemote Inc.
-+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Liu Junliang <liujl@lemote.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/platform_device.h>
-+#include <linux/backlight.h> /* for backlight subdriver */
-+#include <linux/fb.h>
-+#include <linux/hwmon.h> /* for hwmon subdriver */
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/video_output.h> /* for video output subdriver */
-+#include <linux/input.h> /* for hotkey subdriver */
-+#include <linux/input/sparse-keymap.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/power_supply.h> /* for AC & Battery subdriver */
-+
-+#include <cs5536/cs5536.h>
-+
-+#include <loongson.h> /* for loongson_cmdline */
-+#include <ec_kb3310b.h>
-+
-+/* common function */
-+#define EC_VER_LEN 64
-+
-+static int ec_version_before(char *version)
-+{
-+ char *p, ec_ver[EC_VER_LEN];
-+
-+ p = strstr(loongson_cmdline, "EC_VER=");
-+ if (!p)
-+ memset(ec_ver, 0, EC_VER_LEN);
-+ else {
-+ strncpy(ec_ver, p, EC_VER_LEN);
-+ p = strstr(ec_ver, " ");
-+ if (p)
-+ *p = '\0';
-+ }
-+
-+ return (strncasecmp(ec_ver, version, 64) < 0);
-+}
-+
-+/* backlight subdriver */
-+#define MAX_BRIGHTNESS 8
-+
-+static int yeeloong_set_brightness(struct backlight_device *bd)
-+{
-+ unsigned int level, current_level;
-+ static unsigned int old_level;
-+
-+ level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
-+ bd->props.power == FB_BLANK_UNBLANK) ?
-+ bd->props.brightness : 0;
-+
-+ level = SENSORS_LIMIT(level, 0, MAX_BRIGHTNESS);
-+
-+ /* Avoid to modify the brightness when EC is tuning it */
-+ if (old_level != level) {
-+ current_level = ec_read(REG_DISPLAY_BRIGHTNESS);
-+ if (old_level == current_level)
-+ ec_write(REG_DISPLAY_BRIGHTNESS, level);
-+ old_level = level;
-+ }
-+
-+ return 0;
-+}
-+
-+static int yeeloong_get_brightness(struct backlight_device *bd)
-+{
-+ return ec_read(REG_DISPLAY_BRIGHTNESS);
-+}
-+
-+static struct backlight_ops backlight_ops = {
-+ .get_brightness = yeeloong_get_brightness,
-+ .update_status = yeeloong_set_brightness,
-+};
-+
-+static struct backlight_device *yeeloong_backlight_dev;
-+
-+static int yeeloong_backlight_init(void)
-+{
-+ int ret;
-+ struct backlight_properties props;
-+
-+ memset(&props, 0, sizeof(struct backlight_properties));
-+ props.max_brightness = MAX_BRIGHTNESS;
-+ yeeloong_backlight_dev = backlight_device_register("backlight0", NULL,
-+ NULL, &backlight_ops, &props);
-+
-+ if (IS_ERR(yeeloong_backlight_dev)) {
-+ ret = PTR_ERR(yeeloong_backlight_dev);
-+ yeeloong_backlight_dev = NULL;
-+ return ret;
-+ }
-+
-+ yeeloong_backlight_dev->props.brightness =
-+ yeeloong_get_brightness(yeeloong_backlight_dev);
-+ backlight_update_status(yeeloong_backlight_dev);
-+
-+ return 0;
-+}
-+
-+static void yeeloong_backlight_exit(void)
-+{
-+ if (yeeloong_backlight_dev) {
-+ backlight_device_unregister(yeeloong_backlight_dev);
-+ yeeloong_backlight_dev = NULL;
-+ }
-+}
-+
-+/* AC & Battery subdriver */
-+
-+static struct power_supply yeeloong_ac, yeeloong_bat;
-+
-+#define AC_OFFLINE 0
-+#define AC_ONLINE 1
-+
-+static int yeeloong_get_ac_props(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ union power_supply_propval *val)
-+{
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_ONLINE:
-+ val->intval = ((ec_read(REG_BAT_POWER)) & BIT_BAT_POWER_ACIN) ?
-+ AC_ONLINE : AC_OFFLINE;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static enum power_supply_property yeeloong_ac_props[] = {
-+ POWER_SUPPLY_PROP_ONLINE,
-+};
-+
-+static struct power_supply yeeloong_ac = {
-+ .name = "yeeloong-ac",
-+ .type = POWER_SUPPLY_TYPE_MAINS,
-+ .properties = yeeloong_ac_props,
-+ .num_properties = ARRAY_SIZE(yeeloong_ac_props),
-+ .get_property = yeeloong_get_ac_props,
-+};
-+
-+#define BAT_CAP_CRITICAL 5
-+#define BAT_CAP_HIGH 99
-+
-+#define get_bat_info(type) \
-+ ((ec_read(REG_BAT_##type##_HIGH) << 8) | \
-+ (ec_read(REG_BAT_##type##_LOW)))
-+
-+static int yeeloong_bat_get_ex_property(enum power_supply_property psp,
-+ union power_supply_propval *val)
-+{
-+ int bat_in, curr_cap, cap_level, status, charge, health;
-+
-+ status = ec_read(REG_BAT_STATUS);
-+ bat_in = status & BIT_BAT_STATUS_IN;
-+ curr_cap = get_bat_info(RELATIVE_CAP);
-+ if (status & BIT_BAT_STATUS_FULL)
-+ curr_cap = 100;
-+
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_PRESENT:
-+ val->intval = bat_in;
-+ break;
-+ case POWER_SUPPLY_PROP_CAPACITY:
-+ val->intval = curr_cap;
-+ break;
-+ case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
-+ cap_level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
-+ if (status & BIT_BAT_STATUS_LOW) {
-+ cap_level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
-+ if (curr_cap <= BAT_CAP_CRITICAL)
-+ cap_level =
-+ POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
-+ } else if (status & BIT_BAT_STATUS_FULL) {
-+ cap_level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
-+ if (curr_cap >= BAT_CAP_HIGH)
-+ cap_level = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
-+ } else if (status & BIT_BAT_STATUS_DESTROY)
-+ cap_level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
-+ val->intval = cap_level;
-+ break;
-+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
-+ /* seconds */
-+ val->intval = bat_in ? (curr_cap - 3) * 54 + 142 : 0;
-+ break;
-+ case POWER_SUPPLY_PROP_STATUS:
-+ if (!bat_in)
-+ charge = POWER_SUPPLY_STATUS_UNKNOWN;
-+ else {
-+ if (status & BIT_BAT_STATUS_FULL) {
-+ val->intval = POWER_SUPPLY_STATUS_FULL;
-+ break;
-+ }
-+
-+ charge = ec_read(REG_BAT_CHARGE);
-+ if (charge & FLAG_BAT_CHARGE_DISCHARGE)
-+ charge = POWER_SUPPLY_STATUS_DISCHARGING;
-+ else if (charge & FLAG_BAT_CHARGE_CHARGE)
-+ charge = POWER_SUPPLY_STATUS_CHARGING;
-+ else
-+ charge = POWER_SUPPLY_STATUS_NOT_CHARGING;
-+ }
-+ val->intval = charge;
-+ break;
-+ case POWER_SUPPLY_PROP_HEALTH:
-+ if (!bat_in) /* no battery present */
-+ health = POWER_SUPPLY_HEALTH_UNKNOWN;
-+ else { /* Assume it is good */
-+ health = POWER_SUPPLY_HEALTH_GOOD;
-+ if (status &
-+ (BIT_BAT_STATUS_DESTROY | BIT_BAT_STATUS_LOW))
-+ health = POWER_SUPPLY_HEALTH_DEAD;
-+ if (ec_read(REG_BAT_CHARGE_STATUS) &
-+ BIT_BAT_CHARGE_STATUS_OVERTEMP)
-+ health = POWER_SUPPLY_HEALTH_OVERHEAT;
-+ }
-+ val->intval = health;
-+ break;
-+ case POWER_SUPPLY_PROP_CHARGE_NOW: /* 1/100(%)*1000 µAh */
-+ val->intval = curr_cap * get_bat_info(FULLCHG_CAP) * 10;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+static int get_battery_temp(void)
-+{
-+ int value;
-+
-+ value = get_bat_info(TEMPERATURE);
-+
-+ return value * 1000;
-+}
-+
-+static int get_battery_current(void)
-+{
-+ s16 value;
-+
-+ value = get_bat_info(CURRENT);
-+
-+ return -value;
-+}
-+
-+static int get_battery_voltage(void)
-+{
-+ int value;
-+
-+ value = get_bat_info(VOLTAGE);
-+
-+ return value;
-+}
-+
-+static int yeeloong_get_bat_props(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ union power_supply_propval *val)
-+{
-+ switch (psp) {
-+ /* Fixed information */
-+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
-+ val->intval = get_bat_info(DESIGN_VOL) * 1000; /* mV -> µV */
-+ break;
-+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
-+ val->intval = get_bat_info(DESIGN_CAP) * 1000; /* mAh->µAh */
-+ break;
-+ case POWER_SUPPLY_PROP_CHARGE_FULL:
-+ val->intval = get_bat_info(FULLCHG_CAP) * 1000; /* µAh */
-+ break;
-+ case POWER_SUPPLY_PROP_MANUFACTURER:
-+ val->strval = (ec_read(REG_BAT_VENDOR) ==
-+ FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO";
-+ break;
-+ /* Dynamic information */
-+ case POWER_SUPPLY_PROP_CURRENT_NOW:
-+ val->intval = get_battery_current() * 1000; /* mA -> µA */
-+ break;
-+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-+ val->intval = get_battery_voltage() * 1000; /* mV -> µV */
-+ break;
-+ case POWER_SUPPLY_PROP_TEMP:
-+ val->intval = get_battery_temp(); /* Celcius */
-+ break;
-+ /* Dynamic but related information */
-+ default:
-+ return yeeloong_bat_get_ex_property(psp, val);
-+ }
-+
-+ return 0;
-+}
-+
-+static enum power_supply_property yeeloong_bat_props[] = {
-+ POWER_SUPPLY_PROP_STATUS,
-+ POWER_SUPPLY_PROP_PRESENT,
-+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
-+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
-+ POWER_SUPPLY_PROP_CHARGE_FULL,
-+ POWER_SUPPLY_PROP_CHARGE_NOW,
-+ POWER_SUPPLY_PROP_CURRENT_NOW,
-+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
-+ POWER_SUPPLY_PROP_HEALTH,
-+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
-+ POWER_SUPPLY_PROP_CAPACITY,
-+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
-+ POWER_SUPPLY_PROP_TEMP,
-+ POWER_SUPPLY_PROP_MANUFACTURER,
-+};
-+
-+static struct power_supply yeeloong_bat = {
-+ .name = "yeeloong-bat",
-+ .type = POWER_SUPPLY_TYPE_BATTERY,
-+ .properties = yeeloong_bat_props,
-+ .num_properties = ARRAY_SIZE(yeeloong_bat_props),
-+ .get_property = yeeloong_get_bat_props,
-+};
-+
-+static int ac_bat_initialized;
-+
-+static int yeeloong_bat_init(void)
-+{
-+ int ret;
-+
-+ ret = power_supply_register(NULL, &yeeloong_ac);
-+ if (ret)
-+ return ret;
-+ ret = power_supply_register(NULL, &yeeloong_bat);
-+ if (ret) {
-+ power_supply_unregister(&yeeloong_ac);
-+ return ret;
-+ }
-+ ac_bat_initialized = 1;
-+
-+ return 0;
-+}
-+
-+static void yeeloong_bat_exit(void)
-+{
-+ ac_bat_initialized = 0;
-+
-+ power_supply_unregister(&yeeloong_ac);
-+ power_supply_unregister(&yeeloong_bat);
-+}
-+/* hwmon subdriver */
-+
-+#define MIN_FAN_SPEED 0
-+#define MAX_FAN_SPEED 3
-+
-+static int get_fan_pwm_enable(void)
-+{
-+ int level, mode;
-+
-+ level = ec_read(REG_FAN_SPEED_LEVEL);
-+ mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
-+
-+ if (level == MAX_FAN_SPEED && mode == BIT_FAN_MANUAL)
-+ mode = 0;
-+ else if (mode == BIT_FAN_MANUAL)
-+ mode = 1;
-+ else
-+ mode = 2;
-+
-+ return mode;
-+}
-+
-+static void set_fan_pwm_enable(int mode)
-+{
-+ switch (mode) {
-+ case 0:
-+ /* fullspeed */
-+ ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
-+ ec_write(REG_FAN_SPEED_LEVEL, MAX_FAN_SPEED);
-+ break;
-+ case 1:
-+ ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
-+ break;
-+ case 2:
-+ ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_AUTO);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static int get_fan_pwm(void)
-+{
-+ return ec_read(REG_FAN_SPEED_LEVEL);
-+}
-+
-+static void set_fan_pwm(int value)
-+{
-+ int mode;
-+
-+ mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
-+ if (mode != BIT_FAN_MANUAL)
-+ return;
-+
-+ value = SENSORS_LIMIT(value, 0, 3);
-+
-+ /* We must ensure the fan is on */
-+ if (value > 0)
-+ ec_write(REG_FAN_CONTROL, BIT_FAN_CONTROL_ON);
-+
-+ ec_write(REG_FAN_SPEED_LEVEL, value);
-+}
-+
-+static int get_fan_rpm(void)
-+{
-+ int value;
-+
-+ value = FAN_SPEED_DIVIDER /
-+ (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) |
-+ ec_read(REG_FAN_SPEED_LOW));
-+
-+ return value;
-+}
-+
-+static int get_cpu_temp(void)
-+{
-+ s8 value;
-+
-+ value = ec_read(REG_TEMPERATURE_VALUE);
-+
-+ return value * 1000;
-+}
-+
-+static int get_cpu_temp_max(void)
-+{
-+ return 60 * 1000;
-+}
-+
-+static int get_battery_temp_alarm(void)
-+{
-+ int status;
-+
-+ status = (ec_read(REG_BAT_CHARGE_STATUS) &
-+ BIT_BAT_CHARGE_STATUS_OVERTEMP);
-+
-+ return !!status;
-+}
-+
-+static ssize_t store_sys_hwmon(void (*set) (int), const char *buf, size_t count)
-+{
-+ int ret;
-+ unsigned long value;
-+
-+ if (!count)
-+ return 0;
-+
-+ ret = strict_strtoul(buf, 10, &value);
-+ if (ret)
-+ return ret;
-+
-+ set(value);
-+
-+ return count;
-+}
-+
-+static ssize_t show_sys_hwmon(int (*get) (void), char *buf)
-+{
-+ return sprintf(buf, "%d\n", get());
-+}
-+
-+#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
-+ static ssize_t show_##_name(struct device *dev, \
-+ struct device_attribute *attr, \
-+ char *buf) \
-+ { \
-+ return show_sys_hwmon(_set, buf); \
-+ } \
-+ static ssize_t store_##_name(struct device *dev, \
-+ struct device_attribute *attr, \
-+ const char *buf, size_t count) \
-+ { \
-+ return store_sys_hwmon(_get, buf, count); \
-+ } \
-+ static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
-+
-+CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
-+CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, get_fan_pwm, set_fan_pwm);
-+CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, get_fan_pwm_enable,
-+ set_fan_pwm_enable);
-+CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL);
-+CREATE_SENSOR_ATTR(temp1_max, S_IRUGO, get_cpu_temp_max, NULL);
-+CREATE_SENSOR_ATTR(temp2_input, S_IRUGO, get_battery_temp, NULL);
-+CREATE_SENSOR_ATTR(temp2_max_alarm, S_IRUGO, get_battery_temp_alarm, NULL);
-+CREATE_SENSOR_ATTR(curr1_input, S_IRUGO, get_battery_current, NULL);
-+CREATE_SENSOR_ATTR(in1_input, S_IRUGO, get_battery_voltage, NULL);
-+
-+static ssize_t
-+show_name(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ return sprintf(buf, "yeeloong\n");
-+}
-+
-+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
-+
-+static struct attribute *hwmon_attributes[] = {
-+ &sensor_dev_attr_pwm1.dev_attr.attr,
-+ &sensor_dev_attr_pwm1_enable.dev_attr.attr,
-+ &sensor_dev_attr_fan1_input.dev_attr.attr,
-+ &sensor_dev_attr_temp1_input.dev_attr.attr,
-+ &sensor_dev_attr_temp1_max.dev_attr.attr,
-+ &sensor_dev_attr_temp2_input.dev_attr.attr,
-+ &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
-+ &sensor_dev_attr_curr1_input.dev_attr.attr,
-+ &sensor_dev_attr_in1_input.dev_attr.attr,
-+ &sensor_dev_attr_name.dev_attr.attr,
-+ NULL
-+};
-+
-+static struct attribute_group hwmon_attribute_group = {
-+ .attrs = hwmon_attributes
-+};
-+
-+static struct device *yeeloong_hwmon_dev;
-+
-+static int yeeloong_hwmon_init(void)
-+{
-+ int ret;
-+
-+ yeeloong_hwmon_dev = hwmon_device_register(NULL);
-+ if (IS_ERR(yeeloong_hwmon_dev)) {
-+ pr_err("Fail to register yeeloong hwmon device\n");
-+ yeeloong_hwmon_dev = NULL;
-+ return PTR_ERR(yeeloong_hwmon_dev);
-+ }
-+ ret = sysfs_create_group(&yeeloong_hwmon_dev->kobj,
-+ &hwmon_attribute_group);
-+ if (ret) {
-+ hwmon_device_unregister(yeeloong_hwmon_dev);
-+ yeeloong_hwmon_dev = NULL;
-+ return ret;
-+ }
-+ /* ensure fan is set to auto mode */
-+ set_fan_pwm_enable(2);
-+
-+ return 0;
-+}
-+
-+static void yeeloong_hwmon_exit(void)
-+{
-+ if (yeeloong_hwmon_dev) {
-+ sysfs_remove_group(&yeeloong_hwmon_dev->kobj,
-+ &hwmon_attribute_group);
-+ hwmon_device_unregister(yeeloong_hwmon_dev);
-+ yeeloong_hwmon_dev = NULL;
-+ }
-+}
-+
-+/* video output subdriver */
-+
-+static int lcd_video_output_get(struct output_device *od)
-+{
-+ return ec_read(REG_DISPLAY_LCD);
-+}
-+
-+#define LCD 0
-+#define CRT 1
-+
-+static void display_vo_set(int display, int on)
-+{
-+ int addr;
-+ unsigned long value;
-+
-+ addr = (display == LCD) ? 0x31 : 0x21;
-+
-+ outb(addr, 0x3c4);
-+ value = inb(0x3c5);
-+
-+ if (display == LCD)
-+ value |= (on ? 0x03 : 0x02);
-+ else {
-+ if (on)
-+ clear_bit(7, &value);
-+ else
-+ set_bit(7, &value);
-+ }
-+
-+ outb(addr, 0x3c4);
-+ outb(value, 0x3c5);
-+}
-+
-+static int lcd_video_output_set(struct output_device *od)
-+{
-+ unsigned long status;
-+
-+ status = !!od->request_state;
-+
-+ display_vo_set(LCD, status);
-+ ec_write(REG_BACKLIGHT_CTRL, status);
-+
-+ return 0;
-+}
-+
-+static struct output_properties lcd_output_properties = {
-+ .set_state = lcd_video_output_set,
-+ .get_status = lcd_video_output_get,
-+};
-+
-+static int crt_video_output_get(struct output_device *od)
-+{
-+ return ec_read(REG_CRT_DETECT);
-+}
-+
-+static int crt_video_output_set(struct output_device *od)
-+{
-+ unsigned long status;
-+
-+ status = !!od->request_state;
-+
-+ if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_PLUG)
-+ display_vo_set(CRT, status);
-+
-+ return 0;
-+}
-+
-+static struct output_properties crt_output_properties = {
-+ .set_state = crt_video_output_set,
-+ .get_status = crt_video_output_get,
-+};
-+
-+static struct output_device *lcd_output_dev, *crt_output_dev;
-+
-+static void yeeloong_lcd_vo_set(int status)
-+{
-+ lcd_output_dev->request_state = status;
-+ lcd_video_output_set(lcd_output_dev);
-+}
-+
-+static void yeeloong_crt_vo_set(int status)
-+{
-+ crt_output_dev->request_state = status;
-+ crt_video_output_set(crt_output_dev);
-+}
-+
-+static int yeeloong_vo_init(void)
-+{
-+ int ret;
-+
-+ /* Register video output device: lcd, crt */
-+ lcd_output_dev = video_output_register("LCD", NULL, NULL,
-+ &lcd_output_properties);
-+
-+ if (IS_ERR(lcd_output_dev)) {
-+ ret = PTR_ERR(lcd_output_dev);
-+ lcd_output_dev = NULL;
-+ return ret;
-+ }
-+ /* Ensure LCD is on by default */
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
-+
-+ crt_output_dev = video_output_register("CRT", NULL, NULL,
-+ &crt_output_properties);
-+
-+ if (IS_ERR(crt_output_dev)) {
-+ ret = PTR_ERR(crt_output_dev);
-+ crt_output_dev = NULL;
-+ return ret;
-+ }
-+
-+ /* Turn off CRT by default, and will be enabled when the CRT
-+ * connectting event reported by SCI */
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
-+
-+ return 0;
-+}
-+
-+static void yeeloong_vo_exit(void)
-+{
-+ if (lcd_output_dev) {
-+ video_output_unregister(lcd_output_dev);
-+ lcd_output_dev = NULL;
-+ }
-+ if (crt_output_dev) {
-+ video_output_unregister(crt_output_dev);
-+ crt_output_dev = NULL;
-+ }
-+}
-+
-+/* hotkey subdriver */
-+
-+static struct input_dev *yeeloong_hotkey_dev;
-+
-+static const struct key_entry yeeloong_keymap[] = {
-+ {KE_SW, EVENT_LID, { SW_LID } },
-+ {KE_KEY, EVENT_CAMERA, { KEY_CAMERA } }, /* Fn + ESC */
-+ {KE_KEY, EVENT_SLEEP, { KEY_SLEEP } }, /* Fn + F1 */
-+ {KE_KEY, EVENT_DISPLAYTOGGLE, { KEY_DISPLAYTOGGLE } }, /* Fn + F2 */
-+ {KE_KEY, EVENT_SWITCHVIDEOMODE, { KEY_SWITCHVIDEOMODE } }, /* Fn + F3 */
-+ {KE_KEY, EVENT_AUDIO_MUTE, { KEY_MUTE } }, /* Fn + F4 */
-+ {KE_KEY, EVENT_WLAN, { KEY_WLAN } }, /* Fn + F5 */
-+ {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSUP } }, /* Fn + up */
-+ {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSDOWN } }, /* Fn + down */
-+ {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEUP } }, /* Fn + right */
-+ {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEDOWN } }, /* Fn + left */
-+ {KE_END, 0}
-+};
-+
-+static struct key_entry *get_event_key_entry(int event, int status)
-+{
-+ struct key_entry *ke;
-+ static int old_brightness_status = -1;
-+ static int old_volume_status = -1;
-+
-+ ke = sparse_keymap_entry_from_scancode(yeeloong_hotkey_dev, event);
-+ if (!ke)
-+ return NULL;
-+
-+ switch (event) {
-+ case EVENT_DISPLAY_BRIGHTNESS:
-+ /* current status > old one, means up */
-+ if ((status < old_brightness_status) || (0 == status))
-+ ke++;
-+ old_brightness_status = status;
-+ break;
-+ case EVENT_AUDIO_VOLUME:
-+ if ((status < old_volume_status) || (0 == status))
-+ ke++;
-+ old_volume_status = status;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return ke;
-+}
-+
-+static int report_lid_switch(int status)
-+{
-+ input_report_switch(yeeloong_hotkey_dev, SW_LID, !status);
-+ input_sync(yeeloong_hotkey_dev);
-+
-+ return status;
-+}
-+
-+static int crt_detect_handler(int status)
-+{
-+ if (status) {
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
-+ } else {
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
-+ }
-+ return status;
-+}
-+
-+static int displaytoggle_handler(int status)
-+{
-+ /* EC(>=PQ1D26) does this job for us, we can not do it again,
-+ * otherwise, the brightness will not resume to the normal level! */
-+ if (ec_version_before("EC_VER=PQ1D26"))
-+ yeeloong_lcd_vo_set(status);
-+
-+ return status;
-+}
-+
-+static int switchvideomode_handler(int status)
-+{
-+ static int video_output_status;
-+
-+ /* Only enable switch video output button
-+ * when CRT is connected */
-+ if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_UNPLUG)
-+ return 0;
-+ /* 0. no CRT connected: LCD on, CRT off
-+ * 1. BOTH on
-+ * 2. LCD off, CRT on
-+ * 3. BOTH off
-+ * 4. LCD on, CRT off
-+ */
-+ video_output_status++;
-+ if (video_output_status > 4)
-+ video_output_status = 1;
-+
-+ switch (video_output_status) {
-+ case 1:
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
-+ break;
-+ case 2:
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
-+ break;
-+ case 3:
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
-+ break;
-+ case 4:
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
-+ break;
-+ default:
-+ /* Ensure LCD is on */
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
-+ break;
-+ }
-+ return video_output_status;
-+}
-+
-+static int camera_handler(int status)
-+{
-+ int value;
-+
-+ value = ec_read(REG_CAMERA_CONTROL);
-+ ec_write(REG_CAMERA_CONTROL, value | (1 << 1));
-+
-+ return status;
-+}
-+
-+static int usb2_handler(int status)
-+{
-+ pr_emerg("USB2 Over Current occurred\n");
-+
-+ return status;
-+}
-+
-+static int usb0_handler(int status)
-+{
-+ pr_emerg("USB0 Over Current occurred\n");
-+
-+ return status;
-+}
-+
-+static int ac_bat_handler(int status)
-+{
-+ if (ac_bat_initialized) {
-+ power_supply_changed(&yeeloong_ac);
-+ power_supply_changed(&yeeloong_bat);
-+ }
-+ return status;
-+}
-+
-+static void do_event_action(int event)
-+{
-+ sci_handler handler;
-+ int reg, status;
-+ struct key_entry *ke;
-+
-+ reg = 0;
-+ handler = NULL;
-+
-+ switch (event) {
-+ case EVENT_LID:
-+ reg = REG_LID_DETECT;
-+ break;
-+ case EVENT_SWITCHVIDEOMODE:
-+ handler = switchvideomode_handler;
-+ break;
-+ case EVENT_CRT_DETECT:
-+ reg = REG_CRT_DETECT;
-+ handler = crt_detect_handler;
-+ break;
-+ case EVENT_CAMERA:
-+ reg = REG_CAMERA_STATUS;
-+ handler = camera_handler;
-+ break;
-+ case EVENT_USB_OC2:
-+ reg = REG_USB2_FLAG;
-+ handler = usb2_handler;
-+ break;
-+ case EVENT_USB_OC0:
-+ reg = REG_USB0_FLAG;
-+ handler = usb0_handler;
-+ break;
-+ case EVENT_DISPLAYTOGGLE:
-+ reg = REG_DISPLAY_LCD;
-+ handler = displaytoggle_handler;
-+ break;
-+ case EVENT_AUDIO_MUTE:
-+ reg = REG_AUDIO_MUTE;
-+ break;
-+ case EVENT_DISPLAY_BRIGHTNESS:
-+ reg = REG_DISPLAY_BRIGHTNESS;
-+ break;
-+ case EVENT_AUDIO_VOLUME:
-+ reg = REG_AUDIO_VOLUME;
-+ break;
-+ case EVENT_AC_BAT:
-+ handler = ac_bat_handler;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (reg != 0)
-+ status = ec_read(reg);
-+
-+ if (handler != NULL)
-+ status = handler(status);
-+
-+ pr_info("%s: event: %d status: %d\n", __func__, event, status);
-+
-+ /* Report current key to user-space */
-+ ke = get_event_key_entry(event, status);
-+ if (ke) {
-+ if (ke->keycode == SW_LID)
-+ report_lid_switch(status);
-+ else
-+ sparse_keymap_report_entry(yeeloong_hotkey_dev, ke, 1,
-+ true);
-+ }
-+}
-+
-+/*
-+ * SCI(system control interrupt) main interrupt routine
-+ *
-+ * We will do the query and get event number together so the interrupt routine
-+ * should be longer than 120us now at least 3ms elpase for it.
-+ */
-+static irqreturn_t sci_irq_handler(int irq, void *dev_id)
-+{
-+ int ret, event;
-+
-+ if (SCI_IRQ_NUM != irq)
-+ return IRQ_NONE;
-+
-+ /* Query the event number */
-+ ret = ec_query_event_num();
-+ if (ret < 0)
-+ return IRQ_NONE;
-+
-+ event = ec_get_event_num();
-+ if (event < EVENT_START || event > EVENT_END)
-+ return IRQ_NONE;
-+
-+ /* Execute corresponding actions */
-+ do_event_action(event);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+/*
-+ * Config and init some msr and gpio register properly.
-+ */
-+static int sci_irq_init(void)
-+{
-+ u32 hi, lo;
-+ u32 gpio_base;
-+ unsigned long flags;
-+ int ret;
-+
-+ /* Get gpio base */
-+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
-+ gpio_base = lo & 0xff00;
-+
-+ /* Filter the former kb3310 interrupt for security */
-+ ret = ec_query_event_num();
-+ if (ret)
-+ return ret;
-+
-+ /* For filtering next number interrupt */
-+ udelay(10000);
-+
-+ /* Set gpio native registers and msrs for GPIO27 SCI EVENT PIN
-+ * gpio :
-+ * input, pull-up, no-invert, event-count and value 0,
-+ * no-filter, no edge mode
-+ * gpio27 map to Virtual gpio0
-+ * msr :
-+ * no primary and lpc
-+ * Unrestricted Z input to IG10 from Virtual gpio 0.
-+ */
-+ local_irq_save(flags);
-+ _rdmsr(0x80000024, &hi, &lo);
-+ lo &= ~(1 << 10);
-+ _wrmsr(0x80000024, hi, lo);
-+ _rdmsr(0x80000025, &hi, &lo);
-+ lo &= ~(1 << 10);
-+ _wrmsr(0x80000025, hi, lo);
-+ _rdmsr(0x80000023, &hi, &lo);
-+ lo |= (0x0a << 0);
-+ _wrmsr(0x80000023, hi, lo);
-+ local_irq_restore(flags);
-+
-+ /* Set gpio27 as sci interrupt
-+ *
-+ * input, pull-up, no-fliter, no-negedge, invert
-+ * the sci event is just about 120us
-+ */
-+ asm(".set noreorder\n");
-+ /* input enable */
-+ outl(0x00000800, (gpio_base | 0xA0));
-+ /* revert the input */
-+ outl(0x00000800, (gpio_base | 0xA4));
-+ /* event-int enable */
-+ outl(0x00000800, (gpio_base | 0xB8));
-+ asm(".set reorder\n");
-+
-+ return 0;
-+}
-+
-+static struct irqaction sci_irqaction = {
-+ .handler = sci_irq_handler,
-+ .name = "sci",
-+ .flags = IRQF_SHARED,
-+};
-+
-+static int yeeloong_hotkey_init(void)
-+{
-+ int ret;
-+
-+ ret = sci_irq_init();
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = setup_irq(SCI_IRQ_NUM, &sci_irqaction);
-+ if (ret)
-+ return -EFAULT;
-+
-+ yeeloong_hotkey_dev = input_allocate_device();
-+
-+ if (!yeeloong_hotkey_dev) {
-+ remove_irq(SCI_IRQ_NUM, &sci_irqaction);
-+ return -ENOMEM;
-+ }
-+
-+ yeeloong_hotkey_dev->name = "HotKeys";
-+ yeeloong_hotkey_dev->phys = "button/input0";
-+ yeeloong_hotkey_dev->id.bustype = BUS_HOST;
-+ yeeloong_hotkey_dev->dev.parent = NULL;
-+
-+ ret = sparse_keymap_setup(yeeloong_hotkey_dev, yeeloong_keymap, NULL);
-+ if (ret) {
-+ pr_err("Fail to setup input device keymap\n");
-+ input_free_device(yeeloong_hotkey_dev);
-+ return ret;
-+ }
-+
-+ ret = input_register_device(yeeloong_hotkey_dev);
-+ if (ret) {
-+ sparse_keymap_free(yeeloong_hotkey_dev);
-+ input_free_device(yeeloong_hotkey_dev);
-+ return ret;
-+ }
-+
-+ /* Update the current status of LID */
-+ report_lid_switch(BIT_LID_DETECT_ON);
-+
-+#ifdef CONFIG_LOONGSON_SUSPEND
-+ /* Install the real yeeloong_report_lid_status for pm.c */
-+ yeeloong_report_lid_status = report_lid_switch;
-+#endif
-+
-+ return 0;
-+}
-+
-+static void yeeloong_hotkey_exit(void)
-+{
-+ /* Free irq */
-+ remove_irq(SCI_IRQ_NUM, &sci_irqaction);
-+
-+#ifdef CONFIG_LOONGSON_SUSPEND
-+ /* Uninstall yeeloong_report_lid_status for pm.c */
-+ if (yeeloong_report_lid_status == report_lid_switch)
-+ yeeloong_report_lid_status = NULL;
-+#endif
-+
-+ if (yeeloong_hotkey_dev) {
-+ sparse_keymap_free(yeeloong_hotkey_dev);
-+ input_unregister_device(yeeloong_hotkey_dev);
-+ yeeloong_hotkey_dev = NULL;
-+ }
-+}
-+
-+#ifdef CONFIG_PM
-+static void usb_ports_set(int status)
-+{
-+ status = !!status;
-+
-+ ec_write(REG_USB0_FLAG, status);
-+ ec_write(REG_USB1_FLAG, status);
-+ ec_write(REG_USB2_FLAG, status);
-+}
-+
-+static int yeeloong_suspend(struct device *dev)
-+
-+{
-+ if (ec_version_before("EC_VER=PQ1D27"))
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
-+ usb_ports_set(BIT_USB_FLAG_OFF);
-+
-+ return 0;
-+}
-+
-+static int yeeloong_resume(struct device *dev)
-+{
-+ if (ec_version_before("EC_VER=PQ1D27"))
-+ yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
-+ yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
-+ usb_ports_set(BIT_USB_FLAG_ON);
-+
-+ return 0;
-+}
-+
-+static const SIMPLE_DEV_PM_OPS(yeeloong_pm_ops, yeeloong_suspend,
-+ yeeloong_resume);
-+#endif
-+
-+static struct platform_device_id platform_device_ids[] = {
-+ {
-+ .name = "yeeloong_laptop",
-+ },
-+ {}
-+};
-+
-+MODULE_DEVICE_TABLE(platform, platform_device_ids);
-+
-+static struct platform_driver platform_driver = {
-+ .driver = {
-+ .name = "yeeloong_laptop",
-+ .owner = THIS_MODULE,
-+#ifdef CONFIG_PM
-+ .pm = &yeeloong_pm_ops,
-+#endif
-+ },
-+ .id_table = platform_device_ids,
-+};
-+
-+static int __init yeeloong_init(void)
-+{
-+ int ret;
-+
-+ pr_info("Load YeeLoong Laptop Platform Specific Driver.\n");
-+
-+ /* Register platform stuff */
-+ ret = platform_driver_register(&platform_driver);
-+ if (ret) {
-+ pr_err("Fail to register yeeloong platform driver.\n");
-+ return ret;
-+ }
-+
-+ ret = yeeloong_backlight_init();
-+ if (ret) {
-+ pr_err("Fail to register yeeloong backlight driver.\n");
-+ yeeloong_backlight_exit();
-+ return ret;
-+ }
-+
-+ ret = yeeloong_bat_init();
-+ if (ret) {
-+ pr_err("Fail to register yeeloong battery driver.\n");
-+ yeeloong_bat_exit();
-+ return ret;
-+ }
-+
-+ ret = yeeloong_hwmon_init();
-+ if (ret) {
-+ pr_err("Fail to register yeeloong hwmon driver.\n");
-+ yeeloong_hwmon_exit();
-+ return ret;
-+ }
-+
-+ ret = yeeloong_vo_init();
-+ if (ret) {
-+ pr_err("Fail to register yeeloong video output driver.\n");
-+ yeeloong_vo_exit();
-+ return ret;
-+ }
-+
-+ ret = yeeloong_hotkey_init();
-+ if (ret) {
-+ pr_err("Fail to register yeeloong hotkey driver.\n");
-+ yeeloong_hotkey_exit();
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit yeeloong_exit(void)
-+{
-+ yeeloong_hotkey_exit();
-+ yeeloong_vo_exit();
-+ yeeloong_hwmon_exit();
-+ yeeloong_bat_exit();
-+ yeeloong_backlight_exit();
-+ platform_driver_unregister(&platform_driver);
-+
-+ pr_info("Unload YeeLoong Platform Specific Driver.\n");
-+}
-+
-+module_init(yeeloong_init);
-+module_exit(yeeloong_exit);
-+
-+MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Liu Junliang <liujl@lemote.com>");
-+MODULE_DESCRIPTION("YeeLoong laptop driver");
-+MODULE_LICENSE("GPL");
-diff -Nur linux-2.6.37.orig/drivers/staging/sm7xx/smtcfb.c linux-2.6.37/drivers/staging/sm7xx/smtcfb.c
---- linux-2.6.37.orig/drivers/staging/sm7xx/smtcfb.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/drivers/staging/sm7xx/smtcfb.c 2011-01-11 20:44:43.000000000 +0100
-@@ -12,6 +12,8 @@
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
-+ * - Remove the buggy 2D support for Lynx, 2010/01/06, Wu Zhangjin
-+ *
- * Version 0.10.26192.21.01
- * - Add PowerPC/Big endian support
- * - Add 2D support for Lynx
-@@ -107,6 +109,7 @@
- {"0x307", 1280, 1024, 8},
-
- {"0x311", 640, 480, 16},
-+ {"0x313", 800, 480, 16},
- {"0x314", 800, 600, 16},
- {"0x317", 1024, 768, 16},
- {"0x31A", 1280, 1024, 16},
-diff -Nur linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c linux-2.6.37/drivers/usb/host/ohci-hcd.c
---- linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/drivers/usb/host/ohci-hcd.c 2011-01-11 20:44:43.000000000 +0100
-@@ -838,9 +838,13 @@
- }
-
- if (ints & OHCI_INTR_WDH) {
-- spin_lock (&ohci->lock);
-- dl_done_list (ohci);
-- spin_unlock (&ohci->lock);
-+ if (ohci->hcca->done_head == 0) {
-+ ints &= ~OHCI_INTR_WDH;
-+ } else {
-+ spin_lock (&ohci->lock);
-+ dl_done_list (ohci);
-+ spin_unlock (&ohci->lock);
-+ }
- }
-
- if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
-diff -Nur linux-2.6.37.orig/net/rfkill/core.c linux-2.6.37/net/rfkill/core.c
---- linux-2.6.37.orig/net/rfkill/core.c 2011-01-05 01:50:19.000000000 +0100
-+++ linux-2.6.37/net/rfkill/core.c 2011-01-11 20:44:43.000000000 +0100
-@@ -112,7 +112,7 @@
- static DEFINE_MUTEX(rfkill_global_mutex);
- static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */
-
--static unsigned int rfkill_default_state = 1;
-+static unsigned int rfkill_default_state; /* default: 0 = radio off */
- module_param_named(default_state, rfkill_default_state, uint, 0444);
- MODULE_PARM_DESC(default_state,
- "Default initial state for all radio types, 0 = radio off");