Merge tag 'chrome-platform-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform updates from Tzung-Bi Shih:
 "Improvements:

   - Reduce transmission size by dropping unnecessary data in
     cros_ec_lightbar

   - Convert chromeos_privacy_screen, chromeos_tbmc, and wilco_ec/event
     from ACPI drivers to platform drivers

  Fixes:

   - Drop wakeup source on remove() in chromeos_tbmc

  Cleanups:

   - Simplify workqueue usage with devm in cros_usbpd_logger"

* tag 'chrome-platform-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
  platform/chrome: cros_usbpd_logger: Simplify with devm
  platform/chrome: wilco_ec: event: Convert to a platform driver
  platform/chrome: wilco_ec: event: Register ACPI notify handler
  platform/chrome: chromeos_tbmc: Convert to a platform driver
  platform/chrome: chromeos_tbmc: Register ACPI notify handler
  platform/chrome: chromeos_tbmc: Drop wakeup source on remove
  platform/chrome: Convert ChromeOS privacy-screen driver to platform
  platform/chrome: lightbar: Optimize command size
This commit is contained in:
Linus Torvalds
2026-04-15 14:10:40 -07:00
5 changed files with 107 additions and 83 deletions

View File

@@ -12,6 +12,7 @@
*/
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <drm/drm_privacy_screen_driver.h>
/*
@@ -32,11 +33,10 @@ 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);
acpi_handle handle = ACPI_HANDLE(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);
@@ -65,11 +65,9 @@ chromeos_privacy_screen_set_sw_state(struct 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));
acpi_handle handle = ACPI_HANDLE(privacy_screen);
if (state == PRIVACY_SCREEN_DISABLED) {
obj = acpi_evaluate_dsm(handle,
@@ -104,30 +102,28 @@ static const struct drm_privacy_screen_ops chromeos_privacy_screen_ops = {
.set_sw_state = chromeos_privacy_screen_set_sw_state,
};
static int chromeos_privacy_screen_add(struct acpi_device *adev)
static int chromeos_privacy_screen_probe(struct platform_device *pdev)
{
struct drm_privacy_screen *drm_privacy_screen =
drm_privacy_screen_register(&adev->dev,
drm_privacy_screen_register(&pdev->dev,
&chromeos_privacy_screen_ops,
&adev->dev);
&pdev->dev);
if (IS_ERR(drm_privacy_screen)) {
dev_err(&adev->dev, "Error registering privacy-screen\n");
dev_err(&pdev->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",
platform_set_drvdata(pdev, drm_privacy_screen);
dev_info(&pdev->dev, "registered privacy-screen '%s'\n",
dev_name(&drm_privacy_screen->dev));
return 0;
}
static void chromeos_privacy_screen_remove(struct acpi_device *adev)
static void chromeos_privacy_screen_remove(struct platform_device *pdev)
{
struct drm_privacy_screen *drm_privacy_screen = acpi_driver_data(adev);
drm_privacy_screen_unregister(drm_privacy_screen);
drm_privacy_screen_unregister(platform_get_drvdata(pdev));
}
static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = {
@@ -136,17 +132,16 @@ static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = {
};
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,
static struct platform_driver chromeos_privacy_screen_driver = {
.probe = chromeos_privacy_screen_probe,
.remove = chromeos_privacy_screen_remove,
.driver = {
.name = "chromeos_privacy_screen_driver",
.acpi_match_table = chromeos_privacy_screen_device_ids,
},
};
module_acpi_driver(chromeos_privacy_screen_driver);
module_platform_driver(chromeos_privacy_screen_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ChromeOS ACPI Privacy Screen driver");
MODULE_AUTHOR("Rajat Jain <rajatja@google.com>");

View File

@@ -16,6 +16,7 @@
#include <linux/input.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#define DRV_NAME "chromeos_tbmc"
@@ -40,20 +41,20 @@ static int chromeos_tbmc_query_switch(struct acpi_device *adev,
static __maybe_unused int chromeos_tbmc_resume(struct device *dev)
{
struct acpi_device *adev = to_acpi_device(dev);
return chromeos_tbmc_query_switch(adev, adev->driver_data);
return chromeos_tbmc_query_switch(ACPI_COMPANION(dev), dev_get_drvdata(dev));
}
static void chromeos_tbmc_notify(struct acpi_device *adev, u32 event)
static void chromeos_tbmc_notify(acpi_handle handle, u32 event, void *data)
{
acpi_pm_wakeup_event(&adev->dev);
struct device *dev = data;
acpi_pm_wakeup_event(dev);
switch (event) {
case 0x80:
chromeos_tbmc_query_switch(adev, adev->driver_data);
chromeos_tbmc_query_switch(ACPI_COMPANION(dev), dev_get_drvdata(dev));
break;
default:
dev_err(&adev->dev, "Unexpected event: 0x%08X\n", event);
dev_err(dev, "Unexpected event: 0x%08X\n", event);
}
}
@@ -64,10 +65,11 @@ static int chromeos_tbmc_open(struct input_dev *idev)
return chromeos_tbmc_query_switch(adev, idev);
}
static int chromeos_tbmc_add(struct acpi_device *adev)
static int chromeos_tbmc_probe(struct platform_device *pdev)
{
struct input_dev *idev;
struct device *dev = &adev->dev;
struct device *dev = &pdev->dev;
struct acpi_device *adev = ACPI_COMPANION(dev);
int ret;
idev = devm_input_allocate_device(dev);
@@ -83,7 +85,7 @@ static int chromeos_tbmc_add(struct acpi_device *adev)
idev->open = chromeos_tbmc_open;
input_set_drvdata(idev, adev);
adev->driver_data = idev;
platform_set_drvdata(pdev, idev);
input_set_capability(idev, EV_SW, SW_TABLET_MODE);
ret = input_register_device(idev);
@@ -92,9 +94,25 @@ static int chromeos_tbmc_add(struct acpi_device *adev)
return ret;
}
device_init_wakeup(dev, true);
ret = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
chromeos_tbmc_notify, dev);
if (ret) {
dev_err(dev, "cannot install ACPI notify handler\n");
device_init_wakeup(dev, false);
return ret;
}
return 0;
}
static void chromeos_tbmc_remove(struct platform_device *pdev)
{
acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
ACPI_DEVICE_NOTIFY, chromeos_tbmc_notify);
device_init_wakeup(&pdev->dev, false);
}
static const struct acpi_device_id chromeos_tbmc_acpi_device_ids[] = {
{ ACPI_DRV_NAME, 0 },
{ }
@@ -104,18 +122,17 @@ MODULE_DEVICE_TABLE(acpi, chromeos_tbmc_acpi_device_ids);
static SIMPLE_DEV_PM_OPS(chromeos_tbmc_pm_ops, NULL,
chromeos_tbmc_resume);
static struct acpi_driver chromeos_tbmc_driver = {
.name = DRV_NAME,
.class = DRV_NAME,
.ids = chromeos_tbmc_acpi_device_ids,
.ops = {
.add = chromeos_tbmc_add,
.notify = chromeos_tbmc_notify,
static struct platform_driver chromeos_tbmc_driver = {
.probe = chromeos_tbmc_probe,
.remove = chromeos_tbmc_remove,
.driver = {
.name = DRV_NAME,
.acpi_match_table = chromeos_tbmc_acpi_device_ids,
.pm = &chromeos_tbmc_pm_ops,
},
.drv.pm = &chromeos_tbmc_pm_ops,
};
module_acpi_driver(chromeos_tbmc_driver);
module_platform_driver(chromeos_tbmc_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ChromeOS ACPI tablet switch driver");

View File

@@ -461,6 +461,8 @@ static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
param = (struct ec_params_lightbar *)msg->data;
param->cmd = LIGHTBAR_CMD_SEQ;
param->seq.num = num;
msg->outsize = offsetof(typeof(*param), seq) + sizeof(param->seq);
msg->insize = 0;
ret = lb_throttle();
if (ret)
goto exit;
@@ -516,6 +518,7 @@ static ssize_t program_store(struct device *dev, struct device_attribute *attr,
if (ret)
goto exit;
param = (struct ec_params_lightbar *)msg->data;
msg->insize = 0;
if (lb_version < 3) {
dev_info(dev, "Copying %zu byte program to EC", count);

View File

@@ -5,6 +5,7 @@
* Copyright 2018 Google LLC.
*/
#include <linux/devm-helpers.h>
#include <linux/ktime.h>
#include <linux/math64.h>
#include <linux/mod_devicetable.h>
@@ -199,6 +200,7 @@ static int cros_usbpd_logger_probe(struct platform_device *pd)
struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);
struct device *dev = &pd->dev;
struct logger_data *logger;
int ret;
logger = devm_kzalloc(dev, sizeof(*logger), GFP_KERNEL);
if (!logger)
@@ -210,25 +212,20 @@ static int cros_usbpd_logger_probe(struct platform_device *pd)
platform_set_drvdata(pd, logger);
/* Retrieve PD event logs periodically */
INIT_DELAYED_WORK(&logger->log_work, cros_usbpd_log_check);
logger->log_workqueue = create_singlethread_workqueue("cros_usbpd_log");
logger->log_workqueue = devm_alloc_ordered_workqueue(dev, "cros_usbpd_log", 0);
if (!logger->log_workqueue)
return -ENOMEM;
ret = devm_delayed_work_autocancel(dev, &logger->log_work, cros_usbpd_log_check);
if (ret)
return ret;
queue_delayed_work(logger->log_workqueue, &logger->log_work,
CROS_USBPD_LOG_UPDATE_DELAY);
return 0;
}
static void cros_usbpd_logger_remove(struct platform_device *pd)
{
struct logger_data *logger = platform_get_drvdata(pd);
cancel_delayed_work_sync(&logger->log_work);
destroy_workqueue(logger->log_workqueue);
}
static int __maybe_unused cros_usbpd_logger_resume(struct device *dev)
{
struct logger_data *logger = dev_get_drvdata(dev);
@@ -263,7 +260,6 @@ static struct platform_driver cros_usbpd_logger_driver = {
.pm = &cros_usbpd_logger_pm_ops,
},
.probe = cros_usbpd_logger_probe,
.remove = cros_usbpd_logger_remove,
.id_table = cros_usbpd_logger_id,
};

