From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9CF3EC001DF for ; Sat, 29 Jul 2023 14:57:28 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7984986751; Sat, 29 Jul 2023 16:57:26 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1690642646; bh=0k4G1N6DKp3NUjcE6ipG9Ayj0maDZMD2D9pqJMkZ1m8=; h=From:To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=KizaEktHIrB/EQ/totk3G/GBheUtV7Nu1EH5pX11uPE5KwWDmYerAhMJ/qTWcBJvr Q++NZFONYdqxPjtYjPC8A0Zpt6aVKQvK9se8EsPMvxYvQrGXlm66Zp6dbZ6GkOHLx0 Ds96xgqaQzRZwEfyKUMQF4O852wks9hWoDvwPPOIbP4dFksXrtUaq2tMSeR6SnYxov Q5aSZ6NpFy8Ju92jf6drCGe3TJsZROWp2v/gIG0SP71jUf/si7gm0OZA7OjJiouUUS PXvYqZv/QHsfAgLppwcYV9wg6FbP/vtQlPkgkJjly8MpjUoTyHntD3KImBChB8V4bq Jahsr4wATc1GA== Received: from tr.lan (ip-86-49-120-218.bb.vodafone.cz [86.49.120.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id E421686751; Sat, 29 Jul 2023 16:57:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1690642645; bh=0k4G1N6DKp3NUjcE6ipG9Ayj0maDZMD2D9pqJMkZ1m8=; h=From:To:Cc:Subject:Date:From; b=KcGtV14tIxHinqgt4+Eixyejo5pPans5j+LcLgZxEtYNY2zoQr6jiXM1ecUlAWeGB oLLjvhd0FqyUosK5kLoldYBSAgGqluCJ9rZEvGaq6mQ+GSxcR/Yom99Doe+YoaDOqF rClk6+UDokKi9mUurZCwrX8qPBCho740z3qbhHW2eaFU6QH5QQ9ggy7v/zgKRgGXSd iVL1VKis20fzhj29BovWSMLu2k1uE10UaDQQAYsx+pzjZQKuORpo8yw/TTG3vBptw/ RMy7cmajX7gkzzOgUCUnNAFjNcpMjXCsFvDnZ5zoWvFAt+Bqqidw9P/bYLJaVFpw03 WmYsc5N1aQy9A== From: Marek Vasut To: u-boot@lists.denx.de Cc: Marek Vasut , Kevin Hilman , Lukasz Majewski , Miquel Raynal , Simon Glass Subject: [PATCH v3 1/4] cmd: bind: Add unbind command with driver filter Date: Sat, 29 Jul 2023 16:57:09 +0200 Message-Id: <20230729145712.213945-1-marex@denx.de> X-Mailer: git-send-email 2.40.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Extend the driver core to perform lookup by both OF node and driver bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller. USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether " Signed-off-by: Marek Vasut --- Cc: Kevin Hilman Cc: Lukasz Majewski Cc: Miquel Raynal Cc: Simon Glass --- V2: No change V3: No change --- cmd/bind.c | 10 +++++----- drivers/core/device.c | 20 +++++++++++++++----- include/dm/device.h | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/cmd/bind.c b/cmd/bind.c index 4d1b7885e60..3137cdf6cb5 100644 --- a/cmd/bind.c +++ b/cmd/bind.c @@ -162,7 +162,7 @@ static int bind_by_node_path(const char *path, const char *drv_name) return 0; } -static int unbind_by_node_path(const char *path) +static int unbind_by_node_path(const char *path, const char *drv_name) { struct udevice *dev; int ret; @@ -174,7 +174,7 @@ static int unbind_by_node_path(const char *path) return -EINVAL; } - ret = device_find_global_by_ofnode(ofnode, &dev); + ret = device_find_global_by_ofnode_driver(ofnode, drv_name, &dev); if (!dev || ret) { printf("Cannot find a device with path %s\n", path); @@ -214,9 +214,9 @@ static int do_bind_unbind(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; ret = bind_by_node_path(argv[1], argv[2]); } else if (by_node && !bind) { - if (argc != 2) + if (argc != 2 && argc != 3) return CMD_RET_USAGE; - ret = unbind_by_node_path(argv[1]); + ret = unbind_by_node_path(argv[1], argv[2]); } else if (!by_node && bind) { int index = (argc > 2) ? dectoul(argv[2], NULL) : 0; @@ -251,7 +251,7 @@ U_BOOT_CMD( U_BOOT_CMD( unbind, 4, 0, do_bind_unbind, "Unbind a device from a driver", - "\n" + " []\n" "unbind \n" "unbind \n" ); diff --git a/drivers/core/device.c b/drivers/core/device.c index 6e26b64fb81..52fceb69341 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -877,15 +877,17 @@ int device_get_child_by_of_offset(const struct udevice *parent, int node, } static struct udevice *_device_find_global_by_ofnode(struct udevice *parent, - ofnode ofnode) + ofnode ofnode, + const char *drv) { struct udevice *dev, *found; - if (ofnode_equal(dev_ofnode(parent), ofnode)) + if (ofnode_equal(dev_ofnode(parent), ofnode) && + (!drv || (drv && !strcmp(parent->driver->name, drv)))) return parent; device_foreach_child(dev, parent) { - found = _device_find_global_by_ofnode(dev, ofnode); + found = _device_find_global_by_ofnode(dev, ofnode, drv); if (found) return found; } @@ -895,7 +897,15 @@ static struct udevice *_device_find_global_by_ofnode(struct udevice *parent, int device_find_global_by_ofnode(ofnode ofnode, struct udevice **devp) { - *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode); + *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode, NULL); + + return *devp ? 0 : -ENOENT; +} + +int device_find_global_by_ofnode_driver(ofnode ofnode, const char *drv, + struct udevice **devp) +{ + *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode, drv); return *devp ? 0 : -ENOENT; } @@ -904,7 +914,7 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp) { struct udevice *dev; - dev = _device_find_global_by_ofnode(gd->dm_root, ofnode); + dev = _device_find_global_by_ofnode(gd->dm_root, ofnode, NULL); return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp); } diff --git a/include/dm/device.h b/include/dm/device.h index b86bf90609b..5f05ae0924f 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -748,6 +748,23 @@ int device_get_child_by_of_offset(const struct udevice *parent, int of_offset, int device_find_global_by_ofnode(ofnode node, struct udevice **devp); +/** + * device_find_global_by_ofnode_driver() - Get a device based on ofnode and driver + * + * Locates a device by its device tree ofnode and driver currently bound to + * it, searching globally throughout the all driver model devices. + * + * The device is NOT probed + * + * @node: Device tree ofnode to find + * @drv: Driver name bound to device + * @devp: Returns pointer to device if found, otherwise this is set to NULL + * Return: 0 if OK, -ve on error + */ + +int device_find_global_by_ofnode_driver(ofnode node, const char *drv, + struct udevice **devp); + /** * device_get_global_by_ofnode() - Get a device based on ofnode * -- 2.40.1