OSDN Git Service

s390/pci: uninline instruction wrappers
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Tue, 16 Apr 2013 12:14:44 +0000 (14:14 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 17 Apr 2013 12:07:37 +0000 (14:07 +0200)
Uninline pci related instruction wrappers to de-bloat the code:
add/remove: 15/0 grow/shrink: 2/24 up/down: 1326/-12628 (-11302)

This is especially useful for the inlined pci read and write functions
which are used all over the kernel. Also remove the unused __stpcifc
while at it.

Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/pci_insn.h
arch/s390/pci/Makefile
arch/s390/pci/pci_insn.c [new file with mode: 0644]

index 1486a98..c6649e7 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef _ASM_S390_PCI_INSN_H
 #define _ASM_S390_PCI_INSN_H
 
-#include <linux/delay.h>
-
-#define ZPCI_INSN_BUSY_DELAY   1       /* 1 microsecond */
-
 /* Load/Store status codes */
 #define ZPCI_PCI_ST_FUNC_NOT_ENABLED           4
 #define ZPCI_PCI_ST_FUNC_IN_ERR                        8
@@ -82,199 +78,12 @@ struct zpci_fib {
        u64 reserved7;
 } __packed;
 
-/* Modify PCI Function Controls */
-static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status)
-{
-       u8 cc;
-
-       asm volatile (
-               "       .insn   rxy,0xe300000000d0,%[req],%[fib]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib)
-               : : "cc");
-       *status = req >> 24 & 0xff;
-       return cc;
-}
-
-static inline int mpcifc_instr(u64 req, struct zpci_fib *fib)
-{
-       u8 cc, status;
-
-       do {
-               cc = __mpcifc(req, fib, &status);
-               if (cc == 2)
-                       msleep(ZPCI_INSN_BUSY_DELAY);
-       } while (cc == 2);
-
-       if (cc)
-               printk_once(KERN_ERR "%s: error cc: %d  status: %d\n",
-                            __func__, cc, status);
-       return (cc) ? -EIO : 0;
-}
-
-/* Refresh PCI Translations */
-static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status)
-{
-       register u64 __addr asm("2") = addr;
-       register u64 __range asm("3") = range;
-       u8 cc;
-
-       asm volatile (
-               "       .insn   rre,0xb9d30000,%[fn],%[addr]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [fn] "+d" (fn)
-               : [addr] "d" (__addr), "d" (__range)
-               : "cc");
-       *status = fn >> 24 & 0xff;
-       return cc;
-}
-
-static inline int rpcit_instr(u64 fn, u64 addr, u64 range)
-{
-       u8 cc, status;
-
-       do {
-               cc = __rpcit(fn, addr, range, &status);
-               if (cc == 2)
-                       udelay(ZPCI_INSN_BUSY_DELAY);
-       } while (cc == 2);
-
-       if (cc)
-               printk_once(KERN_ERR "%s: error cc: %d  status: %d  dma_addr: %Lx  size: %Lx\n",
-                           __func__, cc, status, addr, range);
-       return (cc) ? -EIO : 0;
-}
-
-/* Store PCI function controls */
-static inline u8 __stpcifc(u32 handle, u8 space, struct zpci_fib *fib, u8 *status)
-{
-       u64 fn = (u64) handle << 32 | space << 16;
-       u8 cc;
-
-       asm volatile (
-               "       .insn   rxy,0xe300000000d4,%[fn],%[fib]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [fn] "+d" (fn), [fib] "=m" (*fib)
-               : : "cc");
-       *status = fn >> 24 & 0xff;
-       return cc;
-}
-
-/* Set Interruption Controls */
-static inline void sic_instr(u16 ctl, char *unused, u8 isc)
-{
-       asm volatile (
-               "       .insn   rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n"
-               : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused));
-}
-
-/* PCI Load */
-static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status)
-{
-       register u64 __req asm("2") = req;
-       register u64 __offset asm("3") = offset;
-       u64 __data;
-       u8 cc;
-
-       asm volatile (
-               "       .insn   rre,0xb9d20000,%[data],%[req]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req)
-               :  "d" (__offset)
-               : "cc");
-       *status = __req >> 24 & 0xff;
-       *data = __data;
-       return cc;
-}
-
-static inline int pcilg_instr(u64 *data, u64 req, u64 offset)
-{
-       u8 cc, status;
-
-       do {
-               cc = __pcilg(data, req, offset, &status);
-               if (cc == 2)
-                       udelay(ZPCI_INSN_BUSY_DELAY);
-       } while (cc == 2);
-
-       if (cc) {
-               printk_once(KERN_ERR "%s: error cc: %d  status: %d  req: %Lx  offset: %Lx\n",
-                           __func__, cc, status, req, offset);
-               /* TODO: on IO errors set data to 0xff...
-                * here or in users of pcilg (le conversion)?
-                */
-       }
-       return (cc) ? -EIO : 0;
-}
-
-/* PCI Store */
-static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status)
-{
-       register u64 __req asm("2") = req;
-       register u64 __offset asm("3") = offset;
-       u8 cc;
-
-       asm volatile (
-               "       .insn   rre,0xb9d00000,%[data],%[req]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [req] "+d" (__req)
-               : "d" (__offset), [data] "d" (data)
-               : "cc");
-       *status = __req >> 24 & 0xff;
-       return cc;
-}
-
-static inline int pcistg_instr(u64 data, u64 req, u64 offset)
-{
-       u8 cc, status;
-
-       do {
-               cc = __pcistg(data, req, offset, &status);
-               if (cc == 2)
-                       udelay(ZPCI_INSN_BUSY_DELAY);
-       } while (cc == 2);
-
-       if (cc)
-               printk_once(KERN_ERR "%s: error cc: %d  status: %d  req: %Lx  offset: %Lx\n",
-                       __func__, cc, status, req, offset);
-       return (cc) ? -EIO : 0;
-}
-
-/* PCI Store Block */
-static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status)
-{
-       u8 cc;
-
-       asm volatile (
-               "       .insn   rsy,0xeb00000000d0,%[req],%[offset],%[data]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [req] "+d" (req)
-               : [offset] "d" (offset), [data] "Q" (*data)
-               : "cc");
-       *status = req >> 24 & 0xff;
-       return cc;
-}
-
-static inline int pcistb_instr(const u64 *data, u64 req, u64 offset)
-{
-       u8 cc, status;
-
-       do {
-               cc = __pcistb(data, req, offset, &status);
-               if (cc == 2)
-                       udelay(ZPCI_INSN_BUSY_DELAY);
-       } while (cc == 2);
 
-       if (cc)
-               printk_once(KERN_ERR "%s: error cc: %d  status: %d  req: %Lx  offset: %Lx\n",
-                           __func__, cc, status, req, offset);
-       return (cc) ? -EIO : 0;
-}
+int mpcifc_instr(u64 req, struct zpci_fib *fib);
+int rpcit_instr(u64 fn, u64 addr, u64 range);
+void sic_instr(u16 ctl, char *unused, u8 isc);
+int pcilg_instr(u64 *data, u64 req, u64 offset);
+int pcistg_instr(u64 data, u64 req, u64 offset);
+int pcistb_instr(const u64 *data, u64 req, u64 offset);
 
 #endif
