diff options
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/db8500-prcmu.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index d2244dc5d3b1..8346a0e39949 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mfd/dbx500-prcmu.h> | 30 | #include <linux/mfd/dbx500-prcmu.h> |
31 | #include <linux/regulator/db8500-prcmu.h> | 31 | #include <linux/regulator/db8500-prcmu.h> |
32 | #include <linux/regulator/machine.h> | 32 | #include <linux/regulator/machine.h> |
33 | #include <asm/hardware/gic.h> | ||
33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
34 | #include <mach/irqs.h> | 35 | #include <mach/irqs.h> |
35 | #include <mach/db8500-regs.h> | 36 | #include <mach/db8500-regs.h> |
@@ -850,6 +851,38 @@ int db8500_prcmu_gic_recouple(void) | |||
850 | return 0; | 851 | return 0; |
851 | } | 852 | } |
852 | 853 | ||
854 | #define PRCMU_GIC_NUMBER_REGS 5 | ||
855 | |||
856 | /* | ||
857 | * This function checks if there are pending irq on the gic. It only | ||
858 | * makes sense if the gic has been decoupled before with the | ||
859 | * db8500_prcmu_gic_decouple function. Disabling an interrupt only | ||
860 | * disables the forwarding of the interrupt to any CPU interface. It | ||
861 | * does not prevent the interrupt from changing state, for example | ||
862 | * becoming pending, or active and pending if it is already | ||
863 | * active. Hence, we have to check the interrupt is pending *and* is | ||
864 | * active. | ||
865 | */ | ||
866 | bool db8500_prcmu_gic_pending_irq(void) | ||
867 | { | ||
868 | u32 pr; /* Pending register */ | ||
869 | u32 er; /* Enable register */ | ||
870 | void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE); | ||
871 | int i; | ||
872 | |||
873 | /* 5 registers. STI & PPI not skipped */ | ||
874 | for (i = 0; i < PRCMU_GIC_NUMBER_REGS; i++) { | ||
875 | |||
876 | pr = readl_relaxed(dist_base + GIC_DIST_PENDING_SET + i * 4); | ||
877 | er = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); | ||
878 | |||
879 | if (pr & er) | ||
880 | return true; /* There is a pending interrupt */ | ||
881 | } | ||
882 | |||
883 | return false; | ||
884 | } | ||
885 | |||
853 | /* This function should only be called while mb0_transfer.lock is held. */ | 886 | /* This function should only be called while mb0_transfer.lock is held. */ |
854 | static void config_wakeups(void) | 887 | static void config_wakeups(void) |
855 | { | 888 | { |