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/prm3xxx.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/prm3xxx.c')
-rw-r--r-- | arch/arm/mach-omap2/prm3xxx.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index e276ff270ac5..1fea656b2ca8 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c | |||
@@ -47,6 +47,27 @@ static struct omap_prcm_irq_setup omap3_prcm_irq_setup = { | |||
47 | .restore_irqen = &omap3xxx_prm_restore_irqen, | 47 | .restore_irqen = &omap3xxx_prm_restore_irqen, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* | ||
51 | * omap3_prm_reset_src_map - map from bits in the PRM_RSTST hardware | ||
52 | * register (which are specific to OMAP3xxx SoCs) to reset source ID | ||
53 | * bit shifts (which is an OMAP SoC-independent enumeration) | ||
54 | */ | ||
55 | static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = { | ||
56 | { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, | ||
57 | { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, | ||
58 | { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, | ||
59 | { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, | ||
60 | { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, | ||
61 | { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT }, | ||
62 | { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT, | ||
63 | OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT }, | ||
64 | { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT, | ||
65 | OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT }, | ||
66 | { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT }, | ||
67 | { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT }, | ||
68 | { -1, -1 }, | ||
69 | }; | ||
70 | |||
50 | /* PRM VP */ | 71 | /* PRM VP */ |
51 | 72 | ||
52 | /* | 73 | /* |
@@ -217,6 +238,30 @@ static void __init omap3xxx_prm_enable_io_wakeup(void) | |||
217 | PM_WKEN); | 238 | PM_WKEN); |
218 | } | 239 | } |
219 | 240 | ||
241 | /** | ||
242 | * omap3xxx_prm_read_reset_sources - return the last SoC reset source | ||
243 | * | ||
244 | * Return a u32 representing the last reset sources of the SoC. The | ||
245 | * returned reset source bits are standardized across OMAP SoCs. | ||
246 | */ | ||
247 | static u32 omap3xxx_prm_read_reset_sources(void) | ||
248 | { | ||
249 | struct prm_reset_src_map *p; | ||
250 | u32 r = 0; | ||
251 | u32 v; | ||
252 | |||
253 | v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST); | ||
254 | |||
255 | p = omap3xxx_prm_reset_src_map; | ||
256 | while (p->reg_shift >= 0 && p->std_shift >= 0) { | ||
257 | if (v & (1 << p->reg_shift)) | ||
258 | r |= 1 << p->std_shift; | ||
259 | p++; | ||
260 | } | ||
261 | |||
262 | return r; | ||
263 | } | ||
264 | |||
220 | /* Powerdomain low-level functions */ | 265 | /* Powerdomain low-level functions */ |
221 | 266 | ||
222 | /* Applicable only for OMAP3. Not supported on OMAP2 */ | 267 | /* Applicable only for OMAP3. Not supported on OMAP2 */ |
@@ -320,6 +365,10 @@ struct pwrdm_ops omap3_pwrdm_operations = { | |||
320 | * | 365 | * |
321 | */ | 366 | */ |
322 | 367 | ||
368 | static struct prm_ll_data omap3xxx_prm_ll_data = { | ||
369 | .read_reset_sources = &omap3xxx_prm_read_reset_sources, | ||
370 | }; | ||
371 | |||
323 | static int __init omap3xxx_prm_init(void) | 372 | static int __init omap3xxx_prm_init(void) |
324 | { | 373 | { |
325 | int ret; | 374 | int ret; |
@@ -327,12 +376,28 @@ static int __init omap3xxx_prm_init(void) | |||
327 | if (!cpu_is_omap34xx()) | 376 | if (!cpu_is_omap34xx()) |
328 | return 0; | 377 | return 0; |
329 | 378 | ||
379 | ret = prm_register(&omap3xxx_prm_ll_data); | ||
380 | if (ret) | ||
381 | return ret; | ||
382 | |||
330 | omap3xxx_prm_enable_io_wakeup(); | 383 | omap3xxx_prm_enable_io_wakeup(); |
331 | ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); | 384 | ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); |
332 | if (!ret) | 385 | if (!ret) |
333 | irq_set_status_flags(omap_prcm_event_to_irq("io"), | 386 | irq_set_status_flags(omap_prcm_event_to_irq("io"), |
334 | IRQ_NOAUTOEN); | 387 | IRQ_NOAUTOEN); |
335 | 388 | ||
389 | |||
336 | return ret; | 390 | return ret; |
337 | } | 391 | } |
338 | subsys_initcall(omap3xxx_prm_init); | 392 | subsys_initcall(omap3xxx_prm_init); |
393 | |||
394 | static void __exit omap3xxx_prm_exit(void) | ||
395 | { | ||
396 | if (!cpu_is_omap34xx()) | ||
397 | return; | ||
398 | |||
399 | /* Should never happen */ | ||
400 | WARN(prm_unregister(&omap3xxx_prm_ll_data), | ||
401 | "%s: prm_ll_data function pointer mismatch\n", __func__); | ||
402 | } | ||
403 | __exitcall(omap3xxx_prm_exit); | ||