32
32
#include "pinctrl-samsung.h"
33
33
#include "pinctrl-exynos.h"
34
34
35
+ #define MAX_WAKEUP_REG 3
36
+
35
37
struct exynos_irq_chip {
36
38
struct irq_chip chip ;
37
39
38
40
u32 eint_con ;
39
41
u32 eint_mask ;
40
42
u32 eint_pend ;
41
- u32 * eint_wake_mask_value ;
43
+ u32 eint_num_wakeup_reg ;
42
44
u32 eint_wake_mask_reg ;
43
45
void (* set_eint_wakeup_mask )(struct samsung_pinctrl_drv_data * drvdata ,
44
46
struct exynos_irq_chip * irq_chip );
45
47
};
46
48
49
+ static u32 eint_wake_mask_values [MAX_WAKEUP_REG ] = { EXYNOS_EINT_WAKEUP_MASK_DISABLED ,
50
+ EXYNOS_EINT_WAKEUP_MASK_DISABLED ,
51
+ EXYNOS_EINT_WAKEUP_MASK_DISABLED };
52
+
47
53
static inline struct exynos_irq_chip * to_exynos_irq_chip (struct irq_chip * chip )
48
54
{
49
55
return container_of (chip , struct exynos_irq_chip , chip );
@@ -307,7 +313,7 @@ static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = {
307
313
.eint_con = EXYNOS_GPIO_ECON_OFFSET ,
308
314
.eint_mask = EXYNOS_GPIO_EMASK_OFFSET ,
309
315
.eint_pend = EXYNOS_GPIO_EPEND_OFFSET ,
310
- /* eint_wake_mask_value not used */
316
+ /* eint_wake_mask_values not used */
311
317
};
312
318
313
319
static int exynos_eint_irq_map (struct irq_domain * h , unsigned int virq ,
@@ -467,20 +473,65 @@ __init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
467
473
return ret ;
468
474
}
469
475
476
+ #define BITS_PER_U32 32
477
+ static int gs101_wkup_irq_set_wake (struct irq_data * irqd , unsigned int on )
478
+ {
479
+ struct samsung_pin_bank * bank = irq_data_get_irq_chip_data (irqd );
480
+ struct samsung_pinctrl_drv_data * d = bank -> drvdata ;
481
+ u32 bit , wakeup_reg , shift ;
482
+
483
+ bit = bank -> eint_num + irqd -> hwirq ;
484
+ wakeup_reg = bit / BITS_PER_U32 ;
485
+ shift = bit - (wakeup_reg * BITS_PER_U32 );
486
+
487
+ if (!on )
488
+ eint_wake_mask_values [wakeup_reg ] |= BIT_U32 (shift );
489
+ else
490
+ eint_wake_mask_values [wakeup_reg ] &= ~BIT_U32 (shift );
491
+
492
+ dev_info (d -> dev , "wake %s for irq %d\n" , str_enabled_disabled (on ),
493
+ irqd -> irq );
494
+
495
+ return 0 ;
496
+ }
497
+
498
+ static void
499
+ gs101_pinctrl_set_eint_wakeup_mask (struct samsung_pinctrl_drv_data * drvdata ,
500
+ struct exynos_irq_chip * irq_chip )
501
+ {
502
+ struct regmap * pmu_regs ;
503
+
504
+ if (!drvdata -> retention_ctrl || !drvdata -> retention_ctrl -> priv ) {
505
+ dev_warn (drvdata -> dev ,
506
+ "No PMU syscon available. Wake-up mask will not be set.\n" );
507
+ return ;
508
+ }
509
+
510
+ pmu_regs = drvdata -> retention_ctrl -> priv ;
511
+
512
+ dev_dbg (drvdata -> dev , "Setting external wakeup interrupt mask:\n" );
513
+
514
+ for (int i = 0 ; i < irq_chip -> eint_num_wakeup_reg ; i ++ ) {
515
+ dev_dbg (drvdata -> dev , "\tWAKEUP_MASK%d[0x%X] value[0x%X]\n" ,
516
+ i , irq_chip -> eint_wake_mask_reg + i * 4 ,
517
+ eint_wake_mask_values [i ]);
518
+ regmap_write (pmu_regs , irq_chip -> eint_wake_mask_reg + i * 4 ,
519
+ eint_wake_mask_values [i ]);
520
+ }
521
+ }
522
+
470
523
static int exynos_wkup_irq_set_wake (struct irq_data * irqd , unsigned int on )
471
524
{
472
- struct irq_chip * chip = irq_data_get_irq_chip (irqd );
473
- struct exynos_irq_chip * our_chip = to_exynos_irq_chip (chip );
474
525
struct samsung_pin_bank * bank = irq_data_get_irq_chip_data (irqd );
475
526
unsigned long bit = 1UL << (2 * bank -> eint_offset + irqd -> hwirq );
476
527
477
528
pr_info ("wake %s for irq %u (%s-%lu)\n" , str_enabled_disabled (on ),
478
529
irqd -> irq , bank -> name , irqd -> hwirq );
479
530
480
531
if (!on )
481
- * our_chip -> eint_wake_mask_value |= bit ;
532
+ eint_wake_mask_values [ 0 ] |= bit ;
482
533
else
483
- * our_chip -> eint_wake_mask_value &= ~bit ;
534
+ eint_wake_mask_values [ 0 ] &= ~bit ;
484
535
485
536
return 0 ;
486
537
}
@@ -500,10 +551,10 @@ exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
500
551
pmu_regs = drvdata -> retention_ctrl -> priv ;
501
552
dev_info (drvdata -> dev ,
502
553
"Setting external wakeup interrupt mask: 0x%x\n" ,
503
- * irq_chip -> eint_wake_mask_value );
554
+ eint_wake_mask_values [ 0 ] );
504
555
505
556
regmap_write (pmu_regs , irq_chip -> eint_wake_mask_reg ,
506
- * irq_chip -> eint_wake_mask_value );
557
+ eint_wake_mask_values [ 0 ] );
507
558
}
508
559
509
560
static void
@@ -522,11 +573,10 @@ s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
522
573
523
574
clk_base = (void __iomem * ) drvdata -> retention_ctrl -> priv ;
524
575
525
- __raw_writel (* irq_chip -> eint_wake_mask_value ,
576
+ __raw_writel (eint_wake_mask_values [ 0 ] ,
526
577
clk_base + irq_chip -> eint_wake_mask_reg );
527
578
}
528
579
529
- static u32 eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED ;
530
580
/*
531
581
* irq_chip for wakeup interrupts
532
582
*/
@@ -544,7 +594,7 @@ static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = {
544
594
.eint_con = EXYNOS_WKUP_ECON_OFFSET ,
545
595
.eint_mask = EXYNOS_WKUP_EMASK_OFFSET ,
546
596
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET ,
547
- .eint_wake_mask_value = & eint_wake_mask_value ,
597
+ .eint_num_wakeup_reg = 1 ,
548
598
/* Only differences with exynos4210_wkup_irq_chip: */
549
599
.eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK ,
550
600
.set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask ,
@@ -564,7 +614,7 @@ static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
564
614
.eint_con = EXYNOS_WKUP_ECON_OFFSET ,
565
615
.eint_mask = EXYNOS_WKUP_EMASK_OFFSET ,
566
616
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET ,
567
- .eint_wake_mask_value = & eint_wake_mask_value ,
617
+ .eint_num_wakeup_reg = 1 ,
568
618
.eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK ,
569
619
.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask ,
570
620
};
@@ -583,7 +633,7 @@ static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
583
633
.eint_con = EXYNOS7_WKUP_ECON_OFFSET ,
584
634
.eint_mask = EXYNOS7_WKUP_EMASK_OFFSET ,
585
635
.eint_pend = EXYNOS7_WKUP_EPEND_OFFSET ,
586
- .eint_wake_mask_value = & eint_wake_mask_value ,
636
+ .eint_num_wakeup_reg = 1 ,
587
637
.eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK ,
588
638
.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask ,
589
639
};
@@ -599,13 +649,34 @@ static const struct exynos_irq_chip exynosautov920_wkup_irq_chip __initconst = {
599
649
.irq_request_resources = exynos_irq_request_resources ,
600
650
.irq_release_resources = exynos_irq_release_resources ,
601
651
},
602
- .eint_wake_mask_value = & eint_wake_mask_value ,
652
+ .eint_num_wakeup_reg = 1 ,
603
653
.eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK ,
604
654
.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask ,
605
655
};
606
656
657
+ static const struct exynos_irq_chip gs101_wkup_irq_chip __initconst = {
658
+ .chip = {
659
+ .name = "gs101_wkup_irq_chip" ,
660
+ .irq_unmask = exynos_irq_unmask ,
661
+ .irq_mask = exynos_irq_mask ,
662
+ .irq_ack = exynos_irq_ack ,
663
+ .irq_set_type = exynos_irq_set_type ,
664
+ .irq_set_wake = gs101_wkup_irq_set_wake ,
665
+ .irq_request_resources = exynos_irq_request_resources ,
666
+ .irq_release_resources = exynos_irq_release_resources ,
667
+ },
668
+ .eint_con = EXYNOS7_WKUP_ECON_OFFSET ,
669
+ .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET ,
670
+ .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET ,
671
+ .eint_num_wakeup_reg = 3 ,
672
+ .eint_wake_mask_reg = GS101_EINT_WAKEUP_MASK ,
673
+ .set_eint_wakeup_mask = gs101_pinctrl_set_eint_wakeup_mask ,
674
+ };
675
+
607
676
/* list of external wakeup controllers supported */
608
677
static const struct of_device_id exynos_wkup_irq_ids [] = {
678
+ { .compatible = "google,gs101-wakeup-eint" ,
679
+ .data = & gs101_wkup_irq_chip },
609
680
{ .compatible = "samsung,s5pv210-wakeup-eint" ,
610
681
.data = & s5pv210_wkup_irq_chip },
611
682
{ .compatible = "samsung,exynos4210-wakeup-eint" ,
@@ -688,6 +759,7 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
688
759
chained_irq_exit (chip , desc );
689
760
}
690
761
762
+ static int eint_num ;
691
763
/*
692
764
* exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
693
765
* @d: driver data of samsung pinctrl driver.
@@ -736,6 +808,9 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
736
808
return - ENXIO ;
737
809
}
738
810
811
+ bank -> eint_num = eint_num ;
812
+ eint_num = eint_num + bank -> nr_pins ;
813
+
739
814
if (!fwnode_property_present (bank -> fwnode , "interrupts" )) {
740
815
bank -> eint_type = EINT_TYPE_WKUP_MUX ;
741
816
++ muxed_banks ;
0 commit comments