2013-04-25 09:50:07

by Andrew Murray

[permalink] [raw]
Subject: [RFC PATCH 0/3] Unify definations of struct pci_controller

PowerPC and Microblaze have nearly identical definations of struct
pci_controller - this patch unifies them in asm-generic to reduce
code duplication and to allow new architectures to reuse.

This patchset follows and depends on "of/pci: Provide common
support for PCI DT parsing" which provided common 'ranges' parsing
code which uses an architecture defined struct pci_controller. This
patch is currently in Jason Coopers mvebu-next/pcie branch.

It is hoped this will pave the way for providing common
implementations of commonly duplicated functions found across the
architectures such as pcibios_alloc|free_controller and
pcibios_setup_phb_resources type functions.

Andrew Murray (3):
powerpc: Move struct pci_controller to asm-generic
microblaze: Use asm-generic version of pci_controller
pci: Use common definations of INDIRECT_TYPE_*

arch/microblaze/include/asm/pci-bridge.h | 70 +-----------------------
arch/powerpc/include/asm/pci-bridge.h | 82 ---------------------------
arch/powerpc/sysdev/fsl_pci.c | 16 +++---
arch/powerpc/sysdev/indirect_pci.c | 20 +++---
arch/powerpc/sysdev/ppc4xx_pci.c | 4 +-
arch/powerpc/sysdev/xilinx_pci.c | 2 +-
include/asm-generic/pci-bridge.h | 90 ++++++++++++++++++++++++++++++
7 files changed, 112 insertions(+), 172 deletions(-)


2013-04-25 09:50:13

by Andrew Murray

[permalink] [raw]
Subject: [RFC PATCH 2/3] microblaze: Use asm-generic version of pci_controller

This patch removes struct pci_controller from Microblaze and instead
uses struct pci_controller from asm-generic.

Signed-off-by: Andrew Murray <[email protected]>
---
arch/microblaze/include/asm/pci-bridge.h | 75 ++++++------------------------
include/asm-generic/pci-bridge.h | 2 +-
2 files changed, 16 insertions(+), 61 deletions(-)

diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 5783cd6..0ee75dc 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -8,9 +8,9 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/pci.h>
-#include <linux/list.h>
#include <linux/ioport.h>
#include <linux/of_pci.h>
+#include <asm-generic/pci-bridge.h>

struct device_node;

@@ -25,72 +25,27 @@ static inline int pcibios_vaddr_is_ioport(void __iomem *address)
#endif

/*
- * Structure of a PCI controller (host bridge)
+ * Used for variants of PCI indirect handling and possible quirks:
+ * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+ * EXT_REG - provides access to PCI-e extended registers
+ * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
+ * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
+ * to determine which bus number to match on when generating type0
+ * config cycles
+ * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
+ * hanging if we don't have link and try to do config cycles to
+ * anything but the PHB. Only allow talking to the PHB if this is
+ * set.
+ * BIG_ENDIAN - cfg_addr is a big endian register
+ * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs
+ * on the PLB4. Effectively disable MRM commands by setting this.
*/
-struct pci_controller {
- struct pci_bus *bus;
- char is_dynamic;
- struct device_node *dn;
- struct list_head list_node;
- struct device *parent;
-
- int first_busno;
- int last_busno;
-
- int self_busno;
-
- void __iomem *io_base_virt;
- resource_size_t io_base_phys;
-
- resource_size_t pci_io_size;
-
- /* Some machines (PReP) have a non 1:1 mapping of
- * the PCI memory space in the CPU bus space
- */
- resource_size_t pci_mem_offset;
-
- /* Some machines have a special region to forward the ISA
- * "memory" cycles such as VGA memory regions. Left to 0
- * if unsupported
- */
- resource_size_t isa_mem_phys;
- resource_size_t isa_mem_size;
-
- struct pci_ops *ops;
- unsigned int __iomem *cfg_addr;
- void __iomem *cfg_data;
-
- /*
- * Used for variants of PCI indirect handling and possible quirks:
- * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
- * EXT_REG - provides access to PCI-e extended registers
- * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
- * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
- * to determine which bus number to match on when generating type0
- * config cycles
- * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
- * hanging if we don't have link and try to do config cycles to
- * anything but the PHB. Only allow talking to the PHB if this is
- * set.
- * BIG_ENDIAN - cfg_addr is a big endian register
- * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs
- * on the PLB4. Effectively disable MRM commands by setting this.
- */
#define INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
#define INDIRECT_TYPE_EXT_REG 0x00000002
#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
#define INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
#define INDIRECT_TYPE_BIG_ENDIAN 0x00000010
#define INDIRECT_TYPE_BROKEN_MRM 0x00000020
- u32 indirect_type;
-
- /* Currently, we limit ourselves to 1 IO range and 3 mem
- * ranges since the common pci_bus structure can't handle more
- */
- struct resource io_resource;
- struct resource mem_resources[3];
- int global_number; /* PCI domain number */
-};

