.. | .. |
---|
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 | |
---|