hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/pwm/sysfs.c
....@@ -1,19 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * A simple sysfs interface for the generic PWM framework
34 *
45 * Copyright (C) 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
56 *
67 * Based on previous work by Lars Poeschel <poeschel@lemonage.de>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2, or (at your option)
11
- * any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
178 */
189
1910 #include <linux/device.h>
....@@ -27,6 +18,7 @@
2718 struct device child;
2819 struct pwm_device *pwm;
2920 struct mutex lock;
21
+ struct pwm_state suspend;
3022 };
3123
3224 static struct pwm_export *child_to_pwm_export(struct device *child)
....@@ -60,10 +52,10 @@
6052 struct pwm_export *export = child_to_pwm_export(child);
6153 struct pwm_device *pwm = export->pwm;
6254 struct pwm_state state;
63
- unsigned int val;
55
+ u64 val;
6456 int ret;
6557
66
- ret = kstrtouint(buf, 0, &val);
58
+ ret = kstrtou64(buf, 0, &val);
6759 if (ret)
6860 return ret;
6961
....@@ -95,10 +87,10 @@
9587 struct pwm_export *export = child_to_pwm_export(child);
9688 struct pwm_device *pwm = export->pwm;
9789 struct pwm_state state;
98
- unsigned int val;
90
+ u64 val;
9991 int ret;
10092
101
- ret = kstrtouint(buf, 0, &val);
93
+ ret = kstrtou64(buf, 0, &val);
10294 if (ret)
10395 return ret;
10496
....@@ -141,6 +133,76 @@
141133 mutex_lock(&export->lock);
142134 pwm_get_state(pwm, &state);
143135 state.oneshot_count = val;
136
+ ret = pwm_apply_state(pwm, &state);
137
+ mutex_unlock(&export->lock);
138
+
139
+ return ret ? : size;
140
+}
141
+
142
+static ssize_t oneshot_repeat_show(struct device *child,
143
+ struct device_attribute *attr,
144
+ char *buf)
145
+{
146
+ const struct pwm_device *pwm = child_to_pwm_device(child);
147
+ struct pwm_state state;
148
+
149
+ pwm_get_state(pwm, &state);
150
+
151
+ return sprintf(buf, "%u\n", state.oneshot_repeat);
152
+}
153
+
154
+static ssize_t oneshot_repeat_store(struct device *child,
155
+ struct device_attribute *attr,
156
+ const char *buf, size_t size)
157
+{
158
+ struct pwm_export *export = child_to_pwm_export(child);
159
+ struct pwm_device *pwm = export->pwm;
160
+ struct pwm_state state;
161
+ unsigned int val;
162
+ int ret;
163
+
164
+ ret = kstrtouint(buf, 0, &val);
165
+ if (ret)
166
+ return ret;
167
+
168
+ mutex_lock(&export->lock);
169
+ pwm_get_state(pwm, &state);
170
+ state.oneshot_repeat = val;
171
+ ret = pwm_apply_state(pwm, &state);
172
+ mutex_unlock(&export->lock);
173
+
174
+ return ret ? : size;
175
+}
176
+
177
+static ssize_t duty_offset_show(struct device *child,
178
+ struct device_attribute *attr,
179
+ char *buf)
180
+{
181
+ const struct pwm_device *pwm = child_to_pwm_device(child);
182
+ struct pwm_state state;
183
+
184
+ pwm_get_state(pwm, &state);
185
+
186
+ return sprintf(buf, "%llu\n", state.duty_offset);
187
+}
188
+
189
+static ssize_t duty_offset_store(struct device *child,
190
+ struct device_attribute *attr,
191
+ const char *buf, size_t size)
192
+{
193
+ struct pwm_export *export = child_to_pwm_export(child);
194
+ struct pwm_device *pwm = export->pwm;
195
+ struct pwm_state state;
196
+ u64 val;
197
+ int ret;
198
+
199
+ ret = kstrtou64(buf, 0, &val);
200
+ if (ret)
201
+ return ret;
202
+
203
+ mutex_lock(&export->lock);
204
+ pwm_get_state(pwm, &state);
205
+ state.duty_offset = val;
144206 ret = pwm_apply_state(pwm, &state);
145207 mutex_unlock(&export->lock);
146208
....@@ -257,27 +319,56 @@
257319 if (ret)
258320 return ret;
259321
260
- return sprintf(buf, "%llu %llu\n", result.period, result.duty_cycle);
322
+ return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
323
+}
324
+
325
+static ssize_t output_type_show(struct device *child,
326
+ struct device_attribute *attr,
327
+ char *buf)
328
+{
329
+ const struct pwm_device *pwm = child_to_pwm_device(child);
330
+ const char *output_type = "unknown";
331
+ struct pwm_state state;
332
+
333
+ pwm_get_state(pwm, &state);
334
+ switch (state.output_type) {
335
+ case PWM_OUTPUT_FIXED:
336
+ output_type = "fixed";
337
+ break;
338
+ case PWM_OUTPUT_MODULATED:
339
+ output_type = "modulated";
340
+ break;
341
+ default:
342
+ break;
343
+ }
344
+
345
+ return snprintf(buf, PAGE_SIZE, "%s\n", output_type);
261346 }
262347
263348 static DEVICE_ATTR_RW(period);
264349 static DEVICE_ATTR_RW(duty_cycle);
265350 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
266351 static DEVICE_ATTR_RW(oneshot_count);
352
+static DEVICE_ATTR_RW(oneshot_repeat);
353
+static DEVICE_ATTR_RW(duty_offset);
267354 #endif
268355 static DEVICE_ATTR_RW(enable);
269356 static DEVICE_ATTR_RW(polarity);
270357 static DEVICE_ATTR_RO(capture);
358
+static DEVICE_ATTR_RO(output_type);
271359
272360 static struct attribute *pwm_attrs[] = {
273361 &dev_attr_period.attr,
274362 &dev_attr_duty_cycle.attr,
275363 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
276364 &dev_attr_oneshot_count.attr,
365
+ &dev_attr_oneshot_repeat.attr,
366
+ &dev_attr_duty_offset.attr,
277367 #endif
278368 &dev_attr_enable.attr,
279369 &dev_attr_polarity.attr,
280370 &dev_attr_capture.attr,
371
+ &dev_attr_output_type.attr,
281372 NULL
282373 };
283374 ATTRIBUTE_GROUPS(pwm);
....@@ -292,6 +383,7 @@
292383 static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
293384 {
294385 struct pwm_export *export;
386
+ char *pwm_prop[2];
295387 int ret;
296388
297389 if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
....@@ -319,6 +411,10 @@
319411 export = NULL;
320412 return ret;
321413 }
414
+ pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
415
+ pwm_prop[1] = NULL;
416
+ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
417
+ kfree(pwm_prop[0]);
322418
323419 return 0;
324420 }
....@@ -331,6 +427,7 @@
331427 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
332428 {
333429 struct device *child;
430
+ char *pwm_prop[2];
334431
335432 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
336433 return -ENODEV;
....@@ -338,6 +435,11 @@
338435 child = device_find_child(parent, pwm, pwm_unexport_match);
339436 if (!child)
340437 return -ENODEV;
438
+
439
+ pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
440
+ pwm_prop[1] = NULL;
441
+ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
442
+ kfree(pwm_prop[0]);
341443
342444 /* for device_find_child() */
343445 put_device(child);
....@@ -413,10 +515,128 @@
413515 };
414516 ATTRIBUTE_GROUPS(pwm_chip);
415517
518
+/* takes export->lock on success */
519
+static struct pwm_export *pwm_class_get_state(struct device *parent,
520
+ struct pwm_device *pwm,
521
+ struct pwm_state *state)
522
+{
523
+ struct device *child;
524
+ struct pwm_export *export;
525
+
526
+ if (!test_bit(PWMF_EXPORTED, &pwm->flags))
527
+ return NULL;
528
+
529
+ child = device_find_child(parent, pwm, pwm_unexport_match);
530
+ if (!child)
531
+ return NULL;
532
+
533
+ export = child_to_pwm_export(child);
534
+ put_device(child); /* for device_find_child() */
535
+
536
+ mutex_lock(&export->lock);
537
+ pwm_get_state(pwm, state);
538
+
539
+ return export;
540
+}
541
+
542
+static int pwm_class_apply_state(struct pwm_export *export,
543
+ struct pwm_device *pwm,
544
+ struct pwm_state *state)
545
+{
546
+ int ret = pwm_apply_state(pwm, state);
547
+
548
+ /* release lock taken in pwm_class_get_state */
549
+ mutex_unlock(&export->lock);
550
+
551
+ return ret;
552
+}
553
+
554
+static int pwm_class_resume_npwm(struct device *parent, unsigned int npwm)
555
+{
556
+ struct pwm_chip *chip = dev_get_drvdata(parent);
557
+ unsigned int i;
558
+ int ret = 0;
559
+
560
+ for (i = 0; i < npwm; i++) {
561
+ struct pwm_device *pwm = &chip->pwms[i];
562
+ struct pwm_state state;
563
+ struct pwm_export *export;
564
+
565
+ export = pwm_class_get_state(parent, pwm, &state);
566
+ if (!export)
567
+ continue;
568
+
569
+ /* If pwmchip was not enabled before suspend, do nothing. */
570
+ if (!export->suspend.enabled) {
571
+ /* release lock taken in pwm_class_get_state */
572
+ mutex_unlock(&export->lock);
573
+ continue;
574
+ }
575
+
576
+ state.enabled = export->suspend.enabled;
577
+ ret = pwm_class_apply_state(export, pwm, &state);
578
+ if (ret < 0)
579
+ break;
580
+ }
581
+
582
+ return ret;
583
+}
584
+
585
+static int __maybe_unused pwm_class_suspend(struct device *parent)
586
+{
587
+ struct pwm_chip *chip = dev_get_drvdata(parent);
588
+ unsigned int i;
589
+ int ret = 0;
590
+
591
+ for (i = 0; i < chip->npwm; i++) {
592
+ struct pwm_device *pwm = &chip->pwms[i];
593
+ struct pwm_state state;
594
+ struct pwm_export *export;
595
+
596
+ export = pwm_class_get_state(parent, pwm, &state);
597
+ if (!export)
598
+ continue;
599
+
600
+ /*
601
+ * If pwmchip was not enabled before suspend, save
602
+ * state for resume time and do nothing else.
603
+ */
604
+ export->suspend = state;
605
+ if (!state.enabled) {
606
+ /* release lock taken in pwm_class_get_state */
607
+ mutex_unlock(&export->lock);
608
+ continue;
609
+ }
610
+
611
+ state.enabled = false;
612
+ ret = pwm_class_apply_state(export, pwm, &state);
613
+ if (ret < 0) {
614
+ /*
615
+ * roll back the PWM devices that were disabled by
616
+ * this suspend function.
617
+ */
618
+ pwm_class_resume_npwm(parent, i);
619
+ break;
620
+ }
621
+ }
622
+
623
+ return ret;
624
+}
625
+
626
+static int __maybe_unused pwm_class_resume(struct device *parent)
627
+{
628
+ struct pwm_chip *chip = dev_get_drvdata(parent);
629
+
630
+ return pwm_class_resume_npwm(parent, chip->npwm);
631
+}
632
+
633
+static SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);
634
+
416635 static struct class pwm_class = {
417636 .name = "pwm",
418637 .owner = THIS_MODULE,
419638 .dev_groups = pwm_chip_groups,
639
+ .pm = &pwm_class_pm_ops,
420640 };
421641
422642 static int pwmchip_sysfs_match(struct device *parent, const void *data)
....@@ -430,7 +650,7 @@
430650
431651 /*
432652 * If device_create() fails the pwm_chip is still usable by
433
- * the kernel its just not exported.
653
+ * the kernel it's just not exported.
434654 */
435655 parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
436656 "pwmchip%d", chip->base);
....@@ -465,8 +685,4 @@
465685 {
466686 return class_register(&pwm_class);
467687 }
468
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
469
-postcore_initcall(pwm_sysfs_init);
470
-#else
471688 subsys_initcall(pwm_sysfs_init);
472
-#endif