[PATCH 01/10] ACPI: video: Ignore devices that aren't present in hardware
Tim Gardner
tcanonical at tpi.com
Thu Nov 20 18:18:45 UTC 2008
Andy Whitcroft wrote:
> From: Thomas Renninger <trenn at suse.de>
>
> Bug: #257827
> commit 22c13f9d8179f4c9caecfcb60a95214562b9addc upstream
>
> This is a reimplemention of commit
> 0119509c4fbc9adcef1472817fda295334612976
> from Matthew Garrett <mjg59 at srcf.ucam.org>
>
> This patch got removed because of a regression: ThinkPads with a
> Intel graphics card and an Integrated Graphics Device BIOS implementation
> stopped working.
> In fact, they only worked because the ACPI device of the discrete, the
> wrong one, got used (via int10). So ACPI functions were poking on the wrong
> hardware used which is a sever bug.
> The next patch provides support for above ThinkPads to be able to
> switch brightness via the legacy thinkpad_acpi driver and automatically
> detect when to use it.
>
> Original commit message from Matthew Garrett:
> Vendors often ship machines with a choice of integrated or discrete
> graphics, and use the same DSDT for both. As a result, the ACPI video
> module will locate devices that may not exist on this specific platform.
> Attempt to determine whether the device exists or not, and abort the
> device creation if it doesn't.
>
> http://bugzilla.kernel.org/show_bug.cgi?id=9614
>
> Signed-off-by: Thomas Renninger <trenn at suse.de>
> Acked-by: Zhang Rui <rui.zhang at intel.com>
> Signed-off-by: Andi Kleen <ak at linux.intel.com>
> Signed-off-by: Len Brown <len.brown at intel.com>
> Signed-off-by: Andy Whitcroft <apw at canonical.com>
> ---
> drivers/acpi/glue.c | 40 ++++++++++++++++++++++++++++++++++++++++
> drivers/acpi/video.c | 7 ++++++-
> include/acpi/acpi_bus.h | 2 ++
> 3 files changed, 48 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
> index 8dd3336..1e79f0c 100644
> --- a/drivers/acpi/glue.c
> +++ b/drivers/acpi/glue.c
> @@ -140,6 +140,46 @@ struct device *acpi_get_physical_device(acpi_handle handle)
>
> EXPORT_SYMBOL(acpi_get_physical_device);
>
> +/* ToDo: When a PCI bridge is found, return the PCI device behind the bridge
> + * This should work in general, but did not on a Lenovo T61 for the
> + * graphics card. But this must be fixed when the PCI device is
> + * bound and the kernel device struct is attached to the acpi device
> + * Note: A success call will increase reference count by one
> + * Do call put_device(dev) on the returned device then
> + */
> +struct device *acpi_get_physical_pci_device(acpi_handle handle)
> +{
> + struct device *dev;
> + long long device_id;
> + acpi_status status;
> +
> + status =
> + acpi_evaluate_integer(handle, "_ADR", NULL, &device_id);
> +
> + if (ACPI_FAILURE(status))
> + return NULL;
> +
> + /* We need to attempt to determine whether the _ADR refers to a
> + PCI device or not. There's no terribly good way to do this,
> + so the best we can hope for is to assume that there'll never
> + be a device in the host bridge */
> + if (device_id >= 0x10000) {
> + /* It looks like a PCI device. Does it exist? */
> + dev = acpi_get_physical_device(handle);
> + } else {
> + /* It doesn't look like a PCI device. Does its parent
> + exist? */
> + acpi_handle phandle;
> + if (acpi_get_parent(handle, &phandle))
> + return NULL;
> + dev = acpi_get_physical_device(phandle);
> + }
> + if (!dev)
> + return NULL;
> + return dev;
> +}
> +EXPORT_SYMBOL(acpi_get_physical_pci_device);
> +
> static int acpi_bind_one(struct device *dev, acpi_handle handle)
> {
> struct acpi_device *acpi_dev;
> diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
> index e8a51a1..d15df51 100644
> --- a/drivers/acpi/video.c
> +++ b/drivers/acpi/video.c
> @@ -842,11 +842,16 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
> static int acpi_video_bus_check(struct acpi_video_bus *video)
> {
> acpi_status status = -ENOENT;
> -
> + struct device *dev;
>
> if (!video)
> return -EINVAL;
>
> + dev = acpi_get_physical_pci_device(video->device->handle);
> + if (!dev)
> + return -ENODEV;
> + put_device(dev);
> +
> /* Since there is no HID, CID and so on for VGA driver, we have
> * to check well known required nodes.
> */
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index a5ac0bc..234733c 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -373,6 +373,8 @@ struct acpi_bus_type {
> int register_acpi_bus_type(struct acpi_bus_type *);
> int unregister_acpi_bus_type(struct acpi_bus_type *);
> struct device *acpi_get_physical_device(acpi_handle);
> +struct device *acpi_get_physical_pci_device(acpi_handle);
> +
> /* helper */
> acpi_handle acpi_get_child(acpi_handle, acpi_integer);
> acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
ACK - if this commit really is intended to fix "brightness changes twice
when using hotkeys". I assume it does so by avoiding duplicate devices,
one of which is bogus?
--
Tim Gardner tim.gardner at canonical.com
More information about the kernel-team
mailing list