143-clocksource-drivers-timer-microchip-pit64b-Add-clock.patch 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. From 5f090a664d62ceeaf9a0f482426e35cab18d65a9 Mon Sep 17 00:00:00 2001
  2. From: Claudiu Beznea <[email protected]>
  3. Date: Tue, 19 Jan 2021 14:59:25 +0200
  4. Subject: [PATCH 143/247] clocksource/drivers/timer-microchip-pit64b: Add
  5. clocksource suspend/resume
  6. Add suspend/resume support for clocksource timer.
  7. Signed-off-by: Claudiu Beznea <[email protected]>
  8. Signed-off-by: Daniel Lezcano <[email protected]>
  9. Link: https://lore.kernel.org/r/[email protected]
  10. ---
  11. drivers/clocksource/timer-microchip-pit64b.c | 86 ++++++++++++++++----
  12. 1 file changed, 71 insertions(+), 15 deletions(-)
  13. --- a/drivers/clocksource/timer-microchip-pit64b.c
  14. +++ b/drivers/clocksource/timer-microchip-pit64b.c
  15. @@ -71,10 +71,24 @@ struct mchp_pit64b_clkevt {
  16. struct clock_event_device clkevt;
  17. };
  18. -#define to_mchp_pit64b_timer(x) \
  19. +#define clkevt_to_mchp_pit64b_timer(x) \
  20. ((struct mchp_pit64b_timer *)container_of(x,\
  21. struct mchp_pit64b_clkevt, clkevt))
  22. +/**
  23. + * mchp_pit64b_clksrc - PIT64B clocksource data structure
  24. + * @timer: PIT64B timer
  25. + * @clksrc: clocksource
  26. + */
  27. +struct mchp_pit64b_clksrc {
  28. + struct mchp_pit64b_timer timer;
  29. + struct clocksource clksrc;
  30. +};
  31. +
  32. +#define clksrc_to_mchp_pit64b_timer(x) \
  33. + ((struct mchp_pit64b_timer *)container_of(x,\
  34. + struct mchp_pit64b_clksrc, clksrc))
  35. +
  36. /* Base address for clocksource timer. */
  37. static void __iomem *mchp_pit64b_cs_base;
  38. /* Default cycles for clockevent timer. */
  39. @@ -116,6 +130,36 @@ static inline void mchp_pit64b_reset(str
  40. writel_relaxed(MCHP_PIT64B_CR_START, timer->base + MCHP_PIT64B_CR);
  41. }
  42. +static void mchp_pit64b_suspend(struct mchp_pit64b_timer *timer)
  43. +{
  44. + writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR);
  45. + if (timer->mode & MCHP_PIT64B_MR_SGCLK)
  46. + clk_disable_unprepare(timer->gclk);
  47. + clk_disable_unprepare(timer->pclk);
  48. +}
  49. +
  50. +static void mchp_pit64b_resume(struct mchp_pit64b_timer *timer)
  51. +{
  52. + clk_prepare_enable(timer->pclk);
  53. + if (timer->mode & MCHP_PIT64B_MR_SGCLK)
  54. + clk_prepare_enable(timer->gclk);
  55. +}
  56. +
  57. +static void mchp_pit64b_clksrc_suspend(struct clocksource *cs)
  58. +{
  59. + struct mchp_pit64b_timer *timer = clksrc_to_mchp_pit64b_timer(cs);
  60. +
  61. + mchp_pit64b_suspend(timer);
  62. +}
  63. +
  64. +static void mchp_pit64b_clksrc_resume(struct clocksource *cs)
  65. +{
  66. + struct mchp_pit64b_timer *timer = clksrc_to_mchp_pit64b_timer(cs);
  67. +
  68. + mchp_pit64b_resume(timer);
  69. + mchp_pit64b_reset(timer, ULLONG_MAX, MCHP_PIT64B_MR_CONT, 0);
  70. +}
  71. +
  72. static u64 mchp_pit64b_clksrc_read(struct clocksource *cs)
  73. {
  74. return mchp_pit64b_cnt_read(mchp_pit64b_cs_base);
  75. @@ -128,7 +172,7 @@ static u64 notrace mchp_pit64b_sched_rea
  76. static int mchp_pit64b_clkevt_shutdown(struct clock_event_device *cedev)
  77. {
  78. - struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev);
  79. + struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev);
  80. writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR);
  81. @@ -137,7 +181,7 @@ static int mchp_pit64b_clkevt_shutdown(s
  82. static int mchp_pit64b_clkevt_set_periodic(struct clock_event_device *cedev)
  83. {
  84. - struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev);
  85. + struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev);
  86. mchp_pit64b_reset(timer, mchp_pit64b_ce_cycles, MCHP_PIT64B_MR_CONT,
  87. MCHP_PIT64B_IER_PERIOD);
  88. @@ -148,7 +192,7 @@ static int mchp_pit64b_clkevt_set_period
  89. static int mchp_pit64b_clkevt_set_next_event(unsigned long evt,
  90. struct clock_event_device *cedev)
  91. {
  92. - struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev);
  93. + struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev);
  94. mchp_pit64b_reset(timer, evt, MCHP_PIT64B_MR_ONE_SHOT,
  95. MCHP_PIT64B_IER_PERIOD);
  96. @@ -158,21 +202,16 @@ static int mchp_pit64b_clkevt_set_next_e
  97. static void mchp_pit64b_clkevt_suspend(struct clock_event_device *cedev)
  98. {
  99. - struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev);
  100. + struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev);
  101. - writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR);
  102. - if (timer->mode & MCHP_PIT64B_MR_SGCLK)
  103. - clk_disable_unprepare(timer->gclk);
  104. - clk_disable_unprepare(timer->pclk);
  105. + mchp_pit64b_suspend(timer);
  106. }
  107. static void mchp_pit64b_clkevt_resume(struct clock_event_device *cedev)
  108. {
  109. - struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev);
  110. + struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev);
  111. - clk_prepare_enable(timer->pclk);
  112. - if (timer->mode & MCHP_PIT64B_MR_SGCLK)
  113. - clk_prepare_enable(timer->gclk);
  114. + mchp_pit64b_resume(timer);
  115. }
  116. static irqreturn_t mchp_pit64b_interrupt(int irq, void *dev_id)
  117. @@ -296,20 +335,37 @@ done:
  118. static int __init mchp_pit64b_init_clksrc(struct mchp_pit64b_timer *timer,
  119. u32 clk_rate)
  120. {
  121. + struct mchp_pit64b_clksrc *cs;
  122. int ret;
  123. + cs = kzalloc(sizeof(*cs), GFP_KERNEL);
  124. + if (!cs)
  125. + return -ENOMEM;
  126. +
  127. mchp_pit64b_reset(timer, ULLONG_MAX, MCHP_PIT64B_MR_CONT, 0);
  128. mchp_pit64b_cs_base = timer->base;
  129. - ret = clocksource_mmio_init(timer->base, MCHP_PIT64B_NAME, clk_rate,
  130. - 210, 64, mchp_pit64b_clksrc_read);
  131. + cs->timer.base = timer->base;
  132. + cs->timer.pclk = timer->pclk;
  133. + cs->timer.gclk = timer->gclk;
  134. + cs->timer.mode = timer->mode;
  135. + cs->clksrc.name = MCHP_PIT64B_NAME;
  136. + cs->clksrc.mask = CLOCKSOURCE_MASK(64);
  137. + cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
  138. + cs->clksrc.rating = 210;
  139. + cs->clksrc.read = mchp_pit64b_clksrc_read;
  140. + cs->clksrc.suspend = mchp_pit64b_clksrc_suspend;
  141. + cs->clksrc.resume = mchp_pit64b_clksrc_resume;
  142. +
  143. + ret = clocksource_register_hz(&cs->clksrc, clk_rate);
  144. if (ret) {
  145. pr_debug("clksrc: Failed to register PIT64B clocksource!\n");
  146. /* Stop timer. */
  147. writel_relaxed(MCHP_PIT64B_CR_SWRST,
  148. timer->base + MCHP_PIT64B_CR);
  149. + kfree(cs);
  150. return ret;
  151. }