.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2014 Philipp Zabel, Pengutronix |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | * |
---|
8 | 5 | * PWM (mis)used as clock output |
---|
9 | 6 | */ |
---|
.. | .. |
---|
47 | 44 | return clk_pwm->fixed_rate; |
---|
48 | 45 | } |
---|
49 | 46 | |
---|
| 47 | +static int clk_pwm_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) |
---|
| 48 | +{ |
---|
| 49 | + struct clk_pwm *clk_pwm = to_clk_pwm(hw); |
---|
| 50 | + struct pwm_state state; |
---|
| 51 | + |
---|
| 52 | + pwm_get_state(clk_pwm->pwm, &state); |
---|
| 53 | + |
---|
| 54 | + duty->num = state.duty_cycle; |
---|
| 55 | + duty->den = state.period; |
---|
| 56 | + |
---|
| 57 | + return 0; |
---|
| 58 | +} |
---|
| 59 | + |
---|
50 | 60 | static const struct clk_ops clk_pwm_ops = { |
---|
51 | 61 | .prepare = clk_pwm_prepare, |
---|
52 | 62 | .unprepare = clk_pwm_unprepare, |
---|
53 | 63 | .recalc_rate = clk_pwm_recalc_rate, |
---|
| 64 | + .get_duty_cycle = clk_pwm_get_duty_cycle, |
---|
54 | 65 | }; |
---|
55 | 66 | |
---|
56 | 67 | static int clk_pwm_probe(struct platform_device *pdev) |
---|
57 | 68 | { |
---|
58 | 69 | struct device_node *node = pdev->dev.of_node; |
---|
59 | | - struct clk_init_data init = {}; |
---|
| 70 | + struct clk_init_data init; |
---|
60 | 71 | struct clk_pwm *clk_pwm; |
---|
61 | 72 | struct pwm_device *pwm; |
---|
62 | 73 | struct pwm_args pargs; |
---|
.. | .. |
---|
80 | 91 | if (of_property_read_u32(node, "clock-frequency", &clk_pwm->fixed_rate)) |
---|
81 | 92 | clk_pwm->fixed_rate = div64_u64(NSEC_PER_SEC, pargs.period); |
---|
82 | 93 | |
---|
| 94 | + if (!clk_pwm->fixed_rate) { |
---|
| 95 | + dev_err(&pdev->dev, "fixed_rate cannot be zero\n"); |
---|
| 96 | + return -EINVAL; |
---|
| 97 | + } |
---|
| 98 | + |
---|
83 | 99 | if (pargs.period != NSEC_PER_SEC / clk_pwm->fixed_rate && |
---|
84 | 100 | pargs.period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) { |
---|
85 | 101 | dev_err(&pdev->dev, |
---|
.. | .. |
---|
101 | 117 | |
---|
102 | 118 | init.name = clk_name; |
---|
103 | 119 | init.ops = &clk_pwm_ops; |
---|
104 | | - init.flags = CLK_IS_BASIC; |
---|
| 120 | + init.flags = 0; |
---|
105 | 121 | init.num_parents = 0; |
---|
106 | 122 | |
---|
107 | 123 | clk_pwm->pwm = pwm; |
---|