aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2016-02-21 22:02:02 -0500
committerMark Brown <broonie@kernel.org>2016-02-21 22:02:02 -0500
commit99777b07efe3b533b4b6c67e59ad9138607c0467 (patch)
treeea3c53dfa6031d7c514670d860d36b4edb7a53a6
parent56e5fd8feb286ab71f4ca7674505b0d17967376d (diff)
parentaacaaa4c8e1cd3b813a3b77c9855e53d96381f40 (diff)
Merge branch 'topic/mmio' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into asoc-fsl-ssl
-rw-r--r--Documentation/devicetree/bindings/regmap/regmap.txt11
-rw-r--r--arch/mips/boot/dts/brcm/bcm6328.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm6368.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7125.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7346.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7358.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7360.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7362.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7420.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7425.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7435.dtsi2
-rw-r--r--drivers/base/regmap/regcache.c41
-rw-r--r--drivers/base/regmap/regmap-mmio.c259
-rw-r--r--drivers/base/regmap/regmap.c5
14 files changed, 191 insertions, 145 deletions
diff --git a/Documentation/devicetree/bindings/regmap/regmap.txt b/Documentation/devicetree/bindings/regmap/regmap.txt
index b494f8b8ef72..e98a9652ccc8 100644
--- a/Documentation/devicetree/bindings/regmap/regmap.txt
+++ b/Documentation/devicetree/bindings/regmap/regmap.txt
@@ -5,15 +5,18 @@ Index Device Endianness properties
5--------------------------------------------------- 5---------------------------------------------------
61 BE 'big-endian' 61 BE 'big-endian'
72 LE 'little-endian' 72 LE 'little-endian'
83 Native 'native-endian'
8 9
9For one device driver, which will run in different scenarios above 10For one device driver, which will run in different scenarios above
10on different SoCs using the devicetree, we need one way to simplify 11on different SoCs using the devicetree, we need one way to simplify
11this. 12this.
12 13
13Required properties: 14Optional properties:
14- {big,little}-endian: these are boolean properties, if absent 15- {big,little,native}-endian: these are boolean properties, if absent
15 meaning that the CPU and the Device are in the same endianness mode, 16 then the implementation will choose a default based on the device
16 these properties are for register values and all the buffers only. 17 being controlled. These properties are for register values and all
18 the buffers only. Native endian means that the CPU and device have
19 the same endianness.
17 20
18Examples: 21Examples:
19Scenario 1 : CPU in LE mode & device in LE mode. 22Scenario 1 : CPU in LE mode & device in LE mode.
diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi
index d61b1616b604..9d19236f53e7 100644
--- a/arch/mips/boot/dts/brcm/bcm6328.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi
@@ -74,7 +74,7 @@
74 timer: timer@10000040 { 74 timer: timer@10000040 {
75 compatible = "syscon"; 75 compatible = "syscon";
76 reg = <0x10000040 0x2c>; 76 reg = <0x10000040 0x2c>;
77 little-endian; 77 native-endian;
78 }; 78 };
79 79
80 reboot { 80 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm6368.dtsi b/arch/mips/boot/dts/brcm/bcm6368.dtsi
index 9c8d3fe28b31..1f6b9b5cddb4 100644
--- a/arch/mips/boot/dts/brcm/bcm6368.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm6368.dtsi
@@ -54,7 +54,7 @@
54 periph_cntl: syscon@10000000 { 54 periph_cntl: syscon@10000000 {
55 compatible = "syscon"; 55 compatible = "syscon";
56 reg = <0x10000000 0x14>; 56 reg = <0x10000000 0x14>;
57 little-endian; 57 native-endian;
58 }; 58 };
59 59
60 reboot: syscon-reboot@10000008 { 60 reboot: syscon-reboot@10000008 {
diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi
index 1a7efa883c5e..3ae16053a0c9 100644
--- a/arch/mips/boot/dts/brcm/bcm7125.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi
@@ -98,7 +98,7 @@
98 sun_top_ctrl: syscon@404000 { 98 sun_top_ctrl: syscon@404000 {
99 compatible = "brcm,bcm7125-sun-top-ctrl", "syscon"; 99 compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
100 reg = <0x404000 0x60c>; 100 reg = <0x404000 0x60c>;
101 little-endian; 101 native-endian;
102 }; 102 };
103 103
104 reboot { 104 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi
index d4bf52cfcf17..be7991917d29 100644
--- a/arch/mips/boot/dts/brcm/bcm7346.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi
@@ -118,7 +118,7 @@
118 sun_top_ctrl: syscon@404000 { 118 sun_top_ctrl: syscon@404000 {
119 compatible = "brcm,bcm7346-sun-top-ctrl", "syscon"; 119 compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
120 reg = <0x404000 0x51c>; 120 reg = <0x404000 0x51c>;
121 little-endian; 121 native-endian;
122 }; 122 };
123 123
124 reboot { 124 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi
index 8e2501694d03..060805be619a 100644
--- a/arch/mips/boot/dts/brcm/bcm7358.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi
@@ -112,7 +112,7 @@
112 sun_top_ctrl: syscon@404000 { 112 sun_top_ctrl: syscon@404000 {
113 compatible = "brcm,bcm7358-sun-top-ctrl", "syscon"; 113 compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
114 reg = <0x404000 0x51c>; 114 reg = <0x404000 0x51c>;
115 little-endian; 115 native-endian;
116 }; 116 };
117 117
118 reboot { 118 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi
index 7e5f76040fb8..bcdb09bfe07b 100644
--- a/arch/mips/boot/dts/brcm/bcm7360.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi
@@ -112,7 +112,7 @@
112 sun_top_ctrl: syscon@404000 { 112 sun_top_ctrl: syscon@404000 {
113 compatible = "brcm,bcm7360-sun-top-ctrl", "syscon"; 113 compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
114 reg = <0x404000 0x51c>; 114 reg = <0x404000 0x51c>;
115 little-endian; 115 native-endian;
116 }; 116 };
117 117
118 reboot { 118 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi
index c739ea77acb0..d3b1b762e6c3 100644
--- a/arch/mips/boot/dts/brcm/bcm7362.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi
@@ -118,7 +118,7 @@
118 sun_top_ctrl: syscon@404000 { 118 sun_top_ctrl: syscon@404000 {
119 compatible = "brcm,bcm7362-sun-top-ctrl", "syscon"; 119 compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
120 reg = <0x404000 0x51c>; 120 reg = <0x404000 0x51c>;
121 little-endian; 121 native-endian;
122 }; 122 };
123 123
124 reboot { 124 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi
index 5f55d0a50a28..3302a1b8a5c9 100644
--- a/arch/mips/boot/dts/brcm/bcm7420.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi
@@ -99,7 +99,7 @@
99 sun_top_ctrl: syscon@404000 { 99 sun_top_ctrl: syscon@404000 {
100 compatible = "brcm,bcm7420-sun-top-ctrl", "syscon"; 100 compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
101 reg = <0x404000 0x60c>; 101 reg = <0x404000 0x60c>;
102 little-endian; 102 native-endian;
103 }; 103 };
104 104
105 reboot { 105 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi
index e24d41ab4e30..15b27aae15a9 100644
--- a/arch/mips/boot/dts/brcm/bcm7425.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi
@@ -100,7 +100,7 @@
100 sun_top_ctrl: syscon@404000 { 100 sun_top_ctrl: syscon@404000 {
101 compatible = "brcm,bcm7425-sun-top-ctrl", "syscon"; 101 compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
102 reg = <0x404000 0x51c>; 102 reg = <0x404000 0x51c>;
103 little-endian; 103 native-endian;
104 }; 104 };
105 105
106 reboot { 106 reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi
index 8b9432cc062b..adb33e355043 100644
--- a/arch/mips/boot/dts/brcm/bcm7435.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi
@@ -114,7 +114,7 @@
114 sun_top_ctrl: syscon@404000 { 114 sun_top_ctrl: syscon@404000 {
115 compatible = "brcm,bcm7425-sun-top-ctrl", "syscon"; 115 compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
116 reg = <0x404000 0x51c>; 116 reg = <0x404000 0x51c>;
117 little-endian; 117 native-endian;
118 }; 118 };
119 119
120 reboot { 120 reboot {
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 348be3a35410..cccceb599b02 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -30,7 +30,7 @@ static int regcache_hw_init(struct regmap *map)
30 int i, j; 30 int i, j;
31 int ret; 31 int ret;
32 int count; 32 int count;
33 unsigned int val; 33 unsigned int reg, val;
34 void *tmp_buf; 34 void *tmp_buf;
35 35
36 if (!map->num_reg_defaults_raw) 36 if (!map->num_reg_defaults_raw)
@@ -67,27 +67,46 @@ static int regcache_hw_init(struct regmap *map)
67 ret = regmap_raw_read(map, 0, tmp_buf, 67 ret = regmap_raw_read(map, 0, tmp_buf,
68 map->num_reg_defaults_raw); 68 map->num_reg_defaults_raw);
69 map->cache_bypass = cache_bypass; 69 map->cache_bypass = cache_bypass;
70 if (ret < 0) 70 if (ret == 0) {
71 goto err_cache_free; 71 map->reg_defaults_raw = tmp_buf;
72 72 map->cache_free = 1;
73 map->reg_defaults_raw = tmp_buf; 73 } else {
74 map->cache_free = 1; 74 kfree(tmp_buf);
75 }
75 } 76 }
76 77
77 /* fill the reg_defaults */ 78 /* fill the reg_defaults */
78 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { 79 for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
79 if (regmap_volatile(map, i * map->reg_stride)) 80 reg = i * map->reg_stride;
81
82 if (!regmap_readable(map, reg))
80 continue; 83 continue;
81 val = regcache_get_val(map, map->reg_defaults_raw, i); 84
82 map->reg_defaults[j].reg = i * map->reg_stride; 85 if (regmap_volatile(map, reg))
86 continue;
87
88 if (map->reg_defaults_raw) {
89 val = regcache_get_val(map, map->reg_defaults_raw, i);
90 } else {
91 bool cache_bypass = map->cache_bypass;
92
93 map->cache_bypass = true;
94 ret = regmap_read(map, reg, &val);
95 map->cache_bypass = cache_bypass;
96 if (ret != 0) {
97 dev_err(map->dev, "Failed to read %d: %d\n",
98 reg, ret);
99 goto err_free;
100 }
101 }
102
103 map->reg_defaults[j].reg = reg;
83 map->reg_defaults[j].def = val; 104 map->reg_defaults[j].def = val;
84 j++; 105 j++;
85 } 106 }
86 107
87 return 0; 108 return 0;
88 109
89err_cache_free:
90 kfree(tmp_buf);
91err_free: 110err_free:
92 kfree(map->reg_defaults); 111 kfree(map->reg_defaults);
93 112
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c
index eea51569f0eb..7526906ca080 100644
--- a/drivers/base/regmap/regmap-mmio.c
+++ b/drivers/base/regmap/regmap-mmio.c
@@ -25,26 +25,14 @@
25 25
26struct regmap_mmio_context { 26struct regmap_mmio_context {
27 void __iomem *regs; 27 void __iomem *regs;
28 unsigned reg_bytes;
29 unsigned val_bytes; 28 unsigned val_bytes;
30 unsigned pad_bytes;
31 struct clk *clk; 29 struct clk *clk;
32};
33 30
34static inline void regmap_mmio_regsize_check(size_t reg_size) 31 void (*reg_write)(struct regmap_mmio_context *ctx,
35{ 32 unsigned int reg, unsigned int val);
36 switch (reg_size) { 33 unsigned int (*reg_read)(struct regmap_mmio_context *ctx,
37 case 1: 34 unsigned int reg);
38 case 2: 35};
39 case 4:
40#ifdef CONFIG_64BIT
41 case 8:
42#endif
43 break;
44 default:
45 BUG();
46 }
47}
48 36
49static int regmap_mmio_regbits_check(size_t reg_bits) 37static int regmap_mmio_regbits_check(size_t reg_bits)
50{ 38{
@@ -88,72 +76,62 @@ static int regmap_mmio_get_min_stride(size_t val_bits)
88 return min_stride; 76 return min_stride;
89} 77}
90 78
91static inline void regmap_mmio_count_check(size_t count, u32 offset) 79static void regmap_mmio_write8(struct regmap_mmio_context *ctx,
80 unsigned int reg,
81 unsigned int val)
82{
83 writeb(val, ctx->regs + reg);
84}
85
86static void regmap_mmio_write16le(struct regmap_mmio_context *ctx,
87 unsigned int reg,
88 unsigned int val)
92{ 89{
93 BUG_ON(count <= offset); 90 writew(val, ctx->regs + reg);
94} 91}
95 92
96static inline unsigned int 93static void regmap_mmio_write16be(struct regmap_mmio_context *ctx,
97regmap_mmio_get_offset(const void *reg, size_t reg_size) 94 unsigned int reg,
95 unsigned int val)
98{ 96{
99 switch (reg_size) { 97 iowrite16be(val, ctx->regs + reg);
100 case 1: 98}
101 return *(u8 *)reg; 99
102 case 2: 100static void regmap_mmio_write32le(struct regmap_mmio_context *ctx,
103 return *(u16 *)reg; 101 unsigned int reg,
104 case 4: 102 unsigned int val)
105 return *(u32 *)reg; 103{
104 writel(val, ctx->regs + reg);
105}
106
107static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
108 unsigned int reg,
109 unsigned int val)
110{
111 iowrite32be(val, ctx->regs + reg);
112}
113
106#ifdef CONFIG_64BIT 114#ifdef CONFIG_64BIT
107 case 8: 115static void regmap_mmio_write64le(struct regmap_mmio_context *ctx,
108 return *(u64 *)reg; 116 unsigned int reg,
109#endif 117 unsigned int val)
110 default: 118{
111 BUG(); 119 writeq(val, ctx->regs + reg);
112 }
113} 120}
121#endif
114 122
115static int regmap_mmio_gather_write(void *context, 123static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val)
116 const void *reg, size_t reg_size,
117 const void *val, size_t val_size)
118{ 124{
119 struct regmap_mmio_context *ctx = context; 125 struct regmap_mmio_context *ctx = context;
120 unsigned int offset;
121 int ret; 126 int ret;
122 127
123 regmap_mmio_regsize_check(reg_size);
124
125 if (!IS_ERR(ctx->clk)) { 128 if (!IS_ERR(ctx->clk)) {
126 ret = clk_enable(ctx->clk); 129 ret = clk_enable(ctx->clk);
127 if (ret < 0) 130 if (ret < 0)
128 return ret; 131 return ret;
129 } 132 }
130 133
131 offset = regmap_mmio_get_offset(reg, reg_size); 134 ctx->reg_write(ctx, reg, val);
132
133 while (val_size) {
134 switch (ctx->val_bytes) {
135 case 1:
136 writeb(*(u8 *)val, ctx->regs + offset);
137 break;
138 case 2:
139 writew(*(u16 *)val, ctx->regs + offset);
140 break;
141 case 4:
142 writel(*(u32 *)val, ctx->regs + offset);
143 break;
144#ifdef CONFIG_64BIT
145 case 8:
146 writeq(*(u64 *)val, ctx->regs + offset);
147 break;
148#endif
149 default:
150 /* Should be caught by regmap_mmio_check_config */
151 BUG();
152 }
153 val_size -= ctx->val_bytes;
154 val += ctx->val_bytes;
155 offset += ctx->val_bytes;
156 }
157 135
158 if (!IS_ERR(ctx->clk)) 136 if (!IS_ERR(ctx->clk))
159 clk_disable(ctx->clk); 137 clk_disable(ctx->clk);
@@ -161,59 +139,56 @@ static int regmap_mmio_gather_write(void *context,
161 return 0; 139 return 0;
162} 140}
163 141
164static int regmap_mmio_write(void *context, const void *data, size_t count) 142static unsigned int regmap_mmio_read8(struct regmap_mmio_context *ctx,
143 unsigned int reg)
165{ 144{
166 struct regmap_mmio_context *ctx = context; 145 return readb(ctx->regs + reg);
167 unsigned int offset = ctx->reg_bytes + ctx->pad_bytes; 146}
147
148static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx,
149 unsigned int reg)
150{
151 return readw(ctx->regs + reg);
152}
153
154static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx,
155 unsigned int reg)
156{
157 return ioread16be(ctx->regs + reg);
158}
159
160static unsigned int regmap_mmio_read32le(struct regmap_mmio_context *ctx,
161 unsigned int reg)
162{
163 return readl(ctx->regs + reg);
164}
168 165
169 regmap_mmio_count_check(count, offset); 166static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx,
167 unsigned int reg)
168{
169 return ioread32be(ctx->regs + reg);
170}
170 171
171 return regmap_mmio_gather_write(context, data, ctx->reg_bytes, 172#ifdef CONFIG_64BIT
172 data + offset, count - offset); 173static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx,
174 unsigned int reg)
175{
176 return readq(ctx->regs + reg);
173} 177}
178#endif
174 179
175static int regmap_mmio_read(void *context, 180static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val)
176 const void *reg, size_t reg_size,
177 void *val, size_t val_size)
178{ 181{
179 struct regmap_mmio_context *ctx = context; 182 struct regmap_mmio_context *ctx = context;
180 unsigned int offset;
181 int ret; 183 int ret;
182 184
183 regmap_mmio_regsize_check(reg_size);
184
185 if (!IS_ERR(ctx->clk)) { 185 if (!IS_ERR(ctx->clk)) {
186 ret = clk_enable(ctx->clk); 186 ret = clk_enable(ctx->clk);
187 if (ret < 0) 187 if (ret < 0)
188 return ret; 188 return ret;
189 } 189 }
190 190
191 offset = regmap_mmio_get_offset(reg, reg_size); 191 *val = ctx->reg_read(ctx, reg);
192
193 while (val_size) {
194 switch (ctx->val_bytes) {
195 case 1:
196 *(u8 *)val = readb(ctx->regs + offset);
197 break;
198 case 2:
199 *(u16 *)val = readw(ctx->regs + offset);
200 break;
201 case 4:
202 *(u32 *)val = readl(ctx->regs + offset);
203 break;
204#ifdef CONFIG_64BIT
205 case 8:
206 *(u64 *)val = readq(ctx->regs + offset);
207 break;
208#endif
209 default:
210 /* Should be caught by regmap_mmio_check_config */
211 BUG();
212 }
213 val_size -= ctx->val_bytes;
214 val += ctx->val_bytes;
215 offset += ctx->val_bytes;
216 }
217 192
218 if (!IS_ERR(ctx->clk)) 193 if (!IS_ERR(ctx->clk))
219 clk_disable(ctx->clk); 194 clk_disable(ctx->clk);
@@ -232,14 +207,11 @@ static void regmap_mmio_free_context(void *context)
232 kfree(context); 207 kfree(context);
233} 208}
234 209
235static struct regmap_bus regmap_mmio = { 210static const struct regmap_bus regmap_mmio = {
236 .fast_io = true, 211 .fast_io = true,
237 .write = regmap_mmio_write, 212 .reg_write = regmap_mmio_write,
238 .gather_write = regmap_mmio_gather_write, 213 .reg_read = regmap_mmio_read,
239 .read = regmap_mmio_read,
240 .free_context = regmap_mmio_free_context, 214 .free_context = regmap_mmio_free_context,
241 .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
242 .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
243}; 215};
244 216
245static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, 217static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
@@ -265,24 +237,71 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
265 if (config->reg_stride < min_stride) 237 if (config->reg_stride < min_stride)
266 return ERR_PTR(-EINVAL); 238 return ERR_PTR(-EINVAL);
267 239
268 switch (config->reg_format_endian) {
269 case REGMAP_ENDIAN_DEFAULT:
270 case REGMAP_ENDIAN_NATIVE:
271 break;
272 default:
273 return ERR_PTR(-EINVAL);
274 }
275
276 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 240 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
277 if (!ctx) 241 if (!ctx)
278 return ERR_PTR(-ENOMEM); 242 return ERR_PTR(-ENOMEM);
279 243
280 ctx->regs = regs; 244 ctx->regs = regs;
281 ctx->val_bytes = config->val_bits / 8; 245 ctx->val_bytes = config->val_bits / 8;
282 ctx->reg_bytes = config->reg_bits / 8;
283 ctx->pad_bytes = config->pad_bits / 8;
284 ctx->clk = ERR_PTR(-ENODEV); 246 ctx->clk = ERR_PTR(-ENODEV);
285 247
248 switch (config->reg_format_endian) {
249 case REGMAP_ENDIAN_DEFAULT:
250 case REGMAP_ENDIAN_LITTLE:
251#ifdef __LITTLE_ENDIAN
252 case REGMAP_ENDIAN_NATIVE:
253#endif
254 switch (config->val_bits) {
255 case 8:
256 ctx->reg_read = regmap_mmio_read8;
257 ctx->reg_write = regmap_mmio_write8;
258 break;
259 case 16:
260 ctx->reg_read = regmap_mmio_read16le;
261 ctx->reg_write = regmap_mmio_write16le;
262 break;
263 case 32:
264 ctx->reg_read = regmap_mmio_read32le;
265 ctx->reg_write = regmap_mmio_write32le;
266 break;
267#ifdef CONFIG_64BIT
268 case 64:
269 ctx->reg_read = regmap_mmio_read64le;
270 ctx->reg_write = regmap_mmio_write64le;
271 break;
272#endif
273 default:
274 ret = -EINVAL;
275 goto err_free;
276 }
277 break;
278 case REGMAP_ENDIAN_BIG:
279#ifdef __BIG_ENDIAN
280 case REGMAP_ENDIAN_NATIVE:
281#endif
282 switch (config->val_bits) {
283 case 8:
284 ctx->reg_read = regmap_mmio_read8;
285 ctx->reg_write = regmap_mmio_write8;
286 break;
287 case 16:
288 ctx->reg_read = regmap_mmio_read16be;
289 ctx->reg_write = regmap_mmio_write16be;
290 break;
291 case 32:
292 ctx->reg_read = regmap_mmio_read32be;
293 ctx->reg_write = regmap_mmio_write32be;
294 break;
295 default:
296 ret = -EINVAL;
297 goto err_free;
298 }
299 break;
300 default:
301 ret = -EINVAL;
302 goto err_free;
303 }
304
286 if (clk_id == NULL) 305 if (clk_id == NULL)
287 return ctx; 306 return ctx;
288 307
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index ee54e841de4a..e2f68807d970 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -557,6 +557,8 @@ enum regmap_endian regmap_get_val_endian(struct device *dev,
557 endian = REGMAP_ENDIAN_BIG; 557 endian = REGMAP_ENDIAN_BIG;
558 else if (of_property_read_bool(np, "little-endian")) 558 else if (of_property_read_bool(np, "little-endian"))
559 endian = REGMAP_ENDIAN_LITTLE; 559 endian = REGMAP_ENDIAN_LITTLE;
560 else if (of_property_read_bool(np, "native-endian"))
561 endian = REGMAP_ENDIAN_NATIVE;
560 562
561 /* If the endianness was specified in DT, use that */ 563 /* If the endianness was specified in DT, use that */
562 if (endian != REGMAP_ENDIAN_DEFAULT) 564 if (endian != REGMAP_ENDIAN_DEFAULT)
@@ -2253,6 +2255,9 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
2253 2255
2254 WARN_ON(!map->bus); 2256 WARN_ON(!map->bus);
2255 2257
2258 if (!map->bus || !map->bus->read)
2259 return -EINVAL;
2260
2256 range = _regmap_range_lookup(map, reg); 2261 range = _regmap_range_lookup(map, reg);
2257 if (range) { 2262 if (range) {
2258 ret = _regmap_select_page(map, &reg, range, 2263 ret = _regmap_select_page(map, &reg, range,