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 'tag-chrome-platform-for-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform updates from Tzung-Bi Shih:
"New drivers
- Driver for ChromeOS human presence sensor

Cleanups:
- Add missing property in dt-binding example.
- Update the availability of properties in dt-binding.
- Separate dt-binding for ChromeOS fingerprint sensor.

Improvements:
- Set PROBE_PREFER_ASYNCHRONOUS for some drivers for shortening boot time.

Fixes:
- Fix an use-after-free in cros_ec_typec.

And minor fixes and cleanups"

* tag 'tag-chrome-platform-for-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
platform/chrome: cros_ec_typec: zero out stale pointers
platform/chrome: cros_usbpd_notify: Fix error handling in cros_usbpd_notify_init()
platform/chrome: cros_ec: Convert to i2c's .probe_new()
platform/chrome: cros_ec_lpc: Force synchronous probe
platform/chrome: cros_ec_spi: Set PROBE_PREFER_ASYNCHRONOUS
platform/chrome: cros_ec_lightbar: Set PROBE_PREFER_ASYNCHRONOUS
platform/chrome: cros_ec_debugfs: Set PROBE_PREFER_ASYNCHRONOUS
platform/chrome: cros_ec_lpc: Mark PROBE_PREFER_ASYNCHRONOUS
platform/chrome: cros_ec_lpc: Move mec_init to device probe
platform/chrome: Use kstrtobool() instead of strtobool()
platform/chrome: cros_ec_lpc_mec: remove cros_ec_lpc_mec_destroy()
dt-bindings: cros-ec: Add ChromeOS fingerprint binding
dt-bindings: cros-ec: Reorganize and enforce property availability
platform/chrome: cros_hps_i2c: make remove callback return void
platform/chrome: add a driver for HPS

