diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/Makefile | 2 | ||||
-rw-r--r-- | drivers/base/bus.c | 9 | ||||
-rw-r--r-- | drivers/base/core.c | 17 | ||||
-rw-r--r-- | drivers/base/cpu.c | 21 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 3 | ||||
-rw-r--r-- | drivers/base/memory.c | 31 | ||||
-rw-r--r-- | drivers/base/node.c | 8 | ||||
-rw-r--r-- | drivers/base/regmap/internal.h | 9 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-lzo.c | 6 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-rbtree.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 20 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-debugfs.c | 84 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-i2c.c | 17 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-spi.c | 17 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 161 | ||||
-rw-r--r-- | drivers/base/sys.c | 383 |
16 files changed, 361 insertions, 429 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 2c8272dd93c4..610f9997a403 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # Makefile for the Linux device tree | 1 | # Makefile for the Linux device tree |
2 | 2 | ||
3 | obj-y := core.o sys.o bus.o dd.o syscore.o \ | 3 | obj-y := core.o bus.o dd.o syscore.o \ |
4 | driver.o class.o platform.o \ | 4 | driver.o class.o platform.o \ |
5 | cpu.o firmware.o init.o map.o devres.o \ | 5 | cpu.o firmware.o init.o map.o devres.o \ |
6 | attribute_container.o transport_class.o \ | 6 | attribute_container.o transport_class.o \ |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 99dc5921e1dd..40fb12288ce2 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -915,9 +915,10 @@ static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | |||
915 | 915 | ||
916 | /** | 916 | /** |
917 | * __bus_register - register a driver-core subsystem | 917 | * __bus_register - register a driver-core subsystem |
918 | * @bus: bus. | 918 | * @bus: bus to register |
919 | * @key: lockdep class key | ||
919 | * | 920 | * |
920 | * Once we have that, we registered the bus with the kobject | 921 | * Once we have that, we register the bus with the kobject |
921 | * infrastructure, then register the children subsystems it has: | 922 | * infrastructure, then register the children subsystems it has: |
922 | * the devices and drivers that belong to the subsystem. | 923 | * the devices and drivers that belong to the subsystem. |
923 | */ | 924 | */ |
@@ -1220,8 +1221,8 @@ static void system_root_device_release(struct device *dev) | |||
1220 | } | 1221 | } |
1221 | /** | 1222 | /** |
1222 | * subsys_system_register - register a subsystem at /sys/devices/system/ | 1223 | * subsys_system_register - register a subsystem at /sys/devices/system/ |
1223 | * @subsys - system subsystem | 1224 | * @subsys: system subsystem |
1224 | * @groups - default attributes for the root device | 1225 | * @groups: default attributes for the root device |
1225 | * | 1226 | * |
1226 | * All 'system' subsystems have a /sys/devices/system/<name> root device | 1227 | * All 'system' subsystems have a /sys/devices/system/<name> root device |
1227 | * with the name of the subsystem. The root device can carry subsystem- | 1228 | * with the name of the subsystem. The root device can carry subsystem- |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 4a67cc0c8b37..74dda4f697f9 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -632,6 +632,11 @@ static void klist_children_put(struct klist_node *n) | |||
632 | * may be used for reference counting of @dev after calling this | 632 | * may be used for reference counting of @dev after calling this |
633 | * function. | 633 | * function. |
634 | * | 634 | * |
635 | * All fields in @dev must be initialized by the caller to 0, except | ||
636 | * for those explicitly set to some other value. The simplest | ||
637 | * approach is to use kzalloc() to allocate the structure containing | ||
638 | * @dev. | ||
639 | * | ||
635 | * NOTE: Use put_device() to give up your reference instead of freeing | 640 | * NOTE: Use put_device() to give up your reference instead of freeing |
636 | * @dev directly once you have called this function. | 641 | * @dev directly once you have called this function. |
637 | */ | 642 | */ |
@@ -930,6 +935,13 @@ int device_private_init(struct device *dev) | |||
930 | * to the global and sibling lists for the device, then | 935 | * to the global and sibling lists for the device, then |
931 | * adds it to the other relevant subsystems of the driver model. | 936 | * adds it to the other relevant subsystems of the driver model. |
932 | * | 937 | * |
938 | * Do not call this routine or device_register() more than once for | ||
939 | * any device structure. The driver model core is not designed to work | ||
940 | * with devices that get unregistered and then spring back to life. | ||
941 | * (Among other things, it's very hard to guarantee that all references | ||
942 | * to the previous incarnation of @dev have been dropped.) Allocate | ||
943 | * and register a fresh new struct device instead. | ||
944 | * | ||
933 | * NOTE: _Never_ directly free @dev after calling this function, even | 945 | * NOTE: _Never_ directly free @dev after calling this function, even |
934 | * if it returned an error! Always use put_device() to give up your | 946 | * if it returned an error! Always use put_device() to give up your |
935 | * reference instead. | 947 | * reference instead. |
@@ -1022,7 +1034,7 @@ int device_add(struct device *dev) | |||
1022 | device_pm_add(dev); | 1034 | device_pm_add(dev); |
1023 | 1035 | ||
1024 | /* Notify clients of device addition. This call must come | 1036 | /* Notify clients of device addition. This call must come |
1025 | * after dpm_sysf_add() and before kobject_uevent(). | 1037 | * after dpm_sysfs_add() and before kobject_uevent(). |
1026 | */ | 1038 | */ |
1027 | if (dev->bus) | 1039 | if (dev->bus) |
1028 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 1040 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
@@ -1090,6 +1102,9 @@ name_error: | |||
1090 | * have a clearly defined need to use and refcount the device | 1102 | * have a clearly defined need to use and refcount the device |
1091 | * before it is added to the hierarchy. | 1103 | * before it is added to the hierarchy. |
1092 | * | 1104 | * |
1105 | * For more information, see the kerneldoc for device_initialize() | ||
1106 | * and device_add(). | ||
1107 | * | ||
1093 | * NOTE: _Never_ directly free @dev after calling this function, even | 1108 | * NOTE: _Never_ directly free @dev after calling this function, even |
1094 | * if it returned an error! Always use put_device() to give up the | 1109 | * if it returned an error! Always use put_device() to give up the |
1095 | * reference initialized in this function instead. | 1110 | * reference initialized in this function instead. |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index db87e78d7459..4dabf5077c48 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -208,6 +208,25 @@ static ssize_t print_cpus_offline(struct device *dev, | |||
208 | } | 208 | } |
209 | static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); | 209 | static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); |
210 | 210 | ||
211 | static void cpu_device_release(struct device *dev) | ||
212 | { | ||
213 | /* | ||
214 | * This is an empty function to prevent the driver core from spitting a | ||
215 | * warning at us. Yes, I know this is directly opposite of what the | ||
216 | * documentation for the driver core and kobjects say, and the author | ||
217 | * of this code has already been publically ridiculed for doing | ||
218 | * something as foolish as this. However, at this point in time, it is | ||
219 | * the only way to handle the issue of statically allocated cpu | ||
220 | * devices. The different architectures will have their cpu device | ||
221 | * code reworked to properly handle this in the near future, so this | ||
222 | * function will then be changed to correctly free up the memory held | ||
223 | * by the cpu device. | ||
224 | * | ||
225 | * Never copy this way of doing things, or you too will be made fun of | ||
226 | * on the linux-kerenl list, you have been warned. | ||
227 | */ | ||
228 | } | ||
229 | |||
211 | /* | 230 | /* |
212 | * register_cpu - Setup a sysfs device for a CPU. | 231 | * register_cpu - Setup a sysfs device for a CPU. |
213 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in | 232 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in |
@@ -221,8 +240,10 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) | |||
221 | int error; | 240 | int error; |
222 | 241 | ||
223 | cpu->node_id = cpu_to_node(num); | 242 | cpu->node_id = cpu_to_node(num); |
243 | memset(&cpu->dev, 0x00, sizeof(struct device)); | ||
224 | cpu->dev.id = num; | 244 | cpu->dev.id = num; |
225 | cpu->dev.bus = &cpu_subsys; | 245 | cpu->dev.bus = &cpu_subsys; |
246 | cpu->dev.release = cpu_device_release; | ||
226 | error = device_register(&cpu->dev); | 247 | error = device_register(&cpu->dev); |
227 | if (!error && cpu->hotpluggable) | 248 | if (!error && cpu->hotpluggable) |
228 | register_cpu_control(cpu); | 249 | register_cpu_control(cpu); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 26ab358dac62..6c9387d646ec 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -525,8 +525,7 @@ static int _request_firmware(const struct firmware **firmware_p, | |||
525 | if (!firmware) { | 525 | if (!firmware) { |
526 | dev_err(device, "%s: kmalloc(struct firmware) failed\n", | 526 | dev_err(device, "%s: kmalloc(struct firmware) failed\n", |
527 | __func__); | 527 | __func__); |
528 | retval = -ENOMEM; | 528 | return -ENOMEM; |
529 | goto out; | ||
530 | } | 529 | } |
531 | 530 | ||
532 | if (fw_get_builtin_firmware(firmware, name)) { | 531 | if (fw_get_builtin_firmware(firmware, name)) { |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index ed5de58c340f..9e60dbe9fd94 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -572,19 +572,36 @@ static int init_memory_block(struct memory_block **memory, | |||
572 | } | 572 | } |
573 | 573 | ||
574 | static int add_memory_section(int nid, struct mem_section *section, | 574 | static int add_memory_section(int nid, struct mem_section *section, |
575 | struct memory_block **mem_p, | ||
575 | unsigned long state, enum mem_add_context context) | 576 | unsigned long state, enum mem_add_context context) |
576 | { | 577 | { |
577 | struct memory_block *mem; | 578 | struct memory_block *mem = NULL; |
579 | int scn_nr = __section_nr(section); | ||
578 | int ret = 0; | 580 | int ret = 0; |
579 | 581 | ||
580 | mutex_lock(&mem_sysfs_mutex); | 582 | mutex_lock(&mem_sysfs_mutex); |
581 | 583 | ||
582 | mem = find_memory_block(section); | 584 | if (context == BOOT) { |
585 | /* same memory block ? */ | ||
586 | if (mem_p && *mem_p) | ||
587 | if (scn_nr >= (*mem_p)->start_section_nr && | ||
588 | scn_nr <= (*mem_p)->end_section_nr) { | ||
589 | mem = *mem_p; | ||
590 | kobject_get(&mem->dev.kobj); | ||
591 | } | ||
592 | } else | ||
593 | mem = find_memory_block(section); | ||
594 | |||
583 | if (mem) { | 595 | if (mem) { |
584 | mem->section_count++; | 596 | mem->section_count++; |
585 | kobject_put(&mem->dev.kobj); | 597 | kobject_put(&mem->dev.kobj); |
586 | } else | 598 | } else { |
587 | ret = init_memory_block(&mem, section, state); | 599 | ret = init_memory_block(&mem, section, state); |
600 | /* store memory_block pointer for next loop */ | ||
601 | if (!ret && context == BOOT) | ||
602 | if (mem_p) | ||
603 | *mem_p = mem; | ||
604 | } | ||
588 | 605 | ||
589 | if (!ret) { | 606 | if (!ret) { |
590 | if (context == HOTPLUG && | 607 | if (context == HOTPLUG && |
@@ -627,7 +644,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, | |||
627 | */ | 644 | */ |
628 | int register_new_memory(int nid, struct mem_section *section) | 645 | int register_new_memory(int nid, struct mem_section *section) |
629 | { | 646 | { |
630 | return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); | 647 | return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG); |
631 | } | 648 | } |
632 | 649 | ||
633 | int unregister_memory_section(struct mem_section *section) | 650 | int unregister_memory_section(struct mem_section *section) |
@@ -647,6 +664,7 @@ int __init memory_dev_init(void) | |||
647 | int ret; | 664 | int ret; |
648 | int err; | 665 | int err; |
649 | unsigned long block_sz; | 666 | unsigned long block_sz; |
667 | struct memory_block *mem = NULL; | ||
650 | 668 | ||
651 | ret = subsys_system_register(&memory_subsys, NULL); | 669 | ret = subsys_system_register(&memory_subsys, NULL); |
652 | if (ret) | 670 | if (ret) |
@@ -662,7 +680,10 @@ int __init memory_dev_init(void) | |||
662 | for (i = 0; i < NR_MEM_SECTIONS; i++) { | 680 | for (i = 0; i < NR_MEM_SECTIONS; i++) { |
663 | if (!present_section_nr(i)) | 681 | if (!present_section_nr(i)) |
664 | continue; | 682 | continue; |
665 | err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, | 683 | /* don't need to reuse memory_block if only one per block */ |
684 | err = add_memory_section(0, __nr_to_section(i), | ||
685 | (sections_per_block == 1) ? NULL : &mem, | ||
686 | MEM_ONLINE, | ||
666 | BOOT); | 687 | BOOT); |
667 | if (!ret) | 688 | if (!ret) |
668 | ret = err; | 689 | ret = err; |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 44f427a66117..90aa2a11a933 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -456,7 +456,15 @@ static int link_mem_sections(int nid) | |||
456 | if (!present_section_nr(section_nr)) | 456 | if (!present_section_nr(section_nr)) |
457 | continue; | 457 | continue; |
458 | mem_sect = __nr_to_section(section_nr); | 458 | mem_sect = __nr_to_section(section_nr); |
459 | |||
460 | /* same memblock ? */ | ||
461 | if (mem_blk) | ||
462 | if ((section_nr >= mem_blk->start_section_nr) && | ||
463 | (section_nr <= mem_blk->end_section_nr)) | ||
464 | continue; | ||
465 | |||
459 | mem_blk = find_memory_block_hinted(mem_sect, mem_blk); | 466 | mem_blk = find_memory_block_hinted(mem_sect, mem_blk); |
467 | |||
460 | ret = register_mem_sect_under_node(mem_blk, nid); | 468 | ret = register_mem_sect_under_node(mem_blk, nid); |
461 | if (!err) | 469 | if (!err) |
462 | err = ret; | 470 | err = ret; |
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 9c1d62e3e15c..fcafc5b2e651 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -22,6 +22,7 @@ struct regcache_ops; | |||
22 | struct regmap_format { | 22 | struct regmap_format { |
23 | size_t buf_size; | 23 | size_t buf_size; |
24 | size_t reg_bytes; | 24 | size_t reg_bytes; |
25 | size_t pad_bytes; | ||
25 | size_t val_bytes; | 26 | size_t val_bytes; |
26 | void (*format_write)(struct regmap *map, | 27 | void (*format_write)(struct regmap *map, |
27 | unsigned int reg, unsigned int val); | 28 | unsigned int reg, unsigned int val); |
@@ -65,16 +66,16 @@ struct regmap { | |||
65 | unsigned int num_reg_defaults_raw; | 66 | unsigned int num_reg_defaults_raw; |
66 | 67 | ||
67 | /* if set, only the cache is modified not the HW */ | 68 | /* if set, only the cache is modified not the HW */ |
68 | unsigned int cache_only:1; | 69 | u32 cache_only; |
69 | /* if set, only the HW is modified not the cache */ | 70 | /* if set, only the HW is modified not the cache */ |
70 | unsigned int cache_bypass:1; | 71 | u32 cache_bypass; |
71 | /* if set, remember to free reg_defaults_raw */ | 72 | /* if set, remember to free reg_defaults_raw */ |
72 | unsigned int cache_free:1; | 73 | bool cache_free; |
73 | 74 | ||
74 | struct reg_default *reg_defaults; | 75 | struct reg_default *reg_defaults; |
75 | const void *reg_defaults_raw; | 76 | const void *reg_defaults_raw; |
76 | void *cache; | 77 | void *cache; |
77 | bool cache_dirty; | 78 | u32 cache_dirty; |
78 | 79 | ||
79 | struct reg_default *patch; | 80 | struct reg_default *patch; |
80 | int patch_regs; | 81 | int patch_regs; |
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c index f0f04060a4ec..8d0061569326 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c | |||
@@ -349,6 +349,12 @@ static int regcache_lzo_sync(struct regmap *map, unsigned int min, | |||
349 | ret = regcache_read(map, i, &val); | 349 | ret = regcache_read(map, i, &val); |
350 | if (ret) | 350 | if (ret) |
351 | return ret; | 351 | return ret; |
352 | |||
353 | /* Is this the hardware default? If so skip. */ | ||
354 | ret = regcache_lookup_reg(map, i); | ||
355 | if (ret > 0 && val == map->reg_defaults[ret].def) | ||
356 | continue; | ||
357 | |||
352 | map->cache_bypass = 1; | 358 | map->cache_bypass = 1; |
353 | ret = _regmap_write(map, i, val); | 359 | ret = _regmap_write(map, i, val); |
354 | map->cache_bypass = 0; | 360 | map->cache_bypass = 0; |
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 313c20f8cc28..8d51916a283d 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c | |||
@@ -396,7 +396,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, | |||
396 | 396 | ||
397 | /* Is this the hardware default? If so skip. */ | 397 | /* Is this the hardware default? If so skip. */ |
398 | ret = regcache_lookup_reg(map, i); | 398 | ret = regcache_lookup_reg(map, i); |
399 | if (ret > 0 && val == map->reg_defaults[ret].def) | 399 | if (ret >= 0 && val == map->reg_defaults[ret].def) |
400 | continue; | 400 | continue; |
401 | 401 | ||
402 | map->cache_bypass = 1; | 402 | map->cache_bypass = 1; |
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index b35f8751471d..fb84d711fbb4 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
@@ -53,7 +53,7 @@ static int regcache_hw_init(struct regmap *map) | |||
53 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { | 53 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { |
54 | val = regcache_get_val(map->reg_defaults_raw, | 54 | val = regcache_get_val(map->reg_defaults_raw, |
55 | i, map->cache_word_size); | 55 | i, map->cache_word_size); |
56 | if (!val) | 56 | if (regmap_volatile(map, i)) |
57 | continue; | 57 | continue; |
58 | count++; | 58 | count++; |
59 | } | 59 | } |
@@ -70,7 +70,7 @@ static int regcache_hw_init(struct regmap *map) | |||
70 | for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { | 70 | for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { |
71 | val = regcache_get_val(map->reg_defaults_raw, | 71 | val = regcache_get_val(map->reg_defaults_raw, |
72 | i, map->cache_word_size); | 72 | i, map->cache_word_size); |
73 | if (!val) | 73 | if (regmap_volatile(map, i)) |
74 | continue; | 74 | continue; |
75 | map->reg_defaults[j].reg = i; | 75 | map->reg_defaults[j].reg = i; |
76 | map->reg_defaults[j].def = val; | 76 | map->reg_defaults[j].def = val; |
@@ -211,7 +211,6 @@ int regcache_read(struct regmap *map, | |||
211 | 211 | ||
212 | return -EINVAL; | 212 | return -EINVAL; |
213 | } | 213 | } |
214 | EXPORT_SYMBOL_GPL(regcache_read); | ||
215 | 214 | ||
216 | /** | 215 | /** |
217 | * regcache_write: Set the value of a given register in the cache. | 216 | * regcache_write: Set the value of a given register in the cache. |
@@ -238,7 +237,6 @@ int regcache_write(struct regmap *map, | |||
238 | 237 | ||
239 | return 0; | 238 | return 0; |
240 | } | 239 | } |
241 | EXPORT_SYMBOL_GPL(regcache_write); | ||
242 | 240 | ||
243 | /** | 241 | /** |
244 | * regcache_sync: Sync the register cache with the hardware. | 242 | * regcache_sync: Sync the register cache with the hardware. |
@@ -360,6 +358,7 @@ void regcache_cache_only(struct regmap *map, bool enable) | |||
360 | mutex_lock(&map->lock); | 358 | mutex_lock(&map->lock); |
361 | WARN_ON(map->cache_bypass && enable); | 359 | WARN_ON(map->cache_bypass && enable); |
362 | map->cache_only = enable; | 360 | map->cache_only = enable; |
361 | trace_regmap_cache_only(map->dev, enable); | ||
363 | mutex_unlock(&map->lock); | 362 | mutex_unlock(&map->lock); |
364 | } | 363 | } |
365 | EXPORT_SYMBOL_GPL(regcache_cache_only); | 364 | EXPORT_SYMBOL_GPL(regcache_cache_only); |
@@ -397,6 +396,7 @@ void regcache_cache_bypass(struct regmap *map, bool enable) | |||
397 | mutex_lock(&map->lock); | 396 | mutex_lock(&map->lock); |
398 | WARN_ON(map->cache_only && enable); | 397 | WARN_ON(map->cache_only && enable); |
399 | map->cache_bypass = enable; | 398 | map->cache_bypass = enable; |
399 | trace_regmap_cache_bypass(map->dev, enable); | ||
400 | mutex_unlock(&map->lock); | 400 | mutex_unlock(&map->lock); |
401 | } | 401 | } |
402 | EXPORT_SYMBOL_GPL(regcache_cache_bypass); | 402 | EXPORT_SYMBOL_GPL(regcache_cache_bypass); |
@@ -419,10 +419,16 @@ bool regcache_set_val(void *base, unsigned int idx, | |||
419 | cache[idx] = val; | 419 | cache[idx] = val; |
420 | break; | 420 | break; |
421 | } | 421 | } |
422 | case 4: { | ||
423 | u32 *cache = base; | ||
424 | if (cache[idx] == val) | ||
425 | return true; | ||
426 | cache[idx] = val; | ||
427 | break; | ||
428 | } | ||
422 | default: | 429 | default: |
423 | BUG(); | 430 | BUG(); |
424 | } | 431 | } |
425 | /* unreachable */ | ||
426 | return false; | 432 | return false; |
427 | } | 433 | } |
428 | 434 | ||
@@ -441,6 +447,10 @@ unsigned int regcache_get_val(const void *base, unsigned int idx, | |||
441 | const u16 *cache = base; | 447 | const u16 *cache = base; |
442 | return cache[idx]; | 448 | return cache[idx]; |
443 | } | 449 | } |
450 | case 4: { | ||
451 | const u32 *cache = base; | ||
452 | return cache[idx]; | ||
453 | } | ||
444 | default: | 454 | default: |
445 | BUG(); | 455 | BUG(); |
446 | } | 456 | } |
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 6f397476e27c..372f81a21201 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c | |||
@@ -11,7 +11,6 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/module.h> | ||
15 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
16 | #include <linux/debugfs.h> | 15 | #include <linux/debugfs.h> |
17 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
@@ -33,6 +32,35 @@ static int regmap_open_file(struct inode *inode, struct file *file) | |||
33 | return 0; | 32 | return 0; |
34 | } | 33 | } |
35 | 34 | ||
35 | static ssize_t regmap_name_read_file(struct file *file, | ||
36 | char __user *user_buf, size_t count, | ||
37 | loff_t *ppos) | ||
38 | { | ||
39 | struct regmap *map = file->private_data; | ||
40 | int ret; | ||
41 | char *buf; | ||
42 | |||
43 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
44 | if (!buf) | ||
45 | return -ENOMEM; | ||
46 | |||
47 | ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name); | ||
48 | if (ret < 0) { | ||
49 | kfree(buf); | ||
50 | return ret; | ||
51 | } | ||
52 | |||
53 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | ||
54 | kfree(buf); | ||
55 | return ret; | ||
56 | } | ||
57 | |||
58 | static const struct file_operations regmap_name_fops = { | ||
59 | .open = regmap_open_file, | ||
60 | .read = regmap_name_read_file, | ||
61 | .llseek = default_llseek, | ||
62 | }; | ||
63 | |||
36 | static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, | 64 | static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, |
37 | size_t count, loff_t *ppos) | 65 | size_t count, loff_t *ppos) |
38 | { | 66 | { |
@@ -103,9 +131,51 @@ out: | |||
103 | return ret; | 131 | return ret; |
104 | } | 132 | } |
105 | 133 | ||
134 | #undef REGMAP_ALLOW_WRITE_DEBUGFS | ||
135 | #ifdef REGMAP_ALLOW_WRITE_DEBUGFS | ||
136 | /* | ||
137 | * This can be dangerous especially when we have clients such as | ||
138 | * PMICs, therefore don't provide any real compile time configuration option | ||
139 | * for this feature, people who want to use this will need to modify | ||
140 | * the source code directly. | ||
141 | */ | ||
142 | static ssize_t regmap_map_write_file(struct file *file, | ||
143 | const char __user *user_buf, | ||
144 | size_t count, loff_t *ppos) | ||
145 | { | ||
146 | char buf[32]; | ||
147 | size_t buf_size; | ||
148 | char *start = buf; | ||
149 | unsigned long reg, value; | ||
150 | struct regmap *map = file->private_data; | ||
151 | |||
152 | buf_size = min(count, (sizeof(buf)-1)); | ||
153 | if (copy_from_user(buf, user_buf, buf_size)) | ||
154 | return -EFAULT; | ||
155 | buf[buf_size] = 0; | ||
156 | |||
157 | while (*start == ' ') | ||
158 | start++; | ||
159 | reg = simple_strtoul(start, &start, 16); | ||
160 | while (*start == ' ') | ||
161 | start++; | ||
162 | if (strict_strtoul(start, 16, &value)) | ||
163 | return -EINVAL; | ||
164 | |||
165 | /* Userspace has been fiddling around behind the kernel's back */ | ||
166 | add_taint(TAINT_USER); | ||
167 | |||
168 | regmap_write(map, reg, value); | ||
169 | return buf_size; | ||
170 | } | ||
171 | #else | ||
172 | #define regmap_map_write_file NULL | ||
173 | #endif | ||
174 | |||
106 | static const struct file_operations regmap_map_fops = { | 175 | static const struct file_operations regmap_map_fops = { |
107 | .open = regmap_open_file, | 176 | .open = regmap_open_file, |
108 | .read = regmap_map_read_file, | 177 | .read = regmap_map_read_file, |
178 | .write = regmap_map_write_file, | ||
109 | .llseek = default_llseek, | 179 | .llseek = default_llseek, |
110 | }; | 180 | }; |
111 | 181 | ||
@@ -186,12 +256,24 @@ void regmap_debugfs_init(struct regmap *map) | |||
186 | return; | 256 | return; |
187 | } | 257 | } |
188 | 258 | ||
259 | debugfs_create_file("name", 0400, map->debugfs, | ||
260 | map, ®map_name_fops); | ||
261 | |||
189 | if (map->max_register) { | 262 | if (map->max_register) { |
190 | debugfs_create_file("registers", 0400, map->debugfs, | 263 | debugfs_create_file("registers", 0400, map->debugfs, |
191 | map, ®map_map_fops); | 264 | map, ®map_map_fops); |
192 | debugfs_create_file("access", 0400, map->debugfs, | 265 | debugfs_create_file("access", 0400, map->debugfs, |
193 | map, ®map_access_fops); | 266 | map, ®map_access_fops); |
194 | } | 267 | } |
268 | |||
269 | if (map->cache_type) { | ||
270 | debugfs_create_bool("cache_only", 0400, map->debugfs, | ||
271 | &map->cache_only); | ||
272 | debugfs_create_bool("cache_dirty", 0400, map->debugfs, | ||
273 | &map->cache_dirty); | ||
274 | debugfs_create_bool("cache_bypass", 0400, map->debugfs, | ||
275 | &map->cache_bypass); | ||
276 | } | ||
195 | } | 277 | } |
196 | 278 | ||
197 | void regmap_debugfs_exit(struct regmap *map) | 279 | void regmap_debugfs_exit(struct regmap *map) |
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 38621ec87c05..9a3a8c564389 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c | |||
@@ -111,4 +111,21 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c, | |||
111 | } | 111 | } |
112 | EXPORT_SYMBOL_GPL(regmap_init_i2c); | 112 | EXPORT_SYMBOL_GPL(regmap_init_i2c); |
113 | 113 | ||
114 | /** | ||
115 | * devm_regmap_init_i2c(): Initialise managed register map | ||
116 | * | ||
117 | * @i2c: Device that will be interacted with | ||
118 | * @config: Configuration for register map | ||
119 | * | ||
120 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
121 | * to a struct regmap. The regmap will be automatically freed by the | ||
122 | * device management code. | ||
123 | */ | ||
124 | struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, | ||
125 | const struct regmap_config *config) | ||
126 | { | ||
127 | return devm_regmap_init(&i2c->dev, ®map_i2c, config); | ||
128 | } | ||
129 | EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); | ||
130 | |||
114 | MODULE_LICENSE("GPL"); | 131 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 2560658de344..7c0c35a39c33 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c | |||
@@ -70,4 +70,21 @@ struct regmap *regmap_init_spi(struct spi_device *spi, | |||
70 | } | 70 | } |
71 | EXPORT_SYMBOL_GPL(regmap_init_spi); | 71 | EXPORT_SYMBOL_GPL(regmap_init_spi); |
72 | 72 | ||
73 | /** | ||
74 | * devm_regmap_init_spi(): Initialise register map | ||
75 | * | ||
76 | * @spi: Device that will be interacted with | ||
77 | * @config: Configuration for register map | ||
78 | * | ||
79 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
80 | * to a struct regmap. The map will be automatically freed by the | ||
81 | * device management code. | ||
82 | */ | ||
83 | struct regmap *devm_regmap_init_spi(struct spi_device *spi, | ||
84 | const struct regmap_config *config) | ||
85 | { | ||
86 | return devm_regmap_init(&spi->dev, ®map_spi, config); | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(devm_regmap_init_spi); | ||
89 | |||
73 | MODULE_LICENSE("GPL"); | 90 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 46b2bd742ee6..e3ee9cabccb4 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -10,8 +10,9 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/device.h> | ||
13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
14 | #include <linux/module.h> | 15 | #include <linux/export.h> |
15 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
16 | #include <linux/err.h> | 17 | #include <linux/err.h> |
17 | 18 | ||
@@ -36,6 +37,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg) | |||
36 | if (map->max_register && reg > map->max_register) | 37 | if (map->max_register && reg > map->max_register) |
37 | return false; | 38 | return false; |
38 | 39 | ||
40 | if (map->format.format_write) | ||
41 | return false; | ||
42 | |||
39 | if (map->readable_reg) | 43 | if (map->readable_reg) |
40 | return map->readable_reg(map->dev, reg); | 44 | return map->readable_reg(map->dev, reg); |
41 | 45 | ||
@@ -44,7 +48,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg) | |||
44 | 48 | ||
45 | bool regmap_volatile(struct regmap *map, unsigned int reg) | 49 | bool regmap_volatile(struct regmap *map, unsigned int reg) |
46 | { | 50 | { |
47 | if (map->max_register && reg > map->max_register) | 51 | if (!regmap_readable(map, reg)) |
48 | return false; | 52 | return false; |
49 | 53 | ||
50 | if (map->volatile_reg) | 54 | if (map->volatile_reg) |
@@ -55,7 +59,7 @@ bool regmap_volatile(struct regmap *map, unsigned int reg) | |||
55 | 59 | ||
56 | bool regmap_precious(struct regmap *map, unsigned int reg) | 60 | bool regmap_precious(struct regmap *map, unsigned int reg) |
57 | { | 61 | { |
58 | if (map->max_register && reg > map->max_register) | 62 | if (!regmap_readable(map, reg)) |
59 | return false; | 63 | return false; |
60 | 64 | ||
61 | if (map->precious_reg) | 65 | if (map->precious_reg) |
@@ -76,6 +80,14 @@ static bool regmap_volatile_range(struct regmap *map, unsigned int reg, | |||
76 | return true; | 80 | return true; |
77 | } | 81 | } |
78 | 82 | ||
83 | static void regmap_format_2_6_write(struct regmap *map, | ||
84 | unsigned int reg, unsigned int val) | ||
85 | { | ||
86 | u8 *out = map->work_buf; | ||
87 | |||
88 | *out = (reg << 6) | val; | ||
89 | } | ||
90 | |||
79 | static void regmap_format_4_12_write(struct regmap *map, | 91 | static void regmap_format_4_12_write(struct regmap *map, |
80 | unsigned int reg, unsigned int val) | 92 | unsigned int reg, unsigned int val) |
81 | { | 93 | { |
@@ -114,6 +126,13 @@ static void regmap_format_16(void *buf, unsigned int val) | |||
114 | b[0] = cpu_to_be16(val); | 126 | b[0] = cpu_to_be16(val); |
115 | } | 127 | } |
116 | 128 | ||
129 | static void regmap_format_32(void *buf, unsigned int val) | ||
130 | { | ||
131 | __be32 *b = buf; | ||
132 | |||
133 | b[0] = cpu_to_be32(val); | ||
134 | } | ||
135 | |||
117 | static unsigned int regmap_parse_8(void *buf) | 136 | static unsigned int regmap_parse_8(void *buf) |
118 | { | 137 | { |
119 | u8 *b = buf; | 138 | u8 *b = buf; |
@@ -130,6 +149,15 @@ static unsigned int regmap_parse_16(void *buf) | |||
130 | return b[0]; | 149 | return b[0]; |
131 | } | 150 | } |
132 | 151 | ||
152 | static unsigned int regmap_parse_32(void *buf) | ||
153 | { | ||
154 | __be32 *b = buf; | ||
155 | |||
156 | b[0] = be32_to_cpu(b[0]); | ||
157 | |||
158 | return b[0]; | ||
159 | } | ||
160 | |||
133 | /** | 161 | /** |
134 | * regmap_init(): Initialise register map | 162 | * regmap_init(): Initialise register map |
135 | * | 163 | * |
@@ -159,8 +187,10 @@ struct regmap *regmap_init(struct device *dev, | |||
159 | 187 | ||
160 | mutex_init(&map->lock); | 188 | mutex_init(&map->lock); |
161 | map->format.buf_size = (config->reg_bits + config->val_bits) / 8; | 189 | map->format.buf_size = (config->reg_bits + config->val_bits) / 8; |
162 | map->format.reg_bytes = config->reg_bits / 8; | 190 | map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); |
163 | map->format.val_bytes = config->val_bits / 8; | 191 | map->format.pad_bytes = config->pad_bits / 8; |
192 | map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); | ||
193 | map->format.buf_size += map->format.pad_bytes; | ||
164 | map->dev = dev; | 194 | map->dev = dev; |
165 | map->bus = bus; | 195 | map->bus = bus; |
166 | map->max_register = config->max_register; | 196 | map->max_register = config->max_register; |
@@ -178,6 +208,16 @@ struct regmap *regmap_init(struct device *dev, | |||
178 | } | 208 | } |
179 | 209 | ||
180 | switch (config->reg_bits) { | 210 | switch (config->reg_bits) { |
211 | case 2: | ||
212 | switch (config->val_bits) { | ||
213 | case 6: | ||
214 | map->format.format_write = regmap_format_2_6_write; | ||
215 | break; | ||
216 | default: | ||
217 | goto err_map; | ||
218 | } | ||
219 | break; | ||
220 | |||
181 | case 4: | 221 | case 4: |
182 | switch (config->val_bits) { | 222 | switch (config->val_bits) { |
183 | case 12: | 223 | case 12: |
@@ -216,6 +256,10 @@ struct regmap *regmap_init(struct device *dev, | |||
216 | map->format.format_reg = regmap_format_16; | 256 | map->format.format_reg = regmap_format_16; |
217 | break; | 257 | break; |
218 | 258 | ||
259 | case 32: | ||
260 | map->format.format_reg = regmap_format_32; | ||
261 | break; | ||
262 | |||
219 | default: | 263 | default: |
220 | goto err_map; | 264 | goto err_map; |
221 | } | 265 | } |
@@ -229,13 +273,17 @@ struct regmap *regmap_init(struct device *dev, | |||
229 | map->format.format_val = regmap_format_16; | 273 | map->format.format_val = regmap_format_16; |
230 | map->format.parse_val = regmap_parse_16; | 274 | map->format.parse_val = regmap_parse_16; |
231 | break; | 275 | break; |
276 | case 32: | ||
277 | map->format.format_val = regmap_format_32; | ||
278 | map->format.parse_val = regmap_parse_32; | ||
279 | break; | ||
232 | } | 280 | } |
233 | 281 | ||
234 | if (!map->format.format_write && | 282 | if (!map->format.format_write && |
235 | !(map->format.format_reg && map->format.format_val)) | 283 | !(map->format.format_reg && map->format.format_val)) |
236 | goto err_map; | 284 | goto err_map; |
237 | 285 | ||
238 | map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL); | 286 | map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL); |
239 | if (map->work_buf == NULL) { | 287 | if (map->work_buf == NULL) { |
240 | ret = -ENOMEM; | 288 | ret = -ENOMEM; |
241 | goto err_map; | 289 | goto err_map; |
@@ -258,6 +306,45 @@ err: | |||
258 | } | 306 | } |
259 | EXPORT_SYMBOL_GPL(regmap_init); | 307 | EXPORT_SYMBOL_GPL(regmap_init); |
260 | 308 | ||
309 | static void devm_regmap_release(struct device *dev, void *res) | ||
310 | { | ||
311 | regmap_exit(*(struct regmap **)res); | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * devm_regmap_init(): Initialise managed register map | ||
316 | * | ||
317 | * @dev: Device that will be interacted with | ||
318 | * @bus: Bus-specific callbacks to use with device | ||
319 | * @config: Configuration for register map | ||
320 | * | ||
321 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
322 | * to a struct regmap. This function should generally not be called | ||
323 | * directly, it should be called by bus-specific init functions. The | ||
324 | * map will be automatically freed by the device management code. | ||
325 | */ | ||
326 | struct regmap *devm_regmap_init(struct device *dev, | ||
327 | const struct regmap_bus *bus, | ||
328 | const struct regmap_config *config) | ||
329 | { | ||
330 | struct regmap **ptr, *regmap; | ||
331 | |||
332 | ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL); | ||
333 | if (!ptr) | ||
334 | return ERR_PTR(-ENOMEM); | ||
335 | |||
336 | regmap = regmap_init(dev, bus, config); | ||
337 | if (!IS_ERR(regmap)) { | ||
338 | *ptr = regmap; | ||
339 | devres_add(dev, ptr); | ||
340 | } else { | ||
341 | devres_free(ptr); | ||
342 | } | ||
343 | |||
344 | return regmap; | ||
345 | } | ||
346 | EXPORT_SYMBOL_GPL(devm_regmap_init); | ||
347 | |||
261 | /** | 348 | /** |
262 | * regmap_reinit_cache(): Reinitialise the current register cache | 349 | * regmap_reinit_cache(): Reinitialise the current register cache |
263 | * | 350 | * |
@@ -276,6 +363,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) | |||
276 | mutex_lock(&map->lock); | 363 | mutex_lock(&map->lock); |
277 | 364 | ||
278 | regcache_exit(map); | 365 | regcache_exit(map); |
366 | regmap_debugfs_exit(map); | ||
279 | 367 | ||
280 | map->max_register = config->max_register; | 368 | map->max_register = config->max_register; |
281 | map->writeable_reg = config->writeable_reg; | 369 | map->writeable_reg = config->writeable_reg; |
@@ -284,6 +372,11 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) | |||
284 | map->precious_reg = config->precious_reg; | 372 | map->precious_reg = config->precious_reg; |
285 | map->cache_type = config->cache_type; | 373 | map->cache_type = config->cache_type; |
286 | 374 | ||
375 | regmap_debugfs_init(map); | ||
376 | |||
377 | map->cache_bypass = false; | ||
378 | map->cache_only = false; | ||
379 | |||
287 | ret = regcache_init(map, config); | 380 | ret = regcache_init(map, config); |
288 | 381 | ||
289 | mutex_unlock(&map->lock); | 382 | mutex_unlock(&map->lock); |
@@ -329,23 +422,28 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
329 | * send the work_buf directly, otherwise try to do a gather | 422 | * send the work_buf directly, otherwise try to do a gather |
330 | * write. | 423 | * write. |
331 | */ | 424 | */ |
332 | if (val == map->work_buf + map->format.reg_bytes) | 425 | if (val == (map->work_buf + map->format.pad_bytes + |
426 | map->format.reg_bytes)) | ||
333 | ret = map->bus->write(map->dev, map->work_buf, | 427 | ret = map->bus->write(map->dev, map->work_buf, |
334 | map->format.reg_bytes + val_len); | 428 | map->format.reg_bytes + |
429 | map->format.pad_bytes + | ||
430 | val_len); | ||
335 | else if (map->bus->gather_write) | 431 | else if (map->bus->gather_write) |
336 | ret = map->bus->gather_write(map->dev, map->work_buf, | 432 | ret = map->bus->gather_write(map->dev, map->work_buf, |
337 | map->format.reg_bytes, | 433 | map->format.reg_bytes + |
434 | map->format.pad_bytes, | ||
338 | val, val_len); | 435 | val, val_len); |
339 | 436 | ||
340 | /* If that didn't work fall back on linearising by hand. */ | 437 | /* If that didn't work fall back on linearising by hand. */ |
341 | if (ret == -ENOTSUPP) { | 438 | if (ret == -ENOTSUPP) { |
342 | len = map->format.reg_bytes + val_len; | 439 | len = map->format.reg_bytes + map->format.pad_bytes + val_len; |
343 | buf = kmalloc(len, GFP_KERNEL); | 440 | buf = kzalloc(len, GFP_KERNEL); |
344 | if (!buf) | 441 | if (!buf) |
345 | return -ENOMEM; | 442 | return -ENOMEM; |
346 | 443 | ||
347 | memcpy(buf, map->work_buf, map->format.reg_bytes); | 444 | memcpy(buf, map->work_buf, map->format.reg_bytes); |
348 | memcpy(buf + map->format.reg_bytes, val, val_len); | 445 | memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, |
446 | val, val_len); | ||
349 | ret = map->bus->write(map->dev, buf, len); | 447 | ret = map->bus->write(map->dev, buf, len); |
350 | 448 | ||
351 | kfree(buf); | 449 | kfree(buf); |
@@ -387,10 +485,12 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
387 | 485 | ||
388 | return ret; | 486 | return ret; |
389 | } else { | 487 | } else { |
390 | map->format.format_val(map->work_buf + map->format.reg_bytes, | 488 | map->format.format_val(map->work_buf + map->format.reg_bytes |
391 | val); | 489 | + map->format.pad_bytes, val); |
392 | return _regmap_raw_write(map, reg, | 490 | return _regmap_raw_write(map, reg, |
393 | map->work_buf + map->format.reg_bytes, | 491 | map->work_buf + |
492 | map->format.reg_bytes + | ||
493 | map->format.pad_bytes, | ||
394 | map->format.val_bytes); | 494 | map->format.val_bytes); |
395 | } | 495 | } |
396 | } | 496 | } |
@@ -473,7 +573,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
473 | trace_regmap_hw_read_start(map->dev, reg, | 573 | trace_regmap_hw_read_start(map->dev, reg, |
474 | val_len / map->format.val_bytes); | 574 | val_len / map->format.val_bytes); |
475 | 575 | ||
476 | ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes, | 576 | ret = map->bus->read(map->dev, map->work_buf, |
577 | map->format.reg_bytes + map->format.pad_bytes, | ||
477 | val, val_len); | 578 | val, val_len); |
478 | 579 | ||
479 | trace_regmap_hw_read_done(map->dev, reg, | 580 | trace_regmap_hw_read_done(map->dev, reg, |
@@ -546,16 +647,32 @@ EXPORT_SYMBOL_GPL(regmap_read); | |||
546 | int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | 647 | int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, |
547 | size_t val_len) | 648 | size_t val_len) |
548 | { | 649 | { |
549 | size_t val_count = val_len / map->format.val_bytes; | 650 | size_t val_bytes = map->format.val_bytes; |
550 | int ret; | 651 | size_t val_count = val_len / val_bytes; |
551 | 652 | unsigned int v; | |
552 | WARN_ON(!regmap_volatile_range(map, reg, val_count) && | 653 | int ret, i; |
553 | map->cache_type != REGCACHE_NONE); | ||
554 | 654 | ||
555 | mutex_lock(&map->lock); | 655 | mutex_lock(&map->lock); |
556 | 656 | ||
557 | ret = _regmap_raw_read(map, reg, val, val_len); | 657 | if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || |
658 | map->cache_type == REGCACHE_NONE) { | ||
659 | /* Physical block read if there's no cache involved */ | ||
660 | ret = _regmap_raw_read(map, reg, val, val_len); | ||
661 | |||
662 | } else { | ||
663 | /* Otherwise go word by word for the cache; should be low | ||
664 | * cost as we expect to hit the cache. | ||
665 | */ | ||
666 | for (i = 0; i < val_count; i++) { | ||
667 | ret = _regmap_read(map, reg + i, &v); | ||
668 | if (ret != 0) | ||
669 | goto out; | ||
670 | |||
671 | map->format.format_val(val + (i * val_bytes), v); | ||
672 | } | ||
673 | } | ||
558 | 674 | ||
675 | out: | ||
559 | mutex_unlock(&map->lock); | 676 | mutex_unlock(&map->lock); |
560 | 677 | ||
561 | return ret; | 678 | return ret; |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c deleted file mode 100644 index 409f5ce78829..000000000000 --- a/drivers/base/sys.c +++ /dev/null | |||
@@ -1,383 +0,0 @@ | |||
1 | /* | ||
2 | * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc) | ||
3 | * | ||
4 | * Copyright (c) 2002-3 Patrick Mochel | ||
5 | * 2002-3 Open Source Development Lab | ||
6 | * | ||
7 | * This file is released under the GPLv2 | ||
8 | * | ||
9 | * This exports a 'system' bus type. | ||
10 | * By default, a 'sys' bus gets added to the root of the system. There will | ||
11 | * always be core system devices. Devices can use sysdev_register() to | ||
12 | * add themselves as children of the system bus. | ||
13 | */ | ||
14 | |||
15 | #include <linux/sysdev.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/mutex.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | |||
26 | #include "base.h" | ||
27 | |||
28 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | ||
29 | #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) | ||
30 | |||
31 | |||
32 | static ssize_t | ||
33 | sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer) | ||
34 | { | ||
35 | struct sys_device *sysdev = to_sysdev(kobj); | ||
36 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); | ||
37 | |||
38 | if (sysdev_attr->show) | ||
39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); | ||
40 | return -EIO; | ||
41 | } | ||
42 | |||
43 | |||
44 | static ssize_t | ||
45 | sysdev_store(struct kobject *kobj, struct attribute *attr, | ||
46 | const char *buffer, size_t count) | ||
47 | { | ||
48 | struct sys_device *sysdev = to_sysdev(kobj); | ||
49 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); | ||
50 | |||
51 | if (sysdev_attr->store) | ||
52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); | ||
53 | return -EIO; | ||
54 | } | ||
55 | |||
56 | static const struct sysfs_ops sysfs_ops = { | ||
57 | .show = sysdev_show, | ||
58 | .store = sysdev_store, | ||
59 | }; | ||
60 | |||
61 | static struct kobj_type ktype_sysdev = { | ||
62 | .sysfs_ops = &sysfs_ops, | ||
63 | }; | ||
64 | |||
65 | |||
66 | int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a) | ||
67 | { | ||
68 | return sysfs_create_file(&s->kobj, &a->attr); | ||
69 | } | ||
70 | |||
71 | |||
72 | void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a) | ||
73 | { | ||
74 | sysfs_remove_file(&s->kobj, &a->attr); | ||
75 | } | ||
76 | |||
77 | EXPORT_SYMBOL_GPL(sysdev_create_file); | ||
78 | EXPORT_SYMBOL_GPL(sysdev_remove_file); | ||
79 | |||
80 | #define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj) | ||
81 | #define to_sysdev_class_attr(a) container_of(a, \ | ||
82 | struct sysdev_class_attribute, attr) | ||
83 | |||
84 | static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, | ||
85 | char *buffer) | ||
86 | { | ||
87 | struct sysdev_class *class = to_sysdev_class(kobj); | ||
88 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); | ||
89 | |||
90 | if (class_attr->show) | ||
91 | return class_attr->show(class, class_attr, buffer); | ||
92 | return -EIO; | ||
93 | } | ||
94 | |||
95 | static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, | ||
96 | const char *buffer, size_t count) | ||
97 | { | ||
98 | struct sysdev_class *class = to_sysdev_class(kobj); | ||
99 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); | ||
100 | |||
101 | if (class_attr->store) | ||
102 | return class_attr->store(class, class_attr, buffer, count); | ||
103 | return -EIO; | ||
104 | } | ||
105 | |||
106 | static const struct sysfs_ops sysfs_class_ops = { | ||
107 | .show = sysdev_class_show, | ||
108 | .store = sysdev_class_store, | ||
109 | }; | ||
110 | |||
111 | static struct kobj_type ktype_sysdev_class = { | ||
112 | .sysfs_ops = &sysfs_class_ops, | ||
113 | }; | ||
114 | |||
115 | int sysdev_class_create_file(struct sysdev_class *c, | ||
116 | struct sysdev_class_attribute *a) | ||
117 | { | ||
118 | return sysfs_create_file(&c->kset.kobj, &a->attr); | ||
119 | } | ||
120 | EXPORT_SYMBOL_GPL(sysdev_class_create_file); | ||
121 | |||
122 | void sysdev_class_remove_file(struct sysdev_class *c, | ||
123 | struct sysdev_class_attribute *a) | ||
124 | { | ||
125 | sysfs_remove_file(&c->kset.kobj, &a->attr); | ||
126 | } | ||
127 | EXPORT_SYMBOL_GPL(sysdev_class_remove_file); | ||
128 | |||
129 | extern struct kset *system_kset; | ||
130 | |||
131 | int sysdev_class_register(struct sysdev_class *cls) | ||
132 | { | ||
133 | int retval; | ||
134 | |||
135 | pr_debug("Registering sysdev class '%s'\n", cls->name); | ||
136 | |||
137 | INIT_LIST_HEAD(&cls->drivers); | ||
138 | memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); | ||
139 | cls->kset.kobj.parent = &system_kset->kobj; | ||
140 | cls->kset.kobj.ktype = &ktype_sysdev_class; | ||
141 | cls->kset.kobj.kset = system_kset; | ||
142 | |||
143 | retval = kobject_set_name(&cls->kset.kobj, "%s", cls->name); | ||
144 | if (retval) | ||
145 | return retval; | ||
146 | |||
147 | retval = kset_register(&cls->kset); | ||
148 | if (!retval && cls->attrs) | ||
149 | retval = sysfs_create_files(&cls->kset.kobj, | ||
150 | (const struct attribute **)cls->attrs); | ||
151 | return retval; | ||
152 | } | ||
153 | |||
154 | void sysdev_class_unregister(struct sysdev_class *cls) | ||
155 | { | ||
156 | pr_debug("Unregistering sysdev class '%s'\n", | ||
157 | kobject_name(&cls->kset.kobj)); | ||
158 | if (cls->attrs) | ||
159 | sysfs_remove_files(&cls->kset.kobj, | ||
160 | (const struct attribute **)cls->attrs); | ||
161 | kset_unregister(&cls->kset); | ||
162 | } | ||
163 | |||
164 | EXPORT_SYMBOL_GPL(sysdev_class_register); | ||
165 | EXPORT_SYMBOL_GPL(sysdev_class_unregister); | ||
166 | |||
167 | static DEFINE_MUTEX(sysdev_drivers_lock); | ||
168 | |||
169 | /* | ||
170 | * @dev != NULL means that we're unwinding because some drv->add() | ||
171 | * failed for some reason. You need to grab sysdev_drivers_lock before | ||
172 | * calling this. | ||
173 | */ | ||
174 | static void __sysdev_driver_remove(struct sysdev_class *cls, | ||
175 | struct sysdev_driver *drv, | ||
176 | struct sys_device *from_dev) | ||
177 | { | ||
178 | struct sys_device *dev = from_dev; | ||
179 | |||
180 | list_del_init(&drv->entry); | ||
181 | if (!cls) | ||
182 | return; | ||
183 | |||
184 | if (!drv->remove) | ||
185 | goto kset_put; | ||
186 | |||
187 | if (dev) | ||
188 | list_for_each_entry_continue_reverse(dev, &cls->kset.list, | ||
189 | kobj.entry) | ||
190 | drv->remove(dev); | ||
191 | else | ||
192 | list_for_each_entry(dev, &cls->kset.list, kobj.entry) | ||
193 | drv->remove(dev); | ||
194 | |||
195 | kset_put: | ||
196 | kset_put(&cls->kset); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * sysdev_driver_register - Register auxiliary driver | ||
201 | * @cls: Device class driver belongs to. | ||
202 | * @drv: Driver. | ||
203 | * | ||
204 | * @drv is inserted into @cls->drivers to be | ||
205 | * called on each operation on devices of that class. The refcount | ||
206 | * of @cls is incremented. | ||
207 | */ | ||
208 | int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) | ||
209 | { | ||
210 | struct sys_device *dev = NULL; | ||
211 | int err = 0; | ||
212 | |||
213 | if (!cls) { | ||
214 | WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n", | ||
215 | __func__); | ||
216 | return -EINVAL; | ||
217 | } | ||
218 | |||
219 | /* Check whether this driver has already been added to a class. */ | ||
220 | if (drv->entry.next && !list_empty(&drv->entry)) | ||
221 | WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already" | ||
222 | " been registered to a class, something is wrong, but " | ||
223 | "will forge on!\n", cls->name, drv); | ||
224 | |||
225 | mutex_lock(&sysdev_drivers_lock); | ||
226 | if (cls && kset_get(&cls->kset)) { | ||
227 | list_add_tail(&drv->entry, &cls->drivers); | ||
228 | |||
229 | /* If devices of this class already exist, tell the driver */ | ||
230 | if (drv->add) { | ||
231 | list_for_each_entry(dev, &cls->kset.list, kobj.entry) { | ||
232 | err = drv->add(dev); | ||
233 | if (err) | ||
234 | goto unwind; | ||
235 | } | ||
236 | } | ||
237 | } else { | ||
238 | err = -EINVAL; | ||
239 | WARN(1, KERN_ERR "%s: invalid device class\n", __func__); | ||
240 | } | ||
241 | |||
242 | goto unlock; | ||
243 | |||
244 | unwind: | ||
245 | __sysdev_driver_remove(cls, drv, dev); | ||
246 | |||
247 | unlock: | ||
248 | mutex_unlock(&sysdev_drivers_lock); | ||
249 | return err; | ||
250 | } | ||
251 | |||
252 | /** | ||
253 | * sysdev_driver_unregister - Remove an auxiliary driver. | ||
254 | * @cls: Class driver belongs to. | ||
255 | * @drv: Driver. | ||
256 | */ | ||
257 | void sysdev_driver_unregister(struct sysdev_class *cls, | ||
258 | struct sysdev_driver *drv) | ||
259 | { | ||
260 | mutex_lock(&sysdev_drivers_lock); | ||
261 | __sysdev_driver_remove(cls, drv, NULL); | ||
262 | mutex_unlock(&sysdev_drivers_lock); | ||
263 | } | ||
264 | EXPORT_SYMBOL_GPL(sysdev_driver_register); | ||
265 | EXPORT_SYMBOL_GPL(sysdev_driver_unregister); | ||
266 | |||
267 | /** | ||
268 | * sysdev_register - add a system device to the tree | ||
269 | * @sysdev: device in question | ||
270 | * | ||
271 | */ | ||
272 | int sysdev_register(struct sys_device *sysdev) | ||
273 | { | ||
274 | int error; | ||
275 | struct sysdev_class *cls = sysdev->cls; | ||
276 | |||
277 | if (!cls) | ||
278 | return -EINVAL; | ||
279 | |||
280 | pr_debug("Registering sys device of class '%s'\n", | ||
281 | kobject_name(&cls->kset.kobj)); | ||
282 | |||
283 | /* initialize the kobject to 0, in case it had previously been used */ | ||
284 | memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); | ||
285 | |||
286 | /* Make sure the kset is set */ | ||
287 | sysdev->kobj.kset = &cls->kset; | ||
288 | |||
289 | /* Register the object */ | ||
290 | error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL, | ||
291 | "%s%d", kobject_name(&cls->kset.kobj), | ||
292 | sysdev->id); | ||
293 | |||
294 | if (!error) { | ||
295 | struct sysdev_driver *drv; | ||
296 | |||
297 | pr_debug("Registering sys device '%s'\n", | ||
298 | kobject_name(&sysdev->kobj)); | ||
299 | |||
300 | mutex_lock(&sysdev_drivers_lock); | ||
301 | /* Generic notification is implicit, because it's that | ||
302 | * code that should have called us. | ||
303 | */ | ||
304 | |||
305 | /* Notify class auxiliary drivers */ | ||
306 | list_for_each_entry(drv, &cls->drivers, entry) { | ||
307 | if (drv->add) | ||
308 | drv->add(sysdev); | ||
309 | } | ||
310 | mutex_unlock(&sysdev_drivers_lock); | ||
311 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); | ||
312 | } | ||
313 | |||
314 | return error; | ||
315 | } | ||
316 | |||
317 | void sysdev_unregister(struct sys_device *sysdev) | ||
318 | { | ||
319 | struct sysdev_driver *drv; | ||
320 | |||
321 | mutex_lock(&sysdev_drivers_lock); | ||
322 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { | ||
323 | if (drv->remove) | ||
324 | drv->remove(sysdev); | ||
325 | } | ||
326 | mutex_unlock(&sysdev_drivers_lock); | ||
327 | |||
328 | kobject_put(&sysdev->kobj); | ||
329 | } | ||
330 | |||
331 | EXPORT_SYMBOL_GPL(sysdev_register); | ||
332 | EXPORT_SYMBOL_GPL(sysdev_unregister); | ||
333 | |||
334 | #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) | ||
335 | |||
336 | ssize_t sysdev_store_ulong(struct sys_device *sysdev, | ||
337 | struct sysdev_attribute *attr, | ||
338 | const char *buf, size_t size) | ||
339 | { | ||
340 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
341 | char *end; | ||
342 | unsigned long new = simple_strtoul(buf, &end, 0); | ||
343 | if (end == buf) | ||
344 | return -EINVAL; | ||
345 | *(unsigned long *)(ea->var) = new; | ||
346 | /* Always return full write size even if we didn't consume all */ | ||
347 | return size; | ||
348 | } | ||
349 | EXPORT_SYMBOL_GPL(sysdev_store_ulong); | ||
350 | |||
351 | ssize_t sysdev_show_ulong(struct sys_device *sysdev, | ||
352 | struct sysdev_attribute *attr, | ||
353 | char *buf) | ||
354 | { | ||
355 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
356 | return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); | ||
357 | } | ||
358 | EXPORT_SYMBOL_GPL(sysdev_show_ulong); | ||
359 | |||
360 | ssize_t sysdev_store_int(struct sys_device *sysdev, | ||
361 | struct sysdev_attribute *attr, | ||
362 | const char *buf, size_t size) | ||
363 | { | ||
364 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
365 | char *end; | ||
366 | long new = simple_strtol(buf, &end, 0); | ||
367 | if (end == buf || new > INT_MAX || new < INT_MIN) | ||
368 | return -EINVAL; | ||
369 | *(int *)(ea->var) = new; | ||
370 | /* Always return full write size even if we didn't consume all */ | ||
371 | return size; | ||
372 | } | ||
373 | EXPORT_SYMBOL_GPL(sysdev_store_int); | ||
374 | |||
375 | ssize_t sysdev_show_int(struct sys_device *sysdev, | ||
376 | struct sysdev_attribute *attr, | ||
377 | char *buf) | ||
378 | { | ||
379 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
380 | return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); | ||
381 | } | ||
382 | EXPORT_SYMBOL_GPL(sysdev_show_int); | ||
383 | |||