#ifdef CONFIG_PCI
static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
diff --git a/include/asm-generic/pci-bridge.h b/include/asm-generic/pci-bridge.h
index e58830e..1a7f96d 100644
--- a/include/asm-generic/pci-bridge.h
+++ b/include/asm-generic/pci-bridge.h
@@ -46,7 +46,7 @@ struct device_node;
/*
* Structure of a PCI controller (host bridge)
*/
-#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) || defined(CONFIG_MICROBLAZE)
struct pci_controller {
struct pci_bus *bus;
char is_dynamic;
--
1.7.0.4

2013-04-25 09:50:16

by Andrew Murray

[permalink] [raw]
Subject: [RFC PATCH 3/3] pci: Use common definations of INDIRECT_TYPE_*

This patch unifies similar definations of INDIRECT_TYPE_* between
PowerPC and Microblaze.

Signed-off-by: Andrew Murray <[email protected]>
---
arch/microblaze/include/asm/pci-bridge.h | 23 -----------------------
arch/powerpc/include/asm/pci-bridge.h | 23 -----------------------
arch/powerpc/sysdev/fsl_pci.c | 16 ++++++++--------
arch/powerpc/sysdev/indirect_pci.c | 20 ++++++++++----------
arch/powerpc/sysdev/ppc4xx_pci.c | 4 ++--
arch/powerpc/sysdev/xilinx_pci.c | 2 +-
include/asm-generic/pci-bridge.h | 22 ++++++++++++++++++++++
7 files changed, 43 insertions(+), 67 deletions(-)

diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 0ee75dc..acf8252 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -24,29 +24,6 @@ static inline int pcibios_vaddr_is_ioport(void __iomem *address)
}
#endif

-/*
- * Used for variants of PCI indirect handling and possible quirks:
- * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
- * EXT_REG - provides access to PCI-e extended registers
- * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
- * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
- * to determine which bus number to match on when generating type0
- * config cycles
- * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
- * hanging if we don't have link and try to do config cycles to
- * anything but the PHB. Only allow talking to the PHB if this is
- * set.
- * BIG_ENDIAN - cfg_addr is a big endian register
- * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs
- * on the PLB4. Effectively disable MRM commands by setting this.
- */
-#define INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
-#define INDIRECT_TYPE_EXT_REG 0x00000002
-#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
-#define INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
-#define INDIRECT_TYPE_BIG_ENDIAN 0x00000010
-#define INDIRECT_TYPE_BROKEN_MRM 0x00000020
-
#ifdef CONFIG_PCI
static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
{
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 163bd40..b2bbf05 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -14,29 +14,6 @@

struct device_node;

-/*
- * Used for variants of PCI indirect handling and possible quirks:
- * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
- * EXT_REG - provides access to PCI-e extended registers
- * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
- * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
- * to determine which bus number to match on when generating type0
- * config cycles
- * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
- * hanging if we don't have link and try to do config cycles to
- * anything but the PHB. Only allow talking to the PHB if this is
- * set.
- * BIG_ENDIAN - cfg_addr is a big endian register
- * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
- * the PLB4. Effectively disable MRM commands by setting this.
- */
-#define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
-#define PPC_INDIRECT_TYPE_EXT_REG 0x00000002
-#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
-#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
-#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
-#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020
-
/* These are used for config access before all the PCI probing
has been done. */
extern int early_read_config_byte(struct pci_controller *hose, int bus,
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 682084d..d73f94a 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -399,7 +399,7 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)

if (fsl_pcie_bus_fixup)
is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
- no_link = !!(hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+ no_link = !!(hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK);

if (bus->parent == hose->bus && (is_pcie || no_link)) {
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; ++i) {
@@ -462,7 +462,7 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
hose->last_busno = bus_range ? bus_range[1] : 0xff;

setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
- PPC_INDIRECT_TYPE_BIG_ENDIAN);
+ INDIRECT_TYPE_BIG_ENDIAN);

if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
/* For PCIE read HEADER_TYPE to identify controler mode */
@@ -481,10 +481,10 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)

