Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tag-chrome-platform-for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform updates from Benson Leung:
"CrOS EC / MFD Migration:
- Move cros_ec core driver from mfd into chrome platform.

Wilco EC:
- Add batt_ppid_info command to Wilco telemetry driver.

CrOS EC:
- cros_ec_rpmsg : Add support to inform EC of suspend/resume status
- cros_ec_rpmsg : Fix race condition on probe failed
- cros_ec_chardev : Add a poll handler to receive MKBP events

Misc:
- bugfixes in cros_usbpd_logger and cros_ec_ishtp"

* tag 'tag-chrome-platform-for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
platform/chrome: cros_usbpd_logger: null check create_singlethread_workqueue
platform/chrome: cros_ec_chardev: Add a poll handler to receive MKBP events
platform/chrome: cros_ec_rpmsg: Fix race with host command when probe failed
platform/chrome: chromeos_tbmc: Report wake events
mfd: cros_ec: Use mfd_add_hotplug_devices() helper
mfd: cros_ec: Add convenience struct to define autodetectable CrOS EC subdevices
mfd: cros_ec: Add convenience struct to define dedicated CrOS EC MCUs
mfd: cros_ec: Use kzalloc and cros_ec_cmd_xfer_status helper
mfd / platform: cros_ec: Reorganize platform and mfd includes
mfd / platform: cros_ec: Rename config to a better name
mfd: cros_ec: Switch to use the new cros-ec-chardev driver
mfd / platform: cros_ec: Miscellaneous character device to talk with the EC
mfd / platform: cros_ec: Move cros-ec core driver out from MFD
mfd / platform: cros_ec: Handle chained ECs as platform devices
platform/chrome: cros_ec_rpmsg: Add host command AP sleep state support
platform/chrome: chromeos_laptop: drop checks of NULL-safe functions
platform/chrome: wilco_ec: Add batt_ppid_info command to telemetry driver

