diff options
| -rw-r--r-- | Documentation/devicetree/bindings/rtc/dw-apb.txt | 19 | ||||
| -rw-r--r-- | drivers/clocksource/dw_apb_timer_of.c | 26 |
2 files changed, 44 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/rtc/dw-apb.txt b/Documentation/devicetree/bindings/rtc/dw-apb.txt index 93e2b0f048e6..eb2327b2bdb3 100644 --- a/Documentation/devicetree/bindings/rtc/dw-apb.txt +++ b/Documentation/devicetree/bindings/rtc/dw-apb.txt | |||
| @@ -5,9 +5,20 @@ Required properties: | |||
| 5 | - reg: physical base address of the controller and length of memory mapped | 5 | - reg: physical base address of the controller and length of memory mapped |
| 6 | region. | 6 | region. |
| 7 | - interrupts: IRQ line for the timer. | 7 | - interrupts: IRQ line for the timer. |
| 8 | - either clocks+clock-names or clock-frequency properties | ||
| 9 | |||
| 10 | Optional properties: | ||
| 11 | - clocks : list of clock specifiers, corresponding to entries in | ||
| 12 | the clock-names property; | ||
| 13 | - clock-names : should contain "timer" and "pclk" entries, matching entries | ||
| 14 | in the clocks property. | ||
| 8 | - clock-frequency: The frequency in HZ of the timer. | 15 | - clock-frequency: The frequency in HZ of the timer. |
| 9 | - clock-freq: For backwards compatibility with picoxcell | 16 | - clock-freq: For backwards compatibility with picoxcell |
| 10 | 17 | ||
| 18 | If using the clock specifiers, the pclk clock is optional, as not all | ||
| 19 | systems may use one. | ||
| 20 | |||
| 21 | |||
| 11 | Example: | 22 | Example: |
| 12 | 23 | ||
| 13 | timer1: timer@ffc09000 { | 24 | timer1: timer@ffc09000 { |
| @@ -23,3 +34,11 @@ Example: | |||
| 23 | clock-frequency = <200000000>; | 34 | clock-frequency = <200000000>; |
| 24 | reg = <0xffd00000 0x1000>; | 35 | reg = <0xffd00000 0x1000>; |
| 25 | }; | 36 | }; |
| 37 | |||
| 38 | timer3: timer@ffe00000 { | ||
| 39 | compatible = "snps,dw-apb-timer-osc"; | ||
| 40 | interrupts = <0 170 4>; | ||
| 41 | reg = <0xffe00000 0x1000>; | ||
| 42 | clocks = <&timer_clk>, <&timer_pclk>; | ||
| 43 | clock-names = "timer", "pclk"; | ||
| 44 | }; | ||
diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c index d6c0fda76a7e..1964f8716966 100644 --- a/drivers/clocksource/dw_apb_timer_of.c +++ b/drivers/clocksource/dw_apb_timer_of.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
| 21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
| 22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
| 23 | #include <linux/clk.h> | ||
| 23 | 24 | ||
| 24 | #include <asm/mach/time.h> | 25 | #include <asm/mach/time.h> |
| 25 | #include <asm/sched_clock.h> | 26 | #include <asm/sched_clock.h> |
| @@ -27,14 +28,37 @@ | |||
| 27 | static void timer_get_base_and_rate(struct device_node *np, | 28 | static void timer_get_base_and_rate(struct device_node *np, |
| 28 | void __iomem **base, u32 *rate) | 29 | void __iomem **base, u32 *rate) |
| 29 | { | 30 | { |
| 31 | struct clk *timer_clk; | ||
| 32 | struct clk *pclk; | ||
| 33 | |||
| 30 | *base = of_iomap(np, 0); | 34 | *base = of_iomap(np, 0); |
| 31 | 35 | ||
| 32 | if (!*base) | 36 | if (!*base) |
| 33 | panic("Unable to map regs for %s", np->name); | 37 | panic("Unable to map regs for %s", np->name); |
| 34 | 38 | ||
| 39 | /* | ||
| 40 | * Not all implementations use a periphal clock, so don't panic | ||
| 41 | * if it's not present | ||
| 42 | */ | ||
| 43 | pclk = of_clk_get_by_name(np, "pclk"); | ||
| 44 | if (!IS_ERR(pclk)) | ||
| 45 | if (clk_prepare_enable(pclk)) | ||
| 46 | pr_warn("pclk for %s is present, but could not be activated\n", | ||
| 47 | np->name); | ||
| 48 | |||
| 49 | timer_clk = of_clk_get_by_name(np, "timer"); | ||
| 50 | if (IS_ERR(timer_clk)) | ||
| 51 | goto try_clock_freq; | ||
| 52 | |||
| 53 | if (!clk_prepare_enable(timer_clk)) { | ||
| 54 | *rate = clk_get_rate(timer_clk); | ||
| 55 | return; | ||
| 56 | } | ||
| 57 | |||
| 58 | try_clock_freq: | ||
| 35 | if (of_property_read_u32(np, "clock-freq", rate) && | 59 | if (of_property_read_u32(np, "clock-freq", rate) && |
| 36 | of_property_read_u32(np, "clock-frequency", rate)) | 60 | of_property_read_u32(np, "clock-frequency", rate)) |
| 37 | panic("No clock-frequency property for %s", np->name); | 61 | panic("No clock nor clock-frequency property for %s", np->name); |
| 38 | } | 62 | } |
| 39 | 63 | ||
| 40 | static void add_clockevent(struct device_node *event_timer) | 64 | static void add_clockevent(struct device_node *event_timer) |
