From patchwork Mon Mar 2 12:58:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 5912701 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 42FC19F373 for ; Mon, 2 Mar 2015 12:59:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5C4DF2021F for ; Mon, 2 Mar 2015 12:59:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7D28C20212 for ; Mon, 2 Mar 2015 12:59:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753768AbbCBM7B (ORCPT ); Mon, 2 Mar 2015 07:59:01 -0500 Received: from mga14.intel.com ([192.55.52.115]:12950 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751478AbbCBM7A (ORCPT ); Mon, 2 Mar 2015 07:59:00 -0500 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 02 Mar 2015 04:54:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,675,1418112000"; d="scan'208";a="673843094" Received: from smile.fi.intel.com (HELO smile) ([10.237.72.90]) by fmsmga001.fm.intel.com with ESMTP; 02 Mar 2015 04:58:58 -0800 Received: from andy by smile with local (Exim 4.84) (envelope-from ) id 1YSPw2-00026V-46; Mon, 02 Mar 2015 14:58:58 +0200 From: Andy Shevchenko To: Mark Brown , linux-spi@vger.kernel.org Cc: Andy Shevchenko Subject: [PATCH v4 1/3] spi: dw: make sure SPI controller is enabled Date: Mon, 2 Mar 2015 14:58:55 +0200 Message-Id: <1425301137-8043-2-git-send-email-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1425301137-8043-1-git-send-email-andriy.shevchenko@linux.intel.com> References: <1425301137-8043-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 was a previous transfer. 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 | 7 ++----- drivers/spi/spi-dw.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 05af817..2e9e1f9 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -272,8 +272,7 @@ static void giveback(struct dw_spi *dws) static void int_error_stop(struct dw_spi *dws, const char *msg) { - /* Stop the hw */ - spi_enable_chip(dws, 0); + spi_reset_chip(dws); dev_err(&dws->master->dev, "%s\n", msg); dws->cur_msg->state = ERROR_STATE; @@ -606,9 +605,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_reset_chip(dws); /* * Try to detect the FIFO depth if not set by interface driver, diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 3d32be6..1a7f083 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -217,6 +217,18 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) } /* + * 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 inline void spi_reset_chip(struct dw_spi *dws) +{ + spi_enable_chip(dws, 0); + spi_mask_intr(dws, 0xff); + spi_enable_chip(dws, 1); +} + +/* * Each SPI slave device to work with dw_api controller should * has such a structure claiming its working mode (PIO/DMA etc), * which can be save in the "controller_data" member of the