Skip to contentSkip to conversation

PCI: Re-factor PCI's 'latency timer' setup

PATCH In review Myron Stowe 6 participants 25 messages Oct 28, 2011 – Dec 5, 2011

Subsystems (9)
Arm (32-bit) x86 PowerPC PCI +5 more subsystems
lore
Share & tools
lore
#0 lore raw

cover PCI: Re-factor PCI's 'latency timer' setup

The 'latency timer' of PCI devices, both Type 0 and Type 1, is setup in architecture-specific code [see: pcibios_set_master()]. There are two approaches being taken by all the architectures - check if the 'latency timer' is currently set between 16 and 255 and if not bring it within bounds, or, do nothing (and then there is the gratuitously different parisc implementation).

There is nothing architecture-specific about PCI's 'latency timer' so this patch pulls the setup functionality up into the PCI core by creating a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over-ridden by architecture-specific code.

The series starts out by converting architecture-specific inlined versions of 'pcibios_set_master()' - all of which are no-ops - into non-inlined equivalents. This is necessary to allow a subsequent patch to create a generic version using the '__weak' attribute and is done for the following architectures: arm, blackfin*, h8300*, ia64, microblaze, powerpc, sparc, tile, unicore32, and xtensa.

Without the conversions, the compiler sees the architecture- specific version, defined as a static inline function typically in <asm/pci.h>, and will have no knowledge about the __weak version once it is introduced, which leads to compile failures as in:
drivers/pci/pci.c: 2605: error: redefinition of 'pcibios_set_master' arch/powerpc/include/asm/pci.h: 49: note: previous definition of
'pcibios_set_master' was here

Next the generic 'pcibios_set_master()' function is introduced in PCI's core. With the generic 'pcibios_set_master()' function in place the series removes the now redundant function from the following
architectures: frv, mips, mn10300, sh, and x86.

It would be nice to have all architectures follow suit and end up using only the single, generic, 'pcibios_set_master()' function.

-v2:
- In the original series I tried to not touch any of the architectures that were not going to end up using the generic 'pcibios_set_master()' function but this just created compile problems for those so I had to generate a number of pre-cursor patches to the series as noted above.
- * blackfin and h8300 architectures do not seem to support PCI (no root bus scanning etc. exists within them) but they do have PCI header files. I removed the inline definitions for each of these within the patch that introduces the generic 'pcibios_set_master()' function so that the __weak version would satisfy any necessary references.

I have only tested x86 although I was able to compile test powerpc in addition this time.
---

Myron Stowe (16):
PCI: latency timer doesn't apply to PCIe
PCI: x86: use generic pcibios_set_master()
PCI: sh: use generic pcibios_set_master()
PCI: mn10300: use generic pcibios_set_master()
PCI: MIPS: use generic pcibios_set_master()
PCI: frv: use generic pcibios_set_master()
PCI: Pull PCI 'latency timer' setup up into the core
PCI: Xtensa: convert pcibios_set_master() to a non-inlined function
PCI: UniCore: convert pcibios_set_master() to a non-inlined function
PCI: TILE: convert pcibios_set_master() to a non-inlined function
PCI: SPARC: convert pcibios_set_master() to a non-inlined function
PCI: PowerPC: convert pcibios_set_master() to a non-inlined function
PCI: MicroBlaze: convert pcibios_set_master() to a non-inlined function
PCI: IA64: convert pcibios_set_master() to a non-inlined function
PCI: ARM: convert pcibios_set_master() to a non-inlined function
PCI: add declaration for pcibios_set_master() to pci core

 arch/arm/common/it8152.c                |    3 +++
 arch/arm/include/asm/pci.h              |   12 -----------
 arch/arm/kernel/bios32.c                |    7 +++++++
 arch/blackfin/include/asm/pci.h         |    4 ----
 arch/frv/mb93090-mb00/pci-frv.c         |   20 -------------------
 arch/frv/mb93090-mb00/pci-frv.h         |    2 --
 arch/h8300/include/asm/pci.h            |    5 -----
 arch/ia64/include/asm/pci.h             |    6 ------
 arch/ia64/pci/pci.c                     |    5 +++++
 arch/microblaze/include/asm/pci.h       |    5 -----
 arch/microblaze/pci/pci-common.c        |    5 +++++
 arch/mips/pci/pci.c                     |   21 --------------------
 arch/mn10300/unit-asb2305/pci-asb2305.c |   22 ---------------------
 arch/mn10300/unit-asb2305/pci-asb2305.h |    2 --
 arch/powerpc/include/asm/pci.h          |    5 -----
 arch/powerpc/kernel/pci-common.c        |    5 +++++
 arch/sh/drivers/pci/pci.c               |   21 --------------------
 arch/sparc/include/asm/pci_32.h         |    5 -----
 arch/sparc/include/asm/pci_64.h         |    5 -----
 arch/sparc/kernel/pci.c                 |    5 +++++
 arch/tile/include/asm/pci.h             |    7 -------
 arch/tile/kernel/pci.c                  |    5 +++++
 arch/unicore32/include/asm/pci.h        |    5 -----
 arch/unicore32/kernel/pci.c             |    5 +++++
 arch/x86/include/asm/pci_x86.h          |    2 --
 arch/x86/pci/i386.c                     |   20 -------------------
 arch/xtensa/include/asm/pci.h           |    5 -----
 arch/xtensa/kernel/pci.c                |    5 +++++
 drivers/pci/pci.c                       |   33 +++++++++++++++++++++++++++++++
 include/linux/pci.h                     |    5 +++++
 30 files changed, 83 insertions(+), 174 deletions(-)
