[PATCH 14/30] loongson: add basic fuloong(2f) support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From d34ce4df75cd3b101c909d5d3d3a6651a3f64656 Mon Sep 17 00:00:00 2001
From: Wu Zhangjin <wuzhangjin@xxxxxxxxx>
Date: Sat, 16 May 2009 03:21:19 +0800
Subject: [PATCH 14/30] loongson: add basic fuloong(2f) support

fuloong(2e) have an VIA686B south bridge, but fuloong(2f) have an AMD
CS5536 south bridge.
---
 arch/mips/Makefile                                 |    1 +
 .../mips/include/asm/mach-loongson/cs5536/cs5536.h |  576 +++++
 .../include/asm/mach-loongson/cs5536/cs5536_pci.h  |  181 ++
 arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h |   15 +
 .../mips/include/asm/mach-loongson/cs5536/pcireg.h |  485 ++++
 arch/mips/include/asm/mach-loongson/machine.h      |   30 +
 arch/mips/loongson/Kconfig                         |   28 +
 arch/mips/loongson/Makefile                        |    6 +
 arch/mips/loongson/common/Makefile                 |    6 +
 arch/mips/loongson/common/bonito-irq.c             |    5 +
 arch/mips/loongson/common/cs5536_vsm.c             | 2321
++++++++++++++++++++
 arch/mips/loongson/common/mem.c                    |    1 +
 arch/mips/loongson/fuloong-2f/Makefile             |    5 +
 arch/mips/loongson/fuloong-2f/irq.c                |   57 +
 arch/mips/loongson/fuloong-2f/reset.c              |   75 +
 arch/mips/pci/Makefile                             |    3 +-
 arch/mips/pci/fixup-fuloong2f.c                    |  189 ++
 arch/mips/pci/ops-fuloong2e.c                      |  159 --
 arch/mips/pci/ops-loongson2.c                      |  210 ++
 19 files changed, 4193 insertions(+), 160 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
 create mode 100644
arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
 create mode 100644 arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h
 create mode 100644 arch/mips/include/asm/mach-loongson/cs5536/pcireg.h
 create mode 100644 arch/mips/loongson/common/cs5536_vsm.c
 create mode 100644 arch/mips/loongson/fuloong-2f/Makefile
 create mode 100644 arch/mips/loongson/fuloong-2f/irq.c
 create mode 100644 arch/mips/loongson/fuloong-2f/reset.c
 create mode 100644 arch/mips/pci/fixup-fuloong2f.c
 delete mode 100644 arch/mips/pci/ops-fuloong2e.c
 create mode 100644 arch/mips/pci/ops-loongson2.c

diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 6cbfc22..abf16c1 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -310,6 +310,7 @@ core-$(CONFIG_LOONGSON_SYSTEMS)
+=arch/mips/loongson/
 cflags-$(CONFIG_LOONGSON_SYSTEMS) += -I
$(srctree)/arch/mips/include/asm/mach-loongson \
 					-mno-branch-likely
 load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
