aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2015-07-10 06:39:23 -0400
committerMark Brown <broonie@kernel.org>2015-07-10 06:39:23 -0400
commitd1b080290f86d134b97bfe63e499ab9ed3935a02 (patch)
tree876c01fc58578c00968edbe057b1db2edb8c80ad
parentd770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff)
parente874e6c7edc43436f73cf84157d9221f8b807c36 (diff)
Merge tag 'regmap-force' into asoc-rcar
regmap: Force write support This allows users to use _update_bits() without the write suppression, useful for some hardware.
-rw-r--r--drivers/base/regmap/regmap.c51
-rw-r--r--include/linux/regmap.h11
2 files changed, 54 insertions, 8 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7111d04f2621..dd63bcbbf8a5 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -34,7 +34,7 @@
34 34
35static int _regmap_update_bits(struct regmap *map, unsigned int reg, 35static int _regmap_update_bits(struct regmap *map, unsigned int reg,
36 unsigned int mask, unsigned int val, 36 unsigned int mask, unsigned int val,
37 bool *change); 37 bool *change, bool force_write);
38 38
39static int _regmap_bus_reg_read(void *context, unsigned int reg, 39static int _regmap_bus_reg_read(void *context, unsigned int reg,
40 unsigned int *val); 40 unsigned int *val);
@@ -1178,7 +1178,7 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
1178 ret = _regmap_update_bits(map, range->selector_reg, 1178 ret = _regmap_update_bits(map, range->selector_reg,
1179 range->selector_mask, 1179 range->selector_mask,
1180 win_page << range->selector_shift, 1180 win_page << range->selector_shift,
1181 &page_chg); 1181 &page_chg, false);
1182 1182
1183 map->work_buf = orig_work_buf; 1183 map->work_buf = orig_work_buf;
1184 1184
@@ -1624,6 +1624,18 @@ int regmap_fields_write(struct regmap_field *field, unsigned int id,
1624} 1624}
1625EXPORT_SYMBOL_GPL(regmap_fields_write); 1625EXPORT_SYMBOL_GPL(regmap_fields_write);
1626 1626
1627int regmap_fields_force_write(struct regmap_field *field, unsigned int id,
1628 unsigned int val)
1629{
1630 if (id >= field->id_size)
1631 return -EINVAL;
1632
1633 return regmap_write_bits(field->regmap,
1634 field->reg + (field->id_offset * id),
1635 field->mask, val << field->shift);
1636}
1637EXPORT_SYMBOL_GPL(regmap_fields_force_write);
1638
1627/** 1639/**
1628 * regmap_fields_update_bits(): Perform a read/modify/write cycle 1640 * regmap_fields_update_bits(): Perform a read/modify/write cycle
1629 * on the register field 1641 * on the register field
@@ -2327,7 +2339,7 @@ EXPORT_SYMBOL_GPL(regmap_bulk_read);
2327 2339
2328static int _regmap_update_bits(struct regmap *map, unsigned int reg, 2340static int _regmap_update_bits(struct regmap *map, unsigned int reg,
2329 unsigned int mask, unsigned int val, 2341 unsigned int mask, unsigned int val,
2330 bool *change) 2342 bool *change, bool force_write)
2331{ 2343{
2332 int ret; 2344 int ret;
2333 unsigned int tmp, orig; 2345 unsigned int tmp, orig;
@@ -2339,7 +2351,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
2339 tmp = orig & ~mask; 2351 tmp = orig & ~mask;
2340 tmp |= val & mask; 2352 tmp |= val & mask;
2341 2353
2342 if (tmp != orig) { 2354 if (force_write || (tmp != orig)) {
2343 ret = _regmap_write(map, reg, tmp); 2355 ret = _regmap_write(map, reg, tmp);
2344 if (change) 2356 if (change)
2345 *change = true; 2357 *change = true;
@@ -2367,7 +2379,7 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
2367 int ret; 2379 int ret;
2368 2380
2369 map->lock(map->lock_arg); 2381 map->lock(map->lock_arg);
2370 ret = _regmap_update_bits(map, reg, mask, val, NULL); 2382 ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
2371 map->unlock(map->lock_arg); 2383 map->unlock(map->lock_arg);
2372 2384
2373 return ret; 2385 return ret;
@@ -2375,6 +2387,29 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
2375EXPORT_SYMBOL_GPL(regmap_update_bits); 2387EXPORT_SYMBOL_GPL(regmap_update_bits);
2376 2388
2377/** 2389/**
2390 * regmap_write_bits: Perform a read/modify/write cycle on the register map
2391 *
2392 * @map: Register map to update
2393 * @reg: Register to update
2394 * @mask: Bitmask to change
2395 * @val: New value for bitmask
2396 *
2397 * Returns zero for success, a negative number on error.
2398 */
2399int regmap_write_bits(struct regmap *map, unsigned int reg,
2400 unsigned int mask, unsigned int val)
2401{
2402 int ret;
2403
2404 map->lock(map->lock_arg);
2405 ret = _regmap_update_bits(map, reg, mask, val, NULL, true);
2406 map->unlock(map->lock_arg);
2407
2408 return ret;
2409}
2410EXPORT_SYMBOL_GPL(regmap_write_bits);
2411
2412/**
2378 * regmap_update_bits_async: Perform a read/modify/write cycle on the register 2413 * regmap_update_bits_async: Perform a read/modify/write cycle on the register
2379 * map asynchronously 2414 * map asynchronously
2380 * 2415 *
@@ -2398,7 +2433,7 @@ int regmap_update_bits_async(struct regmap *map, unsigned int reg,
2398 2433
2399 map->async = true; 2434 map->async = true;
2400 2435
2401 ret = _regmap_update_bits(map, reg, mask, val, NULL); 2436 ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
2402 2437
2403 map->async = false; 2438 map->async = false;
2404 2439
@@ -2427,7 +2462,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
2427 int ret; 2462 int ret;
2428 2463
2429 map->lock(map->lock_arg); 2464 map->lock(map->lock_arg);
2430 ret = _regmap_update_bits(map, reg, mask, val, change); 2465 ret = _regmap_update_bits(map, reg, mask, val, change, false);
2431 map->unlock(map->lock_arg); 2466 map->unlock(map->lock_arg);
2432 return ret; 2467 return ret;
2433} 2468}
@@ -2460,7 +2495,7 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg,
2460 2495
2461 map->async = true; 2496 map->async = true;
2462 2497
2463 ret = _regmap_update_bits(map, reg, mask, val, change); 2498 ret = _regmap_update_bits(map, reg, mask, val, change, false);
2464 2499
2465 map->async = false; 2500 map->async = false;
2466 2501
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 59c55ea0f0b5..519c96231a91 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -424,6 +424,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
424 size_t val_count); 424 size_t val_count);
425int regmap_update_bits(struct regmap *map, unsigned int reg, 425int regmap_update_bits(struct regmap *map, unsigned int reg,
426 unsigned int mask, unsigned int val); 426 unsigned int mask, unsigned int val);
427int regmap_write_bits(struct regmap *map, unsigned int reg,
428 unsigned int mask, unsigned int val);
427int regmap_update_bits_async(struct regmap *map, unsigned int reg, 429int regmap_update_bits_async(struct regmap *map, unsigned int reg,
428 unsigned int mask, unsigned int val); 430 unsigned int mask, unsigned int val);
429int regmap_update_bits_check(struct regmap *map, unsigned int reg, 431int regmap_update_bits_check(struct regmap *map, unsigned int reg,
@@ -503,6 +505,8 @@ int regmap_field_update_bits(struct regmap_field *field,
503 505
504int regmap_fields_write(struct regmap_field *field, unsigned int id, 506int regmap_fields_write(struct regmap_field *field, unsigned int id,
505 unsigned int val); 507 unsigned int val);
508int regmap_fields_force_write(struct regmap_field *field, unsigned int id,
509 unsigned int val);
506int regmap_fields_read(struct regmap_field *field, unsigned int id, 510int regmap_fields_read(struct regmap_field *field, unsigned int id,
507 unsigned int *val); 511 unsigned int *val);
508int regmap_fields_update_bits(struct regmap_field *field, unsigned int id, 512int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
@@ -645,6 +649,13 @@ static inline int regmap_update_bits(struct regmap *map, unsigned int reg,
645 return -EINVAL; 649 return -EINVAL;
646} 650}
647 651
652static inline int regmap_write_bits(struct regmap *map, unsigned int reg,
653 unsigned int mask, unsigned int val)
654{
655 WARN_ONCE(1, "regmap API is disabled");
656 return -EINVAL;
657}
658
648static inline int regmap_update_bits_async(struct regmap *map, 659static inline int regmap_update_bits_async(struct regmap *map,
649 unsigned int reg, 660 unsigned int reg,
650 unsigned int mask, unsigned int val) 661 unsigned int mask, unsigned int val)