#1 lore raw

PATCH 1/16 PCI: add declaration for pcibios_set_master() to pci core

From: Myron Stowe <[email protected]>

Currently, pcibios_set_master() is implemented in architecture- specific code. There is nothing architecture-specific about PCI's 'latency timer'.

This patch adds a declaration for pcibios_set_master() to PCI's core in preperation for pulling the function itself up into the core. Without the addition of this declaration, subsequent patches that remove inline definitions of pcibios_set_master() would be removing the only declaration of such.

No functional change.

---

 include/linux/pci.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
include/linux/pci.h +2 -0
index 8c230cb..abbd8b6 100644
@@ -1440,8 +1440,10 @@ extern u8 pci_cache_line_size;
 extern unsigned long pci_hotplug_io_size;
 extern unsigned long pci_hotplug_mem_size;
 
+/* Architecture specific versions may override these (weak) */
 int pcibios_add_platform_entries(struct pci_dev *dev);
 void pcibios_disable_device(struct pci_dev *dev);
+void pcibios_set_master(struct pci_dev *dev);
 int pcibios_set_pcie_reset_state(struct pci_dev *dev,
 				 enum pcie_reset_state state);
 
#2 lore raw

Re: [PATCH -v2 01/16] PCI: add declaration for pcibios_set_master() to pci core

Quoted 12 lines · On Fri, 28 Oct 2011 15:47:35 -0600 Myron Stowe <[email protected]> wrote:

From: Myron Stowe <[email protected]>

Currently, pcibios_set_master() is implemented in architecture- specific code. There is nothing architecture-specific about PCI's 'latency timer'.

This patch adds a declaration for pcibios_set_master() to PCI's core in preperation for pulling the function itself up into the core. Without the addition of this declaration, subsequent patches that remove inline definitions of pcibios_set_master() would be removing the only declaration of such.

Quoted 4 lines

No functional change.

---

Ok this series is in -next. Let's see what breaks this time. :)

Thanks,

Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center
#3 lore raw

Re: [PATCH -v2 01/16] PCI: add declaration for pcibios_set_master() to pci core

Quoted 15 lines · Jesse Barnes
Quoted 12 lines · On Fri, 28 Oct 2011 15:47:35 -0600 Myron Stowe <[email protected]> wrote:

From: Myron Stowe <[email protected]>

Currently, pcibios_set_master() is implemented in architecture- specific code. There is nothing architecture-specific about PCI's 'latency timer'.

This patch adds a declaration for pcibios_set_master() to PCI's core in preperation for pulling the function itself up into the core. Without the addition of this declaration, subsequent patches that remove inline definitions of pcibios_set_master() would be removing the only declaration of such.

Quoted 6 lines
Quoted 4 lines

No functional change.

---

Ok this series is in -next. Let's see what breaks this time. :)

