diff options
Diffstat (limited to 'drivers/usb/misc')
| -rw-r--r-- | drivers/usb/misc/Kconfig | 26 | ||||
| -rw-r--r-- | drivers/usb/misc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/usb/misc/iowarrior.c | 11 | ||||
| -rw-r--r-- | drivers/usb/misc/ucsi.c | 478 | ||||
| -rw-r--r-- | drivers/usb/misc/ucsi.h | 215 | ||||
| -rw-r--r-- | drivers/usb/misc/usbsevseg.c | 18 | 
6 files changed, 11 insertions, 738 deletions
| diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 1d1d70d62a19..0f9f25db9163 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -275,29 +275,3 @@ config USB_CHAOSKEY  	  To compile this driver as a module, choose M here: the  	  module will be called chaoskey. - -config UCSI -	tristate "USB Type-C Connector System Software Interface driver" -	depends on ACPI -	help -	  UCSI driver is meant to be used as a convenience tool for desktop and -	  server systems that are not equipped to handle USB in device mode. It -	  will always select USB host role for the USB Type-C ports on systems -	  that provide UCSI interface. - -	  USB Type-C Connector System Software Interface (UCSI) is a -	  specification for an interface that allows the Operating System to -	  control the USB Type-C ports on a system. Things the need controlling -	  include the USB Data Role (host or device), and when USB Power -	  Delivery is supported, the Power Role (source or sink). With USB -	  Type-C connectors, when two dual role capable devices are attached -	  together, the data role is selected randomly. Therefore it is -	  important to give the OS a way to select the role. Otherwise the user -	  would have to unplug and replug in order in order to attempt to swap -	  the data and power roles. - -	  The UCSI specification can be downloaded from: -	  http://www.intel.com/content/www/us/en/io/universal-serial-bus/usb-type-c-ucsi-spec.html - -	  To compile the driver as a module, choose M here: the module will be -	  called ucsi. diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index f6ac6c99a6e6..7fdb45fc976f 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_USB_HUB_USB251XB)		+= usb251xb.o  obj-$(CONFIG_USB_HSIC_USB3503)		+= usb3503.o  obj-$(CONFIG_USB_HSIC_USB4604)		+= usb4604.o  obj-$(CONFIG_USB_CHAOSKEY)		+= chaoskey.o -obj-$(CONFIG_UCSI)			+= ucsi.o  obj-$(CONFIG_USB_SISUSBVGA)		+= sisusbvga/  obj-$(CONFIG_USB_LINK_LAYER_TEST)	+= lvstest.o diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 83b05a287b0c..7ca4c7e0ea0d 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -368,14 +368,9 @@ static ssize_t iowarrior_write(struct file *file,  	case USB_DEVICE_ID_CODEMERCS_IOWPV2:  	case USB_DEVICE_ID_CODEMERCS_IOW40:  		/* IOW24 and IOW40 use a synchronous call */ -		buf = kmalloc(count, GFP_KERNEL); -		if (!buf) { -			retval = -ENOMEM; -			goto exit; -		} -		if (copy_from_user(buf, user_buffer, count)) { -			retval = -EFAULT; -			kfree(buf); +		buf = memdup_user(user_buffer, count); +		if (IS_ERR(buf)) { +			retval = PTR_ERR(buf);  			goto exit;  		}  		retval = usb_set_report(dev->interface, 2, 0, buf, count); diff --git a/drivers/usb/misc/ucsi.c b/drivers/usb/misc/ucsi.c deleted file mode 100644 index 07397bddefa3..000000000000 --- a/drivers/usb/misc/ucsi.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * USB Type-C Connector System Software Interface driver - * - * Copyright (C) 2016, Intel Corporation - * Author: Heikki Krogerus <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/acpi.h> - -#include "ucsi.h" - -/* Double the time defined by MIN_TIME_TO_RESPOND_WITH_BUSY */ -#define UCSI_TIMEOUT_MS 20 - -enum ucsi_status { -	UCSI_IDLE = 0, -	UCSI_BUSY, -	UCSI_ERROR, -}; - -struct ucsi_connector { -	int num; -	struct ucsi *ucsi; -	struct work_struct work; -	struct ucsi_connector_capability cap; -}; - -struct ucsi { -	struct device *dev; -	struct ucsi_data __iomem *data; - -	enum ucsi_status status; -	struct completion complete; -	struct ucsi_capability cap; -	struct ucsi_connector *connector; - -	/* device lock */ -	spinlock_t dev_lock; - -	/* PPM Communication lock */ -	struct mutex ppm_lock; - -	/* PPM communication flags */ -	unsigned long flags; -#define EVENT_PENDING	0 -#define COMMAND_PENDING	1 -}; - -static int ucsi_acpi_cmd(struct ucsi *ucsi, struct ucsi_control *ctrl) -{ -	uuid_le uuid = UUID_LE(0x6f8398c2, 0x7ca4, 0x11e4, -			       0xad, 0x36, 0x63, 0x10, 0x42, 0xb5, 0x00, 0x8f); -	union acpi_object *obj; - -	ucsi->data->ctrl.raw_cmd = ctrl->raw_cmd; - -	obj = acpi_evaluate_dsm(ACPI_HANDLE(ucsi->dev), uuid.b, 1, 1, NULL); -	if (!obj) { -		dev_err(ucsi->dev, "%s: failed to evaluate _DSM\n", __func__); -		return -EIO; -	} - -	ACPI_FREE(obj); -	return 0; -} - -static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data) -{ -	struct ucsi *ucsi = data; -	struct ucsi_cci *cci; - -	spin_lock(&ucsi->dev_lock); - -	ucsi->status = UCSI_IDLE; -	cci = &ucsi->data->cci; - -	/* -	 * REVISIT: This is not documented behavior, but all known PPMs ACK -	 * asynchronous events by sending notification with cleared CCI. -	 */ -	if (!ucsi->data->raw_cci) { -		if (test_bit(EVENT_PENDING, &ucsi->flags)) -			complete(&ucsi->complete); -		else -			dev_WARN(ucsi->dev, "spurious notification\n"); -		goto out_unlock; -	} - -	if (test_bit(COMMAND_PENDING, &ucsi->flags)) { -		if (cci->busy) { -			ucsi->status = UCSI_BUSY; -			complete(&ucsi->complete); - -			goto out_unlock; -		} else if (cci->ack_complete || cci->cmd_complete) { -			/* Error Indication is only valid with commands */ -			if (cci->error && cci->cmd_complete) -				ucsi->status = UCSI_ERROR; - -			ucsi->data->ctrl.raw_cmd = 0; -			complete(&ucsi->complete); -		} -	} - -	if (cci->connector_change) { -		struct ucsi_connector *con; - -		/* -		 * This is workaround for buggy PPMs that create asynchronous -		 * event notifications before OPM has enabled them. -		 */ -		if (!ucsi->connector) -			goto out_unlock; - -		con = ucsi->connector + (cci->connector_change - 1); - -		/* -		 * PPM will not clear the connector specific bit in Connector -		 * Change Indication field of CCI until the driver has ACK it, -		 * and the driver can not ACK it before it has been processed. -		 * The PPM will not generate new events before the first has -		 * been acknowledged, even if they are for an other connector. -		 * So only one event at a time. -		 */ -		if (!test_and_set_bit(EVENT_PENDING, &ucsi->flags)) -			schedule_work(&con->work); -	} -out_unlock: -	spin_unlock(&ucsi->dev_lock); -} - -static int ucsi_ack(struct ucsi *ucsi, u8 cmd) -{ -	struct ucsi_control ctrl; -	int ret; - -	ctrl.cmd.cmd = UCSI_ACK_CC_CI; -	ctrl.cmd.length = 0; -	ctrl.cmd.data = cmd; -	ret = ucsi_acpi_cmd(ucsi, &ctrl); -	if (ret) -		return ret; - -	/* Waiting for ACK also with ACK CMD for now */ -	ret = wait_for_completion_timeout(&ucsi->complete, -					  msecs_to_jiffies(UCSI_TIMEOUT_MS)); -	if (!ret) -		return -ETIMEDOUT; -	return 0; -} - -static int ucsi_run_cmd(struct ucsi *ucsi, struct ucsi_control *ctrl, -			void *data, size_t size) -{ -	u16 err_value = 0; -	int ret; - -	set_bit(COMMAND_PENDING, &ucsi->flags); - -	ret = ucsi_acpi_cmd(ucsi, ctrl); -	if (ret) -		goto err_clear_flag; - -	ret = wait_for_completion_timeout(&ucsi->complete, -					  msecs_to_jiffies(UCSI_TIMEOUT_MS)); -	if (!ret) { -		ret = -ETIMEDOUT; -		goto err_clear_flag; -	} - -	switch (ucsi->status) { -	case UCSI_IDLE: -		if (data) -			memcpy(data, ucsi->data->message_in, size); - -		ret = ucsi_ack(ucsi, UCSI_ACK_CMD); -		break; -	case UCSI_BUSY: -		/* The caller decides whether to cancel or not */ -		ret = -EBUSY; -		goto err_clear_flag; -	case UCSI_ERROR: -		ret = ucsi_ack(ucsi, UCSI_ACK_CMD); -		if (ret) -			goto err_clear_flag; - -		ctrl->cmd.cmd = UCSI_GET_ERROR_STATUS; -		ctrl->cmd.length = 0; -		ctrl->cmd.data = 0; -		ret = ucsi_acpi_cmd(ucsi, ctrl); -		if (ret) -			goto err_clear_flag; - -		ret = wait_for_completion_timeout(&ucsi->complete, -					msecs_to_jiffies(UCSI_TIMEOUT_MS)); -		if (!ret) { -			ret = -ETIMEDOUT; -			goto err_clear_flag; -		} - -		memcpy(&err_value, ucsi->data->message_in, sizeof(err_value)); - -		/* Something has really gone wrong */ -		if (WARN_ON(ucsi->status == UCSI_ERROR)) { -			ret = -ENODEV; -			goto err_clear_flag; -		} - -		ret = ucsi_ack(ucsi, UCSI_ACK_CMD); -		if (ret) -			goto err_clear_flag; - -		switch (err_value) { -		case UCSI_ERROR_INCOMPATIBLE_PARTNER: -			ret = -EOPNOTSUPP; -			break; -		case UCSI_ERROR_CC_COMMUNICATION_ERR: -			ret = -ECOMM; -			break; -		case UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL: -			ret = -EIO; -			break; -		case UCSI_ERROR_DEAD_BATTERY: -			dev_warn(ucsi->dev, "Dead battery condition!\n"); -			ret = -EPERM; -			break; -		/* The following mean a bug in this driver */ -		case UCSI_ERROR_INVALID_CON_NUM: -		case UCSI_ERROR_UNREGONIZED_CMD: -		case UCSI_ERROR_INVALID_CMD_ARGUMENT: -		default: -			dev_warn(ucsi->dev, -				 "%s: possible UCSI driver bug - error %hu\n", -				 __func__, err_value); -			ret = -EINVAL; -			break; -		} -		break; -	} -	ctrl->raw_cmd = 0; -err_clear_flag: -	clear_bit(COMMAND_PENDING, &ucsi->flags); -	return ret; -} - -static void ucsi_connector_change(struct work_struct *work) -{ -	struct ucsi_connector *con = container_of(work, struct ucsi_connector, -						  work); -	struct ucsi_connector_status constat; -	struct ucsi *ucsi = con->ucsi; -	struct ucsi_control ctrl; -	int ret; - -	mutex_lock(&ucsi->ppm_lock); - -	ctrl.cmd.cmd = UCSI_GET_CONNECTOR_STATUS; -	ctrl.cmd.length = 0; -	ctrl.cmd.data = con->num; -	ret = ucsi_run_cmd(con->ucsi, &ctrl, &constat, sizeof(constat)); -	if (ret) { -		dev_err(ucsi->dev, "%s: failed to read connector status (%d)\n", -			__func__, ret); -		goto out_ack_event; -	} - -	/* Ignoring disconnections and Alternate Modes */ -	if (!constat.connected || !(constat.change & -	    (UCSI_CONSTAT_PARTNER_CHANGE | UCSI_CONSTAT_CONNECT_CHANGE)) || -	    constat.partner_flags & UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE) -		goto out_ack_event; - -	/* If the partner got USB Host role, attempting swap */ -	if (constat.partner_type & UCSI_CONSTAT_PARTNER_TYPE_DFP) { -		ctrl.uor.cmd = UCSI_SET_UOR; -		ctrl.uor.con_num = con->num; -		ctrl.uor.role = UCSI_UOR_ROLE_DFP; - -		ret = ucsi_run_cmd(con->ucsi, &ctrl, NULL, 0); -		if (ret) -			dev_err(ucsi->dev, "%s: failed to swap role (%d)\n", -				__func__, ret); -	} -out_ack_event: -	ucsi_ack(ucsi, UCSI_ACK_EVENT); -	clear_bit(EVENT_PENDING, &ucsi->flags); -	mutex_unlock(&ucsi->ppm_lock); -} - -static int ucsi_reset_ppm(struct ucsi *ucsi) -{ -	int timeout = UCSI_TIMEOUT_MS; -	struct ucsi_control ctrl; -	int ret; - -	memset(&ctrl, 0, sizeof(ctrl)); -	ctrl.cmd.cmd = UCSI_PPM_RESET; -	ret = ucsi_acpi_cmd(ucsi, &ctrl); -	if (ret) -		return ret; - -	/* There is no quarantee the PPM will ever set the RESET_COMPLETE bit */ -	while (!ucsi->data->cci.reset_complete && timeout--) -		usleep_range(1000, 2000); -	return 0; -} - -static int ucsi_init(struct ucsi *ucsi) -{ -	struct ucsi_connector *con; -	struct ucsi_control ctrl; -	int ret; -	int i; - -	init_completion(&ucsi->complete); -	spin_lock_init(&ucsi->dev_lock); -	mutex_init(&ucsi->ppm_lock); - -	/* Reset the PPM */ -	ret = ucsi_reset_ppm(ucsi); -	if (ret) -		return ret; - -	/* -	 * REVISIT: Executing second reset to WA an issue seen on some of the -	 * Broxton based platforms, where the first reset puts the PPM into a -	 * state where it's unable to recognise some of the commands. -	 */ -	ret = ucsi_reset_ppm(ucsi); -	if (ret) -		return ret; - -	mutex_lock(&ucsi->ppm_lock); - -	/* Enable basic notifications */ -	ctrl.cmd.cmd = UCSI_SET_NOTIFICATION_ENABLE; -	ctrl.cmd.length = 0; -	ctrl.cmd.data = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR; -	ret = ucsi_run_cmd(ucsi, &ctrl, NULL, 0); -	if (ret) -		goto err_reset; - -	/* Get PPM capabilities */ -	ctrl.cmd.cmd = UCSI_GET_CAPABILITY; -	ret = ucsi_run_cmd(ucsi, &ctrl, &ucsi->cap, sizeof(ucsi->cap)); -	if (ret) -		goto err_reset; - -	if (!ucsi->cap.num_connectors) { -		ret = -ENODEV; -		goto err_reset; -	} - -	ucsi->connector = devm_kcalloc(ucsi->dev, ucsi->cap.num_connectors, -				       sizeof(*ucsi->connector), GFP_KERNEL); -	if (!ucsi->connector) { -		ret = -ENOMEM; -		goto err_reset; -	} - -	for (i = 1, con = ucsi->connector; i < ucsi->cap.num_connectors + 1; -	     i++, con++) { -		/* Get connector capability */ -		ctrl.cmd.cmd = UCSI_GET_CONNECTOR_CAPABILITY; -		ctrl.cmd.data = i; -		ret = ucsi_run_cmd(ucsi, &ctrl, &con->cap, sizeof(con->cap)); -		if (ret) -			goto err_reset; - -		con->num = i; -		con->ucsi = ucsi; -		INIT_WORK(&con->work, ucsi_connector_change); -	} - -	/* Enable all notifications */ -	ctrl.cmd.cmd = UCSI_SET_NOTIFICATION_ENABLE; -	ctrl.cmd.data = UCSI_ENABLE_NTFY_ALL; -	ret = ucsi_run_cmd(ucsi, &ctrl, NULL, 0); -	if (ret < 0) -		goto err_reset; - -	mutex_unlock(&ucsi->ppm_lock); -	return 0; -err_reset: -	ucsi_reset_ppm(ucsi); -	mutex_unlock(&ucsi->ppm_lock); -	return ret; -} - -static int ucsi_acpi_probe(struct platform_device *pdev) -{ -	struct resource *res; -	acpi_status status; -	struct ucsi *ucsi; -	int ret; - -	ucsi = devm_kzalloc(&pdev->dev, sizeof(*ucsi), GFP_KERNEL); -	if (!ucsi) -		return -ENOMEM; - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(&pdev->dev, "missing memory resource\n"); -		return -ENODEV; -	} - -	/* -	 * NOTE: ACPI has claimed the memory region as it's also an Operation -	 * Region. It's not possible to request it in the driver. -	 */ -	ucsi->data = devm_ioremap(&pdev->dev, res->start, resource_size(res)); -	if (!ucsi->data) -		return -ENOMEM; - -	ucsi->dev = &pdev->dev; - -	status = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), -					     ACPI_ALL_NOTIFY, -					     ucsi_acpi_notify, ucsi); -	if (ACPI_FAILURE(status)) -		return -ENODEV; - -	ret = ucsi_init(ucsi); -	if (ret) { -		acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), -					   ACPI_ALL_NOTIFY, -					   ucsi_acpi_notify); -		return ret; -	} - -	platform_set_drvdata(pdev, ucsi); -	return 0; -} - -static int ucsi_acpi_remove(struct platform_device *pdev) -{ -	struct ucsi *ucsi = platform_get_drvdata(pdev); - -	acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), -				   ACPI_ALL_NOTIFY, ucsi_acpi_notify); - -	/* Make sure there are no events in the middle of being processed */ -	if (wait_on_bit_timeout(&ucsi->flags, EVENT_PENDING, -				TASK_UNINTERRUPTIBLE, -				msecs_to_jiffies(UCSI_TIMEOUT_MS))) -		dev_WARN(ucsi->dev, "%s: Events still pending\n", __func__); - -	ucsi_reset_ppm(ucsi); -	return 0; -} - -static const struct acpi_device_id ucsi_acpi_match[] = { -	{ "PNP0CA0", 0 }, -	{ }, -}; -MODULE_DEVICE_TABLE(acpi, ucsi_acpi_match); - -static struct platform_driver ucsi_acpi_platform_driver = { -	.driver = { -		.name = "ucsi_acpi", -		.acpi_match_table = ACPI_PTR(ucsi_acpi_match), -	}, -	.probe = ucsi_acpi_probe, -	.remove = ucsi_acpi_remove, -}; - -module_platform_driver(ucsi_acpi_platform_driver); - -MODULE_AUTHOR("Heikki Krogerus <[email protected]>"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("USB Type-C System Software Interface (UCSI) driver"); diff --git a/drivers/usb/misc/ucsi.h b/drivers/usb/misc/ucsi.h deleted file mode 100644 index 6dd11d1fe225..000000000000 --- a/drivers/usb/misc/ucsi.h +++ /dev/null @@ -1,215 +0,0 @@ - -#include <linux/types.h> - -/* -------------------------------------------------------------------------- */ - -/* Command Status and Connector Change Indication (CCI) data structure */ -struct ucsi_cci { -	unsigned int RESERVED1:1; -	unsigned int connector_change:7; -	u8 data_length; -	unsigned int RESERVED9:9; -	unsigned int not_supported:1; -	unsigned int cancel_complete:1; -	unsigned int reset_complete:1; -	unsigned int busy:1; -	unsigned int ack_complete:1; -	unsigned int error:1; -	unsigned int cmd_complete:1; -} __packed; - -/* Default fields in CONTROL data structure */ -struct ucsi_command { -	u8 cmd; -	u8 length; -	u64 data:48; -} __packed; - -/* Set USB Operation Mode Command structure */ -struct ucsi_uor_cmd { -	u8 cmd; -	u8 length; -	u64 con_num:7; -	u64 role:3; -#define UCSI_UOR_ROLE_DFP			BIT(0) -#define UCSI_UOR_ROLE_UFP			BIT(1) -#define UCSI_UOR_ROLE_DRP			BIT(2) -	u64 data:38; -} __packed; - -struct ucsi_control { -	union { -		u64 raw_cmd; -		struct ucsi_command cmd; -		struct ucsi_uor_cmd uor; -	}; -}; - -struct ucsi_data { -	u16 version; -	u16 RESERVED; -	union { -		u32 raw_cci; -		struct ucsi_cci cci; -	}; -	struct ucsi_control ctrl; -	u32 message_in[4]; -	u32 message_out[4]; -} __packed; - -/* Commands */ -#define UCSI_PPM_RESET			0x01 -#define UCSI_CANCEL			0x02 -#define UCSI_CONNECTOR_RESET		0x03 -#define UCSI_ACK_CC_CI			0x04 -#define UCSI_SET_NOTIFICATION_ENABLE	0x05 -#define UCSI_GET_CAPABILITY		0x06 -#define UCSI_GET_CONNECTOR_CAPABILITY	0x07 -#define UCSI_SET_UOM			0x08 -#define UCSI_SET_UOR			0x09 -#define UCSI_SET_PDM			0x0A -#define UCSI_SET_PDR			0x0B -#define UCSI_GET_ALTERNATE_MODES	0x0C -#define UCSI_GET_CAM_SUPPORTED		0x0D -#define UCSI_GET_CURRENT_CAM		0x0E -#define UCSI_SET_NEW_CAM		0x0F -#define UCSI_GET_PDOS			0x10 -#define UCSI_GET_CABLE_PROPERTY		0x11 -#define UCSI_GET_CONNECTOR_STATUS	0x12 -#define UCSI_GET_ERROR_STATUS		0x13 - -/* ACK_CC_CI commands */ -#define UCSI_ACK_EVENT			1 -#define UCSI_ACK_CMD			2 - -/* Bits for SET_NOTIFICATION_ENABLE command */ -#define UCSI_ENABLE_NTFY_CMD_COMPLETE		BIT(0) -#define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE	BIT(1) -#define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE	BIT(2) -#define UCSI_ENABLE_NTFY_CAP_CHANGE		BIT(5) -#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE	BIT(6) -#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE	BIT(7) -#define UCSI_ENABLE_NTFY_CAM_CHANGE		BIT(8) -#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE	BIT(9) -#define UCSI_ENABLE_NTFY_PARTNER_CHANGE		BIT(11) -#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE		BIT(12) -#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE	BIT(14) -#define UCSI_ENABLE_NTFY_ERROR			BIT(15) -#define UCSI_ENABLE_NTFY_ALL			0xdbe7 - -/* Error information returned by PPM in response to GET_ERROR_STATUS command. */ -#define UCSI_ERROR_UNREGONIZED_CMD		BIT(0) -#define UCSI_ERROR_INVALID_CON_NUM		BIT(1) -#define UCSI_ERROR_INVALID_CMD_ARGUMENT		BIT(2) -#define UCSI_ERROR_INCOMPATIBLE_PARTNER		BIT(3) -#define UCSI_ERROR_CC_COMMUNICATION_ERR		BIT(4) -#define UCSI_ERROR_DEAD_BATTERY			BIT(5) -#define UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL	BIT(6) - -/* Data structure filled by PPM in response to GET_CAPABILITY command. */ -struct ucsi_capability { -	u32 attributes; -#define UCSI_CAP_ATTR_DISABLE_STATE		BIT(0) -#define UCSI_CAP_ATTR_BATTERY_CHARGING		BIT(1) -#define UCSI_CAP_ATTR_USB_PD			BIT(2) -#define UCSI_CAP_ATTR_TYPEC_CURRENT		BIT(6) -#define UCSI_CAP_ATTR_POWER_AC_SUPPLY		BIT(8) -#define UCSI_CAP_ATTR_POWER_OTHER		BIT(10) -#define UCSI_CAP_ATTR_POWER_VBUS		BIT(14) -	u8 num_connectors; -	u32 features:24; -#define UCSI_CAP_SET_UOM			BIT(0) -#define UCSI_CAP_SET_PDM			BIT(1) -#define UCSI_CAP_ALT_MODE_DETAILS		BIT(2) -#define UCSI_CAP_ALT_MODE_OVERRIDE		BIT(3) -#define UCSI_CAP_PDO_DETAILS			BIT(4) -#define UCSI_CAP_CABLE_DETAILS			BIT(5) -#define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS	BIT(6) -#define UCSI_CAP_PD_RESET			BIT(7) -	u8 num_alt_modes; -	u8 RESERVED; -	u16 bc_version; -	u16 pd_version; -	u16 typec_version; -} __packed; - -/* Data structure filled by PPM in response to GET_CONNECTOR_CAPABILITY cmd. */ -struct ucsi_connector_capability { -	u8 op_mode; -#define UCSI_CONCAP_OPMODE_DFP			BIT(0) -#define UCSI_CONCAP_OPMODE_UFP			BIT(1) -#define UCSI_CONCAP_OPMODE_DRP			BIT(2) -#define UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY	BIT(3) -#define UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY	BIT(4) -#define UCSI_CONCAP_OPMODE_USB2			BIT(5) -#define UCSI_CONCAP_OPMODE_USB3			BIT(6) -#define UCSI_CONCAP_OPMODE_ALT_MODE		BIT(7) -	u8 provider:1; -	u8 consumer:1; -} __packed; - -/* Data structure filled by PPM in response to GET_CABLE_PROPERTY command. */ -struct ucsi_cable_property { -	u16 speed_supported; -	u8 current_capability; -	u8 vbus_in_cable:1; -	u8 active_cable:1; -	u8 directionality:1; -	u8 plug_type:2; -#define UCSI_CABLE_PROPERTY_PLUG_TYPE_A		0 -#define UCSI_CABLE_PROPERTY_PLUG_TYPE_B		1 -#define UCSI_CABLE_PROPERTY_PLUG_TYPE_C		2 -#define UCSI_CABLE_PROPERTY_PLUG_OTHER		3 -	u8 mode_support:1; -	u8 RESERVED_2:2; -	u8 latency:4; -	u8 RESERVED_4:4; -} __packed; - -/* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */ -struct ucsi_connector_status { -	u16 change; -#define UCSI_CONSTAT_EXT_SUPPLY_CHANGE		BIT(1) -#define UCSI_CONSTAT_POWER_OPMODE_CHANGE	BIT(2) -#define UCSI_CONSTAT_PDOS_CHANGE		BIT(5) -#define UCSI_CONSTAT_POWER_LEVEL_CHANGE		BIT(6) -#define UCSI_CONSTAT_PD_RESET_COMPLETE		BIT(7) -#define UCSI_CONSTAT_CAM_CHANGE			BIT(8) -#define UCSI_CONSTAT_BC_CHANGE			BIT(9) -#define UCSI_CONSTAT_PARTNER_CHANGE		BIT(11) -#define UCSI_CONSTAT_POWER_DIR_CHANGE		BIT(12) -#define UCSI_CONSTAT_CONNECT_CHANGE		BIT(14) -#define UCSI_CONSTAT_ERROR			BIT(15) -	u16 pwr_op_mode:3; -#define UCSI_CONSTAT_PWR_OPMODE_NONE		0 -#define UCSI_CONSTAT_PWR_OPMODE_DEFAULT		1 -#define UCSI_CONSTAT_PWR_OPMODE_BC		2 -#define UCSI_CONSTAT_PWR_OPMODE_PD		3 -#define UCSI_CONSTAT_PWR_OPMODE_TYPEC1_3	4 -#define UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0	5 -	u16 connected:1; -	u16 pwr_dir:1; -	u16 partner_flags:8; -#define UCSI_CONSTAT_PARTNER_FLAG_USB		BIT(0) -#define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE	BIT(1) -	u16 partner_type:3; -#define UCSI_CONSTAT_PARTNER_TYPE_DFP		1 -#define UCSI_CONSTAT_PARTNER_TYPE_UFP		2 -#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_NO_UFP	3 /* Powered Cable */ -#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP	4 /* Powered Cable */ -#define UCSI_CONSTAT_PARTNER_TYPE_DEBUG		5 -#define UCSI_CONSTAT_PARTNER_TYPE_AUDIO		6 -	u32 request_data_obj; -	u8 bc_status:2; -#define UCSI_CONSTAT_BC_NOT_CHARGING		0 -#define UCSI_CONSTAT_BC_NOMINAL_CHARGING	1 -#define UCSI_CONSTAT_BC_SLOW_CHARGING		2 -#define UCSI_CONSTAT_BC_TRICKLE_CHARGING	3 -	u8 provider_cap_limit_reason:4; -#define UCSI_CONSTAT_CAP_PWR_LOWERED		0 -#define UCSI_CONSTAT_CAP_PWR_BUDGET_LIMIT	1 -	u8 RESERVED:2; -} __packed; - -/* -------------------------------------------------------------------------- */ - diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index a0ba5298160c..388fae6373db 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -33,7 +33,7 @@ static const struct usb_device_id id_table[] = {  MODULE_DEVICE_TABLE(usb, id_table);  /* the different text display modes the device is capable of */ -static char *display_textmodes[] = {"raw", "hex", "ascii", NULL}; +static const char *display_textmodes[] = {"raw", "hex", "ascii"};  struct usb_sevsegdev {  	struct usb_device *udev; @@ -280,7 +280,7 @@ static ssize_t show_attr_textmode(struct device *dev,  	buf[0] = 0; -	for (i = 0; display_textmodes[i]; i++) { +	for (i = 0; i < ARRAY_SIZE(display_textmodes); i++) {  		if (mydev->textmode == i) {  			strcat(buf, " [");  			strcat(buf, display_textmodes[i]); @@ -304,15 +304,13 @@ static ssize_t set_attr_textmode(struct device *dev,  	struct usb_sevsegdev *mydev = usb_get_intfdata(intf);  	int i; -	for (i = 0; display_textmodes[i]; i++) { -		if (sysfs_streq(display_textmodes[i], buf)) { -			mydev->textmode = i; -			update_display_visual(mydev, GFP_KERNEL); -			return count; -		} -	} +	i = sysfs_match_string(display_textmodes, buf); +	if (i < 0) +		return i; -	return -EINVAL; +	mydev->textmode = i; +	update_display_visual(mydev, GFP_KERNEL); +	return count;  }  static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode); |