+1164 -776
+1 -1
drivers/extcon/Kconfig
··· 181 181 182 182 config EXTCON_USBC_CROS_EC 183 183 tristate "ChromeOS Embedded Controller EXTCON support" 184 - depends on MFD_CROS_EC 184 + depends on CROS_EC 185 185 help 186 186 Say Y here to enable USB Type C cable detection extcon support when 187 187 using Chrome OS EC based USB Type-C ports.
+2 -1
drivers/extcon/extcon-usbc-cros-ec.c
··· 6 6 7 7 #include <linux/extcon-provider.h> 8 8 #include <linux/kernel.h> 9 - #include <linux/mfd/cros_ec.h> 10 9 #include <linux/module.h> 11 10 #include <linux/notifier.h> 12 11 #include <linux/of.h> 12 + #include <linux/platform_data/cros_ec_commands.h> 13 + #include <linux/platform_data/cros_ec_proto.h> 13 14 #include <linux/platform_device.h> 14 15 #include <linux/slab.h> 15 16 #include <linux/sched.h>
+1 -1
drivers/hid/Kconfig
··· 376 376 377 377 config HID_GOOGLE_HAMMER 378 378 tristate "Google Hammer Keyboard" 379 - depends on USB_HID && LEDS_CLASS && MFD_CROS_EC 379 + depends on USB_HID && LEDS_CLASS && CROS_EC 380 380 ---help--- 381 381 Say Y here if you have a Google Hammer device. 382 382
+2 -2
drivers/hid/hid-google-hammer.c
··· 16 16 #include <linux/acpi.h> 17 17 #include <linux/hid.h> 18 18 #include <linux/leds.h> 19 - #include <linux/mfd/cros_ec.h> 20 - #include <linux/mfd/cros_ec_commands.h> 21 19 #include <linux/module.h> 20 + #include <linux/platform_data/cros_ec_commands.h> 21 + #include <linux/platform_data/cros_ec_proto.h> 22 22 #include <linux/platform_device.h> 23 23 #include <linux/pm_wakeup.h> 24 24 #include <asm/unaligned.h>
+1 -1
drivers/i2c/busses/Kconfig
··· 1345 1345 1346 1346 config I2C_CROS_EC_TUNNEL 1347 1347 tristate "ChromeOS EC tunnel I2C bus" 1348 - depends on MFD_CROS_EC 1348 + depends on CROS_EC 1349 1349 help 1350 1350 If you say yes here you get an I2C bus that will tunnel i2c commands 1351 1351 through to the other side of the ChromeOS EC to the i2c bus
+2 -2
drivers/i2c/busses/i2c-cros-ec-tunnel.c
··· 5 5 6 6 #include <linux/module.h> 7 7 #include <linux/i2c.h> 8 - #include <linux/mfd/cros_ec.h> 9 - #include <linux/mfd/cros_ec_commands.h> 8 + #include <linux/platform_data/cros_ec_commands.h> 9 + #include <linux/platform_data/cros_ec_proto.h> 10 10 #include <linux/platform_device.h> 11 11 #include <linux/slab.h> 12 12
+2 -1
drivers/iio/accel/cros_ec_accel_legacy.c
··· 19 19 #include <linux/iio/triggered_buffer.h> 20 20 #include <linux/kernel.h> 21 21 #include <linux/mfd/cros_ec.h> 22 - #include <linux/mfd/cros_ec_commands.h> 23 22 #include <linux/module.h> 24 23 #include <linux/slab.h> 24 + #include <linux/platform_data/cros_ec_commands.h> 25 + #include <linux/platform_data/cros_ec_proto.h> 25 26 #include <linux/platform_device.h> 26 27 27 28 #define DRV_NAME "cros-ec-accel-legacy"
+1 -1
drivers/iio/common/cros_ec_sensors/Kconfig
··· 4 4 # 5 5 config IIO_CROS_EC_SENSORS_CORE 6 6 tristate "ChromeOS EC Sensors Core" 7 - depends on SYSFS && MFD_CROS_EC 7 + depends on SYSFS && CROS_EC 8 8 select IIO_BUFFER 9 9 select IIO_TRIGGERED_BUFFER 10 10 help
+1 -2
drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
··· 20 20 #include <linux/iio/triggered_buffer.h> 21 21 #include <linux/iio/trigger_consumer.h> 22 22 #include <linux/kernel.h> 23 - #include <linux/mfd/cros_ec.h> 24 - #include <linux/mfd/cros_ec_commands.h> 25 23 #include <linux/module.h> 24 + #include <linux/platform_data/cros_ec_commands.h> 26 25 #include <linux/platform_device.h> 27 26 #include <linux/slab.h> 28 27
+2 -1
drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
··· 17 17 #include <linux/iio/triggered_buffer.h> 18 18 #include <linux/kernel.h> 19 19 #include <linux/mfd/cros_ec.h> 20 - #include <linux/mfd/cros_ec_commands.h> 21 20 #include <linux/module.h> 21 + #include <linux/platform_data/cros_ec_commands.h> 22 + #include <linux/platform_data/cros_ec_proto.h> 22 23 #include <linux/platform_device.h> 23 24 #include <linux/slab.h> 24 25
+2 -1
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
··· 14 14 #include <linux/iio/trigger_consumer.h> 15 15 #include <linux/kernel.h> 16 16 #include <linux/mfd/cros_ec.h> 17 - #include <linux/mfd/cros_ec_commands.h> 18 17 #include <linux/module.h> 19 18 #include <linux/slab.h> 19 + #include <linux/platform_data/cros_ec_commands.h> 20 + #include <linux/platform_data/cros_ec_proto.h> 20 21 #include <linux/platform_device.h> 21 22 22 23 static char *cros_ec_loc[] = {
+2 -1
drivers/iio/light/cros_ec_light_prox.c
··· 15 15 #include <linux/iio/trigger_consumer.h> 16 16 #include <linux/kernel.h> 17 17 #include <linux/mfd/cros_ec.h> 18 - #include <linux/mfd/cros_ec_commands.h> 19 18 #include <linux/module.h> 19 + #include <linux/platform_data/cros_ec_commands.h> 20 + #include <linux/platform_data/cros_ec_proto.h> 20 21 #include <linux/platform_device.h> 21 22 #include <linux/slab.h> 22 23
+2 -1
drivers/iio/pressure/cros_ec_baro.c
··· 15 15 #include <linux/iio/trigger_consumer.h> 16 16 #include <linux/kernel.h> 17 17 #include <linux/mfd/cros_ec.h> 18 - #include <linux/mfd/cros_ec_commands.h> 19 18 #include <linux/module.h> 20 19 #include <linux/slab.h> 20 + #include <linux/platform_data/cros_ec_commands.h> 21 + #include <linux/platform_data/cros_ec_proto.h> 21 22 #include <linux/platform_device.h> 22 23 23 24 /*
+1 -1
drivers/input/keyboard/Kconfig
··· 736 736 config KEYBOARD_CROS_EC 737 737 tristate "ChromeOS EC keyboard" 738 738 select INPUT_MATRIXKMAP 739 - depends on MFD_CROS_EC 739 + depends on CROS_EC 740 740 help 741 741 Say Y here to enable the matrix keyboard used by ChromeOS devices 742 742 and implemented on the ChromeOS EC. You must enable one bus option
+2 -2
drivers/input/keyboard/cros_ec_keyb.c
··· 22 22 #include <linux/slab.h> 23 23 #include <linux/sysrq.h> 24 24 #include <linux/input/matrix_keypad.h> 25 - #include <linux/mfd/cros_ec.h> 26 - #include <linux/mfd/cros_ec_commands.h> 25 + #include <linux/platform_data/cros_ec_commands.h> 26 + #include <linux/platform_data/cros_ec_proto.h> 27 27 28 28 #include <asm/unaligned.h> 29 29
+1 -2
drivers/media/platform/Kconfig
··· 547 547 548 548 config VIDEO_CROS_EC_CEC 549 549 tristate "ChromeOS EC CEC driver" 550 - depends on MFD_CROS_EC 550 + depends on CROS_EC 551 551 select CEC_CORE 552 552 select CEC_NOTIFIER 553 - select CHROME_PLATFORMS 554 553 select CROS_EC_PROTO 555 554 help 556 555 If you say yes here you will get support for the
+3 -2
drivers/media/platform/cros-ec-cec/cros-ec-cec.c
··· 14 14 #include <linux/cec.h> 15 15 #include <linux/slab.h> 16 16 #include <linux/interrupt.h> 17 + #include <linux/mfd/cros_ec.h> 18 + #include <linux/platform_data/cros_ec_commands.h> 19 + #include <linux/platform_data/cros_ec_proto.h> 17 20 #include <media/cec.h> 18 21 #include <media/cec-notifier.h> 19 - #include <linux/mfd/cros_ec.h> 20 - #include <linux/mfd/cros_ec_commands.h> 21 22 22 23 #define DRV_NAME "cros-ec-cec" 23 24
+9 -17
drivers/mfd/Kconfig
··· 211 211 components like regulators or the PEK (Power Enable Key) under the 212 212 corresponding menus. 213 213 214 - config MFD_CROS_EC 215 - tristate "ChromeOS Embedded Controller" 214 + config MFD_CROS_EC_DEV 215 + tristate "ChromeOS Embedded Controller multifunction device" 216 216 select MFD_CORE 217 - select CHROME_PLATFORMS 218 - select CROS_EC_PROTO 219 - depends on X86 || ARM || ARM64 || COMPILE_TEST 217 + depends on CROS_EC 218 + default CROS_EC 220 219 help 221 - If you say Y here you get support for the ChromeOS Embedded 222 - Controller (EC) providing keyboard, battery and power services. 223 - You also need to enable the driver for the bus you are using. The 224 - protocol for talking to the EC is defined by the bus driver. 220 + Select this to get support for ChromeOS Embedded Controller 221 + sub-devices. This driver will instantiate additional drivers such 222 + as RTC, USBPD, etc. but you have to select the individual drivers. 225 223 226 - config MFD_CROS_EC_CHARDEV 227 - tristate "Chrome OS Embedded Controller userspace device interface" 228 - depends on MFD_CROS_EC 229 - ---help--- 230 - This driver adds support to talk with the ChromeOS EC from userspace. 231 - 232 - If you have a supported Chromebook, choose Y or M here. 233 - The module will be called cros_ec_dev. 224 + To compile this driver as a module, choose M here: the module will be 225 + called cros-ec-dev. 234 226 235 227 config MFD_MADERA 236 228 tristate "Cirrus Logic Madera codecs"
+1 -3
drivers/mfd/Makefile
··· 13 13 obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o 14 14 obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o 15 15 obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o 16 - cros_ec_core-objs := cros_ec.o 17 - obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o 18 - obj-$(CONFIG_MFD_CROS_EC_CHARDEV) += cros_ec_dev.o 16 + obj-$(CONFIG_MFD_CROS_EC_DEV) += cros_ec_dev.o 19 17 obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o 20 18 21 19 obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
+33 -31
drivers/mfd/cros_ec.c drivers/platform/chrome/cros_ec.c
··· 13 13 #include <linux/interrupt.h> 14 14 #include <linux/slab.h> 15 15 #include <linux/module.h> 16 - #include <linux/mfd/core.h> 17 - #include <linux/mfd/cros_ec.h> 16 + #include <linux/platform_data/cros_ec_commands.h> 17 + #include <linux/platform_data/cros_ec_proto.h> 18 18 #include <linux/suspend.h> 19 19 #include <asm/unaligned.h> 20 20 ··· 29 29 static struct cros_ec_platform pd_p = { 30 30 .ec_name = CROS_EC_DEV_PD_NAME, 31 31 .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX), 32 - }; 33 - 34 - static const struct mfd_cell ec_cell = { 35 - .name = "cros-ec-dev", 36 - .platform_data = &ec_p, 37 - .pdata_size = sizeof(ec_p), 38 - }; 39 - 40 - static const struct mfd_cell ec_pd_cell = { 41 - .name = "cros-ec-dev", 42 - .platform_data = &pd_p, 43 - .pdata_size = sizeof(pd_p), 44 32 }; 45 33 46 34 static irqreturn_t ec_irq_thread(int irq, void *data) ··· 142 154 } 143 155 } 144 156 145 - err = devm_mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 146 - 1, NULL, ec_dev->irq, NULL); 147 - if (err) { 148 - dev_err(dev, 149 - "Failed to register Embedded Controller subdevice %d\n", 150 - err); 151 - return err; 157 + /* Register a platform device for the main EC instance */ 158 + ec_dev->ec = platform_device_register_data(ec_dev->dev, "cros-ec-dev", 159 + PLATFORM_DEVID_AUTO, &ec_p, 160 + sizeof(struct cros_ec_platform)); 161 + if (IS_ERR(ec_dev->ec)) { 162 + dev_err(ec_dev->dev, 163 + "Failed to create CrOS EC platform device\n"); 164 + return PTR_ERR(ec_dev->ec); 152 165 } 153 166 154 167 if (ec_dev->max_passthru) { 155 168 /* 156 - * Register a PD device as well on top of this device. 169 + * Register a platform device for the PD behind the main EC. 157 170 * We make the following assumptions: 158 171 * - behind an EC, we have a pd 159 172 * - only one device added. 160 173 * - the EC is responsive at init time (it is not true for a 161 - * sensor hub. 174 + * sensor hub). 162 175 */ 163 - err = devm_mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, 164 - &ec_pd_cell, 1, NULL, ec_dev->irq, NULL); 165 - if (err) { 166 - dev_err(dev, 167 - "Failed to register Power Delivery subdevice %d\n", 168 - err); 169 - return err; 176 + ec_dev->pd = platform_device_register_data(ec_dev->dev, 177 + "cros-ec-dev", 178 + PLATFORM_DEVID_AUTO, &pd_p, 179 + sizeof(struct cros_ec_platform)); 180 + if (IS_ERR(ec_dev->pd)) { 181 + dev_err(ec_dev->dev, 182 + "Failed to create CrOS PD platform device\n"); 183 + platform_device_unregister(ec_dev->ec); 184 + return PTR_ERR(ec_dev->pd); 170 185 } 171 186 } 172 187 173 188 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { 174 189 err = devm_of_platform_populate(dev); 175 190 if (err) { 176 - mfd_remove_devices(dev); 191 + platform_device_unregister(ec_dev->pd); 192 + platform_device_unregister(ec_dev->ec); 177 193 dev_err(dev, "Failed to register sub-devices\n"); 178 194 return err; 179 195 } ··· 197 205 return 0; 198 206 } 199 207 EXPORT_SYMBOL(cros_ec_register); 208 + 209 + int cros_ec_unregister(struct cros_ec_device *ec_dev) 210 + { 211 + if (ec_dev->pd) 212 + platform_device_unregister(ec_dev->pd); 213 + platform_device_unregister(ec_dev->ec); 214 + 215 + return 0; 216 + } 217 + EXPORT_SYMBOL(cros_ec_unregister); 200 218 201 219 #ifdef CONFIG_PM_SLEEP 202 220 int cros_ec_suspend(struct cros_ec_device *ec_dev)
+135 -324
drivers/mfd/cros_ec_dev.c
··· 5 5 * Copyright (C) 2014 Google, Inc. 6 6 */ 7 7 8 - #include <linux/fs.h> 9 8 #include <linux/mfd/core.h> 9 + #include <linux/mfd/cros_ec.h> 10 10 #include <linux/module.h> 11 11 #include <linux/mod_devicetable.h> 12 12 #include <linux/of_platform.h> 13 13 #include <linux/platform_device.h> 14 - #include <linux/pm.h> 14 + #include <linux/platform_data/cros_ec_chardev.h> 15 + #include <linux/platform_data/cros_ec_commands.h> 16 + #include <linux/platform_data/cros_ec_proto.h> 15 17 #include <linux/slab.h> 16 - #include <linux/uaccess.h> 17 - 18 - #include "cros_ec_dev.h" 19 18 20 19 #define DRV_NAME "cros-ec-dev" 21 - 22 - /* Device variables */ 23 - #define CROS_MAX_DEV 128 24 - static int ec_major; 25 20 26 21 static struct class cros_class = { 27 22 .owner = THIS_MODULE, 28 23 .name = "chromeos", 29 24 }; 30 25 31 - /* Basic communication */ 32 - static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen) 33 - { 34 - struct ec_response_get_version *resp; 35 - static const char * const current_image_name[] = { 36 - "unknown", "read-only", "read-write", "invalid", 37 - }; 38 - struct cros_ec_command *msg; 39 - int ret; 26 + /** 27 + * cros_feature_to_name - CrOS feature id to name/short description. 28 + * @id: The feature identifier. 29 + * @name: Device name associated with the feature id. 30 + * @desc: Short name that will be displayed. 31 + */ 32 + struct cros_feature_to_name { 33 + unsigned int id; 34 + const char *name; 35 + const char *desc; 36 + }; 40 37 41 - msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL); 42 - if (!msg) 43 - return -ENOMEM; 38 + /** 39 + * cros_feature_to_cells - CrOS feature id to mfd cells association. 40 + * @id: The feature identifier. 41 + * @mfd_cells: Pointer to the array of mfd cells that needs to be added. 42 + * @num_cells: Number of mfd cells into the array. 43 + */ 44 + struct cros_feature_to_cells { 45 + unsigned int id; 46 + const struct mfd_cell *mfd_cells; 47 + unsigned int num_cells; 48 + }; 44 49 45 - msg->version = 0; 46 - msg->command = EC_CMD_GET_VERSION + ec->cmd_offset; 47 - msg->insize = sizeof(*resp); 48 - msg->outsize = 0; 50 + static const struct cros_feature_to_name cros_mcu_devices[] = { 51 + { 52 + .id = EC_FEATURE_FINGERPRINT, 53 + .name = CROS_EC_DEV_FP_NAME, 54 + .desc = "Fingerprint", 55 + }, 56 + { 57 + .id = EC_FEATURE_ISH, 58 + .name = CROS_EC_DEV_ISH_NAME, 59 + .desc = "Integrated Sensor Hub", 60 + }, 61 + { 62 + .id = EC_FEATURE_SCP, 63 + .name = CROS_EC_DEV_SCP_NAME, 64 + .desc = "System Control Processor", 65 + }, 66 + { 67 + .id = EC_FEATURE_TOUCHPAD, 68 + .name = CROS_EC_DEV_TP_NAME, 69 + .desc = "Touchpad", 70 + }, 71 + }; 49 72 50 - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 51 - if (ret < 0) 52 - goto exit; 73 + static const struct mfd_cell cros_ec_cec_cells[] = { 74 + { .name = "cros-ec-cec", }, 75 + }; 53 76 54 - if (msg->result != EC_RES_SUCCESS) { 55 - snprintf(str, maxlen, 56 - "%s\nUnknown EC version: EC returned %d\n", 57 - CROS_EC_DEV_VERSION, msg->result); 58 - ret = -EINVAL; 59 - goto exit; 60 - } 77 + static const struct mfd_cell cros_ec_rtc_cells[] = { 78 + { .name = "cros-ec-rtc", }, 79 + }; 61 80 62 - resp = (struct ec_response_get_version *)msg->data; 63 - if (resp->current_image >= ARRAY_SIZE(current_image_name)) 64 - resp->current_image = 3; /* invalid */ 81 + static const struct mfd_cell cros_usbpd_charger_cells[] = { 82 + { .name = "cros-usbpd-charger", }, 83 + { .name = "cros-usbpd-logger", }, 84 + }; 65 85 66 - snprintf(str, maxlen, "%s\n%s\n%s\n%s\n", CROS_EC_DEV_VERSION, 67 - resp->version_string_ro, resp->version_string_rw, 68 - current_image_name[resp->current_image]); 86 + static const struct cros_feature_to_cells cros_subdevices[] = { 87 + { 88 + .id = EC_FEATURE_CEC, 89 + .mfd_cells = cros_ec_cec_cells, 90 + .num_cells = ARRAY_SIZE(cros_ec_cec_cells), 91 + }, 92 + { 93 + .id = EC_FEATURE_RTC, 94 + .mfd_cells = cros_ec_rtc_cells, 95 + .num_cells = ARRAY_SIZE(cros_ec_rtc_cells), 96 + }, 97 + { 98 + .id = EC_FEATURE_USB_PD, 99 + .mfd_cells = cros_usbpd_charger_cells, 100 + .num_cells = ARRAY_SIZE(cros_usbpd_charger_cells), 101 + }, 102 + }; 69 103 70 - ret = 0; 71 - exit: 72 - kfree(msg); 73 - return ret; 74 - } 104 + static const struct mfd_cell cros_ec_platform_cells[] = { 105 + { .name = "cros-ec-chardev", }, 106 + { .name = "cros-ec-debugfs", }, 107 + { .name = "cros-ec-lightbar", }, 108 + { .name = "cros-ec-sysfs", }, 109 + }; 110 + 111 + static const struct mfd_cell cros_ec_vbc_cells[] = { 112 + { .name = "cros-ec-vbc", } 113 + }; 75 114 76 115 static int cros_ec_check_features(struct cros_ec_dev *ec, int feature) 77 116 { ··· 119 80 120 81 if (ec->features[0] == -1U && ec->features[1] == -1U) { 121 82 /* features bitmap not read yet */ 122 - 123 - msg = kmalloc(sizeof(*msg) + sizeof(ec->features), GFP_KERNEL); 83 + msg = kzalloc(sizeof(*msg) + sizeof(ec->features), GFP_KERNEL); 124 84 if (!msg) 125 85 return -ENOMEM; 126 86 127 - msg->version = 0; 128 87 msg->command = EC_CMD_GET_FEATURES + ec->cmd_offset; 129 88 msg->insize = sizeof(ec->features); 130 - msg->outsize = 0; 131 89 132 - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 133 - if (ret < 0 || msg->result != EC_RES_SUCCESS) { 90 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 91 + if (ret < 0) { 134 92 dev_warn(ec->dev, "cannot get EC features: %d/%d\n", 135 93 ret, msg->result); 136 94 memset(ec->features, 0, sizeof(ec->features)); ··· 143 107 144 108 return ec->features[feature / 32] & EC_FEATURE_MASK_0(feature); 145 109 } 146 - 147 - /* Device file ops */ 148 - static int ec_device_open(struct inode *inode, struct file *filp) 149 - { 150 - struct cros_ec_dev *ec = container_of(inode->i_cdev, 151 - struct cros_ec_dev, cdev); 152 - filp->private_data = ec; 153 - nonseekable_open(inode, filp); 154 - return 0; 155 - } 156 - 157 - static int ec_device_release(struct inode *inode, struct file *filp) 158 - { 159 - return 0; 160 - } 161 - 162 - static ssize_t ec_device_read(struct file *filp, char __user *buffer, 163 - size_t length, loff_t *offset) 164 - { 165 - struct cros_ec_dev *ec = filp->private_data; 166 - char msg[sizeof(struct ec_response_get_version) + 167 - sizeof(CROS_EC_DEV_VERSION)]; 168 - size_t count; 169 - int ret; 170 - 171 - if (*offset != 0) 172 - return 0; 173 - 174 - ret = ec_get_version(ec, msg, sizeof(msg)); 175 - if (ret) 176 - return ret; 177 - 178 - count = min(length, strlen(msg)); 179 - 180 - if (copy_to_user(buffer, msg, count)) 181 - return -EFAULT; 182 - 183 - *offset = count; 184 - return count; 185 - } 186 - 187 - /* Ioctls */ 188 - static long ec_device_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg) 189 - { 190 - long ret; 191 - struct cros_ec_command u_cmd; 192 - struct cros_ec_command *s_cmd; 193 - 194 - if (copy_from_user(&u_cmd, arg, sizeof(u_cmd))) 195 - return -EFAULT; 196 - 197 - if ((u_cmd.outsize > EC_MAX_MSG_BYTES) || 198 - (u_cmd.insize > EC_MAX_MSG_BYTES)) 199 - return -EINVAL; 200 - 201 - s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), 202 - GFP_KERNEL); 203 - if (!s_cmd) 204 - return -ENOMEM; 205 - 206 - if (copy_from_user(s_cmd, arg, sizeof(*s_cmd) + u_cmd.outsize)) { 207 - ret = -EFAULT; 208 - goto exit; 209 - } 210 - 211 - if (u_cmd.outsize != s_cmd->outsize || 212 - u_cmd.insize != s_cmd->insize) { 213 - ret = -EINVAL; 214 - goto exit; 215 - } 216 - 217 - s_cmd->command += ec->cmd_offset; 218 - ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd); 219 - /* Only copy data to userland if data was received. */ 220 - if (ret < 0) 221 - goto exit; 222 - 223 - if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize)) 224 - ret = -EFAULT; 225 - exit: 226 - kfree(s_cmd); 227 - return ret; 228 - } 229 - 230 - static long ec_device_ioctl_readmem(struct cros_ec_dev *ec, void __user *arg) 231 - { 232 - struct cros_ec_device *ec_dev = ec->ec_dev; 233 - struct cros_ec_readmem s_mem = { }; 234 - long num; 235 - 236 - /* Not every platform supports direct reads */ 237 - if (!ec_dev->cmd_readmem) 238 - return -ENOTTY; 239 - 240 - if (copy_from_user(&s_mem, arg, sizeof(s_mem))) 241 - return -EFAULT; 242 - 243 - num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes, 244 - s_mem.buffer); 245 - if (num <= 0) 246 - return num; 247 - 248 - if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem))) 249 - return -EFAULT; 250 - 251 - return num; 252 - } 253 - 254 - static long ec_device_ioctl(struct file *filp, unsigned int cmd, 255 - unsigned long arg) 256 - { 257 - struct cros_ec_dev *ec = filp->private_data; 258 - 259 - if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC) 260 - return -ENOTTY; 261 - 262 - switch (cmd) { 263 - case CROS_EC_DEV_IOCXCMD: 264 - return ec_device_ioctl_xcmd(ec, (void __user *)arg); 265 - case CROS_EC_DEV_IOCRDMEM: 266 - return ec_device_ioctl_readmem(ec, (void __user *)arg); 267 - } 268 - 269 - return -ENOTTY; 270 - } 271 - 272 - /* Module initialization */ 273 - static const struct file_operations fops = { 274 - .open = ec_device_open, 275 - .release = ec_device_release, 276 - .read = ec_device_read, 277 - .unlocked_ioctl = ec_device_ioctl, 278 - #ifdef CONFIG_COMPAT 279 - .compat_ioctl = ec_device_ioctl, 280 - #endif 281 - }; 282 110 283 111 static void cros_ec_class_release(struct device *dev) 284 112 { ··· 176 276 params = (struct ec_params_motion_sense *)msg->data; 177 277 params->cmd = MOTIONSENSE_CMD_DUMP; 178 278 179 - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 180 - if (ret < 0 || msg->result != EC_RES_SUCCESS) { 279 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 280 + if (ret < 0) { 181 281 dev_warn(ec->dev, "cannot get EC sensor information: %d/%d\n", 182 282 ret, msg->result); 183 283 goto error; ··· 204 304 for (i = 0; i < sensor_num; i++) { 205 305 params->cmd = MOTIONSENSE_CMD_INFO; 206 306 params->info.sensor_num = i; 207 - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 208 - if (ret < 0 || msg->result != EC_RES_SUCCESS) { 307 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 308 + if (ret < 0) { 209 309 dev_warn(ec->dev, "no info for EC sensor %d : %d/%d\n", 210 310 i, ret, msg->result); 211 311 continue; ··· 329 429 * Register 2 accelerometers, we will fail in the IIO driver if there 330 430 * are no sensors. 331 431 */ 332 - ret = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, 333 - cros_ec_accel_legacy_cells, 334 - ARRAY_SIZE(cros_ec_accel_legacy_cells), 335 - NULL, 0, NULL); 432 + ret = mfd_add_hotplug_devices(ec->dev, cros_ec_accel_legacy_cells, 433 + ARRAY_SIZE(cros_ec_accel_legacy_cells)); 336 434 if (ret) 337 435 dev_err(ec_dev->dev, "failed to add EC sensors\n"); 338 436 } 339 - 340 - static const struct mfd_cell cros_ec_cec_cells[] = { 341 - { .name = "cros-ec-cec" } 342 - }; 343 - 344 - static const struct mfd_cell cros_ec_rtc_cells[] = { 345 - { .name = "cros-ec-rtc" } 346 - }; 347 - 348 - static const struct mfd_cell cros_usbpd_charger_cells[] = { 349 - { .name = "cros-usbpd-charger" }, 350 - { .name = "cros-usbpd-logger" }, 351 - }; 352 - 353 - static const struct mfd_cell cros_ec_platform_cells[] = { 354 - { .name = "cros-ec-debugfs" }, 355 - { .name = "cros-ec-lightbar" }, 356 - { .name = "cros-ec-sysfs" }, 357 - }; 358 - 359 - static const struct mfd_cell cros_ec_vbc_cells[] = { 360 - { .name = "cros-ec-vbc" } 361 - }; 362 437 363 438 static int ec_device_probe(struct platform_device *pdev) 364 439 { ··· 342 467 struct device *dev = &pdev->dev; 343 468 struct cros_ec_platform *ec_platform = dev_get_platdata(dev); 344 469 struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); 470 + int i; 345 471 346 472 if (!ec) 347 473 return retval; ··· 354 478 ec->features[0] = -1U; /* Not cached yet */ 355 479 ec->features[1] = -1U; /* Not cached yet */ 356 480 device_initialize(&ec->class_dev); 357 - cdev_init(&ec->cdev, &fops); 358 481 359 - /* Check whether this is actually a Fingerprint MCU rather than an EC */ 360 - if (cros_ec_check_features(ec, EC_FEATURE_FINGERPRINT)) { 361 - dev_info(dev, "CrOS Fingerprint MCU detected.\n"); 482 + for (i = 0; i < ARRAY_SIZE(cros_mcu_devices); i++) { 362 483 /* 363 - * Help userspace differentiating ECs from FP MCU, 364 - * regardless of the probing order. 484 + * Check whether this is actually a dedicated MCU rather 485 + * than an standard EC. 365 486 */ 366 - ec_platform->ec_name = CROS_EC_DEV_FP_NAME; 367 - } 368 - 369 - /* 370 - * Check whether this is actually an Integrated Sensor Hub (ISH) 371 - * rather than an EC. 372 - */ 373 - if (cros_ec_check_features(ec, EC_FEATURE_ISH)) { 374 - dev_info(dev, "CrOS ISH MCU detected.\n"); 375 - /* 376 - * Help userspace differentiating ECs from ISH MCU, 377 - * regardless of the probing order. 378 - */ 379 - ec_platform->ec_name = CROS_EC_DEV_ISH_NAME; 380 - } 381 - 382 - /* Check whether this is actually a Touchpad MCU rather than an EC */ 383 - if (cros_ec_check_features(ec, EC_FEATURE_TOUCHPAD)) { 384 - dev_info(dev, "CrOS Touchpad MCU detected.\n"); 385 - /* 386 - * Help userspace differentiating ECs from TP MCU, 387 - * regardless of the probing order. 388 - */ 389 - ec_platform->ec_name = CROS_EC_DEV_TP_NAME; 390 - } 391 - 392 - /* Check whether this is actually a SCP rather than an EC. */ 393 - if (cros_ec_check_features(ec, EC_FEATURE_SCP)) { 394 - dev_info(dev, "CrOS SCP MCU detected.\n"); 395 - /* 396 - * Help userspace differentiating ECs from SCP, 397 - * regardless of the probing order. 398 - */ 399 - ec_platform->ec_name = CROS_EC_DEV_SCP_NAME; 487 + if (cros_ec_check_features(ec, cros_mcu_devices[i].id)) { 488 + dev_info(dev, "CrOS %s MCU detected\n", 489 + cros_mcu_devices[i].desc); 490 + /* 491 + * Help userspace differentiating ECs from other MCU, 492 + * regardless of the probing order. 493 + */ 494 + ec_platform->ec_name = cros_mcu_devices[i].name; 495 + break; 496 + } 400 497 } 401 498 402 499 /* 403 500 * Add the class device 404 - * Link to the character device for creating the /dev entry 405 - * in devtmpfs. 406 501 */ 407 - ec->class_dev.devt = MKDEV(ec_major, pdev->id); 408 502 ec->class_dev.class = &cros_class; 409 503 ec->class_dev.parent = dev; 410 504 ec->class_dev.release = cros_ec_class_release; ··· 385 539 goto failed; 386 540 } 387 541 542 + retval = device_add(&ec->class_dev); 543 + if (retval) 544 + goto failed; 545 + 388 546 /* check whether this EC is a sensor hub. */ 389 547 if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) 390 548 cros_ec_sensors_register(ec); ··· 396 546 /* Workaroud for older EC firmware */ 397 547 cros_ec_accel_legacy_register(ec); 398 548 399 - /* Check whether this EC instance has CEC host command support */ 400 - if (cros_ec_check_features(ec, EC_FEATURE_CEC)) { 401 - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, 402 - cros_ec_cec_cells, 403 - ARRAY_SIZE(cros_ec_cec_cells), 404 - NULL, 0, NULL); 405 - if (retval) 406 - dev_err(ec->dev, 407 - "failed to add cros-ec-cec device: %d\n", 408 - retval); 549 + /* 550 + * The following subdevices can be detected by sending the 551 + * EC_FEATURE_GET_CMD Embedded Controller device. 552 + */ 553 + for (i = 0; i < ARRAY_SIZE(cros_subdevices); i++) { 554 + if (cros_ec_check_features(ec, cros_subdevices[i].id)) { 555 + retval = mfd_add_hotplug_devices(ec->dev, 556 + cros_subdevices[i].mfd_cells, 557 + cros_subdevices[i].num_cells); 558 + if (retval) 559 + dev_err(ec->dev, 560 + "failed to add %s subdevice: %d\n", 561 + cros_subdevices[i].mfd_cells->name, 562 + retval); 563 + } 409 564 } 410 565 411 - /* Check whether this EC instance has RTC host command support */ 412 - if (cros_ec_check_features(ec, EC_FEATURE_RTC)) { 413 - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, 414 - cros_ec_rtc_cells, 415 - ARRAY_SIZE(cros_ec_rtc_cells), 416 - NULL, 0, NULL); 417 - if (retval) 418 - dev_err(ec->dev, 419 - "failed to add cros-ec-rtc device: %d\n", 420 - retval); 421 - } 422 - 423 - /* Check whether this EC instance has the PD charge manager */ 424 - if (cros_ec_check_features(ec, EC_FEATURE_USB_PD)) { 425 - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, 426 - cros_usbpd_charger_cells, 427 - ARRAY_SIZE(cros_usbpd_charger_cells), 428 - NULL, 0, NULL); 429 - if (retval) 430 - dev_err(ec->dev, 431 - "failed to add cros-usbpd-charger device: %d\n", 432 - retval); 433 - } 434 - 435 - /* We can now add the sysfs class, we know which parameter to show */ 436 - retval = cdev_device_add(&ec->cdev, &ec->class_dev); 437 - if (retval) { 438 - dev_err(dev, "cdev_device_add failed => %d\n", retval); 439 - goto failed; 440 - } 441 - 442 - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, 443 - cros_ec_platform_cells, 444 - ARRAY_SIZE(cros_ec_platform_cells), 445 - NULL, 0, NULL); 566 + /* 567 + * The following subdevices cannot be detected by sending the 568 + * EC_FEATURE_GET_CMD to the Embedded Controller device. 569 + */ 570 + retval = mfd_add_hotplug_devices(ec->dev, cros_ec_platform_cells, 571 + ARRAY_SIZE(cros_ec_platform_cells)); 446 572 if (retval) 447 573 dev_warn(ec->dev, 448 574 "failed to add cros-ec platform devices: %d\n", ··· 427 601 /* Check whether this EC instance has a VBC NVRAM */ 428 602 node = ec->ec_dev->dev->of_node; 429 603 if (of_property_read_bool(node, "google,has-vbc-nvram")) { 430 - retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, 431 - cros_ec_vbc_cells, 432 - ARRAY_SIZE(cros_ec_vbc_cells), 433 - NULL, 0, NULL); 604 + retval = mfd_add_hotplug_devices(ec->dev, cros_ec_vbc_cells, 605 + ARRAY_SIZE(cros_ec_vbc_cells)); 434 606 if (retval) 435 607 dev_warn(ec->dev, "failed to add VBC devices: %d\n", 436 608 retval); ··· 446 622 struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); 447 623 448 624 mfd_remove_devices(ec->dev); 449 - cdev_del(&ec->cdev); 450 625 device_unregister(&ec->class_dev); 451 626 return 0; 452 627 } ··· 468 645 static int __init cros_ec_dev_init(void) 469 646 { 470 647 int ret; 471 - dev_t dev = 0; 472 648 473 649 ret = class_register(&cros_class); 474 650 if (ret) { 475 651 pr_err(CROS_EC_DEV_NAME ": failed to register device class\n"); 476 652 return ret; 477 653 } 478 - 479 - /* Get a range of minor numbers (starting with 0) to work with */ 480 - ret = alloc_chrdev_region(&dev, 0, CROS_MAX_DEV, CROS_EC_DEV_NAME); 481 - if (ret < 0) { 482 - pr_err(CROS_EC_DEV_NAME ": alloc_chrdev_region() failed\n"); 483 - goto failed_chrdevreg; 484 - } 485 - ec_major = MAJOR(dev); 486 654 487 655 /* Register the driver */ 488 656 ret = platform_driver_register(&cros_ec_dev_driver); ··· 484 670 return 0; 485 671 486 672 failed_devreg: 487 - unregister_chrdev_region(MKDEV(ec_major, 0), CROS_MAX_DEV); 488 - failed_chrdevreg: 489 673 class_unregister(&cros_class); 490 674 return ret; 491 675 } ··· 491 679 static void __exit cros_ec_dev_exit(void) 492 680 { 493 681 platform_driver_unregister(&cros_ec_dev_driver); 494 - unregister_chrdev(ec_major, CROS_EC_DEV_NAME); 495 682 class_unregister(&cros_class); 496 683 } 497 684
+8 -5
drivers/mfd/cros_ec_dev.h include/linux/platform_data/cros_ec_chardev.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 - * cros_ec_dev - expose the Chrome OS Embedded Controller to userspace 3 + * ChromeOS EC device interface. 4 4 * 5 5 * Copyright (C) 2014 Google, Inc. 6 6 */ 7 7 8 - #ifndef _CROS_EC_DEV_H_ 9 - #define _CROS_EC_DEV_H_ 8 + #ifndef _UAPI_LINUX_CROS_EC_DEV_H_ 9 + #define _UAPI_LINUX_CROS_EC_DEV_H_ 10 10 11 + #include <linux/bits.h> 11 12 #include <linux/ioctl.h> 12 13 #include <linux/types.h> 13 - #include <linux/mfd/cros_ec.h> 14 + 15 + #include <linux/platform_data/cros_ec_commands.h> 14 16 15 17 #define CROS_EC_DEV_VERSION "1.0.0" 16 18 ··· 33 31 #define CROS_EC_DEV_IOC 0xEC 34 32 #define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command) 35 33 #define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem) 34 + #define CROS_EC_DEV_IOCEVENTMASK _IO(CROS_EC_DEV_IOC, 2) 36 35 37 36 #endif /* _CROS_EC_DEV_H_ */
+47 -13
drivers/platform/chrome/Kconfig
··· 3 3 # Platform support for Chrome OS hardware (Chromebooks and Chromeboxes) 4 4 # 5 5 6 + config MFD_CROS_EC 7 + tristate "Platform support for Chrome hardware (transitional)" 8 + select CHROME_PLATFORMS 9 + select CROS_EC 10 + select CONFIG_MFD_CROS_EC_DEV 11 + depends on X86 || ARM || ARM64 || COMPILE_TEST 12 + help 13 + This is a transitional Kconfig option and will be removed after 14 + everyone enables the parts individually. 15 + 6 16 menuconfig CHROME_PLATFORMS 7 17 bool "Platform support for Chrome hardware" 8 18 depends on X86 || ARM || ARM64 || COMPILE_TEST ··· 60 50 To compile this driver as a module, choose M here: the 61 51 module will be called chromeos_tbmc. 62 52 53 + config CROS_EC 54 + tristate "ChromeOS Embedded Controller" 55 + select CROS_EC_PROTO 56 + depends on X86 || ARM || ARM64 || COMPILE_TEST 57 + help 58 + If you say Y here you get support for the ChromeOS Embedded 59 + Controller (EC) providing keyboard, battery and power services. 60 + You also need to enable the driver for the bus you are using. The 61 + protocol for talking to the EC is defined by the bus driver. 62 + 63 + To compile this driver as a module, choose M here: the 64 + module will be called cros_ec. 65 + 63 66 config CROS_EC_I2C 64 67 tristate "ChromeOS Embedded Controller (I2C)" 65 - depends on MFD_CROS_EC && I2C 68 + depends on CROS_EC && I2C 66 69 67 70 help 68 71 If you say Y here, you get support for talking to the ChromeOS ··· 85 62 86 63 config CROS_EC_RPMSG 87 64 tristate "ChromeOS Embedded Controller (rpmsg)" 88 - depends on MFD_CROS_EC && RPMSG && OF 65 + depends on CROS_EC && RPMSG && OF 89 66 help 90 67 If you say Y here, you get support for talking to the ChromeOS EC 91 68 through rpmsg. This uses a simple byte-level protocol with a ··· 97 74 98 75 config CROS_EC_ISHTP 99 76 tristate "ChromeOS Embedded Controller (ISHTP)" 100 - depends on MFD_CROS_EC 77 + depends on CROS_EC 101 78 depends on INTEL_ISH_HID 102 79 help 103 80 If you say Y here, you get support for talking to the ChromeOS EC ··· 110 87 111 88 config CROS_EC_SPI 112 89 tristate "ChromeOS Embedded Controller (SPI)" 113 - depends on MFD_CROS_EC && SPI 90 + depends on CROS_EC && SPI 114 91 115 92 ---help--- 116 93 If you say Y here, you get support for talking to the ChromeOS EC ··· 120 97 121 98 config CROS_EC_LPC 122 99 tristate "ChromeOS Embedded Controller (LPC)" 123 - depends on MFD_CROS_EC && ACPI && (X86 || COMPILE_TEST) 100 + depends on CROS_EC && ACPI && (X86 || COMPILE_TEST) 124 101 help 125 102 If you say Y here, you get support for talking to the ChromeOS EC 126 103 over an LPC bus, including the LPC Microchip EC (MEC) variant. ··· 146 123 To compile this driver as a module, choose M here: the 147 124 module will be called cros_kbd_led_backlight. 148 125 126 + config CROS_EC_CHARDEV 127 + tristate "ChromeOS EC miscdevice" 128 + depends on MFD_CROS_EC_DEV 129 + default MFD_CROS_EC_DEV 130 + help 131 + This driver adds file operations support to talk with the 132 + ChromeOS EC from userspace via a character device. 133 + 134 + To compile this driver as a module, choose M here: the 135 + module will be called cros_ec_chardev. 136 + 149 137 config CROS_EC_LIGHTBAR 150 138 tristate "Chromebook Pixel's lightbar support" 151 - depends on MFD_CROS_EC_CHARDEV 152 - default MFD_CROS_EC_CHARDEV 139 + depends on MFD_CROS_EC_DEV 140 + default MFD_CROS_EC_DEV 153 141 help 154 142 This option exposes the Chromebook Pixel's lightbar to 155 143 userspace. ··· 170 136 171 137 config CROS_EC_VBC 172 138 tristate "ChromeOS EC vboot context support" 173 - depends on MFD_CROS_EC_CHARDEV && OF 174 - default MFD_CROS_EC_CHARDEV 139 + depends on MFD_CROS_EC_DEV && OF 140 + default MFD_CROS_EC_DEV 175 141 help 176 142 This option exposes the ChromeOS EC vboot context nvram to 177 143 userspace. ··· 181 147 182 148 config CROS_EC_DEBUGFS 183 149 tristate "Export ChromeOS EC internals in DebugFS" 184 - depends on MFD_CROS_EC_CHARDEV && DEBUG_FS 185 - default MFD_CROS_EC_CHARDEV 150 + depends on MFD_CROS_EC_DEV && DEBUG_FS 151 + default MFD_CROS_EC_DEV 186 152 help 187 153 This option exposes the ChromeOS EC device internals to 188 154 userspace. ··· 192 158 193 159 config CROS_EC_SYSFS 194 160 tristate "ChromeOS EC control and information through sysfs" 195 - depends on MFD_CROS_EC_CHARDEV && SYSFS 196 - default MFD_CROS_EC_CHARDEV 161 + depends on MFD_CROS_EC_DEV && SYSFS 162 + default MFD_CROS_EC_DEV 197 163 help 198 164 This option exposes some sysfs attributes to control and get 199 165 information from ChromeOS EC.
+2
drivers/platform/chrome/Makefile
··· 6 6 obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 7 7 obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o 8 8 obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o 9 + obj-$(CONFIG_CROS_EC) += cros_ec.o 9 10 obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o 10 11 obj-$(CONFIG_CROS_EC_ISHTP) += cros_ec_ishtp.o 11 12 obj-$(CONFIG_CROS_EC_RPMSG) += cros_ec_rpmsg.o ··· 15 14 obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o 16 15 obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o cros_ec_trace.o 17 16 obj-$(CONFIG_CROS_KBD_LED_BACKLIGHT) += cros_kbd_led_backlight.o 17 + obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_chardev.o 18 18 obj-$(CONFIG_CROS_EC_LIGHTBAR) += cros_ec_lightbar.o 19 19 obj-$(CONFIG_CROS_EC_VBC) += cros_ec_vbc.o 20 20 obj-$(CONFIG_CROS_EC_DEBUGFS) += cros_ec_debugfs.o
+3 -7
drivers/platform/chrome/chromeos_laptop.c
··· 838 838 i2c_dev = &cros_laptop->i2c_peripherals[i]; 839 839 info = &i2c_dev->board_info; 840 840 841 - if (i2c_dev->client) 842 - i2c_unregister_device(i2c_dev->client); 843 - 844 - if (info->properties) 845 - property_entries_free(info->properties); 841 + i2c_unregister_device(i2c_dev->client); 842 + property_entries_free(info->properties); 846 843 } 847 844 848 845 for (i = 0; i < cros_laptop->num_acpi_peripherals; i++) { 849 846 acpi_dev = &cros_laptop->acpi_peripherals[i]; 850 847 851 - if (acpi_dev->properties) 852 - property_entries_free(acpi_dev->properties); 848 + property_entries_free(acpi_dev->properties); 853 849 } 854 850 855 851 kfree(cros_laptop->i2c_peripherals);
+2
drivers/platform/chrome/chromeos_tbmc.c
··· 47 47 48 48 static void chromeos_tbmc_notify(struct acpi_device *adev, u32 event) 49 49 { 50 + acpi_pm_wakeup_event(&adev->dev); 50 51 switch (event) { 51 52 case 0x80: 52 53 chromeos_tbmc_query_switch(adev, adev->driver_data); ··· 91 90 dev_err(dev, "cannot register input device\n"); 92 91 return ret; 93 92 } 93 + device_init_wakeup(dev, true); 94 94 return 0; 95 95 } 96 96
+419
drivers/platform/chrome/cros_ec_chardev.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Miscellaneous character driver for ChromeOS Embedded Controller 4 + * 5 + * Copyright 2014 Google, Inc. 6 + * Copyright 2019 Google LLC 7 + * 8 + * This file is a rework and part of the code is ported from 9 + * drivers/mfd/cros_ec_dev.c that was originally written by 10 + * Bill Richardson. 11 + */ 12 + 13 + #include <linux/init.h> 14 + #include <linux/device.h> 15 + #include <linux/fs.h> 16 + #include <linux/mfd/cros_ec.h> 17 + #include <linux/miscdevice.h> 18 + #include <linux/module.h> 19 + #include <linux/notifier.h> 20 + #include <linux/platform_data/cros_ec_chardev.h> 21 + #include <linux/platform_data/cros_ec_commands.h> 22 + #include <linux/platform_data/cros_ec_proto.h> 23 + #include <linux/platform_device.h> 24 + #include <linux/poll.h> 25 + #include <linux/slab.h> 26 + #include <linux/types.h> 27 + #include <linux/uaccess.h> 28 + 29 + #define DRV_NAME "cros-ec-chardev" 30 + 31 + /* Arbitrary bounded size for the event queue */ 32 + #define CROS_MAX_EVENT_LEN PAGE_SIZE 33 + 34 + struct chardev_data { 35 + struct cros_ec_dev *ec_dev; 36 + struct miscdevice misc; 37 + }; 38 + 39 + struct chardev_priv { 40 + struct cros_ec_dev *ec_dev; 41 + struct notifier_block notifier; 42 + wait_queue_head_t wait_event; 43 + unsigned long event_mask; 44 + struct list_head events; 45 + size_t event_len; 46 + }; 47 + 48 + struct ec_event { 49 + struct list_head node; 50 + size_t size; 51 + u8 event_type; 52 + u8 data[0]; 53 + }; 54 + 55 + static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen) 56 + { 57 + static const char * const current_image_name[] = { 58 + "unknown", "read-only", "read-write", "invalid", 59 + }; 60 + struct ec_response_get_version *resp; 61 + struct cros_ec_command *msg; 62 + int ret; 63 + 64 + msg = kzalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL); 65 + if (!msg) 66 + return -ENOMEM; 67 + 68 + msg->command = EC_CMD_GET_VERSION + ec->cmd_offset; 69 + msg->insize = sizeof(*resp); 70 + 71 + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); 72 + if (ret < 0) { 73 + snprintf(str, maxlen, 74 + "Unknown EC version, returned error: %d\n", 75 + msg->result); 76 + goto exit; 77 + } 78 + 79 + resp = (struct ec_response_get_version *)msg->data; 80 + if (resp->current_image >= ARRAY_SIZE(current_image_name)) 81 + resp->current_image = 3; /* invalid */ 82 + 83 + snprintf(str, maxlen, "%s\n%s\n%s\n%s\n", CROS_EC_DEV_VERSION, 84 + resp->version_string_ro, resp->version_string_rw, 85 + current_image_name[resp->current_image]); 86 + 87 + ret = 0; 88 + exit: 89 + kfree(msg); 90 + return ret; 91 + } 92 + 93 + static int cros_ec_chardev_mkbp_event(struct notifier_block *nb, 94 + unsigned long queued_during_suspend, 95 + void *_notify) 96 + { 97 + struct chardev_priv *priv = container_of(nb, struct chardev_priv, 98 + notifier); 99 + struct cros_ec_device *ec_dev = priv->ec_dev->ec_dev; 100 + struct ec_event *event; 101 + unsigned long event_bit = 1 << ec_dev->event_data.event_type; 102 + int total_size = sizeof(*event) + ec_dev->event_size; 103 + 104 + if (!(event_bit & priv->event_mask) || 105 + (priv->event_len + total_size) > CROS_MAX_EVENT_LEN) 106 + return NOTIFY_DONE; 107 + 108 + event = kzalloc(total_size, GFP_KERNEL); 109 + if (!event) 110 + return NOTIFY_DONE; 111 + 112 + event->size = ec_dev->event_size; 113 + event->event_type = ec_dev->event_data.event_type; 114 + memcpy(event->data, &ec_dev->event_data.data, ec_dev->event_size); 115 + 116 + spin_lock(&priv->wait_event.lock); 117 + list_add_tail(&event->node, &priv->events); 118 + priv->event_len += total_size; 119 + wake_up_locked(&priv->wait_event); 120 + spin_unlock(&priv->wait_event.lock); 121 + 122 + return NOTIFY_OK; 123 + } 124 + 125 + static struct ec_event *cros_ec_chardev_fetch_event(struct chardev_priv *priv, 126 + bool fetch, bool block) 127 + { 128 + struct ec_event *event; 129 + int err; 130 + 131 + spin_lock(&priv->wait_event.lock); 132 + if (!block && list_empty(&priv->events)) { 133 + event = ERR_PTR(-EWOULDBLOCK); 134 + goto out; 135 + } 136 + 137 + if (!fetch) { 138 + event = NULL; 139 + goto out; 140 + } 141 + 142 + err = wait_event_interruptible_locked(priv->wait_event, 143 + !list_empty(&priv->events)); 144 + if (err) { 145 + event = ERR_PTR(err); 146 + goto out; 147 + } 148 + 149 + event = list_first_entry(&priv->events, struct ec_event, node); 150 + list_del(&event->node); 151 + priv->event_len -= sizeof(*event) + event->size; 152 + 153 + out: 154 + spin_unlock(&priv->wait_event.lock); 155 + return event; 156 + } 157 + 158 + /* 159 + * Device file ops 160 + */ 161 + static int cros_ec_chardev_open(struct inode *inode, struct file *filp) 162 + { 163 + struct miscdevice *mdev = filp->private_data; 164 + struct cros_ec_dev *ec_dev = dev_get_drvdata(mdev->parent); 165 + struct chardev_priv *priv; 166 + int ret; 167 + 168 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 169 + if (!priv) 170 + return -ENOMEM; 171 + 172 + priv->ec_dev = ec_dev; 173 + filp->private_data = priv; 174 + INIT_LIST_HEAD(&priv->events); 175 + init_waitqueue_head(&priv->wait_event); 176 + nonseekable_open(inode, filp); 177 + 178 + priv->notifier.notifier_call = cros_ec_chardev_mkbp_event; 179 + ret = blocking_notifier_chain_register(&ec_dev->ec_dev->event_notifier, 180 + &priv->notifier); 181 + if (ret) { 182 + dev_err(ec_dev->dev, "failed to register event notifier\n"); 183 + kfree(priv); 184 + } 185 + 186 + return ret; 187 + } 188 + 189 + static __poll_t cros_ec_chardev_poll(struct file *filp, poll_table *wait) 190 + { 191 + struct chardev_priv *priv = filp->private_data; 192 + 193 + poll_wait(filp, &priv->wait_event, wait); 194 + 195 + if (list_empty(&priv->events)) 196 + return 0; 197 + 198 + return EPOLLIN | EPOLLRDNORM; 199 + } 200 + 201 + static ssize_t cros_ec_chardev_read(struct file *filp, char __user *buffer, 202 + size_t length, loff_t *offset) 203 + { 204 + char msg[sizeof(struct ec_response_get_version) + 205 + sizeof(CROS_EC_DEV_VERSION)]; 206 + struct chardev_priv *priv = filp->private_data; 207 + struct cros_ec_dev *ec_dev = priv->ec_dev; 208 + size_t count; 209 + int ret; 210 + 211 + if (priv->event_mask) { /* queued MKBP event */ 212 + struct ec_event *event; 213 + 214 + event = cros_ec_chardev_fetch_event(priv, length != 0, 215 + !(filp->f_flags & O_NONBLOCK)); 216 + if (IS_ERR(event)) 217 + return PTR_ERR(event); 218 + /* 219 + * length == 0 is special - no IO is done but we check 220 + * for error conditions. 221 + */ 222 + if (length == 0) 223 + return 0; 224 + 225 + /* The event is 1 byte of type plus the payload */ 226 + count = min(length, event->size + 1); 227 + ret = copy_to_user(buffer, &event->event_type, count); 228 + kfree(event); 229 + if (ret) /* the copy failed */ 230 + return -EFAULT; 231 + *offset = count; 232 + return count; 233 + } 234 + 235 + /* 236 + * Legacy behavior if no event mask is defined 237 + */ 238 + if (*offset != 0) 239 + return 0; 240 + 241 + ret = ec_get_version(ec_dev, msg, sizeof(msg)); 242 + if (ret) 243 + return ret; 244 + 245 + count = min(length, strlen(msg)); 246 + 247 + if (copy_to_user(buffer, msg, count)) 248 + return -EFAULT; 249 + 250 + *offset = count; 251 + return count; 252 + } 253 + 254 + static int cros_ec_chardev_release(struct inode *inode, struct file *filp) 255 + { 256 + struct chardev_priv *priv = filp->private_data; 257 + struct cros_ec_dev *ec_dev = priv->ec_dev; 258 + struct ec_event *event, *e; 259 + 260 + blocking_notifier_chain_unregister(&ec_dev->ec_dev->event_notifier, 261 + &priv->notifier); 262 + 263 + list_for_each_entry_safe(event, e, &priv->events, node) { 264 + list_del(&event->node); 265 + kfree(event); 266 + } 267 + kfree(priv); 268 + 269 + return 0; 270 + } 271 + 272 + /* 273 + * Ioctls 274 + */ 275 + static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg) 276 + { 277 + struct cros_ec_command *s_cmd; 278 + struct cros_ec_command u_cmd; 279 + long ret; 280 + 281 + if (copy_from_user(&u_cmd, arg, sizeof(u_cmd))) 282 + return -EFAULT; 283 + 284 + if (u_cmd.outsize > EC_MAX_MSG_BYTES || 285 + u_cmd.insize > EC_MAX_MSG_BYTES) 286 + return -EINVAL; 287 + 288 + s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), 289 + GFP_KERNEL); 290 + if (!s_cmd) 291 + return -ENOMEM; 292 + 293 + if (copy_from_user(s_cmd, arg, sizeof(*s_cmd) + u_cmd.outsize)) { 294 + ret = -EFAULT; 295 + goto exit; 296 + } 297 + 298 + if (u_cmd.outsize != s_cmd->outsize || 299 + u_cmd.insize != s_cmd->insize) { 300 + ret = -EINVAL; 301 + goto exit; 302 + } 303 + 304 + s_cmd->command += ec->cmd_offset; 305 + ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd); 306 + /* Only copy data to userland if data was received. */ 307 + if (ret < 0) 308 + goto exit; 309 + 310 + if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize)) 311 + ret = -EFAULT; 312 + exit: 313 + kfree(s_cmd); 314 + return ret; 315 + } 316 + 317 + static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec, 318 + void __user *arg) 319 + { 320 + struct cros_ec_device *ec_dev = ec->ec_dev; 321 + struct cros_ec_readmem s_mem = { }; 322 + long num; 323 + 324 + /* Not every platform supports direct reads */ 325 + if (!ec_dev->cmd_readmem) 326 + return -ENOTTY; 327 + 328 + if (copy_from_user(&s_mem, arg, sizeof(s_mem))) 329 + return -EFAULT; 330 + 331 + num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes, 332 + s_mem.buffer); 333 + if (num <= 0) 334 + return num; 335 + 336 + if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem))) 337 + return -EFAULT; 338 + 339 + return num; 340 + } 341 + 342 + static long cros_ec_chardev_ioctl(struct file *filp, unsigned int cmd, 343 + unsigned long arg) 344 + { 345 + struct chardev_priv *priv = filp->private_data; 346 + struct cros_ec_dev *ec = priv->ec_dev; 347 + 348 + if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC) 349 + return -ENOTTY; 350 + 351 + switch (cmd) { 352 + case CROS_EC_DEV_IOCXCMD: 353 + return cros_ec_chardev_ioctl_xcmd(ec, (void __user *)arg); 354 + case CROS_EC_DEV_IOCRDMEM: 355 + return cros_ec_chardev_ioctl_readmem(ec, (void __user *)arg); 356 + case CROS_EC_DEV_IOCEVENTMASK: 357 + priv->event_mask = arg; 358 + return 0; 359 + } 360 + 361 + return -ENOTTY; 362 + } 363 + 364 + static const struct file_operations chardev_fops = { 365 + .open = cros_ec_chardev_open, 366 + .poll = cros_ec_chardev_poll, 367 + .read = cros_ec_chardev_read, 368 + .release = cros_ec_chardev_release, 369 + .unlocked_ioctl = cros_ec_chardev_ioctl, 370 + #ifdef CONFIG_COMPAT 371 + .compat_ioctl = cros_ec_chardev_ioctl, 372 + #endif 373 + }; 374 + 375 + static int cros_ec_chardev_probe(struct platform_device *pdev) 376 + { 377 + struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent); 378 + struct cros_ec_platform *ec_platform = dev_get_platdata(ec_dev->dev); 379 + struct chardev_data *data; 380 + 381 + /* Create a char device: we want to create it anew */ 382 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 383 + if (!data) 384 + return -ENOMEM; 385 + 386 + data->ec_dev = ec_dev; 387 + data->misc.minor = MISC_DYNAMIC_MINOR; 388 + data->misc.fops = &chardev_fops; 389 + data->misc.name = ec_platform->ec_name; 390 + data->misc.parent = pdev->dev.parent; 391 + 392 + dev_set_drvdata(&pdev->dev, data); 393 + 394 + return misc_register(&data->misc); 395 + } 396 + 397 + static int cros_ec_chardev_remove(struct platform_device *pdev) 398 + { 399 + struct chardev_data *data = dev_get_drvdata(&pdev->dev); 400 + 401 + misc_deregister(&data->misc); 402 + 403 + return 0; 404 + } 405 + 406 + static struct platform_driver cros_ec_chardev_driver = { 407 + .driver = { 408 + .name = DRV_NAME, 409 + }, 410 + .probe = cros_ec_chardev_probe, 411 + .remove = cros_ec_chardev_remove, 412 + }; 413 + 414 + module_platform_driver(cros_ec_chardev_driver); 415 + 416 + MODULE_ALIAS("platform:" DRV_NAME); 417 + MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>"); 418 + MODULE_DESCRIPTION("ChromeOS EC Miscellaneous Character Driver"); 419 + MODULE_LICENSE("GPL");
+2 -1
drivers/platform/chrome/cros_ec_debugfs.c
··· 8 8 #include <linux/delay.h> 9 9 #include <linux/fs.h> 10 10 #include <linux/mfd/cros_ec.h> 11 - #include <linux/mfd/cros_ec_commands.h> 12 11 #include <linux/module.h> 13 12 #include <linux/mutex.h> 13 + #include <linux/platform_data/cros_ec_commands.h> 14 + #include <linux/platform_data/cros_ec_proto.h> 14 15 #include <linux/platform_device.h> 15 16 #include <linux/poll.h> 16 17 #include <linux/sched.h>
+10 -2
drivers/platform/chrome/cros_ec_i2c.c
··· 9 9 #include <linux/module.h> 10 10 #include <linux/i2c.h> 11 11 #include <linux/interrupt.h> 12 - #include <linux/mfd/cros_ec.h> 13 - #include <linux/mfd/cros_ec_commands.h> 12 + #include <linux/platform_data/cros_ec_commands.h> 13 + #include <linux/platform_data/cros_ec_proto.h> 14 14 #include <linux/platform_device.h> 15 15 #include <linux/slab.h> 16 16 ··· 307 307 return 0; 308 308 } 309 309 310 + static int cros_ec_i2c_remove(struct i2c_client *client) 311 + { 312 + struct cros_ec_device *ec_dev = i2c_get_clientdata(client); 313 + 314 + return cros_ec_unregister(ec_dev); 315 + } 316 + 310 317 #ifdef CONFIG_PM_SLEEP 311 318 static int cros_ec_i2c_suspend(struct device *dev) 312 319 { ··· 364 357 .pm = &cros_ec_i2c_pm_ops, 365 358 }, 366 359 .probe = cros_ec_i2c_probe, 360 + .remove = cros_ec_i2c_remove, 367 361 .id_table = cros_ec_i2c_id, 368 362 }; 369 363
+2 -3
drivers/platform/chrome/cros_ec_ishtp.c
··· 8 8 // (ISH-TP). 9 9 10 10 #include <linux/delay.h> 11 - #include <linux/mfd/core.h> 12 - #include <linux/mfd/cros_ec.h> 13 - #include <linux/mfd/cros_ec_commands.h> 14 11 #include <linux/module.h> 15 12 #include <linux/pci.h> 13 + #include <linux/platform_data/cros_ec_commands.h> 14 + #include <linux/platform_data/cros_ec_proto.h> 16 15 #include <linux/intel-ish-client-if.h> 17 16 18 17 /*
+2 -1
drivers/platform/chrome/cros_ec_lightbar.c
··· 9 9 #include <linux/fs.h> 10 10 #include <linux/kobject.h> 11 11 #include <linux/mfd/cros_ec.h> 12 - #include <linux/mfd/cros_ec_commands.h> 13 12 #include <linux/module.h> 13 + #include <linux/platform_data/cros_ec_commands.h> 14 + #include <linux/platform_data/cros_ec_proto.h> 14 15 #include <linux/platform_device.h> 15 16 #include <linux/sched.h> 16 17 #include <linux/types.h>
+4 -3
drivers/platform/chrome/cros_ec_lpc.c
··· 16 16 #include <linux/delay.h> 17 17 #include <linux/io.h> 18 18 #include <linux/interrupt.h> 19 - #include <linux/mfd/cros_ec.h> 20 - #include <linux/mfd/cros_ec_commands.h> 21 19 #include <linux/module.h> 20 + #include <linux/platform_data/cros_ec_commands.h> 21 + #include <linux/platform_data/cros_ec_proto.h> 22 22 #include <linux/platform_device.h> 23 23 #include <linux/printk.h> 24 24 #include <linux/suspend.h> ··· 421 421 422 422 static int cros_ec_lpc_remove(struct platform_device *pdev) 423 423 { 424 + struct cros_ec_device *ec_dev = platform_get_drvdata(pdev); 424 425 struct acpi_device *adev; 425 426 426 427 adev = ACPI_COMPANION(&pdev->dev); ··· 429 428 acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY, 430 429 cros_ec_lpc_acpi_notify); 431 430 432 - return 0; 431 + return cros_ec_unregister(ec_dev); 433 432 } 434 433 435 434 static const struct acpi_device_id cros_ec_lpc_acpi_device_ids[] = {
+2 -1
drivers/platform/chrome/cros_ec_proto.c
··· 3 3 // 4 4 // Copyright (C) 2015 Google, Inc 5 5 6 - #include <linux/mfd/cros_ec.h> 7 6 #include <linux/delay.h> 8 7 #include <linux/device.h> 9 8 #include <linux/module.h> 9 + #include <linux/platform_data/cros_ec_commands.h> 10 + #include <linux/platform_data/cros_ec_proto.h> 10 11 #include <linux/slab.h> 11 12 #include <asm/unaligned.h> 12 13
+51 -6
drivers/platform/chrome/cros_ec_rpmsg.c
··· 6 6 #include <linux/delay.h> 7 7 #include <linux/kernel.h> 8 8 #include <linux/module.h> 9 - #include <linux/mfd/cros_ec.h> 10 - #include <linux/mfd/cros_ec_commands.h> 11 9 #include <linux/of.h> 10 + #include <linux/platform_data/cros_ec_commands.h> 11 + #include <linux/platform_data/cros_ec_proto.h> 12 12 #include <linux/platform_device.h> 13 13 #include <linux/rpmsg.h> 14 14 #include <linux/slab.h> ··· 41 41 struct rpmsg_device *rpdev; 42 42 struct completion xfer_ack; 43 43 struct work_struct host_event_work; 44 + struct rpmsg_endpoint *ept; 44 45 }; 45 46 46 47 /** ··· 73 72 struct cros_ec_command *ec_msg) 74 73 { 75 74 struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv; 76 - struct rpmsg_device *rpdev = ec_rpmsg->rpdev; 77 75 struct ec_host_response *response; 78 76 unsigned long timeout; 79 77 int len; ··· 85 85 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); 86 86 87 87 reinit_completion(&ec_rpmsg->xfer_ack); 88 - ret = rpmsg_send(rpdev->ept, ec_dev->dout, len); 88 + ret = rpmsg_send(ec_rpmsg->ept, ec_dev->dout, len); 89 89 if (ret) { 90 90 dev_err(ec_dev->dev, "rpmsg send failed\n"); 91 91 return ret; ··· 196 196 return 0; 197 197 } 198 198 199 + static struct rpmsg_endpoint * 200 + cros_ec_rpmsg_create_ept(struct rpmsg_device *rpdev) 201 + { 202 + struct rpmsg_channel_info chinfo = {}; 203 + 204 + strscpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE); 205 + chinfo.src = rpdev->src; 206 + chinfo.dst = RPMSG_ADDR_ANY; 207 + 208 + return rpmsg_create_ept(rpdev, cros_ec_rpmsg_callback, NULL, chinfo); 209 + } 210 + 199 211 static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev) 200 212 { 201 213 struct device *dev = &rpdev->dev; 202 214 struct cros_ec_rpmsg *ec_rpmsg; 203 215 struct cros_ec_device *ec_dev; 216 + int ret; 204 217 205 218 ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); 206 219 if (!ec_dev) ··· 238 225 INIT_WORK(&ec_rpmsg->host_event_work, 239 226 cros_ec_rpmsg_host_event_function); 240 227 241 - return cros_ec_register(ec_dev); 228 + ec_rpmsg->ept = cros_ec_rpmsg_create_ept(rpdev); 229 + if (!ec_rpmsg->ept) 230 + return -ENOMEM; 231 + 232 + ret = cros_ec_register(ec_dev); 233 + if (ret < 0) { 234 + rpmsg_destroy_ept(ec_rpmsg->ept); 235 + cancel_work_sync(&ec_rpmsg->host_event_work); 236 + return ret; 237 + } 238 + 239 + return 0; 242 240 } 243 241 244 242 static void cros_ec_rpmsg_remove(struct rpmsg_device *rpdev) ··· 257 233 struct cros_ec_device *ec_dev = dev_get_drvdata(&rpdev->dev); 258 234 struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv; 259 235 236 + cros_ec_unregister(ec_dev); 237 + rpmsg_destroy_ept(ec_rpmsg->ept); 260 238 cancel_work_sync(&ec_rpmsg->host_event_work); 261 239 } 240 + 241 + #ifdef CONFIG_PM_SLEEP 242 + static int cros_ec_rpmsg_suspend(struct device *dev) 243 + { 244 + struct cros_ec_device *ec_dev = dev_get_drvdata(dev); 245 + 246 + return cros_ec_suspend(ec_dev); 247 + } 248 + 249 + static int cros_ec_rpmsg_resume(struct device *dev) 250 + { 251 + struct cros_ec_device *ec_dev = dev_get_drvdata(dev); 252 + 253 + return cros_ec_resume(ec_dev); 254 + } 255 + #endif 256 + 257 + static SIMPLE_DEV_PM_OPS(cros_ec_rpmsg_pm_ops, cros_ec_rpmsg_suspend, 258 + cros_ec_rpmsg_resume); 262 259 263 260 static const struct of_device_id cros_ec_rpmsg_of_match[] = { 264 261 { .compatible = "google,cros-ec-rpmsg", }, ··· 291 246 .drv = { 292 247 .name = "cros-ec-rpmsg", 293 248 .of_match_table = cros_ec_rpmsg_of_match, 249 + .pm = &cros_ec_rpmsg_pm_ops, 294 250 }, 295 251 .probe = cros_ec_rpmsg_probe, 296 252 .remove = cros_ec_rpmsg_remove, 297 - .callback = cros_ec_rpmsg_callback, 298 253 }; 299 254 300 255 module_rpmsg_driver(cros_ec_driver_rpmsg);
+10 -2
drivers/platform/chrome/cros_ec_spi.c
··· 6 6 #include <linux/delay.h> 7 7 #include <linux/kernel.h> 8 8 #include <linux/module.h> 9 - #include <linux/mfd/cros_ec.h> 10 - #include <linux/mfd/cros_ec_commands.h> 11 9 #include <linux/of.h> 10 + #include <linux/platform_data/cros_ec_commands.h> 11 + #include <linux/platform_data/cros_ec_proto.h> 12 12 #include <linux/platform_device.h> 13 13 #include <linux/slab.h> 14 14 #include <linux/spi/spi.h> ··· 785 785 return 0; 786 786 } 787 787 788 + static int cros_ec_spi_remove(struct spi_device *spi) 789 + { 790 + struct cros_ec_device *ec_dev = spi_get_drvdata(spi); 791 + 792 + return cros_ec_unregister(ec_dev); 793 + } 794 + 788 795 #ifdef CONFIG_PM_SLEEP 789 796 static int cros_ec_spi_suspend(struct device *dev) 790 797 { ··· 830 823 .pm = &cros_ec_spi_pm_ops, 831 824 }, 832 825 .probe = cros_ec_spi_probe, 826 + .remove = cros_ec_spi_remove, 833 827 .id_table = cros_ec_spi_id, 834 828 }; 835 829
+2 -1
drivers/platform/chrome/cros_ec_sysfs.c
··· 9 9 #include <linux/fs.h> 10 10 #include <linux/kobject.h> 11 11 #include <linux/mfd/cros_ec.h> 12 - #include <linux/mfd/cros_ec_commands.h> 13 12 #include <linux/module.h> 13 + #include <linux/platform_data/cros_ec_commands.h> 14 + #include <linux/platform_data/cros_ec_proto.h> 14 15 #include <linux/platform_device.h> 15 16 #include <linux/printk.h> 16 17 #include <linux/slab.h>
+1 -1
drivers/platform/chrome/cros_ec_trace.c
··· 6 6 #define TRACE_SYMBOL(a) {a, #a} 7 7 8 8 // Generate the list using the following script: 9 - // sed -n 's/^#define \(EC_CMD_[[:alnum:]_]*\)\s.*/\tTRACE_SYMBOL(\1), \\/p' include/linux/mfd/cros_ec_commands.h 9 + // sed -n 's/^#define \(EC_CMD_[[:alnum:]_]*\)\s.*/\tTRACE_SYMBOL(\1), \\/p' include/linux/platform_data/cros_ec_commands.h 10 10 #define EC_CMDS \ 11 11 TRACE_SYMBOL(EC_CMD_PROTO_VERSION), \ 12 12 TRACE_SYMBOL(EC_CMD_HELLO), \
+3 -1
drivers/platform/chrome/cros_ec_trace.h
··· 11 11 #if !defined(_CROS_EC_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) 12 12 #define _CROS_EC_TRACE_H_ 13 13 14 + #include <linux/bits.h> 14 15 #include <linux/types.h> 15 - #include <linux/mfd/cros_ec.h> 16 + #include <linux/platform_data/cros_ec_commands.h> 17 + #include <linux/platform_data/cros_ec_proto.h> 16 18 17 19 #include <linux/tracepoint.h> 18 20
+2 -1
drivers/platform/chrome/cros_ec_vbc.c
··· 7 7 #include <linux/of.h> 8 8 #include <linux/platform_device.h> 9 9 #include <linux/mfd/cros_ec.h> 10 - #include <linux/mfd/cros_ec_commands.h> 11 10 #include <linux/module.h> 11 + #include <linux/platform_data/cros_ec_commands.h> 12 + #include <linux/platform_data/cros_ec_proto.h> 12 13 #include <linux/slab.h> 13 14 14 15 #define DRV_NAME "cros-ec-vbc"
+6 -2
drivers/platform/chrome/cros_usbpd_logger.c
··· 6 6 */ 7 7 8 8 #include <linux/ktime.h> 9 - #include <linux/math64.h> 10 9 #include <linux/mfd/cros_ec.h> 11 - #include <linux/mfd/cros_ec_commands.h> 10 + #include <linux/math64.h> 12 11 #include <linux/module.h> 12 + #include <linux/platform_data/cros_ec_commands.h> 13 + #include <linux/platform_data/cros_ec_proto.h> 13 14 #include <linux/platform_device.h> 14 15 #include <linux/rtc.h> 15 16 ··· 210 209 /* Retrieve PD event logs periodically */ 211 210 INIT_DELAYED_WORK(&logger->log_work, cros_usbpd_log_check); 212 211 logger->log_workqueue = create_singlethread_workqueue("cros_usbpd_log"); 212 + if (!logger->log_workqueue) 213 + return -ENOMEM; 214 + 213 215 queue_delayed_work(logger->log_workqueue, &logger->log_work, 214 216 CROS_USBPD_LOG_UPDATE_DELAY); 215 217
+43 -21
drivers/platform/chrome/wilco_ec/telemetry.c
··· 9 9 * the OS sends a command to the EC via a write() to a char device, 10 10 * and can read the response with a read(). The write() request is 11 11 * verified by the driver to ensure that it is performing only one 12 - * of the whitelisted commands, and that no extraneous data is 12 + * of the allowlisted commands, and that no extraneous data is 13 13 * being transmitted to the EC. The response is passed directly 14 14 * back to the reader with no modification. 15 15 * ··· 59 59 #define WILCO_EC_TELEM_GET_TEMP_INFO 0x95 60 60 #define WILCO_EC_TELEM_GET_TEMP_READ 0x2C 61 61 #define WILCO_EC_TELEM_GET_BATT_EXT_INFO 0x07 62 + #define WILCO_EC_TELEM_GET_BATT_PPID_INFO 0x8A 62 63 63 64 #define TELEM_ARGS_SIZE_MAX 30 64 - 65 - /** 66 - * struct wilco_ec_telem_request - Telemetry command and arguments sent to EC. 67 - * @command: One of WILCO_EC_TELEM_GET_* command codes. 68 - * @reserved: Must be 0. 69 - * @args: The first N bytes are one of telem_args_get_* structs, the rest is 0. 70 - */ 71 - struct wilco_ec_telem_request { 72 - u8 command; 73 - u8 reserved; 74 - u8 args[TELEM_ARGS_SIZE_MAX]; 75 - } __packed; 76 65 77 66 /* 78 67 * The following telem_args_get_* structs are embedded within the |args| field ··· 111 122 u8 var_args[5]; 112 123 } __packed; 113 124 125 + struct telem_args_get_batt_ppid_info { 126 + u8 always1; /* Should always be 1 */ 127 + } __packed; 128 + 129 + /** 130 + * struct wilco_ec_telem_request - Telemetry command and arguments sent to EC. 131 + * @command: One of WILCO_EC_TELEM_GET_* command codes. 132 + * @reserved: Must be 0. 133 + * @args: The first N bytes are one of telem_args_get_* structs, the rest is 0. 134 + */ 135 + struct wilco_ec_telem_request { 136 + u8 command; 137 + u8 reserved; 138 + union { 139 + u8 buf[TELEM_ARGS_SIZE_MAX]; 140 + struct telem_args_get_log get_log; 141 + struct telem_args_get_version get_version; 142 + struct telem_args_get_fan_info get_fan_info; 143 + struct telem_args_get_diag_info get_diag_info; 144 + struct telem_args_get_temp_info get_temp_info; 145 + struct telem_args_get_temp_read get_temp_read; 146 + struct telem_args_get_batt_ext_info get_batt_ext_info; 147 + struct telem_args_get_batt_ppid_info get_batt_ppid_info; 148 + } args; 149 + } __packed; 150 + 114 151 /** 115 152 * check_telem_request() - Ensure that a request from userspace is valid. 116 153 * @rq: Request buffer copied from userspace. ··· 148 133 * We do not want to allow userspace to send arbitrary telemetry commands to 149 134 * the EC. Therefore we check to ensure that 150 135 * 1. The request follows the format of struct wilco_ec_telem_request. 151 - * 2. The supplied command code is one of the whitelisted commands. 136 + * 2. The supplied command code is one of the allowlisted commands. 152 137 * 3. The request only contains the necessary data for the header and arguments. 153 138 */ 154 139 static int check_telem_request(struct wilco_ec_telem_request *rq, ··· 161 146 162 147 switch (rq->command) { 163 148 case WILCO_EC_TELEM_GET_LOG: 164 - max_size += sizeof(struct telem_args_get_log); 149 + max_size += sizeof(rq->args.get_log); 165 150 break; 166 151 case WILCO_EC_TELEM_GET_VERSION: 167 - max_size += sizeof(struct telem_args_get_version); 152 + max_size += sizeof(rq->args.get_version); 168 153 break; 169 154 case WILCO_EC_TELEM_GET_FAN_INFO: 170 - max_size += sizeof(struct telem_args_get_fan_info); 155 + max_size += sizeof(rq->args.get_fan_info); 171 156 break; 172 157 case WILCO_EC_TELEM_GET_DIAG_INFO: 173 - max_size += sizeof(struct telem_args_get_diag_info); 158 + max_size += sizeof(rq->args.get_diag_info); 174 159 break; 175 160 case WILCO_EC_TELEM_GET_TEMP_INFO: 176 - max_size += sizeof(struct telem_args_get_temp_info); 161 + max_size += sizeof(rq->args.get_temp_info); 177 162 break; 178 163 case WILCO_EC_TELEM_GET_TEMP_READ: 179 - max_size += sizeof(struct telem_args_get_temp_read); 164 + max_size += sizeof(rq->args.get_temp_read); 180 165 break; 181 166 case WILCO_EC_TELEM_GET_BATT_EXT_INFO: 182 - max_size += sizeof(struct telem_args_get_batt_ext_info); 167 + max_size += sizeof(rq->args.get_batt_ext_info); 168 + break; 169 + case WILCO_EC_TELEM_GET_BATT_PPID_INFO: 170 + if (rq->args.get_batt_ppid_info.always1 != 1) 171 + return -EINVAL; 172 + 173 + max_size += sizeof(rq->args.get_batt_ppid_info); 183 174 break; 184 175 default: 185 176 return -EINVAL; ··· 271 250 272 251 if (count > sizeof(sess_data->request)) 273 252 return -EMSGSIZE; 253 + memset(&sess_data->request, 0, sizeof(sess_data->request)); 274 254 if (copy_from_user(&sess_data->request, buf, count)) 275 255 return -EFAULT; 276 256 ret = check_telem_request(&sess_data->request, count);
+1 -1
drivers/power/supply/Kconfig
··· 670 670 671 671 config CHARGER_CROS_USBPD 672 672 tristate "ChromeOS EC based USBPD charger" 673 - depends on MFD_CROS_EC 673 + depends on CROS_EC 674 674 default n 675 675 help 676 676 Say Y here to enable ChromeOS EC based USBPD charger
+3 -2
drivers/power/supply/cros_usbpd-charger.c
··· 5 5 * Copyright (c) 2014 - 2018 Google, Inc 6 6 */ 7 7 8 - #include <linux/module.h> 9 8 #include <linux/mfd/cros_ec.h> 10 - #include <linux/mfd/cros_ec_commands.h> 9 + #include <linux/module.h> 10 + #include <linux/platform_data/cros_ec_commands.h> 11 + #include <linux/platform_data/cros_ec_proto.h> 11 12 #include <linux/platform_device.h> 12 13 #include <linux/power_supply.h> 13 14 #include <linux/slab.h>
+1 -1
drivers/pwm/Kconfig
··· 145 145 146 146 config PWM_CROS_EC 147 147 tristate "ChromeOS EC PWM driver" 148 - depends on MFD_CROS_EC 148 + depends on CROS_EC 149 149 help 150 150 PWM driver for exposing a PWM attached to the ChromeOS Embedded 151 151 Controller.
+2 -2
drivers/pwm/pwm-cros-ec.c
··· 6 6 */ 7 7 8 8 #include <linux/module.h> 9 - #include <linux/mfd/cros_ec.h> 10 - #include <linux/mfd/cros_ec_commands.h> 9 + #include <linux/platform_data/cros_ec_commands.h> 10 + #include <linux/platform_data/cros_ec_proto.h> 11 11 #include <linux/platform_device.h> 12 12 #include <linux/pwm.h> 13 13 #include <linux/slab.h>
+1 -1
drivers/rtc/Kconfig
··· 1274 1274 1275 1275 config RTC_DRV_CROS_EC 1276 1276 tristate "Chrome OS EC RTC driver" 1277 - depends on MFD_CROS_EC 1277 + depends on CROS_EC 1278 1278 help 1279 1279 If you say yes here you will get support for the 1280 1280 Chrome OS Embedded Controller's RTC.
+2 -1
drivers/rtc/rtc-cros-ec.c
··· 6 6 7 7 #include <linux/kernel.h> 8 8 #include <linux/mfd/cros_ec.h> 9 - #include <linux/mfd/cros_ec_commands.h> 10 9 #include <linux/module.h> 10 + #include <linux/platform_data/cros_ec_commands.h> 11 + #include <linux/platform_data/cros_ec_proto.h> 11 12 #include <linux/platform_device.h> 12 13 #include <linux/rtc.h> 13 14 #include <linux/slab.h>
+1 -1
include/Kbuild
··· 310 310 header-test- += linux/mfd/arizona/pdata.h 311 311 header-test- += linux/mfd/as3711.h 312 312 header-test- += linux/mfd/as3722.h 313 - header-test- += linux/mfd/cros_ec_commands.h 314 313 header-test- += linux/mfd/da903x.h 315 314 header-test- += linux/mfd/da9055/pdata.h 316 315 header-test- += linux/mfd/da9063/pdata.h ··· 454 455 header-test- += linux/platform_data/atmel.h 455 456 header-test- += linux/platform_data/bh1770glc.h 456 457 header-test- += linux/platform_data/brcmfmac.h 458 + header-test- += linux/platform_data/cros_ec_commands.h 457 459 header-test- += linux/platform_data/clk-u300.h 458 460 header-test- += linux/platform_data/cyttsp4.h 459 461 header-test- += linux/platform_data/dma-coh901318.h
+2 -1
include/linux/iio/common/cros_ec_sensors_core.h
··· 10 10 11 11 #include <linux/iio/iio.h> 12 12 #include <linux/irqreturn.h> 13 - #include <linux/mfd/cros_ec.h> 13 + #include <linux/platform_data/cros_ec_commands.h> 14 + #include <linux/platform_data/cros_ec_proto.h> 14 15 15 16 enum { 16 17 CROS_EC_SENSOR_X,
-292
include/linux/mfd/cros_ec.h
··· 8 8 #ifndef __LINUX_MFD_CROS_EC_H 9 9 #define __LINUX_MFD_CROS_EC_H 10 10 11 - #include <linux/cdev.h> 12 11 #include <linux/device.h> 13 - #include <linux/notifier.h> 14 - #include <linux/mfd/cros_ec_commands.h> 15 - #include <linux/mutex.h> 16 - 17 - #define CROS_EC_DEV_NAME "cros_ec" 18 - #define CROS_EC_DEV_FP_NAME "cros_fp" 19 - #define CROS_EC_DEV_PD_NAME "cros_pd" 20 - #define CROS_EC_DEV_TP_NAME "cros_tp" 21 - #define CROS_EC_DEV_ISH_NAME "cros_ish" 22 - #define CROS_EC_DEV_SCP_NAME "cros_scp" 23 - 24 - /* 25 - * The EC is unresponsive for a time after a reboot command. Add a 26 - * simple delay to make sure that the bus stays locked. 27 - */ 28 - #define EC_REBOOT_DELAY_MS 50 29 - 30 - /* 31 - * Max bus-specific overhead incurred by request/responses. 32 - * I2C requires 1 additional byte for requests. 33 - * I2C requires 2 additional bytes for responses. 34 - * SPI requires up to 32 additional bytes for responses. 35 - */ 36 - #define EC_PROTO_VERSION_UNKNOWN 0 37 - #define EC_MAX_REQUEST_OVERHEAD 1 38 - #define EC_MAX_RESPONSE_OVERHEAD 32 39 - 40 - /* 41 - * Command interface between EC and AP, for LPC, I2C and SPI interfaces. 42 - */ 43 - enum { 44 - EC_MSG_TX_HEADER_BYTES = 3, 45 - EC_MSG_TX_TRAILER_BYTES = 1, 46 - EC_MSG_TX_PROTO_BYTES = EC_MSG_TX_HEADER_BYTES + 47 - EC_MSG_TX_TRAILER_BYTES, 48 - EC_MSG_RX_PROTO_BYTES = 3, 49 - 50 - /* Max length of messages for proto 2*/ 51 - EC_PROTO2_MSG_BYTES = EC_PROTO2_MAX_PARAM_SIZE + 52 - EC_MSG_TX_PROTO_BYTES, 53 - 54 - EC_MAX_MSG_BYTES = 64 * 1024, 55 - }; 56 - 57 - /** 58 - * struct cros_ec_command - Information about a ChromeOS EC command. 59 - * @version: Command version number (often 0). 60 - * @command: Command to send (EC_CMD_...). 61 - * @outsize: Outgoing length in bytes. 62 - * @insize: Max number of bytes to accept from the EC. 63 - * @result: EC's response to the command (separate from communication failure). 64 - * @data: Where to put the incoming data from EC and outgoing data to EC. 65 - */ 66 - struct cros_ec_command { 67 - uint32_t version; 68 - uint32_t command; 69 - uint32_t outsize; 70 - uint32_t insize; 71 - uint32_t result; 72 - uint8_t data[0]; 73 - }; 74 - 75 - /** 76 - * struct cros_ec_device - Information about a ChromeOS EC device. 77 - * @phys_name: Name of physical comms layer (e.g. 'i2c-4'). 78 - * @dev: Device pointer for physical comms device 79 - * @was_wake_device: True if this device was set to wake the system from 80 - * sleep at the last suspend. 81 - * @cros_class: The class structure for this device. 82 - * @cmd_readmem: Direct read of the EC memory-mapped region, if supported. 83 - * @offset: Is within EC_LPC_ADDR_MEMMAP region. 84 - * @bytes: Number of bytes to read. zero means "read a string" (including 85 - * the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be 86 - * read. Caller must ensure that the buffer is large enough for the 87 - * result when reading a string. 88 - * @max_request: Max size of message requested. 89 - * @max_response: Max size of message response. 90 - * @max_passthru: Max sice of passthru message. 91 - * @proto_version: The protocol version used for this device. 92 - * @priv: Private data. 93 - * @irq: Interrupt to use. 94 - * @id: Device id. 95 - * @din: Input buffer (for data from EC). This buffer will always be 96 - * dword-aligned and include enough space for up to 7 word-alignment 97 - * bytes also, so we can ensure that the body of the message is always 98 - * dword-aligned (64-bit). We use this alignment to keep ARM and x86 99 - * happy. Probably word alignment would be OK, there might be a small 100 - * performance advantage to using dword. 101 - * @dout: Output buffer (for data to EC). This buffer will always be 102 - * dword-aligned and include enough space for up to 7 word-alignment 103 - * bytes also, so we can ensure that the body of the message is always 104 - * dword-aligned (64-bit). We use this alignment to keep ARM and x86 105 - * happy. Probably word alignment would be OK, there might be a small 106 - * performance advantage to using dword. 107 - * @din_size: Size of din buffer to allocate (zero to use static din). 108 - * @dout_size: Size of dout buffer to allocate (zero to use static dout). 109 - * @wake_enabled: True if this device can wake the system from sleep. 110 - * @suspended: True if this device had been suspended. 111 - * @cmd_xfer: Send command to EC and get response. 112 - * Returns the number of bytes received if the communication 113 - * succeeded, but that doesn't mean the EC was happy with the 114 - * command. The caller should check msg.result for the EC's result 115 - * code. 116 - * @pkt_xfer: Send packet to EC and get response. 117 - * @lock: One transaction at a time. 118 - * @mkbp_event_supported: True if this EC supports the MKBP event protocol. 119 - * @host_sleep_v1: True if this EC supports the sleep v1 command. 120 - * @event_notifier: Interrupt event notifier for transport devices. 121 - * @event_data: Raw payload transferred with the MKBP event. 122 - * @event_size: Size in bytes of the event data. 123 - * @host_event_wake_mask: Mask of host events that cause wake from suspend. 124 - */ 125 - struct cros_ec_device { 126 - /* These are used by other drivers that want to talk to the EC */ 127 - const char *phys_name; 128 - struct device *dev; 129 - bool was_wake_device; 130 - struct class *cros_class; 131 - int (*cmd_readmem)(struct cros_ec_device *ec, unsigned int offset, 132 - unsigned int bytes, void *dest); 133 - 134 - /* These are used to implement the platform-specific interface */ 135 - u16 max_request; 136 - u16 max_response; 137 - u16 max_passthru; 138 - u16 proto_version; 139 - void *priv; 140 - int irq; 141 - u8 *din; 142 - u8 *dout; 143 - int din_size; 144 - int dout_size; 145 - bool wake_enabled; 146 - bool suspended; 147 - int (*cmd_xfer)(struct cros_ec_device *ec, 148 - struct cros_ec_command *msg); 149 - int (*pkt_xfer)(struct cros_ec_device *ec, 150 - struct cros_ec_command *msg); 151 - struct mutex lock; 152 - bool mkbp_event_supported; 153 - bool host_sleep_v1; 154 - struct blocking_notifier_head event_notifier; 155 - 156 - struct ec_response_get_next_event_v1 event_data; 157 - int event_size; 158 - u32 host_event_wake_mask; 159 - u32 last_resume_result; 160 - }; 161 - 162 - /** 163 - * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information. 164 - * @sensor_num: Id of the sensor, as reported by the EC. 165 - */ 166 - struct cros_ec_sensor_platform { 167 - u8 sensor_num; 168 - }; 169 - 170 - /** 171 - * struct cros_ec_platform - ChromeOS EC platform information. 172 - * @ec_name: Name of EC device (e.g. 'cros-ec', 'cros-pd', ...) 173 - * used in /dev/ and sysfs. 174 - * @cmd_offset: Offset to apply for each command. Set when 175 - * registering a device behind another one. 176 - */ 177 - struct cros_ec_platform { 178 - const char *ec_name; 179 - u16 cmd_offset; 180 - }; 181 - 182 - struct cros_ec_debugfs; 183 12 184 13 /** 185 14 * struct cros_ec_dev - ChromeOS EC device entry point. 186 15 * @class_dev: Device structure used in sysfs. 187 - * @cdev: Character device structure in /dev. 188 16 * @ec_dev: cros_ec_device structure to talk to the physical device. 189 17 * @dev: Pointer to the platform device. 190 18 * @debug_info: cros_ec_debugfs structure for debugging information. ··· 22 194 */ 23 195 struct cros_ec_dev { 24 196 struct device class_dev; 25 - struct cdev cdev; 26 197 struct cros_ec_device *ec_dev; 27 198 struct device *dev; 28 199 struct cros_ec_debugfs *debug_info; ··· 31 204 }; 32 205 33 206 #define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev) 34 - 35 - /** 36 - * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. 37 - * @ec_dev: Device to suspend. 38 - * 39 - * This can be called by drivers to handle a suspend event. 40 - * 41 - * Return: 0 on success or negative error code. 42 - */ 43 - int cros_ec_suspend(struct cros_ec_device *ec_dev); 44 - 45 - /** 46 - * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. 47 - * @ec_dev: Device to resume. 48 - * 49 - * This can be called by drivers to handle a resume event. 50 - * 51 - * Return: 0 on success or negative error code. 52 - */ 53 - int cros_ec_resume(struct cros_ec_device *ec_dev); 54 - 55 - /** 56 - * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer. 57 - * @ec_dev: Device to register. 58 - * @msg: Message to write. 59 - * 60 - * This is intended to be used by all ChromeOS EC drivers, but at present 61 - * only SPI uses it. Once LPC uses the same protocol it can start using it. 62 - * I2C could use it now, with a refactor of the existing code. 63 - * 64 - * Return: 0 on success or negative error code. 65 - */ 66 - int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, 67 - struct cros_ec_command *msg); 68 - 69 - /** 70 - * cros_ec_check_result() - Check ec_msg->result. 71 - * @ec_dev: EC device. 72 - * @msg: Message to check. 73 - * 74 - * This is used by ChromeOS EC drivers to check the ec_msg->result for 75 - * errors and to warn about them. 76 - * 77 - * Return: 0 on success or negative error code. 78 - */ 79 - int cros_ec_check_result(struct cros_ec_device *ec_dev, 80 - struct cros_ec_command *msg); 81 - 82 - /** 83 - * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC. 84 - * @ec_dev: EC device. 85 - * @msg: Message to write. 86 - * 87 - * Call this to send a command to the ChromeOS EC. This should be used 88 - * instead of calling the EC's cmd_xfer() callback directly. 89 - * 90 - * Return: 0 on success or negative error code. 91 - */ 92 - int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, 93 - struct cros_ec_command *msg); 94 - 95 - /** 96 - * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. 97 - * @ec_dev: EC device. 98 - * @msg: Message to write. 99 - * 100 - * This function is identical to cros_ec_cmd_xfer, except it returns success 101 - * status only if both the command was transmitted successfully and the EC 102 - * replied with success status. It's not necessary to check msg->result when 103 - * using this function. 104 - * 105 - * Return: The number of bytes transferred on success or negative error code. 106 - */ 107 - int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, 108 - struct cros_ec_command *msg); 109 - 110 - /** 111 - * cros_ec_register() - Register a new ChromeOS EC, using the provided info. 112 - * @ec_dev: Device to register. 113 - * 114 - * Before calling this, allocate a pointer to a new device and then fill 115 - * in all the fields up to the --private-- marker. 116 - * 117 - * Return: 0 on success or negative error code. 118 - */ 119 - int cros_ec_register(struct cros_ec_device *ec_dev); 120 - 121 - /** 122 - * cros_ec_query_all() - Query the protocol version supported by the 123 - * ChromeOS EC. 124 - * @ec_dev: Device to register. 125 - * 126 - * Return: 0 on success or negative error code. 127 - */ 128 - int cros_ec_query_all(struct cros_ec_device *ec_dev); 129 - 130 - /** 131 - * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC. 132 - * @ec_dev: Device to fetch event from. 133 - * @wake_event: Pointer to a bool set to true upon return if the event might be 134 - * treated as a wake event. Ignored if null. 135 - * 136 - * Return: negative error code on errors; 0 for no data; or else number of 137 - * bytes received (i.e., an event was retrieved successfully). Event types are 138 - * written out to @ec_dev->event_data.event_type on success. 139 - */ 140 - int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event); 141 - 142 - /** 143 - * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC. 144 - * @ec_dev: Device to fetch event from. 145 - * 146 - * When MKBP is supported, when the EC raises an interrupt, we collect the 147 - * events raised and call the functions in the ec notifier. This function 148 - * is a helper to know which events are raised. 149 - * 150 - * Return: 0 on error or non-zero bitmask of one or more EC_HOST_EVENT_*. 151 - */ 152 - u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); 153 207 154 208 #endif /* __LINUX_MFD_CROS_EC_H */
include/linux/mfd/cros_ec_commands.h include/linux/platform_data/cros_ec_commands.h
+319
include/linux/platform_data/cros_ec_proto.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * ChromeOS Embedded Controller protocol interface. 4 + * 5 + * Copyright (C) 2012 Google, Inc 6 + */ 7 + 8 + #ifndef __LINUX_CROS_EC_PROTO_H 9 + #define __LINUX_CROS_EC_PROTO_H 10 + 11 + #include <linux/device.h> 12 + #include <linux/mutex.h> 13 + #include <linux/notifier.h> 14 + 15 + #include <linux/platform_data/cros_ec_commands.h> 16 + 17 + #define CROS_EC_DEV_NAME "cros_ec" 18 + #define CROS_EC_DEV_FP_NAME "cros_fp" 19 + #define CROS_EC_DEV_ISH_NAME "cros_ish" 20 + #define CROS_EC_DEV_PD_NAME "cros_pd" 21 + #define CROS_EC_DEV_SCP_NAME "cros_scp" 22 + #define CROS_EC_DEV_TP_NAME "cros_tp" 23 + 24 + /* 25 + * The EC is unresponsive for a time after a reboot command. Add a 26 + * simple delay to make sure that the bus stays locked. 27 + */ 28 + #define EC_REBOOT_DELAY_MS 50 29 + 30 + /* 31 + * Max bus-specific overhead incurred by request/responses. 32 + * I2C requires 1 additional byte for requests. 33 + * I2C requires 2 additional bytes for responses. 34 + * SPI requires up to 32 additional bytes for responses. 35 + */ 36 + #define EC_PROTO_VERSION_UNKNOWN 0 37 + #define EC_MAX_REQUEST_OVERHEAD 1 38 + #define EC_MAX_RESPONSE_OVERHEAD 32 39 + 40 + /* 41 + * Command interface between EC and AP, for LPC, I2C and SPI interfaces. 42 + */ 43 + enum { 44 + EC_MSG_TX_HEADER_BYTES = 3, 45 + EC_MSG_TX_TRAILER_BYTES = 1, 46 + EC_MSG_TX_PROTO_BYTES = EC_MSG_TX_HEADER_BYTES + 47 + EC_MSG_TX_TRAILER_BYTES, 48 + EC_MSG_RX_PROTO_BYTES = 3, 49 + 50 + /* Max length of messages for proto 2*/ 51 + EC_PROTO2_MSG_BYTES = EC_PROTO2_MAX_PARAM_SIZE + 52 + EC_MSG_TX_PROTO_BYTES, 53 + 54 + EC_MAX_MSG_BYTES = 64 * 1024, 55 + }; 56 + 57 + /** 58 + * struct cros_ec_command - Information about a ChromeOS EC command. 59 + * @version: Command version number (often 0). 60 + * @command: Command to send (EC_CMD_...). 61 + * @outsize: Outgoing length in bytes. 62 + * @insize: Max number of bytes to accept from the EC. 63 + * @result: EC's response to the command (separate from communication failure). 64 + * @data: Where to put the incoming data from EC and outgoing data to EC. 65 + */ 66 + struct cros_ec_command { 67 + uint32_t version; 68 + uint32_t command; 69 + uint32_t outsize; 70 + uint32_t insize; 71 + uint32_t result; 72 + uint8_t data[0]; 73 + }; 74 + 75 + /** 76 + * struct cros_ec_device - Information about a ChromeOS EC device. 77 + * @phys_name: Name of physical comms layer (e.g. 'i2c-4'). 78 + * @dev: Device pointer for physical comms device 79 + * @was_wake_device: True if this device was set to wake the system from 80 + * sleep at the last suspend. 81 + * @cros_class: The class structure for this device. 82 + * @cmd_readmem: Direct read of the EC memory-mapped region, if supported. 83 + * @offset: Is within EC_LPC_ADDR_MEMMAP region. 84 + * @bytes: Number of bytes to read. zero means "read a string" (including 85 + * the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be 86 + * read. Caller must ensure that the buffer is large enough for the 87 + * result when reading a string. 88 + * @max_request: Max size of message requested. 89 + * @max_response: Max size of message response. 90 + * @max_passthru: Max sice of passthru message. 91 + * @proto_version: The protocol version used for this device. 92 + * @priv: Private data. 93 + * @irq: Interrupt to use. 94 + * @id: Device id. 95 + * @din: Input buffer (for data from EC). This buffer will always be 96 + * dword-aligned and include enough space for up to 7 word-alignment 97 + * bytes also, so we can ensure that the body of the message is always 98 + * dword-aligned (64-bit). We use this alignment to keep ARM and x86 99 + * happy. Probably word alignment would be OK, there might be a small 100 + * performance advantage to using dword. 101 + * @dout: Output buffer (for data to EC). This buffer will always be 102 + * dword-aligned and include enough space for up to 7 word-alignment 103 + * bytes also, so we can ensure that the body of the message is always 104 + * dword-aligned (64-bit). We use this alignment to keep ARM and x86 105 + * happy. Probably word alignment would be OK, there might be a small 106 + * performance advantage to using dword. 107 + * @din_size: Size of din buffer to allocate (zero to use static din). 108 + * @dout_size: Size of dout buffer to allocate (zero to use static dout). 109 + * @wake_enabled: True if this device can wake the system from sleep. 110 + * @suspended: True if this device had been suspended. 111 + * @cmd_xfer: Send command to EC and get response. 112 + * Returns the number of bytes received if the communication 113 + * succeeded, but that doesn't mean the EC was happy with the 114 + * command. The caller should check msg.result for the EC's result 115 + * code. 116 + * @pkt_xfer: Send packet to EC and get response. 117 + * @lock: One transaction at a time. 118 + * @mkbp_event_supported: True if this EC supports the MKBP event protocol. 119 + * @host_sleep_v1: True if this EC supports the sleep v1 command. 120 + * @event_notifier: Interrupt event notifier for transport devices. 121 + * @event_data: Raw payload transferred with the MKBP event. 122 + * @event_size: Size in bytes of the event data. 123 + * @host_event_wake_mask: Mask of host events that cause wake from suspend. 124 + * @ec: The platform_device used by the mfd driver to interface with the 125 + * main EC. 126 + * @pd: The platform_device used by the mfd driver to interface with the 127 + * PD behind an EC. 128 + */ 129 + struct cros_ec_device { 130 + /* These are used by other drivers that want to talk to the EC */ 131 + const char *phys_name; 132 + struct device *dev; 133 + bool was_wake_device; 134 + struct class *cros_class; 135 + int (*cmd_readmem)(struct cros_ec_device *ec, unsigned int offset, 136 + unsigned int bytes, void *dest); 137 + 138 + /* These are used to implement the platform-specific interface */ 139 + u16 max_request; 140 + u16 max_response; 141 + u16 max_passthru; 142 + u16 proto_version; 143 + void *priv; 144 + int irq; 145 + u8 *din; 146 + u8 *dout; 147 + int din_size; 148 + int dout_size; 149 + bool wake_enabled; 150 + bool suspended; 151 + int (*cmd_xfer)(struct cros_ec_device *ec, 152 + struct cros_ec_command *msg); 153 + int (*pkt_xfer)(struct cros_ec_device *ec, 154 + struct cros_ec_command *msg); 155 + struct mutex lock; 156 + bool mkbp_event_supported; 157 + bool host_sleep_v1; 158 + struct blocking_notifier_head event_notifier; 159 + 160 + struct ec_response_get_next_event_v1 event_data; 161 + int event_size; 162 + u32 host_event_wake_mask; 163 + u32 last_resume_result; 164 + 165 + /* The platform devices used by the mfd driver */ 166 + struct platform_device *ec; 167 + struct platform_device *pd; 168 + }; 169 + 170 + /** 171 + * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information. 172 + * @sensor_num: Id of the sensor, as reported by the EC. 173 + */ 174 + struct cros_ec_sensor_platform { 175 + u8 sensor_num; 176 + }; 177 + 178 + /** 179 + * struct cros_ec_platform - ChromeOS EC platform information. 180 + * @ec_name: Name of EC device (e.g. 'cros-ec', 'cros-pd', ...) 181 + * used in /dev/ and sysfs. 182 + * @cmd_offset: Offset to apply for each command. Set when 183 + * registering a device behind another one. 184 + */ 185 + struct cros_ec_platform { 186 + const char *ec_name; 187 + u16 cmd_offset; 188 + }; 189 + 190 + /** 191 + * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. 192 + * @ec_dev: Device to suspend. 193 + * 194 + * This can be called by drivers to handle a suspend event. 195 + * 196 + * Return: 0 on success or negative error code. 197 + */ 198 + int cros_ec_suspend(struct cros_ec_device *ec_dev); 199 + 200 + /** 201 + * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. 202 + * @ec_dev: Device to resume. 203 + * 204 + * This can be called by drivers to handle a resume event. 205 + * 206 + * Return: 0 on success or negative error code. 207 + */ 208 + int cros_ec_resume(struct cros_ec_device *ec_dev); 209 + 210 + /** 211 + * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer. 212 + * @ec_dev: Device to register. 213 + * @msg: Message to write. 214 + * 215 + * This is intended to be used by all ChromeOS EC drivers, but at present 216 + * only SPI uses it. Once LPC uses the same protocol it can start using it. 217 + * I2C could use it now, with a refactor of the existing code. 218 + * 219 + * Return: 0 on success or negative error code. 220 + */ 221 + int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, 222 + struct cros_ec_command *msg); 223 + 224 + /** 225 + * cros_ec_check_result() - Check ec_msg->result. 226 + * @ec_dev: EC device. 227 + * @msg: Message to check. 228 + * 229 + * This is used by ChromeOS EC drivers to check the ec_msg->result for 230 + * errors and to warn about them. 231 + * 232 + * Return: 0 on success or negative error code. 233 + */ 234 + int cros_ec_check_result(struct cros_ec_device *ec_dev, 235 + struct cros_ec_command *msg); 236 + 237 + /** 238 + * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC. 239 + * @ec_dev: EC device. 240 + * @msg: Message to write. 241 + * 242 + * Call this to send a command to the ChromeOS EC. This should be used 243 + * instead of calling the EC's cmd_xfer() callback directly. 244 + * 245 + * Return: 0 on success or negative error code. 246 + */ 247 + int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, 248 + struct cros_ec_command *msg); 249 + 250 + /** 251 + * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. 252 + * @ec_dev: EC device. 253 + * @msg: Message to write. 254 + * 255 + * This function is identical to cros_ec_cmd_xfer, except it returns success 256 + * status only if both the command was transmitted successfully and the EC 257 + * replied with success status. It's not necessary to check msg->result when 258 + * using this function. 259 + * 260 + * Return: The number of bytes transferred on success or negative error code. 261 + */ 262 + int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, 263 + struct cros_ec_command *msg); 264 + 265 + /** 266 + * cros_ec_register() - Register a new ChromeOS EC, using the provided info. 267 + * @ec_dev: Device to register. 268 + * 269 + * Before calling this, allocate a pointer to a new device and then fill 270 + * in all the fields up to the --private-- marker. 271 + * 272 + * Return: 0 on success or negative error code. 273 + */ 274 + int cros_ec_register(struct cros_ec_device *ec_dev); 275 + 276 + /** 277 + * cros_ec_unregister() - Remove a ChromeOS EC. 278 + * @ec_dev: Device to unregister. 279 + * 280 + * Call this to deregister a ChromeOS EC, then clean up any private data. 281 + * 282 + * Return: 0 on success or negative error code. 283 + */ 284 + int cros_ec_unregister(struct cros_ec_device *ec_dev); 285 + 286 + /** 287 + * cros_ec_query_all() - Query the protocol version supported by the 288 + * ChromeOS EC. 289 + * @ec_dev: Device to register. 290 + * 291 + * Return: 0 on success or negative error code. 292 + */ 293 + int cros_ec_query_all(struct cros_ec_device *ec_dev); 294 + 295 + /** 296 + * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC. 297 + * @ec_dev: Device to fetch event from. 298 + * @wake_event: Pointer to a bool set to true upon return if the event might be 299 + * treated as a wake event. Ignored if null. 300 + * 301 + * Return: negative error code on errors; 0 for no data; or else number of 302 + * bytes received (i.e., an event was retrieved successfully). Event types are 303 + * written out to @ec_dev->event_data.event_type on success. 304 + */ 305 + int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event); 306 + 307 + /** 308 + * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC. 309 + * @ec_dev: Device to fetch event from. 310 + * 311 + * When MKBP is supported, when the EC raises an interrupt, we collect the 312 + * events raised and call the functions in the ec notifier. This function 313 + * is a helper to know which events are raised. 314 + * 315 + * Return: 0 on error or non-zero bitmask of one or more EC_HOST_EVENT_*. 316 + */ 317 + u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); 318 + 319 + #endif /* __LINUX_CROS_EC_PROTO_H */
+2 -2
sound/soc/codecs/Kconfig
··· 51 51 select SND_SOC_BT_SCO 52 52 select SND_SOC_BD28623 53 53 select SND_SOC_CQ0093VC 54 - select SND_SOC_CROS_EC_CODEC if MFD_CROS_EC 54 + select SND_SOC_CROS_EC_CODEC if CROS_EC 55 55 select SND_SOC_CS35L32 if I2C 56 56 select SND_SOC_CS35L33 if I2C 57 57 select SND_SOC_CS35L34 if I2C ··· 477 477 478 478 config SND_SOC_CROS_EC_CODEC 479 479 tristate "codec driver for ChromeOS EC" 480 - depends on MFD_CROS_EC 480 + depends on CROS_EC 481 481 help 482 482 If you say yes here you will get support for the 483 483 ChromeOS Embedded Controller's Audio Codec.
+2 -2
sound/soc/codecs/cros_ec_codec.c
··· 9 9 #include <linux/delay.h> 10 10 #include <linux/device.h> 11 11 #include <linux/kernel.h> 12 - #include <linux/mfd/cros_ec.h> 13 - #include <linux/mfd/cros_ec_commands.h> 14 12 #include <linux/module.h> 13 + #include <linux/platform_data/cros_ec_commands.h> 14 + #include <linux/platform_data/cros_ec_proto.h> 15 15 #include <linux/platform_device.h> 16 16 #include <sound/pcm.h> 17 17 #include <sound/pcm_params.h>
+1 -1
sound/soc/qcom/Kconfig
··· 99 99 100 100 config SND_SOC_SDM845 101 101 tristate "SoC Machine driver for SDM845 boards" 102 - depends on QCOM_APR && MFD_CROS_EC && I2C 102 + depends on QCOM_APR && CROS_EC && I2C 103 103 select SND_SOC_QDSP6 104 104 select SND_SOC_QCOM_COMMON 105 105 select SND_SOC_RT5663