Commit 04265849 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'chrome-platform-v6.19' of...

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

Pull chrome platform updates from Tzung-Bi Shih:
 "Improvements:

   - Support legacy probe behavior in cros_ec_lightbar and
     cros_ec_sensorhub

  Fixes:

   - Don't fall back to legacy probe behavior if it isn't a legacy
     device in cros_usbpd_notify

   - Fix an UAF after unbinding driver in cros_ec_ishtp"

* tag 'chrome-platform-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
  platform/chrome: sensorhub: Support devices without FIFO_INT_ENABLE
  platform/chrome: cros_ec_ishtp: Fix UAF after unbinding driver
  platform/chrome: cros_ec_lightbar: Check if ec supports suspend commands
  platform/chrome: cros_usbpd_notify: defer probe when parent EC driver isn't ready
parents 2aa680df 52075d2c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -667,6 +667,7 @@ static void cros_ec_ishtp_remove(struct ishtp_cl_device *cl_device)

	cancel_work_sync(&client_data->work_ishtp_reset);
	cancel_work_sync(&client_data->work_ec_evt);
	cros_ec_unregister(client_data->ec_dev);
	cros_ish_deinit(cros_ish_cl);
	ishtp_put_device(cl_device);
}
+12 −4
Original line number Diff line number Diff line
@@ -30,6 +30,13 @@ static unsigned long lb_interval_jiffies = 50 * HZ / 1000;
 */
static bool userspace_control;

/*
 * Whether or not the lightbar supports the manual suspend commands.
 * The Pixel 2013 (Link) does not while all other devices with a
 * lightbar do.
 */
static bool has_manual_suspend;

static ssize_t interval_msec_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
@@ -550,7 +557,7 @@ static int cros_ec_lightbar_probe(struct platform_device *pd)
		return -ENODEV;

	/* Take control of the lightbar from the EC. */
	lb_manual_suspend_ctrl(ec_dev, 1);
	has_manual_suspend = (lb_manual_suspend_ctrl(ec_dev, 1) != -EINVAL);

	ret = sysfs_create_group(&ec_dev->class_dev.kobj,
				 &cros_ec_lightbar_attr_group);
@@ -569,6 +576,7 @@ static void cros_ec_lightbar_remove(struct platform_device *pd)
			   &cros_ec_lightbar_attr_group);

	/* Let the EC take over the lightbar again. */
	if (has_manual_suspend)
		lb_manual_suspend_ctrl(ec_dev, 0);
}

@@ -576,7 +584,7 @@ static int __maybe_unused cros_ec_lightbar_resume(struct device *dev)
{
	struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);

	if (userspace_control)
	if (userspace_control || !has_manual_suspend)
		return 0;

	return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_RESUME);
@@ -586,7 +594,7 @@ static int __maybe_unused cros_ec_lightbar_suspend(struct device *dev)
{
	struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);

	if (userspace_control)
	if (userspace_control || !has_manual_suspend)
		return 0;

	return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_SUSPEND);
+11 −0
Original line number Diff line number Diff line
@@ -129,6 +129,17 @@ int cros_ec_sensorhub_ring_fifo_enable(struct cros_ec_sensorhub *sensorhub,
	/* We expect to receive a payload of 4 bytes, ignore. */
	if (ret > 0)
		ret = 0;
	/*
	 * Some platforms (such as Smaug) don't support the FIFO_INT_ENABLE
	 * command and the interrupt is always enabled.  In the case, it
	 * returns -EINVAL.
	 *
	 * N.B: there is no danger of -EINVAL meaning any other invalid
	 * parameter since fifo_int_enable.enable is a bool and can never
	 * be in an invalid range.
	 */
	else if (ret == -EINVAL)
		ret = 0;

	return ret;
}
+15 −2
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 */

#include <linux/acpi.h>
#include <linux/fwnode.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_data/cros_ec_proto.h>
@@ -15,6 +16,7 @@
#define DRV_NAME "cros-usbpd-notify"
#define DRV_NAME_PLAT_ACPI "cros-usbpd-notify-acpi"
#define ACPI_DRV_NAME "GOOG0003"
#define CREC_DRV_NAME "GOOG0004"

static BLOCKING_NOTIFIER_HEAD(cros_usbpd_notifier_list);

@@ -98,8 +100,9 @@ static int cros_usbpd_notify_probe_acpi(struct platform_device *pdev)
{
	struct cros_usbpd_notify_data *pdnotify;
	struct device *dev = &pdev->dev;
	struct acpi_device *adev;
	struct acpi_device *adev, *parent_adev;
	struct cros_ec_device *ec_dev;
	struct fwnode_handle *parent_fwnode;
	acpi_status status;

	adev = ACPI_COMPANION(dev);
@@ -114,8 +117,18 @@ static int cros_usbpd_notify_probe_acpi(struct platform_device *pdev)
		/*
		 * We continue even for older devices which don't have the
		 * correct device heirarchy, namely, GOOG0003 is a child
		 * of GOOG0004.
		 * of GOOG0004. If GOOG0003 is a child of GOOG0004 and we
		 * can't get a pointer to the Chrome EC device, defer the
		 * probe function.
		 */
		parent_fwnode = fwnode_get_parent(dev->fwnode);
		if (parent_fwnode) {
			parent_adev = to_acpi_device_node(parent_fwnode);
			if (parent_adev &&
			    acpi_dev_hid_match(parent_adev, CREC_DRV_NAME)) {
				return -EPROBE_DEFER;
			}
		}
		dev_warn(dev, "Couldn't get Chrome EC device pointer.\n");
	}