hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/pwm/pwm-stm32.c
....@@ -12,12 +12,19 @@
1212 #include <linux/mfd/stm32-timers.h>
1313 #include <linux/module.h>
1414 #include <linux/of.h>
15
+#include <linux/pinctrl/consumer.h>
1516 #include <linux/platform_device.h>
1617 #include <linux/pwm.h>
1718
1819 #define CCMR_CHANNEL_SHIFT 8
1920 #define CCMR_CHANNEL_MASK 0xFF
2021 #define MAX_BREAKINPUT 2
22
+
23
+struct stm32_breakinput {
24
+ u32 index;
25
+ u32 level;
26
+ u32 filter;
27
+};
2128
2229 struct stm32_pwm {
2330 struct pwm_chip chip;
....@@ -26,13 +33,9 @@
2633 struct regmap *regmap;
2734 u32 max_arr;
2835 bool have_complementary_output;
36
+ struct stm32_breakinput breakinputs[MAX_BREAKINPUT];
37
+ unsigned int num_breakinputs;
2938 u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */
30
-};
31
-
32
-struct stm32_breakinput {
33
- u32 index;
34
- u32 level;
35
- u32 filter;
3639 };
3740
3841 static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip)
....@@ -374,9 +377,7 @@
374377 else
375378 regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr);
376379
377
- regmap_update_bits(priv->regmap, TIM_BDTR,
378
- TIM_BDTR_MOE | TIM_BDTR_AOE,
379
- TIM_BDTR_MOE | TIM_BDTR_AOE);
380
+ regmap_update_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE, TIM_BDTR_MOE);
380381
381382 return 0;
382383 }
....@@ -440,7 +441,7 @@
440441 }
441442
442443 static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
443
- struct pwm_state *state)
444
+ const struct pwm_state *state)
444445 {
445446 bool enabled;
446447 struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
....@@ -468,7 +469,7 @@
468469 }
469470
470471 static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm,
471
- struct pwm_state *state)
472
+ const struct pwm_state *state)
472473 {
473474 struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
474475 int ret;
....@@ -488,22 +489,19 @@
488489 };
489490
490491 static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
491
- int index, int level, int filter)
492
+ const struct stm32_breakinput *bi)
492493 {
493
- u32 bke = (index == 0) ? TIM_BDTR_BKE : TIM_BDTR_BK2E;
494
- int shift = (index == 0) ? TIM_BDTR_BKF_SHIFT : TIM_BDTR_BK2F_SHIFT;
495
- u32 mask = (index == 0) ? TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF
496
- : TIM_BDTR_BK2E | TIM_BDTR_BK2P | TIM_BDTR_BK2F;
497
- u32 bdtr = bke;
494
+ u32 shift = TIM_BDTR_BKF_SHIFT(bi->index);
495
+ u32 bke = TIM_BDTR_BKE(bi->index);
496
+ u32 bkp = TIM_BDTR_BKP(bi->index);
497
+ u32 bkf = TIM_BDTR_BKF(bi->index);
498
+ u32 mask = bkf | bkp | bke;
499
+ u32 bdtr;
498500
499
- /*
500
- * The both bits could be set since only one will be wrote
501
- * due to mask value.
502
- */
503
- if (level)
504
- bdtr |= TIM_BDTR_BKP | TIM_BDTR_BK2P;
501
+ bdtr = (bi->filter & TIM_BDTR_BKF_MASK) << shift | bke;
505502
506
- bdtr |= (filter & TIM_BDTR_BKF_MASK) << shift;
503
+ if (bi->level)
504
+ bdtr |= bkp;
507505
508506 regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr);
509507
....@@ -512,11 +510,25 @@
512510 return (bdtr & bke) ? 0 : -EINVAL;
513511 }
514512
515
-static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv,
513
+static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv)
514
+{
515
+ unsigned int i;
516
+ int ret;
517
+
518
+ for (i = 0; i < priv->num_breakinputs; i++) {
519
+ ret = stm32_pwm_set_breakinput(priv, &priv->breakinputs[i]);
520
+ if (ret < 0)
521
+ return ret;
522
+ }
523
+
524
+ return 0;
525
+}
526
+
527
+static int stm32_pwm_probe_breakinputs(struct stm32_pwm *priv,
516528 struct device_node *np)
517529 {
518
- struct stm32_breakinput breakinput[MAX_BREAKINPUT];
519
- int nb, ret, i, array_size;
530
+ int nb, ret, array_size;
531
+ unsigned int i;
520532
521533 nb = of_property_count_elems_of_size(np, "st,breakinput",
522534 sizeof(struct stm32_breakinput));
....@@ -531,20 +543,21 @@
531543 if (nb > MAX_BREAKINPUT)
532544 return -EINVAL;
533545
546
+ priv->num_breakinputs = nb;
534547 array_size = nb * sizeof(struct stm32_breakinput) / sizeof(u32);
535548 ret = of_property_read_u32_array(np, "st,breakinput",
536
- (u32 *)breakinput, array_size);
549
+ (u32 *)priv->breakinputs, array_size);
537550 if (ret)
538551 return ret;
539552
540
- for (i = 0; i < nb && !ret; i++) {
541
- ret = stm32_pwm_set_breakinput(priv,
542
- breakinput[i].index,
543
- breakinput[i].level,
544
- breakinput[i].filter);
553
+ for (i = 0; i < priv->num_breakinputs; i++) {
554
+ if (priv->breakinputs[i].index > 1 ||
555
+ priv->breakinputs[i].level > 1 ||
556
+ priv->breakinputs[i].filter > 15)
557
+ return -EINVAL;
545558 }
546559
547
- return ret;
560
+ return stm32_pwm_apply_breakinputs(priv);
548561 }
549562
550563 static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
....@@ -608,11 +621,13 @@
608621 priv->regmap = ddata->regmap;
609622 priv->clk = ddata->clk;
610623 priv->max_arr = ddata->max_arr;
624
+ priv->chip.of_xlate = of_pwm_xlate_with_flags;
625
+ priv->chip.of_pwm_n_cells = 3;
611626
612627 if (!priv->regmap || !priv->clk)
613628 return -EINVAL;
614629
615
- ret = stm32_pwm_apply_breakinputs(priv, np);
630
+ ret = stm32_pwm_probe_breakinputs(priv, np);
616631 if (ret)
617632 return ret;
618633
....@@ -645,6 +660,42 @@
645660 return 0;
646661 }
647662
663
+static int __maybe_unused stm32_pwm_suspend(struct device *dev)
664
+{
665
+ struct stm32_pwm *priv = dev_get_drvdata(dev);
666
+ unsigned int i;
667
+ u32 ccer, mask;
668
+
669
+ /* Look for active channels */
670
+ ccer = active_channels(priv);
671
+
672
+ for (i = 0; i < priv->chip.npwm; i++) {
673
+ mask = TIM_CCER_CC1E << (i * 4);
674
+ if (ccer & mask) {
675
+ dev_err(dev, "PWM %u still in use by consumer %s\n",
676
+ i, priv->chip.pwms[i].label);
677
+ return -EBUSY;
678
+ }
679
+ }
680
+
681
+ return pinctrl_pm_select_sleep_state(dev);
682
+}
683
+
684
+static int __maybe_unused stm32_pwm_resume(struct device *dev)
685
+{
686
+ struct stm32_pwm *priv = dev_get_drvdata(dev);
687
+ int ret;
688
+
689
+ ret = pinctrl_pm_select_default_state(dev);
690
+ if (ret)
691
+ return ret;
692
+
693
+ /* restore breakinput registers that may have been lost in low power */
694
+ return stm32_pwm_apply_breakinputs(priv);
695
+}
696
+
697
+static SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_resume);
698
+
648699 static const struct of_device_id stm32_pwm_of_match[] = {
649700 { .compatible = "st,stm32-pwm", },
650701 { /* end node */ },
....@@ -657,6 +708,7 @@
657708 .driver = {
658709 .name = "stm32-pwm",
659710 .of_match_table = stm32_pwm_of_match,
711
+ .pm = &stm32_pwm_pm_ops,
660712 },
661713 };
662714 module_platform_driver(stm32_pwm_driver);