[PATCH] SHPC: Fix SHPC Contoller SERR-INT Register bits access
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Tue, 2 May 2006 02:12:37 +0000 (11:12 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 19 Jun 2006 21:13:23 +0000 (14:13 -0700)
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>
drivers/pci/hotplug/shpchp_hpc.c

index 285a21d36524fee61b97a274f731fed6a434f5cb..e2a8671545f2b1ff08210294aa9867ba681746d3 100644 (file)
 #define        MRLSENSOR               0x40000000
 #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
  */
@@ -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 */
                /* of SHPC spec rev 1.0*/
                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);
 
                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
                 */
                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);
                ctrl->cmd_busy = 0;
                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) {
                /* Unmask Global Interrupt Mask */
                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);
        }
        
@@ -1374,7 +1386,9 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
        tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
        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);
        tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
        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) {
                /* Unmask all general input interrupts and SERR */
                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);
                tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
                dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);