| .. | .. |
|---|
| 53 | 53 | static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id) |
|---|
| 54 | 54 | { |
|---|
| 55 | 55 | struct bcm2835_timer *timer = dev_id; |
|---|
| 56 | | - void (*event_handler)(struct clock_event_device *); |
|---|
| 56 | + |
|---|
| 57 | 57 | if (readl_relaxed(timer->control) & timer->match_mask) { |
|---|
| 58 | 58 | writel_relaxed(timer->match_mask, timer->control); |
|---|
| 59 | 59 | |
|---|
| 60 | | - event_handler = READ_ONCE(timer->evt.event_handler); |
|---|
| 61 | | - if (event_handler) |
|---|
| 62 | | - event_handler(&timer->evt); |
|---|
| 60 | + clockevents_handle_event(&timer->evt); |
|---|
| 63 | 61 | return IRQ_HANDLED; |
|---|
| 64 | 62 | } else { |
|---|
| 65 | 63 | return IRQ_NONE; |
|---|
| 66 | 64 | } |
|---|
| 67 | 65 | } |
|---|
| 66 | + |
|---|
| 67 | +static struct clocksource_user_mmio clocksource_bcm2835 = { |
|---|
| 68 | + .mmio.clksrc = { |
|---|
| 69 | + .rating = 300, |
|---|
| 70 | + .read = clocksource_mmio_readl_up, |
|---|
| 71 | + .mask = CLOCKSOURCE_MASK(32), |
|---|
| 72 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
|---|
| 73 | + }, |
|---|
| 74 | +}; |
|---|
| 68 | 75 | |
|---|
| 69 | 76 | static int __init bcm2835_timer_init(struct device_node *node) |
|---|
| 70 | 77 | { |
|---|
| .. | .. |
|---|
| 72 | 79 | u32 freq; |
|---|
| 73 | 80 | int irq, ret; |
|---|
| 74 | 81 | struct bcm2835_timer *timer; |
|---|
| 82 | + struct clocksource_mmio_regs mmr; |
|---|
| 75 | 83 | |
|---|
| 76 | 84 | base = of_iomap(node, 0); |
|---|
| 77 | 85 | if (!base) { |
|---|
| .. | .. |
|---|
| 88 | 96 | system_clock = base + REG_COUNTER_LO; |
|---|
| 89 | 97 | sched_clock_register(bcm2835_sched_read, 32, freq); |
|---|
| 90 | 98 | |
|---|
| 91 | | - clocksource_mmio_init(base + REG_COUNTER_LO, node->name, |
|---|
| 92 | | - freq, 300, 32, clocksource_mmio_readl_up); |
|---|
| 99 | + mmr.reg_lower = base + REG_COUNTER_LO; |
|---|
| 100 | + mmr.bits_lower = 32; |
|---|
| 101 | + mmr.reg_upper = 0; |
|---|
| 102 | + mmr.bits_upper = 0; |
|---|
| 103 | + mmr.revmap = NULL; |
|---|
| 104 | + clocksource_bcm2835.mmio.clksrc.name = node->name; |
|---|
| 105 | + clocksource_user_mmio_init(&clocksource_bcm2835, &mmr, freq); |
|---|
| 93 | 106 | |
|---|
| 94 | 107 | irq = irq_of_parse_and_map(node, DEFAULT_TIMER); |
|---|
| 95 | 108 | if (irq <= 0) { |
|---|
| .. | .. |
|---|
| 109 | 122 | timer->match_mask = BIT(DEFAULT_TIMER); |
|---|
| 110 | 123 | timer->evt.name = node->name; |
|---|
| 111 | 124 | timer->evt.rating = 300; |
|---|
| 112 | | - timer->evt.features = CLOCK_EVT_FEAT_ONESHOT; |
|---|
| 125 | + timer->evt.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PIPELINE; |
|---|
| 113 | 126 | timer->evt.set_next_event = bcm2835_time_set_next_event; |
|---|
| 114 | 127 | timer->evt.cpumask = cpumask_of(0); |
|---|
| 115 | 128 | |
|---|