+load-$(CONFIG_LEMOTE_FULOONG2F) +=0xffffffff80200000
 
 #
 # MIPS Malta board
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
new file mode 100644
index 0000000..502b464
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
@@ -0,0 +1,576 @@
+/*
+ * The include file of cs5536 sourthbridge define which is used in the
pmon only.
+ * you can modify it or change it, please set the modify time and
steps.
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author : jlliu <liujl@xxxxxxxxxx>
+ */
+
+#ifndef	_CS5536_H
+#define	_CS5536_H
+
+extern void _rdmsr(u32 msr, u32 * hi, u32 * lo);
+extern void _wrmsr(u32 msr, u32 hi, u32 lo);
+
+/*************************************************************************/
+
+/*
+ * basic define
+ */
+#define	PCI_IO_BASE_VA	mips_io_port_base
+
+/*
+ * MSR module base
+ */
+#define	CS5536_SB_MSR_BASE	(0x00000000)
+#define	CS5536_GLIU_MSR_BASE	(0x10000000)
+#define	CS5536_ILLEGAL_MSR_BASE	(0x20000000)
+#define	CS5536_USB_MSR_BASE	(0x40000000)
+#define	CS5536_IDE_MSR_BASE	(0x60000000)
+#define	CS5536_DIVIL_MSR_BASE	(0x80000000)
+#define	CS5536_ACC_MSR_BASE	(0xa0000000)
+#define	CS5536_UNUSED_MSR_BASE	(0xc0000000)
+#define	CS5536_GLCP_MSR_BASE	(0xe0000000)
+
+#define	SB_MSR_REG(offset)	(CS5536_SB_MSR_BASE	| offset)
+#define	GLIU_MSR_REG(offset)	(CS5536_GLIU_MSR_BASE	| offset)
+#define	ILLEGAL_MSR_REG(offset)	(CS5536_ILLEGAL_MSR_BASE| offset)
+#define	USB_MSR_REG(offset)	(CS5536_USB_MSR_BASE	| offset)
+#define	IDE_MSR_REG(offset)	(CS5536_IDE_MSR_BASE	| offset)
+#define	DIVIL_MSR_REG(offset)	(CS5536_DIVIL_MSR_BASE	| offset)
+#define	ACC_MSR_REG(offset)	(CS5536_ACC_MSR_BASE	| offset)
+#define	UNUSED_MSR_REG(offset)	(CS5536_UNUSED_MSR_BASE	| offset)
+#define	GLCP_MSR_REG(offset)	(CS5536_GLCP_MSR_BASE	| offset)
+
+/*
+ * BAR SPACE OF VIRTUAL PCI : range for pci probe use, length is the
actual size. 
+ */
+/* IO space for all DIVIL modules */
+#define	CS5536_IRQ_RANGE		0xffffffe0	/* USERD FOR PCI PROBE */
+#define	CS5536_IRQ_LENGTH		0x20	/* THE REGS ACTUAL LENGTH */
+#define	CS5536_SMB_RANGE		0xfffffff8
+#define	CS5536_SMB_LENGTH		0x08
+#define	CS5536_GPIO_RANGE		0xffffff00
+#define	CS5536_GPIO_LENGTH		0x100
+#define	CS5536_MFGPT_RANGE		0xffffffc0
+#define	CS5536_MFGPT_LENGTH		0x40
+#define	CS5536_ACPI_RANGE		0xffffffe0
+#define	CS5536_ACPI_LENGTH		0x20
+#define	CS5536_PMS_RANGE		0xffffff80
+#define	CS5536_PMS_LENGTH		0x80
+/* MEM space for 4KB nand flash; IO space for 16B nor flash. */
+#ifdef	CS5536_USE_NOR_FLASH
+#define	CS5536_FLSH0_RANGE	0xfffffff0
+#define	CS5536_FLSH0_LENGTH	0x10
+#define	CS5536_FLSH1_RANGE	0xfffffff0
+#define	CS5536_FLSH1_LENGTH	0x10
+#define	CS5536_FLSH2_RANGE	0xfffffff0
+#define	CS5536_FLSH2_LENGTH	0x10
+#define	CS5536_FLSH3_RANGE	0xfffffff0
+#define	CS5536_FLSH3_LENGTH	0x10
+#else
+#define	CS5536_FLSH0_RANGE	0xfffff000
+#define	CS5536_FLSH0_LENGTH	0x1000
+#define	CS5536_FLSH1_RANGE	0xfffff000
+#define	CS5536_FLSH1_LENGTH	0x1000
+#define	CS5536_FLSH2_RANGE	0xfffff000
+#define	CS5536_FLSH2_LENGTH	0x1000
+#define	CS5536_FLSH3_RANGE	0xfffff000
+#define	CS5536_FLSH3_LENGTH	0x1000
+#endif
+/* IO space for IDE */
+#define	CS5536_IDE_RANGE	0xfffffff0
+#define	CS5536_IDE_LENGTH	0x10
+/* IO space for ACC */
+#define	CS5536_ACC_RANGE	0xffffff80
+#define	CS5536_ACC_LENGTH	0x80
+/* MEM space for ALL USB modules */
+/* #define       CS5536_OHCI_RANGE       0xfffffff0 */
+#define	CS5536_OHCI_RANGE	0xfffff000
+#define	CS5536_OHCI_LENGTH	0x1000
+/* #define       CS5536_EHCI_RANGE       0xfffffff0 */
+#define	CS5536_EHCI_RANGE	0xfffff000
+#define	CS5536_EHCI_LENGTH	0x1000
+#define	CS5536_UDC_RANGE	0xffffe000
+#define	CS5536_UDC_LENGTH	0x2000
+#define	CS5536_OTG_RANGE	0xfffff000
+#define	CS5536_OTG_LENGTH	0x1000
+
+/*
+ * PCI MSR ACCESS
+ */
+#define	PCI_MSR_CTRL		0xF0
+#define	PCI_MSR_ADDR		0xF4
+#define	PCI_MSR_DATA_LO		0xF8
+#define	PCI_MSR_DATA_HI		0xFC
+
+/******************************* MSR
*********************************************/
+
+/*
+ * GLIU STANDARD MSR
+ */
+#define	GLIU_CAP		0x00
+#define	GLIU_CONFIG		0x01
+#define	GLIU_SMI		0x02
+#define	GLIU_ERROR		0x03
+#define	GLIU_PM			0x04
+#define	GLIU_DIAG		0x05
+
+/*
+ * GLIU SPEC. MSR
+ */
+#define	GLIU_P2D_BM0		0x20
+#define	GLIU_P2D_BM1		0x21
+#define	GLIU_P2D_BM2		0x22
+#define	GLIU_P2D_BMK0		0x23
+#define	GLIU_P2D_BMK1		0x24
+#define	GLIU_P2D_BM3		0x25
+#define	GLIU_P2D_BM4		0x26
+#define	GLIU_COH		0x80
+#define	GLIU_PAE		0x81
+#define	GLIU_ARB		0x82
+#define	GLIU_ASMI		0x83
+#define	GLIU_AERR		0x84
+#define	GLIU_DEBUG		0x85
+#define	GLIU_PHY_CAP		0x86
+#define	GLIU_NOUT_RESP		0x87
+#define	GLIU_NOUT_WDATA		0x88
+#define	GLIU_WHOAMI		0x8B
+#define	GLIU_SLV_DIS		0x8C
+#define	GLIU_IOD_BM0		0xE0
+#define	GLIU_IOD_BM1		0xE1
+#define	GLIU_IOD_BM2		0xE2
+#define	GLIU_IOD_BM3		0xE3
+#define	GLIU_IOD_BM4		0xE4
+#define	GLIU_IOD_BM5		0xE5
+#define	GLIU_IOD_BM6		0xE6
+#define	GLIU_IOD_BM7		0xE7
+#define	GLIU_IOD_BM8		0xE8
+#define	GLIU_IOD_BM9		0xE9
+#define	GLIU_IOD_SC0		0xEA
+#define	GLIU_IOD_SC1		0xEB
+#define	GLIU_IOD_SC2		0xEC
+#define	GLIU_IOD_SC3		0xED
+#define	GLIU_IOD_SC4		0xEE
+#define	GLIU_IOD_SC5		0xEF
+#define	GLIU_IOD_SC6		0xF0
+#define	GLIU_IOD_SC7		0xF1
+
+/*
+ * SB STANDARD
+ */
+#define	SB_CAP		0x00
+#define	SB_CONFIG	0x01
+#define	SB_SMI		0x02
+#define	SB_ERROR	0x03
+#define	SB_MAR_ERR_EN		0x00000001
+#define	SB_TAR_ERR_EN		0x00000002
+#define	SB_RSVD_BIT1		0x00000004
+#define	SB_EXCEP_ERR_EN		0x00000008
+#define	SB_SYSE_ERR_EN		0x00000010
+#define	SB_PARE_ERR_EN		0x00000020
+#define	SB_TAS_ERR_EN		0x00000040
+#define	SB_MAR_ERR_FLAG		0x00010000
+#define	SB_TAR_ERR_FLAG		0x00020000
+#define	SB_RSVD_BIT2		0x00040000
+#define	SB_EXCEP_ERR_FLAG	0x00080000
+#define	SB_SYSE_ERR_FLAG	0x00100000
+#define	SB_PARE_ERR_FLAG	0x00200000
+#define	SB_TAS_ERR_FLAG		0x00400000
+#define	SB_PM		0x04
+#define	SB_DIAG		0x05
+
+/*
+ * SB SPEC.
+ */
+#define	SB_CTRL		0x10
+#define	SB_R0		0x20
+#define	SB_R1		0x21
+#define	SB_R2		0x22
+#define	SB_R3		0x23
+#define	SB_R4		0x24
+#define	SB_R5		0x25
+#define	SB_R6		0x26
+#define	SB_R7		0x27
+#define	SB_R8		0x28
+#define	SB_R9		0x29
+#define	SB_R10		0x2A
+#define	SB_R11		0x2B
+#define	SB_R12		0x2C
+#define	SB_R13		0x2D
+#define	SB_R14		0x2E
+#define	SB_R15		0x2F
+
+/*
+ * GLCP STANDARD
+ */
+#define	GLCP_CAP		0x00
+#define	GLCP_CONFIG		0x01
+#define	GLCP_SMI		0x02
+#define	GLCP_ERROR		0x03
+#define	GLCP_PM			0x04
+#define	GLCP_DIAG		0x05
+
+/*
+ * GLCP SPEC. 
+ */
+#define	GLCP_CLK_DIS_DELAY	0x08
+#define	GLCP_PM_CLK_DISABLE	0x09
+#define	GLCP_GLB_PM		0x0B
+#define	GLCP_DBG_OUT		0x0C
+#define	GLCP_RSVD1		0x0D
+#define	GLCP_SOFT_COM		0x0E
+#define	SOFT_BAR_SMB_FLAG		0x00000001
+#define	SOFT_BAR_GPIO_FLAG		0x00000002
+#define	SOFT_BAR_MFGPT_FLAG		0x00000004
+#define	SOFT_BAR_IRQ_FLAG		0x00000008
+#define	SOFT_BAR_PMS_FLAG		0x00000010
+#define	SOFT_BAR_ACPI_FLAG		0x00000020
+#define	SOFT_BAR_FLSH0_FLAG		0x00000040
+#define	SOFT_BAR_FLSH1_FLAG		0x00000080
+#define	SOFT_BAR_FLSH2_FLAG		0x00000100
+#define	SOFT_BAR_FLSH3_FLAG		0x00000200
+#define	SOFT_BAR_IDE_FLAG		0x00000400
+#define	SOFT_BAR_ACC_FLAG		0x00000800
+#define	SOFT_BAR_OHCI_FLAG		0x00001000
+#define	SOFT_BAR_EHCI_FLAG		0x00002000
+#define	SOFT_BAR_UDC_FLAG		0x00004000
+#define	SOFT_BAR_OTG_FLAG		0x00008000
+#define	GLCP_RSVD2			0x0F
+#define	GLCP_CLK_OFF		0x10
+#define	GLCP_CLK_ACTIVE		0x11
+#define	GLCP_CLK_DISABLE	0x12
+#define	GLCP_CLK4ACK		0x13
+#define	GLCP_SYS_RST		0x14
+#define	GLCP_RSVD3			0x15
+#define	GLCP_DBG_CLK_CTRL	0x16
+#define	GLCP_CHIP_REV_ID	0x17
+
+/*
+ * DIVIL STANDARD
+ */
+#define	DIVIL_CAP		0x00
+#define	DIVIL_CONFIG	0x01
+#define	DIVIL_SMI		0x02
+#define	DIVIL_ERROR		0x03
+#define	DIVIL_PM		0x04
+#define	DIVIL_DIAG		0x05
+
+/*
+ * DIVIL SPEC. 
+ */
+#define	DIVIL_LBAR_IRQ		0x08
+#define	DIVIL_LBAR_KEL		0x09
+#define	DIVIL_LBAR_SMB		0x0B
+#define	DIVIL_LBAR_GPIO		0x0C
+#define	DIVIL_LBAR_MFGPT	0x0D
+#define	DIVIL_LBAR_ACPI		0x0E
+#define	DIVIL_LBAR_PMS		0x0F
+#define	DIVIL_LBAR_FLSH0	0x10
+#define	DIVIL_LBAR_FLSH1	0x11
+#define	DIVIL_LBAR_FLSH2	0x12
+#define	DIVIL_LBAR_FLSH3	0x13
+#define	DIVIL_LEG_IO		0x14
+#define	DIVIL_BALL_OPTS		0x15
+#define	DIVIL_SOFT_IRQ		0x16
+#define	DIVIL_SOFT_RESET	0x17
+/* NOR FLASH */
+#define	NORF_CTRL		0x18
+#define	NORF_T01		0x19
+#define	NORF_T23		0x1A
+/* NAND FLASH */
+#define	NANDF_DATA		0x1B
+#define	NANDF_CTRL		0x1C
+#define	NANDF_RSVD		0x1D
+/* KEL Keyboard Emulation Logic */
+#define	KEL_CTRL		0x1F
+/* PIC */
+#define	PIC_YSEL_LOW		0x20
+#define	PIC_YSEL_LOW_USB_SHIFT		8
+#define	PIC_YSEL_LOW_ACC_SHIFT		16
+#define	PIC_YSEL_LOW_FLASH_SHIFT	24
+#define	PIC_YSEL_HIGH		0x21
+#define	PIC_ZSEL_LOW		0x22
+#define	PIC_ZSEL_HIGH		0x23
+#define	PIC_IRQM_PRIM		0x24
+#define	PIC_IRQM_LPC		0x25
+#define	PIC_XIRR_STS_LOW	0x26
+#define	PIC_XIRR_STS_HIGH	0x27
+#define	PCI_SHDW		0x34
+/* MFGPT */
+#define	MFGPT_IRQ		0x28
+#define	MFGPT_NR		0x29
+#define	MFGPT_RSVD		0x2A
+#define	MFGPT_SETUP		0x2B
+/* FLOPPY */
+#define	FLPY_3F2_SHDW		0x30
+#define	FLPY_3F7_SHDW		0x31
+#define	FLPY_372_SHDW		0x32
+#define	FLPY_377_SHDW		0x33
+/* PIT */
+#define	PIT_SHDW		0x36
+#define	PIT_CNTRL		0x37
+/* UART */
+#define	UART1_MOD		0x38
+#define	UART1_DONG		0x39
+#define	UART1_CONF		0x3A
+#define	UART1_RSVD		0x3B
+#define	UART2_MOD		0x3C
+#define	UART2_DONG		0x3D
+#define	UART2_CONF		0x3E
+#define	UART2_RSVD		0x3F
+/* DMA */
+#define	DIVIL_AC_DMA		0x1E
+#define	DMA_MAP			0x40
+#define	DMA_SHDW_CH0		0x41
+#define	DMA_SHDW_CH1		0x42
+#define	DMA_SHDW_CH2		0x43
+#define	DMA_SHDW_CH3		0x44
+#define	DMA_SHDW_CH4		0x45
+#define	DMA_SHDW_CH5		0x46
+#define	DMA_SHDW_CH6		0x47
+#define	DMA_SHDW_CH7		0x48
+#define	DMA_MSK_SHDW		0x49
+/* LPC */
+#define	LPC_EADDR		0x4C
+#define	LPC_ESTAT		0x4D
+#define	LPC_SIRQ		0x4E
+#define	LPC_RSVD		0x4F
+/* PMC */
+#define	PMC_LTMR		0x50
+#define	PMC_RSVD		0x51
+/* RTC */
+#define	RTC_RAM_LOCK		0x54
+#define	RTC_DOMA_OFFSET		0x55
+#define	RTC_MONA_OFFSET		0x56
+#define	RTC_CEN_OFFSET		0x57
+
+/*
+ * 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
+
+/*
+ * ACC STANDARD
+ */
+#define	ACC_CAP		0x00
+#define	ACC_CONFIG	0x01
+#define	ACC_SMI		0x02
+#define	ACC_ERROR	0x03
+#define	ACC_PM		0x04
+#define	ACC_DIAG	0x05
+
+/*
+ * USB STANDARD
+ */
+#define	USB_CAP		0x00
+#define	USB_CONFIG	0x01
+#define	USB_SMI		0x02
+#define	USB_ERROR	0x03
+#define	USB_PM		0x04
+#define	USB_DIAG	0x05
+
+/*
+ * USB SPEC.
+ */
+#define	USB_OHCI	0x08
+#define	USB_EHCI	0x09
+#define	USB_UDC		0x0A
+#define	USB_OTG		0x0B
+
+/********************************** NATIVE
****************************************/
+/* IDE NATIVE registers */
+#define	IDE_BM_CMD	0x00
+#define	IDE_BM_STS	0x02
+#define	IDE_BM_PRD	0x04
+
+/* OHCI native registers */
+#define	OHCI_REVISION		0x00
+#define	OHCI_CONTROL		0x04
+#define	OHCI_COMMAND_STATUS	0x08
+#define	OHCI_INT_STATUS		0x0C
+#define	OHCI_INT_ENABLE		0x10
+#define	OHCI_INT_DISABLE	0x14
+#define	OHCI_HCCA		0x18
+#define	OHCI_PERI_CUR_ED	0x1C
+#define	OHCI_CTRL_HEAD_ED	0x20
+#define	OHCI_CTRL_CUR_ED	0x24
+#define	OHCI_BULK_HEAD_ED	0x28
+#define	OHCI_BULK_CUR_ED	0x2C
+#define	OHCI_DONE_HEAD		0x30
+#define	OHCI_FM_INTERVAL	0x34
+#define	OHCI_FM_REMAINING	0x38
+#define	OHCI_FM_NUMBER		0x3C
+#define	OHCI_PERI_START		0x40
+#define	OHCI_LS_THRESHOLD	0x44
+#define	OHCI_RH_DESCRIPTORA	0x48
+#define	OHCI_RH_DESCRIPTORB	0x4C
+#define	OHCI_RH_STATUS		0x50
+#define	OHCI_RH_PORT_STATUS1	0x54
+#define	OHCI_RH_PORT_STATUS2	0x58
+#define	OHCI_RH_PORT_STATUS3	0x5C
+#define	OHCI_RH_PORT_STATUS4	0x60
+
+/* KEL : MEM SPACE; REG :32BITS WIDTH */
+#define	KEL_HCE_CTRL	0x100
+#define	KEL_HCE_IN	0x104
+#define	KEL_HCE_OUT	0x108
+#define	KEL_HCE_STS	0x10C
+#define	KEL_PORTA	0x92	/* 8bits */
+/* PIC : I/O SPACE; REG : 8BITS */
+#define	PIC_ICW1_MASTER	0x20
+#define	PIC_ICW1_SLAVE	0xA0
+#define	PIC_ICW2_MASTER	0x21
+#define	PIC_ICW2_SLAVE	0xA1
+#define	PIC_ICW3_MASTER	0x21
+#define	PIC_ICW3_SLAVE	0xA1
+#define	PIC_ICW4_MASTER	0x21
+#define	PIC_ICW4_SLAVE	0xA1
+#define	PIC_OCW1_MASTER	0x21
+#define	PIC_OCW1_SLAVE	0xA1
+#define	PIC_OCW2_MASTER	0x20
+#define	PIC_OCW2_SLAVE	0xA0
+#define	PIC_OCW3_MASTER	0x20
+#define	PIC_OCW3_SLAVE	0xA0
+#define	PIC_IRR_MASTER	0x20
+#define	PIC_IRR_SLAVE	0xA0
+#define	PIC_ISR_MASTER	0x20
+#define	PIC_ISR_SLAVE	0xA0
+#define	PIC_INT_SEL1	0x4D0
+#define	PIC_INT_SEL2	0x4D1
+/* GPIO : I/O SPACE; REG : 32BITS */
+#define	GPIOL_OUT_VAL		0x00
+#define	GPIOL_OUT_EN		0x04
+#define	GPIOL_OUT_OD_EN		0x08
+#define	GPIOL_OUT_INVRT_EN	0x0c
+#define	GPIOL_OUT_AUX1_SEL	0x10
+#define	GPIOL_OUT_AUX2_SEL	0x14
+#define	GPIOL_PU_EN		0x18
+#define	GPIOL_PD_EN		0x1c
+#define	GPIOL_IN_EN		0x20
+#define	GPIOL_IN_INVRT_EN	0x24
+#define	GPIOL_IN_FLTR_EN	0x28
+#define	GPIOL_IN_EVNTCNT_EN	0x2c
+#define	GPIOL_IN_READBACK	0x30
+#define	GPIOL_IN_AUX1_SEL	0x34
+#define	GPIOL_EVNT_EN		0x38
+#define	GPIOL_LOCK_EN		0x3c
+#define	GPIOL_IN_POSEDGE_EN	0x40
+#define	GPIOL_IN_NEGEDGE_EN	0x44
+#define	GPIOL_IN_POSEDGE_STS	0x48
+#define	GPIOL_IN_NEGEDGE_STS	0x4c
+#define	GPIOH_OUT_VAL		0x80
+#define	GPIOH_OUT_EN		0x84
+#define	GPIOH_OUT_OD_EN		0x88
+#define	GPIOH_OUT_INVRT_EN	0x8c
+#define	GPIOH_OUT_AUX1_SEL	0x90
+#define	GPIOH_OUT_AUX2_SEL	0x94
+#define	GPIOH_PU_EN		0x98
+#define	GPIOH_PD_EN		0x9c
+#define	GPIOH_IN_EN		0xA0
+#define	GPIOH_IN_INVRT_EN	0xA4
+#define	GPIOH_IN_FLTR_EN	0xA8
+#define	GPIOH_IN_EVNTCNT_EN	0xAc
+#define	GPIOH_IN_READBACK	0xB0
+#define	GPIOH_IN_AUX1_SEL	0xB4
+#define	GPIOH_EVNT_EN		0xB8
+#define	GPIOH_LOCK_EN		0xBc
+#define	GPIOH_IN_POSEDGE_EN	0xC0
+#define	GPIOH_IN_NEGEDGE_EN	0xC4
+#define	GPIOH_IN_POSEDGE_STS	0xC8
+#define	GPIOH_IN_NEGEDGE_STS	0xCC
+/* 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)	/* (0x7f << 1) */
+#define	SMB_ENABLE		(0x01 << 0)
+#define	SMB_CTRL3			0x06
+
+/*********************************** LEGACY I/O
*******************************/
+
+/*
+ * LEGACY I/O SPACE BASE
+ */
+#define	CS5536_LEGACY_BASE_ADDR		(PCI_IO_BASE_VA | 0x0000)
+
+/*
+ * IDE LEGACY REG : legacy IO address is 0x170~0x177 and 0x376
(0x1f0~0x1f7 and 0x3f6)
+ * all registers are 16bits except the IDE_LEGACY_DATA reg
+ * some registers are read only and the 
+ */
+#define	PRI_IDE_LEGACY_REG(offset) 	(CS5536_LEGACY_BASE_ADDR | 0x1f0 |
offset)
+#define	SEC_IDE_LEGACY_REG(offset)	(CS5536_LEGACY_BASE_ADDR | 0x170 |
offset)
+
+#define	IDE_LEGACY_DATA		0x00	/* RW */
+#define	IDE_LEGACY_ERROR	0x01	/* RO */
+#define	IDE_LEGACY_FEATURE	0x01	/* WO */
+#define	IDE_LEGACY_SECTOR_COUNT	0x02	/* RW */
+#define	IDE_LEGACY_SECTOR_NUM	0x03	/* RW */
+#define	IDE_LEGACY_CYL_LO	0x04	/* RW */
+#define	IDE_LEGACY_CYL_HI	0x05	/* RW */
+#define	IDE_LEGACY_HEAD		0x06	/* RW */
+#define	IDE_LEGACY_HEAD_DRV		(1 << 4)
+#define	IDE_LEGACY_HEAD_LBA		(1 << 6)
+#define	IDE_LEGACY_HEAD_IBM		(1 << 7 | 1 << 5)
+#define	IDE_LEGACY_STATUS	0x07	/* RO */
+#define IDE_LEGACY_STATUS_ERR		(1 << 0)
+#define	IDE_LEGACY_STATUS_IDX		(1 << 1)
+#define IDE_LEGACY_STATUS_CORR		(1 << 2)
+#define	IDE_LEGACY_STATUS_DRQ		(1 << 3)
+#define	IDE_LEGACY_STATUS_DSC 		(1 << 4)
+#define	IDE_LEGACY_STATUS_DWF		(1 << 5)
+#define	IDE_LEGACY_STATUS_DRDY		(1 << 6)
+#define	IDE_LEGACY_STATUS_BUSY		(1 << 7)
+#define	IDE_LEGACY_COMMAND	0x07	/* WO */
+#define	IDE_LEGACY_ASTATUS	0x206	/* RO */
+#define	IDE_LEGACY_CTRL		0x206	/* WO */
+#define	IDE_LEGACY_CTRL_IDS	0x02
+#define	IDE_LEGACY_CTRL_RST	0x04
+#define	IDE_LEGACY_CTRL_4BIT	0x08
+
+/**********************************************************************************/
+
+#endif				/* _CS5536_H */
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
new file mode 100644
index 0000000..e60a824
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
@@ -0,0 +1,181 @@
+/*
+ * the definition file of cs5536 Virtual Support Module(VSM).
+ * pci configuration space can be accessed through the VSM, so
+ * there is no need the MSR read/write now, except the spec. MSR
+ * registers which are not implemented yet.
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author : jlliu, liujl@xxxxxxxxxx
+ */
+
+#ifndef	_CS5536_PCI_H
+#define	_CS5536_PCI_H
+
+#define PCI_OPS_CS5536_IDSEL    14
+extern void cs5536_pci_conf_write4(int function, int reg, u32 value);
+extern u32  cs5536_pci_conf_read4(int function, int reg);
+
+/*
+#define	TEST_CS5536_USE_FLASH
+#ifdef	TEST_CS5536_USE_FLASH
+#define	TEST_CS5536_USE_NOR_FLASH
+#endif
+*/
+#define	TEST_CS5536_USE_EHCI
+#define	TEST_CS5536_USE_UDC
+#define	TEST_CS5536_USE_OTG
+
+#define	PCI_SPECIAL_SHUTDOWN	1
+#define	CS5536_FLASH_INTR	6
+#define	CS5536_ACC_INTR		9
+#define	CS5536_IDE_INTR		14
+#define	CS5536_USB_INTR		11
+#define	CS5536_UART1_INTR	4
+#define	CS5536_UART2_INTR	3
+
+/************************* PCI BUS DEVICE FUNCTION
********************/
+
+/*
+ * PCI bus device function
+ */
+#define	PCI_BUS_CS5536		0
+#define	PCI_IDSEL_CS5536	14
+#define	PCI_CFG_BASE		0x02000000
+
+#define	CS5536_ISA_FUNC		0
+#define	CS5536_FLASH_FUNC	1
+#define	CS5536_IDE_FUNC		2
+#define	CS5536_ACC_FUNC		3
+#define	CS5536_OHCI_FUNC	4
+#define	CS5536_EHCI_FUNC	5
+#define	CS5536_UDC_FUNC		6
+#define	CS5536_OTG_FUNC		7
+#define	CS5536_FUNC_START	0
+#define	CS5536_FUNC_END		7
+#define	CS5536_FUNC_COUNT	(CS5536_FUNC_END - CS5536_FUNC_START + 1)
+
+/***************************** STANDARD PCI-2.2 EXPANSION
***********************/
+
+/*
+ * PCI configuration space
+ * we have to virtualize the PCI configure space head, so we should
+ * define the necessary IDs and some others.
+ */
+/* VENDOR ID */
+#define	CS5536_VENDOR_ID	0x1022
+
+/* DEVICE ID */
+#define	CS5536_ISA_DEVICE_ID		0x2090
+#define	CS5536_FLASH_DEVICE_ID		0x2091
+#define	CS5536_IDE_DEVICE_ID		0x209a
+#define	CS5536_ACC_DEVICE_ID		0x2093
+#define	CS5536_OHCI_DEVICE_ID		0x2094
+#define	CS5536_EHCI_DEVICE_ID		0x2095
+#define	CS5536_UDC_DEVICE_ID		0x2096
+#define	CS5536_OTG_DEVICE_ID		0x2097
+
+/* CLASS CODE : CLASS SUB-CLASS INTERFACE */
+#define	CS5536_ISA_CLASS_CODE		0x060100
+#define	CS5536_FLASH_CLASS_CODE		0x050100
+#define CS5536_IDE_CLASS_CODE		0x010180
+#define	CS5536_ACC_CLASS_CODE		0x040100
+#define	CS5536_OHCI_CLASS_CODE		0x0C0310
+#define	CS5536_EHCI_CLASS_CODE		0x0C0320
+#define	CS5536_UDC_CLASS_CODE		0x0C03FE
+#define	CS5536_OTG_CLASS_CODE		0x0C0380
+
+/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */
+#define	PCI_NONE_BIST			0x00	//RO not implemented yet.
+#define	PCI_BRIDGE_HEADER_TYPE		0x80	//RO
+#define	PCI_NORMAL_HEADER_TYPE		0x00
+#define	PCI_NORMAL_LATENCY_TIMER	0x00
+#define	PCI_NORMAL_CACHE_LINE_SIZE	0x08	//RW
+
+/* BAR */
+#define	PCI_BAR0_REG			0x10
+#define	PCI_BAR1_REG			0x14
+#define	PCI_BAR2_REG			0x18
+#define	PCI_BAR3_REG			0x1c
+#define	PCI_BAR4_REG			0x20
+#define	PCI_BAR5_REG			0x24
+#define	PCI_BAR_COUNT			6
+#define	PCI_BAR_RANGE_MASK		0xFFFFFFFF
+
+/* CARDBUS CIS POINTER */
+#define	PCI_CARDBUS_CIS_POINTER		0x00000000
+
+/* SUBSYSTEM VENDOR ID  */
+#define	CS5536_SUB_VENDOR_ID		CS5536_VENDOR_ID
+
+/* SUBSYSTEM ID */
+#define	CS5536_ISA_SUB_ID		CS5536_ISA_DEVICE_ID
+#define	CS5536_FLASH_SUB_ID		CS5536_FLASH_DEVICE_ID
+#define	CS5536_IDE_SUB_ID		CS5536_IDE_DEVICE_ID
+#define	CS5536_ACC_SUB_ID		CS5536_ACC_DEVICE_ID
+#define	CS5536_OHCI_SUB_ID		CS5536_OHCI_DEVICE_ID
+#define	CS5536_EHCI_SUB_ID		CS5536_EHCI_DEVICE_ID
+#define	CS5536_UDC_SUB_ID		CS5536_UDC_DEVICE_ID
+#define	CS5536_OTG_SUB_ID		CS5536_OTG_DEVICE_ID
+
+/* EXPANSION ROM BAR */
+#define	PCI_EXPANSION_ROM_BAR		0x00000000
+
+/* CAPABILITIES POINTER */
+#define	PCI_CAPLIST_POINTER		0x00000000
+#define PCI_CAPLIST_USB_POINTER		0x40
+/* INTERRUPT */
+#define	PCI_MAX_LATENCY			0x40
+#define	PCI_MIN_GRANT			0x00
+#define	PCI_DEFAULT_PIN			0x01
+
+/**************************** EXPANSION PCI REG
**************************************/
+
+/*
+ * ISA EXPANSION
+ */
+#define	PCI_UART1_INT_REG 	0x50
+#define PCI_UART2_INT_REG	0x54
+#define	PCI_ISA_FIXUP_REG	0x58
+
+/*
+ * FLASH EXPANSION
+ */
+#define	PCI_FLASH_INT_REG		0x50
+#define	PCI_NOR_FLASH_CTRL_REG		0x40
+#define	PCI_NOR_FLASH_T01_REG		0x44
+#define	PCI_NOR_FLASH_T23_REG		0x48
+#define	PCI_NAND_FLASH_TDATA_REG	0x60
+#define	PCI_NAND_FLASH_TCTRL_REG	0x64
+#define	PCI_NAND_FLASH_RSVD_REG		0x68
+#define	PCI_FLASH_SELECT_REG		0x70
+
+/*
+ * IDE EXPANSION
+ */
+#define	PCI_IDE_CFG_REG		0x40
+#define	CS5536_IDE_FLASH_SIGNATURE	0xDEADBEEF
+#define	PCI_IDE_DTC_REG		0x48
+#define	PCI_IDE_CAST_REG	0x4C
+#define	PCI_IDE_ETC_REG		0x50
+#define	PCI_IDE_PM_REG		0x54
+#define	PCI_IDE_INT_REG		0x60
+
+/*
+ * ACC EXPANSION
+ */
+#define	PCI_ACC_INT_REG		0x50
+
+/*
+ * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI
+ */
+#define	PCI_OHCI_PM_REG		0x40
+#define	PCI_OHCI_INT_REG	0x50
+
+/*
+ * EHCI EXPANSION
+ */
+#define	PCI_EHCI_LEGSMIEN_REG	0x50
+#define	PCI_EHCI_LEGSMISTS_REG	0x54
+#define	PCI_EHCI_FLADJ_REG	0x60
+
+#endif				/* _CS5536_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h
b/arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h
new file mode 100644
index 0000000..c435389
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h
@@ -0,0 +1,15 @@
+/*
+ * cs5536 mfgpt header file
+ */
+
+#ifndef _CS5536_MFGPT_H
+#define _CS5536_MFGPT_H
+
+#include <cs5536/cs5536.h>
+
+#define MFGPT_BASE	mfgpt_base
+#define MFGPT0_CMP2	(MFGPT_BASE + 2)
+#define MFGPT0_CNT	(MFGPT_BASE + 4)
+#define MFGPT0_SETUP	(MFGPT_BASE + 6) 
+
+#endif /*!_CS5536_MFGPT_H */
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/pcireg.h
b/arch/mips/include/asm/mach-loongson/cs5536/pcireg.h
new file mode 100644
index 0000000..aa823d3
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/pcireg.h
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2001, 2006 www.ict.ac.cn.
+ * Copyright (c) 2006, 2008 www.lemote.com.cn.
+ *
+ * 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 named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DEV_PCI_PCIREG_H_
+#define	_DEV_PCI_PCIREG_H_
+
+
+/*
+ * Standardized PCI configuration information
+ *
+ * XXX This is not complete.
+ */
+
+/*
+ * Device identification register; contains a vendor ID and a device
ID.
+ */
+#define	PCI_ID_REG			0x00
+
+typedef u_int16_t pci_vendor_id_t;
+typedef u_int16_t pci_product_id_t;
+
+#define	PCI_VENDOR_SHIFT			0
+#define	PCI_VENDOR_MASK				0xffff
+#define	PCI_VENDOR(id) \
+	    (((id) >> PCI_VENDOR_SHIFT) & PCI_VENDOR_MASK)
+
+#define	PCI_PRODUCT_SHIFT			16
+#define	PCI_PRODUCT_MASK			0xffff
+#define	PCI_PRODUCT(id) \
+	    (((id) >> PCI_PRODUCT_SHIFT) & PCI_PRODUCT_MASK)
+
+/*
+ * Command and status register.
+ */
+#define	PCI_COMMAND_STATUS_REG			0x04
+
+#define	PCI_COMMAND_IO_ENABLE			0x00000001
+#define	PCI_COMMAND_MEM_ENABLE			0x00000002
+#define	PCI_COMMAND_MASTER_ENABLE		0x00000004
+#define	PCI_COMMAND_SPECIAL_ENABLE		0x00000008
+#define	PCI_COMMAND_INVALIDATE_ENABLE		0x00000010
+#define	PCI_COMMAND_PALETTE_ENABLE		0x00000020
+#define	PCI_COMMAND_PARITY_ENABLE		0x00000040
+#define	PCI_COMMAND_STEPPING_ENABLE		0x00000080
+#define	PCI_COMMAND_SERR_ENABLE			0x00000100
+#define	PCI_COMMAND_BACKTOBACK_ENABLE		0x00000200
+
+#define	PCI_STATUS_CAPLIST_SUPPORT		0x00100000
+#define	PCI_STATUS_66MHZ_SUPPORT		0x00200000
+#define	PCI_STATUS_UDF_SUPPORT			0x00400000
+#define	PCI_STATUS_BACKTOBACK_SUPPORT		0x00800000
+#define	PCI_STATUS_PARITY_ERROR			0x01000000
+#define	PCI_STATUS_DEVSEL_FAST			0x00000000
+#define	PCI_STATUS_DEVSEL_MEDIUM		0x02000000
+#define	PCI_STATUS_DEVSEL_SLOW			0x04000000
+#define	PCI_STATUS_DEVSEL_MASK			0x06000000
+#define	PCI_STATUS_TARGET_TARGET_ABORT		0x08000000
+#define	PCI_STATUS_MASTER_TARGET_ABORT		0x10000000
+#define	PCI_STATUS_MASTER_ABORT			0x20000000
+#define	PCI_STATUS_SPECIAL_ERROR		0x40000000
+#define	PCI_STATUS_PARITY_DETECT		0x80000000
+
+/*
+ * PCI Class and Revision Register; defines type and revision of
device.
+ */
+#define	PCI_CLASS_REG			0x08
+
+typedef u_int8_t pci_class_t;
+typedef u_int8_t pci_subclass_t;
+typedef u_int8_t pci_interface_t;
+typedef u_int8_t pci_revision_t;
+
+#define	PCI_CLASS_SHIFT				24
+#define	PCI_CLASS_MASK				0xff
+#define	PCI_CLASS(cr) \
+	    (((cr) >> PCI_CLASS_SHIFT) & PCI_CLASS_MASK)
+
+#define	PCI_SUBCLASS_SHIFT			16
+#define	PCI_SUBCLASS_MASK			0xff
+#define	PCI_SUBCLASS(cr) \
+	    (((cr) >> PCI_SUBCLASS_SHIFT) & PCI_SUBCLASS_MASK)
+
+#define PCI_ISCLASS(what, class, subclass) \
+	(((what) & 0xffff0000) == (class << 24 | subclass << 16))
+
+#define	PCI_INTERFACE_SHIFT			8
+#define	PCI_INTERFACE_MASK			0xff
+#define	PCI_INTERFACE(cr) \
+	    (((cr) >> PCI_INTERFACE_SHIFT) & PCI_INTERFACE_MASK)
+
+#define	PCI_REVISION_SHIFT			0
+#define	PCI_REVISION_MASK			0xff
+#define	PCI_REVISION(cr) \
+	    (((cr) >> PCI_REVISION_SHIFT) & PCI_REVISION_MASK)
+
+/* base classes */
+#define	PCI_CLASS_PREHISTORIC			0x00
+#define	PCI_CLASS_MASS_STORAGE			0x01
+#define	PCI_CLASS_NETWORK			0x02
+#define	PCI_CLASS_DISPLAY			0x03
+#define	PCI_CLASS_MULTIMEDIA			0x04
+#define	PCI_CLASS_MEMORY			0x05
+#define	PCI_CLASS_BRIDGE			0x06
+#define	PCI_CLASS_COMMUNICATIONS		0x07
+#define	PCI_CLASS_SYSTEM			0x08
+#define	PCI_CLASS_INPUT				0x09
+#define	PCI_CLASS_DOCK				0x0a
+#define	PCI_CLASS_PROCESSOR			0x0b
+#define	PCI_CLASS_SERIALBUS			0x0c
+#define	PCI_CLASS_WIRELESS			0x0d
+#define	PCI_CLASS_I2O				0x0e
+#define	PCI_CLASS_SATCOM			0x0f
+#define	PCI_CLASS_CRYPTO			0x10
+#define	PCI_CLASS_DASP				0x11
+#define	PCI_CLASS_UNDEFINED			0xff
+
+/* 0x00 prehistoric subclasses */
+#define	PCI_SUBCLASS_PREHISTORIC_MISC		0x00
+#define	PCI_SUBCLASS_PREHISTORIC_VGA		0x01
+
+/* 0x01 mass storage subclasses */
+#define	PCI_SUBCLASS_MASS_STORAGE_SCSI		0x00
+#define	PCI_SUBCLASS_MASS_STORAGE_IDE		0x01
+#define	PCI_SUBCLASS_MASS_STORAGE_FLOPPY	0x02
+#define	PCI_SUBCLASS_MASS_STORAGE_IPI		0x03
+#define	PCI_SUBCLASS_MASS_STORAGE_RAID		0x04
+#define	PCI_SUBCLASS_MASS_STORAGE_ATA		0x05
+#define	PCI_SUBCLASS_MASS_STORAGE_MISC		0x80
+
+/* 0x02 network subclasses */
+#define	PCI_SUBCLASS_NETWORK_ETHERNET		0x00
+#define	PCI_SUBCLASS_NETWORK_TOKENRING		0x01
+#define	PCI_SUBCLASS_NETWORK_FDDI		0x02
+#define	PCI_SUBCLASS_NETWORK_ATM		0x03
+#define	PCI_SUBCLASS_NETWORK_ISDN		0x04
+#define	PCI_SUBCLASS_NETWORK_WORLDFIP		0x05
+#define	PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP	0x06
+#define	PCI_SUBCLASS_NETWORK_MISC		0x80
+
+/* 0x03 display subclasses */
+#define	PCI_SUBCLASS_DISPLAY_VGA		0x00
+#define	PCI_SUBCLASS_DISPLAY_XGA		0x01
+#define	PCI_SUBCLASS_DISPLAY_3D			0x02
+#define	PCI_SUBCLASS_DISPLAY_MISC		0x80
+
+/* 0x04 multimedia subclasses */
+#define	PCI_SUBCLASS_MULTIMEDIA_VIDEO		0x00
+#define	PCI_SUBCLASS_MULTIMEDIA_AUDIO		0x01
+#define	PCI_SUBCLASS_MULTIMEDIA_TELEPHONY	0x02
+#define	PCI_SUBCLASS_MULTIMEDIA_MISC		0x80
+
+/* 0x05 memory subclasses */
+#define	PCI_SUBCLASS_MEMORY_RAM			0x00
+#define	PCI_SUBCLASS_MEMORY_FLASH		0x01
+#define	PCI_SUBCLASS_MEMORY_MISC		0x80
+
+/* 0x06 bridge subclasses */
+#define	PCI_SUBCLASS_BRIDGE_HOST		0x00
+#define	PCI_SUBCLASS_BRIDGE_ISA			0x01
+#define	PCI_SUBCLASS_BRIDGE_EISA		0x02
+#define	PCI_SUBCLASS_BRIDGE_MC			0x03
+#define	PCI_SUBCLASS_BRIDGE_PCI			0x04
+#define	PCI_SUBCLASS_BRIDGE_PCMCIA		0x05
+#define	PCI_SUBCLASS_BRIDGE_NUBUS		0x06
+#define	PCI_SUBCLASS_BRIDGE_CARDBUS		0x07
+#define	PCI_SUBCLASS_BRIDGE_RACEWAY		0x08
+#define	PCI_SUBCLASS_BRIDGE_STPCI		0x09
+#define	PCI_SUBCLASS_BRIDGE_INFINIBAND		0x0a
+#define	PCI_SUBCLASS_BRIDGE_MISC		0x80
+
+/* 0x07 communications subclasses */
+#define	PCI_SUBCLASS_COMMUNICATIONS_SERIAL	0x00
+#define	PCI_SUBCLASS_COMMUNICATIONS_PARALLEL	0x01
+#define	PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL	0x02
+#define	PCI_SUBCLASS_COMMUNICATIONS_MODEM	0x03
+#define	PCI_SUBCLASS_COMMUNICATIONS_MISC	0x80
+
+/* 0x08 system subclasses */
+#define	PCI_SUBCLASS_SYSTEM_PIC			0x00
+#define	PCI_SUBCLASS_SYSTEM_DMA			0x01
+#define	PCI_SUBCLASS_SYSTEM_TIMER		0x02
+#define	PCI_SUBCLASS_SYSTEM_RTC			0x03
+#define	PCI_SUBCLASS_SYSTEM_PCIHOTPLUG		0x04
+#define	PCI_SUBCLASS_SYSTEM_MISC		0x80
+
+/* 0x09 input subclasses */
+#define	PCI_SUBCLASS_INPUT_KEYBOARD		0x00
+#define	PCI_SUBCLASS_INPUT_DIGITIZER		0x01
+#define	PCI_SUBCLASS_INPUT_MOUSE		0x02
+#define	PCI_SUBCLASS_INPUT_SCANNER		0x03
+#define	PCI_SUBCLASS_INPUT_GAMEPORT		0x04
+#define	PCI_SUBCLASS_INPUT_MISC			0x80
+
+/* 0x0a dock subclasses */
+#define	PCI_SUBCLASS_DOCK_GENERIC		0x00
+#define	PCI_SUBCLASS_DOCK_MISC			0x80
+
+/* 0x0b processor subclasses */
+#define	PCI_SUBCLASS_PROCESSOR_386		0x00
+#define	PCI_SUBCLASS_PROCESSOR_486		0x01
+#define	PCI_SUBCLASS_PROCESSOR_PENTIUM		0x02
+#define	PCI_SUBCLASS_PROCESSOR_ALPHA		0x10
+#define	PCI_SUBCLASS_PROCESSOR_POWERPC		0x20
+#define	PCI_SUBCLASS_PROCESSOR_MIPS		0x30
+#define	PCI_SUBCLASS_PROCESSOR_COPROC		0x40
+
+/* 0x0c serial bus subclasses */
+#define	PCI_SUBCLASS_SERIALBUS_FIREWIRE		0x00
+#define	PCI_SUBCLASS_SERIALBUS_ACCESS		0x01
+#define	PCI_SUBCLASS_SERIALBUS_SSA		0x02
+#define	PCI_SUBCLASS_SERIALBUS_USB		0x03
+#define	PCI_SUBCLASS_SERIALBUS_FIBER		0x04
+#define	PCI_SUBCLASS_SERIALBUS_SMBUS		0x05
+#define	PCI_SUBCLASS_SERIALBUS_INFINIBAND	0x06
+#define	PCI_SUBCLASS_SERIALBUS_IPMI		0x07
+#define	PCI_SUBCLASS_SERIALBUS_SERCOS		0x08
+#define	PCI_SUBCLASS_SERIALBUS_CANBUS		0x09
+
+/* 0x0d wireless subclasses */
+#define	PCI_SUBCLASS_WIRELESS_IRDA		0x00
+#define	PCI_SUBCLASS_WIRELESS_CONSUMERIR	0x01
+#define	PCI_SUBCLASS_WIRELESS_RF		0x10
+#define	PCI_SUBCLASS_WIRELESS_MISC		0x80
+
+/* 0x0e I2O (Intelligent I/O) subclasses */
+#define	PCI_SUBCLASS_I2O_STANDARD		0x00
+
+/* 0x0f satellite communication subclasses */
+/*	PCI_SUBCLASS_SATCOM_???			0x00    / * XXX ??? */
+#define	PCI_SUBCLASS_SATCOM_TV			0x01
+#define	PCI_SUBCLASS_SATCOM_AUDIO		0x02
+#define	PCI_SUBCLASS_SATCOM_VOICE		0x03
+#define	PCI_SUBCLASS_SATCOM_DATA		0x04
+
+/* 0x10 encryption/decryption subclasses */
+#define	PCI_SUBCLASS_CRYPTO_NETCOMP		0x00
+#define	PCI_SUBCLASS_CRYPTO_ENTERTAINMENT	0x10
+#define	PCI_SUBCLASS_CRYPTO_MISC		0x80
+
+/* 0x11 data acquisition and signal processing subclasses */
+#define	PCI_SUBCLASS_DASP_DPIO			0x00
+#define	PCI_SUBCLASS_DASP_TIMEFREQ		0x01
+#define	PCI_SUBCLASS_DASP_MISC			0x80
+
+/*
+ * PCI BIST/Header Type/Latency Timer/Cache Line Size Register.
+ */
+#define	PCI_BHLC_REG			0x0c
+
+#define	PCI_BIST_SHIFT				24
+#define	PCI_BIST_MASK				0xff
+#define	PCI_BIST(bhlcr) \
+	    (((bhlcr) >> PCI_BIST_SHIFT) & PCI_BIST_MASK)
+
+#define	PCI_HDRTYPE_SHIFT			16
+#define	PCI_HDRTYPE_MASK			0xff
+#define	PCI_HDRTYPE(bhlcr) \
+	    (((bhlcr) >> PCI_HDRTYPE_SHIFT) & PCI_HDRTYPE_MASK)
+
+#define PCI_HDRTYPE_TYPE(bhlcr) \
+	    (PCI_HDRTYPE(bhlcr) & 0x7f)
+#define	PCI_HDRTYPE_MULTIFN(bhlcr) \
+	    ((PCI_HDRTYPE(bhlcr) & 0x80) != 0)
+
+#define	PCI_LATTIMER_SHIFT			8
+#define	PCI_LATTIMER_MASK			0xff
+#define	PCI_LATTIMER(bhlcr) \
+	    (((bhlcr) >> PCI_LATTIMER_SHIFT) & PCI_LATTIMER_MASK)
+
+#define	PCI_CACHELINE_SHIFT			0
+#define	PCI_CACHELINE_MASK			0xff
+#define	PCI_CACHELINE(bhlcr) \
+	    (((bhlcr) >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK)
+
+/* config registers for header type 0 devices */
+
+#define PCI_MAPS	0x10
+#define PCI_CARDBUSCIS	0x28
+#define PCI_SUBVEND_0	0x2c
+#define PCI_SUBDEV_0	0x2e
+#define PCI_INTLINE	0x3c
+#define PCI_INTPIN	0x3d
+#define PCI_MINGNT	0x3e
+#define PCI_MAXLAT	0x3f
+
+/* config registers for header type 1 devices */
+
+#define PCI_SECSTAT_1	0 /**/
+
+#define PCI_PRIBUS_1	0x18
+#define PCI_SECBUS_1	0x19
+#define PCI_SUBBUS_1	0x1a
+#define PCI_SECLAT_1	0x1b
+
+#define PCI_IOBASEL_1	0x1c
+#define PCI_IOLIMITL_1	0x1d
+#define PCI_IOBASEH_1	0x30 /**/
+#define PCI_IOLIMITH_1	0x32 /**/ 
+
+#define PCI_MEMBASE_1	0x20
+#define PCI_MEMLIMIT_1	0x22
+
+#define PCI_PMBASEL_1	0x24
+#define PCI_PMLIMITL_1	0x26
+#define PCI_PMBASEH_1	0 /**/
+#define PCI_PMLIMITH_1	0 /**/
+
+#define PCI_BRIDGECTL_1 0 /**/
+
+#define PCI_SUBVEND_1	0x34
+#define PCI_SUBDEV_1	0x36
+
+/* config registers for header type 2 devices */
+
+#define PCI_SECSTAT_2	0x16
+
+#define PCI_PRIBUS_2	0x18
+#define PCI_SECBUS_2	0x19
+#define PCI_SUBBUS_2	0x1a
+#define PCI_SECLAT_2	0x1b
+
+#define PCI_MEMBASE0_2	0x1c
+#define PCI_MEMLIMIT0_2 0x20
+#define PCI_MEMBASE1_2	0x24
+#define PCI_MEMLIMIT1_2 0x28
+#define PCI_IOBASE0_2	0x2c
+#define PCI_IOLIMIT0_2	0x30
+#define PCI_IOBASE1_2	0x34
+#define PCI_IOLIMIT1_2	0x38
+
+#define PCI_BRIDGECTL_2 0x3e
+
+#define PCI_SUBVEND_2	0x40
+#define PCI_SUBDEV_2	0x42
+
+#define PCI_PCCARDIF_2	0x44
+
+/*
+ * Mapping registers
+ */
+#define	PCI_MAPREG_START		0x10
+#define	PCI_MAPREG_END			0x28
+#define	PCI_MAPREG_ROM			0x30
+#define	PCI_MAPREG_PPB_END		0x18
+#define	PCI_MAPREG_PCB_END		0x14
+
+#define	PCI_MAPREG_TYPE(mr)						\
+	    ((mr) & PCI_MAPREG_TYPE_MASK)
+#define	PCI_MAPREG_TYPE_MASK			0x00000001
+
+#define	PCI_MAPREG_TYPE_MEM			0x00000000
+#define	PCI_MAPREG_TYPE_IO			0x00000001
+#define	PCI_MAPREG_TYPE_ROM			0x00000001
+
+#define	PCI_MAPREG_MEM_TYPE(mr)						\
+	    ((mr) & PCI_MAPREG_MEM_TYPE_MASK)
+#define	PCI_MAPREG_MEM_TYPE_MASK		0x00000006
+
+#define	PCI_MAPREG_MEM_TYPE_32BIT		0x00000000
+#define	PCI_MAPREG_MEM_TYPE_32BIT_1M		0x00000002
+#define	PCI_MAPREG_MEM_TYPE_64BIT		0x00000004
+
+#define	PCI_MAPREG_MEM_CACHEABLE(mr)					\
+	    (((mr) & PCI_MAPREG_MEM_CACHEABLE_MASK) != 0)
+#define	PCI_MAPREG_MEM_CACHEABLE_MASK		0x00000008
+
+#define	PCI_MAPREG_MEM_PREFETCHABLE(mr)					\
+	    (((mr) & PCI_MAPREG_MEM_PREFETCHABLE_MASK) != 0)
+#define	PCI_MAPREG_MEM_PREFETCHABLE_MASK	0x00000008
+
+#define	PCI_MAPREG_MEM_ADDR(mr)						\
+	    ((mr) & PCI_MAPREG_MEM_ADDR_MASK)
+#define	PCI_MAPREG_MEM_SIZE(mr)						\
+	    (PCI_MAPREG_MEM_ADDR(mr) & -PCI_MAPREG_MEM_ADDR(mr))
+#define	PCI_MAPREG_MEM_ADDR_MASK		0xfffffff0
+
+#define	PCI_MAPREG_MEM64_ADDR(mr)					\
+	    ((mr) & PCI_MAPREG_MEM64_ADDR_MASK)
+#define	PCI_MAPREG_MEM64_SIZE(mr)					\
+	    (PCI_MAPREG_MEM64_ADDR(mr) & -PCI_MAPREG_MEM64_ADDR(mr))
+#define	PCI_MAPREG_MEM64_ADDR_MASK		0xfffffffffffffff0
+
+#define	PCI_MAPREG_IO_ADDR(mr)						\
+	    ((mr) & PCI_MAPREG_IO_ADDR_MASK)
+#define	PCI_MAPREG_IO_SIZE(mr)						\
+	    (PCI_MAPREG_IO_ADDR(mr) & -PCI_MAPREG_IO_ADDR(mr))
+#define	PCI_MAPREG_IO_ADDR_MASK			0xfffffffe
+
+#define	PCI_MAPREG_ROM_ADDR(mr)						\
+	    ((mr) & PCI_MAPREG_ROM_ADDR_MASK)
+#define	PCI_MAPREG_ROM_SIZE(mr)						\
+	    (PCI_MAPREG_ROM_ADDR(mr) & -PCI_MAPREG_ROM_ADDR(mr))
+#define	PCI_MAPREG_ROM_ADDR_MASK		0xfffff800
+
+/*
+ * Cardbus CIS pointer (PCI rev. 2.1)
+ */
+#define PCI_CARDBUS_CIS_REG 0x28
+
+/*
+ * Subsystem identification register; contains a vendor ID and a device
ID.
+ * Types/macros for PCI_ID_REG apply.
+ * (PCI rev. 2.1)
+ */
+#define PCI_SUBSYS_ID_REG 0x2c
+
+/*
+ * capabilities link list (PCI rev. 2.2)
+ */
+#define PCI_CAPLISTPTR_REG		0x34
+#define PCI_CAPLIST_PTR(cpr) ((cpr) & 0xff)
+#define PCI_CAPLIST_NEXT(cr) (((cr) >> 8) & 0xff)
+#define PCI_CAPLIST_CAP(cr) ((cr) & 0xff)
+
+#define PCI_CAP_REESSERVED	0x00
+#define PCI_CAP_PWRMGMT		0x01
+#define PCI_CAP_AGP		0x02
+#define PCI_CAP_VPD		0x03
+#define PCI_CAP_SLOTID		0x04
+#define PCI_CAP_MBI		0x05
+#define PCI_CAP_CPCI_HOTSWAP	0x06
+#define PCI_CAP_PCIX		0x07
+#define PCI_CAP_LDT		0x08
+#define PCI_CAP_VENDSPEC	0x09
+#define PCI_CAP_DEBUGPORT	0x0a
+#define PCI_CAP_CPCI_RSRCCTL	0x0b
+#define PCI_CAP_HOTPLUG		0x0c
+
+/*
+ * Power Management Control Status Register; access via capability
pointer.
+ */
+#define PCI_PMCSR_STATE_MASK	0x03
+#define PCI_PMCSR_STATE_D0	0x00
+#define PCI_PMCSR_STATE_D1	0x01
+#define PCI_PMCSR_STATE_D2	0x02
+#define PCI_PMCSR_STATE_D3	0x03
+
+/*
+ * Interrupt Configuration Register; contains interrupt pin and line.
+ */
+#define	PCI_INTERRUPT_REG		0x3c
+
+typedef u_int8_t pci_intr_pin_t;
+typedef u_int8_t pci_intr_line_t;
+
+#define	PCI_INTERRUPT_PIN_SHIFT			8
+#define	PCI_INTERRUPT_PIN_MASK			0xff
+#define	PCI_INTERRUPT_PIN(icr) \
+	    (((icr) >> PCI_INTERRUPT_PIN_SHIFT) & PCI_INTERRUPT_PIN_MASK)
+
+#define	PCI_INTERRUPT_LINE_SHIFT		0
+#define	PCI_INTERRUPT_LINE_MASK			0xff
+#define	PCI_INTERRUPT_LINE(icr) \
+	    (((icr) >> PCI_INTERRUPT_LINE_SHIFT) & PCI_INTERRUPT_LINE_MASK)
+
+#define	PCI_MIN_GNT_SHIFT			16
+#define	PCI_MIN_GNT_MASK			0xff
+#define	PCI_MIN_GNT(icr) \
+	    (((icr) >> PCI_MIN_GNT_SHIFT) & PCI_MIN_GNT_MASK)
+
+#define	PCI_MAX_LAT_SHIFT			24
+#define	PCI_MAX_LAT_MASK			0xff
+#define	PCI_MAX_LAT(icr) \
+	    (((icr) >> PCI_MAX_LAT_SHIFT) & PCI_MAX_LAT_MASK)
+
+#define	PCI_INTERRUPT_PIN_NONE			0x00
+#define	PCI_INTERRUPT_PIN_A			0x01
+#define	PCI_INTERRUPT_PIN_B			0x02
+#define	PCI_INTERRUPT_PIN_C			0x03
+#define	PCI_INTERRUPT_PIN_D			0x04
+#define	PCI_INTERRUPT_PIN_MAX			0x04
+
+#endif /* _DEV_PCI_PCIREG_H_ */
diff --git a/arch/mips/include/asm/mach-loongson/machine.h
b/arch/mips/include/asm/mach-loongson/machine.h
index 3614619..577b86c 100644
--- a/arch/mips/include/asm/mach-loongson/machine.h
+++ b/arch/mips/include/asm/mach-loongson/machine.h
@@ -13,6 +13,8 @@
 #ifndef __MACHINE_H
 #define __MACHINE_H
 
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
 #define MACH_NAME			"lemote-fuloong(2e)"
 
 #define LOONGSON_UART_BASE		0x1fd003f8
@@ -23,5 +25,33 @@
 #define LOONGSON_TIMER_IRQ        	(MIPS_CPU_IRQ_BASE + 7)
 #define LOONGSON_DMATIMEOUT_IRQ   	(LOONGSON_IRQ_BASE + 10) 
 
+#else /* CONFIG_LEMOTE_FULOONG2F */
+
+#define MACH_NAME			"lemote-fuloong(2f)"
+
+#define LOONGSON_UART_BASE		0x1fd002f8
+
+#define LOONGSON_TIMER_IRQ		(MIPS_CPU_IRQ_BASE + 7)	/* cpu timer */
+#define LOONGSON_PERFCNT_IRQ		(MIPS_CPU_IRQ_BASE + 6)	/* cpu perf
counter */
+#define LOONGSON_NORTH_BRIDGE_IRQ	(MIPS_CPU_IRQ_BASE + 6)	/* bonito */
+#define LOONGSON_UART_IRQ		(MIPS_CPU_IRQ_BASE + 3)	/* cpu serial port
*/
+#define LOONGSON_SOUTH_BRIDGE_IRQ	(MIPS_CPU_IRQ_BASE + 2)	/* i8259 */
+
+#define LOONGSON_INT_BIT_GPIO1		(1 << 1)
+#define LOONGSON_INT_BIT_GPIO2		(1 << 2)
+#define LOONGSON_INT_BIT_GPIO3		(1 << 3)
+#define LOONGSON_INT_BIT_PCI_INTA	(1 << 4)
+#define LOONGSON_INT_BIT_PCI_INTB	(1 << 5)
+#define LOONGSON_INT_BIT_PCI_INTC	(1 << 6)
+#define LOONGSON_INT_BIT_PCI_INTD	(1 << 7)
+#define LOONGSON_INT_BIT_PCI_PERR	(1 << 8)
+#define LOONGSON_INT_BIT_PCI_SERR	(1 << 9)
+#define LOONGSON_INT_BIT_DDR		(1 << 10)
+#define LOONGSON_INT_BIT_INT0		(1 << 11)
+#define LOONGSON_INT_BIT_INT1		(1 << 12)
+#define LOONGSON_INT_BIT_INT2		(1 << 13)
+#define LOONGSON_INT_BIT_INT3		(1 << 14)
+
+#endif
 
 #endif				/* ! __MACHINE_H */
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index 9ae71a5..42a5309 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -27,4 +27,32 @@ config LEMOTE_FULOONG2E
 	  Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and
 	  an FPGA northbridge
 
+config LEMOTE_FULOONG2F
+	bool "Lemote Fuloong(2f) mini-PC"
+	select ARCH_SPARSEMEM_ENABLE
+	select CEVT_R4K
+	select CSRC_R4K
+	select SYS_HAS_CPU_LOONGSON2F
+	select DMA_NONCOHERENT
+	select BOOT_ELF32
+	select BOARD_SCACHE
+	select HW_HAS_PCI
+	select I8259
+	select ISA
+	select IRQ_CPU
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_HIGHMEM
+	select SYS_HAS_EARLY_PRINTK
+	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select GENERIC_ISA_DMA_SUPPORT_BROKEN
+	select CPU_HAS_WB
+	select CS5536
+	help
+	  Lemote Fulong mini-PC board based on the Chinese Loongson-2F CPU
+
 endchoice
+
+config CS5536
+	bool
diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile
index cc9f1c8..e9b8a81 100644
--- a/arch/mips/loongson/Makefile
+++ b/arch/mips/loongson/Makefile
@@ -9,3 +9,9 @@ obj-$(CONFIG_LOONGSON_SYSTEMS) += common/
 #
 
 obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fuloong-2e/
+
+#
+# Lemote Fuloong mini-PC (Loongson 2F-based)
+#
+
+obj-$(CONFIG_LEMOTE_FULOONG2F)	+= fuloong-2f/
diff --git a/arch/mips/loongson/common/Makefile
b/arch/mips/loongson/common/Makefile
index cda3d77..869adb5 100644
--- a/arch/mips/loongson/common/Makefile
+++ b/arch/mips/loongson/common/Makefile
@@ -17,4 +17,10 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 #
 obj-$(CONFIG_RTC_DRV_CMOS) += rtc.o
 
+#
+# Enable CS5536 Virtual Support Module(VSM) for virtulize the PCI
configure
+# space
+#
+obj-$(CONFIG_CS5536) += cs5536_vsm.o
+
 EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/loongson/common/bonito-irq.c
b/arch/mips/loongson/common/bonito-irq.c
index 61f473d..d5a5ae8 100644
--- a/arch/mips/loongson/common/bonito-irq.c
+++ b/arch/mips/loongson/common/bonito-irq.c
@@ -53,10 +53,13 @@ static struct irq_chip bonito_irq_type = {
 	.unmask	= bonito_irq_enable,
 };
 
+/* there is no need to handle dma timeout in loongson-2f base machines
*/
+#ifdef CONFIG_CPU_LOONGSON2E
 static struct irqaction dma_timeout_irqaction = {
 	.handler	= no_action,
 	.name		= "dma_timeout",
 };
+#endif
 
 void bonito_irq_init(void)
 {
@@ -66,5 +69,7 @@ void bonito_irq_init(void)
 		set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
 	}
 
+#ifdef CONFIG_CPU_LOONGSON2E
 	setup_irq(LOONGSON_DMATIMEOUT_IRQ, &dma_timeout_irqaction);
+#endif
 }
