diff options
Diffstat (limited to 'drivers/platform/chrome')
25 files changed, 254 insertions, 104 deletions
| diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index 7d82a0946e1c..7a83346bfa53 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -299,12 +299,12 @@ config CROS_TYPEC_SWITCH  source "drivers/platform/chrome/wilco_ec/Kconfig"  # Kunit test cases -config CROS_KUNIT -	tristate "Kunit tests for ChromeOS" if !KUNIT_ALL_TESTS +config CROS_KUNIT_EC_PROTO_TEST +	tristate "Kunit tests for ChromeOS EC protocol" if !KUNIT_ALL_TESTS  	depends on KUNIT && CROS_EC  	default KUNIT_ALL_TESTS  	select CROS_EC_PROTO  	help -	  ChromeOS Kunit tests. +	  Kunit tests for ChromeOS EC protocol.  endif # CHROMEOS_PLATFORMS diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index 9e26e45c4a37..2dcc6ccc2302 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile @@ -36,6 +36,5 @@ obj-$(CONFIG_CROS_USBPD_NOTIFY)		+= cros_usbpd_notify.o  obj-$(CONFIG_WILCO_EC)			+= wilco_ec/  # Kunit test cases -obj-$(CONFIG_CROS_KUNIT)		+= cros_kunit.o -cros_kunit-objs				:= cros_kunit_util.o -cros_kunit-objs				+= cros_ec_proto_test.o +obj-$(CONFIG_CROS_KUNIT_EC_PROTO_TEST)	+= cros_kunit_proto_test.o +cros_kunit_proto_test-objs		:= cros_ec_proto_test_util.o cros_ec_proto_test.o diff --git a/drivers/platform/chrome/chromeos_acpi.c b/drivers/platform/chrome/chromeos_acpi.c index 50d8a4d4352d..e6e6dcfc74d1 100644 --- a/drivers/platform/chrome/chromeos_acpi.c +++ b/drivers/platform/chrome/chromeos_acpi.c @@ -90,7 +90,36 @@ static int chromeos_acpi_handle_package(struct device *dev, union acpi_object *o  	case ACPI_TYPE_STRING:  		return sysfs_emit(buf, "%s\n", element->string.pointer);  	case ACPI_TYPE_BUFFER: -		return sysfs_emit(buf, "%s\n", element->buffer.pointer); +		{ +			int i, r, at, room_left; +			const int byte_per_line = 16; + +			at = 0; +			room_left = PAGE_SIZE - 1; +			for (i = 0; i < element->buffer.length && room_left; i += byte_per_line) { +				r = hex_dump_to_buffer(element->buffer.pointer + i, +						       element->buffer.length - i, +						       byte_per_line, 1, buf + at, room_left, +						       false); +				if (r > room_left) +					goto truncating; +				at += r; +				room_left -= r; + +				r = sysfs_emit_at(buf, at, "\n"); +				if (!r) +					goto truncating; +				at += r; +				room_left -= r; +			} + +			buf[at] = 0; +			return at; +truncating: +			dev_info_once(dev, "truncating sysfs content for %s\n", name); +			sysfs_emit_at(buf, PAGE_SIZE - 4, "..\n"); +			return PAGE_SIZE - 1; +		}  	default:  		dev_err(dev, "element type %d not supported\n", element->type);  		return -EINVAL; @@ -235,9 +264,9 @@ static int chromeos_acpi_device_probe(struct platform_device *pdev)  	return 0;  } -/* GGL is valid PNP ID of Google. PNP ID can be used with the ACPI devices. */  static const struct acpi_device_id chromeos_device_ids[] = {  	{ "GGL0001", 0 }, +	{ "GOOG0016", 0 },  	{}  };  MODULE_DEVICE_TABLE(acpi, chromeos_device_ids); diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index 8b7949220382..badc68bbae8c 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -12,6 +12,7 @@  #include <linux/interrupt.h>  #include <linux/module.h>  #include <linux/of_platform.h> +#include <linux/platform_device.h>  #include <linux/platform_data/cros_ec_commands.h>  #include <linux/platform_data/cros_ec_proto.h>  #include <linux/slab.h> @@ -320,17 +321,8 @@ void cros_ec_unregister(struct cros_ec_device *ec_dev)  EXPORT_SYMBOL(cros_ec_unregister);  #ifdef CONFIG_PM_SLEEP -/** - * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. - * @ec_dev: Device to suspend. - * - * This can be called by drivers to handle a suspend event. - * - * Return: 0 on success or negative error code. - */ -int cros_ec_suspend(struct cros_ec_device *ec_dev) +static void cros_ec_send_suspend_event(struct cros_ec_device *ec_dev)  { -	struct device *dev = ec_dev->dev;  	int ret;  	u8 sleep_event; @@ -342,7 +334,26 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)  	if (ret < 0)  		dev_dbg(ec_dev->dev, "Error %d sending suspend event to ec\n",  			ret); +} +/** + * cros_ec_suspend_prepare() - Handle a suspend prepare operation for the ChromeOS EC device. + * @ec_dev: Device to suspend. + * + * This can be called by drivers to handle a suspend prepare stage of suspend. + * + * Return: 0 always. + */ +int cros_ec_suspend_prepare(struct cros_ec_device *ec_dev) +{ +	cros_ec_send_suspend_event(ec_dev); +	return 0; +} +EXPORT_SYMBOL(cros_ec_suspend_prepare); + +static void cros_ec_disable_irq(struct cros_ec_device *ec_dev) +{ +	struct device *dev = ec_dev->dev;  	if (device_may_wakeup(dev))  		ec_dev->wake_enabled = !enable_irq_wake(ec_dev->irq);  	else @@ -350,7 +361,35 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)  	disable_irq(ec_dev->irq);  	ec_dev->suspended = true; +} +/** + * cros_ec_suspend_late() - Handle a suspend late operation for the ChromeOS EC device. + * @ec_dev: Device to suspend. + * + * This can be called by drivers to handle a suspend late stage of suspend. + * + * Return: 0 always. + */ +int cros_ec_suspend_late(struct cros_ec_device *ec_dev) +{ +	cros_ec_disable_irq(ec_dev); +	return 0; +} +EXPORT_SYMBOL(cros_ec_suspend_late); + +/** + * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. + * @ec_dev: Device to suspend. + * + * This can be called by drivers to handle a suspend event. + * + * Return: 0 always. + */ +int cros_ec_suspend(struct cros_ec_device *ec_dev) +{ +	cros_ec_send_suspend_event(ec_dev); +	cros_ec_disable_irq(ec_dev);  	return 0;  }  EXPORT_SYMBOL(cros_ec_suspend); @@ -369,22 +408,11 @@ static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev)  	}  } -/** - * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. - * @ec_dev: Device to resume. - * - * This can be called by drivers to handle a resume event. - * - * Return: 0 on success or negative error code. - */ -int cros_ec_resume(struct cros_ec_device *ec_dev) +static void cros_ec_send_resume_event(struct cros_ec_device *ec_dev)  {  	int ret;  	u8 sleep_event; -	ec_dev->suspended = false; -	enable_irq(ec_dev->irq); -  	sleep_event = (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) ?  		      HOST_SLEEP_EVENT_S3_RESUME :  		      HOST_SLEEP_EVENT_S0IX_RESUME; @@ -393,6 +421,24 @@ int cros_ec_resume(struct cros_ec_device *ec_dev)  	if (ret < 0)  		dev_dbg(ec_dev->dev, "Error %d sending resume event to ec\n",  			ret); +} + +/** + * cros_ec_resume_complete() - Handle a resume complete operation for the ChromeOS EC device. + * @ec_dev: Device to resume. + * + * This can be called by drivers to handle a resume complete stage of resume. + */ +void cros_ec_resume_complete(struct cros_ec_device *ec_dev) +{ +	cros_ec_send_resume_event(ec_dev); +} +EXPORT_SYMBOL(cros_ec_resume_complete); + +static void cros_ec_enable_irq(struct cros_ec_device *ec_dev) +{ +	ec_dev->suspended = false; +	enable_irq(ec_dev->irq);  	if (ec_dev->wake_enabled)  		disable_irq_wake(ec_dev->irq); @@ -402,8 +448,35 @@ int cros_ec_resume(struct cros_ec_device *ec_dev)  	 * suspend. This way the clients know what to do with them.  	 */  	cros_ec_report_events_during_suspend(ec_dev); +} +/** + * cros_ec_resume_early() - Handle a resume early operation for the ChromeOS EC device. + * @ec_dev: Device to resume. + * + * This can be called by drivers to handle a resume early stage of resume. + * + * Return: 0 always. + */ +int cros_ec_resume_early(struct cros_ec_device *ec_dev) +{ +	cros_ec_enable_irq(ec_dev); +	return 0; +} +EXPORT_SYMBOL(cros_ec_resume_early); +/** + * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. + * @ec_dev: Device to resume. + * + * This can be called by drivers to handle a resume event. + * + * Return: 0 always. + */ +int cros_ec_resume(struct cros_ec_device *ec_dev) +{ +	cros_ec_enable_irq(ec_dev); +	cros_ec_send_resume_event(ec_dev);  	return 0;  }  EXPORT_SYMBOL(cros_ec_resume); diff --git a/drivers/platform/chrome/cros_ec.h b/drivers/platform/chrome/cros_ec.h index bbca0096868a..6b95f1e0bace 100644 --- a/drivers/platform/chrome/cros_ec.h +++ b/drivers/platform/chrome/cros_ec.h @@ -10,11 +10,17 @@  #include <linux/interrupt.h> +struct cros_ec_device; +  int cros_ec_register(struct cros_ec_device *ec_dev);  void cros_ec_unregister(struct cros_ec_device *ec_dev);  int cros_ec_suspend(struct cros_ec_device *ec_dev); +int cros_ec_suspend_late(struct cros_ec_device *ec_dev); +int cros_ec_suspend_prepare(struct cros_ec_device *ec_dev);  int cros_ec_resume(struct cros_ec_device *ec_dev); +int cros_ec_resume_early(struct cros_ec_device *ec_dev); +void cros_ec_resume_complete(struct cros_ec_device *ec_dev);  irqreturn_t cros_ec_irq_thread(int irq, void *data); diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c index d6de5a294128..81950bb2c6da 100644 --- a/drivers/platform/chrome/cros_ec_chardev.c +++ b/drivers/platform/chrome/cros_ec_chardev.c @@ -396,13 +396,11 @@ static int cros_ec_chardev_probe(struct platform_device *pdev)  	return misc_register(&data->misc);  } -static int cros_ec_chardev_remove(struct platform_device *pdev) +static void cros_ec_chardev_remove(struct platform_device *pdev)  {  	struct chardev_data *data = dev_get_drvdata(&pdev->dev);  	misc_deregister(&data->misc); - -	return 0;  }  static struct platform_driver cros_ec_chardev_driver = { @@ -410,7 +408,7 @@ static struct platform_driver cros_ec_chardev_driver = {  		.name = DRV_NAME,  	},  	.probe = cros_ec_chardev_probe, -	.remove = cros_ec_chardev_remove, +	.remove_new = cros_ec_chardev_remove,  };  module_platform_driver(cros_ec_chardev_driver); diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c index c876120e0ebc..091fdc154d79 100644 --- a/drivers/platform/chrome/cros_ec_debugfs.c +++ b/drivers/platform/chrome/cros_ec_debugfs.c @@ -533,14 +533,12 @@ remove_debugfs:  	return ret;  } -static int cros_ec_debugfs_remove(struct platform_device *pd) +static void cros_ec_debugfs_remove(struct platform_device *pd)  {  	struct cros_ec_dev *ec = dev_get_drvdata(pd->dev.parent);  	debugfs_remove_recursive(ec->debug_info->dir);  	cros_ec_cleanup_console_log(ec->debug_info); - -	return 0;  }  static int __maybe_unused cros_ec_debugfs_suspend(struct device *dev) @@ -573,7 +571,7 @@ static struct platform_driver cros_ec_debugfs_driver = {  		.probe_type = PROBE_PREFER_ASYNCHRONOUS,  	},  	.probe = cros_ec_debugfs_probe, -	.remove = cros_ec_debugfs_remove, +	.remove_new = cros_ec_debugfs_remove,  };  module_platform_driver(cros_ec_debugfs_driver); diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c index 376425bbd8ff..6677cc6c4984 100644 --- a/drivers/platform/chrome/cros_ec_lightbar.c +++ b/drivers/platform/chrome/cros_ec_lightbar.c @@ -560,7 +560,7 @@ static int cros_ec_lightbar_probe(struct platform_device *pd)  	return ret;  } -static int cros_ec_lightbar_remove(struct platform_device *pd) +static void cros_ec_lightbar_remove(struct platform_device *pd)  {  	struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); @@ -569,8 +569,6 @@ static int cros_ec_lightbar_remove(struct platform_device *pd)  	/* Let the EC take over the lightbar again. */  	lb_manual_suspend_ctrl(ec_dev, 0); - -	return 0;  }  static int __maybe_unused cros_ec_lightbar_resume(struct device *dev) @@ -603,7 +601,7 @@ static struct platform_driver cros_ec_lightbar_driver = {  		.probe_type = PROBE_PREFER_ASYNCHRONOUS,  	},  	.probe = cros_ec_lightbar_probe, -	.remove = cros_ec_lightbar_remove, +	.remove_new = cros_ec_lightbar_remove,  };  module_platform_driver(cros_ec_lightbar_driver); diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 500a61b093e4..f0f3d3d56157 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -327,8 +327,8 @@ static void cros_ec_lpc_acpi_notify(acpi_handle device, u32 value, void *data)  		dev_emerg(ec_dev->dev, "CrOS EC Panic Reported. Shutdown is imminent!");  		blocking_notifier_call_chain(&ec_dev->panic_notifier, 0, ec_dev);  		kobject_uevent_env(&ec_dev->dev->kobj, KOBJ_CHANGE, (char **)env); -		/* Begin orderly shutdown. Force shutdown after 1 second. */ -		hw_protection_shutdown("CrOS EC Panic", 1000); +		/* Begin orderly shutdown. EC will force reset after a short period. */ +		hw_protection_shutdown("CrOS EC Panic", -1);  		/* Do not query for other events after a panic is reported */  		return;  	} @@ -460,7 +460,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)  	return 0;  } -static int cros_ec_lpc_remove(struct platform_device *pdev) +static void cros_ec_lpc_remove(struct platform_device *pdev)  {  	struct cros_ec_device *ec_dev = platform_get_drvdata(pdev);  	struct acpi_device *adev; @@ -471,8 +471,6 @@ static int cros_ec_lpc_remove(struct platform_device *pdev)  					   cros_ec_lpc_acpi_notify);  	cros_ec_unregister(ec_dev); - -	return 0;  }  static const struct acpi_device_id cros_ec_lpc_acpi_device_ids[] = { @@ -549,22 +547,36 @@ MODULE_DEVICE_TABLE(dmi, cros_ec_lpc_dmi_table);  static int cros_ec_lpc_prepare(struct device *dev)  {  	struct cros_ec_device *ec_dev = dev_get_drvdata(dev); - -	return cros_ec_suspend(ec_dev); +	return cros_ec_suspend_prepare(ec_dev);  }  static void cros_ec_lpc_complete(struct device *dev)  {  	struct cros_ec_device *ec_dev = dev_get_drvdata(dev); -	cros_ec_resume(ec_dev); +	cros_ec_resume_complete(ec_dev); +} + +static int cros_ec_lpc_suspend_late(struct device *dev) +{ +	struct cros_ec_device *ec_dev = dev_get_drvdata(dev); + +	return cros_ec_suspend_late(ec_dev); +} + +static int cros_ec_lpc_resume_early(struct device *dev) +{ +	struct cros_ec_device *ec_dev = dev_get_drvdata(dev); + +	return cros_ec_resume_early(ec_dev);  }  #endif  static const struct dev_pm_ops cros_ec_lpc_pm_ops = {  #ifdef CONFIG_PM_SLEEP  	.prepare = cros_ec_lpc_prepare, -	.complete = cros_ec_lpc_complete +	.complete = cros_ec_lpc_complete,  #endif +	SET_LATE_SYSTEM_SLEEP_PM_OPS(cros_ec_lpc_suspend_late, cros_ec_lpc_resume_early)  };  static struct platform_driver cros_ec_lpc_driver = { @@ -580,7 +592,7 @@ static struct platform_driver cros_ec_lpc_driver = {  		.probe_type = PROBE_FORCE_SYNCHRONOUS,  	},  	.probe = cros_ec_lpc_probe, -	.remove = cros_ec_lpc_remove, +	.remove_new = cros_ec_lpc_remove,  };  static struct platform_device cros_ec_lpc_device = { diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 475a6dd72db6..945b1b15a04c 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -1004,7 +1004,7 @@ EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count);  int cros_ec_cmd(struct cros_ec_device *ec_dev,  		unsigned int version,  		int command, -		void *outdata, +		const void *outdata,  		size_t outsize,  		void *indata,  		size_t insize) diff --git a/drivers/platform/chrome/cros_ec_proto_test.c b/drivers/platform/chrome/cros_ec_proto_test.c index 5b9748e0463b..b6169d6f2467 100644 --- a/drivers/platform/chrome/cros_ec_proto_test.c +++ b/drivers/platform/chrome/cros_ec_proto_test.c @@ -11,7 +11,7 @@  #include <linux/platform_data/cros_ec_proto.h>  #include "cros_ec.h" -#include "cros_kunit_util.h" +#include "cros_ec_proto_test_util.h"  #define BUFSIZE 512 @@ -2668,6 +2668,7 @@ static int cros_ec_proto_test_init(struct kunit *test)  	ec_dev->dev->release = cros_ec_proto_test_release;  	ec_dev->cmd_xfer = cros_kunit_ec_xfer_mock;  	ec_dev->pkt_xfer = cros_kunit_ec_xfer_mock; +	mutex_init(&ec_dev->lock);  	priv->msg = (struct cros_ec_command *)priv->_msg; diff --git a/drivers/platform/chrome/cros_kunit_util.c b/drivers/platform/chrome/cros_ec_proto_test_util.c index f0fda96b11bd..65d328bcd6eb 100644 --- a/drivers/platform/chrome/cros_kunit_util.c +++ b/drivers/platform/chrome/cros_ec_proto_test_util.c @@ -11,7 +11,7 @@  #include <linux/platform_data/cros_ec_proto.h>  #include "cros_ec.h" -#include "cros_kunit_util.h" +#include "cros_ec_proto_test_util.h"  int cros_kunit_ec_xfer_mock_default_result;  int cros_kunit_ec_xfer_mock_default_ret; @@ -126,5 +126,3 @@ void cros_kunit_mock_reset(void)  	cros_kunit_readmem_mock_data = NULL;  	cros_kunit_readmem_mock_ret = 0;  } - -MODULE_LICENSE("GPL"); diff --git a/drivers/platform/chrome/cros_kunit_util.h b/drivers/platform/chrome/cros_ec_proto_test_util.h index 414002271c9c..414002271c9c 100644 --- a/drivers/platform/chrome/cros_kunit_util.h +++ b/drivers/platform/chrome/cros_ec_proto_test_util.h diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c index 09e3bf5e8ec6..93e67ab4af06 100644 --- a/drivers/platform/chrome/cros_ec_sysfs.c +++ b/drivers/platform/chrome/cros_ec_sysfs.c @@ -340,13 +340,11 @@ static int cros_ec_sysfs_probe(struct platform_device *pd)  	return ret;  } -static int cros_ec_sysfs_remove(struct platform_device *pd) +static void cros_ec_sysfs_remove(struct platform_device *pd)  {  	struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);  	sysfs_remove_group(&ec_dev->class_dev.kobj, &cros_ec_attr_group); - -	return 0;  }  static struct platform_driver cros_ec_sysfs_driver = { @@ -354,7 +352,7 @@ static struct platform_driver cros_ec_sysfs_driver = {  		.name = DRV_NAME,  	},  	.probe = cros_ec_sysfs_probe, -	.remove = cros_ec_sysfs_remove, +	.remove_new = cros_ec_sysfs_remove,  };  module_platform_driver(cros_ec_sysfs_driver); diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 25f9767c28e8..2b2f14a1b711 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -80,28 +80,28 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port,  	port->mux = fwnode_typec_mux_get(fwnode);  	if (IS_ERR(port->mux)) {  		ret = PTR_ERR(port->mux); -		dev_dbg(dev, "Mux handle not found: %d.\n", ret); +		dev_err_probe(dev, ret, "Mux handle not found\n");  		goto mux_err;  	}  	port->retimer = fwnode_typec_retimer_get(fwnode);  	if (IS_ERR(port->retimer)) {  		ret = PTR_ERR(port->retimer); -		dev_dbg(dev, "Retimer handle not found: %d.\n", ret); +		dev_err_probe(dev, ret, "Retimer handle not found\n");  		goto retimer_sw_err;  	}  	port->ori_sw = fwnode_typec_switch_get(fwnode);  	if (IS_ERR(port->ori_sw)) {  		ret = PTR_ERR(port->ori_sw); -		dev_dbg(dev, "Orientation switch handle not found: %d\n", ret); +		dev_err_probe(dev, ret, "Orientation switch handle not found\n");  		goto ori_sw_err;  	}  	port->role_sw = fwnode_usb_role_switch_get(fwnode);  	if (IS_ERR(port->role_sw)) {  		ret = PTR_ERR(port->role_sw); -		dev_dbg(dev, "USB role switch handle not found: %d\n", ret); +		dev_err_probe(dev, ret, "USB role switch handle not found\n");  		goto role_sw_err;  	} @@ -271,9 +271,9 @@ static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,  	struct typec_altmode *amode;  	/* All PD capable CrOS devices are assumed to support DP altmode. */ -	desc.svid = USB_TYPEC_DP_SID, -	desc.mode = USB_TYPEC_DP_MODE, -	desc.vdo = DP_PORT_VDO, +	desc.svid = USB_TYPEC_DP_SID; +	desc.mode = USB_TYPEC_DP_MODE; +	desc.vdo = DP_PORT_VDO;  	amode = typec_port_register_altmode(port->port, &desc);  	if (IS_ERR(amode))  		return PTR_ERR(amode); @@ -287,8 +287,8 @@ static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,  	 * here for now.  	 */  	memset(&desc, 0, sizeof(desc)); -	desc.svid = USB_TYPEC_TBT_SID, -	desc.mode = TYPEC_ANY_MODE, +	desc.svid = USB_TYPEC_TBT_SID; +	desc.mode = TYPEC_ANY_MODE;  	amode = typec_port_register_altmode(port->port, &desc);  	if (IS_ERR(amode))  		return PTR_ERR(amode); @@ -406,6 +406,27 @@ static int cros_typec_usb_safe_state(struct cros_typec_port *port)  	return ret;  } +/** + * cros_typec_get_cable_vdo() - Get Cable VDO of the connected cable + * @port: Type-C port data + * @svid: Standard or Vendor ID to match + * + * Returns the Cable VDO if match is found and returns 0 if match is not found. + */ +static int cros_typec_get_cable_vdo(struct cros_typec_port *port, u16 svid) +{ +	struct list_head *head = &port->plug_mode_list; +	struct cros_typec_altmode_node *node; +	u32 ret = 0; + +	list_for_each_entry(node, head, list) { +		if (node->amode->svid == svid) +			return node->amode->vdo; +	} + +	return ret; +} +  /*   * Spoof the VDOs that were likely communicated by the partner for TBT alt   * mode. @@ -432,6 +453,9 @@ static int cros_typec_enable_tbt(struct cros_typec_data *typec,  	/* Cable Discover Mode VDO */  	data.cable_mode = TBT_MODE; + +	data.cable_mode |= cros_typec_get_cable_vdo(port, USB_TYPEC_TBT_SID); +  	data.cable_mode |= TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);  	if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE) @@ -468,6 +492,8 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec,  {  	struct cros_typec_port *port = typec->ports[port_num];  	struct typec_displayport_data dp_data; +	u32 cable_tbt_vdo; +	u32 cable_dp_vdo;  	int ret;  	if (typec->pd_ctrl_ver < 2) { @@ -500,6 +526,32 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec,  	port->state.data = &dp_data;  	port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode)); +	/* Get cable VDO for cables with DPSID to check DPAM2.1 is supported */ +	cable_dp_vdo = cros_typec_get_cable_vdo(port, USB_TYPEC_DP_SID); + +	/** +	 * Get cable VDO for thunderbolt cables and cables with DPSID but does not +	 * support DPAM2.1. +	 */ +	cable_tbt_vdo = cros_typec_get_cable_vdo(port, USB_TYPEC_TBT_SID); + +	if (cable_dp_vdo & DP_CAP_DPAM_VERSION) { +		dp_data.conf |= cable_dp_vdo; +	} else if (cable_tbt_vdo) { +		dp_data.conf |=  TBT_CABLE_SPEED(cable_tbt_vdo) << DP_CONF_SIGNALLING_SHIFT; + +		/* Cable Type */ +		if (cable_tbt_vdo & TBT_CABLE_OPTICAL) +			dp_data.conf |= DP_CONF_CABLE_TYPE_OPTICAL << DP_CONF_CABLE_TYPE_SHIFT; +		else if (cable_tbt_vdo & TBT_CABLE_RETIMER) +			dp_data.conf |= DP_CONF_CABLE_TYPE_RE_TIMER << DP_CONF_CABLE_TYPE_SHIFT; +		else if (cable_tbt_vdo & TBT_CABLE_ACTIVE_PASSIVE) +			dp_data.conf |= DP_CONF_CABLE_TYPE_RE_DRIVER << DP_CONF_CABLE_TYPE_SHIFT; +	} else if (PD_IDH_PTYPE(port->c_identity.id_header) == IDH_PTYPE_PCABLE) { +		dp_data.conf |= VDO_TYPEC_CABLE_SPEED(port->c_identity.vdo[0]) << +				DP_CONF_SIGNALLING_SHIFT; +	} +  	ret = cros_typec_retimer_set(port->retimer, port->state);  	if (!ret)  		ret = typec_mux_set(port->mux, &port->state); @@ -522,8 +574,10 @@ static int cros_typec_enable_usb4(struct cros_typec_data *typec,  	/* Cable Type */  	if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)  		data.eudo |= EUDO_CABLE_TYPE_OPTICAL << EUDO_CABLE_TYPE_SHIFT; -	else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE) +	else if (cros_typec_get_cable_vdo(port, USB_TYPEC_TBT_SID) & TBT_CABLE_RETIMER)  		data.eudo |= EUDO_CABLE_TYPE_RE_TIMER << EUDO_CABLE_TYPE_SHIFT; +	else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE) +		data.eudo |= EUDO_CABLE_TYPE_RE_DRIVER << EUDO_CABLE_TYPE_SHIFT;  	data.active_link_training = !!(pd_ctrl->control_flags &  				       USB_PD_CTRL_ACTIVE_LINK_UNIDIR); diff --git a/drivers/platform/chrome/cros_ec_vbc.c b/drivers/platform/chrome/cros_ec_vbc.c index c859c862d7ac..2e4af10c7679 100644 --- a/drivers/platform/chrome/cros_ec_vbc.c +++ b/drivers/platform/chrome/cros_ec_vbc.c @@ -121,14 +121,12 @@ static int cros_ec_vbc_probe(struct platform_device *pd)  	return ret;  } -static int cros_ec_vbc_remove(struct platform_device *pd) +static void cros_ec_vbc_remove(struct platform_device *pd)  {  	struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);  	sysfs_remove_group(&ec_dev->class_dev.kobj,  			   &cros_ec_vbc_attr_group); - -	return 0;  }  static struct platform_driver cros_ec_vbc_driver = { @@ -136,7 +134,7 @@ static struct platform_driver cros_ec_vbc_driver = {  		.name = DRV_NAME,  	},  	.probe = cros_ec_vbc_probe, -	.remove = cros_ec_vbc_remove, +	.remove_new = cros_ec_vbc_remove,  };  module_platform_driver(cros_ec_vbc_driver); diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c index 0eefdcf14d63..07a19386dc4e 100644 --- a/drivers/platform/chrome/cros_typec_switch.c +++ b/drivers/platform/chrome/cros_typec_switch.c @@ -297,12 +297,11 @@ static int cros_typec_switch_probe(struct platform_device *pdev)  	return cros_typec_register_switches(sdata);  } -static int cros_typec_switch_remove(struct platform_device *pdev) +static void cros_typec_switch_remove(struct platform_device *pdev)  {  	struct cros_typec_switch_data *sdata = platform_get_drvdata(pdev);  	cros_typec_unregister_switches(sdata); -	return 0;  }  #ifdef CONFIG_ACPI @@ -319,7 +318,7 @@ static struct platform_driver cros_typec_switch_driver = {  		.acpi_match_table = ACPI_PTR(cros_typec_switch_acpi_id),  	},  	.probe = cros_typec_switch_probe, -	.remove = cros_typec_switch_remove, +	.remove_new = cros_typec_switch_remove,  };  module_platform_driver(cros_typec_switch_driver); diff --git a/drivers/platform/chrome/cros_typec_vdm.c b/drivers/platform/chrome/cros_typec_vdm.c index 20515ee0a20e..3f632fd35000 100644 --- a/drivers/platform/chrome/cros_typec_vdm.c +++ b/drivers/platform/chrome/cros_typec_vdm.c @@ -142,7 +142,7 @@ static int cros_typec_port_amode_vdm(struct typec_altmode *amode, const u32 hdr,  			   sizeof(req), NULL, 0);  } -struct typec_altmode_ops port_amode_ops = { +const struct typec_altmode_ops port_amode_ops = {  	.enter = cros_typec_port_amode_enter,  	.vdm = cros_typec_port_amode_vdm,  }; diff --git a/drivers/platform/chrome/cros_typec_vdm.h b/drivers/platform/chrome/cros_typec_vdm.h index 95a6a75d32b6..631bd2ce4b00 100644 --- a/drivers/platform/chrome/cros_typec_vdm.h +++ b/drivers/platform/chrome/cros_typec_vdm.h @@ -5,7 +5,7 @@  #include <linux/usb/typec_altmode.h> -extern struct typec_altmode_ops port_amode_ops; +extern const struct typec_altmode_ops port_amode_ops;  void cros_typec_handle_vdm_attention(struct cros_typec_data *typec, int port_num);  void cros_typec_handle_vdm_response(struct cros_typec_data *typec, int port_num); diff --git a/drivers/platform/chrome/cros_usbpd_logger.c b/drivers/platform/chrome/cros_usbpd_logger.c index d16931203d82..f618757f8b32 100644 --- a/drivers/platform/chrome/cros_usbpd_logger.c +++ b/drivers/platform/chrome/cros_usbpd_logger.c @@ -219,14 +219,12 @@ static int cros_usbpd_logger_probe(struct platform_device *pd)  	return 0;  } -static int cros_usbpd_logger_remove(struct platform_device *pd) +static void cros_usbpd_logger_remove(struct platform_device *pd)  {  	struct logger_data *logger = platform_get_drvdata(pd);  	cancel_delayed_work_sync(&logger->log_work);  	destroy_workqueue(logger->log_workqueue); - -	return 0;  }  static int __maybe_unused cros_usbpd_logger_resume(struct device *dev) @@ -257,7 +255,7 @@ static struct platform_driver cros_usbpd_logger_driver = {  		.pm = &cros_usbpd_logger_pm_ops,  	},  	.probe = cros_usbpd_logger_probe, -	.remove = cros_usbpd_logger_remove, +	.remove_new = cros_usbpd_logger_remove,  };  module_platform_driver(cros_usbpd_logger_driver); diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c index 10670b6588e3..aacad022f21d 100644 --- a/drivers/platform/chrome/cros_usbpd_notify.c +++ b/drivers/platform/chrome/cros_usbpd_notify.c @@ -134,15 +134,13 @@ static int cros_usbpd_notify_probe_acpi(struct platform_device *pdev)  	return 0;  } -static int cros_usbpd_notify_remove_acpi(struct platform_device *pdev) +static void cros_usbpd_notify_remove_acpi(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct acpi_device *adev = ACPI_COMPANION(dev);  	acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY,  				   cros_usbpd_notify_acpi); - -	return 0;  }  static const struct acpi_device_id cros_usbpd_notify_acpi_device_ids[] = { @@ -157,7 +155,7 @@ static struct platform_driver cros_usbpd_notify_acpi_driver = {  		.acpi_match_table = cros_usbpd_notify_acpi_device_ids,  	},  	.probe = cros_usbpd_notify_probe_acpi, -	.remove = cros_usbpd_notify_remove_acpi, +	.remove_new = cros_usbpd_notify_remove_acpi,  };  #endif /* CONFIG_ACPI */ @@ -209,7 +207,7 @@ static int cros_usbpd_notify_probe_plat(struct platform_device *pdev)  	return 0;  } -static int cros_usbpd_notify_remove_plat(struct platform_device *pdev) +static void cros_usbpd_notify_remove_plat(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct cros_ec_dev *ecdev = dev_get_drvdata(dev->parent); @@ -218,8 +216,6 @@ static int cros_usbpd_notify_remove_plat(struct platform_device *pdev)  	blocking_notifier_chain_unregister(&ecdev->ec_dev->event_notifier,  					   &pdnotify->nb); - -	return 0;  }  static struct platform_driver cros_usbpd_notify_plat_driver = { @@ -227,7 +223,7 @@ static struct platform_driver cros_usbpd_notify_plat_driver = {  		.name = DRV_NAME,  	},  	.probe = cros_usbpd_notify_probe_plat, -	.remove = cros_usbpd_notify_remove_plat, +	.remove_new = cros_usbpd_notify_remove_plat,  };  static int __init cros_usbpd_notify_init(void) diff --git a/drivers/platform/chrome/wilco_ec/core.c b/drivers/platform/chrome/wilco_ec/core.c index d6a994bdc182..9b59a1bed286 100644 --- a/drivers/platform/chrome/wilco_ec/core.c +++ b/drivers/platform/chrome/wilco_ec/core.c @@ -132,7 +132,7 @@ unregister_debugfs:  	return ret;  } -static int wilco_ec_remove(struct platform_device *pdev) +static void wilco_ec_remove(struct platform_device *pdev)  {  	struct wilco_ec_device *ec = platform_get_drvdata(pdev); @@ -142,7 +142,6 @@ static int wilco_ec_remove(struct platform_device *pdev)  	platform_device_unregister(ec->rtc_pdev);  	if (ec->debugfs_pdev)  		platform_device_unregister(ec->debugfs_pdev); -	return 0;  }  static const struct acpi_device_id wilco_ec_acpi_device_ids[] = { @@ -157,7 +156,7 @@ static struct platform_driver wilco_ec_driver = {  		.acpi_match_table = wilco_ec_acpi_device_ids,  	},  	.probe = wilco_ec_probe, -	.remove = wilco_ec_remove, +	.remove_new = wilco_ec_remove,  };  module_platform_driver(wilco_ec_driver); diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c b/drivers/platform/chrome/wilco_ec/debugfs.c index 7a13f13b16cd..93c11f81ca45 100644 --- a/drivers/platform/chrome/wilco_ec/debugfs.c +++ b/drivers/platform/chrome/wilco_ec/debugfs.c @@ -260,11 +260,9 @@ static int wilco_ec_debugfs_probe(struct platform_device *pdev)  	return 0;  } -static int wilco_ec_debugfs_remove(struct platform_device *pdev) +static void wilco_ec_debugfs_remove(struct platform_device *pdev)  {  	debugfs_remove_recursive(debug_info->dir); - -	return 0;  }  static struct platform_driver wilco_ec_debugfs_driver = { @@ -272,7 +270,7 @@ static struct platform_driver wilco_ec_debugfs_driver = {  		.name = DRV_NAME,  	},  	.probe = wilco_ec_debugfs_probe, -	.remove = wilco_ec_debugfs_remove, +	.remove_new = wilco_ec_debugfs_remove,  };  module_platform_driver(wilco_ec_debugfs_driver); diff --git a/drivers/platform/chrome/wilco_ec/event.c b/drivers/platform/chrome/wilco_ec/event.c index a40f60bcefb6..f80a7c83cfba 100644 --- a/drivers/platform/chrome/wilco_ec/event.c +++ b/drivers/platform/chrome/wilco_ec/event.c @@ -95,7 +95,7 @@ struct ec_event_queue {  	int capacity;  	int head;  	int tail; -	struct ec_event *entries[]; +	struct ec_event *entries[] __counted_by(capacity);  };  /* Maximum number of events to store in ec_event_queue */ diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c b/drivers/platform/chrome/wilco_ec/telemetry.c index 54708aa6c700..253098bace63 100644 --- a/drivers/platform/chrome/wilco_ec/telemetry.c +++ b/drivers/platform/chrome/wilco_ec/telemetry.c @@ -400,20 +400,18 @@ static int telem_device_probe(struct platform_device *pdev)  	return 0;  } -static int telem_device_remove(struct platform_device *pdev) +static void telem_device_remove(struct platform_device *pdev)  {  	struct telem_device_data *dev_data = platform_get_drvdata(pdev);  	cdev_device_del(&dev_data->cdev, &dev_data->dev);  	ida_simple_remove(&telem_ida, MINOR(dev_data->dev.devt));  	put_device(&dev_data->dev); - -	return 0;  }  static struct platform_driver telem_driver = {  	.probe = telem_device_probe, -	.remove = telem_device_remove, +	.remove_new = telem_device_remove,  	.driver = {  		.name = DRV_NAME,  	}, |