@@ -226,22 +226,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { }
226226 */
227227static unsigned long hpet_freq ;
228228
229- static void hpet_legacy_set_mode (enum clock_event_mode mode ,
230- struct clock_event_device * evt );
231- static int hpet_legacy_next_event (unsigned long delta ,
232- struct clock_event_device * evt );
233-
234- /*
235- * The hpet clock event device
236- */
237- static struct clock_event_device hpet_clockevent = {
238- .name = "hpet" ,
239- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT ,
240- .set_mode = hpet_legacy_set_mode ,
241- .set_next_event = hpet_legacy_next_event ,
242- .irq = 0 ,
243- .rating = 50 ,
244- };
229+ static struct clock_event_device hpet_clockevent ;
245230
246231static void hpet_stop_counter (void )
247232{
@@ -306,64 +291,74 @@ static void hpet_legacy_clockevent_register(void)
306291 printk (KERN_DEBUG "hpet clockevent registered\n" );
307292}
308293
309- static void hpet_set_mode (enum clock_event_mode mode ,
310- struct clock_event_device * evt , int timer )
294+ static int hpet_set_periodic (struct clock_event_device * evt , int timer )
311295{
312296 unsigned int cfg , cmp , now ;
313297 uint64_t delta ;
314298
315- switch (mode ) {
316- case CLOCK_EVT_MODE_PERIODIC :
317- hpet_stop_counter ();
318- delta = ((uint64_t )(NSEC_PER_SEC /HZ )) * evt -> mult ;
319- delta >>= evt -> shift ;
320- now = hpet_readl (HPET_COUNTER );
321- cmp = now + (unsigned int ) delta ;
322- cfg = hpet_readl (HPET_Tn_CFG (timer ));
323- cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
324- HPET_TN_SETVAL | HPET_TN_32BIT ;
325- hpet_writel (cfg , HPET_Tn_CFG (timer ));
326- hpet_writel (cmp , HPET_Tn_CMP (timer ));
327- udelay (1 );
328- /*
329- * HPET on AMD 81xx needs a second write (with HPET_TN_SETVAL
330- * cleared) to T0_CMP to set the period. The HPET_TN_SETVAL
331- * bit is automatically cleared after the first write.
332- * (See AMD-8111 HyperTransport I/O Hub Data Sheet,
333- * Publication # 24674)
334- */
335- hpet_writel ((unsigned int ) delta , HPET_Tn_CMP (timer ));
336- hpet_start_counter ();
337- hpet_print_config ();
338- break ;
299+ hpet_stop_counter ();
300+ delta = ((uint64_t )(NSEC_PER_SEC / HZ )) * evt -> mult ;
301+ delta >>= evt -> shift ;
302+ now = hpet_readl (HPET_COUNTER );
303+ cmp = now + (unsigned int )delta ;
304+ cfg = hpet_readl (HPET_Tn_CFG (timer ));
305+ cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
306+ HPET_TN_32BIT ;
307+ hpet_writel (cfg , HPET_Tn_CFG (timer ));
308+ hpet_writel (cmp , HPET_Tn_CMP (timer ));
309+ udelay (1 );
310+ /*
311+ * HPET on AMD 81xx needs a second write (with HPET_TN_SETVAL
312+ * cleared) to T0_CMP to set the period. The HPET_TN_SETVAL
313+ * bit is automatically cleared after the first write.
314+ * (See AMD-8111 HyperTransport I/O Hub Data Sheet,
315+ * Publication # 24674)
316+ */
317+ hpet_writel ((unsigned int )delta , HPET_Tn_CMP (timer ));
318+ hpet_start_counter ();
319+ hpet_print_config ();
339320
340- case CLOCK_EVT_MODE_ONESHOT :
341- cfg = hpet_readl (HPET_Tn_CFG (timer ));
342- cfg &= ~HPET_TN_PERIODIC ;
343- cfg |= HPET_TN_ENABLE | HPET_TN_32BIT ;
344- hpet_writel (cfg , HPET_Tn_CFG (timer ));
345- break ;
321+ return 0 ;
322+ }
346323
347- case CLOCK_EVT_MODE_UNUSED :
348- case CLOCK_EVT_MODE_SHUTDOWN :
349- cfg = hpet_readl (HPET_Tn_CFG (timer ));
350- cfg &= ~HPET_TN_ENABLE ;
351- hpet_writel (cfg , HPET_Tn_CFG (timer ));
352- break ;
324+ static int hpet_set_oneshot (struct clock_event_device * evt , int timer )
325+ {
326+ unsigned int cfg ;
353327
354- case CLOCK_EVT_MODE_RESUME :
355- if (timer == 0 ) {
356- hpet_enable_legacy_int ();
357- } else {
358- struct hpet_dev * hdev = EVT_TO_HPET_DEV (evt );
359- irq_domain_activate_irq (irq_get_irq_data (hdev -> irq ));
360- disable_irq (hdev -> irq );
361- irq_set_affinity (hdev -> irq , cpumask_of (hdev -> cpu ));
362- enable_irq (hdev -> irq );
363- }
364- hpet_print_config ();
365- break ;
328+ cfg = hpet_readl (HPET_Tn_CFG (timer ));
329+ cfg &= ~HPET_TN_PERIODIC ;
330+ cfg |= HPET_TN_ENABLE | HPET_TN_32BIT ;
331+ hpet_writel (cfg , HPET_Tn_CFG (timer ));
332+
333+ return 0 ;
334+ }
335+
336+ static int hpet_shutdown (struct clock_event_device * evt , int timer )
337+ {
338+ unsigned int cfg ;
339+
340+ cfg = hpet_readl (HPET_Tn_CFG (timer ));
341+ cfg &= ~HPET_TN_ENABLE ;
342+ hpet_writel (cfg , HPET_Tn_CFG (timer ));
343+
344+ return 0 ;
345+ }
346+
347+ static int hpet_resume (struct clock_event_device * evt , int timer )
348+ {
349+ if (!timer ) {
350+ hpet_enable_legacy_int ();
351+ } else {
352+ struct hpet_dev * hdev = EVT_TO_HPET_DEV (evt );
353+
354+ irq_domain_activate_irq (irq_get_irq_data (hdev -> irq ));
355+ disable_irq (hdev -> irq );
356+ irq_set_affinity (hdev -> irq , cpumask_of (hdev -> cpu ));
357+ enable_irq (hdev -> irq );
366358 }
359+ hpet_print_config ();
360+
361+ return 0 ;
367362}
368363
369364static int hpet_next_event (unsigned long delta ,
@@ -403,10 +398,24 @@ static int hpet_next_event(unsigned long delta,
403398 return res < HPET_MIN_CYCLES ? - ETIME : 0 ;
404399}
405400
406- static void hpet_legacy_set_mode (enum clock_event_mode mode ,
407- struct clock_event_device * evt )
401+ static int hpet_legacy_shutdown (struct clock_event_device * evt )
402+ {
403+ return hpet_shutdown (evt , 0 );
404+ }
405+
406+ static int hpet_legacy_set_oneshot (struct clock_event_device * evt )
407+ {
408+ return hpet_set_oneshot (evt , 0 );
409+ }
410+
411+ static int hpet_legacy_set_periodic (struct clock_event_device * evt )
408412{
409- hpet_set_mode (mode , evt , 0 );
413+ return hpet_set_periodic (evt , 0 );
414+ }
415+
416+ static int hpet_legacy_resume (struct clock_event_device * evt )
417+ {
418+ return hpet_resume (evt , 0 );
410419}
411420
412421static int hpet_legacy_next_event (unsigned long delta ,
@@ -415,6 +424,22 @@ static int hpet_legacy_next_event(unsigned long delta,
415424 return hpet_next_event (delta , evt , 0 );
416425}
417426
427+ /*
428+ * The hpet clock event device
429+ */
430+ static struct clock_event_device hpet_clockevent = {
431+ .name = "hpet" ,
432+ .features = CLOCK_EVT_FEAT_PERIODIC |
433+ CLOCK_EVT_FEAT_ONESHOT ,
434+ .set_state_periodic = hpet_legacy_set_periodic ,
435+ .set_state_oneshot = hpet_legacy_set_oneshot ,
436+ .set_state_shutdown = hpet_legacy_shutdown ,
437+ .tick_resume = hpet_legacy_resume ,
438+ .set_next_event = hpet_legacy_next_event ,
439+ .irq = 0 ,
440+ .rating = 50 ,
441+ };
442+
418443/*
419444 * HPET MSI Support
420445 */
@@ -459,11 +484,32 @@ void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg)
459484 msg -> address_hi = 0 ;
460485}
461486
462- static void hpet_msi_set_mode (enum clock_event_mode mode ,
463- struct clock_event_device * evt )
487+ static int hpet_msi_shutdown (struct clock_event_device * evt )
488+ {
489+ struct hpet_dev * hdev = EVT_TO_HPET_DEV (evt );
490+
491+ return hpet_shutdown (evt , hdev -> num );
492+ }
493+
494+ static int hpet_msi_set_oneshot (struct clock_event_device * evt )
495+ {
496+ struct hpet_dev * hdev = EVT_TO_HPET_DEV (evt );
497+
498+ return hpet_set_oneshot (evt , hdev -> num );
499+ }
500+
501+ static int hpet_msi_set_periodic (struct clock_event_device * evt )
464502{
465503 struct hpet_dev * hdev = EVT_TO_HPET_DEV (evt );
466- hpet_set_mode (mode , evt , hdev -> num );
504+
505+ return hpet_set_periodic (evt , hdev -> num );
506+ }
507+
508+ static int hpet_msi_resume (struct clock_event_device * evt )
509+ {
510+ struct hpet_dev * hdev = EVT_TO_HPET_DEV (evt );
511+
512+ return hpet_resume (evt , hdev -> num );
467513}
468514
469515static int hpet_msi_next_event (unsigned long delta ,
@@ -523,10 +569,14 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
523569
524570 evt -> rating = 110 ;
525571 evt -> features = CLOCK_EVT_FEAT_ONESHOT ;
526- if (hdev -> flags & HPET_DEV_PERI_CAP )
572+ if (hdev -> flags & HPET_DEV_PERI_CAP ) {
527573 evt -> features |= CLOCK_EVT_FEAT_PERIODIC ;
574+ evt -> set_state_periodic = hpet_msi_set_periodic ;
575+ }
528576
529- evt -> set_mode = hpet_msi_set_mode ;
577+ evt -> set_state_shutdown = hpet_msi_shutdown ;
578+ evt -> set_state_oneshot = hpet_msi_set_oneshot ;
579+ evt -> tick_resume = hpet_msi_resume ;
530580 evt -> set_next_event = hpet_msi_next_event ;
531581 evt -> cpumask = cpumask_of (hdev -> cpu );
532582
0 commit comments