Re: [PATCH 02/11] Check for ACPI backlight support otherwise use vendor ACPI drivers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2008-07-23 at 17:49 +0800, Thomas Renninger wrote:
> On Wednesday 23 July 2008 05:35:39 Zhang Rui wrote:
> > On Thu, 2008-07-17 at 19:32 +0200, Thomas Renninger wrote:
> > > If an ACPI graphics device supports backlight brightness functions
> (cmp.
> > > with latest ACPI spec Appendix B), let the ACPI video driver
> control
> > > backlight and switch backlight control off in vendor specific ACPI
> > > drivers (asus_acpi, thinkpad_acpi, eeepc, fujitsu_laptop,
> msi_laptop,
> > > sony_laptop, acer-wmi).
> > >
> > > Currently it is possible to load above drivers and let both poke
> on the
> > > brightness HW registers, the video and vendor specific ACPI
> drivers ->
> > > bad.
> > >
> > > This patch provides the basic support to check for BIOS
> capabilities
> > > before driver loading time. Driver specific modifications are in
> separate
> > > follow up patches.
> > >
> > > acpi_backlight=vendor/video
> > >       boot params forces video.ko or vendor specific drivers to
> keep its
> > >       fingers off backlight control even it would find needed
> functions.
> > >       The corresponding vendor specific driver be used then.
> > >
> > > Signed-off-by: Thomas Renninger <trenn@xxxxxxx>
> > > ---
> > >  Documentation/kernel-parameters.txt |   13 ++
> > >  drivers/acpi/Makefile               |    5 +
> > >  drivers/acpi/scan.c                 |   32 +----
> > >  drivers/acpi/video.c                |   28 ++--
> > >  drivers/acpi/video_detect.c         |  267
> > > +++++++++++++++++++++++++++++++++++ include/linux/acpi.h
> |
> > >   44 ++++++
> > >  6 files changed, 346 insertions(+), 43 deletions(-)
> > >  create mode 100644 drivers/acpi/video_detect.c
> > >
> > > diff --git a/Documentation/kernel-parameters.txt
> > > b/Documentation/kernel-parameters.txt index 6acfe8e..56392f8
> 100644
> > > --- a/Documentation/kernel-parameters.txt
> > > +++ b/Documentation/kernel-parameters.txt
> > > @@ -191,6 +191,19 @@ and is between 256 and 4096 characters. It is
> > > defined in the file that require a timer override, but don't have
> > >                     HPET
> > >
> > > +   acpi_backlight= [HW,ACPI]
> > > +                   acpi_backlight=vendor
> > > +                   acpi_backlight=video
> > > +                   If set to vendor, it enforces the use of a
> > > +                   vendor specific ACPI driver for backlight
> switching
> > > +                   (e.g. thinkpad_acpi, sony_acpi, etc.) instead
> > > +                   of the video.ko driver.
> > > +
> > > +   acpi_display_output=    [HW,ACPI]
> > > +                   acpi_display_output=vendor
> > > +                   acpi_display_output=video
> > > +                   See above.
> > > +
> > >     acpi.debug_layer=       [HW,ACPI]
> > >                     Format: <int>
> > >                     Each bit of the <int> indicates an ACPI debug
> layer,
> > > diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> > > index 4efbe59..d91dc80 100644
> > > --- a/drivers/acpi/Makefile
> > > +++ b/drivers/acpi/Makefile
> > > @@ -46,7 +46,12 @@ obj-$(CONFIG_ACPI_BUTTON)        += button.o
> > >  obj-$(CONFIG_ACPI_FAN)             += fan.o
> > >  obj-$(CONFIG_ACPI_DOCK)            += dock.o
> > >  obj-$(CONFIG_ACPI_BAY)             += bay.o
> > > +
> > >  obj-$(CONFIG_ACPI_VIDEO)   += video.o
> > > +ifdef CONFIG_ACPI_VIDEO
> > > +obj-y                              += video_detect.o
> > > +endif
> > > +
> > >  obj-y                              += pci_root.o pci_link.o
> pci_irq.o pci_bind.o
> > >  obj-$(CONFIG_ACPI_POWER)   += power.o
> > >  obj-$(CONFIG_ACPI_PROCESSOR)       += processor.o
> > > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> > > index 5b049cd..fb8e2df 100644
> > > --- a/drivers/acpi/scan.c
> > > +++ b/drivers/acpi/scan.c
> > > @@ -931,36 +931,6 @@ static void acpi_device_get_busid(struct
> acpi_device
> > > *device, }
> > >  }
> > >
> > > -static int
> > > -acpi_video_bus_match(struct acpi_device *device)
> > > -{
> > > -   acpi_handle h_dummy;
> > > -
> > > -   if (!device)
> > > -           return -EINVAL;
> > > -
> > > -   /* Since there is no HID, CID for ACPI Video drivers, we have
> > > -    * to check well known required nodes for each feature we
> support.
> > > -    */
> > > -
> > > -   /* Does this device able to support video switching ? */
> > > -   if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD",
> &h_dummy)) &&
> > > -       ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS",
> &h_dummy)))
> > > -           return 0;
> > > -
> > > -   /* Does this device able to retrieve a video ROM ? */
> > > -   if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM",
> &h_dummy)))
> > > -           return 0;
> > > -
> > > -   /* Does this device able to configure which video head to be
> POSTed ?
> > > */ -        if (ACPI_SUCCESS(acpi_get_handle(device->handle,
> "_VPO", &h_dummy))
> > > && -            ACPI_SUCCESS(acpi_get_handle(device->handle,
> "_GPD", &h_dummy))
> > > && -            ACPI_SUCCESS(acpi_get_handle(device->handle,
> "_SPD", &h_dummy)))
> > > -           return 0;
> > > -
> > > -   return -ENODEV;
> > > -}
> > > -
> > >  /*
> > >   * acpi_bay_match - see if a device is an ejectable driver bay
> > >   *
> > > @@ -1043,7 +1013,7 @@ static void acpi_device_set_id(struct
> acpi_device
> > > *device, will get autoloaded and the device might still match
> > >                against another driver.
> > >             */
> > > -           if (ACPI_SUCCESS(acpi_video_bus_match(device)))
> > > +           if (acpi_is_video_device(device))
> > >                     cid_add = ACPI_VIDEO_HID;
> > >             else if (ACPI_SUCCESS(acpi_bay_match(device)))
> > >                     cid_add = ACPI_BAY_HID;
> > > diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
> > > index 767d9b9..0533e0d 100644
> > > --- a/drivers/acpi/video.c
> > > +++ b/drivers/acpi/video.c
> > > @@ -739,7 +739,8 @@ static void acpi_video_device_find_cap(struct
> > > acpi_video_device *device) device->cap._DSS = 1;
> > >     }
> > >
> > > -   max_level = acpi_video_init_brightness(device);
> > > +   if (acpi_video_backlight_support())
> > > +           max_level = acpi_video_init_brightness(device);
> > >
> > >     if (device->cap._BCL && device->cap._BCM && device->cap._BQC
> &&
> > > max_level > 0){ int result;
> > > @@ -776,18 +777,21 @@ static void
> acpi_video_device_find_cap(struct
> > > acpi_video_device *device) printk(KERN_ERR PREFIX "Create sysfs
> link\n");
> > >
> > >     }
> > > -   if (device->cap._DCS && device->cap._DSS){
> > > -           static int count = 0;
> > > -           char *name;
> > > -           name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
> > > -           if (!name)
> > > -                   return;
> > > -           sprintf(name, "acpi_video%d", count++);
> > > -           device->output_dev = video_output_register(name,
> > > -                           NULL, device,
> &acpi_output_properties);
> > > -           kfree(name);
> > > +
> > > +   if (acpi_video_display_switch_support()) {
> > > +
> > > +           if (device->cap._DCS && device->cap._DSS) {
> > > +                   static int count;
> > > +                   char *name;
> > > +                   name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
> > > +                   if (!name)
> > > +                           return;
> > > +                   sprintf(name, "acpi_video%d", count++);
> > > +                   device->output_dev =
> video_output_register(name,
> > > +                                   NULL, device,
> &acpi_output_properties);
> > > +                   kfree(name);
> > > +           }
> > >     }
> > > -   return;
> > >  }
> > >
> > >  /*
> > > diff --git a/drivers/acpi/video_detect.c
> b/drivers/acpi/video_detect.c
> > > new file mode 100644
> > > index 0000000..e90a5dc
> > > --- /dev/null
> > > +++ b/drivers/acpi/video_detect.c
> > > @@ -0,0 +1,267 @@
> > > +/*
> > > + *  Copyright (C) 2008       SuSE Linux Products GmbH
> > > + *                           Thomas Renninger <trenn@xxxxxxx>
> > > + *
> > > + *  May be copied or modified under the terms of the GNU General
> Public
> > > License + *
> > > + * video_detect.c:
> > > + * Provides acpi_is_video_device() for early scanning of ACPI
> devices in
> > > scan.c + * There a Linux specific (Spec does not provide a HID for
> video
> > > devices) is + * assinged
> > > + *
> > > + * After PCI devices are glued with ACPI devices
> > > + * acpi_get_physical_pci_device() can be called to identify ACPI
> > > graphics + * devices for which a real graphics card is plugged in
> > > + *
> > > + * Now acpi_video_get_capabilities() can be called to check which
> > > + * capabilities the graphics cards plugged in support. The check
> for
> > > general + * video capabilities will be triggered by the first
> caller of
> > > + * acpi_video_get_capabilities(NULL); which will happen when the
> first
> > > + * backlight (or display output) switching supporting driver
> calls:
> > > + * acpi_video_backlight_support();
> > > + *
> > > + * Depending on whether ACPI graphics extensions (cmp. ACPI spec
> > > Appendix B) + * are available, video.ko should be used to handle
> the
> > > device. + *
> > > + * Otherwise vendor specific drivers like thinkpad_acpi,
> asus_acpi,
> > > + * sony_acpi,... can take care about backlight brightness and
> display
> > > output + * switching.
> > > + *
> > > + * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor
> as a
> > > module (m) + * this file will not be compiled,
> > > acpi_video_get_capabilities() and + *
> acpi_video_backlight_support() will
> > > always return 0 and vendor specific + * drivers always can handle
> > > backlight.
> > > + *
> > > + */
> > > +
> > > +#include <linux/acpi.h>
> > > +#include <linux/dmi.h>
> > > +
> > > +ACPI_MODULE_NAME("video");
> > > +#define ACPI_VIDEO_COMPONENT               0x08000000
> > > +#define _COMPONENT         ACPI_VIDEO_COMPONENT
> > > +
> > > +static long acpi_video_support;
> > > +static bool acpi_video_caps_checked;
> > > +
> > > +static acpi_status
> > > +acpi_backlight_cap_match(acpi_handle handle, u32 level, void
> *context,
> > > +                     void **retyurn_value)
> > > +{
> > > +   long *cap = context;
> > > +   acpi_handle h_dummy;
> > > +
> > > +   if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
> > > +       ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
> > > +           ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic
> backlight "
> > > +                             "support\n"));
> > > +           *cap |= ACPI_VIDEO_BACKLIGHT;
> > > +           return 0;
> > > +   }
> > > +   return -ENODEV;
> > > +}
> > > +
> > > +/* Returns true if the device is a video device which can be
> handled by
> > > + * video.ko.
> > > + * The device will get a Linux specific CID added in scan.c to
> > > + * identify the device as an ACPI graphics device
> > > + * Be aware that the graphics device may not be physically
> present
> > > + * Use acpi_video_get_capabilities() to detect general ACPI video
> > > + * capabilities of present cards
> > > + */
> > > +long acpi_is_video_device(struct acpi_device *device)
> > > +{
> > > +   acpi_handle h_dummy;
> > > +   long video_caps = 0;
> > > +
> > > +   if (!device)
> > > +           return 0;
> > > +
> > > +   /* Since there is no HID, CID for ACPI Video drivers, we have
> > > +    * to check well known required nodes for each feature we
> support.
> > > +    */
> > > +
> > > +   /* Does this device able to support video switching ? */
> > > +   if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD",
> &h_dummy)) &&
> > > +       ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS",
> &h_dummy)))
> > > +           video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
> > > +
> > > +   /* Does this device able to retrieve a video ROM ? */
> > > +   if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM",
> &h_dummy)))
> > > +           video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
> > > +
> > > +   /* Does this device able to configure which video head to be
> POSTed ?
> > > */ +        if (ACPI_SUCCESS(acpi_get_handle(device->handle,
> "_VPO", &h_dummy))
> > > && +            ACPI_SUCCESS(acpi_get_handle(device->handle,
> "_GPD", &h_dummy))
> > > && +            ACPI_SUCCESS(acpi_get_handle(device->handle,
> "_SPD", &h_dummy)))
> > > +           video_caps |= ACPI_VIDEO_DEVICE_POSTING;
> > > +
> > > +   acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle,
> ACPI_UINT32_MAX,
> > > +                       acpi_backlight_cap_match, &video_caps,
> NULL);
> > > +
> > > +   return video_caps;
> > > +}
> > > +EXPORT_SYMBOL(acpi_is_video_device);
> > > +
> > > +static acpi_status
> > > +find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
> > > +{
> > > +   long *cap = context;
> > > +   struct device *dev;
> > > +   struct acpi_device *acpi_dev;
> > > +
> > > +   const struct acpi_device_id video_ids[] = {
> > > +           {ACPI_VIDEO_HID, 0},
> > > +           {"", 0},
> > > +   };
> > > +   if (acpi_bus_get_device(handle, &acpi_dev))
> > > +           return AE_OK;
> > > +
> > > +   if (!acpi_match_device_ids(acpi_dev, video_ids)) {
> > > +           dev = acpi_get_physical_pci_device(handle);
> > > +           if (!dev)
> > > +                   return AE_OK;
> > > +           put_device(dev);
> > > +           *cap |= acpi_is_video_device(acpi_dev);
> > > +   }
> > > +   return AE_OK;
> > > +}
> > > +
> > > +/* Returns the video capabilities of a specific ACPI graphics
> device
> > > + *
> > > + * if NULL is passed as argument all ACPI devices are enumerated
> and
> > > + * all graphics capabilities of physically present devices are
> > > + * summerized and returned. This is cached and done only once.
> > > + */
> > > +long acpi_video_get_capabilities(acpi_handle graphics_handle)
> > > +{
> > > +   long caps = 0;
> > > +   struct acpi_device *tmp_dev;
> > > +   acpi_status status;
> > > +
> > > +   if (acpi_video_caps_checked && graphics_handle == NULL)
> > > +           return acpi_video_support;
> > > +
> > > +   if (!graphics_handle) {
> > > +           /* Only do the global walk through all graphics
> devices once */
> > > +           acpi_walk_namespace(ACPI_TYPE_DEVICE,
> ACPI_ROOT_OBJECT,
> > > +                               ACPI_UINT32_MAX, find_video,
> > > +                               &caps, NULL);
> > > +           /* There might be boot param flags set already... */
> > > +           acpi_video_support |= caps;
> > > +           acpi_video_caps_checked = 1;
> > > +           /* Add blacklists here. Be careful to use the right
> *DMI* bits
> > > +            * to still be able to override logic via boot params,
> e.g.:
> > > +            *
> > > +            *   if (dmi_name_in_vendors("XY")) {
> > > +            *      acpi_video_support |=
> > > +            *
> ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR;
> > > +            *      acpi_video_support |=
> > > +            *              ACPI_VIDEO_BACKLIGHT_DMI_VENDOR;
> > > +            *}
> > > +            */
> >
> > so this is for the thinkpad laptops which patch 01 breaks, right?
> > why don't you add the thinkpad dmi entries directly?
> > If we don't blacklist them, this patch set still causes regressions
> on
> > these laptops, unless the IGD OpRegion patches are upstream.
> 
> Because Matthew told us the IGD OpRegion patches will be upstream for
> 2.6.27.
> While this makes it a bit difficult to test these, it is a good idea
> though to
> try to do it right in first place.
> 
> So if there are still problems, people can test with boot params. If
> we are
> not able to fix things during 2.6.27-rcX so that they work properly
> with
> video.ko, we can still add a dmi blacklist for specific models (should
> be
> some general "panasonic" string or something like that, most vendors
> should
> have similar general ACPI brightness implementation as this is quite
> young).

I see. Then I'm okay with the whole patch series.

Acked-by: Zhang Rui <rui.zhang@xxxxxxxxx>

thanks,
rui
> 
> Andi, these patches are needed by Matthews IGD OpRegion driver, or
> video.ko
> will still register for two graphics devices even there is only one.
> Do you plan do push them?
> 
>        Thomas
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux