Messages in this thread | | | From | Guenter Roeck <> | Date | Thu, 30 Nov 2017 12:50:12 -0800 | Subject | Re: [PATCH v2 2/2] cros_ec: Move cros_ec_dev module to drivers/mfd |
| |
On Mon, Nov 20, 2017 at 8:15 AM, Thierry Escande <thierry.escande@collabora.com> wrote: > The cros_ec_dev module is responsible for registering the MFD devices > attached to the ChromeOS EC. This patch moves this module to drivers/mfd > so calls to mfd_add_devices() are not done from outside the MFD subtree > anymore. > > Signed-off-by: Thierry Escande <thierry.escande@collabora.com>
Tested-by: Guenter Roeck <groeck@chromium.org>
> --- > drivers/mfd/Kconfig | 10 + > drivers/mfd/Makefile | 1 + > drivers/mfd/cros_ec_dev.c | 552 ++++++++++++++++++++++++++++ > drivers/mfd/cros_ec_dev.h | 52 +++ > drivers/platform/chrome/Kconfig | 10 - > drivers/platform/chrome/Makefile | 1 - > drivers/platform/chrome/cros_ec_debugfs.c | 3 - > drivers/platform/chrome/cros_ec_debugfs.h | 27 -- > drivers/platform/chrome/cros_ec_dev.c | 553 ----------------------------- > drivers/platform/chrome/cros_ec_dev.h | 52 --- > drivers/platform/chrome/cros_ec_lightbar.c | 2 - > drivers/platform/chrome/cros_ec_sysfs.c | 2 - > include/linux/mfd/cros_ec.h | 4 + > 13 files changed, 619 insertions(+), 650 deletions(-) > create mode 100644 drivers/mfd/cros_ec_dev.c > create mode 100644 drivers/mfd/cros_ec_dev.h > delete mode 100644 drivers/platform/chrome/cros_ec_debugfs.h > delete mode 100644 drivers/platform/chrome/cros_ec_dev.c > delete mode 100644 drivers/platform/chrome/cros_ec_dev.h > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index 1d20a80..538a2ae 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -222,6 +222,16 @@ config MFD_CROS_EC_SPI > response time cannot be guaranteed, we support ignoring > 'pre-amble' bytes before the response actually starts. > > +config MFD_CROS_EC_CHARDEV > + tristate "Chrome OS Embedded Controller userspace device interface" > + depends on MFD_CROS_EC > + select CROS_EC_CTL > + ---help--- > + This driver adds support to talk with the ChromeOS EC from userspace. > + > + If you have a supported Chromebook, choose Y or M here. > + The module will be called cros_ec_dev. > + > config MFD_ASIC3 > bool "Compaq ASIC3" > depends on GPIOLIB && ARM > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index d9474ad..fcd8af8 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -17,6 +17,7 @@ cros_ec_core-$(CONFIG_ACPI) += cros_ec_acpi_gpe.o > obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o > obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o > obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o > +obj-$(CONFIG_MFD_CROS_EC_CHARDEV) += cros_ec_dev.o > obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o > > rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o > diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c > new file mode 100644 > index 0000000..e4fafdd > --- /dev/null > +++ b/drivers/mfd/cros_ec_dev.c > @@ -0,0 +1,552 @@ > +/* > + * cros_ec_dev - expose the Chrome OS Embedded Controller to user-space > + * > + * Copyright (C) 2014 Google, Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <linux/fs.h> > +#include <linux/mfd/core.h> > +#include <linux/module.h> > +#include <linux/platform_device.h> > +#include <linux/pm.h> > +#include <linux/slab.h> > +#include <linux/uaccess.h> > + > +#include "cros_ec_dev.h" > + > +#define DRV_NAME "cros-ec-dev" > + > +/* Device variables */ > +#define CROS_MAX_DEV 128 > +static int ec_major; > + > +static const struct attribute_group *cros_ec_groups[] = { > + &cros_ec_attr_group, > + &cros_ec_lightbar_attr_group, > + &cros_ec_vbc_attr_group, > + NULL, > +}; > + > +static struct class cros_class = { > + .owner = THIS_MODULE, > + .name = "chromeos", > + .dev_groups = cros_ec_groups, > +}; > + > +/* Basic communication */ > +static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen) > +{ > + struct ec_response_get_version *resp; > + static const char * const current_image_name[] = { > + "unknown", "read-only", "read-write", "invalid", > + }; > + struct cros_ec_command *msg; > + int ret; > + > + msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > + msg->version = 0; > + msg->command = EC_CMD_GET_VERSION + ec->cmd_offset; > + msg->insize = sizeof(*resp); > + msg->outsize = 0; > + > + ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > + if (ret < 0) > + goto exit; > + > + if (msg->result != EC_RES_SUCCESS) { > + snprintf(str, maxlen, > + "%s\nUnknown EC version: EC returned %d\n", > + CROS_EC_DEV_VERSION, msg->result); > + ret = -EINVAL; > + goto exit; > + } > + > + resp = (struct ec_response_get_version *)msg->data; > + if (resp->current_image >= ARRAY_SIZE(current_image_name)) > + resp->current_image = 3; /* invalid */ > + > + snprintf(str, maxlen, "%s\n%s\n%s\n%s\n", CROS_EC_DEV_VERSION, > + resp->version_string_ro, resp->version_string_rw, > + current_image_name[resp->current_image]); > + > + ret = 0; > +exit: > + kfree(msg); > + return ret; > +} > + > +static int cros_ec_check_features(struct cros_ec_dev *ec, int feature) > +{ > + struct cros_ec_command *msg; > + int ret; > + > + if (ec->features[0] == -1U && ec->features[1] == -1U) { > + /* features bitmap not read yet */ > + > + msg = kmalloc(sizeof(*msg) + sizeof(ec->features), GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > + msg->version = 0; > + msg->command = EC_CMD_GET_FEATURES + ec->cmd_offset; > + msg->insize = sizeof(ec->features); > + msg->outsize = 0; > + > + ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > + if (ret < 0 || msg->result != EC_RES_SUCCESS) { > + dev_warn(ec->dev, "cannot get EC features: %d/%d\n", > + ret, msg->result); > + memset(ec->features, 0, sizeof(ec->features)); > + } > + > + memcpy(ec->features, msg->data, sizeof(ec->features)); > + > + dev_dbg(ec->dev, "EC features %08x %08x\n", > + ec->features[0], ec->features[1]); > + > + kfree(msg); > + } > + > + return ec->features[feature / 32] & EC_FEATURE_MASK_0(feature); > +} > + > +/* Device file ops */ > +static int ec_device_open(struct inode *inode, struct file *filp) > +{ > + struct cros_ec_dev *ec = container_of(inode->i_cdev, > + struct cros_ec_dev, cdev); > + filp->private_data = ec; > + nonseekable_open(inode, filp); > + return 0; > +} > + > +static int ec_device_release(struct inode *inode, struct file *filp) > +{ > + return 0; > +} > + > +static ssize_t ec_device_read(struct file *filp, char __user *buffer, > + size_t length, loff_t *offset) > +{ > + struct cros_ec_dev *ec = filp->private_data; > + char msg[sizeof(struct ec_response_get_version) + > + sizeof(CROS_EC_DEV_VERSION)]; > + size_t count; > + int ret; > + > + if (*offset != 0) > + return 0; > + > + ret = ec_get_version(ec, msg, sizeof(msg)); > + if (ret) > + return ret; > + > + count = min(length, strlen(msg)); > + > + if (copy_to_user(buffer, msg, count)) > + return -EFAULT; > + > + *offset = count; > + return count; > +} > + > +/* Ioctls */ > +static long ec_device_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg) > +{ > + long ret; > + struct cros_ec_command u_cmd; > + struct cros_ec_command *s_cmd; > + > + if (copy_from_user(&u_cmd, arg, sizeof(u_cmd))) > + return -EFAULT; > + > + if ((u_cmd.outsize > EC_MAX_MSG_BYTES) || > + (u_cmd.insize > EC_MAX_MSG_BYTES)) > + return -EINVAL; > + > + s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), > + GFP_KERNEL); > + if (!s_cmd) > + return -ENOMEM; > + > + if (copy_from_user(s_cmd, arg, sizeof(*s_cmd) + u_cmd.outsize)) { > + ret = -EFAULT; > + goto exit; > + } > + > + if (u_cmd.outsize != s_cmd->outsize || > + u_cmd.insize != s_cmd->insize) { > + ret = -EINVAL; > + goto exit; > + } > + > + s_cmd->command += ec->cmd_offset; > + ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd); > + /* Only copy data to userland if data was received. */ > + if (ret < 0) > + goto exit; > + > + if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize)) > + ret = -EFAULT; > +exit: > + kfree(s_cmd); > + return ret; > +} > + > +static long ec_device_ioctl_readmem(struct cros_ec_dev *ec, void __user *arg) > +{ > + struct cros_ec_device *ec_dev = ec->ec_dev; > + struct cros_ec_readmem s_mem = { }; > + long num; > + > + /* Not every platform supports direct reads */ > + if (!ec_dev->cmd_readmem) > + return -ENOTTY; > + > + if (copy_from_user(&s_mem, arg, sizeof(s_mem))) > + return -EFAULT; > + > + num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes, > + s_mem.buffer); > + if (num <= 0) > + return num; > + > + if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem))) > + return -EFAULT; > + > + return 0; > +} > + > +static long ec_device_ioctl(struct file *filp, unsigned int cmd, > + unsigned long arg) > +{ > + struct cros_ec_dev *ec = filp->private_data; > + > + if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC) > + return -ENOTTY; > + > + switch (cmd) { > + case CROS_EC_DEV_IOCXCMD: > + return ec_device_ioctl_xcmd(ec, (void __user *)arg); > + case CROS_EC_DEV_IOCRDMEM: > + return ec_device_ioctl_readmem(ec, (void __user *)arg); > + } > + > + return -ENOTTY; > +} > + > +/* Module initialization */ > +static const struct file_operations fops = { > + .open = ec_device_open, > + .release = ec_device_release, > + .read = ec_device_read, > + .unlocked_ioctl = ec_device_ioctl, > +#ifdef CONFIG_COMPAT > + .compat_ioctl = ec_device_ioctl, > +#endif > +}; > + > +static void __remove(struct device *dev) > +{ > + struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev, > + class_dev); > + kfree(ec); > +} > + > +static void cros_ec_sensors_register(struct cros_ec_dev *ec) > +{ > + /* > + * Issue a command to get the number of sensor reported. > + * Build an array of sensors driver and register them all. > + */ > + int ret, i, id, sensor_num; > + struct mfd_cell *sensor_cells; > + struct cros_ec_sensor_platform *sensor_platforms; > + int sensor_type[MOTIONSENSE_TYPE_MAX]; > + struct ec_params_motion_sense *params; > + struct ec_response_motion_sense *resp; > + struct cros_ec_command *msg; > + > + msg = kzalloc(sizeof(struct cros_ec_command) + > + max(sizeof(*params), sizeof(*resp)), GFP_KERNEL); > + if (msg == NULL) > + return; > + > + msg->version = 2; > + msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; > + msg->outsize = sizeof(*params); > + msg->insize = sizeof(*resp); > + > + params = (struct ec_params_motion_sense *)msg->data; > + params->cmd = MOTIONSENSE_CMD_DUMP; > + > + ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > + if (ret < 0 || msg->result != EC_RES_SUCCESS) { > + dev_warn(ec->dev, "cannot get EC sensor information: %d/%d\n", > + ret, msg->result); > + goto error; > + } > + > + resp = (struct ec_response_motion_sense *)msg->data; > + sensor_num = resp->dump.sensor_count; > + /* Allocate 2 extra sensors in case lid angle or FIFO are needed */ > + sensor_cells = kzalloc(sizeof(struct mfd_cell) * (sensor_num + 2), > + GFP_KERNEL); > + if (sensor_cells == NULL) > + goto error; > + > + sensor_platforms = kzalloc(sizeof(struct cros_ec_sensor_platform) * > + (sensor_num + 1), GFP_KERNEL); > + if (sensor_platforms == NULL) > + goto error_platforms; > + > + memset(sensor_type, 0, sizeof(sensor_type)); > + id = 0; > + for (i = 0; i < sensor_num; i++) { > + params->cmd = MOTIONSENSE_CMD_INFO; > + params->info.sensor_num = i; > + ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > + if (ret < 0 || msg->result != EC_RES_SUCCESS) { > + dev_warn(ec->dev, "no info for EC sensor %d : %d/%d\n", > + i, ret, msg->result); > + continue; > + } > + switch (resp->info.type) { > + case MOTIONSENSE_TYPE_ACCEL: > + sensor_cells[id].name = "cros-ec-accel"; > + break; > + case MOTIONSENSE_TYPE_BARO: > + sensor_cells[id].name = "cros-ec-baro"; > + break; > + case MOTIONSENSE_TYPE_GYRO: > + sensor_cells[id].name = "cros-ec-gyro"; > + break; > + case MOTIONSENSE_TYPE_MAG: > + sensor_cells[id].name = "cros-ec-mag"; > + break; > + case MOTIONSENSE_TYPE_PROX: > + sensor_cells[id].name = "cros-ec-prox"; > + break; > + case MOTIONSENSE_TYPE_LIGHT: > + sensor_cells[id].name = "cros-ec-light"; > + break; > + case MOTIONSENSE_TYPE_ACTIVITY: > + sensor_cells[id].name = "cros-ec-activity"; > + break; > + default: > + dev_warn(ec->dev, "unknown type %d\n", resp->info.type); > + continue; > + } > + sensor_platforms[id].sensor_num = i; > + sensor_cells[id].id = sensor_type[resp->info.type]; > + sensor_cells[id].platform_data = &sensor_platforms[id]; > + sensor_cells[id].pdata_size = > + sizeof(struct cros_ec_sensor_platform); > + > + sensor_type[resp->info.type]++; > + id++; > + } > + if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2) { > + sensor_platforms[id].sensor_num = sensor_num; > + > + sensor_cells[id].name = "cros-ec-angle"; > + sensor_cells[id].id = 0; > + sensor_cells[id].platform_data = &sensor_platforms[id]; > + sensor_cells[id].pdata_size = > + sizeof(struct cros_ec_sensor_platform); > + id++; > + } > + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { > + sensor_cells[id].name = "cros-ec-ring"; > + id++; > + } > + > + ret = mfd_add_devices(ec->dev, 0, sensor_cells, id, > + NULL, 0, NULL); > + if (ret) > + dev_err(ec->dev, "failed to add EC sensors\n"); > + > + kfree(sensor_platforms); > +error_platforms: > + kfree(sensor_cells); > +error: > + kfree(msg); > +} > + > +static int ec_device_probe(struct platform_device *pdev) > +{ > + int retval = -ENOMEM; > + struct device *dev = &pdev->dev; > + struct cros_ec_platform *ec_platform = dev_get_platdata(dev); > + struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); > + > + if (!ec) > + return retval; > + > + dev_set_drvdata(dev, ec); > + ec->ec_dev = dev_get_drvdata(dev->parent); > + ec->dev = dev; > + ec->cmd_offset = ec_platform->cmd_offset; > + ec->features[0] = -1U; /* Not cached yet */ > + ec->features[1] = -1U; /* Not cached yet */ > + device_initialize(&ec->class_dev); > + cdev_init(&ec->cdev, &fops); > + > + /* > + * Add the class device > + * Link to the character device for creating the /dev entry > + * in devtmpfs. > + */ > + ec->class_dev.devt = MKDEV(ec_major, pdev->id); > + ec->class_dev.class = &cros_class; > + ec->class_dev.parent = dev; > + ec->class_dev.release = __remove; > + > + retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name); > + if (retval) { > + dev_err(dev, "dev_set_name failed => %d\n", retval); > + goto failed; > + } > + > + retval = cdev_device_add(&ec->cdev, &ec->class_dev); > + if (retval) { > + dev_err(dev, "cdev_device_add failed => %d\n", retval); > + goto failed; > + } > + > + if (cros_ec_debugfs_init(ec)) > + dev_warn(dev, "failed to create debugfs directory\n"); > + > + /* check whether this EC is a sensor hub. */ > + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) > + cros_ec_sensors_register(ec); > + > + /* Take control of the lightbar from the EC. */ > + lb_manual_suspend_ctrl(ec, 1); > + > + return 0; > + > +failed: > + put_device(&ec->class_dev); > + return retval; > +} > + > +static int ec_device_remove(struct platform_device *pdev) > +{ > + struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); > + > + /* Let the EC take over the lightbar again. */ > + lb_manual_suspend_ctrl(ec, 0); > + > + cros_ec_debugfs_remove(ec); > + > + cdev_del(&ec->cdev); > + device_unregister(&ec->class_dev); > + return 0; > +} > + > +static const struct platform_device_id cros_ec_id[] = { > + { DRV_NAME, 0 }, > + { /* sentinel */ }, > +}; > +MODULE_DEVICE_TABLE(platform, cros_ec_id); > + > +static __maybe_unused int ec_device_suspend(struct device *dev) > +{ > + struct cros_ec_dev *ec = dev_get_drvdata(dev); > + > + lb_suspend(ec); > + > + return 0; > +} > + > +static __maybe_unused int ec_device_resume(struct device *dev) > +{ > + struct cros_ec_dev *ec = dev_get_drvdata(dev); > + > + lb_resume(ec); > + > + return 0; > +} > + > +static const struct dev_pm_ops cros_ec_dev_pm_ops = { > +#ifdef CONFIG_PM_SLEEP > + .suspend = ec_device_suspend, > + .resume = ec_device_resume, > +#endif > +}; > + > +static struct platform_driver cros_ec_dev_driver = { > + .driver = { > + .name = DRV_NAME, > + .pm = &cros_ec_dev_pm_ops, > + }, > + .probe = ec_device_probe, > + .remove = ec_device_remove, > +}; > + > +static int __init cros_ec_dev_init(void) > +{ > + int ret; > + dev_t dev = 0; > + > + ret = class_register(&cros_class); > + if (ret) { > + pr_err(CROS_EC_DEV_NAME ": failed to register device class\n"); > + return ret; > + } > + > + /* Get a range of minor numbers (starting with 0) to work with */ > + ret = alloc_chrdev_region(&dev, 0, CROS_MAX_DEV, CROS_EC_DEV_NAME); > + if (ret < 0) { > + pr_err(CROS_EC_DEV_NAME ": alloc_chrdev_region() failed\n"); > + goto failed_chrdevreg; > + } > + ec_major = MAJOR(dev); > + > + /* Register the driver */ > + ret = platform_driver_register(&cros_ec_dev_driver); > + if (ret < 0) { > + pr_warn(CROS_EC_DEV_NAME ": can't register driver: %d\n", ret); > + goto failed_devreg; > + } > + return 0; > + > +failed_devreg: > + unregister_chrdev_region(MKDEV(ec_major, 0), CROS_MAX_DEV); > +failed_chrdevreg: > + class_unregister(&cros_class); > + return ret; > +} > + > +static void __exit cros_ec_dev_exit(void) > +{ > + platform_driver_unregister(&cros_ec_dev_driver); > + unregister_chrdev(ec_major, CROS_EC_DEV_NAME); > + class_unregister(&cros_class); > +} > + > +module_init(cros_ec_dev_init); > +module_exit(cros_ec_dev_exit); > + > +MODULE_ALIAS("platform:" DRV_NAME); > +MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>"); > +MODULE_DESCRIPTION("Userspace interface to the Chrome OS Embedded Controller"); > +MODULE_VERSION("1.0"); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/mfd/cros_ec_dev.h b/drivers/mfd/cros_ec_dev.h > new file mode 100644 > index 0000000..45e9453 > --- /dev/null > +++ b/drivers/mfd/cros_ec_dev.h > @@ -0,0 +1,52 @@ > +/* > + * cros_ec_dev - expose the Chrome OS Embedded Controller to userspace > + * > + * Copyright (C) 2014 Google, Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef _CROS_EC_DEV_H_ > +#define _CROS_EC_DEV_H_ > + > +#include <linux/ioctl.h> > +#include <linux/types.h> > +#include <linux/mfd/cros_ec.h> > + > +#define CROS_EC_DEV_VERSION "1.0.0" > + > +/* > + * @offset: within EC_LPC_ADDR_MEMMAP region > + * @bytes: number of bytes to read. zero means "read a string" (including '\0') > + * (at most only EC_MEMMAP_SIZE bytes can be read) > + * @buffer: where to store the result > + * ioctl returns the number of bytes read, negative on error > + */ > +struct cros_ec_readmem { > + uint32_t offset; > + uint32_t bytes; > + uint8_t buffer[EC_MEMMAP_SIZE]; > +}; > + > +#define CROS_EC_DEV_IOC 0xEC > +#define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command) > +#define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem) > + > +/* Lightbar utilities */ > +extern bool ec_has_lightbar(struct cros_ec_dev *ec); > +extern int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable); > +extern int lb_suspend(struct cros_ec_dev *ec); > +extern int lb_resume(struct cros_ec_dev *ec); > + > +#endif /* _CROS_EC_DEV_H_ */ > diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig > index bffc892..e728a96 100644 > --- a/drivers/platform/chrome/Kconfig > +++ b/drivers/platform/chrome/Kconfig > @@ -38,16 +38,6 @@ config CHROMEOS_PSTORE > If you have a supported Chromebook, choose Y or M here. > The module will be called chromeos_pstore. > > -config CROS_EC_CHARDEV > - tristate "Chrome OS Embedded Controller userspace device interface" > - depends on MFD_CROS_EC > - select CROS_EC_CTL > - ---help--- > - This driver adds support to talk with the ChromeOS EC from userspace. > - > - If you have a supported Chromebook, choose Y or M here. > - The module will be called cros_ec_dev. > - > config CROS_EC_CTL > tristate > > diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile > index bc239ec..ff3b369 100644 > --- a/drivers/platform/chrome/Makefile > +++ b/drivers/platform/chrome/Makefile > @@ -5,7 +5,6 @@ obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o > cros_ec_ctl-objs := cros_ec_sysfs.o cros_ec_lightbar.o \ > cros_ec_vbc.o cros_ec_debugfs.o > obj-$(CONFIG_CROS_EC_CTL) += cros_ec_ctl.o > -obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_dev.o > cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o > cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o > obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o > diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c > index d0b8ce0..98a35d3 100644 > --- a/drivers/platform/chrome/cros_ec_debugfs.c > +++ b/drivers/platform/chrome/cros_ec_debugfs.c > @@ -29,9 +29,6 @@ > #include <linux/slab.h> > #include <linux/wait.h> > > -#include "cros_ec_dev.h" > -#include "cros_ec_debugfs.h" > - > #define LOG_SHIFT 14 > #define LOG_SIZE (1 << LOG_SHIFT) > #define LOG_POLL_SEC 10 > diff --git a/drivers/platform/chrome/cros_ec_debugfs.h b/drivers/platform/chrome/cros_ec_debugfs.h > deleted file mode 100644 > index 1ff3a50..0000000 > --- a/drivers/platform/chrome/cros_ec_debugfs.h > +++ /dev/null > @@ -1,27 +0,0 @@ > -/* > - * Copyright 2015 Google, Inc. > - * > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 of the License, or > - * (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program. If not, see <http://www.gnu.org/licenses/>. > - */ > - > -#ifndef _DRV_CROS_EC_DEBUGFS_H_ > -#define _DRV_CROS_EC_DEBUGFS_H_ > - > -#include "cros_ec_dev.h" > - > -/* debugfs stuff */ > -int cros_ec_debugfs_init(struct cros_ec_dev *ec); > -void cros_ec_debugfs_remove(struct cros_ec_dev *ec); > - > -#endif /* _DRV_CROS_EC_DEBUGFS_H_ */ > diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c > deleted file mode 100644 > index daf0ffd..0000000 > --- a/drivers/platform/chrome/cros_ec_dev.c > +++ /dev/null > @@ -1,553 +0,0 @@ > -/* > - * cros_ec_dev - expose the Chrome OS Embedded Controller to user-space > - * > - * Copyright (C) 2014 Google, Inc. > - * > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 of the License, or > - * (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program. If not, see <http://www.gnu.org/licenses/>. > - */ > - > -#include <linux/fs.h> > -#include <linux/mfd/core.h> > -#include <linux/module.h> > -#include <linux/platform_device.h> > -#include <linux/pm.h> > -#include <linux/slab.h> > -#include <linux/uaccess.h> > - > -#include "cros_ec_debugfs.h" > -#include "cros_ec_dev.h" > - > -#define DRV_NAME "cros-ec-dev" > - > -/* Device variables */ > -#define CROS_MAX_DEV 128 > -static int ec_major; > - > -static const struct attribute_group *cros_ec_groups[] = { > - &cros_ec_attr_group, > - &cros_ec_lightbar_attr_group, > - &cros_ec_vbc_attr_group, > - NULL, > -}; > - > -static struct class cros_class = { > - .owner = THIS_MODULE, > - .name = "chromeos", > - .dev_groups = cros_ec_groups, > -}; > - > -/* Basic communication */ > -static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen) > -{ > - struct ec_response_get_version *resp; > - static const char * const current_image_name[] = { > - "unknown", "read-only", "read-write", "invalid", > - }; > - struct cros_ec_command *msg; > - int ret; > - > - msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL); > - if (!msg) > - return -ENOMEM; > - > - msg->version = 0; > - msg->command = EC_CMD_GET_VERSION + ec->cmd_offset; > - msg->insize = sizeof(*resp); > - msg->outsize = 0; > - > - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > - if (ret < 0) > - goto exit; > - > - if (msg->result != EC_RES_SUCCESS) { > - snprintf(str, maxlen, > - "%s\nUnknown EC version: EC returned %d\n", > - CROS_EC_DEV_VERSION, msg->result); > - ret = -EINVAL; > - goto exit; > - } > - > - resp = (struct ec_response_get_version *)msg->data; > - if (resp->current_image >= ARRAY_SIZE(current_image_name)) > - resp->current_image = 3; /* invalid */ > - > - snprintf(str, maxlen, "%s\n%s\n%s\n%s\n", CROS_EC_DEV_VERSION, > - resp->version_string_ro, resp->version_string_rw, > - current_image_name[resp->current_image]); > - > - ret = 0; > -exit: > - kfree(msg); > - return ret; > -} > - > -static int cros_ec_check_features(struct cros_ec_dev *ec, int feature) > -{ > - struct cros_ec_command *msg; > - int ret; > - > - if (ec->features[0] == -1U && ec->features[1] == -1U) { > - /* features bitmap not read yet */ > - > - msg = kmalloc(sizeof(*msg) + sizeof(ec->features), GFP_KERNEL); > - if (!msg) > - return -ENOMEM; > - > - msg->version = 0; > - msg->command = EC_CMD_GET_FEATURES + ec->cmd_offset; > - msg->insize = sizeof(ec->features); > - msg->outsize = 0; > - > - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > - if (ret < 0 || msg->result != EC_RES_SUCCESS) { > - dev_warn(ec->dev, "cannot get EC features: %d/%d\n", > - ret, msg->result); > - memset(ec->features, 0, sizeof(ec->features)); > - } > - > - memcpy(ec->features, msg->data, sizeof(ec->features)); > - > - dev_dbg(ec->dev, "EC features %08x %08x\n", > - ec->features[0], ec->features[1]); > - > - kfree(msg); > - } > - > - return ec->features[feature / 32] & EC_FEATURE_MASK_0(feature); > -} > - > -/* Device file ops */ > -static int ec_device_open(struct inode *inode, struct file *filp) > -{ > - struct cros_ec_dev *ec = container_of(inode->i_cdev, > - struct cros_ec_dev, cdev); > - filp->private_data = ec; > - nonseekable_open(inode, filp); > - return 0; > -} > - > -static int ec_device_release(struct inode *inode, struct file *filp) > -{ > - return 0; > -} > - > -static ssize_t ec_device_read(struct file *filp, char __user *buffer, > - size_t length, loff_t *offset) > -{ > - struct cros_ec_dev *ec = filp->private_data; > - char msg[sizeof(struct ec_response_get_version) + > - sizeof(CROS_EC_DEV_VERSION)]; > - size_t count; > - int ret; > - > - if (*offset != 0) > - return 0; > - > - ret = ec_get_version(ec, msg, sizeof(msg)); > - if (ret) > - return ret; > - > - count = min(length, strlen(msg)); > - > - if (copy_to_user(buffer, msg, count)) > - return -EFAULT; > - > - *offset = count; > - return count; > -} > - > -/* Ioctls */ > -static long ec_device_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg) > -{ > - long ret; > - struct cros_ec_command u_cmd; > - struct cros_ec_command *s_cmd; > - > - if (copy_from_user(&u_cmd, arg, sizeof(u_cmd))) > - return -EFAULT; > - > - if ((u_cmd.outsize > EC_MAX_MSG_BYTES) || > - (u_cmd.insize > EC_MAX_MSG_BYTES)) > - return -EINVAL; > - > - s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), > - GFP_KERNEL); > - if (!s_cmd) > - return -ENOMEM; > - > - if (copy_from_user(s_cmd, arg, sizeof(*s_cmd) + u_cmd.outsize)) { > - ret = -EFAULT; > - goto exit; > - } > - > - if (u_cmd.outsize != s_cmd->outsize || > - u_cmd.insize != s_cmd->insize) { > - ret = -EINVAL; > - goto exit; > - } > - > - s_cmd->command += ec->cmd_offset; > - ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd); > - /* Only copy data to userland if data was received. */ > - if (ret < 0) > - goto exit; > - > - if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize)) > - ret = -EFAULT; > -exit: > - kfree(s_cmd); > - return ret; > -} > - > -static long ec_device_ioctl_readmem(struct cros_ec_dev *ec, void __user *arg) > -{ > - struct cros_ec_device *ec_dev = ec->ec_dev; > - struct cros_ec_readmem s_mem = { }; > - long num; > - > - /* Not every platform supports direct reads */ > - if (!ec_dev->cmd_readmem) > - return -ENOTTY; > - > - if (copy_from_user(&s_mem, arg, sizeof(s_mem))) > - return -EFAULT; > - > - num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes, > - s_mem.buffer); > - if (num <= 0) > - return num; > - > - if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem))) > - return -EFAULT; > - > - return 0; > -} > - > -static long ec_device_ioctl(struct file *filp, unsigned int cmd, > - unsigned long arg) > -{ > - struct cros_ec_dev *ec = filp->private_data; > - > - if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC) > - return -ENOTTY; > - > - switch (cmd) { > - case CROS_EC_DEV_IOCXCMD: > - return ec_device_ioctl_xcmd(ec, (void __user *)arg); > - case CROS_EC_DEV_IOCRDMEM: > - return ec_device_ioctl_readmem(ec, (void __user *)arg); > - } > - > - return -ENOTTY; > -} > - > -/* Module initialization */ > -static const struct file_operations fops = { > - .open = ec_device_open, > - .release = ec_device_release, > - .read = ec_device_read, > - .unlocked_ioctl = ec_device_ioctl, > -#ifdef CONFIG_COMPAT > - .compat_ioctl = ec_device_ioctl, > -#endif > -}; > - > -static void __remove(struct device *dev) > -{ > - struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev, > - class_dev); > - kfree(ec); > -} > - > -static void cros_ec_sensors_register(struct cros_ec_dev *ec) > -{ > - /* > - * Issue a command to get the number of sensor reported. > - * Build an array of sensors driver and register them all. > - */ > - int ret, i, id, sensor_num; > - struct mfd_cell *sensor_cells; > - struct cros_ec_sensor_platform *sensor_platforms; > - int sensor_type[MOTIONSENSE_TYPE_MAX]; > - struct ec_params_motion_sense *params; > - struct ec_response_motion_sense *resp; > - struct cros_ec_command *msg; > - > - msg = kzalloc(sizeof(struct cros_ec_command) + > - max(sizeof(*params), sizeof(*resp)), GFP_KERNEL); > - if (msg == NULL) > - return; > - > - msg->version = 2; > - msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; > - msg->outsize = sizeof(*params); > - msg->insize = sizeof(*resp); > - > - params = (struct ec_params_motion_sense *)msg->data; > - params->cmd = MOTIONSENSE_CMD_DUMP; > - > - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > - if (ret < 0 || msg->result != EC_RES_SUCCESS) { > - dev_warn(ec->dev, "cannot get EC sensor information: %d/%d\n", > - ret, msg->result); > - goto error; > - } > - > - resp = (struct ec_response_motion_sense *)msg->data; > - sensor_num = resp->dump.sensor_count; > - /* Allocate 2 extra sensors in case lid angle or FIFO are needed */ > - sensor_cells = kzalloc(sizeof(struct mfd_cell) * (sensor_num + 2), > - GFP_KERNEL); > - if (sensor_cells == NULL) > - goto error; > - > - sensor_platforms = kzalloc(sizeof(struct cros_ec_sensor_platform) * > - (sensor_num + 1), GFP_KERNEL); > - if (sensor_platforms == NULL) > - goto error_platforms; > - > - memset(sensor_type, 0, sizeof(sensor_type)); > - id = 0; > - for (i = 0; i < sensor_num; i++) { > - params->cmd = MOTIONSENSE_CMD_INFO; > - params->info.sensor_num = i; > - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); > - if (ret < 0 || msg->result != EC_RES_SUCCESS) { > - dev_warn(ec->dev, "no info for EC sensor %d : %d/%d\n", > - i, ret, msg->result); > - continue; > - } > - switch (resp->info.type) { > - case MOTIONSENSE_TYPE_ACCEL: > - sensor_cells[id].name = "cros-ec-accel"; > - break; > - case MOTIONSENSE_TYPE_BARO: > - sensor_cells[id].name = "cros-ec-baro"; > - break; > - case MOTIONSENSE_TYPE_GYRO: > - sensor_cells[id].name = "cros-ec-gyro"; > - break; > - case MOTIONSENSE_TYPE_MAG: > - sensor_cells[id].name = "cros-ec-mag"; > - break; > - case MOTIONSENSE_TYPE_PROX: > - sensor_cells[id].name = "cros-ec-prox"; > - break; > - case MOTIONSENSE_TYPE_LIGHT: > - sensor_cells[id].name = "cros-ec-light"; > - break; > - case MOTIONSENSE_TYPE_ACTIVITY: > - sensor_cells[id].name = "cros-ec-activity"; > - break; > - default: > - dev_warn(ec->dev, "unknown type %d\n", resp->info.type); > - continue; > - } > - sensor_platforms[id].sensor_num = i; > - sensor_cells[id].id = sensor_type[resp->info.type]; > - sensor_cells[id].platform_data = &sensor_platforms[id]; > - sensor_cells[id].pdata_size = > - sizeof(struct cros_ec_sensor_platform); > - > - sensor_type[resp->info.type]++; > - id++; > - } > - if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2) { > - sensor_platforms[id].sensor_num = sensor_num; > - > - sensor_cells[id].name = "cros-ec-angle"; > - sensor_cells[id].id = 0; > - sensor_cells[id].platform_data = &sensor_platforms[id]; > - sensor_cells[id].pdata_size = > - sizeof(struct cros_ec_sensor_platform); > - id++; > - } > - if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { > - sensor_cells[id].name = "cros-ec-ring"; > - id++; > - } > - > - ret = mfd_add_devices(ec->dev, 0, sensor_cells, id, > - NULL, 0, NULL); > - if (ret) > - dev_err(ec->dev, "failed to add EC sensors\n"); > - > - kfree(sensor_platforms); > -error_platforms: > - kfree(sensor_cells); > -error: > - kfree(msg); > -} > - > -static int ec_device_probe(struct platform_device *pdev) > -{ > - int retval = -ENOMEM; > - struct device *dev = &pdev->dev; > - struct cros_ec_platform *ec_platform = dev_get_platdata(dev); > - struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); > - > - if (!ec) > - return retval; > - > - dev_set_drvdata(dev, ec); > - ec->ec_dev = dev_get_drvdata(dev->parent); > - ec->dev = dev; > - ec->cmd_offset = ec_platform->cmd_offset; > - ec->features[0] = -1U; /* Not cached yet */ > - ec->features[1] = -1U; /* Not cached yet */ > - device_initialize(&ec->class_dev); > - cdev_init(&ec->cdev, &fops); > - > - /* > - * Add the class device > - * Link to the character device for creating the /dev entry > - * in devtmpfs. > - */ > - ec->class_dev.devt = MKDEV(ec_major, pdev->id); > - ec->class_dev.class = &cros_class; > - ec->class_dev.parent = dev; > - ec->class_dev.release = __remove; > - > - retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name); > - if (retval) { > - dev_err(dev, "dev_set_name failed => %d\n", retval); > - goto failed; > - } > - > - retval = cdev_device_add(&ec->cdev, &ec->class_dev); > - if (retval) { > - dev_err(dev, "cdev_device_add failed => %d\n", retval); > - goto failed; > - } > - > - if (cros_ec_debugfs_init(ec)) > - dev_warn(dev, "failed to create debugfs directory\n"); > - > - /* check whether this EC is a sensor hub. */ > - if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) > - cros_ec_sensors_register(ec); > - > - /* Take control of the lightbar from the EC. */ > - lb_manual_suspend_ctrl(ec, 1); > - > - return 0; > - > -failed: > - put_device(&ec->class_dev); > - return retval; > -} > - > -static int ec_device_remove(struct platform_device *pdev) > -{ > - struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); > - > - /* Let the EC take over the lightbar again. */ > - lb_manual_suspend_ctrl(ec, 0); > - > - cros_ec_debugfs_remove(ec); > - > - cdev_del(&ec->cdev); > - device_unregister(&ec->class_dev); > - return 0; > -} > - > -static const struct platform_device_id cros_ec_id[] = { > - { DRV_NAME, 0 }, > - { /* sentinel */ }, > -}; > -MODULE_DEVICE_TABLE(platform, cros_ec_id); > - > -static __maybe_unused int ec_device_suspend(struct device *dev) > -{ > - struct cros_ec_dev *ec = dev_get_drvdata(dev); > - > - lb_suspend(ec); > - > - return 0; > -} > - > -static __maybe_unused int ec_device_resume(struct device *dev) > -{ > - struct cros_ec_dev *ec = dev_get_drvdata(dev); > - > - lb_resume(ec); > - > - return 0; > -} > - > -static const struct dev_pm_ops cros_ec_dev_pm_ops = { > -#ifdef CONFIG_PM_SLEEP > - .suspend = ec_device_suspend, > - .resume = ec_device_resume, > -#endif > -}; > - > -static struct platform_driver cros_ec_dev_driver = { > - .driver = { > - .name = DRV_NAME, > - .pm = &cros_ec_dev_pm_ops, > - }, > - .probe = ec_device_probe, > - .remove = ec_device_remove, > -}; > - > -static int __init cros_ec_dev_init(void) > -{ > - int ret; > - dev_t dev = 0; > - > - ret = class_register(&cros_class); > - if (ret) { > - pr_err(CROS_EC_DEV_NAME ": failed to register device class\n"); > - return ret; > - } > - > - /* Get a range of minor numbers (starting with 0) to work with */ > - ret = alloc_chrdev_region(&dev, 0, CROS_MAX_DEV, CROS_EC_DEV_NAME); > - if (ret < 0) { > - pr_err(CROS_EC_DEV_NAME ": alloc_chrdev_region() failed\n"); > - goto failed_chrdevreg; > - } > - ec_major = MAJOR(dev); > - > - /* Register the driver */ > - ret = platform_driver_register(&cros_ec_dev_driver); > - if (ret < 0) { > - pr_warn(CROS_EC_DEV_NAME ": can't register driver: %d\n", ret); > - goto failed_devreg; > - } > - return 0; > - > -failed_devreg: > - unregister_chrdev_region(MKDEV(ec_major, 0), CROS_MAX_DEV); > -failed_chrdevreg: > - class_unregister(&cros_class); > - return ret; > -} > - > -static void __exit cros_ec_dev_exit(void) > -{ > - platform_driver_unregister(&cros_ec_dev_driver); > - unregister_chrdev(ec_major, CROS_EC_DEV_NAME); > - class_unregister(&cros_class); > -} > - > -module_init(cros_ec_dev_init); > -module_exit(cros_ec_dev_exit); > - > -MODULE_ALIAS("platform:" DRV_NAME); > -MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>"); > -MODULE_DESCRIPTION("Userspace interface to the Chrome OS Embedded Controller"); > -MODULE_VERSION("1.0"); > -MODULE_LICENSE("GPL"); > diff --git a/drivers/platform/chrome/cros_ec_dev.h b/drivers/platform/chrome/cros_ec_dev.h > deleted file mode 100644 > index 45e9453..0000000 > --- a/drivers/platform/chrome/cros_ec_dev.h > +++ /dev/null > @@ -1,52 +0,0 @@ > -/* > - * cros_ec_dev - expose the Chrome OS Embedded Controller to userspace > - * > - * Copyright (C) 2014 Google, Inc. > - * > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 of the License, or > - * (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program. If not, see <http://www.gnu.org/licenses/>. > - */ > - > -#ifndef _CROS_EC_DEV_H_ > -#define _CROS_EC_DEV_H_ > - > -#include <linux/ioctl.h> > -#include <linux/types.h> > -#include <linux/mfd/cros_ec.h> > - > -#define CROS_EC_DEV_VERSION "1.0.0" > - > -/* > - * @offset: within EC_LPC_ADDR_MEMMAP region > - * @bytes: number of bytes to read. zero means "read a string" (including '\0') > - * (at most only EC_MEMMAP_SIZE bytes can be read) > - * @buffer: where to store the result > - * ioctl returns the number of bytes read, negative on error > - */ > -struct cros_ec_readmem { > - uint32_t offset; > - uint32_t bytes; > - uint8_t buffer[EC_MEMMAP_SIZE]; > -}; > - > -#define CROS_EC_DEV_IOC 0xEC > -#define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command) > -#define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem) > - > -/* Lightbar utilities */ > -extern bool ec_has_lightbar(struct cros_ec_dev *ec); > -extern int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable); > -extern int lb_suspend(struct cros_ec_dev *ec); > -extern int lb_resume(struct cros_ec_dev *ec); > - > -#endif /* _CROS_EC_DEV_H_ */ > diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c > index 925d91c..6ea79d4 100644 > --- a/drivers/platform/chrome/cros_ec_lightbar.c > +++ b/drivers/platform/chrome/cros_ec_lightbar.c > @@ -33,8 +33,6 @@ > #include <linux/uaccess.h> > #include <linux/slab.h> > > -#include "cros_ec_dev.h" > - > /* Rate-limit the lightbar interface to prevent DoS. */ > static unsigned long lb_interval_jiffies = 50 * HZ / 1000; > > diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c > index 201f11a..d6eebe8 100644 > --- a/drivers/platform/chrome/cros_ec_sysfs.c > +++ b/drivers/platform/chrome/cros_ec_sysfs.c > @@ -34,8 +34,6 @@ > #include <linux/types.h> > #include <linux/uaccess.h> > > -#include "cros_ec_dev.h" > - > /* Accessor functions */ > > static ssize_t show_ec_reboot(struct device *dev, > diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h > index 4e887ba..c615359 100644 > --- a/include/linux/mfd/cros_ec.h > +++ b/include/linux/mfd/cros_ec.h > @@ -322,6 +322,10 @@ extern struct attribute_group cros_ec_attr_group; > extern struct attribute_group cros_ec_lightbar_attr_group; > extern struct attribute_group cros_ec_vbc_attr_group; > > +/* debugfs stuff */ > +int cros_ec_debugfs_init(struct cros_ec_dev *ec); > +void cros_ec_debugfs_remove(struct cros_ec_dev *ec); > + > /* ACPI GPE handler */ > #ifdef CONFIG_ACPI > > -- > 2.7.4 >
| |