From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 CB95D25B0AA; Sat, 12 Sep 2026 10:11:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789207893; cv=none; b=Gc0E1gaLEpPg0gJcvhxFh6CumlxDiJ9acN36Ch2dQj7sSBX3BLaeRHHSz9sm4s7MVvMFVO98i8Rj2SBoHmg3tLB79R1Kg6B/1cblMQv1nugxaAzru9A8w0CJp+dOW7Q0F5/i5EU2Ixb3hILPOd0Vbegs7kEyDjKPO7RITBr6cIQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789207893; c=relaxed/simple; bh=OvQg9AiqYuOKNhJ1f0NVeJ979MYeg0/BlYu33Wl6M2w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YSv2XScA9ixMxo0wuJlHtmUchrDuL33wG/vPqZ5Edzd1BVo/otmeTyZd197eZUH1iqHKYaeN2O/HlX8X4f7z9qqoR5bLQbVMaHXAfMwybYkTrlvk9Sl7gq307S9Wh0NokHthDD09DqjCXcISUX+i0Tjn4aocgapU/HfjX+llJkQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=JATsCRCV; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="JATsCRCV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A24161F000FF; Sat, 12 Sep 2026 10:11:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1789207891; bh=yyp4VIORaXxINi6T1oBFsFzYjivfYYFwkuIhUZu3Ljk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=JATsCRCVs6dPb0muY7fgH6PPiBUYfxkMtxsdr/I0dKlp33Z8KWbQEDUQJ1JUUnzjY swe/bMa6CLW9CNobfg2D2yH+80gZew14VgJRF4Gcqojge1WC2jhLdsk7ELI7RHq5sk JbX53HU2D4wHLJrij/bOmC4uN8L0mESs4J+g39gM= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Alexander Usyskin , Miquel Raynal , Sasha Levin Subject: [PATCH 6.18 0463/1518] mtd: intel-dg: wake card on operations Date: Sat, 12 Sep 2026 08:43:52 +0200 Message-ID: <20260912065633.921153684@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260912065623.398859879@linuxfoundation.org> References: <20260912065623.398859879@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Alexander Usyskin [ Upstream commit 3e9c49d4c3063dcf7ddcdea4c5e3aa21eae359d0 ] The Intel DG cards do not have separate power control for persistent memory. The memory is available when the whole card is awake. Enable runtime PM in mtd driver to notify parent graphics driver that whole card should be kept awake while nvm operations are performed through this driver. Signed-off-by: Alexander Usyskin Signed-off-by: Miquel Raynal Stable-dep-of: df6f582df337 ("mtd: intel-dg: Fix runtime PM error path in probe") Signed-off-by: Sasha Levin --- drivers/mtd/devices/mtd_intel_dg.c | 74 +++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/devices/mtd_intel_dg.c b/drivers/mtd/devices/mtd_intel_dg.c index 114e69135b8d9..7f751c48a76d4 100644 --- a/drivers/mtd/devices/mtd_intel_dg.c +++ b/drivers/mtd/devices/mtd_intel_dg.c @@ -15,14 +15,18 @@ #include #include #include +#include #include #include #include #include +#define INTEL_DG_NVM_RPM_TIMEOUT_MS 500 + struct intel_dg_nvm { struct kref refcnt; struct mtd_info mtd; + struct device *dev; struct mutex lock; /* region access lock */ void __iomem *base; void __iomem *base2; @@ -421,6 +425,8 @@ static int intel_dg_nvm_init(struct intel_dg_nvm *nvm, struct device *device, unsigned int i, n; int ret; + nvm->dev = device; + /* clean error register, previous errors are ignored */ idg_nvm_error(nvm); @@ -498,6 +504,7 @@ static int intel_dg_mtd_erase(struct mtd_info *mtd, struct erase_info *info) size_t len; u8 region; u64 addr; + int ret; if (WARN_ON(!nvm)) return -EINVAL; @@ -512,20 +519,29 @@ static int intel_dg_mtd_erase(struct mtd_info *mtd, struct erase_info *info) total_len = info->len; addr = info->addr; + ret = pm_runtime_resume_and_get(nvm->dev); + if (ret < 0) { + dev_err(&mtd->dev, "rpm: get failed %d\n", ret); + return ret; + } + + ret = 0; guard(mutex)(&nvm->lock); while (total_len > 0) { if (!IS_ALIGNED(addr, SZ_4K) || !IS_ALIGNED(total_len, SZ_4K)) { dev_err(&mtd->dev, "unaligned erase %llx %zx\n", addr, total_len); info->fail_addr = addr; - return -ERANGE; + ret = -ERANGE; + break; } idx = idg_nvm_get_region(nvm, addr); if (idx >= nvm->nregions) { dev_err(&mtd->dev, "out of range"); info->fail_addr = MTD_FAIL_ADDR_UNKNOWN; - return -ERANGE; + ret = -ERANGE; + break; } from = addr - nvm->regions[idx].offset; @@ -541,14 +557,16 @@ static int intel_dg_mtd_erase(struct mtd_info *mtd, struct erase_info *info) if (bytes < 0) { dev_dbg(&mtd->dev, "erase failed with %zd\n", bytes); info->fail_addr += nvm->regions[idx].offset; - return bytes; + ret = bytes; + break; } addr += len; total_len -= len; } - return 0; + pm_runtime_put_autosuspend(nvm->dev); + return ret; } static int intel_dg_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, @@ -577,17 +595,24 @@ static int intel_dg_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, if (len > nvm->regions[idx].size - from) len = nvm->regions[idx].size - from; + ret = pm_runtime_resume_and_get(nvm->dev); + if (ret < 0) { + dev_err(&mtd->dev, "rpm: get failed %zd\n", ret); + return ret; + } + guard(mutex)(&nvm->lock); ret = idg_read(nvm, region, from, len, buf); if (ret < 0) { dev_dbg(&mtd->dev, "read failed with %zd\n", ret); - return ret; + } else { + *retlen = ret; + ret = 0; } - *retlen = ret; - - return 0; + pm_runtime_put_autosuspend(nvm->dev); + return ret; } static int intel_dg_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, @@ -616,17 +641,24 @@ static int intel_dg_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (len > nvm->regions[idx].size - to) len = nvm->regions[idx].size - to; + ret = pm_runtime_resume_and_get(nvm->dev); + if (ret < 0) { + dev_err(&mtd->dev, "rpm: get failed %zd\n", ret); + return ret; + } + guard(mutex)(&nvm->lock); ret = idg_write(nvm, region, to, len, buf); if (ret < 0) { dev_dbg(&mtd->dev, "write failed with %zd\n", ret); - return ret; + } else { + *retlen = ret; + ret = 0; } - *retlen = ret; - - return 0; + pm_runtime_put_autosuspend(nvm->dev); + return ret; } static void intel_dg_nvm_release(struct kref *kref) @@ -756,6 +788,21 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev, n++; } + ret = devm_pm_runtime_enable(device); + if (ret < 0) { + dev_err(device, "rpm: enable failed %d\n", ret); + goto err_norpm; + } + + pm_runtime_set_autosuspend_delay(device, INTEL_DG_NVM_RPM_TIMEOUT_MS); + pm_runtime_use_autosuspend(device); + + ret = pm_runtime_resume_and_get(device); + if (ret < 0) { + dev_err(device, "rpm: get failed %d\n", ret); + goto err_norpm; + } + nvm->base = devm_ioremap_resource(device, &invm->bar); if (IS_ERR(nvm->base)) { ret = PTR_ERR(nvm->base); @@ -784,9 +831,12 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev, dev_set_drvdata(&aux_dev->dev, nvm); + pm_runtime_put(device); return 0; err: + pm_runtime_put(device); +err_norpm: kref_put(&nvm->refcnt, intel_dg_nvm_release); return ret; } -- 2.53.0