summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-02-02 02:38:21 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-02-02 02:38:21 +0000
commit1a00056f1f225ee0d1643d3e4e603de171f7ab9a (patch)
treea73a7d2124305c5578982f1fec872f640bca6b13 /firmware/target/arm/imx31/gigabeat-s/system-imx31.c
parent304aefe80256429e8c1cbdbb5afd1693d90041aa (diff)
i.MX31: Make SPI more tolerant by resetting and forcing a reconfigure of the interface if an error ever happens. Better handle PMIC GPIO interrupt; it definitely doesn't low-pulse PRIINT (remains high if sources become active again or stay active while acking) so needed rising edge may never happen in such a case-- use high-level detection rather than rising edge. Optimize the reg/clr/set/mod functions a bit since they get more regular use now.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19903 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/system-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-imx31.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
index 7454806d07..cb265af0a3 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
@@ -172,24 +172,46 @@ void system_init(void)
gpio_init();
}
-void imx31_regmod32(volatile uint32_t *reg_p, uint32_t value, uint32_t mask)
+void __attribute__((naked)) imx31_regmod32(volatile uint32_t *reg_p,
+ uint32_t value,
+ uint32_t mask)
{
- value &= mask;
- mask = ~mask;
-
- int oldlevel = disable_interrupt_save(IRQ_FIQ_STATUS);
- *reg_p = (*reg_p & mask) | value;
- restore_interrupt(oldlevel);
+ asm volatile("and r1, r1, r2 \n"
+ "mrs ip, cpsr \n"
+ "cpsid if \n"
+ "ldr r3, [r0] \n"
+ "bic r3, r3, r2 \n"
+ "orr r3, r3, r1 \n"
+ "str r3, [r0] \n"
+ "msr cpsr_c, ip \n"
+ "bx lr \n");
+ (void)reg_p; (void)value; (void)mask;
}
-void imx31_regset32(volatile uint32_t *reg_p, uint32_t mask)
+void __attribute__((naked)) imx31_regset32(volatile uint32_t *reg_p,
+ uint32_t mask)
{
- imx31_regmod32(reg_p, mask, mask);
+ asm volatile("mrs r3, cpsr \n"
+ "cpsid if \n"
+ "ldr r2, [r0] \n"
+ "orr r2, r2, r1 \n"
+ "str r2, [r0] \n"
+ "msr cpsr_c, r3 \n"
+ "bx lr \n");
+ (void)reg_p; (void)mask;
}
-void imx31_regclr32(volatile uint32_t *reg_p, uint32_t mask)
+void __attribute__((naked)) imx31_regclr32(volatile uint32_t *reg_p,
+ uint32_t mask)
{
- imx31_regmod32(reg_p, 0, mask);
+ asm volatile("mrs r3, cpsr \n"
+ "cpsid if \n"
+ "ldr r2, [r0] \n"
+ "bic r2, r2, r1 \n"
+ "str r2, [r0] \n"
+ "msr cpsr_c, r3 \n"
+ "bx lr \n");
+ (void)reg_p; (void)mask;
}
#ifdef BOOTLOADER