View File

@@ -38,6 +38,7 @@
#include <linux/io.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
@@ -198,7 +199,7 @@ struct event_device_data {
/**
* enqueue_events() - Place EC events in queue to be read by userspace.
* @adev: Device the events came from.
* @dev: Device the events came from.
* @buf: Buffer of event data.
* @length: Length of event data buffer.
*
@@ -209,9 +210,9 @@ struct event_device_data {
*
* Return: 0 on success or negative error code on failure.
*/
static int enqueue_events(struct acpi_device *adev, const u8 *buf, u32 length)
static int enqueue_events(struct device *dev, const u8 *buf, u32 length)
{
struct event_device_data *dev_data = adev->driver_data;
struct event_device_data *dev_data = dev_get_drvdata(dev);
struct ec_event *event, *queue_event, *old_event;
size_t num_words, event_size;
u32 offset = 0;
@@ -222,14 +223,14 @@ static int enqueue_events(struct acpi_device *adev, const u8 *buf, u32 length)
num_words = ec_event_num_words(event);
event_size = ec_event_size(event);
if (num_words > EC_ACPI_MAX_EVENT_WORDS) {
dev_err(&adev->dev, "Too many event words: %zu > %d\n",
dev_err(dev, "Too many event words: %zu > %d\n",
num_words, EC_ACPI_MAX_EVENT_WORDS);
return -EOVERFLOW;
}
/* Ensure event does not overflow the available buffer */
if ((offset + event_size) > length) {
dev_err(&adev->dev, "Event exceeds buffer: %zu > %d\n",
dev_err(dev, "Event exceeds buffer: %zu > %d\n",
offset + event_size, length);
return -EOVERFLOW;
}
@@ -253,19 +254,22 @@ static int enqueue_events(struct acpi_device *adev, const u8 *buf, u32 length)
/**
* event_device_notify() - Callback when EC generates an event over ACPI.
* @adev: The device that the event is coming from.
* @handle: ACPI handle of the device that the event is coming from.
* @value: Value passed to Notify() in ACPI.
* @data: Notify handler data.
*
* This function will read the events from the device and enqueue them.
*/
static void event_device_notify(struct acpi_device *adev, u32 value)
static void event_device_notify(acpi_handle handle, u32 value, void *data)
{
struct acpi_buffer event_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
struct device *dev = data;
struct acpi_device *adev = ACPI_COMPANION(dev);
union acpi_object *obj;
acpi_status status;
if (value != EC_ACPI_NOTIFY_EVENT) {
dev_err(&adev->dev, "Invalid event: 0x%08x\n", value);
dev_err(dev, "Invalid event: 0x%08x\n", value);
return;
}
@@ -273,31 +277,31 @@ static void event_device_notify(struct acpi_device *adev, u32 value)
status = acpi_evaluate_object(adev->handle, EC_ACPI_GET_EVENT,
NULL, &event_buffer);
if (ACPI_FAILURE(status)) {
dev_err(&adev->dev, "Error executing ACPI method %s()\n",
dev_err(dev, "Error executing ACPI method %s()\n",
EC_ACPI_GET_EVENT);
return;
}
obj = (union acpi_object *)event_buffer.pointer;
if (!obj) {
dev_err(&adev->dev, "Nothing returned from %s()\n",
dev_err(dev, "Nothing returned from %s()\n",
EC_ACPI_GET_EVENT);
return;
}
if (obj->type != ACPI_TYPE_BUFFER) {
dev_err(&adev->dev, "Invalid object returned from %s()\n",
dev_err(dev, "Invalid object returned from %s()\n",
EC_ACPI_GET_EVENT);
kfree(obj);
return;
}
if (obj->buffer.length < sizeof(struct ec_event)) {
dev_err(&adev->dev, "Invalid buffer length %d from %s()\n",
dev_err(dev, "Invalid buffer length %d from %s()\n",
obj->buffer.length, EC_ACPI_GET_EVENT);
kfree(obj);
return;
}
enqueue_events(adev, obj->buffer.pointer, obj->buffer.length);
enqueue_events(dev, obj->buffer.pointer, obj->buffer.length);
kfree(obj);
}
@@ -432,8 +436,8 @@ static void hangup_device(struct event_device_data *dev_data)
}
/**
* event_device_add() - Callback when creating a new device.
* @adev: ACPI device that we will be receiving events from.
* event_device_probe() - Callback when creating a new device.
* @pdev: Platform device that we will be receiving events from.
*
* This finds a free minor number for the device, allocates and initializes
* some device data, and creates a new device and char dev node.
@@ -445,7 +449,7 @@ static void hangup_device(struct event_device_data *dev_data)
*
* Return: 0 on success, negative error code on failure.
*/
static int event_device_add(struct acpi_device *adev)
static int event_device_probe(struct platform_device *pdev)
{
struct event_device_data *dev_data;
int error, minor;
@@ -453,7 +457,7 @@ static int event_device_add(struct acpi_device *adev)
minor = ida_alloc_max(&event_ida, EVENT_MAX_DEV-1, GFP_KERNEL);
if (minor < 0) {
error = minor;
dev_err(&adev->dev, "Failed to find minor number: %d\n", error);
dev_err(&pdev->dev, "Failed to find minor number: %d\n", error);
return error;
}
@@ -464,7 +468,7 @@ static int event_device_add(struct acpi_device *adev)
}
/* Initialize the device data. */
adev->driver_data = dev_data;
platform_set_drvdata(pdev, dev_data);
dev_data->events = event_queue_new(queue_size);
if (!dev_data->events) {
kfree(dev_data);
@@ -489,8 +493,17 @@ static int event_device_add(struct acpi_device *adev)
if (error)
goto free_dev_data;
/* Install an ACPI notify handler. */
error = acpi_dev_install_notify_handler(ACPI_COMPANION(&pdev->dev),
ACPI_DEVICE_NOTIFY,
event_device_notify, &pdev->dev);
if (error)
goto free_cdev;
return 0;
free_cdev:
cdev_device_del(&dev_data->cdev, &dev_data->dev);
free_dev_data:
hangup_device(dev_data);
free_minor:
@@ -498,10 +511,12 @@ free_minor:
return error;
}
static void event_device_remove(struct acpi_device *adev)
static void event_device_remove(struct platform_device *pdev)
{
struct event_device_data *dev_data = adev->driver_data;
struct event_device_data *dev_data = platform_get_drvdata(pdev);
acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
ACPI_DEVICE_NOTIFY, event_device_notify);
cdev_device_del(&dev_data->cdev, &dev_data->dev);
ida_free(&event_ida, MINOR(dev_data->dev.devt));
hangup_device(dev_data);
@@ -513,14 +528,12 @@ static const struct acpi_device_id event_acpi_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, event_acpi_ids);
static struct acpi_driver event_driver = {
.name = DRV_NAME,
.class = DRV_NAME,
.ids = event_acpi_ids,
.ops = {
.add = event_device_add,
.notify = event_device_notify,
.remove = event_device_remove,
static struct platform_driver event_driver = {
.probe = event_device_probe,
.remove = event_device_remove,
.driver = {
.name = DRV_NAME,
.acpi_match_table = event_acpi_ids,
},
};
@@ -543,7 +556,7 @@ static int __init event_module_init(void)
}
event_major = MAJOR(dev_num);
ret = acpi_bus_register_driver(&event_driver);
ret = platform_driver_register(&event_driver);
if (ret < 0) {
pr_err(DRV_NAME ": Failed registering driver: %d\n", ret);
goto unregister_region;
@@ -561,7 +574,7 @@ destroy_class:
static void __exit event_module_exit(void)
{
acpi_bus_unregister_driver(&event_driver);
platform_driver_unregister(&event_driver);
unregister_chrdev_region(MKDEV(event_major, 0), EVENT_MAX_DEV);
class_unregister(&event_class);
ida_destroy(&event_ida);