From patchwork Fri Oct 11 15:32:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 11185727 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A82D8912 for ; Fri, 11 Oct 2019 15:32:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 930ED222BE for ; Fri, 11 Oct 2019 15:32:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727996AbfJKPch (ORCPT ); Fri, 11 Oct 2019 11:32:37 -0400 Received: from mga09.intel.com ([134.134.136.24]:33465 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727928AbfJKPcg (ORCPT ); Fri, 11 Oct 2019 11:32:36 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Oct 2019 08:32:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,284,1566889200"; d="scan'208";a="207450445" Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 11 Oct 2019 08:32:24 -0700 From: Heikki Krogerus To: Guenter Roeck Cc: linux-usb@vger.kernel.org Subject: [PATCH v4 3/9] usb: typec: Separate the operations vector Date: Fri, 11 Oct 2019 18:32:13 +0300 Message-Id: <20191011153219.35701-4-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191011153219.35701-1-heikki.krogerus@linux.intel.com> References: <20191011153219.35701-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Introducing struct typec_operations which has the same callbacks as struct typec_capability. The old callbacks are kept for now, but after all users have been converted, they will be removed. Signed-off-by: Heikki Krogerus Reviewed-by: Guenter Roeck --- drivers/usb/typec/class.c | 39 +++++++++++++++++++++++++++++---------- include/linux/usb/typec.h | 20 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 51154634c2c0..b934a006535a 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -54,6 +54,7 @@ struct typec_port { const struct typec_capability *orig_cap; /* to be removed */ const struct typec_capability *cap; + const struct typec_operations *ops; }; #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) @@ -956,7 +957,7 @@ preferred_role_store(struct device *dev, struct device_attribute *attr, return -EOPNOTSUPP; } - if (!port->cap->try_role) { + if (!port->cap->try_role && (!port->ops || !port->ops->try_role)) { dev_dbg(dev, "Setting preferred role not supported\n"); return -EOPNOTSUPP; } @@ -969,7 +970,10 @@ preferred_role_store(struct device *dev, struct device_attribute *attr, return -EINVAL; } - ret = port->cap->try_role(port->orig_cap, role); + if (port->ops && port->ops->try_role) + ret = port->ops->try_role(port, role); + else + ret = port->cap->try_role(port->orig_cap, role); if (ret) return ret; @@ -1000,7 +1004,7 @@ static ssize_t data_role_store(struct device *dev, struct typec_port *port = to_typec_port(dev); int ret; - if (!port->cap->dr_set) { + if (!port->cap->dr_set && (!port->ops || !port->ops->dr_set)) { dev_dbg(dev, "data role swapping not supported\n"); return -EOPNOTSUPP; } @@ -1015,7 +1019,10 @@ static ssize_t data_role_store(struct device *dev, goto unlock_and_ret; } - ret = port->cap->dr_set(port->orig_cap, ret); + if (port->ops && port->ops->dr_set) + ret = port->ops->dr_set(port, ret); + else + ret = port->cap->dr_set(port->orig_cap, ret); if (ret) goto unlock_and_ret; @@ -1050,7 +1057,7 @@ static ssize_t power_role_store(struct device *dev, return -EOPNOTSUPP; } - if (!port->cap->pr_set) { + if (!port->cap->pr_set && (!port->ops || !port->ops->pr_set)) { dev_dbg(dev, "power role swapping not supported\n"); return -EOPNOTSUPP; } @@ -1072,7 +1079,10 @@ static ssize_t power_role_store(struct device *dev, goto unlock_and_ret; } - ret = port->cap->pr_set(port->orig_cap, ret); + if (port->ops && port->ops->dr_set) + ret = port->ops->pr_set(port, ret); + else + ret = port->cap->pr_set(port->orig_cap, ret); if (ret) goto unlock_and_ret; @@ -1103,7 +1113,8 @@ port_type_store(struct device *dev, struct device_attribute *attr, int ret; enum typec_port_type type; - if (!port->cap->port_type_set || port->cap->type != TYPEC_PORT_DRP) { + if (port->cap->type != TYPEC_PORT_DRP || (!port->cap->port_type_set && + (!port->ops || !port->ops->port_type_set))) { dev_dbg(dev, "changing port type not supported\n"); return -EOPNOTSUPP; } @@ -1120,7 +1131,10 @@ port_type_store(struct device *dev, struct device_attribute *attr, goto unlock_and_ret; } - ret = port->cap->port_type_set(port->orig_cap, type); + if (port->ops && port->ops->port_type_set) + ret = port->ops->port_type_set(port, type); + else + ret = port->cap->port_type_set(port->orig_cap, type); if (ret) goto unlock_and_ret; @@ -1176,7 +1190,7 @@ static ssize_t vconn_source_store(struct device *dev, return -EOPNOTSUPP; } - if (!port->cap->vconn_set) { + if (!port->cap->vconn_set && (!port->ops || !port->ops->vconn_set)) { dev_dbg(dev, "VCONN swapping not supported\n"); return -EOPNOTSUPP; } @@ -1185,7 +1199,11 @@ static ssize_t vconn_source_store(struct device *dev, if (ret) return ret; - ret = port->cap->vconn_set(port->orig_cap, (enum typec_role)source); + if (port->ops && port->ops->vconn_set) + ret = port->ops->vconn_set(port, (enum typec_role)source); + else + ret = port->cap->vconn_set(port->orig_cap, + (enum typec_role)source); if (ret) return ret; @@ -1591,6 +1609,7 @@ struct typec_port *typec_register_port(struct device *parent, mutex_init(&port->port_type_lock); port->id = id; + port->ops = cap->ops; port->orig_cap = cap; port->port_type = cap->type; port->prefer_role = cap->prefer_role; diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 8b90cd77331c..c9bef128453b 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -168,6 +168,23 @@ struct typec_partner_desc { struct usb_pd_identity *identity; }; +/** + * struct typec_operations - USB Type-C Port Operations + * @try_role: Set data role preference for DRP port + * @dr_set: Set Data Role + * @pr_set: Set Power Role + * @vconn_set: Source VCONN + * @port_type_set: Set port type + */ +struct typec_operations { + int (*try_role)(struct typec_port *port, int role); + int (*dr_set)(struct typec_port *port, enum typec_data_role role); + int (*pr_set)(struct typec_port *port, enum typec_role role); + int (*vconn_set)(struct typec_port *port, enum typec_role role); + int (*port_type_set)(struct typec_port *port, + enum typec_port_type type); +}; + /* * struct typec_capability - USB Type-C Port Capabilities * @type: Supported power role of the port @@ -180,6 +197,7 @@ struct typec_partner_desc { * @mux: Multiplexer switch for Alternate/Accessory Modes * @fwnode: Optional fwnode of the port * @driver_data: Private pointer for driver specific info + * @ops: Port operations vector * @try_role: Set data role preference for DRP port * @dr_set: Set Data Role * @pr_set: Set Power Role @@ -201,6 +219,8 @@ struct typec_capability { struct fwnode_handle *fwnode; void *driver_data; + const struct typec_operations *ops; + int (*try_role)(const struct typec_capability *, int role);