forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
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
....@@ -257,7 +249,30 @@
257249 if (ret)
258250 return ret;
259251
260
- return sprintf(buf, "%llu %llu\n", result.period, result.duty_cycle);
252
+ return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
253
+}
254
+
255
+static ssize_t output_type_show(struct device *child,
256
+ struct device_attribute *attr,
257
+ char *buf)
258
+{
259
+ const struct pwm_device *pwm = child_to_pwm_device(child);
260
+ const char *output_type = "unknown";
261
+ struct pwm_state state;
262
+
263
+ pwm_get_state(pwm, &state);
264
+ switch (state.output_type) {
265
+ case PWM_OUTPUT_FIXED:
266
+ output_type = "fixed";
267
+ break;
268
+ case PWM_OUTPUT_MODULATED:
269
+ output_type = "modulated";
270
+ break;
271
+ default:
272
+ break;
273
+ }
274
+
275
+ return snprintf(buf, PAGE_SIZE, "%s\n", output_type);
261276 }
262277
263278 static DEVICE_ATTR_RW(period);
....@@ -268,6 +283,7 @@
268283 static DEVICE_ATTR_RW(enable);
269284 static DEVICE_ATTR_RW(polarity);
270285 static DEVICE_ATTR_RO(capture);
286
+static DEVICE_ATTR_RO(output_type);
271287
272288 static struct attribute *pwm_attrs[] = {
273289 &dev_attr_period.attr,
....@@ -278,6 +294,7 @@
278294 &dev_attr_enable.attr,
279295 &dev_attr_polarity.attr,
280296 &dev_attr_capture.attr,
297
+ &dev_attr_output_type.attr,
281298 NULL
282299 };
283300 ATTRIBUTE_GROUPS(pwm);
....@@ -292,6 +309,7 @@
292309 static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
293310 {
294311 struct pwm_export *export;
312
+ char *pwm_prop[2];
295313 int ret;
296314
297315 if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
....@@ -319,6 +337,10 @@
319337 export = NULL;
320338 return ret;
321339 }
340
+ pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
341
+ pwm_prop[1] = NULL;
342
+ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
343
+ kfree(pwm_prop[0]);
322344
323345 return 0;
324346 }
....@@ -331,6 +353,7 @@
331353 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
332354 {
333355 struct device *child;
356
+ char *pwm_prop[2];
334357
335358 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
336359 return -ENODEV;
....@@ -338,6 +361,11 @@
338361 child = device_find_child(parent, pwm, pwm_unexport_match);
339362 if (!child)
340363 return -ENODEV;
364
+
365
+ pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
366
+ pwm_prop[1] = NULL;
367
+ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
368
+ kfree(pwm_prop[0]);
341369
342370 /* for device_find_child() */
343371 put_device(child);
....@@ -413,10 +441,111 @@
413441 };
414442 ATTRIBUTE_GROUPS(pwm_chip);
415443
444
+/* takes export->lock on success */
445
+static struct pwm_export *pwm_class_get_state(struct device *parent,
446
+ struct pwm_device *pwm,
447
+ struct pwm_state *state)
448
+{
449
+ struct device *child;
450
+ struct pwm_export *export;
451
+
452
+ if (!test_bit(PWMF_EXPORTED, &pwm->flags))
453
+ return NULL;
454
+
455
+ child = device_find_child(parent, pwm, pwm_unexport_match);
456
+ if (!child)
457
+ return NULL;
458
+
459
+ export = child_to_pwm_export(child);
460
+ put_device(child); /* for device_find_child() */
461
+
462
+ mutex_lock(&export->lock);
463
+ pwm_get_state(pwm, state);
464
+
465
+ return export;
466
+}
467
+
468
+static int pwm_class_apply_state(struct pwm_export *export,
469
+ struct pwm_device *pwm,
470
+ struct pwm_state *state)
471
+{
472
+ int ret = pwm_apply_state(pwm, state);
473
+
474
+ /* release lock taken in pwm_class_get_state */
475
+ mutex_unlock(&export->lock);
476
+
477
+ return ret;
478
+}
479
+
480
+static int pwm_class_resume_npwm(struct device *parent, unsigned int npwm)
481
+{
482
+ struct pwm_chip *chip = dev_get_drvdata(parent);
483
+ unsigned int i;
484
+ int ret = 0;
485
+
486
+ for (i = 0; i < npwm; i++) {
487
+ struct pwm_device *pwm = &chip->pwms[i];
488
+ struct pwm_state state;
489
+ struct pwm_export *export;
490
+
491
+ export = pwm_class_get_state(parent, pwm, &state);
492
+ if (!export)
493
+ continue;
494
+
495
+ state.enabled = export->suspend.enabled;
496
+ ret = pwm_class_apply_state(export, pwm, &state);
497
+ if (ret < 0)
498
+ break;
499
+ }
500
+
501
+ return ret;
502
+}
503
+
504
+static int __maybe_unused pwm_class_suspend(struct device *parent)
505
+{
506
+ struct pwm_chip *chip = dev_get_drvdata(parent);
507
+ unsigned int i;
508
+ int ret = 0;
509
+
510
+ for (i = 0; i < chip->npwm; i++) {
511
+ struct pwm_device *pwm = &chip->pwms[i];
512
+ struct pwm_state state;
513
+ struct pwm_export *export;
514
+
515
+ export = pwm_class_get_state(parent, pwm, &state);
516
+ if (!export)
517
+ continue;
518
+
519
+ export->suspend = state;
520
+ state.enabled = false;
521
+ ret = pwm_class_apply_state(export, pwm, &state);
522
+ if (ret < 0) {
523
+ /*
524
+ * roll back the PWM devices that were disabled by
525
+ * this suspend function.
526
+ */
527
+ pwm_class_resume_npwm(parent, i);
528
+ break;
529
+ }
530
+ }
531
+
532
+ return ret;
533
+}
534
+
535
+static int __maybe_unused pwm_class_resume(struct device *parent)
536
+{
537
+ struct pwm_chip *chip = dev_get_drvdata(parent);
538
+
539
+ return pwm_class_resume_npwm(parent, chip->npwm);
540
+}
541
+
542
+static SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);
543
+
416544 static struct class pwm_class = {
417545 .name = "pwm",
418546 .owner = THIS_MODULE,
419547 .dev_groups = pwm_chip_groups,
548
+ .pm = &pwm_class_pm_ops,
420549 };
421550
422551 static int pwmchip_sysfs_match(struct device *parent, const void *data)
....@@ -430,7 +559,7 @@
430559
431560 /*
432561 * If device_create() fails the pwm_chip is still usable by
433
- * the kernel its just not exported.
562
+ * the kernel it's just not exported.
434563 */
435564 parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
436565 "pwmchip%d", chip->base);
....@@ -465,8 +594,4 @@
465594 {
466595 return class_register(&pwm_class);
467596 }
468
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
469
-postcore_initcall(pwm_sysfs_init);
470
-#else
471597 subsys_initcall(pwm_sysfs_init);
472
-#endif