On the other hand...

One thing that annoys the sh*it out of me is that I cannot use pcibios_set_master() to establish the DMA/iommu resources for a device, because set_dma_mask() will be called -after- set_master(), thus I need to provision every device with 32-bit DMA resources (which can be quite scarse) just in case the driver doesn't later call set_dma_mask(64-bit).

If only we could reverse the call order... lots of drivers to fix unfortunately.

In which case I -would- hook into pcibios_set_master()...

Cheers,
Ben.

#4 lore raw

PATCH 2/16 PCI: ARM: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts ARM's architecture-specific inlined 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over- ridden by architecture-specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow ARM's 'pcibios_set_master()' implementation to remain architecture- specific after the generic version is introduced and thus, not change current behavior.

Note that ARM also has a non-inlined 'pcibios_set_master()' that is used if CONFIG_PCI_HOST_ITE8152 is defined. This patch does not change any behavior here either.

No functional change.

---

 arch/arm/common/it8152.c   |    3 +++
 arch/arm/include/asm/pci.h |   12 ------------
 arch/arm/kernel/bios32.c   |    7 +++++++
 3 files changed, 10 insertions(+), 12 deletions(-)
arch/arm/common/it8152.c +3 -0
index a7934ba..b892432 100644
@@ -326,6 +326,9 @@ err0:
  */
 unsigned int pcibios_max_latency = 255;
 
+/* ITE bridge requires setting latency timer to avoid early bus access
+   termination by PCI bus master devices
+*/
 void pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
arch/arm/include/asm/pci.h +0 -12
index 2b1f245..da337ba 100644
@@ -31,18 +31,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif /* CONFIG_PCI_DOMAINS */
 
-#ifdef CONFIG_PCI_HOST_ITE8152
-/* ITE bridge requires setting latency timer to avoid early bus access
-   termination by PIC bus mater devices
-*/
-extern void pcibios_set_master(struct pci_dev *dev);
-#else
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-#endif
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/arm/kernel/bios32.c +7 -0
index d6df359..d8457c6 100644
@@ -572,6 +572,13 @@ void __init pci_common_init(struct hw_pci *hw)
 	}
 }
 
