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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull chrome platform updates from Olof Johansson:
"Here's the branch of chrome platform changes for v4.4. Some have been
queued up for the full 4.3 release cycle since I forgot to send them
in for that round (rebased early on to deal with fixes conflicts).

Most of these enable EC communication stuff -- Pixel 2015 support,
enabling building for ARM64 platforms, and a few fixes for memory
leaks.

There's also a patch in here to allow reading/writing the verified
boot context, which depends on a sysfs patch acked by Greg"

* tag 'chrome-platform-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/olof/chrome-platform:
platform/chrome: Fix i2c-designware adapter name
platform/chrome: Support reading/writing the vboot context
sysfs: Support is_visible() on binary attributes
platform/chrome: cros_ec: Fix possible leak in led_rgb_store()
platform/chrome: cros_ec: Fix leak in sequence_store()
platform/chrome: Enable Chrome platforms on 64-bit ARM
platform/chrome: cros_ec_dev - Add a platform device ID table
platform/chrome: cros_ec_lpc - Add support for Google Pixel 2
platform/chrome: cros_ec_lpc - Use existing function to check EC result
platform/chrome: Make depends on MFD_CROS_EC instead CROS_EC_PROTO
Revert "platform/chrome: Don't make CHROME_PLATFORMS depends on X86 || ARM"

