From patchwork Thu Dec 23 08:16:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 12698026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0605FC433F5 for ; Thu, 23 Dec 2021 08:16:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346829AbhLWIQS (ORCPT ); Thu, 23 Dec 2021 03:16:18 -0500 Received: from mga01.intel.com ([192.55.52.88]:28533 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239315AbhLWIQR (ORCPT ); Thu, 23 Dec 2021 03:16:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640247377; x=1671783377; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QCLhPm/H03yOkTIscFco8BLBYGHhEbUqjfz5Q53NPNY=; b=dMTGUA7G0opQaICkwSv3N9t27JbV/FWhHSoXxZHAkY8Grv/lBBZZwbSV f9TD4bVrW+jkkNgFgZXU+L81q/c1V9FkWTrZEJcAQ7VMZ7fTT0jf3KIdm 8r2lcej5x1yQSkjF6HtTW0dr4JWXUXPTmJu0C5PFqza9346DsxUdLYqHK 3KdGeOsZ6Tz5tz32SUoDod/j6liId0kK3fS7QzvFXI5MqDZ3juJmJt7O9 HOSEWJFwetGGkkkRCaC0p2Qk1hGb2BN34OM/lmjQ4yKS+MvKia7fDjiRw i+JrNAmIb6lTpvK6Vf+AVWZ4zji39yRIWj0Cx7up/k42IphQ4GDKMlvx2 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10206"; a="264990661" X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="264990661" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Dec 2021 00:16:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="664515515" Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 23 Dec 2021 00:16:14 -0800 From: Heikki Krogerus To: "Rafael J. Wysocki" , Greg Kroah-Hartman Cc: Andy Shevchenko , Sakari Ailus , Prashant Malani , linux-acpi@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 1/5] acpi: Export acpi_bus_type Date: Thu, 23 Dec 2021 11:16:16 +0300 Message-Id: <20211223081620.45479-2-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> References: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org So we can use bus_for_each_dev() and others from modules. Signed-off-by: Heikki Krogerus --- drivers/acpi/bus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index dd535b4b9a160..572588bc6ede0 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1043,6 +1043,7 @@ struct bus_type acpi_bus_type = { .remove = acpi_device_remove, .uevent = acpi_device_uevent, }; +EXPORT_SYMBOL_GPL(acpi_bus_type); /* -------------------------------------------------------------------------- Initialization/Cleanup From patchwork Thu Dec 23 08:16:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 12698027 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 30731C433F5 for ; Thu, 23 Dec 2021 08:16:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346939AbhLWIQV (ORCPT ); Thu, 23 Dec 2021 03:16:21 -0500 Received: from mga01.intel.com ([192.55.52.88]:28533 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239315AbhLWIQT (ORCPT ); Thu, 23 Dec 2021 03:16:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640247379; x=1671783379; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZGjf2BsKqKmCiWOumvWShxieb989cWfWjiqvu1NglXs=; b=MPy80rf2L6+okhZooKZsS6kol3HUmSV+ppp/wj0T6TfjZ1Em3JKJkt0E JekETYww5G6HsvZCzYxlGz9RkqsTtYx7NCemLmGqIdKbVucxHs7v2n0zG wlmkqONKwNY3OhN1WBCYS1VVylVzk1E99u0TcRtOoeCg5GWRejKPEzkbO 7iPoMimD2qFm2WRu8FXBD09dza/0WopgA720tkJJia6kzKuv0JxhUM2gj qt13WxbTLvTW7ZYqjrw2dShsO6NM3TsyefYNSSfYLpWaqUdOj7DtLb2iL o9UZPF72CcMv9n3yT3zqUVH0xhq6DtzM3BrP37Sxw3nRb5ejQrC2x5OpM A==; X-IronPort-AV: E=McAfee;i="6200,9189,10206"; a="264990671" X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="264990671" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Dec 2021 00:16:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="664515517" Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 23 Dec 2021 00:16:17 -0800 From: Heikki Krogerus To: "Rafael J. Wysocki" , Greg Kroah-Hartman Cc: Andy Shevchenko , Sakari Ailus , Prashant Malani , linux-acpi@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 2/5] acpi: Store CRC-32 hash of the _PLD in struct acpi_device Date: Thu, 23 Dec 2021 11:16:17 +0300 Message-Id: <20211223081620.45479-3-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> References: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Storing CRC-32 hash of the Physical Location of Device object (_PLD) with devices that have it. The hash is stored to a new struct acpi_device member "pld_crc". The hash makes it easier to find devices that share a location, as there is no need to evaluate the entire object every time. Knowledge about devices that share a location can be used in device drivers that need to know the connections to other components inside a system. USB3 ports will for example always share their location with a USB2 port. Signed-off-by: Heikki Krogerus --- drivers/acpi/scan.c | 16 ++++++++++++++++ include/acpi/acpi_bus.h | 1 + 2 files changed, 17 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7ff55a197a583..113414c46b713 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "internal.h" @@ -667,6 +668,19 @@ static int acpi_tie_acpi_dev(struct acpi_device *adev) return 0; } +static void acpi_store_pld_crc(struct acpi_device *adev) +{ + struct acpi_pld_info *pld; + acpi_status status; + + status = acpi_get_physical_device_location(adev->handle, &pld); + if (ACPI_FAILURE(status)) + return; + + adev->pld_crc = crc32(~0, pld, sizeof(*pld)); + ACPI_FREE(pld); +} + static int __acpi_device_add(struct acpi_device *device, void (*release)(struct device *)) { @@ -725,6 +739,8 @@ static int __acpi_device_add(struct acpi_device *device, if (device->wakeup.flags.valid) list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); + acpi_store_pld_crc(device); + mutex_unlock(&acpi_device_lock); if (device->parent) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 8e87ead2af341..f8c945418df23 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -360,6 +360,7 @@ struct acpi_gpio_mapping; /* Device */ struct acpi_device { + u32 pld_crc; int device_type; acpi_handle handle; /* no handle for fixed hardware */ struct fwnode_handle fwnode; From patchwork Thu Dec 23 08:23:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 12698042 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A1BAC433FE for ; Thu, 23 Dec 2021 08:23:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347136AbhLWIXt (ORCPT ); Thu, 23 Dec 2021 03:23:49 -0500 Received: from mga01.intel.com ([192.55.52.88]:29059 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347084AbhLWIXt (ORCPT ); Thu, 23 Dec 2021 03:23:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640247828; x=1671783828; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CMuI78KUbocQ1A8SQsjVQV3ZHOM5ecZjTBHhcTrKJLw=; b=TMtRxLbbSRZBt19zCj55lSg9YBcy4b6S1EAxglYM/ZLolx+UF0NwzN4E xQPLWk7w0ddGRmq+f6yb0DnsS8odKvmXTmaPUSHWjfQZPCqD82Yp6baGM lMDjB6U7CK8fLC0Cw1Ua2mGPSoDb1lMj4kdapov7QVfHuXob6AO3Z09vV 4KR4rOEGv2+TuTsd4uzyrq48Ii5Wuqu+b+X9OUKg51SDDkkZzr0GkFSSz aFz8HleG/K78287t6KoUMDORm0bMcNeXFJKbDMrOxzyPmmxsWLKEX0yix stBADss8WKtRpIVEJ0nOY3nnORPCqvyZMV8PD5heLU7vDo4JrEGhv8Fpj Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10206"; a="264991786" X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="264991786" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Dec 2021 00:23:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="664517100" Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 23 Dec 2021 00:23:42 -0800 From: Heikki Krogerus To: "Rafael J. Wysocki" , Greg Kroah-Hartman Cc: Andy Shevchenko , Sakari Ailus , Prashant Malani , linux-acpi@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 3/5] usb: Link the ports to the connectors they are attached to Date: Thu, 23 Dec 2021 11:23:49 +0300 Message-Id: <20211223082349.45616-1-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> References: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Creating link to the USB Type-C connector for every new port that is added when possible. Reviewed-by: Andy Shevchenko Signed-off-by: Heikki Krogerus --- Documentation/ABI/testing/sysfs-bus-usb | 9 +++++++ drivers/usb/core/port.c | 32 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 2ebe5708b4bc0..7efe31ed3a25c 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -244,6 +244,15 @@ Description: is permitted, "u2" if only u2 is permitted, "u1_u2" if both u1 and u2 are permitted. +What: /sys/bus/usb/devices/...//port/connector +Date: December 2021 +Contact: Heikki Krogerus +Description: + Link to the USB Type-C connector when available. This link is + only created when USB Type-C Connector Class is enabled, and + only if the system firmware is capable of describing the + connection between a port and its connector. + What: /sys/bus/usb/devices/.../power/usb2_lpm_l1_timeout Date: May 2013 Contact: Mathias Nyman diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index dfcca9c876c73..c2bbf97a79bec 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -9,6 +9,7 @@ #include #include +#include #include "hub.h" @@ -528,6 +529,32 @@ static void find_and_link_peer(struct usb_hub *hub, int port1) link_peers_report(port_dev, peer); } +static int connector_bind(struct device *dev, struct device *connector, void *data) +{ + int ret; + + ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector"); + if (ret) + return ret; + + ret = sysfs_create_link(&connector->kobj, &dev->kobj, dev_name(dev)); + if (ret) + sysfs_remove_link(&dev->kobj, "connector"); + + return ret; +} + +static void connector_unbind(struct device *dev, struct device *connector, void *data) +{ + sysfs_remove_link(&connector->kobj, dev_name(dev)); + sysfs_remove_link(&dev->kobj, "connector"); +} + +static const struct component_ops connector_ops = { + .bind = connector_bind, + .unbind = connector_unbind, +}; + int usb_hub_create_port_device(struct usb_hub *hub, int port1) { struct usb_port *port_dev; @@ -577,6 +604,10 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1) find_and_link_peer(hub, port1); + retval = component_add(&port_dev->dev, &connector_ops); + if (retval) + dev_warn(&port_dev->dev, "failed to add component\n"); + /* * Enable runtime pm and hold a refernce that hub_configure() * will drop once the PM_QOS_NO_POWER_OFF flag state has been set @@ -619,5 +650,6 @@ void usb_hub_remove_port_device(struct usb_hub *hub, int port1) peer = port_dev->peer; if (peer) unlink_peers(port_dev, peer); + component_del(&port_dev->dev, &connector_ops); device_unregister(&port_dev->dev); } From patchwork Thu Dec 23 08:24:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 12698043 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 690F6C433F5 for ; Thu, 23 Dec 2021 08:24:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347168AbhLWIYU (ORCPT ); Thu, 23 Dec 2021 03:24:20 -0500 Received: from mga03.intel.com ([134.134.136.65]:35791 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347146AbhLWIYR (ORCPT ); Thu, 23 Dec 2021 03:24:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640247857; x=1671783857; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=A8g1iuk3ghWAuPckGIO1BkLHCUR6qyahtF5nvankjCc=; b=CyntnZoCrMuz1dHrftS9JS+EEzzwG7s3uf1W5KcF0rrcZUFTSsDZmmv/ w16F/CWLZIVzRiYSHyZ9RgvciXx5WbJKo48J6SUdVt08RGcoX+FHlPflr Jq1DQaNk1rXZyzJxFVVr5nzERDE2qWvOZIQ35ulEP+89kXEyKFRVjnoij c5zI+AGD3syGrdw8xz7r/mXvMGCuVDm2cTOKgR5WHxTXSN6KtCoNiNrSZ 531VsGFzkVzskn1EDorTkcR2Du85UWIDI5mouPWeoyEi5Mg2oC4VaBkfi k45Q3zTGrYzVRmyez0HaJk/yYfmfTLKgTLHI8uZHOGQM40pg70fyl81zB g==; X-IronPort-AV: E=McAfee;i="6200,9189,10206"; a="240735617" X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="240735617" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Dec 2021 00:24:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="664517186" Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 23 Dec 2021 00:24:14 -0800 From: Heikki Krogerus To: "Rafael J. Wysocki" , Greg Kroah-Hartman Cc: Andy Shevchenko , Sakari Ailus , Prashant Malani , linux-acpi@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 4/5] usb: typec: port-mapper: Convert to the component framework Date: Thu, 23 Dec 2021 11:24:22 +0300 Message-Id: <20211223082422.45637-1-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> References: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Instead of trying to keep track of the connections to the USB Type-C connectors separately, letting the component framework take care of that. From now on every USB Type-C connector will register itself as "aggregate" - component master - and anything that can be connected to it inside the system can then simply register itself as a generic component. The matching of the components and the connector shall rely on ACPI _PLD initially. Before registering itself as the aggregate, the connector will find all other ACPI devices that have matching _PLD crc hash with it (matching value in the pld_crc member of struct acpi_device), and add a component match entry for each one of them. Because only ACPI is supported for now, the driver shall only be build when ACPI is supported. This removes the need for the custom API that the driver exposed. The components and the connector can therefore exist completely independently of each other. The order in which they are registered, as well as are they modules or not, is now irrelevant. Signed-off-by: Heikki Krogerus --- drivers/usb/typec/Makefile | 3 +- drivers/usb/typec/class.c | 2 - drivers/usb/typec/class.h | 10 +- drivers/usb/typec/port-mapper.c | 279 +++++--------------------------- include/linux/usb/typec.h | 12 -- 5 files changed, 46 insertions(+), 260 deletions(-) diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index a0adb8947a301..57870a2bd7873 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TYPEC) += typec.o -typec-y := class.o mux.o bus.o port-mapper.o +typec-y := class.o mux.o bus.o +typec-$(CONFIG_ACPI) += port-mapper.o obj-$(CONFIG_TYPEC) += altmodes/ obj-$(CONFIG_TYPEC_TCPM) += tcpm/ obj-$(CONFIG_TYPEC_UCSI) += ucsi/ diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index aeef453aa6585..45a6f0c807cb5 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -2039,8 +2039,6 @@ struct typec_port *typec_register_port(struct device *parent, ida_init(&port->mode_ids); mutex_init(&port->port_type_lock); - mutex_init(&port->port_list_lock); - INIT_LIST_HEAD(&port->port_list); port->id = id; port->ops = cap->ops; diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index aef03eb7e1523..0f1bd6d19d67e 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -54,11 +54,6 @@ struct typec_port { const struct typec_capability *cap; const struct typec_operations *ops; - - struct list_head port_list; - struct mutex port_list_lock; /* Port list lock */ - - void *pld; }; #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) @@ -79,7 +74,12 @@ extern const struct device_type typec_port_dev_type; extern struct class typec_mux_class; extern struct class typec_class; +#if defined(CONFIG_ACPI) int typec_link_ports(struct typec_port *connector); void typec_unlink_ports(struct typec_port *connector); +#else +static inline int typec_link_ports(struct typec_port *connector) { return 0; } +static inline void typec_unlink_ports(struct typec_port *connector) { } +#endif #endif /* __USB_TYPEC_CLASS__ */ diff --git a/drivers/usb/typec/port-mapper.c b/drivers/usb/typec/port-mapper.c index 9b0991bdf391a..07d307418b470 100644 --- a/drivers/usb/typec/port-mapper.c +++ b/drivers/usb/typec/port-mapper.c @@ -7,273 +7,72 @@ */ #include -#include -#include +#include #include "class.h" -struct port_node { - struct list_head list; - struct device *dev; - void *pld; -}; - -static int acpi_pld_match(const struct acpi_pld_info *pld1, - const struct acpi_pld_info *pld2) -{ - if (!pld1 || !pld2) - return 0; - - /* - * To speed things up, first checking only the group_position. It seems - * to often have the first unique value in the _PLD. - */ - if (pld1->group_position == pld2->group_position) - return !memcmp(pld1, pld2, sizeof(struct acpi_pld_info)); - - return 0; -} - -static void *get_pld(struct device *dev) +static int typec_aggregate_bind(struct device *dev) { -#ifdef CONFIG_ACPI - struct acpi_pld_info *pld; - acpi_status status; - - if (!has_acpi_companion(dev)) - return NULL; - - status = acpi_get_physical_device_location(ACPI_HANDLE(dev), &pld); - if (ACPI_FAILURE(status)) - return NULL; - - return pld; -#else - return NULL; -#endif -} - -static void free_pld(void *pld) -{ -#ifdef CONFIG_ACPI - ACPI_FREE(pld); -#endif + return component_bind_all(dev, NULL); } -static int __link_port(struct typec_port *con, struct port_node *node) +static void typec_aggregate_unbind(struct device *dev) { - int ret; - - ret = sysfs_create_link(&node->dev->kobj, &con->dev.kobj, "connector"); - if (ret) - return ret; - - ret = sysfs_create_link(&con->dev.kobj, &node->dev->kobj, - dev_name(node->dev)); - if (ret) { - sysfs_remove_link(&node->dev->kobj, "connector"); - return ret; - } - - list_add_tail(&node->list, &con->port_list); - - return 0; + component_unbind_all(dev, NULL); } -static int link_port(struct typec_port *con, struct port_node *node) -{ - int ret; - - mutex_lock(&con->port_list_lock); - ret = __link_port(con, node); - mutex_unlock(&con->port_list_lock); - - return ret; -} - -static void __unlink_port(struct typec_port *con, struct port_node *node) -{ - sysfs_remove_link(&con->dev.kobj, dev_name(node->dev)); - sysfs_remove_link(&node->dev->kobj, "connector"); - list_del(&node->list); -} - -static void unlink_port(struct typec_port *con, struct port_node *node) -{ - mutex_lock(&con->port_list_lock); - __unlink_port(con, node); - mutex_unlock(&con->port_list_lock); -} - -static struct port_node *create_port_node(struct device *port) -{ - struct port_node *node; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return ERR_PTR(-ENOMEM); - - node->dev = get_device(port); - node->pld = get_pld(port); - - return node; -} - -static void remove_port_node(struct port_node *node) -{ - put_device(node->dev); - free_pld(node->pld); - kfree(node); -} - -static int connector_match(struct device *dev, const void *data) -{ - const struct port_node *node = data; - - if (!is_typec_port(dev)) - return 0; - - return acpi_pld_match(to_typec_port(dev)->pld, node->pld); -} - -static struct device *find_connector(struct port_node *node) -{ - if (!node->pld) - return NULL; - - return class_find_device(&typec_class, NULL, node, connector_match); -} - -/** - * typec_link_port - Link a port to its connector - * @port: The port device - * - * Find the connector of @port and create symlink named "connector" for it. - * Returns 0 on success, or errno in case of a failure. - * - * NOTE. The function increments the reference count of @port on success. - */ -int typec_link_port(struct device *port) -{ - struct device *connector; - struct port_node *node; - int ret; - - node = create_port_node(port); - if (IS_ERR(node)) - return PTR_ERR(node); - - connector = find_connector(node); - if (!connector) { - ret = 0; - goto remove_node; - } - - ret = link_port(to_typec_port(connector), node); - if (ret) - goto put_connector; - - return 0; - -put_connector: - put_device(connector); -remove_node: - remove_port_node(node); - - return ret; -} -EXPORT_SYMBOL_GPL(typec_link_port); - -static int port_match_and_unlink(struct device *connector, void *port) -{ - struct port_node *node; - struct port_node *tmp; - int ret = 0; - - if (!is_typec_port(connector)) - return 0; - - mutex_lock(&to_typec_port(connector)->port_list_lock); - list_for_each_entry_safe(node, tmp, &to_typec_port(connector)->port_list, list) { - ret = node->dev == port; - if (ret) { - unlink_port(to_typec_port(connector), node); - remove_port_node(node); - put_device(connector); - break; - } - } - mutex_unlock(&to_typec_port(connector)->port_list_lock); +static const struct component_master_ops typec_aggregate_ops = { + .bind = typec_aggregate_bind, + .unbind = typec_aggregate_unbind, +}; - return ret; -} +struct each_port_arg { + struct typec_port *port; + struct component_match *match; +}; -/** - * typec_unlink_port - Unlink port from its connector - * @port: The port device - * - * Removes the symlink "connector" and decrements the reference count of @port. - */ -void typec_unlink_port(struct device *port) +static int typec_port_compare(struct device *dev, void *fwnode) { - class_for_each_device(&typec_class, NULL, port, port_match_and_unlink); + return device_match_fwnode(dev, fwnode); } -EXPORT_SYMBOL_GPL(typec_unlink_port); -static int each_port(struct device *port, void *connector) +static int typec_port_match(struct device *dev, void *data) { - struct port_node *node; - int ret; - - node = create_port_node(port); - if (IS_ERR(node)) - return PTR_ERR(node); + struct acpi_device *adev = to_acpi_device(dev); + struct each_port_arg *arg = data; + struct acpi_device *con_adev; - if (!connector_match(connector, node)) { - remove_port_node(node); + con_adev = ACPI_COMPANION(&arg->port->dev); + if (con_adev == adev) return 0; - } - - ret = link_port(to_typec_port(connector), node); - if (ret) { - remove_port_node(node->pld); - return ret; - } - - get_device(connector); + if (con_adev->pld_crc == adev->pld_crc) + component_match_add(&arg->port->dev, &arg->match, typec_port_compare, + acpi_fwnode_handle(adev)); return 0; } int typec_link_ports(struct typec_port *con) { - int ret = 0; + struct each_port_arg arg = { .port = con, .match = NULL }; - con->pld = get_pld(&con->dev); - if (!con->pld) - return 0; + bus_for_each_dev(&acpi_bus_type, NULL, &arg, typec_port_match); - ret = usb_for_each_port(&con->dev, each_port); - if (ret) - typec_unlink_ports(con); - - return ret; + /* + * REVISIT: Now each connector can have only a single component master. + * So far only the USB ports connected to the USB Type-C connector share + * the _PLD with it, but if there one day is something else (like maybe + * the DisplayPort ACPI device object) that also shares the _PLD with + * the connector, every one of those needs to have its own component + * master, because each different type of component needs to be bind to + * the connector independently of the other components. That requires + * improvements to the component framework. Right now you can only have + * one master per device. + */ + return component_master_add_with_match(&con->dev, &typec_aggregate_ops, arg.match); } void typec_unlink_ports(struct typec_port *con) { - struct port_node *node; - struct port_node *tmp; - - mutex_lock(&con->port_list_lock); - - list_for_each_entry_safe(node, tmp, &con->port_list, list) { - __unlink_port(con, node); - remove_port_node(node); - put_device(&con->dev); - } - - mutex_unlock(&con->port_list_lock); - - free_pld(con->pld); + component_master_del(&con->dev, &typec_aggregate_ops); } diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index e2e44bb1dad85..7ba45a97eeae3 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -305,16 +305,4 @@ void typec_partner_set_svdm_version(struct typec_partner *partner, enum usb_pd_svdm_ver svdm_version); int typec_get_negotiated_svdm_version(struct typec_port *port); -#if IS_REACHABLE(CONFIG_TYPEC) -int typec_link_port(struct device *port); -void typec_unlink_port(struct device *port); -#else -static inline int typec_link_port(struct device *port) -{ - return 0; -} - -static inline void typec_unlink_port(struct device *port) { } -#endif - #endif /* __LINUX_USB_TYPEC_H */ From patchwork Thu Dec 23 08:24:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 12698044 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF1E5C4332F for ; Thu, 23 Dec 2021 08:24:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347146AbhLWIYn (ORCPT ); Thu, 23 Dec 2021 03:24:43 -0500 Received: from mga03.intel.com ([134.134.136.65]:35809 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347187AbhLWIY2 (ORCPT ); Thu, 23 Dec 2021 03:24:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640247868; x=1671783868; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=r91At3LZD4Dka+efIxucm5+GDhsdmP3uafoJ8RM7pDw=; b=mFPbj99m6hDFdblry92xhJVS94IjywzvH53bpEvFnuslMgKKK0rkTdAs ATIXwk+67mXVMKR3TcH4q9X7q5J9S6xFjVFhCFnDS09Y7uFpu1SaMXW5P f8ToPuZo5Z7ePqfDzuVvhEI0hfgsRFbycOFIDa4foI49AqyYy2qdOy/CM Xq0Q2tYFrUvJ2QaWTGkTViE4lBX7QOSN8nRgpjU20xBARanpDkswz241t ixhPlOEwQ5bkrYmduvj/U1Vhrcdz+mM5u9BLptmj0JFQe6DW3YkpYFeey FFDthgir4QYqAJYr2jrs5gG82KtPNT06m5lIS2OH/dQoNbVg0/Zk+976i g==; X-IronPort-AV: E=McAfee;i="6200,9189,10206"; a="240735641" X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="240735641" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Dec 2021 00:24:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,228,1635231600"; d="scan'208";a="664517221" Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 23 Dec 2021 00:24:23 -0800 From: Heikki Krogerus To: "Rafael J. Wysocki" , Greg Kroah-Hartman Cc: Andy Shevchenko , Sakari Ailus , Prashant Malani , linux-acpi@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 5/5] usb: Remove usb_for_each_port() Date: Thu, 23 Dec 2021 11:24:32 +0300 Message-Id: <20211223082432.45653-1-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> References: <20211223081620.45479-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org There are no more users for the function. Reviewed-by: Andy Shevchenko Signed-off-by: Heikki Krogerus --- drivers/usb/core/usb.c | 46 ------------------------------------------ include/linux/usb.h | 9 --------- 2 files changed, 55 deletions(-) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 62368c4ed37af..2ce3667ec6fae 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -398,52 +398,6 @@ int usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *)) } EXPORT_SYMBOL_GPL(usb_for_each_dev); -struct each_hub_arg { - void *data; - int (*fn)(struct device *, void *); -}; - -static int __each_hub(struct usb_device *hdev, void *data) -{ - struct each_hub_arg *arg = (struct each_hub_arg *)data; - struct usb_hub *hub; - int ret = 0; - int i; - - hub = usb_hub_to_struct_hub(hdev); - if (!hub) - return 0; - - mutex_lock(&usb_port_peer_mutex); - - for (i = 0; i < hdev->maxchild; i++) { - ret = arg->fn(&hub->ports[i]->dev, arg->data); - if (ret) - break; - } - - mutex_unlock(&usb_port_peer_mutex); - - return ret; -} - -/** - * usb_for_each_port - interate over all USB ports in the system - * @data: data pointer that will be handed to the callback function - * @fn: callback function to be called for each USB port - * - * Iterate over all USB ports and call @fn for each, passing it @data. If it - * returns anything other than 0, we break the iteration prematurely and return - * that value. - */ -int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) -{ - struct each_hub_arg arg = {data, fn}; - - return usb_for_each_dev(&arg, __each_hub); -} -EXPORT_SYMBOL_GPL(usb_for_each_port); - /** * usb_release_dev - free a usb device structure when all users of it are finished. * @dev: device that's been disconnected diff --git a/include/linux/usb.h b/include/linux/usb.h index 7ccaa76a9a968..200b7b79acb56 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -875,15 +875,6 @@ extern struct usb_host_interface *usb_find_alt_setting( unsigned int iface_num, unsigned int alt_num); -#if IS_REACHABLE(CONFIG_USB) -int usb_for_each_port(void *data, int (*fn)(struct device *, void *)); -#else -static inline int usb_for_each_port(void *data, int (*fn)(struct device *, void *)) -{ - return 0; -} -#endif - /* port claiming functions */ int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, struct usb_dev_state *owner);