+#ifndef CONFIG_PCI_HOST_ITE8152
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+#endif
+
 char * __init pcibios_setup(char *str)
 {
 	if (!strcmp(str, "debug")) {
#5 lore raw

PATCH 3/16 PCI: IA64: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts IA64's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over-ridden by architecture- specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow IA64's 'pcibios_set_master()' implementation to remain architecture- specific after the generic version is introduced and thus, not change current behavior.

No functional change.

---

 arch/ia64/include/asm/pci.h |    6 ------
 arch/ia64/pci/pci.c         |    5 +++++
 2 files changed, 5 insertions(+), 6 deletions(-)
arch/ia64/include/asm/pci.h +0 -6
index 73b5f78..6e3d91e 100644
@@ -43,12 +43,6 @@ extern unsigned long ia64_max_iommu_merge_mask;
 #define PCI_DMA_BUS_IS_PHYS	(ia64_max_iommu_merge_mask == ~0UL)
 
 static inline void
-pcibios_set_master (struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
-static inline void
 pcibios_penalize_isa_irq (int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/ia64/pci/pci.c +5 -0
index aa2533a..8273acb 100644
@@ -513,6 +513,11 @@ pcibios_fixup_bus (struct pci_bus *b)
 	return;
 }
 
+void pcibios_set_master (struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
 void __devinit
 pcibios_update_irq (struct pci_dev *dev, int irq)
 {
#6 lore raw

PATCH 4/16 PCI: MicroBlaze: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts MicroBlaze's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over- ridden by architecture-specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow MicroBlaze's 'pcibios_set_master()' implementation to remain architecture-specific after the generic version is introduced and thus, not change current behavior.

No functional change.

---

 arch/microblaze/include/asm/pci.h |    5 -----
 arch/microblaze/pci/pci-common.c  |    5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)
arch/microblaze/include/asm/pci.h +0 -5
index 1dd9d6b..0331376 100644
@@ -42,11 +42,6 @@ struct pci_dev;
  */
 #define pcibios_assign_all_busses()	0
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/microblaze/pci/pci-common.c +5 -0
index 4cfae20..1a500c5 100644
@@ -189,6 +189,11 @@ int pcibios_add_platform_entries(struct pci_dev *pdev)
 	return device_create_file(&pdev->dev, &dev_attr_devspec);
 }
 
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
 char __devinit *pcibios_setup(char *str)
 {
 	return str;
#7 lore raw

PATCH 5/16 PCI: PowerPC: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts PowerPC's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over- ridden by architecture-specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow PowerPC's 'pcibios_set_master()' implementation to remain architecture-specific after the generic version is introduced and thus, not change current behavior.

No functional change.

---

 arch/powerpc/include/asm/pci.h   |    5 -----
 arch/powerpc/kernel/pci-common.c |    5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)
arch/powerpc/include/asm/pci.h +0 -5
index 49c3de5..9284fe8 100644
@@ -46,11 +46,6 @@ struct pci_dev;
 #define pcibios_assign_all_busses() \
 	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/powerpc/kernel/pci-common.c +5 -0
index 32656f1..dd68684 100644
@@ -1117,6 +1117,11 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
 	}
 }
 
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
 	/* When called from the generic PCI probe, read PCI<->PCI bridge
#8 lore raw

PATCH 6/16 PCI: SPARC: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts SPARC's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over- ridden by architecture-specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow SPARC's 'pcibios_set_master()' implementation to remain architecture-specific after the generic version is introduced and thus, not change current behavior.

No functional change.

---

 arch/sparc/include/asm/pci_32.h |    5 -----
 arch/sparc/include/asm/pci_64.h |    5 -----
 arch/sparc/kernel/pci.c         |    5 +++++
 3 files changed, 5 insertions(+), 10 deletions(-)
arch/sparc/include/asm/pci_32.h +0 -5
index 02939ab..6de7f7b 100644
@@ -16,11 +16,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/sparc/include/asm/pci_64.h +0 -5
index 2614d96..755a4bb 100644
@@ -16,11 +16,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/sparc/kernel/pci.c +5 -0
index 1e94f94..269c011 100644
@@ -1082,6 +1082,11 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar,
 	*end = rp->end - offset;
 }
 
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
 static int __init pcibios_init(void)
 {
 	pci_dfl_cache_line_size = 64 >> 2;
#9 lore raw

PATCH 7/16 PCI: TILE: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts TILE's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over-ridden by architecture-specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow TILE's 'pcibios_set_master()' implementation to remain architecture-specific after the generic version is introduced and thus, not change current behavior.

No functional change.

---

 arch/tile/include/asm/pci.h |    7 -------
 arch/tile/kernel/pci.c      |    5 +++++
 2 files changed, 5 insertions(+), 7 deletions(-)
arch/tile/include/asm/pci.h +0 -7
index 7f03cef..2a2abc7 100644
@@ -76,13 +76,6 @@ static inline int pcibios_assign_all_busses(void)
 	return 1;
 }
 
-/*
- * No special bus mastering setup handling.
- */
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-}
-
 #define PCIBIOS_MIN_MEM		0
 #define PCIBIOS_MIN_IO		0
 