/* check PCI express link status */
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
- PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
+ hose->indirect_type |= INDIRECT_TYPE_EXT_REG |
+ INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
if (fsl_pcie_check_link(hose))
- hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ hose->indirect_type |= INDIRECT_TYPE_NO_PCIE_LINK;
}

printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
@@ -545,7 +545,7 @@ static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
{
struct pci_controller *hose = pci_bus_to_host(bus);

- if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
+ if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK)
return PCIBIOS_DEVICE_NOT_FOUND;
/*
* Workaround for the HW bug: for Type 0 configure transactions the
@@ -628,7 +628,7 @@ static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
if (!cfg_addr)
return PCIBIOS_DEVICE_NOT_FOUND;

- /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
+ /* INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
val &= 0xffffff00;

@@ -686,7 +686,7 @@ static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);

if (fsl_pcie_check_link(hose))
- hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ hose->indirect_type |= INDIRECT_TYPE_NO_PCIE_LINK;

return 0;
err1:
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
index 82fdad8..aa9dd5d 100644
--- a/arch/powerpc/sysdev/indirect_pci.c
+++ b/arch/powerpc/sysdev/indirect_pci.c
@@ -29,7 +29,7 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
u8 cfg_type = 0;
u32 bus_no, reg;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
+ if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
if (bus->number != hose->first_busno)
return PCIBIOS_DEVICE_NOT_FOUND;
if (devfn != 0)
@@ -40,19 +40,19 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
return PCIBIOS_DEVICE_NOT_FOUND;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE)
+ if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
if (bus->number != hose->first_busno)
cfg_type = 1;

bus_no = (bus->number == hose->first_busno) ?
hose->self_busno : bus->number;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG)
+ if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
else
reg = offset & 0xfc;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_BIG_ENDIAN)
+ if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
(devfn << 8) | reg | cfg_type));
else
@@ -87,7 +87,7 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
u8 cfg_type = 0;
u32 bus_no, reg;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
+ if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
if (bus->number != hose->first_busno)
return PCIBIOS_DEVICE_NOT_FOUND;
if (devfn != 0)
@@ -98,19 +98,19 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
return PCIBIOS_DEVICE_NOT_FOUND;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE)
+ if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
if (bus->number != hose->first_busno)
cfg_type = 1;

bus_no = (bus->number == hose->first_busno) ?
hose->self_busno : bus->number;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG)
+ if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
else
reg = offset & 0xfc;

- if (hose->indirect_type & PPC_INDIRECT_TYPE_BIG_ENDIAN)
+ if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
(devfn << 8) | reg | cfg_type));
else
@@ -118,13 +118,13 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
(devfn << 8) | reg | cfg_type));

/* suppress setting of PCI_PRIMARY_BUS */
- if (hose->indirect_type & PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
+ if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
if ((offset == PCI_PRIMARY_BUS) &&
(bus->number == hose->first_busno))
val &= 0xffffff00;

/* Workaround for PCI_28 Errata in 440EPx/GRx */
- if ((hose->indirect_type & PPC_INDIRECT_TYPE_BROKEN_MRM) &&
+ if ((hose->indirect_type & INDIRECT_TYPE_BROKEN_MRM) &&
offset == PCI_CACHE_LINE_SIZE) {
val = 0;
}
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 56e8b3c..745cd7a 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -73,7 +73,7 @@ static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev)

if (of_device_is_compatible(hose->dn, "ibm,plb440epx-pci") ||
of_device_is_compatible(hose->dn, "ibm,plb440grx-pci")) {
- hose->indirect_type |= PPC_INDIRECT_TYPE_BROKEN_MRM;
+ hose->indirect_type |= INDIRECT_TYPE_BROKEN_MRM;
}

/* Hide the PCI host BARs from the kernel as their content doesn't
@@ -577,7 +577,7 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np)

/* Setup config space */
setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4,
- PPC_INDIRECT_TYPE_SET_CFG_TYPE);
+ INDIRECT_TYPE_SET_CFG_TYPE);

