diff options
author | Paul Walmsley <paul@pwsan.com> | 2012-10-21 03:01:13 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-10-21 03:01:13 -0400 |
commit | 2bb2a5d30abb0dc99d074877bfad2056142c730b (patch) | |
tree | 6da1f32009cec6777baa0a474f7c2579cc57a6bc /arch/arm/mach-omap2/prm44xx.c | |
parent | b5c5353d417580f7a6ac21a0954f1c500a5cc4f5 (diff) |
ARM: OMAP2+: PRM: create PRM reset source API for the watchdog timer driver
The OMAP watchdog timer driver needs to determine what caused the SoC
to reset for its GETBOOTSTATUS ioctl. So, define a set of standard
reset sources across OMAP SoCs. For OMAP2xxx, 3xxx, and 4xxx SoCs,
define mappings from the SoC-specific reset source register bits to
the standardized reset source IDs. Create SoC-specific PRM functions
that read the appropriate per-SoC register and use the mapping to
return the standardized reset bits. Register the SoC-specific PRM
functions with the common PRM code via prm_register(). Create a
function in the common PRM code, prm_read_reset_sources(), that
calls the SoC-specific function, registered during boot.
This patch does not yet handle some SoCs, such as AM33xx. Those SoCs
were not handled by the code this will replace.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/prm44xx.c')
-rw-r--r-- | arch/arm/mach-omap2/prm44xx.c | 83 |
1 files changed, 80 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 48d91930796d..a799e9552fbf 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP4 PRM module functions | 2 | * OMAP4 PRM module functions |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Texas Instruments, Inc. | 4 | * Copyright (C) 2011-2012 Texas Instruments, Inc. |
5 | * Copyright (C) 2010 Nokia Corporation | 5 | * Copyright (C) 2010 Nokia Corporation |
6 | * Benoît Cousson | 6 | * Benoît Cousson |
7 | * Paul Walmsley | 7 | * Paul Walmsley |
@@ -30,6 +30,8 @@ | |||
30 | #include "prminst44xx.h" | 30 | #include "prminst44xx.h" |
31 | #include "powerdomain.h" | 31 | #include "powerdomain.h" |
32 | 32 | ||
33 | /* Static data */ | ||
34 | |||
33 | static const struct omap_prcm_irq omap4_prcm_irqs[] = { | 35 | static const struct omap_prcm_irq omap4_prcm_irqs[] = { |
34 | OMAP_PRCM_IRQ("wkup", 0, 0), | 36 | OMAP_PRCM_IRQ("wkup", 0, 0), |
35 | OMAP_PRCM_IRQ("io", 9, 1), | 37 | OMAP_PRCM_IRQ("io", 9, 1), |
@@ -48,6 +50,33 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { | |||
48 | .restore_irqen = &omap44xx_prm_restore_irqen, | 50 | .restore_irqen = &omap44xx_prm_restore_irqen, |
49 | }; | 51 | }; |
50 | 52 | ||
53 | /* | ||
54 | * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST | ||
55 | * hardware register (which are specific to OMAP44xx SoCs) to reset | ||
56 | * source ID bit shifts (which is an OMAP SoC-independent | ||
57 | * enumeration) | ||
58 | */ | ||
59 | static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { | ||
60 | { OMAP4430_RST_GLOBAL_WARM_SW_SHIFT, | ||
61 | OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, | ||
62 | { OMAP4430_RST_GLOBAL_COLD_SW_SHIFT, | ||
63 | OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, | ||
64 | { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT, | ||
65 | OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, | ||
66 | { OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, | ||
67 | { OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT }, | ||
68 | { OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT }, | ||
69 | { OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT, | ||
70 | OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT }, | ||
71 | { OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT, | ||
72 | OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT }, | ||
73 | { OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT, | ||
74 | OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT }, | ||
75 | { OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT }, | ||
76 | { OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT }, | ||
77 | { -1, -1 }, | ||
78 | }; | ||
79 | |||
51 | /* PRM low-level functions */ | 80 | /* PRM low-level functions */ |
52 | 81 | ||
53 | /* Read a register in a CM/PRM instance in the PRM module */ | 82 | /* Read a register in a CM/PRM instance in the PRM module */ |
@@ -293,6 +322,31 @@ static void __init omap44xx_prm_enable_io_wakeup(void) | |||
293 | OMAP4_PRM_IO_PMCTRL_OFFSET); | 322 | OMAP4_PRM_IO_PMCTRL_OFFSET); |
294 | } | 323 | } |
295 | 324 | ||
325 | /** | ||
326 | * omap44xx_prm_read_reset_sources - return the last SoC reset source | ||
327 | * | ||
328 | * Return a u32 representing the last reset sources of the SoC. The | ||
329 | * returned reset source bits are standardized across OMAP SoCs. | ||
330 | */ | ||
331 | static u32 omap44xx_prm_read_reset_sources(void) | ||
332 | { | ||
333 | struct prm_reset_src_map *p; | ||
334 | u32 r = 0; | ||
335 | u32 v; | ||
336 | |||
337 | v = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, | ||
338 | OMAP4_RM_RSTST); | ||
339 | |||
340 | p = omap44xx_prm_reset_src_map; | ||
341 | while (p->reg_shift >= 0 && p->std_shift >= 0) { | ||
342 | if (v & (1 << p->reg_shift)) | ||
343 | r |= 1 << p->std_shift; | ||
344 | p++; | ||
345 | } | ||
346 | |||
347 | return r; | ||
348 | } | ||
349 | |||
296 | /* Powerdomain low-level functions */ | 350 | /* Powerdomain low-level functions */ |
297 | 351 | ||
298 | static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) | 352 | static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) |
@@ -555,14 +609,37 @@ struct pwrdm_ops omap4_pwrdm_operations = { | |||
555 | .pwrdm_wait_transition = omap4_pwrdm_wait_transition, | 609 | .pwrdm_wait_transition = omap4_pwrdm_wait_transition, |
556 | }; | 610 | }; |
557 | 611 | ||
612 | /* | ||
613 | * XXX document | ||
614 | */ | ||
615 | static struct prm_ll_data omap44xx_prm_ll_data = { | ||
616 | .read_reset_sources = &omap44xx_prm_read_reset_sources, | ||
617 | }; | ||
558 | 618 | ||
559 | static int __init omap4xxx_prm_init(void) | 619 | static int __init omap44xx_prm_init(void) |
560 | { | 620 | { |
621 | int ret; | ||
622 | |||
561 | if (!cpu_is_omap44xx()) | 623 | if (!cpu_is_omap44xx()) |
562 | return 0; | 624 | return 0; |
563 | 625 | ||
626 | ret = prm_register(&omap44xx_prm_ll_data); | ||
627 | if (ret) | ||
628 | return ret; | ||
629 | |||
564 | omap44xx_prm_enable_io_wakeup(); | 630 | omap44xx_prm_enable_io_wakeup(); |
565 | 631 | ||
566 | return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); | 632 | return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); |
567 | } | 633 | } |
568 | subsys_initcall(omap4xxx_prm_init); | 634 | subsys_initcall(omap44xx_prm_init); |
635 | |||
636 | static void __exit omap44xx_prm_exit(void) | ||
637 | { | ||
638 | if (!cpu_is_omap44xx()) | ||
639 | return; | ||
640 | |||
641 | /* Should never happen */ | ||
642 | WARN(prm_unregister(&omap44xx_prm_ll_data), | ||
643 | "%s: prm_ll_data function pointer mismatch\n", __func__); | ||
644 | } | ||
645 | __exitcall(omap44xx_prm_exit); | ||