Skip to content

Commit 6ab3532

Browse files
committed
ACPI: video: Switch over to auxiliary bus type
Commit 02c057d ("ACPI: video: Convert the driver to a platform one") switched over the ACPI video bus driver from an ACPI driver to a platform driver, but that change introduced an unwanted and unexpected side effect. Namely, on some systems, the ACPI device object of the ACPI video bus device is an ACPI companion of multiple platform devices and, after adding video_device_ids[] as an acpi_match_table to the acpi_video_bus platform driver, all of those devices started to match that driver and its probe callback is invoked for all of them (it fails, but it leaves a confusing message in the log). Moreover, the MODULE_DEVICE_TABLE() of the ACPI video driver module matches all of the devices sharing the ACPI companion with the ACPI video bus device. To address this, make the core ACPI device enumeration code create an auxiliary device for the ACPI video bus device object instead of a platform device and switch over the ACPI video bus driver (once more) to an auxiliary driver. Auxiliary driver generally is a better match for ACPI video bus than platform driver, among other things because the ACPI video bus device does not require any resources to be allocated for it during enumeration. It also allows the ACPI video bus driver to stop abusing device matching based on ACPI device IDs and it allows a special case to be dropped from acpi_create_platform_device() because that function need not worry about the ACPI video bus device any more. Fixes: 02c057d ("ACPI: video: Convert the driver to a platform one") Reported-by: Pratap Nirujogi <[email protected]> Closes: https://lore.kernel.org/linux-acpi/[email protected]/ Tested-by: Pratap Nirujogi <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Mario Limonciello (AMD) <[email protected]> [ rjw: Added AUXILIARY_BUS selection to CONFIG_ACPI to fix build issue ] [ rjw: Fixed error path in acpi_create_video_bus_device() ] Link: https://patch.msgid.link/[email protected] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 1f318b9 commit 6ab3532

4 files changed

Lines changed: 69 additions & 24 deletions

File tree

drivers/acpi/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ config ARCH_SUPPORTS_ACPI
99
menuconfig ACPI
1010
bool "ACPI (Advanced Configuration and Power Interface) Support"
1111
depends on ARCH_SUPPORTS_ACPI
12+
select AUXILIARY_BUS
1213
select PNP
1314
select NLS
1415
select CRC32

drivers/acpi/acpi_platform.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
135135
}
136136
}
137137

138-
if (adev->device_type == ACPI_BUS_TYPE_DEVICE && !adev->pnp.type.backlight) {
138+
if (adev->device_type == ACPI_BUS_TYPE_DEVICE) {
139139
LIST_HEAD(resource_list);
140140

141141
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);

drivers/acpi/acpi_video.c

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#define pr_fmt(fmt) "ACPI: video: " fmt
1111

12+
#include <linux/auxiliary_bus.h>
1213
#include <linux/kernel.h>
1314
#include <linux/module.h>
1415
#include <linux/init.h>
@@ -21,7 +22,6 @@
2122
#include <linux/sort.h>
2223
#include <linux/pci.h>
2324
#include <linux/pci_ids.h>
24-
#include <linux/platform_device.h>
2525
#include <linux/slab.h>
2626
#include <linux/dmi.h>
2727
#include <linux/suspend.h>
@@ -77,8 +77,9 @@ static int register_count;
7777
static DEFINE_MUTEX(register_count_mutex);
7878
static DEFINE_MUTEX(video_list_lock);
7979
static LIST_HEAD(video_bus_head);
80-
static int acpi_video_bus_probe(struct platform_device *pdev);
81-
static void acpi_video_bus_remove(struct platform_device *pdev);
80+
static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
81+
const struct auxiliary_device_id *id);
82+
static void acpi_video_bus_remove(struct auxiliary_device *aux);
8283
static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);
8384

8485
/*
@@ -93,19 +94,16 @@ enum acpi_video_level_idx {
9394
ACPI_VIDEO_FIRST_LEVEL, /* actual supported levels begin here */
9495
};
9596

96-
static const struct acpi_device_id video_device_ids[] = {
97-
{ACPI_VIDEO_HID, 0},
98-
{"", 0},
97+
static const struct auxiliary_device_id video_bus_auxiliary_id_table[] = {
98+
{ .name = "acpi.video_bus" },
99+
{},
99100
};
100-
MODULE_DEVICE_TABLE(acpi, video_device_ids);
101+
MODULE_DEVICE_TABLE(auxiliary, video_bus_auxiliary_id_table);
101102

102-
static struct platform_driver acpi_video_bus = {
103+
static struct auxiliary_driver acpi_video_bus = {
103104
.probe = acpi_video_bus_probe,
104105
.remove = acpi_video_bus_remove,
105-
.driver = {
106-
.name = "acpi-video",
107-
.acpi_match_table = video_device_ids,
108-
},
106+
.id_table = video_bus_auxiliary_id_table,
109107
};
110108

111109
struct acpi_video_bus_flags {
@@ -1885,7 +1883,7 @@ static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device)
18851883
}
18861884

18871885
static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video,
1888-
struct platform_device *pdev)
1886+
struct device *parent)
18891887
{
18901888
struct input_dev *input;
18911889
struct acpi_video_device *dev;
@@ -1908,7 +1906,7 @@ static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video,
19081906
input->phys = video->phys;
19091907
input->id.bustype = BUS_HOST;
19101908
input->id.product = 0x06;
1911-
input->dev.parent = &pdev->dev;
1909+
input->dev.parent = parent;
19121910
input->evbit[0] = BIT(EV_KEY);
19131911
set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
19141912
set_bit(KEY_VIDEO_NEXT, input->keybit);
@@ -1980,9 +1978,10 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
19801978

19811979
static int instance;
19821980

1983-
static int acpi_video_bus_probe(struct platform_device *pdev)
1981+
static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
1982+
const struct auxiliary_device_id *id_unused)
19841983
{
1985-
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
1984+
struct acpi_device *device = ACPI_COMPANION(&aux_dev->dev);
19861985
struct acpi_video_bus *video;
19871986
bool auto_detect;
19881987
int error;
@@ -2019,7 +2018,7 @@ static int acpi_video_bus_probe(struct platform_device *pdev)
20192018
instance++;
20202019
}
20212020

