Received: by 2002:a05:7412:bbc7:b0:fc:a2b0:25d7 with SMTP id kh7csp601608rdb; Thu, 1 Feb 2024 19:53:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IHsUI4QMaCW/bDgGohTjY/UJMQRBe3sdN3syF9MYGA+Qzm2E8gdrKI0C3s4wbyRplKJB4nC X-Received: by 2002:a05:622a:130b:b0:42b:e38c:f8c5 with SMTP id v11-20020a05622a130b00b0042be38cf8c5mr1138561qtk.42.1706846013513; Thu, 01 Feb 2024 19:53:33 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706846013; cv=pass; d=google.com; s=arc-20160816; b=1Bi8uUgmS5foJigVXBYks1CQnHTWW2SfQquD8+aUD4fK2UiAwnX0XKkhRTt04UPsjd V9ZY2/XpujACSN5ij9YWqDH7wLylex6+c1Ky1uwaf/LdYEdiRsAz576Tx3WilS5At3hs 71gJedNjEpHiaq4dyplGaffUL80ahWAF/0pnLbJQBWIR99hjo4gZMhUbLa6rSak27IIO 9JJHc2/6sdH+Evy1RsNqboNf5VNixLv0nJ6TIjHV6SWLAXiLlFErgIJv+OZVScFmb/Cz N2ZgWRDuvRfb128YAlN4MAyc723tXJF874Z978xQmtxHREWPUO9x+IrZSxYUQbAE4Du8 gh/w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:cc :to:from:date:dkim-signature; bh=maUpwwU/7fnXcnAQWXxN7/7j+t2G2BYDrBYD050Mrbo=; fh=0jkI+agd2jWlq5veUAjMxb8Colm10yPGW5xJdW21rCU=; b=w6tp+CmXurapbDsPET3N4JTmvxJXk+0MrigdIONz/ZFrdML4fd1DCF0gUsnZvCBvKG ep7d+qo6RaV+I55q5h6vJwRNv56eQuW9tOlzsCmh066C7hdF5fWpwflRvKPZkFbwxDNf HC8RlTKEuJcqVPoyo5YyZPCEA/BV64MDI9B98NZJPzipDckIXWK0BQmNhzrCdXsgdPLN gvqJpHkTKm9MGCwHMFFtgC2pIzsmtK17m5I3eRF6Q4lsFW37uRn7v7WNIE78qeNPZ4+n fi3MJEwuJvx0zH6xs1+2yS0QCYJp0jxs2GY5IXsWbVxS+3YXVKZzcxqhhhrMG6dDXmqj BbQA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=BWkmgNvs; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-bluetooth+bounces-1558-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-bluetooth+bounces-1558-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=1; AJvYcCWWZvP4Nt7GldAkkS0qBjGScbU0dcOIhMdjUbNwRrqsxQMmf3Qk3LnzPOZxQ9hsFtqWauikPTlYxb3wzZwOWjn+327N8y0dA57fv1+G5Q== Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id c6-20020ac85a86000000b0042a831a4eedsi1123725qtc.399.2024.02.01.19.53.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 19:53:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-bluetooth+bounces-1558-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=BWkmgNvs; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-bluetooth+bounces-1558-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-bluetooth+bounces-1558-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 36D981C243D4 for ; Fri, 2 Feb 2024 03:53:33 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 230C4E563; Fri, 2 Feb 2024 03:53:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BWkmgNvs" X-Original-To: linux-bluetooth@vger.kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6DBE8E549; Fri, 2 Feb 2024 03:53:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706846000; cv=none; b=Ckw3xe6E3LymYaBCmkaTJ9EV7ZJDpNgf9F6FKoYxONZmJRBz2AGApRQqlHz7j3ADnreik3v+/jxCidtNMPATfThQKP+bemYzwfgdcjyDlhGvkAvEtsTAQYanxkqU4tfsG/axuOP7RoProwO3YwbGrRpX6hJftVdTvnFpv0QBGtc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706846000; c=relaxed/simple; bh=3WcD8DCEvMEUv+2oQxxbFJxN/+ZqIL/ovqG9CcxSabs=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=I9waz9hRbg7KhCYLDDM7bby3X6rika0y3co9jpm1TUivYo3j8Ai+bqtM6gAXuBxwgTdKlRZlSasSGoIqW5a05eAoyrQNFe3UrYcF8R3DUlGToHUit+pffAPWC5VP4eQqsjEtoePKE7Xyc6Rq7MhgWz1foWs4QI5MtdRPR//jMRo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BWkmgNvs; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5A96CC433C7; Fri, 2 Feb 2024 03:53:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1706846000; bh=3WcD8DCEvMEUv+2oQxxbFJxN/+ZqIL/ovqG9CcxSabs=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=BWkmgNvsGxEWEs9AH7uUpf63vgbNfsgtO4uYq/9bGC12cqwH3Yjz3IXY4dbjzI5ds 5X1VrnigyrIEHjPXYWyWQit1F/13JIIfSrBHtlm/Whqu683EglPnHR8c6w8Mev48rB wtT8dV9EoOuLjREBE4RGT4xoyTPzthuUYYIb5jILX2ik4eyva7KY7rYkg6h2f890D4 uYxbBgNNoCnS/p4t5nqyvy3U5Fk6Gwl1ZziGuSuPIa3MoLfxeXLgIYvOPN6YVn+brc 2pRYiHQiFNMS1JD2WuTkCYDdsoxy8bNYsLZ00dV+t125EDchQaUTR8DKARlGr+IJrO duEdcKDF0pZDg== Date: Thu, 1 Feb 2024 21:53:16 -0600 From: Bjorn Andersson To: Bartosz Golaszewski Cc: Konrad Dybcio , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Marcel Holtmann , Luiz Augusto von Dentz , Bjorn Helgaas , Neil Armstrong , Alex Elder , Srini Kandagatla , Greg Kroah-Hartman , Arnd Bergmann , Abel Vesa , Manivannan Sadhasivam , Lukas Wunner , linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, linux-pci@vger.kernel.org, Bartosz Golaszewski Subject: Re: [RFC 8/9] PCI/pwrctl: add PCI power control core code Message-ID: <7tbhdkqpl4iuaxmc73pje2nbbkarxxpgmabc7j4q26d2rhzrv5@ltu6niel5eb4> References: <20240201155532.49707-1-brgl@bgdev.pl> <20240201155532.49707-9-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20240201155532.49707-9-brgl@bgdev.pl> On Thu, Feb 01, 2024 at 04:55:31PM +0100, Bartosz Golaszewski wrote: > From: Bartosz Golaszewski > > Some PCI devices must be powered-on before they can be detected on the > bus. Introduce a simple framework reusing the existing PCI OF > infrastructure. > > The way this works is: a DT node representing a PCI device connected to > the port can be matched against its power control platform driver. If > the match succeeds, the driver is responsible for powering-up the device > and calling pcie_pwrctl_device_enable() which will trigger a PCI bus > rescan as well as subscribe to PCI bus notifications. > > When the device is detected and created, we'll make it consume the same > DT node that the platform device did. When the device is bound, we'll > create a device link between it and the parent power control device. > > Signed-off-by: Bartosz Golaszewski > --- > drivers/pci/Kconfig | 1 + > drivers/pci/Makefile | 1 + > drivers/pci/pwrctl/Kconfig | 8 ++++ > drivers/pci/pwrctl/Makefile | 3 ++ > drivers/pci/pwrctl/core.c | 82 +++++++++++++++++++++++++++++++++++++ > include/linux/pci-pwrctl.h | 24 +++++++++++ > 6 files changed, 119 insertions(+) > create mode 100644 drivers/pci/pwrctl/Kconfig > create mode 100644 drivers/pci/pwrctl/Makefile > create mode 100644 drivers/pci/pwrctl/core.c > create mode 100644 include/linux/pci-pwrctl.h > > diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig > index 74147262625b..5b9b84f8774f 100644 > --- a/drivers/pci/Kconfig > +++ b/drivers/pci/Kconfig > @@ -291,5 +291,6 @@ source "drivers/pci/hotplug/Kconfig" > source "drivers/pci/controller/Kconfig" > source "drivers/pci/endpoint/Kconfig" > source "drivers/pci/switch/Kconfig" > +source "drivers/pci/pwrctl/Kconfig" > > endif > diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile > index cc8b4e01e29d..6ae202d950f8 100644 > --- a/drivers/pci/Makefile > +++ b/drivers/pci/Makefile > @@ -9,6 +9,7 @@ obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o \ > > obj-$(CONFIG_PCI) += msi/ > obj-$(CONFIG_PCI) += pcie/ > +obj-$(CONFIG_PCI) += pwrctl/ > > ifdef CONFIG_PCI > obj-$(CONFIG_PROC_FS) += proc.o > diff --git a/drivers/pci/pwrctl/Kconfig b/drivers/pci/pwrctl/Kconfig > new file mode 100644 > index 000000000000..e2dc5e5d2af1 > --- /dev/null > +++ b/drivers/pci/pwrctl/Kconfig > @@ -0,0 +1,8 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +menu "PCI Power control drivers" > + > +config PCI_PWRCTL > + bool > + > +endmenu > diff --git a/drivers/pci/pwrctl/Makefile b/drivers/pci/pwrctl/Makefile > new file mode 100644 > index 000000000000..4381cfbf3f21 > --- /dev/null > +++ b/drivers/pci/pwrctl/Makefile > @@ -0,0 +1,3 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +obj-$(CONFIG_PCI_PWRCTL) += core.o > diff --git a/drivers/pci/pwrctl/core.c b/drivers/pci/pwrctl/core.c > new file mode 100644 > index 000000000000..312e6fe95c31 > --- /dev/null > +++ b/drivers/pci/pwrctl/core.c > @@ -0,0 +1,82 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (C) 2024 Linaro Ltd. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static int pci_pwrctl_notify(struct notifier_block *nb, unsigned long action, > + void *data) > +{ > + struct pci_pwrctl *pwrctl = container_of(nb, struct pci_pwrctl, nb); > + struct device *dev = data; > + > + if (dev_fwnode(dev) != dev_fwnode(pwrctl->dev)) > + return NOTIFY_DONE; > + > + switch (action) { > + case BUS_NOTIFY_ADD_DEVICE: > + device_set_of_node_from_dev(dev, pwrctl->dev); What happens if the bootloader left the power on, and the of_platform_populate() got probe deferred because the pwrseq wasn't ready, so this happens after pci_set_of_node() has been called? (I think dev->of_node will be put, then get and then node_reused assigned...but I'm not entirely sure) > + break; > + case BUS_NOTIFY_BOUND_DRIVER: > + pwrctl->link = device_link_add(dev, pwrctl->dev, > + DL_FLAG_AUTOREMOVE_CONSUMER); > + if (!pwrctl->link) > + dev_err(pwrctl->dev, "Failed to add device link\n"); > + break; > + case BUS_NOTIFY_UNBOUND_DRIVER: > + device_link_del(pwrctl->link); This might however become a NULL-pointer dereference, if dev was bound to its driver before the pci_pwrctl_notify() was registered for the pwrctl and then the PCI device is unbound. This would also happen if device_link_add() failed when the PCI device was bound... > + break; > + } > + > + return NOTIFY_DONE; > +} > + > +int pci_pwrctl_device_enable(struct pci_pwrctl *pwrctl) This function doesn't really "enable the device", looking at the example driver it's rather "device_enabled" than "device_enable"... > +{ > + if (!pwrctl->dev) > + return -ENODEV; > + > + pwrctl->nb.notifier_call = pci_pwrctl_notify; > + bus_register_notifier(&pci_bus_type, &pwrctl->nb); > + > + pci_lock_rescan_remove(); > + pci_rescan_bus(to_pci_dev(pwrctl->dev->parent)->bus); > + pci_unlock_rescan_remove(); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(pci_pwrctl_device_enable); > + > +void pci_pwrctl_device_disable(struct pci_pwrctl *pwrctl) Similarly this doesn't disable the device, the code calling this is doing so... Regards, Bjorn > +{ > + bus_unregister_notifier(&pci_bus_type, &pwrctl->nb); > +} > +EXPORT_SYMBOL_GPL(pci_pwrctl_device_disable); > + > +static void devm_pci_pwrctl_device_disable(void *data) > +{ > + struct pci_pwrctl *pwrctl = data; > + > + pci_pwrctl_device_disable(pwrctl); > +} > + > +int devm_pci_pwrctl_device_enable(struct device *dev, > + struct pci_pwrctl *pwrctl) > +{ > + int ret; > + > + ret = pci_pwrctl_device_enable(pwrctl); > + if (ret) > + return ret; > + > + return devm_add_action_or_reset(dev, devm_pci_pwrctl_device_disable, > + pwrctl); > +} > +EXPORT_SYMBOL_GPL(devm_pci_pwrctl_device_enable); > diff --git a/include/linux/pci-pwrctl.h b/include/linux/pci-pwrctl.h > new file mode 100644 > index 000000000000..8d16d27cbfeb > --- /dev/null > +++ b/include/linux/pci-pwrctl.h > @@ -0,0 +1,24 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * Copyright (C) 2024 Linaro Ltd. > + */ > + > +#ifndef __PCI_PWRCTL_H__ > +#define __PCI_PWRCTL_H__ > + > +#include > + > +struct device; > + > +struct pci_pwrctl { > + struct notifier_block nb; > + struct device *dev; > + struct device_link *link; > +}; > + > +int pci_pwrctl_device_enable(struct pci_pwrctl *pwrctl); > +void pci_pwrctl_device_disable(struct pci_pwrctl *pwrctl); > +int devm_pci_pwrctl_device_enable(struct device *dev, > + struct pci_pwrctl *pwrctl); > + > +#endif /* __PCI_PWRCTL_H__ */ > -- > 2.40.1 >