/* Disable all windows */
writel(0, reg + PCIX0_POM0SA);
diff --git a/arch/powerpc/sysdev/xilinx_pci.c b/arch/powerpc/sysdev/xilinx_pci.c
index 1453b0e..67d4858 100644
--- a/arch/powerpc/sysdev/xilinx_pci.c
+++ b/arch/powerpc/sysdev/xilinx_pci.c
@@ -104,7 +104,7 @@ void __init xilinx_pci_init(void)
/* Setup config space */
setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR,
r.start + XPLB_PCI_DATA,
- PPC_INDIRECT_TYPE_SET_CFG_TYPE);
+ INDIRECT_TYPE_SET_CFG_TYPE);

/* According to the xilinx plbv46_pci documentation the soft-core starts
* a self-init when the bus master enable bit is set. Without this bit
diff --git a/include/asm-generic/pci-bridge.h b/include/asm-generic/pci-bridge.h
index 1a7f96d..c627c59 100644
--- a/include/asm-generic/pci-bridge.h
+++ b/include/asm-generic/pci-bridge.h
@@ -87,6 +87,28 @@ struct pci_controller {
unsigned int __iomem *cfg_addr;
void __iomem *cfg_data;

+ /*
+ * Used for variants of PCI indirect handling and possible quirks:
+ * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+ * EXT_REG - provides access to PCI-e extended registers
+ * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
+ * on PCI-e controllers since they used the PCI_PRIMARY_BUS
+ * to determine which bus number to match on when generating type0
+ * config cycles
+ * NO_PCIE_LINK - some PCI-e controllers have issues with
+ * hanging if we don't have link and try to do config cycles to
+ * anything but the PHB. Only allow talking to the PHB if this is
+ * set.
+ * BIG_ENDIAN - cfg_addr is a big endian register
+ * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs
+ * on the PLB4. Effectively disable MRM commands by setting this.
+ */
+#define INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
+#define INDIRECT_TYPE_EXT_REG 0x00000002
+#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
+#define INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
+#define INDIRECT_TYPE_BIG_ENDIAN 0x00000010
+#define INDIRECT_TYPE_BROKEN_MRM 0x00000020
u32 indirect_type;
/* Currently, we limit ourselves to 1 IO range and 3 mem
* ranges since the common pci_bus structure can't handle more
--
1.7.0.4

2013-04-25 09:50:11

by Andrew Murray

[permalink] [raw]
Subject: [RFC PATCH 1/3] powerpc: Move struct pci_controller to asm-generic

This patch moves struct pci_controller into asm-generic to allow
for use by other architectures thus reducing code duplication in
the kernel.

Signed-off-by: Andrew Murray <[email protected]>
---
arch/powerpc/include/asm/pci-bridge.h | 87 +++++---------------------------
include/asm-generic/pci-bridge.h | 68 +++++++++++++++++++++++++
2 files changed, 82 insertions(+), 73 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 205bfba..163bd40 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -8,7 +8,6 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/pci.h>
-#include <linux/list.h>
#include <linux/ioport.h>
#include <linux/of_pci.h>
#include <asm-generic/pci-bridge.h>
@@ -16,85 +15,27 @@
struct device_node;

/*
- * Structure of a PCI controller (host bridge)
+ * Used for variants of PCI indirect handling and possible quirks:
+ * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+ * EXT_REG - provides access to PCI-e extended registers
+ * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
+ * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
+ * to determine which bus number to match on when generating type0
+ * config cycles
+ * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
+ * hanging if we don't have link and try to do config cycles to
+ * anything but the PHB. Only allow talking to the PHB if this is
+ * set.
+ * BIG_ENDIAN - cfg_addr is a big endian register
+ * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
+ * the PLB4. Effectively disable MRM commands by setting this.
*/
-struct pci_controller {
- struct pci_bus *bus;
- char is_dynamic;
-#ifdef CONFIG_PPC64
- int node;
-#endif
- struct device_node *dn;
- struct list_head list_node;
- struct device *parent;
-
- int first_busno;
- int last_busno;
- int self_busno;
- struct resource busn;
-
- void __iomem *io_base_virt;
-#ifdef CONFIG_PPC64
- void *io_base_alloc;
-#endif
- resource_size_t io_base_phys;
- resource_size_t pci_io_size;
-
- /* Some machines (PReP) have a non 1:1 mapping of
- * the PCI memory space in the CPU bus space
- */
- resource_size_t pci_mem_offset;
-
- /* Some machines have a special region to forward the ISA
- * "memory" cycles such as VGA memory regions. Left to 0
- * if unsupported
- */
- resource_size_t isa_mem_phys;
- resource_size_t isa_mem_size;
-
- struct pci_ops *ops;
- unsigned int __iomem *cfg_addr;
- void __iomem *cfg_data;
-
- /*
- * Used for variants of PCI indirect handling and possible quirks:
- * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
- * EXT_REG - provides access to PCI-e extended registers
- * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
- * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
- * to determine which bus number to match on when generating type0
- * config cycles
- * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
- * hanging if we don't have link and try to do config cycles to
- * anything but the PHB. Only allow talking to the PHB if this is
- * set.
- * BIG_ENDIAN - cfg_addr is a big endian register
- * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
- * the PLB4. Effectively disable MRM commands by setting this.
- */
#define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
#define PPC_INDIRECT_TYPE_EXT_REG 0x00000002
#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020
- u32 indirect_type;
- /* Currently, we limit ourselves to 1 IO range and 3 mem
- * ranges since the common pci_bus structure can't handle more
- */
- struct resource io_resource;
- struct resource mem_resources[3];
- int global_number; /* PCI domain number */
-
- resource_size_t dma_window_base_cur;
- resource_size_t dma_window_size;
-
-#ifdef CONFIG_PPC64
- unsigned long buid;
-
- void *private_data;
-#endif /* CONFIG_PPC64 */
-};

