From patchwork Fri Feb 27 16:36:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 5901961 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0D3BCBF440 for ; Fri, 27 Feb 2015 16:36:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 291C020260 for ; Fri, 27 Feb 2015 16:36:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3FC142022D for ; Fri, 27 Feb 2015 16:36:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752280AbbB0QgU (ORCPT ); Fri, 27 Feb 2015 11:36:20 -0500 Received: from mga03.intel.com ([134.134.136.65]:37061 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752158AbbB0QgU (ORCPT ); Fri, 27 Feb 2015 11:36:20 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 27 Feb 2015 08:30:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,660,1418112000"; d="scan'208";a="684439350" Received: from smile.fi.intel.com (HELO smile) ([10.237.72.90]) by fmsmga002.fm.intel.com with ESMTP; 27 Feb 2015 08:36:17 -0800 Received: from andy by smile with local (Exim 4.84) (envelope-from ) id 1YRNth-0002Zm-ET; Fri, 27 Feb 2015 18:36:17 +0200 From: Andy Shevchenko To: Mark Brown , linux-spi@vger.kernel.org Cc: Andy Shevchenko Subject: [PATCH v3 1/3] spi: dw: make sure SPI controller is enabled Date: Fri, 27 Feb 2015 18:36:15 +0200 Message-Id: <1425054977-9859-2-git-send-email-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1425054977-9859-1-git-send-email-andriy.shevchenko@linux.intel.com> References: <1425054977-9859-1-git-send-email-andriy.shevchenko@linux.intel.com> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The error handling is partially broken since the controller is disabled on error and is not re-enabled until condition occurs, i.e. mode (poll, PIO/DMA), chip (cs_change), or speed (clk_div) is changed. In the result of these changes we will have a predictable state of the SPi controller independently on how successfull a previous transfer was. The patch disables interrupts and re-enables the SPI controller wherever it needs to be done. Thus most of the time the SPI controller is kept enabled. The runtime PM, when it will be implemented, must take care of the controller disabling and re-enabling. Signed-off-by: Andy Shevchenko --- drivers/spi/spi-dw.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 05af817..24aaaf98 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -270,10 +270,21 @@ static void giveback(struct dw_spi *dws) spi_finalize_current_message(dws->master); } -static void int_error_stop(struct dw_spi *dws, const char *msg) +/* + * This does disable the SPI controller, interrupts, and re-enable the + * controller back. Transmit and receive FIFO buffers are cleared when the + * device is disabled. + */ +static void spi_disable_intr(struct dw_spi *dws) { - /* Stop the hw */ spi_enable_chip(dws, 0); + spi_mask_intr(dws, 0xff); + spi_enable_chip(dws, 1); +} + +static void int_error_stop(struct dw_spi *dws, const char *msg) +{ + spi_disable_intr(dws); dev_err(&dws->master->dev, "%s\n", msg); dws->cur_msg->state = ERROR_STATE; @@ -606,9 +617,7 @@ static void dw_spi_cleanup(struct spi_device *spi) /* Restart the controller, disable all interrupts, clean rx fifo */ static void spi_hw_init(struct device *dev, struct dw_spi *dws) { - spi_enable_chip(dws, 0); - spi_mask_intr(dws, 0xff); - spi_enable_chip(dws, 1); + spi_disable_intr(dws); /* * Try to detect the FIFO depth if not set by interface driver,