From nobody Thu Apr 9 20:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B6DA2298CBE; Thu, 5 Mar 2026 20:29:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772742570; cv=none; b=RGdCXfnIowXhlsVEnBIhAZ8iC2kU5dOb1DXGzeW/e439GwySeoZgMUtlV/l+rwznKqYQAbio5g51iZ3EPziF11Zl1Z+oQx7lPg2JPIBR2/XN/UiB5kd1lauRdtkDRj4VsBDsNP3wmTHV+gq+6l3nMrMclivxwJHdviBa98a64g4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772742570; c=relaxed/simple; bh=EEw9askz0wqJGI8+BzgWY3zRUi+YorrUJiw9FNnQOEM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=V6ONNnD5Gdx5je697khO7iKBfmFntQLeaEUhKhdV8ef0XP85ajTRpnizGOXBGxPoCbqK9gpIc+mXWEmGqApNlCQSJT70VibxZ3RaLvetM0M3uKcxvZ7VScxAlgc+PZKW3qfC4eJ6W1EGA7VVd1FjiSxI+P0PDoLGqhniGQ3MlPo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ouhh5c98; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ouhh5c98" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 92AD3C116C6; Thu, 5 Mar 2026 20:29:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772742570; bh=EEw9askz0wqJGI8+BzgWY3zRUi+YorrUJiw9FNnQOEM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ouhh5c98WXrq+0UG4vmsg8poVnJUEK+qnkSi3nSP7UWKZaNPjD5bvXMRnbYI12M8w 4ywPViktVqPahGa39BGUyJIfQEYAJY4vH3n5q9cc95v5k5uWvf0o2aHCOS/Bmf5fl9 sn0DhoZjGoMzF6hsmEJ7KC5dCHpwZK6nHK13wXBgZMOACU95Z8txCwcw37nT3AmKCj NF3+HwYDCbXrP2xrTt3t6ZJVXyZYnVp1G3UFTALnhX1ulKLH9UA9RiMXqv/hYDBFiV 0IZ4rH/BFszbosvPX2IkydfjhYDZJAq1P/uuNIdZMmH5jWHludfbvyOW9pXXMeR4B/ XTB2aYNRQuHGA== From: "Rafael J. Wysocki" To: Linux ACPI Cc: LKML , Hans de Goede Subject: [PATCH v1 4/9] ACPI: video: Rework checking for duplicate video bus devices Date: Thu, 05 Mar 2026 21:16:12 +0100 Message-ID: <5663583.Sb9uPGUboI@rafael.j.wysocki> Organization: Linux Kernel Development In-Reply-To: <4505861.ejJDZkT8p0@rafael.j.wysocki> References: <4505861.ejJDZkT8p0@rafael.j.wysocki> 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 Content-Type: text/plain; charset="utf-8" From: Rafael J. Wysocki The current way of checking for duplicate video bus devices in acpi_video_bus_probe() is based on walking the ACPI namespace which is not necessary after converting the driver to a platform one proper. It is also susceptible to race conditions (for example, if two video bus devices are probed at the same time) and ordering issues. Instead of doing it the old way, inspect the children of the parent of the platform device being probed, excluding the latter and the children that are not platform devices. For each of the remaining children, check if any of the entries in the video_bus_head list is equal to its driver data which can only happen if the given child has been processed by acpi_video_bus_probe() successfully and so it is a duplicate of the one being probed. Moreover, to prevent acpi_video_bus_probe() from processing two devices concurrently, which might defeat the above check, use a new internal mutex in it. Also, print the FW_BUG message only if allow_duplicates is unset which allows the entire duplicates check to be skipped in that case (doing it just to print the message about the case that is going to be ignored anyway is kind of pointless). Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_video.c | 57 +++++++++++++++++++++++------------------= ----- 1 file changed, 29 insertions(+), 28 deletions(-) --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -1683,26 +1683,6 @@ static int acpi_video_resume(struct noti return NOTIFY_DONE; } =20 -static acpi_status -acpi_video_bus_match(acpi_handle handle, u32 level, void *context, - void **return_value) -{ - struct acpi_device *device =3D context; - struct acpi_device *sibling; - - if (handle =3D=3D device->handle) - return AE_CTRL_TERMINATE; - - sibling =3D acpi_fetch_acpi_dev(handle); - if (!sibling) - return AE_OK; - - if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME)) - return AE_ALREADY_EXISTS; - - return AE_OK; -} - static void acpi_video_dev_register_backlight(struct acpi_video_device *de= vice) { struct backlight_properties props; @@ -1978,27 +1958,48 @@ static int acpi_video_bus_put_devices(st return 0; } =20 +static int duplicate_dev_check(struct device *sibling, void *data) +{ + struct acpi_video_bus *video; + + if (sibling =3D=3D data || !dev_is_platform(sibling)) + return 0; + + guard(mutex)(&video_list_lock); + + list_for_each_entry(video, &video_bus_head, entry) { + if (video =3D=3D dev_get_drvdata(sibling)) + return -EEXIST; + } + + return 0; +} + +static bool acpi_video_bus_dev_is_duplicate(struct platform_device *pdev) +{ + return device_for_each_child(pdev->dev.parent, &pdev->dev, + duplicate_dev_check); +} + static int acpi_video_bus_probe(struct platform_device *pdev) { struct acpi_device *device =3D ACPI_COMPANION(&pdev->dev); + static DEFINE_MUTEX(probe_lock); struct acpi_video_bus *video; static int instance; bool auto_detect; int error; - acpi_status status; =20 - status =3D acpi_walk_namespace(ACPI_TYPE_DEVICE, - acpi_dev_parent(device)->handle, 1, - acpi_video_bus_match, NULL, - device, NULL); - if (status =3D=3D AE_ALREADY_EXISTS) { + /* Probe one video bus device at a time in case there are duplicates. */ + guard(mutex)(&probe_lock); + + if (!allow_duplicates && acpi_video_bus_dev_is_duplicate(pdev)) { pr_info(FW_BUG "Duplicate ACPI video bus devices for the" " same VGA controller, please try module " "parameter \"video.allow_duplicates=3D1\"" "if the current driver doesn't work.\n"); - if (!allow_duplicates) - return -ENODEV; + return -ENODEV; } =20 video =3D kzalloc_obj(struct acpi_video_bus);