| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Cirrus Logic CLPS711X clocksource driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 31 | 27 | return ~readw(tcd); |
|---|
| 32 | 28 | } |
|---|
| 33 | 29 | |
|---|
| 34 | | -static int __init _clps711x_clksrc_init(struct clk *clock, void __iomem *base) |
|---|
| 30 | +static void __init clps711x_clksrc_init(struct clk *clock, void __iomem *base) |
|---|
| 35 | 31 | { |
|---|
| 36 | | - unsigned long rate; |
|---|
| 37 | | - |
|---|
| 38 | | - if (!base) |
|---|
| 39 | | - return -ENOMEM; |
|---|
| 40 | | - if (IS_ERR(clock)) |
|---|
| 41 | | - return PTR_ERR(clock); |
|---|
| 42 | | - |
|---|
| 43 | | - rate = clk_get_rate(clock); |
|---|
| 32 | + unsigned long rate = clk_get_rate(clock); |
|---|
| 44 | 33 | |
|---|
| 45 | 34 | tcd = base; |
|---|
| 46 | 35 | |
|---|
| .. | .. |
|---|
| 48 | 37 | clocksource_mmio_readw_down); |
|---|
| 49 | 38 | |
|---|
| 50 | 39 | sched_clock_register(clps711x_sched_clock_read, 16, rate); |
|---|
| 51 | | - |
|---|
| 52 | | - return 0; |
|---|
| 53 | 40 | } |
|---|
| 54 | 41 | |
|---|
| 55 | 42 | static irqreturn_t clps711x_timer_interrupt(int irq, void *dev_id) |
|---|
| .. | .. |
|---|
| 66 | 53 | { |
|---|
| 67 | 54 | struct clock_event_device *clkevt; |
|---|
| 68 | 55 | unsigned long rate; |
|---|
| 69 | | - |
|---|
| 70 | | - if (!irq) |
|---|
| 71 | | - return -EINVAL; |
|---|
| 72 | | - if (!base) |
|---|
| 73 | | - return -ENOMEM; |
|---|
| 74 | | - if (IS_ERR(clock)) |
|---|
| 75 | | - return PTR_ERR(clock); |
|---|
| 76 | 56 | |
|---|
| 77 | 57 | clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL); |
|---|
| 78 | 58 | if (!clkevt) |
|---|
| .. | .. |
|---|
| 93 | 73 | "clps711x-timer", clkevt); |
|---|
| 94 | 74 | } |
|---|
| 95 | 75 | |
|---|
| 96 | | -void __init clps711x_clksrc_init(void __iomem *tc1_base, void __iomem *tc2_base, |
|---|
| 97 | | - unsigned int irq) |
|---|
| 98 | | -{ |
|---|
| 99 | | - struct clk *tc1 = clk_get_sys("clps711x-timer.0", NULL); |
|---|
| 100 | | - struct clk *tc2 = clk_get_sys("clps711x-timer.1", NULL); |
|---|
| 101 | | - |
|---|
| 102 | | - BUG_ON(_clps711x_clksrc_init(tc1, tc1_base)); |
|---|
| 103 | | - BUG_ON(_clps711x_clkevt_init(tc2, tc2_base, irq)); |
|---|
| 104 | | -} |
|---|
| 105 | | - |
|---|
| 106 | | -#ifdef CONFIG_TIMER_OF |
|---|
| 107 | 76 | static int __init clps711x_timer_init(struct device_node *np) |
|---|
| 108 | 77 | { |
|---|
| 109 | 78 | unsigned int irq = irq_of_parse_and_map(np, 0); |
|---|
| 110 | 79 | struct clk *clock = of_clk_get(np, 0); |
|---|
| 111 | 80 | void __iomem *base = of_iomap(np, 0); |
|---|
| 112 | 81 | |
|---|
| 82 | + if (!base) |
|---|
| 83 | + return -ENOMEM; |
|---|
| 84 | + if (!irq) |
|---|
| 85 | + return -EINVAL; |
|---|
| 86 | + if (IS_ERR(clock)) |
|---|
| 87 | + return PTR_ERR(clock); |
|---|
| 88 | + |
|---|
| 113 | 89 | switch (of_alias_get_id(np, "timer")) { |
|---|
| 114 | 90 | case CLPS711X_CLKSRC_CLOCKSOURCE: |
|---|
| 115 | | - return _clps711x_clksrc_init(clock, base); |
|---|
| 91 | + clps711x_clksrc_init(clock, base); |
|---|
| 92 | + break; |
|---|
| 116 | 93 | case CLPS711X_CLKSRC_CLOCKEVENT: |
|---|
| 117 | 94 | return _clps711x_clkevt_init(clock, base, irq); |
|---|
| 118 | 95 | default: |
|---|
| 119 | 96 | return -EINVAL; |
|---|
| 120 | 97 | } |
|---|
| 98 | + |
|---|
| 99 | + return 0; |
|---|
| 121 | 100 | } |
|---|
| 122 | 101 | TIMER_OF_DECLARE(clps711x, "cirrus,ep7209-timer", clps711x_timer_init); |
|---|
| 123 | | -#endif |
|---|