arch/tile/kernel/pci.c +5 -0
index 2a8014c..08b8943 100644
@@ -394,6 +394,11 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 	/* Nothing needs to be done. */
 }
 
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling. */
+}
+
 /*
  * This can be called from the generic PCI layer, but doesn't need to
  * do anything.
Acked-by on v1 7/16
#10 lore raw

Re: [PATCH -v2 07/16] PCI: TILE: convert pcibios_set_master() to a non-inlined function

Quoted 8 lines · Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts TILE's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over-ridden by architecture-specific code.

Quoted 8 lines

Converting 'pci_bios_set_master()' to a non-inlined function will allow TILE's 'pcibios_set_master()' implementation to remain architecture-specific after the generic version is introduced and thus, not change current behavior.

No functional change.

Signature · 2 lines
Chris Metcalf, Tilera Corp.
http://www.tilera.com
#11 lore raw

PATCH 8/16 PCI: UniCore: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts UniCore's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over- ridden by architecture-specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow UniCore's 'pcibios_set_master()' implementation to remain architecture-specific after the generic version is introduced and thus, not change current behavior.

No functional change.

---

 arch/unicore32/include/asm/pci.h |    5 -----
 arch/unicore32/kernel/pci.c      |    5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)
arch/unicore32/include/asm/pci.h +0 -5
index c5b28b4..dd38677 100644
@@ -17,11 +17,6 @@
 #include <asm-generic/pci.h>
 #include <mach/hardware.h> /* for PCIBIOS_MIN_* */
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/unicore32/kernel/pci.c +5 -0
index 4892fbb..a8f07fe 100644
@@ -309,6 +309,11 @@ char * __devinit pcibios_setup(char *str)
 	return str;
 }
 
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
 /*
  * From arch/i386/kernel/pci-i386.c:
  *
#12 lore raw

PATCH 9/16 PCI: Xtensa: convert pcibios_set_master() to a non-inlined function

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch converts Xtensa's architecture-specific 'pcibios_set_master()' routine to a non-inlined function. This will allow follow on patches to create a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over- ridden by architecture-specific code.

Converting 'pci_bios_set_master()' to a non-inlined function will allow Xtensa's 'pcibios_set_master()' implementation to remain architecture-specific after the generic version is introduced and thus, not change current behavior.

No functional change.

---

 arch/xtensa/include/asm/pci.h |    5 -----
 arch/xtensa/kernel/pci.c      |    5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)
arch/xtensa/include/asm/pci.h +0 -5
index 4609b0f..05244f0 100644
@@ -22,11 +22,6 @@
 
 extern struct pci_controller* pcibios_alloc_controller(void);
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/xtensa/kernel/pci.c +5 -0
index cd10269..644b2d4 100644
@@ -227,6 +227,11 @@ char __init *pcibios_setup(char *str)
 	return str;
 }
 
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
 /* the next one is stolen from the alpha port... */
 
 void __init
#13 lore raw

PATCH 10/16 PCI: Pull PCI 'latency timer' setup up into the core

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

The 'latency timer' of PCI devices, both Type 0 and Type 1, is setup in architecture-specific code [see: 'pcibios_set_master()']. There are two approaches being taken by all the architectures - check if the 'latency timer' is currently set between 16 and 255 and if not bring it within bounds, or, do nothing (and then there is the gratuitously different PA-RISC implementation).

There is nothing architecture-specific about PCI's 'latency timer' so this patch pulls its setup functionality up into the PCI core by creating a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over-ridden by architecture-specific code.

No functional change.

---

 arch/blackfin/include/asm/pci.h         |    4 ----
 arch/frv/mb93090-mb00/pci-frv.c         |    6 ------
 arch/frv/mb93090-mb00/pci-frv.h         |    2 --
 arch/h8300/include/asm/pci.h            |    5 -----
 arch/mips/pci/pci.c                     |    6 ------
 arch/mn10300/unit-asb2305/pci-asb2305.c |    6 ------
 arch/mn10300/unit-asb2305/pci-asb2305.h |    2 --
 arch/sh/drivers/pci/pci.c               |    6 ------
 arch/x86/include/asm/pci_x86.h          |    2 --
 arch/x86/pci/i386.c                     |    6 ------
 drivers/pci/pci.c                       |   29 +++++++++++++++++++++++++++++
 include/linux/pci.h                     |    3 +++
 12 files changed, 32 insertions(+), 45 deletions(-)
arch/blackfin/include/asm/pci.h +0 -4
index 99cae2e..74352c4 100644
@@ -10,10 +10,6 @@
 #define PCIBIOS_MIN_IO 0x00001000
 #define PCIBIOS_MIN_MEM 0x10000000
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
 static inline void pcibios_penalize_isa_irq(int irq)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/frv/mb93090-mb00/pci-frv.c +0 -6
index 6b4fb28..6a0cd64 100644
@@ -195,12 +195,6 @@ void __init pcibios_resource_survey(void)
 	pcibios_assign_resources();
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
arch/frv/mb93090-mb00/pci-frv.h +0 -2
index f3fe559..089eeba 100644
@@ -26,8 +26,6 @@ extern unsigned int __nongpreldata pci_probe;
 
 /* pci-frv.c */
 
