From patchwork Wed May 22 10:50:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955723 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C049113AD for ; Wed, 22 May 2019 10:52:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B2011289C6 for ; Wed, 22 May 2019 10:52:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A69B6289D6; Wed, 22 May 2019 10:52:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 68DDA289CB for ; Wed, 22 May 2019 10:52:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729057AbfEVKvS (ORCPT ); Wed, 22 May 2019 06:51:18 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727464AbfEVKvS (ORCPT ); Wed, 22 May 2019 06:51:18 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:17 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:15 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 01/16] software node: Allow node creation without properties Date: Wed, 22 May 2019 13:50:58 +0300 Message-Id: <20190522105113.11153-2-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Software nodes are not forced to have device properties. Adding check to property_entries_dup() to make it possible to create software nodes that don't have any properties. Signed-off-by: Heikki Krogerus --- drivers/base/swnode.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 7fc5a18e02ad..30077454eb68 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -383,6 +383,9 @@ property_entries_dup(const struct property_entry *properties) int i, n = 0; int ret; + if (!properties) + return NULL; + while (properties[n].name) n++; From patchwork Wed May 22 10:50:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955719 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 21039924 for ; Wed, 22 May 2019 10:52:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 13461289C6 for ; Wed, 22 May 2019 10:52:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 07A2A289D7; Wed, 22 May 2019 10:52:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 895D3289CB for ; Wed, 22 May 2019 10:52:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729203AbfEVKvV (ORCPT ); Wed, 22 May 2019 06:51:21 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727464AbfEVKvU (ORCPT ); Wed, 22 May 2019 06:51:20 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:19 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:17 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 02/16] software node: Simplify software_node_release() function Date: Wed, 22 May 2019 13:50:59 +0300 Message-Id: <20190522105113.11153-3-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP It's possible to release the node ID immediately when fwnode_remove_software_node() is called, no need to wait for software_node_release() with that. Signed-off-by: Heikki Krogerus --- drivers/base/swnode.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 30077454eb68..7b321bf8424c 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -557,13 +557,6 @@ static void software_node_release(struct kobject *kobj) { struct software_node *swnode = kobj_to_swnode(kobj); - if (swnode->parent) { - ida_simple_remove(&swnode->parent->child_ids, swnode->id); - list_del(&swnode->entry); - } else { - ida_simple_remove(&swnode_root_ids, swnode->id); - } - ida_destroy(&swnode->child_ids); property_entries_free(swnode->properties); kfree(swnode); @@ -610,9 +603,6 @@ fwnode_create_software_node(const struct property_entry *properties, INIT_LIST_HEAD(&swnode->children); swnode->parent = p; - if (p) - list_add_tail(&swnode->entry, &p->children); - ret = kobject_init_and_add(&swnode->kobj, &software_node_type, p ? &p->kobj : NULL, "node%d", swnode->id); if (ret) { @@ -626,6 +616,9 @@ fwnode_create_software_node(const struct property_entry *properties, return ERR_PTR(ret); } + if (p) + list_add_tail(&swnode->entry, &p->children); + kobject_uevent(&swnode->kobj, KOBJ_ADD); return &swnode->fwnode; } @@ -638,6 +631,13 @@ void fwnode_remove_software_node(struct fwnode_handle *fwnode) if (!swnode) return; + if (swnode->parent) { + ida_simple_remove(&swnode->parent->child_ids, swnode->id); + list_del(&swnode->entry); + } else { + ida_simple_remove(&swnode_root_ids, swnode->id); + } + kobject_put(&swnode->kobj); } EXPORT_SYMBOL_GPL(fwnode_remove_software_node); From patchwork Wed May 22 10:51:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955715 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DB4B117E0 for ; Wed, 22 May 2019 10:52:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB23C289CB for ; Wed, 22 May 2019 10:52:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF4B628989; Wed, 22 May 2019 10:52:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D308D28989 for ; Wed, 22 May 2019 10:52:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727464AbfEVKvY (ORCPT ); Wed, 22 May 2019 06:51:24 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729221AbfEVKvW (ORCPT ); Wed, 22 May 2019 06:51:22 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:22 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:20 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 03/16] software node: Add support for static node descriptors Date: Wed, 22 May 2019 13:51:00 +0300 Message-Id: <20190522105113.11153-4-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Until now the software nodes could only be created dynamically with fwnode_create_software_node() function. This introduces struct software_node data structure, which makes it possible to describe the software nodes also statically. The statically described software nodes can be registered with a new function fwnode_register_software_node(). This also adds a helper fwnode_register_software_nodes() which makes it possible to register an array of struct software_nodes, i.e. multiple nodes at the same time. There is no difference between statically described and dynamically allocated software nodes. Even the registration does not differ, except that during node creation the device properties are only copied if the node is created dynamically. With statically described nodes, the property entries in the descriptor (struct software_node) are assigned directly to the new software node that is being created without any copies. Signed-off-by: Heikki Krogerus --- drivers/base/swnode.c | 256 +++++++++++++++++++++++++++++---------- include/linux/property.h | 19 +++ 2 files changed, 212 insertions(+), 63 deletions(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 7b321bf8424c..ef1a48fec718 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -11,25 +11,25 @@ #include #include -struct software_node { +struct swnode { int id; struct kobject kobj; struct fwnode_handle fwnode; + const struct software_node *node; /* hierarchy */ struct ida child_ids; struct list_head entry; struct list_head children; - struct software_node *parent; + struct swnode *parent; - /* properties */ - const struct property_entry *properties; + unsigned int allocated:1; }; static DEFINE_IDA(swnode_root_ids); static struct kset *swnode_kset; -#define kobj_to_swnode(_kobj_) container_of(_kobj_, struct software_node, kobj) +#define kobj_to_swnode(_kobj_) container_of(_kobj_, struct swnode, kobj) static const struct fwnode_operations software_node_ops; @@ -37,17 +37,56 @@ bool is_software_node(const struct fwnode_handle *fwnode) { return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &software_node_ops; } +EXPORT_SYMBOL_GPL(is_software_node); -#define to_software_node(__fwnode) \ +#define to_swnode(__fwnode) \ ({ \ - typeof(__fwnode) __to_software_node_fwnode = __fwnode; \ + typeof(__fwnode) __to_swnode_fwnode = __fwnode; \ \ - is_software_node(__to_software_node_fwnode) ? \ - container_of(__to_software_node_fwnode, \ - struct software_node, fwnode) : \ - NULL; \ + is_software_node(__to_swnode_fwnode) ? \ + container_of(__to_swnode_fwnode, \ + struct swnode, fwnode) : NULL; \ }) +static struct swnode * +software_node_to_swnode(const struct software_node *node) +{ + struct swnode *swnode; + struct kobject *k; + + if (!node) + return NULL; + + spin_lock(&swnode_kset->list_lock); + + list_for_each_entry(k, &swnode_kset->list, entry) { + swnode = kobj_to_swnode(k); + if (swnode->node == node) + break; + swnode = NULL; + } + + spin_unlock(&swnode_kset->list_lock); + + return swnode; +} + +const struct software_node *to_software_node(struct fwnode_handle *fwnode) +{ + struct swnode *swnode = to_swnode(fwnode); + + return swnode ? swnode->node : NULL; +} +EXPORT_SYMBOL_GPL(to_software_node); + +struct fwnode_handle *software_node_fwnode(const struct software_node *node) +{ + struct swnode *swnode = software_node_to_swnode(node); + + return swnode ? &swnode->fwnode : NULL; +} +EXPORT_SYMBOL_GPL(software_node_fwnode); + /* -------------------------------------------------------------------------- */ /* property_entry processing */ @@ -433,7 +472,7 @@ EXPORT_SYMBOL_GPL(property_entries_free); static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode) { - struct software_node *swnode = to_software_node(fwnode); + struct swnode *swnode = to_swnode(fwnode); kobject_get(&swnode->kobj); @@ -442,7 +481,7 @@ static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode) static void software_node_put(struct fwnode_handle *fwnode) { - struct software_node *swnode = to_software_node(fwnode); + struct swnode *swnode = to_swnode(fwnode); kobject_put(&swnode->kobj); } @@ -450,8 +489,9 @@ static void software_node_put(struct fwnode_handle *fwnode) static bool software_node_property_present(const struct fwnode_handle *fwnode, const char *propname) { - return !!property_entry_get(to_software_node(fwnode)->properties, - propname); + struct swnode *swnode = to_swnode(fwnode); + + return !!property_entry_get(swnode->node->properties, propname); } static int software_node_read_int_array(const struct fwnode_handle *fwnode, @@ -459,9 +499,9 @@ static int software_node_read_int_array(const struct fwnode_handle *fwnode, unsigned int elem_size, void *val, size_t nval) { - struct software_node *swnode = to_software_node(fwnode); + struct swnode *swnode = to_swnode(fwnode); - return property_entry_read_int_array(swnode->properties, propname, + return property_entry_read_int_array(swnode->node->properties, propname, elem_size, val, nval); } @@ -469,27 +509,26 @@ static int software_node_read_string_array(const struct fwnode_handle *fwnode, const char *propname, const char **val, size_t nval) { - struct software_node *swnode = to_software_node(fwnode); + struct swnode *swnode = to_swnode(fwnode); - return property_entry_read_string_array(swnode->properties, propname, - val, nval); + return property_entry_read_string_array(swnode->node->properties, + propname, val, nval); } static struct fwnode_handle * software_node_get_parent(const struct fwnode_handle *fwnode) { - struct software_node *swnode = to_software_node(fwnode); + struct swnode *swnode = to_swnode(fwnode); - return swnode ? (swnode->parent ? &swnode->parent->fwnode : NULL) : - NULL; + return swnode ? (swnode->parent ? &swnode->parent->fwnode : NULL) : NULL; } static struct fwnode_handle * software_node_get_next_child(const struct fwnode_handle *fwnode, struct fwnode_handle *child) { - struct software_node *p = to_software_node(fwnode); - struct software_node *c = to_software_node(child); + struct swnode *p = to_swnode(fwnode); + struct swnode *c = to_swnode(child); if (!p || list_empty(&p->children) || (c && list_is_last(&c->entry, &p->children))) @@ -498,7 +537,7 @@ software_node_get_next_child(const struct fwnode_handle *fwnode, if (c) c = list_next_entry(c, entry); else - c = list_first_entry(&p->children, struct software_node, entry); + c = list_first_entry(&p->children, struct swnode, entry); return &c->fwnode; } @@ -506,15 +545,15 @@ static struct fwnode_handle * software_node_get_named_child_node(const struct fwnode_handle *fwnode, const char *childname) { - struct software_node *swnode = to_software_node(fwnode); + struct swnode *swnode = to_swnode(fwnode); const struct property_entry *prop; - struct software_node *child; + struct swnode *child; if (!swnode || list_empty(&swnode->children)) return NULL; list_for_each_entry(child, &swnode->children, entry) { - prop = property_entry_get(child->properties, "name"); + prop = property_entry_get(child->node->properties, "name"); if (!prop) continue; if (!strcmp(childname, prop->value.str)) { @@ -539,7 +578,7 @@ static const struct fwnode_operations software_node_ops = { /* -------------------------------------------------------------------------- */ static int -software_node_register_properties(struct software_node *swnode, +software_node_register_properties(struct software_node *node, const struct property_entry *properties) { struct property_entry *props; @@ -548,17 +587,20 @@ software_node_register_properties(struct software_node *swnode, if (IS_ERR(props)) return PTR_ERR(props); - swnode->properties = props; + node->properties = props; return 0; } static void software_node_release(struct kobject *kobj) { - struct software_node *swnode = kobj_to_swnode(kobj); + struct swnode *swnode = kobj_to_swnode(kobj); + if (swnode->allocated) { + property_entries_free(swnode->node->properties); + kfree(swnode->node); + } ida_destroy(&swnode->child_ids); - property_entries_free(swnode->properties); kfree(swnode); } @@ -567,66 +609,154 @@ static struct kobj_type software_node_type = { .sysfs_ops = &kobj_sysfs_ops, }; -struct fwnode_handle * -fwnode_create_software_node(const struct property_entry *properties, - const struct fwnode_handle *parent) +static struct fwnode_handle * +swnode_register(const struct software_node *node, struct swnode *parent, + unsigned int allocated) { - struct software_node *p = NULL; - struct software_node *swnode; + struct swnode *swnode; int ret; - if (parent) { - if (IS_ERR(parent)) - return ERR_CAST(parent); - if (!is_software_node(parent)) - return ERR_PTR(-EINVAL); - p = to_software_node(parent); - } - swnode = kzalloc(sizeof(*swnode), GFP_KERNEL); - if (!swnode) - return ERR_PTR(-ENOMEM); + if (!swnode) { + ret = -ENOMEM; + goto out_err; + } - ret = ida_simple_get(p ? &p->child_ids : &swnode_root_ids, 0, 0, - GFP_KERNEL); + ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids, + 0, 0, GFP_KERNEL); if (ret < 0) { kfree(swnode); - return ERR_PTR(ret); + goto out_err; } swnode->id = ret; + swnode->node = node; + swnode->parent = parent; + swnode->allocated = allocated; swnode->kobj.kset = swnode_kset; swnode->fwnode.ops = &software_node_ops; ida_init(&swnode->child_ids); INIT_LIST_HEAD(&swnode->entry); INIT_LIST_HEAD(&swnode->children); - swnode->parent = p; - ret = kobject_init_and_add(&swnode->kobj, &software_node_type, - p ? &p->kobj : NULL, "node%d", swnode->id); + if (node->name) + ret = kobject_init_and_add(&swnode->kobj, &software_node_type, + parent ? &parent->kobj : NULL, + "%s", node->name); + else + ret = kobject_init_and_add(&swnode->kobj, &software_node_type, + parent ? &parent->kobj : NULL, + "node%d", swnode->id); if (ret) { kobject_put(&swnode->kobj); return ERR_PTR(ret); } - ret = software_node_register_properties(swnode, properties); + if (parent) + list_add_tail(&swnode->entry, &parent->children); + + kobject_uevent(&swnode->kobj, KOBJ_ADD); + return &swnode->fwnode; + +out_err: + if (allocated) + property_entries_free(node->properties); + return ERR_PTR(ret); +} + +/** + * software_node_register_nodes - Register an array of software nodes + * @nodes: Zero terminated array of software nodes to be registered + * + * Register multiple software nodes at once. + */ +int software_node_register_nodes(const struct software_node *nodes) +{ + int ret; + int i; + + for (i = 0; nodes[i].name; i++) { + ret = software_node_register(&nodes[i]); + if (ret) { + software_node_unregister_nodes(nodes); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(software_node_register_nodes); + +/** + * software_node_unregister_nodes - Unregister an array of software nodes + * @nodes: Zero terminated array of software nodes to be unregistered + * + * Unregister multiple software nodes at once. + */ +void software_node_unregister_nodes(const struct software_node *nodes) +{ + struct swnode *swnode; + int i; + + for (i = 0; nodes[i].name; i++) { + swnode = software_node_to_swnode(&nodes[i]); + if (swnode) + fwnode_remove_software_node(&swnode->fwnode); + } +} +EXPORT_SYMBOL_GPL(software_node_unregister_nodes); + +/** + * software_node_register - Register static software node + * @node: The software node to be registered + */ +int software_node_register(const struct software_node *node) +{ + struct swnode *parent = software_node_to_swnode(node->parent); + + if (software_node_to_swnode(node)) + return -EEXIST; + + return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0)); +} +EXPORT_SYMBOL_GPL(software_node_register); + +struct fwnode_handle * +fwnode_create_software_node(const struct property_entry *properties, + const struct fwnode_handle *parent) +{ + struct software_node *node; + struct swnode *p = NULL; + int ret; + + if (parent) { + if (IS_ERR(parent)) + return ERR_CAST(parent); + if (!is_software_node(parent)) + return ERR_PTR(-EINVAL); + p = to_swnode(parent); + } + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + return ERR_PTR(-ENOMEM); + + ret = software_node_register_properties(node, properties); if (ret) { - kobject_put(&swnode->kobj); + kfree(node); return ERR_PTR(ret); } - if (p) - list_add_tail(&swnode->entry, &p->children); + node->parent = p ? p->node : NULL; - kobject_uevent(&swnode->kobj, KOBJ_ADD); - return &swnode->fwnode; + return swnode_register(node, p, 1); } EXPORT_SYMBOL_GPL(fwnode_create_software_node); void fwnode_remove_software_node(struct fwnode_handle *fwnode) { - struct software_node *swnode = to_software_node(fwnode); + struct swnode *swnode = to_swnode(fwnode); if (!swnode) return; @@ -645,7 +775,7 @@ EXPORT_SYMBOL_GPL(fwnode_remove_software_node); int software_node_notify(struct device *dev, unsigned long action) { struct fwnode_handle *fwnode = dev_fwnode(dev); - struct software_node *swnode; + struct swnode *swnode; int ret; if (!fwnode) @@ -656,7 +786,7 @@ int software_node_notify(struct device *dev, unsigned long action) if (!is_software_node(fwnode)) return 0; - swnode = to_software_node(fwnode); + swnode = to_swnode(fwnode); switch (action) { case KOBJ_ADD: diff --git a/include/linux/property.h b/include/linux/property.h index a29369c89e6e..a3813ded52ea 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -332,7 +332,26 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, /* -------------------------------------------------------------------------- */ /* Software fwnode support - when HW description is incomplete or missing */ +/** + * struct software_node - Software node description + * @name: Name of the software node + * @parent: Parent of the software node + * @properties: Array of device properties + */ +struct software_node { + const char *name; + const struct software_node *parent; + const struct property_entry *properties; +}; + bool is_software_node(const struct fwnode_handle *fwnode); +const struct software_node *to_software_node(struct fwnode_handle *fwnode); +struct fwnode_handle *software_node_fwnode(const struct software_node *node); + +int software_node_register_nodes(const struct software_node *nodes); +void software_node_unregister_nodes(const struct software_node *nodes); + +int software_node_register(const struct software_node *node); int software_node_notify(struct device *dev, unsigned long action); From patchwork Wed May 22 10:51:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955711 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 51E7E14C0 for ; Wed, 22 May 2019 10:52:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 422CC28980 for ; Wed, 22 May 2019 10:52:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 36EE428989; Wed, 22 May 2019 10:52:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E071A289D6 for ; Wed, 22 May 2019 10:52:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729284AbfEVKvY (ORCPT ); Wed, 22 May 2019 06:51:24 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729271AbfEVKvY (ORCPT ); Wed, 22 May 2019 06:51:24 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:24 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:22 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 04/16] software node: Use kobject name when finding child nodes by name Date: Wed, 22 May 2019 13:51:01 +0300 Message-Id: <20190522105113.11153-5-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Using the kobject name of the node instead of a device property "name" in software_node_get_named_child_node(). Signed-off-by: Heikki Krogerus --- drivers/base/swnode.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index ef1a48fec718..2d925fc2255f 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -546,17 +546,13 @@ software_node_get_named_child_node(const struct fwnode_handle *fwnode, const char *childname) { struct swnode *swnode = to_swnode(fwnode); - const struct property_entry *prop; struct swnode *child; if (!swnode || list_empty(&swnode->children)) return NULL; list_for_each_entry(child, &swnode->children, entry) { - prop = property_entry_get(child->node->properties, "name"); - if (!prop) - continue; - if (!strcmp(childname, prop->value.str)) { + if (!strcmp(childname, kobject_name(&child->kobj))) { kobject_get(&child->kobj); return &child->fwnode; } From patchwork Wed May 22 10:51:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955707 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 99BAE1708 for ; Wed, 22 May 2019 10:52:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C62D28980 for ; Wed, 22 May 2019 10:52:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 806CB289C6; Wed, 22 May 2019 10:52:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 217D128989 for ; Wed, 22 May 2019 10:52:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729332AbfEVKv1 (ORCPT ); Wed, 22 May 2019 06:51:27 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729271AbfEVKv0 (ORCPT ); Wed, 22 May 2019 06:51:26 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:26 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:24 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 05/16] software node: Add software_node_get_reference_args() Date: Wed, 22 May 2019 13:51:02 +0300 Message-Id: <20190522105113.11153-6-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This makes it possible to support drivers that use fwnode_property_get_reference_args() function. Signed-off-by: Heikki Krogerus --- drivers/base/swnode.c | 47 ++++++++++++++++++++++++++++++++++++++++ include/linux/property.h | 28 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 2d925fc2255f..e7b3aa3bd55a 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -560,6 +560,52 @@ software_node_get_named_child_node(const struct fwnode_handle *fwnode, return NULL; } +static int +software_node_get_reference_args(const struct fwnode_handle *fwnode, + const char *propname, const char *nargs_prop, + unsigned int nargs, unsigned int index, + struct fwnode_reference_args *args) +{ + struct swnode *swnode = to_swnode(fwnode); + const struct software_node_reference *ref; + const struct property_entry *prop; + struct fwnode_handle *refnode; + int i; + + if (!swnode || !swnode->node->references) + return -ENOENT; + + for (ref = swnode->node->references; ref->name; ref++) + if (!strcmp(ref->name, propname)) + break; + + if (!ref->name || index > (ref->nrefs - 1)) + return -ENOENT; + + refnode = software_node_fwnode(ref->refs[index].node); + if (!refnode) + return -ENOENT; + + if (nargs_prop) { + prop = property_entry_get(swnode->node->properties, nargs_prop); + if (!prop) + return -EINVAL; + + nargs = prop->value.u32_data; + } + + if (nargs > NR_FWNODE_REFERENCE_ARGS) + return -EINVAL; + + args->fwnode = software_node_get(refnode); + args->nargs = nargs; + + for (i = 0; i < nargs; i++) + args->args[i] = ref->refs[index].args[i]; + + return 0; +} + static const struct fwnode_operations software_node_ops = { .get = software_node_get, .put = software_node_put, @@ -569,6 +615,7 @@ static const struct fwnode_operations software_node_ops = { .get_parent = software_node_get_parent, .get_next_child_node = software_node_get_next_child, .get_named_child_node = software_node_get_named_child_node, + .get_reference_args = software_node_get_reference_args }; /* -------------------------------------------------------------------------- */ diff --git a/include/linux/property.h b/include/linux/property.h index a3813ded52ea..abcde2f236a0 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -332,16 +332,44 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, /* -------------------------------------------------------------------------- */ /* Software fwnode support - when HW description is incomplete or missing */ +struct software_node; + +/** + * struct software_node_ref_args - Reference with additional arguments + * @node: Reference to a software node + * @nargs: Number of elements in @args array + * @args: Integer arguments + */ +struct software_node_ref_args { + const struct software_node *node; + unsigned int nargs; + u64 args[NR_FWNODE_REFERENCE_ARGS]; +}; + +/** + * struct software_node_reference - Named software node reference property + * @name: Name of the property + * @nrefs: Number of elements in @refs array + * @refs: Array of references with optional arguments + */ +struct software_node_reference { + const char *name; + unsigned int nrefs; + const struct software_node_ref_args *refs; +}; + /** * struct software_node - Software node description * @name: Name of the software node * @parent: Parent of the software node * @properties: Array of device properties + * @references: Array of software node reference properties */ struct software_node { const char *name; const struct software_node *parent; const struct property_entry *properties; + const struct software_node_reference *references; }; bool is_software_node(const struct fwnode_handle *fwnode); From patchwork Wed May 22 10:51:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955701 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F285C17E0 for ; Wed, 22 May 2019 10:52:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E14EB289C6 for ; Wed, 22 May 2019 10:52:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D5C2228A50; Wed, 22 May 2019 10:52:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 43DD1289C6 for ; Wed, 22 May 2019 10:52:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729355AbfEVKv3 (ORCPT ); Wed, 22 May 2019 06:51:29 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729353AbfEVKv2 (ORCPT ); Wed, 22 May 2019 06:51:28 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:28 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:26 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 06/16] driver core: Add helper device_find_child_by_name() Date: Wed, 22 May 2019 13:51:03 +0300 Message-Id: <20190522105113.11153-7-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP It looks like the child device is often matched with a name. This introduces a helper that does it automatically. Signed-off-by: Heikki Krogerus Acked-by: Greg Kroah-Hartman --- drivers/base/core.c | 28 ++++++++++++++++++++++++++++ include/linux/device.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index fd7511e04e62..b4c64528f13c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2474,6 +2474,34 @@ struct device *device_find_child(struct device *parent, void *data, } EXPORT_SYMBOL_GPL(device_find_child); +/** + * device_find_child_by_name - device iterator for locating a child device. + * @parent: parent struct device + * @name: name of the child device + * + * This is similar to the device_find_child() function above, but it + * returns a reference to a device that has the name @name. + * + * NOTE: you will need to drop the reference with put_device() after use. + */ +struct device *device_find_child_by_name(struct device *parent, + const char *name) +{ + struct klist_iter i; + struct device *child; + + if (!parent) + return NULL; + + klist_iter_init(&parent->p->klist_children, &i); + while ((child = next_device(&i))) + if (!strcmp(dev_name(child), name) && get_device(child)) + break; + klist_iter_exit(&i); + return child; +} +EXPORT_SYMBOL_GPL(device_find_child_by_name); + int __init devices_init(void) { devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); diff --git a/include/linux/device.h b/include/linux/device.h index 72a6260f2b4d..a0da7d578257 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1250,6 +1250,8 @@ extern int device_for_each_child_reverse(struct device *dev, void *data, int (*fn)(struct device *dev, void *data)); extern struct device *device_find_child(struct device *dev, void *data, int (*match)(struct device *dev, void *data)); +extern struct device *device_find_child_by_name(struct device *parent, + const char *name); extern int device_rename(struct device *dev, const char *new_name); extern int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order); From patchwork Wed May 22 10:51:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955699 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E14DB1708 for ; Wed, 22 May 2019 10:52:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D2A11289CB for ; Wed, 22 May 2019 10:52:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C709928A0E; Wed, 22 May 2019 10:52:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EC857289CB for ; Wed, 22 May 2019 10:52:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729353AbfEVKvb (ORCPT ); Wed, 22 May 2019 06:51:31 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729379AbfEVKvb (ORCPT ); Wed, 22 May 2019 06:51:31 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:30 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:28 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 07/16] ACPI / property: Don't limit named child node matching to data nodes Date: Wed, 22 May 2019 13:51:04 +0300 Message-Id: <20190522105113.11153-8-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There is no reason why we should limit the use of fwnode_get_named_child_node() to data nodes only. Signed-off-by: Heikki Krogerus --- drivers/acpi/property.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 9d460a859be0..39c64291098f 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -603,15 +603,29 @@ static struct fwnode_handle * acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode, const char *childname) { + char name[ACPI_PATH_SEGMENT_LENGTH]; struct fwnode_handle *child; + struct acpi_buffer path; + acpi_status status; - /* - * Find first matching named child node of this fwnode. - * For ACPI this will be a data only sub-node. - */ - fwnode_for_each_child_node(fwnode, child) - if (acpi_data_node_match(child, childname)) + path.length = sizeof(name); + path.pointer = name; + + fwnode_for_each_child_node(fwnode, child) { + if (is_acpi_data_node(child)) { + if (acpi_data_node_match(child, childname)) + return child; + continue; + } + + status = acpi_get_name(ACPI_HANDLE_FWNODE(child), + ACPI_SINGLE_NAME, &path); + if (ACPI_FAILURE(status)) + break; + + if (!strncmp(name, childname, ACPI_NAMESEG_SIZE)) return child; + } return NULL; } From patchwork Wed May 22 10:51:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955689 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 83E871908 for ; Wed, 22 May 2019 10:52:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 72BDE28989 for ; Wed, 22 May 2019 10:52:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 66BD8289D7; Wed, 22 May 2019 10:52:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF187289CB for ; Wed, 22 May 2019 10:52:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729406AbfEVKvf (ORCPT ); Wed, 22 May 2019 06:51:35 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729397AbfEVKvd (ORCPT ); Wed, 22 May 2019 06:51:33 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:32 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:30 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 08/16] device property: Introduce fwnode_find_reference() Date: Wed, 22 May 2019 13:51:05 +0300 Message-Id: <20190522105113.11153-9-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In most cases the references that the drivers look for don't have any arguments. This introduces a wrapper function for fwnode_property_get_reference_args() that looks for references by using only the name and index. Signed-off-by: Heikki Krogerus --- drivers/base/property.c | 24 ++++++++++++++++++++++++ include/linux/property.h | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/drivers/base/property.c b/drivers/base/property.c index 348b37e64944..81bd01ed4042 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -484,6 +484,30 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args); +/** + * fwnode_find_reference - Find named reference to a fwnode_handle + * @fwnode: Firmware node where to look for the reference + * @name: The name of the reference + * @index: Index of the reference + * + * @index can be used when the named reference holds a table of references. + * + * Returns pointer to the reference fwnode, or ERR_PTR. Caller is responsible to + * call fwnode_handle_put() on the returned fwnode pointer. + */ +struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode, + const char *name, + unsigned int index) +{ + struct fwnode_reference_args args; + int ret; + + ret = fwnode_property_get_reference_args(fwnode, name, NULL, 0, index, + &args); + return ret ? ERR_PTR(ret) : args.fwnode; +} +EXPORT_SYMBOL_GPL(fwnode_find_reference); + /** * device_remove_properties - Remove properties from a device object. * @dev: Device whose properties to remove. diff --git a/include/linux/property.h b/include/linux/property.h index abcde2f236a0..088d4db7e949 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -79,6 +79,10 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, unsigned int nargs, unsigned int index, struct fwnode_reference_args *args); +struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode, + const char *name, + unsigned int index); + struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_get_next_parent( struct fwnode_handle *fwnode); From patchwork Wed May 22 10:51:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955697 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3224317E0 for ; Wed, 22 May 2019 10:52:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 22DDD289C6 for ; Wed, 22 May 2019 10:52:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 17634289D7; Wed, 22 May 2019 10:52:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BFF61289C6 for ; Wed, 22 May 2019 10:52:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729373AbfEVKwJ (ORCPT ); Wed, 22 May 2019 06:52:09 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729379AbfEVKvf (ORCPT ); Wed, 22 May 2019 06:51:35 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:34 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:32 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 09/16] device connection: Find connections also by checking the references Date: Wed, 22 May 2019 13:51:06 +0300 Message-Id: <20190522105113.11153-10-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We can also use this API to find named references that the device nodes have by using fwnode_property_get_reference_args() function. Signed-off-by: Heikki Krogerus --- drivers/base/devcon.c | 26 ++++++++++++++++++++++++++ drivers/usb/roles/class.c | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/base/devcon.c b/drivers/base/devcon.c index 04db9ae235e4..f7035fc12b92 100644 --- a/drivers/base/devcon.c +++ b/drivers/base/devcon.c @@ -38,6 +38,28 @@ fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id, return NULL; } +static void * +fwnode_devcon_match(struct fwnode_handle *fwnode, const char *con_id, + void *data, devcon_match_fn_t match) +{ + struct device_connection con = { }; + void *ret; + int i; + + for (i = 0; ; i++) { + con.fwnode = fwnode_find_reference(fwnode, con_id, i); + if (IS_ERR(con.fwnode)) + break; + + ret = match(&con, -1, data); + fwnode_handle_put(con.fwnode); + if (ret) + return ret; + } + + return NULL; +} + /** * device_connection_find_match - Find physical connection to a device * @dev: Device with the connection @@ -65,6 +87,10 @@ void *device_connection_find_match(struct device *dev, const char *con_id, ret = fwnode_graph_devcon_match(fwnode, con_id, data, match); if (ret) return ret; + + ret = fwnode_devcon_match(fwnode, con_id, data, match); + if (ret) + return ret; } mutex_lock(&devcon_lock); diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index f45d8df5cfb8..86defca6623e 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -101,7 +101,7 @@ static void *usb_role_switch_match(struct device_connection *con, int ep, struct device *dev; if (con->fwnode) { - if (!fwnode_property_present(con->fwnode, con->id)) + if (con->id && !fwnode_property_present(con->fwnode, con->id)) return NULL; dev = class_find_device(role_class, NULL, con->fwnode, From patchwork Wed May 22 10:51:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955683 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 428EF14C0 for ; Wed, 22 May 2019 10:52:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 271BC289D6 for ; Wed, 22 May 2019 10:52:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1B86E289D7; Wed, 22 May 2019 10:52:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B48FA28980 for ; Wed, 22 May 2019 10:52:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729426AbfEVKvi (ORCPT ); Wed, 22 May 2019 06:51:38 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729397AbfEVKvh (ORCPT ); Wed, 22 May 2019 06:51:37 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:37 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:34 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 10/16] usb: typec: Registering real device entries for the muxes Date: Wed, 22 May 2019 13:51:07 +0300 Message-Id: <20190522105113.11153-11-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Registering real device entries (struct device) for the mode muxes as well as for the orientation switches. The Type-C mux code was deliberately attempting to avoid creation of separate device entries for the orientation switch and the mode switch (alternate modes) because they are not physical devices. They are functions of a single physical multiplexer/demultiplexer switch device. Unfortunately because of the dependency we still have on the underlying mux device driver, we had to put in hacks like the one in the commit 3e3b81965cbf ("usb: typec: mux: Take care of driver module reference counting") to make sure the driver does not disappear from underneath us. Even with those hacks we were still left with a potential NUll pointer dereference scenario, so just creating the device entries, and letting the core take care of the dependencies. No more hacks needed. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko --- drivers/platform/x86/intel_cht_int33fe.c | 4 +- drivers/usb/typec/bus.h | 15 ++ drivers/usb/typec/class.c | 17 +- drivers/usb/typec/mux.c | 238 ++++++++++++++++------- drivers/usb/typec/mux/pi3usb30532.c | 46 +++-- include/linux/usb/typec_mux.h | 62 +++--- 6 files changed, 259 insertions(+), 123 deletions(-) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 6fa3cced6f8e..657b8d61554c 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -173,10 +173,10 @@ static int cht_int33fe_probe(struct platform_device *pdev) } data->connections[0].endpoint[0] = "port0"; - data->connections[0].endpoint[1] = "i2c-pi3usb30532"; + data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; data->connections[0].id = "orientation-switch"; data->connections[1].endpoint[0] = "port0"; - data->connections[1].endpoint[1] = "i2c-pi3usb30532"; + data->connections[1].endpoint[1] = "i2c-pi3usb30532-mux"; data->connections[1].id = "mode-switch"; data->connections[2].endpoint[0] = "i2c-fusb302"; data->connections[2].endpoint[1] = "intel_xhci_usb_sw-role-switch"; diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h index db40e61d8b72..0c9661c96473 100644 --- a/drivers/usb/typec/bus.h +++ b/drivers/usb/typec/bus.h @@ -35,4 +35,19 @@ extern const struct device_type typec_port_dev_type; #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type) #define is_typec_port(_dev_) (_dev_->type == &typec_port_dev_type) +extern struct class typec_mux_class; + +struct typec_switch { + struct device dev; + typec_switch_set_fn_t set; +}; + +struct typec_mux { + struct device dev; + typec_mux_set_fn_t set; +}; + +#define to_typec_switch(_dev_) container_of(_dev_, struct typec_switch, dev) +#define to_typec_mux(_dev_) container_of(_dev_, struct typec_mux, dev) + #endif /* __USB_TYPEC_ALTMODE_H__ */ diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 2eb623841847..a18285a990a8 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1646,13 +1646,25 @@ static int __init typec_init(void) if (ret) return ret; + ret = class_register(&typec_mux_class); + if (ret) + goto err_unregister_bus; + typec_class = class_create(THIS_MODULE, "typec"); if (IS_ERR(typec_class)) { - bus_unregister(&typec_bus); - return PTR_ERR(typec_class); + ret = PTR_ERR(typec_class); + goto err_unregister_mux_class; } return 0; + +err_unregister_mux_class: + class_unregister(&typec_mux_class); + +err_unregister_bus: + bus_unregister(&typec_bus); + + return ret; } subsys_initcall(typec_init); @@ -1661,6 +1673,7 @@ static void __exit typec_exit(void) class_destroy(typec_class); ida_destroy(&typec_index_ida); bus_unregister(&typec_bus); + class_unregister(&typec_mux_class); } module_exit(typec_exit); diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 2ce54f3fc79c..61b7bc58dd81 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -15,35 +15,47 @@ #include #include -static DEFINE_MUTEX(switch_lock); -static DEFINE_MUTEX(mux_lock); -static LIST_HEAD(switch_list); -static LIST_HEAD(mux_list); +#include "bus.h" + +static int name_match(struct device *dev, const void *name) +{ + return !strcmp((const char *)name, dev_name(dev)); +} + +static bool dev_name_ends_with(struct device *dev, const char *suffix) +{ + const char *name = dev_name(dev); + const int name_len = strlen(name); + const int suffix_len = strlen(suffix); + + if (suffix_len > name_len) + return false; + + return strcmp(name + (name_len - suffix_len), suffix) == 0; +} + +static int switch_fwnode_match(struct device *dev, const void *fwnode) +{ + return dev_fwnode(dev) == fwnode && dev_name_ends_with(dev, "-switch"); +} static void *typec_switch_match(struct device_connection *con, int ep, void *data) { - struct typec_switch *sw; - - if (!con->fwnode) { - list_for_each_entry(sw, &switch_list, entry) - if (!strcmp(con->endpoint[ep], dev_name(sw->dev))) - return sw; - return ERR_PTR(-EPROBE_DEFER); - } + struct device *dev; - /* - * With OF graph the mux node must have a boolean device property named - * "orientation-switch". - */ - if (con->id && !fwnode_property_present(con->fwnode, con->id)) - return NULL; + if (con->fwnode) { + if (con->id && !fwnode_property_present(con->fwnode, con->id)) + return NULL; - list_for_each_entry(sw, &switch_list, entry) - if (dev_fwnode(sw->dev) == con->fwnode) - return sw; + dev = class_find_device(&typec_mux_class, NULL, con->fwnode, + switch_fwnode_match); + } else { + dev = class_find_device(&typec_mux_class, NULL, + con->endpoint[ep], name_match); + } - return con->id ? ERR_PTR(-EPROBE_DEFER) : NULL; + return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER); } /** @@ -59,14 +71,10 @@ struct typec_switch *typec_switch_get(struct device *dev) { struct typec_switch *sw; - mutex_lock(&switch_lock); sw = device_connection_find_match(dev, "orientation-switch", NULL, typec_switch_match); - if (!IS_ERR_OR_NULL(sw)) { - WARN_ON(!try_module_get(sw->dev->driver->owner)); - get_device(sw->dev); - } - mutex_unlock(&switch_lock); + if (!IS_ERR_OR_NULL(sw)) + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); return sw; } @@ -81,28 +89,64 @@ EXPORT_SYMBOL_GPL(typec_switch_get); void typec_switch_put(struct typec_switch *sw) { if (!IS_ERR_OR_NULL(sw)) { - module_put(sw->dev->driver->owner); - put_device(sw->dev); + module_put(sw->dev.parent->driver->owner); + put_device(&sw->dev); } } EXPORT_SYMBOL_GPL(typec_switch_put); +static void typec_switch_release(struct device *dev) +{ + kfree(to_typec_switch(dev)); +} + +static const struct device_type typec_switch_dev_type = { + .name = "orientation_switch", + .release = typec_switch_release, +}; + /** * typec_switch_register - Register USB Type-C orientation switch - * @sw: USB Type-C orientation switch + * @parent: Parent device + * @desc: Orientation switch description * * This function registers a switch that can be used for routing the correct * data pairs depending on the cable plug orientation from the USB Type-C * connector to the USB controllers. USB Type-C plugs can be inserted * right-side-up or upside-down. */ -int typec_switch_register(struct typec_switch *sw) +struct typec_switch * +typec_switch_register(struct device *parent, + const struct typec_switch_desc *desc) { - mutex_lock(&switch_lock); - list_add_tail(&sw->entry, &switch_list); - mutex_unlock(&switch_lock); + struct typec_switch *sw; + int ret; + + if (!desc || !desc->set) + return ERR_PTR(-EINVAL); + + sw = kzalloc(sizeof(*sw), GFP_KERNEL); + if (!sw) + return ERR_PTR(-ENOMEM); - return 0; + sw->set = desc->set; + + device_initialize(&sw->dev); + sw->dev.parent = parent; + sw->dev.fwnode = desc->fwnode; + sw->dev.class = &typec_mux_class; + sw->dev.type = &typec_switch_dev_type; + sw->dev.driver_data = desc->drvdata; + dev_set_name(&sw->dev, "%s-switch", dev_name(parent)); + + ret = device_add(&sw->dev); + if (ret) { + dev_err(parent, "failed to register switch (%d)\n", ret); + put_device(&sw->dev); + return ERR_PTR(ret); + } + + return sw; } EXPORT_SYMBOL_GPL(typec_switch_register); @@ -114,28 +158,44 @@ EXPORT_SYMBOL_GPL(typec_switch_register); */ void typec_switch_unregister(struct typec_switch *sw) { - mutex_lock(&switch_lock); - list_del(&sw->entry); - mutex_unlock(&switch_lock); + if (!IS_ERR_OR_NULL(sw)) + device_unregister(&sw->dev); } EXPORT_SYMBOL_GPL(typec_switch_unregister); +void typec_switch_set_drvdata(struct typec_switch *sw, void *data) +{ + dev_set_drvdata(&sw->dev, data); +} +EXPORT_SYMBOL_GPL(typec_switch_set_drvdata); + +void *typec_switch_get_drvdata(struct typec_switch *sw) +{ + return dev_get_drvdata(&sw->dev); +} +EXPORT_SYMBOL_GPL(typec_switch_get_drvdata); + /* ------------------------------------------------------------------------- */ +static int mux_fwnode_match(struct device *dev, const void *fwnode) +{ + return dev_fwnode(dev) == fwnode && dev_name_ends_with(dev, "-mux"); +} + static void *typec_mux_match(struct device_connection *con, int ep, void *data) { const struct typec_altmode_desc *desc = data; - struct typec_mux *mux; - int nval; + struct device *dev; bool match; + int nval; u16 *val; int i; if (!con->fwnode) { - list_for_each_entry(mux, &mux_list, entry) - if (!strcmp(con->endpoint[ep], dev_name(mux->dev))) - return mux; - return ERR_PTR(-EPROBE_DEFER); + dev = class_find_device(&typec_mux_class, NULL, + con->endpoint[ep], name_match); + + return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER); } /* @@ -180,11 +240,10 @@ static void *typec_mux_match(struct device_connection *con, int ep, void *data) return NULL; find_mux: - list_for_each_entry(mux, &mux_list, entry) - if (dev_fwnode(mux->dev) == con->fwnode) - return mux; + dev = class_find_device(&typec_mux_class, NULL, con->fwnode, + mux_fwnode_match); - return ERR_PTR(-EPROBE_DEFER); + return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER); } /** @@ -202,14 +261,10 @@ struct typec_mux *typec_mux_get(struct device *dev, { struct typec_mux *mux; - mutex_lock(&mux_lock); mux = device_connection_find_match(dev, "mode-switch", (void *)desc, typec_mux_match); - if (!IS_ERR_OR_NULL(mux)) { - WARN_ON(!try_module_get(mux->dev->driver->owner)); - get_device(mux->dev); - } - mutex_unlock(&mux_lock); + if (!IS_ERR_OR_NULL(mux)) + WARN_ON(!try_module_get(mux->dev.parent->driver->owner)); return mux; } @@ -224,28 +279,63 @@ EXPORT_SYMBOL_GPL(typec_mux_get); void typec_mux_put(struct typec_mux *mux) { if (!IS_ERR_OR_NULL(mux)) { - module_put(mux->dev->driver->owner); - put_device(mux->dev); + module_put(mux->dev.parent->driver->owner); + put_device(&mux->dev); } } EXPORT_SYMBOL_GPL(typec_mux_put); +static void typec_mux_release(struct device *dev) +{ + kfree(to_typec_mux(dev)); +} + +static const struct device_type typec_mux_dev_type = { + .name = "mode_switch", + .release = typec_mux_release, +}; + /** * typec_mux_register - Register Multiplexer routing USB Type-C pins - * @mux: USB Type-C Connector Multiplexer/DeMultiplexer + * @parent: Parent device + * @desc: Multiplexer description * * USB Type-C connectors can be used for alternate modes of operation besides * USB when Accessory/Alternate Modes are supported. With some of those modes, * the pins on the connector need to be reconfigured. This function registers * multiplexer switches routing the pins on the connector. */ -int typec_mux_register(struct typec_mux *mux) +struct typec_mux * +typec_mux_register(struct device *parent, const struct typec_mux_desc *desc) { - mutex_lock(&mux_lock); - list_add_tail(&mux->entry, &mux_list); - mutex_unlock(&mux_lock); + struct typec_mux *mux; + int ret; + + if (!desc || !desc->set) + return ERR_PTR(-EINVAL); + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + mux->set = desc->set; + + device_initialize(&mux->dev); + mux->dev.parent = parent; + mux->dev.fwnode = desc->fwnode; + mux->dev.class = &typec_mux_class; + mux->dev.type = &typec_mux_dev_type; + mux->dev.driver_data = desc->drvdata; + dev_set_name(&mux->dev, "%s-mux", dev_name(parent)); + + ret = device_add(&mux->dev); + if (ret) { + dev_err(parent, "failed to register mux (%d)\n", ret); + put_device(&mux->dev); + return ERR_PTR(ret); + } - return 0; + return mux; } EXPORT_SYMBOL_GPL(typec_mux_register); @@ -257,8 +347,24 @@ EXPORT_SYMBOL_GPL(typec_mux_register); */ void typec_mux_unregister(struct typec_mux *mux) { - mutex_lock(&mux_lock); - list_del(&mux->entry); - mutex_unlock(&mux_lock); + if (!IS_ERR_OR_NULL(mux)) + device_unregister(&mux->dev); } EXPORT_SYMBOL_GPL(typec_mux_unregister); + +void typec_mux_set_drvdata(struct typec_mux *mux, void *data) +{ + dev_set_drvdata(&mux->dev, data); +} +EXPORT_SYMBOL_GPL(typec_mux_set_drvdata); + +void *typec_mux_get_drvdata(struct typec_mux *mux) +{ + return dev_get_drvdata(&mux->dev); +} +EXPORT_SYMBOL_GPL(typec_mux_get_drvdata); + +struct class typec_mux_class = { + .name = "typec_mux", + .owner = THIS_MODULE, +}; diff --git a/drivers/usb/typec/mux/pi3usb30532.c b/drivers/usb/typec/mux/pi3usb30532.c index 9294e85fd34b..5585b109095b 100644 --- a/drivers/usb/typec/mux/pi3usb30532.c +++ b/drivers/usb/typec/mux/pi3usb30532.c @@ -23,8 +23,8 @@ struct pi3usb30532 { struct i2c_client *client; struct mutex lock; /* protects the cached conf register */ - struct typec_switch sw; - struct typec_mux mux; + struct typec_switch *sw; + struct typec_mux *mux; u8 conf; }; @@ -48,7 +48,7 @@ static int pi3usb30532_set_conf(struct pi3usb30532 *pi, u8 new_conf) static int pi3usb30532_sw_set(struct typec_switch *sw, enum typec_orientation orientation) { - struct pi3usb30532 *pi = container_of(sw, struct pi3usb30532, sw); + struct pi3usb30532 *pi = typec_switch_get_drvdata(sw); u8 new_conf; int ret; @@ -75,7 +75,7 @@ static int pi3usb30532_sw_set(struct typec_switch *sw, static int pi3usb30532_mux_set(struct typec_mux *mux, int state) { - struct pi3usb30532 *pi = container_of(mux, struct pi3usb30532, mux); + struct pi3usb30532 *pi = typec_mux_get_drvdata(mux); u8 new_conf; int ret; @@ -113,6 +113,8 @@ static int pi3usb30532_mux_set(struct typec_mux *mux, int state) static int pi3usb30532_probe(struct i2c_client *client) { struct device *dev = &client->dev; + struct typec_switch_desc sw_desc; + struct typec_mux_desc mux_desc; struct pi3usb30532 *pi; int ret; @@ -121,10 +123,6 @@ static int pi3usb30532_probe(struct i2c_client *client) return -ENOMEM; pi->client = client; - pi->sw.dev = dev; - pi->sw.set = pi3usb30532_sw_set; - pi->mux.dev = dev; - pi->mux.set = pi3usb30532_mux_set; mutex_init(&pi->lock); ret = i2c_smbus_read_byte_data(client, PI3USB30532_CONF); @@ -134,17 +132,27 @@ static int pi3usb30532_probe(struct i2c_client *client) } pi->conf = ret; - ret = typec_switch_register(&pi->sw); - if (ret) { - dev_err(dev, "Error registering typec switch: %d\n", ret); - return ret; + sw_desc.drvdata = pi; + sw_desc.fwnode = dev->fwnode; + sw_desc.set = pi3usb30532_sw_set; + + pi->sw = typec_switch_register(dev, &sw_desc); + if (IS_ERR(pi->sw)) { + dev_err(dev, "Error registering typec switch: %ld\n", + PTR_ERR(pi->sw)); + return PTR_ERR(pi->sw); } - ret = typec_mux_register(&pi->mux); - if (ret) { - typec_switch_unregister(&pi->sw); - dev_err(dev, "Error registering typec mux: %d\n", ret); - return ret; + mux_desc.drvdata = pi; + mux_desc.fwnode = dev->fwnode; + mux_desc.set = pi3usb30532_mux_set; + + pi->mux = typec_mux_register(dev, &mux_desc); + if (IS_ERR(pi->mux)) { + typec_switch_unregister(pi->sw); + dev_err(dev, "Error registering typec mux: %ld\n", + PTR_ERR(pi->mux)); + return PTR_ERR(pi->mux); } i2c_set_clientdata(client, pi); @@ -155,8 +163,8 @@ static int pi3usb30532_remove(struct i2c_client *client) { struct pi3usb30532 *pi = i2c_get_clientdata(client); - typec_mux_unregister(&pi->mux); - typec_switch_unregister(&pi->sw); + typec_mux_unregister(pi->mux); + typec_switch_unregister(pi->sw); return 0; } diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h index 43f40685e53c..873ace5b0cf8 100644 --- a/include/linux/usb/typec_mux.h +++ b/include/linux/usb/typec_mux.h @@ -3,54 +3,48 @@ #ifndef __USB_TYPEC_MUX #define __USB_TYPEC_MUX -#include #include struct device; +struct typec_mux; +struct typec_switch; +struct fwnode_handle; -/** - * struct typec_switch - USB Type-C cable orientation switch - * @dev: Switch device - * @entry: List entry - * @set: Callback to the driver for setting the orientation - * - * USB Type-C pin flipper switch routing the correct data pairs from the - * connector to the USB controller depending on the orientation of the cable - * plug. - */ -struct typec_switch { - struct device *dev; - struct list_head entry; - - int (*set)(struct typec_switch *sw, enum typec_orientation orientation); -}; +typedef int (*typec_switch_set_fn_t)(struct typec_switch *sw, + enum typec_orientation orientation); -/** - * struct typec_switch - USB Type-C connector pin mux - * @dev: Mux device - * @entry: List entry - * @set: Callback to the driver for setting the state of the mux - * - * Pin Multiplexer/DeMultiplexer switch routing the USB Type-C connector pins to - * different components depending on the requested mode of operation. Used with - * Accessory/Alternate modes. - */ -struct typec_mux { - struct device *dev; - struct list_head entry; - - int (*set)(struct typec_mux *mux, int state); +struct typec_switch_desc { + struct fwnode_handle *fwnode; + typec_switch_set_fn_t set; + void *drvdata; }; struct typec_switch *typec_switch_get(struct device *dev); void typec_switch_put(struct typec_switch *sw); -int typec_switch_register(struct typec_switch *sw); +struct typec_switch * +typec_switch_register(struct device *parent, + const struct typec_switch_desc *desc); void typec_switch_unregister(struct typec_switch *sw); +void typec_switch_set_drvdata(struct typec_switch *sw, void *data); +void *typec_switch_get_drvdata(struct typec_switch *sw); + +typedef int (*typec_mux_set_fn_t)(struct typec_mux *mux, int state); + +struct typec_mux_desc { + struct fwnode_handle *fwnode; + typec_mux_set_fn_t set; + void *drvdata; +}; + struct typec_mux * typec_mux_get(struct device *dev, const struct typec_altmode_desc *desc); void typec_mux_put(struct typec_mux *mux); -int typec_mux_register(struct typec_mux *mux); +struct typec_mux * +typec_mux_register(struct device *parent, const struct typec_mux_desc *desc); void typec_mux_unregister(struct typec_mux *mux); +void typec_mux_set_drvdata(struct typec_mux *mux, void *data); +void *typec_mux_get_drvdata(struct typec_mux *mux); + #endif /* __USB_TYPEC_MUX */ From patchwork Wed May 22 10:51:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955655 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DBA5A1708 for ; Wed, 22 May 2019 10:51:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CAED928980 for ; Wed, 22 May 2019 10:51:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BEF552898B; Wed, 22 May 2019 10:51:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5D4E728980 for ; Wed, 22 May 2019 10:51:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729444AbfEVKvk (ORCPT ); Wed, 22 May 2019 06:51:40 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729442AbfEVKvj (ORCPT ); Wed, 22 May 2019 06:51:39 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:39 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:37 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 11/16] platform/x86: intel_cht_int33fe: Register max17047 in its own function Date: Wed, 22 May 2019 13:51:08 +0300 Message-Id: <20190522105113.11153-12-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To make the probe function a bit more nicer looking, moving the registration of max17047 to its own function. Signed-off-by: Heikki Krogerus --- drivers/platform/x86/intel_cht_int33fe.c | 62 +++++++++++++----------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 657b8d61554c..3f532b5a5133 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -63,14 +63,6 @@ static int cht_int33fe_check_for_max17047(struct device *dev, void *data) return 1; } -static struct i2c_client *cht_int33fe_find_max17047(void) -{ - struct i2c_client *max17047 = NULL; - - i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047); - return max17047; -} - static const char * const max17047_suppliers[] = { "bq24190-charger" }; static const struct property_entry max17047_props[] = { @@ -86,12 +78,40 @@ static const struct property_entry fusb302_props[] = { { } }; +static int +cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) +{ + struct i2c_client *max17047 = NULL; + struct i2c_board_info board_info; + int ret; + + i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047); + if (max17047) { + /* Pre-existing i2c-client for the max17047, add device-props */ + ret = device_add_properties(&max17047->dev, max17047_props); + if (ret) + return ret; + /* And re-probe to get the new device-props applied. */ + ret = device_reprobe(&max17047->dev); + if (ret) + dev_warn(dev, "Reprobing max17047 error: %d\n", ret); + return 0; + } + + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "max17047", I2C_NAME_SIZE); + board_info.dev_name = "max17047"; + board_info.properties = max17047_props; + data->max17047 = i2c_acpi_new_device(dev, 1, &board_info); + + return PTR_ERR_OR_ZERO(data->max17047); +} + static int cht_int33fe_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct i2c_board_info board_info; struct cht_int33fe_data *data; - struct i2c_client *max17047; struct regulator *regulator; unsigned long long ptyp; acpi_status status; @@ -151,26 +171,10 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - /* Work around BIOS bug, see comment on cht_int33fe_find_max17047 */ - max17047 = cht_int33fe_find_max17047(); - if (max17047) { - /* Pre-existing i2c-client for the max17047, add device-props */ - ret = device_add_properties(&max17047->dev, max17047_props); - if (ret) - return ret; - /* And re-probe to get the new device-props applied. */ - ret = device_reprobe(&max17047->dev); - if (ret) - dev_warn(dev, "Reprobing max17047 error: %d\n", ret); - } else { - memset(&board_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "max17047", I2C_NAME_SIZE); - board_info.dev_name = "max17047"; - board_info.properties = max17047_props; - data->max17047 = i2c_acpi_new_device(dev, 1, &board_info); - if (IS_ERR(data->max17047)) - return PTR_ERR(data->max17047); - } + /* Work around BIOS bug, see comment on cht_int33fe_check_for_max17047 */ + ret = cht_int33fe_register_max17047(dev, data); + if (ret) + return ret; data->connections[0].endpoint[0] = "port0"; data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; From patchwork Wed May 22 10:51:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955679 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5BB241708 for ; Wed, 22 May 2019 10:52:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E26B28980 for ; Wed, 22 May 2019 10:52:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4276328989; Wed, 22 May 2019 10:52:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 02C63289DD for ; Wed, 22 May 2019 10:52:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729442AbfEVKvm (ORCPT ); Wed, 22 May 2019 06:51:42 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729471AbfEVKvl (ORCPT ); Wed, 22 May 2019 06:51:41 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:41 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:39 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 12/16] platform/x86: intel_cht_int33fe: Remove unused fusb302 device property Date: Wed, 22 May 2019 13:51:09 +0300 Message-Id: <20190522105113.11153-13-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Device property "fcs,max-sink-microwatt" is not used in fusb302.c, so dropping it. Signed-off-by: Heikki Krogerus --- drivers/platform/x86/intel_cht_int33fe.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 3f532b5a5133..4ab47d6df413 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -74,7 +74,6 @@ static const struct property_entry fusb302_props[] = { PROPERTY_ENTRY_STRING("linux,extcon-name", "cht_wcove_pwrsrc"), PROPERTY_ENTRY_U32("fcs,max-sink-microvolt", 12000000), PROPERTY_ENTRY_U32("fcs,max-sink-microamp", 3000000), - PROPERTY_ENTRY_U32("fcs,max-sink-microwatt", 36000000), { } }; From patchwork Wed May 22 10:51:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955657 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DCB311708 for ; Wed, 22 May 2019 10:51:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CD19128980 for ; Wed, 22 May 2019 10:51:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C16642898B; Wed, 22 May 2019 10:51:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5066028980 for ; Wed, 22 May 2019 10:51:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729504AbfEVKvo (ORCPT ); Wed, 22 May 2019 06:51:44 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729471AbfEVKvn (ORCPT ); Wed, 22 May 2019 06:51:43 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:43 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:41 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 13/16] platform/x86: intel_cht_int33fe: Provide software nodes for the devices Date: Wed, 22 May 2019 13:51:10 +0300 Message-Id: <20190522105113.11153-14-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Software nodes provide two features that we will need later. 1) Software nodes can have references to other software nodes. 2) Software nodes can exist before a device entry is created. Signed-off-by: Heikki Krogerus --- drivers/platform/x86/intel_cht_int33fe.c | 53 ++++++++++++++++++++---- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 4ab47d6df413..a4ebd1d6b5b6 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -27,6 +27,13 @@ #define EXPECTED_PTYPE 4 +enum { + INT33FE_NODE_FUSB302, + INT33FE_NODE_MAX17047, + INT33FE_NODE_PI3USB30532, + INT33FE_NODE_MAX, +}; + struct cht_int33fe_data { struct i2c_client *max17047; struct i2c_client *fusb302; @@ -72,8 +79,13 @@ static const struct property_entry max17047_props[] = { static const struct property_entry fusb302_props[] = { PROPERTY_ENTRY_STRING("linux,extcon-name", "cht_wcove_pwrsrc"), - PROPERTY_ENTRY_U32("fcs,max-sink-microvolt", 12000000), - PROPERTY_ENTRY_U32("fcs,max-sink-microamp", 3000000), + { } +}; + +static const struct software_node nodes[] = { + { "fusb302", NULL, fusb302_props }, + { "max17047", NULL, max17047_props }, + { "pi3usb30532" }, { } }; @@ -82,14 +94,17 @@ cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) { struct i2c_client *max17047 = NULL; struct i2c_board_info board_info; + struct fwnode_handle *fwnode; int ret; + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_MAX17047]); + if (!fwnode) + return -ENODEV; + i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047); if (max17047) { /* Pre-existing i2c-client for the max17047, add device-props */ - ret = device_add_properties(&max17047->dev, max17047_props); - if (ret) - return ret; + max17047->dev.fwnode->secondary = fwnode; /* And re-probe to get the new device-props applied. */ ret = device_reprobe(&max17047->dev); if (ret) @@ -100,7 +115,7 @@ cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) memset(&board_info, 0, sizeof(board_info)); strlcpy(board_info.type, "max17047", I2C_NAME_SIZE); board_info.dev_name = "max17047"; - board_info.properties = max17047_props; + board_info.fwnode = fwnode; data->max17047 = i2c_acpi_new_device(dev, 1, &board_info); return PTR_ERR_OR_ZERO(data->max17047); @@ -111,6 +126,7 @@ static int cht_int33fe_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct i2c_board_info board_info; struct cht_int33fe_data *data; + struct fwnode_handle *fwnode; struct regulator *regulator; unsigned long long ptyp; acpi_status status; @@ -170,10 +186,14 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (!data) return -ENOMEM; + ret = software_node_register_nodes(nodes); + if (ret) + return ret; + /* Work around BIOS bug, see comment on cht_int33fe_check_for_max17047 */ ret = cht_int33fe_register_max17047(dev, data); if (ret) - return ret; + goto out_remove_nodes; data->connections[0].endpoint[0] = "port0"; data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; @@ -187,10 +207,16 @@ static int cht_int33fe_probe(struct platform_device *pdev) device_connections_add(data->connections); + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_FUSB302]); + if (!fwnode) { + ret = -ENODEV; + goto out_unregister_max17047; + } + memset(&board_info, 0, sizeof(board_info)); strlcpy(board_info.type, "typec_fusb302", I2C_NAME_SIZE); board_info.dev_name = "fusb302"; - board_info.properties = fusb302_props; + board_info.fwnode = fwnode; board_info.irq = fusb302_irq; data->fusb302 = i2c_acpi_new_device(dev, 2, &board_info); @@ -199,8 +225,15 @@ static int cht_int33fe_probe(struct platform_device *pdev) goto out_unregister_max17047; } + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_PI3USB30532]); + if (!fwnode) { + ret = -ENODEV; + goto out_unregister_fusb302; + } + memset(&board_info, 0, sizeof(board_info)); board_info.dev_name = "pi3usb30532"; + board_info.fwnode = fwnode; strlcpy(board_info.type, "pi3usb30532", I2C_NAME_SIZE); data->pi3usb30532 = i2c_acpi_new_device(dev, 3, &board_info); @@ -221,6 +254,9 @@ static int cht_int33fe_probe(struct platform_device *pdev) device_connections_remove(data->connections); +out_remove_nodes: + software_node_unregister_nodes(nodes); + return ret; } @@ -233,6 +269,7 @@ static int cht_int33fe_remove(struct platform_device *pdev) i2c_unregister_device(data->max17047); device_connections_remove(data->connections); + software_node_unregister_nodes(nodes); return 0; } From patchwork Wed May 22 10:51:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955673 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C31F1708 for ; Wed, 22 May 2019 10:52:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E5C628980 for ; Wed, 22 May 2019 10:52:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 42F30289C6; Wed, 22 May 2019 10:52:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E205A28989 for ; Wed, 22 May 2019 10:52:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729532AbfEVKvt (ORCPT ); Wed, 22 May 2019 06:51:49 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729326AbfEVKvt (ORCPT ); Wed, 22 May 2019 06:51:49 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:45 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:43 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 14/16] platform/x86: intel_cht_int33fe: Provide fwnode for the USB connector Date: Wed, 22 May 2019 13:51:11 +0300 Message-Id: <20190522105113.11153-15-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In ACPI, and now also in DT, the USB connectors usually have their own device nodes. In case of USB Type-C, those connector (port) nodes are child nodes of the controller or PHY device, in our case the fusb302. The software fwnodes allow us to create a similar child node for fusb302 that represents the connector also on Intel CHT. This makes it possible replace the fusb302 specific device properties which were deprecated with the common USB connector properties that tcpm.c is able to use directly. Signed-off-by: Heikki Krogerus --- drivers/platform/x86/intel_cht_int33fe.c | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index a4ebd1d6b5b6..34bc2d178760 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -24,6 +24,7 @@ #include #include #include +#include #define EXPECTED_PTYPE 4 @@ -31,6 +32,7 @@ enum { INT33FE_NODE_FUSB302, INT33FE_NODE_MAX17047, INT33FE_NODE_PI3USB30532, + INT33FE_NODE_USB_CONNECTOR, INT33FE_NODE_MAX, }; @@ -82,10 +84,33 @@ static const struct property_entry fusb302_props[] = { { } }; +#define PDO_FIXED_FLAGS \ + (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM) + +static const u32 src_pdo[] = { + PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), +}; + +static const u32 snk_pdo[] = { + PDO_FIXED(5000, 400, PDO_FIXED_FLAGS), + PDO_VAR(5000, 12000, 3000), +}; + +static const struct property_entry usb_connector_props[] = { + PROPERTY_ENTRY_STRING("data-role", "dual"), + PROPERTY_ENTRY_STRING("power-role", "dual"), + PROPERTY_ENTRY_STRING("try-power-role", "sink"), + PROPERTY_ENTRY_U32_ARRAY("source-pdos", src_pdo), + PROPERTY_ENTRY_U32_ARRAY("sink-pdos", snk_pdo), + PROPERTY_ENTRY_U32("op-sink-microwatt", 2500000), + { } +}; + static const struct software_node nodes[] = { { "fusb302", NULL, fusb302_props }, { "max17047", NULL, max17047_props }, { "pi3usb30532" }, + { "connector", &nodes[0], usb_connector_props }, { } }; From patchwork Wed May 22 10:51:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10955669 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C8651708 for ; Wed, 22 May 2019 10:51:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5D17F28980 for ; Wed, 22 May 2019 10:51:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 51950289C6; Wed, 22 May 2019 10:51:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CC56828980 for ; Wed, 22 May 2019 10:51:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729357AbfEVKv6 (ORCPT ); Wed, 22 May 2019 06:51:58 -0400 Received: from mga07.intel.com ([134.134.136.100]:32515 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729527AbfEVKvu (ORCPT ); Wed, 22 May 2019 06:51:50 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:49 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:45 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 15/16] platform/x86: intel_cht_int33fe: Supply fwnodes for the external dependencies Date: Wed, 22 May 2019 13:51:12 +0300 Message-Id: <20190522105113.11153-16-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Supplying also external devices, the DisplayPort connector and the USB role switch, software fwnodes. After this the driver has access to all the components tied to the USB Type-C connector and can start creating software node references to actually associate them with the USB Type-C connector device. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko --- drivers/platform/x86/intel_cht_int33fe.c | 128 ++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 34bc2d178760..e5c0b6573618 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,8 @@ enum { INT33FE_NODE_FUSB302, INT33FE_NODE_MAX17047, INT33FE_NODE_PI3USB30532, + INT33FE_NODE_DISPLAYPORT, + INT33FE_NODE_ROLE_SWITCH, INT33FE_NODE_USB_CONNECTOR, INT33FE_NODE_MAX, }; @@ -42,6 +45,9 @@ struct cht_int33fe_data { struct i2c_client *pi3usb30532; /* Contain a list-head must be per device */ struct device_connection connections[4]; + + struct fwnode_handle *dp; + struct fwnode_handle *mux; }; /* @@ -110,10 +116,126 @@ static const struct software_node nodes[] = { { "fusb302", NULL, fusb302_props }, { "max17047", NULL, max17047_props }, { "pi3usb30532" }, + { "displayport" }, + { "usb-role-switch" }, { "connector", &nodes[0], usb_connector_props }, { } }; +static int cht_int33fe_setup_mux(struct cht_int33fe_data *data) +{ + struct fwnode_handle *fwnode; + struct device *dev; + struct device *p; + + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_ROLE_SWITCH]); + if (!fwnode) + return -ENODEV; + + /* First finding the platform device */ + p = bus_find_device_by_name(&platform_bus_type, NULL, + "intel_xhci_usb_sw"); + if (!p) + return -EPROBE_DEFER; + + /* Then the mux child device */ + dev = device_find_child_by_name(p, "intel_xhci_usb_sw-role-switch"); + put_device(p); + if (!dev) + return -EPROBE_DEFER; + + /* If there already is a node for the mux, using that one. */ + if (dev->fwnode) + fwnode_remove_software_node(fwnode); + else + dev->fwnode = fwnode; + + data->mux = fwnode_handle_get(dev->fwnode); + put_device(dev); + + return 0; +} + +static int cht_int33fe_setup_dp(struct cht_int33fe_data *data) +{ + struct fwnode_handle *fwnode; + struct pci_dev *pdev; + + fwnode = software_node_fwnode(&nodes[INT33FE_NODE_DISPLAYPORT]); + if (!fwnode) + return -ENODEV; + + /* First let's find the GPU PCI device */ + pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); + if (!pdev || pdev->vendor != PCI_VENDOR_ID_INTEL) { + pci_dev_put(pdev); + return -ENODEV; + } + + /* Then the DP child device node */ + data->dp = device_get_named_child_node(&pdev->dev, "DD02"); + pci_dev_put(pdev); + if (!data->dp) + return -ENODEV; + + fwnode->secondary = ERR_PTR(-ENODEV); + data->dp->secondary = fwnode; + + return 0; +} + +static void cht_int33fe_remove_nodes(struct cht_int33fe_data *data) +{ + software_node_unregister_nodes(nodes); + + if (data->mux) { + fwnode_handle_put(data->mux); + data->mux = NULL; + } + + if (data->dp) { + data->dp->secondary = NULL; + fwnode_handle_put(data->dp); + data->dp = NULL; + } +} + +static int cht_int33fe_add_nodes(struct cht_int33fe_data *data) +{ + int ret; + + ret = software_node_register_nodes(nodes); + if (ret) + return ret; + + /* The devices that are not created in this driver need extra steps. */ + + /* + * There is no ACPI device node for the USB role mux, so we need to find + * the mux device and assign our node directly to it. That means we + * depend on the mux driver. This function will return -PROBE_DEFER + * until the mux device is registered. + */ + ret = cht_int33fe_setup_mux(data); + if (ret) + goto err_remove_nodes; + + /* + * The DP connector does have ACPI device node. In this case we can just + * find that ACPI node and assing our node as the secondary node to it. + */ + ret = cht_int33fe_setup_dp(data); + if (ret) + goto err_remove_nodes; + + return 0; + +err_remove_nodes: + cht_int33fe_remove_nodes(data); + + return ret; +} + static int cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data) { @@ -211,7 +333,7 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - ret = software_node_register_nodes(nodes); + ret = cht_int33fe_add_nodes(data); if (ret) return ret; @@ -280,7 +402,7 @@ static int cht_int33fe_probe(struct platform_device *pdev) device_connections_remove(data->connections); out_remove_nodes: - software_node_unregister_nodes(nodes); + cht_int33fe_remove_nodes(data); return ret; } @@ -294,7 +416,7 @@ static int cht_int33fe_remove(struct platform_device *pdev) i2c_unregister_device(data->max17047); device_connections_remove(data->connections); - software_node_unregister_nodes(nodes); + cht_int33fe_remove_nodes(data); return 0; } From patchwork Wed May 22 10:51: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: 10955665 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 667E91708 for ; Wed, 22 May 2019 10:51:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5971A28989 for ; Wed, 22 May 2019 10:51:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D8F8289D7; Wed, 22 May 2019 10:51:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E1E9D28989 for ; Wed, 22 May 2019 10:51:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729542AbfEVKvu (ORCPT ); Wed, 22 May 2019 06:51:50 -0400 Received: from mga07.intel.com ([134.134.136.100]:32570 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729535AbfEVKvu (ORCPT ); Wed, 22 May 2019 06:51:50 -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 orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 May 2019 03:51:49 -0700 X-ExtLoop1: 1 Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 22 May 2019 03:51:47 -0700 From: Heikki Krogerus To: "Rafael J. Wysocki" , Hans de Goede Cc: Greg Kroah-Hartman , Andy Shevchenko , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v4 16/16] platform/x86: intel_cht_int33fe: Replacing the old connections with references Date: Wed, 22 May 2019 13:51:13 +0300 Message-Id: <20190522105113.11153-17-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> References: <20190522105113.11153-1-heikki.krogerus@linux.intel.com> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Replacing the old connection descriptions with software node references. Supplying the USB connector also a reference to the DisplayPort while at it. Signed-off-by: Heikki Krogerus --- drivers/platform/x86/intel_cht_int33fe.c | 47 ++++++++++++++---------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index e5c0b6573618..e06b399ffd8e 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -43,13 +43,35 @@ struct cht_int33fe_data { struct i2c_client *max17047; struct i2c_client *fusb302; struct i2c_client *pi3usb30532; - /* Contain a list-head must be per device */ - struct device_connection connections[4]; struct fwnode_handle *dp; struct fwnode_handle *mux; }; +static const struct software_node nodes[]; + +static const struct software_node_ref_args pi3usb30532_ref = { + &nodes[INT33FE_NODE_PI3USB30532] +}; + +static const struct software_node_ref_args dp_ref = { + &nodes[INT33FE_NODE_DISPLAYPORT] +}; + +static struct software_node_ref_args mux_ref; + +static const struct software_node_reference usb_connector_refs[] = { + { "orientation-switch", 1, &pi3usb30532_ref}, + { "mode-switch", 1, &pi3usb30532_ref}, + { "displayport", 1, &dp_ref}, + { } +}; + +static const struct software_node_reference fusb302_refs[] = { + { "usb-role-switch", 1, &mux_ref}, + { } +}; + /* * Grrr I severly dislike buggy BIOS-es. At least one BIOS enumerates * the max17047 both through the INT33FE ACPI device (it is right there @@ -113,12 +135,12 @@ static const struct property_entry usb_connector_props[] = { }; static const struct software_node nodes[] = { - { "fusb302", NULL, fusb302_props }, + { "fusb302", NULL, fusb302_props, fusb302_refs }, { "max17047", NULL, max17047_props }, { "pi3usb30532" }, { "displayport" }, { "usb-role-switch" }, - { "connector", &nodes[0], usb_connector_props }, + { "connector", &nodes[0], usb_connector_props, usb_connector_refs }, { } }; @@ -152,6 +174,7 @@ static int cht_int33fe_setup_mux(struct cht_int33fe_data *data) data->mux = fwnode_handle_get(dev->fwnode); put_device(dev); + mux_ref.node = to_software_node(data->mux); return 0; } @@ -190,6 +213,7 @@ static void cht_int33fe_remove_nodes(struct cht_int33fe_data *data) if (data->mux) { fwnode_handle_put(data->mux); + mux_ref.node = NULL; data->mux = NULL; } @@ -342,18 +366,6 @@ static int cht_int33fe_probe(struct platform_device *pdev) if (ret) goto out_remove_nodes; - data->connections[0].endpoint[0] = "port0"; - data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; - data->connections[0].id = "orientation-switch"; - data->connections[1].endpoint[0] = "port0"; - data->connections[1].endpoint[1] = "i2c-pi3usb30532-mux"; - data->connections[1].id = "mode-switch"; - data->connections[2].endpoint[0] = "i2c-fusb302"; - data->connections[2].endpoint[1] = "intel_xhci_usb_sw-role-switch"; - data->connections[2].id = "usb-role-switch"; - - device_connections_add(data->connections); - fwnode = software_node_fwnode(&nodes[INT33FE_NODE_FUSB302]); if (!fwnode) { ret = -ENODEV; @@ -399,8 +411,6 @@ static int cht_int33fe_probe(struct platform_device *pdev) out_unregister_max17047: i2c_unregister_device(data->max17047); - device_connections_remove(data->connections); - out_remove_nodes: cht_int33fe_remove_nodes(data); @@ -415,7 +425,6 @@ static int cht_int33fe_remove(struct platform_device *pdev) i2c_unregister_device(data->fusb302); i2c_unregister_device(data->max17047); - device_connections_remove(data->connections); cht_int33fe_remove_nodes(data); return 0;