All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-23 19:01 ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

This is my version 12 of the attempt at adding support for generic PCI host
bridge controllers that make use of device tree information to
configure themselves. It contains cleanups to address comments posted for v11.

Bjorn intends to pull this series into his tree and send it to linux-next if
no major issues arise.


Changes from v11:
 - fixed race condition in pci_register_io_range() and bug where the function
   would return with the io_range_lock held.
 - split patch 4/10 that fixes the convertion of IO ranges into resources into
   two patches. The new 4/12 just moves the function into drivers/of/address.c
   and 5/12 makes the functional changes.
 - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
   part
 - Removed the old PCI domain number parser and allocator and split the code
   into two independent functions: 'int pci_get_new_domain_nr(void)' will
   always return a new domain number when called while 'of_get_pci_domain_nr()'
   will parse the DT and try to find a property of the given node called
   'linux,pci-domain'. The property value, if found, will be truncated to
   16-bit value and returned, or a negative value if an error occurs.
 - Made the io_base pointer parameter that gets passed to
   of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
   be explicit when detecting multiple IO ranges about the device used.
 - Fixed comments on commits to explain who uses pci_remap_iospace() as well
   as making clear that the value used inside the function is a virtual address
   and not a physical one. Also be explicit in the warning generated when
   architectures without memory mapped IO support make use of this function
 - Merged the arm64 patch into this series as Bjorn is going to pull it
   into his tree.

Changes from v10:
 - Addressed Lorenzo's comments wrt io_base not being initialised inside the
   function that is supposed to modify it and also updated the comments to
   explain the values returned by the function
 - Updated pci_domain_nr helper function to split the allocation of the domain
   number from the parsing of the device tree to find maximum defined domain
   value
 - Fixed up the commit author for commit 6/10

Changes from v9:
 - Moved the DT parsing and assigning of IRQ patch from this series into arm64
   specific patch. This keeps existing pcibios_add_device() unchanged and adds
   an arch-specific version that can later be expanded to cater for dma_ops.
 - Incorporated the fix for users of of_pci_range_to_resources() into the patch
   that changes the behaviour for easier bisection.
 - Added fixes for tegra and rcar host drivers in their usage of
   of_pci_range_to_resources()
 - Broke up of_create_pci_host_bridge() to remove the callback function. The
   function left has been renamed into of_pci_get_host_bridge_resources(). The
   added benefit of that is that the architectural hook for fixing up host bridge
   resources now dissappears.
 - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
   that adds pci_remap_iospace() function. The arm64 specific override is moved
   into the arm64 patchset.
 - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
   flags are not PCI_PROBE_ONLY

v11 thread here: https://lkml.org/lkml/2014/9/17/732
v10 thread here: https://lkml.org/lkml/2014/9/8/333
v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361

Best regards,
Liviu

Catalin Marinas (1):
  PCI: Introduce generic domain handling for PCI busses.

Liviu Dudau (11):
  Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
  PCI: Introduce helper functions to deal with PCI I/O ranges.
  ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
  PCI: OF: Move of_pci_range_to_resources() into address.c
  PCI: OF: Fix the conversion of IO ranges into IO resources.
  PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
  PCI: OF: Introduce helper function for retrieving PCI domain numbers
  OF: PCI: Add support for parsing PCI host bridge resources from DT
  PCI: Assign unassigned bus resources in pci_scan_root_bus()
  PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
  arm64: Add architectural support for PCIe

 arch/arm/include/asm/io.h         |   1 +
 arch/arm/mach-integrator/pci_v3.c |  23 +++---
 arch/arm64/Kconfig                |  22 +++++-
 arch/arm64/include/asm/Kbuild     |   1 +
 arch/arm64/include/asm/io.h       |   3 +-
 arch/arm64/include/asm/pci.h      |  37 +++++++++
 arch/arm64/include/asm/pgtable.h  |   2 +
 arch/arm64/kernel/Makefile        |   1 +
 arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
 drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
 drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
 drivers/pci/host/pci-tegra.c      |  10 ++-
 drivers/pci/host/pcie-rcar.c      |  21 ++++--
 drivers/pci/pci.c                 |  43 +++++++++++
 drivers/pci/probe.c               |  46 ++++++-----
 include/asm-generic/io.h          |   2 +-
 include/asm-generic/pgtable.h     |   4 +
 include/linux/of_address.h        |  22 +++---
 include/linux/of_pci.h            |  18 +++++
 include/linux/pci.h               |  27 +++++++
 20 files changed, 596 insertions(+), 52 deletions(-)
 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/pci.c

-- 
2.1.0


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-23 19:01 ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

This is my version 12 of the attempt at adding support for generic PCI host
bridge controllers that make use of device tree information to
configure themselves. It contains cleanups to address comments posted for v11.

Bjorn intends to pull this series into his tree and send it to linux-next if
no major issues arise.


Changes from v11:
 - fixed race condition in pci_register_io_range() and bug where the function
   would return with the io_range_lock held.
 - split patch 4/10 that fixes the convertion of IO ranges into resources into
   two patches. The new 4/12 just moves the function into drivers/of/address.c
   and 5/12 makes the functional changes.
 - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
   part
 - Removed the old PCI domain number parser and allocator and split the code
   into two independent functions: 'int pci_get_new_domain_nr(void)' will
   always return a new domain number when called while 'of_get_pci_domain_nr()'
   will parse the DT and try to find a property of the given node called
   'linux,pci-domain'. The property value, if found, will be truncated to
   16-bit value and returned, or a negative value if an error occurs.
 - Made the io_base pointer parameter that gets passed to
   of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
   be explicit when detecting multiple IO ranges about the device used.
 - Fixed comments on commits to explain who uses pci_remap_iospace() as well
   as making clear that the value used inside the function is a virtual address
   and not a physical one. Also be explicit in the warning generated when
   architectures without memory mapped IO support make use of this function
 - Merged the arm64 patch into this series as Bjorn is going to pull it
   into his tree.

Changes from v10:
 - Addressed Lorenzo's comments wrt io_base not being initialised inside the
   function that is supposed to modify it and also updated the comments to
   explain the values returned by the function
 - Updated pci_domain_nr helper function to split the allocation of the domain
   number from the parsing of the device tree to find maximum defined domain
   value
 - Fixed up the commit author for commit 6/10

Changes from v9:
 - Moved the DT parsing and assigning of IRQ patch from this series into arm64
   specific patch. This keeps existing pcibios_add_device() unchanged and adds
   an arch-specific version that can later be expanded to cater for dma_ops.
 - Incorporated the fix for users of of_pci_range_to_resources() into the patch
   that changes the behaviour for easier bisection.
 - Added fixes for tegra and rcar host drivers in their usage of
   of_pci_range_to_resources()
 - Broke up of_create_pci_host_bridge() to remove the callback function. The
   function left has been renamed into of_pci_get_host_bridge_resources(). The
   added benefit of that is that the architectural hook for fixing up host bridge
   resources now dissappears.
 - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
   that adds pci_remap_iospace() function. The arm64 specific override is moved
   into the arm64 patchset.
 - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
   flags are not PCI_PROBE_ONLY

v11 thread here: https://lkml.org/lkml/2014/9/17/732
v10 thread here: https://lkml.org/lkml/2014/9/8/333
v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361

Best regards,
Liviu

Catalin Marinas (1):
  PCI: Introduce generic domain handling for PCI busses.

Liviu Dudau (11):
  Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
  PCI: Introduce helper functions to deal with PCI I/O ranges.
  ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
  PCI: OF: Move of_pci_range_to_resources() into address.c
  PCI: OF: Fix the conversion of IO ranges into IO resources.
  PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
  PCI: OF: Introduce helper function for retrieving PCI domain numbers
  OF: PCI: Add support for parsing PCI host bridge resources from DT
  PCI: Assign unassigned bus resources in pci_scan_root_bus()
  PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
  arm64: Add architectural support for PCIe

 arch/arm/include/asm/io.h         |   1 +
 arch/arm/mach-integrator/pci_v3.c |  23 +++---
 arch/arm64/Kconfig                |  22 +++++-
 arch/arm64/include/asm/Kbuild     |   1 +
 arch/arm64/include/asm/io.h       |   3 +-
 arch/arm64/include/asm/pci.h      |  37 +++++++++
 arch/arm64/include/asm/pgtable.h  |   2 +
 arch/arm64/kernel/Makefile        |   1 +
 arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
 drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
 drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
 drivers/pci/host/pci-tegra.c      |  10 ++-
 drivers/pci/host/pcie-rcar.c      |  21 ++++--
 drivers/pci/pci.c                 |  43 +++++++++++
 drivers/pci/probe.c               |  46 ++++++-----
 include/asm-generic/io.h          |   2 +-
 include/asm-generic/pgtable.h     |   4 +
 include/linux/of_address.h        |  22 +++---
 include/linux/of_pci.h            |  18 +++++
 include/linux/pci.h               |  27 +++++++
 20 files changed, 596 insertions(+), 52 deletions(-)
 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/pci.c

-- 
2.1.0

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 01/12] Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

The inline version of ioport_map() that gets used when !CONFIG_GENERIC_IOMAP
is wrong. It returns a mapped (i.e. virtual) address that can start from
zero and completely ignores the PCI_IOBASE and IO_SPACE_LIMIT that most
architectures that use !CONFIG_GENERIC_MAP define.

Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Tanmay Inamdar <tinamdar@apm.com>
---
 include/asm-generic/io.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 975e1cc..2e2161b 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr)
 #ifndef CONFIG_GENERIC_IOMAP
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
-	return (void __iomem *) port;
+	return (void __iomem *)(PCI_IOBASE + (port & IO_SPACE_LIMIT));
 }
 
 static inline void ioport_unmap(void __iomem *p)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 01/12] Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

The inline version of ioport_map() that gets used when !CONFIG_GENERIC_IOMAP
is wrong. It returns a mapped (i.e. virtual) address that can start from
zero and completely ignores the PCI_IOBASE and IO_SPACE_LIMIT that most
architectures that use !CONFIG_GENERIC_MAP define.

Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Tanmay Inamdar <tinamdar@apm.com>
---
 include/asm-generic/io.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 975e1cc..2e2161b 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr)
 #ifndef CONFIG_GENERIC_IOMAP
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
-	return (void __iomem *) port;
+	return (void __iomem *)(PCI_IOBASE + (port & IO_SPACE_LIMIT));
 }
 
 static inline void ioport_unmap(void __iomem *p)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 02/12] PCI: Introduce helper functions to deal with PCI I/O ranges.
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely

Some architectures do not have a simple view of the PCI I/O space
and instead use a range of CPU addresses that map to bus addresses.
For some architectures these ranges will be expressed by OF bindings
in a device tree file.

This patch introduces a pci_register_io_range() helper function with
a generic implementation that can be used by such architectures to
keep track of the I/O ranges described by the PCI bindings. If the
PCI_IOBASE macro is not defined that signals lack of support for PCI
and we return an error.

In order to retrieve the CPU address associated with an I/O port, a
new helper function pci_pio_to_address() is introduced. This will
search in the list of ranges registered with pci_register_io_range()
and return the CPU address that corresponds to the given port.

Cc: Grant Likely <grant.likely@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/of/address.c       | 109 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_address.h |   2 +
 2 files changed, 111 insertions(+)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index e371825..758d4f0 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -5,6 +5,8 @@
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/pci_regs.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 /* Max address size we deal with */
@@ -601,12 +603,119 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
 }
 EXPORT_SYMBOL(of_get_address);
 
+#ifdef PCI_IOBASE
+struct io_range {
+	struct list_head list;
+	phys_addr_t start;
+	resource_size_t size;
+};
+
+static LIST_HEAD(io_range_list);
+static DEFINE_SPINLOCK(io_range_lock);
+#endif
+
+/*
+ * Record the PCI IO range (expressed as CPU physical address + size).
+ * Return a negative value if an error has occured, zero otherwise
+ */
+int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
+{
+	int err = 0;
+
+#ifdef PCI_IOBASE
+	struct io_range *range;
+	resource_size_t allocated_size = 0;
+
+	/* check if the range hasn't been previously recorded */
+	spin_lock(&io_range_lock);
+	list_for_each_entry(range, &io_range_list, list) {
+		if (addr >= range->start && addr + size <= range->start + size) {
+			/* range already registered, bail out */
+			goto end_register;
+		}
+		allocated_size += range->size;
+	}
+
+	/* range not registed yet, check for available space */
+	if (allocated_size + size - 1 > IO_SPACE_LIMIT) {
+		/* if it's too big check if 64K space can be reserved */
+		if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) {
+			err = -E2BIG;
+			goto end_register;
+		}
+
+		size = SZ_64K;
+		pr_warn("Requested IO range too big, new size set to 64K\n");
+	}
+
+	/* add the range to the list */
+	range = kzalloc(sizeof(*range), GFP_KERNEL);
+	if (!range) {
+		err = -ENOMEM;
+		goto end_register;
+	}
+
+	range->start = addr;
+	range->size = size;
+
+	list_add_tail(&range->list, &io_range_list);
+
+end_register:
+	spin_unlock(&io_range_lock);
+#endif
+
+	return err;
+}
+
+phys_addr_t pci_pio_to_address(unsigned long pio)
+{
+	phys_addr_t address = (phys_addr_t)OF_BAD_ADDR;
+
+#ifdef PCI_IOBASE
+	struct io_range *range;
+	resource_size_t allocated_size = 0;
+
+	if (pio > IO_SPACE_LIMIT)
+		return address;
+
+	spin_lock(&io_range_lock);
+	list_for_each_entry(range, &io_range_list, list) {
+		if (pio >= allocated_size && pio < allocated_size + range->size) {
+			address = range->start + pio - allocated_size;
+			break;
+		}
+		allocated_size += range->size;
+	}
+	spin_unlock(&io_range_lock);
+#endif
+
+	return address;
+}
+
 unsigned long __weak pci_address_to_pio(phys_addr_t address)
 {
+#ifdef PCI_IOBASE
+	struct io_range *res;
+	resource_size_t offset = 0;
+	unsigned long addr = -1;
+
+	spin_lock(&io_range_lock);
+	list_for_each_entry(res, &io_range_list, list) {
+		if (address >= res->start && address < res->start + res->size) {
+			addr = res->start - address + offset;
+			break;
+		}
+		offset += res->size;
+	}
+	spin_unlock(&io_range_lock);
+
+	return addr;
+#else
 	if (address > IO_SPACE_LIMIT)
 		return (unsigned long)-1;
 
 	return (unsigned long) address;
+#endif
 }
 
 static int __of_address_to_resource(struct device_node *dev,
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index fb7b722..f8cc7da 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -55,7 +55,9 @@ extern void __iomem *of_iomap(struct device_node *device, int index);
 extern const __be32 *of_get_address(struct device_node *dev, int index,
 			   u64 *size, unsigned int *flags);
 
+extern int pci_register_io_range(phys_addr_t addr, resource_size_t size);
 extern unsigned long pci_address_to_pio(phys_addr_t addr);
+extern phys_addr_t pci_pio_to_address(unsigned long pio);
 
 extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
 			struct device_node *node);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 02/12] PCI: Introduce helper functions to deal with PCI I/O ranges.
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

Some architectures do not have a simple view of the PCI I/O space
and instead use a range of CPU addresses that map to bus addresses.
For some architectures these ranges will be expressed by OF bindings
in a device tree file.

This patch introduces a pci_register_io_range() helper function with
a generic implementation that can be used by such architectures to
keep track of the I/O ranges described by the PCI bindings. If the
PCI_IOBASE macro is not defined that signals lack of support for PCI
and we return an error.

In order to retrieve the CPU address associated with an I/O port, a
new helper function pci_pio_to_address() is introduced. This will
search in the list of ranges registered with pci_register_io_range()
and return the CPU address that corresponds to the given port.

Cc: Grant Likely <grant.likely@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/of/address.c       | 109 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_address.h |   2 +
 2 files changed, 111 insertions(+)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index e371825..758d4f0 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -5,6 +5,8 @@
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/pci_regs.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 /* Max address size we deal with */
@@ -601,12 +603,119 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
 }
 EXPORT_SYMBOL(of_get_address);
 
+#ifdef PCI_IOBASE
+struct io_range {
+	struct list_head list;
+	phys_addr_t start;
+	resource_size_t size;
+};
+
+static LIST_HEAD(io_range_list);
+static DEFINE_SPINLOCK(io_range_lock);
+#endif
+
+/*
+ * Record the PCI IO range (expressed as CPU physical address + size).
+ * Return a negative value if an error has occured, zero otherwise
+ */
+int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
+{
+	int err = 0;
+
+#ifdef PCI_IOBASE
+	struct io_range *range;
+	resource_size_t allocated_size = 0;
+
+	/* check if the range hasn't been previously recorded */
+	spin_lock(&io_range_lock);
+	list_for_each_entry(range, &io_range_list, list) {
+		if (addr >= range->start && addr + size <= range->start + size) {
+			/* range already registered, bail out */
+			goto end_register;
+		}
+		allocated_size += range->size;
+	}
+
+	/* range not registed yet, check for available space */
+	if (allocated_size + size - 1 > IO_SPACE_LIMIT) {
+		/* if it's too big check if 64K space can be reserved */
+		if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) {
+			err = -E2BIG;
+			goto end_register;
+		}
+
+		size = SZ_64K;
+		pr_warn("Requested IO range too big, new size set to 64K\n");
+	}
+
+	/* add the range to the list */
+	range = kzalloc(sizeof(*range), GFP_KERNEL);
+	if (!range) {
+		err = -ENOMEM;
+		goto end_register;
+	}
+
+	range->start = addr;
+	range->size = size;
+
+	list_add_tail(&range->list, &io_range_list);
+
+end_register:
+	spin_unlock(&io_range_lock);
+#endif
+
+	return err;
+}
+
+phys_addr_t pci_pio_to_address(unsigned long pio)
+{
+	phys_addr_t address = (phys_addr_t)OF_BAD_ADDR;
+
+#ifdef PCI_IOBASE
+	struct io_range *range;
+	resource_size_t allocated_size = 0;
+
+	if (pio > IO_SPACE_LIMIT)
+		return address;
+
+	spin_lock(&io_range_lock);
+	list_for_each_entry(range, &io_range_list, list) {
+		if (pio >= allocated_size && pio < allocated_size + range->size) {
+			address = range->start + pio - allocated_size;
+			break;
+		}
+		allocated_size += range->size;
+	}
+	spin_unlock(&io_range_lock);
+#endif
+
+	return address;
+}
+
 unsigned long __weak pci_address_to_pio(phys_addr_t address)
 {
+#ifdef PCI_IOBASE
+	struct io_range *res;
+	resource_size_t offset = 0;
+	unsigned long addr = -1;
+
+	spin_lock(&io_range_lock);
+	list_for_each_entry(res, &io_range_list, list) {
+		if (address >= res->start && address < res->start + res->size) {
+			addr = res->start - address + offset;
+			break;
+		}
+		offset += res->size;
+	}
+	spin_unlock(&io_range_lock);
+
+	return addr;
+#else
 	if (address > IO_SPACE_LIMIT)
 		return (unsigned long)-1;
 
 	return (unsigned long) address;
+#endif
 }
 
 static int __of_address_to_resource(struct device_node *dev,
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index fb7b722..f8cc7da 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -55,7 +55,9 @@ extern void __iomem *of_iomap(struct device_node *device, int index);
 extern const __be32 *of_get_address(struct device_node *dev, int index,
 			   u64 *size, unsigned int *flags);
 
+extern int pci_register_io_range(phys_addr_t addr, resource_size_t size);
 extern unsigned long pci_address_to_pio(phys_addr_t addr);
+extern phys_addr_t pci_pio_to_address(unsigned long pio);
 
 extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
 			struct device_node *node);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 03/12] ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

This is needed for calls into OF code that parses PCI ranges.
It signals support for memory mapped PCI I/O accesses that
are described be device trees.

Cc: Russell King <linux@arm.linux.org.uk>
Cc: Rob Herring <robh+dt@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 arch/arm/include/asm/io.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 3d23418..22b7529 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -178,6 +178,7 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
 
 /* PCI fixed i/o mapping */
 #define PCI_IO_VIRT_BASE	0xfee00000
+#define PCI_IOBASE		PCI_IO_VIRT_BASE
 
 #if defined(CONFIG_PCI)
 void pci_ioremap_set_mem_type(int mem_type);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 03/12] ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

This is needed for calls into OF code that parses PCI ranges.
It signals support for memory mapped PCI I/O accesses that
are described be device trees.

Cc: Russell King <linux@arm.linux.org.uk>
Cc: Rob Herring <robh+dt@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 arch/arm/include/asm/io.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 3d23418..22b7529 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -178,6 +178,7 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
 
 /* PCI fixed i/o mapping */
 #define PCI_IO_VIRT_BASE	0xfee00000
+#define PCI_IOBASE		PCI_IO_VIRT_BASE
 
 #if defined(CONFIG_PCI)
 void pci_ioremap_set_mem_type(int mem_type);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 04/12] PCI: OF: Move of_pci_range_to_resources() into address.c
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely

The ranges property for a host bridge controller in DT describes
the mapping between the PCI bus address and the CPU physical address.
The resources framework however expects that the IO resources start
at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
The conversion from pci ranges to resources failed to take that into account.

In preparation for fixing this of_pci_range_to_resources(), move it into
drivers/of/address.c.

Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/of/address.c       | 10 ++++++++++
 include/linux/of_address.h | 19 ++++++++-----------
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 758d4f0..86c1055 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -956,3 +956,13 @@ bool of_dma_is_coherent(struct device_node *np)
 	return false;
 }
 EXPORT_SYMBOL_GPL(of_dma_is_coherent);
+
+void of_pci_range_to_resource(struct of_pci_range *range,
+	struct device_node *np,	struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index f8cc7da..ac28338 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -23,17 +23,6 @@ struct of_pci_range {
 #define for_each_of_pci_range(parser, range) \
 	for (; of_pci_range_parser_one(parser, range);)
 
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
 				    const __be32 *in_addr);
@@ -42,6 +31,9 @@ extern u64 of_translate_dma_address(struct device_node *dev,
 extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
 				  struct resource *r);
+extern void of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res);
+
 extern struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
 					const struct of_device_id *matches,
@@ -68,6 +60,11 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
 				u64 *paddr, u64 *size);
 extern bool of_dma_is_coherent(struct device_node *np);
 #else /* CONFIG_OF_ADDRESS */
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res)
+{
+}
+
 static inline struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
 					const struct of_device_id *matches,
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 04/12] PCI: OF: Move of_pci_range_to_resources() into address.c
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

The ranges property for a host bridge controller in DT describes
the mapping between the PCI bus address and the CPU physical address.
The resources framework however expects that the IO resources start
at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
The conversion from pci ranges to resources failed to take that into account.

In preparation for fixing this of_pci_range_to_resources(), move it into
drivers/of/address.c.

Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/of/address.c       | 10 ++++++++++
 include/linux/of_address.h | 19 ++++++++-----------
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 758d4f0..86c1055 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -956,3 +956,13 @@ bool of_dma_is_coherent(struct device_node *np)
 	return false;
 }
 EXPORT_SYMBOL_GPL(of_dma_is_coherent);
+
+void of_pci_range_to_resource(struct of_pci_range *range,
+	struct device_node *np,	struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index f8cc7da..ac28338 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -23,17 +23,6 @@ struct of_pci_range {
 #define for_each_of_pci_range(parser, range) \
 	for (; of_pci_range_parser_one(parser, range);)
 
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
 				    const __be32 *in_addr);
@@ -42,6 +31,9 @@ extern u64 of_translate_dma_address(struct device_node *dev,
 extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
 				  struct resource *r);
+extern void of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res);
+
 extern struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
 					const struct of_device_id *matches,
@@ -68,6 +60,11 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
 				u64 *paddr, u64 *size);
 extern bool of_dma_is_coherent(struct device_node *np);
 #else /* CONFIG_OF_ADDRESS */
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res)
+{
+}
+
 static inline struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
 					const struct of_device_id *matches,
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding, Simon Horman

The ranges property for a host bridge controller in DT describes
the mapping between the PCI bus address and the CPU physical address.
The resources framework however expects that the IO resources start
at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
The conversion from pci ranges to resources failed to take that into account,
returning a CPU physical address instead of a port number.

Also fix all the drivers that depend on the old behaviour by fetching
the CPU physical address based on the port number where it is being needed.

Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Simon Horman <horms@verge.net.au>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
 drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
 drivers/pci/host/pci-tegra.c      | 10 ++++++---
 drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
 include/linux/of_address.h        | 15 ++++++-------
 5 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 05e1f73..c186a17 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
 {
 	unsigned long flags;
 	unsigned int temp;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pcibios_min_mem = 0x00100000;
 
@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
 	/*
 	 * Setup window 2 - PCI IO
 	 */
-	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
 			V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
 
@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
 static void __init pci_v3_postinit(void)
 {
 	unsigned int pci_cmd;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pci_cmd = PCI_COMMAND_MEMORY |
 		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
 		       "interrupt: %d\n", ret);
 #endif
 
-	register_isa_ports(non_mem.start, io_mem.start, 0);
+	register_isa_ports(non_mem.start, io_address, 0);
 }
 
 /*
@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
 
 	for_each_of_pci_range(&parser, &range) {
 		if (!range.flags) {
-			of_pci_range_to_resource(&range, np, &conf_mem);
+			ret = of_pci_range_to_resource(&range, np, &conf_mem);
 			conf_mem.name = "PCIv3 config";
 		}
 		if (range.flags & IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &io_mem);
+			ret = of_pci_range_to_resource(&range, np, &io_mem);
 			io_mem.name = "PCIv3 I/O";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			!(range.flags & IORESOURCE_PREFETCH)) {
 			non_mem_pci = range.pci_addr;
 			non_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &non_mem);
+			ret = of_pci_range_to_resource(&range, np, &non_mem);
 			non_mem.name = "PCIv3 non-prefetched mem";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			(range.flags & IORESOURCE_PREFETCH)) {
 			pre_mem_pci = range.pci_addr;
 			pre_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &pre_mem);
+			ret = of_pci_range_to_resource(&range, np, &pre_mem);
 			pre_mem.name = "PCIv3 prefetched mem";
 		}
-	}
 
-	if (!conf_mem.start || !io_mem.start ||
-	    !non_mem.start || !pre_mem.start) {
-		dev_err(&pdev->dev, "missing ranges in device node\n");
-		return -EINVAL;
+		if (ret < 0) {
+			dev_err(&pdev->dev, "missing ranges in device node\n");
+			return ret;
+		}
 	}
 
 	pci_v3.map_irq = of_irq_parse_and_map_pci;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 86c1055..6bbe61b 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_dma_is_coherent);
 
-void of_pci_range_to_resource(struct of_pci_range *range,
-	struct device_node *np,	struct resource *res)
+/*
+ * of_pci_range_to_resource - Create a resource from an of_pci_range
+ * @range:	the PCI range that describes the resource
+ * @np:		device node where the range belongs to
+ * @res:	pointer to a valid resource that will be updated to
+ *              reflect the values contained in the range.
+ *
+ * Returns EINVAL if the range cannot be converted to resource.
+ *
+ * Note that if the range is an IO range, the resource will be converted
+ * using pci_address_to_pio() which can fail if it is called too early or
+ * if the range cannot be matched to any host bridge IO space (our case here).
+ * To guard against that we try to register the IO range first.
+ * If that fails we know that pci_address_to_pio() will do too.
+ */
+int of_pci_range_to_resource(struct of_pci_range *range,
+	struct device_node *np, struct resource *res)
 {
+	int err;
 	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
 	res->parent = res->child = res->sibling = NULL;
 	res->name = np->full_name;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long port;
+		err = pci_register_io_range(range->cpu_addr, range->size);
+		if (err)
+			goto invalid_range;
+		port = pci_address_to_pio(range->cpu_addr);
+		if (port == (unsigned long)-1) {
+			err = -EINVAL;
+			goto invalid_range;
+		}
+		res->start = port;
+	} else {
+		res->start = range->cpu_addr;
+	}
+	res->end = res->start + range->size - 1;
+	return 0;
+
+invalid_range:
+	res->start = (resource_size_t)OF_BAD_ADDR;
+	res->end = (resource_size_t)OF_BAD_ADDR;
+	return err;
 }
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb..946935d 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
 	struct tegra_pcie *pcie = sys_to_pcie(sys);
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
 				sys->mem_offset);
 	pci_add_resource(&sys->resources, &pcie->busn);
 
-	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
+	pci_ioremap_io(nr * SZ_64K, io_start);
 
 	return 1;
 }
@@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 {
 	u32 fpci_bar, size, axi_address;
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	/* Bar 0: type 1 extended configuration space */
 	fpci_bar = 0xfe100000;
@@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 	/* Bar 1: downstream IO bar */
 	fpci_bar = 0xfdfc0000;
 	size = resource_size(&pcie->io);
-	axi_address = pcie->io.start;
+	axi_address = io_start;
 	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
 	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
 	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
@@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, np, &res);
+		err = of_pci_range_to_resource(&range, np, &res);
+		if (err < 0)
+			return err;
 
 		switch (res.flags & IORESOURCE_TYPE_BITS) {
 		case IORESOURCE_IO:
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..61158e0 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 
 	/* Setup PCIe address space mappings for each resource */
 	resource_size_t size;
+	resource_size_t res_start;
 	u32 mask;
 
 	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
 	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
 
-	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
-	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
+	if (res->flags & IORESOURCE_IO)
+		res_start = pci_pio_to_address(res->start);
+	else
+		res_start = res->start;
+
+	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
+	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
 
 	/* First resource is for IO */
 	mask = PAR_ENABLE;
@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
 
 		rcar_pcie_setup_window(i, pcie);
 
-		if (res->flags & IORESOURCE_IO)
-			pci_ioremap_io(nr * SZ_64K, res->start);
-		else
+		if (res->flags & IORESOURCE_IO) {
+			phys_addr_t io_start = pci_pio_to_address(res->start);
+			pci_ioremap_io(nr * SZ_64K, io_start);
+		} else
 			pci_add_resource(&sys->resources, res);
 	}
 	pci_add_resource(&sys->resources, &pcie->busn);
@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, pdev->dev.of_node,
+		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
 						&pcie->res[win++]);
+		if (err < 0)
+			return err;
 
 		if (win > RCAR_PCI_MAX_RESOURCES)
 			break;
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index ac28338..f8915ef 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -31,8 +31,6 @@ extern u64 of_translate_dma_address(struct device_node *dev,
 extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
 				  struct resource *r);
-extern void of_pci_range_to_resource(struct of_pci_range *range,
-		struct device_node *np, struct resource *res);
 
 extern struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
@@ -60,11 +58,6 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
 				u64 *paddr, u64 *size);
 extern bool of_dma_is_coherent(struct device_node *np);
 #else /* CONFIG_OF_ADDRESS */
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-		struct device_node *np, struct resource *res)
-{
-}
-
 static inline struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
 					const struct of_device_id *matches,
@@ -137,6 +130,8 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
+extern int of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)
@@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 	return -ENOSYS;
 }
 
+static inline int of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res)
+{
+	return -ENOSYS;
+}
+
 static inline const __be32 *of_get_pci_address(struct device_node *dev,
 		int bar_no, u64 *size, unsigned int *flags)
 {
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

The ranges property for a host bridge controller in DT describes
the mapping between the PCI bus address and the CPU physical address.
The resources framework however expects that the IO resources start
at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
The conversion from pci ranges to resources failed to take that into account,
returning a CPU physical address instead of a port number.

Also fix all the drivers that depend on the old behaviour by fetching
the CPU physical address based on the port number where it is being needed.

Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Simon Horman <horms@verge.net.au>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
 drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
 drivers/pci/host/pci-tegra.c      | 10 ++++++---
 drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
 include/linux/of_address.h        | 15 ++++++-------
 5 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 05e1f73..c186a17 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
 {
 	unsigned long flags;
 	unsigned int temp;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pcibios_min_mem = 0x00100000;
 
@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
 	/*
 	 * Setup window 2 - PCI IO
 	 */
-	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
 			V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
 
@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
 static void __init pci_v3_postinit(void)
 {
 	unsigned int pci_cmd;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pci_cmd = PCI_COMMAND_MEMORY |
 		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
 		       "interrupt: %d\n", ret);
 #endif
 
-	register_isa_ports(non_mem.start, io_mem.start, 0);
+	register_isa_ports(non_mem.start, io_address, 0);
 }
 
 /*
@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
 
 	for_each_of_pci_range(&parser, &range) {
 		if (!range.flags) {
-			of_pci_range_to_resource(&range, np, &conf_mem);
+			ret = of_pci_range_to_resource(&range, np, &conf_mem);
 			conf_mem.name = "PCIv3 config";
 		}
 		if (range.flags & IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &io_mem);
+			ret = of_pci_range_to_resource(&range, np, &io_mem);
 			io_mem.name = "PCIv3 I/O";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			!(range.flags & IORESOURCE_PREFETCH)) {
 			non_mem_pci = range.pci_addr;
 			non_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &non_mem);
+			ret = of_pci_range_to_resource(&range, np, &non_mem);
 			non_mem.name = "PCIv3 non-prefetched mem";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			(range.flags & IORESOURCE_PREFETCH)) {
 			pre_mem_pci = range.pci_addr;
 			pre_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &pre_mem);
+			ret = of_pci_range_to_resource(&range, np, &pre_mem);
 			pre_mem.name = "PCIv3 prefetched mem";
 		}
-	}
 
-	if (!conf_mem.start || !io_mem.start ||
-	    !non_mem.start || !pre_mem.start) {
-		dev_err(&pdev->dev, "missing ranges in device node\n");
-		return -EINVAL;
+		if (ret < 0) {
+			dev_err(&pdev->dev, "missing ranges in device node\n");
+			return ret;
+		}
 	}
 
 	pci_v3.map_irq = of_irq_parse_and_map_pci;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 86c1055..6bbe61b 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_dma_is_coherent);
 
-void of_pci_range_to_resource(struct of_pci_range *range,
-	struct device_node *np,	struct resource *res)
+/*
+ * of_pci_range_to_resource - Create a resource from an of_pci_range
+ * @range:	the PCI range that describes the resource
+ * @np:		device node where the range belongs to
+ * @res:	pointer to a valid resource that will be updated to
+ *              reflect the values contained in the range.
+ *
+ * Returns EINVAL if the range cannot be converted to resource.
+ *
+ * Note that if the range is an IO range, the resource will be converted
+ * using pci_address_to_pio() which can fail if it is called too early or
+ * if the range cannot be matched to any host bridge IO space (our case here).
+ * To guard against that we try to register the IO range first.
+ * If that fails we know that pci_address_to_pio() will do too.
+ */
+int of_pci_range_to_resource(struct of_pci_range *range,
+	struct device_node *np, struct resource *res)
 {
+	int err;
 	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
 	res->parent = res->child = res->sibling = NULL;
 	res->name = np->full_name;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long port;
+		err = pci_register_io_range(range->cpu_addr, range->size);
+		if (err)
+			goto invalid_range;
+		port = pci_address_to_pio(range->cpu_addr);
+		if (port == (unsigned long)-1) {
+			err = -EINVAL;
+			goto invalid_range;
+		}
+		res->start = port;
+	} else {
+		res->start = range->cpu_addr;
+	}
+	res->end = res->start + range->size - 1;
+	return 0;
+
+invalid_range:
+	res->start = (resource_size_t)OF_BAD_ADDR;
+	res->end = (resource_size_t)OF_BAD_ADDR;
+	return err;
 }
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb..946935d 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
 	struct tegra_pcie *pcie = sys_to_pcie(sys);
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
 				sys->mem_offset);
 	pci_add_resource(&sys->resources, &pcie->busn);
 
-	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
+	pci_ioremap_io(nr * SZ_64K, io_start);
 
 	return 1;
 }
@@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 {
 	u32 fpci_bar, size, axi_address;
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	/* Bar 0: type 1 extended configuration space */
 	fpci_bar = 0xfe100000;
@@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 	/* Bar 1: downstream IO bar */
 	fpci_bar = 0xfdfc0000;
 	size = resource_size(&pcie->io);
-	axi_address = pcie->io.start;
+	axi_address = io_start;
 	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
 	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
 	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
@@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, np, &res);
+		err = of_pci_range_to_resource(&range, np, &res);
+		if (err < 0)
+			return err;
 
 		switch (res.flags & IORESOURCE_TYPE_BITS) {
 		case IORESOURCE_IO:
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..61158e0 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 
 	/* Setup PCIe address space mappings for each resource */
 	resource_size_t size;
+	resource_size_t res_start;
 	u32 mask;
 
 	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
 	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
 
-	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
-	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
+	if (res->flags & IORESOURCE_IO)
+		res_start = pci_pio_to_address(res->start);
+	else
+		res_start = res->start;
+
+	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
+	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
 
 	/* First resource is for IO */
 	mask = PAR_ENABLE;
@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
 
 		rcar_pcie_setup_window(i, pcie);
 
-		if (res->flags & IORESOURCE_IO)
-			pci_ioremap_io(nr * SZ_64K, res->start);
-		else
+		if (res->flags & IORESOURCE_IO) {
+			phys_addr_t io_start = pci_pio_to_address(res->start);
+			pci_ioremap_io(nr * SZ_64K, io_start);
+		} else
 			pci_add_resource(&sys->resources, res);
 	}
 	pci_add_resource(&sys->resources, &pcie->busn);
@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, pdev->dev.of_node,
+		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
 						&pcie->res[win++]);
+		if (err < 0)
+			return err;
 
 		if (win > RCAR_PCI_MAX_RESOURCES)
 			break;
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index ac28338..f8915ef 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -31,8 +31,6 @@ extern u64 of_translate_dma_address(struct device_node *dev,
 extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
 				  struct resource *r);
-extern void of_pci_range_to_resource(struct of_pci_range *range,
-		struct device_node *np, struct resource *res);
 
 extern struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
@@ -60,11 +58,6 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
 				u64 *paddr, u64 *size);
 extern bool of_dma_is_coherent(struct device_node *np);
 #else /* CONFIG_OF_ADDRESS */
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-		struct device_node *np, struct resource *res)
-{
-}
-
 static inline struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
 					const struct of_device_id *matches,
@@ -137,6 +130,8 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
+extern int of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)
@@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 	return -ENOSYS;
 }
 
+static inline int of_pci_range_to_resource(struct of_pci_range *range,
+		struct device_node *np, struct resource *res)
+{
+	return -ENOSYS;
+}
+
 static inline const __be32 *of_get_pci_address(struct device_node *dev,
 		int bar_no, u64 *size, unsigned int *flags)
 {
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
the creation order has been changed for no good reason. Revert the order of
creation as we are going to depend on the pci_host_bridge structure to retrieve the
domain number of the root bus.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: Grant Likely <grant.likely@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Tanmay Inamdar <tinamdar@apm.com>
---
 drivers/pci/probe.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..5ff72ec 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
 	kfree(bridge);
 }
 
-static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
+static struct pci_host_bridge *pci_alloc_host_bridge(void)
 {
 	struct pci_host_bridge *bridge;
 
@@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
 		return NULL;
 
 	INIT_LIST_HEAD(&bridge->windows);
-	bridge->bus = b;
+	bridge->dev.release = pci_release_host_bridge_dev;
+
 	return bridge;
 }
 
@@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	char bus_addr[64];
 	char *fmt;
 
+	bridge = pci_alloc_host_bridge();
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
 	b = pci_alloc_bus();
 	if (!b)
-		return NULL;
+		goto err_out;
 
 	b->sysdata = sysdata;
 	b->ops = ops;
@@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
 		dev_dbg(&b2->dev, "bus already known\n");
-		goto err_out;
+		goto err_bus_out;
 	}
 
-	bridge = pci_alloc_host_bridge(b);
-	if (!bridge)
-		goto err_out;
-
-	bridge->dev.parent = parent;
-	bridge->dev.release = pci_release_host_bridge_dev;
+	bridge->bus = b;
 	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
 	error = pcibios_root_bridge_prepare(bridge);
-	if (error) {
-		kfree(bridge);
+	if (error)
 		goto err_out;
-	}
 
 	error = device_register(&bridge->dev);
 	if (error) {
 		put_device(&bridge->dev);
-		goto err_out;
+		goto err_bus_out;
 	}
 	b->bridge = get_device(&bridge->dev);
 	device_enable_async_suspend(b->bridge);
@@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 class_dev_reg_err:
 	put_device(&bridge->dev);
 	device_unregister(&bridge->dev);
-err_out:
+err_bus_out:
 	kfree(b);
+err_out:
+	kfree(bridge);
 	return NULL;
 }
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
the creation order has been changed for no good reason. Revert the order of
creation as we are going to depend on the pci_host_bridge structure to retrieve the
domain number of the root bus.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: Grant Likely <grant.likely@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Tanmay Inamdar <tinamdar@apm.com>
---
 drivers/pci/probe.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..5ff72ec 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
 	kfree(bridge);
 }
 
-static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
+static struct pci_host_bridge *pci_alloc_host_bridge(void)
 {
 	struct pci_host_bridge *bridge;
 
@@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
 		return NULL;
 
 	INIT_LIST_HEAD(&bridge->windows);
-	bridge->bus = b;
+	bridge->dev.release = pci_release_host_bridge_dev;
+
 	return bridge;
 }
 
@@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	char bus_addr[64];
 	char *fmt;
 
+	bridge = pci_alloc_host_bridge();
+	if (!bridge)
+		return NULL;
+
+	bridge->dev.parent = parent;
+
 	b = pci_alloc_bus();
 	if (!b)
-		return NULL;
+		goto err_out;
 
 	b->sysdata = sysdata;
 	b->ops = ops;
@@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
 		dev_dbg(&b2->dev, "bus already known\n");
-		goto err_out;
+		goto err_bus_out;
 	}
 
-	bridge = pci_alloc_host_bridge(b);
-	if (!bridge)
-		goto err_out;
-
-	bridge->dev.parent = parent;
-	bridge->dev.release = pci_release_host_bridge_dev;
+	bridge->bus = b;
 	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
 	error = pcibios_root_bridge_prepare(bridge);
-	if (error) {
-		kfree(bridge);
+	if (error)
 		goto err_out;
-	}
 
 	error = device_register(&bridge->dev);
 	if (error) {
 		put_device(&bridge->dev);
-		goto err_out;
+		goto err_bus_out;
 	}
 	b->bridge = get_device(&bridge->dev);
 	device_enable_async_suspend(b->bridge);
@@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 class_dev_reg_err:
 	put_device(&bridge->dev);
 	device_unregister(&bridge->dev);
-err_out:
+err_bus_out:
 	kfree(b);
+err_out:
+	kfree(bridge);
 	return NULL;
 }
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 07/12] PCI: Introduce generic domain handling for PCI busses.
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Catalin Marinas

From: Catalin Marinas <catalin.marinas@arm.com>

The handling of PCI domains (or PCI segments in ACPI speak) is
usually a straightforward affair but its implementation is
currently left to the architectural code, with pci_domain_nr(b)
querying the value of the domain associated with bus b.

This patch introduces CONFIG_PCI_DOMAINS_GENERIC as an
option that can be selected if an architecture want a
simple implementation where the value of the domain
associated with a bus is stored in struct pci_bus.

The architectures that select CONFIG_PCI_DOMAINS_GENERIC will
then have to implement pci_bus_assign_domain_nr() as a way
of setting the domain number associated with a root bus.
All child busses except the root bus will inherit the domain_nr
value from their parent.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Catalin Marinas <Catalin.Marinas@arm.com>
[Renamed pci_set_domain_nr() to pci_bus_assign_domain_nr()]
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/pci/probe.c | 11 ++++++++---
 include/linux/pci.h | 21 +++++++++++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5ff72ec..ef891d2 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -485,7 +485,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
 	}
 }
 
-static struct pci_bus *pci_alloc_bus(void)
+static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
 {
 	struct pci_bus *b;
 
@@ -500,6 +500,10 @@ static struct pci_bus *pci_alloc_bus(void)
 	INIT_LIST_HEAD(&b->resources);
 	b->max_bus_speed = PCI_SPEED_UNKNOWN;
 	b->cur_bus_speed = PCI_SPEED_UNKNOWN;
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+	if (parent)
+		b->domain_nr = parent->domain_nr;
+#endif
 	return b;
 }
 
@@ -672,7 +676,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	/*
 	 * Allocate a new bus, and inherit stuff from the parent..
 	 */
-	child = pci_alloc_bus();
+	child = pci_alloc_bus(parent);
 	if (!child)
 		return NULL;
 
@@ -1768,13 +1772,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 
 	bridge->dev.parent = parent;
 
-	b = pci_alloc_bus();
+	b = pci_alloc_bus(NULL);
 	if (!b)
 		goto err_out;
 
 	b->sysdata = sysdata;
 	b->ops = ops;
 	b->number = b->busn_res.start = bus;
+	pci_bus_assign_domain_nr(b, parent);
 	b2 = pci_find_bus(pci_domain_nr(b), bus);
 	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 61978a4..a494e5d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -456,6 +456,9 @@ struct pci_bus {
 	unsigned char	primary;	/* number of primary bridge */
 	unsigned char	max_bus_speed;	/* enum pci_bus_speed */
 	unsigned char	cur_bus_speed;	/* enum pci_bus_speed */
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+	int		domain_nr;
+#endif
 
 	char		name[48];
 
@@ -1288,6 +1291,24 @@ static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
 #endif /* CONFIG_PCI_DOMAINS */
 
+/*
+ * Generic implementation for PCI domain support. If your
+ * architecture does not need custom management of PCI
+ * domains then this implementation will be used
+ */
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+static inline int pci_domain_nr(struct pci_bus *bus)
+{
+	return bus->domain_nr;
+}
+void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent);
+#else
+static inline void pci_bus_assign_domain_nr(struct pci_bus *bus,
+					struct device *parent)
+{
+}
+#endif
+
 /* some architectures require additional setup to direct VGA traffic */
 typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
 		      unsigned int command_bits, u32 flags);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 07/12] PCI: Introduce generic domain handling for PCI busses.
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

From: Catalin Marinas <catalin.marinas@arm.com>

The handling of PCI domains (or PCI segments in ACPI speak) is
usually a straightforward affair but its implementation is
currently left to the architectural code, with pci_domain_nr(b)
querying the value of the domain associated with bus b.

This patch introduces CONFIG_PCI_DOMAINS_GENERIC as an
option that can be selected if an architecture want a
simple implementation where the value of the domain
associated with a bus is stored in struct pci_bus.

The architectures that select CONFIG_PCI_DOMAINS_GENERIC will
then have to implement pci_bus_assign_domain_nr() as a way
of setting the domain number associated with a root bus.
All child busses except the root bus will inherit the domain_nr
value from their parent.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Catalin Marinas <Catalin.Marinas@arm.com>
[Renamed pci_set_domain_nr() to pci_bus_assign_domain_nr()]
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/pci/probe.c | 11 ++++++++---
 include/linux/pci.h | 21 +++++++++++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5ff72ec..ef891d2 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -485,7 +485,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
 	}
 }
 
-static struct pci_bus *pci_alloc_bus(void)
+static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
 {
 	struct pci_bus *b;
 
@@ -500,6 +500,10 @@ static struct pci_bus *pci_alloc_bus(void)
 	INIT_LIST_HEAD(&b->resources);
 	b->max_bus_speed = PCI_SPEED_UNKNOWN;
 	b->cur_bus_speed = PCI_SPEED_UNKNOWN;
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+	if (parent)
+		b->domain_nr = parent->domain_nr;
+#endif
 	return b;
 }
 
@@ -672,7 +676,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	/*
 	 * Allocate a new bus, and inherit stuff from the parent..
 	 */
-	child = pci_alloc_bus();
+	child = pci_alloc_bus(parent);
 	if (!child)
 		return NULL;
 
@@ -1768,13 +1772,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 
 	bridge->dev.parent = parent;
 
-	b = pci_alloc_bus();
+	b = pci_alloc_bus(NULL);
 	if (!b)
 		goto err_out;
 
 	b->sysdata = sysdata;
 	b->ops = ops;
 	b->number = b->busn_res.start = bus;
+	pci_bus_assign_domain_nr(b, parent);
 	b2 = pci_find_bus(pci_domain_nr(b), bus);
 	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 61978a4..a494e5d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -456,6 +456,9 @@ struct pci_bus {
 	unsigned char	primary;	/* number of primary bridge */
 	unsigned char	max_bus_speed;	/* enum pci_bus_speed */
 	unsigned char	cur_bus_speed;	/* enum pci_bus_speed */
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+	int		domain_nr;
+#endif
 
 	char		name[48];
 
@@ -1288,6 +1291,24 @@ static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
 #endif /* CONFIG_PCI_DOMAINS */
 
+/*
+ * Generic implementation for PCI domain support. If your
+ * architecture does not need custom management of PCI
+ * domains then this implementation will be used
+ */
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+static inline int pci_domain_nr(struct pci_bus *bus)
+{
+	return bus->domain_nr;
+}
+void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent);
+#else
+static inline void pci_bus_assign_domain_nr(struct pci_bus *bus,
+					struct device *parent)
+{
+}
+#endif
+
 /* some architectures require additional setup to direct VGA traffic */
 typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
 		      unsigned int command_bits, u32 flags);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely

Add pci_get_new_domain_nr() to allocate a new domain number
and of_get_pci_domain_nr() to retrieve the PCI domain number
of a given device from DT. Host bridge drivers or architecture
specific code can choose to implement their PCI domain number
policy using these two functions.

Using of_get_pci_domain_nr() guarantees a stable PCI domain
number on every boot provided that all host bridge controllers
are assigned a number in the device tree using "linux,pci-domain"
property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
is not recommended as it can lead to potentially conflicting
domain numbers being assigned to root busses behind different
host bridges.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
 drivers/pci/pci.c      |  9 +++++++++
 include/linux/of_pci.h |  7 +++++++
 include/linux/pci.h    |  3 +++
 4 files changed, 44 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 8481996..82d172f 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
 }
 EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
 
+/**
+ * This function will try to obtain the host bridge domain number by
+ * finding a property called "linux,pci-domain" of the given device node.
+ *
+ * @node: device tree node with the domain information
+ *
+ * Returns the associated domain number from DT in the range [0-0xffff], or
+ * a negative value if the required property is not found.
+ */
+int of_get_pci_domain_nr(struct device_node *node)
+{
+	const __be32 *value;
+	int len;
+	u16 domain;
+
+	value = of_get_property(node, "linux,pci-domain", &len);
+	if (!value || len < sizeof(*value))
+		return -EINVAL;
+
+	domain = (u16)be32_to_cpup(value);
+
+	return domain;
+}
+EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
+
 #ifdef CONFIG_PCI_MSI
 
 static LIST_HEAD(of_pci_msi_chip_list);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 2c9ac70..d36f35f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4406,6 +4406,15 @@ static void pci_no_domains(void)
 #endif
 }
 
+#ifdef CONFIG_PCI_DOMAINS
+static atomic_t __domain_nr = ATOMIC_INIT(-1);
+
+int pci_get_new_domain_nr(void)
+{
+	return atomic_inc_return(&__domain_nr);
+}
+#endif
+
 /**
  * pci_ext_cfg_avail - can we access extended PCI config space?
  *
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index dde3a4a..71062e9 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
 int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
+int of_get_pci_domain_nr(struct device_node *node);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -43,6 +44,12 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
 {
 	return -EINVAL;
 }
+
+static inline int
+of_get_pci_domain_nr(struct device_node *node)
+{
+	return -1;
+}
 #endif
 
 #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a494e5d..150da2d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1285,10 +1285,12 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
  */
 #ifdef CONFIG_PCI_DOMAINS
 extern int pci_domains_supported;
+int pci_get_new_domain_nr(void);
 #else
 enum { pci_domains_supported = 0 };
 static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
+static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
 #endif /* CONFIG_PCI_DOMAINS */
 
 /*
@@ -1417,6 +1419,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
 
 static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
+static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
 
 #define dev_is_pci(d) (false)
 #define dev_is_pf(d) (false)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

Add pci_get_new_domain_nr() to allocate a new domain number
and of_get_pci_domain_nr() to retrieve the PCI domain number
of a given device from DT. Host bridge drivers or architecture
specific code can choose to implement their PCI domain number
policy using these two functions.

Using of_get_pci_domain_nr() guarantees a stable PCI domain
number on every boot provided that all host bridge controllers
are assigned a number in the device tree using "linux,pci-domain"
property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
is not recommended as it can lead to potentially conflicting
domain numbers being assigned to root busses behind different
host bridges.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
 drivers/pci/pci.c      |  9 +++++++++
 include/linux/of_pci.h |  7 +++++++
 include/linux/pci.h    |  3 +++
 4 files changed, 44 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 8481996..82d172f 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
 }
 EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
 
+/**
+ * This function will try to obtain the host bridge domain number by
+ * finding a property called "linux,pci-domain" of the given device node.
+ *
+ * @node: device tree node with the domain information
+ *
+ * Returns the associated domain number from DT in the range [0-0xffff], or
+ * a negative value if the required property is not found.
+ */
+int of_get_pci_domain_nr(struct device_node *node)
+{
+	const __be32 *value;
+	int len;
+	u16 domain;
+
+	value = of_get_property(node, "linux,pci-domain", &len);
+	if (!value || len < sizeof(*value))
+		return -EINVAL;
+
+	domain = (u16)be32_to_cpup(value);
+
+	return domain;
+}
+EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
+
 #ifdef CONFIG_PCI_MSI
 
 static LIST_HEAD(of_pci_msi_chip_list);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 2c9ac70..d36f35f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4406,6 +4406,15 @@ static void pci_no_domains(void)
 #endif
 }
 
+#ifdef CONFIG_PCI_DOMAINS
+static atomic_t __domain_nr = ATOMIC_INIT(-1);
+
+int pci_get_new_domain_nr(void)
+{
+	return atomic_inc_return(&__domain_nr);
+}
+#endif
+
 /**
  * pci_ext_cfg_avail - can we access extended PCI config space?
  *
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index dde3a4a..71062e9 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
 int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
+int of_get_pci_domain_nr(struct device_node *node);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -43,6 +44,12 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
 {
 	return -EINVAL;
 }
+
+static inline int
+of_get_pci_domain_nr(struct device_node *node)
+{
+	return -1;
+}
 #endif
 
 #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a494e5d..150da2d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1285,10 +1285,12 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
  */
 #ifdef CONFIG_PCI_DOMAINS
 extern int pci_domains_supported;
+int pci_get_new_domain_nr(void);
 #else
 enum { pci_domains_supported = 0 };
 static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
+static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
 #endif /* CONFIG_PCI_DOMAINS */
 
 /*
@@ -1417,6 +1419,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
 
 static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
+static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
 
 #define dev_is_pci(d) (false)
 #define dev_is_pf(d) (false)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Robert Richter

Provide a function to parse the PCI DT ranges that can be used to
create a pci_host_bridge structure together with its associated
bus.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
[make io_base parameter optional]
Signed-off-by: Robert Richter <rrichter@cavium.com>
---
 drivers/of/of_pci.c    | 115 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_pci.h |  11 +++++
 2 files changed, 126 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 82d172f..c2285aa 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -1,7 +1,9 @@
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_pci.h>
+#include <linux/slab.h>
 
 static inline int __of_pci_pci_compare(struct device_node *node,
 				       unsigned int data)
@@ -114,6 +116,119 @@ int of_get_pci_domain_nr(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
+/**
+ * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @busno: bus number associated with the bridge root bus
+ * @bus_max: maximum number of busses for this bridge
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain on return the physical
+ * address for the start of the I/O range. Can be NULL if the caller doesn't
+ * expect IO ranges to be present in the device tree.
+ *
+ * It is the callers job to free the @resources list.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * It returns zero if the range parsing has been successful or a standard error
+ * value if it failed.
+ */
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base)
+{
+	struct resource *res;
+	struct resource *bus_range;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	char range_type[4];
+	int err;
+
+	if (io_base)
+		*io_base = (resource_size_t)OF_BAD_ADDR;
+
+	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
+	if (!bus_range)
+		return -ENOMEM;
+
+	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
+
+	err = of_pci_parse_bus_range(dev, bus_range);
+	if (err) {
+		bus_range->start = busno;
+		bus_range->end = bus_max;
+		bus_range->flags = IORESOURCE_BUS;
+		pr_info("  No bus range found for %s, using %pR\n",
+			dev->full_name, bus_range);
+	} else {
+		if (bus_range->end > bus_range->start + bus_max)
+			bus_range->end = bus_range->start + bus_max;
+	}
+	pci_add_resource(resources, bus_range);
+
+	/* Check for ranges property */
+	err = of_pci_range_parser_init(&parser, dev);
+	if (err)
+		goto parse_failed;
+
+	pr_debug("Parsing ranges property...\n");
+	for_each_of_pci_range(&parser, &range) {
+		/* Read next ranges element */
+		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+			snprintf(range_type, 4, " IO");
+		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+			snprintf(range_type, 4, "MEM");
+		else
+			snprintf(range_type, 4, "err");
+		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
+			range.cpu_addr, range.cpu_addr + range.size - 1,
+			range.pci_addr);
+
+		/*
+		 * If we failed translation or got a zero-sized region
+		 * then skip this range
+		 */
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+			continue;
+
+		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+		if (!res) {
+			err = -ENOMEM;
+			goto parse_failed;
+		}
+
+		err = of_pci_range_to_resource(&range, dev, res);
+		if (err)
+			goto conversion_failed;
+
+		if (resource_type(res) == IORESOURCE_IO) {
+			if (!io_base) {
+				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
+					dev->full_name);
+				err = -EINVAL;
+				goto conversion_failed;
+			}
+			if (*io_base != (resource_size_t)OF_BAD_ADDR)
+				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
+					dev->full_name);
+			*io_base = range.cpu_addr;
+		}
+
+		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
+	}
+
+	return 0;
+
+conversion_failed:
+	kfree(res);
+parse_failed:
+	pci_free_resource_list(resources);
+	return err;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+
 #ifdef CONFIG_PCI_MSI
 
 static LIST_HEAD(of_pci_msi_chip_list);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 71062e9..9ff818a 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -16,6 +16,10 @@ int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base);
+
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -50,6 +54,13 @@ of_get_pci_domain_nr(struct device_node *node)
 {
 	return -1;
 }
+
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base);
+{
+	return -EINVAL;
+}
 #endif
 
 #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

Provide a function to parse the PCI DT ranges that can be used to
create a pci_host_bridge structure together with its associated
bus.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
[make io_base parameter optional]
Signed-off-by: Robert Richter <rrichter@cavium.com>
---
 drivers/of/of_pci.c    | 115 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_pci.h |  11 +++++
 2 files changed, 126 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 82d172f..c2285aa 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -1,7 +1,9 @@
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_pci.h>
+#include <linux/slab.h>
 
 static inline int __of_pci_pci_compare(struct device_node *node,
 				       unsigned int data)
@@ -114,6 +116,119 @@ int of_get_pci_domain_nr(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
+/**
+ * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @busno: bus number associated with the bridge root bus
+ * @bus_max: maximum number of busses for this bridge
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain on return the physical
+ * address for the start of the I/O range. Can be NULL if the caller doesn't
+ * expect IO ranges to be present in the device tree.
+ *
+ * It is the callers job to free the @resources list.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * It returns zero if the range parsing has been successful or a standard error
+ * value if it failed.
+ */
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base)
+{
+	struct resource *res;
+	struct resource *bus_range;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	char range_type[4];
+	int err;
+
+	if (io_base)
+		*io_base = (resource_size_t)OF_BAD_ADDR;
+
+	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
+	if (!bus_range)
+		return -ENOMEM;
+
+	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
+
+	err = of_pci_parse_bus_range(dev, bus_range);
+	if (err) {
+		bus_range->start = busno;
+		bus_range->end = bus_max;
+		bus_range->flags = IORESOURCE_BUS;
+		pr_info("  No bus range found for %s, using %pR\n",
+			dev->full_name, bus_range);
+	} else {
+		if (bus_range->end > bus_range->start + bus_max)
+			bus_range->end = bus_range->start + bus_max;
+	}
+	pci_add_resource(resources, bus_range);
+
+	/* Check for ranges property */
+	err = of_pci_range_parser_init(&parser, dev);
+	if (err)
+		goto parse_failed;
+
+	pr_debug("Parsing ranges property...\n");
+	for_each_of_pci_range(&parser, &range) {
+		/* Read next ranges element */
+		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+			snprintf(range_type, 4, " IO");
+		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+			snprintf(range_type, 4, "MEM");
+		else
+			snprintf(range_type, 4, "err");
+		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
+			range.cpu_addr, range.cpu_addr + range.size - 1,
+			range.pci_addr);
+
+		/*
+		 * If we failed translation or got a zero-sized region
+		 * then skip this range
+		 */
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+			continue;
+
+		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+		if (!res) {
+			err = -ENOMEM;
+			goto parse_failed;
+		}
+
+		err = of_pci_range_to_resource(&range, dev, res);
+		if (err)
+			goto conversion_failed;
+
+		if (resource_type(res) == IORESOURCE_IO) {
+			if (!io_base) {
+				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
+					dev->full_name);
+				err = -EINVAL;
+				goto conversion_failed;
+			}
+			if (*io_base != (resource_size_t)OF_BAD_ADDR)
+				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
+					dev->full_name);
+			*io_base = range.cpu_addr;
+		}
+
+		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
+	}
+
+	return 0;
+
+conversion_failed:
+	kfree(res);
+parse_failed:
+	pci_free_resource_list(resources);
+	return err;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+
 #ifdef CONFIG_PCI_MSI
 
 static LIST_HEAD(of_pci_msi_chip_list);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 71062e9..9ff818a 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -16,6 +16,10 @@ int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base);
+
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -50,6 +54,13 @@ of_get_pci_domain_nr(struct device_node *node)
 {
 	return -1;
 }
+
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base);
+{
+	return -EINVAL;
+}
 #endif
 
 #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

If the firmware has not assigned all the bus resources and
we are not just probing the PCIe busses, it makes sense to
assign the unassigned resources in pci_scan_root_bus().

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Cc: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/pci/probe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ef891d2..508cf61 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 	if (!found)
 		pci_bus_update_busn_res_end(b, max);
 
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_assign_unassigned_bus_resources(b);
+
 	pci_bus_add_devices(b);
 	return b;
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

If the firmware has not assigned all the bus resources and
we are not just probing the PCIe busses, it makes sense to
assign the unassigned resources in pci_scan_root_bus().

Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Cc: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Liviu Dudau <Liviu.Dudau-5wv7dgnIgG8@public.gmane.org>
---
 drivers/pci/probe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ef891d2..508cf61 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 	if (!found)
 		pci_bus_update_busn_res_end(b, max);
 
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_assign_unassigned_bus_resources(b);
+
 	pci_bus_add_devices(b);
 	return b;
 }
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

If the firmware has not assigned all the bus resources and
we are not just probing the PCIe busses, it makes sense to
assign the unassigned resources in pci_scan_root_bus().

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Cc: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/pci/probe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ef891d2..508cf61 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 	if (!found)
 		pci_bus_update_busn_res_end(b, max);
 
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_assign_unassigned_bus_resources(b);
+
 	pci_bus_add_devices(b);
 	return b;
 }
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 11/12] PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

Introduce a default implementation for remapping PCI bus I/O resources
onto the CPU address space. Architectures with special needs may
provide their own version, but most should be able to use this one.

This function is useful for PCI host bridge drivers that need to map
the PCI I/O resources into virtual memory space.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/pci/pci.c             | 34 ++++++++++++++++++++++++++++++++++
 include/asm-generic/pgtable.h |  4 ++++
 include/linux/pci.h           |  3 +++
 3 files changed, 41 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d36f35f..ad046a2 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2704,6 +2704,40 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
 }
 EXPORT_SYMBOL(pci_request_regions_exclusive);
 
+/**
+ *	pci_remap_iospace - Remap the memory mapped I/O space
+ *	@res: Resource describing the I/O space
+ *	@phys_addr: physical address where the range will be mapped.
+ *
+ *	Remap the memory mapped I/O space described by the @res
+ *	and the CPU physical address @phys_addr into virtual address space.
+ *	Only architectures that have memory mapped IO functions defined
+ *	(and the PCI_IOBASE value defined) should call this function.
+ */
+int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
+{
+	int err = -ENODEV;
+
+#if defined(PCI_IOBASE) && defined(CONFIG_MMU)
+	unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
+
+	if (!(res->flags & IORESOURCE_IO))
+		return -EINVAL;
+
+	if (res->end > IO_SPACE_LIMIT)
+		return -EINVAL;
+
+	err = ioremap_page_range(vaddr, vaddr + resource_size(res),
+				phys_addr, pgprot_device(PAGE_KERNEL));
+#else
+	/* this architecture does not have memory mapped I/O space,
+	   so this function should never be called */
+	WARN_ONCE(1, "This architecture does not support memory mapped I/O\n");
+#endif
+
+	return err;
+}
+
 static void __pci_set_master(struct pci_dev *dev, bool enable)
 {
 	u16 old_cmd, cmd;
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 53b2acc..977e545 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -249,6 +249,10 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
 #define pgprot_writecombine pgprot_noncached
 #endif
 
+#ifndef pgprot_device
+#define pgprot_device pgprot_noncached
+#endif
+
 /*
  * When walking page tables, get the address of the next boundary,
  * or the end address of the range if that comes earlier.  Although no
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 150da2d..b4995fd 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1100,6 +1100,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
 						  resource_size_t),
 			void *alignf_data);
 
+
+int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
+
 static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
 {
 	struct pci_bus_region region;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 11/12] PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce a default implementation for remapping PCI bus I/O resources
onto the CPU address space. Architectures with special needs may
provide their own version, but most should be able to use this one.

This function is useful for PCI host bridge drivers that need to map
the PCI I/O resources into virtual memory space.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 drivers/pci/pci.c             | 34 ++++++++++++++++++++++++++++++++++
 include/asm-generic/pgtable.h |  4 ++++
 include/linux/pci.h           |  3 +++
 3 files changed, 41 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d36f35f..ad046a2 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2704,6 +2704,40 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
 }
 EXPORT_SYMBOL(pci_request_regions_exclusive);
 
+/**
+ *	pci_remap_iospace - Remap the memory mapped I/O space
+ *	@res: Resource describing the I/O space
+ *	@phys_addr: physical address where the range will be mapped.
+ *
+ *	Remap the memory mapped I/O space described by the @res
+ *	and the CPU physical address @phys_addr into virtual address space.
+ *	Only architectures that have memory mapped IO functions defined
+ *	(and the PCI_IOBASE value defined) should call this function.
+ */
+int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
+{
+	int err = -ENODEV;
+
+#if defined(PCI_IOBASE) && defined(CONFIG_MMU)
+	unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
+
+	if (!(res->flags & IORESOURCE_IO))
+		return -EINVAL;
+
+	if (res->end > IO_SPACE_LIMIT)
+		return -EINVAL;
+
+	err = ioremap_page_range(vaddr, vaddr + resource_size(res),
+				phys_addr, pgprot_device(PAGE_KERNEL));
+#else
+	/* this architecture does not have memory mapped I/O space,
+	   so this function should never be called */
+	WARN_ONCE(1, "This architecture does not support memory mapped I/O\n");
+#endif
+
+	return err;
+}
+
 static void __pci_set_master(struct pci_dev *dev, bool enable)
 {
 	u16 old_cmd, cmd;
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 53b2acc..977e545 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -249,6 +249,10 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
 #define pgprot_writecombine pgprot_noncached
 #endif
 
+#ifndef pgprot_device
+#define pgprot_device pgprot_noncached
+#endif
+
 /*
  * When walking page tables, get the address of the next boundary,
  * or the end address of the range if that comes earlier.  Although no
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 150da2d..b4995fd 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1100,6 +1100,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
 						  resource_size_t),
 			void *alignf_data);
 
+
+int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
+
 static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
 {
 	struct pci_bus_region region;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 12/12] arm64: Add architectural support for PCIe
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 19:01   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

Use the generic PCI domain and OF functions
to provide support for PCI Express on arm64.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 arch/arm64/Kconfig               | 22 ++++++++++++-
 arch/arm64/include/asm/Kbuild    |  1 +
 arch/arm64/include/asm/io.h      |  3 +-
 arch/arm64/include/asm/pci.h     | 37 +++++++++++++++++++++
 arch/arm64/include/asm/pgtable.h |  2 ++
 arch/arm64/kernel/Makefile       |  1 +
 arch/arm64/kernel/pci.c          | 70 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 134 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/pci.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fd4e81a..6b01df9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -81,7 +81,7 @@ config MMU
 	def_bool y
 
 config NO_IOPORT_MAP
-	def_bool y
+	def_bool y if !PCI
 
 config STACKTRACE_SUPPORT
 	def_bool y
@@ -156,6 +156,26 @@ menu "Bus support"
 config ARM_AMBA
 	bool
 
+config PCI
+	bool "PCI support"
+	help
+	  This feature enables support for PCIe bus system. If you say Y
+	  here, the kernel will include drivers and infrastructure code
+	  to support PCIe bus devices.
+
+config PCI_DOMAINS
+	def_bool PCI
+
+config PCI_DOMAINS_GENERIC
+	def_bool PCI
+
+config PCI_SYSCALL
+	def_bool PCI
+
+source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
+
 endmenu
 
 menu "Kernel Features"
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 0b3fcf8..07cb417 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -29,6 +29,7 @@ generic-y += mman.h
 generic-y += msgbuf.h
 generic-y += mutex.h
 generic-y += pci.h
+generic-y += pci-bridge.h
 generic-y += poll.h
 generic-y += preempt.h
 generic-y += resource.h
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index e0ecdcf..f998d90 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -121,7 +121,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 /*
  *  I/O port access primitives.
  */
-#define IO_SPACE_LIMIT		0xffff
+#define arch_has_dev_port()	(1)
+#define IO_SPACE_LIMIT		(SZ_32M - 1)
 #define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_32M))
 
 static inline u8 inb(unsigned long addr)
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
new file mode 100644
index 0000000..872ba93
--- /dev/null
+++ b/arch/arm64/include/asm/pci.h
@@ -0,0 +1,37 @@
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm-generic/pci-bridge.h>
+#include <asm-generic/pci-dma-compat.h>
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0
+
+/*
+ * Set to 1 if the kernel should re-assign all PCI bus numbers
+ */
+#define pcibios_assign_all_busses() \
+	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
+
+/*
+ * PCI address space differs from physical memory address space
+ */
+#define PCI_DMA_BUS_IS_PHYS	(0)
+
+extern int isa_dma_bridge_buggy;
+
+#ifdef CONFIG_PCI
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+	return 1;
+}
+#endif  /* CONFIG_PCI */
+
+#endif  /* __KERNEL__ */
+#endif  /* __ASM_PCI_H */
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index ffe1ba0..a968523 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -296,6 +296,8 @@ static inline int has_transparent_hugepage(void)
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
 #define pgprot_writecombine(prot) \
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+#define pgprot_device(prot) \
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index df7ef87..1ed5a06 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
+arm64-obj-$(CONFIG_PCI)			+= pci.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
new file mode 100644
index 0000000..ce5836c
--- /dev/null
+++ b/arch/arm64/kernel/pci.c
@@ -0,0 +1,70 @@
+/*
+ * Code borrowed from powerpc/kernel/pci-common.c
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include <asm/pci-bridge.h>
+
+/*
+ * Called after each bus is probed, but before its children are examined
+ */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+	/* nothing to do, expected to be removed in the future */
+}
+
+/*
+ * We don't have to worry about legacy ISA devices, so nothing to do here
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
+{
+	return res->start;
+}
+
+/*
+ * Try to assign the IRQ number from DT when adding a new device
+ */
+int pcibios_add_device(struct pci_dev *dev)
+{
+	dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
+
+	return 0;
+}
+
+
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+static bool dt_domain_found = false;
+
+void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
+{
+	int domain = of_get_pci_domain_nr(parent->of_node);
+
+	if (domain >= 0) {
+		dt_domain_found = true;
+	} else if (dt_domain_found == true) {
+		dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n",
+			parent->of_node->full_name);
+		return;
+	} else {
+		domain = pci_get_new_domain_nr();
+	}
+
+	bus->domain_nr = domain;
+}
+#endif
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 12/12] arm64: Add architectural support for PCIe
@ 2014-09-23 19:01   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

Use the generic PCI domain and OF functions
to provide support for PCI Express on arm64.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
 arch/arm64/Kconfig               | 22 ++++++++++++-
 arch/arm64/include/asm/Kbuild    |  1 +
 arch/arm64/include/asm/io.h      |  3 +-
 arch/arm64/include/asm/pci.h     | 37 +++++++++++++++++++++
 arch/arm64/include/asm/pgtable.h |  2 ++
 arch/arm64/kernel/Makefile       |  1 +
 arch/arm64/kernel/pci.c          | 70 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 134 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/pci.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fd4e81a..6b01df9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -81,7 +81,7 @@ config MMU
 	def_bool y
 
 config NO_IOPORT_MAP
-	def_bool y
+	def_bool y if !PCI
 
 config STACKTRACE_SUPPORT
 	def_bool y
@@ -156,6 +156,26 @@ menu "Bus support"
 config ARM_AMBA
 	bool
 
+config PCI
+	bool "PCI support"
+	help
+	  This feature enables support for PCIe bus system. If you say Y
+	  here, the kernel will include drivers and infrastructure code
+	  to support PCIe bus devices.
+
+config PCI_DOMAINS
+	def_bool PCI
+
+config PCI_DOMAINS_GENERIC
+	def_bool PCI
+
+config PCI_SYSCALL
+	def_bool PCI
+
+source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
+
 endmenu
 
 menu "Kernel Features"
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 0b3fcf8..07cb417 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -29,6 +29,7 @@ generic-y += mman.h
 generic-y += msgbuf.h
 generic-y += mutex.h
 generic-y += pci.h
+generic-y += pci-bridge.h
 generic-y += poll.h
 generic-y += preempt.h
 generic-y += resource.h
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index e0ecdcf..f998d90 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -121,7 +121,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 /*
  *  I/O port access primitives.
  */
-#define IO_SPACE_LIMIT		0xffff
+#define arch_has_dev_port()	(1)
+#define IO_SPACE_LIMIT		(SZ_32M - 1)
 #define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_32M))
 
 static inline u8 inb(unsigned long addr)
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
new file mode 100644
index 0000000..872ba93
--- /dev/null
+++ b/arch/arm64/include/asm/pci.h
@@ -0,0 +1,37 @@
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm-generic/pci-bridge.h>
+#include <asm-generic/pci-dma-compat.h>
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0
+
+/*
+ * Set to 1 if the kernel should re-assign all PCI bus numbers
+ */
+#define pcibios_assign_all_busses() \
+	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
+
+/*
+ * PCI address space differs from physical memory address space
+ */
+#define PCI_DMA_BUS_IS_PHYS	(0)
+
+extern int isa_dma_bridge_buggy;
+
+#ifdef CONFIG_PCI
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+	return 1;
+}
+#endif  /* CONFIG_PCI */
+
+#endif  /* __KERNEL__ */
+#endif  /* __ASM_PCI_H */
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index ffe1ba0..a968523 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -296,6 +296,8 @@ static inline int has_transparent_hugepage(void)
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
 #define pgprot_writecombine(prot) \
 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+#define pgprot_device(prot) \
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index df7ef87..1ed5a06 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
+arm64-obj-$(CONFIG_PCI)			+= pci.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
new file mode 100644
index 0000000..ce5836c
--- /dev/null
+++ b/arch/arm64/kernel/pci.c
@@ -0,0 +1,70 @@
+/*
+ * Code borrowed from powerpc/kernel/pci-common.c
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include <asm/pci-bridge.h>
+
+/*
+ * Called after each bus is probed, but before its children are examined
+ */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+	/* nothing to do, expected to be removed in the future */
+}
+
+/*
+ * We don't have to worry about legacy ISA devices, so nothing to do here
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
+{
+	return res->start;
+}
+
+/*
+ * Try to assign the IRQ number from DT when adding a new device
+ */
+int pcibios_add_device(struct pci_dev *dev)
+{
+	dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
+
+	return 0;
+}
+
+
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+static bool dt_domain_found = false;
+
+void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
+{
+	int domain = of_get_pci_domain_nr(parent->of_node);
+
+	if (domain >= 0) {
+		dt_domain_found = true;
+	} else if (dt_domain_found == true) {
+		dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n",
+			parent->of_node->full_name);
+		return;
+	} else {
+		domain = pci_get_new_domain_nr();
+	}
+
+	bus->domain_nr = domain;
+}
+#endif
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
  2014-09-23 19:01 ` Liviu Dudau
@ 2014-09-23 21:54   ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-23 21:54 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 08:01:02PM +0100, Liviu Dudau wrote:
> This is my version 12 of the attempt at adding support for generic PCI host
> bridge controllers that make use of device tree information to
> configure themselves. It contains cleanups to address comments posted for v11.
> 
> Bjorn intends to pull this series into his tree and send it to linux-next if
> no major issues arise.
> 
> 
> Changes from v11:
>  - fixed race condition in pci_register_io_range() and bug where the function
>    would return with the io_range_lock held.
>  - split patch 4/10 that fixes the convertion of IO ranges into resources into
>    two patches. The new 4/12 just moves the function into drivers/of/address.c
>    and 5/12 makes the functional changes.
>  - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
>    part
>  - Removed the old PCI domain number parser and allocator and split the code
>    into two independent functions: 'int pci_get_new_domain_nr(void)' will
>    always return a new domain number when called while 'of_get_pci_domain_nr()'
>    will parse the DT and try to find a property of the given node called
>    'linux,pci-domain'. The property value, if found, will be truncated to
>    16-bit value and returned, or a negative value if an error occurs.
>  - Made the io_base pointer parameter that gets passed to
>    of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
>    be explicit when detecting multiple IO ranges about the device used.
>  - Fixed comments on commits to explain who uses pci_remap_iospace() as well
>    as making clear that the value used inside the function is a virtual address
>    and not a physical one. Also be explicit in the warning generated when
>    architectures without memory mapped IO support make use of this function
>  - Merged the arm64 patch into this series as Bjorn is going to pull it
>    into his tree.
> 
> Changes from v10:
>  - Addressed Lorenzo's comments wrt io_base not being initialised inside the
>    function that is supposed to modify it and also updated the comments to
>    explain the values returned by the function
>  - Updated pci_domain_nr helper function to split the allocation of the domain
>    number from the parsing of the device tree to find maximum defined domain
>    value
>  - Fixed up the commit author for commit 6/10
> 
> Changes from v9:
>  - Moved the DT parsing and assigning of IRQ patch from this series into arm64
>    specific patch. This keeps existing pcibios_add_device() unchanged and adds
>    an arch-specific version that can later be expanded to cater for dma_ops.
>  - Incorporated the fix for users of of_pci_range_to_resources() into the patch
>    that changes the behaviour for easier bisection.
>  - Added fixes for tegra and rcar host drivers in their usage of
>    of_pci_range_to_resources()
>  - Broke up of_create_pci_host_bridge() to remove the callback function. The
>    function left has been renamed into of_pci_get_host_bridge_resources(). The
>    added benefit of that is that the architectural hook for fixing up host bridge
>    resources now dissappears.
>  - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
>    that adds pci_remap_iospace() function. The arm64 specific override is moved
>    into the arm64 patchset.
>  - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
>    flags are not PCI_PROBE_ONLY
> 
> v11 thread here: https://lkml.org/lkml/2014/9/17/732
> v10 thread here: https://lkml.org/lkml/2014/9/8/333
> v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361
> 
> Best regards,
> Liviu
> 
> Catalin Marinas (1):
>   PCI: Introduce generic domain handling for PCI busses.
> 
> Liviu Dudau (11):
>   Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
>   PCI: Introduce helper functions to deal with PCI I/O ranges.
>   ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
>   PCI: OF: Move of_pci_range_to_resources() into address.c
>   PCI: OF: Fix the conversion of IO ranges into IO resources.
>   PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
>   PCI: OF: Introduce helper function for retrieving PCI domain numbers
>   OF: PCI: Add support for parsing PCI host bridge resources from DT
>   PCI: Assign unassigned bus resources in pci_scan_root_bus()
>   PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
>   arm64: Add architectural support for PCIe
> 
>  arch/arm/include/asm/io.h         |   1 +
>  arch/arm/mach-integrator/pci_v3.c |  23 +++---
>  arch/arm64/Kconfig                |  22 +++++-
>  arch/arm64/include/asm/Kbuild     |   1 +
>  arch/arm64/include/asm/io.h       |   3 +-
>  arch/arm64/include/asm/pci.h      |  37 +++++++++
>  arch/arm64/include/asm/pgtable.h  |   2 +
>  arch/arm64/kernel/Makefile        |   1 +
>  arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
>  drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
>  drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
>  drivers/pci/host/pci-tegra.c      |  10 ++-
>  drivers/pci/host/pcie-rcar.c      |  21 ++++--
>  drivers/pci/pci.c                 |  43 +++++++++++
>  drivers/pci/probe.c               |  46 ++++++-----
>  include/asm-generic/io.h          |   2 +-
>  include/asm-generic/pgtable.h     |   4 +
>  include/linux/of_address.h        |  22 +++---
>  include/linux/of_pci.h            |  18 +++++
>  include/linux/pci.h               |  27 +++++++
>  20 files changed, 596 insertions(+), 52 deletions(-)
>  create mode 100644 arch/arm64/include/asm/pci.h
>  create mode 100644 arch/arm64/kernel/pci.c

Applied to pci/host-generic, headed for v3.18, thanks!

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-23 21:54   ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-23 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 08:01:02PM +0100, Liviu Dudau wrote:
> This is my version 12 of the attempt at adding support for generic PCI host
> bridge controllers that make use of device tree information to
> configure themselves. It contains cleanups to address comments posted for v11.
> 
> Bjorn intends to pull this series into his tree and send it to linux-next if
> no major issues arise.
> 
> 
> Changes from v11:
>  - fixed race condition in pci_register_io_range() and bug where the function
>    would return with the io_range_lock held.
>  - split patch 4/10 that fixes the convertion of IO ranges into resources into
>    two patches. The new 4/12 just moves the function into drivers/of/address.c
>    and 5/12 makes the functional changes.
>  - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
>    part
>  - Removed the old PCI domain number parser and allocator and split the code
>    into two independent functions: 'int pci_get_new_domain_nr(void)' will
>    always return a new domain number when called while 'of_get_pci_domain_nr()'
>    will parse the DT and try to find a property of the given node called
>    'linux,pci-domain'. The property value, if found, will be truncated to
>    16-bit value and returned, or a negative value if an error occurs.
>  - Made the io_base pointer parameter that gets passed to
>    of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
>    be explicit when detecting multiple IO ranges about the device used.
>  - Fixed comments on commits to explain who uses pci_remap_iospace() as well
>    as making clear that the value used inside the function is a virtual address
>    and not a physical one. Also be explicit in the warning generated when
>    architectures without memory mapped IO support make use of this function
>  - Merged the arm64 patch into this series as Bjorn is going to pull it
>    into his tree.
> 
> Changes from v10:
>  - Addressed Lorenzo's comments wrt io_base not being initialised inside the
>    function that is supposed to modify it and also updated the comments to
>    explain the values returned by the function
>  - Updated pci_domain_nr helper function to split the allocation of the domain
>    number from the parsing of the device tree to find maximum defined domain
>    value
>  - Fixed up the commit author for commit 6/10
> 
> Changes from v9:
>  - Moved the DT parsing and assigning of IRQ patch from this series into arm64
>    specific patch. This keeps existing pcibios_add_device() unchanged and adds
>    an arch-specific version that can later be expanded to cater for dma_ops.
>  - Incorporated the fix for users of of_pci_range_to_resources() into the patch
>    that changes the behaviour for easier bisection.
>  - Added fixes for tegra and rcar host drivers in their usage of
>    of_pci_range_to_resources()
>  - Broke up of_create_pci_host_bridge() to remove the callback function. The
>    function left has been renamed into of_pci_get_host_bridge_resources(). The
>    added benefit of that is that the architectural hook for fixing up host bridge
>    resources now dissappears.
>  - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
>    that adds pci_remap_iospace() function. The arm64 specific override is moved
>    into the arm64 patchset.
>  - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
>    flags are not PCI_PROBE_ONLY
> 
> v11 thread here: https://lkml.org/lkml/2014/9/17/732
> v10 thread here: https://lkml.org/lkml/2014/9/8/333
> v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361
> 
> Best regards,
> Liviu
> 
> Catalin Marinas (1):
>   PCI: Introduce generic domain handling for PCI busses.
> 
> Liviu Dudau (11):
>   Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
>   PCI: Introduce helper functions to deal with PCI I/O ranges.
>   ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
>   PCI: OF: Move of_pci_range_to_resources() into address.c
>   PCI: OF: Fix the conversion of IO ranges into IO resources.
>   PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
>   PCI: OF: Introduce helper function for retrieving PCI domain numbers
>   OF: PCI: Add support for parsing PCI host bridge resources from DT
>   PCI: Assign unassigned bus resources in pci_scan_root_bus()
>   PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
>   arm64: Add architectural support for PCIe
> 
>  arch/arm/include/asm/io.h         |   1 +
>  arch/arm/mach-integrator/pci_v3.c |  23 +++---
>  arch/arm64/Kconfig                |  22 +++++-
>  arch/arm64/include/asm/Kbuild     |   1 +
>  arch/arm64/include/asm/io.h       |   3 +-
>  arch/arm64/include/asm/pci.h      |  37 +++++++++
>  arch/arm64/include/asm/pgtable.h  |   2 +
>  arch/arm64/kernel/Makefile        |   1 +
>  arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
>  drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
>  drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
>  drivers/pci/host/pci-tegra.c      |  10 ++-
>  drivers/pci/host/pcie-rcar.c      |  21 ++++--
>  drivers/pci/pci.c                 |  43 +++++++++++
>  drivers/pci/probe.c               |  46 ++++++-----
>  include/asm-generic/io.h          |   2 +-
>  include/asm-generic/pgtable.h     |   4 +
>  include/linux/of_address.h        |  22 +++---
>  include/linux/of_pci.h            |  18 +++++
>  include/linux/pci.h               |  27 +++++++
>  20 files changed, 596 insertions(+), 52 deletions(-)
>  create mode 100644 arch/arm64/include/asm/pci.h
>  create mode 100644 arch/arm64/kernel/pci.c

Applied to pci/host-generic, headed for v3.18, thanks!

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
  2014-09-23 21:54   ` Bjorn Helgaas
@ 2014-09-23 22:48     ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 22:48 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 03:54:35PM -0600, Bjorn Helgaas wrote:
> On Tue, Sep 23, 2014 at 08:01:02PM +0100, Liviu Dudau wrote:
> > This is my version 12 of the attempt at adding support for generic PCI host
> > bridge controllers that make use of device tree information to
> > configure themselves. It contains cleanups to address comments posted for v11.
> > 
> > Bjorn intends to pull this series into his tree and send it to linux-next if
> > no major issues arise.
> > 
> > 
> > Changes from v11:
> >  - fixed race condition in pci_register_io_range() and bug where the function
> >    would return with the io_range_lock held.
> >  - split patch 4/10 that fixes the convertion of IO ranges into resources into
> >    two patches. The new 4/12 just moves the function into drivers/of/address.c
> >    and 5/12 makes the functional changes.
> >  - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
> >    part
> >  - Removed the old PCI domain number parser and allocator and split the code
> >    into two independent functions: 'int pci_get_new_domain_nr(void)' will
> >    always return a new domain number when called while 'of_get_pci_domain_nr()'
> >    will parse the DT and try to find a property of the given node called
> >    'linux,pci-domain'. The property value, if found, will be truncated to
> >    16-bit value and returned, or a negative value if an error occurs.
> >  - Made the io_base pointer parameter that gets passed to
> >    of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
> >    be explicit when detecting multiple IO ranges about the device used.
> >  - Fixed comments on commits to explain who uses pci_remap_iospace() as well
> >    as making clear that the value used inside the function is a virtual address
> >    and not a physical one. Also be explicit in the warning generated when
> >    architectures without memory mapped IO support make use of this function
> >  - Merged the arm64 patch into this series as Bjorn is going to pull it
> >    into his tree.
> > 
> > Changes from v10:
> >  - Addressed Lorenzo's comments wrt io_base not being initialised inside the
> >    function that is supposed to modify it and also updated the comments to
> >    explain the values returned by the function
> >  - Updated pci_domain_nr helper function to split the allocation of the domain
> >    number from the parsing of the device tree to find maximum defined domain
> >    value
> >  - Fixed up the commit author for commit 6/10
> > 
> > Changes from v9:
> >  - Moved the DT parsing and assigning of IRQ patch from this series into arm64
> >    specific patch. This keeps existing pcibios_add_device() unchanged and adds
> >    an arch-specific version that can later be expanded to cater for dma_ops.
> >  - Incorporated the fix for users of of_pci_range_to_resources() into the patch
> >    that changes the behaviour for easier bisection.
> >  - Added fixes for tegra and rcar host drivers in their usage of
> >    of_pci_range_to_resources()
> >  - Broke up of_create_pci_host_bridge() to remove the callback function. The
> >    function left has been renamed into of_pci_get_host_bridge_resources(). The
> >    added benefit of that is that the architectural hook for fixing up host bridge
> >    resources now dissappears.
> >  - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
> >    that adds pci_remap_iospace() function. The arm64 specific override is moved
> >    into the arm64 patchset.
> >  - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
> >    flags are not PCI_PROBE_ONLY
> > 
> > v11 thread here: https://lkml.org/lkml/2014/9/17/732
> > v10 thread here: https://lkml.org/lkml/2014/9/8/333
> > v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361
> > 
> > Best regards,
> > Liviu
> > 
> > Catalin Marinas (1):
> >   PCI: Introduce generic domain handling for PCI busses.
> > 
> > Liviu Dudau (11):
> >   Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
> >   PCI: Introduce helper functions to deal with PCI I/O ranges.
> >   ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
> >   PCI: OF: Move of_pci_range_to_resources() into address.c
> >   PCI: OF: Fix the conversion of IO ranges into IO resources.
> >   PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
> >   PCI: OF: Introduce helper function for retrieving PCI domain numbers
> >   OF: PCI: Add support for parsing PCI host bridge resources from DT
> >   PCI: Assign unassigned bus resources in pci_scan_root_bus()
> >   PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
> >   arm64: Add architectural support for PCIe
> > 
> >  arch/arm/include/asm/io.h         |   1 +
> >  arch/arm/mach-integrator/pci_v3.c |  23 +++---
> >  arch/arm64/Kconfig                |  22 +++++-
> >  arch/arm64/include/asm/Kbuild     |   1 +
> >  arch/arm64/include/asm/io.h       |   3 +-
> >  arch/arm64/include/asm/pci.h      |  37 +++++++++
> >  arch/arm64/include/asm/pgtable.h  |   2 +
> >  arch/arm64/kernel/Makefile        |   1 +
> >  arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
> >  drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
> >  drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
> >  drivers/pci/host/pci-tegra.c      |  10 ++-
> >  drivers/pci/host/pcie-rcar.c      |  21 ++++--
> >  drivers/pci/pci.c                 |  43 +++++++++++
> >  drivers/pci/probe.c               |  46 ++++++-----
> >  include/asm-generic/io.h          |   2 +-
> >  include/asm-generic/pgtable.h     |   4 +
> >  include/linux/of_address.h        |  22 +++---
> >  include/linux/of_pci.h            |  18 +++++
> >  include/linux/pci.h               |  27 +++++++
> >  20 files changed, 596 insertions(+), 52 deletions(-)
> >  create mode 100644 arch/arm64/include/asm/pci.h
> >  create mode 100644 arch/arm64/kernel/pci.c
> 
> Applied to pci/host-generic, headed for v3.18, thanks!

I really appreciate this, Bjorn, and many thanks!!!

While the next immediate target is converting pci-host-generic.c, pci-imx6.c
and probably pcie-designware.c to my series, I would like to ask you what
is your longer term plan. Now that I have got my head full of PCI code,
I have some ideas but feel that meeting with you and all those involved
in core PCI support would be a better venue than sending emails back and
forth. When is your next plan to attend a Linux conference?

Best regards,
Liviu

> 
> Bjorn
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-23 22:48     ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 22:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 03:54:35PM -0600, Bjorn Helgaas wrote:
> On Tue, Sep 23, 2014 at 08:01:02PM +0100, Liviu Dudau wrote:
> > This is my version 12 of the attempt at adding support for generic PCI host
> > bridge controllers that make use of device tree information to
> > configure themselves. It contains cleanups to address comments posted for v11.
> > 
> > Bjorn intends to pull this series into his tree and send it to linux-next if
> > no major issues arise.
> > 
> > 
> > Changes from v11:
> >  - fixed race condition in pci_register_io_range() and bug where the function
> >    would return with the io_range_lock held.
> >  - split patch 4/10 that fixes the convertion of IO ranges into resources into
> >    two patches. The new 4/12 just moves the function into drivers/of/address.c
> >    and 5/12 makes the functional changes.
> >  - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
> >    part
> >  - Removed the old PCI domain number parser and allocator and split the code
> >    into two independent functions: 'int pci_get_new_domain_nr(void)' will
> >    always return a new domain number when called while 'of_get_pci_domain_nr()'
> >    will parse the DT and try to find a property of the given node called
> >    'linux,pci-domain'. The property value, if found, will be truncated to
> >    16-bit value and returned, or a negative value if an error occurs.
> >  - Made the io_base pointer parameter that gets passed to
> >    of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
> >    be explicit when detecting multiple IO ranges about the device used.
> >  - Fixed comments on commits to explain who uses pci_remap_iospace() as well
> >    as making clear that the value used inside the function is a virtual address
> >    and not a physical one. Also be explicit in the warning generated when
> >    architectures without memory mapped IO support make use of this function
> >  - Merged the arm64 patch into this series as Bjorn is going to pull it
> >    into his tree.
> > 
> > Changes from v10:
> >  - Addressed Lorenzo's comments wrt io_base not being initialised inside the
> >    function that is supposed to modify it and also updated the comments to
> >    explain the values returned by the function
> >  - Updated pci_domain_nr helper function to split the allocation of the domain
> >    number from the parsing of the device tree to find maximum defined domain
> >    value
> >  - Fixed up the commit author for commit 6/10
> > 
> > Changes from v9:
> >  - Moved the DT parsing and assigning of IRQ patch from this series into arm64
> >    specific patch. This keeps existing pcibios_add_device() unchanged and adds
> >    an arch-specific version that can later be expanded to cater for dma_ops.
> >  - Incorporated the fix for users of of_pci_range_to_resources() into the patch
> >    that changes the behaviour for easier bisection.
> >  - Added fixes for tegra and rcar host drivers in their usage of
> >    of_pci_range_to_resources()
> >  - Broke up of_create_pci_host_bridge() to remove the callback function. The
> >    function left has been renamed into of_pci_get_host_bridge_resources(). The
> >    added benefit of that is that the architectural hook for fixing up host bridge
> >    resources now dissappears.
> >  - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
> >    that adds pci_remap_iospace() function. The arm64 specific override is moved
> >    into the arm64 patchset.
> >  - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
> >    flags are not PCI_PROBE_ONLY
> > 
> > v11 thread here: https://lkml.org/lkml/2014/9/17/732
> > v10 thread here: https://lkml.org/lkml/2014/9/8/333
> > v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361
> > 
> > Best regards,
> > Liviu
> > 
> > Catalin Marinas (1):
> >   PCI: Introduce generic domain handling for PCI busses.
> > 
> > Liviu Dudau (11):
> >   Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
> >   PCI: Introduce helper functions to deal with PCI I/O ranges.
> >   ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
> >   PCI: OF: Move of_pci_range_to_resources() into address.c
> >   PCI: OF: Fix the conversion of IO ranges into IO resources.
> >   PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
> >   PCI: OF: Introduce helper function for retrieving PCI domain numbers
> >   OF: PCI: Add support for parsing PCI host bridge resources from DT
> >   PCI: Assign unassigned bus resources in pci_scan_root_bus()
> >   PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
> >   arm64: Add architectural support for PCIe
> > 
> >  arch/arm/include/asm/io.h         |   1 +
> >  arch/arm/mach-integrator/pci_v3.c |  23 +++---
> >  arch/arm64/Kconfig                |  22 +++++-
> >  arch/arm64/include/asm/Kbuild     |   1 +
> >  arch/arm64/include/asm/io.h       |   3 +-
> >  arch/arm64/include/asm/pci.h      |  37 +++++++++
> >  arch/arm64/include/asm/pgtable.h  |   2 +
> >  arch/arm64/kernel/Makefile        |   1 +
> >  arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
> >  drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
> >  drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
> >  drivers/pci/host/pci-tegra.c      |  10 ++-
> >  drivers/pci/host/pcie-rcar.c      |  21 ++++--
> >  drivers/pci/pci.c                 |  43 +++++++++++
> >  drivers/pci/probe.c               |  46 ++++++-----
> >  include/asm-generic/io.h          |   2 +-
> >  include/asm-generic/pgtable.h     |   4 +
> >  include/linux/of_address.h        |  22 +++---
> >  include/linux/of_pci.h            |  18 +++++
> >  include/linux/pci.h               |  27 +++++++
> >  20 files changed, 596 insertions(+), 52 deletions(-)
> >  create mode 100644 arch/arm64/include/asm/pci.h
> >  create mode 100644 arch/arm64/kernel/pci.c
> 
> Applied to pci/host-generic, headed for v3.18, thanks!

I really appreciate this, Bjorn, and many thanks!!!

While the next immediate target is converting pci-host-generic.c, pci-imx6.c
and probably pcie-designware.c to my series, I would like to ask you what
is your longer term plan. Now that I have got my head full of PCI code,
I have some ideas but feel that meeting with you and all those involved
in core PCI support would be a better venue than sending emails back and
forth. When is your next plan to attend a Linux conference?

Best regards,
Liviu

> 
> Bjorn
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
  2014-09-23 19:01 ` Liviu Dudau
  (?)
@ 2014-09-23 22:49   ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 22:49 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 08:01:02PM +0100, Liviu Dudau wrote:
> This is my version 12 of the attempt at adding support for generic PCI host
> bridge controllers that make use of device tree information to
> configure themselves. It contains cleanups to address comments posted for v11.
> 
> Bjorn intends to pull this series into his tree and send it to linux-next if
> no major issues arise.
> 
> 
> Changes from v11:
>  - fixed race condition in pci_register_io_range() and bug where the function
>    would return with the io_range_lock held.
>  - split patch 4/10 that fixes the convertion of IO ranges into resources into
>    two patches. The new 4/12 just moves the function into drivers/of/address.c
>    and 5/12 makes the functional changes.
>  - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
>    part
>  - Removed the old PCI domain number parser and allocator and split the code
>    into two independent functions: 'int pci_get_new_domain_nr(void)' will
>    always return a new domain number when called while 'of_get_pci_domain_nr()'
>    will parse the DT and try to find a property of the given node called
>    'linux,pci-domain'. The property value, if found, will be truncated to
>    16-bit value and returned, or a negative value if an error occurs.
>  - Made the io_base pointer parameter that gets passed to
>    of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
>    be explicit when detecting multiple IO ranges about the device used.
>  - Fixed comments on commits to explain who uses pci_remap_iospace() as well
>    as making clear that the value used inside the function is a virtual address
>    and not a physical one. Also be explicit in the warning generated when
>    architectures without memory mapped IO support make use of this function
>  - Merged the arm64 patch into this series as Bjorn is going to pull it
>    into his tree.
> 
> Changes from v10:
>  - Addressed Lorenzo's comments wrt io_base not being initialised inside the
>    function that is supposed to modify it and also updated the comments to
>    explain the values returned by the function
>  - Updated pci_domain_nr helper function to split the allocation of the domain
>    number from the parsing of the device tree to find maximum defined domain
>    value
>  - Fixed up the commit author for commit 6/10
> 
> Changes from v9:
>  - Moved the DT parsing and assigning of IRQ patch from this series into arm64
>    specific patch. This keeps existing pcibios_add_device() unchanged and adds
>    an arch-specific version that can later be expanded to cater for dma_ops.
>  - Incorporated the fix for users of of_pci_range_to_resources() into the patch
>    that changes the behaviour for easier bisection.
>  - Added fixes for tegra and rcar host drivers in their usage of
>    of_pci_range_to_resources()
>  - Broke up of_create_pci_host_bridge() to remove the callback function. The
>    function left has been renamed into of_pci_get_host_bridge_resources(). The
>    added benefit of that is that the architectural hook for fixing up host bridge
>    resources now dissappears.
>  - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
>    that adds pci_remap_iospace() function. The arm64 specific override is moved
>    into the arm64 patchset.
>  - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
>    flags are not PCI_PROBE_ONLY
> 
> v11 thread here: https://lkml.org/lkml/2014/9/17/732
> v10 thread here: https://lkml.org/lkml/2014/9/8/333
> v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361

Something of a bad habit of mine, I keep forgetting to post details about the
git tree: git://linux-arm.org/linux-ld.git for-upstream/pci_v12

Best regards,
Liviu

> 
> Best regards,
> Liviu
> 
> Catalin Marinas (1):
>   PCI: Introduce generic domain handling for PCI busses.
> 
> Liviu Dudau (11):
>   Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
>   PCI: Introduce helper functions to deal with PCI I/O ranges.
>   ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
>   PCI: OF: Move of_pci_range_to_resources() into address.c
>   PCI: OF: Fix the conversion of IO ranges into IO resources.
>   PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
>   PCI: OF: Introduce helper function for retrieving PCI domain numbers
>   OF: PCI: Add support for parsing PCI host bridge resources from DT
>   PCI: Assign unassigned bus resources in pci_scan_root_bus()
>   PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
>   arm64: Add architectural support for PCIe
> 
>  arch/arm/include/asm/io.h         |   1 +
>  arch/arm/mach-integrator/pci_v3.c |  23 +++---
>  arch/arm64/Kconfig                |  22 +++++-
>  arch/arm64/include/asm/Kbuild     |   1 +
>  arch/arm64/include/asm/io.h       |   3 +-
>  arch/arm64/include/asm/pci.h      |  37 +++++++++
>  arch/arm64/include/asm/pgtable.h  |   2 +
>  arch/arm64/kernel/Makefile        |   1 +
>  arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
>  drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
>  drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
>  drivers/pci/host/pci-tegra.c      |  10 ++-
>  drivers/pci/host/pcie-rcar.c      |  21 ++++--
>  drivers/pci/pci.c                 |  43 +++++++++++
>  drivers/pci/probe.c               |  46 ++++++-----
>  include/asm-generic/io.h          |   2 +-
>  include/asm-generic/pgtable.h     |   4 +
>  include/linux/of_address.h        |  22 +++---
>  include/linux/of_pci.h            |  18 +++++
>  include/linux/pci.h               |  27 +++++++
>  20 files changed, 596 insertions(+), 52 deletions(-)
>  create mode 100644 arch/arm64/include/asm/pci.h
>  create mode 100644 arch/arm64/kernel/pci.c
> 
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-23 22:49   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 22:49 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: linux-arch, Grant Likely, Kukjin Kim, Russell King,
	Arnd Bergmann, Device Tree ML, linux-pci, Catalin Marinas,
	Linus Walleij, Jingoo Han, Will Deacon, LKML, Jason Gunthorpe,
	Rob Herring, Tanmay Inamdar, Suravee Suthikulanit,
	Benjamin Herrenschmidt, Bjorn Helgaas, Sinan Kaya, LAKML

On Tue, Sep 23, 2014 at 08:01:02PM +0100, Liviu Dudau wrote:
> This is my version 12 of the attempt at adding support for generic PCI host
> bridge controllers that make use of device tree information to
> configure themselves. It contains cleanups to address comments posted for v11.
> 
> Bjorn intends to pull this series into his tree and send it to linux-next if
> no major issues arise.
> 
> 
> Changes from v11:
>  - fixed race condition in pci_register_io_range() and bug where the function
>    would return with the io_range_lock held.
>  - split patch 4/10 that fixes the convertion of IO ranges into resources into
>    two patches. The new 4/12 just moves the function into drivers/of/address.c
>    and 5/12 makes the functional changes.
>  - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
>    part
>  - Removed the old PCI domain number parser and allocator and split the code
>    into two independent functions: 'int pci_get_new_domain_nr(void)' will
>    always return a new domain number when called while 'of_get_pci_domain_nr()'
>    will parse the DT and try to find a property of the given node called
>    'linux,pci-domain'. The property value, if found, will be truncated to
>    16-bit value and returned, or a negative value if an error occurs.
>  - Made the io_base pointer parameter that gets passed to
>    of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
>    be explicit when detecting multiple IO ranges about the device used.
>  - Fixed comments on commits to explain who uses pci_remap_iospace() as well
>    as making clear that the value used inside the function is a virtual address
>    and not a physical one. Also be explicit in the warning generated when
>    architectures without memory mapped IO support make use of this function
>  - Merged the arm64 patch into this series as Bjorn is going to pull it
>    into his tree.
> 
> Changes from v10:
>  - Addressed Lorenzo's comments wrt io_base not being initialised inside the
>    function that is supposed to modify it and also updated the comments to
>    explain the values returned by the function
>  - Updated pci_domain_nr helper function to split the allocation of the domain
>    number from the parsing of the device tree to find maximum defined domain
>    value
>  - Fixed up the commit author for commit 6/10
> 
> Changes from v9:
>  - Moved the DT parsing and assigning of IRQ patch from this series into arm64
>    specific patch. This keeps existing pcibios_add_device() unchanged and adds
>    an arch-specific version that can later be expanded to cater for dma_ops.
>  - Incorporated the fix for users of of_pci_range_to_resources() into the patch
>    that changes the behaviour for easier bisection.
>  - Added fixes for tegra and rcar host drivers in their usage of
>    of_pci_range_to_resources()
>  - Broke up of_create_pci_host_bridge() to remove the callback function. The
>    function left has been renamed into of_pci_get_host_bridge_resources(). The
>    added benefit of that is that the architectural hook for fixing up host bridge
>    resources now dissappears.
>  - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
>    that adds pci_remap_iospace() function. The arm64 specific override is moved
>    into the arm64 patchset.
>  - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
>    flags are not PCI_PROBE_ONLY
> 
> v11 thread here: https://lkml.org/lkml/2014/9/17/732
> v10 thread here: https://lkml.org/lkml/2014/9/8/333
> v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361

Something of a bad habit of mine, I keep forgetting to post details about the
git tree: git://linux-arm.org/linux-ld.git for-upstream/pci_v12

Best regards,
Liviu

> 
> Best regards,
> Liviu
> 
> Catalin Marinas (1):
>   PCI: Introduce generic domain handling for PCI busses.
> 
> Liviu Dudau (11):
>   Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
>   PCI: Introduce helper functions to deal with PCI I/O ranges.
>   ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
>   PCI: OF: Move of_pci_range_to_resources() into address.c
>   PCI: OF: Fix the conversion of IO ranges into IO resources.
>   PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
>   PCI: OF: Introduce helper function for retrieving PCI domain numbers
>   OF: PCI: Add support for parsing PCI host bridge resources from DT
>   PCI: Assign unassigned bus resources in pci_scan_root_bus()
>   PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
>   arm64: Add architectural support for PCIe
> 
>  arch/arm/include/asm/io.h         |   1 +
>  arch/arm/mach-integrator/pci_v3.c |  23 +++---
>  arch/arm64/Kconfig                |  22 +++++-
>  arch/arm64/include/asm/Kbuild     |   1 +
>  arch/arm64/include/asm/io.h       |   3 +-
>  arch/arm64/include/asm/pci.h      |  37 +++++++++
>  arch/arm64/include/asm/pgtable.h  |   2 +
>  arch/arm64/kernel/Makefile        |   1 +
>  arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
>  drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
>  drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
>  drivers/pci/host/pci-tegra.c      |  10 ++-
>  drivers/pci/host/pcie-rcar.c      |  21 ++++--
>  drivers/pci/pci.c                 |  43 +++++++++++
>  drivers/pci/probe.c               |  46 ++++++-----
>  include/asm-generic/io.h          |   2 +-
>  include/asm-generic/pgtable.h     |   4 +
>  include/linux/of_address.h        |  22 +++---
>  include/linux/of_pci.h            |  18 +++++
>  include/linux/pci.h               |  27 +++++++
>  20 files changed, 596 insertions(+), 52 deletions(-)
>  create mode 100644 arch/arm64/include/asm/pci.h
>  create mode 100644 arch/arm64/kernel/pci.c
> 
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-23 22:49   ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-23 22:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 08:01:02PM +0100, Liviu Dudau wrote:
> This is my version 12 of the attempt at adding support for generic PCI host
> bridge controllers that make use of device tree information to
> configure themselves. It contains cleanups to address comments posted for v11.
> 
> Bjorn intends to pull this series into his tree and send it to linux-next if
> no major issues arise.
> 
> 
> Changes from v11:
>  - fixed race condition in pci_register_io_range() and bug where the function
>    would return with the io_range_lock held.
>  - split patch 4/10 that fixes the convertion of IO ranges into resources into
>    two patches. The new 4/12 just moves the function into drivers/of/address.c
>    and 5/12 makes the functional changes.
>  - Added Linus Walleij ACK on 5/12 for the arch/arm/mach-integrator/pci_v3.c
>    part
>  - Removed the old PCI domain number parser and allocator and split the code
>    into two independent functions: 'int pci_get_new_domain_nr(void)' will
>    always return a new domain number when called while 'of_get_pci_domain_nr()'
>    will parse the DT and try to find a property of the given node called
>    'linux,pci-domain'. The property value, if found, will be truncated to
>    16-bit value and returned, or a negative value if an error occurs.
>  - Made the io_base pointer parameter that gets passed to
>    of_pci_get_host_bridge_resources() optional (thanks Robert Richter) and
>    be explicit when detecting multiple IO ranges about the device used.
>  - Fixed comments on commits to explain who uses pci_remap_iospace() as well
>    as making clear that the value used inside the function is a virtual address
>    and not a physical one. Also be explicit in the warning generated when
>    architectures without memory mapped IO support make use of this function
>  - Merged the arm64 patch into this series as Bjorn is going to pull it
>    into his tree.
> 
> Changes from v10:
>  - Addressed Lorenzo's comments wrt io_base not being initialised inside the
>    function that is supposed to modify it and also updated the comments to
>    explain the values returned by the function
>  - Updated pci_domain_nr helper function to split the allocation of the domain
>    number from the parsing of the device tree to find maximum defined domain
>    value
>  - Fixed up the commit author for commit 6/10
> 
> Changes from v9:
>  - Moved the DT parsing and assigning of IRQ patch from this series into arm64
>    specific patch. This keeps existing pcibios_add_device() unchanged and adds
>    an arch-specific version that can later be expanded to cater for dma_ops.
>  - Incorporated the fix for users of of_pci_range_to_resources() into the patch
>    that changes the behaviour for easier bisection.
>  - Added fixes for tegra and rcar host drivers in their usage of
>    of_pci_range_to_resources()
>  - Broke up of_create_pci_host_bridge() to remove the callback function. The
>    function left has been renamed into of_pci_get_host_bridge_resources(). The
>    added benefit of that is that the architectural hook for fixing up host bridge
>    resources now dissappears.
>  - Reshuffled the way pgprot_device gets introduced. It is now part of the patch
>    that adds pci_remap_iospace() function. The arm64 specific override is moved
>    into the arm64 patchset.
>  - Added a patch to pci_scan_root_bus() to assign unassigned resources if PCI
>    flags are not PCI_PROBE_ONLY
> 
> v11 thread here: https://lkml.org/lkml/2014/9/17/732
> v10 thread here: https://lkml.org/lkml/2014/9/8/333
> v9 thread here, with links to previous threads: https://lkml.org/lkml/2014/8/12/361

Something of a bad habit of mine, I keep forgetting to post details about the
git tree: git://linux-arm.org/linux-ld.git for-upstream/pci_v12

Best regards,
Liviu

> 
> Best regards,
> Liviu
> 
> Catalin Marinas (1):
>   PCI: Introduce generic domain handling for PCI busses.
> 
> Liviu Dudau (11):
>   Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
>   PCI: Introduce helper functions to deal with PCI I/O ranges.
>   ARM: Define PCI_IOBASE as the base of virtual PCI IO space.
>   PCI: OF: Move of_pci_range_to_resources() into address.c
>   PCI: OF: Fix the conversion of IO ranges into IO resources.
>   PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
>   PCI: OF: Introduce helper function for retrieving PCI domain numbers
>   OF: PCI: Add support for parsing PCI host bridge resources from DT
>   PCI: Assign unassigned bus resources in pci_scan_root_bus()
>   PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space
>   arm64: Add architectural support for PCIe
> 
>  arch/arm/include/asm/io.h         |   1 +
>  arch/arm/mach-integrator/pci_v3.c |  23 +++---
>  arch/arm64/Kconfig                |  22 +++++-
>  arch/arm64/include/asm/Kbuild     |   1 +
>  arch/arm64/include/asm/io.h       |   3 +-
>  arch/arm64/include/asm/pci.h      |  37 +++++++++
>  arch/arm64/include/asm/pgtable.h  |   2 +
>  arch/arm64/kernel/Makefile        |   1 +
>  arch/arm64/kernel/pci.c           |  70 +++++++++++++++++
>  drivers/of/address.c              | 155 ++++++++++++++++++++++++++++++++++++++
>  drivers/of/of_pci.c               | 140 ++++++++++++++++++++++++++++++++++
>  drivers/pci/host/pci-tegra.c      |  10 ++-
>  drivers/pci/host/pcie-rcar.c      |  21 ++++--
>  drivers/pci/pci.c                 |  43 +++++++++++
>  drivers/pci/probe.c               |  46 ++++++-----
>  include/asm-generic/io.h          |   2 +-
>  include/asm-generic/pgtable.h     |   4 +
>  include/linux/of_address.h        |  22 +++---
>  include/linux/of_pci.h            |  18 +++++
>  include/linux/pci.h               |  27 +++++++
>  20 files changed, 596 insertions(+), 52 deletions(-)
>  create mode 100644 arch/arm64/include/asm/pci.h
>  create mode 100644 arch/arm64/kernel/pci.c
> 
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
  2014-09-23 22:48     ` Liviu Dudau
@ 2014-09-23 23:00       ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-23 23:00 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> ...
> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
> and probably pcie-designware.c to my series, I would like to ask you what
> is your longer term plan. Now that I have got my head full of PCI code,
> I have some ideas but feel that meeting with you and all those involved
> in core PCI support would be a better venue than sending emails back and
> forth. When is your next plan to attend a Linux conference?

That would be nice.  Unfortunately, I don't know what the next
conference will be yet.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-23 23:00       ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-23 23:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> ...
> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
> and probably pcie-designware.c to my series, I would like to ask you what
> is your longer term plan. Now that I have got my head full of PCI code,
> I have some ideas but feel that meeting with you and all those involved
> in core PCI support would be a better venue than sending emails back and
> forth. When is your next plan to attend a Linux conference?

That would be nice.  Unfortunately, I don't know what the next
conference will be yet.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
  2014-09-23 19:01   ` Liviu Dudau
  (?)
@ 2014-09-24  0:22     ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  0:22 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding, Simon Horman, Andrew Murray

[+cc Andrew]

On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
> The ranges property for a host bridge controller in DT describes
> the mapping between the PCI bus address and the CPU physical address.
> The resources framework however expects that the IO resources start
> at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
> The conversion from pci ranges to resources failed to take that into account,
> returning a CPU physical address instead of a port number.
> 
> Also fix all the drivers that depend on the old behaviour by fetching
> the CPU physical address based on the port number where it is being needed.
> 
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Simon Horman <horms@verge.net.au>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> ---
>  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>  include/linux/of_address.h        | 15 ++++++-------
>  5 files changed, 82 insertions(+), 31 deletions(-)
> ...

The of_pci_range_to_resource() implementation in drivers/of/address.c is
always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
CONFIG_PCI is not set, we get the static inline version from
include/linux/of_address.h as well, causing a redefinition error.

> diff --git a/drivers/of/address.c b/drivers/of/address.c
> @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
> ...
> +int of_pci_range_to_resource(struct of_pci_range *range,
> +	struct device_node *np, struct resource *res)

> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> ...
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  	return -ENOSYS;
>  }
>  
> +static inline int of_pci_range_to_resource(struct of_pci_range *range,
> +		struct device_node *np, struct resource *res)
> +{
> +	return -ENOSYS;
> +}

My proposal to fix it is the following three patches.  The first moves the
inline version of of_pci_range_to_resource() into the existing "#if
defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.

Andrew added it (and some other PCI-related things) with 29b635c00f3e
("of/pci: Provide support for parsing PCI DT ranges property") to
of_address.h outside of any ifdefs, so it's always available.  Maybe
there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
it with a quick look.

The second moves of_pci_range_to_resource() to address.c, still inside the
"#ifdef CONFIG_PCI" block.

Bjorn


commit 95a60df1c2d400c676ab1d20271735e2b4735437
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Tue Sep 23 17:27:42 2014 -0600

    of/pci: Define of_pci_range_to_resource() only when CONFIG_PCI=y
    
    of_pci_range_to_resource() was previously defined always, but it's only
    used by PCI code, so move the definition inside the CONFIG_OF_ADDRESS &&
    CONFIG_PCI block.
    
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index f8cc7daa420c..ecf913cf53b2 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -23,17 +23,6 @@ struct of_pci_range {
 #define for_each_of_pci_range(parser, range) \
 	for (; of_pci_range_parser_one(parser, range);)
 
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
 				    const __be32 *in_addr);
@@ -140,6 +129,18 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
+
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+					    struct device_node *np,
+					    struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
+
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)
@@ -155,4 +156,3 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
 #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 
 #endif /* __OF_ADDRESS_H */
-

commit 501857889201723da06aab0ec68186a5beaa9f72
Author: Liviu Dudau <Liviu.Dudau@arm.com>
Date:   Tue Sep 23 20:01:06 2014 +0100

    of/pci: Move of_pci_range_to_resources() to of/address.c
    
    We need to enhance of_pci_range_to_resources() enough that it won't make
    sense for it to be inline anymore.  Move it to drivers/of/address.c,
    keeping it under #ifdef CONFIG_PCI.
    
    [bhelgaas: drop extra detail from changelog, move def under CONFIG_PCI]
    Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    CC: Grant Likely <grant.likely@linaro.org>
    CC: Rob Herring <robh+dt@kernel.org>
    CC: Arnd Bergmann <arnd@arndb.de>
    CC: Catalin Marinas <catalin.marinas@arm.com>

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 758d4f04d4aa..327a57410797 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -295,6 +295,15 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 }
 EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
 
+void of_pci_range_to_resource(struct of_pci_range *range,
+			      struct device_node *np, struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
 #endif /* CONFIG_PCI */
 
 /*
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index ecf913cf53b2..fa20aa15463d 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -129,18 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
-
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
+extern void of_pci_range_to_resource(struct of_pci_range *range,
+				     struct device_node *np,
+				     struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)

commit e01c1ebeee0bc45d6ac5f52b22c57d278799869b
Author: Liviu Dudau <Liviu.Dudau@arm.com>
Date:   Tue Sep 23 20:01:07 2014 +0100

    of/pci: Fix the conversion of IO ranges into IO resources
    
    The ranges property for a host bridge controller in DT describes the
    mapping between the PCI bus address and the CPU physical address.  The
    resources framework however expects that the IO resources start at a pseudo
    "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.  The
    conversion from PCI ranges to resources failed to take that into account,
    returning a CPU physical address instead of a port number.
    
    Also fix all the drivers that depend on the old behaviour by fetching the
    CPU physical address based on the port number where it is being needed.
    
    Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Acked-by: Linus Walleij <linus.walleij@linaro.org>
    CC: Grant Likely <grant.likely@linaro.org>
    CC: Rob Herring <robh+dt@kernel.org>
    CC: Arnd Bergmann <arnd@arndb.de>
    CC: Thierry Reding <thierry.reding@gmail.com>
    CC: Simon Horman <horms@verge.net.au>
    CC: Catalin Marinas <catalin.marinas@arm.com>

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 05e1f73a1e8d..c186a17c2cff 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
 {
 	unsigned long flags;
 	unsigned int temp;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pcibios_min_mem = 0x00100000;
 
@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
 	/*
 	 * Setup window 2 - PCI IO
 	 */
-	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
 			V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
 
@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
 static void __init pci_v3_postinit(void)
 {
 	unsigned int pci_cmd;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pci_cmd = PCI_COMMAND_MEMORY |
 		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
 		       "interrupt: %d\n", ret);
 #endif
 
-	register_isa_ports(non_mem.start, io_mem.start, 0);
+	register_isa_ports(non_mem.start, io_address, 0);
 }
 
 /*
@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
 
 	for_each_of_pci_range(&parser, &range) {
 		if (!range.flags) {
-			of_pci_range_to_resource(&range, np, &conf_mem);
+			ret = of_pci_range_to_resource(&range, np, &conf_mem);
 			conf_mem.name = "PCIv3 config";
 		}
 		if (range.flags & IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &io_mem);
+			ret = of_pci_range_to_resource(&range, np, &io_mem);
 			io_mem.name = "PCIv3 I/O";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			!(range.flags & IORESOURCE_PREFETCH)) {
 			non_mem_pci = range.pci_addr;
 			non_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &non_mem);
+			ret = of_pci_range_to_resource(&range, np, &non_mem);
 			non_mem.name = "PCIv3 non-prefetched mem";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			(range.flags & IORESOURCE_PREFETCH)) {
 			pre_mem_pci = range.pci_addr;
 			pre_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &pre_mem);
+			ret = of_pci_range_to_resource(&range, np, &pre_mem);
 			pre_mem.name = "PCIv3 prefetched mem";
 		}
-	}
 
-	if (!conf_mem.start || !io_mem.start ||
-	    !non_mem.start || !pre_mem.start) {
-		dev_err(&pdev->dev, "missing ranges in device node\n");
-		return -EINVAL;
+		if (ret < 0) {
+			dev_err(&pdev->dev, "missing ranges in device node\n");
+			return ret;
+		}
 	}
 
 	pci_v3.map_irq = of_irq_parse_and_map_pci;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 327a57410797..afdb78299f61 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -295,14 +295,50 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 }
 EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
 
-void of_pci_range_to_resource(struct of_pci_range *range,
-			      struct device_node *np, struct resource *res)
+/*
+ * of_pci_range_to_resource - Create a resource from an of_pci_range
+ * @range:	the PCI range that describes the resource
+ * @np:		device node where the range belongs to
+ * @res:	pointer to a valid resource that will be updated to
+ *              reflect the values contained in the range.
+ *
+ * Returns EINVAL if the range cannot be converted to resource.
+ *
+ * Note that if the range is an IO range, the resource will be converted
+ * using pci_address_to_pio() which can fail if it is called too early or
+ * if the range cannot be matched to any host bridge IO space (our case here).
+ * To guard against that we try to register the IO range first.
+ * If that fails we know that pci_address_to_pio() will do too.
+ */
+int of_pci_range_to_resource(struct of_pci_range *range,
+			     struct device_node *np, struct resource *res)
 {
+	int err;
 	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
 	res->parent = res->child = res->sibling = NULL;
 	res->name = np->full_name;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long port;
+		err = pci_register_io_range(range->cpu_addr, range->size);
+		if (err)
+			goto invalid_range;
+		port = pci_address_to_pio(range->cpu_addr);
+		if (port == (unsigned long)-1) {
+			err = -EINVAL;
+			goto invalid_range;
+		}
+		res->start = port;
+	} else {
+		res->start = range->cpu_addr;
+	}
+	res->end = res->start + range->size - 1;
+	return 0;
+
+invalid_range:
+	res->start = (resource_size_t)OF_BAD_ADDR;
+	res->end = (resource_size_t)OF_BAD_ADDR;
+	return err;
 }
 #endif /* CONFIG_PCI */
 
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb223d5..946935db62b6 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
 	struct tegra_pcie *pcie = sys_to_pcie(sys);
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
 				sys->mem_offset);
 	pci_add_resource(&sys->resources, &pcie->busn);
 
-	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
+	pci_ioremap_io(nr * SZ_64K, io_start);
 
 	return 1;
 }
@@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 {
 	u32 fpci_bar, size, axi_address;
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	/* Bar 0: type 1 extended configuration space */
 	fpci_bar = 0xfe100000;
@@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 	/* Bar 1: downstream IO bar */
 	fpci_bar = 0xfdfc0000;
 	size = resource_size(&pcie->io);
-	axi_address = pcie->io.start;
+	axi_address = io_start;
 	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
 	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
 	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
@@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, np, &res);
+		err = of_pci_range_to_resource(&range, np, &res);
+		if (err < 0)
+			return err;
 
 		switch (res.flags & IORESOURCE_TYPE_BITS) {
 		case IORESOURCE_IO:
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5e07d4..61158e03ab5f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 
 	/* Setup PCIe address space mappings for each resource */
 	resource_size_t size;
+	resource_size_t res_start;
 	u32 mask;
 
 	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
 	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
 
-	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
-	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
+	if (res->flags & IORESOURCE_IO)
+		res_start = pci_pio_to_address(res->start);
+	else
+		res_start = res->start;
+
+	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
+	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
 
 	/* First resource is for IO */
 	mask = PAR_ENABLE;
@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
 
 		rcar_pcie_setup_window(i, pcie);
 
-		if (res->flags & IORESOURCE_IO)
-			pci_ioremap_io(nr * SZ_64K, res->start);
-		else
+		if (res->flags & IORESOURCE_IO) {
+			phys_addr_t io_start = pci_pio_to_address(res->start);
+			pci_ioremap_io(nr * SZ_64K, io_start);
+		} else
 			pci_add_resource(&sys->resources, res);
 	}
 	pci_add_resource(&sys->resources, &pcie->busn);
@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, pdev->dev.of_node,
+		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
 						&pcie->res[win++]);
+		if (err < 0)
+			return err;
 
 		if (win > RCAR_PCI_MAX_RESOURCES)
 			break;
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index fa20aa15463d..7ebb877b07c2 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -129,9 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
-extern void of_pci_range_to_resource(struct of_pci_range *range,
-				     struct device_node *np,
-				     struct resource *res);
+extern int of_pci_range_to_resource(struct of_pci_range *range,
+				    struct device_node *np,
+				    struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  0:22     ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  0:22 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding, Simon Horman

[+cc Andrew]

On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
> The ranges property for a host bridge controller in DT describes
> the mapping between the PCI bus address and the CPU physical address.
> The resources framework however expects that the IO resources start
> at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
> The conversion from pci ranges to resources failed to take that into account,
> returning a CPU physical address instead of a port number.
> 
> Also fix all the drivers that depend on the old behaviour by fetching
> the CPU physical address based on the port number where it is being needed.
> 
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Simon Horman <horms@verge.net.au>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> ---
>  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>  include/linux/of_address.h        | 15 ++++++-------
>  5 files changed, 82 insertions(+), 31 deletions(-)
> ...

The of_pci_range_to_resource() implementation in drivers/of/address.c is
always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
CONFIG_PCI is not set, we get the static inline version from
include/linux/of_address.h as well, causing a redefinition error.

> diff --git a/drivers/of/address.c b/drivers/of/address.c
> @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
> ...
> +int of_pci_range_to_resource(struct of_pci_range *range,
> +	struct device_node *np, struct resource *res)

> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> ...
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  	return -ENOSYS;
>  }
>  
> +static inline int of_pci_range_to_resource(struct of_pci_range *range,
> +		struct device_node *np, struct resource *res)
> +{
> +	return -ENOSYS;
> +}

My proposal to fix it is the following three patches.  The first moves the
inline version of of_pci_range_to_resource() into the existing "#if
defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.

Andrew added it (and some other PCI-related things) with 29b635c00f3e
("of/pci: Provide support for parsing PCI DT ranges property") to
of_address.h outside of any ifdefs, so it's always available.  Maybe
there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
it with a quick look.

The second moves of_pci_range_to_resource() to address.c, still inside the
"#ifdef CONFIG_PCI" block.

Bjorn


commit 95a60df1c2d400c676ab1d20271735e2b4735437
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Tue Sep 23 17:27:42 2014 -0600

    of/pci: Define of_pci_range_to_resource() only when CONFIG_PCI=y
    
    of_pci_range_to_resource() was previously defined always, but it's only
    used by PCI code, so move the definition inside the CONFIG_OF_ADDRESS &&
    CONFIG_PCI block.
    
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index f8cc7daa420c..ecf913cf53b2 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -23,17 +23,6 @@ struct of_pci_range {
 #define for_each_of_pci_range(parser, range) \
 	for (; of_pci_range_parser_one(parser, range);)
 
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
 				    const __be32 *in_addr);
@@ -140,6 +129,18 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
+
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+					    struct device_node *np,
+					    struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
+
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)
@@ -155,4 +156,3 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
 #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 
 #endif /* __OF_ADDRESS_H */
-

commit 501857889201723da06aab0ec68186a5beaa9f72
Author: Liviu Dudau <Liviu.Dudau@arm.com>
Date:   Tue Sep 23 20:01:06 2014 +0100

    of/pci: Move of_pci_range_to_resources() to of/address.c
    
    We need to enhance of_pci_range_to_resources() enough that it won't make
    sense for it to be inline anymore.  Move it to drivers/of/address.c,
    keeping it under #ifdef CONFIG_PCI.
    
    [bhelgaas: drop extra detail from changelog, move def under CONFIG_PCI]
    Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    CC: Grant Likely <grant.likely@linaro.org>
    CC: Rob Herring <robh+dt@kernel.org>
    CC: Arnd Bergmann <arnd@arndb.de>
    CC: Catalin Marinas <catalin.marinas@arm.com>

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 758d4f04d4aa..327a57410797 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -295,6 +295,15 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 }
 EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
 
+void of_pci_range_to_resource(struct of_pci_range *range,
+			      struct device_node *np, struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
 #endif /* CONFIG_PCI */
 
 /*
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index ecf913cf53b2..fa20aa15463d 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -129,18 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
-
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
+extern void of_pci_range_to_resource(struct of_pci_range *range,
+				     struct device_node *np,
+				     struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)

commit e01c1ebeee0bc45d6ac5f52b22c57d278799869b
Author: Liviu Dudau <Liviu.Dudau@arm.com>
Date:   Tue Sep 23 20:01:07 2014 +0100

    of/pci: Fix the conversion of IO ranges into IO resources
    
    The ranges property for a host bridge controller in DT describes the
    mapping between the PCI bus address and the CPU physical address.  The
    resources framework however expects that the IO resources start at a pseudo
    "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.  The
    conversion from PCI ranges to resources failed to take that into account,
    returning a CPU physical address instead of a port number.
    
    Also fix all the drivers that depend on the old behaviour by fetching the
    CPU physical address based on the port number where it is being needed.
    
    Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Acked-by: Linus Walleij <linus.walleij@linaro.org>
    CC: Grant Likely <grant.likely@linaro.org>
    CC: Rob Herring <robh+dt@kernel.org>
    CC: Arnd Bergmann <arnd@arndb.de>
    CC: Thierry Reding <thierry.reding@gmail.com>
    CC: Simon Horman <horms@verge.net.au>
    CC: Catalin Marinas <catalin.marinas@arm.com>

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 05e1f73a1e8d..c186a17c2cff 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
 {
 	unsigned long flags;
 	unsigned int temp;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pcibios_min_mem = 0x00100000;
 
@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
 	/*
 	 * Setup window 2 - PCI IO
 	 */
-	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
 			V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
 
@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
 static void __init pci_v3_postinit(void)
 {
 	unsigned int pci_cmd;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pci_cmd = PCI_COMMAND_MEMORY |
 		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
 		       "interrupt: %d\n", ret);
 #endif
 
-	register_isa_ports(non_mem.start, io_mem.start, 0);
+	register_isa_ports(non_mem.start, io_address, 0);
 }
 
 /*
@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
 
 	for_each_of_pci_range(&parser, &range) {
 		if (!range.flags) {
-			of_pci_range_to_resource(&range, np, &conf_mem);
+			ret = of_pci_range_to_resource(&range, np, &conf_mem);
 			conf_mem.name = "PCIv3 config";
 		}
 		if (range.flags & IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &io_mem);
+			ret = of_pci_range_to_resource(&range, np, &io_mem);
 			io_mem.name = "PCIv3 I/O";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			!(range.flags & IORESOURCE_PREFETCH)) {
 			non_mem_pci = range.pci_addr;
 			non_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &non_mem);
+			ret = of_pci_range_to_resource(&range, np, &non_mem);
 			non_mem.name = "PCIv3 non-prefetched mem";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			(range.flags & IORESOURCE_PREFETCH)) {
 			pre_mem_pci = range.pci_addr;
 			pre_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &pre_mem);
+			ret = of_pci_range_to_resource(&range, np, &pre_mem);
 			pre_mem.name = "PCIv3 prefetched mem";
 		}
-	}
 
-	if (!conf_mem.start || !io_mem.start ||
-	    !non_mem.start || !pre_mem.start) {
-		dev_err(&pdev->dev, "missing ranges in device node\n");
-		return -EINVAL;
+		if (ret < 0) {
+			dev_err(&pdev->dev, "missing ranges in device node\n");
+			return ret;
+		}
 	}
 
 	pci_v3.map_irq = of_irq_parse_and_map_pci;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 327a57410797..afdb78299f61 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -295,14 +295,50 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 }
 EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
 
-void of_pci_range_to_resource(struct of_pci_range *range,
-			      struct device_node *np, struct resource *res)
+/*
+ * of_pci_range_to_resource - Create a resource from an of_pci_range
+ * @range:	the PCI range that describes the resource
+ * @np:		device node where the range belongs to
+ * @res:	pointer to a valid resource that will be updated to
+ *              reflect the values contained in the range.
+ *
+ * Returns EINVAL if the range cannot be converted to resource.
+ *
+ * Note that if the range is an IO range, the resource will be converted
+ * using pci_address_to_pio() which can fail if it is called too early or
+ * if the range cannot be matched to any host bridge IO space (our case here).
+ * To guard against that we try to register the IO range first.
+ * If that fails we know that pci_address_to_pio() will do too.
+ */
+int of_pci_range_to_resource(struct of_pci_range *range,
+			     struct device_node *np, struct resource *res)
 {
+	int err;
 	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
 	res->parent = res->child = res->sibling = NULL;
 	res->name = np->full_name;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long port;
+		err = pci_register_io_range(range->cpu_addr, range->size);
+		if (err)
+			goto invalid_range;
+		port = pci_address_to_pio(range->cpu_addr);
+		if (port == (unsigned long)-1) {
+			err = -EINVAL;
+			goto invalid_range;
+		}
+		res->start = port;
+	} else {
+		res->start = range->cpu_addr;
+	}
+	res->end = res->start + range->size - 1;
+	return 0;
+
+invalid_range:
+	res->start = (resource_size_t)OF_BAD_ADDR;
+	res->end = (resource_size_t)OF_BAD_ADDR;
+	return err;
 }
 #endif /* CONFIG_PCI */
 
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb223d5..946935db62b6 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
 	struct tegra_pcie *pcie = sys_to_pcie(sys);
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
 				sys->mem_offset);
 	pci_add_resource(&sys->resources, &pcie->busn);
 
-	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
+	pci_ioremap_io(nr * SZ_64K, io_start);
 
 	return 1;
 }
@@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 {
 	u32 fpci_bar, size, axi_address;
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	/* Bar 0: type 1 extended configuration space */
 	fpci_bar = 0xfe100000;
@@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 	/* Bar 1: downstream IO bar */
 	fpci_bar = 0xfdfc0000;
 	size = resource_size(&pcie->io);
-	axi_address = pcie->io.start;
+	axi_address = io_start;
 	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
 	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
 	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
@@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, np, &res);
+		err = of_pci_range_to_resource(&range, np, &res);
+		if (err < 0)
+			return err;
 
 		switch (res.flags & IORESOURCE_TYPE_BITS) {
 		case IORESOURCE_IO:
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5e07d4..61158e03ab5f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 
 	/* Setup PCIe address space mappings for each resource */
 	resource_size_t size;
+	resource_size_t res_start;
 	u32 mask;
 
 	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
 	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
 
-	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
-	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
+	if (res->flags & IORESOURCE_IO)
+		res_start = pci_pio_to_address(res->start);
+	else
+		res_start = res->start;
+
+	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
+	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
 
 	/* First resource is for IO */
 	mask = PAR_ENABLE;
@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
 
 		rcar_pcie_setup_window(i, pcie);
 
-		if (res->flags & IORESOURCE_IO)
-			pci_ioremap_io(nr * SZ_64K, res->start);
-		else
+		if (res->flags & IORESOURCE_IO) {
+			phys_addr_t io_start = pci_pio_to_address(res->start);
+			pci_ioremap_io(nr * SZ_64K, io_start);
+		} else
 			pci_add_resource(&sys->resources, res);
 	}
 	pci_add_resource(&sys->resources, &pcie->busn);
@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, pdev->dev.of_node,
+		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
 						&pcie->res[win++]);
+		if (err < 0)
+			return err;
 
 		if (win > RCAR_PCI_MAX_RESOURCES)
 			break;
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index fa20aa15463d..7ebb877b07c2 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -129,9 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
-extern void of_pci_range_to_resource(struct of_pci_range *range,
-				     struct device_node *np,
-				     struct resource *res);
+extern int of_pci_range_to_resource(struct of_pci_range *range,
+				    struct device_node *np,
+				    struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  0:22     ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  0:22 UTC (permalink / raw)
  To: linux-arm-kernel

[+cc Andrew]

On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
> The ranges property for a host bridge controller in DT describes
> the mapping between the PCI bus address and the CPU physical address.
> The resources framework however expects that the IO resources start
> at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
> The conversion from pci ranges to resources failed to take that into account,
> returning a CPU physical address instead of a port number.
> 
> Also fix all the drivers that depend on the old behaviour by fetching
> the CPU physical address based on the port number where it is being needed.
> 
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Simon Horman <horms@verge.net.au>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> ---
>  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>  include/linux/of_address.h        | 15 ++++++-------
>  5 files changed, 82 insertions(+), 31 deletions(-)
> ...

The of_pci_range_to_resource() implementation in drivers/of/address.c is
always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
CONFIG_PCI is not set, we get the static inline version from
include/linux/of_address.h as well, causing a redefinition error.

> diff --git a/drivers/of/address.c b/drivers/of/address.c
> @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
> ...
> +int of_pci_range_to_resource(struct of_pci_range *range,
> +	struct device_node *np, struct resource *res)

> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> ...
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  	return -ENOSYS;
>  }
>  
> +static inline int of_pci_range_to_resource(struct of_pci_range *range,
> +		struct device_node *np, struct resource *res)
> +{
> +	return -ENOSYS;
> +}

My proposal to fix it is the following three patches.  The first moves the
inline version of of_pci_range_to_resource() into the existing "#if
defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.

Andrew added it (and some other PCI-related things) with 29b635c00f3e
("of/pci: Provide support for parsing PCI DT ranges property") to
of_address.h outside of any ifdefs, so it's always available.  Maybe
there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
it with a quick look.

The second moves of_pci_range_to_resource() to address.c, still inside the
"#ifdef CONFIG_PCI" block.

Bjorn


commit 95a60df1c2d400c676ab1d20271735e2b4735437
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Tue Sep 23 17:27:42 2014 -0600

    of/pci: Define of_pci_range_to_resource() only when CONFIG_PCI=y
    
    of_pci_range_to_resource() was previously defined always, but it's only
    used by PCI code, so move the definition inside the CONFIG_OF_ADDRESS &&
    CONFIG_PCI block.
    
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index f8cc7daa420c..ecf913cf53b2 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -23,17 +23,6 @@ struct of_pci_range {
 #define for_each_of_pci_range(parser, range) \
 	for (; of_pci_range_parser_one(parser, range);)
 
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
 				    const __be32 *in_addr);
@@ -140,6 +129,18 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
+
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+					    struct device_node *np,
+					    struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
+
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)
@@ -155,4 +156,3 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
 #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 
 #endif /* __OF_ADDRESS_H */
-

commit 501857889201723da06aab0ec68186a5beaa9f72
Author: Liviu Dudau <Liviu.Dudau@arm.com>
Date:   Tue Sep 23 20:01:06 2014 +0100

    of/pci: Move of_pci_range_to_resources() to of/address.c
    
    We need to enhance of_pci_range_to_resources() enough that it won't make
    sense for it to be inline anymore.  Move it to drivers/of/address.c,
    keeping it under #ifdef CONFIG_PCI.
    
    [bhelgaas: drop extra detail from changelog, move def under CONFIG_PCI]
    Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    CC: Grant Likely <grant.likely@linaro.org>
    CC: Rob Herring <robh+dt@kernel.org>
    CC: Arnd Bergmann <arnd@arndb.de>
    CC: Catalin Marinas <catalin.marinas@arm.com>

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 758d4f04d4aa..327a57410797 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -295,6 +295,15 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 }
 EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
 
+void of_pci_range_to_resource(struct of_pci_range *range,
+			      struct device_node *np, struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = res->child = res->sibling = NULL;
+	res->name = np->full_name;
+}
 #endif /* CONFIG_PCI */
 
 /*
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index ecf913cf53b2..fa20aa15463d 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -129,18 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
-
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
-					    struct device_node *np,
-					    struct resource *res)
-{
-	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
-	res->parent = res->child = res->sibling = NULL;
-	res->name = np->full_name;
-}
-
+extern void of_pci_range_to_resource(struct of_pci_range *range,
+				     struct device_node *np,
+				     struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)

commit e01c1ebeee0bc45d6ac5f52b22c57d278799869b
Author: Liviu Dudau <Liviu.Dudau@arm.com>
Date:   Tue Sep 23 20:01:07 2014 +0100

    of/pci: Fix the conversion of IO ranges into IO resources
    
    The ranges property for a host bridge controller in DT describes the
    mapping between the PCI bus address and the CPU physical address.  The
    resources framework however expects that the IO resources start at a pseudo
    "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.  The
    conversion from PCI ranges to resources failed to take that into account,
    returning a CPU physical address instead of a port number.
    
    Also fix all the drivers that depend on the old behaviour by fetching the
    CPU physical address based on the port number where it is being needed.
    
    Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Acked-by: Linus Walleij <linus.walleij@linaro.org>
    CC: Grant Likely <grant.likely@linaro.org>
    CC: Rob Herring <robh+dt@kernel.org>
    CC: Arnd Bergmann <arnd@arndb.de>
    CC: Thierry Reding <thierry.reding@gmail.com>
    CC: Simon Horman <horms@verge.net.au>
    CC: Catalin Marinas <catalin.marinas@arm.com>

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 05e1f73a1e8d..c186a17c2cff 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
 {
 	unsigned long flags;
 	unsigned int temp;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pcibios_min_mem = 0x00100000;
 
@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
 	/*
 	 * Setup window 2 - PCI IO
 	 */
-	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
 			V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
 
@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
 static void __init pci_v3_postinit(void)
 {
 	unsigned int pci_cmd;
+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
 
 	pci_cmd = PCI_COMMAND_MEMORY |
 		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
 		       "interrupt: %d\n", ret);
 #endif
 
-	register_isa_ports(non_mem.start, io_mem.start, 0);
+	register_isa_ports(non_mem.start, io_address, 0);
 }
 
 /*
@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
 
 	for_each_of_pci_range(&parser, &range) {
 		if (!range.flags) {
-			of_pci_range_to_resource(&range, np, &conf_mem);
+			ret = of_pci_range_to_resource(&range, np, &conf_mem);
 			conf_mem.name = "PCIv3 config";
 		}
 		if (range.flags & IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &io_mem);
+			ret = of_pci_range_to_resource(&range, np, &io_mem);
 			io_mem.name = "PCIv3 I/O";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			!(range.flags & IORESOURCE_PREFETCH)) {
 			non_mem_pci = range.pci_addr;
 			non_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &non_mem);
+			ret = of_pci_range_to_resource(&range, np, &non_mem);
 			non_mem.name = "PCIv3 non-prefetched mem";
 		}
 		if ((range.flags & IORESOURCE_MEM) &&
 			(range.flags & IORESOURCE_PREFETCH)) {
 			pre_mem_pci = range.pci_addr;
 			pre_mem_pci_sz = range.size;
-			of_pci_range_to_resource(&range, np, &pre_mem);
+			ret = of_pci_range_to_resource(&range, np, &pre_mem);
 			pre_mem.name = "PCIv3 prefetched mem";
 		}
-	}
 
-	if (!conf_mem.start || !io_mem.start ||
-	    !non_mem.start || !pre_mem.start) {
-		dev_err(&pdev->dev, "missing ranges in device node\n");
-		return -EINVAL;
+		if (ret < 0) {
+			dev_err(&pdev->dev, "missing ranges in device node\n");
+			return ret;
+		}
 	}
 
 	pci_v3.map_irq = of_irq_parse_and_map_pci;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 327a57410797..afdb78299f61 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -295,14 +295,50 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 }
 EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
 
-void of_pci_range_to_resource(struct of_pci_range *range,
-			      struct device_node *np, struct resource *res)
+/*
+ * of_pci_range_to_resource - Create a resource from an of_pci_range
+ * @range:	the PCI range that describes the resource
+ * @np:		device node where the range belongs to
+ * @res:	pointer to a valid resource that will be updated to
+ *              reflect the values contained in the range.
+ *
+ * Returns EINVAL if the range cannot be converted to resource.
+ *
+ * Note that if the range is an IO range, the resource will be converted
+ * using pci_address_to_pio() which can fail if it is called too early or
+ * if the range cannot be matched to any host bridge IO space (our case here).
+ * To guard against that we try to register the IO range first.
+ * If that fails we know that pci_address_to_pio() will do too.
+ */
+int of_pci_range_to_resource(struct of_pci_range *range,
+			     struct device_node *np, struct resource *res)
 {
+	int err;
 	res->flags = range->flags;
-	res->start = range->cpu_addr;
-	res->end = range->cpu_addr + range->size - 1;
 	res->parent = res->child = res->sibling = NULL;
 	res->name = np->full_name;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long port;
+		err = pci_register_io_range(range->cpu_addr, range->size);
+		if (err)
+			goto invalid_range;
+		port = pci_address_to_pio(range->cpu_addr);
+		if (port == (unsigned long)-1) {
+			err = -EINVAL;
+			goto invalid_range;
+		}
+		res->start = port;
+	} else {
+		res->start = range->cpu_addr;
+	}
+	res->end = res->start + range->size - 1;
+	return 0;
+
+invalid_range:
+	res->start = (resource_size_t)OF_BAD_ADDR;
+	res->end = (resource_size_t)OF_BAD_ADDR;
+	return err;
 }
 #endif /* CONFIG_PCI */
 
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb223d5..946935db62b6 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
 static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 {
 	struct tegra_pcie *pcie = sys_to_pcie(sys);
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
 				sys->mem_offset);
 	pci_add_resource(&sys->resources, &pcie->busn);
 
-	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
+	pci_ioremap_io(nr * SZ_64K, io_start);
 
 	return 1;
 }
@@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 {
 	u32 fpci_bar, size, axi_address;
+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
 
 	/* Bar 0: type 1 extended configuration space */
 	fpci_bar = 0xfe100000;
@@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 	/* Bar 1: downstream IO bar */
 	fpci_bar = 0xfdfc0000;
 	size = resource_size(&pcie->io);
-	axi_address = pcie->io.start;
+	axi_address = io_start;
 	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
 	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
 	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
@@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, np, &res);
+		err = of_pci_range_to_resource(&range, np, &res);
+		if (err < 0)
+			return err;
 
 		switch (res.flags & IORESOURCE_TYPE_BITS) {
 		case IORESOURCE_IO:
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5e07d4..61158e03ab5f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 
 	/* Setup PCIe address space mappings for each resource */
 	resource_size_t size;
+	resource_size_t res_start;
 	u32 mask;
 
 	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
 	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
 	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
 
-	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
-	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
+	if (res->flags & IORESOURCE_IO)
+		res_start = pci_pio_to_address(res->start);
+	else
+		res_start = res->start;
+
+	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
+	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
 
 	/* First resource is for IO */
 	mask = PAR_ENABLE;
@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
 
 		rcar_pcie_setup_window(i, pcie);
 
-		if (res->flags & IORESOURCE_IO)
-			pci_ioremap_io(nr * SZ_64K, res->start);
-		else
+		if (res->flags & IORESOURCE_IO) {
+			phys_addr_t io_start = pci_pio_to_address(res->start);
+			pci_ioremap_io(nr * SZ_64K, io_start);
+		} else
 			pci_add_resource(&sys->resources, res);
 	}
 	pci_add_resource(&sys->resources, &pcie->busn);
@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 	}
 
 	for_each_of_pci_range(&parser, &range) {
-		of_pci_range_to_resource(&range, pdev->dev.of_node,
+		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
 						&pcie->res[win++]);
+		if (err < 0)
+			return err;
 
 		if (win > RCAR_PCI_MAX_RESOURCES)
 			break;
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index fa20aa15463d..7ebb877b07c2 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -129,9 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
-extern void of_pci_range_to_resource(struct of_pci_range *range,
-				     struct device_node *np,
-				     struct resource *res);
+extern int of_pci_range_to_resource(struct of_pci_range *range,
+				    struct device_node *np,
+				    struct resource *res);
 #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
  2014-09-24  0:22     ` Bjorn Helgaas
  (?)
@ 2014-09-24  1:12       ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:12 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding, Simon Horman, Andrew Murray

On Tue, Sep 23, 2014 at 06:22:53PM -0600, Bjorn Helgaas wrote:
> [+cc Andrew]
> 
> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
> > The ranges property for a host bridge controller in DT describes
> > the mapping between the PCI bus address and the CPU physical address.
> > The resources framework however expects that the IO resources start
> > at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
> > The conversion from pci ranges to resources failed to take that into account,
> > returning a CPU physical address instead of a port number.
> > 
> > Also fix all the drivers that depend on the old behaviour by fetching
> > the CPU physical address based on the port number where it is being needed.
> > 
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
> > Cc: Thierry Reding <thierry.reding@gmail.com>
> > Cc: Simon Horman <horms@verge.net.au>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > ---
> >  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
> >  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
> >  drivers/pci/host/pci-tegra.c      | 10 ++++++---
> >  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
> >  include/linux/of_address.h        | 15 ++++++-------
> >  5 files changed, 82 insertions(+), 31 deletions(-)
> > ...
> 
> The of_pci_range_to_resource() implementation in drivers/of/address.c is
> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
> CONFIG_PCI is not set, we get the static inline version from
> include/linux/of_address.h as well, causing a redefinition error.
> 
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
> > ...
> > +int of_pci_range_to_resource(struct of_pci_range *range,
> > +	struct device_node *np, struct resource *res)
> 
> > diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> > ...
> >  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
> >  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
> >  				             struct resource *r)
> > @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
> >  	return -ENOSYS;
> >  }
> >  
> > +static inline int of_pci_range_to_resource(struct of_pci_range *range,
> > +		struct device_node *np, struct resource *res)
> > +{
> > +	return -ENOSYS;
> > +}
> 
> My proposal to fix it is the following three patches.  The first moves the
> inline version of of_pci_range_to_resource() into the existing "#if
> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
> 
> Andrew added it (and some other PCI-related things) with 29b635c00f3e
> ("of/pci: Provide support for parsing PCI DT ranges property") to
> of_address.h outside of any ifdefs, so it's always available.  Maybe
> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
> it with a quick look.
> 
> The second moves of_pci_range_to_resource() to address.c, still inside the
> "#ifdef CONFIG_PCI" block.

Hi Bjorn,

Looks good to me. Sorry for messing this up, I've tested a combination of
CONFIG_PCI=y and CONFIG_PCI=n but it looks like I've only tested
CONFIG_OF_ADDRESS=CONFIG_PCI (both enabled or both disabled).

Best regards,
Liviu

> 
> Bjorn
> 
> 
> commit 95a60df1c2d400c676ab1d20271735e2b4735437
> Author: Bjorn Helgaas <bhelgaas@google.com>
> Date:   Tue Sep 23 17:27:42 2014 -0600
> 
>     of/pci: Define of_pci_range_to_resource() only when CONFIG_PCI=y
>     
>     of_pci_range_to_resource() was previously defined always, but it's only
>     used by PCI code, so move the definition inside the CONFIG_OF_ADDRESS &&
>     CONFIG_PCI block.
>     
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> 
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index f8cc7daa420c..ecf913cf53b2 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -23,17 +23,6 @@ struct of_pci_range {
>  #define for_each_of_pci_range(parser, range) \
>  	for (; of_pci_range_parser_one(parser, range);)
>  
> -static inline void of_pci_range_to_resource(struct of_pci_range *range,
> -					    struct device_node *np,
> -					    struct resource *res)
> -{
> -	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
> -	res->parent = res->child = res->sibling = NULL;
> -	res->name = np->full_name;
> -}
> -
>  /* Translate a DMA address from device space to CPU space */
>  extern u64 of_translate_dma_address(struct device_node *dev,
>  				    const __be32 *in_addr);
> @@ -140,6 +129,18 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> +
> +static inline void of_pci_range_to_resource(struct of_pci_range *range,
> +					    struct device_node *np,
> +					    struct resource *res)
> +{
> +	res->flags = range->flags;
> +	res->start = range->cpu_addr;
> +	res->end = range->cpu_addr + range->size - 1;
> +	res->parent = res->child = res->sibling = NULL;
> +	res->name = np->full_name;
> +}
> +
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> @@ -155,4 +156,3 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
>  #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  
>  #endif /* __OF_ADDRESS_H */
> -
> 
> commit 501857889201723da06aab0ec68186a5beaa9f72
> Author: Liviu Dudau <Liviu.Dudau@arm.com>
> Date:   Tue Sep 23 20:01:06 2014 +0100
> 
>     of/pci: Move of_pci_range_to_resources() to of/address.c
>     
>     We need to enhance of_pci_range_to_resources() enough that it won't make
>     sense for it to be inline anymore.  Move it to drivers/of/address.c,
>     keeping it under #ifdef CONFIG_PCI.
>     
>     [bhelgaas: drop extra detail from changelog, move def under CONFIG_PCI]
>     Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>     CC: Grant Likely <grant.likely@linaro.org>
>     CC: Rob Herring <robh+dt@kernel.org>
>     CC: Arnd Bergmann <arnd@arndb.de>
>     CC: Catalin Marinas <catalin.marinas@arm.com>
> 
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 758d4f04d4aa..327a57410797 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -295,6 +295,15 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
>  }
>  EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
>  
> +void of_pci_range_to_resource(struct of_pci_range *range,
> +			      struct device_node *np, struct resource *res)
> +{
> +	res->flags = range->flags;
> +	res->start = range->cpu_addr;
> +	res->end = range->cpu_addr + range->size - 1;
> +	res->parent = res->child = res->sibling = NULL;
> +	res->name = np->full_name;
> +}
>  #endif /* CONFIG_PCI */
>  
>  /*
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index ecf913cf53b2..fa20aa15463d 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -129,18 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> -
> -static inline void of_pci_range_to_resource(struct of_pci_range *range,
> -					    struct device_node *np,
> -					    struct resource *res)
> -{
> -	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
> -	res->parent = res->child = res->sibling = NULL;
> -	res->name = np->full_name;
> -}
> -
> +extern void of_pci_range_to_resource(struct of_pci_range *range,
> +				     struct device_node *np,
> +				     struct resource *res);
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> 
> commit e01c1ebeee0bc45d6ac5f52b22c57d278799869b
> Author: Liviu Dudau <Liviu.Dudau@arm.com>
> Date:   Tue Sep 23 20:01:07 2014 +0100
> 
>     of/pci: Fix the conversion of IO ranges into IO resources
>     
>     The ranges property for a host bridge controller in DT describes the
>     mapping between the PCI bus address and the CPU physical address.  The
>     resources framework however expects that the IO resources start at a pseudo
>     "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.  The
>     conversion from PCI ranges to resources failed to take that into account,
>     returning a CPU physical address instead of a port number.
>     
>     Also fix all the drivers that depend on the old behaviour by fetching the
>     CPU physical address based on the port number where it is being needed.
>     
>     Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>     Acked-by: Linus Walleij <linus.walleij@linaro.org>
>     CC: Grant Likely <grant.likely@linaro.org>
>     CC: Rob Herring <robh+dt@kernel.org>
>     CC: Arnd Bergmann <arnd@arndb.de>
>     CC: Thierry Reding <thierry.reding@gmail.com>
>     CC: Simon Horman <horms@verge.net.au>
>     CC: Catalin Marinas <catalin.marinas@arm.com>
> 
> diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
> index 05e1f73a1e8d..c186a17c2cff 100644
> --- a/arch/arm/mach-integrator/pci_v3.c
> +++ b/arch/arm/mach-integrator/pci_v3.c
> @@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
>  {
>  	unsigned long flags;
>  	unsigned int temp;
> +	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
>  
>  	pcibios_min_mem = 0x00100000;
>  
> @@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
>  	/*
>  	 * Setup window 2 - PCI IO
>  	 */
> -	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
> +	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
>  			V3_LB_BASE_ENABLE);
>  	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
>  
> @@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
>  static void __init pci_v3_postinit(void)
>  {
>  	unsigned int pci_cmd;
> +	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
>  
>  	pci_cmd = PCI_COMMAND_MEMORY |
>  		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
> @@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
>  		       "interrupt: %d\n", ret);
>  #endif
>  
> -	register_isa_ports(non_mem.start, io_mem.start, 0);
> +	register_isa_ports(non_mem.start, io_address, 0);
>  }
>  
>  /*
> @@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
>  
>  	for_each_of_pci_range(&parser, &range) {
>  		if (!range.flags) {
> -			of_pci_range_to_resource(&range, np, &conf_mem);
> +			ret = of_pci_range_to_resource(&range, np, &conf_mem);
>  			conf_mem.name = "PCIv3 config";
>  		}
>  		if (range.flags & IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &io_mem);
> +			ret = of_pci_range_to_resource(&range, np, &io_mem);
>  			io_mem.name = "PCIv3 I/O";
>  		}
>  		if ((range.flags & IORESOURCE_MEM) &&
>  			!(range.flags & IORESOURCE_PREFETCH)) {
>  			non_mem_pci = range.pci_addr;
>  			non_mem_pci_sz = range.size;
> -			of_pci_range_to_resource(&range, np, &non_mem);
> +			ret = of_pci_range_to_resource(&range, np, &non_mem);
>  			non_mem.name = "PCIv3 non-prefetched mem";
>  		}
>  		if ((range.flags & IORESOURCE_MEM) &&
>  			(range.flags & IORESOURCE_PREFETCH)) {
>  			pre_mem_pci = range.pci_addr;
>  			pre_mem_pci_sz = range.size;
> -			of_pci_range_to_resource(&range, np, &pre_mem);
> +			ret = of_pci_range_to_resource(&range, np, &pre_mem);
>  			pre_mem.name = "PCIv3 prefetched mem";
>  		}
> -	}
>  
> -	if (!conf_mem.start || !io_mem.start ||
> -	    !non_mem.start || !pre_mem.start) {
> -		dev_err(&pdev->dev, "missing ranges in device node\n");
> -		return -EINVAL;
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "missing ranges in device node\n");
> +			return ret;
> +		}
>  	}
>  
>  	pci_v3.map_irq = of_irq_parse_and_map_pci;
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 327a57410797..afdb78299f61 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -295,14 +295,50 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
>  }
>  EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
>  
> -void of_pci_range_to_resource(struct of_pci_range *range,
> -			      struct device_node *np, struct resource *res)
> +/*
> + * of_pci_range_to_resource - Create a resource from an of_pci_range
> + * @range:	the PCI range that describes the resource
> + * @np:		device node where the range belongs to
> + * @res:	pointer to a valid resource that will be updated to
> + *              reflect the values contained in the range.
> + *
> + * Returns EINVAL if the range cannot be converted to resource.
> + *
> + * Note that if the range is an IO range, the resource will be converted
> + * using pci_address_to_pio() which can fail if it is called too early or
> + * if the range cannot be matched to any host bridge IO space (our case here).
> + * To guard against that we try to register the IO range first.
> + * If that fails we know that pci_address_to_pio() will do too.
> + */
> +int of_pci_range_to_resource(struct of_pci_range *range,
> +			     struct device_node *np, struct resource *res)
>  {
> +	int err;
>  	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
>  	res->parent = res->child = res->sibling = NULL;
>  	res->name = np->full_name;
> +
> +	if (res->flags & IORESOURCE_IO) {
> +		unsigned long port;
> +		err = pci_register_io_range(range->cpu_addr, range->size);
> +		if (err)
> +			goto invalid_range;
> +		port = pci_address_to_pio(range->cpu_addr);
> +		if (port == (unsigned long)-1) {
> +			err = -EINVAL;
> +			goto invalid_range;
> +		}
> +		res->start = port;
> +	} else {
> +		res->start = range->cpu_addr;
> +	}
> +	res->end = res->start + range->size - 1;
> +	return 0;
> +
> +invalid_range:
> +	res->start = (resource_size_t)OF_BAD_ADDR;
> +	res->end = (resource_size_t)OF_BAD_ADDR;
> +	return err;
>  }
>  #endif /* CONFIG_PCI */
>  
> diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
> index 0fb0fdb223d5..946935db62b6 100644
> --- a/drivers/pci/host/pci-tegra.c
> +++ b/drivers/pci/host/pci-tegra.c
> @@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
>  static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
>  {
>  	struct tegra_pcie *pcie = sys_to_pcie(sys);
> +	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
>  
>  	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
>  	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
>  				sys->mem_offset);
>  	pci_add_resource(&sys->resources, &pcie->busn);
>  
> -	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
> +	pci_ioremap_io(nr * SZ_64K, io_start);
>  
>  	return 1;
>  }
> @@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
>  	u32 fpci_bar, size, axi_address;
> +	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
>  
>  	/* Bar 0: type 1 extended configuration space */
>  	fpci_bar = 0xfe100000;
> @@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  	/* Bar 1: downstream IO bar */
>  	fpci_bar = 0xfdfc0000;
>  	size = resource_size(&pcie->io);
> -	axi_address = pcie->io.start;
> +	axi_address = io_start;
>  	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>  	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>  	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> @@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  	}
>  
>  	for_each_of_pci_range(&parser, &range) {
> -		of_pci_range_to_resource(&range, np, &res);
> +		err = of_pci_range_to_resource(&range, np, &res);
> +		if (err < 0)
> +			return err;
>  
>  		switch (res.flags & IORESOURCE_TYPE_BITS) {
>  		case IORESOURCE_IO:
> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
> index 4884ee5e07d4..61158e03ab5f 100644
> --- a/drivers/pci/host/pcie-rcar.c
> +++ b/drivers/pci/host/pcie-rcar.c
> @@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
>  
>  	/* Setup PCIe address space mappings for each resource */
>  	resource_size_t size;
> +	resource_size_t res_start;
>  	u32 mask;
>  
>  	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
> @@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
>  	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
>  	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
>  
> -	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
> -	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
> +	if (res->flags & IORESOURCE_IO)
> +		res_start = pci_pio_to_address(res->start);
> +	else
> +		res_start = res->start;
> +
> +	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
> +	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
>  
>  	/* First resource is for IO */
>  	mask = PAR_ENABLE;
> @@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
>  
>  		rcar_pcie_setup_window(i, pcie);
>  
> -		if (res->flags & IORESOURCE_IO)
> -			pci_ioremap_io(nr * SZ_64K, res->start);
> -		else
> +		if (res->flags & IORESOURCE_IO) {
> +			phys_addr_t io_start = pci_pio_to_address(res->start);
> +			pci_ioremap_io(nr * SZ_64K, io_start);
> +		} else
>  			pci_add_resource(&sys->resources, res);
>  	}
>  	pci_add_resource(&sys->resources, &pcie->busn);
> @@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
>  	}
>  
>  	for_each_of_pci_range(&parser, &range) {
> -		of_pci_range_to_resource(&range, pdev->dev.of_node,
> +		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
>  						&pcie->res[win++]);
> +		if (err < 0)
> +			return err;
>  
>  		if (win > RCAR_PCI_MAX_RESOURCES)
>  			break;
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index fa20aa15463d..7ebb877b07c2 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -129,9 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> -extern void of_pci_range_to_resource(struct of_pci_range *range,
> -				     struct device_node *np,
> -				     struct resource *res);
> +extern int of_pci_range_to_resource(struct of_pci_range *range,
> +				    struct device_node *np,
> +				    struct resource *res);
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  1:12       ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:12 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding

On Tue, Sep 23, 2014 at 06:22:53PM -0600, Bjorn Helgaas wrote:
> [+cc Andrew]
> 
> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
> > The ranges property for a host bridge controller in DT describes
> > the mapping between the PCI bus address and the CPU physical address.
> > The resources framework however expects that the IO resources start
> > at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
> > The conversion from pci ranges to resources failed to take that into account,
> > returning a CPU physical address instead of a port number.
> > 
> > Also fix all the drivers that depend on the old behaviour by fetching
> > the CPU physical address based on the port number where it is being needed.
> > 
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
> > Cc: Thierry Reding <thierry.reding@gmail.com>
> > Cc: Simon Horman <horms@verge.net.au>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > ---
> >  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
> >  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
> >  drivers/pci/host/pci-tegra.c      | 10 ++++++---
> >  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
> >  include/linux/of_address.h        | 15 ++++++-------
> >  5 files changed, 82 insertions(+), 31 deletions(-)
> > ...
> 
> The of_pci_range_to_resource() implementation in drivers/of/address.c is
> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
> CONFIG_PCI is not set, we get the static inline version from
> include/linux/of_address.h as well, causing a redefinition error.
> 
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
> > ...
> > +int of_pci_range_to_resource(struct of_pci_range *range,
> > +	struct device_node *np, struct resource *res)
> 
> > diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> > ...
> >  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
> >  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
> >  				             struct resource *r)
> > @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
> >  	return -ENOSYS;
> >  }
> >  
> > +static inline int of_pci_range_to_resource(struct of_pci_range *range,
> > +		struct device_node *np, struct resource *res)
> > +{
> > +	return -ENOSYS;
> > +}
> 
> My proposal to fix it is the following three patches.  The first moves the
> inline version of of_pci_range_to_resource() into the existing "#if
> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
> 
> Andrew added it (and some other PCI-related things) with 29b635c00f3e
> ("of/pci: Provide support for parsing PCI DT ranges property") to
> of_address.h outside of any ifdefs, so it's always available.  Maybe
> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
> it with a quick look.
> 
> The second moves of_pci_range_to_resource() to address.c, still inside the
> "#ifdef CONFIG_PCI" block.

Hi Bjorn,

Looks good to me. Sorry for messing this up, I've tested a combination of
CONFIG_PCI=y and CONFIG_PCI=n but it looks like I've only tested
CONFIG_OF_ADDRESS=CONFIG_PCI (both enabled or both disabled).

Best regards,
Liviu

> 
> Bjorn
> 
> 
> commit 95a60df1c2d400c676ab1d20271735e2b4735437
> Author: Bjorn Helgaas <bhelgaas@google.com>
> Date:   Tue Sep 23 17:27:42 2014 -0600
> 
>     of/pci: Define of_pci_range_to_resource() only when CONFIG_PCI=y
>     
>     of_pci_range_to_resource() was previously defined always, but it's only
>     used by PCI code, so move the definition inside the CONFIG_OF_ADDRESS &&
>     CONFIG_PCI block.
>     
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> 
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index f8cc7daa420c..ecf913cf53b2 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -23,17 +23,6 @@ struct of_pci_range {
>  #define for_each_of_pci_range(parser, range) \
>  	for (; of_pci_range_parser_one(parser, range);)
>  
> -static inline void of_pci_range_to_resource(struct of_pci_range *range,
> -					    struct device_node *np,
> -					    struct resource *res)
> -{
> -	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
> -	res->parent = res->child = res->sibling = NULL;
> -	res->name = np->full_name;
> -}
> -
>  /* Translate a DMA address from device space to CPU space */
>  extern u64 of_translate_dma_address(struct device_node *dev,
>  				    const __be32 *in_addr);
> @@ -140,6 +129,18 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> +
> +static inline void of_pci_range_to_resource(struct of_pci_range *range,
> +					    struct device_node *np,
> +					    struct resource *res)
> +{
> +	res->flags = range->flags;
> +	res->start = range->cpu_addr;
> +	res->end = range->cpu_addr + range->size - 1;
> +	res->parent = res->child = res->sibling = NULL;
> +	res->name = np->full_name;
> +}
> +
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> @@ -155,4 +156,3 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
>  #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  
>  #endif /* __OF_ADDRESS_H */
> -
> 
> commit 501857889201723da06aab0ec68186a5beaa9f72
> Author: Liviu Dudau <Liviu.Dudau@arm.com>
> Date:   Tue Sep 23 20:01:06 2014 +0100
> 
>     of/pci: Move of_pci_range_to_resources() to of/address.c
>     
>     We need to enhance of_pci_range_to_resources() enough that it won't make
>     sense for it to be inline anymore.  Move it to drivers/of/address.c,
>     keeping it under #ifdef CONFIG_PCI.
>     
>     [bhelgaas: drop extra detail from changelog, move def under CONFIG_PCI]
>     Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>     CC: Grant Likely <grant.likely@linaro.org>
>     CC: Rob Herring <robh+dt@kernel.org>
>     CC: Arnd Bergmann <arnd@arndb.de>
>     CC: Catalin Marinas <catalin.marinas@arm.com>
> 
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 758d4f04d4aa..327a57410797 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -295,6 +295,15 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
>  }
>  EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
>  
> +void of_pci_range_to_resource(struct of_pci_range *range,
> +			      struct device_node *np, struct resource *res)
> +{
> +	res->flags = range->flags;
> +	res->start = range->cpu_addr;
> +	res->end = range->cpu_addr + range->size - 1;
> +	res->parent = res->child = res->sibling = NULL;
> +	res->name = np->full_name;
> +}
>  #endif /* CONFIG_PCI */
>  
>  /*
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index ecf913cf53b2..fa20aa15463d 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -129,18 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> -
> -static inline void of_pci_range_to_resource(struct of_pci_range *range,
> -					    struct device_node *np,
> -					    struct resource *res)
> -{
> -	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
> -	res->parent = res->child = res->sibling = NULL;
> -	res->name = np->full_name;
> -}
> -
> +extern void of_pci_range_to_resource(struct of_pci_range *range,
> +				     struct device_node *np,
> +				     struct resource *res);
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> 
> commit e01c1ebeee0bc45d6ac5f52b22c57d278799869b
> Author: Liviu Dudau <Liviu.Dudau@arm.com>
> Date:   Tue Sep 23 20:01:07 2014 +0100
> 
>     of/pci: Fix the conversion of IO ranges into IO resources
>     
>     The ranges property for a host bridge controller in DT describes the
>     mapping between the PCI bus address and the CPU physical address.  The
>     resources framework however expects that the IO resources start at a pseudo
>     "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.  The
>     conversion from PCI ranges to resources failed to take that into account,
>     returning a CPU physical address instead of a port number.
>     
>     Also fix all the drivers that depend on the old behaviour by fetching the
>     CPU physical address based on the port number where it is being needed.
>     
>     Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>     Acked-by: Linus Walleij <linus.walleij@linaro.org>
>     CC: Grant Likely <grant.likely@linaro.org>
>     CC: Rob Herring <robh+dt@kernel.org>
>     CC: Arnd Bergmann <arnd@arndb.de>
>     CC: Thierry Reding <thierry.reding@gmail.com>
>     CC: Simon Horman <horms@verge.net.au>
>     CC: Catalin Marinas <catalin.marinas@arm.com>
> 
> diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
> index 05e1f73a1e8d..c186a17c2cff 100644
> --- a/arch/arm/mach-integrator/pci_v3.c
> +++ b/arch/arm/mach-integrator/pci_v3.c
> @@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
>  {
>  	unsigned long flags;
>  	unsigned int temp;
> +	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
>  
>  	pcibios_min_mem = 0x00100000;
>  
> @@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
>  	/*
>  	 * Setup window 2 - PCI IO
>  	 */
> -	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
> +	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
>  			V3_LB_BASE_ENABLE);
>  	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
>  
> @@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
>  static void __init pci_v3_postinit(void)
>  {
>  	unsigned int pci_cmd;
> +	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
>  
>  	pci_cmd = PCI_COMMAND_MEMORY |
>  		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
> @@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
>  		       "interrupt: %d\n", ret);
>  #endif
>  
> -	register_isa_ports(non_mem.start, io_mem.start, 0);
> +	register_isa_ports(non_mem.start, io_address, 0);
>  }
>  
>  /*
> @@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
>  
>  	for_each_of_pci_range(&parser, &range) {
>  		if (!range.flags) {
> -			of_pci_range_to_resource(&range, np, &conf_mem);
> +			ret = of_pci_range_to_resource(&range, np, &conf_mem);
>  			conf_mem.name = "PCIv3 config";
>  		}
>  		if (range.flags & IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &io_mem);
> +			ret = of_pci_range_to_resource(&range, np, &io_mem);
>  			io_mem.name = "PCIv3 I/O";
>  		}
>  		if ((range.flags & IORESOURCE_MEM) &&
>  			!(range.flags & IORESOURCE_PREFETCH)) {
>  			non_mem_pci = range.pci_addr;
>  			non_mem_pci_sz = range.size;
> -			of_pci_range_to_resource(&range, np, &non_mem);
> +			ret = of_pci_range_to_resource(&range, np, &non_mem);
>  			non_mem.name = "PCIv3 non-prefetched mem";
>  		}
>  		if ((range.flags & IORESOURCE_MEM) &&
>  			(range.flags & IORESOURCE_PREFETCH)) {
>  			pre_mem_pci = range.pci_addr;
>  			pre_mem_pci_sz = range.size;
> -			of_pci_range_to_resource(&range, np, &pre_mem);
> +			ret = of_pci_range_to_resource(&range, np, &pre_mem);
>  			pre_mem.name = "PCIv3 prefetched mem";
>  		}
> -	}
>  
> -	if (!conf_mem.start || !io_mem.start ||
> -	    !non_mem.start || !pre_mem.start) {
> -		dev_err(&pdev->dev, "missing ranges in device node\n");
> -		return -EINVAL;
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "missing ranges in device node\n");
> +			return ret;
> +		}
>  	}
>  
>  	pci_v3.map_irq = of_irq_parse_and_map_pci;
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 327a57410797..afdb78299f61 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -295,14 +295,50 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
>  }
>  EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
>  
> -void of_pci_range_to_resource(struct of_pci_range *range,
> -			      struct device_node *np, struct resource *res)
> +/*
> + * of_pci_range_to_resource - Create a resource from an of_pci_range
> + * @range:	the PCI range that describes the resource
> + * @np:		device node where the range belongs to
> + * @res:	pointer to a valid resource that will be updated to
> + *              reflect the values contained in the range.
> + *
> + * Returns EINVAL if the range cannot be converted to resource.
> + *
> + * Note that if the range is an IO range, the resource will be converted
> + * using pci_address_to_pio() which can fail if it is called too early or
> + * if the range cannot be matched to any host bridge IO space (our case here).
> + * To guard against that we try to register the IO range first.
> + * If that fails we know that pci_address_to_pio() will do too.
> + */
> +int of_pci_range_to_resource(struct of_pci_range *range,
> +			     struct device_node *np, struct resource *res)
>  {
> +	int err;
>  	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
>  	res->parent = res->child = res->sibling = NULL;
>  	res->name = np->full_name;
> +
> +	if (res->flags & IORESOURCE_IO) {
> +		unsigned long port;
> +		err = pci_register_io_range(range->cpu_addr, range->size);
> +		if (err)
> +			goto invalid_range;
> +		port = pci_address_to_pio(range->cpu_addr);
> +		if (port == (unsigned long)-1) {
> +			err = -EINVAL;
> +			goto invalid_range;
> +		}
> +		res->start = port;
> +	} else {
> +		res->start = range->cpu_addr;
> +	}
> +	res->end = res->start + range->size - 1;
> +	return 0;
> +
> +invalid_range:
> +	res->start = (resource_size_t)OF_BAD_ADDR;
> +	res->end = (resource_size_t)OF_BAD_ADDR;
> +	return err;
>  }
>  #endif /* CONFIG_PCI */
>  
> diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
> index 0fb0fdb223d5..946935db62b6 100644
> --- a/drivers/pci/host/pci-tegra.c
> +++ b/drivers/pci/host/pci-tegra.c
> @@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
>  static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
>  {
>  	struct tegra_pcie *pcie = sys_to_pcie(sys);
> +	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
>  
>  	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
>  	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
>  				sys->mem_offset);
>  	pci_add_resource(&sys->resources, &pcie->busn);
>  
> -	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
> +	pci_ioremap_io(nr * SZ_64K, io_start);
>  
>  	return 1;
>  }
> @@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
>  	u32 fpci_bar, size, axi_address;
> +	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
>  
>  	/* Bar 0: type 1 extended configuration space */
>  	fpci_bar = 0xfe100000;
> @@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  	/* Bar 1: downstream IO bar */
>  	fpci_bar = 0xfdfc0000;
>  	size = resource_size(&pcie->io);
> -	axi_address = pcie->io.start;
> +	axi_address = io_start;
>  	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>  	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>  	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> @@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  	}
>  
>  	for_each_of_pci_range(&parser, &range) {
> -		of_pci_range_to_resource(&range, np, &res);
> +		err = of_pci_range_to_resource(&range, np, &res);
> +		if (err < 0)
> +			return err;
>  
>  		switch (res.flags & IORESOURCE_TYPE_BITS) {
>  		case IORESOURCE_IO:
> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
> index 4884ee5e07d4..61158e03ab5f 100644
> --- a/drivers/pci/host/pcie-rcar.c
> +++ b/drivers/pci/host/pcie-rcar.c
> @@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
>  
>  	/* Setup PCIe address space mappings for each resource */
>  	resource_size_t size;
> +	resource_size_t res_start;
>  	u32 mask;
>  
>  	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
> @@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
>  	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
>  	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
>  
> -	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
> -	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
> +	if (res->flags & IORESOURCE_IO)
> +		res_start = pci_pio_to_address(res->start);
> +	else
> +		res_start = res->start;
> +
> +	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
> +	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
>  
>  	/* First resource is for IO */
>  	mask = PAR_ENABLE;
> @@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
>  
>  		rcar_pcie_setup_window(i, pcie);
>  
> -		if (res->flags & IORESOURCE_IO)
> -			pci_ioremap_io(nr * SZ_64K, res->start);
> -		else
> +		if (res->flags & IORESOURCE_IO) {
> +			phys_addr_t io_start = pci_pio_to_address(res->start);
> +			pci_ioremap_io(nr * SZ_64K, io_start);
> +		} else
>  			pci_add_resource(&sys->resources, res);
>  	}
>  	pci_add_resource(&sys->resources, &pcie->busn);
> @@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
>  	}
>  
>  	for_each_of_pci_range(&parser, &range) {
> -		of_pci_range_to_resource(&range, pdev->dev.of_node,
> +		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
>  						&pcie->res[win++]);
> +		if (err < 0)
> +			return err;
>  
>  		if (win > RCAR_PCI_MAX_RESOURCES)
>  			break;
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index fa20aa15463d..7ebb877b07c2 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -129,9 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> -extern void of_pci_range_to_resource(struct of_pci_range *range,
> -				     struct device_node *np,
> -				     struct resource *res);
> +extern int of_pci_range_to_resource(struct of_pci_range *range,
> +				    struct device_node *np,
> +				    struct resource *res);
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  1:12       ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 06:22:53PM -0600, Bjorn Helgaas wrote:
> [+cc Andrew]
> 
> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
> > The ranges property for a host bridge controller in DT describes
> > the mapping between the PCI bus address and the CPU physical address.
> > The resources framework however expects that the IO resources start
> > at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
> > The conversion from pci ranges to resources failed to take that into account,
> > returning a CPU physical address instead of a port number.
> > 
> > Also fix all the drivers that depend on the old behaviour by fetching
> > the CPU physical address based on the port number where it is being needed.
> > 
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
> > Cc: Thierry Reding <thierry.reding@gmail.com>
> > Cc: Simon Horman <horms@verge.net.au>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > ---
> >  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
> >  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
> >  drivers/pci/host/pci-tegra.c      | 10 ++++++---
> >  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
> >  include/linux/of_address.h        | 15 ++++++-------
> >  5 files changed, 82 insertions(+), 31 deletions(-)
> > ...
> 
> The of_pci_range_to_resource() implementation in drivers/of/address.c is
> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
> CONFIG_PCI is not set, we get the static inline version from
> include/linux/of_address.h as well, causing a redefinition error.
> 
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
> > ...
> > +int of_pci_range_to_resource(struct of_pci_range *range,
> > +	struct device_node *np, struct resource *res)
> 
> > diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> > ...
> >  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
> >  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
> >  				             struct resource *r)
> > @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
> >  	return -ENOSYS;
> >  }
> >  
> > +static inline int of_pci_range_to_resource(struct of_pci_range *range,
> > +		struct device_node *np, struct resource *res)
> > +{
> > +	return -ENOSYS;
> > +}
> 
> My proposal to fix it is the following three patches.  The first moves the
> inline version of of_pci_range_to_resource() into the existing "#if
> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
> 
> Andrew added it (and some other PCI-related things) with 29b635c00f3e
> ("of/pci: Provide support for parsing PCI DT ranges property") to
> of_address.h outside of any ifdefs, so it's always available.  Maybe
> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
> it with a quick look.
> 
> The second moves of_pci_range_to_resource() to address.c, still inside the
> "#ifdef CONFIG_PCI" block.

Hi Bjorn,

Looks good to me. Sorry for messing this up, I've tested a combination of
CONFIG_PCI=y and CONFIG_PCI=n but it looks like I've only tested
CONFIG_OF_ADDRESS=CONFIG_PCI (both enabled or both disabled).

Best regards,
Liviu

> 
> Bjorn
> 
> 
> commit 95a60df1c2d400c676ab1d20271735e2b4735437
> Author: Bjorn Helgaas <bhelgaas@google.com>
> Date:   Tue Sep 23 17:27:42 2014 -0600
> 
>     of/pci: Define of_pci_range_to_resource() only when CONFIG_PCI=y
>     
>     of_pci_range_to_resource() was previously defined always, but it's only
>     used by PCI code, so move the definition inside the CONFIG_OF_ADDRESS &&
>     CONFIG_PCI block.
>     
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> 
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index f8cc7daa420c..ecf913cf53b2 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -23,17 +23,6 @@ struct of_pci_range {
>  #define for_each_of_pci_range(parser, range) \
>  	for (; of_pci_range_parser_one(parser, range);)
>  
> -static inline void of_pci_range_to_resource(struct of_pci_range *range,
> -					    struct device_node *np,
> -					    struct resource *res)
> -{
> -	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
> -	res->parent = res->child = res->sibling = NULL;
> -	res->name = np->full_name;
> -}
> -
>  /* Translate a DMA address from device space to CPU space */
>  extern u64 of_translate_dma_address(struct device_node *dev,
>  				    const __be32 *in_addr);
> @@ -140,6 +129,18 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> +
> +static inline void of_pci_range_to_resource(struct of_pci_range *range,
> +					    struct device_node *np,
> +					    struct resource *res)
> +{
> +	res->flags = range->flags;
> +	res->start = range->cpu_addr;
> +	res->end = range->cpu_addr + range->size - 1;
> +	res->parent = res->child = res->sibling = NULL;
> +	res->name = np->full_name;
> +}
> +
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> @@ -155,4 +156,3 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
>  #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  
>  #endif /* __OF_ADDRESS_H */
> -
> 
> commit 501857889201723da06aab0ec68186a5beaa9f72
> Author: Liviu Dudau <Liviu.Dudau@arm.com>
> Date:   Tue Sep 23 20:01:06 2014 +0100
> 
>     of/pci: Move of_pci_range_to_resources() to of/address.c
>     
>     We need to enhance of_pci_range_to_resources() enough that it won't make
>     sense for it to be inline anymore.  Move it to drivers/of/address.c,
>     keeping it under #ifdef CONFIG_PCI.
>     
>     [bhelgaas: drop extra detail from changelog, move def under CONFIG_PCI]
>     Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>     CC: Grant Likely <grant.likely@linaro.org>
>     CC: Rob Herring <robh+dt@kernel.org>
>     CC: Arnd Bergmann <arnd@arndb.de>
>     CC: Catalin Marinas <catalin.marinas@arm.com>
> 
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 758d4f04d4aa..327a57410797 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -295,6 +295,15 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
>  }
>  EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
>  
> +void of_pci_range_to_resource(struct of_pci_range *range,
> +			      struct device_node *np, struct resource *res)
> +{
> +	res->flags = range->flags;
> +	res->start = range->cpu_addr;
> +	res->end = range->cpu_addr + range->size - 1;
> +	res->parent = res->child = res->sibling = NULL;
> +	res->name = np->full_name;
> +}
>  #endif /* CONFIG_PCI */
>  
>  /*
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index ecf913cf53b2..fa20aa15463d 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -129,18 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> -
> -static inline void of_pci_range_to_resource(struct of_pci_range *range,
> -					    struct device_node *np,
> -					    struct resource *res)
> -{
> -	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
> -	res->parent = res->child = res->sibling = NULL;
> -	res->name = np->full_name;
> -}
> -
> +extern void of_pci_range_to_resource(struct of_pci_range *range,
> +				     struct device_node *np,
> +				     struct resource *res);
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> 
> commit e01c1ebeee0bc45d6ac5f52b22c57d278799869b
> Author: Liviu Dudau <Liviu.Dudau@arm.com>
> Date:   Tue Sep 23 20:01:07 2014 +0100
> 
>     of/pci: Fix the conversion of IO ranges into IO resources
>     
>     The ranges property for a host bridge controller in DT describes the
>     mapping between the PCI bus address and the CPU physical address.  The
>     resources framework however expects that the IO resources start at a pseudo
>     "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.  The
>     conversion from PCI ranges to resources failed to take that into account,
>     returning a CPU physical address instead of a port number.
>     
>     Also fix all the drivers that depend on the old behaviour by fetching the
>     CPU physical address based on the port number where it is being needed.
>     
>     Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>     Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>     Acked-by: Linus Walleij <linus.walleij@linaro.org>
>     CC: Grant Likely <grant.likely@linaro.org>
>     CC: Rob Herring <robh+dt@kernel.org>
>     CC: Arnd Bergmann <arnd@arndb.de>
>     CC: Thierry Reding <thierry.reding@gmail.com>
>     CC: Simon Horman <horms@verge.net.au>
>     CC: Catalin Marinas <catalin.marinas@arm.com>
> 
> diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
> index 05e1f73a1e8d..c186a17c2cff 100644
> --- a/arch/arm/mach-integrator/pci_v3.c
> +++ b/arch/arm/mach-integrator/pci_v3.c
> @@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
>  {
>  	unsigned long flags;
>  	unsigned int temp;
> +	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
>  
>  	pcibios_min_mem = 0x00100000;
>  
> @@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
>  	/*
>  	 * Setup window 2 - PCI IO
>  	 */
> -	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
> +	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
>  			V3_LB_BASE_ENABLE);
>  	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
>  
> @@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
>  static void __init pci_v3_postinit(void)
>  {
>  	unsigned int pci_cmd;
> +	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
>  
>  	pci_cmd = PCI_COMMAND_MEMORY |
>  		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
> @@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
>  		       "interrupt: %d\n", ret);
>  #endif
>  
> -	register_isa_ports(non_mem.start, io_mem.start, 0);
> +	register_isa_ports(non_mem.start, io_address, 0);
>  }
>  
>  /*
> @@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
>  
>  	for_each_of_pci_range(&parser, &range) {
>  		if (!range.flags) {
> -			of_pci_range_to_resource(&range, np, &conf_mem);
> +			ret = of_pci_range_to_resource(&range, np, &conf_mem);
>  			conf_mem.name = "PCIv3 config";
>  		}
>  		if (range.flags & IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &io_mem);
> +			ret = of_pci_range_to_resource(&range, np, &io_mem);
>  			io_mem.name = "PCIv3 I/O";
>  		}
>  		if ((range.flags & IORESOURCE_MEM) &&
>  			!(range.flags & IORESOURCE_PREFETCH)) {
>  			non_mem_pci = range.pci_addr;
>  			non_mem_pci_sz = range.size;
> -			of_pci_range_to_resource(&range, np, &non_mem);
> +			ret = of_pci_range_to_resource(&range, np, &non_mem);
>  			non_mem.name = "PCIv3 non-prefetched mem";
>  		}
>  		if ((range.flags & IORESOURCE_MEM) &&
>  			(range.flags & IORESOURCE_PREFETCH)) {
>  			pre_mem_pci = range.pci_addr;
>  			pre_mem_pci_sz = range.size;
> -			of_pci_range_to_resource(&range, np, &pre_mem);
> +			ret = of_pci_range_to_resource(&range, np, &pre_mem);
>  			pre_mem.name = "PCIv3 prefetched mem";
>  		}
> -	}
>  
> -	if (!conf_mem.start || !io_mem.start ||
> -	    !non_mem.start || !pre_mem.start) {
> -		dev_err(&pdev->dev, "missing ranges in device node\n");
> -		return -EINVAL;
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "missing ranges in device node\n");
> +			return ret;
> +		}
>  	}
>  
>  	pci_v3.map_irq = of_irq_parse_and_map_pci;
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 327a57410797..afdb78299f61 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -295,14 +295,50 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
>  }
>  EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
>  
> -void of_pci_range_to_resource(struct of_pci_range *range,
> -			      struct device_node *np, struct resource *res)
> +/*
> + * of_pci_range_to_resource - Create a resource from an of_pci_range
> + * @range:	the PCI range that describes the resource
> + * @np:		device node where the range belongs to
> + * @res:	pointer to a valid resource that will be updated to
> + *              reflect the values contained in the range.
> + *
> + * Returns EINVAL if the range cannot be converted to resource.
> + *
> + * Note that if the range is an IO range, the resource will be converted
> + * using pci_address_to_pio() which can fail if it is called too early or
> + * if the range cannot be matched to any host bridge IO space (our case here).
> + * To guard against that we try to register the IO range first.
> + * If that fails we know that pci_address_to_pio() will do too.
> + */
> +int of_pci_range_to_resource(struct of_pci_range *range,
> +			     struct device_node *np, struct resource *res)
>  {
> +	int err;
>  	res->flags = range->flags;
> -	res->start = range->cpu_addr;
> -	res->end = range->cpu_addr + range->size - 1;
>  	res->parent = res->child = res->sibling = NULL;
>  	res->name = np->full_name;
> +
> +	if (res->flags & IORESOURCE_IO) {
> +		unsigned long port;
> +		err = pci_register_io_range(range->cpu_addr, range->size);
> +		if (err)
> +			goto invalid_range;
> +		port = pci_address_to_pio(range->cpu_addr);
> +		if (port == (unsigned long)-1) {
> +			err = -EINVAL;
> +			goto invalid_range;
> +		}
> +		res->start = port;
> +	} else {
> +		res->start = range->cpu_addr;
> +	}
> +	res->end = res->start + range->size - 1;
> +	return 0;
> +
> +invalid_range:
> +	res->start = (resource_size_t)OF_BAD_ADDR;
> +	res->end = (resource_size_t)OF_BAD_ADDR;
> +	return err;
>  }
>  #endif /* CONFIG_PCI */
>  
> diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
> index 0fb0fdb223d5..946935db62b6 100644
> --- a/drivers/pci/host/pci-tegra.c
> +++ b/drivers/pci/host/pci-tegra.c
> @@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
>  static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
>  {
>  	struct tegra_pcie *pcie = sys_to_pcie(sys);
> +	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
>  
>  	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
>  	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
>  				sys->mem_offset);
>  	pci_add_resource(&sys->resources, &pcie->busn);
>  
> -	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
> +	pci_ioremap_io(nr * SZ_64K, io_start);
>  
>  	return 1;
>  }
> @@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
>  	u32 fpci_bar, size, axi_address;
> +	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
>  
>  	/* Bar 0: type 1 extended configuration space */
>  	fpci_bar = 0xfe100000;
> @@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  	/* Bar 1: downstream IO bar */
>  	fpci_bar = 0xfdfc0000;
>  	size = resource_size(&pcie->io);
> -	axi_address = pcie->io.start;
> +	axi_address = io_start;
>  	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>  	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>  	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> @@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  	}
>  
>  	for_each_of_pci_range(&parser, &range) {
> -		of_pci_range_to_resource(&range, np, &res);
> +		err = of_pci_range_to_resource(&range, np, &res);
> +		if (err < 0)
> +			return err;
>  
>  		switch (res.flags & IORESOURCE_TYPE_BITS) {
>  		case IORESOURCE_IO:
> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
> index 4884ee5e07d4..61158e03ab5f 100644
> --- a/drivers/pci/host/pcie-rcar.c
> +++ b/drivers/pci/host/pcie-rcar.c
> @@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
>  
>  	/* Setup PCIe address space mappings for each resource */
>  	resource_size_t size;
> +	resource_size_t res_start;
>  	u32 mask;
>  
>  	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
> @@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
>  	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
>  	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
>  
> -	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
> -	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
> +	if (res->flags & IORESOURCE_IO)
> +		res_start = pci_pio_to_address(res->start);
> +	else
> +		res_start = res->start;
> +
> +	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
> +	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
>  
>  	/* First resource is for IO */
>  	mask = PAR_ENABLE;
> @@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
>  
>  		rcar_pcie_setup_window(i, pcie);
>  
> -		if (res->flags & IORESOURCE_IO)
> -			pci_ioremap_io(nr * SZ_64K, res->start);
> -		else
> +		if (res->flags & IORESOURCE_IO) {
> +			phys_addr_t io_start = pci_pio_to_address(res->start);
> +			pci_ioremap_io(nr * SZ_64K, io_start);
> +		} else
>  			pci_add_resource(&sys->resources, res);
>  	}
>  	pci_add_resource(&sys->resources, &pcie->busn);
> @@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
>  	}
>  
>  	for_each_of_pci_range(&parser, &range) {
> -		of_pci_range_to_resource(&range, pdev->dev.of_node,
> +		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
>  						&pcie->res[win++]);
> +		if (err < 0)
> +			return err;
>  
>  		if (win > RCAR_PCI_MAX_RESOURCES)
>  			break;
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index fa20aa15463d..7ebb877b07c2 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -129,9 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> -extern void of_pci_range_to_resource(struct of_pci_range *range,
> -				     struct device_node *np,
> -				     struct resource *res);
> +extern int of_pci_range_to_resource(struct of_pci_range *range,
> +				    struct device_node *np,
> +				    struct resource *res);
>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				             struct resource *r)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
  2014-09-24  1:12       ` Liviu Dudau
  (?)
@ 2014-09-24  1:16         ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  1:16 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding, Simon Horman, Andrew Murray

On Tue, Sep 23, 2014 at 7:12 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> On Tue, Sep 23, 2014 at 06:22:53PM -0600, Bjorn Helgaas wrote:
>> [+cc Andrew]
>>
>> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
>> > The ranges property for a host bridge controller in DT describes
>> > the mapping between the PCI bus address and the CPU physical address.
>> > The resources framework however expects that the IO resources start
>> > at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
>> > The conversion from pci ranges to resources failed to take that into account,
>> > returning a CPU physical address instead of a port number.
>> >
>> > Also fix all the drivers that depend on the old behaviour by fetching
>> > the CPU physical address based on the port number where it is being needed.
>> >
>> > Cc: Grant Likely <grant.likely@linaro.org>
>> > Cc: Rob Herring <robh+dt@kernel.org>
>> > Cc: Arnd Bergmann <arnd@arndb.de>
>> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
>> > Cc: Thierry Reding <thierry.reding@gmail.com>
>> > Cc: Simon Horman <horms@verge.net.au>
>> > Cc: Catalin Marinas <catalin.marinas@arm.com>
>> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> > ---
>> >  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>> >  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>> >  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>> >  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>> >  include/linux/of_address.h        | 15 ++++++-------
>> >  5 files changed, 82 insertions(+), 31 deletions(-)
>> > ...
>>
>> The of_pci_range_to_resource() implementation in drivers/of/address.c is
>> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
>> CONFIG_PCI is not set, we get the static inline version from
>> include/linux/of_address.h as well, causing a redefinition error.
>>
>> > diff --git a/drivers/of/address.c b/drivers/of/address.c
>> > @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
>> > ...
>> > +int of_pci_range_to_resource(struct of_pci_range *range,
>> > +   struct device_node *np, struct resource *res)
>>
>> > diff --git a/include/linux/of_address.h b/include/linux/of_address.h
>> > ...
>> >  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>> >  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>> >                                          struct resource *r)
>> > @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>> >     return -ENOSYS;
>> >  }
>> >
>> > +static inline int of_pci_range_to_resource(struct of_pci_range *range,
>> > +           struct device_node *np, struct resource *res)
>> > +{
>> > +   return -ENOSYS;
>> > +}
>>
>> My proposal to fix it is the following three patches.  The first moves the
>> inline version of of_pci_range_to_resource() into the existing "#if
>> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
>>
>> Andrew added it (and some other PCI-related things) with 29b635c00f3e
>> ("of/pci: Provide support for parsing PCI DT ranges property") to
>> of_address.h outside of any ifdefs, so it's always available.  Maybe
>> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
>> it with a quick look.
>>
>> The second moves of_pci_range_to_resource() to address.c, still inside the
>> "#ifdef CONFIG_PCI" block.
>
> Hi Bjorn,
>
> Looks good to me. Sorry for messing this up, I've tested a combination of
> CONFIG_PCI=y and CONFIG_PCI=n but it looks like I've only tested
> CONFIG_OF_ADDRESS=CONFIG_PCI (both enabled or both disabled).

You probably saw the subsequent [pci:pci/host-generic 10/13]
drivers/of/of_pci.c:202:3: error: implicit declaration of function
'of_pci_range_to_resource' error.

I looked at that a bit, but gave up.  Apparently drivers/of/of_pci.c
can be compiled with CONFIG_PCI=y but CONFIG_OF_ADDRESS not set..

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  1:16         ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  1:16 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding

On Tue, Sep 23, 2014 at 7:12 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> On Tue, Sep 23, 2014 at 06:22:53PM -0600, Bjorn Helgaas wrote:
>> [+cc Andrew]
>>
>> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
>> > The ranges property for a host bridge controller in DT describes
>> > the mapping between the PCI bus address and the CPU physical address.
>> > The resources framework however expects that the IO resources start
>> > at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
>> > The conversion from pci ranges to resources failed to take that into account,
>> > returning a CPU physical address instead of a port number.
>> >
>> > Also fix all the drivers that depend on the old behaviour by fetching
>> > the CPU physical address based on the port number where it is being needed.
>> >
>> > Cc: Grant Likely <grant.likely@linaro.org>
>> > Cc: Rob Herring <robh+dt@kernel.org>
>> > Cc: Arnd Bergmann <arnd@arndb.de>
>> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
>> > Cc: Thierry Reding <thierry.reding@gmail.com>
>> > Cc: Simon Horman <horms@verge.net.au>
>> > Cc: Catalin Marinas <catalin.marinas@arm.com>
>> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> > ---
>> >  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>> >  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>> >  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>> >  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>> >  include/linux/of_address.h        | 15 ++++++-------
>> >  5 files changed, 82 insertions(+), 31 deletions(-)
>> > ...
>>
>> The of_pci_range_to_resource() implementation in drivers/of/address.c is
>> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
>> CONFIG_PCI is not set, we get the static inline version from
>> include/linux/of_address.h as well, causing a redefinition error.
>>
>> > diff --git a/drivers/of/address.c b/drivers/of/address.c
>> > @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
>> > ...
>> > +int of_pci_range_to_resource(struct of_pci_range *range,
>> > +   struct device_node *np, struct resource *res)
>>
>> > diff --git a/include/linux/of_address.h b/include/linux/of_address.h
>> > ...
>> >  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>> >  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>> >                                          struct resource *r)
>> > @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>> >     return -ENOSYS;
>> >  }
>> >
>> > +static inline int of_pci_range_to_resource(struct of_pci_range *range,
>> > +           struct device_node *np, struct resource *res)
>> > +{
>> > +   return -ENOSYS;
>> > +}
>>
>> My proposal to fix it is the following three patches.  The first moves the
>> inline version of of_pci_range_to_resource() into the existing "#if
>> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
>>
>> Andrew added it (and some other PCI-related things) with 29b635c00f3e
>> ("of/pci: Provide support for parsing PCI DT ranges property") to
>> of_address.h outside of any ifdefs, so it's always available.  Maybe
>> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
>> it with a quick look.
>>
>> The second moves of_pci_range_to_resource() to address.c, still inside the
>> "#ifdef CONFIG_PCI" block.
>
> Hi Bjorn,
>
> Looks good to me. Sorry for messing this up, I've tested a combination of
> CONFIG_PCI=y and CONFIG_PCI=n but it looks like I've only tested
> CONFIG_OF_ADDRESS=CONFIG_PCI (both enabled or both disabled).

You probably saw the subsequent [pci:pci/host-generic 10/13]
drivers/of/of_pci.c:202:3: error: implicit declaration of function
'of_pci_range_to_resource' error.

I looked at that a bit, but gave up.  Apparently drivers/of/of_pci.c
can be compiled with CONFIG_PCI=y but CONFIG_OF_ADDRESS not set..

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  1:16         ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  1:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 7:12 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> On Tue, Sep 23, 2014 at 06:22:53PM -0600, Bjorn Helgaas wrote:
>> [+cc Andrew]
>>
>> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
>> > The ranges property for a host bridge controller in DT describes
>> > the mapping between the PCI bus address and the CPU physical address.
>> > The resources framework however expects that the IO resources start
>> > at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
>> > The conversion from pci ranges to resources failed to take that into account,
>> > returning a CPU physical address instead of a port number.
>> >
>> > Also fix all the drivers that depend on the old behaviour by fetching
>> > the CPU physical address based on the port number where it is being needed.
>> >
>> > Cc: Grant Likely <grant.likely@linaro.org>
>> > Cc: Rob Herring <robh+dt@kernel.org>
>> > Cc: Arnd Bergmann <arnd@arndb.de>
>> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
>> > Cc: Thierry Reding <thierry.reding@gmail.com>
>> > Cc: Simon Horman <horms@verge.net.au>
>> > Cc: Catalin Marinas <catalin.marinas@arm.com>
>> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> > ---
>> >  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>> >  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>> >  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>> >  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>> >  include/linux/of_address.h        | 15 ++++++-------
>> >  5 files changed, 82 insertions(+), 31 deletions(-)
>> > ...
>>
>> The of_pci_range_to_resource() implementation in drivers/of/address.c is
>> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
>> CONFIG_PCI is not set, we get the static inline version from
>> include/linux/of_address.h as well, causing a redefinition error.
>>
>> > diff --git a/drivers/of/address.c b/drivers/of/address.c
>> > @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
>> > ...
>> > +int of_pci_range_to_resource(struct of_pci_range *range,
>> > +   struct device_node *np, struct resource *res)
>>
>> > diff --git a/include/linux/of_address.h b/include/linux/of_address.h
>> > ...
>> >  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>> >  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>> >                                          struct resource *r)
>> > @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>> >     return -ENOSYS;
>> >  }
>> >
>> > +static inline int of_pci_range_to_resource(struct of_pci_range *range,
>> > +           struct device_node *np, struct resource *res)
>> > +{
>> > +   return -ENOSYS;
>> > +}
>>
>> My proposal to fix it is the following three patches.  The first moves the
>> inline version of of_pci_range_to_resource() into the existing "#if
>> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
>>
>> Andrew added it (and some other PCI-related things) with 29b635c00f3e
>> ("of/pci: Provide support for parsing PCI DT ranges property") to
>> of_address.h outside of any ifdefs, so it's always available.  Maybe
>> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
>> it with a quick look.
>>
>> The second moves of_pci_range_to_resource() to address.c, still inside the
>> "#ifdef CONFIG_PCI" block.
>
> Hi Bjorn,
>
> Looks good to me. Sorry for messing this up, I've tested a combination of
> CONFIG_PCI=y and CONFIG_PCI=n but it looks like I've only tested
> CONFIG_OF_ADDRESS=CONFIG_PCI (both enabled or both disabled).

You probably saw the subsequent [pci:pci/host-generic 10/13]
drivers/of/of_pci.c:202:3: error: implicit declaration of function
'of_pci_range_to_resource' error.

I looked at that a bit, but gave up.  Apparently drivers/of/of_pci.c
can be compiled with CONFIG_PCI=y but CONFIG_OF_ADDRESS not set..

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
  2014-09-23 19:01   ` Liviu Dudau
  (?)
@ 2014-09-24  1:18     ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:18 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
> If the firmware has not assigned all the bus resources and
> we are not just probing the PCIe busses, it makes sense to
> assign the unassigned resources in pci_scan_root_bus().
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> ---
>  drivers/pci/probe.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index ef891d2..508cf61 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>  	if (!found)
>  		pci_bus_update_busn_res_end(b, max);
>  
> +	if (!pci_has_flag(PCI_PROBE_ONLY))
> +		pci_assign_unassigned_bus_resources(b);
> +
>  	pci_bus_add_devices(b);
>  	return b;
>  }
> -- 
> 2.1.0
> 

Bjorn,

If you are OK with this patch, can you let me know how do you feel about
making pci_scan_root_bus() set up the bus->msi pointer as well?

Side note: I don't know exactly how to do it now, but setting bus->msi is
needed by platforms that are based on my patches and want to use MSI,
otherwise they have to open code pci_scan_root_bus() to set it. I haven't
made any attempts to do it in this series as the GICv2m patches are not
ready yet, but I can see the need arriving soon.

Best regards,
Liviu

> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-24  1:18     ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:18 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: linux-arch, Grant Likely, Kukjin Kim, Russell King,
	Arnd Bergmann, Device Tree ML, linux-pci, Catalin Marinas,
	Linus Walleij, Jingoo Han, Will Deacon, LKML, Jason Gunthorpe,
	Rob Herring, Tanmay Inamdar, Suravee Suthikulanit,
	Benjamin Herrenschmidt, Bjorn Helgaas, Sinan Kaya, LAKML

On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
> If the firmware has not assigned all the bus resources and
> we are not just probing the PCIe busses, it makes sense to
> assign the unassigned resources in pci_scan_root_bus().
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> ---
>  drivers/pci/probe.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index ef891d2..508cf61 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>  	if (!found)
>  		pci_bus_update_busn_res_end(b, max);
>  
> +	if (!pci_has_flag(PCI_PROBE_ONLY))
> +		pci_assign_unassigned_bus_resources(b);
> +
>  	pci_bus_add_devices(b);
>  	return b;
>  }
> -- 
> 2.1.0
> 

Bjorn,

If you are OK with this patch, can you let me know how do you feel about
making pci_scan_root_bus() set up the bus->msi pointer as well?

Side note: I don't know exactly how to do it now, but setting bus->msi is
needed by platforms that are based on my patches and want to use MSI,
otherwise they have to open code pci_scan_root_bus() to set it. I haven't
made any attempts to do it in this series as the GICv2m patches are not
ready yet, but I can see the need arriving soon.

Best regards,
Liviu

> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-24  1:18     ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
> If the firmware has not assigned all the bus resources and
> we are not just probing the PCIe busses, it makes sense to
> assign the unassigned resources in pci_scan_root_bus().
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> ---
>  drivers/pci/probe.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index ef891d2..508cf61 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>  	if (!found)
>  		pci_bus_update_busn_res_end(b, max);
>  
> +	if (!pci_has_flag(PCI_PROBE_ONLY))
> +		pci_assign_unassigned_bus_resources(b);
> +
>  	pci_bus_add_devices(b);
>  	return b;
>  }
> -- 
> 2.1.0
> 

Bjorn,

If you are OK with this patch, can you let me know how do you feel about
making pci_scan_root_bus() set up the bus->msi pointer as well?

Side note: I don't know exactly how to do it now, but setting bus->msi is
needed by platforms that are based on my patches and want to use MSI,
otherwise they have to open code pci_scan_root_bus() to set it. I haven't
made any attempts to do it in this series as the GICv2m patches are not
ready yet, but I can see the need arriving soon.

Best regards,
Liviu

> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
-------------------
   .oooO
   (   )
    \ (  Oooo.
     \_) (   )
          ) /
         (_/

 One small step
   for me ...

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
  2014-09-24  1:18     ` Liviu Dudau
@ 2014-09-24  1:41       ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  1:41 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 7:18 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
>> If the firmware has not assigned all the bus resources and
>> we are not just probing the PCIe busses, it makes sense to
>> assign the unassigned resources in pci_scan_root_bus().
>>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> ---
>>  drivers/pci/probe.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index ef891d2..508cf61 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>>       if (!found)
>>               pci_bus_update_busn_res_end(b, max);
>>
>> +     if (!pci_has_flag(PCI_PROBE_ONLY))
>> +             pci_assign_unassigned_bus_resources(b);
>> +
>>       pci_bus_add_devices(b);
>>       return b;
>>  }
>> --
>> 2.1.0
>>
>
> Bjorn,
>
> If you are OK with this patch, can you let me know how do you feel about
> making pci_scan_root_bus() set up the bus->msi pointer as well?

I'm not opposed to it, but I have the same question as for setting up
the domain: how does pci_scan_root_bus() learn what to assign to
bus->msi?  It currently only gets a "void *sysdata" so there's no
obvious place to put it there.  You could add a pcibios interface to
retrieve it, I suppose, but I'm starting to get uncomfortable with
adding more of those because we have such a mess of them already.

Bjorn

> Side note: I don't know exactly how to do it now, but setting bus->msi is
> needed by platforms that are based on my patches and want to use MSI,
> otherwise they have to open code pci_scan_root_bus() to set it. I haven't
> made any attempts to do it in this series as the GICv2m patches are not
> ready yet, but I can see the need arriving soon.
>
> Best regards,
> Liviu
>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
> --
> -------------------
>    .oooO
>    (   )
>     \ (  Oooo.
>      \_) (   )
>           ) /
>          (_/
>
>  One small step
>    for me ...
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-24  1:41       ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24  1:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 7:18 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
>> If the firmware has not assigned all the bus resources and
>> we are not just probing the PCIe busses, it makes sense to
>> assign the unassigned resources in pci_scan_root_bus().
>>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> ---
>>  drivers/pci/probe.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index ef891d2..508cf61 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>>       if (!found)
>>               pci_bus_update_busn_res_end(b, max);
>>
>> +     if (!pci_has_flag(PCI_PROBE_ONLY))
>> +             pci_assign_unassigned_bus_resources(b);
>> +
>>       pci_bus_add_devices(b);
>>       return b;
>>  }
>> --
>> 2.1.0
>>
>
> Bjorn,
>
> If you are OK with this patch, can you let me know how do you feel about
> making pci_scan_root_bus() set up the bus->msi pointer as well?

I'm not opposed to it, but I have the same question as for setting up
the domain: how does pci_scan_root_bus() learn what to assign to
bus->msi?  It currently only gets a "void *sysdata" so there's no
obvious place to put it there.  You could add a pcibios interface to
retrieve it, I suppose, but I'm starting to get uncomfortable with
adding more of those because we have such a mess of them already.

Bjorn

> Side note: I don't know exactly how to do it now, but setting bus->msi is
> needed by platforms that are based on my patches and want to use MSI,
> otherwise they have to open code pci_scan_root_bus() to set it. I haven't
> made any attempts to do it in this series as the GICv2m patches are not
> ready yet, but I can see the need arriving soon.
>
> Best regards,
> Liviu
>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
> --
> -------------------
>    .oooO
>    (   )
>     \ (  Oooo.
>      \_) (   )
>           ) /
>          (_/
>
>  One small step
>    for me ...
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
  2014-09-24  1:41       ` Bjorn Helgaas
@ 2014-09-24  1:48         ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:48 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 07:41:35PM -0600, Bjorn Helgaas wrote:
> On Tue, Sep 23, 2014 at 7:18 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> > On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
> >> If the firmware has not assigned all the bus resources and
> >> we are not just probing the PCIe busses, it makes sense to
> >> assign the unassigned resources in pci_scan_root_bus().
> >>
> >> Cc: Bjorn Helgaas <bhelgaas@google.com>
> >> Cc: Arnd Bergmann <arnd@arndb.de>
> >> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> >> Cc: Rob Herring <robh+dt@kernel.org>
> >> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> >> ---
> >>  drivers/pci/probe.c | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> >> index ef891d2..508cf61 100644
> >> --- a/drivers/pci/probe.c
> >> +++ b/drivers/pci/probe.c
> >> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> >>       if (!found)
> >>               pci_bus_update_busn_res_end(b, max);
> >>
> >> +     if (!pci_has_flag(PCI_PROBE_ONLY))
> >> +             pci_assign_unassigned_bus_resources(b);
> >> +
> >>       pci_bus_add_devices(b);
> >>       return b;
> >>  }
> >> --
> >> 2.1.0
> >>
> >
> > Bjorn,
> >
> > If you are OK with this patch, can you let me know how do you feel about
> > making pci_scan_root_bus() set up the bus->msi pointer as well?
> 
> I'm not opposed to it, but I have the same question as for setting up
> the domain: how does pci_scan_root_bus() learn what to assign to
> bus->msi?  It currently only gets a "void *sysdata" so there's no
> obvious place to put it there.  You could add a pcibios interface to
> retrieve it, I suppose, but I'm starting to get uncomfortable with
> adding more of those because we have such a mess of them already.

My long term view is that the creation of the pci_host_bridge structure
needs to be separated from the creation and scanning of the root bus.
Then we can add host bridge ops or some other API to the structure
that should allow for less friction in passing information to the bridge.

Best regards,
Liviu

> 
> Bjorn
> 
> > Side note: I don't know exactly how to do it now, but setting bus->msi is
> > needed by platforms that are based on my patches and want to use MSI,
> > otherwise they have to open code pci_scan_root_bus() to set it. I haven't
> > made any attempts to do it in this series as the GICv2m patches are not
> > ready yet, but I can see the need arriving soon.
> >
> > Best regards,
> > Liviu
> >
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> >> the body of a message to majordomo@vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-24  1:48         ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24  1:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 07:41:35PM -0600, Bjorn Helgaas wrote:
> On Tue, Sep 23, 2014 at 7:18 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> > On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
> >> If the firmware has not assigned all the bus resources and
> >> we are not just probing the PCIe busses, it makes sense to
> >> assign the unassigned resources in pci_scan_root_bus().
> >>
> >> Cc: Bjorn Helgaas <bhelgaas@google.com>
> >> Cc: Arnd Bergmann <arnd@arndb.de>
> >> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> >> Cc: Rob Herring <robh+dt@kernel.org>
> >> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> >> ---
> >>  drivers/pci/probe.c | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> >> index ef891d2..508cf61 100644
> >> --- a/drivers/pci/probe.c
> >> +++ b/drivers/pci/probe.c
> >> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> >>       if (!found)
> >>               pci_bus_update_busn_res_end(b, max);
> >>
> >> +     if (!pci_has_flag(PCI_PROBE_ONLY))
> >> +             pci_assign_unassigned_bus_resources(b);
> >> +
> >>       pci_bus_add_devices(b);
> >>       return b;
> >>  }
> >> --
> >> 2.1.0
> >>
> >
> > Bjorn,
> >
> > If you are OK with this patch, can you let me know how do you feel about
> > making pci_scan_root_bus() set up the bus->msi pointer as well?
> 
> I'm not opposed to it, but I have the same question as for setting up
> the domain: how does pci_scan_root_bus() learn what to assign to
> bus->msi?  It currently only gets a "void *sysdata" so there's no
> obvious place to put it there.  You could add a pcibios interface to
> retrieve it, I suppose, but I'm starting to get uncomfortable with
> adding more of those because we have such a mess of them already.

My long term view is that the creation of the pci_host_bridge structure
needs to be separated from the creation and scanning of the root bus.
Then we can add host bridge ops or some other API to the structure
that should allow for less friction in passing information to the bridge.

Best regards,
Liviu

> 
> Bjorn
> 
> > Side note: I don't know exactly how to do it now, but setting bus->msi is
> > needed by platforms that are based on my patches and want to use MSI,
> > otherwise they have to open code pci_scan_root_bus() to set it. I haven't
> > made any attempts to do it in this series as the GICv2m patches are not
> > ready yet, but I can see the need arriving soon.
> >
> > Best regards,
> > Liviu
> >
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> >> the body of a message to majordomo at vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
  2014-09-24  1:16         ` Bjorn Helgaas
  (?)
@ 2014-09-24  9:20           ` Robert Richter
  -1 siblings, 0 replies; 101+ messages in thread
From: Robert Richter @ 2014-09-24  9:20 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Liviu Dudau, Arnd Bergmann, Rob Herring,
	Jason Gunthorpe, Benjamin Herrenschmidt, Catalin Marinas,
	Will Deacon, Russell King, linux-pci, Linus Walleij,
	Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding, Simon Horman, Andrew Murray

On 23.09.14 19:16:19, Bjorn Helgaas wrote:
> You probably saw the subsequent [pci:pci/host-generic 10/13]
> drivers/of/of_pci.c:202:3: error: implicit declaration of function
> 'of_pci_range_to_resource' error.
> 
> I looked at that a bit, but gave up.  Apparently drivers/of/of_pci.c
> can be compiled with CONFIG_PCI=y but CONFIG_OF_ADDRESS not set..

This is due to the !SPARC dependency in drivers/of/Kconfig:

config OF_ADDRESS
        def_bool y
        depends on !SPARC
        select OF_ADDRESS_PCI if PCI

Error above occurs with ARCH=sparc.

-Robert

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  9:20           ` Robert Richter
  0 siblings, 0 replies; 101+ messages in thread
From: Robert Richter @ 2014-09-24  9:20 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Liviu Dudau, Arnd Bergmann, Rob Herring,
	Jason Gunthorpe, Benjamin Herrenschmidt, Catalin Marinas,
	Will Deacon, Russell King, linux-pci, Linus Walleij,
	Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely

On 23.09.14 19:16:19, Bjorn Helgaas wrote:
> You probably saw the subsequent [pci:pci/host-generic 10/13]
> drivers/of/of_pci.c:202:3: error: implicit declaration of function
> 'of_pci_range_to_resource' error.
> 
> I looked at that a bit, but gave up.  Apparently drivers/of/of_pci.c
> can be compiled with CONFIG_PCI=y but CONFIG_OF_ADDRESS not set..

This is due to the !SPARC dependency in drivers/of/Kconfig:

config OF_ADDRESS
        def_bool y
        depends on !SPARC
        select OF_ADDRESS_PCI if PCI

Error above occurs with ARCH=sparc.

-Robert

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24  9:20           ` Robert Richter
  0 siblings, 0 replies; 101+ messages in thread
From: Robert Richter @ 2014-09-24  9:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 23.09.14 19:16:19, Bjorn Helgaas wrote:
> You probably saw the subsequent [pci:pci/host-generic 10/13]
> drivers/of/of_pci.c:202:3: error: implicit declaration of function
> 'of_pci_range_to_resource' error.
> 
> I looked at that a bit, but gave up.  Apparently drivers/of/of_pci.c
> can be compiled with CONFIG_PCI=y but CONFIG_OF_ADDRESS not set..

This is due to the !SPARC dependency in drivers/of/Kconfig:

config OF_ADDRESS
        def_bool y
        depends on !SPARC
        select OF_ADDRESS_PCI if PCI

Error above occurs with ARCH=sparc.

-Robert

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
  2014-09-24  0:22     ` Bjorn Helgaas
  (?)
@ 2014-09-24 10:14       ` Andrew Murray
  -1 siblings, 0 replies; 101+ messages in thread
From: Andrew Murray @ 2014-09-24 10:14 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding, Simon Horman

On 24 September 2014 01:22, Bjorn Helgaas <bhelgaas@google.com> wrote:
> [+cc Andrew]
>
> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
>> The ranges property for a host bridge controller in DT describes
>> the mapping between the PCI bus address and the CPU physical address.
>> The resources framework however expects that the IO resources start
>> at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
>> The conversion from pci ranges to resources failed to take that into account,
>> returning a CPU physical address instead of a port number.
>>
>> Also fix all the drivers that depend on the old behaviour by fetching
>> the CPU physical address based on the port number where it is being needed.
>>
>> Cc: Grant Likely <grant.likely@linaro.org>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Acked-by: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Thierry Reding <thierry.reding@gmail.com>
>> Cc: Simon Horman <horms@verge.net.au>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> ---
>>  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>>  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>>  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>>  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>>  include/linux/of_address.h        | 15 ++++++-------
>>  5 files changed, 82 insertions(+), 31 deletions(-)
>> ...
>
> The of_pci_range_to_resource() implementation in drivers/of/address.c is
> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
> CONFIG_PCI is not set, we get the static inline version from
> include/linux/of_address.h as well, causing a redefinition error.
>
>> diff --git a/drivers/of/address.c b/drivers/of/address.c
>> @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
>> ...
>> +int of_pci_range_to_resource(struct of_pci_range *range,
>> +     struct device_node *np, struct resource *res)
>
>> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
>> ...
>>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>>                                            struct resource *r)
>> @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>>       return -ENOSYS;
>>  }
>>
>> +static inline int of_pci_range_to_resource(struct of_pci_range *range,
>> +             struct device_node *np, struct resource *res)
>> +{
>> +     return -ENOSYS;
>> +}
>
> My proposal to fix it is the following three patches.  The first moves the
> inline version of of_pci_range_to_resource() into the existing "#if
> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
>
> Andrew added it (and some other PCI-related things) with 29b635c00f3e
> ("of/pci: Provide support for parsing PCI DT ranges property") to
> of_address.h outside of any ifdefs, so it's always available.  Maybe
> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
> it with a quick look.
>

There was no reason - it probably should have been inside a #ifdef
like the others.

Andrew Murray

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24 10:14       ` Andrew Murray
  0 siblings, 0 replies; 101+ messages in thread
From: Andrew Murray @ 2014-09-24 10:14 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely, Thierry Reding

On 24 September 2014 01:22, Bjorn Helgaas <bhelgaas@google.com> wrote:
> [+cc Andrew]
>
> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
>> The ranges property for a host bridge controller in DT describes
>> the mapping between the PCI bus address and the CPU physical address.
>> The resources framework however expects that the IO resources start
>> at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
>> The conversion from pci ranges to resources failed to take that into account,
>> returning a CPU physical address instead of a port number.
>>
>> Also fix all the drivers that depend on the old behaviour by fetching
>> the CPU physical address based on the port number where it is being needed.
>>
>> Cc: Grant Likely <grant.likely@linaro.org>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Acked-by: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Thierry Reding <thierry.reding@gmail.com>
>> Cc: Simon Horman <horms@verge.net.au>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> ---
>>  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>>  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>>  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>>  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>>  include/linux/of_address.h        | 15 ++++++-------
>>  5 files changed, 82 insertions(+), 31 deletions(-)
>> ...
>
> The of_pci_range_to_resource() implementation in drivers/of/address.c is
> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
> CONFIG_PCI is not set, we get the static inline version from
> include/linux/of_address.h as well, causing a redefinition error.
>
>> diff --git a/drivers/of/address.c b/drivers/of/address.c
>> @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
>> ...
>> +int of_pci_range_to_resource(struct of_pci_range *range,
>> +     struct device_node *np, struct resource *res)
>
>> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
>> ...
>>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>>                                            struct resource *r)
>> @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>>       return -ENOSYS;
>>  }
>>
>> +static inline int of_pci_range_to_resource(struct of_pci_range *range,
>> +             struct device_node *np, struct resource *res)
>> +{
>> +     return -ENOSYS;
>> +}
>
> My proposal to fix it is the following three patches.  The first moves the
> inline version of of_pci_range_to_resource() into the existing "#if
> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
>
> Andrew added it (and some other PCI-related things) with 29b635c00f3e
> ("of/pci: Provide support for parsing PCI DT ranges property") to
> of_address.h outside of any ifdefs, so it's always available.  Maybe
> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
> it with a quick look.
>

There was no reason - it probably should have been inside a #ifdef
like the others.

Andrew Murray

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources.
@ 2014-09-24 10:14       ` Andrew Murray
  0 siblings, 0 replies; 101+ messages in thread
From: Andrew Murray @ 2014-09-24 10:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 24 September 2014 01:22, Bjorn Helgaas <bhelgaas@google.com> wrote:
> [+cc Andrew]
>
> On Tue, Sep 23, 2014 at 08:01:07PM +0100, Liviu Dudau wrote:
>> The ranges property for a host bridge controller in DT describes
>> the mapping between the PCI bus address and the CPU physical address.
>> The resources framework however expects that the IO resources start
>> at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
>> The conversion from pci ranges to resources failed to take that into account,
>> returning a CPU physical address instead of a port number.
>>
>> Also fix all the drivers that depend on the old behaviour by fetching
>> the CPU physical address based on the port number where it is being needed.
>>
>> Cc: Grant Likely <grant.likely@linaro.org>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Acked-by: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Thierry Reding <thierry.reding@gmail.com>
>> Cc: Simon Horman <horms@verge.net.au>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> ---
>>  arch/arm/mach-integrator/pci_v3.c | 23 ++++++++++----------
>>  drivers/of/address.c              | 44 +++++++++++++++++++++++++++++++++++----
>>  drivers/pci/host/pci-tegra.c      | 10 ++++++---
>>  drivers/pci/host/pcie-rcar.c      | 21 +++++++++++++------
>>  include/linux/of_address.h        | 15 ++++++-------
>>  5 files changed, 82 insertions(+), 31 deletions(-)
>> ...
>
> The of_pci_range_to_resource() implementation in drivers/of/address.c is
> always compiled when CONFIG_OF_ADDRESS=y, but when CONFIG_OF_ADDRESS=y and
> CONFIG_PCI is not set, we get the static inline version from
> include/linux/of_address.h as well, causing a redefinition error.
>
>> diff --git a/drivers/of/address.c b/drivers/of/address.c
>> @@ -957,12 +957,48 @@ bool of_dma_is_coherent(struct device_node *np)
>> ...
>> +int of_pci_range_to_resource(struct of_pci_range *range,
>> +     struct device_node *np, struct resource *res)
>
>> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
>> ...
>>  #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
>>  static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>>                                            struct resource *r)
>> @@ -144,6 +139,12 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>>       return -ENOSYS;
>>  }
>>
>> +static inline int of_pci_range_to_resource(struct of_pci_range *range,
>> +             struct device_node *np, struct resource *res)
>> +{
>> +     return -ENOSYS;
>> +}
>
> My proposal to fix it is the following three patches.  The first moves the
> inline version of of_pci_range_to_resource() into the existing "#if
> defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)" block.
>
> Andrew added it (and some other PCI-related things) with 29b635c00f3e
> ("of/pci: Provide support for parsing PCI DT ranges property") to
> of_address.h outside of any ifdefs, so it's always available.  Maybe
> there's a reason that's needed in the non-CONFIG_PCI case, but I didn't see
> it with a quick look.
>

There was no reason - it probably should have been inside a #ifdef
like the others.

Andrew Murray

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
  2014-09-23 23:00       ` Bjorn Helgaas
@ 2014-09-24 13:30         ` Rob Herring
  -1 siblings, 0 replies; 101+ messages in thread
From: Rob Herring @ 2014-09-24 13:30 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Liviu Dudau, Liviu Dudau, Arnd Bergmann, Rob Herring,
	Jason Gunthorpe, Benjamin Herrenschmidt, Catalin Marinas,
	Will Deacon, Russell King, linux-pci, Linus Walleij,
	Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 6:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
>> ...
>> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
>> and probably pcie-designware.c to my series, I would like to ask you what
>> is your longer term plan. Now that I have got my head full of PCI code,
>> I have some ideas but feel that meeting with you and all those involved
>> in core PCI support would be a better venue than sending emails back and
>> forth. When is your next plan to attend a Linux conference?
>
> That would be nice.  Unfortunately, I don't know what the next
> conference will be yet.

Perhaps an irc meeting or Google hangout. These have been happening on
several areas like DT and ARM KVM.

Rob

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-24 13:30         ` Rob Herring
  0 siblings, 0 replies; 101+ messages in thread
From: Rob Herring @ 2014-09-24 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 6:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
>> ...
>> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
>> and probably pcie-designware.c to my series, I would like to ask you what
>> is your longer term plan. Now that I have got my head full of PCI code,
>> I have some ideas but feel that meeting with you and all those involved
>> in core PCI support would be a better venue than sending emails back and
>> forth. When is your next plan to attend a Linux conference?
>
> That would be nice.  Unfortunately, I don't know what the next
> conference will be yet.

Perhaps an irc meeting or Google hangout. These have been happening on
several areas like DT and ARM KVM.

Rob

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
  2014-09-24 13:30         ` Rob Herring
@ 2014-09-24 14:23           ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24 14:23 UTC (permalink / raw)
  To: Rob Herring
  Cc: Bjorn Helgaas, Liviu Dudau, Arnd Bergmann, Rob Herring,
	Jason Gunthorpe, Benjamin Herrenschmidt, Catalin Marinas,
	Will Deacon, Russell King, linux-pci, Linus Walleij,
	Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Wed, Sep 24, 2014 at 02:30:37PM +0100, Rob Herring wrote:
> On Tue, Sep 23, 2014 at 6:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> > On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> >> ...
> >> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
> >> and probably pcie-designware.c to my series, I would like to ask you what
> >> is your longer term plan. Now that I have got my head full of PCI code,
> >> I have some ideas but feel that meeting with you and all those involved
> >> in core PCI support would be a better venue than sending emails back and
> >> forth. When is your next plan to attend a Linux conference?
> >
> > That would be nice.  Unfortunately, I don't know what the next
> > conference will be yet.
> 
> Perhaps an irc meeting or Google hangout. These have been happening on
> several areas like DT and ARM KVM.

I'm open to the idea. I don't know if there is a recurring one already for
PCI or how Bjorn has been handling future planning previously.

Best regards,
Liviu

> 
> Rob
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-24 14:23           ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 02:30:37PM +0100, Rob Herring wrote:
> On Tue, Sep 23, 2014 at 6:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> > On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
> >> ...
> >> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
> >> and probably pcie-designware.c to my series, I would like to ask you what
> >> is your longer term plan. Now that I have got my head full of PCI code,
> >> I have some ideas but feel that meeting with you and all those involved
> >> in core PCI support would be a better venue than sending emails back and
> >> forth. When is your next plan to attend a Linux conference?
> >
> > That would be nice.  Unfortunately, I don't know what the next
> > conference will be yet.
> 
> Perhaps an irc meeting or Google hangout. These have been happening on
> several areas like DT and ARM KVM.

I'm open to the idea. I don't know if there is a recurring one already for
PCI or how Bjorn has been handling future planning previously.

Best regards,
Liviu

> 
> Rob
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
  2014-09-24 14:23           ` Liviu Dudau
@ 2014-09-24 15:38             ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24 15:38 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Rob Herring, Liviu Dudau, Arnd Bergmann, Rob Herring,
	Jason Gunthorpe, Benjamin Herrenschmidt, Catalin Marinas,
	Will Deacon, Russell King, linux-pci, Linus Walleij,
	Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Wed, Sep 24, 2014 at 8:23 AM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Wed, Sep 24, 2014 at 02:30:37PM +0100, Rob Herring wrote:
>> On Tue, Sep 23, 2014 at 6:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> > On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
>> >> ...
>> >> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
>> >> and probably pcie-designware.c to my series, I would like to ask you what
>> >> is your longer term plan. Now that I have got my head full of PCI code,
>> >> I have some ideas but feel that meeting with you and all those involved
>> >> in core PCI support would be a better venue than sending emails back and
>> >> forth. When is your next plan to attend a Linux conference?
>> >
>> > That would be nice.  Unfortunately, I don't know what the next
>> > conference will be yet.
>>
>> Perhaps an irc meeting or Google hangout. These have been happening on
>> several areas like DT and ARM KVM.
>
> I'm open to the idea. I don't know if there is a recurring one already for
> PCI or how Bjorn has been handling future planning previously.

There is no periodic PCI meeting, and I don't have any formal future
planning.  We had PCI microconferences at the last couple Linux
Plumbers conferences, but we didn't plan one for this year because it
has been hard to get topic proposals (and I'm not going to be in
Düsseldorf).

I would attend an IRC or hangout meeting, of course.  For myself, I
think it would be most useful if it were to follow up on
previously-posted patches, so I'd have a chance to look them over
first, and then have the opportunity in a meeting to talk in more
detail.  If a meeting is a forum for abstract thinking about what we
might do, it's hard for me to respond meaningfully in real time
because I need time to research and explore things.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 00/12] Support for creating generic PCI host bridges from DT
@ 2014-09-24 15:38             ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 8:23 AM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Wed, Sep 24, 2014 at 02:30:37PM +0100, Rob Herring wrote:
>> On Tue, Sep 23, 2014 at 6:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> > On Tue, Sep 23, 2014 at 4:48 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
>> >> ...
>> >> While the next immediate target is converting pci-host-generic.c, pci-imx6.c
>> >> and probably pcie-designware.c to my series, I would like to ask you what
>> >> is your longer term plan. Now that I have got my head full of PCI code,
>> >> I have some ideas but feel that meeting with you and all those involved
>> >> in core PCI support would be a better venue than sending emails back and
>> >> forth. When is your next plan to attend a Linux conference?
>> >
>> > That would be nice.  Unfortunately, I don't know what the next
>> > conference will be yet.
>>
>> Perhaps an irc meeting or Google hangout. These have been happening on
>> several areas like DT and ARM KVM.
>
> I'm open to the idea. I don't know if there is a recurring one already for
> PCI or how Bjorn has been handling future planning previously.

There is no periodic PCI meeting, and I don't have any formal future
planning.  We had PCI microconferences at the last couple Linux
Plumbers conferences, but we didn't plan one for this year because it
has been hard to get topic proposals (and I'm not going to be in
D?sseldorf).

I would attend an IRC or hangout meeting, of course.  For myself, I
think it would be most useful if it were to follow up on
previously-posted patches, so I'd have a chance to look them over
first, and then have the opportunity in a meeting to talk in more
detail.  If a meeting is a forum for abstract thinking about what we
might do, it's hard for me to respond meaningfully in real time
because I need time to research and explore things.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
  2014-09-23 19:01   ` Liviu Dudau
@ 2014-09-24 16:43     ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24 16:43 UTC (permalink / raw)
  To: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij
  Cc: Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	grant.likely, Robert Richter

Provide a function to parse the PCI DT ranges that can be used to
create a pci_host_bridge structure together with its associated
bus.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
[make io_base parameter optional]
Signed-off-by: Robert Richter <rrichter@cavium.com>
---
Hi Bjorn,

I have fixed the compilation error that this patch was triggering. I
have validated that the patch applies to your pci/host-generic branch
as well as to my series.

Best regards,
Liviu


 drivers/of/of_pci.c    | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_pci.h |   6 +++
 2 files changed, 123 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 82d172f..3cad1af 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -1,7 +1,9 @@
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_pci.h>
+#include <linux/slab.h>
 
 static inline int __of_pci_pci_compare(struct device_node *node,
 				       unsigned int data)
@@ -114,6 +116,121 @@ int of_get_pci_domain_nr(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
+#if defined(CONFIG_OF_ADDRESS)
+/**
+ * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @busno: bus number associated with the bridge root bus
+ * @bus_max: maximum number of busses for this bridge
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain on return the physical
+ * address for the start of the I/O range. Can be NULL if the caller doesn't
+ * expect IO ranges to be present in the device tree.
+ *
+ * It is the callers job to free the @resources list.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * It returns zero if the range parsing has been successful or a standard error
+ * value if it failed.
+ */
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base)
+{
+	struct resource *res;
+	struct resource *bus_range;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	char range_type[4];
+	int err;
+
+	if (io_base)
+		*io_base = (resource_size_t)OF_BAD_ADDR;
+
+	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
+	if (!bus_range)
+		return -ENOMEM;
+
+	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
+
+	err = of_pci_parse_bus_range(dev, bus_range);
+	if (err) {
+		bus_range->start = busno;
+		bus_range->end = bus_max;
+		bus_range->flags = IORESOURCE_BUS;
+		pr_info("  No bus range found for %s, using %pR\n",
+			dev->full_name, bus_range);
+	} else {
+		if (bus_range->end > bus_range->start + bus_max)
+			bus_range->end = bus_range->start + bus_max;
+	}
+	pci_add_resource(resources, bus_range);
+
+	/* Check for ranges property */
+	err = of_pci_range_parser_init(&parser, dev);
+	if (err)
+		goto parse_failed;
+
+	pr_debug("Parsing ranges property...\n");
+	for_each_of_pci_range(&parser, &range) {
+		/* Read next ranges element */
+		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+			snprintf(range_type, 4, " IO");
+		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+			snprintf(range_type, 4, "MEM");
+		else
+			snprintf(range_type, 4, "err");
+		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
+			range.cpu_addr, range.cpu_addr + range.size - 1,
+			range.pci_addr);
+
+		/*
+		 * If we failed translation or got a zero-sized region
+		 * then skip this range
+		 */
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+			continue;
+
+		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+		if (!res) {
+			err = -ENOMEM;
+			goto parse_failed;
+		}
+
+		err = of_pci_range_to_resource(&range, dev, res);
+		if (err)
+			goto conversion_failed;
+
+		if (resource_type(res) == IORESOURCE_IO) {
+			if (!io_base) {
+				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
+					dev->full_name);
+				err = -EINVAL;
+				goto conversion_failed;
+			}
+			if (*io_base != (resource_size_t)OF_BAD_ADDR)
+				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
+					dev->full_name);
+			*io_base = range.cpu_addr;
+		}
+
+		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
+	}
+
+	return 0;
+
+conversion_failed:
+	kfree(res);
+parse_failed:
+	pci_free_resource_list(resources);
+	return err;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+#endif /* CONFIG_OF_ADDRESS */
+
 #ifdef CONFIG_PCI_MSI
 
 static LIST_HEAD(of_pci_msi_chip_list);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 71062e9..1fd207e 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -52,6 +52,12 @@ of_get_pci_domain_nr(struct device_node *node)
 }
 #endif
 
+#if defined(CONFIG_OF_ADDRESS)
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base);
+#endif
+
 #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
 int of_pci_msi_chip_add(struct msi_chip *chip);
 void of_pci_msi_chip_remove(struct msi_chip *chip);
-- 
2.1.0



^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
@ 2014-09-24 16:43     ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

Provide a function to parse the PCI DT ranges that can be used to
create a pci_host_bridge structure together with its associated
bus.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
[make io_base parameter optional]
Signed-off-by: Robert Richter <rrichter@cavium.com>
---
Hi Bjorn,

I have fixed the compilation error that this patch was triggering. I
have validated that the patch applies to your pci/host-generic branch
as well as to my series.

Best regards,
Liviu


 drivers/of/of_pci.c    | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_pci.h |   6 +++
 2 files changed, 123 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 82d172f..3cad1af 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -1,7 +1,9 @@
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_pci.h>
+#include <linux/slab.h>
 
 static inline int __of_pci_pci_compare(struct device_node *node,
 				       unsigned int data)
@@ -114,6 +116,121 @@ int of_get_pci_domain_nr(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
+#if defined(CONFIG_OF_ADDRESS)
+/**
+ * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @busno: bus number associated with the bridge root bus
+ * @bus_max: maximum number of busses for this bridge
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain on return the physical
+ * address for the start of the I/O range. Can be NULL if the caller doesn't
+ * expect IO ranges to be present in the device tree.
+ *
+ * It is the callers job to free the @resources list.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * It returns zero if the range parsing has been successful or a standard error
+ * value if it failed.
+ */
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base)
+{
+	struct resource *res;
+	struct resource *bus_range;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	char range_type[4];
+	int err;
+
+	if (io_base)
+		*io_base = (resource_size_t)OF_BAD_ADDR;
+
+	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
+	if (!bus_range)
+		return -ENOMEM;
+
+	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
+
+	err = of_pci_parse_bus_range(dev, bus_range);
+	if (err) {
+		bus_range->start = busno;
+		bus_range->end = bus_max;
+		bus_range->flags = IORESOURCE_BUS;
+		pr_info("  No bus range found for %s, using %pR\n",
+			dev->full_name, bus_range);
+	} else {
+		if (bus_range->end > bus_range->start + bus_max)
+			bus_range->end = bus_range->start + bus_max;
+	}
+	pci_add_resource(resources, bus_range);
+
+	/* Check for ranges property */
+	err = of_pci_range_parser_init(&parser, dev);
+	if (err)
+		goto parse_failed;
+
+	pr_debug("Parsing ranges property...\n");
+	for_each_of_pci_range(&parser, &range) {
+		/* Read next ranges element */
+		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+			snprintf(range_type, 4, " IO");
+		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+			snprintf(range_type, 4, "MEM");
+		else
+			snprintf(range_type, 4, "err");
+		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
+			range.cpu_addr, range.cpu_addr + range.size - 1,
+			range.pci_addr);
+
+		/*
+		 * If we failed translation or got a zero-sized region
+		 * then skip this range
+		 */
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+			continue;
+
+		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+		if (!res) {
+			err = -ENOMEM;
+			goto parse_failed;
+		}
+
+		err = of_pci_range_to_resource(&range, dev, res);
+		if (err)
+			goto conversion_failed;
+
+		if (resource_type(res) == IORESOURCE_IO) {
+			if (!io_base) {
+				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
+					dev->full_name);
+				err = -EINVAL;
+				goto conversion_failed;
+			}
+			if (*io_base != (resource_size_t)OF_BAD_ADDR)
+				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
+					dev->full_name);
+			*io_base = range.cpu_addr;
+		}
+
+		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
+	}
+
+	return 0;
+
+conversion_failed:
+	kfree(res);
+parse_failed:
+	pci_free_resource_list(resources);
+	return err;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+#endif /* CONFIG_OF_ADDRESS */
+
 #ifdef CONFIG_PCI_MSI
 
 static LIST_HEAD(of_pci_msi_chip_list);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 71062e9..1fd207e 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -52,6 +52,12 @@ of_get_pci_domain_nr(struct device_node *node)
 }
 #endif
 
+#if defined(CONFIG_OF_ADDRESS)
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base);
+#endif
+
 #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
 int of_pci_msi_chip_add(struct msi_chip *chip);
 void of_pci_msi_chip_remove(struct msi_chip *chip);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
  2014-09-24 16:43     ` Liviu Dudau
@ 2014-09-24 17:31       ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24 17:31 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	grant.likely, Robert Richter

On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> Provide a function to parse the PCI DT ranges that can be used to
> create a pci_host_bridge structure together with its associated
> bus.
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> [make io_base parameter optional]
> Signed-off-by: Robert Richter <rrichter@cavium.com>
> ---
> Hi Bjorn,
> 
> I have fixed the compilation error that this patch was triggering. I
> have validated that the patch applies to your pci/host-generic branch
> as well as to my series.

I applied this to pci/host-generic along with the following patches and
pushed the branch, thanks!

Bjorn

>  drivers/of/of_pci.c    | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_pci.h |   6 +++
>  2 files changed, 123 insertions(+)
> 
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 82d172f..3cad1af 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -1,7 +1,9 @@
>  #include <linux/kernel.h>
>  #include <linux/export.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/of_pci.h>
> +#include <linux/slab.h>
>  
>  static inline int __of_pci_pci_compare(struct device_node *node,
>  				       unsigned int data)
> @@ -114,6 +116,121 @@ int of_get_pci_domain_nr(struct device_node *node)
>  }
>  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>  
> +#if defined(CONFIG_OF_ADDRESS)
> +/**
> + * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
> + * @dev: device node of the host bridge having the range property
> + * @busno: bus number associated with the bridge root bus
> + * @bus_max: maximum number of busses for this bridge
> + * @resources: list where the range of resources will be added after DT parsing
> + * @io_base: pointer to a variable that will contain on return the physical
> + * address for the start of the I/O range. Can be NULL if the caller doesn't
> + * expect IO ranges to be present in the device tree.
> + *
> + * It is the callers job to free the @resources list.
> + *
> + * This function will parse the "ranges" property of a PCI host bridge device
> + * node and setup the resource mapping based on its content. It is expected
> + * that the property conforms with the Power ePAPR document.
> + *
> + * It returns zero if the range parsing has been successful or a standard error
> + * value if it failed.
> + */
> +int of_pci_get_host_bridge_resources(struct device_node *dev,
> +			unsigned char busno, unsigned char bus_max,
> +			struct list_head *resources, resource_size_t *io_base)
> +{
> +	struct resource *res;
> +	struct resource *bus_range;
> +	struct of_pci_range range;
> +	struct of_pci_range_parser parser;
> +	char range_type[4];
> +	int err;
> +
> +	if (io_base)
> +		*io_base = (resource_size_t)OF_BAD_ADDR;
> +
> +	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
> +	if (!bus_range)
> +		return -ENOMEM;
> +
> +	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
> +
> +	err = of_pci_parse_bus_range(dev, bus_range);
> +	if (err) {
> +		bus_range->start = busno;
> +		bus_range->end = bus_max;
> +		bus_range->flags = IORESOURCE_BUS;
> +		pr_info("  No bus range found for %s, using %pR\n",
> +			dev->full_name, bus_range);
> +	} else {
> +		if (bus_range->end > bus_range->start + bus_max)
> +			bus_range->end = bus_range->start + bus_max;
> +	}
> +	pci_add_resource(resources, bus_range);
> +
> +	/* Check for ranges property */
> +	err = of_pci_range_parser_init(&parser, dev);
> +	if (err)
> +		goto parse_failed;
> +
> +	pr_debug("Parsing ranges property...\n");
> +	for_each_of_pci_range(&parser, &range) {
> +		/* Read next ranges element */
> +		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
> +			snprintf(range_type, 4, " IO");
> +		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
> +			snprintf(range_type, 4, "MEM");
> +		else
> +			snprintf(range_type, 4, "err");
> +		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
> +			range.cpu_addr, range.cpu_addr + range.size - 1,
> +			range.pci_addr);
> +
> +		/*
> +		 * If we failed translation or got a zero-sized region
> +		 * then skip this range
> +		 */
> +		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
> +			continue;
> +
> +		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
> +		if (!res) {
> +			err = -ENOMEM;
> +			goto parse_failed;
> +		}
> +
> +		err = of_pci_range_to_resource(&range, dev, res);
> +		if (err)
> +			goto conversion_failed;
> +
> +		if (resource_type(res) == IORESOURCE_IO) {
> +			if (!io_base) {
> +				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
> +					dev->full_name);
> +				err = -EINVAL;
> +				goto conversion_failed;
> +			}
> +			if (*io_base != (resource_size_t)OF_BAD_ADDR)
> +				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
> +					dev->full_name);
> +			*io_base = range.cpu_addr;
> +		}
> +
> +		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
> +	}
> +
> +	return 0;
> +
> +conversion_failed:
> +	kfree(res);
> +parse_failed:
> +	pci_free_resource_list(resources);
> +	return err;
> +}
> +EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
> +#endif /* CONFIG_OF_ADDRESS */
> +
>  #ifdef CONFIG_PCI_MSI
>  
>  static LIST_HEAD(of_pci_msi_chip_list);
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index 71062e9..1fd207e 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -52,6 +52,12 @@ of_get_pci_domain_nr(struct device_node *node)
>  }
>  #endif
>  
> +#if defined(CONFIG_OF_ADDRESS)
> +int of_pci_get_host_bridge_resources(struct device_node *dev,
> +			unsigned char busno, unsigned char bus_max,
> +			struct list_head *resources, resource_size_t *io_base);
> +#endif
> +
>  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
>  int of_pci_msi_chip_add(struct msi_chip *chip);
>  void of_pci_msi_chip_remove(struct msi_chip *chip);
> -- 
> 2.1.0
> 
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
@ 2014-09-24 17:31       ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-24 17:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> Provide a function to parse the PCI DT ranges that can be used to
> create a pci_host_bridge structure together with its associated
> bus.
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> [make io_base parameter optional]
> Signed-off-by: Robert Richter <rrichter@cavium.com>
> ---
> Hi Bjorn,
> 
> I have fixed the compilation error that this patch was triggering. I
> have validated that the patch applies to your pci/host-generic branch
> as well as to my series.

I applied this to pci/host-generic along with the following patches and
pushed the branch, thanks!

Bjorn

>  drivers/of/of_pci.c    | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_pci.h |   6 +++
>  2 files changed, 123 insertions(+)
> 
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 82d172f..3cad1af 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -1,7 +1,9 @@
>  #include <linux/kernel.h>
>  #include <linux/export.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/of_pci.h>
> +#include <linux/slab.h>
>  
>  static inline int __of_pci_pci_compare(struct device_node *node,
>  				       unsigned int data)
> @@ -114,6 +116,121 @@ int of_get_pci_domain_nr(struct device_node *node)
>  }
>  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>  
> +#if defined(CONFIG_OF_ADDRESS)
> +/**
> + * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
> + * @dev: device node of the host bridge having the range property
> + * @busno: bus number associated with the bridge root bus
> + * @bus_max: maximum number of busses for this bridge
> + * @resources: list where the range of resources will be added after DT parsing
> + * @io_base: pointer to a variable that will contain on return the physical
> + * address for the start of the I/O range. Can be NULL if the caller doesn't
> + * expect IO ranges to be present in the device tree.
> + *
> + * It is the callers job to free the @resources list.
> + *
> + * This function will parse the "ranges" property of a PCI host bridge device
> + * node and setup the resource mapping based on its content. It is expected
> + * that the property conforms with the Power ePAPR document.
> + *
> + * It returns zero if the range parsing has been successful or a standard error
> + * value if it failed.
> + */
> +int of_pci_get_host_bridge_resources(struct device_node *dev,
> +			unsigned char busno, unsigned char bus_max,
> +			struct list_head *resources, resource_size_t *io_base)
> +{
> +	struct resource *res;
> +	struct resource *bus_range;
> +	struct of_pci_range range;
> +	struct of_pci_range_parser parser;
> +	char range_type[4];
> +	int err;
> +
> +	if (io_base)
> +		*io_base = (resource_size_t)OF_BAD_ADDR;
> +
> +	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
> +	if (!bus_range)
> +		return -ENOMEM;
> +
> +	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
> +
> +	err = of_pci_parse_bus_range(dev, bus_range);
> +	if (err) {
> +		bus_range->start = busno;
> +		bus_range->end = bus_max;
> +		bus_range->flags = IORESOURCE_BUS;
> +		pr_info("  No bus range found for %s, using %pR\n",
> +			dev->full_name, bus_range);
> +	} else {
> +		if (bus_range->end > bus_range->start + bus_max)
> +			bus_range->end = bus_range->start + bus_max;
> +	}
> +	pci_add_resource(resources, bus_range);
> +
> +	/* Check for ranges property */
> +	err = of_pci_range_parser_init(&parser, dev);
> +	if (err)
> +		goto parse_failed;
> +
> +	pr_debug("Parsing ranges property...\n");
> +	for_each_of_pci_range(&parser, &range) {
> +		/* Read next ranges element */
> +		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
> +			snprintf(range_type, 4, " IO");
> +		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
> +			snprintf(range_type, 4, "MEM");
> +		else
> +			snprintf(range_type, 4, "err");
> +		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
> +			range.cpu_addr, range.cpu_addr + range.size - 1,
> +			range.pci_addr);
> +
> +		/*
> +		 * If we failed translation or got a zero-sized region
> +		 * then skip this range
> +		 */
> +		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
> +			continue;
> +
> +		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
> +		if (!res) {
> +			err = -ENOMEM;
> +			goto parse_failed;
> +		}
> +
> +		err = of_pci_range_to_resource(&range, dev, res);
> +		if (err)
> +			goto conversion_failed;
> +
> +		if (resource_type(res) == IORESOURCE_IO) {
> +			if (!io_base) {
> +				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
> +					dev->full_name);
> +				err = -EINVAL;
> +				goto conversion_failed;
> +			}
> +			if (*io_base != (resource_size_t)OF_BAD_ADDR)
> +				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
> +					dev->full_name);
> +			*io_base = range.cpu_addr;
> +		}
> +
> +		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
> +	}
> +
> +	return 0;
> +
> +conversion_failed:
> +	kfree(res);
> +parse_failed:
> +	pci_free_resource_list(resources);
> +	return err;
> +}
> +EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
> +#endif /* CONFIG_OF_ADDRESS */
> +
>  #ifdef CONFIG_PCI_MSI
>  
>  static LIST_HEAD(of_pci_msi_chip_list);
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index 71062e9..1fd207e 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -52,6 +52,12 @@ of_get_pci_domain_nr(struct device_node *node)
>  }
>  #endif
>  
> +#if defined(CONFIG_OF_ADDRESS)
> +int of_pci_get_host_bridge_resources(struct device_node *dev,
> +			unsigned char busno, unsigned char bus_max,
> +			struct list_head *resources, resource_size_t *io_base);
> +#endif
> +
>  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
>  int of_pci_msi_chip_add(struct msi_chip *chip);
>  void of_pci_msi_chip_remove(struct msi_chip *chip);
> -- 
> 2.1.0
> 
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
  2014-09-24 17:31       ` Bjorn Helgaas
@ 2014-09-24 17:53         ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24 17:53 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	grant.likely, Robert Richter

On Wed, Sep 24, 2014 at 06:31:09PM +0100, Bjorn Helgaas wrote:
> On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> > Provide a function to parse the PCI DT ranges that can be used to
> > create a pci_host_bridge structure together with its associated
> > bus.
> > 
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > [make io_base parameter optional]
> > Signed-off-by: Robert Richter <rrichter@cavium.com>
> > ---
> > Hi Bjorn,
> > 
> > I have fixed the compilation error that this patch was triggering. I
> > have validated that the patch applies to your pci/host-generic branch
> > as well as to my series.
> 
> I applied this to pci/host-generic along with the following patches and
> pushed the branch, thanks!

Thanks again and sorry for lack of thorough testing. I still haven't managed
to get a cross compiler for sparc and as I don't run Ubuntu or debian the
make.cross script doesn't work for me.

Best regards,
Liviu

> 
> Bjorn
> 
> >  drivers/of/of_pci.c    | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/of_pci.h |   6 +++
> >  2 files changed, 123 insertions(+)
> > 
> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> > index 82d172f..3cad1af 100644
> > --- a/drivers/of/of_pci.c
> > +++ b/drivers/of/of_pci.c
> > @@ -1,7 +1,9 @@
> >  #include <linux/kernel.h>
> >  #include <linux/export.h>
> >  #include <linux/of.h>
> > +#include <linux/of_address.h>
> >  #include <linux/of_pci.h>
> > +#include <linux/slab.h>
> >  
> >  static inline int __of_pci_pci_compare(struct device_node *node,
> >  				       unsigned int data)
> > @@ -114,6 +116,121 @@ int of_get_pci_domain_nr(struct device_node *node)
> >  }
> >  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
> >  
> > +#if defined(CONFIG_OF_ADDRESS)
> > +/**
> > + * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
> > + * @dev: device node of the host bridge having the range property
> > + * @busno: bus number associated with the bridge root bus
> > + * @bus_max: maximum number of busses for this bridge
> > + * @resources: list where the range of resources will be added after DT parsing
> > + * @io_base: pointer to a variable that will contain on return the physical
> > + * address for the start of the I/O range. Can be NULL if the caller doesn't
> > + * expect IO ranges to be present in the device tree.
> > + *
> > + * It is the callers job to free the @resources list.
> > + *
> > + * This function will parse the "ranges" property of a PCI host bridge device
> > + * node and setup the resource mapping based on its content. It is expected
> > + * that the property conforms with the Power ePAPR document.
> > + *
> > + * It returns zero if the range parsing has been successful or a standard error
> > + * value if it failed.
> > + */
> > +int of_pci_get_host_bridge_resources(struct device_node *dev,
> > +			unsigned char busno, unsigned char bus_max,
> > +			struct list_head *resources, resource_size_t *io_base)
> > +{
> > +	struct resource *res;
> > +	struct resource *bus_range;
> > +	struct of_pci_range range;
> > +	struct of_pci_range_parser parser;
> > +	char range_type[4];
> > +	int err;
> > +
> > +	if (io_base)
> > +		*io_base = (resource_size_t)OF_BAD_ADDR;
> > +
> > +	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
> > +	if (!bus_range)
> > +		return -ENOMEM;
> > +
> > +	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
> > +
> > +	err = of_pci_parse_bus_range(dev, bus_range);
> > +	if (err) {
> > +		bus_range->start = busno;
> > +		bus_range->end = bus_max;
> > +		bus_range->flags = IORESOURCE_BUS;
> > +		pr_info("  No bus range found for %s, using %pR\n",
> > +			dev->full_name, bus_range);
> > +	} else {
> > +		if (bus_range->end > bus_range->start + bus_max)
> > +			bus_range->end = bus_range->start + bus_max;
> > +	}
> > +	pci_add_resource(resources, bus_range);
> > +
> > +	/* Check for ranges property */
> > +	err = of_pci_range_parser_init(&parser, dev);
> > +	if (err)
> > +		goto parse_failed;
> > +
> > +	pr_debug("Parsing ranges property...\n");
> > +	for_each_of_pci_range(&parser, &range) {
> > +		/* Read next ranges element */
> > +		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
> > +			snprintf(range_type, 4, " IO");
> > +		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
> > +			snprintf(range_type, 4, "MEM");
> > +		else
> > +			snprintf(range_type, 4, "err");
> > +		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
> > +			range.cpu_addr, range.cpu_addr + range.size - 1,
> > +			range.pci_addr);
> > +
> > +		/*
> > +		 * If we failed translation or got a zero-sized region
> > +		 * then skip this range
> > +		 */
> > +		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
> > +			continue;
> > +
> > +		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
> > +		if (!res) {
> > +			err = -ENOMEM;
> > +			goto parse_failed;
> > +		}
> > +
> > +		err = of_pci_range_to_resource(&range, dev, res);
> > +		if (err)
> > +			goto conversion_failed;
> > +
> > +		if (resource_type(res) == IORESOURCE_IO) {
> > +			if (!io_base) {
> > +				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
> > +					dev->full_name);
> > +				err = -EINVAL;
> > +				goto conversion_failed;
> > +			}
> > +			if (*io_base != (resource_size_t)OF_BAD_ADDR)
> > +				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
> > +					dev->full_name);
> > +			*io_base = range.cpu_addr;
> > +		}
> > +
> > +		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
> > +	}
> > +
> > +	return 0;
> > +
> > +conversion_failed:
> > +	kfree(res);
> > +parse_failed:
> > +	pci_free_resource_list(resources);
> > +	return err;
> > +}
> > +EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
> > +#endif /* CONFIG_OF_ADDRESS */
> > +
> >  #ifdef CONFIG_PCI_MSI
> >  
> >  static LIST_HEAD(of_pci_msi_chip_list);
> > diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> > index 71062e9..1fd207e 100644
> > --- a/include/linux/of_pci.h
> > +++ b/include/linux/of_pci.h
> > @@ -52,6 +52,12 @@ of_get_pci_domain_nr(struct device_node *node)
> >  }
> >  #endif
> >  
> > +#if defined(CONFIG_OF_ADDRESS)
> > +int of_pci_get_host_bridge_resources(struct device_node *dev,
> > +			unsigned char busno, unsigned char bus_max,
> > +			struct list_head *resources, resource_size_t *io_base);
> > +#endif
> > +
> >  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
> >  int of_pci_msi_chip_add(struct msi_chip *chip);
> >  void of_pci_msi_chip_remove(struct msi_chip *chip);
> > -- 
> > 2.1.0
> > 
> > 
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
@ 2014-09-24 17:53         ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-24 17:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 06:31:09PM +0100, Bjorn Helgaas wrote:
> On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> > Provide a function to parse the PCI DT ranges that can be used to
> > create a pci_host_bridge structure together with its associated
> > bus.
> > 
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > [make io_base parameter optional]
> > Signed-off-by: Robert Richter <rrichter@cavium.com>
> > ---
> > Hi Bjorn,
> > 
> > I have fixed the compilation error that this patch was triggering. I
> > have validated that the patch applies to your pci/host-generic branch
> > as well as to my series.
> 
> I applied this to pci/host-generic along with the following patches and
> pushed the branch, thanks!

Thanks again and sorry for lack of thorough testing. I still haven't managed
to get a cross compiler for sparc and as I don't run Ubuntu or debian the
make.cross script doesn't work for me.

Best regards,
Liviu

> 
> Bjorn
> 
> >  drivers/of/of_pci.c    | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/of_pci.h |   6 +++
> >  2 files changed, 123 insertions(+)
> > 
> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> > index 82d172f..3cad1af 100644
> > --- a/drivers/of/of_pci.c
> > +++ b/drivers/of/of_pci.c
> > @@ -1,7 +1,9 @@
> >  #include <linux/kernel.h>
> >  #include <linux/export.h>
> >  #include <linux/of.h>
> > +#include <linux/of_address.h>
> >  #include <linux/of_pci.h>
> > +#include <linux/slab.h>
> >  
> >  static inline int __of_pci_pci_compare(struct device_node *node,
> >  				       unsigned int data)
> > @@ -114,6 +116,121 @@ int of_get_pci_domain_nr(struct device_node *node)
> >  }
> >  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
> >  
> > +#if defined(CONFIG_OF_ADDRESS)
> > +/**
> > + * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
> > + * @dev: device node of the host bridge having the range property
> > + * @busno: bus number associated with the bridge root bus
> > + * @bus_max: maximum number of busses for this bridge
> > + * @resources: list where the range of resources will be added after DT parsing
> > + * @io_base: pointer to a variable that will contain on return the physical
> > + * address for the start of the I/O range. Can be NULL if the caller doesn't
> > + * expect IO ranges to be present in the device tree.
> > + *
> > + * It is the callers job to free the @resources list.
> > + *
> > + * This function will parse the "ranges" property of a PCI host bridge device
> > + * node and setup the resource mapping based on its content. It is expected
> > + * that the property conforms with the Power ePAPR document.
> > + *
> > + * It returns zero if the range parsing has been successful or a standard error
> > + * value if it failed.
> > + */
> > +int of_pci_get_host_bridge_resources(struct device_node *dev,
> > +			unsigned char busno, unsigned char bus_max,
> > +			struct list_head *resources, resource_size_t *io_base)
> > +{
> > +	struct resource *res;
> > +	struct resource *bus_range;
> > +	struct of_pci_range range;
> > +	struct of_pci_range_parser parser;
> > +	char range_type[4];
> > +	int err;
> > +
> > +	if (io_base)
> > +		*io_base = (resource_size_t)OF_BAD_ADDR;
> > +
> > +	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
> > +	if (!bus_range)
> > +		return -ENOMEM;
> > +
> > +	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
> > +
> > +	err = of_pci_parse_bus_range(dev, bus_range);
> > +	if (err) {
> > +		bus_range->start = busno;
> > +		bus_range->end = bus_max;
> > +		bus_range->flags = IORESOURCE_BUS;
> > +		pr_info("  No bus range found for %s, using %pR\n",
> > +			dev->full_name, bus_range);
> > +	} else {
> > +		if (bus_range->end > bus_range->start + bus_max)
> > +			bus_range->end = bus_range->start + bus_max;
> > +	}
> > +	pci_add_resource(resources, bus_range);
> > +
> > +	/* Check for ranges property */
> > +	err = of_pci_range_parser_init(&parser, dev);
> > +	if (err)
> > +		goto parse_failed;
> > +
> > +	pr_debug("Parsing ranges property...\n");
> > +	for_each_of_pci_range(&parser, &range) {
> > +		/* Read next ranges element */
> > +		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
> > +			snprintf(range_type, 4, " IO");
> > +		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
> > +			snprintf(range_type, 4, "MEM");
> > +		else
> > +			snprintf(range_type, 4, "err");
> > +		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
> > +			range.cpu_addr, range.cpu_addr + range.size - 1,
> > +			range.pci_addr);
> > +
> > +		/*
> > +		 * If we failed translation or got a zero-sized region
> > +		 * then skip this range
> > +		 */
> > +		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
> > +			continue;
> > +
> > +		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
> > +		if (!res) {
> > +			err = -ENOMEM;
> > +			goto parse_failed;
> > +		}
> > +
> > +		err = of_pci_range_to_resource(&range, dev, res);
> > +		if (err)
> > +			goto conversion_failed;
> > +
> > +		if (resource_type(res) == IORESOURCE_IO) {
> > +			if (!io_base) {
> > +				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
> > +					dev->full_name);
> > +				err = -EINVAL;
> > +				goto conversion_failed;
> > +			}
> > +			if (*io_base != (resource_size_t)OF_BAD_ADDR)
> > +				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
> > +					dev->full_name);
> > +			*io_base = range.cpu_addr;
> > +		}
> > +
> > +		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
> > +	}
> > +
> > +	return 0;
> > +
> > +conversion_failed:
> > +	kfree(res);
> > +parse_failed:
> > +	pci_free_resource_list(resources);
> > +	return err;
> > +}
> > +EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
> > +#endif /* CONFIG_OF_ADDRESS */
> > +
> >  #ifdef CONFIG_PCI_MSI
> >  
> >  static LIST_HEAD(of_pci_msi_chip_list);
> > diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> > index 71062e9..1fd207e 100644
> > --- a/include/linux/of_pci.h
> > +++ b/include/linux/of_pci.h
> > @@ -52,6 +52,12 @@ of_get_pci_domain_nr(struct device_node *node)
> >  }
> >  #endif
> >  
> > +#if defined(CONFIG_OF_ADDRESS)
> > +int of_pci_get_host_bridge_resources(struct device_node *dev,
> > +			unsigned char busno, unsigned char bus_max,
> > +			struct list_head *resources, resource_size_t *io_base);
> > +#endif
> > +
> >  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
> >  int of_pci_msi_chip_add(struct msi_chip *chip);
> >  void of_pci_msi_chip_remove(struct msi_chip *chip);
> > -- 
> > 2.1.0
> > 
> > 
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
  2014-09-24 17:53         ` Liviu Dudau
@ 2014-09-24 18:01           ` Will Deacon
  -1 siblings, 0 replies; 101+ messages in thread
From: Will Deacon @ 2014-09-24 18:01 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Russell King, linux-pci,
	Linus Walleij, Tanmay Inamdar, Grant Likely, Sinan Kaya,
	Jingoo Han, Kukjin Kim, Suravee Suthikulanit, linux-arch, LKML,
	Device Tree ML, LAKML, grant.likely, Robert Richter

On Wed, Sep 24, 2014 at 06:53:31PM +0100, Liviu Dudau wrote:
> On Wed, Sep 24, 2014 at 06:31:09PM +0100, Bjorn Helgaas wrote:
> > On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> > > Provide a function to parse the PCI DT ranges that can be used to
> > > create a pci_host_bridge structure together with its associated
> > > bus.
> > > 
> > > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: Grant Likely <grant.likely@linaro.org>
> > > Cc: Rob Herring <robh+dt@kernel.org>
> > > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > > [make io_base parameter optional]
> > > Signed-off-by: Robert Richter <rrichter@cavium.com>
> > > ---
> > > Hi Bjorn,
> > > 
> > > I have fixed the compilation error that this patch was triggering. I
> > > have validated that the patch applies to your pci/host-generic branch
> > > as well as to my series.
> > 
> > I applied this to pci/host-generic along with the following patches and
> > pushed the branch, thanks!
> 
> Thanks again and sorry for lack of thorough testing. I still haven't managed
> to get a cross compiler for sparc and as I don't run Ubuntu or debian the
> make.cross script doesn't work for me.

  https://www.kernel.org/pub/tools/crosstool/

No libc, but good enough for building the kernel. I've asked for an aarch64
compiler there for a while, but it didn't materialise for some reason.

Will

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
@ 2014-09-24 18:01           ` Will Deacon
  0 siblings, 0 replies; 101+ messages in thread
From: Will Deacon @ 2014-09-24 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 06:53:31PM +0100, Liviu Dudau wrote:
> On Wed, Sep 24, 2014 at 06:31:09PM +0100, Bjorn Helgaas wrote:
> > On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> > > Provide a function to parse the PCI DT ranges that can be used to
> > > create a pci_host_bridge structure together with its associated
> > > bus.
> > > 
> > > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: Grant Likely <grant.likely@linaro.org>
> > > Cc: Rob Herring <robh+dt@kernel.org>
> > > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > > [make io_base parameter optional]
> > > Signed-off-by: Robert Richter <rrichter@cavium.com>
> > > ---
> > > Hi Bjorn,
> > > 
> > > I have fixed the compilation error that this patch was triggering. I
> > > have validated that the patch applies to your pci/host-generic branch
> > > as well as to my series.
> > 
> > I applied this to pci/host-generic along with the following patches and
> > pushed the branch, thanks!
> 
> Thanks again and sorry for lack of thorough testing. I still haven't managed
> to get a cross compiler for sparc and as I don't run Ubuntu or debian the
> make.cross script doesn't work for me.

  https://www.kernel.org/pub/tools/crosstool/

No libc, but good enough for building the kernel. I've asked for an aarch64
compiler there for a while, but it didn't materialise for some reason.

Will

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
  2014-09-24 18:01           ` Will Deacon
@ 2014-09-25  8:54             ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-25  8:54 UTC (permalink / raw)
  To: Will Deacon
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Russell King, linux-pci,
	Linus Walleij, Tanmay Inamdar, Grant Likely, Sinan Kaya,
	Jingoo Han, Kukjin Kim, Suravee Suthikulanit, linux-arch, LKML,
	Device Tree ML, LAKML, grant.likely, Robert Richter

On Wed, Sep 24, 2014 at 07:01:19PM +0100, Will Deacon wrote:
> On Wed, Sep 24, 2014 at 06:53:31PM +0100, Liviu Dudau wrote:
> > On Wed, Sep 24, 2014 at 06:31:09PM +0100, Bjorn Helgaas wrote:
> > > On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> > > > Provide a function to parse the PCI DT ranges that can be used to
> > > > create a pci_host_bridge structure together with its associated
> > > > bus.
> > > > 
> > > > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > > Cc: Grant Likely <grant.likely@linaro.org>
> > > > Cc: Rob Herring <robh+dt@kernel.org>
> > > > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > > > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > > > [make io_base parameter optional]
> > > > Signed-off-by: Robert Richter <rrichter@cavium.com>
> > > > ---
> > > > Hi Bjorn,
> > > > 
> > > > I have fixed the compilation error that this patch was triggering. I
> > > > have validated that the patch applies to your pci/host-generic branch
> > > > as well as to my series.
> > > 
> > > I applied this to pci/host-generic along with the following patches and
> > > pushed the branch, thanks!
> > 
> > Thanks again and sorry for lack of thorough testing. I still haven't managed
> > to get a cross compiler for sparc and as I don't run Ubuntu or debian the
> > make.cross script doesn't work for me.
> 
>   https://www.kernel.org/pub/tools/crosstool/
> 
> No libc, but good enough for building the kernel. I've asked for an aarch64
> compiler there for a while, but it didn't materialise for some reason.

I'm familiar with crosstool and busybox uses a variant of crosstool-ng, but
it currently fails with "configure: error: cannot compute suffix of object files: cannot compile"
on the stage2 of the compilation.

Best regards,
Liviu

> 
> Will
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
@ 2014-09-25  8:54             ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-25  8:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 07:01:19PM +0100, Will Deacon wrote:
> On Wed, Sep 24, 2014 at 06:53:31PM +0100, Liviu Dudau wrote:
> > On Wed, Sep 24, 2014 at 06:31:09PM +0100, Bjorn Helgaas wrote:
> > > On Wed, Sep 24, 2014 at 05:43:04PM +0100, Liviu Dudau wrote:
> > > > Provide a function to parse the PCI DT ranges that can be used to
> > > > create a pci_host_bridge structure together with its associated
> > > > bus.
> > > > 
> > > > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > > Cc: Grant Likely <grant.likely@linaro.org>
> > > > Cc: Rob Herring <robh+dt@kernel.org>
> > > > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > > > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> > > > [make io_base parameter optional]
> > > > Signed-off-by: Robert Richter <rrichter@cavium.com>
> > > > ---
> > > > Hi Bjorn,
> > > > 
> > > > I have fixed the compilation error that this patch was triggering. I
> > > > have validated that the patch applies to your pci/host-generic branch
> > > > as well as to my series.
> > > 
> > > I applied this to pci/host-generic along with the following patches and
> > > pushed the branch, thanks!
> > 
> > Thanks again and sorry for lack of thorough testing. I still haven't managed
> > to get a cross compiler for sparc and as I don't run Ubuntu or debian the
> > make.cross script doesn't work for me.
> 
>   https://www.kernel.org/pub/tools/crosstool/
> 
> No libc, but good enough for building the kernel. I've asked for an aarch64
> compiler there for a while, but it didn't materialise for some reason.

I'm familiar with crosstool and busybox uses a variant of crosstool-ng, but
it currently fails with "configure: error: cannot compute suffix of object files: cannot compile"
on the stage2 of the compilation.

Best regards,
Liviu

> 
> Will
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
  2014-09-25  8:54             ` Liviu Dudau
@ 2014-09-25  9:04               ` Will Deacon
  -1 siblings, 0 replies; 101+ messages in thread
From: Will Deacon @ 2014-09-25  9:04 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Russell King, linux-pci,
	Linus Walleij, Tanmay Inamdar, Grant Likely, Sinan Kaya,
	Jingoo Han, Kukjin Kim, Suravee Suthikulanit, linux-arch, LKML,
	Device Tree ML, LAKML, grant.likely, Robert Richter

On Thu, Sep 25, 2014 at 09:54:32AM +0100, Liviu Dudau wrote:
> On Wed, Sep 24, 2014 at 07:01:19PM +0100, Will Deacon wrote:
> > On Wed, Sep 24, 2014 at 06:53:31PM +0100, Liviu Dudau wrote:
> > > Thanks again and sorry for lack of thorough testing. I still haven't managed
> > > to get a cross compiler for sparc and as I don't run Ubuntu or debian the
> > > make.cross script doesn't work for me.
> > 
> >   https://www.kernel.org/pub/tools/crosstool/
> > 
> > No libc, but good enough for building the kernel. I've asked for an aarch64
> > compiler there for a while, but it didn't materialise for some reason.
> 
> I'm familiar with crosstool and busybox uses a variant of crosstool-ng, but
> it currently fails with "configure: error: cannot compute suffix of object files: cannot compile"
> on the stage2 of the compilation.

Did you even follow the link? There are binary toolchains hosted there --
you don't have to build anything yourself if you don't want to.

Will

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT
@ 2014-09-25  9:04               ` Will Deacon
  0 siblings, 0 replies; 101+ messages in thread
From: Will Deacon @ 2014-09-25  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 25, 2014 at 09:54:32AM +0100, Liviu Dudau wrote:
> On Wed, Sep 24, 2014 at 07:01:19PM +0100, Will Deacon wrote:
> > On Wed, Sep 24, 2014 at 06:53:31PM +0100, Liviu Dudau wrote:
> > > Thanks again and sorry for lack of thorough testing. I still haven't managed
> > > to get a cross compiler for sparc and as I don't run Ubuntu or debian the
> > > make.cross script doesn't work for me.
> > 
> >   https://www.kernel.org/pub/tools/crosstool/
> > 
> > No libc, but good enough for building the kernel. I've asked for an aarch64
> > compiler there for a while, but it didn't materialise for some reason.
> 
> I'm familiar with crosstool and busybox uses a variant of crosstool-ng, but
> it currently fails with "configure: error: cannot compute suffix of object files: cannot compile"
> on the stage2 of the compilation.

Did you even follow the link? There are binary toolchains hosted there --
you don't have to build anything yourself if you don't want to.

Will

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
  2014-09-23 19:01   ` Liviu Dudau
@ 2014-09-25 18:15     ` Yinghai Lu
  -1 siblings, 0 replies; 101+ messages in thread
From: Yinghai Lu @ 2014-09-25 18:15 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
> the creation order has been changed for no good reason. Revert the order of
> creation as we are going to depend on the pci_host_bridge structure to retrieve the
> domain number of the root bus.
>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> Acked-by: Grant Likely <grant.likely@linaro.org>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
> ---
>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
>  1 file changed, 17 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index e3cf8a2..5ff72ec 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
>         kfree(bridge);
>  }
>
> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
>  {
>         struct pci_host_bridge *bridge;
>
> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>                 return NULL;
>
>         INIT_LIST_HEAD(&bridge->windows);
> -       bridge->bus = b;
> +       bridge->dev.release = pci_release_host_bridge_dev;
> +
>         return bridge;
>  }
>
> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>         char bus_addr[64];
>         char *fmt;
>
> +       bridge = pci_alloc_host_bridge();
> +       if (!bridge)
> +               return NULL;
> +
> +       bridge->dev.parent = parent;
> +
>         b = pci_alloc_bus();
>         if (!b)
> -               return NULL;
> +               goto err_out;
>
>         b->sysdata = sysdata;
>         b->ops = ops;
> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>         if (b2) {
>                 /* If we already got to this bus through a different bridge, ignore it */
>                 dev_dbg(&b2->dev, "bus already known\n");
> -               goto err_out;
> +               goto err_bus_out;
>         }
>
> -       bridge = pci_alloc_host_bridge(b);
> -       if (!bridge)
> -               goto err_out;
> -
> -       bridge->dev.parent = parent;
> -       bridge->dev.release = pci_release_host_bridge_dev;
> +       bridge->bus = b;
>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
>         error = pcibios_root_bridge_prepare(bridge);
> -       if (error) {
> -               kfree(bridge);
> +       if (error)
>                 goto err_out;
> -       }
>
>         error = device_register(&bridge->dev);
>         if (error) {
>                 put_device(&bridge->dev);
> -               goto err_out;
> +               goto err_bus_out;
>         }
>         b->bridge = get_device(&bridge->dev);
>         device_enable_async_suspend(b->bridge);
> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  class_dev_reg_err:
>         put_device(&bridge->dev);
>         device_unregister(&bridge->dev);
> -err_out:
> +err_bus_out:
>         kfree(b);
> +err_out:
> +       kfree(bridge);
>         return NULL;
>  }

Hi Bjorn,

Noticed that you put this one into pci/next.

This patch has problem for the class_dev_reg_err path.
as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
So will have double free for bridge or else.

Please drop this patch from pci/next.

Also looks strange that the patch have long CC list, but just omit me
and Jiang Liu that
touched those code before.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
@ 2014-09-25 18:15     ` Yinghai Lu
  0 siblings, 0 replies; 101+ messages in thread
From: Yinghai Lu @ 2014-09-25 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
> the creation order has been changed for no good reason. Revert the order of
> creation as we are going to depend on the pci_host_bridge structure to retrieve the
> domain number of the root bus.
>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> Acked-by: Grant Likely <grant.likely@linaro.org>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
> ---
>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
>  1 file changed, 17 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index e3cf8a2..5ff72ec 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
>         kfree(bridge);
>  }
>
> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
>  {
>         struct pci_host_bridge *bridge;
>
> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>                 return NULL;
>
>         INIT_LIST_HEAD(&bridge->windows);
> -       bridge->bus = b;
> +       bridge->dev.release = pci_release_host_bridge_dev;
> +
>         return bridge;
>  }
>
> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>         char bus_addr[64];
>         char *fmt;
>
> +       bridge = pci_alloc_host_bridge();
> +       if (!bridge)
> +               return NULL;
> +
> +       bridge->dev.parent = parent;
> +
>         b = pci_alloc_bus();
>         if (!b)
> -               return NULL;
> +               goto err_out;
>
>         b->sysdata = sysdata;
>         b->ops = ops;
> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>         if (b2) {
>                 /* If we already got to this bus through a different bridge, ignore it */
>                 dev_dbg(&b2->dev, "bus already known\n");
> -               goto err_out;
> +               goto err_bus_out;
>         }
>
> -       bridge = pci_alloc_host_bridge(b);
> -       if (!bridge)
> -               goto err_out;
> -
> -       bridge->dev.parent = parent;
> -       bridge->dev.release = pci_release_host_bridge_dev;
> +       bridge->bus = b;
>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
>         error = pcibios_root_bridge_prepare(bridge);
> -       if (error) {
> -               kfree(bridge);
> +       if (error)
>                 goto err_out;
> -       }
>
>         error = device_register(&bridge->dev);
>         if (error) {
>                 put_device(&bridge->dev);
> -               goto err_out;
> +               goto err_bus_out;
>         }
>         b->bridge = get_device(&bridge->dev);
>         device_enable_async_suspend(b->bridge);
> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  class_dev_reg_err:
>         put_device(&bridge->dev);
>         device_unregister(&bridge->dev);
> -err_out:
> +err_bus_out:
>         kfree(b);
> +err_out:
> +       kfree(bridge);
>         return NULL;
>  }

Hi Bjorn,

Noticed that you put this one into pci/next.

This patch has problem for the class_dev_reg_err path.
as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
So will have double free for bridge or else.

Please drop this patch from pci/next.

Also looks strange that the patch have long CC list, but just omit me
and Jiang Liu that
touched those code before.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
  2014-09-25 18:15     ` Yinghai Lu
@ 2014-09-25 19:59       ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-25 19:59 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Thu, Sep 25, 2014 at 12:15 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
>> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
>> the creation order has been changed for no good reason. Revert the order of
>> creation as we are going to depend on the pci_host_bridge structure to retrieve the
>> domain number of the root bus.
>>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> Acked-by: Grant Likely <grant.likely@linaro.org>
>> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
>> ---
>>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
>>  1 file changed, 17 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index e3cf8a2..5ff72ec 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
>>         kfree(bridge);
>>  }
>>
>> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
>>  {
>>         struct pci_host_bridge *bridge;
>>
>> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>>                 return NULL;
>>
>>         INIT_LIST_HEAD(&bridge->windows);
>> -       bridge->bus = b;
>> +       bridge->dev.release = pci_release_host_bridge_dev;
>> +
>>         return bridge;
>>  }
>>
>> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>         char bus_addr[64];
>>         char *fmt;
>>
>> +       bridge = pci_alloc_host_bridge();
>> +       if (!bridge)
>> +               return NULL;
>> +
>> +       bridge->dev.parent = parent;
>> +
>>         b = pci_alloc_bus();
>>         if (!b)
>> -               return NULL;
>> +               goto err_out;
>>
>>         b->sysdata = sysdata;
>>         b->ops = ops;
>> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>         if (b2) {
>>                 /* If we already got to this bus through a different bridge, ignore it */
>>                 dev_dbg(&b2->dev, "bus already known\n");
>> -               goto err_out;
>> +               goto err_bus_out;
>>         }
>>
>> -       bridge = pci_alloc_host_bridge(b);
>> -       if (!bridge)
>> -               goto err_out;
>> -
>> -       bridge->dev.parent = parent;
>> -       bridge->dev.release = pci_release_host_bridge_dev;
>> +       bridge->bus = b;
>>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
>>         error = pcibios_root_bridge_prepare(bridge);
>> -       if (error) {
>> -               kfree(bridge);
>> +       if (error)
>>                 goto err_out;
>> -       }
>>
>>         error = device_register(&bridge->dev);
>>         if (error) {
>>                 put_device(&bridge->dev);
>> -               goto err_out;
>> +               goto err_bus_out;
>>         }
>>         b->bridge = get_device(&bridge->dev);
>>         device_enable_async_suspend(b->bridge);
>> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>  class_dev_reg_err:
>>         put_device(&bridge->dev);
>>         device_unregister(&bridge->dev);
>> -err_out:
>> +err_bus_out:
>>         kfree(b);
>> +err_out:
>> +       kfree(bridge);
>>         return NULL;
>>  }
>
> Hi Bjorn,
>
> Noticed that you put this one into pci/next.
>
> This patch has problem for the class_dev_reg_err path.
> as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
> So will have double free for bridge or else.
>
> Please drop this patch from pci/next.
>
> Also looks strange that the patch have long CC list, but just omit me
> and Jiang Liu that
> touched those code before.

Thanks for noticing that.  I was concerned, but couldn't remember the details.

I dropped this patch and the subsequent ones from pci/host and rebased
my "next" branch.

Sorry I didn't notice you weren't on the CC list.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
@ 2014-09-25 19:59       ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-25 19:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 25, 2014 at 12:15 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
>> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
>> the creation order has been changed for no good reason. Revert the order of
>> creation as we are going to depend on the pci_host_bridge structure to retrieve the
>> domain number of the root bus.
>>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> Acked-by: Grant Likely <grant.likely@linaro.org>
>> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
>> ---
>>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
>>  1 file changed, 17 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index e3cf8a2..5ff72ec 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
>>         kfree(bridge);
>>  }
>>
>> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
>>  {
>>         struct pci_host_bridge *bridge;
>>
>> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>>                 return NULL;
>>
>>         INIT_LIST_HEAD(&bridge->windows);
>> -       bridge->bus = b;
>> +       bridge->dev.release = pci_release_host_bridge_dev;
>> +
>>         return bridge;
>>  }
>>
>> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>         char bus_addr[64];
>>         char *fmt;
>>
>> +       bridge = pci_alloc_host_bridge();
>> +       if (!bridge)
>> +               return NULL;
>> +
>> +       bridge->dev.parent = parent;
>> +
>>         b = pci_alloc_bus();
>>         if (!b)
>> -               return NULL;
>> +               goto err_out;
>>
>>         b->sysdata = sysdata;
>>         b->ops = ops;
>> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>         if (b2) {
>>                 /* If we already got to this bus through a different bridge, ignore it */
>>                 dev_dbg(&b2->dev, "bus already known\n");
>> -               goto err_out;
>> +               goto err_bus_out;
>>         }
>>
>> -       bridge = pci_alloc_host_bridge(b);
>> -       if (!bridge)
>> -               goto err_out;
>> -
>> -       bridge->dev.parent = parent;
>> -       bridge->dev.release = pci_release_host_bridge_dev;
>> +       bridge->bus = b;
>>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
>>         error = pcibios_root_bridge_prepare(bridge);
>> -       if (error) {
>> -               kfree(bridge);
>> +       if (error)
>>                 goto err_out;
>> -       }
>>
>>         error = device_register(&bridge->dev);
>>         if (error) {
>>                 put_device(&bridge->dev);
>> -               goto err_out;
>> +               goto err_bus_out;
>>         }
>>         b->bridge = get_device(&bridge->dev);
>>         device_enable_async_suspend(b->bridge);
>> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>  class_dev_reg_err:
>>         put_device(&bridge->dev);
>>         device_unregister(&bridge->dev);
>> -err_out:
>> +err_bus_out:
>>         kfree(b);
>> +err_out:
>> +       kfree(bridge);
>>         return NULL;
>>  }
>
> Hi Bjorn,
>
> Noticed that you put this one into pci/next.
>
> This patch has problem for the class_dev_reg_err path.
> as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
> So will have double free for bridge or else.
>
> Please drop this patch from pci/next.
>
> Also looks strange that the patch have long CC list, but just omit me
> and Jiang Liu that
> touched those code before.

Thanks for noticing that.  I was concerned, but couldn't remember the details.

I dropped this patch and the subsequent ones from pci/host and rebased
my "next" branch.

Sorry I didn't notice you weren't on the CC list.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
  2014-09-25 19:59       ` Bjorn Helgaas
@ 2014-09-26 14:58         ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-26 14:58 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Yinghai Lu, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Thu, Sep 25, 2014 at 08:59:26PM +0100, Bjorn Helgaas wrote:
> On Thu, Sep 25, 2014 at 12:15 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> > On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> >> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
> >> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
> >> the creation order has been changed for no good reason. Revert the order of
> >> creation as we are going to depend on the pci_host_bridge structure to retrieve the
> >> domain number of the root bus.
> >>
> >> Cc: Bjorn Helgaas <bhelgaas@google.com>
> >> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> >> Acked-by: Grant Likely <grant.likely@linaro.org>
> >> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> >> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
> >> ---
> >>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
> >>  1 file changed, 17 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> >> index e3cf8a2..5ff72ec 100644
> >> --- a/drivers/pci/probe.c
> >> +++ b/drivers/pci/probe.c
> >> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
> >>         kfree(bridge);
> >>  }
> >>
> >> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> >> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
> >>  {
> >>         struct pci_host_bridge *bridge;
> >>
> >> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> >>                 return NULL;
> >>
> >>         INIT_LIST_HEAD(&bridge->windows);
> >> -       bridge->bus = b;
> >> +       bridge->dev.release = pci_release_host_bridge_dev;
> >> +
> >>         return bridge;
> >>  }
> >>
> >> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> >>         char bus_addr[64];
> >>         char *fmt;
> >>
> >> +       bridge = pci_alloc_host_bridge();
> >> +       if (!bridge)
> >> +               return NULL;
> >> +
> >> +       bridge->dev.parent = parent;
> >> +
> >>         b = pci_alloc_bus();
> >>         if (!b)
> >> -               return NULL;
> >> +               goto err_out;
> >>
> >>         b->sysdata = sysdata;
> >>         b->ops = ops;
> >> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> >>         if (b2) {
> >>                 /* If we already got to this bus through a different bridge, ignore it */
> >>                 dev_dbg(&b2->dev, "bus already known\n");
> >> -               goto err_out;
> >> +               goto err_bus_out;
> >>         }
> >>
> >> -       bridge = pci_alloc_host_bridge(b);
> >> -       if (!bridge)
> >> -               goto err_out;
> >> -
> >> -       bridge->dev.parent = parent;
> >> -       bridge->dev.release = pci_release_host_bridge_dev;
> >> +       bridge->bus = b;
> >>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
> >>         error = pcibios_root_bridge_prepare(bridge);
> >> -       if (error) {
> >> -               kfree(bridge);
> >> +       if (error)
> >>                 goto err_out;
> >> -       }
> >>
> >>         error = device_register(&bridge->dev);
> >>         if (error) {
> >>                 put_device(&bridge->dev);
> >> -               goto err_out;
> >> +               goto err_bus_out;
> >>         }
> >>         b->bridge = get_device(&bridge->dev);
> >>         device_enable_async_suspend(b->bridge);
> >> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> >>  class_dev_reg_err:
> >>         put_device(&bridge->dev);
> >>         device_unregister(&bridge->dev);
> >> -err_out:
> >> +err_bus_out:
> >>         kfree(b);
> >> +err_out:
> >> +       kfree(bridge);
> >>         return NULL;
> >>  }
> >
> > Hi Bjorn,
> >
> > Noticed that you put this one into pci/next.
> >
> > This patch has problem for the class_dev_reg_err path.
> > as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
> > So will have double free for bridge or else.
> >
> > Please drop this patch from pci/next.
> >
> > Also looks strange that the patch have long CC list, but just omit me
> > and Jiang Liu that
> > touched those code before.
> 
> Thanks for noticing that.  I was concerned, but couldn't remember the details.
> 
> I dropped this patch and the subsequent ones from pci/host and rebased
> my "next" branch.
> 
> Sorry I didn't notice you weren't on the CC list.
> 
> Bjorn
> 

Bjorn,

I have refreshed/rebuilt the series from what was on 25th in linux-next and I have
dropped this patch. I have pushed the series into 

git://linux-arm.org/linux-ld.git for-upstream/pci-next

I hope that I've carried all your Sign-off-bys correctly, but I would like to ask you
to double check that I haven't screwed up things.

This patch dates from the times I was trying to add the domain number information
into the pci_host_bridge structure. Now, with Catalin's patch that adds the data in
the pci_bus structure, this is not needed, so it is safe to drop. I did try to fix
the patch but I've realised how intricately linked pci_host_bridge and root bus are,
which to my opinion is a strong hint that the creation of the two should be split
into separate functions.

I can send an official v13 patchset to the mailing list if you want, but if not, here
is the changelog:

- updated "[PATCH 01/12] asm-generic/io.h: Fix ioport_map() for !CONFIG_GENERIC_IOMAP" to match
  the patch that Thierry Reding has submitted through the asm-generic branch. If his
  series lands first upstream this patch will be skipped.
- updated "[PATCH 03/12] ARM: Define PCI_IOBASE as the base of virtual PCI IO space" to
  cast the PCI_IOBASE value to (void __iomem *) as is the case with most #defined versions
- dropped the patch that was changing the order of initialisation between pci_host_bridge
  and root bus in pci_create_root_bus()
- fixed "[PATCH 07/12] PCI: Add generic domain handling" to account for the previous patch
  being removed
- fixed the title of commit 08/12 to reflect the name of the functions that are actually
  added (s/of_pci_get_domain_nr/pci_get_new_domain_nr/)

I've compiled tested the series on sparc, microblaze (no)mmu_defconfig, arm omap2plus_defconfig
and multi_v7_defconfig and arm64. I've also tested the series on my Juno (arm64) board.

Sorry for causing this amount of churn! And to Yinghai Lu and Jiang Liu: appologies for not
including you in the Cc list, I'm still getting the grip on the whole submission process.

Best regards,
Liviu

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
@ 2014-09-26 14:58         ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-26 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 25, 2014 at 08:59:26PM +0100, Bjorn Helgaas wrote:
> On Thu, Sep 25, 2014 at 12:15 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> > On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> >> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
> >> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
> >> the creation order has been changed for no good reason. Revert the order of
> >> creation as we are going to depend on the pci_host_bridge structure to retrieve the
> >> domain number of the root bus.
> >>
> >> Cc: Bjorn Helgaas <bhelgaas@google.com>
> >> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> >> Acked-by: Grant Likely <grant.likely@linaro.org>
> >> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> >> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
> >> ---
> >>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
> >>  1 file changed, 17 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> >> index e3cf8a2..5ff72ec 100644
> >> --- a/drivers/pci/probe.c
> >> +++ b/drivers/pci/probe.c
> >> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
> >>         kfree(bridge);
> >>  }
> >>
> >> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> >> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
> >>  {
> >>         struct pci_host_bridge *bridge;
> >>
> >> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> >>                 return NULL;
> >>
> >>         INIT_LIST_HEAD(&bridge->windows);
> >> -       bridge->bus = b;
> >> +       bridge->dev.release = pci_release_host_bridge_dev;
> >> +
> >>         return bridge;
> >>  }
> >>
> >> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> >>         char bus_addr[64];
> >>         char *fmt;
> >>
> >> +       bridge = pci_alloc_host_bridge();
> >> +       if (!bridge)
> >> +               return NULL;
> >> +
> >> +       bridge->dev.parent = parent;
> >> +
> >>         b = pci_alloc_bus();
> >>         if (!b)
> >> -               return NULL;
> >> +               goto err_out;
> >>
> >>         b->sysdata = sysdata;
> >>         b->ops = ops;
> >> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> >>         if (b2) {
> >>                 /* If we already got to this bus through a different bridge, ignore it */
> >>                 dev_dbg(&b2->dev, "bus already known\n");
> >> -               goto err_out;
> >> +               goto err_bus_out;
> >>         }
> >>
> >> -       bridge = pci_alloc_host_bridge(b);
> >> -       if (!bridge)
> >> -               goto err_out;
> >> -
> >> -       bridge->dev.parent = parent;
> >> -       bridge->dev.release = pci_release_host_bridge_dev;
> >> +       bridge->bus = b;
> >>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
> >>         error = pcibios_root_bridge_prepare(bridge);
> >> -       if (error) {
> >> -               kfree(bridge);
> >> +       if (error)
> >>                 goto err_out;
> >> -       }
> >>
> >>         error = device_register(&bridge->dev);
> >>         if (error) {
> >>                 put_device(&bridge->dev);
> >> -               goto err_out;
> >> +               goto err_bus_out;
> >>         }
> >>         b->bridge = get_device(&bridge->dev);
> >>         device_enable_async_suspend(b->bridge);
> >> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
> >>  class_dev_reg_err:
> >>         put_device(&bridge->dev);
> >>         device_unregister(&bridge->dev);
> >> -err_out:
> >> +err_bus_out:
> >>         kfree(b);
> >> +err_out:
> >> +       kfree(bridge);
> >>         return NULL;
> >>  }
> >
> > Hi Bjorn,
> >
> > Noticed that you put this one into pci/next.
> >
> > This patch has problem for the class_dev_reg_err path.
> > as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
> > So will have double free for bridge or else.
> >
> > Please drop this patch from pci/next.
> >
> > Also looks strange that the patch have long CC list, but just omit me
> > and Jiang Liu that
> > touched those code before.
> 
> Thanks for noticing that.  I was concerned, but couldn't remember the details.
> 
> I dropped this patch and the subsequent ones from pci/host and rebased
> my "next" branch.
> 
> Sorry I didn't notice you weren't on the CC list.
> 
> Bjorn
> 

Bjorn,

I have refreshed/rebuilt the series from what was on 25th in linux-next and I have
dropped this patch. I have pushed the series into 

git://linux-arm.org/linux-ld.git for-upstream/pci-next

I hope that I've carried all your Sign-off-bys correctly, but I would like to ask you
to double check that I haven't screwed up things.

This patch dates from the times I was trying to add the domain number information
into the pci_host_bridge structure. Now, with Catalin's patch that adds the data in
the pci_bus structure, this is not needed, so it is safe to drop. I did try to fix
the patch but I've realised how intricately linked pci_host_bridge and root bus are,
which to my opinion is a strong hint that the creation of the two should be split
into separate functions.

I can send an official v13 patchset to the mailing list if you want, but if not, here
is the changelog:

- updated "[PATCH 01/12] asm-generic/io.h: Fix ioport_map() for !CONFIG_GENERIC_IOMAP" to match
  the patch that Thierry Reding has submitted through the asm-generic branch. If his
  series lands first upstream this patch will be skipped.
- updated "[PATCH 03/12] ARM: Define PCI_IOBASE as the base of virtual PCI IO space" to
  cast the PCI_IOBASE value to (void __iomem *) as is the case with most #defined versions
- dropped the patch that was changing the order of initialisation between pci_host_bridge
  and root bus in pci_create_root_bus()
- fixed "[PATCH 07/12] PCI: Add generic domain handling" to account for the previous patch
  being removed
- fixed the title of commit 08/12 to reflect the name of the functions that are actually
  added (s/of_pci_get_domain_nr/pci_get_new_domain_nr/)

I've compiled tested the series on sparc, microblaze (no)mmu_defconfig, arm omap2plus_defconfig
and multi_v7_defconfig and arm64. I've also tested the series on my Juno (arm64) board.

Sorry for causing this amount of churn! And to Yinghai Lu and Jiang Liu: appologies for not
including you in the Cc list, I'm still getting the grip on the whole submission process.

Best regards,
Liviu

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
  2014-09-26 14:58         ` Liviu Dudau
@ 2014-09-26 16:17           ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-26 16:17 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Yinghai Lu, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML

On Fri, Sep 26, 2014 at 8:58 AM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Thu, Sep 25, 2014 at 08:59:26PM +0100, Bjorn Helgaas wrote:
>> On Thu, Sep 25, 2014 at 12:15 PM, Yinghai Lu <yinghai@kernel.org> wrote:
>> > On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>> >> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
>> >> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
>> >> the creation order has been changed for no good reason. Revert the order of
>> >> creation as we are going to depend on the pci_host_bridge structure to retrieve the
>> >> domain number of the root bus.
>> >>
>> >> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> >> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> >> Acked-by: Grant Likely <grant.likely@linaro.org>
>> >> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> >> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
>> >> ---
>> >>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
>> >>  1 file changed, 17 insertions(+), 15 deletions(-)
>> >>
>> >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> >> index e3cf8a2..5ff72ec 100644
>> >> --- a/drivers/pci/probe.c
>> >> +++ b/drivers/pci/probe.c
>> >> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
>> >>         kfree(bridge);
>> >>  }
>> >>
>> >> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>> >> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
>> >>  {
>> >>         struct pci_host_bridge *bridge;
>> >>
>> >> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>> >>                 return NULL;
>> >>
>> >>         INIT_LIST_HEAD(&bridge->windows);
>> >> -       bridge->bus = b;
>> >> +       bridge->dev.release = pci_release_host_bridge_dev;
>> >> +
>> >>         return bridge;
>> >>  }
>> >>
>> >> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>> >>         char bus_addr[64];
>> >>         char *fmt;
>> >>
>> >> +       bridge = pci_alloc_host_bridge();
>> >> +       if (!bridge)
>> >> +               return NULL;
>> >> +
>> >> +       bridge->dev.parent = parent;
>> >> +
>> >>         b = pci_alloc_bus();
>> >>         if (!b)
>> >> -               return NULL;
>> >> +               goto err_out;
>> >>
>> >>         b->sysdata = sysdata;
>> >>         b->ops = ops;
>> >> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>> >>         if (b2) {
>> >>                 /* If we already got to this bus through a different bridge, ignore it */
>> >>                 dev_dbg(&b2->dev, "bus already known\n");
>> >> -               goto err_out;
>> >> +               goto err_bus_out;
>> >>         }
>> >>
>> >> -       bridge = pci_alloc_host_bridge(b);
>> >> -       if (!bridge)
>> >> -               goto err_out;
>> >> -
>> >> -       bridge->dev.parent = parent;
>> >> -       bridge->dev.release = pci_release_host_bridge_dev;
>> >> +       bridge->bus = b;
>> >>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
>> >>         error = pcibios_root_bridge_prepare(bridge);
>> >> -       if (error) {
>> >> -               kfree(bridge);
>> >> +       if (error)
>> >>                 goto err_out;
>> >> -       }
>> >>
>> >>         error = device_register(&bridge->dev);
>> >>         if (error) {
>> >>                 put_device(&bridge->dev);
>> >> -               goto err_out;
>> >> +               goto err_bus_out;
>> >>         }
>> >>         b->bridge = get_device(&bridge->dev);
>> >>         device_enable_async_suspend(b->bridge);
>> >> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>> >>  class_dev_reg_err:
>> >>         put_device(&bridge->dev);
>> >>         device_unregister(&bridge->dev);
>> >> -err_out:
>> >> +err_bus_out:
>> >>         kfree(b);
>> >> +err_out:
>> >> +       kfree(bridge);
>> >>         return NULL;
>> >>  }
>> >
>> > Hi Bjorn,
>> >
>> > Noticed that you put this one into pci/next.
>> >
>> > This patch has problem for the class_dev_reg_err path.
>> > as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
>> > So will have double free for bridge or else.
>> >
>> > Please drop this patch from pci/next.
>> >
>> > Also looks strange that the patch have long CC list, but just omit me
>> > and Jiang Liu that
>> > touched those code before.
>>
>> Thanks for noticing that.  I was concerned, but couldn't remember the details.
>>
>> I dropped this patch and the subsequent ones from pci/host and rebased
>> my "next" branch.
>>
>> Sorry I didn't notice you weren't on the CC list.
>>
>> Bjorn
>>
>
> Bjorn,
>
> I have refreshed/rebuilt the series from what was on 25th in linux-next and I have
> dropped this patch. I have pushed the series into
>
> git://linux-arm.org/linux-ld.git for-upstream/pci-next
>
> I hope that I've carried all your Sign-off-bys correctly, but I would like to ask you
> to double check that I haven't screwed up things.

I personally don't pull directly from git trees because I'm in the
habit of applying patches from email.  That's partly just habit, but
it's also a convenient way to ensure that every patch is posted on
linux-pci, which in turn helps me use patchwork as a "to-do" list, and
it allows me to make minor edits (whitespace, changelogs, etc.) for
consistency.

> This patch dates from the times I was trying to add the domain number information
> into the pci_host_bridge structure. Now, with Catalin's patch that adds the data in
> the pci_bus structure, this is not needed, so it is safe to drop. I did try to fix
> the patch but I've realised how intricately linked pci_host_bridge and root bus are,
> which to my opinion is a strong hint that the creation of the two should be split
> into separate functions.
>
> I can send an official v13 patchset to the mailing list if you want, but if not, here
> is the changelog:
>
> - updated "[PATCH 01/12] asm-generic/io.h: Fix ioport_map() for !CONFIG_GENERIC_IOMAP" to match
>   the patch that Thierry Reding has submitted through the asm-generic branch. If his
>   series lands first upstream this patch will be skipped.
> - updated "[PATCH 03/12] ARM: Define PCI_IOBASE as the base of virtual PCI IO space" to
>   cast the PCI_IOBASE value to (void __iomem *) as is the case with most #defined versions
> - dropped the patch that was changing the order of initialisation between pci_host_bridge
>   and root bus in pci_create_root_bus()
> - fixed "[PATCH 07/12] PCI: Add generic domain handling" to account for the previous patch
>   being removed
> - fixed the title of commit 08/12 to reflect the name of the functions that are actually
>   added (s/of_pci_get_domain_nr/pci_get_new_domain_nr/)
>
> I've compiled tested the series on sparc, microblaze (no)mmu_defconfig, arm omap2plus_defconfig
> and multi_v7_defconfig and arm64. I've also tested the series on my Juno (arm64) board.

It sounds like the v3.18 merge window is likely to open this weekend.
Therefore, I don't want to change anything that's already in my "next"
branch unless it is seriously broken, e.g., introduces a regression or
build error.

But you can post a series that would apply on top if you want, and
it's possible we could merge that later in the merge window,
especially if it is obviously low-risk.  If you go this route, please
do post it to the mailing list.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus.
@ 2014-09-26 16:17           ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-26 16:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 26, 2014 at 8:58 AM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Thu, Sep 25, 2014 at 08:59:26PM +0100, Bjorn Helgaas wrote:
>> On Thu, Sep 25, 2014 at 12:15 PM, Yinghai Lu <yinghai@kernel.org> wrote:
>> > On Tue, Sep 23, 2014 at 12:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>> >> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
>> >> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
>> >> the creation order has been changed for no good reason. Revert the order of
>> >> creation as we are going to depend on the pci_host_bridge structure to retrieve the
>> >> domain number of the root bus.
>> >>
>> >> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> >> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>> >> Acked-by: Grant Likely <grant.likely@linaro.org>
>> >> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> >> Tested-by: Tanmay Inamdar <tinamdar@apm.com>
>> >> ---
>> >>  drivers/pci/probe.c | 32 +++++++++++++++++---------------
>> >>  1 file changed, 17 insertions(+), 15 deletions(-)
>> >>
>> >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> >> index e3cf8a2..5ff72ec 100644
>> >> --- a/drivers/pci/probe.c
>> >> +++ b/drivers/pci/probe.c
>> >> @@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
>> >>         kfree(bridge);
>> >>  }
>> >>
>> >> -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>> >> +static struct pci_host_bridge *pci_alloc_host_bridge(void)
>> >>  {
>> >>         struct pci_host_bridge *bridge;
>> >>
>> >> @@ -524,7 +524,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>> >>                 return NULL;
>> >>
>> >>         INIT_LIST_HEAD(&bridge->windows);
>> >> -       bridge->bus = b;
>> >> +       bridge->dev.release = pci_release_host_bridge_dev;
>> >> +
>> >>         return bridge;
>> >>  }
>> >>
>> >> @@ -1761,9 +1762,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>> >>         char bus_addr[64];
>> >>         char *fmt;
>> >>
>> >> +       bridge = pci_alloc_host_bridge();
>> >> +       if (!bridge)
>> >> +               return NULL;
>> >> +
>> >> +       bridge->dev.parent = parent;
>> >> +
>> >>         b = pci_alloc_bus();
>> >>         if (!b)
>> >> -               return NULL;
>> >> +               goto err_out;
>> >>
>> >>         b->sysdata = sysdata;
>> >>         b->ops = ops;
>> >> @@ -1772,26 +1779,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>> >>         if (b2) {
>> >>                 /* If we already got to this bus through a different bridge, ignore it */
>> >>                 dev_dbg(&b2->dev, "bus already known\n");
>> >> -               goto err_out;
>> >> +               goto err_bus_out;
>> >>         }
>> >>
>> >> -       bridge = pci_alloc_host_bridge(b);
>> >> -       if (!bridge)
>> >> -               goto err_out;
>> >> -
>> >> -       bridge->dev.parent = parent;
>> >> -       bridge->dev.release = pci_release_host_bridge_dev;
>> >> +       bridge->bus = b;
>> >>         dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
>> >>         error = pcibios_root_bridge_prepare(bridge);
>> >> -       if (error) {
>> >> -               kfree(bridge);
>> >> +       if (error)
>> >>                 goto err_out;
>> >> -       }
>> >>
>> >>         error = device_register(&bridge->dev);
>> >>         if (error) {
>> >>                 put_device(&bridge->dev);
>> >> -               goto err_out;
>> >> +               goto err_bus_out;
>> >>         }
>> >>         b->bridge = get_device(&bridge->dev);
>> >>         device_enable_async_suspend(b->bridge);
>> >> @@ -1848,8 +1848,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>> >>  class_dev_reg_err:
>> >>         put_device(&bridge->dev);
>> >>         device_unregister(&bridge->dev);
>> >> -err_out:
>> >> +err_bus_out:
>> >>         kfree(b);
>> >> +err_out:
>> >> +       kfree(bridge);
>> >>         return NULL;
>> >>  }
>> >
>> > Hi Bjorn,
>> >
>> > Noticed that you put this one into pci/next.
>> >
>> > This patch has problem for the class_dev_reg_err path.
>> > as device_unregister(&bridge->dev) will trigger pci_release_host_bridge_dev.
>> > So will have double free for bridge or else.
>> >
>> > Please drop this patch from pci/next.
>> >
>> > Also looks strange that the patch have long CC list, but just omit me
>> > and Jiang Liu that
>> > touched those code before.
>>
>> Thanks for noticing that.  I was concerned, but couldn't remember the details.
>>
>> I dropped this patch and the subsequent ones from pci/host and rebased
>> my "next" branch.
>>
>> Sorry I didn't notice you weren't on the CC list.
>>
>> Bjorn
>>
>
> Bjorn,
>
> I have refreshed/rebuilt the series from what was on 25th in linux-next and I have
> dropped this patch. I have pushed the series into
>
> git://linux-arm.org/linux-ld.git for-upstream/pci-next
>
> I hope that I've carried all your Sign-off-bys correctly, but I would like to ask you
> to double check that I haven't screwed up things.

I personally don't pull directly from git trees because I'm in the
habit of applying patches from email.  That's partly just habit, but
it's also a convenient way to ensure that every patch is posted on
linux-pci, which in turn helps me use patchwork as a "to-do" list, and
it allows me to make minor edits (whitespace, changelogs, etc.) for
consistency.

> This patch dates from the times I was trying to add the domain number information
> into the pci_host_bridge structure. Now, with Catalin's patch that adds the data in
> the pci_bus structure, this is not needed, so it is safe to drop. I did try to fix
> the patch but I've realised how intricately linked pci_host_bridge and root bus are,
> which to my opinion is a strong hint that the creation of the two should be split
> into separate functions.
>
> I can send an official v13 patchset to the mailing list if you want, but if not, here
> is the changelog:
>
> - updated "[PATCH 01/12] asm-generic/io.h: Fix ioport_map() for !CONFIG_GENERIC_IOMAP" to match
>   the patch that Thierry Reding has submitted through the asm-generic branch. If his
>   series lands first upstream this patch will be skipped.
> - updated "[PATCH 03/12] ARM: Define PCI_IOBASE as the base of virtual PCI IO space" to
>   cast the PCI_IOBASE value to (void __iomem *) as is the case with most #defined versions
> - dropped the patch that was changing the order of initialisation between pci_host_bridge
>   and root bus in pci_create_root_bus()
> - fixed "[PATCH 07/12] PCI: Add generic domain handling" to account for the previous patch
>   being removed
> - fixed the title of commit 08/12 to reflect the name of the functions that are actually
>   added (s/of_pci_get_domain_nr/pci_get_new_domain_nr/)
>
> I've compiled tested the series on sparc, microblaze (no)mmu_defconfig, arm omap2plus_defconfig
> and multi_v7_defconfig and arm64. I've also tested the series on my Juno (arm64) board.

It sounds like the v3.18 merge window is likely to open this weekend.
Therefore, I don't want to change anything that's already in my "next"
branch unless it is seriously broken, e.g., introduces a regression or
build error.

But you can post a series that would apply on top if you want, and
it's possible we could merge that later in the merge window,
especially if it is obviously low-risk.  If you go this route, please
do post it to the mailing list.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
  2014-09-23 19:01   ` Liviu Dudau
@ 2014-09-26 18:20     ` Rob Herring
  -1 siblings, 0 replies; 101+ messages in thread
From: Rob Herring @ 2014-09-26 18:20 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely

On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> Add pci_get_new_domain_nr() to allocate a new domain number
> and of_get_pci_domain_nr() to retrieve the PCI domain number
> of a given device from DT. Host bridge drivers or architecture
> specific code can choose to implement their PCI domain number
> policy using these two functions.
>
> Using of_get_pci_domain_nr() guarantees a stable PCI domain
> number on every boot provided that all host bridge controllers
> are assigned a number in the device tree using "linux,pci-domain"
> property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
> is not recommended as it can lead to potentially conflicting
> domain numbers being assigned to root busses behind different
> host bridges.
>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>

Looks pretty good, but a couple of comments that can be addressed as
follow-up patches.

> ---
>  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
>  drivers/pci/pci.c      |  9 +++++++++
>  include/linux/of_pci.h |  7 +++++++
>  include/linux/pci.h    |  3 +++
>  4 files changed, 44 insertions(+)
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 8481996..82d172f 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
>  }
>  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
>
> +/**
> + * This function will try to obtain the host bridge domain number by
> + * finding a property called "linux,pci-domain" of the given device node.
> + *
> + * @node: device tree node with the domain information
> + *
> + * Returns the associated domain number from DT in the range [0-0xffff], or
> + * a negative value if the required property is not found.
> + */
> +int of_get_pci_domain_nr(struct device_node *node)
> +{
> +       const __be32 *value;
> +       int len;
> +       u16 domain;
> +
> +       value = of_get_property(node, "linux,pci-domain", &len);

This needs to be documented.

> +       if (!value || len < sizeof(*value))
> +               return -EINVAL;
> +
> +       domain = (u16)be32_to_cpup(value);

of_property_read_u32 would not work here?

> +
> +       return domain;
> +}
> +EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
> +
>  #ifdef CONFIG_PCI_MSI
>
>  static LIST_HEAD(of_pci_msi_chip_list);
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 2c9ac70..d36f35f 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4406,6 +4406,15 @@ static void pci_no_domains(void)
>  #endif
>  }
>
> +#ifdef CONFIG_PCI_DOMAINS
> +static atomic_t __domain_nr = ATOMIC_INIT(-1);
> +
> +int pci_get_new_domain_nr(void)
> +{
> +       return atomic_inc_return(&__domain_nr);
> +}
> +#endif
> +
>  /**
>   * pci_ext_cfg_avail - can we access extended PCI config space?
>   *
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index dde3a4a..71062e9 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
>  int of_pci_get_devfn(struct device_node *np);
>  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
>  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
> +int of_get_pci_domain_nr(struct device_node *node);
>  #else
>  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
>  {
> @@ -43,6 +44,12 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
>  {
>         return -EINVAL;
>  }
> +
> +static inline int
> +of_get_pci_domain_nr(struct device_node *node)
> +{
> +       return -1;
> +}
>  #endif
>
>  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index a494e5d..150da2d 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1285,10 +1285,12 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
>   */
>  #ifdef CONFIG_PCI_DOMAINS
>  extern int pci_domains_supported;
> +int pci_get_new_domain_nr(void);
>  #else
>  enum { pci_domains_supported = 0 };
>  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
>  static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
> +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
>  #endif /* CONFIG_PCI_DOMAINS */
>
>  /*
> @@ -1417,6 +1419,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
>
>  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
>  static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
> +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
>
>  #define dev_is_pci(d) (false)
>  #define dev_is_pf(d) (false)
> --
> 2.1.0
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-26 18:20     ` Rob Herring
  0 siblings, 0 replies; 101+ messages in thread
From: Rob Herring @ 2014-09-26 18:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> Add pci_get_new_domain_nr() to allocate a new domain number
> and of_get_pci_domain_nr() to retrieve the PCI domain number
> of a given device from DT. Host bridge drivers or architecture
> specific code can choose to implement their PCI domain number
> policy using these two functions.
>
> Using of_get_pci_domain_nr() guarantees a stable PCI domain
> number on every boot provided that all host bridge controllers
> are assigned a number in the device tree using "linux,pci-domain"
> property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
> is not recommended as it can lead to potentially conflicting
> domain numbers being assigned to root busses behind different
> host bridges.
>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>

Looks pretty good, but a couple of comments that can be addressed as
follow-up patches.

> ---
>  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
>  drivers/pci/pci.c      |  9 +++++++++
>  include/linux/of_pci.h |  7 +++++++
>  include/linux/pci.h    |  3 +++
>  4 files changed, 44 insertions(+)
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 8481996..82d172f 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
>  }
>  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
>
> +/**
> + * This function will try to obtain the host bridge domain number by
> + * finding a property called "linux,pci-domain" of the given device node.
> + *
> + * @node: device tree node with the domain information
> + *
> + * Returns the associated domain number from DT in the range [0-0xffff], or
> + * a negative value if the required property is not found.
> + */
> +int of_get_pci_domain_nr(struct device_node *node)
> +{
> +       const __be32 *value;
> +       int len;
> +       u16 domain;
> +
> +       value = of_get_property(node, "linux,pci-domain", &len);

This needs to be documented.

> +       if (!value || len < sizeof(*value))
> +               return -EINVAL;
> +
> +       domain = (u16)be32_to_cpup(value);

of_property_read_u32 would not work here?

> +
> +       return domain;
> +}
> +EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
> +
>  #ifdef CONFIG_PCI_MSI
>
>  static LIST_HEAD(of_pci_msi_chip_list);
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 2c9ac70..d36f35f 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4406,6 +4406,15 @@ static void pci_no_domains(void)
>  #endif
>  }
>
> +#ifdef CONFIG_PCI_DOMAINS
> +static atomic_t __domain_nr = ATOMIC_INIT(-1);
> +
> +int pci_get_new_domain_nr(void)
> +{
> +       return atomic_inc_return(&__domain_nr);
> +}
> +#endif
> +
>  /**
>   * pci_ext_cfg_avail - can we access extended PCI config space?
>   *
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index dde3a4a..71062e9 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
>  int of_pci_get_devfn(struct device_node *np);
>  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
>  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
> +int of_get_pci_domain_nr(struct device_node *node);
>  #else
>  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
>  {
> @@ -43,6 +44,12 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
>  {
>         return -EINVAL;
>  }
> +
> +static inline int
> +of_get_pci_domain_nr(struct device_node *node)
> +{
> +       return -1;
> +}
>  #endif
>
>  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index a494e5d..150da2d 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1285,10 +1285,12 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
>   */
>  #ifdef CONFIG_PCI_DOMAINS
>  extern int pci_domains_supported;
> +int pci_get_new_domain_nr(void);
>  #else
>  enum { pci_domains_supported = 0 };
>  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
>  static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
> +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
>  #endif /* CONFIG_PCI_DOMAINS */
>
>  /*
> @@ -1417,6 +1419,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
>
>  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
>  static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
> +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
>
>  #define dev_is_pci(d) (false)
>  #define dev_is_pf(d) (false)
> --
> 2.1.0
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
  2014-09-26 18:20     ` Rob Herring
  (?)
@ 2014-09-26 21:20       ` liviu
  -1 siblings, 0 replies; 101+ messages in thread
From: liviu @ 2014-09-26 21:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: Liviu Dudau, Bjorn Helgaas, Arnd Bergmann, Rob Herring,
	Jason Gunthorpe, Benjamin Herrenschmidt, Catalin Marinas,
	Will Deacon, Russell King, linux-pci, Linus Walleij,
	Tanmay Inamdar, Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	Grant Likely

On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > Add pci_get_new_domain_nr() to allocate a new domain number
> > and of_get_pci_domain_nr() to retrieve the PCI domain number
> > of a given device from DT. Host bridge drivers or architecture
> > specific code can choose to implement their PCI domain number
> > policy using these two functions.
> >
> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
> > number on every boot provided that all host bridge controllers
> > are assigned a number in the device tree using "linux,pci-domain"
> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
> > is not recommended as it can lead to potentially conflicting
> > domain numbers being assigned to root busses behind different
> > host bridges.
> >
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> 
> Looks pretty good, but a couple of comments that can be addressed as
> follow-up patches.
> 
> > ---
> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
> >  drivers/pci/pci.c      |  9 +++++++++
> >  include/linux/of_pci.h |  7 +++++++
> >  include/linux/pci.h    |  3 +++
> >  4 files changed, 44 insertions(+)
> >
> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> > index 8481996..82d172f 100644
> > --- a/drivers/of/of_pci.c
> > +++ b/drivers/of/of_pci.c
> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >  }
> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
> >
> > +/**
> > + * This function will try to obtain the host bridge domain number by
> > + * finding a property called "linux,pci-domain" of the given device node.
> > + *
> > + * @node: device tree node with the domain information
> > + *
> > + * Returns the associated domain number from DT in the range [0-0xffff], or
> > + * a negative value if the required property is not found.
> > + */
> > +int of_get_pci_domain_nr(struct device_node *node)
> > +{
> > +       const __be32 *value;
> > +       int len;
> > +       u16 domain;
> > +
> > +       value = of_get_property(node, "linux,pci-domain", &len);
> 
> This needs to be documented.

I would say needs agreed on *and* documented.

> 
> > +       if (!value || len < sizeof(*value))
> > +               return -EINVAL;
> > +
> > +       domain = (u16)be32_to_cpup(value);
> 
> of_property_read_u32 would not work here?

It should, I guess, but I want to limit the domain number range to 16 bits.

Best regards,
Liviu

> 
> > +
> > +       return domain;
> > +}
> > +EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
> > +
> >  #ifdef CONFIG_PCI_MSI
> >
> >  static LIST_HEAD(of_pci_msi_chip_list);
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > index 2c9ac70..d36f35f 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -4406,6 +4406,15 @@ static void pci_no_domains(void)
> >  #endif
> >  }
> >
> > +#ifdef CONFIG_PCI_DOMAINS
> > +static atomic_t __domain_nr = ATOMIC_INIT(-1);
> > +
> > +int pci_get_new_domain_nr(void)
> > +{
> > +       return atomic_inc_return(&__domain_nr);
> > +}
> > +#endif
> > +
> >  /**
> >   * pci_ext_cfg_avail - can we access extended PCI config space?
> >   *
> > diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> > index dde3a4a..71062e9 100644
> > --- a/include/linux/of_pci.h
> > +++ b/include/linux/of_pci.h
> > @@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
> >  int of_pci_get_devfn(struct device_node *np);
> >  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
> >  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
> > +int of_get_pci_domain_nr(struct device_node *node);
> >  #else
> >  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
> >  {
> > @@ -43,6 +44,12 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >  {
> >         return -EINVAL;
> >  }
> > +
> > +static inline int
> > +of_get_pci_domain_nr(struct device_node *node)
> > +{
> > +       return -1;
> > +}
> >  #endif
> >
> >  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index a494e5d..150da2d 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -1285,10 +1285,12 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
> >   */
> >  #ifdef CONFIG_PCI_DOMAINS
> >  extern int pci_domains_supported;
> > +int pci_get_new_domain_nr(void);
> >  #else
> >  enum { pci_domains_supported = 0 };
> >  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
> >  static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
> > +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
> >  #endif /* CONFIG_PCI_DOMAINS */
> >
> >  /*
> > @@ -1417,6 +1419,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
> >
> >  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
> >  static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
> > +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
> >
> >  #define dev_is_pci(d) (false)
> >  #define dev_is_pf(d) (false)
> > --
> > 2.1.0
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-26 21:20       ` liviu
  0 siblings, 0 replies; 101+ messages in thread
From: liviu @ 2014-09-26 21:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: Catalin Marinas, linux-pci, Linus Walleij, Liviu Dudau,
	Grant Likely, Tanmay Inamdar, linux-arch, Kukjin Kim,
	Russell King, Jingoo Han, Jason Gunthorpe,
	Benjamin Herrenschmidt, Grant Likely, Device Tree ML,
	Arnd Bergmann, Will Deacon, Rob Herring, Bjorn Helgaas, LAKML,
	Sinan Kaya, LKML, Suravee Suthikulanit

On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > Add pci_get_new_domain_nr() to allocate a new domain number
> > and of_get_pci_domain_nr() to retrieve the PCI domain number
> > of a given device from DT. Host bridge drivers or architecture
> > specific code can choose to implement their PCI domain number
> > policy using these two functions.
> >
> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
> > number on every boot provided that all host bridge controllers
> > are assigned a number in the device tree using "linux,pci-domain"
> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
> > is not recommended as it can lead to potentially conflicting
> > domain numbers being assigned to root busses behind different
> > host bridges.
> >
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> 
> Looks pretty good, but a couple of comments that can be addressed as
> follow-up patches.
> 
> > ---
> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
> >  drivers/pci/pci.c      |  9 +++++++++
> >  include/linux/of_pci.h |  7 +++++++
> >  include/linux/pci.h    |  3 +++
> >  4 files changed, 44 insertions(+)
> >
> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> > index 8481996..82d172f 100644
> > --- a/drivers/of/of_pci.c
> > +++ b/drivers/of/of_pci.c
> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >  }
> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
> >
> > +/**
> > + * This function will try to obtain the host bridge domain number by
> > + * finding a property called "linux,pci-domain" of the given device node.
> > + *
> > + * @node: device tree node with the domain information
> > + *
> > + * Returns the associated domain number from DT in the range [0-0xffff], or
> > + * a negative value if the required property is not found.
> > + */
> > +int of_get_pci_domain_nr(struct device_node *node)
> > +{
> > +       const __be32 *value;
> > +       int len;
> > +       u16 domain;
> > +
> > +       value = of_get_property(node, "linux,pci-domain", &len);
> 
> This needs to be documented.

I would say needs agreed on *and* documented.

> 
> > +       if (!value || len < sizeof(*value))
> > +               return -EINVAL;
> > +
> > +       domain = (u16)be32_to_cpup(value);
> 
> of_property_read_u32 would not work here?

It should, I guess, but I want to limit the domain number range to 16 bits.

Best regards,
Liviu

> 
> > +
> > +       return domain;
> > +}
> > +EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
> > +
> >  #ifdef CONFIG_PCI_MSI
> >
> >  static LIST_HEAD(of_pci_msi_chip_list);
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > index 2c9ac70..d36f35f 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -4406,6 +4406,15 @@ static void pci_no_domains(void)
> >  #endif
> >  }
> >
> > +#ifdef CONFIG_PCI_DOMAINS
> > +static atomic_t __domain_nr = ATOMIC_INIT(-1);
> > +
> > +int pci_get_new_domain_nr(void)
> > +{
> > +       return atomic_inc_return(&__domain_nr);
> > +}
> > +#endif
> > +
> >  /**
> >   * pci_ext_cfg_avail - can we access extended PCI config space?
> >   *
> > diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> > index dde3a4a..71062e9 100644
> > --- a/include/linux/of_pci.h
> > +++ b/include/linux/of_pci.h
> > @@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
> >  int of_pci_get_devfn(struct device_node *np);
> >  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
> >  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
> > +int of_get_pci_domain_nr(struct device_node *node);
> >  #else
> >  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
> >  {
> > @@ -43,6 +44,12 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >  {
> >         return -EINVAL;
> >  }
> > +
> > +static inline int
> > +of_get_pci_domain_nr(struct device_node *node)
> > +{
> > +       return -1;
> > +}
> >  #endif
> >
> >  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index a494e5d..150da2d 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -1285,10 +1285,12 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
> >   */
> >  #ifdef CONFIG_PCI_DOMAINS
> >  extern int pci_domains_supported;
> > +int pci_get_new_domain_nr(void);
> >  #else
> >  enum { pci_domains_supported = 0 };
> >  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
> >  static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
> > +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
> >  #endif /* CONFIG_PCI_DOMAINS */
> >
> >  /*
> > @@ -1417,6 +1419,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
> >
> >  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
> >  static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
> > +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
> >
> >  #define dev_is_pci(d) (false)
> >  #define dev_is_pf(d) (false)
> > --
> > 2.1.0
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-26 21:20       ` liviu
  0 siblings, 0 replies; 101+ messages in thread
From: liviu at dudau.co.uk @ 2014-09-26 21:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > Add pci_get_new_domain_nr() to allocate a new domain number
> > and of_get_pci_domain_nr() to retrieve the PCI domain number
> > of a given device from DT. Host bridge drivers or architecture
> > specific code can choose to implement their PCI domain number
> > policy using these two functions.
> >
> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
> > number on every boot provided that all host bridge controllers
> > are assigned a number in the device tree using "linux,pci-domain"
> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
> > is not recommended as it can lead to potentially conflicting
> > domain numbers being assigned to root busses behind different
> > host bridges.
> >
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Grant Likely <grant.likely@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> 
> Looks pretty good, but a couple of comments that can be addressed as
> follow-up patches.
> 
> > ---
> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
> >  drivers/pci/pci.c      |  9 +++++++++
> >  include/linux/of_pci.h |  7 +++++++
> >  include/linux/pci.h    |  3 +++
> >  4 files changed, 44 insertions(+)
> >
> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> > index 8481996..82d172f 100644
> > --- a/drivers/of/of_pci.c
> > +++ b/drivers/of/of_pci.c
> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >  }
> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
> >
> > +/**
> > + * This function will try to obtain the host bridge domain number by
> > + * finding a property called "linux,pci-domain" of the given device node.
> > + *
> > + * @node: device tree node with the domain information
> > + *
> > + * Returns the associated domain number from DT in the range [0-0xffff], or
> > + * a negative value if the required property is not found.
> > + */
> > +int of_get_pci_domain_nr(struct device_node *node)
> > +{
> > +       const __be32 *value;
> > +       int len;
> > +       u16 domain;
> > +
> > +       value = of_get_property(node, "linux,pci-domain", &len);
> 
> This needs to be documented.

I would say needs agreed on *and* documented.

> 
> > +       if (!value || len < sizeof(*value))
> > +               return -EINVAL;
> > +
> > +       domain = (u16)be32_to_cpup(value);
> 
> of_property_read_u32 would not work here?

It should, I guess, but I want to limit the domain number range to 16 bits.

Best regards,
Liviu

> 
> > +
> > +       return domain;
> > +}
> > +EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
> > +
> >  #ifdef CONFIG_PCI_MSI
> >
> >  static LIST_HEAD(of_pci_msi_chip_list);
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > index 2c9ac70..d36f35f 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -4406,6 +4406,15 @@ static void pci_no_domains(void)
> >  #endif
> >  }
> >
> > +#ifdef CONFIG_PCI_DOMAINS
> > +static atomic_t __domain_nr = ATOMIC_INIT(-1);
> > +
> > +int pci_get_new_domain_nr(void)
> > +{
> > +       return atomic_inc_return(&__domain_nr);
> > +}
> > +#endif
> > +
> >  /**
> >   * pci_ext_cfg_avail - can we access extended PCI config space?
> >   *
> > diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> > index dde3a4a..71062e9 100644
> > --- a/include/linux/of_pci.h
> > +++ b/include/linux/of_pci.h
> > @@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
> >  int of_pci_get_devfn(struct device_node *np);
> >  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
> >  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
> > +int of_get_pci_domain_nr(struct device_node *node);
> >  #else
> >  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
> >  {
> > @@ -43,6 +44,12 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >  {
> >         return -EINVAL;
> >  }
> > +
> > +static inline int
> > +of_get_pci_domain_nr(struct device_node *node)
> > +{
> > +       return -1;
> > +}
> >  #endif
> >
> >  #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index a494e5d..150da2d 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -1285,10 +1285,12 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
> >   */
> >  #ifdef CONFIG_PCI_DOMAINS
> >  extern int pci_domains_supported;
> > +int pci_get_new_domain_nr(void);
> >  #else
> >  enum { pci_domains_supported = 0 };
> >  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
> >  static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
> > +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
> >  #endif /* CONFIG_PCI_DOMAINS */
> >
> >  /*
> > @@ -1417,6 +1419,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
> >
> >  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
> >  static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
> > +static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
> >
> >  #define dev_is_pci(d) (false)
> >  #define dev_is_pf(d) (false)
> > --
> > 2.1.0
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
  2014-09-26 21:20       ` liviu
  (?)
@ 2014-09-26 21:53         ` Rob Herring
  -1 siblings, 0 replies; 101+ messages in thread
From: Rob Herring @ 2014-09-26 21:53 UTC (permalink / raw)
  To: Rob Herring, Liviu Dudau, Bjorn Helgaas, Arnd Bergmann,
	Rob Herring, Jason Gunthorpe, Benjamin Herrenschmidt,
	Catalin Marinas, Will Deacon, Russell King, linux-pci,
	Linus Walleij, Tanmay Inamdar, Grant Likely, Sinan Kaya,
	Jingoo Han, Kukjin Kim, Suravee Suthikulanit, linux-arch, LKML,
	Device Tree ML, LAKML, Grant Likely

On Fri, Sep 26, 2014 at 4:20 PM,  <liviu@dudau.co.uk> wrote:
> On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
>> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>> > Add pci_get_new_domain_nr() to allocate a new domain number
>> > and of_get_pci_domain_nr() to retrieve the PCI domain number
>> > of a given device from DT. Host bridge drivers or architecture
>> > specific code can choose to implement their PCI domain number
>> > policy using these two functions.
>> >
>> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
>> > number on every boot provided that all host bridge controllers
>> > are assigned a number in the device tree using "linux,pci-domain"
>> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
>> > is not recommended as it can lead to potentially conflicting
>> > domain numbers being assigned to root busses behind different
>> > host bridges.
>> >
>> > Cc: Bjorn Helgaas <bhelgaas@google.com>
>> > Cc: Arnd Bergmann <arnd@arndb.de>
>> > Cc: Grant Likely <grant.likely@linaro.org>
>> > Cc: Rob Herring <robh+dt@kernel.org>
>> > Cc: Catalin Marinas <catalin.marinas@arm.com>
>> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>>
>> Looks pretty good, but a couple of comments that can be addressed as
>> follow-up patches.
>>
>> > ---
>> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
>> >  drivers/pci/pci.c      |  9 +++++++++
>> >  include/linux/of_pci.h |  7 +++++++
>> >  include/linux/pci.h    |  3 +++
>> >  4 files changed, 44 insertions(+)
>> >
>> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>> > index 8481996..82d172f 100644
>> > --- a/drivers/of/of_pci.c
>> > +++ b/drivers/of/of_pci.c
>> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
>> >  }
>> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
>> >
>> > +/**
>> > + * This function will try to obtain the host bridge domain number by
>> > + * finding a property called "linux,pci-domain" of the given device node.
>> > + *
>> > + * @node: device tree node with the domain information
>> > + *
>> > + * Returns the associated domain number from DT in the range [0-0xffff], or
>> > + * a negative value if the required property is not found.
>> > + */
>> > +int of_get_pci_domain_nr(struct device_node *node)
>> > +{
>> > +       const __be32 *value;
>> > +       int len;
>> > +       u16 domain;
>> > +
>> > +       value = of_get_property(node, "linux,pci-domain", &len);
>>
>> This needs to be documented.
>
> I would say needs agreed on *and* documented.

I thought Bjorn already applied the series. Who's agreement are you
waiting for specifically.

>>
>> > +       if (!value || len < sizeof(*value))
>> > +               return -EINVAL;
>> > +
>> > +       domain = (u16)be32_to_cpup(value);
>>
>> of_property_read_u32 would not work here?
>
> It should, I guess, but I want to limit the domain number range to 16 bits.

Okay, but it would still be fewer lines to use of_property_read_u32
and then cast it. You could use the u16 variant and make the property
be defined to be 16-bit in the documentation.

Rob

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-26 21:53         ` Rob Herring
  0 siblings, 0 replies; 101+ messages in thread
From: Rob Herring @ 2014-09-26 21:53 UTC (permalink / raw)
  To: Rob Herring, Liviu Dudau, Bjorn Helgaas, Arnd Bergmann,
	Rob Herring, Jason Gunthorpe, Benjamin Herrenschmidt,
	Catalin Marinas, Will Deacon, Russell King, linux-pci,
	Linus Walleij, Tanmay Inamdar, Grant Likely, Sinan Kaya,
	Jingoo Han, Kukjin Kim, Suravee Suthikulanit, linux-arch, LKML,
	Device Tree ML, LAKML

On Fri, Sep 26, 2014 at 4:20 PM,  <liviu@dudau.co.uk> wrote:
> On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
>> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>> > Add pci_get_new_domain_nr() to allocate a new domain number
>> > and of_get_pci_domain_nr() to retrieve the PCI domain number
>> > of a given device from DT. Host bridge drivers or architecture
>> > specific code can choose to implement their PCI domain number
>> > policy using these two functions.
>> >
>> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
>> > number on every boot provided that all host bridge controllers
>> > are assigned a number in the device tree using "linux,pci-domain"
>> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
>> > is not recommended as it can lead to potentially conflicting
>> > domain numbers being assigned to root busses behind different
>> > host bridges.
>> >
>> > Cc: Bjorn Helgaas <bhelgaas@google.com>
>> > Cc: Arnd Bergmann <arnd@arndb.de>
>> > Cc: Grant Likely <grant.likely@linaro.org>
>> > Cc: Rob Herring <robh+dt@kernel.org>
>> > Cc: Catalin Marinas <catalin.marinas@arm.com>
>> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>>
>> Looks pretty good, but a couple of comments that can be addressed as
>> follow-up patches.
>>
>> > ---
>> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
>> >  drivers/pci/pci.c      |  9 +++++++++
>> >  include/linux/of_pci.h |  7 +++++++
>> >  include/linux/pci.h    |  3 +++
>> >  4 files changed, 44 insertions(+)
>> >
>> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>> > index 8481996..82d172f 100644
>> > --- a/drivers/of/of_pci.c
>> > +++ b/drivers/of/of_pci.c
>> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
>> >  }
>> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
>> >
>> > +/**
>> > + * This function will try to obtain the host bridge domain number by
>> > + * finding a property called "linux,pci-domain" of the given device node.
>> > + *
>> > + * @node: device tree node with the domain information
>> > + *
>> > + * Returns the associated domain number from DT in the range [0-0xffff], or
>> > + * a negative value if the required property is not found.
>> > + */
>> > +int of_get_pci_domain_nr(struct device_node *node)
>> > +{
>> > +       const __be32 *value;
>> > +       int len;
>> > +       u16 domain;
>> > +
>> > +       value = of_get_property(node, "linux,pci-domain", &len);
>>
>> This needs to be documented.
>
> I would say needs agreed on *and* documented.

I thought Bjorn already applied the series. Who's agreement are you
waiting for specifically.

>>
>> > +       if (!value || len < sizeof(*value))
>> > +               return -EINVAL;
>> > +
>> > +       domain = (u16)be32_to_cpup(value);
>>
>> of_property_read_u32 would not work here?
>
> It should, I guess, but I want to limit the domain number range to 16 bits.

Okay, but it would still be fewer lines to use of_property_read_u32
and then cast it. You could use the u16 variant and make the property
be defined to be 16-bit in the documentation.

Rob

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-26 21:53         ` Rob Herring
  0 siblings, 0 replies; 101+ messages in thread
From: Rob Herring @ 2014-09-26 21:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 26, 2014 at 4:20 PM,  <liviu@dudau.co.uk> wrote:
> On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
>> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>> > Add pci_get_new_domain_nr() to allocate a new domain number
>> > and of_get_pci_domain_nr() to retrieve the PCI domain number
>> > of a given device from DT. Host bridge drivers or architecture
>> > specific code can choose to implement their PCI domain number
>> > policy using these two functions.
>> >
>> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
>> > number on every boot provided that all host bridge controllers
>> > are assigned a number in the device tree using "linux,pci-domain"
>> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
>> > is not recommended as it can lead to potentially conflicting
>> > domain numbers being assigned to root busses behind different
>> > host bridges.
>> >
>> > Cc: Bjorn Helgaas <bhelgaas@google.com>
>> > Cc: Arnd Bergmann <arnd@arndb.de>
>> > Cc: Grant Likely <grant.likely@linaro.org>
>> > Cc: Rob Herring <robh+dt@kernel.org>
>> > Cc: Catalin Marinas <catalin.marinas@arm.com>
>> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>>
>> Looks pretty good, but a couple of comments that can be addressed as
>> follow-up patches.
>>
>> > ---
>> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
>> >  drivers/pci/pci.c      |  9 +++++++++
>> >  include/linux/of_pci.h |  7 +++++++
>> >  include/linux/pci.h    |  3 +++
>> >  4 files changed, 44 insertions(+)
>> >
>> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>> > index 8481996..82d172f 100644
>> > --- a/drivers/of/of_pci.c
>> > +++ b/drivers/of/of_pci.c
>> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
>> >  }
>> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
>> >
>> > +/**
>> > + * This function will try to obtain the host bridge domain number by
>> > + * finding a property called "linux,pci-domain" of the given device node.
>> > + *
>> > + * @node: device tree node with the domain information
>> > + *
>> > + * Returns the associated domain number from DT in the range [0-0xffff], or
>> > + * a negative value if the required property is not found.
>> > + */
>> > +int of_get_pci_domain_nr(struct device_node *node)
>> > +{
>> > +       const __be32 *value;
>> > +       int len;
>> > +       u16 domain;
>> > +
>> > +       value = of_get_property(node, "linux,pci-domain", &len);
>>
>> This needs to be documented.
>
> I would say needs agreed on *and* documented.

I thought Bjorn already applied the series. Who's agreement are you
waiting for specifically.

>>
>> > +       if (!value || len < sizeof(*value))
>> > +               return -EINVAL;
>> > +
>> > +       domain = (u16)be32_to_cpup(value);
>>
>> of_property_read_u32 would not work here?
>
> It should, I guess, but I want to limit the domain number range to 16 bits.

Okay, but it would still be fewer lines to use of_property_read_u32
and then cast it. You could use the u16 variant and make the property
be defined to be 16-bit in the documentation.

Rob

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
  2014-09-26 21:53         ` Rob Herring
@ 2014-09-26 22:47           ` Liviu Dudau
  -1 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-26 22:47 UTC (permalink / raw)
  To: Rob Herring
  Cc: Bjorn Helgaas, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	grant.likely

On Fri, Sep 26, 2014 at 10:53:26PM +0100, Rob Herring wrote:
> On Fri, Sep 26, 2014 at 4:20 PM,  <liviu@dudau.co.uk> wrote:
> > On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
> >> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> >> > Add pci_get_new_domain_nr() to allocate a new domain number
> >> > and of_get_pci_domain_nr() to retrieve the PCI domain number
> >> > of a given device from DT. Host bridge drivers or architecture
> >> > specific code can choose to implement their PCI domain number
> >> > policy using these two functions.
> >> >
> >> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
> >> > number on every boot provided that all host bridge controllers
> >> > are assigned a number in the device tree using "linux,pci-domain"
> >> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
> >> > is not recommended as it can lead to potentially conflicting
> >> > domain numbers being assigned to root busses behind different
> >> > host bridges.
> >> >
> >> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> >> > Cc: Arnd Bergmann <arnd@arndb.de>
> >> > Cc: Grant Likely <grant.likely@linaro.org>
> >> > Cc: Rob Herring <robh+dt@kernel.org>
> >> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> >> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> >>
> >> Looks pretty good, but a couple of comments that can be addressed as
> >> follow-up patches.
> >>
> >> > ---
> >> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
> >> >  drivers/pci/pci.c      |  9 +++++++++
> >> >  include/linux/of_pci.h |  7 +++++++
> >> >  include/linux/pci.h    |  3 +++
> >> >  4 files changed, 44 insertions(+)
> >> >
> >> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> >> > index 8481996..82d172f 100644
> >> > --- a/drivers/of/of_pci.c
> >> > +++ b/drivers/of/of_pci.c
> >> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >> >  }
> >> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
> >> >
> >> > +/**
> >> > + * This function will try to obtain the host bridge domain number by
> >> > + * finding a property called "linux,pci-domain" of the given device node.
> >> > + *
> >> > + * @node: device tree node with the domain information
> >> > + *
> >> > + * Returns the associated domain number from DT in the range [0-0xffff], or
> >> > + * a negative value if the required property is not found.
> >> > + */
> >> > +int of_get_pci_domain_nr(struct device_node *node)
> >> > +{
> >> > +       const __be32 *value;
> >> > +       int len;
> >> > +       u16 domain;
> >> > +
> >> > +       value = of_get_property(node, "linux,pci-domain", &len);
> >>
> >> This needs to be documented.
> >
> > I would say needs agreed on *and* documented.
> 
> I thought Bjorn already applied the series. Who's agreement are you
> waiting for specifically.

Looks like he only applied about 60% of the series.

I'm not waiting on anyones specifig agreement, just general agreement.
Jason Gunthrope have initially suggested using pci-domain alias which
you don't like, now I'm using "linux,pci-domain" property which you've
ACKed, I wonder if I need to give people more time to catch up to the
fact?

> 
> >>
> >> > +       if (!value || len < sizeof(*value))
> >> > +               return -EINVAL;
> >> > +
> >> > +       domain = (u16)be32_to_cpup(value);
> >>
> >> of_property_read_u32 would not work here?
> >
> > It should, I guess, but I want to limit the domain number range to 16 bits.
> 
> Okay, but it would still be fewer lines to use of_property_read_u32
> and then cast it. You could use the u16 variant and make the property
> be defined to be 16-bit in the documentation.

True. Will do.

Best regards,
Liviu

> 
> Rob
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-26 22:47           ` Liviu Dudau
  0 siblings, 0 replies; 101+ messages in thread
From: Liviu Dudau @ 2014-09-26 22:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 26, 2014 at 10:53:26PM +0100, Rob Herring wrote:
> On Fri, Sep 26, 2014 at 4:20 PM,  <liviu@dudau.co.uk> wrote:
> > On Fri, Sep 26, 2014 at 01:20:39PM -0500, Rob Herring wrote:
> >> On Tue, Sep 23, 2014 at 2:01 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> >> > Add pci_get_new_domain_nr() to allocate a new domain number
> >> > and of_get_pci_domain_nr() to retrieve the PCI domain number
> >> > of a given device from DT. Host bridge drivers or architecture
> >> > specific code can choose to implement their PCI domain number
> >> > policy using these two functions.
> >> >
> >> > Using of_get_pci_domain_nr() guarantees a stable PCI domain
> >> > number on every boot provided that all host bridge controllers
> >> > are assigned a number in the device tree using "linux,pci-domain"
> >> > property. Mix use of pci_get_new_domain_nr() and of_get_pci_domain_nr()
> >> > is not recommended as it can lead to potentially conflicting
> >> > domain numbers being assigned to root busses behind different
> >> > host bridges.
> >> >
> >> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> >> > Cc: Arnd Bergmann <arnd@arndb.de>
> >> > Cc: Grant Likely <grant.likely@linaro.org>
> >> > Cc: Rob Herring <robh+dt@kernel.org>
> >> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> >> > Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> >>
> >> Looks pretty good, but a couple of comments that can be addressed as
> >> follow-up patches.
> >>
> >> > ---
> >> >  drivers/of/of_pci.c    | 25 +++++++++++++++++++++++++
> >> >  drivers/pci/pci.c      |  9 +++++++++
> >> >  include/linux/of_pci.h |  7 +++++++
> >> >  include/linux/pci.h    |  3 +++
> >> >  4 files changed, 44 insertions(+)
> >> >
> >> > diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> >> > index 8481996..82d172f 100644
> >> > --- a/drivers/of/of_pci.c
> >> > +++ b/drivers/of/of_pci.c
> >> > @@ -89,6 +89,31 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
> >> >  }
> >> >  EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
> >> >
> >> > +/**
> >> > + * This function will try to obtain the host bridge domain number by
> >> > + * finding a property called "linux,pci-domain" of the given device node.
> >> > + *
> >> > + * @node: device tree node with the domain information
> >> > + *
> >> > + * Returns the associated domain number from DT in the range [0-0xffff], or
> >> > + * a negative value if the required property is not found.
> >> > + */
> >> > +int of_get_pci_domain_nr(struct device_node *node)
> >> > +{
> >> > +       const __be32 *value;
> >> > +       int len;
> >> > +       u16 domain;
> >> > +
> >> > +       value = of_get_property(node, "linux,pci-domain", &len);
> >>
> >> This needs to be documented.
> >
> > I would say needs agreed on *and* documented.
> 
> I thought Bjorn already applied the series. Who's agreement are you
> waiting for specifically.

Looks like he only applied about 60% of the series.

I'm not waiting on anyones specifig agreement, just general agreement.
Jason Gunthrope have initially suggested using pci-domain alias which
you don't like, now I'm using "linux,pci-domain" property which you've
ACKed, I wonder if I need to give people more time to catch up to the
fact?

> 
> >>
> >> > +       if (!value || len < sizeof(*value))
> >> > +               return -EINVAL;
> >> > +
> >> > +       domain = (u16)be32_to_cpup(value);
> >>
> >> of_property_read_u32 would not work here?
> >
> > It should, I guess, but I want to limit the domain number range to 16 bits.
> 
> Okay, but it would still be fewer lines to use of_property_read_u32
> and then cast it. You could use the u16 variant and make the property
> be defined to be 16-bit in the documentation.

True. Will do.

Best regards,
Liviu

> 
> Rob
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
  2014-09-26 22:47           ` Liviu Dudau
  (?)
@ 2014-09-27 20:18             ` Bjorn Helgaas
  -1 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-27 20:18 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Rob Herring, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	grant.likely, Yinghai Lu

[+cc Yinghai]

On Fri, Sep 26, 2014 at 4:47 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Fri, Sep 26, 2014 at 10:53:26PM +0100, Rob Herring wrote:

>> I thought Bjorn already applied the series. Who's agreement are you
>> waiting for specifically.
>
> Looks like he only applied about 60% of the series.

I applied it all but Yinghai pointed out a problem with a patch in the
middle, so I dropped that patch and everything after it because I didn't
have time to work out whether the later patches depended on anything
in the one I dropped.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-27 20:18             ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-27 20:18 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Rob Herring, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim,
	Suravee Suthikulanit, linux-arch, LKML, Device Tree ML, LAKML,
	grant.likely, Yinghai Lu

[+cc Yinghai]

On Fri, Sep 26, 2014 at 4:47 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Fri, Sep 26, 2014 at 10:53:26PM +0100, Rob Herring wrote:

>> I thought Bjorn already applied the series. Who's agreement are you
>> waiting for specifically.
>
> Looks like he only applied about 60% of the series.

I applied it all but Yinghai pointed out a problem with a patch in the
middle, so I dropped that patch and everything after it because I didn't
have time to work out whether the later patches depended on anything
in the one I dropped.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers
@ 2014-09-27 20:18             ` Bjorn Helgaas
  0 siblings, 0 replies; 101+ messages in thread
From: Bjorn Helgaas @ 2014-09-27 20:18 UTC (permalink / raw)
  To: linux-arm-kernel

[+cc Yinghai]

On Fri, Sep 26, 2014 at 4:47 PM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Fri, Sep 26, 2014 at 10:53:26PM +0100, Rob Herring wrote:

>> I thought Bjorn already applied the series. Who's agreement are you
>> waiting for specifically.
>
> Looks like he only applied about 60% of the series.

I applied it all but Yinghai pointed out a problem with a patch in the
middle, so I dropped that patch and everything after it because I didn't
have time to work out whether the later patches depended on anything
in the one I dropped.

Bjorn

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
  2014-09-24  1:41       ` Bjorn Helgaas
@ 2014-09-28 21:16         ` Suravee Suthikulpanit
  -1 siblings, 0 replies; 101+ messages in thread
From: Suravee Suthikulpanit @ 2014-09-28 21:16 UTC (permalink / raw)
  To: Bjorn Helgaas, Liviu Dudau
  Cc: Liviu Dudau, Arnd Bergmann, Rob Herring, Jason Gunthorpe,
	Benjamin Herrenschmidt, Catalin Marinas, Will Deacon,
	Russell King, linux-pci, Linus Walleij, Tanmay Inamdar,
	Grant Likely, Sinan Kaya, Jingoo Han, Kukjin Kim, linux-arch,
	LKML, Device Tree ML, LAKML

On 09/23/2014 08:41 PM, Bjorn Helgaas wrote:
> On Tue, Sep 23, 2014 at 7:18 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
>> On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
>>> If the firmware has not assigned all the bus resources and
>>> we are not just probing the PCIe busses, it makes sense to
>>> assign the unassigned resources in pci_scan_root_bus().
>>>
>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>> Cc: Arnd Bergmann <arnd@arndb.de>
>>> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
>>> Cc: Rob Herring <robh+dt@kernel.org>
>>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>>> ---
>>>   drivers/pci/probe.c | 3 +++
>>>   1 file changed, 3 insertions(+)
>>>
>>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>>> index ef891d2..508cf61 100644
>>> --- a/drivers/pci/probe.c
>>> +++ b/drivers/pci/probe.c
>>> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>>>        if (!found)
>>>                pci_bus_update_busn_res_end(b, max);
>>>
>>> +     if (!pci_has_flag(PCI_PROBE_ONLY))
>>> +             pci_assign_unassigned_bus_resources(b);
>>> +
>>>        pci_bus_add_devices(b);
>>>        return b;
>>>   }
>>> --
>>> 2.1.0
>>>
>>
>> Bjorn,
>>
>> If you are OK with this patch, can you let me know how do you feel about
>> making pci_scan_root_bus() set up the bus->msi pointer as well?
>
> I'm not opposed to it, but I have the same question as for setting up
> the domain: how does pci_scan_root_bus() learn what to assign to
> bus->msi?  It currently only gets a "void *sysdata" so there's no
> obvious place to put it there.  You could add a pcibios interface to
> retrieve it, I suppose, but I'm starting to get uncomfortable with
> adding more of those because we have such a mess of them already.
>
> Bjorn

[Suravee] Liviu and I had a talk during Linaro Connect, and we came up
with a new binding for the pcie controller called "msi-parent" which is
supposed to contain phandle to the corresponded msi-controller.

>
>> Side note: I don't know exactly how to do it now, but setting bus->msi is
>> needed by platforms that are based on my patches and want to use MSI,
>> otherwise they have to open code pci_scan_root_bus() to set it. I haven't
>> made any attempts to do it in this series as the GICv2m patches are not
>> ready yet, but I can see the need arriving soon.

[Suravee] I just sent out an RFC which implements the described binding 
here.

https://lkml.org/lkml/2014/9/28/149

Any feedback/comments are welcome :)

Thanks,

Suravee

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-28 21:16         ` Suravee Suthikulpanit
  0 siblings, 0 replies; 101+ messages in thread
From: Suravee Suthikulpanit @ 2014-09-28 21:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/23/2014 08:41 PM, Bjorn Helgaas wrote:
> On Tue, Sep 23, 2014 at 7:18 PM, Liviu Dudau <liviu@dudau.co.uk> wrote:
>> On Tue, Sep 23, 2014 at 08:01:12PM +0100, Liviu Dudau wrote:
>>> If the firmware has not assigned all the bus resources and
>>> we are not just probing the PCIe busses, it makes sense to
>>> assign the unassigned resources in pci_scan_root_bus().
>>>
>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>> Cc: Arnd Bergmann <arnd@arndb.de>
>>> Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
>>> Cc: Rob Herring <robh+dt@kernel.org>
>>> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>>> ---
>>>   drivers/pci/probe.c | 3 +++
>>>   1 file changed, 3 insertions(+)
>>>
>>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>>> index ef891d2..508cf61 100644
>>> --- a/drivers/pci/probe.c
>>> +++ b/drivers/pci/probe.c
>>> @@ -1953,6 +1953,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>>>        if (!found)
>>>                pci_bus_update_busn_res_end(b, max);
>>>
>>> +     if (!pci_has_flag(PCI_PROBE_ONLY))
>>> +             pci_assign_unassigned_bus_resources(b);
>>> +
>>>        pci_bus_add_devices(b);
>>>        return b;
>>>   }
>>> --
>>> 2.1.0
>>>
>>
>> Bjorn,
>>
>> If you are OK with this patch, can you let me know how do you feel about
>> making pci_scan_root_bus() set up the bus->msi pointer as well?
>
> I'm not opposed to it, but I have the same question as for setting up
> the domain: how does pci_scan_root_bus() learn what to assign to
> bus->msi?  It currently only gets a "void *sysdata" so there's no
> obvious place to put it there.  You could add a pcibios interface to
> retrieve it, I suppose, but I'm starting to get uncomfortable with
> adding more of those because we have such a mess of them already.
>
> Bjorn

[Suravee] Liviu and I had a talk during Linaro Connect, and we came up
with a new binding for the pcie controller called "msi-parent" which is
supposed to contain phandle to the corresponded msi-controller.

>
>> Side note: I don't know exactly how to do it now, but setting bus->msi is
>> needed by platforms that are based on my patches and want to use MSI,
>> otherwise they have to open code pci_scan_root_bus() to set it. I haven't
>> made any attempts to do it in this series as the GICv2m patches are not
>> ready yet, but I can see the need arriving soon.

[Suravee] I just sent out an RFC which implements the described binding 
here.

https://lkml.org/lkml/2014/9/28/149

Any feedback/comments are welcome :)

Thanks,

Suravee

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
  2014-09-28 21:16         ` Suravee Suthikulpanit
@ 2014-09-29 18:18           ` Arnd Bergmann
  -1 siblings, 0 replies; 101+ messages in thread
From: Arnd Bergmann @ 2014-09-29 18:18 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Suravee Suthikulpanit, Bjorn Helgaas, Liviu Dudau, linux-arch,
	Grant Likely, Kukjin Kim, Russell King, Device Tree ML,
	linux-pci, Benjamin Herrenschmidt, Linus Walleij, Jingoo Han,
	Liviu Dudau, LKML, Will Deacon, Jason Gunthorpe, Rob Herring,
	Tanmay Inamdar, Catalin Marinas, Sinan Kaya

On Sunday 28 September 2014 16:16:21 Suravee Suthikulpanit wrote:
> >
> > I'm not opposed to it, but I have the same question as for setting up
> > the domain: how does pci_scan_root_bus() learn what to assign to
> > bus->msi?  It currently only gets a "void *sysdata" so there's no
> > obvious place to put it there.  You could add a pcibios interface to
> > retrieve it, I suppose, but I'm starting to get uncomfortable with
> > adding more of those because we have such a mess of them already.
> >
> 
> [Suravee] Liviu and I had a talk during Linaro Connect, and we came up
> with a new binding for the pcie controller called "msi-parent" which is
> supposed to contain phandle to the corresponded msi-controller.

Is this based on the property that we have in the pci-mvebu driver?

I hope this is meant to be compatible so we can share the implementation.

	Arnd

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus()
@ 2014-09-29 18:18           ` Arnd Bergmann
  0 siblings, 0 replies; 101+ messages in thread
From: Arnd Bergmann @ 2014-09-29 18:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 28 September 2014 16:16:21 Suravee Suthikulpanit wrote:
> >
> > I'm not opposed to it, but I have the same question as for setting up
> > the domain: how does pci_scan_root_bus() learn what to assign to
> > bus->msi?  It currently only gets a "void *sysdata" so there's no
> > obvious place to put it there.  You could add a pcibios interface to
> > retrieve it, I suppose, but I'm starting to get uncomfortable with
> > adding more of those because we have such a mess of them already.
> >
> 
> [Suravee] Liviu and I had a talk during Linaro Connect, and we came up
> with a new binding for the pcie controller called "msi-parent" which is
> supposed to contain phandle to the corresponded msi-controller.

Is this based on the property that we have in the pci-mvebu driver?

I hope this is meant to be compatible so we can share the implementation.

	Arnd

^ permalink raw reply	[flat|nested] 101+ messages in thread

end of thread, other threads:[~2014-09-29 18:19 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-23 19:01 [PATCH v12 00/12] Support for creating generic PCI host bridges from DT Liviu Dudau
2014-09-23 19:01 ` Liviu Dudau
2014-09-23 19:01 ` [PATCH v12 01/12] Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 19:01 ` [PATCH v12 02/12] PCI: Introduce helper functions to deal with PCI I/O ranges Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 19:01 ` [PATCH v12 03/12] ARM: Define PCI_IOBASE as the base of virtual PCI IO space Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 19:01 ` [PATCH v12 04/12] PCI: OF: Move of_pci_range_to_resources() into address.c Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 19:01 ` [PATCH v12 05/12] PCI: OF: Fix the conversion of IO ranges into IO resources Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-24  0:22   ` Bjorn Helgaas
2014-09-24  0:22     ` Bjorn Helgaas
2014-09-24  0:22     ` Bjorn Helgaas
2014-09-24  1:12     ` Liviu Dudau
2014-09-24  1:12       ` Liviu Dudau
2014-09-24  1:12       ` Liviu Dudau
2014-09-24  1:16       ` Bjorn Helgaas
2014-09-24  1:16         ` Bjorn Helgaas
2014-09-24  1:16         ` Bjorn Helgaas
2014-09-24  9:20         ` Robert Richter
2014-09-24  9:20           ` Robert Richter
2014-09-24  9:20           ` Robert Richter
2014-09-24 10:14     ` Andrew Murray
2014-09-24 10:14       ` Andrew Murray
2014-09-24 10:14       ` Andrew Murray
2014-09-23 19:01 ` [PATCH v12 06/12] PCI: Create pci_host_bridge before its associated bus in pci_create_root_bus Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-25 18:15   ` Yinghai Lu
2014-09-25 18:15     ` Yinghai Lu
2014-09-25 19:59     ` Bjorn Helgaas
2014-09-25 19:59       ` Bjorn Helgaas
2014-09-26 14:58       ` Liviu Dudau
2014-09-26 14:58         ` Liviu Dudau
2014-09-26 16:17         ` Bjorn Helgaas
2014-09-26 16:17           ` Bjorn Helgaas
2014-09-23 19:01 ` [PATCH v12 07/12] PCI: Introduce generic domain handling for PCI busses Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 19:01 ` [PATCH v12 08/12] PCI: OF: Introduce helper function for retrieving PCI domain numbers Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-26 18:20   ` Rob Herring
2014-09-26 18:20     ` Rob Herring
2014-09-26 21:20     ` liviu
2014-09-26 21:20       ` liviu at dudau.co.uk
2014-09-26 21:20       ` liviu
2014-09-26 21:53       ` Rob Herring
2014-09-26 21:53         ` Rob Herring
2014-09-26 21:53         ` Rob Herring
2014-09-26 22:47         ` Liviu Dudau
2014-09-26 22:47           ` Liviu Dudau
2014-09-27 20:18           ` Bjorn Helgaas
2014-09-27 20:18             ` Bjorn Helgaas
2014-09-27 20:18             ` Bjorn Helgaas
2014-09-23 19:01 ` [PATCH v12 09/12] OF: PCI: Add support for parsing PCI host bridge resources from DT Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-24 16:43   ` Liviu Dudau
2014-09-24 16:43     ` Liviu Dudau
2014-09-24 17:31     ` Bjorn Helgaas
2014-09-24 17:31       ` Bjorn Helgaas
2014-09-24 17:53       ` Liviu Dudau
2014-09-24 17:53         ` Liviu Dudau
2014-09-24 18:01         ` Will Deacon
2014-09-24 18:01           ` Will Deacon
2014-09-25  8:54           ` Liviu Dudau
2014-09-25  8:54             ` Liviu Dudau
2014-09-25  9:04             ` Will Deacon
2014-09-25  9:04               ` Will Deacon
2014-09-23 19:01 ` [PATCH v12 10/12] PCI: Assign unassigned bus resources in pci_scan_root_bus() Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-24  1:18   ` Liviu Dudau
2014-09-24  1:18     ` Liviu Dudau
2014-09-24  1:18     ` Liviu Dudau
2014-09-24  1:41     ` Bjorn Helgaas
2014-09-24  1:41       ` Bjorn Helgaas
2014-09-24  1:48       ` Liviu Dudau
2014-09-24  1:48         ` Liviu Dudau
2014-09-28 21:16       ` Suravee Suthikulpanit
2014-09-28 21:16         ` Suravee Suthikulpanit
2014-09-29 18:18         ` Arnd Bergmann
2014-09-29 18:18           ` Arnd Bergmann
2014-09-23 19:01 ` [PATCH v12 11/12] PCI: Introduce pci_remap_iospace() for remapping PCI I/O bus resources into CPU space Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 19:01 ` [PATCH v12 12/12] arm64: Add architectural support for PCIe Liviu Dudau
2014-09-23 19:01   ` Liviu Dudau
2014-09-23 21:54 ` [PATCH v12 00/12] Support for creating generic PCI host bridges from DT Bjorn Helgaas
2014-09-23 21:54   ` Bjorn Helgaas
2014-09-23 22:48   ` Liviu Dudau
2014-09-23 22:48     ` Liviu Dudau
2014-09-23 23:00     ` Bjorn Helgaas
2014-09-23 23:00       ` Bjorn Helgaas
2014-09-24 13:30       ` Rob Herring
2014-09-24 13:30         ` Rob Herring
2014-09-24 14:23         ` Liviu Dudau
2014-09-24 14:23           ` Liviu Dudau
2014-09-24 15:38           ` Bjorn Helgaas
2014-09-24 15:38             ` Bjorn Helgaas
2014-09-23 22:49 ` Liviu Dudau
2014-09-23 22:49   ` Liviu Dudau
2014-09-23 22:49   ` Liviu Dudau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.