index f0f426a..086a2e3 100644 (file)
@@ -2,5 +2,5 @@
 # Makefile for the s390 PCI subsystem.
 #
 
-obj-$(CONFIG_PCI)      += pci.o pci_dma.o pci_clp.o pci_msi.o \
-                          pci_sysfs.o pci_event.o pci_debug.o
+obj-$(CONFIG_PCI)      += pci.o pci_dma.o pci_clp.o pci_msi.o pci_sysfs.o \
+                          pci_event.o pci_debug.o pci_insn.o
diff --git a/arch/s390/pci/pci_insn.c b/arch/s390/pci/pci_insn.c
new file mode 100644 (file)
index 0000000..c559625
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * s390 specific pci instructions
+ *
+ * Copyright IBM Corp. 2013
+ */
+
+#include <linux/export.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <asm/pci_insn.h>
+
+#define ZPCI_INSN_BUSY_DELAY   1       /* 1 microsecond */
+
+/* Modify PCI Function Controls */
+static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status)
+{
+       u8 cc;
+
+       asm volatile (
+               "       .insn   rxy,0xe300000000d0,%[req],%[fib]\n"
+               "       ipm     %[cc]\n"
+               "       srl     %[cc],28\n"
+               : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib)
+               : : "cc");
+       *status = req >> 24 & 0xff;
+       return cc;
+}
+
+int mpcifc_instr(u64 req, struct zpci_fib *fib)
+{
+       u8 cc, status;
+
+       do {
+               cc = __mpcifc(req, fib, &status);
+               if (cc == 2)
+                       msleep(ZPCI_INSN_BUSY_DELAY);
+       } while (cc == 2);
+
+       if (cc)
+               printk_once(KERN_ERR "%s: error cc: %d  status: %d\n",
+                            __func__, cc, status);
+       return (cc) ? -EIO : 0;
+}
+
+/* Refresh PCI Translations */
+static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status)
+{
+       register u64 __addr asm("2") = addr;
+       register u64 __range asm("3") = range;
+       u8 cc;
+
+       asm volatile (
+               "       .insn   rre,0xb9d30000,%[fn],%[addr]\n"
+               "       ipm     %[cc]\n"
+               "       srl     %[cc],28\n"
+               : [cc] "=d" (cc), [fn] "+d" (fn)
+               : [addr] "d" (__addr), "d" (__range)
+               : "cc");
+       *status = fn >> 24 & 0xff;
+       return cc;
+}
+
+int rpcit_instr(u64 fn, u64 addr, u64 range)
+{
+       u8 cc, status;
+
+       do {
+               cc = __rpcit(fn, addr, range, &status);
+               if (cc == 2)
+                       udelay(ZPCI_INSN_BUSY_DELAY);
+       } while (cc == 2);
+
+       if (cc)
+               printk_once(KERN_ERR "%s: error cc: %d  status: %d  dma_addr: %Lx  size: %Lx\n",
+                           __func__, cc, status, addr, range);
+       return (cc) ? -EIO : 0;
+}
+
+/* Set Interruption Controls */
+void sic_instr(u16 ctl, char *unused, u8 isc)
+{
+       asm volatile (
+               "       .insn   rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n"
+               : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused));
+}
+
+/* PCI Load */
+static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status)
+{
+       register u64 __req asm("2") = req;
+       register u64 __offset asm("3") = offset;
+       u64 __data;
+       u8 cc;
+
+       asm volatile (
+               "       .insn   rre,0xb9d20000,%[data],%[req]\n"
+               "       ipm     %[cc]\n"
+               "       srl     %[cc],28\n"
+               : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req)
+               :  "d" (__offset)
+               : "cc");
+       *status = __req >> 24 & 0xff;
+       *data = __data;
+       return cc;
+}
+
+int pcilg_instr(u64 *data, u64 req, u64 offset)
+{
+       u8 cc, status;
+
+       do {
+               cc = __pcilg(data, req, offset, &status);
+               if (cc == 2)
+                       udelay(ZPCI_INSN_BUSY_DELAY);
+       } while (cc == 2);
+
+       if (cc) {
+               printk_once(KERN_ERR "%s: error cc: %d  status: %d  req: %Lx  offset: %Lx\n",
+                           __func__, cc, status, req, offset);
+               /* TODO: on IO errors set data to 0xff...
+                * here or in users of pcilg (le conversion)?
+                */
+       }
+       return (cc) ? -EIO : 0;
+}
+EXPORT_SYMBOL_GPL(pcilg_instr);
+
+/* PCI Store */
+static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status)
+{
+       register u64 __req asm("2") = req;
+       register u64 __offset asm("3") = offset;
+       u8 cc;
+
+       asm volatile (
+               "       .insn   rre,0xb9d00000,%[data],%[req]\n"
+               "       ipm     %[cc]\n"
+               "       srl     %[cc],28\n"
+               : [cc] "=d" (cc), [req] "+d" (__req)
+               : "d" (__offset), [data] "d" (data)
+               : "cc");
+       *status = __req >> 24 & 0xff;
+       return cc;
+}
+
+int pcistg_instr(u64 data, u64 req, u64 offset)
+{
+       u8 cc, status;
+
+       do {
+               cc = __pcistg(data, req, offset, &status);
+               if (cc == 2)
+                       udelay(ZPCI_INSN_BUSY_DELAY);
+       } while (cc == 2);
+
+       if (cc)
+               printk_once(KERN_ERR "%s: error cc: %d  status: %d  req: %Lx  offset: %Lx\n",
+                       __func__, cc, status, req, offset);
+       return (cc) ? -EIO : 0;
+}
+EXPORT_SYMBOL_GPL(pcistg_instr);
+
+/* PCI Store Block */
+static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status)
+{
+       u8 cc;
+
+       asm volatile (
+               "       .insn   rsy,0xeb00000000d0,%[req],%[offset],%[data]\n"
+               "       ipm     %[cc]\n"
+               "       srl     %[cc],28\n"
+               : [cc] "=d" (cc), [req] "+d" (req)
+               : [offset] "d" (offset), [data] "Q" (*data)
+               : "cc");
+       *status = req >> 24 & 0xff;
+       return cc;
+}
+
+int pcistb_instr(const u64 *data, u64 req, u64 offset)
+{
+       u8 cc, status;
+
+       do {
+               cc = __pcistb(data, req, offset, &status);
+               if (cc == 2)
+                       udelay(ZPCI_INSN_BUSY_DELAY);
+       } while (cc == 2);
+
+       if (cc)
+               printk_once(KERN_ERR "%s: error cc: %d  status: %d  req: %Lx  offset: %Lx\n",
+                           __func__, cc, status, req, offset);
+       return (cc) ? -EIO : 0;
+}
+EXPORT_SYMBOL_GPL(pcistb_instr);