Merge tag 'chrome-platform-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux
Pull chrome platform updates from Tzung-Bi Shih:
"New:
- Add a new API cros_ec_device_registered() for checking if the
cros_ec_deivce is ready
Improvements:
- Use TRAILING_OVERLAP() to fix -Wflex-array-member-not-at-end
warning
- Defer probe until parent EC device is ready in cros_ec_keyb
Cleanups:
- Remove redundant and simplify code in cros_ec_chardev
- Centralize cros_ec_device allocation and initialization to remove
duplicate code"
* tag 'chrome-platform-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
Input: cros_ec_keyb - Defer probe until parent EC device is registered
platform/chrome: cros_ec: Add a flag to track registration state
platform/chrome: cros_ec: Separate initialization from cros_ec_register()
platform/chrome: Centralize common cros_ec_device initialization
platform/chrome: Centralize cros_ec_device allocation
platform/chrome: wilco_ec: Remove redundant semicolons
platform/chrome: cros_ec: Avoid -Wflex-array-member-not-at-end warning
platform/chrome: cros_ec_chardev: Decouple fops from struct cros_ec_dev
platform/chrome: cros_ec_chardev: Remove redundant struct field
This commit is contained in:
@@ -705,6 +705,12 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
|
||||
ec = dev_get_drvdata(pdev->dev.parent);
|
||||
if (!ec)
|
||||
return -EPROBE_DEFER;
|
||||
/*
|
||||
* Even if the cros_ec_device pointer is available, still need to check
|
||||
* if the device is fully registered before using it.
|
||||
*/
|
||||
if (!cros_ec_device_registered(ec))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL);
|
||||
if (!ckdev)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* battery charging and regulator control, firmware update.
|
||||
*/
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
@@ -30,6 +31,56 @@ static struct cros_ec_platform pd_p = {
|
||||
.cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX),
|
||||
};
|
||||
|
||||
static void cros_ec_device_free(void *data)
|
||||
{
|
||||
struct cros_ec_device *ec_dev = data;
|
||||
|
||||
mutex_destroy(&ec_dev->lock);
|
||||
lockdep_unregister_key(&ec_dev->lockdep_key);
|
||||
}
|
||||
|
||||
struct cros_ec_device *cros_ec_device_alloc(struct device *dev)
|
||||
{
|
||||
struct cros_ec_device *ec_dev;
|
||||
|
||||
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
|
||||
if (!ec_dev)
|
||||
return NULL;
|
||||
|
||||
ec_dev->din_size = sizeof(struct ec_host_response) +
|
||||
sizeof(struct ec_response_get_protocol_info) +
|
||||
EC_MAX_RESPONSE_OVERHEAD;
|
||||
ec_dev->dout_size = sizeof(struct ec_host_request) +
|
||||
sizeof(struct ec_params_rwsig_action) +
|
||||
EC_MAX_REQUEST_OVERHEAD;
|
||||
|
||||
ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
|
||||
if (!ec_dev->din)
|
||||
return NULL;
|
||||
|
||||
ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
|
||||
if (!ec_dev->dout)
|
||||
return NULL;
|
||||
|
||||
ec_dev->dev = dev;
|
||||
ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->max_request = sizeof(struct ec_params_rwsig_action);
|
||||
ec_dev->suspend_timeout_ms = EC_HOST_SLEEP_TIMEOUT_DEFAULT;
|
||||
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->panic_notifier);
|
||||
|
||||
lockdep_register_key(&ec_dev->lockdep_key);
|
||||
mutex_init(&ec_dev->lock);
|
||||
lockdep_set_class(&ec_dev->lock, &ec_dev->lockdep_key);
|
||||
|
||||
if (devm_add_action_or_reset(dev, cros_ec_device_free, ec_dev))
|
||||
return NULL;
|
||||
|
||||
return ec_dev;
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_device_alloc);
|
||||
|
||||
/**
|
||||
* cros_ec_irq_handler() - top half part of the interrupt handler
|
||||
* @irq: IRQ id
|
||||
@@ -102,14 +153,13 @@ EXPORT_SYMBOL(cros_ec_irq_thread);
|
||||
static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event)
|
||||
{
|
||||
int ret;
|
||||
struct {
|
||||
struct cros_ec_command msg;
|
||||
TRAILING_OVERLAP(struct cros_ec_command, msg, data,
|
||||
union {
|
||||
struct ec_params_host_sleep_event req0;
|
||||
struct ec_params_host_sleep_event_v1 req1;
|
||||
struct ec_response_host_sleep_event_v1 resp1;
|
||||
} u;
|
||||
} __packed buf;
|
||||
) __packed buf;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
@@ -180,29 +230,7 @@ static int cros_ec_ready_event(struct notifier_block *nb,
|
||||
int cros_ec_register(struct cros_ec_device *ec_dev)
|
||||
{
|
||||
struct device *dev = ec_dev->dev;
|
||||
int err = 0;
|
||||
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->panic_notifier);
|
||||
|
||||
ec_dev->max_request = sizeof(struct ec_params_hello);
|
||||
ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->max_passthru = 0;
|
||||
ec_dev->ec = NULL;
|
||||
ec_dev->pd = NULL;
|
||||
ec_dev->suspend_timeout_ms = EC_HOST_SLEEP_TIMEOUT_DEFAULT;
|
||||
|
||||
ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
|
||||
if (!ec_dev->din)
|
||||
return -ENOMEM;
|
||||
|
||||
ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
|
||||
if (!ec_dev->dout)
|
||||
return -ENOMEM;
|
||||
|
||||
lockdep_register_key(&ec_dev->lockdep_key);
|
||||
mutex_init(&ec_dev->lock);
|
||||
lockdep_set_class(&ec_dev->lock, &ec_dev->lockdep_key);
|
||||
int err;
|
||||
|
||||
/* Send RWSIG continue to jump to RW for devices using RWSIG. */
|
||||
err = cros_ec_rwsig_continue(ec_dev);
|
||||
@@ -289,6 +317,9 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
scoped_guard(mutex, &ec_dev->lock)
|
||||
ec_dev->registered = true;
|
||||
|
||||
dev_info(dev, "Chrome EC device registered\n");
|
||||
|
||||
/*
|
||||
@@ -302,8 +333,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
||||
exit:
|
||||
platform_device_unregister(ec_dev->ec);
|
||||
platform_device_unregister(ec_dev->pd);
|
||||
mutex_destroy(&ec_dev->lock);
|
||||
lockdep_unregister_key(&ec_dev->lockdep_key);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_register);
|
||||
@@ -318,13 +347,14 @@ EXPORT_SYMBOL(cros_ec_register);
|
||||
*/
|
||||
void cros_ec_unregister(struct cros_ec_device *ec_dev)
|
||||
{
|
||||
scoped_guard(mutex, &ec_dev->lock)
|
||||
ec_dev->registered = false;
|
||||
|
||||
if (ec_dev->mkbp_event_supported)
|
||||
blocking_notifier_chain_unregister(&ec_dev->event_notifier,
|
||||
&ec_dev->notifier_ready);
|
||||
platform_device_unregister(ec_dev->pd);
|
||||
platform_device_unregister(ec_dev->ec);
|
||||
mutex_destroy(&ec_dev->lock);
|
||||
lockdep_unregister_key(&ec_dev->lockdep_key);
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_unregister);
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
struct cros_ec_device;
|
||||
struct device;
|
||||
|
||||
struct cros_ec_device *cros_ec_device_alloc(struct device *dev);
|
||||
|
||||
int cros_ec_register(struct cros_ec_device *ec_dev);
|
||||
void cros_ec_unregister(struct cros_ec_device *ec_dev);
|
||||
|
||||
@@ -31,18 +31,14 @@
|
||||
/* Arbitrary bounded size for the event queue */
|
||||
#define CROS_MAX_EVENT_LEN PAGE_SIZE
|
||||
|
||||
struct chardev_data {
|
||||
struct cros_ec_dev *ec_dev;
|
||||
struct miscdevice misc;
|
||||
};
|
||||
|
||||
struct chardev_priv {
|
||||
struct cros_ec_dev *ec_dev;
|
||||
struct cros_ec_device *ec_dev;
|
||||
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 ec_event {
|
||||
@@ -52,7 +48,7 @@ struct ec_event {
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen)
|
||||
static int ec_get_version(struct chardev_priv *priv, char *str, int maxlen)
|
||||
{
|
||||
static const char * const current_image_name[] = {
|
||||
"unknown", "read-only", "read-write", "invalid",
|
||||
@@ -65,10 +61,10 @@ static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen)
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
|
||||
msg->command = EC_CMD_GET_VERSION + priv->cmd_offset;
|
||||
msg->insize = sizeof(*resp);
|
||||
|
||||
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
|
||||
ret = cros_ec_cmd_xfer_status(priv->ec_dev, msg);
|
||||
if (ret < 0) {
|
||||
snprintf(str, maxlen,
|
||||
"Unknown EC version, returned error: %d\n",
|
||||
@@ -96,7 +92,7 @@ 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->ec_dev;
|
||||
struct cros_ec_device *ec_dev = priv->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;
|
||||
@@ -161,7 +157,8 @@ out:
|
||||
static int cros_ec_chardev_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct miscdevice *mdev = filp->private_data;
|
||||
struct cros_ec_dev *ec_dev = dev_get_drvdata(mdev->parent);
|
||||
struct cros_ec_dev *ec = dev_get_drvdata(mdev->parent);
|
||||
struct cros_ec_device *ec_dev = ec->ec_dev;
|
||||
struct chardev_priv *priv;
|
||||
int ret;
|
||||
|
||||
@@ -170,13 +167,14 @@ static int cros_ec_chardev_open(struct inode *inode, struct file *filp)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->ec_dev = ec_dev;
|
||||
priv->cmd_offset = ec->cmd_offset;
|
||||
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->ec_dev->event_notifier,
|
||||
ret = blocking_notifier_chain_register(&ec_dev->event_notifier,
|
||||
&priv->notifier);
|
||||
if (ret) {
|
||||
dev_err(ec_dev->dev, "failed to register event notifier\n");
|
||||
@@ -204,7 +202,6 @@ static ssize_t cros_ec_chardev_read(struct file *filp, char __user *buffer,
|
||||
char msg[sizeof(struct ec_response_get_version) +
|
||||
sizeof(CROS_EC_DEV_VERSION)];
|
||||
struct chardev_priv *priv = filp->private_data;
|
||||
struct cros_ec_dev *ec_dev = priv->ec_dev;
|
||||
size_t count;
|
||||
int ret;
|
||||
|
||||
@@ -238,7 +235,7 @@ static ssize_t cros_ec_chardev_read(struct file *filp, char __user *buffer,
|
||||
if (*offset != 0)
|
||||
return 0;
|
||||
|
||||
ret = ec_get_version(ec_dev, msg, sizeof(msg));
|
||||
ret = ec_get_version(priv, msg, sizeof(msg));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -254,10 +251,10 @@ 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_dev *ec_dev = priv->ec_dev;
|
||||
struct cros_ec_device *ec_dev = priv->ec_dev;
|
||||
struct ec_event *event, *e;
|
||||
|
||||
blocking_notifier_chain_unregister(&ec_dev->ec_dev->event_notifier,
|
||||
blocking_notifier_chain_unregister(&ec_dev->event_notifier,
|
||||
&priv->notifier);
|
||||
|
||||
list_for_each_entry_safe(event, e, &priv->events, node) {
|
||||
@@ -272,7 +269,7 @@ static int cros_ec_chardev_release(struct inode *inode, struct file *filp)
|
||||
/*
|
||||
* Ioctls
|
||||
*/
|
||||
static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg)
|
||||
static long cros_ec_chardev_ioctl_xcmd(struct chardev_priv *priv, void __user *arg)
|
||||
{
|
||||
struct cros_ec_command *s_cmd;
|
||||
struct cros_ec_command u_cmd;
|
||||
@@ -301,8 +298,8 @@ static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
s_cmd->command += ec->cmd_offset;
|
||||
ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd);
|
||||
s_cmd->command += priv->cmd_offset;
|
||||
ret = cros_ec_cmd_xfer(priv->ec_dev, s_cmd);
|
||||
/* Only copy data to userland if data was received. */
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
@@ -314,10 +311,9 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec,
|
||||
void __user *arg)
|
||||
static long cros_ec_chardev_ioctl_readmem(struct chardev_priv *priv, void __user *arg)
|
||||
{
|
||||
struct cros_ec_device *ec_dev = ec->ec_dev;
|
||||
struct cros_ec_device *ec_dev = priv->ec_dev;
|
||||
struct cros_ec_readmem s_mem = { };
|
||||
long num;
|
||||
|
||||
@@ -346,16 +342,15 @@ static long cros_ec_chardev_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct chardev_priv *priv = filp->private_data;
|
||||
struct cros_ec_dev *ec = priv->ec_dev;
|
||||
|
||||
if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC)
|
||||
return -ENOTTY;
|
||||
|
||||
switch (cmd) {
|
||||
case CROS_EC_DEV_IOCXCMD:
|
||||
return cros_ec_chardev_ioctl_xcmd(ec, (void __user *)arg);
|
||||
return cros_ec_chardev_ioctl_xcmd(priv, (void __user *)arg);
|
||||
case CROS_EC_DEV_IOCRDMEM:
|
||||
return cros_ec_chardev_ioctl_readmem(ec, (void __user *)arg);
|
||||
return cros_ec_chardev_ioctl_readmem(priv, (void __user *)arg);
|
||||
case CROS_EC_DEV_IOCEVENTMASK:
|
||||
priv->event_mask = arg;
|
||||
return 0;
|
||||
@@ -377,31 +372,30 @@ static const struct file_operations chardev_fops = {
|
||||
|
||||
static int cros_ec_chardev_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct cros_ec_platform *ec_platform = dev_get_platdata(ec_dev->dev);
|
||||
struct chardev_data *data;
|
||||
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;
|
||||
|
||||
/* Create a char device: we want to create it anew */
|
||||
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
misc = devm_kzalloc(&pdev->dev, sizeof(*misc), GFP_KERNEL);
|
||||
if (!misc)
|
||||
return -ENOMEM;
|
||||
|
||||
data->ec_dev = ec_dev;
|
||||
data->misc.minor = MISC_DYNAMIC_MINOR;
|
||||
data->misc.fops = &chardev_fops;
|
||||
data->misc.name = ec_platform->ec_name;
|
||||
data->misc.parent = pdev->dev.parent;
|
||||
misc->minor = MISC_DYNAMIC_MINOR;
|
||||
misc->fops = &chardev_fops;
|
||||
misc->name = ec_platform->ec_name;
|
||||
misc->parent = pdev->dev.parent;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, data);
|
||||
dev_set_drvdata(&pdev->dev, misc);
|
||||
|
||||
return misc_register(&data->misc);
|
||||
return misc_register(misc);
|
||||
}
|
||||
|
||||
static void cros_ec_chardev_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct chardev_data *data = dev_get_drvdata(&pdev->dev);
|
||||
struct miscdevice *misc = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
misc_deregister(&data->misc);
|
||||
misc_deregister(misc);
|
||||
}
|
||||
|
||||
static const struct platform_device_id cros_ec_chardev_id[] = {
|
||||
|
||||
@@ -289,24 +289,19 @@ done:
|
||||
static int cros_ec_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct cros_ec_device *ec_dev = NULL;
|
||||
struct cros_ec_device *ec_dev;
|
||||
int err;
|
||||
|
||||
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
|
||||
ec_dev = cros_ec_device_alloc(dev);
|
||||
if (!ec_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, ec_dev);
|
||||
ec_dev->dev = dev;
|
||||
ec_dev->priv = client;
|
||||
ec_dev->irq = client->irq;
|
||||
ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c;
|
||||
ec_dev->pkt_xfer = cros_ec_pkt_xfer_i2c;
|
||||
ec_dev->phys_name = client->adapter->name;
|
||||
ec_dev->din_size = sizeof(struct ec_host_response_i2c) +
|
||||
sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->dout_size = sizeof(struct ec_host_request_i2c) +
|
||||
sizeof(struct ec_params_rwsig_action);
|
||||
|
||||
err = cros_ec_register(ec_dev);
|
||||
if (err) {
|
||||
|
||||
@@ -543,21 +543,17 @@ static int cros_ec_dev_init(struct ishtp_cl_data *client_data)
|
||||
struct cros_ec_device *ec_dev;
|
||||
struct device *dev = cl_data_to_dev(client_data);
|
||||
|
||||
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
|
||||
ec_dev = cros_ec_device_alloc(dev);
|
||||
if (!ec_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
client_data->ec_dev = ec_dev;
|
||||
dev->driver_data = ec_dev;
|
||||
|
||||
ec_dev->dev = dev;
|
||||
ec_dev->priv = client_data->cros_ish_cl;
|
||||
ec_dev->cmd_xfer = NULL;
|
||||
ec_dev->pkt_xfer = cros_ec_pkt_xfer_ish;
|
||||
ec_dev->phys_name = dev_name(dev);
|
||||
ec_dev->din_size = sizeof(struct cros_ish_in_msg) +
|
||||
sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->dout_size = sizeof(struct cros_ish_out_msg) + sizeof(struct ec_params_rwsig_action);
|
||||
|
||||
return cros_ec_register(ec_dev);
|
||||
}
|
||||
|
||||
@@ -637,19 +637,15 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
|
||||
ec_dev = cros_ec_device_alloc(dev);
|
||||
if (!ec_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, ec_dev);
|
||||
ec_dev->dev = dev;
|
||||
ec_dev->phys_name = dev_name(dev);
|
||||
ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc;
|
||||
ec_dev->pkt_xfer = cros_ec_pkt_xfer_lpc;
|
||||
ec_dev->cmd_readmem = cros_ec_lpc_readmem;
|
||||
ec_dev->din_size = sizeof(struct ec_host_response) +
|
||||
sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action);
|
||||
ec_dev->priv = ec_lpc;
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//
|
||||
// Copyright (C) 2015 Google, Inc
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/limits.h>
|
||||
@@ -1153,5 +1154,19 @@ int cros_ec_get_cmd_versions(struct cros_ec_device *ec_dev, u16 cmd)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cros_ec_get_cmd_versions);
|
||||
|
||||
/**
|
||||
* cros_ec_device_registered - Return if the ec_dev is registered.
|
||||
*
|
||||
* @ec_dev: EC device
|
||||
*
|
||||
* Return: true if registered. Otherwise, false.
|
||||
*/
|
||||
bool cros_ec_device_registered(struct cros_ec_device *ec_dev)
|
||||
{
|
||||
guard(mutex)(&ec_dev->lock);
|
||||
return ec_dev->registered;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cros_ec_device_registered);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("ChromeOS EC communication protocol helpers");
|
||||
|
||||
@@ -216,7 +216,7 @@ static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
struct cros_ec_device *ec_dev;
|
||||
int ret;
|
||||
|
||||
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
|
||||
ec_dev = cros_ec_device_alloc(dev);
|
||||
if (!ec_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -224,14 +224,10 @@ static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
if (!ec_rpmsg)
|
||||
return -ENOMEM;
|
||||
|
||||
ec_dev->dev = dev;
|
||||
ec_dev->priv = ec_rpmsg;
|
||||
ec_dev->cmd_xfer = cros_ec_cmd_xfer_rpmsg;
|
||||
ec_dev->pkt_xfer = cros_ec_pkt_xfer_rpmsg;
|
||||
ec_dev->phys_name = dev_name(&rpdev->dev);
|
||||
ec_dev->din_size = sizeof(struct ec_host_response) +
|
||||
sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action);
|
||||
dev_set_drvdata(dev, ec_dev);
|
||||
|
||||
ec_rpmsg->rpdev = rpdev;
|
||||
|
||||
@@ -749,7 +749,7 @@ static int cros_ec_spi_probe(struct spi_device *spi)
|
||||
if (ec_spi == NULL)
|
||||
return -ENOMEM;
|
||||
ec_spi->spi = spi;
|
||||
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
|
||||
ec_dev = cros_ec_device_alloc(dev);
|
||||
if (!ec_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -757,16 +757,11 @@ static int cros_ec_spi_probe(struct spi_device *spi)
|
||||
cros_ec_spi_dt_probe(ec_spi, dev);
|
||||
|
||||
spi_set_drvdata(spi, ec_dev);
|
||||
ec_dev->dev = dev;
|
||||
ec_dev->priv = ec_spi;
|
||||
ec_dev->irq = spi->irq;
|
||||
ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi;
|
||||
ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi;
|
||||
ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
|
||||
ec_dev->din_size = EC_MSG_PREAMBLE_COUNT +
|
||||
sizeof(struct ec_host_response) +
|
||||
sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action);
|
||||
|
||||
ec_spi->last_transfer_ns = ktime_get_ns();
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ static int cros_ec_uart_probe(struct serdev_device *serdev)
|
||||
if (!ec_uart)
|
||||
return -ENOMEM;
|
||||
|
||||
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
|
||||
ec_dev = cros_ec_device_alloc(dev);
|
||||
if (!ec_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -276,14 +276,10 @@ static int cros_ec_uart_probe(struct serdev_device *serdev)
|
||||
|
||||
/* Initialize ec_dev for cros_ec */
|
||||
ec_dev->phys_name = dev_name(dev);
|
||||
ec_dev->dev = dev;
|
||||
ec_dev->priv = ec_uart;
|
||||
ec_dev->irq = ec_uart->irq;
|
||||
ec_dev->cmd_xfer = NULL;
|
||||
ec_dev->pkt_xfer = cros_ec_uart_pkt_xfer;
|
||||
ec_dev->din_size = sizeof(struct ec_host_response) +
|
||||
sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->dout_size = sizeof(struct ec_host_request) + sizeof(struct ec_params_rwsig_action);
|
||||
|
||||
serdev_device_set_client_ops(serdev, &cros_ec_uart_client_ops);
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ static int telem_device_probe(struct platform_device *pdev)
|
||||
dev_set_name(&dev_data->dev, TELEM_DEV_NAME_FMT, minor);
|
||||
device_initialize(&dev_data->dev);
|
||||
|
||||
/* Initialize the character device and add it to userspace */;
|
||||
/* Initialize the character device and add it to userspace */
|
||||
cdev_init(&dev_data->cdev, &telem_fops);
|
||||
error = cdev_device_add(&dev_data->cdev, &dev_data->dev);
|
||||
if (error) {
|
||||
|
||||
@@ -33,12 +33,18 @@
|
||||
|
||||
/*
|
||||
* Max bus-specific overhead incurred by request/responses.
|
||||
* I2C requires 1 additional byte for requests.
|
||||
* I2C requires 2 additional bytes for responses.
|
||||
* SPI requires up to 32 additional bytes for responses.
|
||||
*
|
||||
* Request:
|
||||
* - I2C requires 1 byte (see struct ec_host_request_i2c).
|
||||
* - ISHTP requires 4 bytes (see struct cros_ish_out_msg).
|
||||
*
|
||||
* Response:
|
||||
* - I2C requires 2 bytes (see struct ec_host_response_i2c).
|
||||
* - ISHTP requires 4 bytes (see struct cros_ish_in_msg).
|
||||
* - SPI requires 32 bytes (see EC_MSG_PREAMBLE_COUNT).
|
||||
*/
|
||||
#define EC_PROTO_VERSION_UNKNOWN 0
|
||||
#define EC_MAX_REQUEST_OVERHEAD 1
|
||||
#define EC_MAX_REQUEST_OVERHEAD 4
|
||||
#define EC_MAX_RESPONSE_OVERHEAD 32
|
||||
|
||||
/*
|
||||
@@ -122,6 +128,7 @@ struct cros_ec_command {
|
||||
* @dout_size: Size of dout buffer to allocate (zero to use static dout).
|
||||
* @wake_enabled: True if this device can wake the system from sleep.
|
||||
* @suspended: True if this device had been suspended.
|
||||
* @registered: True if this device had been registered.
|
||||
* @cmd_xfer: Send command to EC and get response.
|
||||
* Returns the number of bytes received if the communication
|
||||
* succeeded, but that doesn't mean the EC was happy with the
|
||||
@@ -180,6 +187,7 @@ struct cros_ec_device {
|
||||
int dout_size;
|
||||
bool wake_enabled;
|
||||
bool suspended;
|
||||
bool registered;
|
||||
int (*cmd_xfer)(struct cros_ec_device *ec,
|
||||
struct cros_ec_command *msg);
|
||||
int (*pkt_xfer)(struct cros_ec_device *ec,
|
||||
@@ -272,6 +280,8 @@ int cros_ec_cmd_readmem(struct cros_ec_device *ec_dev, u8 offset, u8 size, void
|
||||
|
||||
int cros_ec_get_cmd_versions(struct cros_ec_device *ec_dev, u16 cmd);
|
||||
|
||||
bool cros_ec_device_registered(struct cros_ec_device *ec_dev);
|
||||
|
||||
/**
|
||||
* cros_ec_get_time_ns() - Return time in ns.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user