Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'devprop-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull device properties framework updates from Rafael Wysocki:
"Improve software node support (Heikki Krogerus) and clean up two
assorted pieces of code (Andy Shevchenko, Geert Uytterhoeven)"

* tag 'devprop-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
software node: Initialize the return value in software_node_find_by_name()
software node: Initialize the return value in software_node_to_swnode()
ACPI / property: Fix acpi_graph_get_remote_endpoint() name in kerneldoc
device property: Remove duplicate test for NULL
platform/x86: intel_cht_int33fe: Use new API to gain access to the role switch
usb: roles: intel_xhci: Supplying software node for the role mux
software node: Add software_node_find_by_name()

+78 -60
+1 -1
drivers/acpi/property.c
··· 1210 1210 1211 1211 1212 1212 /** 1213 - * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint 1213 + * acpi_graph_get_remote_endpoint - Parses and returns remote end of an endpoint 1214 1214 * @fwnode: Endpoint firmware node pointing to a remote device 1215 1215 * @endpoint: Firmware node of remote endpoint is filled here if not %NULL 1216 1216 *
+38 -1
drivers/base/swnode.c
··· 51 51 static struct swnode * 52 52 software_node_to_swnode(const struct software_node *node) 53 53 { 54 - struct swnode *swnode; 54 + struct swnode *swnode = NULL; 55 55 struct kobject *k; 56 56 57 57 if (!node) ··· 619 619 }; 620 620 621 621 /* -------------------------------------------------------------------------- */ 622 + 623 + /** 624 + * software_node_find_by_name - Find software node by name 625 + * @parent: Parent of the software node 626 + * @name: Name of the software node 627 + * 628 + * The function will find a node that is child of @parent and that is named 629 + * @name. If no node is found, the function returns NULL. 630 + * 631 + * NOTE: you will need to drop the reference with fwnode_handle_put() after use. 632 + */ 633 + const struct software_node * 634 + software_node_find_by_name(const struct software_node *parent, const char *name) 635 + { 636 + struct swnode *swnode = NULL; 637 + struct kobject *k; 638 + 639 + if (!name) 640 + return NULL; 641 + 642 + spin_lock(&swnode_kset->list_lock); 643 + 644 + list_for_each_entry(k, &swnode_kset->list, entry) { 645 + swnode = kobj_to_swnode(k); 646 + if (parent == swnode->node->parent && swnode->node->name && 647 + !strcmp(name, swnode->node->name)) { 648 + kobject_get(&swnode->kobj); 649 + break; 650 + } 651 + swnode = NULL; 652 + } 653 + 654 + spin_unlock(&swnode_kset->list_lock); 655 + 656 + return swnode ? swnode->node : NULL; 657 + } 658 + EXPORT_SYMBOL_GPL(software_node_find_by_name); 622 659 623 660 static int 624 661 software_node_register_properties(struct software_node *node,
+10 -47
drivers/platform/x86/intel_cht_int33fe.c
··· 34 34 INT33FE_NODE_MAX17047, 35 35 INT33FE_NODE_PI3USB30532, 36 36 INT33FE_NODE_DISPLAYPORT, 37 - INT33FE_NODE_ROLE_SWITCH, 38 37 INT33FE_NODE_USB_CONNECTOR, 39 38 INT33FE_NODE_MAX, 40 39 }; ··· 44 45 struct i2c_client *pi3usb30532; 45 46 46 47 struct fwnode_handle *dp; 47 - struct fwnode_handle *mux; 48 48 }; 49 49 50 50 static const struct software_node nodes[]; ··· 137 139 { "max17047", NULL, max17047_props }, 138 140 { "pi3usb30532" }, 139 141 { "displayport" }, 140 - { "usb-role-switch" }, 141 142 { "connector", &nodes[0], usb_connector_props, usb_connector_refs }, 142 143 { } 143 144 }; 144 - 145 - static int cht_int33fe_setup_mux(struct cht_int33fe_data *data) 146 - { 147 - struct fwnode_handle *fwnode; 148 - struct device *dev; 149 - struct device *p; 150 - 151 - fwnode = software_node_fwnode(&nodes[INT33FE_NODE_ROLE_SWITCH]); 152 - if (!fwnode) 153 - return -ENODEV; 154 - 155 - /* First finding the platform device */ 156 - p = bus_find_device_by_name(&platform_bus_type, NULL, 157 - "intel_xhci_usb_sw"); 158 - if (!p) 159 - return -EPROBE_DEFER; 160 - 161 - /* Then the mux child device */ 162 - dev = device_find_child_by_name(p, "intel_xhci_usb_sw-role-switch"); 163 - put_device(p); 164 - if (!dev) 165 - return -EPROBE_DEFER; 166 - 167 - /* If there already is a node for the mux, using that one. */ 168 - if (dev->fwnode) 169 - fwnode_remove_software_node(fwnode); 170 - else 171 - dev->fwnode = fwnode; 172 - 173 - data->mux = fwnode_handle_get(dev->fwnode); 174 - put_device(dev); 175 - mux_ref.node = to_software_node(data->mux); 176 - 177 - return 0; 178 - } 179 145 180 146 static int cht_int33fe_setup_dp(struct cht_int33fe_data *data) 181 147 { ··· 173 211 { 174 212 software_node_unregister_nodes(nodes); 175 213 176 - if (data->mux) { 177 - fwnode_handle_put(data->mux); 214 + if (mux_ref.node) { 215 + fwnode_handle_put(software_node_fwnode(mux_ref.node)); 178 216 mux_ref.node = NULL; 179 - data->mux = NULL; 180 217 } 181 218 182 219 if (data->dp) { ··· 196 235 /* The devices that are not created in this driver need extra steps. */ 197 236 198 237 /* 199 - * There is no ACPI device node for the USB role mux, so we need to find 200 - * the mux device and assign our node directly to it. That means we 201 - * depend on the mux driver. This function will return -PROBE_DEFER 202 - * until the mux device is registered. 238 + * There is no ACPI device node for the USB role mux, so we need to wait 239 + * until the mux driver has created software node for the mux device. 240 + * It means we depend on the mux driver. This function will return 241 + * -EPROBE_DEFER until the mux device is registered. 203 242 */ 204 - ret = cht_int33fe_setup_mux(data); 205 - if (ret) 243 + mux_ref.node = software_node_find_by_name(NULL, "intel-xhci-usb-sw"); 244 + if (!mux_ref.node) { 245 + ret = -EPROBE_DEFER; 206 246 goto err_remove_nodes; 247 + } 207 248 208 249 /* 209 250 * The DP connector does have ACPI device node. In this case we can just
+20 -7
drivers/usb/roles/intel-xhci-usb-role-switch.c
··· 39 39 void __iomem *base; 40 40 }; 41 41 42 + static const struct software_node intel_xhci_usb_node = { 43 + "intel-xhci-usb-sw", 44 + }; 45 + 42 46 static int intel_xhci_usb_set_role(struct device *dev, enum usb_role role) 43 47 { 44 48 struct intel_xhci_usb_data *data = dev_get_drvdata(dev); ··· 126 122 return role; 127 123 } 128 124 129 - static const struct usb_role_switch_desc sw_desc = { 130 - .set = intel_xhci_usb_set_role, 131 - .get = intel_xhci_usb_get_role, 132 - .allow_userspace_control = true, 133 - }; 134 - 135 125 static int intel_xhci_usb_probe(struct platform_device *pdev) 136 126 { 127 + struct usb_role_switch_desc sw_desc = { }; 137 128 struct device *dev = &pdev->dev; 138 129 struct intel_xhci_usb_data *data; 139 130 struct resource *res; 131 + int ret; 140 132 141 133 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 142 134 if (!data) ··· 147 147 148 148 platform_set_drvdata(pdev, data); 149 149 150 + ret = software_node_register(&intel_xhci_usb_node); 151 + if (ret) 152 + return ret; 153 + 154 + sw_desc.set = intel_xhci_usb_set_role, 155 + sw_desc.get = intel_xhci_usb_get_role, 156 + sw_desc.allow_userspace_control = true, 157 + sw_desc.fwnode = software_node_fwnode(&intel_xhci_usb_node); 158 + 150 159 data->role_sw = usb_role_switch_register(dev, &sw_desc); 151 - if (IS_ERR(data->role_sw)) 160 + if (IS_ERR(data->role_sw)) { 161 + fwnode_handle_put(sw_desc.fwnode); 152 162 return PTR_ERR(data->role_sw); 163 + } 153 164 154 165 pm_runtime_set_active(dev); 155 166 pm_runtime_enable(dev); ··· 175 164 pm_runtime_disable(&pdev->dev); 176 165 177 166 usb_role_switch_unregister(data->role_sw); 167 + fwnode_handle_put(software_node_fwnode(&intel_xhci_usb_node)); 168 + 178 169 return 0; 179 170 } 180 171
+5 -4
include/linux/fwnode.h
··· 110 110 (fwnode ? (fwnode_has_op(fwnode, op) ? \ 111 111 (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \ 112 112 -EINVAL) 113 - #define fwnode_call_bool_op(fwnode, op, ...) \ 114 - (fwnode ? (fwnode_has_op(fwnode, op) ? \ 115 - (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : false) : \ 116 - false) 113 + 114 + #define fwnode_call_bool_op(fwnode, op, ...) \ 115 + (fwnode_has_op(fwnode, op) ? \ 116 + (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : false) 117 + 117 118 #define fwnode_call_ptr_op(fwnode, op, ...) \ 118 119 (fwnode_has_op(fwnode, op) ? \ 119 120 (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : NULL)
+4
include/linux/property.h
··· 421 421 const struct software_node *to_software_node(struct fwnode_handle *fwnode); 422 422 struct fwnode_handle *software_node_fwnode(const struct software_node *node); 423 423 424 + const struct software_node * 425 + software_node_find_by_name(const struct software_node *parent, 426 + const char *name); 427 + 424 428 int software_node_register_nodes(const struct software_node *nodes); 425 429 void software_node_unregister_nodes(const struct software_node *nodes); 426 430