Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753830AbbLKHE1 (ORCPT ); Fri, 11 Dec 2015 02:04:27 -0500 Received: from mail-bl2on0053.outbound.protection.outlook.com ([65.55.169.53]:3808 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753587AbbLKHEY (ORCPT ); Fri, 11 Dec 2015 02:04:24 -0500 Authentication-Results: spf=none (sender IP is 165.204.84.222) smtp.mailfrom=amd.com; linux.intel.com; dkim=none (message not signed) header.d=none;linux.intel.com; dmarc=permerror action=none header.from=amd.com; X-WSS-ID: 0NZ6MB6-08-E66-02 X-M-MSG: From: Xiangliang Yu To: , , , , , CC: , Xiangliang Yu Subject: [PATCH v2] I2C: designware: fix IO timeout issue for AMD controller Date: Fri, 11 Dec 2015 20:02:53 +0800 Message-ID: <1449835373-4669-1-git-send-email-Xiangliang.Yu@amd.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 Content-Type: text/plain X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:165.204.84.222;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(428002)(189002)(199003)(19580395003)(101416001)(106466001)(92566002)(229853001)(19580405001)(87936001)(86362001)(77096005)(50986999)(53416004)(105586002)(2201001)(5003600100002)(50226001)(586003)(36756003)(50466002)(48376002)(47776003)(1096002)(1220700001)(97736004)(5003940100001)(5001770100001)(11100500001)(189998001)(5008740100001);DIR:OUT;SFP:1101;SCL:1;SRVR:BN4PR12MB0852;H:atltwp02.amd.com;FPR:;SPF:None;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BN4PR12MB0852;2:+vNryaaHUHEyPgJ7ctT64qsDA5YZJw3EbXhwSfoQ1SGoUCSqYaK2mGAfNdUVGy2oUqLYNplGITzji6mn1Il1sXQ/pYTa3ixqGB2bxOAS9t2VtTvUwgLUs74yaVFOSKiU2tp2WTadUqh2orS7Hx8b5w==;3:ZzL8rpykU+D3mGi191ifyUTTZpKfTjvLcYd1RTSdj+roqmrj6ezjV7/AFXyYdoZiAvSBLzFnCt1ff2CQ4lfaqknc8hT88UyOvKPVph8ol2xR2JFP7lDQpdu4nTSotUbWywVCBmzGk7ACgptslDSaIPdNqPlx+fmBCLLiuYKVR7idjL7DlUE2WXnP3wLsvbJyyhfAdCFSFUZl9Ty3vNdRgikWpQTnicSDawSRMRfhg/o=;25:kdFlFo3MTpmg/ChFKF4b8zFnYAMmHpiuxiY1IMU/n33v4YLlw+z05/WzcaIkei1RmqYBlhuRo/UZmuVICtiLR0jLR7/M/sd+mQw8v5LrB9ZkyQq2GfZEZ3GVlkVtU8RsVNQr1NJNFEkwIy/wewHFyx9QpZm/NeS09uvmIp/9TprK5S1hYfgN6Sm1MhpoSJT51tiEugyIZNXTB2xRVhoy5dPcQfc/3/tRsJJpL4+KTf+xv1egsBmqYpiALe5XEz8r X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN4PR12MB0852; X-Microsoft-Exchange-Diagnostics: 1;BN4PR12MB0852;20:IKTu14ZMAPY1QorFl9o8cXXqJFFyLvsD8XmJEqIjp97jp9q90tjUQJr9s3H3zhD7KPaKsPOr1j0bOg3la127aXXjt8CmHWzx1X+ga+ZMxjZ5hqqo8VFAKr2QB0fCfTpElzuvS+ppA2LDWTO/krH/+kluDgmsfwdYyJM+8NlDurSZPyamys5Z5g9/3TS5pe01b0htCAipm895f4w62oSd9wTD7hb1YQyEb+45p1791GUMO2ib9dMcjBROBldFmeSE7ylFsC44IpXGFv6stBTHDO6TWWf+LL9ShBpCL/DGfrqYSdSTS5InlqLmIscBs4MqmbPIbg9O0MvUtJ+tWcAfcZNsXNoiGnTr0RwSngfgS6y5YwXlci+lX0BoH3riOrXOEZtAcs9d3wp6CgSod7t5Q64cvzwQreCzjFOFy7U97s8zxJXvcIKOFuZRVf3kqFik3HxiIHy2PM4jrwKwi9rhjDp/sZ3L9622JPLxlylZ3AY+hkn45HGdBJ5JK3QM26bj;4:mNNJLrBUQtbymV5POjLzuOCsRnKGCkgQrPNfciyEZJF2n7XpaDe19dvVs3Llkd4Qoc4c0vaEMulPYIzSdlXEa/Ln2MaQGKkIMj+r++Kd7FiBMfs8VDSPd17Az34PCkhUGBXe4/NX8NqRmFVfau1hCPmduP2IvEENQM+JSgXWEkVWc0mXbJUwMe4Pe3457eXt0gdEXmaFPKUkUevrpGvncFPLwBp0UcUYjT4aeN6XnHCwerKgYt+zUOoAtSREBf8fRBlZX+4kTpUY2zYVkz6kwuDwDtXSTiuEFn8e2fZFvQm90vSo+9xxMX6Oo5sXrRs2nmUIz2jynOAm2J8DhwilFysv+B5L6SG87SNr6rU6gFE68Hf7P1aA+ssJWR+FBxOIYIq5I6FbGRycu3Fg+1i8MmsE0Fv93o7qGHRXc2hRcQM= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(3002001)(10201501046);SRVR:BN4PR12MB0852;BCL:0;PCL:0;RULEID:;SRVR:BN4PR12MB0852; X-Forefront-PRVS: 0787459938 X-Microsoft-Exchange-Diagnostics: 1;BN4PR12MB0852;23:7fHjUIvC1r1sgGr+yPR3DZvEUkSk+0+OK8Qot4FdmXbwoa3Hjl2Ga+H0oKP2Q9gXnDmdOwldIaerXR4RRxgwR13YNh5Za5xO/zVTgzqyUpgtlIyHPHu77a3hRRA4C9Kbw8Zs+ZX2XeqpwUSafK5zCt7hvAkuy7jpgSm3+LYN3TtrmlY3qOxo8K1Noi04zxMCNJ6EqfLMZ7NDUmkJ/l7IPaiwxiwGoSAScV5USXHhz7OjlKC1a1SiCjQqGY0/NZ3/VZNQurldCQlTjgCAjfXPi20A+hZbZO3/qqwMNl7kJcq+BNTbG7uqBq7sXjFkywtoVkp0T40FZtxUEpuKx5Psx0PrwWZc0mqj1svsVcf/dzm0aCR2wg8mvlmBeR3nfh46Hq2748iVO0x2V/rPHtVXpt1l4W6VzqW6qXYqFYuScWsOmEjGJEqeq/iCD4uzv7Ae+iyHx5J8ov3mLJtkb4AP8ZYYkuiHoU3bzx8oBzPa569z5LnuOdvXGMe+WyCkZYKF7d2DwxKft2uSGnuQTxg0ayvlAHKY89mJEYEn62dbzsjlRSyh/43pFpjFqQfW4oqYpMQMPYseohvN35xq//XVZty09bc7h898ZBXjK1r2wuatpSZEaypEErG132M5/Q1ftTgoCnUFja0PMzgQKrFaffBp+y/F2GhU1wseexYpqPQQZmc29UzKes+k1r9vaiaXbsYZizEkRxNESB1a52vuU/vidqOsX/5JyOEOrjvdC0ckdSEi2Ms9fdLnwJQkd+6vMwGMsNMWHrba9ByNHLdpkFlUL+MaFkUs4fASA5j8T2XF03m3+qRDfwOEIvk+336jSrz0/Eqs67ueKXFx3khlPbEnAey1EA5gNbT7JWSp67RbgN4tHoIolOa2yohZ6MsRpViQvFD0X1HHGtfslpZ4HZNZ2Sw8ym1PFVDIqPNsNks= X-Microsoft-Exchange-Diagnostics: 1;BN4PR12MB0852;5:8+21j5fE++Kb4uWK2Hu7jfuaN+hbDMqQStrQY5HdK4+YRNtEbjtOtyUu1ZY8sTv+sFOg4PDVc9jQOk71PcckMhc1p1NVytywktbQ9M9hfFtPjkPtCq0E7k1xWt7UlRCkEHXMn64rhONwW1neJDVfYA==;24:cf33wADL5BGPfqWlC2zAGQP38zsTFjoA+kEpkyc1zHqeVvU8+OxFAL3czYMXfU6rKnVYGCcOk+f44XsKL+MDXgiIDuAgkShTYh9VOTKol94=;20:TPtAAdWe6cWxh39/kbQsGIkWnP5WtOn9/SkDvECRbiX8kqlw7hEFe1A4FUEXm4/tdgC0Bo3Q7BGopAGeQ97/iTYT2JWNUriRcS/sMYAdT4Ugs/0ruSmnmfN+oRANG75lQS3Iyjswc7Hk9FmmM1Q4n+u5GXplMCBX4ctCFHe8vVNorFAVsnP2eM870KVsbYQiHJgCZJT2Gn5DlXT+q0vtZAGNZ1HcWo4BLbgd0I39Rg6gDvU1IPcR0WNelXPRaTU+ SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Dec 2015 07:04:19.7562 (UTC) X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.222];Helo=[atltwp02.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN4PR12MB0852 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3370 Lines: 92 Because of some hardware limitation, AMD I2C controller can't trigger pending interrupt if interrupt status has been changed after clearing interrupt status bits. Then, I2C will lost interrupt and IO timeout. According to hardware design, this patch implements a workaround to disable i2c controller interrupt and re-enable i2c interrupt before exiting ISR. To reduce the performance impacts on other vendors, use unlikely function to check flag in ISR. --- Changes in v2: - pass flags with ->driver_data - unmask interrupt right after masking Signed-off-by: Xiangliang Yu --- drivers/i2c/busses/i2c-designware-core.c | 6 ++++++ drivers/i2c/busses/i2c-designware-core.h | 1 + drivers/i2c/busses/i2c-designware-platdrv.c | 7 ++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 8c48b27..de7fbbb 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -813,6 +813,12 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) tx_aborted: if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) complete(&dev->cmd_complete); + else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) { + /* workaround to trigger pending interrupt */ + stat = dw_readl(dev, DW_IC_INTR_MASK); + i2c_dw_disable_int(dev); + dw_writel(dev, stat, DW_IC_INTR_MASK); + } return IRQ_HANDLED; } diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 1d50898..9ffb63a 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -111,6 +111,7 @@ struct dw_i2c_dev { #define ACCESS_SWAP 0x00000001 #define ACCESS_16BIT 0x00000002 +#define ACCESS_INTR_MASK 0x00000004 extern int i2c_dw_init(struct dw_i2c_dev *dev); extern void i2c_dw_disable(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 809579e..f03ea71 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -93,6 +93,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], static int dw_i2c_acpi_configure(struct platform_device *pdev) { struct dw_i2c_dev *dev = platform_get_drvdata(pdev); + const struct acpi_device_id *id; dev->adapter.nr = -1; dev->tx_fifo_depth = 32; @@ -106,6 +107,10 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev) dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &dev->sda_hold_time); + id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev); + if (id && id->driver_data) + dev->accessor_flags |= (u32)id->driver_data; + return 0; } @@ -116,7 +121,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = { { "INT3433", 0 }, { "80860F41", 0 }, { "808622C1", 0 }, - { "AMD0010", 0 }, + { "AMD0010", ACCESS_INTR_MASK }, { } }; MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/