Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp693115ybl; Fri, 23 Aug 2019 07:06:09 -0700 (PDT) X-Google-Smtp-Source: APXvYqz/B9aexqzIoM+cXxwamb1LO6LxBI1UEby3HQKW3YeSYCphgUehi4YEqnOFIqfwUTBNDuEl X-Received: by 2002:aa7:90d4:: with SMTP id k20mr5324254pfk.78.1566569169477; Fri, 23 Aug 2019 07:06:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566569169; cv=none; d=google.com; s=arc-20160816; b=OTXoRps+RcYJ33pONe5L3SH9qvhWaSABNWsAq4DOd3kTegtEtj5j19Byj3FRmnczWS ILL9RLa6jR9NrNoYaIlLqXVwp0bmlp+HYub/X8eMwQ4Hzw0ESsqd/JpeLh5li1SX6Tal bpLwLhnf59Otqa1imu3/1B1K8lAl1+BQY788/qaoVCx0+pvTim73DpwQWUQb/jg7e732 kxGGci2TwACT9JvDsaFyCbbmiRvSfyZyUVodzx04AdENnCJbeCRCnOlpLKAD/2ivC8zu /0OijiTRqmQtnVWWTsql8lPbsvIVjQlEkL+gk6iUlInMLxk7PwfIotC1TqnzgVSgEboN JMpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=ZothcN6Bqy4o1FtBOntfj8dAuHCpsgXZRU/8m3bFF7w=; b=mqUZ9wrrYZCd88IAGFt0eL5CsdFbaViXR293OWub98Izu/UGBeaWfm1dleiHqp+KuL Y9OxyQJ5yKVdSUR27fMmTDhQYHpb6/L/d8tRoWsaFCb4lpjhw9U9WJMvKaSCgQLZ0Njo 83/90vCjTwLqx1tgLpseoSivSKmmBLmIigxrMw64BvkXPskcVBAtCCmGONv8XIyRp1ke D/KjM1mY6gEL8aBDd5eNOKiiPBdWB7Hp+OIjl0+s8Npfp0uGeMIXO5J8Xs5UGQ0VmCld ytzA8NtF38tIOxtoGuQ8R+IL71NBURVSIYfRA3KIxNGBb2OHDY1hSQKznITyZiBdh4a8 lmaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=p3oIMjED; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s8si1536987pfd.83.2019.08.23.07.05.53; Fri, 23 Aug 2019 07:06:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=p3oIMjED; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391118AbfHVVP4 (ORCPT + 99 others); Thu, 22 Aug 2019 17:15:56 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:34978 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390231AbfHVVPz (ORCPT ); Thu, 22 Aug 2019 17:15:55 -0400 Received: by mail-wm1-f65.google.com with SMTP id l2so7123891wmg.0; Thu, 22 Aug 2019 14:15:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZothcN6Bqy4o1FtBOntfj8dAuHCpsgXZRU/8m3bFF7w=; b=p3oIMjED49DVZk8QmpOAKxF1KXl/QAxS8z8WomGhSMLXXuj+wYRlCI4jyM02PpXm5X g1ngNLoYnFqR1eXXuLVOkHOs1sQY0dzVjNOTIr6EvPjL3X55A5sgeMWypD0/mSsdBwa1 9zRL37w1NfdFazzYDTrxNNhULI7N2nCqkzuCw/SWGEMfx+JZf2Fyd5qOuJ8cQKDFGOGr AMIDOvrfWjZda7CHB9CZxWT+YDSirjxOHvggJnK+jzjVX6IV7YLvxsSOKGYAyQq3/huq 7HLZEbZcyyNpRO/QIepmf3kdGulwvvn2Wxt0RjxSl6t/vel4n5nMzcGx6yKQP5AnPSha hleg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZothcN6Bqy4o1FtBOntfj8dAuHCpsgXZRU/8m3bFF7w=; b=YCe3Oh80yG2UKSYTEuI3880vI8D+YWCY3lKbnaFmwJ+mECnnB3zvoEb39q/ERJuBjZ RANuJ1V1oHpvez9Z3BaZaVId0/A2hfYTtti3xg/EHIvC8rN2vfnuk+4Gc84LmlpOiygC WciJAa68vba313393tFRhtbTZmVPDU4/tiFUgFjCJC17qnAI8kBJgFjQOBIdsmcvcTZ5 8utB5IbeonwL7UNZC68F/P0MoN3xNxvZihdaWUjoB+vLPu9VpcIOi4iRfSzNYSYzPpRJ YeYMX3zeHfL37YF0XH8hBJekAsHHEWy6G7/mPbLroACBDkj1ewHdQsrA2WR76zAYf8wS W/bQ== X-Gm-Message-State: APjAAAW0Gadi61BIEigGoQ0OEZ9uwzXKY5pD9u3QKNpT1XVUIS+QyiPh 46Z7UMKeo6B+IJEBu56W13ikWrd9 X-Received: by 2002:a1c:a6cd:: with SMTP id p196mr1020890wme.111.1566508552749; Thu, 22 Aug 2019 14:15:52 -0700 (PDT) Received: from localhost.localdomain ([86.126.25.232]) by smtp.gmail.com with ESMTPSA id g197sm578488wme.30.2019.08.22.14.15.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Aug 2019 14:15:52 -0700 (PDT) From: Vladimir Oltean To: broonie@kernel.org Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, netdev@vger.kernel.org, Vladimir Oltean Subject: [PATCH v2 4/5] spi: spi-fsl-dspi: Use poll mode in case the platform IRQ is missing Date: Fri, 23 Aug 2019 00:15:13 +0300 Message-Id: <20190822211514.19288-5-olteanv@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190822211514.19288-1-olteanv@gmail.com> References: <20190822211514.19288-1-olteanv@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On platforms like LS1021A which use TCFQ mode, an interrupt needs to be processed after each byte is TXed/RXed. I tried to make the DSPI implementation on this SoC operate in other, more efficient modes (EOQ, DMA) but it looks like it simply isn't possible. Therefore allow the driver to operate in poll mode, to ease a bit of this absurd amount of IRQ load generated in TCFQ mode. Doing so reduces both the net time it takes to transmit a SPI message, as well as the inter-frame jitter that occurs while doing so. Signed-off-by: Vladimir Oltean --- drivers/spi/spi-fsl-dspi.c | 87 ++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 6d2c7984ab0e..77db43f1290f 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -647,19 +647,12 @@ static void dspi_eoq_read(struct fsl_dspi *dspi) dspi_push_rx(dspi, fifo_read(dspi)); } -static irqreturn_t dspi_interrupt(int irq, void *dev_id) +static int dspi_rxtx(struct fsl_dspi *dspi) { - struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id; struct spi_message *msg = dspi->cur_msg; enum dspi_trans_mode trans_mode; - u32 spi_sr, spi_tcr; u16 spi_tcnt; - - regmap_read(dspi->regmap, SPI_SR, &spi_sr); - regmap_write(dspi->regmap, SPI_SR, spi_sr); - - if (!(spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF))) - return IRQ_NONE; + u32 spi_tcr; /* Get transfer counter (in number of SPI transfers). It was * reset to 0 when transfer(s) were started. @@ -675,17 +668,55 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) else if (trans_mode == DSPI_TCFQ_MODE) dspi_tcfq_read(dspi); - if (!dspi->len) { - dspi->waitflags = 1; - wake_up_interruptible(&dspi->waitq); - return IRQ_HANDLED; - } + if (!dspi->len) + /* Success! */ + return 0; if (trans_mode == DSPI_EOQ_MODE) dspi_eoq_write(dspi); else if (trans_mode == DSPI_TCFQ_MODE) dspi_tcfq_write(dspi); + return -EINPROGRESS; +} + +static int dspi_poll(struct fsl_dspi *dspi) +{ + int tries = 1000; + u32 spi_sr; + + do { + regmap_read(dspi->regmap, SPI_SR, &spi_sr); + regmap_write(dspi->regmap, SPI_SR, spi_sr); + + if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) + break; + } while (--tries); + + if (!tries) + return -ETIMEDOUT; + + return dspi_rxtx(dspi); +} + +static irqreturn_t dspi_interrupt(int irq, void *dev_id) +{ + struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id; + u32 spi_sr; + + regmap_read(dspi->regmap, SPI_SR, &spi_sr); + regmap_write(dspi->regmap, SPI_SR, spi_sr); + + if (!(spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF))) + return IRQ_NONE; + + dspi_rxtx(dspi); + + if (!dspi->len) { + dspi->waitflags = 1; + wake_up_interruptible(&dspi->waitq); + } + return IRQ_HANDLED; } @@ -773,13 +804,18 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, goto out; } - if (trans_mode != DSPI_DMA_MODE) { - if (wait_event_interruptible(dspi->waitq, - dspi->waitflags)) - dev_err(&dspi->pdev->dev, - "wait transfer complete fail!\n"); + if (!dspi->irq) { + do { + status = dspi_poll(dspi); + } while (status == -EINPROGRESS); + } else if (trans_mode != DSPI_DMA_MODE) { + status = wait_event_interruptible(dspi->waitq, + dspi->waitflags); dspi->waitflags = 0; } + if (status) + dev_err(&dspi->pdev->dev, + "Waiting for transfer to complete failed!\n"); if (transfer->delay_usecs) udelay(transfer->delay_usecs); @@ -1079,10 +1115,13 @@ static int dspi_probe(struct platform_device *pdev) goto out_ctlr_put; dspi_init(dspi); + dspi->irq = platform_get_irq(pdev, 0); - if (dspi->irq < 0) { - ret = dspi->irq; - goto out_clk_put; + if (dspi->irq <= 0) { + dev_info(&pdev->dev, + "can't get platform irq, using poll mode\n"); + dspi->irq = 0; + goto poll_mode; } ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, @@ -1092,6 +1131,9 @@ static int dspi_probe(struct platform_device *pdev) goto out_clk_put; } + init_waitqueue_head(&dspi->waitq); + +poll_mode: if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { ret = dspi_request_dma(dspi, res->start); if (ret < 0) { @@ -1103,7 +1145,6 @@ static int dspi_probe(struct platform_device *pdev) ctlr->max_speed_hz = clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; - init_waitqueue_head(&dspi->waitq); platform_set_drvdata(pdev, ctlr); ret = spi_register_controller(ctlr); -- 2.17.1