Re: [PATCH v6 03/11] pwm: rzg2l-gpt: Add support for gpt linking with poeg
Uwe Kleine-König <[email protected]> Thu, 16 Jul 2026 10:25:43 +0200
| Newsgroups | org.kernel.vger.linux-pwm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-renesas-soc |
|---|---|
| Message-ID | <aliNlCVK5qrZKPWi@monoceros> |
Hello Biju, On Thu, Jun 04, 2026 at 10:56:33AM +0100, Biju wrote: > From: Biju Das <[email protected]> > > The General PWM Timer (GPT) is capable of detecting "dead time error > and short-circuits between output pins" and send Output disable > request to poeg(Port Output Enable for GPT). What is a dead time error? > Add support for linking poeg group with gpt, so that gpt can control > the output disable function by adding rzg2l_gpt_poeg_init() to parse > the renesas,poegs device tree property and establish links between POEG > groups (A–D) and GPT hardware channels (0–7). For each valid, enabled > POEG phandle entry, the driver: > - Reads the renesas,poeg-id from the POEG node and validates it against > the supported range > - Records the GPT–POEG association in a per-chip bitmap (poeg_gpt_link) > - Configures GTINTAD to route the output disable request to the correct > POEG group > - Configures GTIOR (OADF/OBDF fields) to set both output pins to > high-impedance on an output disable event For my understanding: If GPT is linked to a POEG, an error detected by GPT makes the pin High-Z? > +/* > + * This function links a POEG group{A,B,C,D} with a GPT channel{0..7} and > + * configures the pin for output disable. > + */ > +static int rzg2l_gpt_poeg_init(struct platform_device *pdev, > + struct rzg2l_gpt_chip *rzg2l_gpt) > +{ > + const char *poeg_name = "renesas,poegs"; > + struct of_phandle_args of_args; > + struct property *poegs; > + unsigned int i; > + u32 poeg_grp; > + u32 bitpos; > + int cells; > + int ret; > + > + poegs = of_find_property(pdev->dev.of_node, poeg_name, NULL); > + if (!poegs) > + return 0; > + > + cells = of_property_count_u32_elems(pdev->dev.of_node, poeg_name); It's a bit sad that of_find_property() is called twice here. But I didn't spot a function that implements what of_property_count_u32_elems() does for a given struct property*. > + if (cells < 0) > + return cells; > + > + if (cells & 1) Maybe add a comment here like: /* poegs is a list of pairs, so cells must be even */ > + return -EINVAL; > + > + cells >>= 1; I think a better name for `cells` from here on would be beneficial, something like `num_poeg_pairs`. For before here the name isn't optimal, but I don't have a spontanious suggestion here. `len` comes to mind. > + for (i = 0; i < cells; i++) { > + ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, > + poeg_name, 1, i, > + &of_args); > + if (ret) > + return ret; > + > + if (of_args.args[0] >= RZG2L_MAX_HW_CHANNELS) { > + dev_err(&pdev->dev, "Invalid channel %u >= %u\n", > + of_args.args[0], RZG2L_MAX_HW_CHANNELS); Given that rzg2l_gpt_poeg_init() is called from .probe() only, use dev_err_probe() here. > + goto err_of_node; > + } > + > + if (!of_device_is_available(of_args.np)) { > + /* It's fine to have a phandle to a non-enabled poeg. */ > + of_node_put(of_args.np); > + continue; > + } > + > + if (!of_property_read_u32(of_args.np, "renesas,poeg-id", &poeg_grp)) { > + if (poeg_grp > RZG2L_LAST_POEG_GROUP) { > + dev_err(&pdev->dev, "Invalid poeg group %u > %u\n", > + poeg_grp, RZG2L_LAST_POEG_GROUP); > + goto err_of_node; > + } > + > + bitpos = of_args.args[0] + poeg_grp * RZG2L_MAX_HW_CHANNELS; > + set_bit(bitpos, rzg2l_gpt->poeg_gpt_link); > + > + rzg2l_gpt_modify(rzg2l_gpt, RZG2L_GTINTAD(of_args.args[0]), > + RZG2L_GTINTAD_GRP_MASK, poeg_grp << 24); > + > + rzg2l_gpt_modify(rzg2l_gpt, RZG2L_GTIOR(of_args.args[0]), > + RZG2L_GTIOR_OBDF | RZG2L_GTIOR_OADF, > + RZG2L_GTIOR_PIN_DISABLE_SETTING); > + } > + > + of_node_put(of_args.np); > + } > + > + return 0; > + > +err_of_node: > + of_node_put(of_args.np); Would be great if this could be prettified using __free. > + return -EINVAL; > +} > + > static int rzg2l_gpt_probe(struct platform_device *pdev) > { > struct rzg2l_gpt_chip *rzg2l_gpt; > @@ -426,6 +515,10 @@ static int rzg2l_gpt_probe(struct platform_device *pdev) > if (rzg2l_gpt->rate_khz * KILO != rate) > return dev_err_probe(dev, -EINVAL, "Rate is not multiple of 1000"); > > + ret = rzg2l_gpt_poeg_init(pdev, rzg2l_gpt); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to link gpt with poeg\n"); > + > mutex_init(&rzg2l_gpt->lock); > > chip->ops = &rzg2l_gpt_ops; Best regards Uwe
signature.asc
(application/pgp-signature, 488 B)
-----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEP4GsaTp6HlmJrf7Tj4D7WH0S/k4FAmpYlYQACgkQj4D7WH0S /k56HQgAlmtbr142kZu51xY9wPHqykkBXem4lYob0iqtaJ+3Ylgy4P5x15CpS/s6 an6g6TwcmPw98jaEvOMA3j3hO5Ys7W+h13cdqdy0QrulojILPfB74266Qq+ec7uN V2gGx73e/VA+XMVm5kMTN64x8V8YafEqiq34M4c8dPzEst9UtpXp+vfErACMeACT PZGIN1XR3FVBRRcNux9UNgbzSjad8p+H2uIJoj+xRyyIdiyEJ3pyZrs8qi+RSXGS iZX1rJkN2xUQpG8x1ake+Pb25tUzujg5Ftr+MKv845MRiMKNuMaTLyIrhsuwddlT jpEUQ7FSnObJWneJ+SHAeXyuS4u5Cg== =7rkm -----END PGP SIGNATURE-----