diff options
author | Dave Airlie <airlied@redhat.com> | 2022-01-31 16:33:54 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2022-02-01 19:02:41 +1000 |
commit | 53dbee4926d3706ca9e03f3928fa85b5ec3bc0cc (patch) | |
tree | a1c8f86cb049ddb5fe37cd1d4fedd2e0bb3d7b0f /drivers/platform | |
parent | 26291c54e111ff6ba87a164d85d4a4e134b7315c (diff) | |
parent | a5d092d37eb5d25520d283985082e977bda68eb7 (diff) | |
download | lwn-53dbee4926d3706ca9e03f3928fa85b5ec3bc0cc.tar.gz lwn-53dbee4926d3706ca9e03f3928fa85b5ec3bc0cc.zip |
Merge tag 'drm-misc-next-2022-01-27' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
[airlied: add two missing Kconfig]
drm-misc-next for v5.18:
UAPI Changes:
- Fix invalid IN_FORMATS blob when plane->format_mod_supported is NULL.
Cross-subsystem Changes:
- Assorted dt bindings updates.
- Fix vga16fb vga checking on x86.
- Fix extra semicolon in rwsem.h's _down_write_nest_lock.
- Assorted small fixes to agp and fbdev drivers.
- Fix oops in creating a udmabuf with 0 pages.
- Hot-unplug firmware fb devices on forced removal
- Reqquest memory region in simplefb and simpledrm, and don't make the ioresource as busy.
Core Changes:
- Mock a drm_plane in drm-plane-helper selftest.
- Assorted bug fixes to device logging, dbi.
- Use DP helper for sink count in mst.
- Assorted documentation fixes.
- Assorted small fixes.
- Move DP headers to drm/dp, and add a drm dp helper module.
- Move the buddy allocator from i915 to common drm.
- Add simple pci and platform module init macros to remove a lot of boilerplate from some drivers.
- Support microsoft extension for HMDs and specialized monitors.
- Improve edid parser's deep color handling.
- Add type 7 timing support to edid parser.
- Add a weak backpointer to the ttm_bo from ttm_resource
- Add 3 eDP panels.
Driver Changes:
- Add support for HDMI and JZ4780 to ingenic.
- Add support for higher DP/eDP bitrates to nouveau.
- Assorted driver fixes to tilcdc, vmwgfx, sn65dsi83, meson, stm, panfrost, v3d, gma500, vc4, virtio, mgag200, ast, radeon, amdgpu, nouveau, various bridge drivers.
- Convert and revert exynos dsi support to bridge driver.
- Add vcc supply regulator support for sn65dsi83.
- More conversion of bridge/chipone-icn6211 to atomic.
- Remove conflicting fb's from stm, and add support for new hw version.
- Add device link in parade-ps8640 to fix suspend/resume.
- Update Boe-tv110c9m init sequence.
- Add wide screen support to AST2600.
- Fix omapdrm implicit dma_buf fencing.
- Add support for multiple overlay planes to vkms.
- Convert bridge/anx7625 to atomic, add HDCP support,
add eld support for audio, and fix HPD.
- Add driver for ChromeOS privacy screen.
- Handover display from firmware to vc4 more gracefully, and support nomodeset.
- Add flexible and ycbcr pixel formats to stm/ltdc.
- Convert exynos mipi dsi to atomic.
- Add initial dual core group GPUs support to panfrost.
- No longer add exclusive fence in amdgpu as shared fence.
- Add CSC and full range supoprt to vc4.
- Shutdown the display on system shutdown and unbind.
- Add Multi-Inno Technology MI0700S4T-6 simple panel.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/456a23c6-7324-7543-0c45-751f30ef83f7@linux.intel.com
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/chrome/Kconfig | 11 | ||||
-rw-r--r-- | drivers/platform/chrome/Makefile | 1 | ||||
-rw-r--r-- | drivers/platform/chrome/chromeos_privacy_screen.c | 153 | ||||
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 2 |
4 files changed, 166 insertions, 1 deletions
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index ccc23d8686e8..75e93efd669f 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -243,6 +243,17 @@ config CROS_USBPD_NOTIFY To compile this driver as a module, choose M here: the module will be called cros_usbpd_notify. +config CHROMEOS_PRIVACY_SCREEN + tristate "ChromeOS Privacy Screen support" + depends on ACPI + depends on DRM + select DRM_PRIVACY_SCREEN + help + This driver provides the support needed for the in-built electronic + privacy screen that is present on some ChromeOS devices. When enabled, + this should probably always be built into the kernel to avoid or + minimize drm probe deferral. + source "drivers/platform/chrome/wilco_ec/Kconfig" endif # CHROMEOS_PLATFORMS diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index f901d2e43166..5d4be9735d9d 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile @@ -4,6 +4,7 @@ CFLAGS_cros_ec_trace.o:= -I$(src) obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o +obj-$(CONFIG_CHROMEOS_PRIVACY_SCREEN) += chromeos_privacy_screen.o obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o obj-$(CONFIG_CROS_EC) += cros_ec.o diff --git a/drivers/platform/chrome/chromeos_privacy_screen.c b/drivers/platform/chrome/chromeos_privacy_screen.c new file mode 100644 index 000000000000..77e9f5ee8e33 --- /dev/null +++ b/drivers/platform/chrome/chromeos_privacy_screen.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * ChromeOS Privacy Screen support + * + * Copyright (C) 2022 Google LLC + * + * This is the Chromeos privacy screen provider, present on certain chromebooks, + * represented by a GOOG0010 device in the ACPI. This ACPI device, if present, + * will cause the i915 drm driver to probe defer until this driver registers + * the privacy-screen. + */ + +#include <linux/acpi.h> +#include <drm/drm_privacy_screen_driver.h> + +/* + * The DSM (Device Specific Method) constants below are the agreed API with + * the firmware team, on how to control privacy screen using ACPI methods. + */ +#define PRIV_SCRN_DSM_REVID 1 /* DSM version */ +#define PRIV_SCRN_DSM_FN_GET_STATUS 1 /* Get privacy screen status */ +#define PRIV_SCRN_DSM_FN_ENABLE 2 /* Enable privacy screen */ +#define PRIV_SCRN_DSM_FN_DISABLE 3 /* Disable privacy screen */ + +static const guid_t chromeos_privacy_screen_dsm_guid = + GUID_INIT(0xc7033113, 0x8720, 0x4ceb, + 0x90, 0x90, 0x9d, 0x52, 0xb3, 0xe5, 0x2d, 0x73); + +static void +chromeos_privacy_screen_get_hw_state(struct drm_privacy_screen + *drm_privacy_screen) +{ + union acpi_object *obj; + acpi_handle handle; + struct device *privacy_screen = + drm_privacy_screen_get_drvdata(drm_privacy_screen); + + handle = acpi_device_handle(to_acpi_device(privacy_screen)); + obj = acpi_evaluate_dsm(handle, &chromeos_privacy_screen_dsm_guid, + PRIV_SCRN_DSM_REVID, + PRIV_SCRN_DSM_FN_GET_STATUS, NULL); + if (!obj) { + dev_err(privacy_screen, + "_DSM failed to get privacy-screen state\n"); + return; + } + + if (obj->type != ACPI_TYPE_INTEGER) + dev_err(privacy_screen, + "Bad _DSM to get privacy-screen state\n"); + else if (obj->integer.value == 1) + drm_privacy_screen->hw_state = drm_privacy_screen->sw_state = + PRIVACY_SCREEN_ENABLED; + else + drm_privacy_screen->hw_state = drm_privacy_screen->sw_state = + PRIVACY_SCREEN_DISABLED; + + ACPI_FREE(obj); +} + +static int +chromeos_privacy_screen_set_sw_state(struct drm_privacy_screen + *drm_privacy_screen, + enum drm_privacy_screen_status state) +{ + union acpi_object *obj = NULL; + acpi_handle handle; + struct device *privacy_screen = + drm_privacy_screen_get_drvdata(drm_privacy_screen); + + handle = acpi_device_handle(to_acpi_device(privacy_screen)); + + if (state == PRIVACY_SCREEN_DISABLED) { + obj = acpi_evaluate_dsm(handle, + &chromeos_privacy_screen_dsm_guid, + PRIV_SCRN_DSM_REVID, + PRIV_SCRN_DSM_FN_DISABLE, NULL); + } else if (state == PRIVACY_SCREEN_ENABLED) { + obj = acpi_evaluate_dsm(handle, + &chromeos_privacy_screen_dsm_guid, + PRIV_SCRN_DSM_REVID, + PRIV_SCRN_DSM_FN_ENABLE, NULL); + } else { + dev_err(privacy_screen, + "Bad attempt to set privacy-screen status to %u\n", + state); + return -EINVAL; + } + + if (!obj) { + dev_err(privacy_screen, + "_DSM failed to set privacy-screen state\n"); + return -EIO; + } + + drm_privacy_screen->hw_state = drm_privacy_screen->sw_state = state; + ACPI_FREE(obj); + return 0; +} + +static const struct drm_privacy_screen_ops chromeos_privacy_screen_ops = { + .get_hw_state = chromeos_privacy_screen_get_hw_state, + .set_sw_state = chromeos_privacy_screen_set_sw_state, +}; + +static int chromeos_privacy_screen_add(struct acpi_device *adev) +{ + struct drm_privacy_screen *drm_privacy_screen = + drm_privacy_screen_register(&adev->dev, + &chromeos_privacy_screen_ops, + &adev->dev); + + if (IS_ERR(drm_privacy_screen)) { + dev_err(&adev->dev, "Error registering privacy-screen\n"); + return PTR_ERR(drm_privacy_screen); + } + + adev->driver_data = drm_privacy_screen; + dev_info(&adev->dev, "registered privacy-screen '%s'\n", + dev_name(&drm_privacy_screen->dev)); + + return 0; +} + +static int chromeos_privacy_screen_remove(struct acpi_device *adev) +{ + struct drm_privacy_screen *drm_privacy_screen = acpi_driver_data(adev); + + drm_privacy_screen_unregister(drm_privacy_screen); + return 0; +} + +static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = { + {"GOOG0010", 0}, /* Google's electronic privacy screen for eDP-1 */ + {} +}; +MODULE_DEVICE_TABLE(acpi, chromeos_privacy_screen_device_ids); + +static struct acpi_driver chromeos_privacy_screen_driver = { + .name = "chromeos_privacy_screen_driver", + .class = "ChromeOS", + .ids = chromeos_privacy_screen_device_ids, + .ops = { + .add = chromeos_privacy_screen_add, + .remove = chromeos_privacy_screen_remove, + }, +}; + +module_acpi_driver(chromeos_privacy_screen_driver); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ChromeOS ACPI Privacy Screen driver"); +MODULE_AUTHOR("Rajat Jain <rajatja@google.com>"); diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 098180fb1cfc..99fbe90c926e 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9869,7 +9869,7 @@ static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm) return 0; lcdshadow_dev = drm_privacy_screen_register(&tpacpi_pdev->dev, - &lcdshadow_ops); + &lcdshadow_ops, NULL); if (IS_ERR(lcdshadow_dev)) return PTR_ERR(lcdshadow_dev); |