@@ -226,22 +226,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { }
226
226
*/
227
227
static unsigned long hpet_freq ;
228
228
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 ;
245
230
246
231
static void hpet_stop_counter (void )
247
232
{
@@ -306,64 +291,74 @@ static void hpet_legacy_clockevent_register(void)
306
291
printk (KERN_DEBUG "hpet clockevent registered\n" );
307
292
}
308
293
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 )
311
295
{
312
296
unsigned int cfg , cmp , now ;
313
297
uint64_t delta ;
314
298
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 ();
339
320
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
+ }
346
323
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 ;
353
327
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 );
366
358
}
359
+ hpet_print_config ();
360
+
361
+ return 0 ;
367
362
}
368
363
369
364
static int hpet_next_event (unsigned long delta ,
@@ -403,10 +398,24 @@ static int hpet_next_event(unsigned long delta,
403
398
return res < HPET_MIN_CYCLES ? - ETIME : 0 ;
404
399
}
405
400
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 )
408
412
{
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 );
410
419
}
411
420
412
421
static int hpet_legacy_next_event (unsigned long delta ,
@@ -415,6 +424,22 @@ static int hpet_legacy_next_event(unsigned long delta,
415
424
return hpet_next_event (delta , evt , 0 );
416
425
}
417
426
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
+
418
443
/*
419
444
* HPET MSI Support
420
445
*/
@@ -459,11 +484,32 @@ void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg)
459
484
msg -> address_hi = 0 ;
460
485
}
461
486
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 )
464
502
{
465
503
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 );
467
513
}
468
514
469
515
static 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)
523
569
524
570
evt -> rating = 110 ;
525
571
evt -> features = CLOCK_EVT_FEAT_ONESHOT ;
526
- if (hdev -> flags & HPET_DEV_PERI_CAP )
572
+ if (hdev -> flags & HPET_DEV_PERI_CAP ) {
527
573
evt -> features |= CLOCK_EVT_FEAT_PERIODIC ;
574
+ evt -> set_state_periodic = hpet_msi_set_periodic ;
575
+ }
528
576
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 ;
530
580
evt -> set_next_event = hpet_msi_next_event ;
531
581
evt -> cpumask = cpumask_of (hdev -> cpu );
532
582
0 commit comments