From nobody Thu Apr 16 22:34:50 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2FAB030E842; Wed, 25 Feb 2026 08:02:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772006580; cv=none; b=BFyWwkBqehQdLuc9YA+4hKr65jEgTKPNNsVfWEo65rAAGkjeWheCyFgUNFsqqlBzjaSLDGi4wVUOwuOt4GQhRKmCkjRJ1hAOfx/uA/Dfohknd0McM+P3IRAFfy6F9VZqlBdyDVZ2fb3JTnQsuBsL46sF6nKtk2EHjIbMU3kIzMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772006580; c=relaxed/simple; bh=05HYwy2erpJLKB7Mh8DoTKgJhjWHXkPPnFJKMaluA2I=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=YfK2jZ8SD0DBskk/xGWYBlNfF4uXsgTV3dS1iCpYuCOErGVoR+KVPUhBa6OmLii5HvcfvgVRJuWst21o3hpSa/Bhdm6XbmCXT/7dCDJLKsxqoOdxU7EzvUjZL+RuOEGWwZaYLX5uJJTAI86M6f/wscF2RwJ09C+ggcBp4zhnKRE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=csI7P1yE; arc=none smtp.client-ip=220.197.31.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="csI7P1yE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=6j 4FIPp0ly8uif79IFwRDcphLeNtFMFlSHTupDt8554=; b=csI7P1yEqzm2dU9tbH el46Ezg5edXKSp+liSm0BGO6NAOovhDSnB52i6OdVUtPKZdDjMIjPxcKEWnJVyrt EIh4x5tXWzvJhIYl6HUks2vfU9wGAWXmBQ9LP0qpGW3T80zExRDh7UNN+6t+qo8M TOX9jhBTud8Zwy7oQu06FKxlQ= Received: from pek-lpg-core5.wrs.com (unknown []) by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id _____wAXBgqfrJ5pkhArMg--.61139S2; Wed, 25 Feb 2026 16:02:40 +0800 (CST) From: Robert Garcia To: stable@vger.kernel.org, Khairul Anuar Romli Cc: Mark Brown , Niravkumar L Rabara , Robert Garcia , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 6.12.y] spi: cadence-quadspi: Implement refcount to handle unbind during busy Date: Wed, 25 Feb 2026 16:02:39 +0800 Message-Id: <20260225080239.3844427-1-rob_garcia@163.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wAXBgqfrJ5pkhArMg--.61139S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxZFWrXFykur4rAw1fXw4DCFg_yoWrWFWUpF 4UJ3y5tF4xtFWIq3ZrJa4DZF1akrWxJ34fW39rt34avry3Jwn0ya4F9FyUtr43AF97AF1U WF409ry2kF43ZF7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UP9N-UUUUU= X-CM-SenderInfo: 5uresw5dufxti6rwjhhfrp/xtbDAQBVwGmerKByxwAA3a Content-Type: text/plain; charset="utf-8" From: Khairul Anuar Romli [ Upstream commit 7446284023e8ef694fb392348185349c773eefb3 ] driver support indirect read and indirect write operation with assumption no force device removal(unbind) operation. However force device removal(removal) is still available to root superuser. Unbinding driver during operation causes kernel crash. This changes ensure driver able to handle such operation for indirect read and indirect write by implementing refcount to track attached devices to the controller and gracefully wait and until attached devices remove operation completed before proceed with removal operation. Signed-off-by: Khairul Anuar Romli Reviewed-by: Matthew Gerlach Reviewed-by: Niravkumar L Rabara Link: https://patch.msgid.link/8704fd6bd2ff4d37bba4a0eacf5eba3ba001079e.175= 6168074.git.khairul.anuar.romli@altera.com Signed-off-by: Mark Brown Signed-off-by: Robert Garcia --- drivers/spi/spi-cadence-quadspi.c | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-qu= adspi.c index e1d64a9a3446..288a0467c937 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -105,6 +105,8 @@ struct cqspi_st { =20 bool is_jh7110; /* Flag for StarFive JH7110 SoC */ bool disable_stig_mode; + refcount_t refcount; + refcount_t inflight_ops; =20 const struct cqspi_driver_platdata *ddata; }; @@ -731,6 +733,9 @@ static int cqspi_indirect_read_execute(struct cqspi_fla= sh_pdata *f_pdata, u8 *rxbuf_end =3D rxbuf + n_rx; int ret =3D 0; =20 + if (!refcount_read(&cqspi->refcount)) + return -ENODEV; + writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR); writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES); =20 @@ -1058,6 +1063,9 @@ static int cqspi_indirect_write_execute(struct cqspi_= flash_pdata *f_pdata, unsigned int write_bytes; int ret; =20 + if (!refcount_read(&cqspi->refcount)) + return -ENODEV; + writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR); writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES); =20 @@ -1450,12 +1458,26 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, c= onst struct spi_mem_op *op) struct cqspi_st *cqspi =3D spi_controller_get_devdata(mem->spi->controlle= r); struct device *dev =3D &cqspi->pdev->dev; =20 + if (refcount_read(&cqspi->inflight_ops) =3D=3D 0) + return -ENODEV; + ret =3D pm_runtime_resume_and_get(dev); if (ret) { dev_err(&mem->spi->dev, "resume failed with %d\n", ret); return ret; } =20 + if (!refcount_read(&cqspi->refcount)) + return -EBUSY; + + refcount_inc(&cqspi->inflight_ops); + + if (!refcount_read(&cqspi->refcount)) { + if (refcount_read(&cqspi->inflight_ops)) + refcount_dec(&cqspi->inflight_ops); + return -EBUSY; + } + ret =3D cqspi_mem_process(mem, op); =20 pm_runtime_mark_last_busy(dev); @@ -1464,6 +1486,9 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, con= st struct spi_mem_op *op) if (ret) dev_err(&mem->spi->dev, "operation failed with %d\n", ret); =20 + if (refcount_read(&cqspi->inflight_ops) > 1) + refcount_dec(&cqspi->inflight_ops); + return ret; } =20 @@ -1916,6 +1941,9 @@ static int cqspi_probe(struct platform_device *pdev) } } =20 + refcount_set(&cqspi->refcount, 1); + refcount_set(&cqspi->inflight_ops, 1); + ret =3D devm_request_irq(dev, irq, cqspi_irq_handler, 0, pdev->name, cqspi); if (ret) { @@ -1978,6 +2006,11 @@ static void cqspi_remove(struct platform_device *pde= v) { struct cqspi_st *cqspi =3D platform_get_drvdata(pdev); =20 + refcount_set(&cqspi->refcount, 0); + + if (!refcount_dec_and_test(&cqspi->inflight_ops)) + cqspi_wait_idle(cqspi); + spi_unregister_controller(cqspi->host); cqspi_controller_enable(cqspi, 0); =20 --=20 2.34.1