-extern unsigned int pcibios_max_latency;
-
 void pcibios_resource_survey(void);
 
 /* pci-vdk.c */
arch/h8300/include/asm/pci.h +0 -5
index cc97620..0b2acaa 100644
@@ -9,11 +9,6 @@
 
 #define pcibios_assign_all_busses()	0
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
arch/mips/pci/pci.c +0 -6
index 33bba7b..a6de9b8 100644
@@ -204,12 +204,6 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-static unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
arch/mn10300/unit-asb2305/pci-asb2305.c +0 -6
index 8e6763e..2b299c4 100644
@@ -213,12 +213,6 @@ void __init pcibios_resource_survey(void)
 	pcibios_allocate_resources(1);
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
arch/mn10300/unit-asb2305/pci-asb2305.h +0 -2
index c3fa294..1194fe4 100644
@@ -31,8 +31,6 @@ extern unsigned int pci_probe;
 
 /* pci-asb2305.c */
 
-extern unsigned int pcibios_max_latency;
-
 extern void pcibios_resource_survey(void);
 
 /* pci.c */
arch/sh/drivers/pci/pci.c +0 -6
index 194231c..a0c92fd 100644
@@ -242,12 +242,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return pci_enable_resources(dev, mask);
 }
 
-/*
- *  If we set up a device for bus mastering, we need to check and set
- *  the latency timer as it may not be properly set.
- */
-static unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
arch/x86/include/asm/pci_x86.h +0 -2
index 7045267..497c8a3 100644
@@ -44,8 +44,6 @@ enum pci_bf_sort_state {
 
 /* pci-i386.c */
 
-extern unsigned int pcibios_max_latency;
-
 void pcibios_resource_survey(void);
 void pcibios_set_cache_line_size(void);
 
arch/x86/pci/i386.c +0 -6
index 494f2e7..5663bc2 100644
@@ -253,12 +253,6 @@ void __init pcibios_resource_survey(void)
  */
 fs_initcall(pcibios_assign_resources);
 
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
 void pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
drivers/pci/pci.c +29 -0
index 466fad6..a50e643 100644
@@ -88,6 +88,12 @@ enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
 u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2;
 u8 pci_cache_line_size;
 
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as certain BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -2590,6 +2596,29 @@ static void __pci_set_master(struct pci_dev *dev, bool enable)
 }
 
 /**
+ * pcibios_set_master - enable PCI bus-mastering for device dev
+ * @dev: the PCI device to enable
+ *
+ * Enables PCI bus-mastering for the device.  This is the default
+ * implementation.  Architecture specific implementations can override
+ * this if necessary.
+ */
+void __weak pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+/**
  * pci_set_master - enables bus-mastering for device dev
  * @dev: the PCI device to enable
  *
include/linux/pci.h +3 -0
index abbd8b6..182b93d 100644
@@ -790,8 +790,11 @@ static inline int pci_is_managed(struct pci_dev *pdev)
 }
 
 void pci_disable_device(struct pci_dev *dev);
+
+extern unsigned int pcibios_max_latency;
 void pci_set_master(struct pci_dev *dev);
 void pci_clear_master(struct pci_dev *dev);
+
 int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
 int pci_set_cacheline_size(struct pci_dev *dev);
 #define HAVE_PCI_SET_MWI
#14 lore raw

PATCH 11/16 PCI: frv: use generic pcibios_set_master()

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch removes frv's architecture-specific 'pcibios_set_master()' routine and lets the default PCI core based implementation handle PCI device 'latency timer' setup.

No functional change.

---

 arch/frv/mb93090-mb00/pci-frv.c |   14 --------------
 1 files changed, 0 insertions(+), 14 deletions(-)
arch/frv/mb93090-mb00/pci-frv.c +0 -14
index 6a0cd64..c281217 100644
@@ -194,17 +194,3 @@ void __init pcibios_resource_survey(void)
 	pcibios_allocate_resources(1);
 	pcibios_assign_resources();
 }
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
#15 lore raw

PATCH 12/16 PCI: MIPS: use generic pcibios_set_master()

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch removes mip's architecture-specific 'pcibios_set_master()' routine and lets the default PCI core based implementation handle PCI device 'latency timer' setup.

No functional change.

---

 arch/mips/pci/pci.c |   15 ---------------
 1 files changed, 0 insertions(+), 15 deletions(-)
arch/mips/pci/pci.c +0 -15
index a6de9b8..19cce25 100644
@@ -204,21 +204,6 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
-	       pci_name(dev), lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
 unsigned int pcibios_assign_all_busses(void)
 {
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
#16 lore raw

PATCH 13/16 PCI: mn10300: use generic pcibios_set_master()

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch removes mn10300's architecture-specific 'pcibios_set_master()' routine for ASB2305 and lets the default PCI core based implementation handle PCI device 'latency timer' setup.

No functional change.

---

 arch/mn10300/unit-asb2305/pci-asb2305.c |   16 ----------------
 1 files changed, 0 insertions(+), 16 deletions(-)
arch/mn10300/unit-asb2305/pci-asb2305.c +0 -16
index 2b299c4..c4e2e79 100644
@@ -213,22 +213,6 @@ void __init pcibios_resource_survey(void)
 	pcibios_allocate_resources(1);
 }
 
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
 int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			enum pci_mmap_state mmap_state, int write_combine)
 {
#17 lore raw

PATCH 14/16 PCI: sh: use generic pcibios_set_master()

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch removes sh's architecture-specific 'pcibios_set_master()' routine and lets the default PCI core based implementation handle PCI device 'latency timer' setup.

No functional change.

---

 arch/sh/drivers/pci/pci.c |   15 ---------------
 1 files changed, 0 insertions(+), 15 deletions(-)
arch/sh/drivers/pci/pci.c +0 -15
index a0c92fd..280e2a1 100644
@@ -242,21 +242,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return pci_enable_resources(dev, mask);
 }
 
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n",
-	       pci_name(dev), lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
 void __init pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
#18 lore raw

PATCH 15/16 PCI: x86: use generic pcibios_set_master()

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

This patch removes x86's architecture-specific 'pcibios_set_master()' routine and lets the default PCI core based implementation handle PCI device 'latency timer' setup.

No functional change.

---

 arch/x86/pci/i386.c |   14 --------------
 1 files changed, 0 insertions(+), 14 deletions(-)
arch/x86/pci/i386.c +0 -14
index 5663bc2..463c247 100644
@@ -253,20 +253,6 @@ void __init pcibios_resource_survey(void)
  */
 fs_initcall(pcibios_assign_resources);
 
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
 static const struct vm_operations_struct pci_mmap_ops = {
 	.access = generic_access_phys,
 };
