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 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).

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