aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHitoshi Mitake <mitake@dcl.info.waseda.ac.jp>2012-02-06 21:45:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-02-21 19:47:28 -0500
commit797a796a13df6b84a4791e57306737059b5b2384 (patch)
tree400d13deef98fdf3fc893e9e55f208c5716b8ba9
parent27e74da9800289e69ba907777df1e2085231eff7 (diff)
asm-generic: architecture independent readq/writeq for 32bit environment
This provides unified readq()/writeq() helper functions for 32-bit drivers. For some cases, readq/writeq without atomicity is harmful, and order of io access has to be specified explicitly. So in this patch, new two header files which contain non-atomic readq/writeq are added. - <asm-generic/io-64-nonatomic-lo-hi.h> provides non-atomic readq/ writeq with the order of lower address -> higher address - <asm-generic/io-64-nonatomic-hi-lo.h> provides non-atomic readq/ writeq with reversed order This allows us to remove some readq()s that were added drivers when the default non-atomic ones were removed in commit dbee8a0affd5 ("x86: remove 32-bit versions of readq()/writeq()") The drivers which need readq/writeq but can do with the non-atomic ones must add the line: #include <asm-generic/io-64-nonatomic-lo-hi.h> /* or hi-lo.h */ But this will be nop in 64-bit environments, and no other #ifdefs are required. So I believe that this patch can solve the problem of 1. driver-specific readq/writeq 2. atomicity and order of io access This patch is tested with building allyesconfig and allmodconfig as ARCH=x86 and ARCH=i386 on top of tip/master. Cc: Kashyap Desai <Kashyap.Desai@lsi.com> Cc: Len Brown <lenb@kernel.org> Cc: Ravi Anand <ravi.anand@qlogic.com> Cc: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Cc: Matthew Garrett <mjg@redhat.com> Cc: Jason Uhlenkott <juhlenko@akamai.com> Cc: James Bottomley <James.Bottomley@parallels.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Roland Dreier <roland@purestorage.com> Cc: James Bottomley <jbottomley@parallels.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Matthew Wilcox <matthew.r.wilcox@intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Hitoshi Mitake <h.mitake@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/block/nvme.c2
-rw-r--r--drivers/edac/i3200_edac.c15
-rw-r--r--drivers/platform/x86/ibm_rtl.c15
-rw-r--r--drivers/platform/x86/intel_ips.c15
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c23
-rw-r--r--include/asm-generic/io-64-nonatomic-hi-lo.h28
-rw-r--r--include/asm-generic/io-64-nonatomic-lo-hi.h28
7 files changed, 66 insertions, 60 deletions
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index c1dc4d86c221..1f3c1a7d132a 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -41,6 +41,8 @@
41#include <linux/types.h> 41#include <linux/types.h>
42#include <linux/version.h> 42#include <linux/version.h>
43 43
44#include <asm-generic/io-64-nonatomic-lo-hi.h>
45
44#define NVME_Q_DEPTH 1024 46#define NVME_Q_DEPTH 1024
45#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) 47#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command))
46#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) 48#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion))
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
index aa08497a075a..73f55e2008c2 100644
--- a/drivers/edac/i3200_edac.c
+++ b/drivers/edac/i3200_edac.c
@@ -15,6 +15,8 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include "edac_core.h" 16#include "edac_core.h"
17 17
18#include <asm-generic/io-64-nonatomic-lo-hi.h>
19
18#define I3200_REVISION "1.1" 20#define I3200_REVISION "1.1"
19 21
20#define EDAC_MOD_STR "i3200_edac" 22#define EDAC_MOD_STR "i3200_edac"
@@ -101,19 +103,6 @@ struct i3200_priv {
101 103
102static int nr_channels; 104static int nr_channels;
103 105
104#ifndef readq
105static inline __u64 readq(const volatile void __iomem *addr)
106{
107 const volatile u32 __iomem *p = addr;
108 u32 low, high;
109
110 low = readl(p);
111 high = readl(p + 1);
112
113 return low + ((u64)high << 32);
114}
115#endif
116
117static int how_many_channels(struct pci_dev *pdev) 106static int how_many_channels(struct pci_dev *pdev)
118{ 107{
119 unsigned char capid0_8b; /* 8th byte of CAPID0 */ 108 unsigned char capid0_8b; /* 8th byte of CAPID0 */
diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c
index 42a7d603c870..7481146a5b47 100644
--- a/drivers/platform/x86/ibm_rtl.c
+++ b/drivers/platform/x86/ibm_rtl.c
@@ -33,6 +33,8 @@
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <asm/bios_ebda.h> 34#include <asm/bios_ebda.h>
35 35
36#include <asm-generic/io-64-nonatomic-lo-hi.h>
37
36static bool force; 38static bool force;
37module_param(force, bool, 0); 39module_param(force, bool, 0);
38MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); 40MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -83,19 +85,6 @@ static void __iomem *rtl_cmd_addr;
83static u8 rtl_cmd_type; 85static u8 rtl_cmd_type;
84static u8 rtl_cmd_width; 86static u8 rtl_cmd_width;
85 87
86#ifndef readq
87static inline __u64 readq(const volatile void __iomem *addr)
88{
89 const volatile u32 __iomem *p = addr;
90 u32 low, high;
91
92 low = readl(p);
93 high = readl(p + 1);
94
95 return low + ((u64)high << 32);
96}
97#endif
98
99static void __iomem *rtl_port_map(phys_addr_t addr, unsigned long len) 88static void __iomem *rtl_port_map(phys_addr_t addr, unsigned long len)
100{ 89{
101 if (rtl_cmd_type == RTL_ADDR_TYPE_MMIO) 90 if (rtl_cmd_type == RTL_ADDR_TYPE_MMIO)
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 809a3ae943c6..88a98cff5a44 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -77,6 +77,8 @@
77#include <asm/processor.h> 77#include <asm/processor.h>
78#include "intel_ips.h" 78#include "intel_ips.h"
79 79
80#include <asm-generic/io-64-nonatomic-lo-hi.h>
81
80#define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32 82#define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
81 83
82/* 84/*
@@ -344,19 +346,6 @@ struct ips_driver {
344static bool 346static bool
345ips_gpu_turbo_enabled(struct ips_driver *ips); 347ips_gpu_turbo_enabled(struct ips_driver *ips);
346 348
347#ifndef readq
348static inline __u64 readq(const volatile void __iomem *addr)
349{
350 const volatile u32 __iomem *p = addr;
351 u32 low, high;
352
353 low = readl(p);
354 high = readl(p + 1);
355
356 return low + ((u64)high << 32);
357}
358#endif
359
360/** 349/**
361 * ips_cpu_busy - is CPU busy? 350 * ips_cpu_busy - is CPU busy?
362 * @ips: IPS driver struct 351 * @ips: IPS driver struct
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 78f1111158d7..65253dfbe962 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -10,6 +10,8 @@
10#include "ql4_def.h" 10#include "ql4_def.h"
11#include "ql4_glbl.h" 11#include "ql4_glbl.h"
12 12
13#include <asm-generic/io-64-nonatomic-lo-hi.h>
14
13#define MASK(n) DMA_BIT_MASK(n) 15#define MASK(n) DMA_BIT_MASK(n)
14#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) 16#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
15#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) 17#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
@@ -655,27 +657,6 @@ static int qla4_8xxx_pci_is_same_window(struct scsi_qla_host *ha,
655 return 0; 657 return 0;
656} 658}
657 659
658#ifndef readq
659static inline __u64 readq(const volatile void __iomem *addr)
660{
661 const volatile u32 __iomem *p = addr;
662 u32 low, high;
663
664 low = readl(p);
665 high = readl(p + 1);
666
667 return low + ((u64)high << 32);
668}
669#endif
670
671#ifndef writeq
672static inline void writeq(__u64 val, volatile void __iomem *addr)
673{
674 writel(val, addr);
675 writel(val >> 32, addr+4);
676}
677#endif
678
679static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha, 660static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha,
680 u64 off, void *data, int size) 661 u64 off, void *data, int size)
681{ 662{
diff --git a/include/asm-generic/io-64-nonatomic-hi-lo.h b/include/asm-generic/io-64-nonatomic-hi-lo.h
new file mode 100644
index 000000000000..a6806a94250d
--- /dev/null
+++ b/include/asm-generic/io-64-nonatomic-hi-lo.h
@@ -0,0 +1,28 @@
1#ifndef _ASM_IO_64_NONATOMIC_HI_LO_H_
2#define _ASM_IO_64_NONATOMIC_HI_LO_H_
3
4#include <linux/io.h>
5#include <asm-generic/int-ll64.h>
6
7#ifndef readq
8static inline __u64 readq(const volatile void __iomem *addr)
9{
10 const volatile u32 __iomem *p = addr;
11 u32 low, high;
12
13 high = readl(p + 1);
14 low = readl(p);
15
16 return low + ((u64)high << 32);
17}
18#endif
19
20#ifndef writeq
21static inline void writeq(__u64 val, volatile void __iomem *addr)
22{
23 writel(val >> 32, addr + 4);
24 writel(val, addr);
25}
26#endif
27
28#endif /* _ASM_IO_64_NONATOMIC_HI_LO_H_ */
diff --git a/include/asm-generic/io-64-nonatomic-lo-hi.h b/include/asm-generic/io-64-nonatomic-lo-hi.h
new file mode 100644
index 000000000000..ca546b1ff8b5
--- /dev/null
+++ b/include/asm-generic/io-64-nonatomic-lo-hi.h
@@ -0,0 +1,28 @@
1#ifndef _ASM_IO_64_NONATOMIC_LO_HI_H_
2#define _ASM_IO_64_NONATOMIC_LO_HI_H_
3
4#include <linux/io.h>
5#include <asm-generic/int-ll64.h>
6
7#ifndef readq
8static inline __u64 readq(const volatile void __iomem *addr)
9{
10 const volatile u32 __iomem *p = addr;
11 u32 low, high;
12
13 low = readl(p);
14 high = readl(p + 1);
15
16 return low + ((u64)high << 32);
17}
18#endif
19
20#ifndef writeq
21static inline void writeq(__u64 val, volatile void __iomem *addr)
22{
23 writel(val, addr);
24 writel(val >> 32, addr + 4);
25}
26#endif
27
28#endif /* _ASM_IO_64_NONATOMIC_LO_HI_H_ */