| .. | .. |
|---|
| 14 | 14 | #include <linux/property.h> |
|---|
| 15 | 15 | #include <linux/rbtree.h> |
|---|
| 16 | 16 | #include <linux/sched.h> |
|---|
| 17 | +#include <linux/dovetail.h> |
|---|
| 17 | 18 | #include <linux/delay.h> |
|---|
| 18 | 19 | #include <linux/log2.h> |
|---|
| 19 | 20 | #include <linux/hwspinlock.h> |
|---|
| .. | .. |
|---|
| 523 | 524 | spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags); |
|---|
| 524 | 525 | } |
|---|
| 525 | 526 | |
|---|
| 527 | +static void regmap_lock_oob(void *__map) |
|---|
| 528 | +__acquires(&map->oob_lock) |
|---|
| 529 | +{ |
|---|
| 530 | + struct regmap *map = __map; |
|---|
| 531 | + unsigned long flags; |
|---|
| 532 | + |
|---|
| 533 | + raw_spin_lock_irqsave(&map->oob_lock, flags); |
|---|
| 534 | + map->spinlock_flags = flags; |
|---|
| 535 | +} |
|---|
| 536 | + |
|---|
| 537 | +static void regmap_unlock_oob(void *__map) |
|---|
| 538 | +__releases(&map->oob_lock) |
|---|
| 539 | +{ |
|---|
| 540 | + struct regmap *map = __map; |
|---|
| 541 | + raw_spin_unlock_irqrestore(&map->oob_lock, map->spinlock_flags); |
|---|
| 542 | +} |
|---|
| 543 | + |
|---|
| 526 | 544 | static void dev_get_regmap_release(struct device *dev, void *res) |
|---|
| 527 | 545 | { |
|---|
| 528 | 546 | /* |
|---|
| .. | .. |
|---|
| 761 | 779 | } else { |
|---|
| 762 | 780 | if ((bus && bus->fast_io) || |
|---|
| 763 | 781 | config->fast_io) { |
|---|
| 764 | | - spin_lock_init(&map->spinlock); |
|---|
| 765 | | - map->lock = regmap_lock_spinlock; |
|---|
| 766 | | - map->unlock = regmap_unlock_spinlock; |
|---|
| 767 | | - lockdep_set_class_and_name(&map->spinlock, |
|---|
| 768 | | - lock_key, lock_name); |
|---|
| 769 | | - } else { |
|---|
| 782 | + if (dovetailing() && config->oob_io) { |
|---|
| 783 | + raw_spin_lock_init(&map->oob_lock); |
|---|
| 784 | + map->lock = regmap_lock_oob; |
|---|
| 785 | + map->unlock = regmap_unlock_oob; |
|---|
| 786 | + lockdep_set_class_and_name(&map->oob_lock, |
|---|
| 787 | + lock_key, lock_name); |
|---|
| 788 | + } else { |
|---|
| 789 | + spin_lock_init(&map->spinlock); |
|---|
| 790 | + map->lock = regmap_lock_spinlock; |
|---|
| 791 | + map->unlock = regmap_unlock_spinlock; |
|---|
| 792 | + lockdep_set_class_and_name(&map->spinlock, |
|---|
| 793 | + lock_key, lock_name); |
|---|
| 794 | + } |
|---|
| 795 | + } else if (!config->oob_io) { |
|---|
| 770 | 796 | mutex_init(&map->mutex); |
|---|
| 771 | 797 | map->lock = regmap_lock_mutex; |
|---|
| 772 | 798 | map->unlock = regmap_unlock_mutex; |
|---|
| 773 | 799 | map->can_sleep = true; |
|---|
| 774 | 800 | lockdep_set_class_and_name(&map->mutex, |
|---|
| 775 | 801 | lock_key, lock_name); |
|---|
| 802 | + } else { |
|---|
| 803 | + ret = -ENXIO; |
|---|
| 804 | + goto err_name; |
|---|
| 776 | 805 | } |
|---|
| 777 | 806 | map->lock_arg = map; |
|---|
| 778 | 807 | } |
|---|