diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:40:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:40:58 -0400 |
commit | a6e6d863cf68bba886acfe47dbdc8f245cce588f (patch) | |
tree | cf6a408da597c5e39def6a28c38d117c5899eef8 | |
parent | 60b5adffb4f3e4b4c1978959f24e8e531b2ef3cb (diff) | |
parent | 7bc8c4c37aea74332b16ffb5412a8ad355d508ce (diff) |
Merge tag 'regmap-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown:
"A small but useful set of regmap updates this time around:
- An abstraction for bitfields within a register map contributed by
Srinivas Kandagatla, allowing drivers to cope more easily when
hardware designers randomly move things about (mainly when talking
to things like system controllers).
- Changes from Lars-Peter Clausen to allow the MMIO regmap to be used
from hard IRQ context.
- Small improvements to the cache infrastructure and performance,
including a default cache sync operation so now all regmaps can
sync easily.
There's also a pinctrl driver making use of the new bitfield API,
merged here for dependency reasons. There will be a simple add/add
conflict with the pinctrl tree as a result."
* tag 'regmap-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
pinctrl: st: Remove unnecessary use of of_match_ptr macro
pinctrl: st: fix return value check
pinctrl: st: Add pinctrl and pinconf support.
regmap: debugfs: Suppress cache for partial register files
regmap: Add regmap_field APIs
regmap: core: Cache all registers by default when cache is enabled
regmap: Implemented default cache sync operation
regmap: Make regmap-mmio usable from atomic contexts
regmap: regcache: Fixup locking for custom lock callbacks
regmap: debugfs: Fix return from regmap_debugfs_get_dump_start
regmap: debugfs: Don't mark lockdep as broken due to debugfs write
regmap: rbtree: Use range information to allocate nodes
regmap: rbtree: Factor out node allocation
regmap: Make regmap_check_range_table() a public API
regmap: Add support for discarding parts of the register cache
-rw-r--r-- | Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt | 110 | ||||
-rw-r--r-- | drivers/base/regmap/internal.h | 10 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-rbtree.c | 62 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 83 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-debugfs.c | 8 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 156 | ||||
-rw-r--r-- | drivers/pinctrl/Kconfig | 6 | ||||
-rw-r--r-- | drivers/pinctrl/Makefile | 1 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-st.c | 1403 | ||||
-rw-r--r-- | include/linux/regmap.h | 43 | ||||
-rw-r--r-- | include/trace/events/regmap.h | 23 |
11 files changed, 1875 insertions, 30 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt new file mode 100644 index 000000000000..05bf82a07dfd --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt | |||
@@ -0,0 +1,110 @@ | |||
1 | *ST pin controller. | ||
2 | |||
3 | Each multi-function pin is controlled, driven and routed through the | ||
4 | PIO multiplexing block. Each pin supports GPIO functionality (ALT0) | ||
5 | and multiple alternate functions(ALT1 - ALTx) that directly connect | ||
6 | the pin to different hardware blocks. | ||
7 | |||
8 | When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and | ||
9 | Pull Up (PU) are driven by the related PIO block. | ||
10 | |||
11 | ST pinctrl driver controls PIO multiplexing block and also interacts with | ||
12 | gpio driver to configure a pin. | ||
13 | |||
14 | Required properties: (PIO multiplexing block) | ||
15 | - compatible : should be "st,<SOC>-<pio-block>-pinctrl" | ||
16 | like st,stih415-sbc-pinctrl, st,stih415-front-pinctrl and so on. | ||
17 | - gpio-controller : Indicates this device is a GPIO controller | ||
18 | - #gpio-cells : Should be one. The first cell is the pin number. | ||
19 | - st,retime-pin-mask : Should be mask to specify which pins can be retimed. | ||
20 | If the property is not present, it is assumed that all the pins in the | ||
21 | bank are capable of retiming. Retiming is mainly used to improve the | ||
22 | IO timing margins of external synchronous interfaces. | ||
23 | - st,bank-name : Should be a name string for this bank as | ||
24 | specified in datasheet. | ||
25 | - st,syscfg : Should be a phandle of the syscfg node. | ||
26 | |||
27 | Example: | ||
28 | pin-controller-sbc { | ||
29 | #address-cells = <1>; | ||
30 | #size-cells = <1>; | ||
31 | compatible = "st,stih415-sbc-pinctrl"; | ||
32 | st,syscfg = <&syscfg_sbc>; | ||
33 | ranges = <0 0xfe610000 0x5000>; | ||
34 | PIO0: gpio@fe610000 { | ||
35 | gpio-controller; | ||
36 | #gpio-cells = <1>; | ||
37 | reg = <0 0x100>; | ||
38 | st,bank-name = "PIO0"; | ||
39 | }; | ||
40 | ... | ||
41 | pin-functions nodes follow... | ||
42 | }; | ||
43 | |||
44 | |||
45 | Contents of function subnode node: | ||
46 | ---------------------- | ||
47 | Required properties for pin configuration node: | ||
48 | - st,pins : Child node with list of pins with configuration. | ||
49 | |||
50 | Below is the format of how each pin conf should look like. | ||
51 | |||
52 | <bank offset mux mode rt_type rt_delay rt_clk> | ||
53 | |||
54 | Every PIO is represented with 4-7 parameters depending on retime configuration. | ||
55 | Each parameter is explained as below. | ||
56 | |||
57 | -bank : Should be bank phandle to which this PIO belongs. | ||
58 | -offset : Offset in the PIO bank. | ||
59 | -mux : Should be alternate function number associated this pin. | ||
60 | Use same numbers from datasheet. | ||
61 | -mode :pin configuration is selected from one of the below values. | ||
62 | IN | ||
63 | IN_PU | ||
64 | OUT | ||
65 | BIDIR | ||
66 | BIDIR_PU | ||
67 | |||
68 | -rt_type Retiming Configuration for the pin. | ||
69 | Possible retime configuration are: | ||
70 | |||
71 | ------- ------------- | ||
72 | value args | ||
73 | ------- ------------- | ||
74 | NICLK <delay> <clk> | ||
75 | ICLK_IO <delay> <clk> | ||
76 | BYPASS <delay> | ||
77 | DE_IO <delay> <clk> | ||
78 | SE_ICLK_IO <delay> <clk> | ||
79 | SE_NICLK_IO <delay> <clk> | ||
80 | |||
81 | - delay is retime delay in pico seconds as mentioned in data sheet. | ||
82 | |||
83 | - rt_clk :clk to be use for retime. | ||
84 | Possible values are: | ||
85 | CLK_A | ||
86 | CLK_B | ||
87 | CLK_C | ||
88 | CLK_D | ||
89 | |||
90 | Example of mmcclk pin which is a bi-direction pull pu with retime config | ||
91 | as non inverted clock retimed with CLK_B and delay of 0 pico seconds: | ||
92 | |||
93 | pin-controller { | ||
94 | ... | ||
95 | mmc0 { | ||
96 | pinctrl_mmc: mmc { | ||
97 | st,pins { | ||
98 | mmcclk = <&PIO13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>; | ||
99 | ... | ||
100 | }; | ||
101 | }; | ||
102 | ... | ||
103 | }; | ||
104 | }; | ||
105 | |||
106 | sdhci0:sdhci@fe810000{ | ||
107 | ... | ||
108 | pinctrl-names = "default"; | ||
109 | pinctrl-0 = <&pinctrl_mmc>; | ||
110 | }; | ||
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index c130536e0ab0..29c83160ca29 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -52,6 +52,7 @@ struct regmap_async { | |||
52 | struct regmap { | 52 | struct regmap { |
53 | struct mutex mutex; | 53 | struct mutex mutex; |
54 | spinlock_t spinlock; | 54 | spinlock_t spinlock; |
55 | unsigned long spinlock_flags; | ||
55 | regmap_lock lock; | 56 | regmap_lock lock; |
56 | regmap_unlock unlock; | 57 | regmap_unlock unlock; |
57 | void *lock_arg; /* This is passed to lock/unlock functions */ | 58 | void *lock_arg; /* This is passed to lock/unlock functions */ |
@@ -148,6 +149,7 @@ struct regcache_ops { | |||
148 | int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); | 149 | int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); |
149 | int (*write)(struct regmap *map, unsigned int reg, unsigned int value); | 150 | int (*write)(struct regmap *map, unsigned int reg, unsigned int value); |
150 | int (*sync)(struct regmap *map, unsigned int min, unsigned int max); | 151 | int (*sync)(struct regmap *map, unsigned int min, unsigned int max); |
152 | int (*drop)(struct regmap *map, unsigned int min, unsigned int max); | ||
151 | }; | 153 | }; |
152 | 154 | ||
153 | bool regmap_writeable(struct regmap *map, unsigned int reg); | 155 | bool regmap_writeable(struct regmap *map, unsigned int reg); |
@@ -174,6 +176,14 @@ struct regmap_range_node { | |||
174 | unsigned int window_len; | 176 | unsigned int window_len; |
175 | }; | 177 | }; |
176 | 178 | ||
179 | struct regmap_field { | ||
180 | struct regmap *regmap; | ||
181 | unsigned int mask; | ||
182 | /* lsb */ | ||
183 | unsigned int shift; | ||
184 | unsigned int reg; | ||
185 | }; | ||
186 | |||
177 | #ifdef CONFIG_DEBUG_FS | 187 | #ifdef CONFIG_DEBUG_FS |
178 | extern void regmap_debugfs_initcall(void); | 188 | extern void regmap_debugfs_initcall(void); |
179 | extern void regmap_debugfs_init(struct regmap *map, const char *name); | 189 | extern void regmap_debugfs_init(struct regmap *map, const char *name); |
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 02f490bad30f..5c1435c4e210 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c | |||
@@ -304,6 +304,48 @@ static int regcache_rbtree_insert_to_block(struct regmap *map, | |||
304 | return 0; | 304 | return 0; |
305 | } | 305 | } |
306 | 306 | ||
307 | static struct regcache_rbtree_node * | ||
308 | regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg) | ||
309 | { | ||
310 | struct regcache_rbtree_node *rbnode; | ||
311 | const struct regmap_range *range; | ||
312 | int i; | ||
313 | |||
314 | rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL); | ||
315 | if (!rbnode) | ||
316 | return NULL; | ||
317 | |||
318 | /* If there is a read table then use it to guess at an allocation */ | ||
319 | if (map->rd_table) { | ||
320 | for (i = 0; i < map->rd_table->n_yes_ranges; i++) { | ||
321 | if (regmap_reg_in_range(reg, | ||
322 | &map->rd_table->yes_ranges[i])) | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | if (i != map->rd_table->n_yes_ranges) { | ||
327 | range = &map->rd_table->yes_ranges[i]; | ||
328 | rbnode->blklen = range->range_max - range->range_min | ||
329 | + 1; | ||
330 | rbnode->base_reg = range->range_min; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | if (!rbnode->blklen) { | ||
335 | rbnode->blklen = sizeof(*rbnode); | ||
336 | rbnode->base_reg = reg; | ||
337 | } | ||
338 | |||
339 | rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size, | ||
340 | GFP_KERNEL); | ||
341 | if (!rbnode->block) { | ||
342 | kfree(rbnode); | ||
343 | return NULL; | ||
344 | } | ||
345 | |||
346 | return rbnode; | ||
347 | } | ||
348 | |||
307 | static int regcache_rbtree_write(struct regmap *map, unsigned int reg, | 349 | static int regcache_rbtree_write(struct regmap *map, unsigned int reg, |
308 | unsigned int value) | 350 | unsigned int value) |
309 | { | 351 | { |
@@ -354,23 +396,15 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, | |||
354 | return 0; | 396 | return 0; |
355 | } | 397 | } |
356 | } | 398 | } |
357 | /* we did not manage to find a place to insert it in an existing | 399 | |
358 | * block so create a new rbnode with a single register in its block. | 400 | /* We did not manage to find a place to insert it in |
359 | * This block will get populated further if any other adjacent | 401 | * an existing block so create a new rbnode. |
360 | * registers get modified in the future. | ||
361 | */ | 402 | */ |
362 | rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL); | 403 | rbnode = regcache_rbtree_node_alloc(map, reg); |
363 | if (!rbnode) | 404 | if (!rbnode) |
364 | return -ENOMEM; | 405 | return -ENOMEM; |
365 | rbnode->blklen = sizeof(*rbnode); | 406 | regcache_rbtree_set_register(map, rbnode, |
366 | rbnode->base_reg = reg; | 407 | reg - rbnode->base_reg, value); |
367 | rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size, | ||
368 | GFP_KERNEL); | ||
369 | if (!rbnode->block) { | ||
370 | kfree(rbnode); | ||
371 | return -ENOMEM; | ||
372 | } | ||
373 | regcache_rbtree_set_register(map, rbnode, 0, value); | ||
374 | regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); | 408 | regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); |
375 | rbtree_ctx->cached_rbnode = rbnode; | 409 | rbtree_ctx->cached_rbnode = rbnode; |
376 | } | 410 | } |
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 507ee2da0f6e..e69102696533 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
@@ -250,6 +250,38 @@ int regcache_write(struct regmap *map, | |||
250 | return 0; | 250 | return 0; |
251 | } | 251 | } |
252 | 252 | ||
253 | static int regcache_default_sync(struct regmap *map, unsigned int min, | ||
254 | unsigned int max) | ||
255 | { | ||
256 | unsigned int reg; | ||
257 | |||
258 | for (reg = min; reg <= max; reg++) { | ||
259 | unsigned int val; | ||
260 | int ret; | ||
261 | |||
262 | if (regmap_volatile(map, reg)) | ||
263 | continue; | ||
264 | |||
265 | ret = regcache_read(map, reg, &val); | ||
266 | if (ret) | ||
267 | return ret; | ||
268 | |||
269 | /* Is this the hardware default? If so skip. */ | ||
270 | ret = regcache_lookup_reg(map, reg); | ||
271 | if (ret >= 0 && val == map->reg_defaults[ret].def) | ||
272 | continue; | ||
273 | |||
274 | map->cache_bypass = 1; | ||
275 | ret = _regmap_write(map, reg, val); | ||
276 | map->cache_bypass = 0; | ||
277 | if (ret) | ||
278 | return ret; | ||
279 | dev_dbg(map->dev, "Synced register %#x, value %#x\n", reg, val); | ||
280 | } | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
253 | /** | 285 | /** |
254 | * regcache_sync: Sync the register cache with the hardware. | 286 | * regcache_sync: Sync the register cache with the hardware. |
255 | * | 287 | * |
@@ -268,7 +300,7 @@ int regcache_sync(struct regmap *map) | |||
268 | const char *name; | 300 | const char *name; |
269 | unsigned int bypass; | 301 | unsigned int bypass; |
270 | 302 | ||
271 | BUG_ON(!map->cache_ops || !map->cache_ops->sync); | 303 | BUG_ON(!map->cache_ops); |
272 | 304 | ||
273 | map->lock(map->lock_arg); | 305 | map->lock(map->lock_arg); |
274 | /* Remember the initial bypass state */ | 306 | /* Remember the initial bypass state */ |
@@ -297,7 +329,10 @@ int regcache_sync(struct regmap *map) | |||
297 | } | 329 | } |
298 | map->cache_bypass = 0; | 330 | map->cache_bypass = 0; |
299 | 331 | ||
300 | ret = map->cache_ops->sync(map, 0, map->max_register); | 332 | if (map->cache_ops->sync) |
333 | ret = map->cache_ops->sync(map, 0, map->max_register); | ||
334 | else | ||
335 | ret = regcache_default_sync(map, 0, map->max_register); | ||
301 | 336 | ||
302 | if (ret == 0) | 337 | if (ret == 0) |
303 | map->cache_dirty = false; | 338 | map->cache_dirty = false; |
@@ -331,7 +366,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, | |||
331 | const char *name; | 366 | const char *name; |
332 | unsigned int bypass; | 367 | unsigned int bypass; |
333 | 368 | ||
334 | BUG_ON(!map->cache_ops || !map->cache_ops->sync); | 369 | BUG_ON(!map->cache_ops); |
335 | 370 | ||
336 | map->lock(map->lock_arg); | 371 | map->lock(map->lock_arg); |
337 | 372 | ||
@@ -346,7 +381,10 @@ int regcache_sync_region(struct regmap *map, unsigned int min, | |||
346 | if (!map->cache_dirty) | 381 | if (!map->cache_dirty) |
347 | goto out; | 382 | goto out; |
348 | 383 | ||
349 | ret = map->cache_ops->sync(map, min, max); | 384 | if (map->cache_ops->sync) |
385 | ret = map->cache_ops->sync(map, min, max); | ||
386 | else | ||
387 | ret = regcache_default_sync(map, min, max); | ||
350 | 388 | ||
351 | out: | 389 | out: |
352 | trace_regcache_sync(map->dev, name, "stop region"); | 390 | trace_regcache_sync(map->dev, name, "stop region"); |
@@ -359,6 +397,43 @@ out: | |||
359 | EXPORT_SYMBOL_GPL(regcache_sync_region); | 397 | EXPORT_SYMBOL_GPL(regcache_sync_region); |
360 | 398 | ||
361 | /** | 399 | /** |
400 | * regcache_drop_region: Discard part of the register cache | ||
401 | * | ||
402 | * @map: map to operate on | ||
403 | * @min: first register to discard | ||
404 | * @max: last register to discard | ||
405 | * | ||
406 | * Discard part of the register cache. | ||
407 | * | ||
408 | * Return a negative value on failure, 0 on success. | ||
409 | */ | ||
410 | int regcache_drop_region(struct regmap *map, unsigned int min, | ||
411 | unsigned int max) | ||
412 | { | ||
413 | unsigned int reg; | ||
414 | int ret = 0; | ||
415 | |||
416 | if (!map->cache_present && !(map->cache_ops && map->cache_ops->drop)) | ||
417 | return -EINVAL; | ||
418 | |||
419 | map->lock(map->lock_arg); | ||
420 | |||
421 | trace_regcache_drop_region(map->dev, min, max); | ||
422 | |||
423 | if (map->cache_present) | ||
424 | for (reg = min; reg < max + 1; reg++) | ||
425 | clear_bit(reg, map->cache_present); | ||
426 | |||
427 | if (map->cache_ops && map->cache_ops->drop) | ||
428 | ret = map->cache_ops->drop(map, min, max); | ||
429 | |||
430 | map->unlock(map->lock_arg); | ||
431 | |||
432 | return ret; | ||
433 | } | ||
434 | EXPORT_SYMBOL_GPL(regcache_drop_region); | ||
435 | |||
436 | /** | ||
362 | * regcache_cache_only: Put a register map into cache only mode | 437 | * regcache_cache_only: Put a register map into cache only mode |
363 | * | 438 | * |
364 | * @map: map to configure | 439 | * @map: map to configure |
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 975719bc3450..53495753fbdb 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c | |||
@@ -84,6 +84,10 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, | |||
84 | unsigned int fpos_offset; | 84 | unsigned int fpos_offset; |
85 | unsigned int reg_offset; | 85 | unsigned int reg_offset; |
86 | 86 | ||
87 | /* Suppress the cache if we're using a subrange */ | ||
88 | if (from) | ||
89 | return from; | ||
90 | |||
87 | /* | 91 | /* |
88 | * If we don't have a cache build one so we don't have to do a | 92 | * If we don't have a cache build one so we don't have to do a |
89 | * linear scan each time. | 93 | * linear scan each time. |
@@ -145,7 +149,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, | |||
145 | reg_offset = fpos_offset / map->debugfs_tot_len; | 149 | reg_offset = fpos_offset / map->debugfs_tot_len; |
146 | *pos = c->min + (reg_offset * map->debugfs_tot_len); | 150 | *pos = c->min + (reg_offset * map->debugfs_tot_len); |
147 | mutex_unlock(&map->cache_lock); | 151 | mutex_unlock(&map->cache_lock); |
148 | return c->base_reg + reg_offset; | 152 | return c->base_reg + (reg_offset * map->reg_stride); |
149 | } | 153 | } |
150 | 154 | ||
151 | *pos = c->max; | 155 | *pos = c->max; |
@@ -281,7 +285,7 @@ static ssize_t regmap_map_write_file(struct file *file, | |||
281 | return -EINVAL; | 285 | return -EINVAL; |
282 | 286 | ||
283 | /* Userspace has been fiddling around behind the kernel's back */ | 287 | /* Userspace has been fiddling around behind the kernel's back */ |
284 | add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE); | 288 | add_taint(TAINT_USER, LOCKDEP_STILL_OK); |
285 | 289 | ||
286 | ret = regmap_write(map, reg, value); | 290 | ret = regmap_write(map, reg, value); |
287 | if (ret < 0) | 291 | if (ret < 0) |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index a941dcfe7590..95920583e31e 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -65,9 +65,8 @@ bool regmap_reg_in_ranges(unsigned int reg, | |||
65 | } | 65 | } |
66 | EXPORT_SYMBOL_GPL(regmap_reg_in_ranges); | 66 | EXPORT_SYMBOL_GPL(regmap_reg_in_ranges); |
67 | 67 | ||
68 | static bool _regmap_check_range_table(struct regmap *map, | 68 | bool regmap_check_range_table(struct regmap *map, unsigned int reg, |
69 | unsigned int reg, | 69 | const struct regmap_access_table *table) |
70 | const struct regmap_access_table *table) | ||
71 | { | 70 | { |
72 | /* Check "no ranges" first */ | 71 | /* Check "no ranges" first */ |
73 | if (regmap_reg_in_ranges(reg, table->no_ranges, table->n_no_ranges)) | 72 | if (regmap_reg_in_ranges(reg, table->no_ranges, table->n_no_ranges)) |
@@ -80,6 +79,7 @@ static bool _regmap_check_range_table(struct regmap *map, | |||
80 | return regmap_reg_in_ranges(reg, table->yes_ranges, | 79 | return regmap_reg_in_ranges(reg, table->yes_ranges, |
81 | table->n_yes_ranges); | 80 | table->n_yes_ranges); |
82 | } | 81 | } |
82 | EXPORT_SYMBOL_GPL(regmap_check_range_table); | ||
83 | 83 | ||
84 | bool regmap_writeable(struct regmap *map, unsigned int reg) | 84 | bool regmap_writeable(struct regmap *map, unsigned int reg) |
85 | { | 85 | { |
@@ -90,7 +90,7 @@ bool regmap_writeable(struct regmap *map, unsigned int reg) | |||
90 | return map->writeable_reg(map->dev, reg); | 90 | return map->writeable_reg(map->dev, reg); |
91 | 91 | ||
92 | if (map->wr_table) | 92 | if (map->wr_table) |
93 | return _regmap_check_range_table(map, reg, map->wr_table); | 93 | return regmap_check_range_table(map, reg, map->wr_table); |
94 | 94 | ||
95 | return true; | 95 | return true; |
96 | } | 96 | } |
@@ -107,7 +107,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg) | |||
107 | return map->readable_reg(map->dev, reg); | 107 | return map->readable_reg(map->dev, reg); |
108 | 108 | ||
109 | if (map->rd_table) | 109 | if (map->rd_table) |
110 | return _regmap_check_range_table(map, reg, map->rd_table); | 110 | return regmap_check_range_table(map, reg, map->rd_table); |
111 | 111 | ||
112 | return true; | 112 | return true; |
113 | } | 113 | } |
@@ -121,9 +121,12 @@ bool regmap_volatile(struct regmap *map, unsigned int reg) | |||
121 | return map->volatile_reg(map->dev, reg); | 121 | return map->volatile_reg(map->dev, reg); |
122 | 122 | ||
123 | if (map->volatile_table) | 123 | if (map->volatile_table) |
124 | return _regmap_check_range_table(map, reg, map->volatile_table); | 124 | return regmap_check_range_table(map, reg, map->volatile_table); |
125 | 125 | ||
126 | return true; | 126 | if (map->cache_ops) |
127 | return false; | ||
128 | else | ||
129 | return true; | ||
127 | } | 130 | } |
128 | 131 | ||
129 | bool regmap_precious(struct regmap *map, unsigned int reg) | 132 | bool regmap_precious(struct regmap *map, unsigned int reg) |
@@ -135,7 +138,7 @@ bool regmap_precious(struct regmap *map, unsigned int reg) | |||
135 | return map->precious_reg(map->dev, reg); | 138 | return map->precious_reg(map->dev, reg); |
136 | 139 | ||
137 | if (map->precious_table) | 140 | if (map->precious_table) |
138 | return _regmap_check_range_table(map, reg, map->precious_table); | 141 | return regmap_check_range_table(map, reg, map->precious_table); |
139 | 142 | ||
140 | return false; | 143 | return false; |
141 | } | 144 | } |
@@ -302,13 +305,16 @@ static void regmap_unlock_mutex(void *__map) | |||
302 | static void regmap_lock_spinlock(void *__map) | 305 | static void regmap_lock_spinlock(void *__map) |
303 | { | 306 | { |
304 | struct regmap *map = __map; | 307 | struct regmap *map = __map; |
305 | spin_lock(&map->spinlock); | 308 | unsigned long flags; |
309 | |||
310 | spin_lock_irqsave(&map->spinlock, flags); | ||
311 | map->spinlock_flags = flags; | ||
306 | } | 312 | } |
307 | 313 | ||
308 | static void regmap_unlock_spinlock(void *__map) | 314 | static void regmap_unlock_spinlock(void *__map) |
309 | { | 315 | { |
310 | struct regmap *map = __map; | 316 | struct regmap *map = __map; |
311 | spin_unlock(&map->spinlock); | 317 | spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags); |
312 | } | 318 | } |
313 | 319 | ||
314 | static void dev_get_regmap_release(struct device *dev, void *res) | 320 | static void dev_get_regmap_release(struct device *dev, void *res) |
@@ -801,6 +807,95 @@ struct regmap *devm_regmap_init(struct device *dev, | |||
801 | } | 807 | } |
802 | EXPORT_SYMBOL_GPL(devm_regmap_init); | 808 | EXPORT_SYMBOL_GPL(devm_regmap_init); |
803 | 809 | ||
810 | static void regmap_field_init(struct regmap_field *rm_field, | ||
811 | struct regmap *regmap, struct reg_field reg_field) | ||
812 | { | ||
813 | int field_bits = reg_field.msb - reg_field.lsb + 1; | ||
814 | rm_field->regmap = regmap; | ||
815 | rm_field->reg = reg_field.reg; | ||
816 | rm_field->shift = reg_field.lsb; | ||
817 | rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb); | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * devm_regmap_field_alloc(): Allocate and initialise a register field | ||
822 | * in a register map. | ||
823 | * | ||
824 | * @dev: Device that will be interacted with | ||
825 | * @regmap: regmap bank in which this register field is located. | ||
826 | * @reg_field: Register field with in the bank. | ||
827 | * | ||
828 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
829 | * to a struct regmap_field. The regmap_field will be automatically freed | ||
830 | * by the device management code. | ||
831 | */ | ||
832 | struct regmap_field *devm_regmap_field_alloc(struct device *dev, | ||
833 | struct regmap *regmap, struct reg_field reg_field) | ||
834 | { | ||
835 | struct regmap_field *rm_field = devm_kzalloc(dev, | ||
836 | sizeof(*rm_field), GFP_KERNEL); | ||
837 | if (!rm_field) | ||
838 | return ERR_PTR(-ENOMEM); | ||
839 | |||
840 | regmap_field_init(rm_field, regmap, reg_field); | ||
841 | |||
842 | return rm_field; | ||
843 | |||
844 | } | ||
845 | EXPORT_SYMBOL_GPL(devm_regmap_field_alloc); | ||
846 | |||
847 | /** | ||
848 | * devm_regmap_field_free(): Free register field allocated using | ||
849 | * devm_regmap_field_alloc. Usally drivers need not call this function, | ||
850 | * as the memory allocated via devm will be freed as per device-driver | ||
851 | * life-cyle. | ||
852 | * | ||
853 | * @dev: Device that will be interacted with | ||
854 | * @field: regmap field which should be freed. | ||
855 | */ | ||
856 | void devm_regmap_field_free(struct device *dev, | ||
857 | struct regmap_field *field) | ||
858 | { | ||
859 | devm_kfree(dev, field); | ||
860 | } | ||
861 | EXPORT_SYMBOL_GPL(devm_regmap_field_free); | ||
862 | |||
863 | /** | ||
864 | * regmap_field_alloc(): Allocate and initialise a register field | ||
865 | * in a register map. | ||
866 | * | ||
867 | * @regmap: regmap bank in which this register field is located. | ||
868 | * @reg_field: Register field with in the bank. | ||
869 | * | ||
870 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
871 | * to a struct regmap_field. The regmap_field should be freed by the | ||
872 | * user once its finished working with it using regmap_field_free(). | ||
873 | */ | ||
874 | struct regmap_field *regmap_field_alloc(struct regmap *regmap, | ||
875 | struct reg_field reg_field) | ||
876 | { | ||
877 | struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL); | ||
878 | |||
879 | if (!rm_field) | ||
880 | return ERR_PTR(-ENOMEM); | ||
881 | |||
882 | regmap_field_init(rm_field, regmap, reg_field); | ||
883 | |||
884 | return rm_field; | ||
885 | } | ||
886 | EXPORT_SYMBOL_GPL(regmap_field_alloc); | ||
887 | |||
888 | /** | ||
889 | * regmap_field_free(): Free register field allocated using regmap_field_alloc | ||
890 | * | ||
891 | * @field: regmap field which should be freed. | ||
892 | */ | ||
893 | void regmap_field_free(struct regmap_field *field) | ||
894 | { | ||
895 | kfree(field); | ||
896 | } | ||
897 | EXPORT_SYMBOL_GPL(regmap_field_free); | ||
898 | |||
804 | /** | 899 | /** |
805 | * regmap_reinit_cache(): Reinitialise the current register cache | 900 | * regmap_reinit_cache(): Reinitialise the current register cache |
806 | * | 901 | * |
@@ -1249,6 +1344,22 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, | |||
1249 | } | 1344 | } |
1250 | EXPORT_SYMBOL_GPL(regmap_raw_write); | 1345 | EXPORT_SYMBOL_GPL(regmap_raw_write); |
1251 | 1346 | ||
1347 | /** | ||
1348 | * regmap_field_write(): Write a value to a single register field | ||
1349 | * | ||
1350 | * @field: Register field to write to | ||
1351 | * @val: Value to be written | ||
1352 | * | ||
1353 | * A value of zero will be returned on success, a negative errno will | ||
1354 | * be returned in error cases. | ||
1355 | */ | ||
1356 | int regmap_field_write(struct regmap_field *field, unsigned int val) | ||
1357 | { | ||
1358 | return regmap_update_bits(field->regmap, field->reg, | ||
1359 | field->mask, val << field->shift); | ||
1360 | } | ||
1361 | EXPORT_SYMBOL_GPL(regmap_field_write); | ||
1362 | |||
1252 | /* | 1363 | /* |
1253 | * regmap_bulk_write(): Write multiple registers to the device | 1364 | * regmap_bulk_write(): Write multiple registers to the device |
1254 | * | 1365 | * |
@@ -1532,6 +1643,31 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
1532 | EXPORT_SYMBOL_GPL(regmap_raw_read); | 1643 | EXPORT_SYMBOL_GPL(regmap_raw_read); |
1533 | 1644 | ||
1534 | /** | 1645 | /** |
1646 | * regmap_field_read(): Read a value to a single register field | ||
1647 | * | ||
1648 | * @field: Register field to read from | ||
1649 | * @val: Pointer to store read value | ||
1650 | * | ||
1651 | * A value of zero will be returned on success, a negative errno will | ||
1652 | * be returned in error cases. | ||
1653 | */ | ||
1654 | int regmap_field_read(struct regmap_field *field, unsigned int *val) | ||
1655 | { | ||
1656 | int ret; | ||
1657 | unsigned int reg_val; | ||
1658 | ret = regmap_read(field->regmap, field->reg, ®_val); | ||
1659 | if (ret != 0) | ||
1660 | return ret; | ||
1661 | |||
1662 | reg_val &= field->mask; | ||
1663 | reg_val >>= field->shift; | ||
1664 | *val = reg_val; | ||
1665 | |||
1666 | return ret; | ||
1667 | } | ||
1668 | EXPORT_SYMBOL_GPL(regmap_field_read); | ||
1669 | |||
1670 | /** | ||
1535 | * regmap_bulk_read(): Read multiple registers from the device | 1671 | * regmap_bulk_read(): Read multiple registers from the device |
1536 | * | 1672 | * |
1537 | * @map: Register map to write to | 1673 | * @map: Register map to write to |
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 901a388dbea7..19396c8ffe45 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -169,6 +169,12 @@ config PINCTRL_SUNXI | |||
169 | select PINMUX | 169 | select PINMUX |
170 | select GENERIC_PINCONF | 170 | select GENERIC_PINCONF |
171 | 171 | ||
172 | config PINCTRL_ST | ||
173 | bool | ||
174 | depends on OF | ||
175 | select PINMUX | ||
176 | select PINCONF | ||
177 | |||
172 | config PINCTRL_TEGRA | 178 | config PINCTRL_TEGRA |
173 | bool | 179 | bool |
174 | select PINMUX | 180 | select PINMUX |
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f90b645fb601..76c937cbbb13 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
@@ -46,6 +46,7 @@ obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o | |||
46 | obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o | 46 | obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o |
47 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o | 47 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o |
48 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o | 48 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o |
49 | obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o | ||
49 | 50 | ||
50 | obj-$(CONFIG_PLAT_ORION) += mvebu/ | 51 | obj-$(CONFIG_PLAT_ORION) += mvebu/ |
51 | obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/ | 52 | obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/ |
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c new file mode 100644 index 000000000000..04d4506ae18d --- /dev/null +++ b/drivers/pinctrl/pinctrl-st.c | |||
@@ -0,0 +1,1403 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 STMicroelectronics (R&D) Limited. | ||
3 | * Authors: | ||
4 | * Srinivas Kandagatla <srinivas.kandagatla@st.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_gpio.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/mfd/syscon.h> | ||
21 | #include <linux/pinctrl/pinctrl.h> | ||
22 | #include <linux/pinctrl/pinmux.h> | ||
23 | #include <linux/pinctrl/pinconf.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include "core.h" | ||
26 | |||
27 | /* PIO Block registers */ | ||
28 | /* PIO output */ | ||
29 | #define REG_PIO_POUT 0x00 | ||
30 | /* Set bits of POUT */ | ||
31 | #define REG_PIO_SET_POUT 0x04 | ||
32 | /* Clear bits of POUT */ | ||
33 | #define REG_PIO_CLR_POUT 0x08 | ||
34 | /* PIO input */ | ||
35 | #define REG_PIO_PIN 0x10 | ||
36 | /* PIO configuration */ | ||
37 | #define REG_PIO_PC(n) (0x20 + (n) * 0x10) | ||
38 | /* Set bits of PC[2:0] */ | ||
39 | #define REG_PIO_SET_PC(n) (0x24 + (n) * 0x10) | ||
40 | /* Clear bits of PC[2:0] */ | ||
41 | #define REG_PIO_CLR_PC(n) (0x28 + (n) * 0x10) | ||
42 | /* PIO input comparison */ | ||
43 | #define REG_PIO_PCOMP 0x50 | ||
44 | /* Set bits of PCOMP */ | ||
45 | #define REG_PIO_SET_PCOMP 0x54 | ||
46 | /* Clear bits of PCOMP */ | ||
47 | #define REG_PIO_CLR_PCOMP 0x58 | ||
48 | /* PIO input comparison mask */ | ||
49 | #define REG_PIO_PMASK 0x60 | ||
50 | /* Set bits of PMASK */ | ||
51 | #define REG_PIO_SET_PMASK 0x64 | ||
52 | /* Clear bits of PMASK */ | ||
53 | #define REG_PIO_CLR_PMASK 0x68 | ||
54 | |||
55 | #define ST_GPIO_DIRECTION_BIDIR 0x1 | ||
56 | #define ST_GPIO_DIRECTION_OUT 0x2 | ||
57 | #define ST_GPIO_DIRECTION_IN 0x4 | ||
58 | |||
59 | /** | ||
60 | * Packed style retime configuration. | ||
61 | * There are two registers cfg0 and cfg1 in this style for each bank. | ||
62 | * Each field in this register is 8 bit corresponding to 8 pins in the bank. | ||
63 | */ | ||
64 | #define RT_P_CFGS_PER_BANK 2 | ||
65 | #define RT_P_CFG0_CLK1NOTCLK0_FIELD(reg) REG_FIELD(reg, 0, 7) | ||
66 | #define RT_P_CFG0_DELAY_0_FIELD(reg) REG_FIELD(reg, 16, 23) | ||
67 | #define RT_P_CFG0_DELAY_1_FIELD(reg) REG_FIELD(reg, 24, 31) | ||
68 | #define RT_P_CFG1_INVERTCLK_FIELD(reg) REG_FIELD(reg, 0, 7) | ||
69 | #define RT_P_CFG1_RETIME_FIELD(reg) REG_FIELD(reg, 8, 15) | ||
70 | #define RT_P_CFG1_CLKNOTDATA_FIELD(reg) REG_FIELD(reg, 16, 23) | ||
71 | #define RT_P_CFG1_DOUBLE_EDGE_FIELD(reg) REG_FIELD(reg, 24, 31) | ||
72 | |||
73 | /** | ||
74 | * Dedicated style retime Configuration register | ||
75 | * each register is dedicated per pin. | ||
76 | */ | ||
77 | #define RT_D_CFGS_PER_BANK 8 | ||
78 | #define RT_D_CFG_CLK_SHIFT 0 | ||
79 | #define RT_D_CFG_CLK_MASK (0x3 << 0) | ||
80 | #define RT_D_CFG_CLKNOTDATA_SHIFT 2 | ||
81 | #define RT_D_CFG_CLKNOTDATA_MASK BIT(2) | ||
82 | #define RT_D_CFG_DELAY_SHIFT 3 | ||
83 | #define RT_D_CFG_DELAY_MASK (0xf << 3) | ||
84 | #define RT_D_CFG_DELAY_INNOTOUT_SHIFT 7 | ||
85 | #define RT_D_CFG_DELAY_INNOTOUT_MASK BIT(7) | ||
86 | #define RT_D_CFG_DOUBLE_EDGE_SHIFT 8 | ||
87 | #define RT_D_CFG_DOUBLE_EDGE_MASK BIT(8) | ||
88 | #define RT_D_CFG_INVERTCLK_SHIFT 9 | ||
89 | #define RT_D_CFG_INVERTCLK_MASK BIT(9) | ||
90 | #define RT_D_CFG_RETIME_SHIFT 10 | ||
91 | #define RT_D_CFG_RETIME_MASK BIT(10) | ||
92 | |||
93 | /* | ||
94 | * Pinconf is represented in an opaque unsigned long variable. | ||
95 | * Below is the bit allocation details for each possible configuration. | ||
96 | * All the bit fields can be encapsulated into four variables | ||
97 | * (direction, retime-type, retime-clk, retime-delay) | ||
98 | * | ||
99 | * +----------------+ | ||
100 | *[31:28]| reserved-3 | | ||
101 | * +----------------+------------- | ||
102 | *[27] | oe | | | ||
103 | * +----------------+ v | ||
104 | *[26] | pu | [Direction ] | ||
105 | * +----------------+ ^ | ||
106 | *[25] | od | | | ||
107 | * +----------------+------------- | ||
108 | *[24] | reserved-2 | | ||
109 | * +----------------+------------- | ||
110 | *[23] | retime | | | ||
111 | * +----------------+ | | ||
112 | *[22] | retime-invclk | | | ||
113 | * +----------------+ v | ||
114 | *[21] |retime-clknotdat| [Retime-type ] | ||
115 | * +----------------+ ^ | ||
116 | *[20] | retime-de | | | ||
117 | * +----------------+------------- | ||
118 | *[19:18]| retime-clk |------>[Retime-Clk ] | ||
119 | * +----------------+ | ||
120 | *[17:16]| reserved-1 | | ||
121 | * +----------------+ | ||
122 | *[15..0]| retime-delay |------>[Retime Delay] | ||
123 | * +----------------+ | ||
124 | */ | ||
125 | |||
126 | #define ST_PINCONF_UNPACK(conf, param)\ | ||
127 | ((conf >> ST_PINCONF_ ##param ##_SHIFT) \ | ||
128 | & ST_PINCONF_ ##param ##_MASK) | ||
129 | |||
130 | #define ST_PINCONF_PACK(conf, val, param) (conf |=\ | ||
131 | ((val & ST_PINCONF_ ##param ##_MASK) << \ | ||
132 | ST_PINCONF_ ##param ##_SHIFT)) | ||
133 | |||
134 | /* Output enable */ | ||
135 | #define ST_PINCONF_OE_MASK 0x1 | ||
136 | #define ST_PINCONF_OE_SHIFT 27 | ||
137 | #define ST_PINCONF_OE BIT(27) | ||
138 | #define ST_PINCONF_UNPACK_OE(conf) ST_PINCONF_UNPACK(conf, OE) | ||
139 | #define ST_PINCONF_PACK_OE(conf) ST_PINCONF_PACK(conf, 1, OE) | ||
140 | |||
141 | /* Pull Up */ | ||
142 | #define ST_PINCONF_PU_MASK 0x1 | ||
143 | #define ST_PINCONF_PU_SHIFT 26 | ||
144 | #define ST_PINCONF_PU BIT(26) | ||
145 | #define ST_PINCONF_UNPACK_PU(conf) ST_PINCONF_UNPACK(conf, PU) | ||
146 | #define ST_PINCONF_PACK_PU(conf) ST_PINCONF_PACK(conf, 1, PU) | ||
147 | |||
148 | /* Open Drain */ | ||
149 | #define ST_PINCONF_OD_MASK 0x1 | ||
150 | #define ST_PINCONF_OD_SHIFT 25 | ||
151 | #define ST_PINCONF_OD BIT(25) | ||
152 | #define ST_PINCONF_UNPACK_OD(conf) ST_PINCONF_UNPACK(conf, OD) | ||
153 | #define ST_PINCONF_PACK_OD(conf) ST_PINCONF_PACK(conf, 1, OD) | ||
154 | |||
155 | #define ST_PINCONF_RT_MASK 0x1 | ||
156 | #define ST_PINCONF_RT_SHIFT 23 | ||
157 | #define ST_PINCONF_RT BIT(23) | ||
158 | #define ST_PINCONF_UNPACK_RT(conf) ST_PINCONF_UNPACK(conf, RT) | ||
159 | #define ST_PINCONF_PACK_RT(conf) ST_PINCONF_PACK(conf, 1, RT) | ||
160 | |||
161 | #define ST_PINCONF_RT_INVERTCLK_MASK 0x1 | ||
162 | #define ST_PINCONF_RT_INVERTCLK_SHIFT 22 | ||
163 | #define ST_PINCONF_RT_INVERTCLK BIT(22) | ||
164 | #define ST_PINCONF_UNPACK_RT_INVERTCLK(conf) \ | ||
165 | ST_PINCONF_UNPACK(conf, RT_INVERTCLK) | ||
166 | #define ST_PINCONF_PACK_RT_INVERTCLK(conf) \ | ||
167 | ST_PINCONF_PACK(conf, 1, RT_INVERTCLK) | ||
168 | |||
169 | #define ST_PINCONF_RT_CLKNOTDATA_MASK 0x1 | ||
170 | #define ST_PINCONF_RT_CLKNOTDATA_SHIFT 21 | ||
171 | #define ST_PINCONF_RT_CLKNOTDATA BIT(21) | ||
172 | #define ST_PINCONF_UNPACK_RT_CLKNOTDATA(conf) \ | ||
173 | ST_PINCONF_UNPACK(conf, RT_CLKNOTDATA) | ||
174 | #define ST_PINCONF_PACK_RT_CLKNOTDATA(conf) \ | ||
175 | ST_PINCONF_PACK(conf, 1, RT_CLKNOTDATA) | ||
176 | |||
177 | #define ST_PINCONF_RT_DOUBLE_EDGE_MASK 0x1 | ||
178 | #define ST_PINCONF_RT_DOUBLE_EDGE_SHIFT 20 | ||
179 | #define ST_PINCONF_RT_DOUBLE_EDGE BIT(20) | ||
180 | #define ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(conf) \ | ||
181 | ST_PINCONF_UNPACK(conf, RT_DOUBLE_EDGE) | ||
182 | #define ST_PINCONF_PACK_RT_DOUBLE_EDGE(conf) \ | ||
183 | ST_PINCONF_PACK(conf, 1, RT_DOUBLE_EDGE) | ||
184 | |||
185 | #define ST_PINCONF_RT_CLK_MASK 0x3 | ||
186 | #define ST_PINCONF_RT_CLK_SHIFT 18 | ||
187 | #define ST_PINCONF_RT_CLK BIT(18) | ||
188 | #define ST_PINCONF_UNPACK_RT_CLK(conf) ST_PINCONF_UNPACK(conf, RT_CLK) | ||
189 | #define ST_PINCONF_PACK_RT_CLK(conf, val) ST_PINCONF_PACK(conf, val, RT_CLK) | ||
190 | |||
191 | /* RETIME_DELAY in Pico Secs */ | ||
192 | #define ST_PINCONF_RT_DELAY_MASK 0xffff | ||
193 | #define ST_PINCONF_RT_DELAY_SHIFT 0 | ||
194 | #define ST_PINCONF_UNPACK_RT_DELAY(conf) ST_PINCONF_UNPACK(conf, RT_DELAY) | ||
195 | #define ST_PINCONF_PACK_RT_DELAY(conf, val) \ | ||
196 | ST_PINCONF_PACK(conf, val, RT_DELAY) | ||
197 | |||
198 | #define ST_GPIO_PINS_PER_BANK (8) | ||
199 | #define OF_GPIO_ARGS_MIN (4) | ||
200 | #define OF_RT_ARGS_MIN (2) | ||
201 | |||
202 | #define gpio_range_to_bank(chip) \ | ||
203 | container_of(chip, struct st_gpio_bank, range) | ||
204 | |||
205 | #define gpio_chip_to_bank(chip) \ | ||
206 | container_of(chip, struct st_gpio_bank, gpio_chip) | ||
207 | |||
208 | |||
209 | enum st_retime_style { | ||
210 | st_retime_style_none, | ||
211 | st_retime_style_packed, | ||
212 | st_retime_style_dedicated, | ||
213 | }; | ||
214 | |||
215 | struct st_retime_dedicated { | ||
216 | struct regmap_field *rt[ST_GPIO_PINS_PER_BANK]; | ||
217 | }; | ||
218 | |||
219 | struct st_retime_packed { | ||
220 | struct regmap_field *clk1notclk0; | ||
221 | struct regmap_field *delay_0; | ||
222 | struct regmap_field *delay_1; | ||
223 | struct regmap_field *invertclk; | ||
224 | struct regmap_field *retime; | ||
225 | struct regmap_field *clknotdata; | ||
226 | struct regmap_field *double_edge; | ||
227 | }; | ||
228 | |||
229 | struct st_pio_control { | ||
230 | u32 rt_pin_mask; | ||
231 | struct regmap_field *alt, *oe, *pu, *od; | ||
232 | /* retiming */ | ||
233 | union { | ||
234 | struct st_retime_packed rt_p; | ||
235 | struct st_retime_dedicated rt_d; | ||
236 | } rt; | ||
237 | }; | ||
238 | |||
239 | struct st_pctl_data { | ||
240 | enum st_retime_style rt_style; | ||
241 | unsigned int *input_delays; | ||
242 | int ninput_delays; | ||
243 | unsigned int *output_delays; | ||
244 | int noutput_delays; | ||
245 | /* register offset information */ | ||
246 | int alt, oe, pu, od, rt; | ||
247 | }; | ||
248 | |||
249 | struct st_pinconf { | ||
250 | int pin; | ||
251 | const char *name; | ||
252 | unsigned long config; | ||
253 | int altfunc; | ||
254 | }; | ||
255 | |||
256 | struct st_pmx_func { | ||
257 | const char *name; | ||
258 | const char **groups; | ||
259 | unsigned ngroups; | ||
260 | }; | ||
261 | |||
262 | struct st_pctl_group { | ||
263 | const char *name; | ||
264 | unsigned int *pins; | ||
265 | unsigned npins; | ||
266 | struct st_pinconf *pin_conf; | ||
267 | }; | ||
268 | |||
269 | struct st_gpio_bank { | ||
270 | struct gpio_chip gpio_chip; | ||
271 | struct pinctrl_gpio_range range; | ||
272 | void __iomem *base; | ||
273 | struct st_pio_control pc; | ||
274 | }; | ||
275 | |||
276 | struct st_pinctrl { | ||
277 | struct device *dev; | ||
278 | struct pinctrl_dev *pctl; | ||
279 | struct st_gpio_bank *banks; | ||
280 | int nbanks; | ||
281 | struct st_pmx_func *functions; | ||
282 | int nfunctions; | ||
283 | struct st_pctl_group *groups; | ||
284 | int ngroups; | ||
285 | struct regmap *regmap; | ||
286 | const struct st_pctl_data *data; | ||
287 | }; | ||
288 | |||
289 | /* SOC specific data */ | ||
290 | /* STiH415 data */ | ||
291 | unsigned int stih415_input_delays[] = {0, 500, 1000, 1500}; | ||
292 | unsigned int stih415_output_delays[] = {0, 1000, 2000, 3000}; | ||
293 | |||
294 | #define STIH415_PCTRL_COMMON_DATA \ | ||
295 | .rt_style = st_retime_style_packed, \ | ||
296 | .input_delays = stih415_input_delays, \ | ||
297 | .ninput_delays = 4, \ | ||
298 | .output_delays = stih415_output_delays, \ | ||
299 | .noutput_delays = 4 | ||
300 | |||
301 | static const struct st_pctl_data stih415_sbc_data = { | ||
302 | STIH415_PCTRL_COMMON_DATA, | ||
303 | .alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 16, | ||
304 | }; | ||
305 | |||
306 | static const struct st_pctl_data stih415_front_data = { | ||
307 | STIH415_PCTRL_COMMON_DATA, | ||
308 | .alt = 0, .oe = 8, .pu = 10, .od = 12, .rt = 16, | ||
309 | }; | ||
310 | |||
311 | static const struct st_pctl_data stih415_rear_data = { | ||
312 | STIH415_PCTRL_COMMON_DATA, | ||
313 | .alt = 0, .oe = 6, .pu = 8, .od = 10, .rt = 38, | ||
314 | }; | ||
315 | |||
316 | static const struct st_pctl_data stih415_left_data = { | ||
317 | STIH415_PCTRL_COMMON_DATA, | ||
318 | .alt = 0, .oe = 3, .pu = 4, .od = 5, .rt = 6, | ||
319 | }; | ||
320 | |||
321 | static const struct st_pctl_data stih415_right_data = { | ||
322 | STIH415_PCTRL_COMMON_DATA, | ||
323 | .alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 11, | ||
324 | }; | ||
325 | |||
326 | /* STiH416 data */ | ||
327 | unsigned int stih416_delays[] = {0, 300, 500, 750, 1000, 1250, 1500, | ||
328 | 1750, 2000, 2250, 2500, 2750, 3000, 3250 }; | ||
329 | |||
330 | static const struct st_pctl_data stih416_data = { | ||
331 | .rt_style = st_retime_style_dedicated, | ||
332 | .input_delays = stih416_delays, | ||
333 | .ninput_delays = 14, | ||
334 | .output_delays = stih416_delays, | ||
335 | .noutput_delays = 14, | ||
336 | .alt = 0, .oe = 40, .pu = 50, .od = 60, .rt = 100, | ||
337 | }; | ||
338 | |||
339 | /* Low level functions.. */ | ||
340 | static inline int st_gpio_bank(int gpio) | ||
341 | { | ||
342 | return gpio/ST_GPIO_PINS_PER_BANK; | ||
343 | } | ||
344 | |||
345 | static inline int st_gpio_pin(int gpio) | ||
346 | { | ||
347 | return gpio%ST_GPIO_PINS_PER_BANK; | ||
348 | } | ||
349 | |||
350 | static void st_pinconf_set_config(struct st_pio_control *pc, | ||
351 | int pin, unsigned long config) | ||
352 | { | ||
353 | struct regmap_field *output_enable = pc->oe; | ||
354 | struct regmap_field *pull_up = pc->pu; | ||
355 | struct regmap_field *open_drain = pc->od; | ||
356 | unsigned int oe_value, pu_value, od_value; | ||
357 | unsigned long mask = BIT(pin); | ||
358 | |||
359 | regmap_field_read(output_enable, &oe_value); | ||
360 | regmap_field_read(pull_up, &pu_value); | ||
361 | regmap_field_read(open_drain, &od_value); | ||
362 | |||
363 | /* Clear old values */ | ||
364 | oe_value &= ~mask; | ||
365 | pu_value &= ~mask; | ||
366 | od_value &= ~mask; | ||
367 | |||
368 | if (config & ST_PINCONF_OE) | ||
369 | oe_value |= mask; | ||
370 | if (config & ST_PINCONF_PU) | ||
371 | pu_value |= mask; | ||
372 | if (config & ST_PINCONF_OD) | ||
373 | od_value |= mask; | ||
374 | |||
375 | regmap_field_write(output_enable, oe_value); | ||
376 | regmap_field_write(pull_up, pu_value); | ||
377 | regmap_field_write(open_drain, od_value); | ||
378 | } | ||
379 | |||
380 | static void st_pctl_set_function(struct st_pio_control *pc, | ||
381 | int pin_id, int function) | ||
382 | { | ||
383 | struct regmap_field *alt = pc->alt; | ||
384 | unsigned int val; | ||
385 | int pin = st_gpio_pin(pin_id); | ||
386 | int offset = pin * 4; | ||
387 | |||
388 | regmap_field_read(alt, &val); | ||
389 | val &= ~(0xf << offset); | ||
390 | val |= function << offset; | ||
391 | regmap_field_write(alt, val); | ||
392 | } | ||
393 | |||
394 | static unsigned long st_pinconf_delay_to_bit(unsigned int delay, | ||
395 | const struct st_pctl_data *data, unsigned long config) | ||
396 | { | ||
397 | unsigned int *delay_times; | ||
398 | int num_delay_times, i, closest_index = -1; | ||
399 | unsigned int closest_divergence = UINT_MAX; | ||
400 | |||
401 | if (ST_PINCONF_UNPACK_OE(config)) { | ||
402 | delay_times = data->output_delays; | ||
403 | num_delay_times = data->noutput_delays; | ||
404 | } else { | ||
405 | delay_times = data->input_delays; | ||
406 | num_delay_times = data->ninput_delays; | ||
407 | } | ||
408 | |||
409 | for (i = 0; i < num_delay_times; i++) { | ||
410 | unsigned int divergence = abs(delay - delay_times[i]); | ||
411 | |||
412 | if (divergence == 0) | ||
413 | return i; | ||
414 | |||
415 | if (divergence < closest_divergence) { | ||
416 | closest_divergence = divergence; | ||
417 | closest_index = i; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | pr_warn("Attempt to set delay %d, closest available %d\n", | ||
422 | delay, delay_times[closest_index]); | ||
423 | |||
424 | return closest_index; | ||
425 | } | ||
426 | |||
427 | static unsigned long st_pinconf_bit_to_delay(unsigned int index, | ||
428 | const struct st_pctl_data *data, unsigned long output) | ||
429 | { | ||
430 | unsigned int *delay_times; | ||
431 | int num_delay_times; | ||
432 | |||
433 | if (output) { | ||
434 | delay_times = data->output_delays; | ||
435 | num_delay_times = data->noutput_delays; | ||
436 | } else { | ||
437 | delay_times = data->input_delays; | ||
438 | num_delay_times = data->ninput_delays; | ||
439 | } | ||
440 | |||
441 | if (index < num_delay_times) { | ||
442 | return delay_times[index]; | ||
443 | } else { | ||
444 | pr_warn("Delay not found in/out delay list\n"); | ||
445 | return 0; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | static void st_regmap_field_bit_set_clear_pin(struct regmap_field *field, | ||
450 | int enable, int pin) | ||
451 | { | ||
452 | unsigned int val = 0; | ||
453 | |||
454 | regmap_field_read(field, &val); | ||
455 | if (enable) | ||
456 | val |= BIT(pin); | ||
457 | else | ||
458 | val &= ~BIT(pin); | ||
459 | regmap_field_write(field, val); | ||
460 | } | ||
461 | |||
462 | static void st_pinconf_set_retime_packed(struct st_pinctrl *info, | ||
463 | struct st_pio_control *pc, unsigned long config, int pin) | ||
464 | { | ||
465 | const struct st_pctl_data *data = info->data; | ||
466 | struct st_retime_packed *rt_p = &pc->rt.rt_p; | ||
467 | unsigned int delay; | ||
468 | |||
469 | st_regmap_field_bit_set_clear_pin(rt_p->clk1notclk0, | ||
470 | ST_PINCONF_UNPACK_RT_CLK(config), pin); | ||
471 | |||
472 | st_regmap_field_bit_set_clear_pin(rt_p->clknotdata, | ||
473 | ST_PINCONF_UNPACK_RT_CLKNOTDATA(config), pin); | ||
474 | |||
475 | st_regmap_field_bit_set_clear_pin(rt_p->double_edge, | ||
476 | ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(config), pin); | ||
477 | |||
478 | st_regmap_field_bit_set_clear_pin(rt_p->invertclk, | ||
479 | ST_PINCONF_UNPACK_RT_INVERTCLK(config), pin); | ||
480 | |||
481 | st_regmap_field_bit_set_clear_pin(rt_p->retime, | ||
482 | ST_PINCONF_UNPACK_RT(config), pin); | ||
483 | |||
484 | delay = st_pinconf_delay_to_bit(ST_PINCONF_UNPACK_RT_DELAY(config), | ||
485 | data, config); | ||
486 | /* 2 bit delay, lsb */ | ||
487 | st_regmap_field_bit_set_clear_pin(rt_p->delay_0, delay & 0x1, pin); | ||
488 | /* 2 bit delay, msb */ | ||
489 | st_regmap_field_bit_set_clear_pin(rt_p->delay_1, delay & 0x2, pin); | ||
490 | |||
491 | } | ||
492 | |||
493 | static void st_pinconf_set_retime_dedicated(struct st_pinctrl *info, | ||
494 | struct st_pio_control *pc, unsigned long config, int pin) | ||
495 | { | ||
496 | int input = ST_PINCONF_UNPACK_OE(config) ? 0 : 1; | ||
497 | int clk = ST_PINCONF_UNPACK_RT_CLK(config); | ||
498 | int clknotdata = ST_PINCONF_UNPACK_RT_CLKNOTDATA(config); | ||
499 | int double_edge = ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(config); | ||
500 | int invertclk = ST_PINCONF_UNPACK_RT_INVERTCLK(config); | ||
501 | int retime = ST_PINCONF_UNPACK_RT(config); | ||
502 | |||
503 | unsigned long delay = st_pinconf_delay_to_bit( | ||
504 | ST_PINCONF_UNPACK_RT_DELAY(config), | ||
505 | info->data, config); | ||
506 | struct st_retime_dedicated *rt_d = &pc->rt.rt_d; | ||
507 | |||
508 | unsigned long retime_config = | ||
509 | ((clk) << RT_D_CFG_CLK_SHIFT) | | ||
510 | ((delay) << RT_D_CFG_DELAY_SHIFT) | | ||
511 | ((input) << RT_D_CFG_DELAY_INNOTOUT_SHIFT) | | ||
512 | ((retime) << RT_D_CFG_RETIME_SHIFT) | | ||
513 | ((clknotdata) << RT_D_CFG_CLKNOTDATA_SHIFT) | | ||
514 | ((invertclk) << RT_D_CFG_INVERTCLK_SHIFT) | | ||
515 | ((double_edge) << RT_D_CFG_DOUBLE_EDGE_SHIFT); | ||
516 | |||
517 | regmap_field_write(rt_d->rt[pin], retime_config); | ||
518 | } | ||
519 | |||
520 | static void st_pinconf_get_direction(struct st_pio_control *pc, | ||
521 | int pin, unsigned long *config) | ||
522 | { | ||
523 | unsigned int oe_value, pu_value, od_value; | ||
524 | |||
525 | regmap_field_read(pc->oe, &oe_value); | ||
526 | regmap_field_read(pc->pu, &pu_value); | ||
527 | regmap_field_read(pc->od, &od_value); | ||
528 | |||
529 | if (oe_value & BIT(pin)) | ||
530 | ST_PINCONF_PACK_OE(*config); | ||
531 | if (pu_value & BIT(pin)) | ||
532 | ST_PINCONF_PACK_PU(*config); | ||
533 | if (od_value & BIT(pin)) | ||
534 | ST_PINCONF_PACK_OD(*config); | ||
535 | |||
536 | } | ||
537 | |||
538 | static int st_pinconf_get_retime_packed(struct st_pinctrl *info, | ||
539 | struct st_pio_control *pc, int pin, unsigned long *config) | ||
540 | { | ||
541 | const struct st_pctl_data *data = info->data; | ||
542 | struct st_retime_packed *rt_p = &pc->rt.rt_p; | ||
543 | unsigned int delay_bits, delay, delay0, delay1, val; | ||
544 | int output = ST_PINCONF_UNPACK_OE(*config); | ||
545 | |||
546 | if (!regmap_field_read(rt_p->retime, &val) && (val & BIT(pin))) | ||
547 | ST_PINCONF_PACK_RT(*config); | ||
548 | |||
549 | if (!regmap_field_read(rt_p->clk1notclk0, &val) && (val & BIT(pin))) | ||
550 | ST_PINCONF_PACK_RT_CLK(*config, 1); | ||
551 | |||
552 | if (!regmap_field_read(rt_p->clknotdata, &val) && (val & BIT(pin))) | ||
553 | ST_PINCONF_PACK_RT_CLKNOTDATA(*config); | ||
554 | |||
555 | if (!regmap_field_read(rt_p->double_edge, &val) && (val & BIT(pin))) | ||
556 | ST_PINCONF_PACK_RT_DOUBLE_EDGE(*config); | ||
557 | |||
558 | if (!regmap_field_read(rt_p->invertclk, &val) && (val & BIT(pin))) | ||
559 | ST_PINCONF_PACK_RT_INVERTCLK(*config); | ||
560 | |||
561 | regmap_field_read(rt_p->delay_0, &delay0); | ||
562 | regmap_field_read(rt_p->delay_1, &delay1); | ||
563 | delay_bits = (((delay1 & BIT(pin)) ? 1 : 0) << 1) | | ||
564 | (((delay0 & BIT(pin)) ? 1 : 0)); | ||
565 | delay = st_pinconf_bit_to_delay(delay_bits, data, output); | ||
566 | ST_PINCONF_PACK_RT_DELAY(*config, delay); | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | static int st_pinconf_get_retime_dedicated(struct st_pinctrl *info, | ||
572 | struct st_pio_control *pc, int pin, unsigned long *config) | ||
573 | { | ||
574 | unsigned int value; | ||
575 | unsigned long delay_bits, delay, rt_clk; | ||
576 | int output = ST_PINCONF_UNPACK_OE(*config); | ||
577 | struct st_retime_dedicated *rt_d = &pc->rt.rt_d; | ||
578 | |||
579 | regmap_field_read(rt_d->rt[pin], &value); | ||
580 | |||
581 | rt_clk = (value & RT_D_CFG_CLK_MASK) >> RT_D_CFG_CLK_SHIFT; | ||
582 | ST_PINCONF_PACK_RT_CLK(*config, rt_clk); | ||
583 | |||
584 | delay_bits = (value & RT_D_CFG_DELAY_MASK) >> RT_D_CFG_DELAY_SHIFT; | ||
585 | delay = st_pinconf_bit_to_delay(delay_bits, info->data, output); | ||
586 | ST_PINCONF_PACK_RT_DELAY(*config, delay); | ||
587 | |||
588 | if (value & RT_D_CFG_CLKNOTDATA_MASK) | ||
589 | ST_PINCONF_PACK_RT_CLKNOTDATA(*config); | ||
590 | |||
591 | if (value & RT_D_CFG_DOUBLE_EDGE_MASK) | ||
592 | ST_PINCONF_PACK_RT_DOUBLE_EDGE(*config); | ||
593 | |||
594 | if (value & RT_D_CFG_INVERTCLK_MASK) | ||
595 | ST_PINCONF_PACK_RT_INVERTCLK(*config); | ||
596 | |||
597 | if (value & RT_D_CFG_RETIME_MASK) | ||
598 | ST_PINCONF_PACK_RT(*config); | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | /* GPIO related functions */ | ||
604 | |||
605 | static inline void __st_gpio_set(struct st_gpio_bank *bank, | ||
606 | unsigned offset, int value) | ||
607 | { | ||
608 | if (value) | ||
609 | writel(BIT(offset), bank->base + REG_PIO_SET_POUT); | ||
610 | else | ||
611 | writel(BIT(offset), bank->base + REG_PIO_CLR_POUT); | ||
612 | } | ||
613 | |||
614 | static void st_gpio_direction(struct st_gpio_bank *bank, | ||
615 | unsigned int gpio, unsigned int direction) | ||
616 | { | ||
617 | int offset = st_gpio_pin(gpio); | ||
618 | int i = 0; | ||
619 | /** | ||
620 | * There are three configuration registers (PIOn_PC0, PIOn_PC1 | ||
621 | * and PIOn_PC2) for each port. These are used to configure the | ||
622 | * PIO port pins. Each pin can be configured as an input, output, | ||
623 | * bidirectional, or alternative function pin. Three bits, one bit | ||
624 | * from each of the three registers, configure the corresponding bit of | ||
625 | * the port. Valid bit settings is: | ||
626 | * | ||
627 | * PC2 PC1 PC0 Direction. | ||
628 | * 0 0 0 [Input Weak pull-up] | ||
629 | * 0 0 or 1 1 [Bidirection] | ||
630 | * 0 1 0 [Output] | ||
631 | * 1 0 0 [Input] | ||
632 | * | ||
633 | * PIOn_SET_PC and PIOn_CLR_PC registers are used to set and clear bits | ||
634 | * individually. | ||
635 | */ | ||
636 | for (i = 0; i <= 2; i++) { | ||
637 | if (direction & BIT(i)) | ||
638 | writel(BIT(offset), bank->base + REG_PIO_SET_PC(i)); | ||
639 | else | ||
640 | writel(BIT(offset), bank->base + REG_PIO_CLR_PC(i)); | ||
641 | } | ||
642 | } | ||
643 | |||
644 | static int st_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
645 | { | ||
646 | return pinctrl_request_gpio(chip->base + offset); | ||
647 | } | ||
648 | |||
649 | static void st_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
650 | { | ||
651 | pinctrl_free_gpio(chip->base + offset); | ||
652 | } | ||
653 | |||
654 | static int st_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
655 | { | ||
656 | struct st_gpio_bank *bank = gpio_chip_to_bank(chip); | ||
657 | |||
658 | return !!(readl(bank->base + REG_PIO_PIN) & BIT(offset)); | ||
659 | } | ||
660 | |||
661 | static void st_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
662 | { | ||
663 | struct st_gpio_bank *bank = gpio_chip_to_bank(chip); | ||
664 | __st_gpio_set(bank, offset, value); | ||
665 | } | ||
666 | |||
667 | static int st_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
668 | { | ||
669 | pinctrl_gpio_direction_input(chip->base + offset); | ||
670 | |||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | static int st_gpio_direction_output(struct gpio_chip *chip, | ||
675 | unsigned offset, int value) | ||
676 | { | ||
677 | struct st_gpio_bank *bank = gpio_chip_to_bank(chip); | ||
678 | |||
679 | __st_gpio_set(bank, offset, value); | ||
680 | pinctrl_gpio_direction_output(chip->base + offset); | ||
681 | |||
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static int st_gpio_xlate(struct gpio_chip *gc, | ||
686 | const struct of_phandle_args *gpiospec, u32 *flags) | ||
687 | { | ||
688 | if (WARN_ON(gc->of_gpio_n_cells < 1)) | ||
689 | return -EINVAL; | ||
690 | |||
691 | if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) | ||
692 | return -EINVAL; | ||
693 | |||
694 | if (gpiospec->args[0] > gc->ngpio) | ||
695 | return -EINVAL; | ||
696 | |||
697 | return gpiospec->args[0]; | ||
698 | } | ||
699 | |||
700 | /* Pinctrl Groups */ | ||
701 | static int st_pctl_get_groups_count(struct pinctrl_dev *pctldev) | ||
702 | { | ||
703 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
704 | |||
705 | return info->ngroups; | ||
706 | } | ||
707 | |||
708 | static const char *st_pctl_get_group_name(struct pinctrl_dev *pctldev, | ||
709 | unsigned selector) | ||
710 | { | ||
711 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
712 | |||
713 | return info->groups[selector].name; | ||
714 | } | ||
715 | |||
716 | static int st_pctl_get_group_pins(struct pinctrl_dev *pctldev, | ||
717 | unsigned selector, const unsigned **pins, unsigned *npins) | ||
718 | { | ||
719 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
720 | |||
721 | if (selector >= info->ngroups) | ||
722 | return -EINVAL; | ||
723 | |||
724 | *pins = info->groups[selector].pins; | ||
725 | *npins = info->groups[selector].npins; | ||
726 | |||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static const inline struct st_pctl_group *st_pctl_find_group_by_name( | ||
731 | const struct st_pinctrl *info, const char *name) | ||
732 | { | ||
733 | int i; | ||
734 | |||
735 | for (i = 0; i < info->ngroups; i++) { | ||
736 | if (!strcmp(info->groups[i].name, name)) | ||
737 | return &info->groups[i]; | ||
738 | } | ||
739 | |||
740 | return NULL; | ||
741 | } | ||
742 | |||
743 | static int st_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
744 | struct device_node *np, struct pinctrl_map **map, unsigned *num_maps) | ||
745 | { | ||
746 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
747 | const struct st_pctl_group *grp; | ||
748 | struct pinctrl_map *new_map; | ||
749 | struct device_node *parent; | ||
750 | int map_num, i; | ||
751 | |||
752 | grp = st_pctl_find_group_by_name(info, np->name); | ||
753 | if (!grp) { | ||
754 | dev_err(info->dev, "unable to find group for node %s\n", | ||
755 | np->name); | ||
756 | return -EINVAL; | ||
757 | } | ||
758 | |||
759 | map_num = grp->npins + 1; | ||
760 | new_map = devm_kzalloc(pctldev->dev, | ||
761 | sizeof(*new_map) * map_num, GFP_KERNEL); | ||
762 | if (!new_map) | ||
763 | return -ENOMEM; | ||
764 | |||
765 | parent = of_get_parent(np); | ||
766 | if (!parent) { | ||
767 | devm_kfree(pctldev->dev, new_map); | ||
768 | return -EINVAL; | ||
769 | } | ||
770 | |||
771 | *map = new_map; | ||
772 | *num_maps = map_num; | ||
773 | new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; | ||
774 | new_map[0].data.mux.function = parent->name; | ||
775 | new_map[0].data.mux.group = np->name; | ||
776 | of_node_put(parent); | ||
777 | |||
778 | /* create config map per pin */ | ||
779 | new_map++; | ||
780 | for (i = 0; i < grp->npins; i++) { | ||
781 | new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; | ||
782 | new_map[i].data.configs.group_or_pin = | ||
783 | pin_get_name(pctldev, grp->pins[i]); | ||
784 | new_map[i].data.configs.configs = &grp->pin_conf[i].config; | ||
785 | new_map[i].data.configs.num_configs = 1; | ||
786 | } | ||
787 | dev_info(pctldev->dev, "maps: function %s group %s num %d\n", | ||
788 | (*map)->data.mux.function, grp->name, map_num); | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static void st_pctl_dt_free_map(struct pinctrl_dev *pctldev, | ||
794 | struct pinctrl_map *map, unsigned num_maps) | ||
795 | { | ||
796 | } | ||
797 | |||
798 | static struct pinctrl_ops st_pctlops = { | ||
799 | .get_groups_count = st_pctl_get_groups_count, | ||
800 | .get_group_pins = st_pctl_get_group_pins, | ||
801 | .get_group_name = st_pctl_get_group_name, | ||
802 | .dt_node_to_map = st_pctl_dt_node_to_map, | ||
803 | .dt_free_map = st_pctl_dt_free_map, | ||
804 | }; | ||
805 | |||
806 | /* Pinmux */ | ||
807 | static int st_pmx_get_funcs_count(struct pinctrl_dev *pctldev) | ||
808 | { | ||
809 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
810 | |||
811 | return info->nfunctions; | ||
812 | } | ||
813 | |||
814 | const char *st_pmx_get_fname(struct pinctrl_dev *pctldev, | ||
815 | unsigned selector) | ||
816 | { | ||
817 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
818 | |||
819 | return info->functions[selector].name; | ||
820 | } | ||
821 | |||
822 | static int st_pmx_get_groups(struct pinctrl_dev *pctldev, | ||
823 | unsigned selector, const char * const **grps, unsigned * const ngrps) | ||
824 | { | ||
825 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
826 | *grps = info->functions[selector].groups; | ||
827 | *ngrps = info->functions[selector].ngroups; | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | static struct st_pio_control *st_get_pio_control( | ||
833 | struct pinctrl_dev *pctldev, int pin) | ||
834 | { | ||
835 | struct pinctrl_gpio_range *range = | ||
836 | pinctrl_find_gpio_range_from_pin(pctldev, pin); | ||
837 | struct st_gpio_bank *bank = gpio_range_to_bank(range); | ||
838 | |||
839 | return &bank->pc; | ||
840 | } | ||
841 | |||
842 | static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector, | ||
843 | unsigned group) | ||
844 | { | ||
845 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
846 | struct st_pinconf *conf = info->groups[group].pin_conf; | ||
847 | struct st_pio_control *pc; | ||
848 | int i; | ||
849 | |||
850 | for (i = 0; i < info->groups[group].npins; i++) { | ||
851 | pc = st_get_pio_control(pctldev, conf[i].pin); | ||
852 | st_pctl_set_function(pc, conf[i].pin, conf[i].altfunc); | ||
853 | } | ||
854 | |||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | static void st_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, | ||
859 | unsigned group) | ||
860 | { | ||
861 | } | ||
862 | |||
863 | static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev, | ||
864 | struct pinctrl_gpio_range *range, unsigned gpio, | ||
865 | bool input) | ||
866 | { | ||
867 | struct st_gpio_bank *bank = gpio_range_to_bank(range); | ||
868 | /* | ||
869 | * When a PIO bank is used in its primary function mode (altfunc = 0) | ||
870 | * Output Enable (OE), Open Drain(OD), and Pull Up (PU) | ||
871 | * for the primary PIO functions are driven by the related PIO block | ||
872 | */ | ||
873 | st_pctl_set_function(&bank->pc, gpio, 0); | ||
874 | st_gpio_direction(bank, gpio, input ? | ||
875 | ST_GPIO_DIRECTION_IN : ST_GPIO_DIRECTION_OUT); | ||
876 | |||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | static struct pinmux_ops st_pmxops = { | ||
881 | .get_functions_count = st_pmx_get_funcs_count, | ||
882 | .get_function_name = st_pmx_get_fname, | ||
883 | .get_function_groups = st_pmx_get_groups, | ||
884 | .enable = st_pmx_enable, | ||
885 | .disable = st_pmx_disable, | ||
886 | .gpio_set_direction = st_pmx_set_gpio_direction, | ||
887 | }; | ||
888 | |||
889 | /* Pinconf */ | ||
890 | static void st_pinconf_get_retime(struct st_pinctrl *info, | ||
891 | struct st_pio_control *pc, int pin, unsigned long *config) | ||
892 | { | ||
893 | if (info->data->rt_style == st_retime_style_packed) | ||
894 | st_pinconf_get_retime_packed(info, pc, pin, config); | ||
895 | else if (info->data->rt_style == st_retime_style_dedicated) | ||
896 | if ((BIT(pin) & pc->rt_pin_mask)) | ||
897 | st_pinconf_get_retime_dedicated(info, pc, | ||
898 | pin, config); | ||
899 | } | ||
900 | |||
901 | static void st_pinconf_set_retime(struct st_pinctrl *info, | ||
902 | struct st_pio_control *pc, int pin, unsigned long config) | ||
903 | { | ||
904 | if (info->data->rt_style == st_retime_style_packed) | ||
905 | st_pinconf_set_retime_packed(info, pc, config, pin); | ||
906 | else if (info->data->rt_style == st_retime_style_dedicated) | ||
907 | if ((BIT(pin) & pc->rt_pin_mask)) | ||
908 | st_pinconf_set_retime_dedicated(info, pc, | ||
909 | config, pin); | ||
910 | } | ||
911 | |||
912 | static int st_pinconf_set(struct pinctrl_dev *pctldev, | ||
913 | unsigned pin_id, unsigned long config) | ||
914 | { | ||
915 | int pin = st_gpio_pin(pin_id); | ||
916 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
917 | struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id); | ||
918 | |||
919 | st_pinconf_set_config(pc, pin, config); | ||
920 | st_pinconf_set_retime(info, pc, pin, config); | ||
921 | |||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static int st_pinconf_get(struct pinctrl_dev *pctldev, | ||
926 | unsigned pin_id, unsigned long *config) | ||
927 | { | ||
928 | int pin = st_gpio_pin(pin_id); | ||
929 | struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | ||
930 | struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id); | ||
931 | |||
932 | *config = 0; | ||
933 | st_pinconf_get_direction(pc, pin, config); | ||
934 | st_pinconf_get_retime(info, pc, pin, config); | ||
935 | |||
936 | return 0; | ||
937 | } | ||
938 | |||
939 | static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev, | ||
940 | struct seq_file *s, unsigned pin_id) | ||
941 | { | ||
942 | unsigned long config; | ||
943 | st_pinconf_get(pctldev, pin_id, &config); | ||
944 | |||
945 | seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n" | ||
946 | "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld," | ||
947 | "de:%ld,rt-clk:%ld,rt-delay:%ld]", | ||
948 | ST_PINCONF_UNPACK_OE(config), | ||
949 | ST_PINCONF_UNPACK_PU(config), | ||
950 | ST_PINCONF_UNPACK_OD(config), | ||
951 | ST_PINCONF_UNPACK_RT(config), | ||
952 | ST_PINCONF_UNPACK_RT_INVERTCLK(config), | ||
953 | ST_PINCONF_UNPACK_RT_CLKNOTDATA(config), | ||
954 | ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(config), | ||
955 | ST_PINCONF_UNPACK_RT_CLK(config), | ||
956 | ST_PINCONF_UNPACK_RT_DELAY(config)); | ||
957 | } | ||
958 | |||
959 | static struct pinconf_ops st_confops = { | ||
960 | .pin_config_get = st_pinconf_get, | ||
961 | .pin_config_set = st_pinconf_set, | ||
962 | .pin_config_dbg_show = st_pinconf_dbg_show, | ||
963 | }; | ||
964 | |||
965 | static void st_pctl_dt_child_count(struct st_pinctrl *info, | ||
966 | struct device_node *np) | ||
967 | { | ||
968 | struct device_node *child; | ||
969 | for_each_child_of_node(np, child) { | ||
970 | if (of_property_read_bool(child, "gpio-controller")) { | ||
971 | info->nbanks++; | ||
972 | } else { | ||
973 | info->nfunctions++; | ||
974 | info->ngroups += of_get_child_count(child); | ||
975 | } | ||
976 | } | ||
977 | } | ||
978 | |||
979 | static int st_pctl_dt_setup_retime_packed(struct st_pinctrl *info, | ||
980 | int bank, struct st_pio_control *pc) | ||
981 | { | ||
982 | struct device *dev = info->dev; | ||
983 | struct regmap *rm = info->regmap; | ||
984 | const struct st_pctl_data *data = info->data; | ||
985 | /* 2 registers per bank */ | ||
986 | int reg = (data->rt + bank * RT_P_CFGS_PER_BANK) * 4; | ||
987 | struct st_retime_packed *rt_p = &pc->rt.rt_p; | ||
988 | /* cfg0 */ | ||
989 | struct reg_field clk1notclk0 = RT_P_CFG0_CLK1NOTCLK0_FIELD(reg); | ||
990 | struct reg_field delay_0 = RT_P_CFG0_DELAY_0_FIELD(reg); | ||
991 | struct reg_field delay_1 = RT_P_CFG0_DELAY_1_FIELD(reg); | ||
992 | /* cfg1 */ | ||
993 | struct reg_field invertclk = RT_P_CFG1_INVERTCLK_FIELD(reg + 4); | ||
994 | struct reg_field retime = RT_P_CFG1_RETIME_FIELD(reg + 4); | ||
995 | struct reg_field clknotdata = RT_P_CFG1_CLKNOTDATA_FIELD(reg + 4); | ||
996 | struct reg_field double_edge = RT_P_CFG1_DOUBLE_EDGE_FIELD(reg + 4); | ||
997 | |||
998 | rt_p->clk1notclk0 = devm_regmap_field_alloc(dev, rm, clk1notclk0); | ||
999 | rt_p->delay_0 = devm_regmap_field_alloc(dev, rm, delay_0); | ||
1000 | rt_p->delay_1 = devm_regmap_field_alloc(dev, rm, delay_1); | ||
1001 | rt_p->invertclk = devm_regmap_field_alloc(dev, rm, invertclk); | ||
1002 | rt_p->retime = devm_regmap_field_alloc(dev, rm, retime); | ||
1003 | rt_p->clknotdata = devm_regmap_field_alloc(dev, rm, clknotdata); | ||
1004 | rt_p->double_edge = devm_regmap_field_alloc(dev, rm, double_edge); | ||
1005 | |||
1006 | if (IS_ERR(rt_p->clk1notclk0) || IS_ERR(rt_p->delay_0) || | ||
1007 | IS_ERR(rt_p->delay_1) || IS_ERR(rt_p->invertclk) || | ||
1008 | IS_ERR(rt_p->retime) || IS_ERR(rt_p->clknotdata) || | ||
1009 | IS_ERR(rt_p->double_edge)) | ||
1010 | return -EINVAL; | ||
1011 | |||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int st_pctl_dt_setup_retime_dedicated(struct st_pinctrl *info, | ||
1016 | int bank, struct st_pio_control *pc) | ||
1017 | { | ||
1018 | struct device *dev = info->dev; | ||
1019 | struct regmap *rm = info->regmap; | ||
1020 | const struct st_pctl_data *data = info->data; | ||
1021 | /* 8 registers per bank */ | ||
1022 | int reg_offset = (data->rt + bank * RT_D_CFGS_PER_BANK) * 4; | ||
1023 | struct st_retime_dedicated *rt_d = &pc->rt.rt_d; | ||
1024 | unsigned int j; | ||
1025 | u32 pin_mask = pc->rt_pin_mask; | ||
1026 | |||
1027 | for (j = 0; j < RT_D_CFGS_PER_BANK; j++) { | ||
1028 | if (BIT(j) & pin_mask) { | ||
1029 | struct reg_field reg = REG_FIELD(reg_offset, 0, 31); | ||
1030 | rt_d->rt[j] = devm_regmap_field_alloc(dev, rm, reg); | ||
1031 | if (IS_ERR(rt_d->rt[j])) | ||
1032 | return -EINVAL; | ||
1033 | reg_offset += 4; | ||
1034 | } | ||
1035 | } | ||
1036 | return 0; | ||
1037 | } | ||
1038 | |||
1039 | static int st_pctl_dt_setup_retime(struct st_pinctrl *info, | ||
1040 | int bank, struct st_pio_control *pc) | ||
1041 | { | ||
1042 | const struct st_pctl_data *data = info->data; | ||
1043 | if (data->rt_style == st_retime_style_packed) | ||
1044 | return st_pctl_dt_setup_retime_packed(info, bank, pc); | ||
1045 | else if (data->rt_style == st_retime_style_dedicated) | ||
1046 | return st_pctl_dt_setup_retime_dedicated(info, bank, pc); | ||
1047 | |||
1048 | return -EINVAL; | ||
1049 | } | ||
1050 | |||
1051 | static int st_parse_syscfgs(struct st_pinctrl *info, | ||
1052 | int bank, struct device_node *np) | ||
1053 | { | ||
1054 | const struct st_pctl_data *data = info->data; | ||
1055 | /** | ||
1056 | * For a given shared register like OE/PU/OD, there are 8 bits per bank | ||
1057 | * 0:7 belongs to bank0, 8:15 belongs to bank1 ... | ||
1058 | * So each register is shared across 4 banks. | ||
1059 | */ | ||
1060 | int lsb = (bank%4) * ST_GPIO_PINS_PER_BANK; | ||
1061 | int msb = lsb + ST_GPIO_PINS_PER_BANK - 1; | ||
1062 | struct reg_field alt_reg = REG_FIELD((data->alt + bank) * 4, 0, 31); | ||
1063 | struct reg_field oe_reg = REG_FIELD((data->oe + bank/4) * 4, lsb, msb); | ||
1064 | struct reg_field pu_reg = REG_FIELD((data->pu + bank/4) * 4, lsb, msb); | ||
1065 | struct reg_field od_reg = REG_FIELD((data->od + bank/4) * 4, lsb, msb); | ||
1066 | struct st_pio_control *pc = &info->banks[bank].pc; | ||
1067 | struct device *dev = info->dev; | ||
1068 | struct regmap *regmap = info->regmap; | ||
1069 | |||
1070 | pc->alt = devm_regmap_field_alloc(dev, regmap, alt_reg); | ||
1071 | pc->oe = devm_regmap_field_alloc(dev, regmap, oe_reg); | ||
1072 | pc->pu = devm_regmap_field_alloc(dev, regmap, pu_reg); | ||
1073 | pc->od = devm_regmap_field_alloc(dev, regmap, od_reg); | ||
1074 | |||
1075 | if (IS_ERR(pc->alt) || IS_ERR(pc->oe) || | ||
1076 | IS_ERR(pc->pu) || IS_ERR(pc->od)) | ||
1077 | return -EINVAL; | ||
1078 | |||
1079 | /* retime avaiable for all pins by default */ | ||
1080 | pc->rt_pin_mask = 0xff; | ||
1081 | of_property_read_u32(np, "st,retime-pin-mask", &pc->rt_pin_mask); | ||
1082 | st_pctl_dt_setup_retime(info, bank, pc); | ||
1083 | |||
1084 | return 0; | ||
1085 | } | ||
1086 | |||
1087 | /* | ||
1088 | * Each pin is represented in of the below forms. | ||
1089 | * <bank offset mux direction rt_type rt_delay rt_clk> | ||
1090 | */ | ||
1091 | static int st_pctl_dt_parse_groups(struct device_node *np, | ||
1092 | struct st_pctl_group *grp, struct st_pinctrl *info, int idx) | ||
1093 | { | ||
1094 | /* bank pad direction val altfunction */ | ||
1095 | const __be32 *list; | ||
1096 | struct property *pp; | ||
1097 | struct st_pinconf *conf; | ||
1098 | phandle phandle; | ||
1099 | struct device_node *pins; | ||
1100 | u32 pin; | ||
1101 | int i = 0, npins = 0, nr_props; | ||
1102 | |||
1103 | pins = of_get_child_by_name(np, "st,pins"); | ||
1104 | if (!pins) | ||
1105 | return -ENODATA; | ||
1106 | |||
1107 | for_each_property_of_node(pins, pp) { | ||
1108 | /* Skip those we do not want to proceed */ | ||
1109 | if (!strcmp(pp->name, "name")) | ||
1110 | continue; | ||
1111 | |||
1112 | if (pp && (pp->length/sizeof(__be32)) >= OF_GPIO_ARGS_MIN) { | ||
1113 | npins++; | ||
1114 | } else { | ||
1115 | pr_warn("Invalid st,pins in %s node\n", np->name); | ||
1116 | return -EINVAL; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | grp->npins = npins; | ||
1121 | grp->name = np->name; | ||
1122 | grp->pins = devm_kzalloc(info->dev, npins * sizeof(u32), GFP_KERNEL); | ||
1123 | grp->pin_conf = devm_kzalloc(info->dev, | ||
1124 | npins * sizeof(*conf), GFP_KERNEL); | ||
1125 | |||
1126 | if (!grp->pins || !grp->pin_conf) | ||
1127 | return -ENOMEM; | ||
1128 | |||
1129 | /* <bank offset mux direction rt_type rt_delay rt_clk> */ | ||
1130 | for_each_property_of_node(pins, pp) { | ||
1131 | if (!strcmp(pp->name, "name")) | ||
1132 | continue; | ||
1133 | nr_props = pp->length/sizeof(u32); | ||
1134 | list = pp->value; | ||
1135 | conf = &grp->pin_conf[i]; | ||
1136 | |||
1137 | /* bank & offset */ | ||
1138 | phandle = be32_to_cpup(list++); | ||
1139 | pin = be32_to_cpup(list++); | ||
1140 | conf->pin = of_get_named_gpio(pins, pp->name, 0); | ||
1141 | conf->name = pp->name; | ||
1142 | grp->pins[i] = conf->pin; | ||
1143 | /* mux */ | ||
1144 | conf->altfunc = be32_to_cpup(list++); | ||
1145 | conf->config = 0; | ||
1146 | /* direction */ | ||
1147 | conf->config |= be32_to_cpup(list++); | ||
1148 | /* rt_type rt_delay rt_clk */ | ||
1149 | if (nr_props >= OF_GPIO_ARGS_MIN + OF_RT_ARGS_MIN) { | ||
1150 | /* rt_type */ | ||
1151 | conf->config |= be32_to_cpup(list++); | ||
1152 | /* rt_delay */ | ||
1153 | conf->config |= be32_to_cpup(list++); | ||
1154 | /* rt_clk */ | ||
1155 | if (nr_props > OF_GPIO_ARGS_MIN + OF_RT_ARGS_MIN) | ||
1156 | conf->config |= be32_to_cpup(list++); | ||
1157 | } | ||
1158 | i++; | ||
1159 | } | ||
1160 | of_node_put(pins); | ||
1161 | |||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | static int st_pctl_parse_functions(struct device_node *np, | ||
1166 | struct st_pinctrl *info, u32 index, int *grp_index) | ||
1167 | { | ||
1168 | struct device_node *child; | ||
1169 | struct st_pmx_func *func; | ||
1170 | struct st_pctl_group *grp; | ||
1171 | int ret, i; | ||
1172 | |||
1173 | func = &info->functions[index]; | ||
1174 | func->name = np->name; | ||
1175 | func->ngroups = of_get_child_count(np); | ||
1176 | if (func->ngroups <= 0) { | ||
1177 | dev_err(info->dev, "No groups defined\n"); | ||
1178 | return -EINVAL; | ||
1179 | } | ||
1180 | func->groups = devm_kzalloc(info->dev, | ||
1181 | func->ngroups * sizeof(char *), GFP_KERNEL); | ||
1182 | if (!func->groups) | ||
1183 | return -ENOMEM; | ||
1184 | |||
1185 | i = 0; | ||
1186 | for_each_child_of_node(np, child) { | ||
1187 | func->groups[i] = child->name; | ||
1188 | grp = &info->groups[*grp_index]; | ||
1189 | *grp_index += 1; | ||
1190 | ret = st_pctl_dt_parse_groups(child, grp, info, i++); | ||
1191 | if (ret) | ||
1192 | return ret; | ||
1193 | } | ||
1194 | dev_info(info->dev, "Function[%d\t name:%s,\tgroups:%d]\n", | ||
1195 | index, func->name, func->ngroups); | ||
1196 | |||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | static struct gpio_chip st_gpio_template = { | ||
1201 | .request = st_gpio_request, | ||
1202 | .free = st_gpio_free, | ||
1203 | .get = st_gpio_get, | ||
1204 | .set = st_gpio_set, | ||
1205 | .direction_input = st_gpio_direction_input, | ||
1206 | .direction_output = st_gpio_direction_output, | ||
1207 | .ngpio = ST_GPIO_PINS_PER_BANK, | ||
1208 | .of_gpio_n_cells = 1, | ||
1209 | .of_xlate = st_gpio_xlate, | ||
1210 | }; | ||
1211 | |||
1212 | static int st_gpiolib_register_bank(struct st_pinctrl *info, | ||
1213 | int bank_nr, struct device_node *np) | ||
1214 | { | ||
1215 | struct st_gpio_bank *bank = &info->banks[bank_nr]; | ||
1216 | struct pinctrl_gpio_range *range = &bank->range; | ||
1217 | struct device *dev = info->dev; | ||
1218 | int bank_num = of_alias_get_id(np, "gpio"); | ||
1219 | struct resource res; | ||
1220 | int err; | ||
1221 | |||
1222 | if (of_address_to_resource(np, 0, &res)) | ||
1223 | return -ENODEV; | ||
1224 | |||
1225 | bank->base = devm_request_and_ioremap(dev, &res); | ||
1226 | if (!bank->base) { | ||
1227 | dev_err(dev, "Can't get IO memory mapping!\n"); | ||
1228 | return -ENODEV; | ||
1229 | } | ||
1230 | |||
1231 | bank->gpio_chip = st_gpio_template; | ||
1232 | bank->gpio_chip.base = bank_num * ST_GPIO_PINS_PER_BANK; | ||
1233 | bank->gpio_chip.ngpio = ST_GPIO_PINS_PER_BANK; | ||
1234 | bank->gpio_chip.of_node = np; | ||
1235 | |||
1236 | of_property_read_string(np, "st,bank-name", &range->name); | ||
1237 | bank->gpio_chip.label = range->name; | ||
1238 | |||
1239 | range->id = bank_num; | ||
1240 | range->pin_base = range->base = range->id * ST_GPIO_PINS_PER_BANK; | ||
1241 | range->npins = bank->gpio_chip.ngpio; | ||
1242 | range->gc = &bank->gpio_chip; | ||
1243 | err = gpiochip_add(&bank->gpio_chip); | ||
1244 | if (err) { | ||
1245 | dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_num); | ||
1246 | return err; | ||
1247 | } | ||
1248 | dev_info(dev, "%s bank added.\n", range->name); | ||
1249 | |||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1253 | static struct of_device_id st_pctl_of_match[] = { | ||
1254 | { .compatible = "st,stih415-sbc-pinctrl", .data = &stih415_sbc_data }, | ||
1255 | { .compatible = "st,stih415-rear-pinctrl", .data = &stih415_rear_data }, | ||
1256 | { .compatible = "st,stih415-left-pinctrl", .data = &stih415_left_data }, | ||
1257 | { .compatible = "st,stih415-right-pinctrl", | ||
1258 | .data = &stih415_right_data }, | ||
1259 | { .compatible = "st,stih415-front-pinctrl", | ||
1260 | .data = &stih415_front_data }, | ||
1261 | { .compatible = "st,stih416-sbc-pinctrl", .data = &stih416_data}, | ||
1262 | { .compatible = "st,stih416-front-pinctrl", .data = &stih416_data}, | ||
1263 | { .compatible = "st,stih416-rear-pinctrl", .data = &stih416_data}, | ||
1264 | { .compatible = "st,stih416-fvdp-fe-pinctrl", .data = &stih416_data}, | ||
1265 | { .compatible = "st,stih416-fvdp-lite-pinctrl", .data = &stih416_data}, | ||
1266 | { /* sentinel */ } | ||
1267 | }; | ||
1268 | |||
1269 | static int st_pctl_probe_dt(struct platform_device *pdev, | ||
1270 | struct pinctrl_desc *pctl_desc, struct st_pinctrl *info) | ||
1271 | { | ||
1272 | int ret = 0; | ||
1273 | int i = 0, j = 0, k = 0, bank; | ||
1274 | struct pinctrl_pin_desc *pdesc; | ||
1275 | struct device_node *np = pdev->dev.of_node; | ||
1276 | struct device_node *child; | ||
1277 | int grp_index = 0; | ||
1278 | |||
1279 | st_pctl_dt_child_count(info, np); | ||
1280 | if (!info->nbanks) { | ||
1281 | dev_err(&pdev->dev, "you need atleast one gpio bank\n"); | ||
1282 | return -EINVAL; | ||
1283 | } | ||
1284 | |||
1285 | dev_info(&pdev->dev, "nbanks = %d\n", info->nbanks); | ||
1286 | dev_info(&pdev->dev, "nfunctions = %d\n", info->nfunctions); | ||
1287 | dev_info(&pdev->dev, "ngroups = %d\n", info->ngroups); | ||
1288 | |||
1289 | info->functions = devm_kzalloc(&pdev->dev, | ||
1290 | info->nfunctions * sizeof(*info->functions), GFP_KERNEL); | ||
1291 | |||
1292 | info->groups = devm_kzalloc(&pdev->dev, | ||
1293 | info->ngroups * sizeof(*info->groups) , GFP_KERNEL); | ||
1294 | |||
1295 | info->banks = devm_kzalloc(&pdev->dev, | ||
1296 | info->nbanks * sizeof(*info->banks), GFP_KERNEL); | ||
1297 | |||
1298 | if (!info->functions || !info->groups || !info->banks) | ||
1299 | return -ENOMEM; | ||
1300 | |||
1301 | info->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); | ||
1302 | if (IS_ERR(info->regmap)) { | ||
1303 | dev_err(info->dev, "No syscfg phandle specified\n"); | ||
1304 | return PTR_ERR(info->regmap); | ||
1305 | } | ||
1306 | info->data = of_match_node(st_pctl_of_match, np)->data; | ||
1307 | |||
1308 | pctl_desc->npins = info->nbanks * ST_GPIO_PINS_PER_BANK; | ||
1309 | pdesc = devm_kzalloc(&pdev->dev, | ||
1310 | sizeof(*pdesc) * pctl_desc->npins, GFP_KERNEL); | ||
1311 | if (!pdesc) | ||
1312 | return -ENOMEM; | ||
1313 | |||
1314 | pctl_desc->pins = pdesc; | ||
1315 | |||
1316 | bank = 0; | ||
1317 | for_each_child_of_node(np, child) { | ||
1318 | if (of_property_read_bool(child, "gpio-controller")) { | ||
1319 | const char *bank_name = NULL; | ||
1320 | ret = st_gpiolib_register_bank(info, bank, child); | ||
1321 | if (ret) | ||
1322 | return ret; | ||
1323 | |||
1324 | k = info->banks[bank].range.pin_base; | ||
1325 | bank_name = info->banks[bank].range.name; | ||
1326 | for (j = 0; j < ST_GPIO_PINS_PER_BANK; j++, k++) { | ||
1327 | pdesc->number = k; | ||
1328 | pdesc->name = kasprintf(GFP_KERNEL, "%s[%d]", | ||
1329 | bank_name, j); | ||
1330 | pdesc++; | ||
1331 | } | ||
1332 | st_parse_syscfgs(info, bank, child); | ||
1333 | bank++; | ||
1334 | } else { | ||
1335 | ret = st_pctl_parse_functions(child, info, | ||
1336 | i++, &grp_index); | ||
1337 | if (ret) { | ||
1338 | dev_err(&pdev->dev, "No functions found.\n"); | ||
1339 | return ret; | ||
1340 | } | ||
1341 | } | ||
1342 | } | ||
1343 | |||
1344 | return 0; | ||
1345 | } | ||
1346 | |||
1347 | static int st_pctl_probe(struct platform_device *pdev) | ||
1348 | { | ||
1349 | struct st_pinctrl *info; | ||
1350 | struct pinctrl_desc *pctl_desc; | ||
1351 | int ret, i; | ||
1352 | |||
1353 | if (!pdev->dev.of_node) { | ||
1354 | dev_err(&pdev->dev, "device node not found.\n"); | ||
1355 | return -EINVAL; | ||
1356 | } | ||
1357 | |||
1358 | pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL); | ||
1359 | if (!pctl_desc) | ||
1360 | return -ENOMEM; | ||
1361 | |||
1362 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
1363 | if (!info) | ||
1364 | return -ENOMEM; | ||
1365 | |||
1366 | info->dev = &pdev->dev; | ||
1367 | platform_set_drvdata(pdev, info); | ||
1368 | ret = st_pctl_probe_dt(pdev, pctl_desc, info); | ||
1369 | if (ret) | ||
1370 | return ret; | ||
1371 | |||
1372 | pctl_desc->owner = THIS_MODULE, | ||
1373 | pctl_desc->pctlops = &st_pctlops, | ||
1374 | pctl_desc->pmxops = &st_pmxops, | ||
1375 | pctl_desc->confops = &st_confops, | ||
1376 | pctl_desc->name = dev_name(&pdev->dev); | ||
1377 | |||
1378 | info->pctl = pinctrl_register(pctl_desc, &pdev->dev, info); | ||
1379 | if (!info->pctl) { | ||
1380 | dev_err(&pdev->dev, "Failed pinctrl registration\n"); | ||
1381 | return -EINVAL; | ||
1382 | } | ||
1383 | |||
1384 | for (i = 0; i < info->nbanks; i++) | ||
1385 | pinctrl_add_gpio_range(info->pctl, &info->banks[i].range); | ||
1386 | |||
1387 | return 0; | ||
1388 | } | ||
1389 | |||
1390 | static struct platform_driver st_pctl_driver = { | ||
1391 | .driver = { | ||
1392 | .name = "st-pinctrl", | ||
1393 | .owner = THIS_MODULE, | ||
1394 | .of_match_table = st_pctl_of_match, | ||
1395 | }, | ||
1396 | .probe = st_pctl_probe, | ||
1397 | }; | ||
1398 | |||
1399 | static int __init st_pctl_init(void) | ||
1400 | { | ||
1401 | return platform_driver_register(&st_pctl_driver); | ||
1402 | } | ||
1403 | arch_initcall(st_pctl_init); | ||
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 02d84e24b7c2..75981d0b57dc 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -23,6 +23,7 @@ struct irq_domain; | |||
23 | struct spi_device; | 23 | struct spi_device; |
24 | struct regmap; | 24 | struct regmap; |
25 | struct regmap_range_cfg; | 25 | struct regmap_range_cfg; |
26 | struct regmap_field; | ||
26 | 27 | ||
27 | /* An enum of all the supported cache types */ | 28 | /* An enum of all the supported cache types */ |
28 | enum regcache_type { | 29 | enum regcache_type { |
@@ -394,10 +395,15 @@ bool regmap_can_raw_write(struct regmap *map); | |||
394 | int regcache_sync(struct regmap *map); | 395 | int regcache_sync(struct regmap *map); |
395 | int regcache_sync_region(struct regmap *map, unsigned int min, | 396 | int regcache_sync_region(struct regmap *map, unsigned int min, |
396 | unsigned int max); | 397 | unsigned int max); |
398 | int regcache_drop_region(struct regmap *map, unsigned int min, | ||
399 | unsigned int max); | ||
397 | void regcache_cache_only(struct regmap *map, bool enable); | 400 | void regcache_cache_only(struct regmap *map, bool enable); |
398 | void regcache_cache_bypass(struct regmap *map, bool enable); | 401 | void regcache_cache_bypass(struct regmap *map, bool enable); |
399 | void regcache_mark_dirty(struct regmap *map); | 402 | void regcache_mark_dirty(struct regmap *map); |
400 | 403 | ||
404 | bool regmap_check_range_table(struct regmap *map, unsigned int reg, | ||
405 | const struct regmap_access_table *table); | ||
406 | |||
401 | int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | 407 | int regmap_register_patch(struct regmap *map, const struct reg_default *regs, |
402 | int num_regs); | 408 | int num_regs); |
403 | 409 | ||
@@ -412,6 +418,36 @@ bool regmap_reg_in_ranges(unsigned int reg, | |||
412 | unsigned int nranges); | 418 | unsigned int nranges); |
413 | 419 | ||
414 | /** | 420 | /** |
421 | * Description of an register field | ||
422 | * | ||
423 | * @reg: Offset of the register within the regmap bank | ||
424 | * @lsb: lsb of the register field. | ||
425 | * @reg: msb of the register field. | ||
426 | */ | ||
427 | struct reg_field { | ||
428 | unsigned int reg; | ||
429 | unsigned int lsb; | ||
430 | unsigned int msb; | ||
431 | }; | ||
432 | |||
433 | #define REG_FIELD(_reg, _lsb, _msb) { \ | ||
434 | .reg = _reg, \ | ||
435 | .lsb = _lsb, \ | ||
436 | .msb = _msb, \ | ||
437 | } | ||
438 | |||
439 | struct regmap_field *regmap_field_alloc(struct regmap *regmap, | ||
440 | struct reg_field reg_field); | ||
441 | void regmap_field_free(struct regmap_field *field); | ||
442 | |||
443 | struct regmap_field *devm_regmap_field_alloc(struct device *dev, | ||
444 | struct regmap *regmap, struct reg_field reg_field); | ||
445 | void devm_regmap_field_free(struct device *dev, struct regmap_field *field); | ||
446 | |||
447 | int regmap_field_read(struct regmap_field *field, unsigned int *val); | ||
448 | int regmap_field_write(struct regmap_field *field, unsigned int val); | ||
449 | |||
450 | /** | ||
415 | * Description of an IRQ for the generic regmap irq_chip. | 451 | * Description of an IRQ for the generic regmap irq_chip. |
416 | * | 452 | * |
417 | * @reg_offset: Offset of the status/mask register within the bank | 453 | * @reg_offset: Offset of the status/mask register within the bank |
@@ -562,6 +598,13 @@ static inline int regcache_sync_region(struct regmap *map, unsigned int min, | |||
562 | return -EINVAL; | 598 | return -EINVAL; |
563 | } | 599 | } |
564 | 600 | ||
601 | static inline int regcache_drop_region(struct regmap *map, unsigned int min, | ||
602 | unsigned int max) | ||
603 | { | ||
604 | WARN_ONCE(1, "regmap API is disabled"); | ||
605 | return -EINVAL; | ||
606 | } | ||
607 | |||
565 | static inline void regcache_cache_only(struct regmap *map, bool enable) | 608 | static inline void regcache_cache_only(struct regmap *map, bool enable) |
566 | { | 609 | { |
567 | WARN_ONCE(1, "regmap API is disabled"); | 610 | WARN_ONCE(1, "regmap API is disabled"); |
diff --git a/include/trace/events/regmap.h b/include/trace/events/regmap.h index a43a2f67bd8e..23d561512f64 100644 --- a/include/trace/events/regmap.h +++ b/include/trace/events/regmap.h | |||
@@ -223,6 +223,29 @@ DEFINE_EVENT(regmap_async, regmap_async_complete_done, | |||
223 | 223 | ||
224 | ); | 224 | ); |
225 | 225 | ||
226 | TRACE_EVENT(regcache_drop_region, | ||
227 | |||
228 | TP_PROTO(struct device *dev, unsigned int from, | ||
229 | unsigned int to), | ||
230 | |||
231 | TP_ARGS(dev, from, to), | ||
232 | |||
233 | TP_STRUCT__entry( | ||
234 | __string( name, dev_name(dev) ) | ||
235 | __field( unsigned int, from ) | ||
236 | __field( unsigned int, to ) | ||
237 | ), | ||
238 | |||
239 | TP_fast_assign( | ||
240 | __assign_str(name, dev_name(dev)); | ||
241 | __entry->from = from; | ||
242 | __entry->to = to; | ||
243 | ), | ||
244 | |||
245 | TP_printk("%s %u-%u", __get_str(name), (unsigned int)__entry->from, | ||
246 | (unsigned int)__entry->to) | ||
247 | ); | ||
248 | |||
226 | #endif /* _TRACE_REGMAP_H */ | 249 | #endif /* _TRACE_REGMAP_H */ |
227 | 250 | ||
228 | /* This part must be outside protection */ | 251 | /* This part must be outside protection */ |