mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
Merge tag 'chrome-platform-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux
Pull chrome-platform updates from Tzung-Bi Shih:
"Improvements:
- Use named initializers for struct i2c_device_id
Fixes:
- Fix a probe race between cros_ec_sensorhub and cros_ec_sysfs
- Check for the presence of ACPI_COMPANION() for drivers converted
from acpi_driver to platform_driver to avoid issues where
device_match_driver_override() might forcibly match the driver to
the device
- Fix a possible UAF in cros_ec_chardev
- Prevent build for big-endian systems as CHROME_PLATFORMS drivers
are only running and testing under little-endian systems
Cleanups:
- Drop some redundant bits in cros_kbd_led_backlight and Kconfig"
* tag 'chrome-platform-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
platform/chrome: Prevent build for big-endian systems
platform/chrome: Remove superfluous dependencies from CROS_EC
platform/chrome: cros_ec_chardev: Introduce rwsem for protecting ec_dev
platform/chrome: cros_ec_chardev: Add event relayer
platform/chrome: cros_ec_chardev: Move data to chardev_pdata
platform/chrome: cros_ec_chardev: Introduce chardev_data
platform/chrome: Use named initializers for struct i2c_device_id
platform/chrome: wilco_ec: event: Check ACPI_COMPANION()
platform/chrome: chromeos_tbmc: Check ACPI_COMPANION()
platform/chrome: chromeos_privacy_screen: Check ACPI_COMPANION()
platform/chrome: cros_kbd_led_backlight: Drop CONFIG_MFD_CROS_EC_DEV ifdeffery
platform/chrome: cros_kbd_led_backlight: Pass keyboard_led as parameter
platform/chrome: cros_kbd_led_backlight: Drop max_brightness from driver data
platform/chrome: Resolve kb_wake_angle visibility race
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
menuconfig CHROME_PLATFORMS
|
||||
bool "Platform support for Chrome hardware"
|
||||
depends on X86 || ARM || ARM64 || COMPILE_TEST
|
||||
depends on !CPU_BIG_ENDIAN || COMPILE_TEST
|
||||
help
|
||||
Say Y here to get to see options for platform support for
|
||||
various Chromebooks and Chromeboxes. This option alone does
|
||||
@@ -75,7 +76,6 @@ config CHROMEOS_OF_HW_PROBER
|
||||
config CROS_EC
|
||||
tristate "ChromeOS Embedded Controller"
|
||||
select CROS_EC_PROTO
|
||||
depends on X86 || ARM || ARM64 || COMPILE_TEST
|
||||
help
|
||||
If you say Y here you get support for the ChromeOS Embedded
|
||||
Controller (EC) providing keyboard, battery and power services.
|
||||
|
||||
@@ -104,6 +104,9 @@ static const struct drm_privacy_screen_ops chromeos_privacy_screen_ops = {
|
||||
|
||||
static int chromeos_privacy_screen_probe(struct platform_device *pdev)
|
||||
{
|
||||
if (!ACPI_COMPANION(&pdev->dev))
|
||||
return -ENODEV;
|
||||
|
||||
struct drm_privacy_screen *drm_privacy_screen =
|
||||
drm_privacy_screen_register(&pdev->dev,
|
||||
&chromeos_privacy_screen_ops,
|
||||
|
||||
@@ -69,9 +69,13 @@ static int chromeos_tbmc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct input_dev *idev;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
struct acpi_device *adev;
|
||||
int ret;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
idev = devm_input_allocate_device(dev);
|
||||
if (!idev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
@@ -22,6 +23,7 @@
|
||||
#include <linux/platform_data/cros_ec_proto.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
@@ -31,14 +33,44 @@
|
||||
/* Arbitrary bounded size for the event queue */
|
||||
#define CROS_MAX_EVENT_LEN PAGE_SIZE
|
||||
|
||||
struct chardev_priv {
|
||||
/*
|
||||
* Platform device driver data.
|
||||
*/
|
||||
struct chardev_pdata {
|
||||
struct miscdevice misc;
|
||||
struct kref kref;
|
||||
struct rw_semaphore ec_dev_sem;
|
||||
struct cros_ec_device *ec_dev;
|
||||
u16 cmd_offset;
|
||||
struct blocking_notifier_head subscribers;
|
||||
struct notifier_block relay;
|
||||
};
|
||||
|
||||
static void chardev_pdata_release(struct kref *kref)
|
||||
{
|
||||
struct chardev_pdata *pdata = container_of(kref, typeof(*pdata), kref);
|
||||
|
||||
kfree(pdata);
|
||||
}
|
||||
|
||||
static int cros_ec_chardev_relay_event(struct notifier_block *nb,
|
||||
unsigned long queued_during_suspend,
|
||||
void *_notify)
|
||||
{
|
||||
struct chardev_pdata *pdata = container_of(nb, typeof(*pdata), relay);
|
||||
|
||||
blocking_notifier_call_chain(&pdata->subscribers, queued_during_suspend,
|
||||
_notify);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
struct chardev_priv {
|
||||
struct notifier_block notifier;
|
||||
wait_queue_head_t wait_event;
|
||||
unsigned long event_mask;
|
||||
struct list_head events;
|
||||
size_t event_len;
|
||||
u16 cmd_offset;
|
||||
struct chardev_pdata *pdata;
|
||||
};
|
||||
|
||||
struct ec_event {
|
||||
@@ -61,10 +93,10 @@ static int ec_get_version(struct chardev_priv *priv, char *str, int maxlen)
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
msg->command = EC_CMD_GET_VERSION + priv->cmd_offset;
|
||||
msg->command = EC_CMD_GET_VERSION + priv->pdata->cmd_offset;
|
||||
msg->insize = sizeof(*resp);
|
||||
|
||||
ret = cros_ec_cmd_xfer_status(priv->ec_dev, msg);
|
||||
ret = cros_ec_cmd_xfer_status(priv->pdata->ec_dev, msg);
|
||||
if (ret < 0) {
|
||||
snprintf(str, maxlen,
|
||||
"Unknown EC version, returned error: %d\n",
|
||||
@@ -92,10 +124,18 @@ static int cros_ec_chardev_mkbp_event(struct notifier_block *nb,
|
||||
{
|
||||
struct chardev_priv *priv = container_of(nb, struct chardev_priv,
|
||||
notifier);
|
||||
struct cros_ec_device *ec_dev = priv->ec_dev;
|
||||
struct cros_ec_device *ec_dev;
|
||||
struct ec_event *event;
|
||||
unsigned long event_bit = 1 << ec_dev->event_data.event_type;
|
||||
int total_size = sizeof(*event) + ec_dev->event_size;
|
||||
unsigned long event_bit;
|
||||
int total_size;
|
||||
|
||||
guard(rwsem_read)(&priv->pdata->ec_dev_sem);
|
||||
if (!priv->pdata->ec_dev)
|
||||
return NOTIFY_DONE;
|
||||
ec_dev = priv->pdata->ec_dev;
|
||||
|
||||
event_bit = 1 << ec_dev->event_data.event_type;
|
||||
total_size = sizeof(*event) + ec_dev->event_size;
|
||||
|
||||
if (!(event_bit & priv->event_mask) ||
|
||||
(priv->event_len + total_size) > CROS_MAX_EVENT_LEN)
|
||||
@@ -157,8 +197,7 @@ static struct ec_event *cros_ec_chardev_fetch_event(struct chardev_priv *priv,
|
||||
static int cros_ec_chardev_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct miscdevice *mdev = filp->private_data;
|
||||
struct cros_ec_dev *ec = dev_get_drvdata(mdev->parent);
|
||||
struct cros_ec_device *ec_dev = ec->ec_dev;
|
||||
struct chardev_pdata *pdata = container_of(mdev, typeof(*pdata), misc);
|
||||
struct chardev_priv *priv;
|
||||
int ret;
|
||||
|
||||
@@ -166,18 +205,20 @@ static int cros_ec_chardev_open(struct inode *inode, struct file *filp)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->ec_dev = ec_dev;
|
||||
priv->cmd_offset = ec->cmd_offset;
|
||||
priv->pdata = pdata;
|
||||
kref_get(&pdata->kref);
|
||||
filp->private_data = priv;
|
||||
INIT_LIST_HEAD(&priv->events);
|
||||
init_waitqueue_head(&priv->wait_event);
|
||||
nonseekable_open(inode, filp);
|
||||
|
||||
priv->notifier.notifier_call = cros_ec_chardev_mkbp_event;
|
||||
ret = blocking_notifier_chain_register(&ec_dev->event_notifier,
|
||||
ret = blocking_notifier_chain_register(&pdata->subscribers,
|
||||
&priv->notifier);
|
||||
if (ret) {
|
||||
dev_err(ec_dev->dev, "failed to register event notifier\n");
|
||||
dev_err(pdata->ec_dev->dev,
|
||||
"failed to register event notifier\n");
|
||||
kref_put(&priv->pdata->kref, chardev_pdata_release);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
@@ -188,6 +229,10 @@ static __poll_t cros_ec_chardev_poll(struct file *filp, poll_table *wait)
|
||||
{
|
||||
struct chardev_priv *priv = filp->private_data;
|
||||
|
||||
guard(rwsem_read)(&priv->pdata->ec_dev_sem);
|
||||
if (!priv->pdata->ec_dev)
|
||||
return EPOLLHUP;
|
||||
|
||||
poll_wait(filp, &priv->wait_event, wait);
|
||||
|
||||
if (list_empty(&priv->events))
|
||||
@@ -205,6 +250,10 @@ static ssize_t cros_ec_chardev_read(struct file *filp, char __user *buffer,
|
||||
size_t count;
|
||||
int ret;
|
||||
|
||||
guard(rwsem_read)(&priv->pdata->ec_dev_sem);
|
||||
if (!priv->pdata->ec_dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (priv->event_mask) { /* queued MKBP event */
|
||||
struct ec_event *event;
|
||||
|
||||
@@ -251,11 +300,11 @@ static ssize_t cros_ec_chardev_read(struct file *filp, char __user *buffer,
|
||||
static int cros_ec_chardev_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct chardev_priv *priv = filp->private_data;
|
||||
struct cros_ec_device *ec_dev = priv->ec_dev;
|
||||
struct ec_event *event, *e;
|
||||
|
||||
blocking_notifier_chain_unregister(&ec_dev->event_notifier,
|
||||
blocking_notifier_chain_unregister(&priv->pdata->subscribers,
|
||||
&priv->notifier);
|
||||
kref_put(&priv->pdata->kref, chardev_pdata_release);
|
||||
|
||||
list_for_each_entry_safe(event, e, &priv->events, node) {
|
||||
list_del(&event->node);
|
||||
@@ -298,8 +347,8 @@ static long cros_ec_chardev_ioctl_xcmd(struct chardev_priv *priv, void __user *a
|
||||
goto exit;
|
||||
}
|
||||
|
||||
s_cmd->command += priv->cmd_offset;
|
||||
ret = cros_ec_cmd_xfer(priv->ec_dev, s_cmd);
|
||||
s_cmd->command += priv->pdata->cmd_offset;
|
||||
ret = cros_ec_cmd_xfer(priv->pdata->ec_dev, s_cmd);
|
||||
/* Only copy data to userland if data was received. */
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
@@ -313,7 +362,7 @@ static long cros_ec_chardev_ioctl_xcmd(struct chardev_priv *priv, void __user *a
|
||||
|
||||
static long cros_ec_chardev_ioctl_readmem(struct chardev_priv *priv, void __user *arg)
|
||||
{
|
||||
struct cros_ec_device *ec_dev = priv->ec_dev;
|
||||
struct cros_ec_device *ec_dev = priv->pdata->ec_dev;
|
||||
struct cros_ec_readmem s_mem = { };
|
||||
long num;
|
||||
|
||||
@@ -343,6 +392,10 @@ static long cros_ec_chardev_ioctl(struct file *filp, unsigned int cmd,
|
||||
{
|
||||
struct chardev_priv *priv = filp->private_data;
|
||||
|
||||
guard(rwsem_read)(&priv->pdata->ec_dev_sem);
|
||||
if (!priv->pdata->ec_dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC)
|
||||
return -ENOTTY;
|
||||
|
||||
@@ -374,28 +427,61 @@ static int cros_ec_chardev_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent);
|
||||
struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);
|
||||
struct miscdevice *misc;
|
||||
struct chardev_pdata *pdata;
|
||||
int ret;
|
||||
|
||||
/* Create a char device: we want to create it anew */
|
||||
misc = devm_kzalloc(&pdev->dev, sizeof(*misc), GFP_KERNEL);
|
||||
if (!misc)
|
||||
pdata = kzalloc_obj(*pdata);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
misc->minor = MISC_DYNAMIC_MINOR;
|
||||
misc->fops = &chardev_fops;
|
||||
misc->name = ec_platform->ec_name;
|
||||
misc->parent = pdev->dev.parent;
|
||||
platform_set_drvdata(pdev, pdata);
|
||||
kref_init(&pdata->kref);
|
||||
init_rwsem(&pdata->ec_dev_sem);
|
||||
pdata->ec_dev = ec->ec_dev;
|
||||
pdata->cmd_offset = ec->cmd_offset;
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&pdata->subscribers);
|
||||
pdata->relay.notifier_call = cros_ec_chardev_relay_event;
|
||||
ret = blocking_notifier_chain_register(&pdata->ec_dev->event_notifier,
|
||||
&pdata->relay);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register event notifier\n");
|
||||
goto err_put_pdata;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, misc);
|
||||
pdata->misc.minor = MISC_DYNAMIC_MINOR;
|
||||
pdata->misc.fops = &chardev_fops;
|
||||
pdata->misc.name = ec_platform->ec_name;
|
||||
pdata->misc.parent = pdev->dev.parent;
|
||||
|
||||
return misc_register(misc);
|
||||
ret = misc_register(&pdata->misc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register misc device\n");
|
||||
goto err_unregister_notifier;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_unregister_notifier:
|
||||
blocking_notifier_chain_unregister(&pdata->ec_dev->event_notifier,
|
||||
&pdata->relay);
|
||||
err_put_pdata:
|
||||
kref_put(&pdata->kref, chardev_pdata_release);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cros_ec_chardev_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct miscdevice *misc = dev_get_drvdata(&pdev->dev);
|
||||
struct chardev_pdata *pdata = platform_get_drvdata(pdev);
|
||||
struct cros_ec_device *ec_dev = pdata->ec_dev;
|
||||
|
||||
misc_deregister(misc);
|
||||
/* stop new fops from being created */
|
||||
misc_deregister(&pdata->misc);
|
||||
/* stop existing fops from running */
|
||||
scoped_guard(rwsem_write, &pdata->ec_dev_sem)
|
||||
pdata->ec_dev = NULL;
|
||||
|
||||
blocking_notifier_chain_unregister(&ec_dev->event_notifier,
|
||||
&pdata->relay);
|
||||
kref_put(&pdata->kref, chardev_pdata_release);
|
||||
}
|
||||
|
||||
static const struct platform_device_id cros_ec_chardev_id[] = {
|
||||
|
||||
@@ -348,7 +348,7 @@ MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id cros_ec_i2c_id[] = {
|
||||
{ "cros-ec-i2c" },
|
||||
{ .name = "cros-ec-i2c" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cros_ec_i2c_id);
|
||||
|
||||
@@ -122,8 +122,12 @@ static int cros_ec_sensorhub_register(struct device *dev,
|
||||
sensor_type[sensorhub->resp->info.type]++;
|
||||
}
|
||||
|
||||
if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2)
|
||||
if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2) {
|
||||
ec->has_kb_wake_angle = true;
|
||||
if (ec->group && sysfs_update_group(&ec->class_dev.kobj,
|
||||
ec->group))
|
||||
dev_warn(dev, "Unable to update sysfs");
|
||||
}
|
||||
|
||||
if (cros_ec_check_features(ec,
|
||||
EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS)) {
|
||||
|
||||
@@ -405,7 +405,8 @@ static int cros_ec_sysfs_probe(struct platform_device *pd)
|
||||
struct device *dev = &pd->dev;
|
||||
int ret;
|
||||
|
||||
ret = sysfs_create_group(&ec_dev->class_dev.kobj, &cros_ec_attr_group);
|
||||
ec_dev->group = &cros_ec_attr_group;
|
||||
ret = sysfs_create_group(&ec_dev->class_dev.kobj, ec_dev->group);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "failed to create attributes. err=%d\n", ret);
|
||||
|
||||
@@ -416,7 +417,7 @@ static void cros_ec_sysfs_remove(struct platform_device *pd)
|
||||
{
|
||||
struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);
|
||||
|
||||
sysfs_remove_group(&ec_dev->class_dev.kobj, &cros_ec_attr_group);
|
||||
sysfs_remove_group(&ec_dev->class_dev.kobj, ec_dev->group);
|
||||
}
|
||||
|
||||
static const struct platform_device_id cros_ec_sysfs_id[] = {
|
||||
|
||||
@@ -131,7 +131,7 @@ static int hps_resume(struct device *dev)
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(hps_pm_ops, hps_suspend, hps_resume, NULL);
|
||||
|
||||
static const struct i2c_device_id hps_i2c_id[] = {
|
||||
{ "cros-hps" },
|
||||
{ .name = "cros-hps" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, hps_i2c_id);
|
||||
|
||||
@@ -32,12 +32,11 @@ struct keyboard_led {
|
||||
* @brightness_set_blocking: Set LED brightness level. It can block the
|
||||
* caller for the time required for accessing a
|
||||
* LED device register
|
||||
* @max_brightness: Maximum brightness.
|
||||
*
|
||||
* See struct led_classdev in include/linux/leds.h for more details.
|
||||
*/
|
||||
struct keyboard_led_drvdata {
|
||||
int (*init)(struct platform_device *pdev);
|
||||
int (*init)(struct platform_device *pdev, struct keyboard_led *keyboard_led);
|
||||
|
||||
enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
|
||||
|
||||
@@ -45,12 +44,8 @@ struct keyboard_led_drvdata {
|
||||
enum led_brightness brightness);
|
||||
int (*brightness_set_blocking)(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness);
|
||||
|
||||
enum led_brightness max_brightness;
|
||||
};
|
||||
|
||||
#define KEYBOARD_BACKLIGHT_MAX 100
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
/* Keyboard LED ACPI Device must be defined in firmware */
|
||||
@@ -94,7 +89,8 @@ keyboard_led_get_brightness_acpi(struct led_classdev *cdev)
|
||||
return brightness;
|
||||
}
|
||||
|
||||
static int keyboard_led_init_acpi(struct platform_device *pdev)
|
||||
static int keyboard_led_init_acpi(struct platform_device *pdev,
|
||||
struct keyboard_led *keyboard_led)
|
||||
{
|
||||
acpi_handle handle;
|
||||
acpi_status status;
|
||||
@@ -116,17 +112,15 @@ static const struct keyboard_led_drvdata keyboard_led_drvdata_acpi = {
|
||||
.init = keyboard_led_init_acpi,
|
||||
.brightness_set = keyboard_led_set_brightness_acpi,
|
||||
.brightness_get = keyboard_led_get_brightness_acpi,
|
||||
.max_brightness = KEYBOARD_BACKLIGHT_MAX,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
#if IS_ENABLED(CONFIG_MFD_CROS_EC_DEV)
|
||||
static int keyboard_led_init_ec_pwm_mfd(struct platform_device *pdev)
|
||||
static int keyboard_led_init_ec_pwm_mfd(struct platform_device *pdev,
|
||||
struct keyboard_led *keyboard_led)
|
||||
{
|
||||
struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct cros_ec_device *cros_ec = ec_dev->ec_dev;
|
||||
struct keyboard_led *keyboard_led = platform_get_drvdata(pdev);
|
||||
|
||||
keyboard_led->ec = cros_ec;
|
||||
|
||||
@@ -175,15 +169,8 @@ static const struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm_mfd = {
|
||||
.init = keyboard_led_init_ec_pwm_mfd,
|
||||
.brightness_set_blocking = keyboard_led_set_brightness_ec_pwm,
|
||||
.brightness_get = keyboard_led_get_brightness_ec_pwm,
|
||||
.max_brightness = KEYBOARD_BACKLIGHT_MAX,
|
||||
};
|
||||
|
||||
#else /* IS_ENABLED(CONFIG_MFD_CROS_EC_DEV) */
|
||||
|
||||
static const struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm_mfd = {};
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_MFD_CROS_EC_DEV) */
|
||||
|
||||
static int keyboard_led_is_mfd_device(struct platform_device *pdev)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_MFD_CROS_EC_DEV) && mfd_get_cell(pdev);
|
||||
@@ -205,17 +192,16 @@ static int keyboard_led_probe(struct platform_device *pdev)
|
||||
keyboard_led = devm_kzalloc(&pdev->dev, sizeof(*keyboard_led), GFP_KERNEL);
|
||||
if (!keyboard_led)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, keyboard_led);
|
||||
|
||||
if (drvdata->init) {
|
||||
err = drvdata->init(pdev);
|
||||
err = drvdata->init(pdev, keyboard_led);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
keyboard_led->cdev.name = "chromeos::kbd_backlight";
|
||||
keyboard_led->cdev.flags |= LED_CORE_SUSPENDRESUME | LED_REJECT_NAME_CONFLICT;
|
||||
keyboard_led->cdev.max_brightness = drvdata->max_brightness;
|
||||
keyboard_led->cdev.max_brightness = 100;
|
||||
keyboard_led->cdev.brightness_set = drvdata->brightness_set;
|
||||
keyboard_led->cdev.brightness_set_blocking = drvdata->brightness_set_blocking;
|
||||
keyboard_led->cdev.brightness_get = drvdata->brightness_get;
|
||||
|
||||
@@ -452,8 +452,13 @@ static void hangup_device(struct event_device_data *dev_data)
|
||||
static int event_device_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct event_device_data *dev_data;
|
||||
struct acpi_device *adev;
|
||||
int error, minor;
|
||||
|
||||
adev = ACPI_COMPANION(&pdev->dev);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
minor = ida_alloc_max(&event_ida, EVENT_MAX_DEV-1, GFP_KERNEL);
|
||||
if (minor < 0) {
|
||||
error = minor;
|
||||
@@ -494,8 +499,7 @@ static int event_device_probe(struct platform_device *pdev)
|
||||
goto free_dev_data;
|
||||
|
||||
/* Install an ACPI notify handler. */
|
||||
error = acpi_dev_install_notify_handler(ACPI_COMPANION(&pdev->dev),
|
||||
ACPI_DEVICE_NOTIFY,
|
||||
error = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
|
||||
event_device_notify, &pdev->dev);
|
||||
if (error)
|
||||
goto free_cdev;
|
||||
|
||||
@@ -228,6 +228,7 @@ struct cros_ec_platform {
|
||||
/**
|
||||
* struct cros_ec_dev - ChromeOS EC device entry point.
|
||||
* @class_dev: Device structure used in sysfs.
|
||||
* @group: sysfs attributes groups for this EC.
|
||||
* @ec_dev: cros_ec_device structure to talk to the physical device.
|
||||
* @dev: Pointer to the platform device.
|
||||
* @debug_info: cros_ec_debugfs structure for debugging information.
|
||||
@@ -237,6 +238,7 @@ struct cros_ec_platform {
|
||||
*/
|
||||
struct cros_ec_dev {
|
||||
struct device class_dev;
|
||||
const struct attribute_group *group;
|
||||
struct cros_ec_device *ec_dev;
|
||||
struct device *dev;
|
||||
struct cros_ec_debugfs *debug_info;
|
||||
|
||||
Reference in New Issue
Block a user