aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2015-09-11 19:37:05 -0400
committerMark Brown <broonie@kernel.org>2015-09-14 14:49:26 -0400
commitb4a21fc275e99fc63c77b30da92ee497f8a7bdb6 (patch)
tree0402fddcd4ae52a6a6d358dae0d6581df881a4ac /drivers/base
parent6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff)
regmap: Allocate buffers with GFP_ATOMIC when fast_io == true
If a regmap is using fast_io, allocate the scratch buffer in regmap_bulk_write() with GFP_ATOMIC instead of GFP_KERNEL. Otherwise we may schedule while atomic. Reported-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/internal.h1
-rw-r--r--drivers/base/regmap/regmap.c12
2 files changed, 12 insertions, 1 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index cc557886ab23..f3b1445da0a5 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -59,6 +59,7 @@ struct regmap {
59 regmap_lock lock; 59 regmap_lock lock;
60 regmap_unlock unlock; 60 regmap_unlock unlock;
61 void *lock_arg; /* This is passed to lock/unlock functions */ 61 void *lock_arg; /* This is passed to lock/unlock functions */
62 gfp_t alloc_flags;
62 63
63 struct device *dev; /* Device we do I/O on */ 64 struct device *dev; /* Device we do I/O on */
64 void *work_buf; /* Scratch buffer used to format I/O */ 65 void *work_buf; /* Scratch buffer used to format I/O */
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index afaf56200674..0b51190c13df 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -561,6 +561,16 @@ struct regmap *__regmap_init(struct device *dev,
561 } 561 }
562 map->lock_arg = map; 562 map->lock_arg = map;
563 } 563 }
564
565 /*
566 * When we write in fast-paths with regmap_bulk_write() don't allocate
567 * scratch buffers with sleeping allocations.
568 */
569 if ((bus && bus->fast_io) || config->fast_io)
570 map->alloc_flags = GFP_ATOMIC;
571 else
572 map->alloc_flags = GFP_KERNEL;
573
564 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); 574 map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
565 map->format.pad_bytes = config->pad_bits / 8; 575 map->format.pad_bytes = config->pad_bits / 8;
566 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); 576 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
@@ -1786,7 +1796,7 @@ out:
1786 if (!val_count) 1796 if (!val_count)
1787 return -EINVAL; 1797 return -EINVAL;
1788 1798
1789 wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL); 1799 wval = kmemdup(val, val_count * val_bytes, map->alloc_flags);
1790 if (!wval) { 1800 if (!wval) {
1791 dev_err(map->dev, "Error in memory allocation\n"); 1801 dev_err(map->dev, "Error in memory allocation\n");
1792 return -ENOMEM; 1802 return -ENOMEM;