.. | .. |
---|
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 | } |
---|