2022-
platform_set_drvdata(pdev, video);
2021+
auxiliary_set_drvdata(aux_dev, video);
20232022

20242023
video->device = device;
20252024
strscpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
@@ -2068,7 +2067,7 @@ static int acpi_video_bus_probe(struct platform_device *pdev)
20682067
!auto_detect)
20692068
acpi_video_bus_register_backlight(video);
20702069

2071-
error = acpi_video_bus_add_notify_handler(video, pdev);
2070+
error = acpi_video_bus_add_notify_handler(video, &aux_dev->dev);
20722071
if (error)
20732072
goto err_del;
20742073

@@ -2096,10 +2095,10 @@ static int acpi_video_bus_probe(struct platform_device *pdev)
20962095
return error;
20972096
}
20982097

2099-
static void acpi_video_bus_remove(struct platform_device *pdev)
2098+
static void acpi_video_bus_remove(struct auxiliary_device *aux_dev)
21002099
{
2101-
struct acpi_video_bus *video = platform_get_drvdata(pdev);
2102-
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
2100+
struct acpi_video_bus *video = auxiliary_get_drvdata(aux_dev);
2101+
struct acpi_device *device = ACPI_COMPANION(&aux_dev->dev);
21032102

21042103
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
21052104
acpi_video_bus_notify);
@@ -2163,7 +2162,7 @@ int acpi_video_register(void)
21632162

21642163
dmi_check_system(video_dmi_table);
21652164

2166-
ret = platform_driver_register(&acpi_video_bus);
2165+
ret = auxiliary_driver_register(&acpi_video_bus);
21672166
if (ret)
21682167
goto leave;
21692168

@@ -2183,7 +2182,7 @@ void acpi_video_unregister(void)
21832182
{
21842183
mutex_lock(&register_count_mutex);
21852184
if (register_count) {
2186-
platform_driver_unregister(&acpi_video_bus);
2185+
auxiliary_driver_unregister(&acpi_video_bus);
21872186
register_count = 0;
21882187
may_report_brightness_keys = false;
21892188
}

drivers/acpi/scan.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define pr_fmt(fmt) "ACPI: " fmt
77

88
#include <linux/async.h>
9+
#include <linux/auxiliary_bus.h>
910
#include <linux/module.h>
1011
#include <linux/init.h>
1112
#include <linux/slab.h>
@@ -2192,6 +2193,44 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used,
21922193
return acpi_bus_check_add(handle, false, (struct acpi_device **)ret_p);
21932194
}
21942195

2196+
static void acpi_video_bus_device_release(struct device *dev)
2197+
{
2198+
struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
2199+
2200+
kfree(aux_dev);
2201+
}
2202+
2203+
static void acpi_create_video_bus_device(struct acpi_device *adev,
2204+
struct acpi_device *parent)
2205+
{
2206+
struct auxiliary_device *aux_dev;
2207+
static unsigned int aux_dev_id;
2208+
2209+
aux_dev = kzalloc_obj(*aux_dev);
2210+
if (!aux_dev)
2211+
return;
2212+
2213+
aux_dev->id = aux_dev_id++;
2214+
aux_dev->name = "video_bus";
2215+
aux_dev->dev.parent = acpi_get_first_physical_node(parent);
2216+
if (!aux_dev->dev.parent)
2217+
goto err;
2218+
2219+
aux_dev->dev.release = acpi_video_bus_device_release;
2220+
2221+
if (auxiliary_device_init(aux_dev))
2222+
goto err;
2223+
2224+
ACPI_COMPANION_SET(&aux_dev->dev, adev);
2225+
if (__auxiliary_device_add(aux_dev, "acpi"))
2226+
auxiliary_device_uninit(aux_dev);
2227+
2228+
return;
2229+
2230+
err:
2231+
kfree(aux_dev);
2232+
}
2233+
21952234
struct acpi_scan_system_dev {
21962235
struct list_head node;
21972236
struct acpi_device *adev;
@@ -2229,6 +2268,12 @@ static void acpi_default_enumeration(struct acpi_device *device)
22292268
sd->adev = device;
22302269
list_add_tail(&sd->node, &acpi_scan_system_dev_list);
22312270
}
2271+
} else if (device->pnp.type.backlight) {
2272+
struct acpi_device *parent;
2273+
2274+
parent = acpi_dev_parent(device);
2275+
if (parent)
2276+
acpi_create_video_bus_device(device, parent);
22322277
} else {
22332278
/* For a regular device object, create a platform device. */
22342279
acpi_create_platform_device(device, NULL);

0 commit comments

Comments
 (0)