mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-02 09:05:51 +00:00
[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:
parent
795eb5c4a7
commit
e713872369
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user