From patchwork Tue Jun 16 00:09:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 11606043 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0AB63913 for ; Tue, 16 Jun 2020 00:09:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EF66220786 for ; Tue, 16 Jun 2020 00:09:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726468AbgFPAJl (ORCPT ); Mon, 15 Jun 2020 20:09:41 -0400 Received: from foss.arm.com ([217.140.110.172]:56968 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726452AbgFPAJl (ORCPT ); Mon, 15 Jun 2020 20:09:41 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 457A531B; Mon, 15 Jun 2020 17:09:40 -0700 (PDT) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.37]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id B11E93F73C; Mon, 15 Jun 2020 17:09:38 -0700 (PDT) From: Robin Murphy To: broonie@kernel.org, nsaenzjulienne@suse.de, f.fainelli@gmail.com, rjui@broadcom.com, sbranden@broadcom.com Cc: bcm-kernel-feedback-list@broadcom.com, linux-spi@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@martin.sperl.org, lukas@wunner.de, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] spi: bcm3835: Tidy up bcm2835_spi_reset_hw() Date: Tue, 16 Jun 2020 01:09:27 +0100 Message-Id: X-Mailer: git-send-email 2.23.0.dirty In-Reply-To: References: MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org It doesn't need a struct spi_controller, and every callsite has already retrieved the appropriate struct bcm2835_spi, so just pass that directly. Signed-off-by: Robin Murphy --- drivers/spi/spi-bcm2835.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 237bd306c268..524a91e52111 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -335,9 +335,8 @@ static inline void bcm2835_wr_fifo_blind(struct bcm2835_spi *bs, int count) } } -static void bcm2835_spi_reset_hw(struct spi_controller *ctlr) +static void bcm2835_spi_reset_hw(struct bcm2835_spi *bs) { - struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); /* Disable SPI interrupts and transfer */ @@ -386,7 +385,7 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) if (!bs->rx_len) { /* Transfer complete - reset SPI HW */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); /* wake up the framework */ complete(&ctlr->xfer_completion); } @@ -607,7 +606,7 @@ static void bcm2835_spi_dma_rx_done(void *data) bcm2835_spi_undo_prologue(bs); /* reset fifo and HW */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); /* and mark as completed */; complete(&ctlr->xfer_completion); @@ -641,7 +640,7 @@ static void bcm2835_spi_dma_tx_done(void *data) dmaengine_terminate_async(ctlr->dma_rx); bcm2835_spi_undo_prologue(bs); - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); complete(&ctlr->xfer_completion); } @@ -825,14 +824,14 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr, if (!bs->rx_buf && !bs->tx_dma_active && cmpxchg(&bs->rx_dma_active, true, false)) { dmaengine_terminate_async(ctlr->dma_rx); - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); } /* wait for wakeup in framework */ return 1; err_reset_hw: - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); bcm2835_spi_undo_prologue(bs); return ret; } @@ -1074,7 +1073,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_controller *ctlr, } /* Transfer complete - reset SPI HW */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); /* and return without waiting for completion */ return 0; } @@ -1182,7 +1181,7 @@ static void bcm2835_spi_handle_err(struct spi_controller *ctlr, bcm2835_spi_undo_prologue(bs); /* and reset */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); } static int chip_match_name(struct gpio_chip *chip, void *data) From patchwork Tue Jun 16 00:09:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 11606041 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 37E2B13A0 for ; Tue, 16 Jun 2020 00:09:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2AA5520786 for ; Tue, 16 Jun 2020 00:09:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726535AbgFPAJp (ORCPT ); Mon, 15 Jun 2020 20:09:45 -0400 Received: from foss.arm.com ([217.140.110.172]:56986 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726486AbgFPAJm (ORCPT ); Mon, 15 Jun 2020 20:09:42 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0D9A91042; Mon, 15 Jun 2020 17:09:42 -0700 (PDT) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.37]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 794253F73C; Mon, 15 Jun 2020 17:09:40 -0700 (PDT) From: Robin Murphy To: broonie@kernel.org, nsaenzjulienne@suse.de, f.fainelli@gmail.com, rjui@broadcom.com, sbranden@broadcom.com Cc: bcm-kernel-feedback-list@broadcom.com, linux-spi@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@martin.sperl.org, lukas@wunner.de, linux-kernel@vger.kernel.org Subject: [PATCH 2/3] spi: bcm2835: Micro-optimise IRQ handler Date: Tue, 16 Jun 2020 01:09:28 +0100 Message-Id: <6b401cb521539caffab21f05b4c8cba6c9d27c6e.1592261248.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.23.0.dirty In-Reply-To: References: MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org The IRQ handler only needs the struct spi_controller for the sake of the completion at the end of a transfer. Passing the struct bcm2835_spi directly as the IRQ data allows that level of indirection to be pushed into the completion path for the reverse lookup, and avoided entirely in all other cases. This saves one explicit load in the critical path, plus (for a GCC 8.3 build) two registers worth of stack frame overhead. Signed-off-by: Robin Murphy --- drivers/spi/spi-bcm2835.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 524a91e52111..aec70ac8911e 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -86,6 +86,7 @@ MODULE_PARM_DESC(polling_limit_us, * @clk: core clock, divided to calculate serial clock * @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full * @tfr: SPI transfer currently processed + * @ctlr: SPI controller reverse lookup * @tx_buf: pointer whence next transmitted byte is read * @rx_buf: pointer where next received byte is written * @tx_len: remaining bytes to transmit @@ -125,6 +126,7 @@ struct bcm2835_spi { struct clk *clk; int irq; struct spi_transfer *tfr; + struct spi_controller *ctlr; const u8 *tx_buf; u8 *rx_buf; int tx_len; @@ -362,8 +364,7 @@ static void bcm2835_spi_reset_hw(struct bcm2835_spi *bs) static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) { - struct spi_controller *ctlr = dev_id; - struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); + struct bcm2835_spi *bs = dev_id; u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); /* @@ -387,7 +388,7 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) /* Transfer complete - reset SPI HW */ bcm2835_spi_reset_hw(bs); /* wake up the framework */ - complete(&ctlr->xfer_completion); + complete(&bs->ctlr->xfer_completion); } return IRQ_HANDLED; @@ -1310,6 +1311,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ctlr->dev.of_node = pdev->dev.of_node; bs = spi_controller_get_devdata(ctlr); + bs->ctlr = ctlr; bs->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(bs->regs)) { @@ -1344,7 +1346,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, - dev_name(&pdev->dev), ctlr); + dev_name(&pdev->dev), bs); if (err) { dev_err(&pdev->dev, "could not request IRQ: %d\n", err); goto out_dma_release; From patchwork Tue Jun 16 00:09:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 11606039 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7A0B590 for ; Tue, 16 Jun 2020 00:09:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6BF8B2078E for ; Tue, 16 Jun 2020 00:09:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726540AbgFPAJp (ORCPT ); Mon, 15 Jun 2020 20:09:45 -0400 Received: from foss.arm.com ([217.140.110.172]:57002 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726452AbgFPAJo (ORCPT ); Mon, 15 Jun 2020 20:09:44 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id CD7FC1045; Mon, 15 Jun 2020 17:09:43 -0700 (PDT) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.37]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 447363F73C; Mon, 15 Jun 2020 17:09:42 -0700 (PDT) From: Robin Murphy To: broonie@kernel.org, nsaenzjulienne@suse.de, f.fainelli@gmail.com, rjui@broadcom.com, sbranden@broadcom.com Cc: bcm-kernel-feedback-list@broadcom.com, linux-spi@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@martin.sperl.org, lukas@wunner.de, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] spi: bcm2835: Micro-optimise FIFO loops Date: Tue, 16 Jun 2020 01:09:29 +0100 Message-Id: <9242863077acf9a64e4b3720e479855b88d19e82.1592261248.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.23.0.dirty In-Reply-To: References: MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org The blind and counted loops are always called with nonzero count, so convert them to do-while loops that lead to slightly more efficient code generation. With GCC 8.3 this shaves off 1-2 instructions per iteration in each case. Signed-off-by: Robin Murphy --- drivers/spi/spi-bcm2835.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index aec70ac8911e..e9a91adf03eb 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -245,13 +245,13 @@ static inline void bcm2835_rd_fifo_count(struct bcm2835_spi *bs, int count) bs->rx_len -= count; - while (count > 0) { + do { val = bcm2835_rd(bs, BCM2835_SPI_FIFO); len = min(count, 4); memcpy(bs->rx_buf, &val, len); bs->rx_buf += len; count -= 4; - } + } while (count > 0); } /** @@ -271,7 +271,7 @@ static inline void bcm2835_wr_fifo_count(struct bcm2835_spi *bs, int count) bs->tx_len -= count; - while (count > 0) { + do { if (bs->tx_buf) { len = min(count, 4); memcpy(&val, bs->tx_buf, len); @@ -281,7 +281,7 @@ static inline void bcm2835_wr_fifo_count(struct bcm2835_spi *bs, int count) } bcm2835_wr(bs, BCM2835_SPI_FIFO, val); count -= 4; - } + } while (count > 0); } /** @@ -310,12 +310,11 @@ static inline void bcm2835_rd_fifo_blind(struct bcm2835_spi *bs, int count) count = min(count, bs->rx_len); bs->rx_len -= count; - while (count) { + do { val = bcm2835_rd(bs, BCM2835_SPI_FIFO); if (bs->rx_buf) *bs->rx_buf++ = val; - count--; - } + } while (--count); } /** @@ -330,11 +329,10 @@ static inline void bcm2835_wr_fifo_blind(struct bcm2835_spi *bs, int count) count = min(count, bs->tx_len); bs->tx_len -= count; - while (count) { + do { val = bs->tx_buf ? *bs->tx_buf++ : 0; bcm2835_wr(bs, BCM2835_SPI_FIFO, val); - count--; - } + } while (--count); } static void bcm2835_spi_reset_hw(struct bcm2835_spi *bs)