#19 lore raw

PATCH 16/16 PCI: latency timer doesn't apply to PCIe

In reply to Myron Stowe

From: Myron Stowe <[email protected]>

The latency timer is read-only and hardwired to zero for all PCIe devices, both Type 0 and Type 1, so don't bother trying to update it and cluttering the dmesg log with meaningless "setting latency timer to 64" messages.

---

 drivers/pci/pci.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/pci/pci.c +4 -0
index a50e643..a20c01a 100644
@@ -2607,6 +2607,10 @@ void __weak pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
 
+	/* The latency timer doesn't apply to PCIe (either Type 0 or Type 1) */
+	if (pci_is_pcie(dev))
+		return;
+
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
 	if (lat < 16)
 		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
#20 lore raw
In reply to Myron Stowe
Quoted 3 lines · Myron Stowe

 - * blackfin and h8300 architectures do not seem to support PCI (no root bus scanning etc. exists within them) but they do have PCI header files.

correct, all Blackfin parts in current mainline lack any sort of PCI support. the header existence (iirc) is two fold:
- a lot of drivers like to use the pci/dma interface to manage memory
instead of a pure dma interface
- BF535 has pci support, but we don't support that, and have largely
dropped anything related to it

so if this compile passes for Blackfin, it should be fine. however, i'm lazy, so i don't suppose you've got a branch somewhere for me to pull to quickly compile test ? if not, simply putting it into a branch that gets into linux-next should be sufficient as i think Stephen had Blackfin coverage in there ...
-mike

#21 lore raw
Quoted 12 lines · Mike Frysinger
Quoted 3 lines · Myron Stowe

 - * blackfin and h8300 architectures do not seem to support PCI (no root bus scanning etc. exists within them) but they do have PCI header files.