+207 -37
+3 -2
drivers/platform/chrome/Kconfig
··· 4 4 5 5 menuconfig CHROME_PLATFORMS 6 6 bool "Platform support for Chrome hardware" 7 + depends on X86 || ARM || ARM64 || COMPILE_TEST 7 8 ---help--- 8 9 Say Y here to get to see options for platform support for 9 10 various Chromebooks and Chromeboxes. This option alone does ··· 40 39 41 40 config CROS_EC_CHARDEV 42 41 tristate "Chrome OS Embedded Controller userspace device interface" 43 - depends on CROS_EC_PROTO 42 + depends on MFD_CROS_EC 44 43 ---help--- 45 44 This driver adds support to talk with the ChromeOS EC from userspace. 46 45 ··· 49 48 50 49 config CROS_EC_LPC 51 50 tristate "ChromeOS Embedded Controller (LPC)" 52 - depends on MFD_CROS_EC && CROS_EC_PROTO && (X86 || COMPILE_TEST) 51 + depends on MFD_CROS_EC && (X86 || COMPILE_TEST) 53 52 help 54 53 If you say Y here, you get support for talking to the ChromeOS EC 55 54 over an LPC bus. This uses a simple byte-level protocol with a
+2 -1
drivers/platform/chrome/Makefile
··· 1 1 2 2 obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 3 3 obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o 4 - cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o 4 + cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ 5 + cros_ec_lightbar.o cros_ec_vbc.o 5 6 obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o 6 7 obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o 7 8 obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o
+2 -2
drivers/platform/chrome/chromeos_laptop.c
··· 47 47 "SMBus I801 adapter", 48 48 "i915 gmbus vga", 49 49 "i915 gmbus panel", 50 - "i2c-designware-pci", 51 - "i2c-designware-pci", 50 + "Synopsys DesignWare I2C adapter", 51 + "Synopsys DesignWare I2C adapter", 52 52 }; 53 53 54 54 /* Keep this enum consistent with i2c_adapter_names */
+7
drivers/platform/chrome/cros_ec_dev.c
··· 32 32 static const struct attribute_group *cros_ec_groups[] = { 33 33 &cros_ec_attr_group, 34 34 &cros_ec_lightbar_attr_group, 35 + &cros_ec_vbc_attr_group, 35 36 NULL, 36 37 }; 37 38 ··· 287 286 device_unregister(&ec->class_dev); 288 287 return 0; 289 288 } 289 + 290 + static const struct platform_device_id cros_ec_id[] = { 291 + { "cros-ec-ctl", 0 }, 292 + { /* sentinel */ }, 293 + }; 294 + MODULE_DEVICE_TABLE(platform, cros_ec_id); 290 295 291 296 static struct platform_driver cros_ec_dev_driver = { 292 297 .driver = {
+17 -14
drivers/platform/chrome/cros_ec_lightbar.c
··· 252 252 253 253 ret = sscanf(buf, "%i", &val[i++]); 254 254 if (ret == 0) 255 - return -EINVAL; 255 + goto exit; 256 256 257 257 if (i == 4) { 258 258 param = (struct ec_params_lightbar *)msg->data; ··· 268 268 if ((j++ % 4) == 0) { 269 269 ret = lb_throttle(); 270 270 if (ret) 271 - return ret; 271 + goto exit; 272 272 } 273 273 274 274 ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 275 275 if (ret < 0) 276 276 goto exit; 277 277 278 - if (msg->result != EC_RES_SUCCESS) { 279 - ret = -EINVAL; 278 + if (msg->result != EC_RES_SUCCESS) 280 279 goto exit; 281 - } 282 280 283 281 i = 0; 284 282 ok = 1; ··· 350 352 struct cros_ec_dev *ec = container_of(dev, 351 353 struct cros_ec_dev, class_dev); 352 354 353 - msg = alloc_lightbar_cmd_msg(ec); 354 - if (!msg) 355 - return -ENOMEM; 356 - 357 355 for (len = 0; len < count; len++) 358 356 if (!isalnum(buf[len])) 359 357 break; ··· 364 370 return ret; 365 371 } 366 372 373 + msg = alloc_lightbar_cmd_msg(ec); 374 + if (!msg) 375 + return -ENOMEM; 376 + 367 377 param = (struct ec_params_lightbar *)msg->data; 368 378 param->cmd = LIGHTBAR_CMD_SEQ; 369 379 param->seq.num = num; 370 380 ret = lb_throttle(); 371 381 if (ret) 372 - return ret; 382 + goto exit; 373 383 374 384 ret = cros_ec_cmd_xfer(ec->ec_dev, msg); 375 385 if (ret < 0) 376 - return ret; 386 + goto exit; 377 387 378 - if (msg->result != EC_RES_SUCCESS) 379 - return -EINVAL; 388 + if (msg->result != EC_RES_SUCCESS) { 389 + ret = -EINVAL; 390 + goto exit; 391 + } 380 392 381 - return count; 393 + ret = count; 394 + exit: 395 + kfree(msg); 396 + return ret; 382 397 } 383 398 384 399 /* Module initialization */
+9 -12
drivers/platform/chrome/cros_ec_lpc.c
··· 166 166 167 167 /* Check result */ 168 168 msg->result = inb(EC_LPC_ADDR_HOST_DATA); 169 - 170 - switch (msg->result) { 171 - case EC_RES_SUCCESS: 172 - break; 173 - case EC_RES_IN_PROGRESS: 174 - ret = -EAGAIN; 175 - dev_dbg(ec->dev, "command 0x%02x in progress\n", 176 - msg->command); 169 + ret = cros_ec_check_result(ec, msg); 170 + if (ret) 177 171 goto done; 178 - default: 179 - dev_dbg(ec->dev, "command 0x%02x returned %d\n", 180 - msg->command, msg->result); 181 - } 182 172 183 173 /* Read back args */ 184 174 args.flags = inb(EC_LPC_ADDR_HOST_ARGS); ··· 317 327 .matches = { 318 328 DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 319 329 DMI_MATCH(DMI_PRODUCT_NAME, "Link"), 330 + }, 331 + }, 332 + { 333 + /* x86-samus, the Chromebook Pixel 2. */ 334 + .matches = { 335 + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 336 + DMI_MATCH(DMI_PRODUCT_NAME, "Samus"), 320 337 }, 321 338 }, 322 339 {
+137
drivers/platform/chrome/cros_ec_vbc.c
··· 1 + /* 2 + * cros_ec_vbc - Expose the vboot context nvram to userspace 3 + * 4 + * Copyright (C) 2015 Collabora Ltd. 5 + * 6 + * based on vendor driver, 7 + * 8 + * Copyright (C) 2012 The Chromium OS Authors 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation; either version 2 of the License, or 13 + * (at your option) any later version. 14 + * 15 + * This program is distributed in the hope that it will be useful, 16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 + * GNU General Public License for more details. 19 + */ 20 + 21 + #include <linux/of.h> 22 + #include <linux/platform_device.h> 23 + #include <linux/mfd/cros_ec.h> 24 + #include <linux/mfd/cros_ec_commands.h> 25 + #include <linux/slab.h> 26 + 27 + static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj, 28 + struct bin_attribute *att, char *buf, 29 + loff_t pos, size_t count) 30 + { 31 + struct device *dev = container_of(kobj, struct device, kobj); 32 + struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev, 33 + class_dev); 34 + struct cros_ec_device *ecdev = ec->ec_dev; 35 + struct ec_params_vbnvcontext *params; 36 + struct cros_ec_command *msg; 37 + int err; 38 + const size_t para_sz = sizeof(params->op); 39 + const size_t resp_sz = sizeof(struct ec_response_vbnvcontext); 40 + const size_t payload = max(para_sz, resp_sz); 41 + 42 + msg = kmalloc(sizeof(*msg) + payload, GFP_KERNEL); 43 + if (!msg) 44 + return -ENOMEM; 45 + 46 + /* NB: we only kmalloc()ated enough space for the op field */ 47 + params = (struct ec_params_vbnvcontext *)msg->data; 48 + params->op = EC_VBNV_CONTEXT_OP_READ; 49 + 50 + msg->version = EC_VER_VBNV_CONTEXT; 51 + msg->command = EC_CMD_VBNV_CONTEXT; 52 + msg->outsize = para_sz; 53 + msg->insize = resp_sz; 54 + 55 + err = cros_ec_cmd_xfer(ecdev, msg); 56 + if (err < 0) { 57 + dev_err(dev, "Error sending read request: %d\n", err); 58 + kfree(msg); 59 + return err; 60 + } 61 + 62 + memcpy(buf, msg->data, resp_sz); 63 + 64 + kfree(msg); 65 + return resp_sz; 66 + } 67 + 68 + static ssize_t vboot_context_write(struct file *filp, struct kobject *kobj, 69 + struct bin_attribute *attr, char *buf, 70 + loff_t pos, size_t count) 71 + { 72 + struct device *dev = container_of(kobj, struct device, kobj); 73 + struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev, 74 + class_dev); 75 + struct cros_ec_device *ecdev = ec->ec_dev; 76 + struct ec_params_vbnvcontext *params; 77 + struct cros_ec_command *msg; 78 + int err; 79 + const size_t para_sz = sizeof(*params); 80 + const size_t data_sz = sizeof(params->block); 81 + 82 + /* Only write full values */ 83 + if (count != data_sz) 84 + return -EINVAL; 85 + 86 + msg = kmalloc(sizeof(*msg) + para_sz, GFP_KERNEL); 87 + if (!msg) 88 + return -ENOMEM; 89 + 90 + params = (struct ec_params_vbnvcontext *)msg->data; 91 + params->op = EC_VBNV_CONTEXT_OP_WRITE; 92 + memcpy(params->block, buf, data_sz); 93 + 94 + msg->version = EC_VER_VBNV_CONTEXT; 95 + msg->command = EC_CMD_VBNV_CONTEXT; 96 + msg->outsize = para_sz; 97 + msg->insize = 0; 98 + 99 + err = cros_ec_cmd_xfer(ecdev, msg); 100 + if (err < 0) { 101 + dev_err(dev, "Error sending write request: %d\n", err); 102 + kfree(msg); 103 + return err; 104 + } 105 + 106 + kfree(msg); 107 + return data_sz; 108 + } 109 + 110 + static umode_t cros_ec_vbc_is_visible(struct kobject *kobj, 111 + struct bin_attribute *a, int n) 112 + { 113 + struct device *dev = container_of(kobj, struct device, kobj); 114 + struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev, 115 + class_dev); 116 + struct device_node *np = ec->ec_dev->dev->of_node; 117 + 118 + if (IS_ENABLED(CONFIG_OF) && np) { 119 + if (of_property_read_bool(np, "google,has-vbc-nvram")) 120 + return a->attr.mode; 121 + } 122 + 123 + return 0; 124 + } 125 + 126 + static BIN_ATTR_RW(vboot_context, 16); 127 + 128 + static struct bin_attribute *cros_ec_vbc_bin_attrs[] = { 129 + &bin_attr_vboot_context, 130 + NULL 131 + }; 132 + 133 + struct attribute_group cros_ec_vbc_attr_group = { 134 + .name = "vbc", 135 + .bin_attrs = cros_ec_vbc_bin_attrs, 136 + .is_bin_visible = cros_ec_vbc_is_visible, 137 + };
+15 -2
fs/sysfs/group.c
··· 73 73 } 74 74 75 75 if (grp->bin_attrs) { 76 - for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { 76 + for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) { 77 + umode_t mode = (*bin_attr)->attr.mode; 78 + 77 79 if (update) 78 80 kernfs_remove_by_name(parent, 79 81 (*bin_attr)->attr.name); 82 + if (grp->is_bin_visible) { 83 + mode = grp->is_bin_visible(kobj, *bin_attr, i); 84 + if (!mode) 85 + continue; 86 + } 87 + 88 + WARN(mode & ~(SYSFS_PREALLOC | 0664), 89 + "Attribute %s: Invalid permissions 0%o\n", 90 + (*bin_attr)->attr.name, mode); 91 + 92 + mode &= SYSFS_PREALLOC | 0664; 80 93 error = sysfs_add_file_mode_ns(parent, 81 94 &(*bin_attr)->attr, true, 82 - (*bin_attr)->attr.mode, NULL); 95 + mode, NULL); 83 96 if (error) 84 97 break; 85 98 }
+1
include/linux/mfd/cros_ec.h
··· 255 255 /* sysfs stuff */ 256 256 extern struct attribute_group cros_ec_attr_group; 257 257 extern struct attribute_group cros_ec_lightbar_attr_group; 258 + extern struct attribute_group cros_ec_vbc_attr_group; 258 259 259 260 #endif /* __LINUX_MFD_CROS_EC_H */
+14 -4
include/linux/sysfs.h
··· 64 64 * a new subdirectory with this name. 65 65 * @is_visible: Optional: Function to return permissions associated with an 66 66 * attribute of the group. Will be called repeatedly for each 67 - * attribute in the group. Only read/write permissions as well as 68 - * SYSFS_PREALLOC are accepted. Must return 0 if an attribute is 69 - * not visible. The returned value will replace static permissions 70 - * defined in struct attribute or struct bin_attribute. 67 + * non-binary attribute in the group. Only read/write 68 + * permissions as well as SYSFS_PREALLOC are accepted. Must 69 + * return 0 if an attribute is not visible. The returned value 70 + * will replace static permissions defined in struct attribute. 71 + * @is_bin_visible: 72 + * Optional: Function to return permissions associated with a 73 + * binary attribute of the group. Will be called repeatedly 74 + * for each binary attribute in the group. Only read/write 75 + * permissions as well as SYSFS_PREALLOC are accepted. Must 76 + * return 0 if a binary attribute is not visible. The returned 77 + * value will replace static permissions defined in 78 + * struct bin_attribute. 71 79 * @attrs: Pointer to NULL terminated list of attributes. 72 80 * @bin_attrs: Pointer to NULL terminated list of binary attributes. 73 81 * Either attrs or bin_attrs or both must be provided. ··· 84 76 const char *name; 85 77 umode_t (*is_visible)(struct kobject *, 86 78 struct attribute *, int); 79 + umode_t (*is_bin_visible)(struct kobject *, 80 + struct bin_attribute *, int); 87 81 struct attribute **attrs; 88 82 struct bin_attribute **bin_attrs; 89 83 };