diff --git a/arch/mips/loongson/common/cs5536_vsm.c
b/arch/mips/loongson/common/cs5536_vsm.c
new file mode 100644
index 0000000..727b871
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536_vsm.c
@@ -0,0 +1,2321 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author : jlliu, liujl@xxxxxxxxxx
+ *
+ * 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.
+ *
+ * 	the Virtual Support Module(VSM) for virtulize the PCI configure  
+ * 	space. so user can access the PCI configure space directly as
+ *	a normal multi-function PCI device which following the PCI-2.2 spec.
+ */
+#include <linux/types.h>
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+#include <cs5536/pcireg.h>
+
+/* internal used functions */
+
+/*
+ * enable/disable the divil module bar space.
+ *
+ * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg
+ * and the RCONFx(0~5) reg to use the modules.
+ */
+static void divil_lbar_enable_disable(int enable)
+{
+	u32 hi, lo;
+
+	/* 
+	 * The DIVIL IRQ is not used yet. and make the RCONF0 reserved.
+	 */
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo);
+
+	/*
+	 * RCONF0 is reserved to the DIVIL IRQ mdoule
+	 */
+#if	0
+	_rdmsr(SB_MSR_REG(SB_R1), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R1), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R2), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R2), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R3), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R3), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R4), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R4), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R5), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R5), hi, lo);
+#endif
+	return;
+}
+
+#ifdef	TEST_CS5536_USE_FLASH
+/*
+ * enable or disable the region of flashs(NOR or NAND)
+ *
+ * the same as the DIVIL other modules above, two groups of regs should
be modified
+ * here to control the region. DIVIL flash LBAR and the RCONFx(6~9
reserved).
+ */
+static void flash_lbar_enable_disable(int enable)
+{
+	u32 hi, lo;
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo);
+	if (enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R6), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R6), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R7), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R7), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R8), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R8), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R9), &hi, &lo);
+	if (enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R9), hi, lo);
+
+	return;
+}
+#endif
+
+/* cs5536 modules */
+
+/*
+ * isa_write : isa write transfering.
+ * WE assume that the ISA is not the BUS MASTER.!!!
+ */
+/* FAST BACK TO BACK '1' for BUS MASTER '0' for BUS SALVE */
+/* COMMAND :
+ * 	bit0 : IO SPACE ENABLE
+ *	bit1 : MEMORY SPACE ENABLE(ignore)
+ *	bit2 : BUS MASTER ENABLE(ignore)
+ *	bit3 : SPECIAL CYCLE(ignore)? default is ignored.
+ *	bit4 : MEMORY WRITE and INVALIDATE(ignore)
+ *	bit5 : VGA PALETTE(ignore)
+ *	bit6 : PARITY ERROR(ignore)? : default is ignored.
+ *	bit7 : WAIT CYCLE CONTROL(ignore)
+ *	bit8 : SYSTEM ERROR(ignore)
+ *	bit9 : FAST BACK TO BACK(ignore)
+ *	bit10-bit15 : RESERVED
+ * STATUS :
+ *	bit0-bit3 : RESERVED
+ *	bit4 : CAPABILITY LIST(ignore)
+ *	bit5 : 66MHZ CAPABLE
+ *	bit6 : RESERVED
+ *	bit7 : FAST BACK TO BACK(ignore)
+ *	bit8 : DATA PARITY ERROR DETECED(ignore)
+ *	bit9-bit10 : DEVSEL TIMING(ALL MEDIUM)
+ *	bit11: SIGNALED TARGET ABORT
+ *	bit12: RECEIVED TARGET ABORT
+ *	bit13: RECEIVED MASTER ABORT
+ *	bit14: SIGNALED SYSTEM ERROR
+ *	bit15: DETECTED PARITY ERROR
+ */
+static void pci_isa_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+	u32 temp;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_IO_ENABLE) {
+			divil_lbar_enable_disable(1);
+		} else {
+			divil_lbar_enable_disable(0);
+		}
+#if	0
+		/* PER response enable or disable. */
+		if (value & PCI_COMMAND_PARITY_ENABLE) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			lo |= SB_PARE_ERR_EN;
+			_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+		} else {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			lo &= ~SB_PARE_ERR_EN;
+			_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+		}
+#endif
+		/* status */
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		temp = lo & 0x0000ffff;
+		if ((value & PCI_STATUS_TARGET_TARGET_ABORT) &&
+		    (lo & SB_TAS_ERR_EN)) {
+			temp |= SB_TAS_ERR_FLAG;
+		}
+		if ((value & PCI_STATUS_MASTER_TARGET_ABORT) &&
+		    (lo & SB_TAR_ERR_EN)) {
+			temp |= SB_TAR_ERR_FLAG;
+		}
+		if ((value & PCI_STATUS_MASTER_ABORT)
+		    && (lo & SB_MAR_ERR_EN)) {
+			temp |= SB_MAR_ERR_FLAG;
+		}
+		if ((value & PCI_STATUS_PARITY_DETECT)
+		    && (lo & SB_PARE_ERR_EN)) {
+			temp |= SB_PARE_ERR_FLAG;
+		}
+		lo = temp;
+		_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+		break;
+	case PCI_BHLC_REG:
+		value &= 0x0000ff00;
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0xffffff00;
+		hi |= (value >> 8);
+		_wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_SMB_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* SMB NATIVE IO space has 8bytes */
+			hi = 0x0000f001;
+			lo = value & 0x0000fff8;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+
+			/* RCONFx is 4bytes in units for IO space. */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_SMB_LENGTH - 4) << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R0), hi, lo);
+		}
+		break;
+	case PCI_BAR1_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_GPIO_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* GPIO NATIVE reg is 256bytes */
+			hi = 0x0000f001;
+			lo = value & 0x0000ff00;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo);
+
+			/* RCONFx is 4bytes in units for IO space */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_GPIO_LENGTH - 4)
+			     << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R1), hi, lo);
+		}
+		break;
+	case PCI_BAR2_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_MFGPT_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* MFGPT NATIVE reg is 64bytes */
+			hi = 0x0000f001;
+			lo = value & 0x0000ffc0;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo);
+
+			/* RCONFx is 4bytes in units for IO space */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_MFGPT_LENGTH - 4)
+			     << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R2), hi, lo);
+		}
+		break;
+	case PCI_BAR3_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_IRQ_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* IRQ NATIVE reg is 32bytes */
+			hi = 0x0000f001;
+			lo = value & 0x0000ffc0;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), hi, lo);
+
+			/* RCONFx is 4bytes in units for IO space */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_IRQ_LENGTH - 4) << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R3), hi, lo);
+		}
+		break;
+	case PCI_BAR4_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_PMS_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* PMS NATIVE reg is 128bytes */
+			hi = 0x0000f001;
+			lo = value & 0x0000ff80;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo);
+
+			/* RCONFx is 4bytes in units for IO space. */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_PMS_LENGTH - 4) << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R4), hi, lo);
+		}
+		break;
+	case PCI_BAR5_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_ACPI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* ACPI NATIVE reg is 32bytes */
+			hi = 0x0000f001;
+			lo = value & 0x0000ffe0;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo);
+
+			/* RCONFx is 4bytes in units for IO space. */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_ACPI_LENGTH - 4)
+			     << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R5), hi, lo);
+		}
+		break;
+	case PCI_UART1_INT_REG:
+		if (value) {
+			/* enable uart1 interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+			lo &= ~(0xf << 24);
+			lo |= (CS5536_UART1_INTR << 24);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+		} else {
+			/* disable uart1 interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+			lo &= ~(0xf << 24);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+		}
+		break;
+	case PCI_UART2_INT_REG:
+		if (value) {
+			/* enable uart2 interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+			lo &= ~(0xf << 28);
+			lo |= (CS5536_UART2_INTR << 28);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+		} else {
+			/* disable uart2 interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+			lo &= ~(0xf << 28);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+		}
+		break;
+	case PCI_ISA_FIXUP_REG:
+		if (value) {
+			/* enable the TARGET ABORT/MASTER ABORT etc. */
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			lo |= 0x00000063;
+			_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+		}
+
+	default:
+		/* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */
+		break;
+	}
+
+	return;
+}
+
+/*
+ * isa_read : isa read transfering.
+ * we assume that the ISA is not the BUS MASTER. 
+ */
+
+ /* COMMAND :
+  *     bit0 : IO SPACE ENABLE
+  *     bit1 : MEMORY SPACE ENABLE(ignore)
+  *     bit2 : BUS MASTER ENABLE(ignore)
+  *     bit3 : SPECIAL CYCLE(ignore)? default is ignored.
+  *     bit4 : MEMORY WRITE and INVALIDATE(ignore)
+  *     bit5 : VGA PALETTE(ignore)
+  *     bit6 : PARITY ERROR(ignore)? : default is ignored.
+  *     bit7 : WAIT CYCLE CONTROL(ignore)
+  *     bit8 : SYSTEM ERROR(ignore)
+  *     bit9 : FAST BACK TO BACK(ignore)
+  *     bit10-bit15 : RESERVED
+  * STATUS :
+  *     bit0-bit3 : RESERVED
+  *     bit4 : CAPABILITY LIST(ignore)
+  *     bit5 : 66MHZ CAPABLE
+  *     bit6 : RESERVED
+  *     bit7 : FAST BACK TO BACK(ignore)
+  *     bit8 : DATA PARITY ERROR DETECED(ignore)?
+  *     bit9-bit10 : DEVSEL TIMING(ALL MEDIUM)
+  *     bit11: SIGNALED TARGET ABORT
+  *     bit12: RECEIVED TARGET ABORT
+  *     bit13: RECEIVED MASTER ABORT
+  *     bit14: SIGNALED SYSTEM ERROR
+  *     bit15: DETECTED PARITY ERROR(?)
+  */
+
+static u32 pci_isa_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_ISA_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		/* we just check the first LBAR for the IO enable bit, */
+		/* maybe we should changed later. */
+		_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+		if (hi & 0x01) {
+			conf_data |= PCI_COMMAND_IO_ENABLE;
+		}
+		/* conf_data |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
PCI_COMMAND_MASTER_ENABLE; */
+#if	0
+		conf_data |= PCI_COMMAND_SPECIAL_ENABLE;
+#endif
+#if	0
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_EN) {
+			conf_data |= PCI_COMMAND_PARITY_ENABLE;
+		} else {
+			conf_data &= ~PCI_COMMAND_PARITY_ENABLE;
+		}
+#endif
+		/* status */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+#if	1
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+#endif
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_TAS_ERR_FLAG)
+			conf_data |= PCI_STATUS_TARGET_TARGET_ABORT;
+		if (lo & SB_TAR_ERR_FLAG)
+			conf_data |= PCI_STATUS_MASTER_TARGET_ABORT;
+		if (lo & SB_MAR_ERR_FLAG)
+			conf_data |= PCI_STATUS_MASTER_ABORT;
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_DETECT;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_ISA_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0x000000f8;
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_BRIDGE_HEADER_TYPE << 16)
+		    | (hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+		break;
+		/*
+		 * we only use the LBAR of DIVIL, no RCONF used. 
+		 * all of them are IO space.
+		 */
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_SMB_FLAG) {
+			conf_data = CS5536_SMB_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_SMB_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+			conf_data = lo & 0x0000fff8;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_BAR1_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_GPIO_FLAG) {
+			conf_data = CS5536_GPIO_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_GPIO_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
+			conf_data = lo & 0x0000ff00;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_BAR2_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_MFGPT_FLAG) {
+			conf_data = CS5536_MFGPT_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_MFGPT_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo);
+			conf_data = lo & 0x0000ffc0;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+#if	1
+	case PCI_BAR3_REG:
+		conf_data = 0;
+		break;
+#else
+	case PCI_BAR3_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_IRQ_FLAG) {
+			conf_data = CS5536_IRQ_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_IRQ_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), &hi, &lo);
+			conf_data = lo & 0x0000ffc0;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+#endif
+	case PCI_BAR4_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_PMS_FLAG) {
+			conf_data = CS5536_PMS_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_PMS_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo);
+			conf_data = lo & 0x0000ff80;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_BAR5_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_ACPI_FLAG) {
+			conf_data = CS5536_ACPI_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_ACPI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo);
+			conf_data = lo & 0x0000ffe0;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_ISA_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+								(0x00 << 8) | 0x00;
+		break;
+	default:
+		conf_data = 0;
+		break;
+	}
+
+	return conf_data;
+}
+
+#ifdef	TEST_CS5536_USE_FLASH
+
+#ifndef	TEST_CS5536_USE_NOR_FLASH	/* for nand flash */
+static void pci_flash_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_MEM_ENABLE) {
+			flash_lbar_enable_disable(1);
+		} else {
+			flash_lbar_enable_disable(0);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			/* make the flag for reading the bar length. */
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH0_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			/* mem space nand flash native reg base addr */
+			hi = 0xfffff007;
+			lo = value & 0xfffff000;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo);
+
+			/* RCONFx is 4KB in units for mem space. */
+			hi = ((value & 0xfffff000) << 12) |
+			    ((CS5536_FLSH0_LENGTH & 0xfffff000) -
+			     (1 << 12)) | 0x00;
+			lo = ((value & 0xfffff000) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R6), hi, lo);
+		}
+		break;
+	case PCI_BAR1_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH1_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			/* mem space nand flash native reg base addr */
+			hi = 0xfffff007;
+			lo = value & 0xfffff000;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo);
+
+			/* RCONFx is 4KB in units for mem space. */
+			hi = ((value & 0xfffff000) << 12) |
+			    ((CS5536_FLSH1_LENGTH & 0xfffff000) -
+			     (1 << 12)) | 0x00;
+			lo = ((value & 0xfffff000) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R7), hi, lo);
+		}
+		break;
+	case PCI_BAR2_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH2_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			/* mem space nand flash native reg base addr */
+			hi = 0xfffff007;
+			lo = value & 0xfffff000;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo);
+
+			/* RCONFx is 4KB in units for mem space. */
+			hi = ((value & 0xfffff000) << 12) |
+			    ((CS5536_FLSH2_LENGTH & 0xfffff000) -
+			     (1 << 12)) | 0x00;
+			lo = ((value & 0xfffff000) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R8), hi, lo);
+		}
+		break;
+	case PCI_BAR3_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH3_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			/* mem space nand flash native reg base addr */
+			hi = 0xfffff007;
+			lo = value & 0xfffff000;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo);
+
+			/* RCONFx is 4KB in units for mem space. */
+			hi = ((value & 0xfffff000) << 12) |
+			    ((CS5536_FLSH3_LENGTH & 0xfffff000) -
+			     (1 << 12)) | 0x00;
+			lo = ((value & 0xfffff000) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R9), hi, lo);
+		}
+		break;
+	case PCI_FLASH_INT_REG:
+		if (value) {
+			/* enable all the flash interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+			lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		} else {
+			/* disable all the flash interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		}
+		break;
+	case PCI_NAND_FLASH_TDATA_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(DIVIL_MSR_REG(NANDF_DATA), hi, lo);
+		break;
+	case PCI_NAND_FLASH_TCTRL_REG:
+		hi = 0;
+		lo = value & 0x00000fff;
+		_wrmsr(DIVIL_MSR_REG(NANDF_CTRL), hi, lo);
+		break;
+	case PCI_NAND_FLASH_RSVD_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(DIVIL_MSR_REG(NANDF_RSVD), hi, lo);
+		break;
+	case PCI_FLASH_SELECT_REG:
+		if (value == CS5536_IDE_FLASH_SIGNATURE) {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+			lo &= ~0x01;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+static u32 pci_flash_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		/* we just read one lbar for returning. */
+		_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+		if (hi & 0x01)
+			conf_data |= PCI_COMMAND_MEM_ENABLE;
+		/* STATUS */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_FLASH_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (PCI_NORMAL_LATENCY_TIMER << 8) |
+		    PCI_NORMAL_CACHE_LINE_SIZE;
+		break;
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH0_FLAG) {
+			conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH0_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+			conf_data = lo;
+			conf_data &= ~0x0f;
+		}
+		break;
+	case PCI_BAR1_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH1_FLAG) {
+			conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH1_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo);
+			conf_data = lo;
+			conf_data &= ~0x0f;
+		}
+		break;
+	case PCI_BAR2_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH2_FLAG) {
+			conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH2_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo);
+			conf_data = lo;
+			conf_data &= ~0x0f;
+		}
+		break;
+	case PCI_BAR3_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH3_FLAG) {
+			conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH3_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo);
+			conf_data = lo;
+			conf_data &= ~0x0f;
+		}
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR);
+		break;
+	case PCI_NAND_FLASH_TDATA_REG:
+		_rdmsr(DIVIL_MSR_REG(NANDF_DATA), &hi, &lo);
+		conf_data = lo;
+		break;
+	case PCI_NAND_FLASH_TCTRL_REG:
+		_rdmsr(DIVIL_MSR_REG(NANDF_CTRL), &hi, &lo);
+		conf_data = lo & 0x00000fff;
+		break;
+	case PCI_NAND_FLASH_RSVD_REG:
+		_rdmsr(DIVIL_MSR_REG(NANDF_RSVD), &hi, &lo);
+		conf_data = lo;
+		break;
+	case PCI_FLASH_SELECT_REG:
+		_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+		conf_data = lo & 0x01;
+		break;
+
+	}
+	return 0;
+}
+
+#else				/* nor flash */
+
+static void pci_flash_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_IO_ENABLE) {
+			flash_lbar_enable_disable(1);
+		} else {
+			flash_lbar_enable_disable(0);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH0_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* IO space of 16bytes nor flash */
+			hi = 0x0000fff1;
+			lo = value & 0x0000fff0;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo);
+
+			/* RCONFx used for 16bytes reserved. */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_FLSH0_LENGTH - 4)
+			     << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R6), hi, lo);
+		}
+		break;
+	case PCI_BAR1_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH1_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* IO space of 16bytes nor flash */
+			hi = 0x0000fff1;
+			lo = value & 0x0000fff0;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo);
+
+			/* RCONFx used for 16bytes reserved. */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_FLSH1_LENGTH - 4)
+			     << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R7), hi, lo);
+		}
+		break;
+	case PCI_BAR2_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH2_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			hi = 0x0000fff1;
+			lo = value & 0x0000fff0;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo);
+
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_FLSH2_LENGTH - 4)
+			     << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R8), hi, lo);
+		}
+		break;
+	case PCI_BAR3_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_FLSH3_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			/* 16bytes for nor flash */
+			hi = 0x0000fff1;
+			lo = value & 0x0000fff0;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo);
+
+			/* 16bytes of IO space of RCONFx region. */
+			hi = ((value & 0x000ffffc) << 12) |
+			    ((CS5536_FLSH3_LENGTH - 4)
+			     << 12) | 0x01;
+			lo = ((value & 0x000ffffc) << 12) | 0x01;
+			_wrmsr(SB_MSR_REG(SB_R9), hi, lo);
+		}
+		break;
+
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR);
+		break;
+	case PCI_FLASH_INT_REG:
+		if (value) {
+			/* enable all the flash interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+			lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		} else {
+			/* disable all the flash interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		}
+		break;
+	case PCI_NOR_FLASH_CTRL_REG:
+		hi = 0;
+		lo = value & 0x000000ff;
+		_wrmsr(DIVIL_MSR_REG(NORF_CTRL), hi, lo);
+		break;
+	case PCI_NOR_FLASH_T01_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(DIVIL_MSR_REG(NORF_T01), hi, lo);
+		break;
+	case PCI_NOR_FLASH_T23_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(DIVIL_MSR_REG(NORF_T23), hi, lo);
+		break;
+	case PCI_FLASH_SELECT_REG:
+		if (value == CS5536_IDE_FLASH_SIGNATURE) {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+			lo &= ~0x01;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return;
+}
+
+static u32 pci_flash_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		/* we just check one flash bar for returning. */
+		_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+		if (hi & 0x01)
+			conf_data |= PCI_COMMAND_IO_ENABLE;
+		/* STATUS */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_FLASH_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (PCI_NORMAL_LATENCY_TIMER << 8) |
+		    PCI_NORMAL_CACHE_LINE_SIZE;
+		break;
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH0_FLAG) {
+			conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH0_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+			conf_data = lo & 0x0000ffff;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_BAR1_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH1_FLAG) {
+			conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH1_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo);
+			conf_data = lo & 0x0000ffff;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_BAR2_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH2_FLAG) {
+			conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH2_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo);
+			conf_data = lo & 0x0000ffff;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_BAR3_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_FLSH3_FLAG) {
+			conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_FLSH3_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo);
+			conf_data = lo & 0x0000ffff;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR);
+		break;
+	case PCI_NOR_FLASH_CTRL_REG:
+		_rdmsr(DIVIL_MSR_REG(NORF_CTRL), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		break;
+	case PCI_NOR_FLASH_T01_REG:
+		_rdmsr(DIVIL_MSR_REG(NORF_T01), &hi, &lo);
+		conf_data = lo;
+		break;
+	case PCI_NOR_FLASH_T23_REG:
+		_rdmsr(DIVIL_MSR_REG(NORF_T23), &hi, &lo);
+		conf_data = lo;
+		break;
+	default:
+		conf_data = 0;
+		break;
+	}
+	return conf_data;
+}
+#endif				/* TEST_CS5536_USE_NOR_FLASH */
+
+#else				/* TEST_CS5536_USE_FLASH */
+
+static void pci_flash_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_flash_read_reg(int reg)
+{
+	return 0xffffffff;
+}
+
+#endif				/* TEST_CS5536_USE_FLASH */
+
+/*
+ * ide_write : ide write transfering
+ */
+static void pci_ide_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_MASTER_ENABLE) {
+			_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+			lo |= (0x03 << 4);
+			_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+		} else {
+			_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+			lo &= ~(0x03 << 4);
+			_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BHLC_REG:
+		value &= 0x0000ff00;
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0xffffff00;
+		hi |= (value >> 8);
+		_wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+		break;
+	case PCI_BAR4_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_IDE_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			hi = 0x00000000;
+			/* lo = ((value & 0x0fffffff) << 4) | 0x001; */
+			lo = (value & 0xfffffff0) | 0x1;
+			_wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
+
+			value &= 0xfffffffc;
+			hi = 0x60000000 | ((value & 0x000ff000) >> 12);
+			lo = 0x000ffff0 | ((value & 0x00000fff) << 20);
+			_wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo);
+		}
+		break;
+	case PCI_IDE_CFG_REG:
+		if (value == CS5536_IDE_FLASH_SIGNATURE) {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+			lo |= 0x01;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+		} else {
+			hi = 0;
+			lo = value;
+			_wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
+		}
+		break;
+	case PCI_IDE_DTC_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
+		break;
+	case PCI_IDE_CAST_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
+		break;
+	case PCI_IDE_ETC_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
+		break;
+	case PCI_IDE_PM_REG:
+		hi = 0;
+		lo = value;
+		_wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+/*
+ * ide_read : ide read tranfering.
+ */
+static u32 pci_ide_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_IDE_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+		if (lo & 0xfffffff0)
+			conf_data |= PCI_COMMAND_IO_ENABLE;
+		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+		if ((lo & 0x30) == 0x30)
+			conf_data |= PCI_COMMAND_MASTER_ENABLE;
+		/* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET.. */
+		/* STATUS */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_IDE_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0x000000f8;
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+		break;
+	case PCI_BAR0_REG:
+		conf_data = 0x00000000;
+		break;
+	case PCI_BAR1_REG:
+		conf_data = 0x00000000;
+		break;
+	case PCI_BAR2_REG:
+		conf_data = 0x00000000;
+		break;
+	case PCI_BAR3_REG:
+		conf_data = 0x00000000;
+		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 | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			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 >> 4; */
+			conf_data = lo & 0xfffffff0;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_BAR5_REG:
+		conf_data = 0x00000000;
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_IDE_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (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;
+	case PCI_IDE_PM_REG:
+		_rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
+		conf_data = lo;
+		break;
+
+	default:
+		conf_data = 0;
+		break;
+	}
+
+	return conf_data;
+}
+
+static void pci_acc_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_MASTER_ENABLE) {
+			_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+			lo |= (0x03 << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+		} else {
+			_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+			lo &= ~(0x03 << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_ACC_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			value &= 0xfffffffc;
+			hi = 0xA0000000 | ((value & 0x000ff000) >> 12);
+			lo = 0x000fff80 | ((value & 0x00000fff) << 20);
+			_wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo);
+		}
+		break;
+	case PCI_ACC_INT_REG:
+		if (value) {
+			/* enable all the acc interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT);
+			lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		} else {
+			/* disable all the usb interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+static u32 pci_acc_read_reg(int reg)
+{
+	u32 hi, lo;
+	u32 conf_data;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_ACC_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+
+		conf_data = 0;
+		/* command */
+		_rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
+		if (((lo & 0xfff00000) || (hi & 0x000000ff))
+		    && ((hi & 0xf0000000) == 0xa0000000))
+			conf_data |= PCI_COMMAND_IO_ENABLE;
+		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+		if ((lo & 0x300) == 0x300)
+			conf_data |= PCI_COMMAND_MASTER_ENABLE;
+		/* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET.. */
+		/* STATUS */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_ACC_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (PCI_NORMAL_LATENCY_TIMER << 8) |
+		    PCI_NORMAL_CACHE_LINE_SIZE;
+		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 | PCI_MAPREG_TYPE_IO;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			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;
+		}
+		break;
+	case PCI_BAR1_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR2_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR3_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR4_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR5_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_ACC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_ACC_INTR);
+		break;
+	default:
+		conf_data = 0;
+		break;
+	}
+
+	return conf_data;
+}
+
+/*
+ * ohci_write : ohci write tranfering.
+ */
+static void pci_ohci_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_MASTER_ENABLE) {
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			hi |= (1 << 2);
+			_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			hi &= ~(1 << 2);
+			_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+		}
+		if (value & PCI_COMMAND_MEM_ENABLE) {
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			hi |= (1 << 1);
+			_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			hi &= ~(1 << 1);
+			_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_OHCI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			/* lo = (value & 0xffffff00) << 8; */
+			lo = value;
+			_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+
+			value &= 0xfffffff0;
+			hi = 0x40000000 | ((value & 0xff000000) >> 24);
+			lo = 0x000fffff | ((value & 0x00fff000) << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo);
+		}
+		break;
+	case PCI_INTERRUPT_REG:
+		value &= 0x000000ff;
+		break;
+	case PCI_OHCI_PM_REG:
+		break;
+	case PCI_OHCI_INT_REG:
+		if (value) {
+			/* enable all the usb interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << 8);
+			lo |= (CS5536_USB_INTR << 8);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		} else {
+			/* disable all the usb interrupt in PIC */
+			_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+			lo &= ~(0xf << 8);
+			_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+/*
+ * ohci_read : ohci read transfering.
+ */
+static u32 pci_ohci_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_OHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+		if (hi & 0x04)
+			conf_data |= PCI_COMMAND_MASTER_ENABLE;
+		if (hi & 0x02)
+			conf_data |= PCI_COMMAND_MEM_ENABLE;
+		/* status */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (0x00 << 8)
+		    | PCI_NORMAL_CACHE_LINE_SIZE;
+		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 | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			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 >> 8; */
+			conf_data = lo & 0xffffff00;
+			conf_data &= ~0x0000000f;	/* 32bit mem */
+		}
+		break;
+	case PCI_BAR1_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR2_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR3_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR4_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR5_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_OHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+		break;
+	case PCI_OHCI_PM_REG:
+		conf_data = 0;
+		break;
+	case PCI_OHCI_INT_REG:
+		_rdmsr(DIVIL_MSR_REG(0x20), &hi, &lo);
+		if ((lo & 0x00000f00) == 11)
+			conf_data = 1;
+		else
+			conf_data = 0;
+		break;
+	default:
+		conf_data = 0;
+		break;
+	}
+
+	return conf_data;
+}
+
+#ifdef	TEST_CS5536_USE_EHCI
+static void pci_ehci_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_MASTER_ENABLE) {
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			hi |= (1 << 2);
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			hi &= ~(1 << 2);
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		}
+		if (value & PCI_COMMAND_MEM_ENABLE) {
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			hi |= (1 << 1);
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			hi &= ~(1 << 1);
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_EHCI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			lo = value;
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+
+			value &= 0xfffffff0;
+			hi = 0x40000000 | ((value & 0xff000000) >> 24);
+			lo = 0x000fffff | ((value & 0x00fff000) << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo);
+		}
+		break;
+	case PCI_EHCI_LEGSMIEN_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		hi &= 0x003f0000;
+		hi |= (value & 0x3f) << 16;
+		_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		break;
+	case PCI_EHCI_FLADJ_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		hi &= ~0x00003f00;
+		hi |= value & 0x00003f00;
+		_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+static u32 pci_ehci_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_EHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		if (hi & 0x04)
+			conf_data |= PCI_COMMAND_MASTER_ENABLE;
+		if (hi & 0x02)
+			conf_data |= PCI_COMMAND_MEM_ENABLE;
+		/* status */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (PCI_NORMAL_LATENCY_TIMER << 8) |
+		    PCI_NORMAL_CACHE_LINE_SIZE;
+		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 | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			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;
+		}
+		break;
+	case PCI_BAR1_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR2_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR3_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR4_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR5_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_EHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+		break;
+	case PCI_EHCI_LEGSMIEN_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		conf_data = (hi & 0x003f0000) >> 16;
+		break;
+	case PCI_EHCI_LEGSMISTS_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		conf_data = (hi & 0x3f000000) >> 24;
+		break;
+	case PCI_EHCI_FLADJ_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		conf_data = hi & 0x00003f00;
+		break;
+	default:
+		conf_data = 0;
+		break;
+	}
+
+	return conf_data;
+}
+#else
+static void pci_ehci_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_ehci_read_reg(int reg)
+{
+	return 0xffffffff;
+}
+
+#endif
+
+#ifdef	TEST_CS5536_USE_UDC
+static void pci_udc_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_MASTER_ENABLE) {
+			_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+			hi |= (1 << 2);
+			_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+			hi &= ~(1 << 2);
+			_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+		}
+		if (value & PCI_COMMAND_MEM_ENABLE) {
+			_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+			hi |= (1 << 1);
+			_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+			hi &= ~(1 << 1);
+			_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_UDC_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+			lo = value;
+			_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+
+			value &= 0xfffffff0;
+			hi = 0x40000000 | ((value & 0xff000000) >> 24);
+			lo = 0x000fffff | ((value & 0x00fff000) << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM0), hi, lo);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+static u32 pci_udc_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_UDC_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+		if (hi & 0x04)
+			conf_data |= PCI_COMMAND_MASTER_ENABLE;
+		if (hi & 0x02)
+			conf_data |= PCI_COMMAND_MEM_ENABLE;
+		/* status */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_UDC_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (0x00 << 8)
+		    | PCI_NORMAL_CACHE_LINE_SIZE;
+		break;
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_UDC_FLAG) {
+			conf_data = CS5536_UDC_RANGE | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_UDC_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+			conf_data = lo & 0xfffff000;
+			conf_data &= ~0x0000000f;	/* 32bit mem */
+		}
+		break;
+	case PCI_BAR1_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR2_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR3_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR4_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR5_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_UDC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+		break;
+	default:
+		conf_data = 0;
+		break;
+	}
+
+	return conf_data;
+}
+
+#else				/* TEST_CS5536_USE_UDC */
+
+static void pci_udc_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_udc_read_reg(int reg)
+{
+	return 0xffffffff;
+}
+
+#endif				/* TEST_CS5536_USE_UDC */
+
+#ifdef	TEST_CS5536_USE_OTG
+static void pci_otg_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_COMMAND_STATUS_REG:
+		/* command */
+		if (value & PCI_COMMAND_MEM_ENABLE) {
+			_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+			hi |= (1 << 1);
+			_wrmsr(USB_MSR_REG(USB_OTG), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+			hi &= ~(1 << 1);
+			_wrmsr(USB_MSR_REG(USB_OTG), hi, lo);
+		}
+		/* status */
+		if (value & PCI_STATUS_PARITY_ERROR) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_OTG_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+			lo = value & 0xffffff00;
+			_wrmsr(USB_MSR_REG(USB_OTG), hi, lo);
+
+			value &= 0xfffffff0;
+			hi = 0x40000000 | ((value & 0xff000000) >> 24);
+			lo = 0x000fffff | ((value & 0x00fff000) << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM1), hi, lo);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return;
+}
+
+static u32 pci_otg_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_ID_REG:
+		conf_data = (CS5536_OTG_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND_STATUS_REG:
+		conf_data = 0;
+		/* command */
+		_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+		if (hi & 0x02)
+			conf_data |= PCI_COMMAND_MEM_ENABLE;
+		/* status */
+		conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+		conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY_ERROR;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REG:
+		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_OTG_CLASS_CODE << 8);
+		break;
+	case PCI_BHLC_REG:
+		conf_data =
+		    (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16)
+		    | (0x00 << 8)
+		    | PCI_NORMAL_CACHE_LINE_SIZE;
+		break;
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_OTG_FLAG) {
+			conf_data = CS5536_OTG_RANGE | PCI_MAPREG_TYPE_MEM;
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo &= ~SOFT_BAR_OTG_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+			conf_data = lo & 0xffffff00;
+			conf_data &= ~0x0000000f;
+		}
+		break;
+	case PCI_BAR1_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR2_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR3_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR4_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_BAR5_REG:
+		conf_data = 0x000000;
+		break;
+	case PCI_CARDBUS_CIS_REG:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYS_ID_REG:
+		conf_data = (CS5536_OTG_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+		break;
+	case PCI_MAPREG_ROM:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPLISTPTR_REG:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_REG:
+		conf_data =
+		    (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) |
+		    (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+		break;
+	default:
+		conf_data = 0;
+		break;
+	}
+
+	return conf_data;
+}
+
+#else				/* TEST_CS5536_USE_OTG */
+
+static void pci_otg_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_otg_read_reg(int reg)
+{
+	return 0xffffffff;
+}
+
+#endif				/* TEST_CS5536_USE_OTG */
+
+/* read/write to PCI config space and transfer it to MSR write */
+
+/*
+ * write to PCI config space and transfer it to MSR write.
+ */
+void cs5536_pci_conf_write4(int function, int reg, u32 value)
+{
+	/* some basic checking. */
+	if ((function < CS5536_FUNC_START) || (function > CS5536_FUNC_END)) {
+		return;
+	}
+	if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) {
+		return;
+	}
+
+	switch (function) {
+	case CS5536_ISA_FUNC:
+		pci_isa_write_reg(reg, value);
+		break;
+	case CS5536_FLASH_FUNC:
+		pci_flash_write_reg(reg, value);
+		break;
+	case CS5536_IDE_FUNC:
+		pci_ide_write_reg(reg, value);
+		break;
+	case CS5536_ACC_FUNC:
+		pci_acc_write_reg(reg, value);
+		break;
+	case CS5536_OHCI_FUNC:
+		pci_ohci_write_reg(reg, value);
+		break;
+	case CS5536_EHCI_FUNC:
+		pci_ehci_write_reg(reg, value);
+		break;
+	case CS5536_UDC_FUNC:
+		pci_udc_write_reg(reg, value);
+		break;
+	case CS5536_OTG_FUNC:
+		pci_otg_write_reg(reg, value);
+		break;
+	default:
+		break;
+	}
+	return;
+}
+
+/*
+ * read PCI config space and transfer it to MSR access.
+ */
+u32 cs5536_pci_conf_read4(int function, int reg)
+{
+	u32 data = 0;
+
+	/* some basic checking. */
+	if ((function < CS5536_FUNC_START) || (function > CS5536_FUNC_END)) {
+		return 0;
+	}
+	if ((reg < 0) || ((reg & 0x03) != 0)) {
+		return 0;
+	}
+	if (reg > 0x100)
+		return 0xffffffff;
+
+	switch (function) {
+	case CS5536_ISA_FUNC:
+		data = pci_isa_read_reg(reg);
+		break;
+	case CS5536_FLASH_FUNC:
+		data = pci_flash_read_reg(reg);
+		break;
+	case CS5536_IDE_FUNC:
+		data = pci_ide_read_reg(reg);
+		break;
+	case CS5536_ACC_FUNC:
+		data = pci_acc_read_reg(reg);
+		break;
+	case CS5536_OHCI_FUNC:
+		data = pci_ohci_read_reg(reg);
+		break;
+	case CS5536_EHCI_FUNC:
+		data = pci_ehci_read_reg(reg);
+		break;
+	case CS5536_UDC_FUNC:
+		data = pci_udc_read_reg(reg);
+		break;
+	case CS5536_OTG_FUNC:
+		data = pci_otg_read_reg(reg);
+		break;
+	default:
+		break;
+	}
+	return data;
+}
diff --git a/arch/mips/loongson/common/mem.c
b/arch/mips/loongson/common/mem.c
index 85de2dc..059d43f 100644
--- a/arch/mips/loongson/common/mem.c
+++ b/arch/mips/loongson/common/mem.c
@@ -11,6 +11,7 @@
 
 #include <asm/bootinfo.h>
 
