From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932936AbdACGpp (ORCPT ); Tue, 3 Jan 2017 01:45:45 -0500 Received: from mga01.intel.com ([192.55.52.88]:13566 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752782AbdACGpi (ORCPT ); Tue, 3 Jan 2017 01:45:38 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,451,1477983600"; d="scan'208";a="45247256" From: Lu Baolu To: Mathias Nyman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu , , Felipe Balbi Subject: [PATCH v2 1/1] usb: xhci: clear EINT bit in status correctly Date: Tue, 3 Jan 2017 14:45:22 +0800 Message-Id: <1483425922-30156-1-git-send-email-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.1.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org EINT(Event Interrupt) is a write-1-to-clear type of bit in xhci status register. It should be cleared by writing a 1. Writing 0 to this bit has no effect. Xhci driver tries to clear this bit by writing 0 to it. This is not the right way to go. This patch corrects this by reading the register first, then clearing all RO/RW1C/RsvZ bits and setting the clearing bit, and writing back the new value at last. Xhci spec requires that software that uses EINT shall clear it prior to clearing any IP flags in section 5.4.2. This is the reason why this patch is CC'ed stable as well. Cc: # v3.14+ Cc: Felipe Balbi Signed-off-by: Lu Baolu --- Change log: v1->v2: - Fixed a warning reported by 0-day kbuild robot. drivers/usb/host/xhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1cd5641..bb08c6b 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -721,7 +721,7 @@ void xhci_stop(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Disabling event ring interrupts"); temp = readl(&xhci->op_regs->status); - writel(temp & ~STS_EINT, &xhci->op_regs->status); + writel((temp & ~0x1fff) | STS_EINT, &xhci->op_regs->status); temp = readl(&xhci->ir_set->irq_pending); writel(ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending); xhci_print_ir_set(xhci, 0); @@ -1054,7 +1054,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci_dbg(xhci, "// Disabling event ring interrupts\n"); temp = readl(&xhci->op_regs->status); - writel(temp & ~STS_EINT, &xhci->op_regs->status); + writel((temp & ~0x1fff) | STS_EINT, &xhci->op_regs->status); temp = readl(&xhci->ir_set->irq_pending); writel(ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending); xhci_print_ir_set(xhci, 0); -- 2.1.4