diff options
| -rw-r--r-- | arch/arm/include/asm/cacheflush.h | 4 | ||||
| -rw-r--r-- | arch/arm/include/asm/smp_twd.h | 17 | ||||
| -rw-r--r-- | arch/arm/include/asm/tlbflush.h | 29 | ||||
| -rw-r--r-- | arch/arm/kernel/smp_twd.c | 17 | ||||
| -rw-r--r-- | arch/arm/lib/clear_user.S | 1 | ||||
| -rw-r--r-- | arch/arm/lib/copy_to_user.S | 1 | ||||
| -rw-r--r-- | arch/arm/mm/cache-v6.S | 17 | ||||
| -rw-r--r-- | arch/arm/mm/cache-v7.S | 4 | ||||
| -rw-r--r-- | arch/arm/mm/nommu.c | 13 | ||||
| -rw-r--r-- | arch/arm/mm/tlb-v7.S | 8 | ||||
| -rw-r--r-- | drivers/watchdog/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/watchdog/mpcore_wdt.c | 21 |
12 files changed, 99 insertions, 35 deletions
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 0d08d4170b64..4656a24058d2 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
| @@ -371,6 +371,10 @@ static inline void __flush_icache_all(void) | |||
| 371 | #ifdef CONFIG_ARM_ERRATA_411920 | 371 | #ifdef CONFIG_ARM_ERRATA_411920 |
| 372 | extern void v6_icache_inval_all(void); | 372 | extern void v6_icache_inval_all(void); |
| 373 | v6_icache_inval_all(); | 373 | v6_icache_inval_all(); |
| 374 | #elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7 | ||
| 375 | asm("mcr p15, 0, %0, c7, c1, 0 @ invalidate I-cache inner shareable\n" | ||
| 376 | : | ||
| 377 | : "r" (0)); | ||
| 374 | #else | 378 | #else |
| 375 | asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" | 379 | asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" |
| 376 | : | 380 | : |
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index 7be0978b2625..634f357be6bb 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h | |||
| @@ -1,6 +1,23 @@ | |||
| 1 | #ifndef __ASMARM_SMP_TWD_H | 1 | #ifndef __ASMARM_SMP_TWD_H |
| 2 | #define __ASMARM_SMP_TWD_H | 2 | #define __ASMARM_SMP_TWD_H |
| 3 | 3 | ||
| 4 | #define TWD_TIMER_LOAD 0x00 | ||
| 5 | #define TWD_TIMER_COUNTER 0x04 | ||
| 6 | #define TWD_TIMER_CONTROL 0x08 | ||
| 7 | #define TWD_TIMER_INTSTAT 0x0C | ||
| 8 | |||
| 9 | #define TWD_WDOG_LOAD 0x20 | ||
| 10 | #define TWD_WDOG_COUNTER 0x24 | ||
| 11 | #define TWD_WDOG_CONTROL 0x28 | ||
| 12 | #define TWD_WDOG_INTSTAT 0x2C | ||
| 13 | #define TWD_WDOG_RESETSTAT 0x30 | ||
| 14 | #define TWD_WDOG_DISABLE 0x34 | ||
| 15 | |||
| 16 | #define TWD_TIMER_CONTROL_ENABLE (1 << 0) | ||
| 17 | #define TWD_TIMER_CONTROL_ONESHOT (0 << 1) | ||
| 18 | #define TWD_TIMER_CONTROL_PERIODIC (1 << 1) | ||
| 19 | #define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2) | ||
| 20 | |||
| 4 | struct clock_event_device; | 21 | struct clock_event_device; |
| 5 | 22 | ||
| 6 | extern void __iomem *twd_base; | 23 | extern void __iomem *twd_base; |
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index e085e2c545eb..bd863d8608cd 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h | |||
| @@ -46,6 +46,9 @@ | |||
| 46 | #define TLB_V7_UIS_FULL (1 << 20) | 46 | #define TLB_V7_UIS_FULL (1 << 20) |
| 47 | #define TLB_V7_UIS_ASID (1 << 21) | 47 | #define TLB_V7_UIS_ASID (1 << 21) |
| 48 | 48 | ||
| 49 | /* Inner Shareable BTB operation (ARMv7 MP extensions) */ | ||
| 50 | #define TLB_V7_IS_BTB (1 << 22) | ||
| 51 | |||
| 49 | #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ | 52 | #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ |
| 50 | #define TLB_DCLEAN (1 << 30) | 53 | #define TLB_DCLEAN (1 << 30) |
| 51 | #define TLB_WB (1 << 31) | 54 | #define TLB_WB (1 << 31) |
| @@ -183,7 +186,7 @@ | |||
| 183 | #endif | 186 | #endif |
| 184 | 187 | ||
| 185 | #ifdef CONFIG_SMP | 188 | #ifdef CONFIG_SMP |
| 186 | #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ | 189 | #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \ |
| 187 | TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) | 190 | TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) |
| 188 | #else | 191 | #else |
| 189 | #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ | 192 | #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ |
| @@ -339,6 +342,12 @@ static inline void local_flush_tlb_all(void) | |||
| 339 | dsb(); | 342 | dsb(); |
| 340 | isb(); | 343 | isb(); |
| 341 | } | 344 | } |
| 345 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
| 346 | /* flush the branch target cache */ | ||
| 347 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
| 348 | dsb(); | ||
| 349 | isb(); | ||
| 350 | } | ||
| 342 | } | 351 | } |
| 343 | 352 | ||
| 344 | static inline void local_flush_tlb_mm(struct mm_struct *mm) | 353 | static inline void local_flush_tlb_mm(struct mm_struct *mm) |
| @@ -376,6 +385,12 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) | |||
| 376 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | 385 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); |
| 377 | dsb(); | 386 | dsb(); |
| 378 | } | 387 | } |
| 388 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
| 389 | /* flush the branch target cache */ | ||
| 390 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
| 391 | dsb(); | ||
| 392 | isb(); | ||
| 393 | } | ||
| 379 | } | 394 | } |
| 380 | 395 | ||
| 381 | static inline void | 396 | static inline void |
| @@ -416,6 +431,12 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
| 416 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | 431 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); |
| 417 | dsb(); | 432 | dsb(); |
| 418 | } | 433 | } |
| 434 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
| 435 | /* flush the branch target cache */ | ||
| 436 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
| 437 | dsb(); | ||
| 438 | isb(); | ||
| 439 | } | ||
| 419 | } | 440 | } |
| 420 | 441 | ||
| 421 | static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | 442 | static inline void local_flush_tlb_kernel_page(unsigned long kaddr) |
| @@ -454,6 +475,12 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | |||
| 454 | dsb(); | 475 | dsb(); |
| 455 | isb(); | 476 | isb(); |
| 456 | } | 477 | } |
| 478 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
| 479 | /* flush the branch target cache */ | ||
| 480 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
| 481 | dsb(); | ||
| 482 | isb(); | ||
| 483 | } | ||
| 457 | } | 484 | } |
| 458 | 485 | ||
| 459 | /* | 486 | /* |
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index ea02a7b1c244..7c5f0c024db7 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c | |||
| @@ -21,23 +21,6 @@ | |||
| 21 | #include <asm/smp_twd.h> | 21 | #include <asm/smp_twd.h> |
| 22 | #include <asm/hardware/gic.h> | 22 | #include <asm/hardware/gic.h> |
| 23 | 23 | ||
| 24 | #define TWD_TIMER_LOAD 0x00 | ||
| 25 | #define TWD_TIMER_COUNTER 0x04 | ||
| 26 | #define TWD_TIMER_CONTROL 0x08 | ||
| 27 | #define TWD_TIMER_INTSTAT 0x0C | ||
| 28 | |||
| 29 | #define TWD_WDOG_LOAD 0x20 | ||
| 30 | #define TWD_WDOG_COUNTER 0x24 | ||
| 31 | #define TWD_WDOG_CONTROL 0x28 | ||
| 32 | #define TWD_WDOG_INTSTAT 0x2C | ||
| 33 | #define TWD_WDOG_RESETSTAT 0x30 | ||
| 34 | #define TWD_WDOG_DISABLE 0x34 | ||
| 35 | |||
| 36 | #define TWD_TIMER_CONTROL_ENABLE (1 << 0) | ||
| 37 | #define TWD_TIMER_CONTROL_ONESHOT (0 << 1) | ||
| 38 | #define TWD_TIMER_CONTROL_PERIODIC (1 << 1) | ||
| 39 | #define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2) | ||
| 40 | |||
| 41 | /* set up by the platform code */ | 24 | /* set up by the platform code */ |
| 42 | void __iomem *twd_base; | 25 | void __iomem *twd_base; |
| 43 | 26 | ||
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S index 5e3f99620c04..14a0d988c82c 100644 --- a/arch/arm/lib/clear_user.S +++ b/arch/arm/lib/clear_user.S | |||
| @@ -45,6 +45,7 @@ USER( strnebt r2, [r0]) | |||
| 45 | mov r0, #0 | 45 | mov r0, #0 |
| 46 | ldmfd sp!, {r1, pc} | 46 | ldmfd sp!, {r1, pc} |
| 47 | ENDPROC(__clear_user) | 47 | ENDPROC(__clear_user) |
| 48 | ENDPROC(__clear_user_std) | ||
| 48 | 49 | ||
| 49 | .pushsection .fixup,"ax" | 50 | .pushsection .fixup,"ax" |
| 50 | .align 0 | 51 | .align 0 |
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S index 027b69bdbad1..d066df686e17 100644 --- a/arch/arm/lib/copy_to_user.S +++ b/arch/arm/lib/copy_to_user.S | |||
| @@ -93,6 +93,7 @@ WEAK(__copy_to_user) | |||
| 93 | #include "copy_template.S" | 93 | #include "copy_template.S" |
| 94 | 94 | ||
| 95 | ENDPROC(__copy_to_user) | 95 | ENDPROC(__copy_to_user) |
| 96 | ENDPROC(__copy_to_user_std) | ||
| 96 | 97 | ||
| 97 | .pushsection .fixup,"ax" | 98 | .pushsection .fixup,"ax" |
| 98 | .align 0 | 99 | .align 0 |
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 9d89c67a1cc3..e46ecd847138 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
| @@ -211,6 +211,9 @@ v6_dma_inv_range: | |||
| 211 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line | 211 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line |
| 212 | #endif | 212 | #endif |
| 213 | 1: | 213 | 1: |
| 214 | #ifdef CONFIG_SMP | ||
| 215 | str r0, [r0] @ write for ownership | ||
| 216 | #endif | ||
| 214 | #ifdef HARVARD_CACHE | 217 | #ifdef HARVARD_CACHE |
| 215 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line | 218 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line |
| 216 | #else | 219 | #else |
| @@ -231,6 +234,9 @@ v6_dma_inv_range: | |||
| 231 | v6_dma_clean_range: | 234 | v6_dma_clean_range: |
| 232 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 235 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
| 233 | 1: | 236 | 1: |
| 237 | #ifdef CONFIG_SMP | ||
| 238 | ldr r2, [r0] @ read for ownership | ||
| 239 | #endif | ||
| 234 | #ifdef HARVARD_CACHE | 240 | #ifdef HARVARD_CACHE |
| 235 | mcr p15, 0, r0, c7, c10, 1 @ clean D line | 241 | mcr p15, 0, r0, c7, c10, 1 @ clean D line |
| 236 | #else | 242 | #else |
| @@ -251,6 +257,10 @@ v6_dma_clean_range: | |||
| 251 | ENTRY(v6_dma_flush_range) | 257 | ENTRY(v6_dma_flush_range) |
| 252 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 258 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
| 253 | 1: | 259 | 1: |
| 260 | #ifdef CONFIG_SMP | ||
| 261 | ldr r2, [r0] @ read for ownership | ||
| 262 | str r2, [r0] @ write for ownership | ||
| 263 | #endif | ||
| 254 | #ifdef HARVARD_CACHE | 264 | #ifdef HARVARD_CACHE |
| 255 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | 265 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line |
| 256 | #else | 266 | #else |
| @@ -273,7 +283,9 @@ ENTRY(v6_dma_map_area) | |||
| 273 | add r1, r1, r0 | 283 | add r1, r1, r0 |
| 274 | teq r2, #DMA_FROM_DEVICE | 284 | teq r2, #DMA_FROM_DEVICE |
| 275 | beq v6_dma_inv_range | 285 | beq v6_dma_inv_range |
| 276 | b v6_dma_clean_range | 286 | teq r2, #DMA_TO_DEVICE |
| 287 | beq v6_dma_clean_range | ||
| 288 | b v6_dma_flush_range | ||
| 277 | ENDPROC(v6_dma_map_area) | 289 | ENDPROC(v6_dma_map_area) |
| 278 | 290 | ||
| 279 | /* | 291 | /* |
| @@ -283,9 +295,6 @@ ENDPROC(v6_dma_map_area) | |||
| 283 | * - dir - DMA direction | 295 | * - dir - DMA direction |
| 284 | */ | 296 | */ |
| 285 | ENTRY(v6_dma_unmap_area) | 297 | ENTRY(v6_dma_unmap_area) |
| 286 | add r1, r1, r0 | ||
| 287 | teq r2, #DMA_TO_DEVICE | ||
| 288 | bne v6_dma_inv_range | ||
| 289 | mov pc, lr | 298 | mov pc, lr |
| 290 | ENDPROC(v6_dma_unmap_area) | 299 | ENDPROC(v6_dma_unmap_area) |
| 291 | 300 | ||
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index bcd64f265870..06a90dcfc60a 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
| @@ -167,7 +167,11 @@ ENTRY(v7_coherent_user_range) | |||
| 167 | cmp r0, r1 | 167 | cmp r0, r1 |
| 168 | blo 1b | 168 | blo 1b |
| 169 | mov r0, #0 | 169 | mov r0, #0 |
| 170 | #ifdef CONFIG_SMP | ||
| 171 | mcr p15, 0, r0, c7, c1, 6 @ invalidate BTB Inner Shareable | ||
| 172 | #else | ||
| 170 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB | 173 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB |
| 174 | #endif | ||
| 171 | dsb | 175 | dsb |
| 172 | isb | 176 | isb |
| 173 | mov pc, lr | 177 | mov pc, lr |
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 9bfeb6b9509a..33b327379f07 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c | |||
| @@ -65,6 +65,15 @@ void flush_dcache_page(struct page *page) | |||
| 65 | } | 65 | } |
| 66 | EXPORT_SYMBOL(flush_dcache_page); | 66 | EXPORT_SYMBOL(flush_dcache_page); |
| 67 | 67 | ||
| 68 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | ||
| 69 | unsigned long uaddr, void *dst, const void *src, | ||
| 70 | unsigned long len) | ||
| 71 | { | ||
| 72 | memcpy(dst, src, len); | ||
| 73 | if (vma->vm_flags & VM_EXEC) | ||
| 74 | __cpuc_coherent_user_range(uaddr, uaddr + len); | ||
| 75 | } | ||
| 76 | |||
| 68 | void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, | 77 | void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, |
| 69 | size_t size, unsigned int mtype) | 78 | size_t size, unsigned int mtype) |
| 70 | { | 79 | { |
| @@ -87,8 +96,8 @@ void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size, | |||
| 87 | } | 96 | } |
| 88 | EXPORT_SYMBOL(__arm_ioremap); | 97 | EXPORT_SYMBOL(__arm_ioremap); |
| 89 | 98 | ||
| 90 | void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size, | 99 | void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size, |
| 91 | unsigned int mtype, void *caller) | 100 | unsigned int mtype, void *caller) |
| 92 | { | 101 | { |
| 93 | return __arm_ioremap(phys_addr, size, mtype); | 102 | return __arm_ioremap(phys_addr, size, mtype); |
| 94 | } | 103 | } |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index 0cb1848bd876..f3f288a9546d 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
| @@ -50,7 +50,11 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
| 50 | cmp r0, r1 | 50 | cmp r0, r1 |
| 51 | blo 1b | 51 | blo 1b |
| 52 | mov ip, #0 | 52 | mov ip, #0 |
| 53 | #ifdef CONFIG_SMP | ||
| 54 | mcr p15, 0, ip, c7, c1, 6 @ flush BTAC/BTB Inner Shareable | ||
| 55 | #else | ||
| 53 | mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB | 56 | mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB |
| 57 | #endif | ||
| 54 | dsb | 58 | dsb |
| 55 | mov pc, lr | 59 | mov pc, lr |
| 56 | ENDPROC(v7wbi_flush_user_tlb_range) | 60 | ENDPROC(v7wbi_flush_user_tlb_range) |
| @@ -79,7 +83,11 @@ ENTRY(v7wbi_flush_kern_tlb_range) | |||
| 79 | cmp r0, r1 | 83 | cmp r0, r1 |
| 80 | blo 1b | 84 | blo 1b |
| 81 | mov r2, #0 | 85 | mov r2, #0 |
| 86 | #ifdef CONFIG_SMP | ||
| 87 | mcr p15, 0, r2, c7, c1, 6 @ flush BTAC/BTB Inner Shareable | ||
| 88 | #else | ||
| 82 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 89 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
| 90 | #endif | ||
| 83 | dsb | 91 | dsb |
| 84 | isb | 92 | isb |
| 85 | mov pc, lr | 93 | mov pc, lr |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0bf5020d0d32..b87ba23442d2 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -175,7 +175,7 @@ config SA1100_WATCHDOG | |||
| 175 | 175 | ||
| 176 | config MPCORE_WATCHDOG | 176 | config MPCORE_WATCHDOG |
| 177 | tristate "MPcore watchdog" | 177 | tristate "MPcore watchdog" |
| 178 | depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS | 178 | depends on HAVE_ARM_TWD |
| 179 | help | 179 | help |
| 180 | Watchdog timer embedded into the MPcore system. | 180 | Watchdog timer embedded into the MPcore system. |
| 181 | 181 | ||
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 016c6a791cab..b8ec7aca3c8e 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
| @@ -31,8 +31,9 @@ | |||
| 31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 32 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
| 33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
| 34 | #include <linux/io.h> | ||
| 34 | 35 | ||
| 35 | #include <asm/hardware/arm_twd.h> | 36 | #include <asm/smp_twd.h> |
| 36 | 37 | ||
| 37 | struct mpcore_wdt { | 38 | struct mpcore_wdt { |
| 38 | unsigned long timer_alive; | 39 | unsigned long timer_alive; |
| @@ -44,7 +45,7 @@ struct mpcore_wdt { | |||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | static struct platform_device *mpcore_wdt_dev; | 47 | static struct platform_device *mpcore_wdt_dev; |
| 47 | extern unsigned int mpcore_timer_rate; | 48 | static DEFINE_SPINLOCK(wdt_lock); |
| 48 | 49 | ||
| 49 | #define TIMER_MARGIN 60 | 50 | #define TIMER_MARGIN 60 |
| 50 | static int mpcore_margin = TIMER_MARGIN; | 51 | static int mpcore_margin = TIMER_MARGIN; |
| @@ -94,13 +95,15 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg) | |||
| 94 | */ | 95 | */ |
| 95 | static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) | 96 | static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) |
| 96 | { | 97 | { |
| 97 | unsigned int count; | 98 | unsigned long count; |
| 98 | 99 | ||
| 100 | spin_lock(&wdt_lock); | ||
| 99 | /* Assume prescale is set to 256 */ | 101 | /* Assume prescale is set to 256 */ |
| 100 | count = (mpcore_timer_rate / 256) * mpcore_margin; | 102 | count = __raw_readl(wdt->base + TWD_WDOG_COUNTER); |
| 103 | count = (0xFFFFFFFFU - count) * (HZ / 5); | ||
| 104 | count = (count / 256) * mpcore_margin; | ||
| 101 | 105 | ||
| 102 | /* Reload the counter */ | 106 | /* Reload the counter */ |
| 103 | spin_lock(&wdt_lock); | ||
| 104 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); | 107 | writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); |
| 105 | wdt->perturb = wdt->perturb ? 0 : 1; | 108 | wdt->perturb = wdt->perturb ? 0 : 1; |
| 106 | spin_unlock(&wdt_lock); | 109 | spin_unlock(&wdt_lock); |
| @@ -119,7 +122,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
| 119 | { | 122 | { |
| 120 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); | 123 | dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); |
| 121 | 124 | ||
| 122 | spin_lock(&wdt_lock); | ||
| 123 | /* This loads the count register but does NOT start the count yet */ | 125 | /* This loads the count register but does NOT start the count yet */ |
| 124 | mpcore_wdt_keepalive(wdt); | 126 | mpcore_wdt_keepalive(wdt); |
| 125 | 127 | ||
| @@ -130,7 +132,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt) | |||
| 130 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ | 132 | /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ |
| 131 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); | 133 | writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); |
| 132 | } | 134 | } |
| 133 | spin_unlock(&wdt_lock); | ||
| 134 | } | 135 | } |
| 135 | 136 | ||
| 136 | static int mpcore_wdt_set_heartbeat(int t) | 137 | static int mpcore_wdt_set_heartbeat(int t) |
| @@ -360,7 +361,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
| 360 | mpcore_wdt_miscdev.parent = &dev->dev; | 361 | mpcore_wdt_miscdev.parent = &dev->dev; |
| 361 | ret = misc_register(&mpcore_wdt_miscdev); | 362 | ret = misc_register(&mpcore_wdt_miscdev); |
| 362 | if (ret) { | 363 | if (ret) { |
| 363 | dev_printk(KERN_ERR, _dev, | 364 | dev_printk(KERN_ERR, wdt->dev, |
| 364 | "cannot register miscdev on minor=%d (err=%d)\n", | 365 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 365 | WATCHDOG_MINOR, ret); | 366 | WATCHDOG_MINOR, ret); |
| 366 | goto err_misc; | 367 | goto err_misc; |
| @@ -369,13 +370,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
| 369 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, | 370 | ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, |
| 370 | "mpcore_wdt", wdt); | 371 | "mpcore_wdt", wdt); |
| 371 | if (ret) { | 372 | if (ret) { |
| 372 | dev_printk(KERN_ERR, _dev, | 373 | dev_printk(KERN_ERR, wdt->dev, |
| 373 | "cannot register IRQ%d for watchdog\n", wdt->irq); | 374 | "cannot register IRQ%d for watchdog\n", wdt->irq); |
| 374 | goto err_irq; | 375 | goto err_irq; |
| 375 | } | 376 | } |
| 376 | 377 | ||
| 377 | mpcore_wdt_stop(wdt); | 378 | mpcore_wdt_stop(wdt); |
| 378 | platform_set_drvdata(&dev->dev, wdt); | 379 | platform_set_drvdata(dev, wdt); |
| 379 | mpcore_wdt_dev = dev; | 380 | mpcore_wdt_dev = dev; |
| 380 | 381 | ||
| 381 | return 0; | 382 | return 0; |
