hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/pwm/pwm-lpss.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Intel Low Power Subsystem PWM controller driver
34 *
....@@ -7,10 +8,6 @@
78 * Author: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
89 * Author: Chew Chiau Ee <chiau.ee.chew@intel.com>
910 * Author: Alan Cox <alan@linux.intel.com>
10
- *
11
- * This program is free software; you can redistribute it and/or modify
12
- * it under the terms of the GNU General Public License version 2 as
13
- * published by the Free Software Foundation.
1411 */
1512
1613 #include <linux/delay.h>
....@@ -31,15 +28,6 @@
3128
3229 /* Size of each PWM register space if multiple */
3330 #define PWM_SIZE 0x400
34
-
35
-#define MAX_PWMS 4
36
-
37
-struct pwm_lpss_chip {
38
- struct pwm_chip chip;
39
- void __iomem *regs;
40
- const struct pwm_lpss_boardinfo *info;
41
- u32 saved_ctrl[MAX_PWMS];
42
-};
4331
4432 static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
4533 {
....@@ -97,7 +85,7 @@
9785 unsigned long long on_time_div;
9886 unsigned long c = lpwm->info->clk_rate, base_unit_range;
9987 unsigned long long base_unit, freq = NSEC_PER_SEC;
100
- u32 orig_ctrl, ctrl;
88
+ u32 ctrl;
10189
10290 do_div(freq, period_ns);
10391
....@@ -116,16 +104,14 @@
116104 do_div(on_time_div, period_ns);
117105 on_time_div = 255ULL - on_time_div;
118106
119
- orig_ctrl = ctrl = pwm_lpss_read(pwm);
107
+ ctrl = pwm_lpss_read(pwm);
120108 ctrl &= ~PWM_ON_TIME_DIV_MASK;
121109 ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT);
122110 ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
123111 ctrl |= on_time_div;
124112
125
- if (orig_ctrl != ctrl) {
126
- pwm_lpss_write(pwm, ctrl);
127
- pwm_lpss_write(pwm, ctrl | PWM_SW_UPDATE);
128
- }
113
+ pwm_lpss_write(pwm, ctrl);
114
+ pwm_lpss_write(pwm, ctrl | PWM_SW_UPDATE);
129115 }
130116
131117 static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond)
....@@ -134,45 +120,85 @@
134120 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
135121 }
136122
123
+static int pwm_lpss_prepare_enable(struct pwm_lpss_chip *lpwm,
124
+ struct pwm_device *pwm,
125
+ const struct pwm_state *state)
126
+{
127
+ int ret;
128
+
129
+ ret = pwm_lpss_is_updating(pwm);
130
+ if (ret)
131
+ return ret;
132
+
133
+ pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
134
+ pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false);
135
+ ret = pwm_lpss_wait_for_update(pwm);
136
+ if (ret)
137
+ return ret;
138
+
139
+ pwm_lpss_cond_enable(pwm, lpwm->info->bypass == true);
140
+ return 0;
141
+}
142
+
137143 static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
138
- struct pwm_state *state)
144
+ const struct pwm_state *state)
139145 {
140146 struct pwm_lpss_chip *lpwm = to_lpwm(chip);
141
- int ret;
147
+ int ret = 0;
142148
143149 if (state->enabled) {
144150 if (!pwm_is_enabled(pwm)) {
145151 pm_runtime_get_sync(chip->dev);
146
- ret = pwm_lpss_is_updating(pwm);
147
- if (ret) {
148
- pm_runtime_put(chip->dev);
149
- return ret;
150
- }
151
- pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
152
- pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false);
153
- ret = pwm_lpss_wait_for_update(pwm);
154
- if (ret) {
155
- pm_runtime_put(chip->dev);
156
- return ret;
157
- }
158
- pwm_lpss_cond_enable(pwm, lpwm->info->bypass == true);
159
- } else {
160
- ret = pwm_lpss_is_updating(pwm);
152
+ ret = pwm_lpss_prepare_enable(lpwm, pwm, state);
161153 if (ret)
162
- return ret;
163
- pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
164
- return pwm_lpss_wait_for_update(pwm);
154
+ pm_runtime_put(chip->dev);
155
+ } else {
156
+ ret = pwm_lpss_prepare_enable(lpwm, pwm, state);
165157 }
166158 } else if (pwm_is_enabled(pwm)) {
167159 pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
168160 pm_runtime_put(chip->dev);
169161 }
170162
171
- return 0;
163
+ return ret;
164
+}
165
+
166
+static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
167
+ struct pwm_state *state)
168
+{
169
+ struct pwm_lpss_chip *lpwm = to_lpwm(chip);
170
+ unsigned long base_unit_range;
171
+ unsigned long long base_unit, freq, on_time_div;
172
+ u32 ctrl;
173
+
174
+ pm_runtime_get_sync(chip->dev);
175
+
176
+ base_unit_range = BIT(lpwm->info->base_unit_bits);
177
+
178
+ ctrl = pwm_lpss_read(pwm);
179
+ on_time_div = 255 - (ctrl & PWM_ON_TIME_DIV_MASK);
180
+ base_unit = (ctrl >> PWM_BASE_UNIT_SHIFT) & (base_unit_range - 1);
181
+
182
+ freq = base_unit * lpwm->info->clk_rate;
183
+ do_div(freq, base_unit_range);
184
+ if (freq == 0)
185
+ state->period = NSEC_PER_SEC;
186
+ else
187
+ state->period = NSEC_PER_SEC / (unsigned long)freq;
188
+
189
+ on_time_div *= state->period;
190
+ do_div(on_time_div, 255);
191
+ state->duty_cycle = on_time_div;
192
+
193
+ state->polarity = PWM_POLARITY_NORMAL;
194
+ state->enabled = !!(ctrl & PWM_ENABLE);
195
+
196
+ pm_runtime_put(chip->dev);
172197 }
173198
174199 static const struct pwm_ops pwm_lpss_ops = {
175200 .apply = pwm_lpss_apply,
201
+ .get_state = pwm_lpss_get_state,
176202 .owner = THIS_MODULE,
177203 };
178204
....@@ -181,7 +207,8 @@
181207 {
182208 struct pwm_lpss_chip *lpwm;
183209 unsigned long c;
184
- int ret;
210
+ int i, ret;
211
+ u32 ctrl;
185212
186213 if (WARN_ON(info->npwm > MAX_PWMS))
187214 return ERR_PTR(-ENODEV);
....@@ -211,6 +238,12 @@
211238 return ERR_PTR(ret);
212239 }
213240
241
+ for (i = 0; i < lpwm->info->npwm; i++) {
242
+ ctrl = pwm_lpss_read(&lpwm->chip.pwms[i]);
243
+ if (ctrl & PWM_ENABLE)
244
+ pm_runtime_get(dev);
245
+ }
246
+
214247 return lpwm;
215248 }
216249 EXPORT_SYMBOL_GPL(pwm_lpss_probe);
....@@ -226,30 +259,6 @@
226259 return pwmchip_remove(&lpwm->chip);
227260 }
228261 EXPORT_SYMBOL_GPL(pwm_lpss_remove);
229
-
230
-int pwm_lpss_suspend(struct device *dev)
231
-{
232
- struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);
233
- int i;
234
-
235
- for (i = 0; i < lpwm->info->npwm; i++)
236
- lpwm->saved_ctrl[i] = readl(lpwm->regs + i * PWM_SIZE + PWM);
237
-
238
- return 0;
239
-}
240
-EXPORT_SYMBOL_GPL(pwm_lpss_suspend);
241
-
242
-int pwm_lpss_resume(struct device *dev)
243
-{
244
- struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);
245
- int i;
246
-
247
- for (i = 0; i < lpwm->info->npwm; i++)
248
- writel(lpwm->saved_ctrl[i], lpwm->regs + i * PWM_SIZE + PWM);
249
-
250
- return 0;
251
-}
252
-EXPORT_SYMBOL_GPL(pwm_lpss_resume);
253262
254263 MODULE_DESCRIPTION("PWM driver for Intel LPSS");
255264 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");