correct, all Blackfin parts in current mainline lack any sort of PCI support.  the header existence (iirc) is two fold:
 - a lot of drivers like to use the pci/dma interface to manage memory instead of a pure dma interface
 - BF535 has pci support, but we don't support that, and have largely dropped anything related to it

Quoted 5 lines

so if this compile passes for Blackfin, it should be fine.  however, i'm lazy, so i don't suppose you've got a branch somewhere for me to pull to quickly compile test ?  if not, simply putting it into a branch that gets into linux-next should be sufficient as i think Stephen had Blackfin coverage in there ...

Hi Mike,

Don't blame you for being lazy, maintainership is not a fun task. I do not have a cross compile environment so could not compile test Blackfin so I really would be interested in such. I don't want to rely on linux-next if at all possible as I already tried that once - unsuccessfully.

The three architectures I would really like to get compile tested and feedback from the maintainers are: ARM, Blackfin, and H3/800. To compile test Blackfin would only require pulling in patches 01/16 and 10/16 (which would be the same for H3/800) so if that wouldn't be too much of a pain I would really appreciate it. I do not have a branch from which you could pull but I am willing
to look into such and give it a try.

Myron

Quoted 6 lines

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

#22 lore raw
In reply to Mike Frysinger
Quoted 12 lines · Mike Frysinger
Quoted 3 lines · Myron Stowe

 - * blackfin and h8300 architectures do not seem to support PCI (no root bus scanning etc. exists within them) but they do have PCI header files.

correct, all Blackfin parts in current mainline lack any sort of PCI support.  the header existence (iirc) is two fold:
 - a lot of drivers like to use the pci/dma interface to manage memory instead of a pure dma interface
 - BF535 has pci support, but we don't support that, and have largely dropped anything related to it

Quoted 3 lines

so if this compile passes for Blackfin, it should be fine.  however, i'm lazy, so i don't suppose you've got a branch somewhere for me to pull to quickly compile test ?

I created a 'pci-latency-v2' branch at git://github.com/myron-stowe/linux.git
that maintainers of the various architectures can use to pull from for a compile test of this patch series.

Myron

Quoted 9 lines

 if not, simply putting it into a
branch that gets into linux-next should be sufficient as i think Stephen had Blackfin coverage in there ...
-mike
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

#23 lore raw
In reply to Myron Stowe
Quoted 7 lines · On Fri, 28 Oct 2011 15:47:26 -0600 Myron Stowe <[email protected]> wrote:

The 'latency timer' of PCI devices, both Type 0 and Type 1, is setup in architecture-specific code [see: pcibios_set_master()]. There are two approaches being taken by all the architectures - check if the 'latency timer' is currently set between 16 and 255 and if not bring it within bounds, or, do nothing (and then there is the gratuitously different parisc implementation).

Quoted 5 lines

There is nothing architecture-specific about PCI's 'latency timer' so this patch pulls the setup functionality up into the PCI core by creating a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over-ridden by architecture-specific code.

I have acks from Chris, Ralf, and Mike. Any other arch maintainers want to ack or nack this before it goes into my -next branch?

Thanks,

Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center
#24 lore raw
Quoted 10 lines · Jesse Barnes
Quoted 7 lines · On Fri, 28 Oct 2011 15:47:26 -0600 Myron Stowe <[email protected]> wrote:

The 'latency timer' of PCI devices, both Type 0 and Type 1, is setup in architecture-specific code [see: pcibios_set_master()]. There are two approaches being taken by all the architectures - check if the 'latency timer' is currently set between 16 and 255 and if not bring it within bounds, or, do nothing (and then there is the gratuitously different parisc implementation).

Quoted 8 lines
Quoted 5 lines

There is nothing architecture-specific about PCI's 'latency timer' so this patch pulls the setup functionality up into the PCI core by creating a generic 'pcibios_set_master()' function using the '__weak' attribute which can be used by all architectures as a default which, if necessary, can then be over-ridden by architecture-specific code.

I have acks from Chris, Ralf, and Mike. Any other arch maintainers want to ack or nack this before it goes into my -next branch?

I somewhat missed the original patch. As long as it's a nop for ppc, I don't care tho :-)

Cheers,
Ben.