Skip to content

Commit e713c80

Browse files
committed
Merge branch 'x86-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 clockevent update from Thomas Gleixner: "A single commit, which converts HPET clockevents driver to the new callbacks" * 'x86-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/hpet: Migrate to new set_state interface
2 parents 43af987 + c8b5db7 commit e713c80

File tree

1 file changed

+124
-74
lines changed

1 file changed

+124
-74
lines changed

arch/x86/kernel/hpet.c

Lines changed: 124 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -226,22 +226,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { }
226226
*/
227227
static 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

246231
static 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

369364
static 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

412421
static 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

469515
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)
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

Comments
 (0)