Linux-i2c Archive on lore.kernel.org
 help / color / Atom feed
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Wolfram Sang <wsa+renesas@sang-engineering.com>,
	Jean Delvare <jdelvare@suse.de>, Lee Jones <lee.jones@linaro.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Tan Jui Nee <jui.nee.tan@intel.com>,
	Jim Quinlan <james.quinlan@broadcom.com>,
	Jonathan Yong <jonathan.yong@intel.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org,
	linux-pci@vger.kernel.org
Cc: Jean Delvare <jdelvare@suse.com>,
	Peter Tyser <ptyser@xes-inc.com>,
	hdegoede@redhat.com, henning.schild@siemens.com
Subject: [PATCH v1 2/7] PCI: Convert __pci_read_base() to __pci_bus_read_base()
Date: Mon,  8 Mar 2021 14:20:15 +0200
Message-ID: <20210308122020.57071-3-andriy.shevchenko@linux.intel.com> (raw)
In-Reply-To: <20210308122020.57071-1-andriy.shevchenko@linux.intel.com>

Some drivers would like to read PCI BAR of the devices which has been not or
can't be enumerated.

In particular such mechanism is required to read PCI BAR of hidden
devices behind Primary to Sideband (P2SB) bridge.

Refactor __pci_read_base() to provide __pci_bus_read_base() and
represent the former one as static inline helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pci/pci.h   | 13 ++++++++-
 drivers/pci/probe.c | 69 +++++++++++++++++++++++----------------------
 2 files changed, 48 insertions(+), 34 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index ef7c4661314f..58a0e9f7a530 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -258,8 +258,19 @@ bool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
 int pci_idt_bus_quirk(struct pci_bus *bus, int devfn, u32 *pl, int crs_timeout);
 
 int pci_setup_device(struct pci_dev *dev);
+
+int __pci_bus_read_base(struct pci_bus *bus, unsigned int devfn,
+			enum pci_bar_type type,
+			struct resource *res, unsigned int reg,
+			bool mmio_always_on);
+static inline
 int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
-		    struct resource *res, unsigned int reg);
+		    struct resource *res, unsigned int reg)
+{
+	res->name = pci_name(dev);
+	return __pci_bus_read_base(dev->bus, dev->devfn, type, res, reg, dev->mmio_always_on);
+}
+
 void pci_configure_ari(struct pci_dev *dev);
 void __pci_bus_size_bridges(struct pci_bus *bus,
 			struct list_head *realloc_head);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 7d67be52d8e5..8cf139724a42 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -129,7 +129,7 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
 	return size;
 }
 
