[PATCH] pinctrl: single: add support for pinctrl-single, pins when #pinctrl-cells = 2
Tom Rini
trini at konsulko.com
Fri Jan 14 19:17:23 CET 2022
On Fri, Dec 03, 2021 at 03:18:53PM +0000, AJ Bagwell wrote:
> Changes to the am33xx device (33e9021a) trees have been merged in from
> the upstream linux kernel which now means the device tree uses the new
> pins format (as of 5.10) where the confinguration can be stores as a
> separate configuration value and pin mux mode which are then OR'd
> together.
>
> This patch adds support for the new format to u-boot so that
> pinctrl-cells is now respected when reading in pinctrl-single,pins
> ---
> drivers/pinctrl/pinctrl-single.c | 55 +++++++++++++++++---------------
> 1 file changed, 29 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
> index 8fc07e3498..bc9c17bce8 100644
> --- a/drivers/pinctrl/pinctrl-single.c
> +++ b/drivers/pinctrl/pinctrl-single.c
> @@ -28,6 +28,7 @@ struct single_pdata {
> int offset;
> u32 mask;
> u32 width;
> + u32 args_count;
> bool bits_per_mux;
> };
>
> @@ -78,20 +79,6 @@ struct single_priv {
> struct list_head gpiofuncs;
> };
>
> -/**
> - * struct single_fdt_pin_cfg - pin configuration
> - *
> - * This structure is used for the pin configuration parameters in case
> - * the register controls only one pin.
> - *
> - * @reg: configuration register offset
> - * @val: configuration register value
> - */
> -struct single_fdt_pin_cfg {
> - fdt32_t reg;
> - fdt32_t val;
> -};
> -
> /**
> * struct single_fdt_bits_cfg - pin configuration
> *
> @@ -314,25 +301,28 @@ static int single_pin_compare(const void *s1, const void *s2)
> * @dev: Pointer to single pin configuration device which is the parent of
> * the pins node holding the pin configuration data.
> * @pins: Pointer to the first element of an array of register/value pairs
> - * of type 'struct single_fdt_pin_cfg'. Each such pair describes the
> - * the pin to be configured and the value to be used for configuration.
> + * of type 'u32'. Each such pair describes the pin to be configured
> + * and the value to be used for configuration.
> + * The value can either be a simple value if #pinctrl-cells = 1
> + * or a configuration value and a pin mux mode value if it is 2
> * This pointer points to a 'pinctrl-single,pins' property in the
> * device-tree.
> * @size: Size of the 'pins' array in bytes.
> - * The number of register/value pairs in the 'pins' array therefore
> - * equals to 'size / sizeof(struct single_fdt_pin_cfg)'.
> + * The number of cells in the array therefore equals to
> + * 'size / sizeof(u32)'.
> * @fname: Function name.
> */
> static int single_configure_pins(struct udevice *dev,
> - const struct single_fdt_pin_cfg *pins,
> + const u32 *pins,
> int size, const char *fname)
> {
> struct single_pdata *pdata = dev_get_plat(dev);
> struct single_priv *priv = dev_get_priv(dev);
> - int n, pin, count = size / sizeof(struct single_fdt_pin_cfg);
> + int stride = pdata->args_count + 1;
> + int n, pin, count = size / sizeof(u32);
> struct single_func *func;
> phys_addr_t reg;
> - u32 offset, val;
> + u32 offset, val, mux;
>
> /* If function mask is null, needn't enable it. */
> if (!pdata->mask)
> @@ -344,16 +334,22 @@ static int single_configure_pins(struct udevice *dev,
>
> func->name = fname;
> func->npins = 0;
> - for (n = 0; n < count; n++, pins++) {
> - offset = fdt32_to_cpu(pins->reg);
> + for (n = 0; n < count; n += stride) {
> + offset = fdt32_to_cpu(pins[n]);
> if (offset > pdata->offset) {
> dev_err(dev, " invalid register offset 0x%x\n",
> offset);
> continue;
> }
>
> + /* if the pinctrl-cells is 2 then the second cell contains the mux */
> + if (stride == 3)
> + mux = fdt32_to_cpu(pins[n + 2]);
> + else
> + mux = 0;
> +
> reg = pdata->base + offset;
> - val = fdt32_to_cpu(pins->val) & pdata->mask;
> + val = (fdt32_to_cpu(pins[n + 1]) | mux) & pdata->mask;
> pin = single_get_pin_by_offset(dev, offset);
> if (pin < 0) {
> dev_err(dev, " failed to get pin by offset %x\n",
> @@ -453,7 +449,7 @@ static int single_configure_bits(struct udevice *dev,
> static int single_set_state(struct udevice *dev,
> struct udevice *config)
> {
> - const struct single_fdt_pin_cfg *prop;
> + const u32 *prop;
> const struct single_fdt_bits_cfg *prop_bits;
> int len;
>
> @@ -461,7 +457,7 @@ static int single_set_state(struct udevice *dev,
>
> if (prop) {
> dev_dbg(dev, "configuring pins for %s\n", config->name);
> - if (len % sizeof(struct single_fdt_pin_cfg)) {
> + if (len % sizeof(u32)) {
> dev_dbg(dev, " invalid pin configuration in fdt\n");
> return -FDT_ERR_BADSTRUCTURE;
> }
> @@ -612,6 +608,13 @@ static int single_of_to_plat(struct udevice *dev)
>
> pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux");
>
> + /* If no pinctrl-cells is present, default to old style of 2 cells with
> + * bits per mux and 1 cell otherwise.
> + */
> + ret = dev_read_u32(dev, "#pinctrl-cells", &pdata->args_count);
> + if (ret)
> + pdata->args_count = pdata->bits_per_mux ? 2 : 1;
> +
> return 0;
> }
While this change seems fine, it is missing a Signed-off-by line.
Please see https://developercertificate.org/ and if so, either repost or
reply with your line here as the change otherwise still applies fine,
thanks.
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20220114/b3a6270d/attachment.sig>
More information about the U-Boot
mailing list