diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c index 5c70411c30..545905d4c2 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c | |||
@@ -84,7 +84,62 @@ void watchdog_service(void) | |||
84 | WDOG_WSR = 0xaaaa; | 84 | WDOG_WSR = 0xaaaa; |
85 | } | 85 | } |
86 | 86 | ||
87 | /** GPT timer routines - basis for udelay **/ | 87 | |
88 | /** uevent APIs **/ | ||
89 | |||
90 | static void (*ucallback)(void) = NULL; /* uevent callback */ | ||
91 | |||
92 | static void cancel_uevent(void) | ||
93 | { | ||
94 | GPTSR = GPTSR_OF1; | ||
95 | GPTIR &= ~GPTIR_OF1IE; | ||
96 | ucallback = NULL; | ||
97 | } | ||
98 | |||
99 | static void __attribute__((interrupt("IRQ"))) GPT_HANDLER(void) | ||
100 | { | ||
101 | uevent_cb_type cb = ucallback; | ||
102 | cancel_uevent(); | ||
103 | cb(); | ||
104 | } | ||
105 | |||
106 | void uevent(unsigned long usecs, uevent_cb_type callback) | ||
107 | { | ||
108 | if (!callback || ucallback) | ||
109 | return; /* Is busy */ | ||
110 | |||
111 | unsigned long status = disable_interrupt_save(IRQ_FIQ_STATUS); | ||
112 | |||
113 | ucallback = callback; | ||
114 | |||
115 | for (int i = 0; i < 1; i++) | ||
116 | { | ||
117 | unsigned long utime = GPTCNT; | ||
118 | unsigned long time = utime + usecs + 1; | ||
119 | |||
120 | GPTOCR1 = time; | ||
121 | GPTSR = GPTSR_OF1; | ||
122 | GPTIR |= GPTIR_OF1IE; | ||
123 | |||
124 | if (TIME_BEFORE(GPTCNT, time)) | ||
125 | break; /* Didn't miss it */ | ||
126 | } | ||
127 | |||
128 | restore_interrupt(status); | ||
129 | } | ||
130 | |||
131 | void uevent_cancel(void) | ||
132 | { | ||
133 | unsigned long status = disable_interrupt_save(IRQ_FIQ_STATUS); | ||
134 | |||
135 | if (ucallback) | ||
136 | cancel_uevent(); | ||
137 | |||
138 | restore_interrupt(status); | ||
139 | } | ||
140 | |||
141 | |||
142 | /** GPT timer routines - basis for udelay/uevent **/ | ||
88 | 143 | ||
89 | /* Start the general-purpose timer (1MHz) */ | 144 | /* Start the general-purpose timer (1MHz) */ |
90 | void gpt_start(void) | 145 | void gpt_start(void) |
@@ -102,13 +157,20 @@ void gpt_start(void) | |||
102 | */ | 157 | */ |
103 | GPTCR = GPTCR_FRR | GPTCR_WAITEN | GPTCR_CLKSRC_IPG_CLK; | 158 | GPTCR = GPTCR_FRR | GPTCR_WAITEN | GPTCR_CLKSRC_IPG_CLK; |
104 | GPTPR = ipg_mhz - 1; | 159 | GPTPR = ipg_mhz - 1; |
160 | GPTSR = GPTSR_OF1; | ||
105 | GPTCR |= GPTCR_EN; | 161 | GPTCR |= GPTCR_EN; |
162 | |||
163 | avic_enable_int(INT_GPT, INT_TYPE_IRQ, INT_PRIO_GPT, GPT_HANDLER); | ||
106 | } | 164 | } |
107 | 165 | ||
108 | /* Stop the general-purpose timer */ | 166 | /* Stop the general-purpose timer */ |
109 | void gpt_stop(void) | 167 | void gpt_stop(void) |
110 | { | 168 | { |
169 | unsigned long status = disable_interrupt_save(IRQ_FIQ_STATUS); | ||
170 | avic_disable_int(INT_GPT); | ||
171 | cancel_uevent(); | ||
111 | GPTCR &= ~GPTCR_EN; | 172 | GPTCR &= ~GPTCR_EN; |
173 | restore_interrupt(status); | ||
112 | } | 174 | } |
113 | 175 | ||
114 | int system_memory_guard(int newmode) | 176 | int system_memory_guard(int newmode) |
@@ -258,7 +320,7 @@ void dumpregs(void) | |||
258 | "mov %3,r12": | 320 | "mov %3,r12": |
259 | "=r"(regs.r8),"=r"(regs.r9), | 321 | "=r"(regs.r8),"=r"(regs.r9), |
260 | "=r"(regs.r10),"=r"(regs.r11):); | 322 | "=r"(regs.r10),"=r"(regs.r11):); |
261 | 323 | ||
262 | asm volatile ("mov %0,r12\n\t" | 324 | asm volatile ("mov %0,r12\n\t" |
263 | "mov %1,sp\n\t" | 325 | "mov %1,sp\n\t" |
264 | "mov %2,lr\n\t" | 326 | "mov %2,lr\n\t" |
@@ -280,7 +342,7 @@ void dumpregs(void) | |||
280 | DEBUGF("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11); | 342 | DEBUGF("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11); |
281 | DEBUGF("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc); | 343 | DEBUGF("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc); |
282 | //DEBUGF("CPSR=0x%x\t\n",regs.cpsr); | 344 | //DEBUGF("CPSR=0x%x\t\n",regs.cpsr); |
283 | 345 | ||
284 | } | 346 | } |
285 | 347 | ||
286 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 348 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |