From patchwork Fri Apr 24 10:42:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dilip Kota X-Patchwork-Id: 11507499 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 8440613B2 for ; Fri, 24 Apr 2020 10:43:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 723522071E for ; Fri, 24 Apr 2020 10:43:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726907AbgDXKne (ORCPT ); Fri, 24 Apr 2020 06:43:34 -0400 Received: from mga14.intel.com ([192.55.52.115]:54501 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726815AbgDXKnd (ORCPT ); Fri, 24 Apr 2020 06:43:33 -0400 IronPort-SDR: tRR8oNGNPruI9ica38lPNORZtfJi+vwlzNeCzoqtiPu/DrviI2yH4PkkIeezhpi5QL/SNWNmkn zSsN4zunMOJw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 03:43:32 -0700 IronPort-SDR: qH+g6aud2kSY1yU53VAt1ke6qVjY8cWTVhupc5SVjH37+rB75skLOFbepHF+kIN/f9nH8yGVZB jN2me8jxPCcQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,311,1583222400"; d="scan'208";a="274560638" Received: from sgsxdev004.isng.intel.com (HELO localhost) ([10.226.88.13]) by orsmga002.jf.intel.com with ESMTP; 24 Apr 2020 03:43:29 -0700 From: Dilip Kota To: broonie@kernel.org, robh@kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, daniel.schwierzeck@gmail.com, hauke@hauke-m.de, andriy.shevchenko@intel.com, cheol.yong.kim@intel.com, chuanhua.lei@linux.intel.com, qi-ming.wu@intel.com, Dilip Kota Subject: [PATCH 1/4] spi: lantiq: Synchronize interrupt handlers and transfers Date: Fri, 24 Apr 2020 18:42:30 +0800 Message-Id: <3bf88d24b9cad9f3df1da8ed65bf55c05693b0f2.1587702428.git.eswara.kota@linux.intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Synchronize tx, rx and error interrupts by registering to the same interrupt handler. Interrupt handler will recognize and process the appropriate interrupt on the basis of interrupt status register. Also, establish synchronization between the interrupt handler and transfer operation by taking the locks and registering the interrupt handler as thread IRQ which avoids the bottom half. Fixes the wrongly populated interrupt register offsets too. Fixes: 17f84b793c01 ("spi: lantiq-ssc: add support for Lantiq SSC SPI controller") Fixes: ad2fca0721d1 ("spi: lantiq-ssc: add LTQ_ prefix to defines") Signed-off-by: Dilip Kota --- drivers/spi/spi-lantiq-ssc.c | 89 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c index 1fd7ee53d451..b67f5925bcb0 100644 --- a/drivers/spi/spi-lantiq-ssc.c +++ b/drivers/spi/spi-lantiq-ssc.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -13,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -50,8 +50,8 @@ #define LTQ_SPI_RXCNT 0x84 #define LTQ_SPI_DMACON 0xec #define LTQ_SPI_IRNEN 0xf4 -#define LTQ_SPI_IRNICR 0xf8 -#define LTQ_SPI_IRNCR 0xfc +#define LTQ_SPI_IRNCR 0xf8 +#define LTQ_SPI_IRNICR 0xfc #define LTQ_SPI_CLC_SMC_S 16 /* Clock divider for sleep mode */ #define LTQ_SPI_CLC_SMC_M (0xFF << LTQ_SPI_CLC_SMC_S) @@ -171,9 +171,7 @@ struct lantiq_ssc_spi { struct clk *fpi_clk; const struct lantiq_ssc_hwcfg *hwcfg; - spinlock_t lock; - struct workqueue_struct *wq; - struct work_struct work; + struct mutex lock; const u8 *tx; u8 *rx; @@ -186,6 +184,8 @@ struct lantiq_ssc_spi { unsigned int base_cs; }; +static void lantiq_ssc_busy_wait(struct lantiq_ssc_spi *spi); + static u32 lantiq_ssc_readl(const struct lantiq_ssc_spi *spi, u32 reg) { return __raw_readl(spi->regbase + reg); @@ -464,8 +464,6 @@ static int lantiq_ssc_unprepare_message(struct spi_master *master, { struct lantiq_ssc_spi *spi = spi_master_get_devdata(master); - flush_workqueue(spi->wq); - /* Disable transmitter and receiver while idle */ lantiq_ssc_maskl(spi, 0, LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF, LTQ_SPI_CON); @@ -610,10 +608,8 @@ static void rx_request(struct lantiq_ssc_spi *spi) lantiq_ssc_writel(spi, rxreq, LTQ_SPI_RXREQ); } -static irqreturn_t lantiq_ssc_xmit_interrupt(int irq, void *data) +static irqreturn_t lantiq_ssc_xmit_interrupt(struct lantiq_ssc_spi *spi) { - struct lantiq_ssc_spi *spi = data; - if (spi->tx) { if (spi->rx && spi->rx_todo) rx_fifo_read_full_duplex(spi); @@ -638,19 +634,15 @@ static irqreturn_t lantiq_ssc_xmit_interrupt(int irq, void *data) return IRQ_HANDLED; completed: - queue_work(spi->wq, &spi->work); + lantiq_ssc_busy_wait(spi); return IRQ_HANDLED; } -static irqreturn_t lantiq_ssc_err_interrupt(int irq, void *data) +static irqreturn_t lantiq_ssc_err_interrupt(struct lantiq_ssc_spi *spi) { - struct lantiq_ssc_spi *spi = data; u32 stat = lantiq_ssc_readl(spi, LTQ_SPI_STAT); - if (!(stat & LTQ_SPI_STAT_ERRORS)) - return IRQ_NONE; - if (stat & LTQ_SPI_STAT_RUE) dev_err(spi->dev, "receive underflow error\n"); if (stat & LTQ_SPI_STAT_TUE) @@ -670,17 +662,39 @@ static irqreturn_t lantiq_ssc_err_interrupt(int irq, void *data) /* set bad status so it can be retried */ if (spi->master->cur_msg) spi->master->cur_msg->status = -EIO; - queue_work(spi->wq, &spi->work); + + spi_finalize_current_transfer(spi->master); return IRQ_HANDLED; } +static irqreturn_t lantiq_ssc_isr(int irq, void *data) +{ + struct lantiq_ssc_spi *spi = data; + const struct lantiq_ssc_hwcfg *hwcfg = spi->hwcfg; + irqreturn_t ret = IRQ_NONE; + u32 val; + + mutex_lock(&spi->lock); + val = lantiq_ssc_readl(spi, LTQ_SPI_IRNCR); + lantiq_ssc_maskl(spi, val, 0, LTQ_SPI_IRNEN); + + if (val & LTQ_SPI_IRNEN_E) + ret = lantiq_ssc_err_interrupt(spi); + + if ((val & hwcfg->irnen_t) || (val & hwcfg->irnen_r)) + ret = lantiq_ssc_xmit_interrupt(spi); + + lantiq_ssc_maskl(spi, 0, val, LTQ_SPI_IRNEN); + mutex_unlock(&spi->lock); + + return ret; +} + static int transfer_start(struct lantiq_ssc_spi *spi, struct spi_device *spidev, struct spi_transfer *t) { - unsigned long flags; - - spin_lock_irqsave(&spi->lock, flags); + mutex_lock(&spi->lock); spi->tx = t->tx_buf; spi->rx = t->rx_buf; @@ -700,7 +714,7 @@ static int transfer_start(struct lantiq_ssc_spi *spi, struct spi_device *spidev, rx_request(spi); } - spin_unlock_irqrestore(&spi->lock, flags); + mutex_unlock(&spi->lock); return t->len; } @@ -712,14 +726,11 @@ static int transfer_start(struct lantiq_ssc_spi *spi, struct spi_device *spidev, * write the last word to the wire, not when it is finished. Do busy * waiting till it finishes. */ -static void lantiq_ssc_bussy_work(struct work_struct *work) +static void lantiq_ssc_busy_wait(struct lantiq_ssc_spi *spi) { - struct lantiq_ssc_spi *spi; unsigned long long timeout = 8LL * 1000LL; unsigned long end; - spi = container_of(work, typeof(*spi), work); - do_div(timeout, spi->speed_hz); timeout += timeout + 100; /* some tolerance */ @@ -838,18 +849,18 @@ static int lantiq_ssc_probe(struct platform_device *pdev) goto err_master_put; } - err = devm_request_irq(dev, rx_irq, lantiq_ssc_xmit_interrupt, - 0, LTQ_SPI_RX_IRQ_NAME, spi); + err = devm_request_threaded_irq(dev, rx_irq, NULL, lantiq_ssc_isr, + IRQF_ONESHOT, LTQ_SPI_RX_IRQ_NAME, spi); if (err) goto err_master_put; - err = devm_request_irq(dev, tx_irq, lantiq_ssc_xmit_interrupt, - 0, LTQ_SPI_TX_IRQ_NAME, spi); + err = devm_request_threaded_irq(dev, tx_irq, NULL, lantiq_ssc_isr, + IRQF_ONESHOT, LTQ_SPI_TX_IRQ_NAME, spi); if (err) goto err_master_put; - err = devm_request_irq(dev, err_irq, lantiq_ssc_err_interrupt, - 0, LTQ_SPI_ERR_IRQ_NAME, spi); + err = devm_request_threaded_irq(dev, err_irq, NULL, lantiq_ssc_isr, + IRQF_ONESHOT, LTQ_SPI_ERR_IRQ_NAME, spi); if (err) goto err_master_put; @@ -882,7 +893,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev) spi->base_cs = 1; of_property_read_u32(pdev->dev.of_node, "base-cs", &spi->base_cs); - spin_lock_init(&spi->lock); + mutex_init(&spi->lock); spi->bits_per_word = 8; spi->speed_hz = 0; @@ -899,13 +910,6 @@ static int lantiq_ssc_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32); - spi->wq = alloc_ordered_workqueue(dev_name(dev), 0); - if (!spi->wq) { - err = -ENOMEM; - goto err_clk_put; - } - INIT_WORK(&spi->work, lantiq_ssc_bussy_work); - id = lantiq_ssc_readl(spi, LTQ_SPI_ID); spi->tx_fifo_size = (id & LTQ_SPI_ID_TXFS_M) >> LTQ_SPI_ID_TXFS_S; spi->rx_fifo_size = (id & LTQ_SPI_ID_RXFS_M) >> LTQ_SPI_ID_RXFS_S; @@ -921,13 +925,11 @@ static int lantiq_ssc_probe(struct platform_device *pdev) err = devm_spi_register_master(dev, master); if (err) { dev_err(dev, "failed to register spi_master\n"); - goto err_wq_destroy; + goto err_clk_put; } return 0; -err_wq_destroy: - destroy_workqueue(spi->wq); err_clk_put: clk_put(spi->fpi_clk); err_clk_disable: @@ -948,7 +950,6 @@ static int lantiq_ssc_remove(struct platform_device *pdev) tx_fifo_flush(spi); hw_enter_config_mode(spi); - destroy_workqueue(spi->wq); clk_disable_unprepare(spi->spi_clk); clk_put(spi->fpi_clk); From patchwork Fri Apr 24 10:42:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dilip Kota X-Patchwork-Id: 11507501 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 BABB714B4 for ; Fri, 24 Apr 2020 10:43:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB75C2071E for ; Fri, 24 Apr 2020 10:43:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726925AbgDXKnh (ORCPT ); Fri, 24 Apr 2020 06:43:37 -0400 Received: from mga14.intel.com ([192.55.52.115]:54501 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726815AbgDXKnh (ORCPT ); Fri, 24 Apr 2020 06:43:37 -0400 IronPort-SDR: ELsXngcPa2/SwgNaqp3dIyC9irzB2D6PI4AjNGkH4YQ1Bi2GIBo4mTroQxPmro6ELlC3Qd18Gq /b9pBqRefhrQ== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 03:43:36 -0700 IronPort-SDR: MZht+JuIYucJM8e6D2WVRiOSaPTpLaSBhs/V+wfIsz3ipgZzsKVDYwbRO4HIuwSXSVKRUkU2nY gZsXoo6ptpkg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,311,1583222400"; d="scan'208";a="403261185" Received: from sgsxdev004.isng.intel.com (HELO localhost) ([10.226.88.13]) by orsmga004.jf.intel.com with ESMTP; 24 Apr 2020 03:43:33 -0700 From: Dilip Kota To: broonie@kernel.org, robh@kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, daniel.schwierzeck@gmail.com, hauke@hauke-m.de, andriy.shevchenko@intel.com, cheol.yong.kim@intel.com, chuanhua.lei@linux.intel.com, qi-ming.wu@intel.com, Dilip Kota Subject: [PATCH 2/4] spi: lantiq: Dynamic configuration of interrupts and FIFO size Date: Fri, 24 Apr 2020 18:42:31 +0800 Message-Id: X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Newer chipsets are having larger transfer FIFOs and lesser interrupt lines. So, add the interrupt configuration operation and FIFO size mask to the SoC specific data structure. On the existing chipsets, interrupt controller acknowledges the triggered interrupts automatically. Whereas in the newer chipsests like Lightning Mountain interrupt status register should be cleared for the acknowledgment of triggered interrupts. So, add a flag in the SoC specific data structure to specify driver to clear the interrupt status register. Signed-off-by: Dilip Kota --- drivers/spi/spi-lantiq-ssc.c | 97 ++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 40 deletions(-) diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c index b67f5925bcb0..74a5d36c5048 100644 --- a/drivers/spi/spi-lantiq-ssc.c +++ b/drivers/spi/spi-lantiq-ssc.c @@ -61,9 +61,7 @@ #define LTQ_SPI_CLC_DISR BIT(0) /* Disable request bit */ #define LTQ_SPI_ID_TXFS_S 24 /* Implemented TX FIFO size */ -#define LTQ_SPI_ID_TXFS_M (0x3F << LTQ_SPI_ID_TXFS_S) #define LTQ_SPI_ID_RXFS_S 16 /* Implemented RX FIFO size */ -#define LTQ_SPI_ID_RXFS_M (0x3F << LTQ_SPI_ID_RXFS_S) #define LTQ_SPI_ID_MOD_S 8 /* Module ID */ #define LTQ_SPI_ID_MOD_M (0xff << LTQ_SPI_ID_MOD_S) #define LTQ_SPI_ID_CFG_S 5 /* DMA interface support */ @@ -126,19 +124,15 @@ LTQ_SPI_WHBSTATE_CLRTUE) #define LTQ_SPI_RXFCON_RXFITL_S 8 /* FIFO interrupt trigger level */ -#define LTQ_SPI_RXFCON_RXFITL_M (0x3F << LTQ_SPI_RXFCON_RXFITL_S) #define LTQ_SPI_RXFCON_RXFLU BIT(1) /* FIFO flush */ #define LTQ_SPI_RXFCON_RXFEN BIT(0) /* FIFO enable */ #define LTQ_SPI_TXFCON_TXFITL_S 8 /* FIFO interrupt trigger level */ -#define LTQ_SPI_TXFCON_TXFITL_M (0x3F << LTQ_SPI_TXFCON_TXFITL_S) #define LTQ_SPI_TXFCON_TXFLU BIT(1) /* FIFO flush */ #define LTQ_SPI_TXFCON_TXFEN BIT(0) /* FIFO enable */ #define LTQ_SPI_FSTAT_RXFFL_S 0 -#define LTQ_SPI_FSTAT_RXFFL_M (0x3f << LTQ_SPI_FSTAT_RXFFL_S) #define LTQ_SPI_FSTAT_TXFFL_S 8 -#define LTQ_SPI_FSTAT_TXFFL_M (0x3f << LTQ_SPI_FSTAT_TXFFL_S) #define LTQ_SPI_GPOCON_ISCSBN_S 8 #define LTQ_SPI_GPOCON_INVOUTN_S 0 @@ -158,9 +152,14 @@ #define LTQ_SPI_IRNEN_T_XRX BIT(0) /* Receive end interrupt request */ #define LTQ_SPI_IRNEN_ALL 0x1F +struct lantiq_ssc_spi; + struct lantiq_ssc_hwcfg { + int (*cfg_irq)(struct platform_device *pdev, struct lantiq_ssc_spi *spi); + u32 fifo_size_mask; unsigned int irnen_r; unsigned int irnen_t; + bool irq_ack; }; struct lantiq_ssc_spi { @@ -209,16 +208,18 @@ static void lantiq_ssc_maskl(const struct lantiq_ssc_spi *spi, u32 clr, static unsigned int tx_fifo_level(const struct lantiq_ssc_spi *spi) { + const struct lantiq_ssc_hwcfg *hwcfg = spi->hwcfg; u32 fstat = lantiq_ssc_readl(spi, LTQ_SPI_FSTAT); - return (fstat & LTQ_SPI_FSTAT_TXFFL_M) >> LTQ_SPI_FSTAT_TXFFL_S; + return (fstat >> LTQ_SPI_FSTAT_TXFFL_S) & hwcfg->fifo_size_mask; } static unsigned int rx_fifo_level(const struct lantiq_ssc_spi *spi) { + const struct lantiq_ssc_hwcfg *hwcfg = spi->hwcfg; u32 fstat = lantiq_ssc_readl(spi, LTQ_SPI_FSTAT); - return fstat & LTQ_SPI_FSTAT_RXFFL_M; + return (fstat >> LTQ_SPI_FSTAT_RXFFL_S) & hwcfg->fifo_size_mask; } static unsigned int tx_fifo_free(const struct lantiq_ssc_spi *spi) @@ -678,6 +679,8 @@ static irqreturn_t lantiq_ssc_isr(int irq, void *data) mutex_lock(&spi->lock); val = lantiq_ssc_readl(spi, LTQ_SPI_IRNCR); lantiq_ssc_maskl(spi, val, 0, LTQ_SPI_IRNEN); + if (hwcfg->irq_ack) + lantiq_ssc_writel(spi, val, LTQ_SPI_IRNCR); if (val & LTQ_SPI_IRNEN_E) ret = lantiq_ssc_err_interrupt(spi); @@ -786,14 +789,52 @@ static int lantiq_ssc_transfer_one(struct spi_master *master, return transfer_start(spi, spidev, t); } +static int lantiq_cfg_irq(struct platform_device *pdev, struct lantiq_ssc_spi *spi) +{ + int irq, err; + + irq = platform_get_irq_byname(pdev, LTQ_SPI_RX_IRQ_NAME); + if (irq < 0) + return irq; + + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, lantiq_ssc_isr, + IRQF_ONESHOT, LTQ_SPI_RX_IRQ_NAME, spi); + if (err) + return err; + + irq = platform_get_irq_byname(pdev, LTQ_SPI_TX_IRQ_NAME); + if (irq < 0) + return irq; + + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, lantiq_ssc_isr, + IRQF_ONESHOT, LTQ_SPI_TX_IRQ_NAME, spi); + if (err) + return err; + + irq = platform_get_irq_byname(pdev, LTQ_SPI_ERR_IRQ_NAME); + if (irq < 0) + return irq; + + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, lantiq_ssc_isr, + IRQF_ONESHOT, LTQ_SPI_ERR_IRQ_NAME, spi); + + return err; +} + static const struct lantiq_ssc_hwcfg lantiq_ssc_xway = { - .irnen_r = LTQ_SPI_IRNEN_R_XWAY, - .irnen_t = LTQ_SPI_IRNEN_T_XWAY, + .irnen_r = LTQ_SPI_IRNEN_R_XWAY, + .irnen_t = LTQ_SPI_IRNEN_T_XWAY, + .fifo_size_mask = GENMASK(5, 0), + .cfg_irq = lantiq_cfg_irq, + .irq_ack = false, }; static const struct lantiq_ssc_hwcfg lantiq_ssc_xrx = { - .irnen_r = LTQ_SPI_IRNEN_R_XRX, - .irnen_t = LTQ_SPI_IRNEN_T_XRX, + .irnen_r = LTQ_SPI_IRNEN_R_XRX, + .irnen_t = LTQ_SPI_IRNEN_T_XRX, + .fifo_size_mask = GENMASK(5, 0), + .cfg_irq = lantiq_cfg_irq, + .irq_ack = false, }; static const struct of_device_id lantiq_ssc_match[] = { @@ -811,9 +852,9 @@ static int lantiq_ssc_probe(struct platform_device *pdev) struct lantiq_ssc_spi *spi; const struct lantiq_ssc_hwcfg *hwcfg; const struct of_device_id *match; - int err, rx_irq, tx_irq, err_irq; u32 id, supports_dma, revision; unsigned int num_cs; + int err; match = of_match_device(lantiq_ssc_match, dev); if (!match) { @@ -821,19 +862,6 @@ static int lantiq_ssc_probe(struct platform_device *pdev) return -EINVAL; } hwcfg = match->data; - - rx_irq = platform_get_irq_byname(pdev, LTQ_SPI_RX_IRQ_NAME); - if (rx_irq < 0) - return -ENXIO; - - tx_irq = platform_get_irq_byname(pdev, LTQ_SPI_TX_IRQ_NAME); - if (tx_irq < 0) - return -ENXIO; - - err_irq = platform_get_irq_byname(pdev, LTQ_SPI_ERR_IRQ_NAME); - if (err_irq < 0) - return -ENXIO; - master = spi_alloc_master(dev, sizeof(struct lantiq_ssc_spi)); if (!master) return -ENOMEM; @@ -849,18 +877,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev) goto err_master_put; } - err = devm_request_threaded_irq(dev, rx_irq, NULL, lantiq_ssc_isr, - IRQF_ONESHOT, LTQ_SPI_RX_IRQ_NAME, spi); - if (err) - goto err_master_put; - - err = devm_request_threaded_irq(dev, tx_irq, NULL, lantiq_ssc_isr, - IRQF_ONESHOT, LTQ_SPI_TX_IRQ_NAME, spi); - if (err) - goto err_master_put; - - err = devm_request_threaded_irq(dev, err_irq, NULL, lantiq_ssc_isr, - IRQF_ONESHOT, LTQ_SPI_ERR_IRQ_NAME, spi); + err = hwcfg->cfg_irq(pdev, spi); if (err) goto err_master_put; @@ -911,8 +928,8 @@ static int lantiq_ssc_probe(struct platform_device *pdev) SPI_BPW_MASK(16) | SPI_BPW_MASK(32); id = lantiq_ssc_readl(spi, LTQ_SPI_ID); - spi->tx_fifo_size = (id & LTQ_SPI_ID_TXFS_M) >> LTQ_SPI_ID_TXFS_S; - spi->rx_fifo_size = (id & LTQ_SPI_ID_RXFS_M) >> LTQ_SPI_ID_RXFS_S; + spi->tx_fifo_size = (id >> LTQ_SPI_ID_TXFS_S) & hwcfg->fifo_size_mask; + spi->rx_fifo_size = (id >> LTQ_SPI_ID_RXFS_S) & hwcfg->fifo_size_mask; supports_dma = (id & LTQ_SPI_ID_CFG_M) >> LTQ_SPI_ID_CFG_S; revision = id & LTQ_SPI_ID_REV_M; From patchwork Fri Apr 24 10:42:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dilip Kota X-Patchwork-Id: 11507503 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 63F21112C for ; Fri, 24 Apr 2020 10:43:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5501E2071E for ; Fri, 24 Apr 2020 10:43:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726942AbgDXKnn (ORCPT ); Fri, 24 Apr 2020 06:43:43 -0400 Received: from mga18.intel.com ([134.134.136.126]:18143 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726815AbgDXKnl (ORCPT ); Fri, 24 Apr 2020 06:43:41 -0400 IronPort-SDR: 5fqVPSMhYsw1Lj/69+ezKqRIrNvytikxsKZzhCCHhNyqMknjRbkalLL5G3LINyYYTrJZHbCd/e Q/efRI7L2F9A== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 03:43:40 -0700 IronPort-SDR: 44ljB5D2GbRr2TC8bkgbVFcVdOgeAdsA4mySKntYe1NImqKNBMzmIgJHN6c0rWlu9eRa6dxzz9 MONxo8ARDrHg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,311,1583222400"; d="scan'208";a="430726378" Received: from sgsxdev004.isng.intel.com (HELO localhost) ([10.226.88.13]) by orsmga005.jf.intel.com with ESMTP; 24 Apr 2020 03:43:37 -0700 From: Dilip Kota To: broonie@kernel.org, robh@kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, daniel.schwierzeck@gmail.com, hauke@hauke-m.de, andriy.shevchenko@intel.com, cheol.yong.kim@intel.com, chuanhua.lei@linux.intel.com, qi-ming.wu@intel.com, Dilip Kota Subject: [PATCH 3/4] dt-bindings: spi: Add support to Lightning Mountain SoC Date: Fri, 24 Apr 2020 18:42:32 +0800 Message-Id: <1f447a5ab8fee5bc9116ba70b0344193c9c6cc06.1587702428.git.eswara.kota@linux.intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Add support to SPI controller on Intel Atom based Lightning Mountain SoC which reuses the Lantiq SPI controller IP. Signed-off-by: Dilip Kota Reviewed-by: Rob Herring --- .../devicetree/bindings/spi/spi-lantiq-ssc.txt | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt b/Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt index ce3230c8e28d..76a3dd35f796 100644 --- a/Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt +++ b/Documentation/devicetree/bindings/spi/spi-lantiq-ssc.txt @@ -1,11 +1,17 @@ Lantiq Synchronous Serial Controller (SSC) SPI master driver Required properties: -- compatible: "lantiq,ase-spi", "lantiq,falcon-spi", "lantiq,xrx100-spi" +- compatible: "lantiq,ase-spi", "lantiq,falcon-spi", "lantiq,xrx100-spi", + "intel,lgm-spi" - #address-cells: see spi-bus.txt - #size-cells: see spi-bus.txt - reg: address and length of the spi master registers -- interrupts: should contain the "spi_rx", "spi_tx" and "spi_err" interrupt. +- interrupts: + For compatible "intel,lgm-ssc" - the common interrupt number for + all of tx rx & err interrupts. + or + For rest of the compatibles, should contain the "spi_rx", "spi_tx" and + "spi_err" interrupt. Optional properties: @@ -27,3 +33,14 @@ spi: spi@e100800 { num-cs = <6>; base-cs = <1>; }; + +ssc0: spi@e0800000 { + compatible = "intel,lgm-spi"; + reg = <0xe0800000 0x400>; + interrupt-parent = <&ioapic1>; + interrupts = <35 1>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cgu0 LGM_CLK_NGI>, <&cgu0 LGM_GCLK_SSC0>; + clock-names = "freq", "gate"; +}; From patchwork Fri Apr 24 10:42:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dilip Kota X-Patchwork-Id: 11507505 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 4AF2613B2 for ; Fri, 24 Apr 2020 10:43:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D9192084D for ; Fri, 24 Apr 2020 10:43:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726954AbgDXKnr (ORCPT ); Fri, 24 Apr 2020 06:43:47 -0400 Received: from mga12.intel.com ([192.55.52.136]:57626 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726815AbgDXKnp (ORCPT ); Fri, 24 Apr 2020 06:43:45 -0400 IronPort-SDR: 2LF38Ww+7SFX2fAonbYCBKJpXoAs4TlQ1bh3oYhO6McgsDh3Hhx9rn947RzRx77FOoIJXjjaGZ SAHiPsUlZd8Q== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 03:43:44 -0700 IronPort-SDR: hYzhB4UPsAzvlETcc5tInjsnGgPykrj0j6Bw2g80I+2+qN3x7+/EoaaGcTPKvvzvI65w56KUKP L/Iv0muCKI/w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,311,1583222400"; d="scan'208";a="335307522" Received: from sgsxdev004.isng.intel.com (HELO localhost) ([10.226.88.13]) by orsmga001.jf.intel.com with ESMTP; 24 Apr 2020 03:43:41 -0700 From: Dilip Kota To: broonie@kernel.org, robh@kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, daniel.schwierzeck@gmail.com, hauke@hauke-m.de, andriy.shevchenko@intel.com, cheol.yong.kim@intel.com, chuanhua.lei@linux.intel.com, qi-ming.wu@intel.com, Dilip Kota Subject: [PATCH 4/4] spi: lantiq: Add support to Lightning Mountain SoC Date: Fri, 24 Apr 2020 18:42:33 +0800 Message-Id: <5431aaf70b59ff668b347bc84782296a5f950439.1587702428.git.eswara.kota@linux.intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Add support to SPI controller on Intel Atom based Lightning Mountain SoC which reuses Lantiq SPI controller IP. Signed-off-by: Dilip Kota --- drivers/spi/Kconfig | 4 ++-- drivers/spi/spi-lantiq-ssc.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4887be7f16de..089b0ba4afe3 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -495,11 +495,11 @@ config SPI_NPCM_PSPI config SPI_LANTIQ_SSC tristate "Lantiq SSC SPI controller" - depends on LANTIQ || COMPILE_TEST + depends on (LANTIQ || X86) || COMPILE_TEST help This driver supports the Lantiq SSC SPI controller in master mode. This controller is found on Intel (former Lantiq) SoCs like - the Danube, Falcon, xRX200, xRX300. + the Danube, Falcon, xRX200, xRX300, Lightning Mountain. config SPI_OC_TINY tristate "OpenCores tiny SPI" diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c index 74a5d36c5048..f07fa6fbadbe 100644 --- a/drivers/spi/spi-lantiq-ssc.c +++ b/drivers/spi/spi-lantiq-ssc.c @@ -789,6 +789,18 @@ static int lantiq_ssc_transfer_one(struct spi_master *master, return transfer_start(spi, spidev, t); } +static int intel_cfg_irq(struct platform_device *pdev, struct lantiq_ssc_spi *spi) +{ + int irq; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + return devm_request_threaded_irq(&pdev->dev, irq, NULL, lantiq_ssc_isr, + IRQF_ONESHOT, "spi", spi); +} + static int lantiq_cfg_irq(struct platform_device *pdev, struct lantiq_ssc_spi *spi) { int irq, err; @@ -837,10 +849,18 @@ static const struct lantiq_ssc_hwcfg lantiq_ssc_xrx = { .irq_ack = false, }; +static const struct lantiq_ssc_hwcfg intel_ssc_lgm = { + .irnen_r = LTQ_SPI_IRNEN_R_XRX, + .irnen_t = LTQ_SPI_IRNEN_T_XRX, + .fifo_size_mask = GENMASK(7, 0), + .cfg_irq = intel_cfg_irq, +}; + static const struct of_device_id lantiq_ssc_match[] = { { .compatible = "lantiq,ase-spi", .data = &lantiq_ssc_xway, }, { .compatible = "lantiq,falcon-spi", .data = &lantiq_ssc_xrx, }, { .compatible = "lantiq,xrx100-spi", .data = &lantiq_ssc_xrx, }, + { .compatible = "intel,lgm-spi", .data = &intel_ssc_lgm, }, {}, }; MODULE_DEVICE_TABLE(of, lantiq_ssc_match);