1*4891f015SMarc Zyngier // SPDX-License-Identifier: GPL-2.0-only 2*4891f015SMarc Zyngier /* 3*4891f015SMarc Zyngier * ARM Generic Memory Mapped Timer support 4*4891f015SMarc Zyngier * 5*4891f015SMarc Zyngier * Split from drivers/clocksource/arm_arch_timer.c 6*4891f015SMarc Zyngier * 7*4891f015SMarc Zyngier * Copyright (C) 2011 ARM Ltd. 8*4891f015SMarc Zyngier * All Rights Reserved 9*4891f015SMarc Zyngier */ 10*4891f015SMarc Zyngier 11*4891f015SMarc Zyngier #define pr_fmt(fmt) "arch_timer_mmio: " fmt 12*4891f015SMarc Zyngier 13*4891f015SMarc Zyngier #include <linux/clockchips.h> 14*4891f015SMarc Zyngier #include <linux/interrupt.h> 15*4891f015SMarc Zyngier #include <linux/io-64-nonatomic-lo-hi.h> 16*4891f015SMarc Zyngier #include <linux/of_irq.h> 17*4891f015SMarc Zyngier #include <linux/of_address.h> 18*4891f015SMarc Zyngier #include <linux/platform_device.h> 19*4891f015SMarc Zyngier 20*4891f015SMarc Zyngier #include <clocksource/arm_arch_timer.h> 21*4891f015SMarc Zyngier 22*4891f015SMarc Zyngier #define CNTTIDR 0x08 23*4891f015SMarc Zyngier #define CNTTIDR_VIRT(n) (BIT(1) << ((n) * 4)) 24*4891f015SMarc Zyngier 25*4891f015SMarc Zyngier #define CNTACR(n) (0x40 + ((n) * 4)) 26*4891f015SMarc Zyngier #define CNTACR_RPCT BIT(0) 27*4891f015SMarc Zyngier #define CNTACR_RVCT BIT(1) 28*4891f015SMarc Zyngier #define CNTACR_RFRQ BIT(2) 29*4891f015SMarc Zyngier #define CNTACR_RVOFF BIT(3) 30*4891f015SMarc Zyngier #define CNTACR_RWVT BIT(4) 31*4891f015SMarc Zyngier #define CNTACR_RWPT BIT(5) 32*4891f015SMarc Zyngier 33*4891f015SMarc Zyngier #define CNTPCT_LO 0x00 34*4891f015SMarc Zyngier #define CNTVCT_LO 0x08 35*4891f015SMarc Zyngier #define CNTFRQ 0x10 36*4891f015SMarc Zyngier #define CNTP_CVAL_LO 0x20 37*4891f015SMarc Zyngier #define CNTP_CTL 0x2c 38*4891f015SMarc Zyngier #define CNTV_CVAL_LO 0x30 39*4891f015SMarc Zyngier #define CNTV_CTL 0x3c 40*4891f015SMarc Zyngier 41*4891f015SMarc Zyngier enum arch_timer_access { 42*4891f015SMarc Zyngier PHYS_ACCESS, 43*4891f015SMarc Zyngier VIRT_ACCESS, 44*4891f015SMarc Zyngier }; 45*4891f015SMarc Zyngier 46*4891f015SMarc Zyngier struct arch_timer { 47*4891f015SMarc Zyngier struct clock_event_device evt; 48*4891f015SMarc Zyngier struct arch_timer_mem *gt_block; 49*4891f015SMarc Zyngier void __iomem *base; 50*4891f015SMarc Zyngier enum arch_timer_access access; 51*4891f015SMarc Zyngier u32 rate; 52*4891f015SMarc Zyngier }; 53*4891f015SMarc Zyngier 54*4891f015SMarc Zyngier #define evt_to_arch_timer(e) container_of(e, struct arch_timer, evt) 55*4891f015SMarc Zyngier 56*4891f015SMarc Zyngier static void arch_timer_mmio_write(struct arch_timer *timer, 57*4891f015SMarc Zyngier enum arch_timer_reg reg, u64 val) 58*4891f015SMarc Zyngier { 59*4891f015SMarc Zyngier switch (timer->access) { 60*4891f015SMarc Zyngier case PHYS_ACCESS: 61*4891f015SMarc Zyngier switch (reg) { 62*4891f015SMarc Zyngier case ARCH_TIMER_REG_CTRL: 63*4891f015SMarc Zyngier writel_relaxed((u32)val, timer->base + CNTP_CTL); 64*4891f015SMarc Zyngier return; 65*4891f015SMarc Zyngier case ARCH_TIMER_REG_CVAL: 66*4891f015SMarc Zyngier /* 67*4891f015SMarc Zyngier * Not guaranteed to be atomic, so the timer 68*4891f015SMarc Zyngier * must be disabled at this point. 69*4891f015SMarc Zyngier */ 70*4891f015SMarc Zyngier writeq_relaxed(val, timer->base + CNTP_CVAL_LO); 71*4891f015SMarc Zyngier return; 72*4891f015SMarc Zyngier } 73*4891f015SMarc Zyngier break; 74*4891f015SMarc Zyngier case VIRT_ACCESS: 75*4891f015SMarc Zyngier switch (reg) { 76*4891f015SMarc Zyngier case ARCH_TIMER_REG_CTRL: 77*4891f015SMarc Zyngier writel_relaxed((u32)val, timer->base + CNTV_CTL); 78*4891f015SMarc Zyngier return; 79*4891f015SMarc Zyngier case ARCH_TIMER_REG_CVAL: 80*4891f015SMarc Zyngier /* Same restriction as above */ 81*4891f015SMarc Zyngier writeq_relaxed(val, timer->base + CNTV_CVAL_LO); 82*4891f015SMarc Zyngier return; 83*4891f015SMarc Zyngier } 84*4891f015SMarc Zyngier break; 85*4891f015SMarc Zyngier } 86*4891f015SMarc Zyngier 87*4891f015SMarc Zyngier /* Should never be here */ 88*4891f015SMarc Zyngier WARN_ON_ONCE(1); 89*4891f015SMarc Zyngier } 90*4891f015SMarc Zyngier 91*4891f015SMarc Zyngier static u32 arch_timer_mmio_read(struct arch_timer *timer, enum arch_timer_reg reg) 92*4891f015SMarc Zyngier { 93*4891f015SMarc Zyngier switch (timer->access) { 94*4891f015SMarc Zyngier case PHYS_ACCESS: 95*4891f015SMarc Zyngier switch (reg) { 96*4891f015SMarc Zyngier case ARCH_TIMER_REG_CTRL: 97*4891f015SMarc Zyngier return readl_relaxed(timer->base + CNTP_CTL); 98*4891f015SMarc Zyngier default: 99*4891f015SMarc Zyngier break; 100*4891f015SMarc Zyngier } 101*4891f015SMarc Zyngier break; 102*4891f015SMarc Zyngier case VIRT_ACCESS: 103*4891f015SMarc Zyngier switch (reg) { 104*4891f015SMarc Zyngier case ARCH_TIMER_REG_CTRL: 105*4891f015SMarc Zyngier return readl_relaxed(timer->base + CNTV_CTL); 106*4891f015SMarc Zyngier default: 107*4891f015SMarc Zyngier break; 108*4891f015SMarc Zyngier } 109*4891f015SMarc Zyngier break; 110*4891f015SMarc Zyngier } 111*4891f015SMarc Zyngier 112*4891f015SMarc Zyngier /* Should never be here */ 113*4891f015SMarc Zyngier WARN_ON_ONCE(1); 114*4891f015SMarc Zyngier return 0; 115*4891f015SMarc Zyngier } 116*4891f015SMarc Zyngier 117*4891f015SMarc Zyngier static noinstr u64 arch_counter_mmio_get_cnt(struct arch_timer *t) 118*4891f015SMarc Zyngier { 119*4891f015SMarc Zyngier int offset_lo = t->access == VIRT_ACCESS ? CNTVCT_LO : CNTPCT_LO; 120*4891f015SMarc Zyngier u32 cnt_lo, cnt_hi, tmp_hi; 121*4891f015SMarc Zyngier 122*4891f015SMarc Zyngier do { 123*4891f015SMarc Zyngier cnt_hi = __le32_to_cpu((__le32 __force)__raw_readl(t->base + offset_lo + 4)); 124*4891f015SMarc Zyngier cnt_lo = __le32_to_cpu((__le32 __force)__raw_readl(t->base + offset_lo)); 125*4891f015SMarc Zyngier tmp_hi = __le32_to_cpu((__le32 __force)__raw_readl(t->base + offset_lo + 4)); 126*4891f015SMarc Zyngier } while (cnt_hi != tmp_hi); 127*4891f015SMarc Zyngier 128*4891f015SMarc Zyngier return ((u64) cnt_hi << 32) | cnt_lo; 129*4891f015SMarc Zyngier } 130*4891f015SMarc Zyngier 131*4891f015SMarc Zyngier static int arch_timer_mmio_shutdown(struct clock_event_device *clk) 132*4891f015SMarc Zyngier { 133*4891f015SMarc Zyngier struct arch_timer *at = evt_to_arch_timer(clk); 134*4891f015SMarc Zyngier unsigned long ctrl; 135*4891f015SMarc Zyngier 136*4891f015SMarc Zyngier ctrl = arch_timer_mmio_read(at, ARCH_TIMER_REG_CTRL); 137*4891f015SMarc Zyngier ctrl &= ~ARCH_TIMER_CTRL_ENABLE; 138*4891f015SMarc Zyngier arch_timer_mmio_write(at, ARCH_TIMER_REG_CTRL, ctrl); 139*4891f015SMarc Zyngier 140*4891f015SMarc Zyngier return 0; 141*4891f015SMarc Zyngier } 142*4891f015SMarc Zyngier 143*4891f015SMarc Zyngier static int arch_timer_mmio_set_next_event(unsigned long evt, 144*4891f015SMarc Zyngier struct clock_event_device *clk) 145*4891f015SMarc Zyngier { 146*4891f015SMarc Zyngier struct arch_timer *timer = evt_to_arch_timer(clk); 147*4891f015SMarc Zyngier unsigned long ctrl; 148*4891f015SMarc Zyngier u64 cnt; 149*4891f015SMarc Zyngier 150*4891f015SMarc Zyngier ctrl = arch_timer_mmio_read(timer, ARCH_TIMER_REG_CTRL); 151*4891f015SMarc Zyngier 152*4891f015SMarc Zyngier /* Timer must be disabled before programming CVAL */ 153*4891f015SMarc Zyngier if (ctrl & ARCH_TIMER_CTRL_ENABLE) { 154*4891f015SMarc Zyngier ctrl &= ~ARCH_TIMER_CTRL_ENABLE; 155*4891f015SMarc Zyngier arch_timer_mmio_write(timer, ARCH_TIMER_REG_CTRL, ctrl); 156*4891f015SMarc Zyngier } 157*4891f015SMarc Zyngier 158*4891f015SMarc Zyngier ctrl |= ARCH_TIMER_CTRL_ENABLE; 159*4891f015SMarc Zyngier ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; 160*4891f015SMarc Zyngier 161*4891f015SMarc Zyngier cnt = arch_counter_mmio_get_cnt(timer); 162*4891f015SMarc Zyngier 163*4891f015SMarc Zyngier arch_timer_mmio_write(timer, ARCH_TIMER_REG_CVAL, evt + cnt); 164*4891f015SMarc Zyngier arch_timer_mmio_write(timer, ARCH_TIMER_REG_CTRL, ctrl); 165*4891f015SMarc Zyngier return 0; 166*4891f015SMarc Zyngier } 167*4891f015SMarc Zyngier 168*4891f015SMarc Zyngier static irqreturn_t arch_timer_mmio_handler(int irq, void *dev_id) 169*4891f015SMarc Zyngier { 170*4891f015SMarc Zyngier struct clock_event_device *evt = dev_id; 171*4891f015SMarc Zyngier struct arch_timer *at = evt_to_arch_timer(evt); 172*4891f015SMarc Zyngier unsigned long ctrl; 173*4891f015SMarc Zyngier 174*4891f015SMarc Zyngier ctrl = arch_timer_mmio_read(at, ARCH_TIMER_REG_CTRL); 175*4891f015SMarc Zyngier if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { 176*4891f015SMarc Zyngier ctrl |= ARCH_TIMER_CTRL_IT_MASK; 177*4891f015SMarc Zyngier arch_timer_mmio_write(at, ARCH_TIMER_REG_CTRL, ctrl); 178*4891f015SMarc Zyngier evt->event_handler(evt); 179*4891f015SMarc Zyngier return IRQ_HANDLED; 180*4891f015SMarc Zyngier } 181*4891f015SMarc Zyngier 182*4891f015SMarc Zyngier return IRQ_NONE; 183*4891f015SMarc Zyngier } 184*4891f015SMarc Zyngier 185*4891f015SMarc Zyngier static struct arch_timer_mem_frame *find_best_frame(struct platform_device *pdev) 186*4891f015SMarc Zyngier { 187*4891f015SMarc Zyngier struct arch_timer_mem_frame *frame, *best_frame = NULL; 188*4891f015SMarc Zyngier struct arch_timer *at = platform_get_drvdata(pdev); 189*4891f015SMarc Zyngier void __iomem *cntctlbase; 190*4891f015SMarc Zyngier u32 cnttidr; 191*4891f015SMarc Zyngier 192*4891f015SMarc Zyngier cntctlbase = ioremap(at->gt_block->cntctlbase, at->gt_block->size); 193*4891f015SMarc Zyngier if (!cntctlbase) { 194*4891f015SMarc Zyngier dev_err(&pdev->dev, "Can't map CNTCTLBase @ %pa\n", 195*4891f015SMarc Zyngier &at->gt_block->cntctlbase); 196*4891f015SMarc Zyngier return NULL; 197*4891f015SMarc Zyngier } 198*4891f015SMarc Zyngier 199*4891f015SMarc Zyngier cnttidr = readl_relaxed(cntctlbase + CNTTIDR); 200*4891f015SMarc Zyngier 201*4891f015SMarc Zyngier /* 202*4891f015SMarc Zyngier * Try to find a virtual capable frame. Otherwise fall back to a 203*4891f015SMarc Zyngier * physical capable frame. 204*4891f015SMarc Zyngier */ 205*4891f015SMarc Zyngier for (int i = 0; i < ARCH_TIMER_MEM_MAX_FRAMES; i++) { 206*4891f015SMarc Zyngier u32 cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT | 207*4891f015SMarc Zyngier CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT; 208*4891f015SMarc Zyngier 209*4891f015SMarc Zyngier frame = &at->gt_block->frame[i]; 210*4891f015SMarc Zyngier if (!frame->valid) 211*4891f015SMarc Zyngier continue; 212*4891f015SMarc Zyngier 213*4891f015SMarc Zyngier /* Try enabling everything, and see what sticks */ 214*4891f015SMarc Zyngier writel_relaxed(cntacr, cntctlbase + CNTACR(i)); 215*4891f015SMarc Zyngier cntacr = readl_relaxed(cntctlbase + CNTACR(i)); 216*4891f015SMarc Zyngier 217*4891f015SMarc Zyngier /* Pick a suitable frame for which we have an IRQ */ 218*4891f015SMarc Zyngier if ((cnttidr & CNTTIDR_VIRT(i)) && 219*4891f015SMarc Zyngier !(~cntacr & (CNTACR_RWVT | CNTACR_RVCT)) && 220*4891f015SMarc Zyngier frame->virt_irq) { 221*4891f015SMarc Zyngier best_frame = frame; 222*4891f015SMarc Zyngier at->access = VIRT_ACCESS; 223*4891f015SMarc Zyngier break; 224*4891f015SMarc Zyngier } 225*4891f015SMarc Zyngier 226*4891f015SMarc Zyngier if ((~cntacr & (CNTACR_RWPT | CNTACR_RPCT)) || 227*4891f015SMarc Zyngier !frame->phys_irq) 228*4891f015SMarc Zyngier continue; 229*4891f015SMarc Zyngier 230*4891f015SMarc Zyngier at->access = PHYS_ACCESS; 231*4891f015SMarc Zyngier best_frame = frame; 232*4891f015SMarc Zyngier } 233*4891f015SMarc Zyngier 234*4891f015SMarc Zyngier iounmap(cntctlbase); 235*4891f015SMarc Zyngier 236*4891f015SMarc Zyngier return best_frame; 237*4891f015SMarc Zyngier } 238*4891f015SMarc Zyngier 239*4891f015SMarc Zyngier static void arch_timer_mmio_setup(struct arch_timer *at, int irq) 240*4891f015SMarc Zyngier { 241*4891f015SMarc Zyngier at->evt = (struct clock_event_device) { 242*4891f015SMarc Zyngier .features = (CLOCK_EVT_FEAT_ONESHOT | 243*4891f015SMarc Zyngier CLOCK_EVT_FEAT_DYNIRQ), 244*4891f015SMarc Zyngier .name = "arch_mem_timer", 245*4891f015SMarc Zyngier .rating = 400, 246*4891f015SMarc Zyngier .cpumask = cpu_possible_mask, 247*4891f015SMarc Zyngier .irq = irq, 248*4891f015SMarc Zyngier .set_next_event = arch_timer_mmio_set_next_event, 249*4891f015SMarc Zyngier .set_state_oneshot_stopped = arch_timer_mmio_shutdown, 250*4891f015SMarc Zyngier .set_state_shutdown = arch_timer_mmio_shutdown, 251*4891f015SMarc Zyngier }; 252*4891f015SMarc Zyngier 253*4891f015SMarc Zyngier at->evt.set_state_shutdown(&at->evt); 254*4891f015SMarc Zyngier 255*4891f015SMarc Zyngier clockevents_config_and_register(&at->evt, at->rate, 0xf, 256*4891f015SMarc Zyngier (unsigned long)CLOCKSOURCE_MASK(56)); 257*4891f015SMarc Zyngier 258*4891f015SMarc Zyngier enable_irq(at->evt.irq); 259*4891f015SMarc Zyngier } 260*4891f015SMarc Zyngier 261*4891f015SMarc Zyngier static int arch_timer_mmio_frame_register(struct platform_device *pdev, 262*4891f015SMarc Zyngier struct arch_timer_mem_frame *frame) 263*4891f015SMarc Zyngier { 264*4891f015SMarc Zyngier struct arch_timer *at = platform_get_drvdata(pdev); 265*4891f015SMarc Zyngier struct device_node *np = pdev->dev.of_node; 266*4891f015SMarc Zyngier int ret, irq; 267*4891f015SMarc Zyngier u32 rate; 268*4891f015SMarc Zyngier 269*4891f015SMarc Zyngier if (!devm_request_mem_region(&pdev->dev, frame->cntbase, frame->size, 270*4891f015SMarc Zyngier "arch_mem_timer")) 271*4891f015SMarc Zyngier return -EBUSY; 272*4891f015SMarc Zyngier 273*4891f015SMarc Zyngier at->base = devm_ioremap(&pdev->dev, frame->cntbase, frame->size); 274*4891f015SMarc Zyngier if (!at->base) { 275*4891f015SMarc Zyngier dev_err(&pdev->dev, "Can't map frame's registers\n"); 276*4891f015SMarc Zyngier return -ENXIO; 277*4891f015SMarc Zyngier } 278*4891f015SMarc Zyngier 279*4891f015SMarc Zyngier /* 280*4891f015SMarc Zyngier * Allow "clock-frequency" to override the probed rate. If neither 281*4891f015SMarc Zyngier * lead to something useful, use the CPU timer frequency as the 282*4891f015SMarc Zyngier * fallback. The nice thing about that last point is that we woudn't 283*4891f015SMarc Zyngier * made it here if we didn't have a valid frequency. 284*4891f015SMarc Zyngier */ 285*4891f015SMarc Zyngier rate = readl_relaxed(at->base + CNTFRQ); 286*4891f015SMarc Zyngier 287*4891f015SMarc Zyngier if (!np || of_property_read_u32(np, "clock-frequency", &at->rate)) 288*4891f015SMarc Zyngier at->rate = rate; 289*4891f015SMarc Zyngier 290*4891f015SMarc Zyngier if (!at->rate) 291*4891f015SMarc Zyngier at->rate = arch_timer_get_rate(); 292*4891f015SMarc Zyngier 293*4891f015SMarc Zyngier irq = at->access == VIRT_ACCESS ? frame->virt_irq : frame->phys_irq; 294*4891f015SMarc Zyngier ret = devm_request_irq(&pdev->dev, irq, arch_timer_mmio_handler, 295*4891f015SMarc Zyngier IRQF_TIMER | IRQF_NO_AUTOEN, "arch_mem_timer", 296*4891f015SMarc Zyngier &at->evt); 297*4891f015SMarc Zyngier if (ret) { 298*4891f015SMarc Zyngier dev_err(&pdev->dev, "Failed to request mem timer irq\n"); 299*4891f015SMarc Zyngier return ret; 300*4891f015SMarc Zyngier } 301*4891f015SMarc Zyngier 302*4891f015SMarc Zyngier /* Afer this point, we're not allowed to fail anymore */ 303*4891f015SMarc Zyngier arch_timer_mmio_setup(at, irq); 304*4891f015SMarc Zyngier return 0; 305*4891f015SMarc Zyngier } 306*4891f015SMarc Zyngier 307*4891f015SMarc Zyngier static int of_populate_gt_block(struct platform_device *pdev, 308*4891f015SMarc Zyngier struct arch_timer *at) 309*4891f015SMarc Zyngier { 310*4891f015SMarc Zyngier struct resource res; 311*4891f015SMarc Zyngier 312*4891f015SMarc Zyngier if (of_address_to_resource(pdev->dev.of_node, 0, &res)) 313*4891f015SMarc Zyngier return -EINVAL; 314*4891f015SMarc Zyngier 315*4891f015SMarc Zyngier at->gt_block->cntctlbase = res.start; 316*4891f015SMarc Zyngier at->gt_block->size = resource_size(&res); 317*4891f015SMarc Zyngier 318*4891f015SMarc Zyngier for_each_available_child_of_node_scoped(pdev->dev.of_node, frame_node) { 319*4891f015SMarc Zyngier struct arch_timer_mem_frame *frame; 320*4891f015SMarc Zyngier u32 n; 321*4891f015SMarc Zyngier 322*4891f015SMarc Zyngier if (of_property_read_u32(frame_node, "frame-number", &n)) { 323*4891f015SMarc Zyngier dev_err(&pdev->dev, FW_BUG "Missing frame-number\n"); 324*4891f015SMarc Zyngier return -EINVAL; 325*4891f015SMarc Zyngier } 326*4891f015SMarc Zyngier if (n >= ARCH_TIMER_MEM_MAX_FRAMES) { 327*4891f015SMarc Zyngier dev_err(&pdev->dev, 328*4891f015SMarc Zyngier FW_BUG "Wrong frame-number, only 0-%u are permitted\n", 329*4891f015SMarc Zyngier ARCH_TIMER_MEM_MAX_FRAMES - 1); 330*4891f015SMarc Zyngier return -EINVAL; 331*4891f015SMarc Zyngier } 332*4891f015SMarc Zyngier 333*4891f015SMarc Zyngier frame = &at->gt_block->frame[n]; 334*4891f015SMarc Zyngier 335*4891f015SMarc Zyngier if (frame->valid) { 336*4891f015SMarc Zyngier dev_err(&pdev->dev, FW_BUG "Duplicated frame-number\n"); 337*4891f015SMarc Zyngier return -EINVAL; 338*4891f015SMarc Zyngier } 339*4891f015SMarc Zyngier 340*4891f015SMarc Zyngier if (of_address_to_resource(frame_node, 0, &res)) 341*4891f015SMarc Zyngier return -EINVAL; 342*4891f015SMarc Zyngier 343*4891f015SMarc Zyngier frame->cntbase = res.start; 344*4891f015SMarc Zyngier frame->size = resource_size(&res); 345*4891f015SMarc Zyngier 346*4891f015SMarc Zyngier frame->phys_irq = irq_of_parse_and_map(frame_node, 0); 347*4891f015SMarc Zyngier frame->virt_irq = irq_of_parse_and_map(frame_node, 1); 348*4891f015SMarc Zyngier 349*4891f015SMarc Zyngier frame->valid = true; 350*4891f015SMarc Zyngier } 351*4891f015SMarc Zyngier 352*4891f015SMarc Zyngier return 0; 353*4891f015SMarc Zyngier } 354*4891f015SMarc Zyngier 355*4891f015SMarc Zyngier static int arch_timer_mmio_probe(struct platform_device *pdev) 356*4891f015SMarc Zyngier { 357*4891f015SMarc Zyngier struct arch_timer_mem_frame *frame; 358*4891f015SMarc Zyngier struct arch_timer *at; 359*4891f015SMarc Zyngier struct device_node *np; 360*4891f015SMarc Zyngier int ret; 361*4891f015SMarc Zyngier 362*4891f015SMarc Zyngier np = pdev->dev.of_node; 363*4891f015SMarc Zyngier 364*4891f015SMarc Zyngier at = devm_kmalloc(&pdev->dev, sizeof(*at), GFP_KERNEL | __GFP_ZERO); 365*4891f015SMarc Zyngier if (!at) 366*4891f015SMarc Zyngier return -ENOMEM; 367*4891f015SMarc Zyngier 368*4891f015SMarc Zyngier if (np) { 369*4891f015SMarc Zyngier at->gt_block = devm_kmalloc(&pdev->dev, sizeof(*at->gt_block), 370*4891f015SMarc Zyngier GFP_KERNEL | __GFP_ZERO); 371*4891f015SMarc Zyngier if (!at->gt_block) 372*4891f015SMarc Zyngier return -ENOMEM; 373*4891f015SMarc Zyngier ret = of_populate_gt_block(pdev, at); 374*4891f015SMarc Zyngier if (ret) 375*4891f015SMarc Zyngier return ret; 376*4891f015SMarc Zyngier } else { 377*4891f015SMarc Zyngier at->gt_block = dev_get_platdata(&pdev->dev); 378*4891f015SMarc Zyngier } 379*4891f015SMarc Zyngier 380*4891f015SMarc Zyngier platform_set_drvdata(pdev, at); 381*4891f015SMarc Zyngier 382*4891f015SMarc Zyngier frame = find_best_frame(pdev); 383*4891f015SMarc Zyngier if (!frame) { 384*4891f015SMarc Zyngier dev_err(&pdev->dev, 385*4891f015SMarc Zyngier "Unable to find a suitable frame in timer @ %pa\n", 386*4891f015SMarc Zyngier &at->gt_block->cntctlbase); 387*4891f015SMarc Zyngier return -EINVAL; 388*4891f015SMarc Zyngier } 389*4891f015SMarc Zyngier 390*4891f015SMarc Zyngier ret = arch_timer_mmio_frame_register(pdev, frame); 391*4891f015SMarc Zyngier if (!ret) 392*4891f015SMarc Zyngier dev_info(&pdev->dev, 393*4891f015SMarc Zyngier "mmio timer running at %lu.%02luMHz (%s)\n", 394*4891f015SMarc Zyngier (unsigned long)at->rate / 1000000, 395*4891f015SMarc Zyngier (unsigned long)(at->rate / 10000) % 100, 396*4891f015SMarc Zyngier at->access == VIRT_ACCESS ? "virt" : "phys"); 397*4891f015SMarc Zyngier 398*4891f015SMarc Zyngier return ret; 399*4891f015SMarc Zyngier } 400*4891f015SMarc Zyngier 401*4891f015SMarc Zyngier static const struct of_device_id arch_timer_mmio_of_table[] = { 402*4891f015SMarc Zyngier { .compatible = "arm,armv7-timer-mem", }, 403*4891f015SMarc Zyngier {} 404*4891f015SMarc Zyngier }; 405*4891f015SMarc Zyngier 406*4891f015SMarc Zyngier static struct platform_driver arch_timer_mmio_drv = { 407*4891f015SMarc Zyngier .driver = { 408*4891f015SMarc Zyngier .name = "arch-timer-mmio", 409*4891f015SMarc Zyngier .of_match_table = arch_timer_mmio_of_table, 410*4891f015SMarc Zyngier }, 411*4891f015SMarc Zyngier .probe = arch_timer_mmio_probe, 412*4891f015SMarc Zyngier }; 413*4891f015SMarc Zyngier builtin_platform_driver(arch_timer_mmio_drv); 414*4891f015SMarc Zyngier 415*4891f015SMarc Zyngier static struct platform_driver arch_timer_mmio_acpi_drv = { 416*4891f015SMarc Zyngier .driver = { 417*4891f015SMarc Zyngier .name = "gtdt-arm-mmio-timer", 418*4891f015SMarc Zyngier }, 419*4891f015SMarc Zyngier .probe = arch_timer_mmio_probe, 420*4891f015SMarc Zyngier }; 421*4891f015SMarc Zyngier builtin_platform_driver(arch_timer_mmio_acpi_drv); 422