summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2013-05-11 19:59:01 -0400
committerMichael Sevakis <jethead71@rockbox.org>2013-05-11 21:09:01 -0400
commit0a7d941fb9e8dba5934255e37ceaa9063b38ed25 (patch)
tree5e972b74abfd73c662430672cd57997c4a8056d0
parent4877f618d664f53694132b91fc7712844566bfbb (diff)
downloadrockbox-0a7d941fb9e8dba5934255e37ceaa9063b38ed25.tar.gz
rockbox-0a7d941fb9e8dba5934255e37ceaa9063b38ed25.zip
i.MX31: Remove long udelay from DVFS interrupt handler
Split the ISR into two parts and alllow quick return from first half. Introduces a uevent() API to have a callback happen in a specified number of microseconds. Right now only one event is supported. Change-Id: Ib1666165be2f6082e5275d64961f083cab104f9f
-rw-r--r--firmware/target/arm/imx31/avic-imx31.h1
-rw-r--r--firmware/target/arm/imx31/dvfs_dptc-imx31.c90
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c8
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c53
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c68
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-target.h8
6 files changed, 140 insertions, 88 deletions
diff --git a/firmware/target/arm/imx31/avic-imx31.h b/firmware/target/arm/imx31/avic-imx31.h
index 7398c8464c..50b04635ee 100644
--- a/firmware/target/arm/imx31/avic-imx31.h
+++ b/firmware/target/arm/imx31/avic-imx31.h
@@ -25,6 +25,7 @@
25#define INT_PRIO_DEFAULT 7 25#define INT_PRIO_DEFAULT 7
26#define INT_PRIO_DVFS (INT_PRIO_DEFAULT+1) 26#define INT_PRIO_DVFS (INT_PRIO_DEFAULT+1)
27#define INT_PRIO_DPTC (INT_PRIO_DEFAULT+1) 27#define INT_PRIO_DPTC (INT_PRIO_DEFAULT+1)
28#define INT_PRIO_GPT (INT_PRIO_DEFAULT+1)
28#define INT_PRIO_SDMA (INT_PRIO_DEFAULT+2) 29#define INT_PRIO_SDMA (INT_PRIO_DEFAULT+2)
29 30
30enum INT_TYPE 31enum INT_TYPE
diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.c b/firmware/target/arm/imx31/dvfs_dptc-imx31.c
index 02955a5aa4..3f9e9a3dd8 100644
--- a/firmware/target/arm/imx31/dvfs_dptc-imx31.c
+++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.c
@@ -75,6 +75,7 @@ static uint32_t check_regulator_setting(uint32_t setting)
75 75
76 76
77/** DVFS **/ 77/** DVFS **/
78#define DVFS_TVWAIT 100 /* Voltage ramp wait time */
78static bool dvfs_running = false; /* Has driver enabled DVFS? */ 79static bool dvfs_running = false; /* Has driver enabled DVFS? */
79 80
80/* Request tracking since boot */ 81/* Request tracking since boot */
@@ -90,10 +91,9 @@ static inline void updten_wait(void)
90} 91}
91 92
92/* Do the actual frequency and DVFS pin change - always call with IRQ masked */ 93/* Do the actual frequency and DVFS pin change - always call with IRQ masked */
93static void do_dvfs_update(unsigned int level) 94static void do_dvfs_update(unsigned long pmcr0, unsigned int level)
94{ 95{
95 const struct dvfs_clock_table_entry *setting = &dvfs_clock_table[level]; 96 const struct dvfs_clock_table_entry *setting = &dvfs_clock_table[level];
96 unsigned long pmcr0 = CCM_PMCR0;
97 97
98 if (pmcr0 & CCM_PMCR0_DPTEN) 98 if (pmcr0 & CCM_PMCR0_DPTEN)
99 { 99 {
@@ -106,7 +106,7 @@ static void do_dvfs_update(unsigned int level)
106 pmcr0 &= ~CCM_PMCR0_VSCNT; 106 pmcr0 &= ~CCM_PMCR0_VSCNT;
107 107
108 if (level < ((pmcr0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS)) 108 if (level < ((pmcr0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS))
109 { 109 {
110 pmcr0 |= CCM_PMCR0_UDSC; /* Up scaling, increase */ 110 pmcr0 |= CCM_PMCR0_UDSC; /* Up scaling, increase */
111 pmcr0 |= setting->vscnt << CCM_PMCR0_VSCNT_POS; 111 pmcr0 |= setting->vscnt << CCM_PMCR0_VSCNT_POS;
112 } 112 }
@@ -136,12 +136,20 @@ static void do_dvfs_update(unsigned int level)
136 } 136 }
137 137
138 CCM_PMCR0 = pmcr0; 138 CCM_PMCR0 = pmcr0;
139 /* Note: changes to frequency with ints unmaked seem to cause spurious 139
140 * DVFS interrupts with value CCM_PMCR0_FSVAI_NO_INT. These aren't 140 /* dvfs_int_voltage_wait_complete must be call to complete this; how that
141 * supposed to happen. Only do the lengthy delay with them enabled. */ 141 is accomplished depends upon whether this was an interrupt with DVFS
142 enable_irq(); 142 enabled or a manual setting of the CPU frequency */
143 udelay(100); /* Software wait for voltage ramp-up */ 143}
144 disable_irq(); 144
145/* Perform final DVFS frequency change steps after voltage ramp wait */
146static void dvfs_int_voltage_wait_complete(void)
147{
148 const struct dvfs_clock_table_entry *setting =
149 &dvfs_clock_table[dvfs_level];
150
151 unsigned long pmcr0 = CCM_PMCR0;
152
145 CCM_PDR0 = setting->pdr_val; 153 CCM_PDR0 = setting->pdr_val;
146 154
147 if (!(pmcr0 & CCM_PMCR0_DFSUP_POST_DIVIDERS)) 155 if (!(pmcr0 & CCM_PMCR0_DFSUP_POST_DIVIDERS))
@@ -155,6 +163,9 @@ static void do_dvfs_update(unsigned int level)
155 163
156 cpu_frequency = ccm_get_mcu_clk(); 164 cpu_frequency = ccm_get_mcu_clk();
157 165
166 if (dvfs_running)
167 CCM_PMCR0 &= ~CCM_PMCR0_FSVAIM;
168
158 if (pmcr0 & CCM_PMCR0_DPTEN) 169 if (pmcr0 & CCM_PMCR0_DPTEN)
159 { 170 {
160 update_dptc_counts(); 171 update_dptc_counts();
@@ -165,24 +176,28 @@ static void do_dvfs_update(unsigned int level)
165/* Start DVFS, change the set point and stop it */ 176/* Start DVFS, change the set point and stop it */
166static void set_current_dvfs_level(unsigned int level) 177static void set_current_dvfs_level(unsigned int level)
167{ 178{
168 int oldlevel;
169
170 /* Have to wait at least 3 div3 clocks before enabling after being 179 /* Have to wait at least 3 div3 clocks before enabling after being
171 * stopped. */ 180 * stopped before calling. */
172 udelay(1500);
173 181
174 oldlevel = disable_irq_save(); 182 updten_wait();
183
184 int oldlevel = disable_irq_save();
175 CCM_PMCR0 |= CCM_PMCR0_DVFEN; 185 CCM_PMCR0 |= CCM_PMCR0_DVFEN;
176 do_dvfs_update(level); 186 do_dvfs_update(CCM_PMCR0, level);
177 restore_irq(oldlevel); 187 restore_irq(oldlevel);
178 188
179 updten_wait(); 189 udelay(DVFS_TVWAIT);
190
191 oldlevel = disable_irq_save();
192 dvfs_int_voltage_wait_complete();
193 restore_irq(oldlevel);
180 194
195 updten_wait();
181 bitclr32(&CCM_PMCR0, CCM_PMCR0_DVFEN); 196 bitclr32(&CCM_PMCR0, CCM_PMCR0_DVFEN);
182} 197}
183 198
184/* DVFS Interrupt handler */ 199/* Interrupt handler for DVFS */
185static void USED_ATTR dvfs_int(void) 200static void dvfs_int(void)
186{ 201{
187 unsigned long pmcr0 = CCM_PMCR0; 202 unsigned long pmcr0 = CCM_PMCR0;
188 unsigned long fsvai = pmcr0 & CCM_PMCR0_FSVAI; 203 unsigned long fsvai = pmcr0 & CCM_PMCR0_FSVAI;
@@ -235,14 +250,19 @@ static void USED_ATTR dvfs_int(void)
235 return; /* Do nothing. Freq change is not required */ 250 return; /* Do nothing. Freq change is not required */
236 } /* end switch */ 251 } /* end switch */
237 252
238 do_dvfs_update(level); 253 /* Mask DVFS interrupt until voltage wait is complete */
254 pmcr0 |= CCM_PMCR0_FSVAIM;
255
256 do_dvfs_update(pmcr0, level);
257
258 /* Complete this in a few microseconds from now */
259 uevent(DVFS_TVWAIT, dvfs_int_voltage_wait_complete);
239} 260}
240 261
241/* Interrupt vector for DVFS */ 262/* Interrupt vector for DVFS */
242static __attribute__((naked, interrupt("IRQ"))) void CCM_DVFS_HANDLER(void) 263static __attribute__((interrupt("IRQ"))) void CCM_DVFS_HANDLER(void)
243{ 264{
244 /* Audio can glitch with the long udelay if nested IRQ isn't allowed. */ 265 dvfs_int();
245 AVIC_NESTED_NI_CALL(dvfs_int, INT_PRIO_DVFS);
246} 266}
247 267
248/* Initialize the DVFS hardware */ 268/* Initialize the DVFS hardware */
@@ -273,7 +293,7 @@ static void INIT_ATTR dvfs_init(void)
273 293
274 /* GP load bits disabled */ 294 /* GP load bits disabled */
275 bitclr32(&CCM_PMCR1, 0xf); 295 bitclr32(&CCM_PMCR1, 0xf);
276 296
277 /* Initialize DVFS signal weights and detection modes. */ 297 /* Initialize DVFS signal weights and detection modes. */
278 int i; 298 int i;
279 for (i = 0; i < 16; i++) 299 for (i = 0; i < 16; i++)
@@ -312,6 +332,7 @@ static void INIT_ATTR dvfs_init(void)
312 dvfs_clock_table[DVFS_LEVEL_DEFAULT].pdr_val); 332 dvfs_clock_table[DVFS_LEVEL_DEFAULT].pdr_val);
313 333
314 /* Set initial level and working point. */ 334 /* Set initial level and working point. */
335 udelay(1500);
315 set_current_dvfs_level(DVFS_LEVEL_DEFAULT); 336 set_current_dvfs_level(DVFS_LEVEL_DEFAULT);
316 337
317 logf("DVFS: Initialized"); 338 logf("DVFS: Initialized");
@@ -537,33 +558,23 @@ void dvfs_stop(void)
537 if (!dvfs_running) 558 if (!dvfs_running)
538 return; 559 return;
539 560
561 uevent_cancel();
562
540 /* Mask DVFS interrupts. */ 563 /* Mask DVFS interrupts. */
541 avic_disable_int(INT_CCM_DVFS); 564 avic_disable_int(INT_CCM_DVFS);
542 bitset32(&CCM_PMCR0, CCM_PMCR0_FSVAIM | CCM_PMCR0_LBMI); 565 bitset32(&CCM_PMCR0, CCM_PMCR0_FSVAIM | CCM_PMCR0_LBMI);
543 566
544 if (((CCM_PMCR0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS) !=
545 DVFS_LEVEL_DEFAULT)
546 {
547 int oldlevel;
548 /* Set default frequency level */
549 updten_wait();
550 oldlevel = disable_irq_save();
551 do_dvfs_update(DVFS_LEVEL_DEFAULT);
552 restore_irq(oldlevel);
553 updten_wait();
554 }
555
556 /* Disable DVFS. */
557 bitclr32(&CCM_PMCR0, CCM_PMCR0_DVFEN);
558 dvfs_running = false; 567 dvfs_running = false;
559 568
569 /* Set default frequency level */
570 set_current_dvfs_level(DVFS_LEVEL_DEFAULT);
560 logf("DVFS: stopped"); 571 logf("DVFS: stopped");
561} 572}
562 573
563/* Is DVFS enabled? */ 574/* Is DVFS enabled? */
564bool dvfs_enabled(void) 575bool dvfs_enabled(void)
565{ 576{
566 return dvfs_running; 577 return dvfs_running;
567} 578}
568 579
569/* If DVFS is disabled, set the level explicitly */ 580/* If DVFS is disabled, set the level explicitly */
@@ -575,6 +586,7 @@ void dvfs_set_level(unsigned int level)
575 level == ((CCM_PMCR0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS)) 586 level == ((CCM_PMCR0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS))
576 return; 587 return;
577 588
589 udelay(1500);
578 set_current_dvfs_level(level); 590 set_current_dvfs_level(level);
579} 591}
580 592
@@ -778,7 +790,7 @@ void dptc_start(void)
778 enable_dptc(); 790 enable_dptc();
779 restore_irq(oldlevel); 791 restore_irq(oldlevel);
780 792
781 avic_enable_int(INT_CCM_CLK, INT_TYPE_IRQ, INT_PRIO_DPTC, 793 avic_enable_int(INT_CCM_CLK, INT_TYPE_IRQ, INT_PRIO_DPTC,
782 CCM_CLK_HANDLER); 794 CCM_CLK_HANDLER);
783 795
784 logf("DPTC: started"); 796 logf("DPTC: started");
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c
index f30287d4e9..491bd52a66 100644
--- a/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c
@@ -56,7 +56,7 @@ void INIT_ATTR tick_start(unsigned int interval_in_ms)
56 EPITCR1 = EPITCR_CLKSRC_IPG_CLK | EPITCR_WAITEN | EPITCR_IOVW | 56 EPITCR1 = EPITCR_CLKSRC_IPG_CLK | EPITCR_WAITEN | EPITCR_IOVW |
57 ((2640-1) << EPITCR_PRESCALER_POS) | EPITCR_RLD | 57 ((2640-1) << EPITCR_PRESCALER_POS) | EPITCR_RLD |
58 EPITCR_OCIEN | EPITCR_ENMOD; 58 EPITCR_OCIEN | EPITCR_ENMOD;
59 59
60 EPITLR1 = interval_in_ms*25; /* Count down from interval */ 60 EPITLR1 = interval_in_ms*25; /* Count down from interval */
61 EPITCMPR1 = 0; /* Event when counter reaches 0 */ 61 EPITCMPR1 = 0; /* Event when counter reaches 0 */
62 EPITSR1 = EPITSR_OCIF; /* Clear any pending interrupt */ 62 EPITSR1 = EPITSR_OCIF; /* Clear any pending interrupt */
@@ -86,9 +86,3 @@ void tick_stop(void)
86 EPITSR1 = EPITSR_OCIF; /* Clear pending */ 86 EPITSR1 = EPITSR_OCIF; /* Clear pending */
87 ccm_module_clock_gating(CG_EPIT1, CGM_OFF); /* Turn off module clock */ 87 ccm_module_clock_gating(CG_EPIT1, CGM_OFF); /* Turn off module clock */
88} 88}
89
90
91void kernel_audio_locking(bool locking)
92{
93 dvfs_int_mask(locking);
94} \ No newline at end of file
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
index 76789a7dbd..7304bdcff3 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
@@ -104,7 +104,7 @@ static void play_dma_callback(void)
104 PCM_DMAST_ERR_DMA : PCM_DMAST_OK; 104 PCM_DMAST_ERR_DMA : PCM_DMAST_OK;
105 const void *addr; 105 const void *addr;
106 size_t size; 106 size_t size;
107 107
108 if (pcm_play_dma_complete_callback(status, &addr, &size)) 108 if (pcm_play_dma_complete_callback(status, &addr, &size))
109 { 109 {
110 play_start_dma(addr, size); 110 play_start_dma(addr, size);
@@ -114,33 +114,20 @@ static void play_dma_callback(void)
114 114
115void pcm_play_lock(void) 115void pcm_play_lock(void)
116{ 116{
117 /* Need to prevent DVFS from causing interrupt priority inversion if audio
118 * is locked and a DVFS interrupt fires, blocking reenabling of audio by a
119 * low-priority mode for at least the duration of the lengthy DVFS routine.
120 * Not really an issue with state changes but lockout when playing.
121 *
122 * Keep direct use of DVFS code away from here though. This could provide
123 * more services in the future anyway. */
124 kernel_audio_locking(true);
125 ++dma_play_data.locked; 117 ++dma_play_data.locked;
126} 118}
127 119
128void pcm_play_unlock(void) 120void pcm_play_unlock(void)
129{ 121{
130 if (--dma_play_data.locked == 0) 122 if (--dma_play_data.locked == 0 && dma_play_data.state != 0)
131 { 123 {
132 if (dma_play_data.state != 0) 124 int oldstatus = disable_irq_save();
133 { 125 int pending = dma_play_data.callback_pending;
134 int oldstatus = disable_irq_save(); 126 dma_play_data.callback_pending = 0;
135 int pending = dma_play_data.callback_pending; 127 restore_irq(oldstatus);
136 dma_play_data.callback_pending = 0; 128
137 restore_irq(oldstatus); 129 if (pending != 0)
138 130 play_dma_callback();
139 if (pending != 0)
140 play_dma_callback();
141 }
142
143 kernel_audio_locking(false);
144 } 131 }
145} 132}
146 133
@@ -368,26 +355,20 @@ static void rec_dma_callback(void)
368 355
369void pcm_rec_lock(void) 356void pcm_rec_lock(void)
370{ 357{
371 kernel_audio_locking(true);
372 ++dma_rec_data.locked; 358 ++dma_rec_data.locked;
373} 359}
374 360
375void pcm_rec_unlock(void) 361void pcm_rec_unlock(void)
376{ 362{
377 if (--dma_rec_data.locked == 0) 363 if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0)
378 { 364 {
379 if (dma_rec_data.state != 0) 365 int oldstatus = disable_irq_save();
380 { 366 int pending = dma_rec_data.callback_pending;
381 int oldstatus = disable_irq_save(); 367 dma_rec_data.callback_pending = 0;
382 int pending = dma_rec_data.callback_pending; 368 restore_irq(oldstatus);
383 dma_rec_data.callback_pending = 0; 369
384 restore_irq(oldstatus); 370 if (pending != 0)
385 371 rec_dma_callback();
386 if (pending != 0)
387 rec_dma_callback();
388 }
389
390 kernel_audio_locking(false);
391 } 372 }
392} 373}
393 374
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
90static void (*ucallback)(void) = NULL; /* uevent callback */
91
92static void cancel_uevent(void)
93{
94 GPTSR = GPTSR_OF1;
95 GPTIR &= ~GPTIR_OF1IE;
96 ucallback = NULL;
97}
98
99static void __attribute__((interrupt("IRQ"))) GPT_HANDLER(void)
100{
101 uevent_cb_type cb = ucallback;
102 cancel_uevent();
103 cb();
104}
105
106void 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
131void 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) */
90void gpt_start(void) 145void 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 */
109void gpt_stop(void) 167void 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
114int system_memory_guard(int newmode) 176int 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
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h
index 44a97c7ca9..b12ca13bb5 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h
@@ -44,6 +44,11 @@ static inline unsigned long usec_timer(void)
44 return GPTCNT; 44 return GPTCNT;
45} 45}
46 46
47/* Fire an event usecs microseconds from now */
48typedef void (* uevent_cb_type)(void);
49void uevent(unsigned long usecs, uevent_cb_type callback);
50void uevent_cancel(void);
51
47void watchdog_init(unsigned int half_seconds); 52void watchdog_init(unsigned int half_seconds);
48void watchdog_service(void); 53void watchdog_service(void);
49 54
@@ -58,9 +63,6 @@ void tick_stop(void);
58void kernel_device_init(void); 63void kernel_device_init(void);
59void system_halt(void); 64void system_halt(void);
60 65
61/* Handle some audio lockout related tasks */
62void kernel_audio_locking(bool locking);
63
64#define KDEV_INIT 66#define KDEV_INIT
65 67
66struct ARM_REGS { 68struct ARM_REGS {