@@ -28,6 +28,7 @@ struct bcm2835_pwm {
28
28
struct device * dev ;
29
29
void __iomem * base ;
30
30
struct clk * clk ;
31
+ unsigned long rate ;
31
32
};
32
33
33
34
static inline struct bcm2835_pwm * to_bcm2835_pwm (struct pwm_chip * chip )
@@ -63,17 +64,11 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
63
64
{
64
65
65
66
struct bcm2835_pwm * pc = to_bcm2835_pwm (chip );
66
- unsigned long rate = clk_get_rate (pc -> clk );
67
67
unsigned long long period_cycles ;
68
68
u64 max_period ;
69
69
70
70
u32 val ;
71
71
72
- if (!rate ) {
73
- dev_err (pc -> dev , "failed to get clock rate\n" );
74
- return - EINVAL ;
75
- }
76
-
77
72
/*
78
73
* period_cycles must be a 32 bit value, so period * rate / NSEC_PER_SEC
79
74
* must be <= U32_MAX. As U32_MAX * NSEC_PER_SEC < U64_MAX the
@@ -88,13 +83,13 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
88
83
* <=> period < ((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate
89
84
* <=> period <= ceil((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate) - 1
90
85
*/
91
- max_period = DIV_ROUND_UP_ULL ((u64 )U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC / 2 , rate ) - 1 ;
86
+ max_period = DIV_ROUND_UP_ULL ((u64 )U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC / 2 , pc -> rate ) - 1 ;
92
87
93
88
if (state -> period > max_period )
94
89
return - EINVAL ;
95
90
96
91
/* set period */
97
- period_cycles = DIV_ROUND_CLOSEST_ULL (state -> period * rate , NSEC_PER_SEC );
92
+ period_cycles = DIV_ROUND_CLOSEST_ULL (state -> period * pc -> rate , NSEC_PER_SEC );
98
93
99
94
/* don't accept a period that is too small */
100
95
if (period_cycles < PERIOD_MIN )
@@ -103,7 +98,7 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
103
98
writel (period_cycles , pc -> base + PERIOD (pwm -> hwpwm ));
104
99
105
100
/* set duty cycle */
106
- val = DIV_ROUND_CLOSEST_ULL (state -> duty_cycle * rate , NSEC_PER_SEC );
101
+ val = DIV_ROUND_CLOSEST_ULL (state -> duty_cycle * pc -> rate , NSEC_PER_SEC );
107
102
writel (val , pc -> base + DUTY (pwm -> hwpwm ));
108
103
109
104
/* set polarity */
@@ -131,6 +126,13 @@ static const struct pwm_ops bcm2835_pwm_ops = {
131
126
.apply = bcm2835_pwm_apply ,
132
127
};
133
128
129
+ static void devm_clk_rate_exclusive_put (void * data )
130
+ {
131
+ struct clk * clk = data ;
132
+
133
+ clk_rate_exclusive_put (clk );
134
+ }
135
+
134
136
static int bcm2835_pwm_probe (struct platform_device * pdev )
135
137
{
136
138
struct bcm2835_pwm * pc ;
@@ -151,8 +153,26 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
151
153
return dev_err_probe (& pdev -> dev , PTR_ERR (pc -> clk ),
152
154
"clock not found\n" );
153
155
156
+ ret = clk_rate_exclusive_get (pc -> clk );
157
+ if (ret )
158
+ return dev_err_probe (& pdev -> dev , ret ,
159
+ "fail to get exclusive rate\n" );
160
+
161
+ ret = devm_add_action_or_reset (& pdev -> dev , devm_clk_rate_exclusive_put ,
162
+ pc -> clk );
163
+ if (ret ) {
164
+ clk_rate_exclusive_put (pc -> clk );
165
+ return ret ;
166
+ }
167
+
168
+ pc -> rate = clk_get_rate (pc -> clk );
169
+ if (!pc -> rate )
170
+ return dev_err_probe (& pdev -> dev , - EINVAL ,
171
+ "failed to get clock rate\n" );
172
+
154
173
pc -> chip .dev = & pdev -> dev ;
155
174
pc -> chip .ops = & bcm2835_pwm_ops ;
175
+ pc -> chip .atomic = true;
156
176
pc -> chip .npwm = 2 ;
157
177
158
178
platform_set_drvdata (pdev , pc );
0 commit comments