From 97ab5c1ac6744ad307bfb3d10aa63f2773846d24 Mon Sep 17 00:00:00 2001 From: Manisha Podhuturi Date: Tue, 29 Nov 2022 12:09:57 +0530 Subject: [PATCH] spi: spi-msm-geni: Handle IRQ enable and disable Handle irq enable and disable based on irq status flag, to avoid unbalanced irq errors. Enable irq only if irq status is disabled. Disable irq only if irq status is enabled. Change-Id: Ie01f89d10b0e2413bc8ba9a442ef99d358ce7f50 Signed-off-by: Manisha Podhuturi --- drivers/spi/spi-msm-geni.c | 44 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index ecbe17055e56..200955a3a6db 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ @@ -162,6 +163,7 @@ struct spi_geni_master { int num_tx_eot; int num_rx_eot; int num_xfers; + atomic_t is_irq_enable; void *ipc; bool gsi_mode; /* GSI Mode */ bool shared_ee; /* Dual EE use case */ @@ -181,6 +183,7 @@ struct spi_geni_master { }; static void spi_slv_setup(struct spi_geni_master *mas); +static void spi_geni_irq_enable(struct spi_geni_master *mas, bool irq_flag); static ssize_t spi_slave_state_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -2087,6 +2090,8 @@ static int spi_geni_probe(struct platform_device *pdev) } } + atomic_set(&geni_mas->is_irq_enable, 0); + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (ret) { ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); @@ -2230,12 +2235,12 @@ static int spi_geni_runtime_suspend(struct device *dev) struct spi_master *spi = get_spi_master(dev); struct spi_geni_master *geni_mas = spi_master_get_devdata(spi); - disable_irq(geni_mas->irq); if (geni_mas->is_le_vm) { spi_geni_unlock_bus(spi); return 0; } + spi_geni_irq_enable(geni_mas, false); GENI_SE_DBG(geni_mas->ipc, false, NULL, "%s:\n", __func__); /* Do not unconfigure the GPIOs for a shared_se usecase */ if (geni_mas->shared_ee && !geni_mas->shared_se) @@ -2295,7 +2300,7 @@ static int spi_geni_runtime_resume(struct device *dev) exit_rt_resume: ret = se_geni_resources_on(&geni_mas->spi_rsc); - enable_irq(geni_mas->irq); + spi_geni_irq_enable(geni_mas, true); return ret; } @@ -2342,6 +2347,41 @@ static int spi_geni_suspend(struct device *dev) } #endif +/** + * spi_geni_irq_enable() - Enable or Disable irq. + * @mas: Pointer to spi_geni_master structure. + * @irq_flag: irq flag which indicates irq enable + * or disable + * irq_flag - false - irq disable + * irq_flag - true - irq enable. + * + * This function is used to enable or disable irq. + * Based on irq_flag the enabling or disabling of + * irq will be done. Enable if irq_flag is true, + * disable if irq_flag is false. + * Return: None. + */ +static void spi_geni_irq_enable(struct spi_geni_master *mas, bool irq_flag) +{ + if (irq_flag) { + if (!(atomic_read(&mas->is_irq_enable))) { + enable_irq(mas->irq); + atomic_set(&mas->is_irq_enable, 1); + } else { + GENI_SE_DBG(mas->ipc, true, mas->dev, + "%s: irq already enabled\n", __func__); + } + } else { + if (atomic_read(&mas->is_irq_enable)) { + disable_irq(mas->irq); + atomic_set(&mas->is_irq_enable, 0); + } else { + GENI_SE_DBG(mas->ipc, true, mas->dev, + "%s: irq already disabled\n", __func__); + } + } +} + static const struct dev_pm_ops spi_geni_pm_ops = { SET_RUNTIME_PM_OPS(spi_geni_runtime_suspend, spi_geni_runtime_resume, NULL)