[PATCH] SHPC: Fix SHPC Contoller SERR-INT Register bits access

Current SHPCHP driver doesn't take care of RsvdP/RsvdZ[*] bits in
controller SERR-INT register. This might cause unpredicable
results. This patch fixes this bug.

[*] RsvdP and RsvdZ are defined in SHPC spec as follows:

    RsvdP - Reserved and Preserved. Register bits of this type are
    reserved for future use as R/W bits. The value read is
    undefined. Writes are ignored. Software must follow These rules
    when accessing RsvdP bits:

	- Software must ignore RsvdP bits when testing values read
          from these registers.
	- Software must not depend on RsvdP bit's ability to retain
          information when written
	- Software must always write back the value read in the RsvdP
	  bits when writing one of these registers.

    RsvdZ - Reserved and Zero. Register bits of this type are reserved
    for future use as R/WC bits. The value read is undefined. Writes
    are ignored. Software must follow these rules when accessing RsvdZ
    bits:

        - Software must ignore RsvdZ bits when testing values read
	  from these registers.
	- Software must not depends on a RsvdZ bit's ability to retain
	  information when written.
	- Software must always write 0 to RsvdZ bits when writing one
	  of these register.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Cc: Kristen Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Kenji Kaneshige 2006-05-02 11:12:37 +09:00 committed by Greg Kroah-Hartman
parent 795eb5c4a7
commit e713872369

View File

@ -90,6 +90,17 @@
#define MRLSENSOR 0x40000000 #define MRLSENSOR 0x40000000
#define ATTN_BUTTON 0x80000000 #define ATTN_BUTTON 0x80000000
/*
* Controller SERR-INT Register
*/
#define GLOBAL_INTR_MASK (1 << 0)
#define GLOBAL_SERR_MASK (1 << 1)
#define COMMAND_INTR_MASK (1 << 2)
#define ARBITER_SERR_MASK (1 << 3)
#define COMMAND_DETECTED (1 << 16)
#define ARBITER_DETECTED (1 << 17)
#define SERR_INTR_RSVDZ_MASK 0xfffc0000
/* /*
* Logical Slot Register definitions * Logical Slot Register definitions
*/ */
@ -1047,7 +1058,8 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* Mask Global Interrupt Mask - see implementation note on p. 139 */ /* Mask Global Interrupt Mask - see implementation note on p. 139 */
/* of SHPC spec rev 1.0*/ /* of SHPC spec rev 1.0*/
temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
temp_dword |= 0x00000001; temp_dword |= GLOBAL_INTR_MASK;
temp_dword &= ~SERR_INTR_RSVDZ_MASK;
shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
intr_loc2 = shpc_readl(ctrl, INTR_LOC); intr_loc2 = shpc_readl(ctrl, INTR_LOC);
@ -1061,7 +1073,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
* Detect bit in Controller SERR-INT register * Detect bit in Controller SERR-INT register
*/ */
temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
temp_dword &= 0xfffdffff; temp_dword &= ~SERR_INTR_RSVDZ_MASK;
shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
ctrl->cmd_busy = 0; ctrl->cmd_busy = 0;
wake_up_interruptible(&ctrl->queue); wake_up_interruptible(&ctrl->queue);
@ -1105,7 +1117,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
if (!shpchp_poll_mode) { if (!shpchp_poll_mode) {
/* Unmask Global Interrupt Mask */ /* Unmask Global Interrupt Mask */
temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
temp_dword &= 0xfffffffe; temp_dword &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
} }
@ -1374,7 +1386,9 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
/* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
tempdword = 0x0003000f; tempdword |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK |
COMMAND_INTR_MASK | ARBITER_SERR_MASK);
tempdword &= ~SERR_INTR_RSVDZ_MASK;
shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword);
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
@ -1452,7 +1466,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
if (!shpchp_poll_mode) { if (!shpchp_poll_mode) {
/* Unmask all general input interrupts and SERR */ /* Unmask all general input interrupts and SERR */
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
tempdword = 0x0000000a; tempdword &= ~(GLOBAL_INTR_MASK | COMMAND_INTR_MASK |
SERR_INTR_RSVDZ_MASK);
shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword);
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);