-static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
+static inline unsigned long decode_bar(u32 bar)
 {
 	u32 mem_type;
 	unsigned long flags;
@@ -165,16 +165,21 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
 #define PCI_COMMAND_DECODE_ENABLE	(PCI_COMMAND_MEMORY | PCI_COMMAND_IO)
 
 /**
- * __pci_read_base - Read a PCI BAR
- * @dev: the PCI device
+ * __pci_bus_read_base - Read a PCI BAR
+ * @bus: the PCI bus
+ * @devfn: the PCI device and function
  * @type: type of the BAR
  * @res: resource buffer to be filled in
  * @pos: BAR position in the config space
+ * @mmio_always_on: disallow turning off IO/MEM decoding during BAR sizing
  *
  * Returns 1 if the BAR is 64-bit, or 0 if 32-bit.
+ * In case of error resulting @res->flags is 0.
  */
-int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
-		    struct resource *res, unsigned int pos)
+int __pci_bus_read_base(struct pci_bus *bus, unsigned int devfn,
+			enum pci_bar_type type,
+			struct resource *res, unsigned int pos,
+			bool mmio_always_on)
 {
 	u32 l = 0, sz = 0, mask;
 	u64 l64, sz64, mask64;
@@ -184,20 +189,18 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
 	/* No printks while decoding is disabled! */
-	if (!dev->mmio_always_on) {
-		pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);
+	if (!mmio_always_on) {
+		pci_bus_read_config_word(bus, devfn, PCI_COMMAND, &orig_cmd);
 		if (orig_cmd & PCI_COMMAND_DECODE_ENABLE) {
-			pci_write_config_word(dev, PCI_COMMAND,
+			pci_bus_write_config_word(bus, devfn, PCI_COMMAND,
 				orig_cmd & ~PCI_COMMAND_DECODE_ENABLE);
 		}
 	}
 
-	res->name = pci_name(dev);
-
-	pci_read_config_dword(dev, pos, &l);
-	pci_write_config_dword(dev, pos, l | mask);
-	pci_read_config_dword(dev, pos, &sz);
-	pci_write_config_dword(dev, pos, l);
+	pci_bus_read_config_dword(bus, devfn, pos, &l);
+	pci_bus_write_config_dword(bus, devfn, pos, l | mask);
+	pci_bus_read_config_dword(bus, devfn, pos, &sz);
+	pci_bus_write_config_dword(bus, devfn, pos, l);
 
 	/*
 	 * All bits set in sz means the device isn't working properly.
@@ -216,7 +219,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		l = 0;
 
 	if (type == pci_bar_unknown) {
-		res->flags = decode_bar(dev, l);
+		res->flags = decode_bar(l);
 		res->flags |= IORESOURCE_SIZEALIGN;
 		if (res->flags & IORESOURCE_IO) {
 			l64 = l & PCI_BASE_ADDRESS_IO_MASK;
@@ -236,26 +239,25 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 	}
 
 	if (res->flags & IORESOURCE_MEM_64) {
-		pci_read_config_dword(dev, pos + 4, &l);
-		pci_write_config_dword(dev, pos + 4, ~0);
-		pci_read_config_dword(dev, pos + 4, &sz);
-		pci_write_config_dword(dev, pos + 4, l);
+		pci_bus_read_config_dword(bus, devfn, pos + 4, &l);
+		pci_bus_write_config_dword(bus, devfn, pos + 4, ~0);
+		pci_bus_read_config_dword(bus, devfn, pos + 4, &sz);
+		pci_bus_write_config_dword(bus, devfn, pos + 4, l);
 
 		l64 |= ((u64)l << 32);
 		sz64 |= ((u64)sz << 32);
 		mask64 |= ((u64)~0 << 32);
 	}
 
-	if (!dev->mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE))
-		pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
+	if (!mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE))
+		pci_bus_write_config_word(bus, devfn, PCI_COMMAND, orig_cmd);
 
 	if (!sz64)
 		goto fail;
 
 	sz64 = pci_size(l64, sz64, mask64);
 	if (!sz64) {
-		pci_info(dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
-			 pos);
+		pci_bus_info(bus, devfn, FW_BUG "reg 0x%x: invalid BAR (can't size)\n", pos);
 		goto fail;
 	}
 
@@ -265,8 +267,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
 			res->start = 0;
 			res->end = 0;
-			pci_err(dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
-				pos, (unsigned long long)sz64);
+			pci_bus_err(bus, devfn,
+				    "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
+				    pos, (unsigned long long)sz64);
 			goto out;
 		}
 
@@ -275,8 +278,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			res->flags |= IORESOURCE_UNSET;
 			res->start = 0;
 			res->end = sz64 - 1;
-			pci_info(dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
-				 pos, (unsigned long long)l64);
+			pci_bus_info(bus, devfn,
+				     "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
+				     pos, (unsigned long long)l64);
 			goto out;
 		}
 	}
@@ -284,8 +288,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 	region.start = l64;
 	region.end = l64 + sz64 - 1;
 
-	pcibios_bus_to_resource(dev->bus, res, &region);
-	pcibios_resource_to_bus(dev->bus, &inverted_region, res);
+	pcibios_bus_to_resource(bus, res, &region);
+	pcibios_resource_to_bus(bus, &inverted_region, res);
 
 	/*
 	 * If "A" is a BAR value (a bus address), "bus_to_resource(A)" is
@@ -302,18 +306,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		res->flags |= IORESOURCE_UNSET;
 		res->start = 0;
 		res->end = region.end - region.start;
-		pci_info(dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
-			 pos, (unsigned long long)region.start);
+		pci_bus_info(bus, devfn, "reg 0x%x: initial BAR value %#010llx invalid\n",
+			     pos, (unsigned long long)region.start);
 	}
 
 	goto out;
 
-
 fail:
 	res->flags = 0;
 out:
 	if (res->flags)
-		pci_info(dev, "reg 0x%x: %pR\n", pos, res);
+		pci_bus_info(bus, devfn, "reg 0x%x: %pR\n", pos, res);
 
 	return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
 }
-- 
2.30.1


  parent reply index

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-08 12:20 [rfc, PATCH v1 0/7] PCI: introduce p2sb helper Andy Shevchenko
2021-03-08 12:20 ` [PATCH v1 1/7] PCI: Introduce pci_bus_*() printing macros when device is not available Andy Shevchenko
2021-03-10 14:57   ` Jean Delvare
2021-03-08 12:20 ` Andy Shevchenko [this message]
2021-03-10 17:14   ` [PATCH v1 2/7] PCI: Convert __pci_read_base() to __pci_bus_read_base() Christoph Hellwig
2021-03-08 12:20 ` [PATCH v1 3/7] PCI: New Primary to Sideband (P2SB) bridge support library Andy Shevchenko
2021-03-08 18:52   ` Bjorn Helgaas
2021-03-08 19:16     ` Andy Shevchenko
2021-03-09  1:42       ` Bjorn Helgaas
2021-03-09  8:42         ` Henning Schild
2021-04-02 13:09           ` Enrico Weigelt, metux IT consult
2021-04-06 13:40             ` Henning Schild
2021-03-13  9:45   ` Henning Schild
2021-04-01 15:43     ` Andy Shevchenko
2021-04-01 18:06       ` Mika Westerberg
2021-04-01 18:22         ` Andy Shevchenko
2021-04-01 18:32           ` Mika Westerberg
2021-03-08 12:20 ` [PATCH v1 4/7] mfd: lpc_ich: Factor out lpc_ich_enable_spi_write() Andy Shevchenko
2021-03-10 10:29   ` Lee Jones
2021-03-08 12:20 ` [PATCH v1 5/7] mfd: lpc_ich: Switch to generic pci_p2sb_bar() Andy Shevchenko
2021-03-10 10:35   ` Lee Jones
2021-03-10 12:05     ` Andy Shevchenko
2021-03-10 12:57       ` Lee Jones
2021-03-08 12:20 ` [PATCH v1 6/7] mfd: lpc_ich: Add support for pinctrl in non-ACPI system Andy Shevchenko
2021-03-10 10:27   ` Lee Jones
2021-04-12 16:01   ` Henning Schild
2021-04-12 16:40     ` Henning Schild
2021-04-12 16:59       ` Andy Shevchenko
2021-04-12 17:16         ` Henning Schild
2021-04-12 17:34           ` Andy Shevchenko
2021-04-13  6:47             ` Henning Schild
2021-04-12 16:51     ` Andy Shevchenko
2021-04-12 17:27       ` Henning Schild
2021-04-12 17:41         ` Andy Shevchenko
2021-03-08 12:20 ` [PATCH v1 7/7] i2c: i801: convert to use common P2SB accessor Andy Shevchenko
2021-03-10 14:51   ` Jean Delvare
2021-03-13  9:25 ` [rfc, PATCH v1 0/7] PCI: introduce p2sb helper Henning Schild
2021-06-10  9:02 ` Henning Schild
2021-06-10 10:14   ` Andy Shevchenko
2021-06-10 13:48     ` Henning Schild
2021-06-10 14:04       ` Andy Shevchenko
2021-04-01 15:45 [PATCH v1 3/7] PCI: New Primary to Sideband (P2SB) bridge support library Andy Shevchenko
2021-04-01 16:42 ` Bjorn Helgaas
2021-04-01 18:23   ` Andy Shevchenko
2021-04-01 18:44     ` Bjorn Helgaas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210308122020.57071-3-andriy.shevchenko@linux.intel.com \
    --to=andriy.shevchenko@linux.intel.com \
    --cc=bhelgaas@google.com \
    --cc=hdegoede@redhat.com \
    --cc=henning.schild@siemens.com \
    --cc=james.quinlan@broadcom.com \
    --cc=jdelvare@suse.com \
    --cc=jdelvare@suse.de \
    --cc=jonathan.yong@intel.com \
    --cc=jui.nee.tan@intel.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=ptyser@xes-inc.com \
    --cc=wsa+renesas@sang-engineering.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-i2c Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-i2c/0 linux-i2c/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-i2c linux-i2c/ https://lore.kernel.org/linux-i2c \
		linux-i2c@vger.kernel.org
	public-inbox-index linux-i2c

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-i2c


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git