aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/regmap/regcache.c21
-rw-r--r--drivers/base/regmap/regmap-irq.c100
-rw-r--r--drivers/base/regmap/regmap.c102
-rw-r--r--include/linux/regmap.h16
4 files changed, 239 insertions, 0 deletions
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 60aeaad7fb69..348be3a35410 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -543,19 +543,30 @@ bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
543 switch (map->cache_word_size) { 543 switch (map->cache_word_size) {
544 case 1: { 544 case 1: {
545 u8 *cache = base; 545 u8 *cache = base;
546
546 cache[idx] = val; 547 cache[idx] = val;
547 break; 548 break;
548 } 549 }
549 case 2: { 550 case 2: {
550 u16 *cache = base; 551 u16 *cache = base;
552
551 cache[idx] = val; 553 cache[idx] = val;
552 break; 554 break;
553 } 555 }
554 case 4: { 556 case 4: {
555 u32 *cache = base; 557 u32 *cache = base;
558
559 cache[idx] = val;
560 break;
561 }
562#ifdef CONFIG_64BIT
563 case 8: {
564 u64 *cache = base;
565
556 cache[idx] = val; 566 cache[idx] = val;
557 break; 567 break;
558 } 568 }
569#endif
559 default: 570 default:
560 BUG(); 571 BUG();
561 } 572 }
@@ -576,16 +587,26 @@ unsigned int regcache_get_val(struct regmap *map, const void *base,
576 switch (map->cache_word_size) { 587 switch (map->cache_word_size) {
577 case 1: { 588 case 1: {
578 const u8 *cache = base; 589 const u8 *cache = base;
590
579 return cache[idx]; 591 return cache[idx];
580 } 592 }
581 case 2: { 593 case 2: {
582 const u16 *cache = base; 594 const u16 *cache = base;
595
583 return cache[idx]; 596 return cache[idx];
584 } 597 }
585 case 4: { 598 case 4: {
586 const u32 *cache = base; 599 const u32 *cache = base;
600
601 return cache[idx];
602 }
603#ifdef CONFIG_64BIT
604 case 8: {
605 const u64 *cache = base;
606
587 return cache[idx]; 607 return cache[idx];
588 } 608 }
609#endif
589 default: 610 default:
590 BUG(); 611 BUG();
591 } 612 }
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 4d2cb21254aa..9b0d202414d0 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -39,8 +39,11 @@ struct regmap_irq_chip_data {
39 unsigned int *mask_buf; 39 unsigned int *mask_buf;
40 unsigned int *mask_buf_def; 40 unsigned int *mask_buf_def;
41 unsigned int *wake_buf; 41 unsigned int *wake_buf;
42 unsigned int *type_buf;
43 unsigned int *type_buf_def;
42 44
43 unsigned int irq_reg_stride; 45 unsigned int irq_reg_stride;
46 unsigned int type_reg_stride;
44}; 47};
45 48
46static inline const 49static inline const
@@ -144,6 +147,22 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
144 } 147 }
145 } 148 }
146 149
150 for (i = 0; i < d->chip->num_type_reg; i++) {
151 if (!d->type_buf_def[i])
152 continue;
153 reg = d->chip->type_base +
154 (i * map->reg_stride * d->type_reg_stride);
155 if (d->chip->type_invert)
156 ret = regmap_update_bits(d->map, reg,
157 d->type_buf_def[i], ~d->type_buf[i]);
158 else
159 ret = regmap_update_bits(d->map, reg,
160 d->type_buf_def[i], d->type_buf[i]);
161 if (ret != 0)
162 dev_err(d->map->dev, "Failed to sync type in %x\n",
163 reg);
164 }
165
147 if (d->chip->runtime_pm) 166 if (d->chip->runtime_pm)
148 pm_runtime_put(map->dev); 167 pm_runtime_put(map->dev);
149 168
@@ -178,6 +197,38 @@ static void regmap_irq_disable(struct irq_data *data)
178 d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; 197 d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask;
179} 198}
180 199
200static int regmap_irq_set_type(struct irq_data *data, unsigned int type)
201{
202 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
203 struct regmap *map = d->map;
204 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
205 int reg = irq_data->type_reg_offset / map->reg_stride;
206
207 if (!(irq_data->type_rising_mask | irq_data->type_falling_mask))
208 return 0;
209
210 d->type_buf[reg] &= ~(irq_data->type_falling_mask |
211 irq_data->type_rising_mask);
212 switch (type) {
213 case IRQ_TYPE_EDGE_FALLING:
214 d->type_buf[reg] |= irq_data->type_falling_mask;
215 break;
216
217 case IRQ_TYPE_EDGE_RISING:
218 d->type_buf[reg] |= irq_data->type_rising_mask;
219 break;
220
221 case IRQ_TYPE_EDGE_BOTH:
222 d->type_buf[reg] |= (irq_data->type_falling_mask |
223 irq_data->type_rising_mask);
224 break;
225
226 default:
227 return -EINVAL;
228 }
229 return 0;
230}
231
181static int regmap_irq_set_wake(struct irq_data *data, unsigned int on) 232static int regmap_irq_set_wake(struct irq_data *data, unsigned int on)
182{ 233{
183 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 234 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
@@ -204,6 +255,7 @@ static const struct irq_chip regmap_irq_chip = {
204 .irq_bus_sync_unlock = regmap_irq_sync_unlock, 255 .irq_bus_sync_unlock = regmap_irq_sync_unlock,
205 .irq_disable = regmap_irq_disable, 256 .irq_disable = regmap_irq_disable,
206 .irq_enable = regmap_irq_enable, 257 .irq_enable = regmap_irq_enable,
258 .irq_set_type = regmap_irq_set_type,
207 .irq_set_wake = regmap_irq_set_wake, 259 .irq_set_wake = regmap_irq_set_wake,
208}; 260};
209 261
@@ -408,6 +460,18 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
408 goto err_alloc; 460 goto err_alloc;
409 } 461 }
410 462
463 if (chip->num_type_reg) {
464 d->type_buf_def = kcalloc(chip->num_type_reg,
465 sizeof(unsigned int), GFP_KERNEL);
466 if (!d->type_buf_def)
467 goto err_alloc;
468
469 d->type_buf = kcalloc(chip->num_type_reg, sizeof(unsigned int),
470 GFP_KERNEL);
471 if (!d->type_buf)
472 goto err_alloc;
473 }
474
411 d->irq_chip = regmap_irq_chip; 475 d->irq_chip = regmap_irq_chip;
412 d->irq_chip.name = chip->name; 476 d->irq_chip.name = chip->name;
413 d->irq = irq; 477 d->irq = irq;
@@ -420,6 +484,11 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
420 else 484 else
421 d->irq_reg_stride = 1; 485 d->irq_reg_stride = 1;
422 486
487 if (chip->type_reg_stride)
488 d->type_reg_stride = chip->type_reg_stride;
489 else
490 d->type_reg_stride = 1;
491
423 if (!map->use_single_read && map->reg_stride == 1 && 492 if (!map->use_single_read && map->reg_stride == 1 &&
424 d->irq_reg_stride == 1) { 493 d->irq_reg_stride == 1) {
425 d->status_reg_buf = kmalloc_array(chip->num_regs, 494 d->status_reg_buf = kmalloc_array(chip->num_regs,
@@ -512,6 +581,33 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
512 } 581 }
513 } 582 }
514 583
584 if (chip->num_type_reg) {
585 for (i = 0; i < chip->num_irqs; i++) {
586 reg = chip->irqs[i].type_reg_offset / map->reg_stride;
587 d->type_buf_def[reg] |= chip->irqs[i].type_rising_mask |
588 chip->irqs[i].type_falling_mask;
589 }
590 for (i = 0; i < chip->num_type_reg; ++i) {
591 if (!d->type_buf_def[i])
592 continue;
593
594 reg = chip->type_base +
595 (i * map->reg_stride * d->type_reg_stride);
596 if (chip->type_invert)
597 ret = regmap_update_bits(map, reg,
598 d->type_buf_def[i], 0xFF);
599 else
600 ret = regmap_update_bits(map, reg,
601 d->type_buf_def[i], 0x0);
602 if (ret != 0) {
603 dev_err(map->dev,
604 "Failed to set type in 0x%x: %x\n",
605 reg, ret);
606 goto err_alloc;
607 }
608 }
609 }
610
515 if (irq_base) 611 if (irq_base)
516 d->domain = irq_domain_add_legacy(map->dev->of_node, 612 d->domain = irq_domain_add_legacy(map->dev->of_node,
517 chip->num_irqs, irq_base, 0, 613 chip->num_irqs, irq_base, 0,
@@ -542,6 +638,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
542err_domain: 638err_domain:
543 /* Should really dispose of the domain but... */ 639 /* Should really dispose of the domain but... */
544err_alloc: 640err_alloc:
641 kfree(d->type_buf);
642 kfree(d->type_buf_def);
545 kfree(d->wake_buf); 643 kfree(d->wake_buf);
546 kfree(d->mask_buf_def); 644 kfree(d->mask_buf_def);
547 kfree(d->mask_buf); 645 kfree(d->mask_buf);
@@ -565,6 +663,8 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
565 663
566 free_irq(irq, d); 664 free_irq(irq, d);
567 irq_domain_remove(d->domain); 665 irq_domain_remove(d->domain);
666 kfree(d->type_buf);
667 kfree(d->type_buf_def);
568 kfree(d->wake_buf); 668 kfree(d->wake_buf);
569 kfree(d->mask_buf_def); 669 kfree(d->mask_buf_def);
570 kfree(d->mask_buf); 670 kfree(d->mask_buf);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a8f6dd9457be..ee54e841de4a 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -245,6 +245,28 @@ static void regmap_format_32_native(void *buf, unsigned int val,
245 *(u32 *)buf = val << shift; 245 *(u32 *)buf = val << shift;
246} 246}
247 247
248#ifdef CONFIG_64BIT
249static void regmap_format_64_be(void *buf, unsigned int val, unsigned int shift)
250{
251 __be64 *b = buf;
252
253 b[0] = cpu_to_be64((u64)val << shift);
254}
255
256static void regmap_format_64_le(void *buf, unsigned int val, unsigned int shift)
257{
258 __le64 *b = buf;
259
260 b[0] = cpu_to_le64((u64)val << shift);
261}
262
263static void regmap_format_64_native(void *buf, unsigned int val,
264 unsigned int shift)
265{
266 *(u64 *)buf = (u64)val << shift;
267}
268#endif
269
248static void regmap_parse_inplace_noop(void *buf) 270static void regmap_parse_inplace_noop(void *buf)
249{ 271{
250} 272}
@@ -332,6 +354,41 @@ static unsigned int regmap_parse_32_native(const void *buf)
332 return *(u32 *)buf; 354 return *(u32 *)buf;
333} 355}
334 356
357#ifdef CONFIG_64BIT
358static unsigned int regmap_parse_64_be(const void *buf)
359{
360 const __be64 *b = buf;
361
362 return be64_to_cpu(b[0]);
363}
364
365static unsigned int regmap_parse_64_le(const void *buf)
366{
367 const __le64 *b = buf;
368
369 return le64_to_cpu(b[0]);
370}
371
372static void regmap_parse_64_be_inplace(void *buf)
373{
374 __be64 *b = buf;
375
376 b[0] = be64_to_cpu(b[0]);
377}
378
379static void regmap_parse_64_le_inplace(void *buf)
380{
381 __le64 *b = buf;
382
383 b[0] = le64_to_cpu(b[0]);
384}
385
386static unsigned int regmap_parse_64_native(const void *buf)
387{
388 return *(u64 *)buf;
389}
390#endif
391
335static void regmap_lock_mutex(void *__map) 392static void regmap_lock_mutex(void *__map)
336{ 393{
337 struct regmap *map = __map; 394 struct regmap *map = __map;
@@ -712,6 +769,21 @@ struct regmap *__regmap_init(struct device *dev,
712 } 769 }
713 break; 770 break;
714 771
772#ifdef CONFIG_64BIT
773 case 64:
774 switch (reg_endian) {
775 case REGMAP_ENDIAN_BIG:
776 map->format.format_reg = regmap_format_64_be;
777 break;
778 case REGMAP_ENDIAN_NATIVE:
779 map->format.format_reg = regmap_format_64_native;
780 break;
781 default:
782 goto err_map;
783 }
784 break;
785#endif
786
715 default: 787 default:
716 goto err_map; 788 goto err_map;
717 } 789 }
@@ -771,6 +843,28 @@ struct regmap *__regmap_init(struct device *dev,
771 goto err_map; 843 goto err_map;
772 } 844 }
773 break; 845 break;
846#ifdef CONFIG_64BIT
847 case 64:
848 switch (val_endian) {
849 case REGMAP_ENDIAN_BIG:
850 map->format.format_val = regmap_format_64_be;
851 map->format.parse_val = regmap_parse_64_be;
852 map->format.parse_inplace = regmap_parse_64_be_inplace;
853 break;
854 case REGMAP_ENDIAN_LITTLE:
855 map->format.format_val = regmap_format_64_le;
856 map->format.parse_val = regmap_parse_64_le;
857 map->format.parse_inplace = regmap_parse_64_le_inplace;
858 break;
859 case REGMAP_ENDIAN_NATIVE:
860 map->format.format_val = regmap_format_64_native;
861 map->format.parse_val = regmap_parse_64_native;
862 break;
863 default:
864 goto err_map;
865 }
866 break;
867#endif
774 } 868 }
775 869
776 if (map->format.format_write) { 870 if (map->format.format_write) {
@@ -2488,11 +2582,19 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
2488 * we assume that the values are native 2582 * we assume that the values are native
2489 * endian. 2583 * endian.
2490 */ 2584 */
2585#ifdef CONFIG_64BIT
2586 u64 *u64 = val;
2587#endif
2491 u32 *u32 = val; 2588 u32 *u32 = val;
2492 u16 *u16 = val; 2589 u16 *u16 = val;
2493 u8 *u8 = val; 2590 u8 *u8 = val;
2494 2591
2495 switch (map->format.val_bytes) { 2592 switch (map->format.val_bytes) {
2593#ifdef CONFIG_64BIT
2594 case 8:
2595 u64[i] = ival;
2596 break;
2597#endif
2496 case 4: 2598 case 4:
2497 u32[i] = ival; 2599 u32[i] = ival;
2498 break; 2600 break;
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 4d9a1a04647b..18394343f489 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -788,10 +788,16 @@ int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
788 * 788 *
789 * @reg_offset: Offset of the status/mask register within the bank 789 * @reg_offset: Offset of the status/mask register within the bank
790 * @mask: Mask used to flag/control the register. 790 * @mask: Mask used to flag/control the register.
791 * @type_reg_offset: Offset register for the irq type setting.
792 * @type_rising_mask: Mask bit to configure RISING type irq.
793 * @type_falling_mask: Mask bit to configure FALLING type irq.
791 */ 794 */
792struct regmap_irq { 795struct regmap_irq {
793 unsigned int reg_offset; 796 unsigned int reg_offset;
794 unsigned int mask; 797 unsigned int mask;
798 unsigned int type_reg_offset;
799 unsigned int type_rising_mask;
800 unsigned int type_falling_mask;
795}; 801};
796 802
797#define REGMAP_IRQ_REG(_irq, _off, _mask) \ 803#define REGMAP_IRQ_REG(_irq, _off, _mask) \
@@ -811,18 +817,23 @@ struct regmap_irq {
811 * @ack_base: Base ack address. If zero then the chip is clear on read. 817 * @ack_base: Base ack address. If zero then the chip is clear on read.
812 * Using zero value is possible with @use_ack bit. 818 * Using zero value is possible with @use_ack bit.
813 * @wake_base: Base address for wake enables. If zero unsupported. 819 * @wake_base: Base address for wake enables. If zero unsupported.
820 * @type_base: Base address for irq type. If zero unsupported.
814 * @irq_reg_stride: Stride to use for chips where registers are not contiguous. 821 * @irq_reg_stride: Stride to use for chips where registers are not contiguous.
815 * @init_ack_masked: Ack all masked interrupts once during initalization. 822 * @init_ack_masked: Ack all masked interrupts once during initalization.
816 * @mask_invert: Inverted mask register: cleared bits are masked out. 823 * @mask_invert: Inverted mask register: cleared bits are masked out.
817 * @use_ack: Use @ack register even if it is zero. 824 * @use_ack: Use @ack register even if it is zero.
818 * @ack_invert: Inverted ack register: cleared bits for ack. 825 * @ack_invert: Inverted ack register: cleared bits for ack.
819 * @wake_invert: Inverted wake register: cleared bits are wake enabled. 826 * @wake_invert: Inverted wake register: cleared bits are wake enabled.
827 * @type_invert: Invert the type flags.
820 * @runtime_pm: Hold a runtime PM lock on the device when accessing it. 828 * @runtime_pm: Hold a runtime PM lock on the device when accessing it.
821 * 829 *
822 * @num_regs: Number of registers in each control bank. 830 * @num_regs: Number of registers in each control bank.
823 * @irqs: Descriptors for individual IRQs. Interrupt numbers are 831 * @irqs: Descriptors for individual IRQs. Interrupt numbers are
824 * assigned based on the index in the array of the interrupt. 832 * assigned based on the index in the array of the interrupt.
825 * @num_irqs: Number of descriptors. 833 * @num_irqs: Number of descriptors.
834 * @num_type_reg: Number of type registers.
835 * @type_reg_stride: Stride to use for chips where type registers are not
836 * contiguous.
826 */ 837 */
827struct regmap_irq_chip { 838struct regmap_irq_chip {
828 const char *name; 839 const char *name;
@@ -832,6 +843,7 @@ struct regmap_irq_chip {
832 unsigned int unmask_base; 843 unsigned int unmask_base;
833 unsigned int ack_base; 844 unsigned int ack_base;
834 unsigned int wake_base; 845 unsigned int wake_base;
846 unsigned int type_base;
835 unsigned int irq_reg_stride; 847 unsigned int irq_reg_stride;
836 bool init_ack_masked:1; 848 bool init_ack_masked:1;
837 bool mask_invert:1; 849 bool mask_invert:1;
@@ -839,11 +851,15 @@ struct regmap_irq_chip {
839 bool ack_invert:1; 851 bool ack_invert:1;
840 bool wake_invert:1; 852 bool wake_invert:1;
841 bool runtime_pm:1; 853 bool runtime_pm:1;
854 bool type_invert:1;
842 855
843 int num_regs; 856 int num_regs;
844 857
845 const struct regmap_irq *irqs; 858 const struct regmap_irq *irqs;
846 int num_irqs; 859 int num_irqs;
860
861 int num_type_reg;
862 unsigned int type_reg_stride;
847}; 863};
848 864
849struct regmap_irq_chip_data; 865struct regmap_irq_chip_data;