diff options
-rw-r--r-- | drivers/base/regmap/internal.h | 17 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 57 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-mmio.c | 30 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 344 | ||||
-rw-r--r-- | include/linux/regmap.h | 69 |
5 files changed, 478 insertions, 39 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index b986b8660b0c..80f9ab9c3aa4 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -95,6 +95,9 @@ struct regmap { | |||
95 | 95 | ||
96 | /* if set, converts bulk rw to single rw */ | 96 | /* if set, converts bulk rw to single rw */ |
97 | bool use_single_rw; | 97 | bool use_single_rw; |
98 | |||
99 | struct rb_root range_tree; | ||
100 | void *selector_work_buf; /* Scratch buffer used for selector */ | ||
98 | }; | 101 | }; |
99 | 102 | ||
100 | struct regcache_ops { | 103 | struct regcache_ops { |
@@ -115,6 +118,20 @@ bool regmap_precious(struct regmap *map, unsigned int reg); | |||
115 | int _regmap_write(struct regmap *map, unsigned int reg, | 118 | int _regmap_write(struct regmap *map, unsigned int reg, |
116 | unsigned int val); | 119 | unsigned int val); |
117 | 120 | ||
121 | struct regmap_range_node { | ||
122 | struct rb_node node; | ||
123 | |||
124 | unsigned int range_min; | ||
125 | unsigned int range_max; | ||
126 | |||
127 | unsigned int selector_reg; | ||
128 | unsigned int selector_mask; | ||
129 | int selector_shift; | ||
130 | |||
131 | unsigned int window_start; | ||
132 | unsigned int window_len; | ||
133 | }; | ||
134 | |||
118 | #ifdef CONFIG_DEBUG_FS | 135 | #ifdef CONFIG_DEBUG_FS |
119 | extern void regmap_debugfs_initcall(void); | 136 | extern void regmap_debugfs_initcall(void); |
120 | extern void regmap_debugfs_init(struct regmap *map, const char *name); | 137 | extern void regmap_debugfs_init(struct regmap *map, const char *name); |
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 4fac4b9be88f..a89734621e51 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c | |||
@@ -24,14 +24,18 @@ struct regmap_irq_chip_data { | |||
24 | struct mutex lock; | 24 | struct mutex lock; |
25 | 25 | ||
26 | struct regmap *map; | 26 | struct regmap *map; |
27 | struct regmap_irq_chip *chip; | 27 | const struct regmap_irq_chip *chip; |
28 | 28 | ||
29 | int irq_base; | 29 | int irq_base; |
30 | struct irq_domain *domain; | 30 | struct irq_domain *domain; |
31 | 31 | ||
32 | int irq; | ||
33 | int wake_count; | ||
34 | |||
32 | unsigned int *status_buf; | 35 | unsigned int *status_buf; |
33 | unsigned int *mask_buf; | 36 | unsigned int *mask_buf; |
34 | unsigned int *mask_buf_def; | 37 | unsigned int *mask_buf_def; |
38 | unsigned int *wake_buf; | ||
35 | 39 | ||
36 | unsigned int irq_reg_stride; | 40 | unsigned int irq_reg_stride; |
37 | }; | 41 | }; |
@@ -71,6 +75,16 @@ static void regmap_irq_sync_unlock(struct irq_data *data) | |||
71 | d->chip->mask_base + (i * map->reg_stride)); | 75 | d->chip->mask_base + (i * map->reg_stride)); |
72 | } | 76 | } |
73 | 77 | ||
78 | /* If we've changed our wakeup count propagate it to the parent */ | ||
79 | if (d->wake_count < 0) | ||
80 | for (i = d->wake_count; i < 0; i++) | ||
81 | irq_set_irq_wake(d->irq, 0); | ||
82 | else if (d->wake_count > 0) | ||
83 | for (i = 0; i < d->wake_count; i++) | ||
84 | irq_set_irq_wake(d->irq, 1); | ||
85 | |||
86 | d->wake_count = 0; | ||
87 | |||
74 | mutex_unlock(&d->lock); | 88 | mutex_unlock(&d->lock); |
75 | } | 89 | } |
76 | 90 | ||
@@ -92,18 +106,41 @@ static void regmap_irq_disable(struct irq_data *data) | |||
92 | d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; | 106 | d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; |
93 | } | 107 | } |
94 | 108 | ||
109 | static int regmap_irq_set_wake(struct irq_data *data, unsigned int on) | ||
110 | { | ||
111 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); | ||
112 | struct regmap *map = d->map; | ||
113 | const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); | ||
114 | |||
115 | if (!d->chip->wake_base) | ||
116 | return -EINVAL; | ||
117 | |||
118 | if (on) { | ||
119 | d->wake_buf[irq_data->reg_offset / map->reg_stride] | ||
120 | &= ~irq_data->mask; | ||
121 | d->wake_count++; | ||
122 | } else { | ||
123 | d->wake_buf[irq_data->reg_offset / map->reg_stride] | ||
124 | |= irq_data->mask; | ||
125 | d->wake_count--; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
95 | static struct irq_chip regmap_irq_chip = { | 131 | static struct irq_chip regmap_irq_chip = { |
96 | .name = "regmap", | 132 | .name = "regmap", |
97 | .irq_bus_lock = regmap_irq_lock, | 133 | .irq_bus_lock = regmap_irq_lock, |
98 | .irq_bus_sync_unlock = regmap_irq_sync_unlock, | 134 | .irq_bus_sync_unlock = regmap_irq_sync_unlock, |
99 | .irq_disable = regmap_irq_disable, | 135 | .irq_disable = regmap_irq_disable, |
100 | .irq_enable = regmap_irq_enable, | 136 | .irq_enable = regmap_irq_enable, |
137 | .irq_set_wake = regmap_irq_set_wake, | ||
101 | }; | 138 | }; |
102 | 139 | ||
103 | static irqreturn_t regmap_irq_thread(int irq, void *d) | 140 | static irqreturn_t regmap_irq_thread(int irq, void *d) |
104 | { | 141 | { |
105 | struct regmap_irq_chip_data *data = d; | 142 | struct regmap_irq_chip_data *data = d; |
106 | struct regmap_irq_chip *chip = data->chip; | 143 | const struct regmap_irq_chip *chip = data->chip; |
107 | struct regmap *map = data->map; | 144 | struct regmap *map = data->map; |
108 | int ret, i; | 145 | int ret, i; |
109 | bool handled = false; | 146 | bool handled = false; |
@@ -195,7 +232,7 @@ static struct irq_domain_ops regmap_domain_ops = { | |||
195 | * register values used by the IRQ controller over suspend and resume. | 232 | * register values used by the IRQ controller over suspend and resume. |
196 | */ | 233 | */ |
197 | int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | 234 | int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, |
198 | int irq_base, struct regmap_irq_chip *chip, | 235 | int irq_base, const struct regmap_irq_chip *chip, |
199 | struct regmap_irq_chip_data **data) | 236 | struct regmap_irq_chip_data **data) |
200 | { | 237 | { |
201 | struct regmap_irq_chip_data *d; | 238 | struct regmap_irq_chip_data *d; |
@@ -240,6 +277,14 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | |||
240 | if (!d->mask_buf_def) | 277 | if (!d->mask_buf_def) |
241 | goto err_alloc; | 278 | goto err_alloc; |
242 | 279 | ||
280 | if (chip->wake_base) { | ||
281 | d->wake_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, | ||
282 | GFP_KERNEL); | ||
283 | if (!d->wake_buf) | ||
284 | goto err_alloc; | ||
285 | } | ||
286 | |||
287 | d->irq = irq; | ||
243 | d->map = map; | 288 | d->map = map; |
244 | d->chip = chip; | 289 | d->chip = chip; |
245 | d->irq_base = irq_base; | 290 | d->irq_base = irq_base; |
@@ -294,6 +339,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | |||
294 | err_domain: | 339 | err_domain: |
295 | /* Should really dispose of the domain but... */ | 340 | /* Should really dispose of the domain but... */ |
296 | err_alloc: | 341 | err_alloc: |
342 | kfree(d->wake_buf); | ||
297 | kfree(d->mask_buf_def); | 343 | kfree(d->mask_buf_def); |
298 | kfree(d->mask_buf); | 344 | kfree(d->mask_buf); |
299 | kfree(d->status_buf); | 345 | kfree(d->status_buf); |
@@ -315,6 +361,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) | |||
315 | 361 | ||
316 | free_irq(irq, d); | 362 | free_irq(irq, d); |
317 | /* We should unmap the domain but... */ | 363 | /* We should unmap the domain but... */ |
364 | kfree(d->wake_buf); | ||
318 | kfree(d->mask_buf_def); | 365 | kfree(d->mask_buf_def); |
319 | kfree(d->mask_buf); | 366 | kfree(d->mask_buf); |
320 | kfree(d->status_buf); | 367 | kfree(d->status_buf); |
@@ -346,6 +393,10 @@ EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base); | |||
346 | */ | 393 | */ |
347 | int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq) | 394 | int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq) |
348 | { | 395 | { |
396 | /* Handle holes in the IRQ list */ | ||
397 | if (!data->chip->irqs[irq].mask) | ||
398 | return -EINVAL; | ||
399 | |||
349 | return irq_create_mapping(data->domain, irq); | 400 | return irq_create_mapping(data->domain, irq); |
350 | } | 401 | } |
351 | EXPORT_SYMBOL_GPL(regmap_irq_get_virq); | 402 | EXPORT_SYMBOL_GPL(regmap_irq_get_virq); |
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index febd6de6c8ac..f05fc74dd84a 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c | |||
@@ -37,7 +37,7 @@ static int regmap_mmio_gather_write(void *context, | |||
37 | 37 | ||
38 | BUG_ON(reg_size != 4); | 38 | BUG_ON(reg_size != 4); |
39 | 39 | ||
40 | offset = be32_to_cpup(reg); | 40 | offset = *(u32 *)reg; |
41 | 41 | ||
42 | while (val_size) { | 42 | while (val_size) { |
43 | switch (ctx->val_bytes) { | 43 | switch (ctx->val_bytes) { |
@@ -45,14 +45,14 @@ static int regmap_mmio_gather_write(void *context, | |||
45 | writeb(*(u8 *)val, ctx->regs + offset); | 45 | writeb(*(u8 *)val, ctx->regs + offset); |
46 | break; | 46 | break; |
47 | case 2: | 47 | case 2: |
48 | writew(be16_to_cpup(val), ctx->regs + offset); | 48 | writew(*(u16 *)val, ctx->regs + offset); |
49 | break; | 49 | break; |
50 | case 4: | 50 | case 4: |
51 | writel(be32_to_cpup(val), ctx->regs + offset); | 51 | writel(*(u32 *)val, ctx->regs + offset); |
52 | break; | 52 | break; |
53 | #ifdef CONFIG_64BIT | 53 | #ifdef CONFIG_64BIT |
54 | case 8: | 54 | case 8: |
55 | writeq(be64_to_cpup(val), ctx->regs + offset); | 55 | writeq(*(u64 *)val, ctx->regs + offset); |
56 | break; | 56 | break; |
57 | #endif | 57 | #endif |
58 | default: | 58 | default: |
@@ -83,7 +83,7 @@ static int regmap_mmio_read(void *context, | |||
83 | 83 | ||
84 | BUG_ON(reg_size != 4); | 84 | BUG_ON(reg_size != 4); |
85 | 85 | ||
86 | offset = be32_to_cpup(reg); | 86 | offset = *(u32 *)reg; |
87 | 87 | ||
88 | while (val_size) { | 88 | while (val_size) { |
89 | switch (ctx->val_bytes) { | 89 | switch (ctx->val_bytes) { |
@@ -91,14 +91,14 @@ static int regmap_mmio_read(void *context, | |||
91 | *(u8 *)val = readb(ctx->regs + offset); | 91 | *(u8 *)val = readb(ctx->regs + offset); |
92 | break; | 92 | break; |
93 | case 2: | 93 | case 2: |
94 | *(u16 *)val = cpu_to_be16(readw(ctx->regs + offset)); | 94 | *(u16 *)val = readw(ctx->regs + offset); |
95 | break; | 95 | break; |
96 | case 4: | 96 | case 4: |
97 | *(u32 *)val = cpu_to_be32(readl(ctx->regs + offset)); | 97 | *(u32 *)val = readl(ctx->regs + offset); |
98 | break; | 98 | break; |
99 | #ifdef CONFIG_64BIT | 99 | #ifdef CONFIG_64BIT |
100 | case 8: | 100 | case 8: |
101 | *(u64 *)val = cpu_to_be32(readq(ctx->regs + offset)); | 101 | *(u64 *)val = readq(ctx->regs + offset); |
102 | break; | 102 | break; |
103 | #endif | 103 | #endif |
104 | default: | 104 | default: |
@@ -124,9 +124,11 @@ static struct regmap_bus regmap_mmio = { | |||
124 | .gather_write = regmap_mmio_gather_write, | 124 | .gather_write = regmap_mmio_gather_write, |
125 | .read = regmap_mmio_read, | 125 | .read = regmap_mmio_read, |
126 | .free_context = regmap_mmio_free_context, | 126 | .free_context = regmap_mmio_free_context, |
127 | .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, | ||
128 | .val_format_endian_default = REGMAP_ENDIAN_NATIVE, | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, | 131 | static struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, |
130 | const struct regmap_config *config) | 132 | const struct regmap_config *config) |
131 | { | 133 | { |
132 | struct regmap_mmio_context *ctx; | 134 | struct regmap_mmio_context *ctx; |
@@ -162,7 +164,15 @@ struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, | |||
162 | if (config->reg_stride < min_stride) | 164 | if (config->reg_stride < min_stride) |
163 | return ERR_PTR(-EINVAL); | 165 | return ERR_PTR(-EINVAL); |
164 | 166 | ||
165 | ctx = kzalloc(GFP_KERNEL, sizeof(*ctx)); | 167 | switch (config->reg_format_endian) { |
168 | case REGMAP_ENDIAN_DEFAULT: | ||
169 | case REGMAP_ENDIAN_NATIVE: | ||
170 | break; | ||
171 | default: | ||
172 | return ERR_PTR(-EINVAL); | ||
173 | } | ||
174 | |||
175 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
166 | if (!ctx) | 176 | if (!ctx) |
167 | return ERR_PTR(-ENOMEM); | 177 | return ERR_PTR(-ENOMEM); |
168 | 178 | ||
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index c89aa01fb1de..c241ae2f2f10 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -15,12 +15,25 @@ | |||
15 | #include <linux/export.h> | 15 | #include <linux/export.h> |
16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/rbtree.h> | ||
18 | 19 | ||
19 | #define CREATE_TRACE_POINTS | 20 | #define CREATE_TRACE_POINTS |
20 | #include <trace/events/regmap.h> | 21 | #include <trace/events/regmap.h> |
21 | 22 | ||
22 | #include "internal.h" | 23 | #include "internal.h" |
23 | 24 | ||
25 | /* | ||
26 | * Sometimes for failures during very early init the trace | ||
27 | * infrastructure isn't available early enough to be used. For this | ||
28 | * sort of problem defining LOG_DEVICE will add printks for basic | ||
29 | * register I/O on a specific device. | ||
30 | */ | ||
31 | #undef LOG_DEVICE | ||
32 | |||
33 | static int _regmap_update_bits(struct regmap *map, unsigned int reg, | ||
34 | unsigned int mask, unsigned int val, | ||
35 | bool *change); | ||
36 | |||
24 | bool regmap_writeable(struct regmap *map, unsigned int reg) | 37 | bool regmap_writeable(struct regmap *map, unsigned int reg) |
25 | { | 38 | { |
26 | if (map->max_register && reg > map->max_register) | 39 | if (map->max_register && reg > map->max_register) |
@@ -119,13 +132,19 @@ static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) | |||
119 | b[0] = val << shift; | 132 | b[0] = val << shift; |
120 | } | 133 | } |
121 | 134 | ||
122 | static void regmap_format_16(void *buf, unsigned int val, unsigned int shift) | 135 | static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift) |
123 | { | 136 | { |
124 | __be16 *b = buf; | 137 | __be16 *b = buf; |
125 | 138 | ||
126 | b[0] = cpu_to_be16(val << shift); | 139 | b[0] = cpu_to_be16(val << shift); |
127 | } | 140 | } |
128 | 141 | ||
142 | static void regmap_format_16_native(void *buf, unsigned int val, | ||
143 | unsigned int shift) | ||
144 | { | ||
145 | *(u16 *)buf = val << shift; | ||
146 | } | ||
147 | |||
129 | static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) | 148 | static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) |
130 | { | 149 | { |
131 | u8 *b = buf; | 150 | u8 *b = buf; |
@@ -137,13 +156,19 @@ static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) | |||
137 | b[2] = val; | 156 | b[2] = val; |
138 | } | 157 | } |
139 | 158 | ||
140 | static void regmap_format_32(void *buf, unsigned int val, unsigned int shift) | 159 | static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift) |
141 | { | 160 | { |
142 | __be32 *b = buf; | 161 | __be32 *b = buf; |
143 | 162 | ||
144 | b[0] = cpu_to_be32(val << shift); | 163 | b[0] = cpu_to_be32(val << shift); |
145 | } | 164 | } |
146 | 165 | ||
166 | static void regmap_format_32_native(void *buf, unsigned int val, | ||
167 | unsigned int shift) | ||
168 | { | ||
169 | *(u32 *)buf = val << shift; | ||
170 | } | ||
171 | |||
147 | static unsigned int regmap_parse_8(void *buf) | 172 | static unsigned int regmap_parse_8(void *buf) |
148 | { | 173 | { |
149 | u8 *b = buf; | 174 | u8 *b = buf; |
@@ -151,7 +176,7 @@ static unsigned int regmap_parse_8(void *buf) | |||
151 | return b[0]; | 176 | return b[0]; |
152 | } | 177 | } |
153 | 178 | ||
154 | static unsigned int regmap_parse_16(void *buf) | 179 | static unsigned int regmap_parse_16_be(void *buf) |
155 | { | 180 | { |
156 | __be16 *b = buf; | 181 | __be16 *b = buf; |
157 | 182 | ||
@@ -160,6 +185,11 @@ static unsigned int regmap_parse_16(void *buf) | |||
160 | return b[0]; | 185 | return b[0]; |
161 | } | 186 | } |
162 | 187 | ||
188 | static unsigned int regmap_parse_16_native(void *buf) | ||
189 | { | ||
190 | return *(u16 *)buf; | ||
191 | } | ||
192 | |||
163 | static unsigned int regmap_parse_24(void *buf) | 193 | static unsigned int regmap_parse_24(void *buf) |
164 | { | 194 | { |
165 | u8 *b = buf; | 195 | u8 *b = buf; |
@@ -170,7 +200,7 @@ static unsigned int regmap_parse_24(void *buf) | |||
170 | return ret; | 200 | return ret; |
171 | } | 201 | } |
172 | 202 | ||
173 | static unsigned int regmap_parse_32(void *buf) | 203 | static unsigned int regmap_parse_32_be(void *buf) |
174 | { | 204 | { |
175 | __be32 *b = buf; | 205 | __be32 *b = buf; |
176 | 206 | ||
@@ -179,6 +209,11 @@ static unsigned int regmap_parse_32(void *buf) | |||
179 | return b[0]; | 209 | return b[0]; |
180 | } | 210 | } |
181 | 211 | ||
212 | static unsigned int regmap_parse_32_native(void *buf) | ||
213 | { | ||
214 | return *(u32 *)buf; | ||
215 | } | ||
216 | |||
182 | static void regmap_lock_mutex(struct regmap *map) | 217 | static void regmap_lock_mutex(struct regmap *map) |
183 | { | 218 | { |
184 | mutex_lock(&map->mutex); | 219 | mutex_lock(&map->mutex); |
@@ -208,6 +243,67 @@ static void dev_get_regmap_release(struct device *dev, void *res) | |||
208 | */ | 243 | */ |
209 | } | 244 | } |
210 | 245 | ||
246 | static bool _regmap_range_add(struct regmap *map, | ||
247 | struct regmap_range_node *data) | ||
248 | { | ||
249 | struct rb_root *root = &map->range_tree; | ||
250 | struct rb_node **new = &(root->rb_node), *parent = NULL; | ||
251 | |||
252 | while (*new) { | ||
253 | struct regmap_range_node *this = | ||
254 | container_of(*new, struct regmap_range_node, node); | ||
255 | |||
256 | parent = *new; | ||
257 | if (data->range_max < this->range_min) | ||
258 | new = &((*new)->rb_left); | ||
259 | else if (data->range_min > this->range_max) | ||
260 | new = &((*new)->rb_right); | ||
261 | else | ||
262 | return false; | ||
263 | } | ||
264 | |||
265 | rb_link_node(&data->node, parent, new); | ||
266 | rb_insert_color(&data->node, root); | ||
267 | |||
268 | return true; | ||
269 | } | ||
270 | |||
271 | static struct regmap_range_node *_regmap_range_lookup(struct regmap *map, | ||
272 | unsigned int reg) | ||
273 | { | ||
274 | struct rb_node *node = map->range_tree.rb_node; | ||
275 | |||
276 | while (node) { | ||
277 | struct regmap_range_node *this = | ||
278 | container_of(node, struct regmap_range_node, node); | ||
279 | |||
280 | if (reg < this->range_min) | ||
281 | node = node->rb_left; | ||
282 | else if (reg > this->range_max) | ||
283 | node = node->rb_right; | ||
284 | else | ||
285 | return this; | ||
286 | } | ||
287 | |||
288 | return NULL; | ||
289 | } | ||
290 | |||
291 | static void regmap_range_exit(struct regmap *map) | ||
292 | { | ||
293 | struct rb_node *next; | ||
294 | struct regmap_range_node *range_node; | ||
295 | |||
296 | next = rb_first(&map->range_tree); | ||
297 | while (next) { | ||
298 | range_node = rb_entry(next, struct regmap_range_node, node); | ||
299 | next = rb_next(&range_node->node); | ||
300 | rb_erase(&range_node->node, &map->range_tree); | ||
301 | kfree(range_node); | ||
302 | } | ||
303 | |||
304 | kfree(map->selector_work_buf); | ||
305 | } | ||
306 | |||
211 | /** | 307 | /** |
212 | * regmap_init(): Initialise register map | 308 | * regmap_init(): Initialise register map |
213 | * | 309 | * |
@@ -227,6 +323,8 @@ struct regmap *regmap_init(struct device *dev, | |||
227 | { | 323 | { |
228 | struct regmap *map, **m; | 324 | struct regmap *map, **m; |
229 | int ret = -EINVAL; | 325 | int ret = -EINVAL; |
326 | enum regmap_endian reg_endian, val_endian; | ||
327 | int i, j; | ||
230 | 328 | ||
231 | if (!bus || !config) | 329 | if (!bus || !config) |
232 | goto err; | 330 | goto err; |
@@ -275,6 +373,18 @@ struct regmap *regmap_init(struct device *dev, | |||
275 | map->read_flag_mask = bus->read_flag_mask; | 373 | map->read_flag_mask = bus->read_flag_mask; |
276 | } | 374 | } |
277 | 375 | ||
376 | reg_endian = config->reg_format_endian; | ||
377 | if (reg_endian == REGMAP_ENDIAN_DEFAULT) | ||
378 | reg_endian = bus->reg_format_endian_default; | ||
379 | if (reg_endian == REGMAP_ENDIAN_DEFAULT) | ||
380 | reg_endian = REGMAP_ENDIAN_BIG; | ||
381 | |||
382 | val_endian = config->val_format_endian; | ||
383 | if (val_endian == REGMAP_ENDIAN_DEFAULT) | ||
384 | val_endian = bus->val_format_endian_default; | ||
385 | if (val_endian == REGMAP_ENDIAN_DEFAULT) | ||
386 | val_endian = REGMAP_ENDIAN_BIG; | ||
387 | |||
278 | switch (config->reg_bits + map->reg_shift) { | 388 | switch (config->reg_bits + map->reg_shift) { |
279 | case 2: | 389 | case 2: |
280 | switch (config->val_bits) { | 390 | switch (config->val_bits) { |
@@ -321,11 +431,29 @@ struct regmap *regmap_init(struct device *dev, | |||
321 | break; | 431 | break; |
322 | 432 | ||
323 | case 16: | 433 | case 16: |
324 | map->format.format_reg = regmap_format_16; | 434 | switch (reg_endian) { |
435 | case REGMAP_ENDIAN_BIG: | ||
436 | map->format.format_reg = regmap_format_16_be; | ||
437 | break; | ||
438 | case REGMAP_ENDIAN_NATIVE: | ||
439 | map->format.format_reg = regmap_format_16_native; | ||
440 | break; | ||
441 | default: | ||
442 | goto err_map; | ||
443 | } | ||
325 | break; | 444 | break; |
326 | 445 | ||
327 | case 32: | 446 | case 32: |
328 | map->format.format_reg = regmap_format_32; | 447 | switch (reg_endian) { |
448 | case REGMAP_ENDIAN_BIG: | ||
449 | map->format.format_reg = regmap_format_32_be; | ||
450 | break; | ||
451 | case REGMAP_ENDIAN_NATIVE: | ||
452 | map->format.format_reg = regmap_format_32_native; | ||
453 | break; | ||
454 | default: | ||
455 | goto err_map; | ||
456 | } | ||
329 | break; | 457 | break; |
330 | 458 | ||
331 | default: | 459 | default: |
@@ -338,21 +466,47 @@ struct regmap *regmap_init(struct device *dev, | |||
338 | map->format.parse_val = regmap_parse_8; | 466 | map->format.parse_val = regmap_parse_8; |
339 | break; | 467 | break; |
340 | case 16: | 468 | case 16: |
341 | map->format.format_val = regmap_format_16; | 469 | switch (val_endian) { |
342 | map->format.parse_val = regmap_parse_16; | 470 | case REGMAP_ENDIAN_BIG: |
471 | map->format.format_val = regmap_format_16_be; | ||
472 | map->format.parse_val = regmap_parse_16_be; | ||
473 | break; | ||
474 | case REGMAP_ENDIAN_NATIVE: | ||
475 | map->format.format_val = regmap_format_16_native; | ||
476 | map->format.parse_val = regmap_parse_16_native; | ||
477 | break; | ||
478 | default: | ||
479 | goto err_map; | ||
480 | } | ||
343 | break; | 481 | break; |
344 | case 24: | 482 | case 24: |
483 | if (val_endian != REGMAP_ENDIAN_BIG) | ||
484 | goto err_map; | ||
345 | map->format.format_val = regmap_format_24; | 485 | map->format.format_val = regmap_format_24; |
346 | map->format.parse_val = regmap_parse_24; | 486 | map->format.parse_val = regmap_parse_24; |
347 | break; | 487 | break; |
348 | case 32: | 488 | case 32: |
349 | map->format.format_val = regmap_format_32; | 489 | switch (val_endian) { |
350 | map->format.parse_val = regmap_parse_32; | 490 | case REGMAP_ENDIAN_BIG: |
491 | map->format.format_val = regmap_format_32_be; | ||
492 | map->format.parse_val = regmap_parse_32_be; | ||
493 | break; | ||
494 | case REGMAP_ENDIAN_NATIVE: | ||
495 | map->format.format_val = regmap_format_32_native; | ||
496 | map->format.parse_val = regmap_parse_32_native; | ||
497 | break; | ||
498 | default: | ||
499 | goto err_map; | ||
500 | } | ||
351 | break; | 501 | break; |
352 | } | 502 | } |
353 | 503 | ||
354 | if (map->format.format_write) | 504 | if (map->format.format_write) { |
505 | if ((reg_endian != REGMAP_ENDIAN_BIG) || | ||
506 | (val_endian != REGMAP_ENDIAN_BIG)) | ||
507 | goto err_map; | ||
355 | map->use_single_rw = true; | 508 | map->use_single_rw = true; |
509 | } | ||
356 | 510 | ||
357 | if (!map->format.format_write && | 511 | if (!map->format.format_write && |
358 | !(map->format.format_reg && map->format.format_val)) | 512 | !(map->format.format_reg && map->format.format_val)) |
@@ -364,27 +518,88 @@ struct regmap *regmap_init(struct device *dev, | |||
364 | goto err_map; | 518 | goto err_map; |
365 | } | 519 | } |
366 | 520 | ||
367 | regmap_debugfs_init(map, config->name); | 521 | map->range_tree = RB_ROOT; |
522 | for (i = 0; i < config->n_ranges; i++) { | ||
523 | const struct regmap_range_cfg *range_cfg = &config->ranges[i]; | ||
524 | struct regmap_range_node *new; | ||
525 | |||
526 | /* Sanity check */ | ||
527 | if (range_cfg->range_max < range_cfg->range_min || | ||
528 | range_cfg->range_max > map->max_register || | ||
529 | range_cfg->selector_reg > map->max_register || | ||
530 | range_cfg->window_len == 0) | ||
531 | goto err_range; | ||
532 | |||
533 | /* Make sure, that this register range has no selector | ||
534 | or data window within its boundary */ | ||
535 | for (j = 0; j < config->n_ranges; j++) { | ||
536 | unsigned sel_reg = config->ranges[j].selector_reg; | ||
537 | unsigned win_min = config->ranges[j].window_start; | ||
538 | unsigned win_max = win_min + | ||
539 | config->ranges[j].window_len - 1; | ||
540 | |||
541 | if (range_cfg->range_min <= sel_reg && | ||
542 | sel_reg <= range_cfg->range_max) { | ||
543 | goto err_range; | ||
544 | } | ||
545 | |||
546 | if (!(win_max < range_cfg->range_min || | ||
547 | win_min > range_cfg->range_max)) { | ||
548 | goto err_range; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | new = kzalloc(sizeof(*new), GFP_KERNEL); | ||
553 | if (new == NULL) { | ||
554 | ret = -ENOMEM; | ||
555 | goto err_range; | ||
556 | } | ||
557 | |||
558 | new->range_min = range_cfg->range_min; | ||
559 | new->range_max = range_cfg->range_max; | ||
560 | new->selector_reg = range_cfg->selector_reg; | ||
561 | new->selector_mask = range_cfg->selector_mask; | ||
562 | new->selector_shift = range_cfg->selector_shift; | ||
563 | new->window_start = range_cfg->window_start; | ||
564 | new->window_len = range_cfg->window_len; | ||
565 | |||
566 | if (_regmap_range_add(map, new) == false) { | ||
567 | kfree(new); | ||
568 | goto err_range; | ||
569 | } | ||
570 | |||
571 | if (map->selector_work_buf == NULL) { | ||
572 | map->selector_work_buf = | ||
573 | kzalloc(map->format.buf_size, GFP_KERNEL); | ||
574 | if (map->selector_work_buf == NULL) { | ||
575 | ret = -ENOMEM; | ||
576 | goto err_range; | ||
577 | } | ||
578 | } | ||
579 | } | ||
368 | 580 | ||
369 | ret = regcache_init(map, config); | 581 | ret = regcache_init(map, config); |
370 | if (ret < 0) | 582 | if (ret < 0) |
371 | goto err_debugfs; | 583 | goto err_range; |
584 | |||
585 | regmap_debugfs_init(map, config->name); | ||
372 | 586 | ||
373 | /* Add a devres resource for dev_get_regmap() */ | 587 | /* Add a devres resource for dev_get_regmap() */ |
374 | m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); | 588 | m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); |
375 | if (!m) { | 589 | if (!m) { |
376 | ret = -ENOMEM; | 590 | ret = -ENOMEM; |
377 | goto err_cache; | 591 | goto err_debugfs; |
378 | } | 592 | } |
379 | *m = map; | 593 | *m = map; |
380 | devres_add(dev, m); | 594 | devres_add(dev, m); |
381 | 595 | ||
382 | return map; | 596 | return map; |
383 | 597 | ||
384 | err_cache: | ||
385 | regcache_exit(map); | ||
386 | err_debugfs: | 598 | err_debugfs: |
387 | regmap_debugfs_exit(map); | 599 | regmap_debugfs_exit(map); |
600 | regcache_exit(map); | ||
601 | err_range: | ||
602 | regmap_range_exit(map); | ||
388 | kfree(map->work_buf); | 603 | kfree(map->work_buf); |
389 | err_map: | 604 | err_map: |
390 | kfree(map); | 605 | kfree(map); |
@@ -481,6 +696,7 @@ void regmap_exit(struct regmap *map) | |||
481 | { | 696 | { |
482 | regcache_exit(map); | 697 | regcache_exit(map); |
483 | regmap_debugfs_exit(map); | 698 | regmap_debugfs_exit(map); |
699 | regmap_range_exit(map); | ||
484 | if (map->bus->free_context) | 700 | if (map->bus->free_context) |
485 | map->bus->free_context(map->bus_context); | 701 | map->bus->free_context(map->bus_context); |
486 | kfree(map->work_buf); | 702 | kfree(map->work_buf); |
@@ -526,6 +742,57 @@ struct regmap *dev_get_regmap(struct device *dev, const char *name) | |||
526 | } | 742 | } |
527 | EXPORT_SYMBOL_GPL(dev_get_regmap); | 743 | EXPORT_SYMBOL_GPL(dev_get_regmap); |
528 | 744 | ||
745 | static int _regmap_select_page(struct regmap *map, unsigned int *reg, | ||
746 | unsigned int val_num) | ||
747 | { | ||
748 | struct regmap_range_node *range; | ||
749 | void *orig_work_buf; | ||
750 | unsigned int win_offset; | ||
751 | unsigned int win_page; | ||
752 | bool page_chg; | ||
753 | int ret; | ||
754 | |||
755 | range = _regmap_range_lookup(map, *reg); | ||
756 | if (range) { | ||
757 | win_offset = (*reg - range->range_min) % range->window_len; | ||
758 | win_page = (*reg - range->range_min) / range->window_len; | ||
759 | |||
760 | if (val_num > 1) { | ||
761 | /* Bulk write shouldn't cross range boundary */ | ||
762 | if (*reg + val_num - 1 > range->range_max) | ||
763 | return -EINVAL; | ||
764 | |||
765 | /* ... or single page boundary */ | ||
766 | if (val_num > range->window_len - win_offset) | ||
767 | return -EINVAL; | ||
768 | } | ||
769 | |||
770 | /* It is possible to have selector register inside data window. | ||
771 | In that case, selector register is located on every page and | ||
772 | it needs no page switching, when accessed alone. */ | ||
773 | if (val_num > 1 || | ||
774 | range->window_start + win_offset != range->selector_reg) { | ||
775 | /* Use separate work_buf during page switching */ | ||
776 | orig_work_buf = map->work_buf; | ||
777 | map->work_buf = map->selector_work_buf; | ||
778 | |||
779 | ret = _regmap_update_bits(map, range->selector_reg, | ||
780 | range->selector_mask, | ||
781 | win_page << range->selector_shift, | ||
782 | &page_chg); | ||
783 | |||
784 | map->work_buf = orig_work_buf; | ||
785 | |||
786 | if (ret < 0) | ||
787 | return ret; | ||
788 | } | ||
789 | |||
790 | *reg = range->window_start + win_offset; | ||
791 | } | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | |||
529 | static int _regmap_raw_write(struct regmap *map, unsigned int reg, | 796 | static int _regmap_raw_write(struct regmap *map, unsigned int reg, |
530 | const void *val, size_t val_len) | 797 | const void *val, size_t val_len) |
531 | { | 798 | { |
@@ -563,6 +830,10 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
563 | } | 830 | } |
564 | } | 831 | } |
565 | 832 | ||
833 | ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); | ||
834 | if (ret < 0) | ||
835 | return ret; | ||
836 | |||
566 | map->format.format_reg(map->work_buf, reg, map->reg_shift); | 837 | map->format.format_reg(map->work_buf, reg, map->reg_shift); |
567 | 838 | ||
568 | u8[0] |= map->write_flag_mask; | 839 | u8[0] |= map->write_flag_mask; |
@@ -623,9 +894,18 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
623 | } | 894 | } |
624 | } | 895 | } |
625 | 896 | ||
897 | #ifdef LOG_DEVICE | ||
898 | if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) | ||
899 | dev_info(map->dev, "%x <= %x\n", reg, val); | ||
900 | #endif | ||
901 | |||
626 | trace_regmap_reg_write(map->dev, reg, val); | 902 | trace_regmap_reg_write(map->dev, reg, val); |
627 | 903 | ||
628 | if (map->format.format_write) { | 904 | if (map->format.format_write) { |
905 | ret = _regmap_select_page(map, ®, 1); | ||
906 | if (ret < 0) | ||
907 | return ret; | ||
908 | |||
629 | map->format.format_write(map, reg, val); | 909 | map->format.format_write(map, reg, val); |
630 | 910 | ||
631 | trace_regmap_hw_write_start(map->dev, reg, 1); | 911 | trace_regmap_hw_write_start(map->dev, reg, 1); |
@@ -783,6 +1063,10 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
783 | u8 *u8 = map->work_buf; | 1063 | u8 *u8 = map->work_buf; |
784 | int ret; | 1064 | int ret; |
785 | 1065 | ||
1066 | ret = _regmap_select_page(map, ®, val_len / map->format.val_bytes); | ||
1067 | if (ret < 0) | ||
1068 | return ret; | ||
1069 | |||
786 | map->format.format_reg(map->work_buf, reg, map->reg_shift); | 1070 | map->format.format_reg(map->work_buf, reg, map->reg_shift); |
787 | 1071 | ||
788 | /* | 1072 | /* |
@@ -826,6 +1110,12 @@ static int _regmap_read(struct regmap *map, unsigned int reg, | |||
826 | ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); | 1110 | ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); |
827 | if (ret == 0) { | 1111 | if (ret == 0) { |
828 | *val = map->format.parse_val(map->work_buf); | 1112 | *val = map->format.parse_val(map->work_buf); |
1113 | |||
1114 | #ifdef LOG_DEVICE | ||
1115 | if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) | ||
1116 | dev_info(map->dev, "%x => %x\n", reg, *val); | ||
1117 | #endif | ||
1118 | |||
829 | trace_regmap_reg_read(map->dev, reg, *val); | 1119 | trace_regmap_reg_read(map->dev, reg, *val); |
830 | } | 1120 | } |
831 | 1121 | ||
@@ -982,11 +1272,9 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, | |||
982 | int ret; | 1272 | int ret; |
983 | unsigned int tmp, orig; | 1273 | unsigned int tmp, orig; |
984 | 1274 | ||
985 | map->lock(map); | ||
986 | |||
987 | ret = _regmap_read(map, reg, &orig); | 1275 | ret = _regmap_read(map, reg, &orig); |
988 | if (ret != 0) | 1276 | if (ret != 0) |
989 | goto out; | 1277 | return ret; |
990 | 1278 | ||
991 | tmp = orig & ~mask; | 1279 | tmp = orig & ~mask; |
992 | tmp |= val & mask; | 1280 | tmp |= val & mask; |
@@ -998,9 +1286,6 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, | |||
998 | *change = false; | 1286 | *change = false; |
999 | } | 1287 | } |
1000 | 1288 | ||
1001 | out: | ||
1002 | map->unlock(map); | ||
1003 | |||
1004 | return ret; | 1289 | return ret; |
1005 | } | 1290 | } |
1006 | 1291 | ||
@@ -1018,7 +1303,13 @@ int regmap_update_bits(struct regmap *map, unsigned int reg, | |||
1018 | unsigned int mask, unsigned int val) | 1303 | unsigned int mask, unsigned int val) |
1019 | { | 1304 | { |
1020 | bool change; | 1305 | bool change; |
1021 | return _regmap_update_bits(map, reg, mask, val, &change); | 1306 | int ret; |
1307 | |||
1308 | map->lock(map); | ||
1309 | ret = _regmap_update_bits(map, reg, mask, val, &change); | ||
1310 | map->unlock(map); | ||
1311 | |||
1312 | return ret; | ||
1022 | } | 1313 | } |
1023 | EXPORT_SYMBOL_GPL(regmap_update_bits); | 1314 | EXPORT_SYMBOL_GPL(regmap_update_bits); |
1024 | 1315 | ||
@@ -1038,7 +1329,12 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, | |||
1038 | unsigned int mask, unsigned int val, | 1329 | unsigned int mask, unsigned int val, |
1039 | bool *change) | 1330 | bool *change) |
1040 | { | 1331 | { |
1041 | return _regmap_update_bits(map, reg, mask, val, change); | 1332 | int ret; |
1333 | |||
1334 | map->lock(map); | ||
1335 | ret = _regmap_update_bits(map, reg, mask, val, change); | ||
1336 | map->unlock(map); | ||
1337 | return ret; | ||
1042 | } | 1338 | } |
1043 | EXPORT_SYMBOL_GPL(regmap_update_bits_check); | 1339 | EXPORT_SYMBOL_GPL(regmap_update_bits_check); |
1044 | 1340 | ||
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 56af22ec9aba..7f7e00df3adf 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -14,12 +14,14 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/rbtree.h> | ||
17 | 18 | ||
18 | struct module; | 19 | struct module; |
19 | struct device; | 20 | struct device; |
20 | struct i2c_client; | 21 | struct i2c_client; |
21 | struct spi_device; | 22 | struct spi_device; |
22 | struct regmap; | 23 | struct regmap; |
24 | struct regmap_range_cfg; | ||
23 | 25 | ||
24 | /* An enum of all the supported cache types */ | 26 | /* An enum of all the supported cache types */ |
25 | enum regcache_type { | 27 | enum regcache_type { |
@@ -43,6 +45,14 @@ struct reg_default { | |||
43 | 45 | ||
44 | #ifdef CONFIG_REGMAP | 46 | #ifdef CONFIG_REGMAP |
45 | 47 | ||
48 | enum regmap_endian { | ||
49 | /* Unspecified -> 0 -> Backwards compatible default */ | ||
50 | REGMAP_ENDIAN_DEFAULT = 0, | ||
51 | REGMAP_ENDIAN_BIG, | ||
52 | REGMAP_ENDIAN_LITTLE, | ||
53 | REGMAP_ENDIAN_NATIVE, | ||
54 | }; | ||
55 | |||
46 | /** | 56 | /** |
47 | * Configuration for the register map of a device. | 57 | * Configuration for the register map of a device. |
48 | * | 58 | * |
@@ -84,6 +94,15 @@ struct reg_default { | |||
84 | * @reg_defaults_raw: Power on reset values for registers (for use with | 94 | * @reg_defaults_raw: Power on reset values for registers (for use with |
85 | * register cache support). | 95 | * register cache support). |
86 | * @num_reg_defaults_raw: Number of elements in reg_defaults_raw. | 96 | * @num_reg_defaults_raw: Number of elements in reg_defaults_raw. |
97 | * @reg_format_endian: Endianness for formatted register addresses. If this is | ||
98 | * DEFAULT, the @reg_format_endian_default value from the | ||
99 | * regmap bus is used. | ||
100 | * @val_format_endian: Endianness for formatted register values. If this is | ||
101 | * DEFAULT, the @reg_format_endian_default value from the | ||
102 | * regmap bus is used. | ||
103 | * | ||
104 | * @ranges: Array of configuration entries for virtual address ranges. | ||
105 | * @num_ranges: Number of range configuration entries. | ||
87 | */ | 106 | */ |
88 | struct regmap_config { | 107 | struct regmap_config { |
89 | const char *name; | 108 | const char *name; |
@@ -109,6 +128,43 @@ struct regmap_config { | |||
109 | u8 write_flag_mask; | 128 | u8 write_flag_mask; |
110 | 129 | ||
111 | bool use_single_rw; | 130 | bool use_single_rw; |
131 | |||
132 | enum regmap_endian reg_format_endian; | ||
133 | enum regmap_endian val_format_endian; | ||
134 | |||
135 | const struct regmap_range_cfg *ranges; | ||
136 | unsigned int n_ranges; | ||
137 | }; | ||
138 | |||
139 | /** | ||
140 | * Configuration for indirectly accessed or paged registers. | ||
141 | * Registers, mapped to this virtual range, are accessed in two steps: | ||
142 | * 1. page selector register update; | ||
143 | * 2. access through data window registers. | ||
144 | * | ||
145 | * @range_min: Address of the lowest register address in virtual range. | ||
146 | * @range_max: Address of the highest register in virtual range. | ||
147 | * | ||
148 | * @page_sel_reg: Register with selector field. | ||
149 | * @page_sel_mask: Bit shift for selector value. | ||
150 | * @page_sel_shift: Bit mask for selector value. | ||
151 | * | ||
152 | * @window_start: Address of first (lowest) register in data window. | ||
153 | * @window_len: Number of registers in data window. | ||
154 | */ | ||
155 | struct regmap_range_cfg { | ||
156 | /* Registers of virtual address range */ | ||
157 | unsigned int range_min; | ||
158 | unsigned int range_max; | ||
159 | |||
160 | /* Page selector for indirect addressing */ | ||
161 | unsigned int selector_reg; | ||
162 | unsigned int selector_mask; | ||
163 | int selector_shift; | ||
164 | |||
165 | /* Data window (per each page) */ | ||
166 | unsigned int window_start; | ||
167 | unsigned int window_len; | ||
112 | }; | 168 | }; |
113 | 169 | ||
114 | typedef int (*regmap_hw_write)(void *context, const void *data, | 170 | typedef int (*regmap_hw_write)(void *context, const void *data, |
@@ -133,6 +189,12 @@ typedef void (*regmap_hw_free_context)(void *context); | |||
133 | * data. | 189 | * data. |
134 | * @read_flag_mask: Mask to be set in the top byte of the register when doing | 190 | * @read_flag_mask: Mask to be set in the top byte of the register when doing |
135 | * a read. | 191 | * a read. |
192 | * @reg_format_endian_default: Default endianness for formatted register | ||
193 | * addresses. Used when the regmap_config specifies DEFAULT. If this is | ||
194 | * DEFAULT, BIG is assumed. | ||
195 | * @val_format_endian_default: Default endianness for formatted register | ||
196 | * values. Used when the regmap_config specifies DEFAULT. If this is | ||
197 | * DEFAULT, BIG is assumed. | ||
136 | */ | 198 | */ |
137 | struct regmap_bus { | 199 | struct regmap_bus { |
138 | bool fast_io; | 200 | bool fast_io; |
@@ -141,6 +203,8 @@ struct regmap_bus { | |||
141 | regmap_hw_read read; | 203 | regmap_hw_read read; |
142 | regmap_hw_free_context free_context; | 204 | regmap_hw_free_context free_context; |
143 | u8 read_flag_mask; | 205 | u8 read_flag_mask; |
206 | enum regmap_endian reg_format_endian_default; | ||
207 | enum regmap_endian val_format_endian_default; | ||
144 | }; | 208 | }; |
145 | 209 | ||
146 | struct regmap *regmap_init(struct device *dev, | 210 | struct regmap *regmap_init(struct device *dev, |
@@ -219,6 +283,7 @@ struct regmap_irq { | |||
219 | * @status_base: Base status register address. | 283 | * @status_base: Base status register address. |
220 | * @mask_base: Base mask register address. | 284 | * @mask_base: Base mask register address. |
221 | * @ack_base: Base ack address. If zero then the chip is clear on read. | 285 | * @ack_base: Base ack address. If zero then the chip is clear on read. |
286 | * @wake_base: Base address for wake enables. If zero unsupported. | ||
222 | * @irq_reg_stride: Stride to use for chips where registers are not contiguous. | 287 | * @irq_reg_stride: Stride to use for chips where registers are not contiguous. |
223 | * | 288 | * |
224 | * @num_regs: Number of registers in each control bank. | 289 | * @num_regs: Number of registers in each control bank. |
@@ -232,6 +297,7 @@ struct regmap_irq_chip { | |||
232 | unsigned int status_base; | 297 | unsigned int status_base; |
233 | unsigned int mask_base; | 298 | unsigned int mask_base; |
234 | unsigned int ack_base; | 299 | unsigned int ack_base; |
300 | unsigned int wake_base; | ||
235 | unsigned int irq_reg_stride; | 301 | unsigned int irq_reg_stride; |
236 | 302 | ||
237 | int num_regs; | 303 | int num_regs; |
@@ -243,7 +309,7 @@ struct regmap_irq_chip { | |||
243 | struct regmap_irq_chip_data; | 309 | struct regmap_irq_chip_data; |
244 | 310 | ||
245 | int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | 311 | int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, |
246 | int irq_base, struct regmap_irq_chip *chip, | 312 | int irq_base, const struct regmap_irq_chip *chip, |
247 | struct regmap_irq_chip_data **data); | 313 | struct regmap_irq_chip_data **data); |
248 | void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); | 314 | void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); |
249 | int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data); | 315 | int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data); |
@@ -361,7 +427,6 @@ static inline int regmap_register_patch(struct regmap *map, | |||
361 | static inline struct regmap *dev_get_regmap(struct device *dev, | 427 | static inline struct regmap *dev_get_regmap(struct device *dev, |
362 | const char *name) | 428 | const char *name) |
363 | { | 429 | { |
364 | WARN_ONCE(1, "regmap API is disabled"); | ||
365 | return NULL; | 430 | return NULL; |
366 | } | 431 | } |
367 | 432 | ||