+298 -42
+1
Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml
··· 48 48 cros_ec: ec@0 { 49 49 compatible = "google,cros-ec-spi"; 50 50 reg = <0>; 51 + interrupts = <35 0>; 51 52 52 53 typec { 53 54 compatible = "google,cros-ec-typec";
+1
Documentation/devicetree/bindings/chrome/google,cros-kbd-led-backlight.yaml
··· 27 27 cros_ec: ec@0 { 28 28 compatible = "google,cros-ec-spi"; 29 29 reg = <0>; 30 + interrupts = <15 0>; 30 31 31 32 kbd-led-backlight { 32 33 compatible = "google,cros-kbd-led-backlight";
+1
Documentation/devicetree/bindings/extcon/extcon-usbc-cros-ec.yaml
··· 40 40 cros-ec@0 { 41 41 compatible = "google,cros-ec-spi"; 42 42 reg = <0>; 43 + interrupts = <44 0>; 43 44 44 45 usbc_extcon0: extcon0 { 45 46 compatible = "google,extcon-usbc-cros-ec";
+1
Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml
··· 47 47 compatible = "google,cros-ec-spi"; 48 48 reg = <0>; 49 49 spi-max-frequency = <5000000>; 50 + interrupts = <99 0>; 50 51 51 52 i2c-tunnel { 52 53 compatible = "google,cros-ec-i2c-tunnel";
+90 -13
Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
··· 20 20 compatible: 21 21 oneOf: 22 22 - description: 23 - For implementations of the EC is connected through I2C. 23 + For implementations of the EC connected through I2C. 24 24 const: google,cros-ec-i2c 25 25 - description: 26 - For implementations of the EC is connected through SPI. 26 + For implementations of the EC connected through SPI. 27 27 const: google,cros-ec-spi 28 28 - description: 29 - For implementations of the EC is connected through RPMSG. 29 + For implementations of the FPMCU connected through SPI. 30 + items: 31 + - const: google,cros-ec-fp 32 + - const: google,cros-ec-spi 33 + - description: 34 + For implementations of the EC connected through RPMSG. 30 35 const: google,cros-ec-rpmsg 31 36 32 - controller-data: 33 - description: 34 - SPI controller data, see bindings/spi/samsung,spi-peripheral-props.yaml 35 - type: object 37 + controller-data: true 36 38 37 39 google,cros-ec-spi-pre-delay: 38 40 description: ··· 64 62 the SCP. 65 63 $ref: "/schemas/types.yaml#/definitions/string" 66 64 67 - spi-max-frequency: 68 - description: Maximum SPI frequency of the device in Hz. 65 + spi-max-frequency: true 69 66 70 67 reg: 71 68 maxItems: 1 72 69 73 70 interrupts: 74 71 maxItems: 1 72 + 73 + reset-gpios: 74 + maxItems: 1 75 + 76 + boot0-gpios: 77 + maxItems: 1 78 + description: Assert for bootloader mode. 79 + 80 + vdd-supply: true 75 81 76 82 wakeup-source: 77 83 description: Button can wake-up the system. ··· 165 155 - if: 166 156 properties: 167 157 compatible: 168 - contains: 169 - enum: 170 - - google,cros-ec-i2c 171 - - google,cros-ec-rpmsg 158 + not: 159 + contains: 160 + const: google,cros-ec-spi 172 161 then: 173 162 properties: 163 + controller-data: false 174 164 google,cros-ec-spi-pre-delay: false 175 165 google,cros-ec-spi-msg-delay: false 176 166 spi-max-frequency: false 177 167 else: 178 168 $ref: /schemas/spi/spi-peripheral-props.yaml 169 + 170 + - if: 171 + properties: 172 + compatible: 173 + not: 174 + contains: 175 + const: google,cros-ec-rpmsg 176 + then: 177 + properties: 178 + mediatek,rpmsg-name: false 179 + 180 + required: 181 + - reg 182 + - interrupts 183 + 184 + - if: 185 + properties: 186 + compatible: 187 + contains: 188 + const: google,cros-ec-fp 189 + then: 190 + properties: 191 + '#address-cells': false 192 + '#size-cells': false 193 + typec: false 194 + ec-pwm: false 195 + kbd-led-backlight: false 196 + keyboard-controller: false 197 + proximity: false 198 + codecs: false 199 + cbas: false 200 + 201 + patternProperties: 202 + "^i2c-tunnel[0-9]*$": false 203 + "^regulator@[0-9]+$": false 204 + "^extcon[0-9]*$": false 205 + 206 + # Using additionalProperties: false here and 207 + # listing true properties doesn't work 208 + 209 + required: 210 + - reset-gpios 211 + - boot0-gpios 212 + - vdd-supply 213 + else: 214 + properties: 215 + reset-gpios: false 216 + boot0-gpios: false 217 + vdd-supply: false 179 218 180 219 additionalProperties: false 181 220 ··· 280 221 cros-ec { 281 222 compatible = "google,cros-ec-rpmsg"; 282 223 }; 224 + }; 225 + 226 + # Example for FPMCU 227 + - | 228 + spi0 { 229 + #address-cells = <0x1>; 230 + #size-cells = <0x0>; 231 + 232 + ec@0 { 233 + compatible = "google,cros-ec-fp", "google,cros-ec-spi"; 234 + reg = <0x0>; 235 + interrupt-parent = <&gpio_controller>; 236 + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; 237 + spi-max-frequency = <3000000>; 238 + reset-gpios = <&gpio_controller 5 GPIO_ACTIVE_LOW>; 239 + boot0-gpios = <&gpio_controller 10 GPIO_ACTIVE_HIGH>; 240 + vdd-supply = <&pp3300_fp_mcu>; 241 + }; 283 242 }; 284 243 ...
+1
Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
··· 48 48 cros-ec@0 { 49 49 compatible = "google,cros-ec-spi"; 50 50 reg = <0>; 51 + interrupts = <101 0>; 51 52 52 53 cros_ec_pwm: pwm { 53 54 compatible = "google,cros-ec-pwm";
+1
Documentation/devicetree/bindings/regulator/google,cros-ec-regulator.yaml
··· 41 41 reg = <0>; 42 42 #address-cells = <1>; 43 43 #size-cells = <0>; 44 + interrupts = <99 0>; 44 45 45 46 regulator@0 { 46 47 compatible = "google,cros-ec-regulator";
+1
Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
··· 57 57 cros-ec@0 { 58 58 compatible = "google,cros-ec-spi"; 59 59 reg = <0>; 60 + interrupts = <93 0>; 60 61 61 62 codecs { 62 63 #address-cells = <2>;
+6
MAINTAINERS
··· 4954 4954 F: drivers/platform/chrome/cros_usbpd_notify.c 4955 4955 F: include/linux/platform_data/cros_usbpd_notify.h 4956 4956 4957 + CHROMEOS HPS DRIVER 4958 + M: Dan Callaghan <dcallagh@chromium.org> 4959 + R: Sami Kyöstilä <skyostil@chromium.org> 4960 + S: Maintained 4961 + F: drivers/platform/chrome/cros_hps_i2c.c 4962 + 4957 4963 CHRONTEL CH7322 CEC DRIVER 4958 4964 M: Joe Tessler <jrt@google.com> 4959 4965 L: linux-media@vger.kernel.org
+10
drivers/platform/chrome/Kconfig
··· 228 228 To compile this driver as a module, choose M here: the module will be 229 229 called cros_ec_typec. 230 230 231 + config CROS_HPS_I2C 232 + tristate "ChromeOS HPS device" 233 + depends on HID && I2C && PM 234 + help 235 + Say Y here if you want to enable support for the ChromeOS 236 + human presence sensor (HPS), attached via I2C. The driver supports a 237 + sensor connected to the I2C bus and exposes it as a character device. 238 + To save power, the sensor is automatically powered down when no 239 + clients are accessing it. 240 + 231 241 config CROS_USBPD_LOGGER 232 242 tristate "Logging driver for USB PD charger" 233 243 depends on CHARGER_CROS_USBPD
+1
drivers/platform/chrome/Makefile
··· 27 27 cros-ec-sensorhub-objs := cros_ec_sensorhub.o cros_ec_sensorhub_ring.o 28 28 obj-$(CONFIG_CROS_EC_SENSORHUB) += cros-ec-sensorhub.o 29 29 obj-$(CONFIG_CROS_EC_SYSFS) += cros_ec_sysfs.o 30 + obj-$(CONFIG_CROS_HPS_I2C) += cros_hps_i2c.o 30 31 obj-$(CONFIG_CROS_USBPD_LOGGER) += cros_usbpd_logger.o 31 32 obj-$(CONFIG_CROS_USBPD_NOTIFY) += cros_usbpd_notify.o 32 33
+1
drivers/platform/chrome/cros_ec_debugfs.c
··· 521 521 .driver = { 522 522 .name = DRV_NAME, 523 523 .pm = &cros_ec_debugfs_pm_ops, 524 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 524 525 }, 525 526 .probe = cros_ec_debugfs_probe, 526 527 .remove = cros_ec_debugfs_remove,
+2 -3
drivers/platform/chrome/cros_ec_i2c.c
··· 286 286 return ret; 287 287 } 288 288 289 - static int cros_ec_i2c_probe(struct i2c_client *client, 290 - const struct i2c_device_id *dev_id) 289 + static int cros_ec_i2c_probe(struct i2c_client *client) 291 290 { 292 291 struct device *dev = &client->dev; 293 292 struct cros_ec_device *ec_dev = NULL; ··· 372 373 .of_match_table = of_match_ptr(cros_ec_i2c_of_match), 373 374 .pm = &cros_ec_i2c_pm_ops, 374 375 }, 375 - .probe = cros_ec_i2c_probe, 376 + .probe_new = cros_ec_i2c_probe, 376 377 .remove = cros_ec_i2c_remove, 377 378 .id_table = cros_ec_i2c_id, 378 379 };
+3 -1
drivers/platform/chrome/cros_ec_lightbar.c
··· 8 8 #include <linux/device.h> 9 9 #include <linux/fs.h> 10 10 #include <linux/kobject.h> 11 + #include <linux/kstrtox.h> 11 12 #include <linux/module.h> 12 13 #include <linux/platform_data/cros_ec_commands.h> 13 14 #include <linux/platform_data/cros_ec_proto.h> ··· 494 493 bool enable; 495 494 int ret; 496 495 497 - ret = strtobool(buf, &enable); 496 + ret = kstrtobool(buf, &enable); 498 497 if (ret < 0) 499 498 return ret; 500 499 ··· 602 601 .driver = { 603 602 .name = DRV_NAME, 604 603 .pm = &cros_ec_lightbar_pm_ops, 604 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 605 605 }, 606 606 .probe = cros_ec_lightbar_probe, 607 607 .remove = cros_ec_lightbar_remove,
+9 -6
drivers/platform/chrome/cros_ec_lpc.c
··· 354 354 return -EBUSY; 355 355 } 356 356 357 + cros_ec_lpc_mec_init(EC_HOST_CMD_REGION0, 358 + EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE); 359 + 357 360 /* 358 361 * Read the mapped ID twice, the first one is assuming the 359 362 * EC is a Microchip Embedded Controller (MEC) variant, if the ··· 557 554 .name = DRV_NAME, 558 555 .acpi_match_table = cros_ec_lpc_acpi_device_ids, 559 556 .pm = &cros_ec_lpc_pm_ops, 557 + /* 558 + * ACPI child devices may probe before us, and they racily 559 + * check our drvdata pointer. Force synchronous probe until 560 + * those races are resolved. 561 + */ 562 + .probe_type = PROBE_FORCE_SYNCHRONOUS, 560 563 }, 561 564 .probe = cros_ec_lpc_probe, 562 565 .remove = cros_ec_lpc_remove, ··· 595 586 return -ENODEV; 596 587 } 597 588 598 - cros_ec_lpc_mec_init(EC_HOST_CMD_REGION0, 599 - EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE); 600 - 601 589 /* Register the driver */ 602 590 ret = platform_driver_register(&cros_ec_lpc_driver); 603 591 if (ret) { 604 592 pr_err(DRV_NAME ": can't register driver: %d\n", ret); 605 - cros_ec_lpc_mec_destroy(); 606 593 return ret; 607 594 } 608 595 ··· 608 603 if (ret) { 609 604 pr_err(DRV_NAME ": can't register device: %d\n", ret); 610 605 platform_driver_unregister(&cros_ec_lpc_driver); 611 - cros_ec_lpc_mec_destroy(); 612 606 } 613 607 } 614 608 ··· 619 615 if (!cros_ec_lpc_acpi_device_found) 620 616 platform_device_unregister(&cros_ec_lpc_device); 621 617 platform_driver_unregister(&cros_ec_lpc_driver); 622 - cros_ec_lpc_mec_destroy(); 623 618 } 624 619 625 620 module_init(cros_ec_lpc_init);
-6
drivers/platform/chrome/cros_ec_lpc_mec.c
··· 146 146 mec_emi_end = end; 147 147 } 148 148 EXPORT_SYMBOL(cros_ec_lpc_mec_init); 149 - 150 - void cros_ec_lpc_mec_destroy(void) 151 - { 152 - mutex_destroy(&io_mutex); 153 - } 154 - EXPORT_SYMBOL(cros_ec_lpc_mec_destroy);
-7
drivers/platform/chrome/cros_ec_lpc_mec.h
··· 45 45 */ 46 46 void cros_ec_lpc_mec_init(unsigned int base, unsigned int end); 47 47 48 - /* 49 - * cros_ec_lpc_mec_destroy 50 - * 51 - * Cleanup MEC I/O. 52 - */ 53 - void cros_ec_lpc_mec_destroy(void); 54 - 55 48 /** 56 49 * cros_ec_lpc_mec_in_range() - Determine if addresses are in MEC EMI range. 57 50 *
+1
drivers/platform/chrome/cros_ec_spi.c
··· 834 834 .name = "cros-ec-spi", 835 835 .of_match_table = cros_ec_spi_of_match, 836 836 .pm = &cros_ec_spi_pm_ops, 837 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 837 838 }, 838 839 .probe = cros_ec_spi_probe, 839 840 .remove = cros_ec_spi_remove,
+3
drivers/platform/chrome/cros_ec_typec.c
··· 173 173 174 174 role_sw_err: 175 175 typec_switch_put(port->ori_sw); 176 + port->ori_sw = NULL; 176 177 ori_sw_err: 177 178 typec_retimer_put(port->retimer); 179 + port->retimer = NULL; 178 180 retimer_sw_err: 179 181 typec_mux_put(port->mux); 182 + port->mux = NULL; 180 183 mux_err: 181 184 return -ENODEV; 182 185 }
+160
drivers/platform/chrome/cros_hps_i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Driver for the ChromeOS human presence sensor (HPS), attached via I2C. 4 + * 5 + * The driver exposes HPS as a character device, although currently no read or 6 + * write operations are supported. Instead, the driver only controls the power 7 + * state of the sensor, keeping it on only while userspace holds an open file 8 + * descriptor to the HPS device. 9 + * 10 + * Copyright 2022 Google LLC. 11 + */ 12 + 13 + #include <linux/acpi.h> 14 + #include <linux/fs.h> 15 + #include <linux/gpio/consumer.h> 16 + #include <linux/i2c.h> 17 + #include <linux/miscdevice.h> 18 + #include <linux/module.h> 19 + #include <linux/pm_runtime.h> 20 + 21 + #define HPS_ACPI_ID "GOOG0020" 22 + 23 + struct hps_drvdata { 24 + struct i2c_client *client; 25 + struct miscdevice misc_device; 26 + struct gpio_desc *enable_gpio; 27 + }; 28 + 29 + static void hps_set_power(struct hps_drvdata *hps, bool state) 30 + { 31 + gpiod_set_value_cansleep(hps->enable_gpio, state); 32 + } 33 + 34 + static int hps_open(struct inode *inode, struct file *file) 35 + { 36 + struct hps_drvdata *hps = container_of(file->private_data, 37 + struct hps_drvdata, misc_device); 38 + struct device *dev = &hps->client->dev; 39 + 40 + return pm_runtime_resume_and_get(dev); 41 + } 42 + 43 + static int hps_release(struct inode *inode, struct file *file) 44 + { 45 + struct hps_drvdata *hps = container_of(file->private_data, 46 + struct hps_drvdata, misc_device); 47 + struct device *dev = &hps->client->dev; 48 + 49 + return pm_runtime_put(dev); 50 + } 51 + 52 + static const struct file_operations hps_fops = { 53 + .owner = THIS_MODULE, 54 + .open = hps_open, 55 + .release = hps_release, 56 + }; 57 + 58 + static int hps_i2c_probe(struct i2c_client *client) 59 + { 60 + struct hps_drvdata *hps; 61 + int ret; 62 + 63 + hps = devm_kzalloc(&client->dev, sizeof(*hps), GFP_KERNEL); 64 + if (!hps) 65 + return -ENOMEM; 66 + 67 + hps->misc_device.parent = &client->dev; 68 + hps->misc_device.minor = MISC_DYNAMIC_MINOR; 69 + hps->misc_device.name = "cros-hps"; 70 + hps->misc_device.fops = &hps_fops; 71 + 72 + i2c_set_clientdata(client, hps); 73 + hps->client = client; 74 + 75 + /* 76 + * HPS is powered on from firmware before entering the kernel, so we 77 + * acquire the line with GPIOD_OUT_HIGH here to preserve the existing 78 + * state. The peripheral is powered off after successful probe below. 79 + */ 80 + hps->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_HIGH); 81 + if (IS_ERR(hps->enable_gpio)) { 82 + ret = PTR_ERR(hps->enable_gpio); 83 + dev_err(&client->dev, "failed to get enable gpio: %d\n", ret); 84 + return ret; 85 + } 86 + 87 + ret = misc_register(&hps->misc_device); 88 + if (ret) { 89 + dev_err(&client->dev, "failed to initialize misc device: %d\n", ret); 90 + return ret; 91 + } 92 + 93 + hps_set_power(hps, false); 94 + pm_runtime_enable(&client->dev); 95 + return 0; 96 + } 97 + 98 + static void hps_i2c_remove(struct i2c_client *client) 99 + { 100 + struct hps_drvdata *hps = i2c_get_clientdata(client); 101 + 102 + pm_runtime_disable(&client->dev); 103 + misc_deregister(&hps->misc_device); 104 + 105 + /* 106 + * Re-enable HPS, in order to return it to its default state 107 + * (i.e. powered on). 108 + */ 109 + hps_set_power(hps, true); 110 + } 111 + 112 + static int hps_suspend(struct device *dev) 113 + { 114 + struct i2c_client *client = to_i2c_client(dev); 115 + struct hps_drvdata *hps = i2c_get_clientdata(client); 116 + 117 + hps_set_power(hps, false); 118 + return 0; 119 + } 120 + 121 + static int hps_resume(struct device *dev) 122 + { 123 + struct i2c_client *client = to_i2c_client(dev); 124 + struct hps_drvdata *hps = i2c_get_clientdata(client); 125 + 126 + hps_set_power(hps, true); 127 + return 0; 128 + } 129 + static UNIVERSAL_DEV_PM_OPS(hps_pm_ops, hps_suspend, hps_resume, NULL); 130 + 131 + static const struct i2c_device_id hps_i2c_id[] = { 132 + { "cros-hps", 0 }, 133 + { } 134 + }; 135 + MODULE_DEVICE_TABLE(i2c, hps_i2c_id); 136 + 137 + #ifdef CONFIG_ACPI 138 + static const struct acpi_device_id hps_acpi_id[] = { 139 + { HPS_ACPI_ID, 0 }, 140 + { } 141 + }; 142 + MODULE_DEVICE_TABLE(acpi, hps_acpi_id); 143 + #endif /* CONFIG_ACPI */ 144 + 145 + static struct i2c_driver hps_i2c_driver = { 146 + .probe_new = hps_i2c_probe, 147 + .remove = hps_i2c_remove, 148 + .id_table = hps_i2c_id, 149 + .driver = { 150 + .name = "cros-hps", 151 + .pm = &hps_pm_ops, 152 + .acpi_match_table = ACPI_PTR(hps_acpi_id), 153 + }, 154 + }; 155 + module_i2c_driver(hps_i2c_driver); 156 + 157 + MODULE_ALIAS("acpi:" HPS_ACPI_ID); 158 + MODULE_AUTHOR("Sami Kyöstilä <skyostil@chromium.org>"); 159 + MODULE_DESCRIPTION("Driver for ChromeOS HPS"); 160 + MODULE_LICENSE("GPL");
+5 -1
drivers/platform/chrome/cros_usbpd_notify.c
··· 239 239 return ret; 240 240 241 241 #ifdef CONFIG_ACPI 242 - platform_driver_register(&cros_usbpd_notify_acpi_driver); 242 + ret = platform_driver_register(&cros_usbpd_notify_acpi_driver); 243 + if (ret) { 244 + platform_driver_unregister(&cros_usbpd_notify_plat_driver); 245 + return ret; 246 + } 243 247 #endif 244 248 return 0; 245 249 }
-5
drivers/platform/chrome/wilco_ec/core.c
··· 129 129 unregister_debugfs: 130 130 if (ec->debugfs_pdev) 131 131 platform_device_unregister(ec->debugfs_pdev); 132 - cros_ec_lpc_mec_destroy(); 133 132 return ret; 134 133 } 135 134 ··· 142 143 platform_device_unregister(ec->rtc_pdev); 143 144 if (ec->debugfs_pdev) 144 145 platform_device_unregister(ec->debugfs_pdev); 145 - 146 - /* Teardown cros_ec interface */ 147 - cros_ec_lpc_mec_destroy(); 148 - 149 146 return 0; 150 147 } 151 148