010-mips_clocksource_init_war.patch 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. --- a/arch/mips/kernel/cevt-r4k.c
  2. +++ b/arch/mips/kernel/cevt-r4k.c
  3. @@ -13,6 +13,22 @@
  4. #include <asm/smtc_ipi.h>
  5. #include <asm/time.h>
  6. +/*
  7. + * Compare interrupt can be routed and latched outside the core,
  8. + * so a single execution hazard barrier may not be enough to give
  9. + * it time to clear as seen in the Cause register. 4 time the
  10. + * pipeline depth seems reasonably conservative, and empirically
  11. + * works better in configurations with high CPU/bus clock ratios.
  12. + */
  13. +
  14. +#define compare_change_hazard() \
  15. + do { \
  16. + irq_disable_hazard(); \
  17. + irq_disable_hazard(); \
  18. + irq_disable_hazard(); \
  19. + irq_disable_hazard(); \
  20. + } while (0)
  21. +
  22. static int mips_next_event(unsigned long delta,
  23. struct clock_event_device *evt)
  24. {
  25. @@ -28,6 +44,7 @@ static int mips_next_event(unsigned long
  26. cnt = read_c0_count();
  27. cnt += delta;
  28. write_c0_compare(cnt);
  29. + compare_change_hazard();
  30. res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
  31. #ifdef CONFIG_MIPS_MT_SMTC
  32. evpe(vpflags);
  33. @@ -187,7 +204,7 @@ static int c0_compare_int_usable(void)
  34. */
  35. if (c0_compare_int_pending()) {
  36. write_c0_compare(read_c0_count());
  37. - irq_disable_hazard();
  38. + compare_change_hazard();
  39. if (c0_compare_int_pending())
  40. return 0;
  41. }
  42. @@ -196,7 +213,7 @@ static int c0_compare_int_usable(void)
  43. cnt = read_c0_count();
  44. cnt += delta;
  45. write_c0_compare(cnt);
  46. - irq_disable_hazard();
  47. + compare_change_hazard();
  48. if ((int)(read_c0_count() - cnt) < 0)
  49. break;
  50. /* increase delta if the timer was already expired */
  51. @@ -205,11 +222,12 @@ static int c0_compare_int_usable(void)
  52. while ((int)(read_c0_count() - cnt) <= 0)
  53. ; /* Wait for expiry */
  54. + compare_change_hazard();
  55. if (!c0_compare_int_pending())
  56. return 0;
  57. write_c0_compare(read_c0_count());
  58. - irq_disable_hazard();
  59. + compare_change_hazard();
  60. if (c0_compare_int_pending())
  61. return 0;