platform-driver-x86.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
To: platform-driver-x86@vger.kernel.org
Cc: "Hans de Goede" <hdegoede@redhat.com>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
	danilrybakov249@gmail.com, "Lukas Wunner" <lukas@wunner.de>,
	"Klara Modin" <klarasmodin@gmail.com>,
	linux-pci@vger.kernel.org,
	"Shin'ichiro Kawasaki" <shinichiro.kawasaki@wdc.com>
Subject: [PATCH v3] platform/x86: p2sb: Defer P2SB device scan when P2SB device has func 0
Date: Mon,  4 Mar 2024 16:19:12 +0900	[thread overview]
Message-ID: <20240304071912.2340622-1-shinichiro.kawasaki@wdc.com> (raw)

The commit 5913320eb0b3 ("platform/x86: p2sb: Allow p2sb_bar() calls
during PCI device probe") triggered repeated ACPI errors on ASUS
VivoBook D540NV-GQ065T [1]. The P2SB device on the system has multiple
functions, and the system requires P2SB device function 2. The commit
introduced the P2SB device scan for all functions including function 0
and 2. It was confirmed that the P2SB device scan for function 0 on the
system triggered the errors.

To avoid the errors, defer the P2SB device scan on the concerned device.
If the P2SB device has function 0, defer the device scan and do it later
when p2sb_bar() is called for the first time. At the deferred scan, do
not scan multiple functions and scan only the requested function to
avoid the unnecessary scan of function 0.

If sysfs pci bus rescans trigger the first p2sb_bar() call, deadlock
happens in the deferred P2SB device scan. In most cases, the p2sb_bar()
calls happen during the system boot process, then there is no chance of
deadlock.

After this change, the code to scan multiple functions for P2SB devices
with function 0 in p2sb_scan_and_cache() is no longer required. The
resource validity check in p2sb_scan_and_cache() is not required either
since it is done in p2sb_bar() also. Remove p2sb_scan_and_cache() and
call p2sb_scan_and_cache_devfn() instead.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=218531 [1]
Fixes: 5913320eb0b3 ("platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe")
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
Changes from v2:
* Target only the requested devfn at the deferred scan and cache
* Removed p2sb_scan_and_cache() and use p2sb_scan_and_cache_devfn() instead

Changes from v1:
* Removed unnecessary p2sb_resource_cached()
* Reflected other review comments

 drivers/platform/x86/p2sb.c | 47 ++++++++++++++++---------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
index 6bd14d0132db..c829dbd8f058 100644
--- a/drivers/platform/x86/p2sb.c
+++ b/drivers/platform/x86/p2sb.c
@@ -96,30 +96,6 @@ static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn)
 	pci_stop_and_remove_bus_device(pdev);
 }
 
-static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
-{
-	unsigned int slot, fn;
-
-	if (PCI_FUNC(devfn) == 0) {
-		/*
-		 * When function number of the P2SB device is zero, scan it and
-		 * other function numbers, and if devices are available, cache
-		 * their BAR0s.
-		 */
-		slot = PCI_SLOT(devfn);
-		for (fn = 0; fn < NR_P2SB_RES_CACHE; fn++)
-			p2sb_scan_and_cache_devfn(bus, PCI_DEVFN(slot, fn));
-	} else {
-		/* Scan the P2SB device and cache its BAR0 */
-		p2sb_scan_and_cache_devfn(bus, devfn);
-	}
-
-	if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res))
-		return -ENOENT;
-
-	return 0;
-}
-
 static struct pci_bus *p2sb_get_bus(struct pci_bus *bus)
 {
 	static struct pci_bus *p2sb_bus;
@@ -133,7 +109,7 @@ static struct pci_bus *p2sb_get_bus(struct pci_bus *bus)
 	return p2sb_bus;
 }
 
-static int p2sb_cache_resources(void)
+static int p2sb_cache_resources(unsigned int devfn_to_cache, bool from_fs_init)
 {
 	unsigned int devfn_p2sb;
 	u32 value = P2SBC_HIDE;
@@ -150,6 +126,18 @@ static int p2sb_cache_resources(void)
 	if (!bus)
 		return -ENODEV;
 
+	/*
+	 * On ASUS VivoBook D540NV-GQ065T which has Goldmont CPU family Pentium
+	 * N4200, P2SB device scan including function 0 at fs_initcall() step
+	 * causes ACPI errors. To avoid the errors, defer P2SB device scan and
+	 * cache when P2SB devices has function 0.
+	 */
+	if (PCI_FUNC(devfn_p2sb) == 0 && from_fs_init)
+		return -EBUSY;
+
+	if (devfn_to_cache == 0)
+		devfn_to_cache = devfn_p2sb;
+
 	/*
 	 * When a device with same devfn exists and its device class is not
 	 * PCI_CLASS_MEMORY_OTHER for P2SB, do not touch it.
@@ -173,7 +161,7 @@ static int p2sb_cache_resources(void)
 	if (value & P2SBC_HIDE)
 		pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0);
 
-	ret = p2sb_scan_and_cache(bus, devfn_p2sb);
+	p2sb_scan_and_cache_devfn(bus, devfn_to_cache);
 
 	/* Hide the P2SB device, if it was hidden */
 	if (value & P2SBC_HIDE)
@@ -214,6 +202,11 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
 	}
 
 	cache = &p2sb_resources[PCI_FUNC(devfn)];
+
+	/* Scan and cache P2SB device if it was deferred at fs_initcall() */
+	if (!p2sb_valid_resource(&cache->res))
+		p2sb_cache_resources(devfn, false);
+
 	if (cache->bus_dev_id != bus->dev.id)
 		return -ENODEV;
 
@@ -227,7 +220,7 @@ EXPORT_SYMBOL_GPL(p2sb_bar);
 
 static int __init p2sb_fs_init(void)
 {
-	p2sb_cache_resources();
+	p2sb_cache_resources(0, true);
 	return 0;
 }
 
-- 
2.43.0


                 reply	other threads:[~2024-03-04  7:19 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240304071912.2340622-1-shinichiro.kawasaki@wdc.com \
    --to=shinichiro.kawasaki@wdc.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=danilrybakov249@gmail.com \
    --cc=hdegoede@redhat.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=klarasmodin@gmail.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).