diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/bus.c | 3 | ||||
-rw-r--r-- | drivers/base/core.c | 58 | ||||
-rw-r--r-- | drivers/base/cpu.c | 4 | ||||
-rw-r--r-- | drivers/base/devres.c | 35 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 6 | ||||
-rw-r--r-- | drivers/base/dma-buf.c | 12 | ||||
-rw-r--r-- | drivers/base/driver.c | 2 | ||||
-rw-r--r-- | drivers/base/regmap/Kconfig | 4 | ||||
-rw-r--r-- | drivers/base/regmap/Makefile | 1 | ||||
-rw-r--r-- | drivers/base/regmap/internal.h | 26 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-lzo.c | 11 | ||||
-rw-r--r-- | drivers/base/regmap/regcache-rbtree.c | 44 | ||||
-rw-r--r-- | drivers/base/regmap/regcache.c | 34 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-debugfs.c | 18 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-i2c.c | 13 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 184 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-mmio.c | 224 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-spi.c | 13 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 278 |
19 files changed, 778 insertions, 192 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 26a06b801b5b..2bcef657a60c 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -21,8 +21,7 @@ | |||
21 | #include "power/power.h" | 21 | #include "power/power.h" |
22 | 22 | ||
23 | /* /sys/devices/system */ | 23 | /* /sys/devices/system */ |
24 | /* FIXME: make static after drivers/base/sys.c is deleted */ | 24 | static struct kset *system_kset; |
25 | struct kset *system_kset; | ||
26 | 25 | ||
27 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) | 26 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) |
28 | 27 | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index e28ce9898af4..346be8b78b24 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/async.h> | 26 | #include <linux/async.h> |
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/netdevice.h> | ||
28 | 29 | ||
29 | #include "base.h" | 30 | #include "base.h" |
30 | #include "power/power.h" | 31 | #include "power/power.h" |
@@ -65,7 +66,7 @@ static inline int device_is_not_partition(struct device *dev) | |||
65 | * @dev: struct device to get the name of | 66 | * @dev: struct device to get the name of |
66 | * | 67 | * |
67 | * Will return the device's driver's name if it is bound to a device. If | 68 | * Will return the device's driver's name if it is bound to a device. If |
68 | * the device is not bound to a device, it will return the name of the bus | 69 | * the device is not bound to a driver, it will return the name of the bus |
69 | * it is attached to. If it is not attached to a bus either, an empty | 70 | * it is attached to. If it is not attached to a bus either, an empty |
70 | * string will be returned. | 71 | * string will be returned. |
71 | */ | 72 | */ |
@@ -878,8 +879,8 @@ EXPORT_SYMBOL_GPL(dev_set_name); | |||
878 | * to NULL prevents an entry from being created. class->dev_kobj must | 879 | * to NULL prevents an entry from being created. class->dev_kobj must |
879 | * be set (or cleared) before any devices are registered to the class | 880 | * be set (or cleared) before any devices are registered to the class |
880 | * otherwise device_create_sys_dev_entry() and | 881 | * otherwise device_create_sys_dev_entry() and |
881 | * device_remove_sys_dev_entry() will disagree about the the presence | 882 | * device_remove_sys_dev_entry() will disagree about the presence of |
882 | * of the link. | 883 | * the link. |
883 | */ | 884 | */ |
884 | static struct kobject *device_to_dev_kobj(struct device *dev) | 885 | static struct kobject *device_to_dev_kobj(struct device *dev) |
885 | { | 886 | { |
@@ -1843,15 +1844,60 @@ void device_shutdown(void) | |||
1843 | */ | 1844 | */ |
1844 | 1845 | ||
1845 | #ifdef CONFIG_PRINTK | 1846 | #ifdef CONFIG_PRINTK |
1846 | |||
1847 | int __dev_printk(const char *level, const struct device *dev, | 1847 | int __dev_printk(const char *level, const struct device *dev, |
1848 | struct va_format *vaf) | 1848 | struct va_format *vaf) |
1849 | { | 1849 | { |
1850 | char dict[128]; | ||
1851 | size_t dictlen = 0; | ||
1852 | const char *subsys; | ||
1853 | |||
1850 | if (!dev) | 1854 | if (!dev) |
1851 | return printk("%s(NULL device *): %pV", level, vaf); | 1855 | return printk("%s(NULL device *): %pV", level, vaf); |
1852 | 1856 | ||
1853 | return printk("%s%s %s: %pV", | 1857 | if (dev->class) |
1854 | level, dev_driver_string(dev), dev_name(dev), vaf); | 1858 | subsys = dev->class->name; |
1859 | else if (dev->bus) | ||
1860 | subsys = dev->bus->name; | ||
1861 | else | ||
1862 | goto skip; | ||
1863 | |||
1864 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1865 | "SUBSYSTEM=%s", subsys); | ||
1866 | |||
1867 | /* | ||
1868 | * Add device identifier DEVICE=: | ||
1869 | * b12:8 block dev_t | ||
1870 | * c127:3 char dev_t | ||
1871 | * n8 netdev ifindex | ||
1872 | * +sound:card0 subsystem:devname | ||
1873 | */ | ||
1874 | if (MAJOR(dev->devt)) { | ||
1875 | char c; | ||
1876 | |||
1877 | if (strcmp(subsys, "block") == 0) | ||
1878 | c = 'b'; | ||
1879 | else | ||
1880 | c = 'c'; | ||
1881 | dictlen++; | ||
1882 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1883 | "DEVICE=%c%u:%u", | ||
1884 | c, MAJOR(dev->devt), MINOR(dev->devt)); | ||
1885 | } else if (strcmp(subsys, "net") == 0) { | ||
1886 | struct net_device *net = to_net_dev(dev); | ||
1887 | |||
1888 | dictlen++; | ||
1889 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1890 | "DEVICE=n%u", net->ifindex); | ||
1891 | } else { | ||
1892 | dictlen++; | ||
1893 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1894 | "DEVICE=+%s:%s", subsys, dev_name(dev)); | ||
1895 | } | ||
1896 | skip: | ||
1897 | return printk_emit(0, level[1] - '0', | ||
1898 | dictlen ? dict : NULL, dictlen, | ||
1899 | "%s %s: %pV", | ||
1900 | dev_driver_string(dev), dev_name(dev), vaf); | ||
1855 | } | 1901 | } |
1856 | EXPORT_SYMBOL(__dev_printk); | 1902 | EXPORT_SYMBOL(__dev_printk); |
1857 | 1903 | ||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index adf937bf4091..63452943abd1 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -330,8 +330,4 @@ void __init cpu_dev_init(void) | |||
330 | panic("Failed to register CPU subsystem"); | 330 | panic("Failed to register CPU subsystem"); |
331 | 331 | ||
332 | cpu_dev_register_generic(); | 332 | cpu_dev_register_generic(); |
333 | |||
334 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) | ||
335 | sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root); | ||
336 | #endif | ||
337 | } | 333 | } |
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 524bf96c289f..2360adb7a58f 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -309,6 +309,10 @@ EXPORT_SYMBOL_GPL(devres_remove); | |||
309 | * which @match returns 1. If @match is NULL, it's considered to | 309 | * which @match returns 1. If @match is NULL, it's considered to |
310 | * match all. If found, the resource is removed atomically and freed. | 310 | * match all. If found, the resource is removed atomically and freed. |
311 | * | 311 | * |
312 | * Note that the release function for the resource will not be called, | ||
313 | * only the devres-allocated data will be freed. The caller becomes | ||
314 | * responsible for freeing any other data. | ||
315 | * | ||
312 | * RETURNS: | 316 | * RETURNS: |
313 | * 0 if devres is found and freed, -ENOENT if not found. | 317 | * 0 if devres is found and freed, -ENOENT if not found. |
314 | */ | 318 | */ |
@@ -326,6 +330,37 @@ int devres_destroy(struct device *dev, dr_release_t release, | |||
326 | } | 330 | } |
327 | EXPORT_SYMBOL_GPL(devres_destroy); | 331 | EXPORT_SYMBOL_GPL(devres_destroy); |
328 | 332 | ||
333 | |||
334 | /** | ||
335 | * devres_release - Find a device resource and destroy it, calling release | ||
336 | * @dev: Device to find resource from | ||
337 | * @release: Look for resources associated with this release function | ||
338 | * @match: Match function (optional) | ||
339 | * @match_data: Data for the match function | ||
340 | * | ||
341 | * Find the latest devres of @dev associated with @release and for | ||
342 | * which @match returns 1. If @match is NULL, it's considered to | ||
343 | * match all. If found, the resource is removed atomically, the | ||
344 | * release function called and the resource freed. | ||
345 | * | ||
346 | * RETURNS: | ||
347 | * 0 if devres is found and freed, -ENOENT if not found. | ||
348 | */ | ||
349 | int devres_release(struct device *dev, dr_release_t release, | ||
350 | dr_match_t match, void *match_data) | ||
351 | { | ||
352 | void *res; | ||
353 | |||
354 | res = devres_remove(dev, release, match, match_data); | ||
355 | if (unlikely(!res)) | ||
356 | return -ENOENT; | ||
357 | |||
358 | (*release)(dev, res); | ||
359 | devres_free(res); | ||
360 | return 0; | ||
361 | } | ||
362 | EXPORT_SYMBOL_GPL(devres_release); | ||
363 | |||
329 | static int remove_nodes(struct device *dev, | 364 | static int remove_nodes(struct device *dev, |
330 | struct list_head *first, struct list_head *end, | 365 | struct list_head *first, struct list_head *end, |
331 | struct list_head *todo) | 366 | struct list_head *todo) |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 8493536ea55b..765c3a28077a 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -7,9 +7,9 @@ | |||
7 | * devtmpfs, a tmpfs-based filesystem is created. Every driver-core | 7 | * devtmpfs, a tmpfs-based filesystem is created. Every driver-core |
8 | * device which requests a device node, will add a node in this | 8 | * device which requests a device node, will add a node in this |
9 | * filesystem. | 9 | * filesystem. |
10 | * By default, all devices are named after the the name of the | 10 | * By default, all devices are named after the name of the device, |
11 | * device, owned by root and have a default mode of 0600. Subsystems | 11 | * owned by root and have a default mode of 0600. Subsystems can |
12 | * can overwrite the default setting if needed. | 12 | * overwrite the default setting if needed. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 07cbbc6fddb4..05c64c11bad2 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
@@ -293,7 +293,7 @@ EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); | |||
293 | * cpu in the kernel context. Calls begin_cpu_access to allow exporter-specific | 293 | * cpu in the kernel context. Calls begin_cpu_access to allow exporter-specific |
294 | * preparations. Coherency is only guaranteed in the specified range for the | 294 | * preparations. Coherency is only guaranteed in the specified range for the |
295 | * specified access direction. | 295 | * specified access direction. |
296 | * @dma_buf: [in] buffer to prepare cpu access for. | 296 | * @dmabuf: [in] buffer to prepare cpu access for. |
297 | * @start: [in] start of range for cpu access. | 297 | * @start: [in] start of range for cpu access. |
298 | * @len: [in] length of range for cpu access. | 298 | * @len: [in] length of range for cpu access. |
299 | * @direction: [in] length of range for cpu access. | 299 | * @direction: [in] length of range for cpu access. |
@@ -320,7 +320,7 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); | |||
320 | * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific | 320 | * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific |
321 | * actions. Coherency is only guaranteed in the specified range for the | 321 | * actions. Coherency is only guaranteed in the specified range for the |
322 | * specified access direction. | 322 | * specified access direction. |
323 | * @dma_buf: [in] buffer to complete cpu access for. | 323 | * @dmabuf: [in] buffer to complete cpu access for. |
324 | * @start: [in] start of range for cpu access. | 324 | * @start: [in] start of range for cpu access. |
325 | * @len: [in] length of range for cpu access. | 325 | * @len: [in] length of range for cpu access. |
326 | * @direction: [in] length of range for cpu access. | 326 | * @direction: [in] length of range for cpu access. |
@@ -340,7 +340,7 @@ EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); | |||
340 | /** | 340 | /** |
341 | * dma_buf_kmap_atomic - Map a page of the buffer object into kernel address | 341 | * dma_buf_kmap_atomic - Map a page of the buffer object into kernel address |
342 | * space. The same restrictions as for kmap_atomic and friends apply. | 342 | * space. The same restrictions as for kmap_atomic and friends apply. |
343 | * @dma_buf: [in] buffer to map page from. | 343 | * @dmabuf: [in] buffer to map page from. |
344 | * @page_num: [in] page in PAGE_SIZE units to map. | 344 | * @page_num: [in] page in PAGE_SIZE units to map. |
345 | * | 345 | * |
346 | * This call must always succeed, any necessary preparations that might fail | 346 | * This call must always succeed, any necessary preparations that might fail |
@@ -356,7 +356,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kmap_atomic); | |||
356 | 356 | ||
357 | /** | 357 | /** |
358 | * dma_buf_kunmap_atomic - Unmap a page obtained by dma_buf_kmap_atomic. | 358 | * dma_buf_kunmap_atomic - Unmap a page obtained by dma_buf_kmap_atomic. |
359 | * @dma_buf: [in] buffer to unmap page from. | 359 | * @dmabuf: [in] buffer to unmap page from. |
360 | * @page_num: [in] page in PAGE_SIZE units to unmap. | 360 | * @page_num: [in] page in PAGE_SIZE units to unmap. |
361 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap_atomic. | 361 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap_atomic. |
362 | * | 362 | * |
@@ -375,7 +375,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kunmap_atomic); | |||
375 | /** | 375 | /** |
376 | * dma_buf_kmap - Map a page of the buffer object into kernel address space. The | 376 | * dma_buf_kmap - Map a page of the buffer object into kernel address space. The |
377 | * same restrictions as for kmap and friends apply. | 377 | * same restrictions as for kmap and friends apply. |
378 | * @dma_buf: [in] buffer to map page from. | 378 | * @dmabuf: [in] buffer to map page from. |
379 | * @page_num: [in] page in PAGE_SIZE units to map. | 379 | * @page_num: [in] page in PAGE_SIZE units to map. |
380 | * | 380 | * |
381 | * This call must always succeed, any necessary preparations that might fail | 381 | * This call must always succeed, any necessary preparations that might fail |
@@ -391,7 +391,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kmap); | |||
391 | 391 | ||
392 | /** | 392 | /** |
393 | * dma_buf_kunmap - Unmap a page obtained by dma_buf_kmap. | 393 | * dma_buf_kunmap - Unmap a page obtained by dma_buf_kmap. |
394 | * @dma_buf: [in] buffer to unmap page from. | 394 | * @dmabuf: [in] buffer to unmap page from. |
395 | * @page_num: [in] page in PAGE_SIZE units to unmap. | 395 | * @page_num: [in] page in PAGE_SIZE units to unmap. |
396 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap. | 396 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap. |
397 | * | 397 | * |
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 3ec3896c83a6..207c27ddf828 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -80,7 +80,7 @@ struct device *driver_find_device(struct device_driver *drv, | |||
80 | struct klist_iter i; | 80 | struct klist_iter i; |
81 | struct device *dev; | 81 | struct device *dev; |
82 | 82 | ||
83 | if (!drv) | 83 | if (!drv || !drv->p) |
84 | return NULL; | 84 | return NULL; |
85 | 85 | ||
86 | klist_iter_init_node(&drv->p->klist_devices, &i, | 86 | klist_iter_init_node(&drv->p->klist_devices, &i, |
diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig index 0f6c7fb418e8..6be390bd8bd1 100644 --- a/drivers/base/regmap/Kconfig +++ b/drivers/base/regmap/Kconfig | |||
@@ -6,6 +6,7 @@ config REGMAP | |||
6 | default y if (REGMAP_I2C || REGMAP_SPI) | 6 | default y if (REGMAP_I2C || REGMAP_SPI) |
7 | select LZO_COMPRESS | 7 | select LZO_COMPRESS |
8 | select LZO_DECOMPRESS | 8 | select LZO_DECOMPRESS |
9 | select IRQ_DOMAIN if REGMAP_IRQ | ||
9 | bool | 10 | bool |
10 | 11 | ||
11 | config REGMAP_I2C | 12 | config REGMAP_I2C |
@@ -14,5 +15,8 @@ config REGMAP_I2C | |||
14 | config REGMAP_SPI | 15 | config REGMAP_SPI |
15 | tristate | 16 | tristate |
16 | 17 | ||
18 | config REGMAP_MMIO | ||
19 | tristate | ||
20 | |||
17 | config REGMAP_IRQ | 21 | config REGMAP_IRQ |
18 | bool | 22 | bool |
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile index defd57963c84..5e75d1b683e2 100644 --- a/drivers/base/regmap/Makefile +++ b/drivers/base/regmap/Makefile | |||
@@ -3,4 +3,5 @@ obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o | |||
3 | obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o | 3 | obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o |
4 | obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o | 4 | obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o |
5 | obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o | 5 | obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o |
6 | obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o | ||
6 | obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o | 7 | obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o |
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index fcafc5b2e651..b986b8660b0c 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -26,21 +26,30 @@ struct regmap_format { | |||
26 | size_t val_bytes; | 26 | size_t val_bytes; |
27 | void (*format_write)(struct regmap *map, | 27 | void (*format_write)(struct regmap *map, |
28 | unsigned int reg, unsigned int val); | 28 | unsigned int reg, unsigned int val); |
29 | void (*format_reg)(void *buf, unsigned int reg); | 29 | void (*format_reg)(void *buf, unsigned int reg, unsigned int shift); |
30 | void (*format_val)(void *buf, unsigned int val); | 30 | void (*format_val)(void *buf, unsigned int val, unsigned int shift); |
31 | unsigned int (*parse_val)(void *buf); | 31 | unsigned int (*parse_val)(void *buf); |
32 | }; | 32 | }; |
33 | 33 | ||
34 | typedef void (*regmap_lock)(struct regmap *map); | ||
35 | typedef void (*regmap_unlock)(struct regmap *map); | ||
36 | |||
34 | struct regmap { | 37 | struct regmap { |
35 | struct mutex lock; | 38 | struct mutex mutex; |
39 | spinlock_t spinlock; | ||
40 | regmap_lock lock; | ||
41 | regmap_unlock unlock; | ||
36 | 42 | ||
37 | struct device *dev; /* Device we do I/O on */ | 43 | struct device *dev; /* Device we do I/O on */ |
38 | void *work_buf; /* Scratch buffer used to format I/O */ | 44 | void *work_buf; /* Scratch buffer used to format I/O */ |
39 | struct regmap_format format; /* Buffer format */ | 45 | struct regmap_format format; /* Buffer format */ |
40 | const struct regmap_bus *bus; | 46 | const struct regmap_bus *bus; |
47 | void *bus_context; | ||
48 | const char *name; | ||
41 | 49 | ||
42 | #ifdef CONFIG_DEBUG_FS | 50 | #ifdef CONFIG_DEBUG_FS |
43 | struct dentry *debugfs; | 51 | struct dentry *debugfs; |
52 | const char *debugfs_name; | ||
44 | #endif | 53 | #endif |
45 | 54 | ||
46 | unsigned int max_register; | 55 | unsigned int max_register; |
@@ -52,6 +61,10 @@ struct regmap { | |||
52 | u8 read_flag_mask; | 61 | u8 read_flag_mask; |
53 | u8 write_flag_mask; | 62 | u8 write_flag_mask; |
54 | 63 | ||
64 | /* number of bits to (left) shift the reg value when formatting*/ | ||
65 | int reg_shift; | ||
66 | int reg_stride; | ||
67 | |||
55 | /* regcache specific members */ | 68 | /* regcache specific members */ |
56 | const struct regcache_ops *cache_ops; | 69 | const struct regcache_ops *cache_ops; |
57 | enum regcache_type cache_type; | 70 | enum regcache_type cache_type; |
@@ -79,6 +92,9 @@ struct regmap { | |||
79 | 92 | ||
80 | struct reg_default *patch; | 93 | struct reg_default *patch; |
81 | int patch_regs; | 94 | int patch_regs; |
95 | |||
96 | /* if set, converts bulk rw to single rw */ | ||
97 | bool use_single_rw; | ||
82 | }; | 98 | }; |
83 | 99 | ||
84 | struct regcache_ops { | 100 | struct regcache_ops { |
@@ -101,11 +117,11 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
101 | 117 | ||
102 | #ifdef CONFIG_DEBUG_FS | 118 | #ifdef CONFIG_DEBUG_FS |
103 | extern void regmap_debugfs_initcall(void); | 119 | extern void regmap_debugfs_initcall(void); |
104 | extern void regmap_debugfs_init(struct regmap *map); | 120 | extern void regmap_debugfs_init(struct regmap *map, const char *name); |
105 | extern void regmap_debugfs_exit(struct regmap *map); | 121 | extern void regmap_debugfs_exit(struct regmap *map); |
106 | #else | 122 | #else |
107 | static inline void regmap_debugfs_initcall(void) { } | 123 | static inline void regmap_debugfs_initcall(void) { } |
108 | static inline void regmap_debugfs_init(struct regmap *map) { } | 124 | static inline void regmap_debugfs_init(struct regmap *map, const char *name) { } |
109 | static inline void regmap_debugfs_exit(struct regmap *map) { } | 125 | static inline void regmap_debugfs_exit(struct regmap *map) { } |
110 | #endif | 126 | #endif |
111 | 127 | ||
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c index 483b06d4a380..afd6aa91a0df 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c | |||
@@ -108,7 +108,7 @@ static int regcache_lzo_decompress_cache_block(struct regmap *map, | |||
108 | static inline int regcache_lzo_get_blkindex(struct regmap *map, | 108 | static inline int regcache_lzo_get_blkindex(struct regmap *map, |
109 | unsigned int reg) | 109 | unsigned int reg) |
110 | { | 110 | { |
111 | return (reg * map->cache_word_size) / | 111 | return ((reg / map->reg_stride) * map->cache_word_size) / |
112 | DIV_ROUND_UP(map->cache_size_raw, | 112 | DIV_ROUND_UP(map->cache_size_raw, |
113 | regcache_lzo_block_count(map)); | 113 | regcache_lzo_block_count(map)); |
114 | } | 114 | } |
@@ -116,9 +116,10 @@ static inline int regcache_lzo_get_blkindex(struct regmap *map, | |||
116 | static inline int regcache_lzo_get_blkpos(struct regmap *map, | 116 | static inline int regcache_lzo_get_blkpos(struct regmap *map, |
117 | unsigned int reg) | 117 | unsigned int reg) |
118 | { | 118 | { |
119 | return reg % (DIV_ROUND_UP(map->cache_size_raw, | 119 | return (reg / map->reg_stride) % |
120 | regcache_lzo_block_count(map)) / | 120 | (DIV_ROUND_UP(map->cache_size_raw, |
121 | map->cache_word_size); | 121 | regcache_lzo_block_count(map)) / |
122 | map->cache_word_size); | ||
122 | } | 123 | } |
123 | 124 | ||
124 | static inline int regcache_lzo_get_blksize(struct regmap *map) | 125 | static inline int regcache_lzo_get_blksize(struct regmap *map) |
@@ -322,7 +323,7 @@ static int regcache_lzo_write(struct regmap *map, | |||
322 | } | 323 | } |
323 | 324 | ||
324 | /* set the bit so we know we have to sync this register */ | 325 | /* set the bit so we know we have to sync this register */ |
325 | set_bit(reg, lzo_block->sync_bmp); | 326 | set_bit(reg / map->reg_stride, lzo_block->sync_bmp); |
326 | kfree(tmp_dst); | 327 | kfree(tmp_dst); |
327 | kfree(lzo_block->src); | 328 | kfree(lzo_block->src); |
328 | return 0; | 329 | return 0; |
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 92b779ee002b..e6732cf7c06e 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c | |||
@@ -39,11 +39,12 @@ struct regcache_rbtree_ctx { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | static inline void regcache_rbtree_get_base_top_reg( | 41 | static inline void regcache_rbtree_get_base_top_reg( |
42 | struct regmap *map, | ||
42 | struct regcache_rbtree_node *rbnode, | 43 | struct regcache_rbtree_node *rbnode, |
43 | unsigned int *base, unsigned int *top) | 44 | unsigned int *base, unsigned int *top) |
44 | { | 45 | { |
45 | *base = rbnode->base_reg; | 46 | *base = rbnode->base_reg; |
46 | *top = rbnode->base_reg + rbnode->blklen - 1; | 47 | *top = rbnode->base_reg + ((rbnode->blklen - 1) * map->reg_stride); |
47 | } | 48 | } |
48 | 49 | ||
49 | static unsigned int regcache_rbtree_get_register( | 50 | static unsigned int regcache_rbtree_get_register( |
@@ -70,7 +71,8 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, | |||
70 | 71 | ||
71 | rbnode = rbtree_ctx->cached_rbnode; | 72 | rbnode = rbtree_ctx->cached_rbnode; |
72 | if (rbnode) { | 73 | if (rbnode) { |
73 | regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg); | 74 | regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg, |
75 | &top_reg); | ||
74 | if (reg >= base_reg && reg <= top_reg) | 76 | if (reg >= base_reg && reg <= top_reg) |
75 | return rbnode; | 77 | return rbnode; |
76 | } | 78 | } |
@@ -78,7 +80,8 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, | |||
78 | node = rbtree_ctx->root.rb_node; | 80 | node = rbtree_ctx->root.rb_node; |
79 | while (node) { | 81 | while (node) { |
80 | rbnode = container_of(node, struct regcache_rbtree_node, node); | 82 | rbnode = container_of(node, struct regcache_rbtree_node, node); |
81 | regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg); | 83 | regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg, |
84 | &top_reg); | ||
82 | if (reg >= base_reg && reg <= top_reg) { | 85 | if (reg >= base_reg && reg <= top_reg) { |
83 | rbtree_ctx->cached_rbnode = rbnode; | 86 | rbtree_ctx->cached_rbnode = rbnode; |
84 | return rbnode; | 87 | return rbnode; |
@@ -92,7 +95,7 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, | |||
92 | return NULL; | 95 | return NULL; |
93 | } | 96 | } |
94 | 97 | ||
95 | static int regcache_rbtree_insert(struct rb_root *root, | 98 | static int regcache_rbtree_insert(struct regmap *map, struct rb_root *root, |
96 | struct regcache_rbtree_node *rbnode) | 99 | struct regcache_rbtree_node *rbnode) |
97 | { | 100 | { |
98 | struct rb_node **new, *parent; | 101 | struct rb_node **new, *parent; |
@@ -106,7 +109,7 @@ static int regcache_rbtree_insert(struct rb_root *root, | |||
106 | rbnode_tmp = container_of(*new, struct regcache_rbtree_node, | 109 | rbnode_tmp = container_of(*new, struct regcache_rbtree_node, |
107 | node); | 110 | node); |
108 | /* base and top registers of the current rbnode */ | 111 | /* base and top registers of the current rbnode */ |
109 | regcache_rbtree_get_base_top_reg(rbnode_tmp, &base_reg_tmp, | 112 | regcache_rbtree_get_base_top_reg(map, rbnode_tmp, &base_reg_tmp, |
110 | &top_reg_tmp); | 113 | &top_reg_tmp); |
111 | /* base register of the rbnode to be added */ | 114 | /* base register of the rbnode to be added */ |
112 | base_reg = rbnode->base_reg; | 115 | base_reg = rbnode->base_reg; |
@@ -138,19 +141,20 @@ static int rbtree_show(struct seq_file *s, void *ignored) | |||
138 | unsigned int base, top; | 141 | unsigned int base, top; |
139 | int nodes = 0; | 142 | int nodes = 0; |
140 | int registers = 0; | 143 | int registers = 0; |
141 | int average; | 144 | int this_registers, average; |
142 | 145 | ||
143 | mutex_lock(&map->lock); | 146 | map->lock(map); |
144 | 147 | ||
145 | for (node = rb_first(&rbtree_ctx->root); node != NULL; | 148 | for (node = rb_first(&rbtree_ctx->root); node != NULL; |
146 | node = rb_next(node)) { | 149 | node = rb_next(node)) { |
147 | n = container_of(node, struct regcache_rbtree_node, node); | 150 | n = container_of(node, struct regcache_rbtree_node, node); |
148 | 151 | ||
149 | regcache_rbtree_get_base_top_reg(n, &base, &top); | 152 | regcache_rbtree_get_base_top_reg(map, n, &base, &top); |
150 | seq_printf(s, "%x-%x (%d)\n", base, top, top - base + 1); | 153 | this_registers = ((top - base) / map->reg_stride) + 1; |
154 | seq_printf(s, "%x-%x (%d)\n", base, top, this_registers); | ||
151 | 155 | ||
152 | nodes++; | 156 | nodes++; |
153 | registers += top - base + 1; | 157 | registers += this_registers; |
154 | } | 158 | } |
155 | 159 | ||
156 | if (nodes) | 160 | if (nodes) |
@@ -161,7 +165,7 @@ static int rbtree_show(struct seq_file *s, void *ignored) | |||
161 | seq_printf(s, "%d nodes, %d registers, average %d registers\n", | 165 | seq_printf(s, "%d nodes, %d registers, average %d registers\n", |
162 | nodes, registers, average); | 166 | nodes, registers, average); |
163 | 167 | ||
164 | mutex_unlock(&map->lock); | 168 | map->unlock(map); |
165 | 169 | ||
166 | return 0; | 170 | return 0; |
167 | } | 171 | } |
@@ -255,7 +259,7 @@ static int regcache_rbtree_read(struct regmap *map, | |||
255 | 259 | ||
256 | rbnode = regcache_rbtree_lookup(map, reg); | 260 | rbnode = regcache_rbtree_lookup(map, reg); |
257 | if (rbnode) { | 261 | if (rbnode) { |
258 | reg_tmp = reg - rbnode->base_reg; | 262 | reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; |
259 | *value = regcache_rbtree_get_register(rbnode, reg_tmp, | 263 | *value = regcache_rbtree_get_register(rbnode, reg_tmp, |
260 | map->cache_word_size); | 264 | map->cache_word_size); |
261 | } else { | 265 | } else { |
@@ -310,7 +314,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, | |||
310 | */ | 314 | */ |
311 | rbnode = regcache_rbtree_lookup(map, reg); | 315 | rbnode = regcache_rbtree_lookup(map, reg); |
312 | if (rbnode) { | 316 | if (rbnode) { |
313 | reg_tmp = reg - rbnode->base_reg; | 317 | reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; |
314 | val = regcache_rbtree_get_register(rbnode, reg_tmp, | 318 | val = regcache_rbtree_get_register(rbnode, reg_tmp, |
315 | map->cache_word_size); | 319 | map->cache_word_size); |
316 | if (val == value) | 320 | if (val == value) |
@@ -321,13 +325,15 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, | |||
321 | /* look for an adjacent register to the one we are about to add */ | 325 | /* look for an adjacent register to the one we are about to add */ |
322 | for (node = rb_first(&rbtree_ctx->root); node; | 326 | for (node = rb_first(&rbtree_ctx->root); node; |
323 | node = rb_next(node)) { | 327 | node = rb_next(node)) { |
324 | rbnode_tmp = rb_entry(node, struct regcache_rbtree_node, node); | 328 | rbnode_tmp = rb_entry(node, struct regcache_rbtree_node, |
329 | node); | ||
325 | for (i = 0; i < rbnode_tmp->blklen; i++) { | 330 | for (i = 0; i < rbnode_tmp->blklen; i++) { |
326 | reg_tmp = rbnode_tmp->base_reg + i; | 331 | reg_tmp = rbnode_tmp->base_reg + |
327 | if (abs(reg_tmp - reg) != 1) | 332 | (i * map->reg_stride); |
333 | if (abs(reg_tmp - reg) != map->reg_stride) | ||
328 | continue; | 334 | continue; |
329 | /* decide where in the block to place our register */ | 335 | /* decide where in the block to place our register */ |
330 | if (reg_tmp + 1 == reg) | 336 | if (reg_tmp + map->reg_stride == reg) |
331 | pos = i + 1; | 337 | pos = i + 1; |
332 | else | 338 | else |
333 | pos = i; | 339 | pos = i; |
@@ -357,7 +363,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, | |||
357 | return -ENOMEM; | 363 | return -ENOMEM; |
358 | } | 364 | } |
359 | regcache_rbtree_set_register(rbnode, 0, value, map->cache_word_size); | 365 | regcache_rbtree_set_register(rbnode, 0, value, map->cache_word_size); |
360 | regcache_rbtree_insert(&rbtree_ctx->root, rbnode); | 366 | regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); |
361 | rbtree_ctx->cached_rbnode = rbnode; | 367 | rbtree_ctx->cached_rbnode = rbnode; |
362 | } | 368 | } |
363 | 369 | ||
@@ -397,7 +403,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, | |||
397 | end = rbnode->blklen; | 403 | end = rbnode->blklen; |
398 | 404 | ||
399 | for (i = base; i < end; i++) { | 405 | for (i = base; i < end; i++) { |
400 | regtmp = rbnode->base_reg + i; | 406 | regtmp = rbnode->base_reg + (i * map->reg_stride); |
401 | val = regcache_rbtree_get_register(rbnode, i, | 407 | val = regcache_rbtree_get_register(rbnode, i, |
402 | map->cache_word_size); | 408 | map->cache_word_size); |
403 | 409 | ||
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 74b69095def6..835883bda977 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c | |||
@@ -59,7 +59,7 @@ static int regcache_hw_init(struct regmap *map) | |||
59 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { | 59 | for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { |
60 | val = regcache_get_val(map->reg_defaults_raw, | 60 | val = regcache_get_val(map->reg_defaults_raw, |
61 | i, map->cache_word_size); | 61 | i, map->cache_word_size); |
62 | if (regmap_volatile(map, i)) | 62 | if (regmap_volatile(map, i * map->reg_stride)) |
63 | continue; | 63 | continue; |
64 | count++; | 64 | count++; |
65 | } | 65 | } |
@@ -76,9 +76,9 @@ static int regcache_hw_init(struct regmap *map) | |||
76 | for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { | 76 | for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { |
77 | val = regcache_get_val(map->reg_defaults_raw, | 77 | val = regcache_get_val(map->reg_defaults_raw, |
78 | i, map->cache_word_size); | 78 | i, map->cache_word_size); |
79 | if (regmap_volatile(map, i)) | 79 | if (regmap_volatile(map, i * map->reg_stride)) |
80 | continue; | 80 | continue; |
81 | map->reg_defaults[j].reg = i; | 81 | map->reg_defaults[j].reg = i * map->reg_stride; |
82 | map->reg_defaults[j].def = val; | 82 | map->reg_defaults[j].def = val; |
83 | j++; | 83 | j++; |
84 | } | 84 | } |
@@ -98,6 +98,10 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) | |||
98 | int i; | 98 | int i; |
99 | void *tmp_buf; | 99 | void *tmp_buf; |
100 | 100 | ||
101 | for (i = 0; i < config->num_reg_defaults; i++) | ||
102 | if (config->reg_defaults[i].reg % map->reg_stride) | ||
103 | return -EINVAL; | ||
104 | |||
101 | if (map->cache_type == REGCACHE_NONE) { | 105 | if (map->cache_type == REGCACHE_NONE) { |
102 | map->cache_bypass = true; | 106 | map->cache_bypass = true; |
103 | return 0; | 107 | return 0; |
@@ -264,7 +268,7 @@ int regcache_sync(struct regmap *map) | |||
264 | 268 | ||
265 | BUG_ON(!map->cache_ops || !map->cache_ops->sync); | 269 | BUG_ON(!map->cache_ops || !map->cache_ops->sync); |
266 | 270 | ||
267 | mutex_lock(&map->lock); | 271 | map->lock(map); |
268 | /* Remember the initial bypass state */ | 272 | /* Remember the initial bypass state */ |
269 | bypass = map->cache_bypass; | 273 | bypass = map->cache_bypass; |
270 | dev_dbg(map->dev, "Syncing %s cache\n", | 274 | dev_dbg(map->dev, "Syncing %s cache\n", |
@@ -278,6 +282,10 @@ int regcache_sync(struct regmap *map) | |||
278 | /* Apply any patch first */ | 282 | /* Apply any patch first */ |
279 | map->cache_bypass = 1; | 283 | map->cache_bypass = 1; |
280 | for (i = 0; i < map->patch_regs; i++) { | 284 | for (i = 0; i < map->patch_regs; i++) { |
285 | if (map->patch[i].reg % map->reg_stride) { | ||
286 | ret = -EINVAL; | ||
287 | goto out; | ||
288 | } | ||
281 | ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); | 289 | ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); |
282 | if (ret != 0) { | 290 | if (ret != 0) { |
283 | dev_err(map->dev, "Failed to write %x = %x: %d\n", | 291 | dev_err(map->dev, "Failed to write %x = %x: %d\n", |
@@ -296,7 +304,7 @@ out: | |||
296 | trace_regcache_sync(map->dev, name, "stop"); | 304 | trace_regcache_sync(map->dev, name, "stop"); |
297 | /* Restore the bypass state */ | 305 | /* Restore the bypass state */ |
298 | map->cache_bypass = bypass; | 306 | map->cache_bypass = bypass; |
299 | mutex_unlock(&map->lock); | 307 | map->unlock(map); |
300 | 308 | ||
301 | return ret; | 309 | return ret; |
302 | } | 310 | } |
@@ -323,7 +331,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, | |||
323 | 331 | ||
324 | BUG_ON(!map->cache_ops || !map->cache_ops->sync); | 332 | BUG_ON(!map->cache_ops || !map->cache_ops->sync); |
325 | 333 | ||
326 | mutex_lock(&map->lock); | 334 | map->lock(map); |
327 | 335 | ||
328 | /* Remember the initial bypass state */ | 336 | /* Remember the initial bypass state */ |
329 | bypass = map->cache_bypass; | 337 | bypass = map->cache_bypass; |
@@ -342,7 +350,7 @@ out: | |||
342 | trace_regcache_sync(map->dev, name, "stop region"); | 350 | trace_regcache_sync(map->dev, name, "stop region"); |
343 | /* Restore the bypass state */ | 351 | /* Restore the bypass state */ |
344 | map->cache_bypass = bypass; | 352 | map->cache_bypass = bypass; |
345 | mutex_unlock(&map->lock); | 353 | map->unlock(map); |
346 | 354 | ||
347 | return ret; | 355 | return ret; |
348 | } | 356 | } |
@@ -362,11 +370,11 @@ EXPORT_SYMBOL_GPL(regcache_sync_region); | |||
362 | */ | 370 | */ |
363 | void regcache_cache_only(struct regmap *map, bool enable) | 371 | void regcache_cache_only(struct regmap *map, bool enable) |
364 | { | 372 | { |
365 | mutex_lock(&map->lock); | 373 | map->lock(map); |
366 | WARN_ON(map->cache_bypass && enable); | 374 | WARN_ON(map->cache_bypass && enable); |
367 | map->cache_only = enable; | 375 | map->cache_only = enable; |
368 | trace_regmap_cache_only(map->dev, enable); | 376 | trace_regmap_cache_only(map->dev, enable); |
369 | mutex_unlock(&map->lock); | 377 | map->unlock(map); |
370 | } | 378 | } |
371 | EXPORT_SYMBOL_GPL(regcache_cache_only); | 379 | EXPORT_SYMBOL_GPL(regcache_cache_only); |
372 | 380 | ||
@@ -381,9 +389,9 @@ EXPORT_SYMBOL_GPL(regcache_cache_only); | |||
381 | */ | 389 | */ |
382 | void regcache_mark_dirty(struct regmap *map) | 390 | void regcache_mark_dirty(struct regmap *map) |
383 | { | 391 | { |
384 | mutex_lock(&map->lock); | 392 | map->lock(map); |
385 | map->cache_dirty = true; | 393 | map->cache_dirty = true; |
386 | mutex_unlock(&map->lock); | 394 | map->unlock(map); |
387 | } | 395 | } |
388 | EXPORT_SYMBOL_GPL(regcache_mark_dirty); | 396 | EXPORT_SYMBOL_GPL(regcache_mark_dirty); |
389 | 397 | ||
@@ -400,11 +408,11 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty); | |||
400 | */ | 408 | */ |
401 | void regcache_cache_bypass(struct regmap *map, bool enable) | 409 | void regcache_cache_bypass(struct regmap *map, bool enable) |
402 | { | 410 | { |
403 | mutex_lock(&map->lock); | 411 | map->lock(map); |
404 | WARN_ON(map->cache_only && enable); | 412 | WARN_ON(map->cache_only && enable); |
405 | map->cache_bypass = enable; | 413 | map->cache_bypass = enable; |
406 | trace_regmap_cache_bypass(map->dev, enable); | 414 | trace_regmap_cache_bypass(map->dev, enable); |
407 | mutex_unlock(&map->lock); | 415 | map->unlock(map); |
408 | } | 416 | } |
409 | EXPORT_SYMBOL_GPL(regcache_cache_bypass); | 417 | EXPORT_SYMBOL_GPL(regcache_cache_bypass); |
410 | 418 | ||
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 251eb70f83e7..bb1ff175b962 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c | |||
@@ -80,7 +80,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, | |||
80 | val_len = 2 * map->format.val_bytes; | 80 | val_len = 2 * map->format.val_bytes; |
81 | tot_len = reg_len + val_len + 3; /* : \n */ | 81 | tot_len = reg_len + val_len + 3; /* : \n */ |
82 | 82 | ||
83 | for (i = 0; i < map->max_register + 1; i++) { | 83 | for (i = 0; i <= map->max_register; i += map->reg_stride) { |
84 | if (!regmap_readable(map, i)) | 84 | if (!regmap_readable(map, i)) |
85 | continue; | 85 | continue; |
86 | 86 | ||
@@ -197,7 +197,7 @@ static ssize_t regmap_access_read_file(struct file *file, | |||
197 | reg_len = regmap_calc_reg_len(map->max_register, buf, count); | 197 | reg_len = regmap_calc_reg_len(map->max_register, buf, count); |
198 | tot_len = reg_len + 10; /* ': R W V P\n' */ | 198 | tot_len = reg_len + 10; /* ': R W V P\n' */ |
199 | 199 | ||
200 | for (i = 0; i < map->max_register + 1; i++) { | 200 | for (i = 0; i <= map->max_register; i += map->reg_stride) { |
201 | /* Ignore registers which are neither readable nor writable */ | 201 | /* Ignore registers which are neither readable nor writable */ |
202 | if (!regmap_readable(map, i) && !regmap_writeable(map, i)) | 202 | if (!regmap_readable(map, i) && !regmap_writeable(map, i)) |
203 | continue; | 203 | continue; |
@@ -242,10 +242,17 @@ static const struct file_operations regmap_access_fops = { | |||
242 | .llseek = default_llseek, | 242 | .llseek = default_llseek, |
243 | }; | 243 | }; |
244 | 244 | ||
245 | void regmap_debugfs_init(struct regmap *map) | 245 | void regmap_debugfs_init(struct regmap *map, const char *name) |
246 | { | 246 | { |
247 | map->debugfs = debugfs_create_dir(dev_name(map->dev), | 247 | if (name) { |
248 | regmap_debugfs_root); | 248 | map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", |
249 | dev_name(map->dev), name); | ||
250 | name = map->debugfs_name; | ||
251 | } else { | ||
252 | name = dev_name(map->dev); | ||
253 | } | ||
254 | |||
255 | map->debugfs = debugfs_create_dir(name, regmap_debugfs_root); | ||
249 | if (!map->debugfs) { | 256 | if (!map->debugfs) { |
250 | dev_warn(map->dev, "Failed to create debugfs directory\n"); | 257 | dev_warn(map->dev, "Failed to create debugfs directory\n"); |
251 | return; | 258 | return; |
@@ -274,6 +281,7 @@ void regmap_debugfs_init(struct regmap *map) | |||
274 | void regmap_debugfs_exit(struct regmap *map) | 281 | void regmap_debugfs_exit(struct regmap *map) |
275 | { | 282 | { |
276 | debugfs_remove_recursive(map->debugfs); | 283 | debugfs_remove_recursive(map->debugfs); |
284 | kfree(map->debugfs_name); | ||
277 | } | 285 | } |
278 | 286 | ||
279 | void regmap_debugfs_initcall(void) | 287 | void regmap_debugfs_initcall(void) |
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 9a3a8c564389..5f6b2478bf17 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c | |||
@@ -15,8 +15,9 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | 17 | ||
18 | static int regmap_i2c_write(struct device *dev, const void *data, size_t count) | 18 | static int regmap_i2c_write(void *context, const void *data, size_t count) |
19 | { | 19 | { |
20 | struct device *dev = context; | ||
20 | struct i2c_client *i2c = to_i2c_client(dev); | 21 | struct i2c_client *i2c = to_i2c_client(dev); |
21 | int ret; | 22 | int ret; |
22 | 23 | ||
@@ -29,10 +30,11 @@ static int regmap_i2c_write(struct device *dev, const void *data, size_t count) | |||
29 | return -EIO; | 30 | return -EIO; |
30 | } | 31 | } |
31 | 32 | ||
32 | static int regmap_i2c_gather_write(struct device *dev, | 33 | static int regmap_i2c_gather_write(void *context, |
33 | const void *reg, size_t reg_size, | 34 | const void *reg, size_t reg_size, |
34 | const void *val, size_t val_size) | 35 | const void *val, size_t val_size) |
35 | { | 36 | { |
37 | struct device *dev = context; | ||
36 | struct i2c_client *i2c = to_i2c_client(dev); | 38 | struct i2c_client *i2c = to_i2c_client(dev); |
37 | struct i2c_msg xfer[2]; | 39 | struct i2c_msg xfer[2]; |
38 | int ret; | 40 | int ret; |
@@ -62,10 +64,11 @@ static int regmap_i2c_gather_write(struct device *dev, | |||
62 | return -EIO; | 64 | return -EIO; |
63 | } | 65 | } |
64 | 66 | ||
65 | static int regmap_i2c_read(struct device *dev, | 67 | static int regmap_i2c_read(void *context, |
66 | const void *reg, size_t reg_size, | 68 | const void *reg, size_t reg_size, |
67 | void *val, size_t val_size) | 69 | void *val, size_t val_size) |
68 | { | 70 | { |
71 | struct device *dev = context; | ||
69 | struct i2c_client *i2c = to_i2c_client(dev); | 72 | struct i2c_client *i2c = to_i2c_client(dev); |
70 | struct i2c_msg xfer[2]; | 73 | struct i2c_msg xfer[2]; |
71 | int ret; | 74 | int ret; |
@@ -107,7 +110,7 @@ static struct regmap_bus regmap_i2c = { | |||
107 | struct regmap *regmap_init_i2c(struct i2c_client *i2c, | 110 | struct regmap *regmap_init_i2c(struct i2c_client *i2c, |
108 | const struct regmap_config *config) | 111 | const struct regmap_config *config) |
109 | { | 112 | { |
110 | return regmap_init(&i2c->dev, ®map_i2c, config); | 113 | return regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config); |
111 | } | 114 | } |
112 | EXPORT_SYMBOL_GPL(regmap_init_i2c); | 115 | EXPORT_SYMBOL_GPL(regmap_init_i2c); |
113 | 116 | ||
@@ -124,7 +127,7 @@ EXPORT_SYMBOL_GPL(regmap_init_i2c); | |||
124 | struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, | 127 | struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, |
125 | const struct regmap_config *config) | 128 | const struct regmap_config *config) |
126 | { | 129 | { |
127 | return devm_regmap_init(&i2c->dev, ®map_i2c, config); | 130 | return devm_regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config); |
128 | } | 131 | } |
129 | EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); | 132 | EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); |
130 | 133 | ||
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 1befaa7a31cb..4fac4b9be88f 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/regmap.h> | 15 | #include <linux/regmap.h> |
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/irqdomain.h> | ||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | 20 | ||
20 | #include "internal.h" | 21 | #include "internal.h" |
@@ -26,18 +27,20 @@ struct regmap_irq_chip_data { | |||
26 | struct regmap_irq_chip *chip; | 27 | struct regmap_irq_chip *chip; |
27 | 28 | ||
28 | int irq_base; | 29 | int irq_base; |
30 | struct irq_domain *domain; | ||
29 | 31 | ||
30 | void *status_reg_buf; | ||
31 | unsigned int *status_buf; | 32 | unsigned int *status_buf; |
32 | unsigned int *mask_buf; | 33 | unsigned int *mask_buf; |
33 | unsigned int *mask_buf_def; | 34 | unsigned int *mask_buf_def; |
35 | |||
36 | unsigned int irq_reg_stride; | ||
34 | }; | 37 | }; |
35 | 38 | ||
36 | static inline const | 39 | static inline const |
37 | struct regmap_irq *irq_to_regmap_irq(struct regmap_irq_chip_data *data, | 40 | struct regmap_irq *irq_to_regmap_irq(struct regmap_irq_chip_data *data, |
38 | int irq) | 41 | int irq) |
39 | { | 42 | { |
40 | return &data->chip->irqs[irq - data->irq_base]; | 43 | return &data->chip->irqs[irq]; |
41 | } | 44 | } |
42 | 45 | ||
43 | static void regmap_irq_lock(struct irq_data *data) | 46 | static void regmap_irq_lock(struct irq_data *data) |
@@ -50,6 +53,7 @@ static void regmap_irq_lock(struct irq_data *data) | |||
50 | static void regmap_irq_sync_unlock(struct irq_data *data) | 53 | static void regmap_irq_sync_unlock(struct irq_data *data) |
51 | { | 54 | { |
52 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); | 55 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); |
56 | struct regmap *map = d->map; | ||
53 | int i, ret; | 57 | int i, ret; |
54 | 58 | ||
55 | /* | 59 | /* |
@@ -58,11 +62,13 @@ static void regmap_irq_sync_unlock(struct irq_data *data) | |||
58 | * suppress pointless writes. | 62 | * suppress pointless writes. |
59 | */ | 63 | */ |
60 | for (i = 0; i < d->chip->num_regs; i++) { | 64 | for (i = 0; i < d->chip->num_regs; i++) { |
61 | ret = regmap_update_bits(d->map, d->chip->mask_base + i, | 65 | ret = regmap_update_bits(d->map, d->chip->mask_base + |
66 | (i * map->reg_stride * | ||
67 | d->irq_reg_stride), | ||
62 | d->mask_buf_def[i], d->mask_buf[i]); | 68 | d->mask_buf_def[i], d->mask_buf[i]); |
63 | if (ret != 0) | 69 | if (ret != 0) |
64 | dev_err(d->map->dev, "Failed to sync masks in %x\n", | 70 | dev_err(d->map->dev, "Failed to sync masks in %x\n", |
65 | d->chip->mask_base + i); | 71 | d->chip->mask_base + (i * map->reg_stride)); |
66 | } | 72 | } |
67 | 73 | ||
68 | mutex_unlock(&d->lock); | 74 | mutex_unlock(&d->lock); |
@@ -71,17 +77,19 @@ static void regmap_irq_sync_unlock(struct irq_data *data) | |||
71 | static void regmap_irq_enable(struct irq_data *data) | 77 | static void regmap_irq_enable(struct irq_data *data) |
72 | { | 78 | { |
73 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); | 79 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); |
74 | const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); | 80 | struct regmap *map = d->map; |
81 | const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); | ||
75 | 82 | ||
76 | d->mask_buf[irq_data->reg_offset] &= ~irq_data->mask; | 83 | d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask; |
77 | } | 84 | } |
78 | 85 | ||
79 | static void regmap_irq_disable(struct irq_data *data) | 86 | static void regmap_irq_disable(struct irq_data *data) |
80 | { | 87 | { |
81 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); | 88 | struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); |
82 | const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); | 89 | struct regmap *map = d->map; |
90 | const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); | ||
83 | 91 | ||
84 | d->mask_buf[irq_data->reg_offset] |= irq_data->mask; | 92 | d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; |
85 | } | 93 | } |
86 | 94 | ||
87 | static struct irq_chip regmap_irq_chip = { | 95 | static struct irq_chip regmap_irq_chip = { |
@@ -98,18 +106,8 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) | |||
98 | struct regmap_irq_chip *chip = data->chip; | 106 | struct regmap_irq_chip *chip = data->chip; |
99 | struct regmap *map = data->map; | 107 | struct regmap *map = data->map; |
100 | int ret, i; | 108 | int ret, i; |
101 | u8 *buf8 = data->status_reg_buf; | ||
102 | u16 *buf16 = data->status_reg_buf; | ||
103 | u32 *buf32 = data->status_reg_buf; | ||
104 | bool handled = false; | 109 | bool handled = false; |
105 | 110 | ||
106 | ret = regmap_bulk_read(map, chip->status_base, data->status_reg_buf, | ||
107 | chip->num_regs); | ||
108 | if (ret != 0) { | ||
109 | dev_err(map->dev, "Failed to read IRQ status: %d\n", ret); | ||
110 | return IRQ_NONE; | ||
111 | } | ||
112 | |||
113 | /* | 111 | /* |
114 | * Ignore masked IRQs and ack if we need to; we ack early so | 112 | * Ignore masked IRQs and ack if we need to; we ack early so |
115 | * there is no race between handling and acknowleding the | 113 | * there is no race between handling and acknowleding the |
@@ -118,36 +116,34 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) | |||
118 | * doing a write per register. | 116 | * doing a write per register. |
119 | */ | 117 | */ |
120 | for (i = 0; i < data->chip->num_regs; i++) { | 118 | for (i = 0; i < data->chip->num_regs; i++) { |
121 | switch (map->format.val_bytes) { | 119 | ret = regmap_read(map, chip->status_base + (i * map->reg_stride |
122 | case 1: | 120 | * data->irq_reg_stride), |
123 | data->status_buf[i] = buf8[i]; | 121 | &data->status_buf[i]); |
124 | break; | 122 | |
125 | case 2: | 123 | if (ret != 0) { |
126 | data->status_buf[i] = buf16[i]; | 124 | dev_err(map->dev, "Failed to read IRQ status: %d\n", |
127 | break; | 125 | ret); |
128 | case 4: | ||
129 | data->status_buf[i] = buf32[i]; | ||
130 | break; | ||
131 | default: | ||
132 | BUG(); | ||
133 | return IRQ_NONE; | 126 | return IRQ_NONE; |
134 | } | 127 | } |
135 | 128 | ||
136 | data->status_buf[i] &= ~data->mask_buf[i]; | 129 | data->status_buf[i] &= ~data->mask_buf[i]; |
137 | 130 | ||
138 | if (data->status_buf[i] && chip->ack_base) { | 131 | if (data->status_buf[i] && chip->ack_base) { |
139 | ret = regmap_write(map, chip->ack_base + i, | 132 | ret = regmap_write(map, chip->ack_base + |
133 | (i * map->reg_stride * | ||
134 | data->irq_reg_stride), | ||
140 | data->status_buf[i]); | 135 | data->status_buf[i]); |
141 | if (ret != 0) | 136 | if (ret != 0) |
142 | dev_err(map->dev, "Failed to ack 0x%x: %d\n", | 137 | dev_err(map->dev, "Failed to ack 0x%x: %d\n", |
143 | chip->ack_base + i, ret); | 138 | chip->ack_base + (i * map->reg_stride), |
139 | ret); | ||
144 | } | 140 | } |
145 | } | 141 | } |
146 | 142 | ||
147 | for (i = 0; i < chip->num_irqs; i++) { | 143 | for (i = 0; i < chip->num_irqs; i++) { |
148 | if (data->status_buf[chip->irqs[i].reg_offset] & | 144 | if (data->status_buf[chip->irqs[i].reg_offset / |
149 | chip->irqs[i].mask) { | 145 | map->reg_stride] & chip->irqs[i].mask) { |
150 | handle_nested_irq(data->irq_base + i); | 146 | handle_nested_irq(irq_find_mapping(data->domain, i)); |
151 | handled = true; | 147 | handled = true; |
152 | } | 148 | } |
153 | } | 149 | } |
@@ -158,6 +154,31 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) | |||
158 | return IRQ_NONE; | 154 | return IRQ_NONE; |
159 | } | 155 | } |
160 | 156 | ||
157 | static int regmap_irq_map(struct irq_domain *h, unsigned int virq, | ||
158 | irq_hw_number_t hw) | ||
159 | { | ||
160 | struct regmap_irq_chip_data *data = h->host_data; | ||
161 | |||
162 | irq_set_chip_data(virq, data); | ||
163 | irq_set_chip_and_handler(virq, ®map_irq_chip, handle_edge_irq); | ||
164 | irq_set_nested_thread(virq, 1); | ||
165 | |||
166 | /* ARM needs us to explicitly flag the IRQ as valid | ||
167 | * and will set them noprobe when we do so. */ | ||
168 | #ifdef CONFIG_ARM | ||
169 | set_irq_flags(virq, IRQF_VALID); | ||
170 | #else | ||
171 | irq_set_noprobe(virq); | ||
172 | #endif | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static struct irq_domain_ops regmap_domain_ops = { | ||
178 | .map = regmap_irq_map, | ||
179 | .xlate = irq_domain_xlate_twocell, | ||
180 | }; | ||
181 | |||
161 | /** | 182 | /** |
162 | * regmap_add_irq_chip(): Use standard regmap IRQ controller handling | 183 | * regmap_add_irq_chip(): Use standard regmap IRQ controller handling |
163 | * | 184 | * |
@@ -178,30 +199,37 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | |||
178 | struct regmap_irq_chip_data **data) | 199 | struct regmap_irq_chip_data **data) |
179 | { | 200 | { |
180 | struct regmap_irq_chip_data *d; | 201 | struct regmap_irq_chip_data *d; |
181 | int cur_irq, i; | 202 | int i; |
182 | int ret = -ENOMEM; | 203 | int ret = -ENOMEM; |
183 | 204 | ||
184 | irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0); | 205 | for (i = 0; i < chip->num_irqs; i++) { |
185 | if (irq_base < 0) { | 206 | if (chip->irqs[i].reg_offset % map->reg_stride) |
186 | dev_warn(map->dev, "Failed to allocate IRQs: %d\n", | 207 | return -EINVAL; |
187 | irq_base); | 208 | if (chip->irqs[i].reg_offset / map->reg_stride >= |
188 | return irq_base; | 209 | chip->num_regs) |
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | if (irq_base) { | ||
214 | irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0); | ||
215 | if (irq_base < 0) { | ||
216 | dev_warn(map->dev, "Failed to allocate IRQs: %d\n", | ||
217 | irq_base); | ||
218 | return irq_base; | ||
219 | } | ||
189 | } | 220 | } |
190 | 221 | ||
191 | d = kzalloc(sizeof(*d), GFP_KERNEL); | 222 | d = kzalloc(sizeof(*d), GFP_KERNEL); |
192 | if (!d) | 223 | if (!d) |
193 | return -ENOMEM; | 224 | return -ENOMEM; |
194 | 225 | ||
226 | *data = d; | ||
227 | |||
195 | d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, | 228 | d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, |
196 | GFP_KERNEL); | 229 | GFP_KERNEL); |
197 | if (!d->status_buf) | 230 | if (!d->status_buf) |
198 | goto err_alloc; | 231 | goto err_alloc; |
199 | 232 | ||
200 | d->status_reg_buf = kzalloc(map->format.val_bytes * chip->num_regs, | ||
201 | GFP_KERNEL); | ||
202 | if (!d->status_reg_buf) | ||
203 | goto err_alloc; | ||
204 | |||
205 | d->mask_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, | 233 | d->mask_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, |
206 | GFP_KERNEL); | 234 | GFP_KERNEL); |
207 | if (!d->mask_buf) | 235 | if (!d->mask_buf) |
@@ -215,54 +243,59 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | |||
215 | d->map = map; | 243 | d->map = map; |
216 | d->chip = chip; | 244 | d->chip = chip; |
217 | d->irq_base = irq_base; | 245 | d->irq_base = irq_base; |
246 | |||
247 | if (chip->irq_reg_stride) | ||
248 | d->irq_reg_stride = chip->irq_reg_stride; | ||
249 | else | ||
250 | d->irq_reg_stride = 1; | ||
251 | |||
218 | mutex_init(&d->lock); | 252 | mutex_init(&d->lock); |
219 | 253 | ||
220 | for (i = 0; i < chip->num_irqs; i++) | 254 | for (i = 0; i < chip->num_irqs; i++) |
221 | d->mask_buf_def[chip->irqs[i].reg_offset] | 255 | d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride] |
222 | |= chip->irqs[i].mask; | 256 | |= chip->irqs[i].mask; |
223 | 257 | ||
224 | /* Mask all the interrupts by default */ | 258 | /* Mask all the interrupts by default */ |
225 | for (i = 0; i < chip->num_regs; i++) { | 259 | for (i = 0; i < chip->num_regs; i++) { |
226 | d->mask_buf[i] = d->mask_buf_def[i]; | 260 | d->mask_buf[i] = d->mask_buf_def[i]; |
227 | ret = regmap_write(map, chip->mask_base + i, d->mask_buf[i]); | 261 | ret = regmap_write(map, chip->mask_base + (i * map->reg_stride |
262 | * d->irq_reg_stride), | ||
263 | d->mask_buf[i]); | ||
228 | if (ret != 0) { | 264 | if (ret != 0) { |
229 | dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", | 265 | dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", |
230 | chip->mask_base + i, ret); | 266 | chip->mask_base + (i * map->reg_stride), ret); |
231 | goto err_alloc; | 267 | goto err_alloc; |
232 | } | 268 | } |
233 | } | 269 | } |
234 | 270 | ||
235 | /* Register them with genirq */ | 271 | if (irq_base) |
236 | for (cur_irq = irq_base; | 272 | d->domain = irq_domain_add_legacy(map->dev->of_node, |
237 | cur_irq < chip->num_irqs + irq_base; | 273 | chip->num_irqs, irq_base, 0, |
238 | cur_irq++) { | 274 | ®map_domain_ops, d); |
239 | irq_set_chip_data(cur_irq, d); | 275 | else |
240 | irq_set_chip_and_handler(cur_irq, ®map_irq_chip, | 276 | d->domain = irq_domain_add_linear(map->dev->of_node, |
241 | handle_edge_irq); | 277 | chip->num_irqs, |
242 | irq_set_nested_thread(cur_irq, 1); | 278 | ®map_domain_ops, d); |
243 | 279 | if (!d->domain) { | |
244 | /* ARM needs us to explicitly flag the IRQ as valid | 280 | dev_err(map->dev, "Failed to create IRQ domain\n"); |
245 | * and will set them noprobe when we do so. */ | 281 | ret = -ENOMEM; |
246 | #ifdef CONFIG_ARM | 282 | goto err_alloc; |
247 | set_irq_flags(cur_irq, IRQF_VALID); | ||
248 | #else | ||
249 | irq_set_noprobe(cur_irq); | ||
250 | #endif | ||
251 | } | 283 | } |
252 | 284 | ||
253 | ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags, | 285 | ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags, |
254 | chip->name, d); | 286 | chip->name, d); |
255 | if (ret != 0) { | 287 | if (ret != 0) { |
256 | dev_err(map->dev, "Failed to request IRQ %d: %d\n", irq, ret); | 288 | dev_err(map->dev, "Failed to request IRQ %d: %d\n", irq, ret); |
257 | goto err_alloc; | 289 | goto err_domain; |
258 | } | 290 | } |
259 | 291 | ||
260 | return 0; | 292 | return 0; |
261 | 293 | ||
294 | err_domain: | ||
295 | /* Should really dispose of the domain but... */ | ||
262 | err_alloc: | 296 | err_alloc: |
263 | kfree(d->mask_buf_def); | 297 | kfree(d->mask_buf_def); |
264 | kfree(d->mask_buf); | 298 | kfree(d->mask_buf); |
265 | kfree(d->status_reg_buf); | ||
266 | kfree(d->status_buf); | 299 | kfree(d->status_buf); |
267 | kfree(d); | 300 | kfree(d); |
268 | return ret; | 301 | return ret; |
@@ -281,9 +314,9 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) | |||
281 | return; | 314 | return; |
282 | 315 | ||
283 | free_irq(irq, d); | 316 | free_irq(irq, d); |
317 | /* We should unmap the domain but... */ | ||
284 | kfree(d->mask_buf_def); | 318 | kfree(d->mask_buf_def); |
285 | kfree(d->mask_buf); | 319 | kfree(d->mask_buf); |
286 | kfree(d->status_reg_buf); | ||
287 | kfree(d->status_buf); | 320 | kfree(d->status_buf); |
288 | kfree(d); | 321 | kfree(d); |
289 | } | 322 | } |
@@ -298,6 +331,21 @@ EXPORT_SYMBOL_GPL(regmap_del_irq_chip); | |||
298 | */ | 331 | */ |
299 | int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data) | 332 | int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data) |
300 | { | 333 | { |
334 | WARN_ON(!data->irq_base); | ||
301 | return data->irq_base; | 335 | return data->irq_base; |
302 | } | 336 | } |
303 | EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base); | 337 | EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base); |
338 | |||
339 | /** | ||
340 | * regmap_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ | ||
341 | * | ||
342 | * Useful for drivers to request their own IRQs. | ||
343 | * | ||
344 | * @data: regmap_irq controller to operate on. | ||
345 | * @irq: index of the interrupt requested in the chip IRQs | ||
346 | */ | ||
347 | int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq) | ||
348 | { | ||
349 | return irq_create_mapping(data->domain, irq); | ||
350 | } | ||
351 | EXPORT_SYMBOL_GPL(regmap_irq_get_virq); | ||
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c new file mode 100644 index 000000000000..febd6de6c8ac --- /dev/null +++ b/drivers/base/regmap/regmap-mmio.c | |||
@@ -0,0 +1,224 @@ | |||
1 | /* | ||
2 | * Register map access API - MMIO support | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/err.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/regmap.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | struct regmap_mmio_context { | ||
27 | void __iomem *regs; | ||
28 | unsigned val_bytes; | ||
29 | }; | ||
30 | |||
31 | static int regmap_mmio_gather_write(void *context, | ||
32 | const void *reg, size_t reg_size, | ||
33 | const void *val, size_t val_size) | ||
34 | { | ||
35 | struct regmap_mmio_context *ctx = context; | ||
36 | u32 offset; | ||
37 | |||
38 | BUG_ON(reg_size != 4); | ||
39 | |||
40 | offset = be32_to_cpup(reg); | ||
41 | |||
42 | while (val_size) { | ||
43 | switch (ctx->val_bytes) { | ||
44 | case 1: | ||
45 | writeb(*(u8 *)val, ctx->regs + offset); | ||
46 | break; | ||
47 | case 2: | ||
48 | writew(be16_to_cpup(val), ctx->regs + offset); | ||
49 | break; | ||
50 | case 4: | ||
51 | writel(be32_to_cpup(val), ctx->regs + offset); | ||
52 | break; | ||
53 | #ifdef CONFIG_64BIT | ||
54 | case 8: | ||
55 | writeq(be64_to_cpup(val), ctx->regs + offset); | ||
56 | break; | ||
57 | #endif | ||
58 | default: | ||
59 | /* Should be caught by regmap_mmio_check_config */ | ||
60 | BUG(); | ||
61 | } | ||
62 | val_size -= ctx->val_bytes; | ||
63 | val += ctx->val_bytes; | ||
64 | offset += ctx->val_bytes; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int regmap_mmio_write(void *context, const void *data, size_t count) | ||
71 | { | ||
72 | BUG_ON(count < 4); | ||
73 | |||
74 | return regmap_mmio_gather_write(context, data, 4, data + 4, count - 4); | ||
75 | } | ||
76 | |||
77 | static int regmap_mmio_read(void *context, | ||
78 | const void *reg, size_t reg_size, | ||
79 | void *val, size_t val_size) | ||
80 | { | ||
81 | struct regmap_mmio_context *ctx = context; | ||
82 | u32 offset; | ||
83 | |||
84 | BUG_ON(reg_size != 4); | ||
85 | |||
86 | offset = be32_to_cpup(reg); | ||
87 | |||
88 | while (val_size) { | ||
89 | switch (ctx->val_bytes) { | ||
90 | case 1: | ||
91 | *(u8 *)val = readb(ctx->regs + offset); | ||
92 | break; | ||
93 | case 2: | ||
94 | *(u16 *)val = cpu_to_be16(readw(ctx->regs + offset)); | ||
95 | break; | ||
96 | case 4: | ||
97 | *(u32 *)val = cpu_to_be32(readl(ctx->regs + offset)); | ||
98 | break; | ||
99 | #ifdef CONFIG_64BIT | ||
100 | case 8: | ||
101 | *(u64 *)val = cpu_to_be32(readq(ctx->regs + offset)); | ||
102 | break; | ||
103 | #endif | ||
104 | default: | ||
105 | /* Should be caught by regmap_mmio_check_config */ | ||
106 | BUG(); | ||
107 | } | ||
108 | val_size -= ctx->val_bytes; | ||
109 | val += ctx->val_bytes; | ||
110 | offset += ctx->val_bytes; | ||
111 | } | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static void regmap_mmio_free_context(void *context) | ||
117 | { | ||
118 | kfree(context); | ||
119 | } | ||
120 | |||
121 | static struct regmap_bus regmap_mmio = { | ||
122 | .fast_io = true, | ||
123 | .write = regmap_mmio_write, | ||
124 | .gather_write = regmap_mmio_gather_write, | ||
125 | .read = regmap_mmio_read, | ||
126 | .free_context = regmap_mmio_free_context, | ||
127 | }; | ||
128 | |||
129 | struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, | ||
130 | const struct regmap_config *config) | ||
131 | { | ||
132 | struct regmap_mmio_context *ctx; | ||
133 | int min_stride; | ||
134 | |||
135 | if (config->reg_bits != 32) | ||
136 | return ERR_PTR(-EINVAL); | ||
137 | |||
138 | if (config->pad_bits) | ||
139 | return ERR_PTR(-EINVAL); | ||
140 | |||
141 | switch (config->val_bits) { | ||
142 | case 8: | ||
143 | /* The core treats 0 as 1 */ | ||
144 | min_stride = 0; | ||
145 | break; | ||
146 | case 16: | ||
147 | min_stride = 2; | ||
148 | break; | ||
149 | case 32: | ||
150 | min_stride = 4; | ||
151 | break; | ||
152 | #ifdef CONFIG_64BIT | ||
153 | case 64: | ||
154 | min_stride = 8; | ||
155 | break; | ||
156 | #endif | ||
157 | break; | ||
158 | default: | ||
159 | return ERR_PTR(-EINVAL); | ||
160 | } | ||
161 | |||
162 | if (config->reg_stride < min_stride) | ||
163 | return ERR_PTR(-EINVAL); | ||
164 | |||
165 | ctx = kzalloc(GFP_KERNEL, sizeof(*ctx)); | ||
166 | if (!ctx) | ||
167 | return ERR_PTR(-ENOMEM); | ||
168 | |||
169 | ctx->regs = regs; | ||
170 | ctx->val_bytes = config->val_bits / 8; | ||
171 | |||
172 | return ctx; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * regmap_init_mmio(): Initialise register map | ||
177 | * | ||
178 | * @dev: Device that will be interacted with | ||
179 | * @regs: Pointer to memory-mapped IO region | ||
180 | * @config: Configuration for register map | ||
181 | * | ||
182 | * The return value will be an ERR_PTR() on error or a valid pointer to | ||
183 | * a struct regmap. | ||
184 | */ | ||
185 | struct regmap *regmap_init_mmio(struct device *dev, | ||
186 | void __iomem *regs, | ||
187 | const struct regmap_config *config) | ||
188 | { | ||
189 | struct regmap_mmio_context *ctx; | ||
190 | |||
191 | ctx = regmap_mmio_gen_context(regs, config); | ||
192 | if (IS_ERR(ctx)) | ||
193 | return ERR_CAST(ctx); | ||
194 | |||
195 | return regmap_init(dev, ®map_mmio, ctx, config); | ||
196 | } | ||
197 | EXPORT_SYMBOL_GPL(regmap_init_mmio); | ||
198 | |||
199 | /** | ||
200 | * devm_regmap_init_mmio(): Initialise managed register map | ||
201 | * | ||
202 | * @dev: Device that will be interacted with | ||
203 | * @regs: Pointer to memory-mapped IO region | ||
204 | * @config: Configuration for register map | ||
205 | * | ||
206 | * The return value will be an ERR_PTR() on error or a valid pointer | ||
207 | * to a struct regmap. The regmap will be automatically freed by the | ||
208 | * device management code. | ||
209 | */ | ||
210 | struct regmap *devm_regmap_init_mmio(struct device *dev, | ||
211 | void __iomem *regs, | ||
212 | const struct regmap_config *config) | ||
213 | { | ||
214 | struct regmap_mmio_context *ctx; | ||
215 | |||
216 | ctx = regmap_mmio_gen_context(regs, config); | ||
217 | if (IS_ERR(ctx)) | ||
218 | return ERR_CAST(ctx); | ||
219 | |||
220 | return devm_regmap_init(dev, ®map_mmio, ctx, config); | ||
221 | } | ||
222 | EXPORT_SYMBOL_GPL(devm_regmap_init_mmio); | ||
223 | |||
224 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 7c0c35a39c33..ffa46a92ad33 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c | |||
@@ -15,17 +15,19 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | 17 | ||
18 | static int regmap_spi_write(struct device *dev, const void *data, size_t count) | 18 | static int regmap_spi_write(void *context, const void *data, size_t count) |
19 | { | 19 | { |
20 | struct device *dev = context; | ||
20 | struct spi_device *spi = to_spi_device(dev); | 21 | struct spi_device *spi = to_spi_device(dev); |
21 | 22 | ||
22 | return spi_write(spi, data, count); | 23 | return spi_write(spi, data, count); |
23 | } | 24 | } |
24 | 25 | ||
25 | static int regmap_spi_gather_write(struct device *dev, | 26 | static int regmap_spi_gather_write(void *context, |
26 | const void *reg, size_t reg_len, | 27 | const void *reg, size_t reg_len, |
27 | const void *val, size_t val_len) | 28 | const void *val, size_t val_len) |
28 | { | 29 | { |
30 | struct device *dev = context; | ||
29 | struct spi_device *spi = to_spi_device(dev); | 31 | struct spi_device *spi = to_spi_device(dev); |
30 | struct spi_message m; | 32 | struct spi_message m; |
31 | struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, }, | 33 | struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, }, |
@@ -38,10 +40,11 @@ static int regmap_spi_gather_write(struct device *dev, | |||
38 | return spi_sync(spi, &m); | 40 | return spi_sync(spi, &m); |
39 | } | 41 | } |
40 | 42 | ||
41 | static int regmap_spi_read(struct device *dev, | 43 | static int regmap_spi_read(void *context, |
42 | const void *reg, size_t reg_size, | 44 | const void *reg, size_t reg_size, |
43 | void *val, size_t val_size) | 45 | void *val, size_t val_size) |
44 | { | 46 | { |
47 | struct device *dev = context; | ||
45 | struct spi_device *spi = to_spi_device(dev); | 48 | struct spi_device *spi = to_spi_device(dev); |
46 | 49 | ||
47 | return spi_write_then_read(spi, reg, reg_size, val, val_size); | 50 | return spi_write_then_read(spi, reg, reg_size, val, val_size); |
@@ -66,7 +69,7 @@ static struct regmap_bus regmap_spi = { | |||
66 | struct regmap *regmap_init_spi(struct spi_device *spi, | 69 | struct regmap *regmap_init_spi(struct spi_device *spi, |
67 | const struct regmap_config *config) | 70 | const struct regmap_config *config) |
68 | { | 71 | { |
69 | return regmap_init(&spi->dev, ®map_spi, config); | 72 | return regmap_init(&spi->dev, ®map_spi, &spi->dev, config); |
70 | } | 73 | } |
71 | EXPORT_SYMBOL_GPL(regmap_init_spi); | 74 | EXPORT_SYMBOL_GPL(regmap_init_spi); |
72 | 75 | ||
@@ -83,7 +86,7 @@ EXPORT_SYMBOL_GPL(regmap_init_spi); | |||
83 | struct regmap *devm_regmap_init_spi(struct spi_device *spi, | 86 | struct regmap *devm_regmap_init_spi(struct spi_device *spi, |
84 | const struct regmap_config *config) | 87 | const struct regmap_config *config) |
85 | { | 88 | { |
86 | return devm_regmap_init(&spi->dev, ®map_spi, config); | 89 | return devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config); |
87 | } | 90 | } |
88 | EXPORT_SYMBOL_GPL(devm_regmap_init_spi); | 91 | EXPORT_SYMBOL_GPL(devm_regmap_init_spi); |
89 | 92 | ||
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 7a3f535e481c..0bcda488f11c 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -112,25 +112,36 @@ static void regmap_format_10_14_write(struct regmap *map, | |||
112 | out[0] = reg >> 2; | 112 | out[0] = reg >> 2; |
113 | } | 113 | } |
114 | 114 | ||
115 | static void regmap_format_8(void *buf, unsigned int val) | 115 | static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) |
116 | { | 116 | { |
117 | u8 *b = buf; | 117 | u8 *b = buf; |
118 | 118 | ||
119 | b[0] = val; | 119 | b[0] = val << shift; |
120 | } | 120 | } |
121 | 121 | ||
122 | static void regmap_format_16(void *buf, unsigned int val) | 122 | static void regmap_format_16(void *buf, unsigned int val, unsigned int shift) |
123 | { | 123 | { |
124 | __be16 *b = buf; | 124 | __be16 *b = buf; |
125 | 125 | ||
126 | b[0] = cpu_to_be16(val); | 126 | b[0] = cpu_to_be16(val << shift); |
127 | } | 127 | } |
128 | 128 | ||
129 | static void regmap_format_32(void *buf, unsigned int val) | 129 | static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) |
130 | { | ||
131 | u8 *b = buf; | ||
132 | |||
133 | val <<= shift; | ||
134 | |||
135 | b[0] = val >> 16; | ||
136 | b[1] = val >> 8; | ||
137 | b[2] = val; | ||
138 | } | ||
139 | |||
140 | static void regmap_format_32(void *buf, unsigned int val, unsigned int shift) | ||
130 | { | 141 | { |
131 | __be32 *b = buf; | 142 | __be32 *b = buf; |
132 | 143 | ||
133 | b[0] = cpu_to_be32(val); | 144 | b[0] = cpu_to_be32(val << shift); |
134 | } | 145 | } |
135 | 146 | ||
136 | static unsigned int regmap_parse_8(void *buf) | 147 | static unsigned int regmap_parse_8(void *buf) |
@@ -149,6 +160,16 @@ static unsigned int regmap_parse_16(void *buf) | |||
149 | return b[0]; | 160 | return b[0]; |
150 | } | 161 | } |
151 | 162 | ||
163 | static unsigned int regmap_parse_24(void *buf) | ||
164 | { | ||
165 | u8 *b = buf; | ||
166 | unsigned int ret = b[2]; | ||
167 | ret |= ((unsigned int)b[1]) << 8; | ||
168 | ret |= ((unsigned int)b[0]) << 16; | ||
169 | |||
170 | return ret; | ||
171 | } | ||
172 | |||
152 | static unsigned int regmap_parse_32(void *buf) | 173 | static unsigned int regmap_parse_32(void *buf) |
153 | { | 174 | { |
154 | __be32 *b = buf; | 175 | __be32 *b = buf; |
@@ -158,11 +179,41 @@ static unsigned int regmap_parse_32(void *buf) | |||
158 | return b[0]; | 179 | return b[0]; |
159 | } | 180 | } |
160 | 181 | ||
182 | static void regmap_lock_mutex(struct regmap *map) | ||
183 | { | ||
184 | mutex_lock(&map->mutex); | ||
185 | } | ||
186 | |||
187 | static void regmap_unlock_mutex(struct regmap *map) | ||
188 | { | ||
189 | mutex_unlock(&map->mutex); | ||
190 | } | ||
191 | |||
192 | static void regmap_lock_spinlock(struct regmap *map) | ||
193 | { | ||
194 | spin_lock(&map->spinlock); | ||
195 | } | ||
196 | |||
197 | static void regmap_unlock_spinlock(struct regmap *map) | ||
198 | { | ||
199 | spin_unlock(&map->spinlock); | ||
200 | } | ||
201 | |||
202 | static void dev_get_regmap_release(struct device *dev, void *res) | ||
203 | { | ||
204 | /* | ||
205 | * We don't actually have anything to do here; the goal here | ||
206 | * is not to manage the regmap but to provide a simple way to | ||
207 | * get the regmap back given a struct device. | ||
208 | */ | ||
209 | } | ||
210 | |||
161 | /** | 211 | /** |
162 | * regmap_init(): Initialise register map | 212 | * regmap_init(): Initialise register map |
163 | * | 213 | * |
164 | * @dev: Device that will be interacted with | 214 | * @dev: Device that will be interacted with |
165 | * @bus: Bus-specific callbacks to use with device | 215 | * @bus: Bus-specific callbacks to use with device |
216 | * @bus_context: Data passed to bus-specific callbacks | ||
166 | * @config: Configuration for register map | 217 | * @config: Configuration for register map |
167 | * | 218 | * |
168 | * The return value will be an ERR_PTR() on error or a valid pointer to | 219 | * The return value will be an ERR_PTR() on error or a valid pointer to |
@@ -171,9 +222,10 @@ static unsigned int regmap_parse_32(void *buf) | |||
171 | */ | 222 | */ |
172 | struct regmap *regmap_init(struct device *dev, | 223 | struct regmap *regmap_init(struct device *dev, |
173 | const struct regmap_bus *bus, | 224 | const struct regmap_bus *bus, |
225 | void *bus_context, | ||
174 | const struct regmap_config *config) | 226 | const struct regmap_config *config) |
175 | { | 227 | { |
176 | struct regmap *map; | 228 | struct regmap *map, **m; |
177 | int ret = -EINVAL; | 229 | int ret = -EINVAL; |
178 | 230 | ||
179 | if (!bus || !config) | 231 | if (!bus || !config) |
@@ -185,20 +237,36 @@ struct regmap *regmap_init(struct device *dev, | |||
185 | goto err; | 237 | goto err; |
186 | } | 238 | } |
187 | 239 | ||
188 | mutex_init(&map->lock); | 240 | if (bus->fast_io) { |
241 | spin_lock_init(&map->spinlock); | ||
242 | map->lock = regmap_lock_spinlock; | ||
243 | map->unlock = regmap_unlock_spinlock; | ||
244 | } else { | ||
245 | mutex_init(&map->mutex); | ||
246 | map->lock = regmap_lock_mutex; | ||
247 | map->unlock = regmap_unlock_mutex; | ||
248 | } | ||
189 | map->format.buf_size = (config->reg_bits + config->val_bits) / 8; | 249 | map->format.buf_size = (config->reg_bits + config->val_bits) / 8; |
190 | map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); | 250 | map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); |
191 | map->format.pad_bytes = config->pad_bits / 8; | 251 | map->format.pad_bytes = config->pad_bits / 8; |
192 | map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); | 252 | map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); |
193 | map->format.buf_size += map->format.pad_bytes; | 253 | map->format.buf_size += map->format.pad_bytes; |
254 | map->reg_shift = config->pad_bits % 8; | ||
255 | if (config->reg_stride) | ||
256 | map->reg_stride = config->reg_stride; | ||
257 | else | ||
258 | map->reg_stride = 1; | ||
259 | map->use_single_rw = config->use_single_rw; | ||
194 | map->dev = dev; | 260 | map->dev = dev; |
195 | map->bus = bus; | 261 | map->bus = bus; |
262 | map->bus_context = bus_context; | ||
196 | map->max_register = config->max_register; | 263 | map->max_register = config->max_register; |
197 | map->writeable_reg = config->writeable_reg; | 264 | map->writeable_reg = config->writeable_reg; |
198 | map->readable_reg = config->readable_reg; | 265 | map->readable_reg = config->readable_reg; |
199 | map->volatile_reg = config->volatile_reg; | 266 | map->volatile_reg = config->volatile_reg; |
200 | map->precious_reg = config->precious_reg; | 267 | map->precious_reg = config->precious_reg; |
201 | map->cache_type = config->cache_type; | 268 | map->cache_type = config->cache_type; |
269 | map->name = config->name; | ||
202 | 270 | ||
203 | if (config->read_flag_mask || config->write_flag_mask) { | 271 | if (config->read_flag_mask || config->write_flag_mask) { |
204 | map->read_flag_mask = config->read_flag_mask; | 272 | map->read_flag_mask = config->read_flag_mask; |
@@ -207,7 +275,7 @@ struct regmap *regmap_init(struct device *dev, | |||
207 | map->read_flag_mask = bus->read_flag_mask; | 275 | map->read_flag_mask = bus->read_flag_mask; |
208 | } | 276 | } |
209 | 277 | ||
210 | switch (config->reg_bits) { | 278 | switch (config->reg_bits + map->reg_shift) { |
211 | case 2: | 279 | case 2: |
212 | switch (config->val_bits) { | 280 | switch (config->val_bits) { |
213 | case 6: | 281 | case 6: |
@@ -273,12 +341,19 @@ struct regmap *regmap_init(struct device *dev, | |||
273 | map->format.format_val = regmap_format_16; | 341 | map->format.format_val = regmap_format_16; |
274 | map->format.parse_val = regmap_parse_16; | 342 | map->format.parse_val = regmap_parse_16; |
275 | break; | 343 | break; |
344 | case 24: | ||
345 | map->format.format_val = regmap_format_24; | ||
346 | map->format.parse_val = regmap_parse_24; | ||
347 | break; | ||
276 | case 32: | 348 | case 32: |
277 | map->format.format_val = regmap_format_32; | 349 | map->format.format_val = regmap_format_32; |
278 | map->format.parse_val = regmap_parse_32; | 350 | map->format.parse_val = regmap_parse_32; |
279 | break; | 351 | break; |
280 | } | 352 | } |
281 | 353 | ||
354 | if (map->format.format_write) | ||
355 | map->use_single_rw = true; | ||
356 | |||
282 | if (!map->format.format_write && | 357 | if (!map->format.format_write && |
283 | !(map->format.format_reg && map->format.format_val)) | 358 | !(map->format.format_reg && map->format.format_val)) |
284 | goto err_map; | 359 | goto err_map; |
@@ -289,14 +364,25 @@ struct regmap *regmap_init(struct device *dev, | |||
289 | goto err_map; | 364 | goto err_map; |
290 | } | 365 | } |
291 | 366 | ||
292 | regmap_debugfs_init(map); | 367 | regmap_debugfs_init(map, config->name); |
293 | 368 | ||
294 | ret = regcache_init(map, config); | 369 | ret = regcache_init(map, config); |
295 | if (ret < 0) | 370 | if (ret < 0) |
296 | goto err_free_workbuf; | 371 | goto err_free_workbuf; |
297 | 372 | ||
373 | /* Add a devres resource for dev_get_regmap() */ | ||
374 | m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); | ||
375 | if (!m) { | ||
376 | ret = -ENOMEM; | ||
377 | goto err_cache; | ||
378 | } | ||
379 | *m = map; | ||
380 | devres_add(dev, m); | ||
381 | |||
298 | return map; | 382 | return map; |
299 | 383 | ||
384 | err_cache: | ||
385 | regcache_exit(map); | ||
300 | err_free_workbuf: | 386 | err_free_workbuf: |
301 | kfree(map->work_buf); | 387 | kfree(map->work_buf); |
302 | err_map: | 388 | err_map: |
@@ -316,6 +402,7 @@ static void devm_regmap_release(struct device *dev, void *res) | |||
316 | * | 402 | * |
317 | * @dev: Device that will be interacted with | 403 | * @dev: Device that will be interacted with |
318 | * @bus: Bus-specific callbacks to use with device | 404 | * @bus: Bus-specific callbacks to use with device |
405 | * @bus_context: Data passed to bus-specific callbacks | ||
319 | * @config: Configuration for register map | 406 | * @config: Configuration for register map |
320 | * | 407 | * |
321 | * The return value will be an ERR_PTR() on error or a valid pointer | 408 | * The return value will be an ERR_PTR() on error or a valid pointer |
@@ -325,6 +412,7 @@ static void devm_regmap_release(struct device *dev, void *res) | |||
325 | */ | 412 | */ |
326 | struct regmap *devm_regmap_init(struct device *dev, | 413 | struct regmap *devm_regmap_init(struct device *dev, |
327 | const struct regmap_bus *bus, | 414 | const struct regmap_bus *bus, |
415 | void *bus_context, | ||
328 | const struct regmap_config *config) | 416 | const struct regmap_config *config) |
329 | { | 417 | { |
330 | struct regmap **ptr, *regmap; | 418 | struct regmap **ptr, *regmap; |
@@ -333,7 +421,7 @@ struct regmap *devm_regmap_init(struct device *dev, | |||
333 | if (!ptr) | 421 | if (!ptr) |
334 | return ERR_PTR(-ENOMEM); | 422 | return ERR_PTR(-ENOMEM); |
335 | 423 | ||
336 | regmap = regmap_init(dev, bus, config); | 424 | regmap = regmap_init(dev, bus, bus_context, config); |
337 | if (!IS_ERR(regmap)) { | 425 | if (!IS_ERR(regmap)) { |
338 | *ptr = regmap; | 426 | *ptr = regmap; |
339 | devres_add(dev, ptr); | 427 | devres_add(dev, ptr); |
@@ -360,7 +448,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) | |||
360 | { | 448 | { |
361 | int ret; | 449 | int ret; |
362 | 450 | ||
363 | mutex_lock(&map->lock); | 451 | map->lock(map); |
364 | 452 | ||
365 | regcache_exit(map); | 453 | regcache_exit(map); |
366 | regmap_debugfs_exit(map); | 454 | regmap_debugfs_exit(map); |
@@ -372,14 +460,14 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) | |||
372 | map->precious_reg = config->precious_reg; | 460 | map->precious_reg = config->precious_reg; |
373 | map->cache_type = config->cache_type; | 461 | map->cache_type = config->cache_type; |
374 | 462 | ||
375 | regmap_debugfs_init(map); | 463 | regmap_debugfs_init(map, config->name); |
376 | 464 | ||
377 | map->cache_bypass = false; | 465 | map->cache_bypass = false; |
378 | map->cache_only = false; | 466 | map->cache_only = false; |
379 | 467 | ||
380 | ret = regcache_init(map, config); | 468 | ret = regcache_init(map, config); |
381 | 469 | ||
382 | mutex_unlock(&map->lock); | 470 | map->unlock(map); |
383 | 471 | ||
384 | return ret; | 472 | return ret; |
385 | } | 473 | } |
@@ -391,11 +479,51 @@ void regmap_exit(struct regmap *map) | |||
391 | { | 479 | { |
392 | regcache_exit(map); | 480 | regcache_exit(map); |
393 | regmap_debugfs_exit(map); | 481 | regmap_debugfs_exit(map); |
482 | if (map->bus->free_context) | ||
483 | map->bus->free_context(map->bus_context); | ||
394 | kfree(map->work_buf); | 484 | kfree(map->work_buf); |
395 | kfree(map); | 485 | kfree(map); |
396 | } | 486 | } |
397 | EXPORT_SYMBOL_GPL(regmap_exit); | 487 | EXPORT_SYMBOL_GPL(regmap_exit); |
398 | 488 | ||
489 | static int dev_get_regmap_match(struct device *dev, void *res, void *data) | ||
490 | { | ||
491 | struct regmap **r = res; | ||
492 | if (!r || !*r) { | ||
493 | WARN_ON(!r || !*r); | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | /* If the user didn't specify a name match any */ | ||
498 | if (data) | ||
499 | return (*r)->name == data; | ||
500 | else | ||
501 | return 1; | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * dev_get_regmap(): Obtain the regmap (if any) for a device | ||
506 | * | ||
507 | * @dev: Device to retrieve the map for | ||
508 | * @name: Optional name for the register map, usually NULL. | ||
509 | * | ||
510 | * Returns the regmap for the device if one is present, or NULL. If | ||
511 | * name is specified then it must match the name specified when | ||
512 | * registering the device, if it is NULL then the first regmap found | ||
513 | * will be used. Devices with multiple register maps are very rare, | ||
514 | * generic code should normally not need to specify a name. | ||
515 | */ | ||
516 | struct regmap *dev_get_regmap(struct device *dev, const char *name) | ||
517 | { | ||
518 | struct regmap **r = devres_find(dev, dev_get_regmap_release, | ||
519 | dev_get_regmap_match, (void *)name); | ||
520 | |||
521 | if (!r) | ||
522 | return NULL; | ||
523 | return *r; | ||
524 | } | ||
525 | EXPORT_SYMBOL_GPL(dev_get_regmap); | ||
526 | |||
399 | static int _regmap_raw_write(struct regmap *map, unsigned int reg, | 527 | static int _regmap_raw_write(struct regmap *map, unsigned int reg, |
400 | const void *val, size_t val_len) | 528 | const void *val, size_t val_len) |
401 | { | 529 | { |
@@ -408,7 +536,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
408 | /* Check for unwritable registers before we start */ | 536 | /* Check for unwritable registers before we start */ |
409 | if (map->writeable_reg) | 537 | if (map->writeable_reg) |
410 | for (i = 0; i < val_len / map->format.val_bytes; i++) | 538 | for (i = 0; i < val_len / map->format.val_bytes; i++) |
411 | if (!map->writeable_reg(map->dev, reg + i)) | 539 | if (!map->writeable_reg(map->dev, |
540 | reg + (i * map->reg_stride))) | ||
412 | return -EINVAL; | 541 | return -EINVAL; |
413 | 542 | ||
414 | if (!map->cache_bypass && map->format.parse_val) { | 543 | if (!map->cache_bypass && map->format.parse_val) { |
@@ -417,7 +546,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
417 | for (i = 0; i < val_len / val_bytes; i++) { | 546 | for (i = 0; i < val_len / val_bytes; i++) { |
418 | memcpy(map->work_buf, val + (i * val_bytes), val_bytes); | 547 | memcpy(map->work_buf, val + (i * val_bytes), val_bytes); |
419 | ival = map->format.parse_val(map->work_buf); | 548 | ival = map->format.parse_val(map->work_buf); |
420 | ret = regcache_write(map, reg + i, ival); | 549 | ret = regcache_write(map, reg + (i * map->reg_stride), |
550 | ival); | ||
421 | if (ret) { | 551 | if (ret) { |
422 | dev_err(map->dev, | 552 | dev_err(map->dev, |
423 | "Error in caching of register: %u ret: %d\n", | 553 | "Error in caching of register: %u ret: %d\n", |
@@ -431,7 +561,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
431 | } | 561 | } |
432 | } | 562 | } |
433 | 563 | ||
434 | map->format.format_reg(map->work_buf, reg); | 564 | map->format.format_reg(map->work_buf, reg, map->reg_shift); |
435 | 565 | ||
436 | u8[0] |= map->write_flag_mask; | 566 | u8[0] |= map->write_flag_mask; |
437 | 567 | ||
@@ -444,12 +574,12 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
444 | */ | 574 | */ |
445 | if (val == (map->work_buf + map->format.pad_bytes + | 575 | if (val == (map->work_buf + map->format.pad_bytes + |
446 | map->format.reg_bytes)) | 576 | map->format.reg_bytes)) |
447 | ret = map->bus->write(map->dev, map->work_buf, | 577 | ret = map->bus->write(map->bus_context, map->work_buf, |
448 | map->format.reg_bytes + | 578 | map->format.reg_bytes + |
449 | map->format.pad_bytes + | 579 | map->format.pad_bytes + |
450 | val_len); | 580 | val_len); |
451 | else if (map->bus->gather_write) | 581 | else if (map->bus->gather_write) |
452 | ret = map->bus->gather_write(map->dev, map->work_buf, | 582 | ret = map->bus->gather_write(map->bus_context, map->work_buf, |
453 | map->format.reg_bytes + | 583 | map->format.reg_bytes + |
454 | map->format.pad_bytes, | 584 | map->format.pad_bytes, |
455 | val, val_len); | 585 | val, val_len); |
@@ -464,7 +594,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
464 | memcpy(buf, map->work_buf, map->format.reg_bytes); | 594 | memcpy(buf, map->work_buf, map->format.reg_bytes); |
465 | memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, | 595 | memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, |
466 | val, val_len); | 596 | val, val_len); |
467 | ret = map->bus->write(map->dev, buf, len); | 597 | ret = map->bus->write(map->bus_context, buf, len); |
468 | 598 | ||
469 | kfree(buf); | 599 | kfree(buf); |
470 | } | 600 | } |
@@ -498,7 +628,7 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
498 | 628 | ||
499 | trace_regmap_hw_write_start(map->dev, reg, 1); | 629 | trace_regmap_hw_write_start(map->dev, reg, 1); |
500 | 630 | ||
501 | ret = map->bus->write(map->dev, map->work_buf, | 631 | ret = map->bus->write(map->bus_context, map->work_buf, |
502 | map->format.buf_size); | 632 | map->format.buf_size); |
503 | 633 | ||
504 | trace_regmap_hw_write_done(map->dev, reg, 1); | 634 | trace_regmap_hw_write_done(map->dev, reg, 1); |
@@ -506,7 +636,7 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
506 | return ret; | 636 | return ret; |
507 | } else { | 637 | } else { |
508 | map->format.format_val(map->work_buf + map->format.reg_bytes | 638 | map->format.format_val(map->work_buf + map->format.reg_bytes |
509 | + map->format.pad_bytes, val); | 639 | + map->format.pad_bytes, val, 0); |
510 | return _regmap_raw_write(map, reg, | 640 | return _regmap_raw_write(map, reg, |
511 | map->work_buf + | 641 | map->work_buf + |
512 | map->format.reg_bytes + | 642 | map->format.reg_bytes + |
@@ -529,11 +659,14 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val) | |||
529 | { | 659 | { |
530 | int ret; | 660 | int ret; |
531 | 661 | ||
532 | mutex_lock(&map->lock); | 662 | if (reg % map->reg_stride) |
663 | return -EINVAL; | ||
664 | |||
665 | map->lock(map); | ||
533 | 666 | ||
534 | ret = _regmap_write(map, reg, val); | 667 | ret = _regmap_write(map, reg, val); |
535 | 668 | ||
536 | mutex_unlock(&map->lock); | 669 | map->unlock(map); |
537 | 670 | ||
538 | return ret; | 671 | return ret; |
539 | } | 672 | } |
@@ -560,11 +693,16 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, | |||
560 | { | 693 | { |
561 | int ret; | 694 | int ret; |
562 | 695 | ||
563 | mutex_lock(&map->lock); | 696 | if (val_len % map->format.val_bytes) |
697 | return -EINVAL; | ||
698 | if (reg % map->reg_stride) | ||
699 | return -EINVAL; | ||
700 | |||
701 | map->lock(map); | ||
564 | 702 | ||
565 | ret = _regmap_raw_write(map, reg, val, val_len); | 703 | ret = _regmap_raw_write(map, reg, val, val_len); |
566 | 704 | ||
567 | mutex_unlock(&map->lock); | 705 | map->unlock(map); |
568 | 706 | ||
569 | return ret; | 707 | return ret; |
570 | } | 708 | } |
@@ -593,8 +731,10 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | |||
593 | 731 | ||
594 | if (!map->format.parse_val) | 732 | if (!map->format.parse_val) |
595 | return -EINVAL; | 733 | return -EINVAL; |
734 | if (reg % map->reg_stride) | ||
735 | return -EINVAL; | ||
596 | 736 | ||
597 | mutex_lock(&map->lock); | 737 | map->lock(map); |
598 | 738 | ||
599 | /* No formatting is require if val_byte is 1 */ | 739 | /* No formatting is require if val_byte is 1 */ |
600 | if (val_bytes == 1) { | 740 | if (val_bytes == 1) { |
@@ -609,13 +749,28 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | |||
609 | for (i = 0; i < val_count * val_bytes; i += val_bytes) | 749 | for (i = 0; i < val_count * val_bytes; i += val_bytes) |
610 | map->format.parse_val(wval + i); | 750 | map->format.parse_val(wval + i); |
611 | } | 751 | } |
612 | ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); | 752 | /* |
753 | * Some devices does not support bulk write, for | ||
754 | * them we have a series of single write operations. | ||
755 | */ | ||
756 | if (map->use_single_rw) { | ||
757 | for (i = 0; i < val_count; i++) { | ||
758 | ret = regmap_raw_write(map, | ||
759 | reg + (i * map->reg_stride), | ||
760 | val + (i * val_bytes), | ||
761 | val_bytes); | ||
762 | if (ret != 0) | ||
763 | return ret; | ||
764 | } | ||
765 | } else { | ||
766 | ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); | ||
767 | } | ||
613 | 768 | ||
614 | if (val_bytes != 1) | 769 | if (val_bytes != 1) |
615 | kfree(wval); | 770 | kfree(wval); |
616 | 771 | ||
617 | out: | 772 | out: |
618 | mutex_unlock(&map->lock); | 773 | map->unlock(map); |
619 | return ret; | 774 | return ret; |
620 | } | 775 | } |
621 | EXPORT_SYMBOL_GPL(regmap_bulk_write); | 776 | EXPORT_SYMBOL_GPL(regmap_bulk_write); |
@@ -626,7 +781,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
626 | u8 *u8 = map->work_buf; | 781 | u8 *u8 = map->work_buf; |
627 | int ret; | 782 | int ret; |
628 | 783 | ||
629 | map->format.format_reg(map->work_buf, reg); | 784 | map->format.format_reg(map->work_buf, reg, map->reg_shift); |
630 | 785 | ||
631 | /* | 786 | /* |
632 | * Some buses or devices flag reads by setting the high bits in the | 787 | * Some buses or devices flag reads by setting the high bits in the |
@@ -639,7 +794,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
639 | trace_regmap_hw_read_start(map->dev, reg, | 794 | trace_regmap_hw_read_start(map->dev, reg, |
640 | val_len / map->format.val_bytes); | 795 | val_len / map->format.val_bytes); |
641 | 796 | ||
642 | ret = map->bus->read(map->dev, map->work_buf, | 797 | ret = map->bus->read(map->bus_context, map->work_buf, |
643 | map->format.reg_bytes + map->format.pad_bytes, | 798 | map->format.reg_bytes + map->format.pad_bytes, |
644 | val, val_len); | 799 | val, val_len); |
645 | 800 | ||
@@ -672,6 +827,9 @@ static int _regmap_read(struct regmap *map, unsigned int reg, | |||
672 | trace_regmap_reg_read(map->dev, reg, *val); | 827 | trace_regmap_reg_read(map->dev, reg, *val); |
673 | } | 828 | } |
674 | 829 | ||
830 | if (ret == 0 && !map->cache_bypass) | ||
831 | regcache_write(map, reg, *val); | ||
832 | |||
675 | return ret; | 833 | return ret; |
676 | } | 834 | } |
677 | 835 | ||
@@ -689,11 +847,14 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) | |||
689 | { | 847 | { |
690 | int ret; | 848 | int ret; |
691 | 849 | ||
692 | mutex_lock(&map->lock); | 850 | if (reg % map->reg_stride) |
851 | return -EINVAL; | ||
852 | |||
853 | map->lock(map); | ||
693 | 854 | ||
694 | ret = _regmap_read(map, reg, val); | 855 | ret = _regmap_read(map, reg, val); |
695 | 856 | ||
696 | mutex_unlock(&map->lock); | 857 | map->unlock(map); |
697 | 858 | ||
698 | return ret; | 859 | return ret; |
699 | } | 860 | } |
@@ -718,7 +879,12 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
718 | unsigned int v; | 879 | unsigned int v; |
719 | int ret, i; | 880 | int ret, i; |
720 | 881 | ||
721 | mutex_lock(&map->lock); | 882 | if (val_len % map->format.val_bytes) |
883 | return -EINVAL; | ||
884 | if (reg % map->reg_stride) | ||
885 | return -EINVAL; | ||
886 | |||
887 | map->lock(map); | ||
722 | 888 | ||
723 | if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || | 889 | if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || |
724 | map->cache_type == REGCACHE_NONE) { | 890 | map->cache_type == REGCACHE_NONE) { |
@@ -730,16 +896,17 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
730 | * cost as we expect to hit the cache. | 896 | * cost as we expect to hit the cache. |
731 | */ | 897 | */ |
732 | for (i = 0; i < val_count; i++) { | 898 | for (i = 0; i < val_count; i++) { |
733 | ret = _regmap_read(map, reg + i, &v); | 899 | ret = _regmap_read(map, reg + (i * map->reg_stride), |
900 | &v); | ||
734 | if (ret != 0) | 901 | if (ret != 0) |
735 | goto out; | 902 | goto out; |
736 | 903 | ||
737 | map->format.format_val(val + (i * val_bytes), v); | 904 | map->format.format_val(val + (i * val_bytes), v, 0); |
738 | } | 905 | } |
739 | } | 906 | } |
740 | 907 | ||
741 | out: | 908 | out: |
742 | mutex_unlock(&map->lock); | 909 | map->unlock(map); |
743 | 910 | ||
744 | return ret; | 911 | return ret; |
745 | } | 912 | } |
@@ -765,19 +932,40 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, | |||
765 | 932 | ||
766 | if (!map->format.parse_val) | 933 | if (!map->format.parse_val) |
767 | return -EINVAL; | 934 | return -EINVAL; |
935 | if (reg % map->reg_stride) | ||
936 | return -EINVAL; | ||
768 | 937 | ||
769 | if (vol || map->cache_type == REGCACHE_NONE) { | 938 | if (vol || map->cache_type == REGCACHE_NONE) { |
770 | ret = regmap_raw_read(map, reg, val, val_bytes * val_count); | 939 | /* |
771 | if (ret != 0) | 940 | * Some devices does not support bulk read, for |
772 | return ret; | 941 | * them we have a series of single read operations. |
942 | */ | ||
943 | if (map->use_single_rw) { | ||
944 | for (i = 0; i < val_count; i++) { | ||
945 | ret = regmap_raw_read(map, | ||
946 | reg + (i * map->reg_stride), | ||
947 | val + (i * val_bytes), | ||
948 | val_bytes); | ||
949 | if (ret != 0) | ||
950 | return ret; | ||
951 | } | ||
952 | } else { | ||
953 | ret = regmap_raw_read(map, reg, val, | ||
954 | val_bytes * val_count); | ||
955 | if (ret != 0) | ||
956 | return ret; | ||
957 | } | ||
773 | 958 | ||
774 | for (i = 0; i < val_count * val_bytes; i += val_bytes) | 959 | for (i = 0; i < val_count * val_bytes; i += val_bytes) |
775 | map->format.parse_val(val + i); | 960 | map->format.parse_val(val + i); |
776 | } else { | 961 | } else { |
777 | for (i = 0; i < val_count; i++) { | 962 | for (i = 0; i < val_count; i++) { |
778 | ret = regmap_read(map, reg + i, val + (i * val_bytes)); | 963 | unsigned int ival; |
964 | ret = regmap_read(map, reg + (i * map->reg_stride), | ||
965 | &ival); | ||
779 | if (ret != 0) | 966 | if (ret != 0) |
780 | return ret; | 967 | return ret; |
968 | memcpy(val + (i * val_bytes), &ival, val_bytes); | ||
781 | } | 969 | } |
782 | } | 970 | } |
783 | 971 | ||
@@ -792,7 +980,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, | |||
792 | int ret; | 980 | int ret; |
793 | unsigned int tmp, orig; | 981 | unsigned int tmp, orig; |
794 | 982 | ||
795 | mutex_lock(&map->lock); | 983 | map->lock(map); |
796 | 984 | ||
797 | ret = _regmap_read(map, reg, &orig); | 985 | ret = _regmap_read(map, reg, &orig); |
798 | if (ret != 0) | 986 | if (ret != 0) |
@@ -809,7 +997,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, | |||
809 | } | 997 | } |
810 | 998 | ||
811 | out: | 999 | out: |
812 | mutex_unlock(&map->lock); | 1000 | map->unlock(map); |
813 | 1001 | ||
814 | return ret; | 1002 | return ret; |
815 | } | 1003 | } |
@@ -876,7 +1064,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | |||
876 | if (map->patch) | 1064 | if (map->patch) |
877 | return -EBUSY; | 1065 | return -EBUSY; |
878 | 1066 | ||
879 | mutex_lock(&map->lock); | 1067 | map->lock(map); |
880 | 1068 | ||
881 | bypass = map->cache_bypass; | 1069 | bypass = map->cache_bypass; |
882 | 1070 | ||
@@ -904,7 +1092,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, | |||
904 | out: | 1092 | out: |
905 | map->cache_bypass = bypass; | 1093 | map->cache_bypass = bypass; |
906 | 1094 | ||
907 | mutex_unlock(&map->lock); | 1095 | map->unlock(map); |
908 | 1096 | ||
909 | return ret; | 1097 | return ret; |
910 | } | 1098 | } |