/* These are used for config access before all the PCI probing
has been done. */
diff --git a/include/asm-generic/pci-bridge.h b/include/asm-generic/pci-bridge.h
index 20db2e5..e58830e 100644
--- a/include/asm-generic/pci-bridge.h
+++ b/include/asm-generic/pci-bridge.h
@@ -9,6 +9,9 @@

#ifdef __KERNEL__

+#include <linux/pci.h>
+#include <linux/list.h>
+
enum {
/* Force re-assigning all resources (ignore firmware
* setup completely)
@@ -38,6 +41,71 @@ enum {
PCI_SCAN_ALL_PCIE_DEVS = 0x00000040,
};

+struct device_node;
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
+struct pci_controller {
+ struct pci_bus *bus;
+ char is_dynamic;
+#ifdef CONFIG_PPC64
+ int node;
+#endif
+ struct device_node *dn;
+ struct list_head list_node;
+ struct device *parent;
+
+ int first_busno;
+ int last_busno;
+ int self_busno;
+#if defined(CONFIG_PPC64) || defined(CONFIG_PPC32)
+ struct resource busn;
+#endif
+
+ void __iomem *io_base_virt;
+#ifdef CONFIG_PPC64
+ void *io_base_alloc;
+#endif
+ resource_size_t io_base_phys;
+ resource_size_t pci_io_size;
+
+ /* Some machines (PReP) have a non 1:1 mapping of
+ * the PCI memory space in the CPU bus space
+ */
+ resource_size_t pci_mem_offset;
+
+ /* Some machines have a special region to forward the ISA
+ * "memory" cycles such as VGA memory regions. Left to 0
+ * if unsupported
+ */
+ resource_size_t isa_mem_phys;
+ resource_size_t isa_mem_size;
+
+ struct pci_ops *ops;
+ unsigned int __iomem *cfg_addr;
+ void __iomem *cfg_data;
+
+ u32 indirect_type;
+ /* Currently, we limit ourselves to 1 IO range and 3 mem
+ * ranges since the common pci_bus structure can't handle more
+ */
+ struct resource io_resource;
+ struct resource mem_resources[3];
+ int global_number; /* PCI domain number */
+
+ resource_size_t dma_window_base_cur;
+ resource_size_t dma_window_size;
+
+#ifdef CONFIG_PPC64
+ unsigned long buid;
+
+ void *private_data;
+#endif /* CONFIG_PPC64 */
+};
+#endif
+
#ifdef CONFIG_PCI
extern unsigned int pci_flags;