+#include <loongson.h>
 #include <mem.h>
 
 extern unsigned int memsize, highmemsize;
diff --git a/arch/mips/loongson/fuloong-2f/Makefile
b/arch/mips/loongson/fuloong-2f/Makefile
new file mode 100644
index 0000000..010b86c
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2f/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for fuloong-2f
+#
+
+obj-y += irq.o reset.o
diff --git a/arch/mips/loongson/fuloong-2f/irq.c
b/arch/mips/loongson/fuloong-2f/irq.c
new file mode 100644
index 0000000..94a4def
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2f/irq.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@xxxxxxxxxx
+ *
+ *  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/interrupt.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+inline int mach_i8259_irq(void)
+{
+	int irq, isr, imr;
+
+	irq = -1;
+
+	if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) {
+		imr = inb(0x21) | (inb(0xa1) << 8);
+		isr = inb(0x20) | (inb(0xa0) << 8);
+		isr &= ~0x4;	/* irq2 for cascade */
+		isr &= ~imr;
+		irq = ffs(isr) - 1;
+	}
+
+	return irq;
+}
+
+extern void bonito_irqdispatch(void);
+extern void i8259_irqdispatch(void);
+
+inline void mach_irq_dispatch(unsigned int pending)
+{
+	if (pending & CAUSEF_IP7) {
+		do_IRQ( LOONGSON_TIMER_IRQ );
+	} else if (pending & CAUSEF_IP6) {	/* North Bridge, Performance
counter */
+		do_IRQ( LOONGSON_PERFCNT_IRQ );
+		bonito_irqdispatch();
+	} else if (pending & CAUSEF_IP3) {	/* CPU UART */
+		do_IRQ( LOONGSON_UART_IRQ );
+	} else if (pending & CAUSEF_IP2) {	/* South Bridge */
+		i8259_irqdispatch();
+	} else {
+		spurious_interrupt();
+	}
+}
+
+void __init set_irq_trigger_mode(void)
+{
+	/* setup cs5536 as high level trigger */
+	LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1;
+	LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1);
+}
diff --git a/arch/mips/loongson/fuloong-2f/reset.c
b/arch/mips/loongson/fuloong-2f/reset.c
new file mode 100644
index 0000000..19a0941
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2f/reset.c
@@ -0,0 +1,75 @@
+/* Board-specific reboot/shutdown routines
+ *
+ * Copyright (c) 2009 Philippe Vachon <philippe@xxxxxxxxx>
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@xxxxxxxxxx
+ *
+ * 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/io.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#include <loongson.h>
+
+/* cs5536 is the south bridge used by fuloong2f mini PC */
+#include <cs5536/cs5536.h>	
+
+void inline mach_prepare_reboot(void)
+{
+	/* 
+	 * reset cpu to full speed, this is needed when enabling cpu
frequency 
+	 * scalling
+	 */
+	LOONGSON_CHIPCFG0 |= 0x7;
+
+	/* send a reset signal to south bridge. 
+	 * anyone of the following two methods works well.
+	 *
+	 * NOTE: if enable "Power Management" in kernel, rtl8169 will not
reset
+	 * normally with this reset operation and it will not work in PMON,
but 
+	 * you can tyep halt command and then reboot, seems the hardware
reset 
+	 * logic not work normally.
+	 */
+#if 0 
+	{
+		u32 hi, lo;
+		_rdmsr(GLCP_MSR_REG(GLCP_SYS_RST), &hi, &lo);
+		lo |= 0x00000001;
+		_wrmsr(GLCP_MSR_REG(GLCP_SYS_RST), hi, lo);
+	}
+#else	
+	{
+		u32 hi, lo;
+		_rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
+		lo |= 0x00000001;
+		_wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
+	}
+#endif
+}
+
+void inline mach_prepare_shutdown(void)
+{
+	u32 hi, lo, val;
+	phys_addr_t gpio_base;
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
+
+	gpio_base = mips_io_port_base | (lo & 0xff00);
+
+	/* make cs5536 gpio13 output enable */
+	val = (readl((u32 *) (gpio_base + GPIOL_OUT_EN)) & ~(1 << (16 + 13)))
+	    | (1 << 13);
+	writel(val, (u32 *) (gpio_base + GPIOL_OUT_EN));
+	mmiowb();
+	/* make cs5536 gpio13 output low level voltage. */
+	val = (readl((u32 *) (gpio_base + GPIOL_OUT_VAL)) & ~(1 << (13)))
+	    | (1 << (16 + 13));
+	writel(val, (u32 *) (gpio_base + GPIOL_OUT_VAL));
+	mmiowb();
+}
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index a0cc238..b96ed14 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -26,7 +26,8 @@ obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
 obj-$(CONFIG_SOC_AU1500)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)	+= fixup-pnx8550.o ops-pnx8550.o
-obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fixup-fuloong2e.o ops-fuloong2e.o
+obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fixup-fuloong2e.o ops-loongson2.o
+obj-$(CONFIG_LEMOTE_FULOONG2F)	+= fixup-fuloong2f.o ops-loongson2.o
 obj-$(CONFIG_MIPS_MALTA)	+= fixup-malta.o
 obj-$(CONFIG_PMC_MSP7120_GW)	+= fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_EVAL)	+= fixup-pmcmsp.o ops-pmcmsp.o
diff --git a/arch/mips/pci/fixup-fuloong2f.c
b/arch/mips/pci/fixup-fuloong2f.c
new file mode 100644
index 0000000..8118e91
--- /dev/null
+++ b/arch/mips/pci/fixup-fuloong2f.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2008 Lemote Technology
+ * Copyright (C) 2004 ICT CAS
+ * Author: Li xiaoyu, lixy@xxxxxxxxx
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@xxxxxxxxxx
+ *
+ *  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/init.h>
+#include <linux/pci.h>
+
+#include <loongson.h>
+#include <cs5536/cs5536.h>
+
+/* 
+ * PCI interrupt pins 
+ *
+ * These should not be changed, or you should consider loongson2f
interrupt register and
+ * your pci card dispatch
+ */
+#define PCIA		4
+#define PCIB		5
+#define PCIC		6
+#define PCID		7
+
+/* all the pci device has the PCIA pin, check the datasheet. */
+static char irq_tab[][5] __initdata = {
+	/*      INTA    INTB    INTC    INTD */
+	{0, 0, 0, 0, 0},	/*  11: Unused */
+	{0, 0, 0, 0, 0},	/*  12: Unused */
+	{0, 0, 0, 0, 0},	/*  13: Unused */
+	{0, 0, 0, 0, 0},	/*  14: Unused */
+	{0, 0, 0, 0, 0},	/*  15: Unused */
+	{0, 0, 0, 0, 0},	/*  16: Unused */
+	{0, PCIA, 0, 0, 0},	/*  17: RTL8110-0 */
+	{0, PCIB, 0, 0, 0},	/*  18: RTL8110-1 */
+	{0, PCIC, 0, 0, 0},	/*  19: SiI3114 */
+	{0, PCID, 0, 0, 0},	/*  20: 3-ports nec usb */
+	{0, PCIA, PCIB, PCIC, PCID},	/*  21: PCI-SLOT */
+	{0, 0, 0, 0, 0},	/*  22: Unused */
+	{0, 0, 0, 0, 0},	/*  23: Unused */
+	{0, 0, 0, 0, 0},	/*  24: Unused */
+	{0, 0, 0, 0, 0},	/*  25: Unused */
+	{0, 0, 0, 0, 0},	/*  26: Unused */
+	{0, 0, 0, 0, 0},	/*  27: Unused */
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int virq;
+
+	if ((PCI_SLOT(dev->devfn) != (14)) && (PCI_SLOT(dev->devfn) < 32)) {
+		virq = irq_tab[slot][pin];
+		printk("slot: %d, pin: %d, irq: %d\n", slot, pin,
+		       virq + LOONGSON_IRQ_BASE);
+		if (virq != 0)
+			return (LOONGSON_IRQ_BASE + virq);
+		else
+			return 0;
+	} else if (PCI_SLOT(dev->devfn) == 14) {	/*  cs5536 */
+		switch (PCI_FUNC(dev->devfn)) {
+		case 2:
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14);
+			return 14;	/*  for IDE */
+		case 3:
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 9);
+			return 9;	/*  for AUDIO */
+		case 4:	/*  for OHCI */
+		case 5:	/*  for EHCI */
+		case 6:	/*  for UDC */
+		case 7:	/*  for OTG */
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+			return 11;
+		}
+		return dev->irq;
+	} else {
+		printk(" strange pci slot number.\n");
+		return 0;
+	}
+}
+
+/* Do platform specific device initialization at pci_enable_device()
time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+/* CS5536 SPEC. fixup */
+static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev)
+{
+	/* the uart1 and uart2 interrupt in PIC is enabled as default */
+	pci_write_config_dword(pdev, 0x50, 1);
+	pci_write_config_dword(pdev, 0x54, 1);
+	/* enable the pci MASTER ABORT/ TARGET ABORT etc. */
+	/* pci_write_config_dword(pdev, 0x58, 1); */
+	return;
+}
+
+static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev)
+{
+	/* setting the mutex pin as IDE function */
+	/* the IDE interrupt in PIC is enabled as default */
+	pci_write_config_dword(pdev, 0x40, 0xDEADBEEF);
+	return;
+}
+
+static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev)
+{
+	u8 val;
+
+	/* enable the AUDIO interrupt in PIC  */
+	pci_write_config_dword(pdev, 0x50, 1);
+
+#if 1
+	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val);
+	printk("cs5536 acc latency %x\n", val);
+	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);
+#endif
+	return;
+}
+
+static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev)
+{
+	/* enable the OHCI interrupt in PIC */
+	/* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */
+	pci_write_config_dword(pdev, 0x50, 1);
+	return;
+}
+
+static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev)
+{
+	u32 hi, lo;
+
+	/* Serial short detect enable */
+	_rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
+	_wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo);
+
+#if 0
+	{
+		u32 bar;
+		void __iomem *base;
+
+		/* Write to clear diag register */
+		_rdmsr(USB_MSR_REG(USB_DIAG), &hi, &lo);
+		_wrmsr(USB_MSR_REG(USB_DIAG), hi, lo);
+
+		pci_read_config_dword(pdev, 0x10, &bar);
+		base = ioremap_nocache(bar, 0x100);
+
+		/* Make HCCAPARMS writable */
+		writel(readl(base + 0xA0) | (1 << 1), (base + 0xA0));
+
+		/* EECP=50h, IST=01h, ASPC=1h */
+		writel(0x00000012, base + 0x08);
+		iounmap(base);
+	}
+#endif
+
+	/* setting the USB2.0 micro frame length */
+	pci_write_config_dword(pdev, 0x60, 0x2000);
+	return;
+}
+
+static void __init loongson_nec_fixup(struct pci_dev *pdev)
+{
+	unsigned int val;
+
+	pci_read_config_dword(pdev, 0xe0, &val);
+	/* Only 2 port be used */
+	pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_CS5536_ISA,
+			 loongson_cs5536_isa_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_CS5536_OHC,
+			 loongson_cs5536_ohci_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_CS5536_EHC,
+			 loongson_cs5536_ehci_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_CS5536_AUDIO,
+			 loongson_cs5536_acc_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_CS5536_IDE,
+			 loongson_cs5536_ide_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+			 loongson_nec_fixup);
diff --git a/arch/mips/pci/ops-fuloong2e.c
b/arch/mips/pci/ops-fuloong2e.c
deleted file mode 100644
index dbcc1eb..0000000
--- a/arch/mips/pci/ops-fuloong2e.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
- *	All rights reserved.
- *	Authors: Carsten Langgaard <carstenl@xxxxxxxx>
- *		 Maciej W. Rozycki <macro@xxxxxxxx>
- *
- *  This program is free software; you can distribute it and/or modify
it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but
WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License
along
- *  with this program; if not, write to the Free Software Foundation,
Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * MIPS boards specific PCI support.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <loongson.h>
-
-#define PCI_ACCESS_READ  0
-#define PCI_ACCESS_WRITE 1
-
-#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE |
(offset))
-#define ID_SEL_BEGIN 11
-#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
-
-
-static int loongson_pcibios_config_access(unsigned char access_type,
-				      struct pci_bus *bus,
-				      unsigned int devfn, int where,
-				      u32 * data)
-{
-	u32 busnum = bus->number;
-	u32 addr, type;
-	u32 dummy;
-	void *addrp;
-	int device = PCI_SLOT(devfn);
-	int function = PCI_FUNC(devfn);
-	int reg = where & ~3;
-
-	if (busnum == 0) {
-		/* Type 0 configuration for onboard PCI bus */
-		if (device > MAX_DEV_NUM)
-			return -1;
-
-		addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
-		type = 0;
-	} else {
-		/* Type 1 configuration for offboard PCI bus */
-		addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
-		type = 0x10000;
-	}
-
-	/* Clear aborts */
-	LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR |
LOONGSON_PCICMD_MTABORT_CLR;
-
-	LOONGSON_PCIMAP_CFG = (addr >> 16) | type;
-
-	/* Flush Bonito register block */
-	dummy = LOONGSON_PCIMAP_CFG;
-	mmiowb();
-
-	addrp = CFG_SPACE_REG(addr & 0xffff);
-	if (access_type == PCI_ACCESS_WRITE) {
-		writel(cpu_to_le32(*data), addrp);
-	} else {
-		*data = le32_to_cpu(readl(addrp));
-	}
-
-	/* Detect Master/Target abort */
-	if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR |
-			     LOONGSON_PCICMD_MTABORT_CLR)) {
-		/* Error occurred */
-
-		/* Clear bits */
-		LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR |
-				  LOONGSON_PCICMD_MTABORT_CLR);
-
-		return -1;
-	}
-
-	return 0;
-
-}
-
-
-/*
- * We can't address 8 and 16 bit words directly.  Instead we have to
- * read/write a 32bit word and mask/modify the data we actually want.
- */
-static int loongson_pcibios_read(struct pci_bus *bus, unsigned int
devfn,
-			     int where, int size, u32 * val)
-{
-	u32 data = 0;
-
-	if ((size == 2) && (where & 1))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	else if ((size == 4) && (where & 3))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
-				       &data))
-		return -1;
-
-	if (size == 1)
-		*val = (data >> ((where & 3) << 3)) & 0xff;
-	else if (size == 2)
-		*val = (data >> ((where & 3) << 3)) & 0xffff;
-	else
-		*val = data;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int loongson_pcibios_write(struct pci_bus *bus, unsigned int
devfn,
-			      int where, int size, u32 val)
-{
-	u32 data = 0;
-
-	if ((size == 2) && (where & 1))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	else if ((size == 4) && (where & 3))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (size == 4)
-		data = val;
-	else {
-		if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
-		                               where, &data))
-			return -1;
-
-		if (size == 1)
-			data = (data & ~(0xff << ((where & 3) << 3))) |
-				(val << ((where & 3) << 3));
-		else if (size == 2)
-			data = (data & ~(0xffff << ((where & 3) << 3))) |
-				(val << ((where & 3) << 3));
-	}
-
-	if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
where,
-				       &data))
-		return -1;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops loongson_pci_ops = {
-	.read = loongson_pcibios_read,
-	.write = loongson_pcibios_write
-};
diff --git a/arch/mips/pci/ops-loongson2.c
b/arch/mips/pci/ops-loongson2.c
new file mode 100644
index 0000000..a391307
--- /dev/null
+++ b/arch/mips/pci/ops-loongson2.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@xxxxxxxx>
+ *		 Maciej W. Rozycki <macro@xxxxxxxx>
+ *
+ *  This program is free software; you can distribute it and/or modify
it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but
WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
along
+ *  with this program; if not, write to the Free Software Foundation,
Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <loongson.h>
+
+#ifdef CONFIG_CS5536
+#include <cs5536/cs5536_pci.h>
+#endif
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE |
(offset))
+#define ID_SEL_BEGIN 11
+#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
+
+
+static int loongson_pcibios_config_access(unsigned char access_type,
+				      struct pci_bus *bus,
+				      unsigned int devfn, int where,
+				      u32 * data)
+{
+	u32 busnum = bus->number;
+	u32 addr, type;
+	u32 dummy;
+	void *addrp;
+	int device = PCI_SLOT(devfn);
+	int function = PCI_FUNC(devfn);
+	int reg = where & ~3;
+
+	if (busnum == 0) {
+		/* board-specific parts, currently, only fuloong2f,yeeloong2f use
CS5536,
+		   fuloong2e use via686b */
+#ifdef CONFIG_CS5536
+		/*  
+		 * CS5536 PCI ACCESS ROUTINE, Note the functions circle call:
+		 *
loongson_pcibios_config_access()--->cs5536_pci_conf_read/write4()--->
+		 *    _rdmsr/_wrmsr()--->loongson_pcibios_read/write()
+		 */
+		if ((PCI_OPS_CS5536_IDSEL == device) && (reg < 0xF0)) {
+			switch (access_type) {
+			case PCI_ACCESS_READ:
+				*data = cs5536_pci_conf_read4(function, reg);
+				break;
+			case PCI_ACCESS_WRITE:
+				cs5536_pci_conf_write4(function, reg, *data);
+				break;
+			}
+			return 0;
+		}
+#endif
+		/* Type 0 configuration for onboard PCI bus */
+		if (device > MAX_DEV_NUM)
+			return -1;
+
+		addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
+		type = 0;
+	} else {
+		/* Type 1 configuration for offboard PCI bus */
+		addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
+		type = 0x10000;
+	}
+
+	/* Clear aborts */
+	LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR |
LOONGSON_PCICMD_MTABORT_CLR;
+
+	LOONGSON_PCIMAP_CFG = (addr >> 16) | type;
+
+	/* Flush Bonito register block */
+	dummy = LOONGSON_PCIMAP_CFG;
+	mmiowb();
+
+	addrp = CFG_SPACE_REG(addr & 0xffff);
+	if (access_type == PCI_ACCESS_WRITE) {
+		writel(cpu_to_le32(*data), addrp);
+	} else {
+		*data = le32_to_cpu(readl(addrp));
+	}
+
+	/* Detect Master/Target abort */
+	if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR |
+			     LOONGSON_PCICMD_MTABORT_CLR)) {
+		/* Error occurred */
+
+		/* Clear bits */
+		LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR |
+				  LOONGSON_PCICMD_MTABORT_CLR);
+
+		return -1;
+	}
+
+	return 0;
+
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int loongson_pcibios_read(struct pci_bus *bus, unsigned int
devfn,
+			     int where, int size, u32 * val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+				       &data))
+		return -1;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int loongson_pcibios_write(struct pci_bus *bus, unsigned int
devfn,
+			      int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (size == 4)
+		data = val;
+	else {
+		if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+		                               where, &data))
+			return -1;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
where,
+				       &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops loongson_pci_ops = {
+	.read = loongson_pcibios_read,
+	.write = loongson_pcibios_write
+};
+
+#ifdef CONFIG_CS5536
+void _rdmsr(u32 msr, u32 * hi, u32 * lo)
+{
+	struct pci_bus bus = {
+		.number = 0
+	};
+	u32 devfn = PCI_DEVFN(PCI_OPS_CS5536_IDSEL, 0);
+	loongson_pcibios_write(&bus, devfn, 0xf4, 4, msr);
+	loongson_pcibios_read(&bus, devfn, 0xf8, 4, lo);
+	loongson_pcibios_read(&bus, devfn, 0xfc, 4, hi);
+}
+
+void _wrmsr(u32 msr, u32 hi, u32 lo)
+{
+	struct pci_bus bus = {
+		.number = 0
+	};
+	u32 devfn = PCI_DEVFN(PCI_OPS_CS5536_IDSEL, 0);
+	loongson_pcibios_write(&bus, devfn, 0xf4, 4, msr);
+	loongson_pcibios_write(&bus, devfn, 0xf8, 4, lo);
+	loongson_pcibios_write(&bus, devfn, 0xfc, 4, hi);
+}
+
+EXPORT_SYMBOL(_rdmsr);
+EXPORT_SYMBOL(_wrmsr);
+#endif
-- 
1.6.2.1





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux