On Wed, Jun 10, 2015 at 03:01:07PM +0200, Hans de Goede wrote: > Currently we have 2 kernel commandline options + dmi-quirks in 3 places all > interacting (in interesting ways) to select which which backlight interface > to use. On the commandline we've acpi_backlight=[video|vendor] and > video.use_native_backlight=[0|1]. DMI quirks we have in > acpi/video-detect.c, acpi/video.c and drivers/platform/x86/*.c . > > This commit is the first step to cleaning this up, replacing the 2 cmdline > options with just acpi_video.backlight=[video|vendor|native|none], and > adding a new API to video_detect.c to reflect this. I like backlight=[firmware|platform|raw|none] better, but that would require to put the selection/quirk logic to backlight core. What do you think? Regards, Aaron > > Follow up commits will also move other related code, like unregistering the > acpi_video backlight interface if it was registered before other drivers > which take priority over it are loaded, to video_detect.c where this > logic really belongs. > > Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> > --- > drivers/acpi/video_detect.c | 172 +++++++++++++++++++++----------------------- > include/acpi/video.h | 17 +++++ > 2 files changed, 100 insertions(+), 89 deletions(-) > > diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c > index 0bc8b98..01c8c46 100644 > --- a/drivers/acpi/video_detect.c > +++ b/drivers/acpi/video_detect.c > @@ -1,4 +1,6 @@ > /* > + * Copyright (C) 2015 Red Hat Inc. > + * Hans de Goede <hdegoede@xxxxxxxxxx> > * Copyright (C) 2008 SuSE Linux Products GmbH > * Thomas Renninger <trenn@xxxxxxx> > * > @@ -9,28 +11,24 @@ > * acpi_get_pci_dev() 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 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-laptop, > * sony_acpi,... can take care about backlight brightness. > * > - * 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. > + * Backlight drivers can use acpi_video_get_backlight_type() to determine > + * which driver should handle the backlight. > * > + * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) > + * this file will not be compiled and acpi_video_get_backlight_type() will > + * always return acpi_backlight_vendor. > */ > > +#include <acpi/video.h> > #include <linux/export.h> > #include <linux/acpi.h> > +#include <linux/backlight.h> > #include <linux/dmi.h> > #include <linux/module.h> > #include <linux/pci.h> > @@ -38,20 +36,24 @@ > ACPI_MODULE_NAME("video"); > #define _COMPONENT ACPI_VIDEO_COMPONENT > > -static long acpi_video_support; > -static bool acpi_video_caps_checked; > +static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef; > +static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef; > > static char acpi_backlight_str[16]; > module_param_string(backlight, acpi_backlight_str, 16, 0444); > MODULE_PARM_DESC(backlight, > - "Select which backlight interface to use [vendor|video]"); > + "Select which backlight interface to use [vendor|video|native]"); > > static void acpi_video_parse_cmdline(void) > { > if (!strcmp("vendor", acpi_backlight_str)) > - acpi_video_support |= ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; > + acpi_backlight_cmdline = acpi_backlight_vendor; > if (!strcmp("video", acpi_backlight_str)) > - acpi_video_support |= ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO; > + acpi_backlight_cmdline = acpi_backlight_video; > + if (!strcmp("native", acpi_backlight_str)) > + acpi_backlight_cmdline = acpi_backlight_native; > + if (!strcmp("none", acpi_backlight_str)) > + acpi_backlight_cmdline = acpi_backlight_none; > } > > static acpi_status > @@ -82,7 +84,7 @@ find_video(acpi_handle handle, u32 lvl, void *context, void **rv) > * buggy */ > static int video_detect_force_vendor(const struct dmi_system_id *d) > { > - acpi_video_support |= ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; > + acpi_backlight_dmi = acpi_backlight_vendor; > return 0; > } > > @@ -130,99 +132,91 @@ static struct dmi_system_id video_detect_dmi_table[] = { > }; > > /* > - * Returns the video capabilities of a specific ACPI graphics device > + * Determine which type of backlight interface to use on this system, > + * First check cmdline, then dmi quirks, then do autodetect. > + * > + * The autodetect order is: > + * 1) Is the acpi-video backlight interface supported -> > + * no, use a vendor interface > + * 2) Is this a win8 "ready" BIOS and do we have a native interface -> > + * yes, use a native interface > + * 3) Else use the acpi-video interface > * > - * if NULL is passed as argument all ACPI devices are enumerated and > - * all graphics capabilities of physically present devices are > - * summarized and returned. This is cached and done only once. > + * Arguably the native on win8 check should be done first, but that would > + * be a behavior change, which may causes issues. > */ > -static long acpi_video_get_capabilities(acpi_handle graphics_handle) > +enum acpi_backlight_type acpi_video_get_backlight_type(void) > { > - 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, NULL, > - &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_BACKLIGHT_DMI_VENDOR; > - *} > - */ > + static DEFINE_MUTEX(init_mutex); > + static bool init_done; > + static long video_caps; > > + /* Parse cmdline, dmi and acpi only once */ > + mutex_lock(&init_mutex); > + if (!init_done) { > + acpi_video_parse_cmdline(); > dmi_check_system(video_detect_dmi_table); > - } else { > - status = acpi_bus_get_device(graphics_handle, &tmp_dev); > - if (ACPI_FAILURE(status)) { > - ACPI_EXCEPTION((AE_INFO, status, "Invalid device")); > - return 0; > - } > - acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle, > + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, > ACPI_UINT32_MAX, find_video, NULL, > - &caps, NULL); > + &video_caps, NULL); > + init_done = true; > } > - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n", > - graphics_handle ? caps : acpi_video_support, > - graphics_handle ? "on device " : "in general", > - graphics_handle ? acpi_device_bid(tmp_dev) : "")); > - return caps; > + mutex_unlock(&init_mutex); > + > + if (acpi_backlight_cmdline != acpi_backlight_undef) > + return acpi_backlight_cmdline; > + > + if (acpi_backlight_dmi != acpi_backlight_undef) > + return acpi_backlight_dmi; > + > + if (!(video_caps & ACPI_VIDEO_BACKLIGHT)) > + return acpi_backlight_vendor; > + > + if (acpi_osi_is_win8() && backlight_device_registered(BACKLIGHT_RAW)) > + return acpi_backlight_native; > + > + return acpi_backlight_video; > } > +EXPORT_SYMBOL(acpi_video_get_backlight_type); > > -static void acpi_video_caps_check(void) > +/* > + * Set the preferred backlight interface type based on DMI info. > + * This function allows DMI blacklists to be implemented by external > + * platform drivers instead of putting a big blacklist in video_detect.c > + */ > +void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type) > { > - /* > - * We must check whether the ACPI graphics device is physically plugged > - * in. Therefore this must be called after binding PCI and ACPI devices > - */ > - if (!acpi_video_caps_checked) { > - acpi_video_parse_cmdline(); > - acpi_video_get_capabilities(NULL); > - } > + acpi_backlight_dmi = type; > } > +EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type); > > -/* Promote the vendor interface instead of the generic video module. > - * This function allow DMI blacklists to be implemented by externals > - * platform drivers instead of putting a big blacklist in video_detect.c > +/* > + * Compatiblity function, this is going away as soon as all drivers are > + * converted to acpi_video_set_dmi_backlight_type(). > + * > + * Promote the vendor interface instead of the generic video module. > * After calling this function you will probably want to call > * acpi_video_unregister() to make sure the video module is not loaded > */ > void acpi_video_dmi_promote_vendor(void) > { > - acpi_video_caps_check(); > - acpi_video_support |= ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; > + acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); > } > EXPORT_SYMBOL(acpi_video_dmi_promote_vendor); > > -/* Returns true if video.ko can do backlight switching */ > +/* > + * Compatiblity function, this is going away as soon as all drivers are > + * converted to acpi_video_get_backlight_type(). > + * > + * Returns true if video.ko can do backlight switching. > + */ > int acpi_video_backlight_support(void) > { > - acpi_video_caps_check(); > - > - /* First check for boot param -> highest prio */ > - if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR) > - return 0; > - else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO) > - return 1; > - > - /* Then check for DMI blacklist -> second highest prio */ > - if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VENDOR) > - return 0; > - else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VIDEO) > - return 1; > - > - /* Then go the default way */ > - return acpi_video_support & ACPI_VIDEO_BACKLIGHT; > + /* > + * This is done this way since vendor drivers call this to see > + * if they should load, and we do not want them to load for both > + * the acpi_backlight_video and acpi_backlight_native cases. > + */ > + return acpi_video_get_backlight_type() != acpi_backlight_vendor; > } > EXPORT_SYMBOL(acpi_video_backlight_support); > diff --git a/include/acpi/video.h b/include/acpi/video.h > index 843ef1a..01b5cc7 100644 > --- a/include/acpi/video.h > +++ b/include/acpi/video.h > @@ -16,6 +16,14 @@ struct acpi_device; > #define ACPI_VIDEO_DISPLAY_LEGACY_PANEL 0x0110 > #define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200 > > +enum acpi_backlight_type { > + acpi_backlight_undef = -1, > + acpi_backlight_none = 0, > + acpi_backlight_video, > + acpi_backlight_vendor, > + acpi_backlight_native, > +}; > + > #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) > extern int acpi_video_register(void); > extern void acpi_video_unregister(void); > @@ -23,6 +31,8 @@ extern void acpi_video_unregister_backlight(void); > extern int acpi_video_get_edid(struct acpi_device *device, int type, > int device_id, void **edid); > extern bool acpi_video_verify_backlight_support(void); > +extern enum acpi_backlight_type acpi_video_get_backlight_type(void); > +extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type); > #else > static inline int acpi_video_register(void) { return 0; } > static inline void acpi_video_unregister(void) { return; } > @@ -33,6 +43,13 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type, > return -ENODEV; > } > static inline bool acpi_video_verify_backlight_support(void) { return false; } > +static inline enum acpi_backlight_type acpi_video_get_backlight_type(void) > +{ > + return acpi_backlight_vendor; > +} > +static void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type) > +{ > +} > #endif > > #endif > -- > 2.4.2 > > -- > 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 ------------------------------------------------------------------------------ _______________________________________________ ibm-acpi-devel mailing list ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/ibm-acpi-devel