--
1.7.0.4

2013-04-25 19:09:11

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] powerpc: Move struct pci_controller to asm-generic

On Thu, Apr 25, 2013 at 3:49 AM, Andrew Murray <[email protected]> wrote:
> This patch moves struct pci_controller into asm-generic to allow
> for use by other architectures thus reducing code duplication in
> the kernel.
>
> Signed-off-by: Andrew Murray <[email protected]>
> ---
> arch/powerpc/include/asm/pci-bridge.h | 87 +++++---------------------------
> include/asm-generic/pci-bridge.h | 68 +++++++++++++++++++++++++
> 2 files changed, 82 insertions(+), 73 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
> index 205bfba..163bd40 100644
> --- a/arch/powerpc/include/asm/pci-bridge.h
> +++ b/arch/powerpc/include/asm/pci-bridge.h
> @@ -8,7 +8,6 @@
> * 2 of the License, or (at your option) any later version.
> */
> #include <linux/pci.h>
> -#include <linux/list.h>
> #include <linux/ioport.h>
> #include <linux/of_pci.h>
> #include <asm-generic/pci-bridge.h>
> @@ -16,85 +15,27 @@
> struct device_node;
>
> /*
> - * Structure of a PCI controller (host bridge)
> + * Used for variants of PCI indirect handling and possible quirks:
> + * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
> + * EXT_REG - provides access to PCI-e extended registers
> + * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS

s/SURPRESS/SUPRESS/ throughout.

I'm not sure how generic these flags will end up being. If they wind
up in a shared header file, it seems like we might want a PCI_ prefix
to anchor them.

> + * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
> + * to determine which bus number to match on when generating type0
> + * config cycles
> + * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
> + * hanging if we don't have link and try to do config cycles to
> + * anything but the PHB. Only allow talking to the PHB if this is
> + * set.
> + * BIG_ENDIAN - cfg_addr is a big endian register
> + * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
> + * the PLB4. Effectively disable MRM commands by setting this.
> */
> -struct pci_controller {
> - struct pci_bus *bus;
> - char is_dynamic;
> -#ifdef CONFIG_PPC64
> - int node;
> -#endif
> - struct device_node *dn;
> - struct list_head list_node;
> - struct device *parent;
> -
> - int first_busno;
> - int last_busno;
> - int self_busno;
> - struct resource busn;
> -
> - void __iomem *io_base_virt;
> -#ifdef CONFIG_PPC64
> - void *io_base_alloc;
> -#endif
> - resource_size_t io_base_phys;
> - resource_size_t pci_io_size;
> -
> - /* Some machines (PReP) have a non 1:1 mapping of
> - * the PCI memory space in the CPU bus space
> - */
> - resource_size_t pci_mem_offset;
> -
> - /* Some machines have a special region to forward the ISA
> - * "memory" cycles such as VGA memory regions. Left to 0
> - * if unsupported
> - */
> - resource_size_t isa_mem_phys;
> - resource_size_t isa_mem_size;
> -
> - struct pci_ops *ops;
> - unsigned int __iomem *cfg_addr;
> - void __iomem *cfg_data;
> -
> - /*
> - * Used for variants of PCI indirect handling and possible quirks:
> - * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
> - * EXT_REG - provides access to PCI-e extended registers
> - * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS
> - * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
> - * to determine which bus number to match on when generating type0
> - * config cycles
> - * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
> - * hanging if we don't have link and try to do config cycles to
> - * anything but the PHB. Only allow talking to the PHB if this is
> - * set.
> - * BIG_ENDIAN - cfg_addr is a big endian register
> - * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
> - * the PLB4. Effectively disable MRM commands by setting this.
> - */
> #define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
> #define PPC_INDIRECT_TYPE_EXT_REG 0x00000002
> #define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
> #define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
> #define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
> #define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020
> - u32 indirect_type;
> - /* Currently, we limit ourselves to 1 IO range and 3 mem
> - * ranges since the common pci_bus structure can't handle more
> - */
> - struct resource io_resource;
> - struct resource mem_resources[3];
> - int global_number; /* PCI domain number */
> -
> - resource_size_t dma_window_base_cur;
> - resource_size_t dma_window_size;
> -
> -#ifdef CONFIG_PPC64
> - unsigned long buid;
> -
> - void *private_data;
> -#endif /* CONFIG_PPC64 */
> -};
>
> /* These are used for config access before all the PCI probing
> has been done. */
> diff --git a/include/asm-generic/pci-bridge.h b/include/asm-generic/pci-bridge.h
> index 20db2e5..e58830e 100644
> --- a/include/asm-generic/pci-bridge.h
> +++ b/include/asm-generic/pci-bridge.h
> @@ -9,6 +9,9 @@
>
> #ifdef __KERNEL__
>
> +#include <linux/pci.h>
> +#include <linux/list.h>
> +
> enum {
> /* Force re-assigning all resources (ignore firmware
> * setup completely)
> @@ -38,6 +41,71 @@ enum {
> PCI_SCAN_ALL_PCIE_DEVS = 0x00000040,
> };
>
> +struct device_node;
> +
> +/*
> + * Structure of a PCI controller (host bridge)
> + */
> +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
> +struct pci_controller {
> + struct pci_bus *bus;

A lot of the information here (struct pci_bus *bus, first_/last_busno,
busn, window information) is already in the struct pci_host_bridge,
and I'm not sure it makes sense to duplicate it here. I'd like to use
that structure when it makes sense, and use the sysdata pointer, i.e.,
the pointer to "struct pci_controller" here, for things that are truly
arch-specific.

> + char is_dynamic;
> +#ifdef CONFIG_PPC64
> + int node;
> +#endif
> + struct device_node *dn;
> + struct list_head list_node;
> + struct device *parent;
> +
> + int first_busno;
> + int last_busno;
> + int self_busno;
> +#if defined(CONFIG_PPC64) || defined(CONFIG_PPC32)
> + struct resource busn;
> +#endif
> +
> + void __iomem *io_base_virt;
> +#ifdef CONFIG_PPC64
> + void *io_base_alloc;
> +#endif
> + resource_size_t io_base_phys;
> + resource_size_t pci_io_size;
> +
> + /* Some machines (PReP) have a non 1:1 mapping of
> + * the PCI memory space in the CPU bus space
> + */
> + resource_size_t pci_mem_offset;
> +
> + /* Some machines have a special region to forward the ISA
> + * "memory" cycles such as VGA memory regions. Left to 0
> + * if unsupported
> + */
> + resource_size_t isa_mem_phys;
> + resource_size_t isa_mem_size;
> +
> + struct pci_ops *ops;
> + unsigned int __iomem *cfg_addr;
> + void __iomem *cfg_data;
> +
> + u32 indirect_type;
> + /* Currently, we limit ourselves to 1 IO range and 3 mem
> + * ranges since the common pci_bus structure can't handle more
> + */
> + struct resource io_resource;
> + struct resource mem_resources[3];

pci_host_bridge has a list for apertures, which contains this
information (and the offset between CPU and PCI bus addresses).

> + int global_number; /* PCI domain number */

The domain is a good candidate for going in the pci_host_bridge
structure. I'm not sure how to plumb it in there, but it is something
that's pretty generic and I'd like to get rid of all the arch-specific
pci_domain_nr() implementations that are really the same.

> +
> + resource_size_t dma_window_base_cur;
> + resource_size_t dma_window_size;
> +
> +#ifdef CONFIG_PPC64
> + unsigned long buid;
> +
> + void *private_data;
> +#endif /* CONFIG_PPC64 */
> +};
> +#endif
> +
> #ifdef CONFIG_PCI
> extern unsigned int pci_flags;
>
> --
> 1.7.0.4
>