Blob Blame History Raw
From: Jiri Slaby <jslaby@suse.cz>
Subject: kABI: PCI: Add locking to RMW PCI Express Capability Register accessors
Patch-mainline: never, kabi
References: kabi

Commit 5e70d0acf082 (PCI: Add locking to RMW PCI Express Capability
Register accessors) added a spinlock to struct pci_dev. It also made an
inline from pcie_capability_clear_and_set_word(). All this made the
kABI checker complaining.

Hide the spinlock from the kabi checker as struct pci_dev is exclusively
allocated by pci_alloc_dev(). Only move it to the end, so that offsets
do not change.

Convert pcie_capability_clear_and_set_word() from inline back to an
exported function.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/pci/access.c |   27 +++++++++++++++++++++++++++
 include/linux/pci.h  |   33 +++++----------------------------
 2 files changed, 32 insertions(+), 28 deletions(-)

--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -885,6 +885,33 @@ int pcie_capability_clear_and_set_word_l
 }
 EXPORT_SYMBOL(pcie_capability_clear_and_set_word_locked);
 
+/**
+ * pcie_capability_clear_and_set_word - RMW accessor for PCI Express Capability Registers
+ * @dev:	PCI device structure of the PCI Express device
+ * @pos:	PCI Express Capability Register
+ * @clear:	Clear bitmask
+ * @set:	Set bitmask
+ *
+ * Perform a Read-Modify-Write (RMW) operation using @clear and @set
+ * bitmasks on PCI Express Capability Register at @pos. Certain PCI Express
+ * Capability Registers are accessed concurrently in RMW fashion, hence
+ * require locking which is handled transparently to the caller.
+ */
+int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+				       u16 clear, u16 set)
+{
+	switch (pos) {
+	case PCI_EXP_LNKCTL:
+	case PCI_EXP_RTCTL:
+		return pcie_capability_clear_and_set_word_locked(dev, pos,
+								 clear, set);
+	default:
+		return pcie_capability_clear_and_set_word_unlocked(dev, pos,
+								   clear, set);
+	}
+}
+EXPORT_SYMBOL(pcie_capability_clear_and_set_word);
+
 int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
 					u32 clear, u32 set)
 {
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -419,7 +419,6 @@ struct pci_dev {
 	pci_dev_flags_t dev_flags;
 	atomic_t	enable_cnt;	/* pci_enable_device has been called */
 
-	spinlock_t	pcie_cap_lock;		/* Protects RMW ops in capability accessors */
 	u32		saved_config_space[16]; /* config space saved at suspend time */
 	struct hlist_head saved_cap_space;
 	struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
@@ -466,6 +465,9 @@ struct pci_dev {
 #ifndef __GENKSYMS__
 	unsigned int	no_command_memory:1;	/* No PCI_COMMAND_MEMORY */
 #endif
+#ifndef __GENKSYMS__
+	spinlock_t	pcie_cap_lock;		/* Protects RMW ops in capability accessors */
+#endif
 };
 
 static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
@@ -1050,6 +1052,8 @@ int pcie_capability_read_word(struct pci
 int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val);
 int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val);
 int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val);
+int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+				       u16 clear, u16 set);
 int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos,
 						u16 clear, u16 set);
 int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos,
@@ -1057,33 +1061,6 @@ int pcie_capability_clear_and_set_word_l
 int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
 					u32 clear, u32 set);
 
-/**
- * pcie_capability_clear_and_set_word - RMW accessor for PCI Express Capability Registers
- * @dev:	PCI device structure of the PCI Express device
- * @pos:	PCI Express Capability Register
- * @clear:	Clear bitmask
- * @set:	Set bitmask
- *
- * Perform a Read-Modify-Write (RMW) operation using @clear and @set
- * bitmasks on PCI Express Capability Register at @pos. Certain PCI Express
- * Capability Registers are accessed concurrently in RMW fashion, hence
- * require locking which is handled transparently to the caller.
- */
-static inline int pcie_capability_clear_and_set_word(struct pci_dev *dev,
-						     int pos,
-						     u16 clear, u16 set)
-{
-	switch (pos) {
-	case PCI_EXP_LNKCTL:
-	case PCI_EXP_RTCTL:
-		return pcie_capability_clear_and_set_word_locked(dev, pos,
-								 clear, set);
-	default:
-		return pcie_capability_clear_and_set_word_unlocked(dev, pos,
-								   clear, set);
-	}
-}
-
 static inline int pcie_capability_set_word(struct pci_dev *dev, int pos,
 					   u16 set)
 {