2021-12-02 12:41:26

by Aswath Govindraju

[permalink] [raw]
Subject: [PATCH v2 0/2] MUX: Add support for mux-states

The following series of patches add support for reading mux
state from the device tree.

changes since v1:
- Made grammer corrections and added more information
on the usage for mux-states and mux-controls

Aswath Govindraju (2):
dt-bindings: mux: Document mux-states property
mux: Add support for reading mux state from consumer DT node

.../devicetree/bindings/mux/gpio-mux.yaml | 11 +-
.../devicetree/bindings/mux/mux-consumer.yaml | 21 ++
.../bindings/mux/mux-controller.yaml | 26 ++-
drivers/mux/core.c | 219 ++++++++++++++++--
include/linux/mux/consumer.h | 19 +-
5 files changed, 271 insertions(+), 25 deletions(-)

--
2.17.1



2021-12-02 12:41:31

by Aswath Govindraju

[permalink] [raw]
Subject: [PATCH v2 1/2] dt-bindings: mux: Document mux-states property

In some cases, it is required to provide the state to which the mux
controller has to be set to, from the consumer device tree node. Document
the property mux-states that can be used for adding this support.

Signed-off-by: Aswath Govindraju <[email protected]>
---

Note:
- on running dt_binding_check with "DT_CHECKER_FLAGS=-m" the following
error was seen,

LINT Documentation/devicetree/bindings
CHKDT Documentation/devicetree/bindings/processed-schema-examples.json
SCHEMA Documentation/devicetree/bindings/processed-schema-examples.json
DTC Documentation/devicetree/bindings/mux/mux-controller.example.dt.yaml
CHECK Documentation/devicetree/bindings/mux/mux-controller.example.dt.yaml
/home/gsaswath/presil/ks3-linux-integrated/linux/Documentation/devicetree/bindings/
mux/mux-controller.example.dt.yaml: can-phy4: 'mux-states' does not match any of
the regexes: 'pinctrl-[0-9]+'
From schema: /home/gsaswath/presil/ks3-linux-integrated/linux/
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml

"mux-states" is a new property that is being added and the patch adding this
property to TCAN104x can transceiver bindings will be sent as a follow up
of this series.

.../devicetree/bindings/mux/gpio-mux.yaml | 11 ++++++--
.../devicetree/bindings/mux/mux-consumer.yaml | 21 +++++++++++++++
.../bindings/mux/mux-controller.yaml | 26 ++++++++++++++++++-
3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mux/gpio-mux.yaml b/Documentation/devicetree/bindings/mux/gpio-mux.yaml
index 0a7c8d64981a..ee4de9fbaf4d 100644
--- a/Documentation/devicetree/bindings/mux/gpio-mux.yaml
+++ b/Documentation/devicetree/bindings/mux/gpio-mux.yaml
@@ -26,7 +26,10 @@ properties:
List of gpios used to control the multiplexer, least significant bit first.

'#mux-control-cells':
- const: 0
+ enum: [ 0, 1 ]
+
+ '#mux-state-cells':
+ enum: [ 1, 2 ]

idle-state:
default: -1
@@ -34,7 +37,11 @@ properties:
required:
- compatible
- mux-gpios
- - "#mux-control-cells"
+anyOf:
+ - required:
+ - "#mux-control-cells"
+ - required:
+ - "#mux-state-cells"

additionalProperties: false

diff --git a/Documentation/devicetree/bindings/mux/mux-consumer.yaml b/Documentation/devicetree/bindings/mux/mux-consumer.yaml
index 7af93298ab5c..d3d854967359 100644
--- a/Documentation/devicetree/bindings/mux/mux-consumer.yaml
+++ b/Documentation/devicetree/bindings/mux/mux-consumer.yaml
@@ -25,6 +25,17 @@ description: |
strings to label each of the mux controllers listed in the "mux-controls"
property.

+ If it is required to provide the state that the mux controller needs to
+ be set to, the property "mux-states" must be used. An optional property
+ "mux-state-names" can be used to provide a list of strings, to label
+ each of the multiplixer states listed in the "mux-states" property.
+
+ Properties "mux-controls" and "mux-states" can be used depending on how
+ the consumers want to control the mux controller. If the consumer needs
+ needs to set multiple states in a mux controller, then property
+ "mux-controls" can be used. If the consumer needs to set the mux
+ controller to a given state then property "mux-states" can be used.
+
mux-ctrl-specifier typically encodes the chip-relative mux controller number.
If the mux controller chip only provides a single mux controller, the
mux-ctrl-specifier can typically be left out.
@@ -35,12 +46,22 @@ properties:
mux-controls:
$ref: /schemas/types.yaml#/definitions/phandle-array

+ mux-states:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+
mux-control-names:
description:
Devices that use more than a single mux controller can use the
"mux-control-names" property to map the name of the requested mux
controller to an index into the list given by the "mux-controls" property.

+ mux-state-names:
+ description:
+ Devices that use more than a single multiplexer state can use the
+ "mux-state-names" property to map the name of the requested mux
+ controller to an index into the list given by the "mux-states"
+ property.
+
additionalProperties: true

...
diff --git a/Documentation/devicetree/bindings/mux/mux-controller.yaml b/Documentation/devicetree/bindings/mux/mux-controller.yaml
index 736a84c3b6a5..c855fbad3884 100644
--- a/Documentation/devicetree/bindings/mux/mux-controller.yaml
+++ b/Documentation/devicetree/bindings/mux/mux-controller.yaml
@@ -25,7 +25,9 @@ description: |
--------------------

Mux controller nodes must specify the number of cells used for the
- specifier using the '#mux-control-cells' property.
+ specifier using the '#mux-control-cells' or '#mux-state-cells' property.
+ The value of '#mux-state-cells' will always be one greater than the value
+ of '#mux-control-cells'.

Optionally, mux controller nodes can also specify the state the mux should
have when it is idle. The idle-state property is used for this. If the
@@ -67,6 +69,8 @@ select:
pattern: '^mux-controller'
- required:
- '#mux-control-cells'
+ - required:
+ - '#mux-state-cells'

properties:
$nodename:
@@ -75,6 +79,9 @@ properties:
'#mux-control-cells':
enum: [ 0, 1 ]

+ '#mux-state-cells':
+ enum: [ 1, 2 ]
+
idle-state:
$ref: /schemas/types.yaml#/definitions/int32
minimum: -2
@@ -179,4 +186,21 @@ examples:
};
};
};
+
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ mux1: mux-controller {
+ compatible = "gpio-mux";
+ #mux-state-cells = <1>;
+ mux-gpios = <&exp_som 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver4: can-phy4 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ standby-gpios = <&exp_som 7 GPIO_ACTIVE_HIGH>;
+ mux-states = <&mux1 1>;
+ };
...
--
2.17.1


2021-12-06 20:55:57

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] dt-bindings: mux: Document mux-states property

On Thu, 02 Dec 2021 18:10:52 +0530, Aswath Govindraju wrote:
> In some cases, it is required to provide the state to which the mux
> controller has to be set to, from the consumer device tree node. Document
> the property mux-states that can be used for adding this support.
>
> Signed-off-by: Aswath Govindraju <[email protected]>
> ---
>
> Note:
> - on running dt_binding_check with "DT_CHECKER_FLAGS=-m" the following
> error was seen,
>
> LINT Documentation/devicetree/bindings
> CHKDT Documentation/devicetree/bindings/processed-schema-examples.json
> SCHEMA Documentation/devicetree/bindings/processed-schema-examples.json
> DTC Documentation/devicetree/bindings/mux/mux-controller.example.dt.yaml
> CHECK Documentation/devicetree/bindings/mux/mux-controller.example.dt.yaml
> /home/gsaswath/presil/ks3-linux-integrated/linux/Documentation/devicetree/bindings/
> mux/mux-controller.example.dt.yaml: can-phy4: 'mux-states' does not match any of
> the regexes: 'pinctrl-[0-9]+'
> From schema: /home/gsaswath/presil/ks3-linux-integrated/linux/
> Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
>
> "mux-states" is a new property that is being added and the patch adding this
> property to TCAN104x can transceiver bindings will be sent as a follow up
> of this series.
>
> .../devicetree/bindings/mux/gpio-mux.yaml | 11 ++++++--
> .../devicetree/bindings/mux/mux-consumer.yaml | 21 +++++++++++++++
> .../bindings/mux/mux-controller.yaml | 26 ++++++++++++++++++-
> 3 files changed, 55 insertions(+), 3 deletions(-)
>

Reviewed-by: Rob Herring <[email protected]>

2021-12-17 05:57:48

by Peter Rosin

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] MUX: Add support for mux-states

Hi Aswath!

On 2021-12-02 13:40, Aswath Govindraju wrote:
> The following series of patches add support for reading mux
> state from the device tree.
>
> changes since v1:
> - Made grammer corrections and added more information
> on the usage for mux-states and mux-controls
>
> Aswath Govindraju (2):
> dt-bindings: mux: Document mux-states property
> mux: Add support for reading mux state from consumer DT node
>
> .../devicetree/bindings/mux/gpio-mux.yaml | 11 +-
> .../devicetree/bindings/mux/mux-consumer.yaml | 21 ++
> .../bindings/mux/mux-controller.yaml | 26 ++-
> drivers/mux/core.c | 219 ++++++++++++++++--
> include/linux/mux/consumer.h | 19 +-
> 5 files changed, 271 insertions(+), 25 deletions(-)
>

I finally found some time to have a last look at this (fingers crossed) and
pushed it out for testing in linux-next.

I did end up squashing in these trivial changes in patch 2/2, I hope that's
fine with you. Just holler if not...

Cheers,
Peter

diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index 148e19381b79..5018403fe82f 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -368,6 +368,7 @@ MUX
devm_mux_chip_alloc()
devm_mux_chip_register()
devm_mux_control_get()
+ devm_mux_state_get()

NET
devm_alloc_etherdev()
diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index 7355c5ad41f7..bf448069ca85 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -30,12 +30,13 @@
#define MUX_CACHE_UNKNOWN MUX_IDLE_AS_IS

/**
- * struct mux_state - Represents a mux controller specific to a given device
- * @mux: Pointer to a mux controller
- * @state State of the mux to be set
+ * struct mux_state - Represents a mux controller state specific to a given
+ * consumer.
+ * @mux: Pointer to a mux controller.
+ * @state State of the mux to be selected.
*
- * This structure is specific to a device that acquires it and has information
- * specific to the device.
+ * This structure is specific to the consumer that acquires it and has
+ * information specific to that consumer.
*/
struct mux_state {
struct mux_control *mux;
@@ -354,7 +355,8 @@ static void mux_control_delay(struct mux_control *mux, unsigned int delay_us)
* On successfully selecting the mux-control state, it will be locked until
* there is a call to mux_control_deselect(). If the mux-control is already
* selected when mux_control_select() is called, the caller will be blocked
- * until mux_control_deselect() is called (by someone else).
+ * until mux_control_deselect() or mux_state_deselect() is called (by someone
+ * else).
*
* Therefore, make sure to call mux_control_deselect() when the operation is
* complete and the mux-control is free for others to use, but do not call
@@ -384,16 +386,15 @@ int mux_control_select_delay(struct mux_control *mux, unsigned int state,
EXPORT_SYMBOL_GPL(mux_control_select_delay);

/**
- * mux_state_select_delay() - Select mux-state
- * @mstate: The mux-state to select
- * @delay_us: The time to delay (in microseconds) if the mux control
- * changes state on select
+ * mux_state_select_delay() - Select the given multiplexer state.
+ * @mstate: The mux-state to select.
+ * @delay_us: The time to delay (in microseconds) if the mux state is changed.
*
- * On successfully selecting the mux-state, it will be locked until
- * there is a call to mux_state_deselect() or mux_control_deselect().
- * If the mux-control is already selected when mux_state_select() is
- * called, the caller will be blocked until mux_state_deselect() or
- * mux_control_deselect() is called (by someone else).
+ * On successfully selecting the mux-state, its mux-control will be locked
+ * until there is a call to mux_state_deselect(). If the mux-control is already
+ * selected when mux_state_select() is called, the caller will be blocked
+ * until mux_state_deselect() or mux_control_deselect() is called (by someone
+ * else).
*
* Therefore, make sure to call mux_state_deselect() when the operation is
* complete and the mux-control is free for others to use, but do not call
@@ -415,7 +416,7 @@ EXPORT_SYMBOL_GPL(mux_state_select_delay);
* @delay_us: The time to delay (in microseconds) if the mux state is changed.
*
* On successfully selecting the mux-control state, it will be locked until
- * mux_control_deselect() or mux_state_deselect() called.
+ * mux_control_deselect() called.
*
* Therefore, make sure to call mux_control_deselect() when the operation is
* complete and the mux-control is free for others to use, but do not call
@@ -444,12 +445,12 @@ int mux_control_try_select_delay(struct mux_control *mux, unsigned int state,
EXPORT_SYMBOL_GPL(mux_control_try_select_delay);

/**
- * mux_state_try_select_delay() - Try to select the mux-state.
- * @mstate: The mux-state to select
+ * mux_state_try_select_delay() - Try to select the given multiplexer state.
+ * @mstate: The mux-state to select.
* @delay_us: The time to delay (in microseconds) if the mux state is changed.
*
- * On successfully selecting the mux-state, it will be locked until
- * mux_state_deselect() or mux_control_deselect() is called.
+ * On successfully selecting the mux-state, its mux-control will be locked
+ * until mux_state_deselect() is called.
*
* Therefore, make sure to call mux_state_deselect() when the operation is
* complete and the mux-control is free for others to use, but do not call
@@ -642,26 +643,6 @@ static void devm_mux_control_release(struct device *dev, void *res)
mux_control_put(mux);
}

-/**
- * mux_state_put() - Put away the mux-state for good.
- * @mstate: The mux-state to put away.
- *
- * mux_control_put() reverses the effects of mux_control_get().
- */
-void mux_state_put(struct mux_state *mstate)
-{
- mux_control_put(mstate->mux);
- kfree(mstate);
-}
-EXPORT_SYMBOL_GPL(mux_state_put);
-
-static void devm_mux_state_release(struct device *dev, void *res)
-{
- struct mux_state *mstate = *(struct mux_state **)res;
-
- mux_state_put(mstate);
-}
-
/**
* devm_mux_control_get() - Get the mux-control for a device, with resource
* management.
@@ -692,6 +673,26 @@ struct mux_control *devm_mux_control_get(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_mux_control_get);

+/**
+ * mux_state_put() - Put away the mux-state for good.
+ * @mstate: The mux-state to put away.
+ *
+ * mux_control_put() reverses the effects of mux_control_get().
+ */
+void mux_state_put(struct mux_state *mstate)
+{
+ mux_control_put(mstate->mux);
+ kfree(mstate);
+}
+EXPORT_SYMBOL_GPL(mux_state_put);
+
+static void devm_mux_state_release(struct device *dev, void *res)
+{
+ struct mux_state *mstate = *(struct mux_state **)res;
+
+ mux_state_put(mstate);
+}
+
/**
* devm_mux_state_get() - Get the mux-state for a device, with resource
* management.
diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
index bf5abf062c21..babf2a744056 100644
--- a/include/linux/mux/consumer.h
+++ b/include/linux/mux/consumer.h
@@ -27,6 +27,7 @@ int __must_check mux_control_try_select_delay(struct mux_control *mux,
unsigned int delay_us);
int __must_check mux_state_try_select_delay(struct mux_state *mstate,
unsigned int delay_us);
+
static inline int __must_check mux_control_select(struct mux_control *mux,
unsigned int state)
{
@@ -37,6 +38,7 @@ static inline int __must_check mux_state_select(struct mux_state *mstate)
{
return mux_state_select_delay(mstate, 0);
}
+
static inline int __must_check mux_control_try_select(struct mux_control *mux,
unsigned int state)
{

2021-12-17 06:26:59

by Peter Rosin

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] MUX: Add support for mux-states

Hi again.

On 2021-12-17 06:57, Peter Rosin wrote:
> Hi Aswath!
>
> On 2021-12-02 13:40, Aswath Govindraju wrote:
>> The following series of patches add support for reading mux
>> state from the device tree.
>>
>> changes since v1:
>> - Made grammer corrections and added more information
>> on the usage for mux-states and mux-controls
>>
>> Aswath Govindraju (2):
>> dt-bindings: mux: Document mux-states property
>> mux: Add support for reading mux state from consumer DT node
>>
>> .../devicetree/bindings/mux/gpio-mux.yaml | 11 +-
>> .../devicetree/bindings/mux/mux-consumer.yaml | 21 ++
>> .../bindings/mux/mux-controller.yaml | 26 ++-
>> drivers/mux/core.c | 219 ++++++++++++++++--
>> include/linux/mux/consumer.h | 19 +-
>> 5 files changed, 271 insertions(+), 25 deletions(-)
>>
>
> I finally found some time to have a last look at this (fingers crossed) and
> pushed it out for testing in linux-next.
>
> I did end up squashing in these trivial changes in patch 2/2, I hope that's
> fine with you. Just holler if not...
>
> Cheers,
> Peter
>
> diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
> index 148e19381b79..5018403fe82f 100644
> --- a/Documentation/driver-api/driver-model/devres.rst
> +++ b/Documentation/driver-api/driver-model/devres.rst
> @@ -368,6 +368,7 @@ MUX
> devm_mux_chip_alloc()
> devm_mux_chip_register()
> devm_mux_control_get()
> + devm_mux_state_get()
>
> NET
> devm_alloc_etherdev()
> diff --git a/drivers/mux/core.c b/drivers/mux/core.c
> index 7355c5ad41f7..bf448069ca85 100644
> --- a/drivers/mux/core.c
> +++ b/drivers/mux/core.c
> @@ -30,12 +30,13 @@
> #define MUX_CACHE_UNKNOWN MUX_IDLE_AS_IS
>
> /**
> - * struct mux_state - Represents a mux controller specific to a given device
> - * @mux: Pointer to a mux controller
> - * @state State of the mux to be set
> + * struct mux_state - Represents a mux controller state specific to a given
> + * consumer.
> + * @mux: Pointer to a mux controller.
> + * @state State of the mux to be selected.
> *
> - * This structure is specific to a device that acquires it and has information
> - * specific to the device.
> + * This structure is specific to the consumer that acquires it and has
> + * information specific to that consumer.
> */
> struct mux_state {
> struct mux_control *mux;
> @@ -354,7 +355,8 @@ static void mux_control_delay(struct mux_control *mux, unsigned int delay_us)
> * On successfully selecting the mux-control state, it will be locked until
> * there is a call to mux_control_deselect(). If the mux-control is already
> * selected when mux_control_select() is called, the caller will be blocked
> - * until mux_control_deselect() is called (by someone else).
> + * until mux_control_deselect() or mux_state_deselect() is called (by someone
> + * else).
> *
> * Therefore, make sure to call mux_control_deselect() when the operation is
> * complete and the mux-control is free for others to use, but do not call
> @@ -384,16 +386,15 @@ int mux_control_select_delay(struct mux_control *mux, unsigned int state,
> EXPORT_SYMBOL_GPL(mux_control_select_delay);
>
> /**
> - * mux_state_select_delay() - Select mux-state
> - * @mstate: The mux-state to select
> - * @delay_us: The time to delay (in microseconds) if the mux control
> - * changes state on select
> + * mux_state_select_delay() - Select the given multiplexer state.
> + * @mstate: The mux-state to select.
> + * @delay_us: The time to delay (in microseconds) if the mux state is changed.
> *
> - * On successfully selecting the mux-state, it will be locked until
> - * there is a call to mux_state_deselect() or mux_control_deselect().
> - * If the mux-control is already selected when mux_state_select() is
> - * called, the caller will be blocked until mux_state_deselect() or
> - * mux_control_deselect() is called (by someone else).
> + * On successfully selecting the mux-state, its mux-control will be locked
> + * until there is a call to mux_state_deselect(). If the mux-control is already
> + * selected when mux_state_select() is called, the caller will be blocked
> + * until mux_state_deselect() or mux_control_deselect() is called (by someone
> + * else).
> *
> * Therefore, make sure to call mux_state_deselect() when the operation is
> * complete and the mux-control is free for others to use, but do not call
> @@ -415,7 +416,7 @@ EXPORT_SYMBOL_GPL(mux_state_select_delay);
> * @delay_us: The time to delay (in microseconds) if the mux state is changed.
> *
> * On successfully selecting the mux-control state, it will be locked until
> - * mux_control_deselect() or mux_state_deselect() called.
> + * mux_control_deselect() called.
> *
> * Therefore, make sure to call mux_control_deselect() when the operation is
> * complete and the mux-control is free for others to use, but do not call
> @@ -444,12 +445,12 @@ int mux_control_try_select_delay(struct mux_control *mux, unsigned int state,
> EXPORT_SYMBOL_GPL(mux_control_try_select_delay);
>
> /**
> - * mux_state_try_select_delay() - Try to select the mux-state.
> - * @mstate: The mux-state to select
> + * mux_state_try_select_delay() - Try to select the given multiplexer state.
> + * @mstate: The mux-state to select.
> * @delay_us: The time to delay (in microseconds) if the mux state is changed.
> *
> - * On successfully selecting the mux-state, it will be locked until
> - * mux_state_deselect() or mux_control_deselect() is called.
> + * On successfully selecting the mux-state, its mux-control will be locked
> + * until mux_state_deselect() is called.
> *
> * Therefore, make sure to call mux_state_deselect() when the operation is
> * complete and the mux-control is free for others to use, but do not call
> @@ -642,26 +643,6 @@ static void devm_mux_control_release(struct device *dev, void *res)
> mux_control_put(mux);
> }
>
> -/**
> - * mux_state_put() - Put away the mux-state for good.
> - * @mstate: The mux-state to put away.
> - *
> - * mux_control_put() reverses the effects of mux_control_get().
> - */
> -void mux_state_put(struct mux_state *mstate)
> -{
> - mux_control_put(mstate->mux);
> - kfree(mstate);
> -}
> -EXPORT_SYMBOL_GPL(mux_state_put);
> -
> -static void devm_mux_state_release(struct device *dev, void *res)
> -{
> - struct mux_state *mstate = *(struct mux_state **)res;
> -
> - mux_state_put(mstate);
> -}
> -
> /**
> * devm_mux_control_get() - Get the mux-control for a device, with resource
> * management.
> @@ -692,6 +673,26 @@ struct mux_control *devm_mux_control_get(struct device *dev,
> }
> EXPORT_SYMBOL_GPL(devm_mux_control_get);
>
> +/**
> + * mux_state_put() - Put away the mux-state for good.
> + * @mstate: The mux-state to put away.
> + *
> + * mux_control_put() reverses the effects of mux_control_get().

And, a couple of minutes later, I squashed in this on top:

- * mux_control_put() reverses the effects of mux_control_get().
+ * mux_state_put() reverses the effects of mux_state_get().

Cheers,
Peter

> + */
> +void mux_state_put(struct mux_state *mstate)
> +{
> + mux_control_put(mstate->mux);
> + kfree(mstate);
> +}
> +EXPORT_SYMBOL_GPL(mux_state_put);
> +
> +static void devm_mux_state_release(struct device *dev, void *res)
> +{
> + struct mux_state *mstate = *(struct mux_state **)res;
> +
> + mux_state_put(mstate);
> +}
> +
> /**
> * devm_mux_state_get() - Get the mux-state for a device, with resource
> * management.
> diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
> index bf5abf062c21..babf2a744056 100644
> --- a/include/linux/mux/consumer.h
> +++ b/include/linux/mux/consumer.h
> @@ -27,6 +27,7 @@ int __must_check mux_control_try_select_delay(struct mux_control *mux,
> unsigned int delay_us);
> int __must_check mux_state_try_select_delay(struct mux_state *mstate,
> unsigned int delay_us);
> +
> static inline int __must_check mux_control_select(struct mux_control *mux,
> unsigned int state)
> {
> @@ -37,6 +38,7 @@ static inline int __must_check mux_state_select(struct mux_state *mstate)
> {
> return mux_state_select_delay(mstate, 0);
> }
> +
> static inline int __must_check mux_control_try_select(struct mux_control *mux,
> unsigned int state)
> {
>

2021-12-18 18:36:21

by Peter Rosin

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] MUX: Add support for mux-states

Hi Aswath!

See below.

On 2021-12-17 07:26, Peter Rosin wrote:
> Hi again.
>
> On 2021-12-17 06:57, Peter Rosin wrote:
>> Hi Aswath!
>>
>> On 2021-12-02 13:40, Aswath Govindraju wrote:
>>> The following series of patches add support for reading mux
>>> state from the device tree.
>>>
>>> changes since v1:
>>> - Made grammer corrections and added more information
>>> on the usage for mux-states and mux-controls
>>>
>>> Aswath Govindraju (2):
>>> dt-bindings: mux: Document mux-states property
>>> mux: Add support for reading mux state from consumer DT node
>>>
>>> .../devicetree/bindings/mux/gpio-mux.yaml | 11 +-
>>> .../devicetree/bindings/mux/mux-consumer.yaml | 21 ++
>>> .../bindings/mux/mux-controller.yaml | 26 ++-
>>> drivers/mux/core.c | 219 ++++++++++++++++--
>>> include/linux/mux/consumer.h | 19 +-
>>> 5 files changed, 271 insertions(+), 25 deletions(-)
>>>
>>
>> I finally found some time to have a last look at this (fingers crossed) and
>> pushed it out for testing in linux-next.
>>
>> I did end up squashing in these trivial changes in patch 2/2, I hope that's
>> fine with you. Just holler if not...
>>
>> Cheers,
>> Peter
>>
>> diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
>> index 148e19381b79..5018403fe82f 100644
>> --- a/Documentation/driver-api/driver-model/devres.rst
>> +++ b/Documentation/driver-api/driver-model/devres.rst
>> @@ -368,6 +368,7 @@ MUX
>> devm_mux_chip_alloc()
>> devm_mux_chip_register()
>> devm_mux_control_get()
>> + devm_mux_state_get()
>>
>> NET
>> devm_alloc_etherdev()
>> diff --git a/drivers/mux/core.c b/drivers/mux/core.c
>> index 7355c5ad41f7..bf448069ca85 100644
>> --- a/drivers/mux/core.c
>> +++ b/drivers/mux/core.c
>> @@ -30,12 +30,13 @@
>> #define MUX_CACHE_UNKNOWN MUX_IDLE_AS_IS
>>
>> /**
>> - * struct mux_state - Represents a mux controller specific to a given device
>> - * @mux: Pointer to a mux controller
>> - * @state State of the mux to be set
>> + * struct mux_state - Represents a mux controller state specific to a given
>> + * consumer.
>> + * @mux: Pointer to a mux controller.
>> + * @state State of the mux to be selected.
>> *
>> - * This structure is specific to a device that acquires it and has information
>> - * specific to the device.
>> + * This structure is specific to the consumer that acquires it and has
>> + * information specific to that consumer.
>> */
>> struct mux_state {
>> struct mux_control *mux;
>> @@ -354,7 +355,8 @@ static void mux_control_delay(struct mux_control *mux, unsigned int delay_us)
>> * On successfully selecting the mux-control state, it will be locked until
>> * there is a call to mux_control_deselect(). If the mux-control is already
>> * selected when mux_control_select() is called, the caller will be blocked
>> - * until mux_control_deselect() is called (by someone else).
>> + * until mux_control_deselect() or mux_state_deselect() is called (by someone
>> + * else).
>> *
>> * Therefore, make sure to call mux_control_deselect() when the operation is
>> * complete and the mux-control is free for others to use, but do not call
>> @@ -384,16 +386,15 @@ int mux_control_select_delay(struct mux_control *mux, unsigned int state,
>> EXPORT_SYMBOL_GPL(mux_control_select_delay);
>>
>> /**
>> - * mux_state_select_delay() - Select mux-state
>> - * @mstate: The mux-state to select
>> - * @delay_us: The time to delay (in microseconds) if the mux control
>> - * changes state on select
>> + * mux_state_select_delay() - Select the given multiplexer state.
>> + * @mstate: The mux-state to select.
>> + * @delay_us: The time to delay (in microseconds) if the mux state is changed.
>> *
>> - * On successfully selecting the mux-state, it will be locked until
>> - * there is a call to mux_state_deselect() or mux_control_deselect().
>> - * If the mux-control is already selected when mux_state_select() is
>> - * called, the caller will be blocked until mux_state_deselect() or
>> - * mux_control_deselect() is called (by someone else).
>> + * On successfully selecting the mux-state, its mux-control will be locked
>> + * until there is a call to mux_state_deselect(). If the mux-control is already
>> + * selected when mux_state_select() is called, the caller will be blocked
>> + * until mux_state_deselect() or mux_control_deselect() is called (by someone
>> + * else).
>> *
>> * Therefore, make sure to call mux_state_deselect() when the operation is
>> * complete and the mux-control is free for others to use, but do not call
>> @@ -415,7 +416,7 @@ EXPORT_SYMBOL_GPL(mux_state_select_delay);
>> * @delay_us: The time to delay (in microseconds) if the mux state is changed.
>> *
>> * On successfully selecting the mux-control state, it will be locked until
>> - * mux_control_deselect() or mux_state_deselect() called.
>> + * mux_control_deselect() called.
>> *
>> * Therefore, make sure to call mux_control_deselect() when the operation is
>> * complete and the mux-control is free for others to use, but do not call
>> @@ -444,12 +445,12 @@ int mux_control_try_select_delay(struct mux_control *mux, unsigned int state,
>> EXPORT_SYMBOL_GPL(mux_control_try_select_delay);
>>
>> /**
>> - * mux_state_try_select_delay() - Try to select the mux-state.
>> - * @mstate: The mux-state to select
>> + * mux_state_try_select_delay() - Try to select the given multiplexer state.
>> + * @mstate: The mux-state to select.
>> * @delay_us: The time to delay (in microseconds) if the mux state is changed.
>> *
>> - * On successfully selecting the mux-state, it will be locked until
>> - * mux_state_deselect() or mux_control_deselect() is called.
>> + * On successfully selecting the mux-state, its mux-control will be locked
>> + * until mux_state_deselect() is called.
>> *
>> * Therefore, make sure to call mux_state_deselect() when the operation is
>> * complete and the mux-control is free for others to use, but do not call
>> @@ -642,26 +643,6 @@ static void devm_mux_control_release(struct device *dev, void *res)
>> mux_control_put(mux);
>> }
>>
>> -/**
>> - * mux_state_put() - Put away the mux-state for good.
>> - * @mstate: The mux-state to put away.
>> - *
>> - * mux_control_put() reverses the effects of mux_control_get().
>> - */
>> -void mux_state_put(struct mux_state *mstate)
>> -{
>> - mux_control_put(mstate->mux);
>> - kfree(mstate);
>> -}
>> -EXPORT_SYMBOL_GPL(mux_state_put);
>> -
>> -static void devm_mux_state_release(struct device *dev, void *res)
>> -{
>> - struct mux_state *mstate = *(struct mux_state **)res;
>> -
>> - mux_state_put(mstate);
>> -}
>> -
>> /**
>> * devm_mux_control_get() - Get the mux-control for a device, with resource
>> * management.
>> @@ -692,6 +673,26 @@ struct mux_control *devm_mux_control_get(struct device *dev,
>> }
>> EXPORT_SYMBOL_GPL(devm_mux_control_get);
>>
>> +/**
>> + * mux_state_put() - Put away the mux-state for good.
>> + * @mstate: The mux-state to put away.
>> + *
>> + * mux_control_put() reverses the effects of mux_control_get().
>
> And, a couple of minutes later, I squashed in this on top:
>
> - * mux_control_put() reverses the effects of mux_control_get().
> + * mux_state_put() reverses the effects of mux_state_get().
>

And now I notice that there is no mux_state_get. There should be one,
in my opinion, at least if there is an exported mux_state_put.

So, Aswath, can you please test the patch that's coming as a reply
to this message on top of what is currently on its way into linux-next?

I.e. wait for the next linux-next to be released, or
https://gitlab.com/peda-linux/mux.git#for-next

Or, optionally, just grab the mux-state-get branch:

https://gitlab.com/peda-linux/mux.git#mux-state-get

Cheers,
Peter

>
>> + */
>> +void mux_state_put(struct mux_state *mstate)
>> +{
>> + mux_control_put(mstate->mux);
>> + kfree(mstate);
>> +}
>> +EXPORT_SYMBOL_GPL(mux_state_put);
>> +
>> +static void devm_mux_state_release(struct device *dev, void *res)
>> +{
>> + struct mux_state *mstate = *(struct mux_state **)res;
>> +
>> + mux_state_put(mstate);
>> +}
>> +
>> /**
>> * devm_mux_state_get() - Get the mux-state for a device, with resource
>> * management.
>> diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
>> index bf5abf062c21..babf2a744056 100644
>> --- a/include/linux/mux/consumer.h
>> +++ b/include/linux/mux/consumer.h
>> @@ -27,6 +27,7 @@ int __must_check mux_control_try_select_delay(struct mux_control *mux,
>> unsigned int delay_us);
>> int __must_check mux_state_try_select_delay(struct mux_state *mstate,
>> unsigned int delay_us);
>> +
>> static inline int __must_check mux_control_select(struct mux_control *mux,
>> unsigned int state)
>> {
>> @@ -37,6 +38,7 @@ static inline int __must_check mux_state_select(struct mux_state *mstate)
>> {
>> return mux_state_select_delay(mstate, 0);
>> }
>> +
>> static inline int __must_check mux_control_try_select(struct mux_control *mux,
>> unsigned int state)
>> {
>>

2021-12-18 18:37:43

by Peter Rosin

[permalink] [raw]
Subject: [PATCH] mux: add missing mux_state_get

And implement devm_mux_state_get in terms of the new function.

Signed-off-by: Peter Rosin <[email protected]>
---
drivers/mux/core.c | 41 ++++++++++++++++++++++++++----------
include/linux/mux/consumer.h | 1 +
2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index 7d38e7c0c02e..90073ce01539 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -673,6 +673,33 @@ struct mux_control *devm_mux_control_get(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_mux_control_get);

+/**
+ * mux_state_get() - Get the mux-state for a device.
+ * @dev: The device that needs a mux-state.
+ * @mux_name: The name identifying the mux-state.
+ *
+ * Return: A pointer to the mux-state, or an ERR_PTR with a negative errno.
+ */
+struct mux_state *mux_state_get(struct device *dev, const char *mux_name)
+{
+ struct mux_state *mstate;
+
+ mstate = kzalloc(sizeof(*mstate), GFP_KERNEL);
+ if (!mstate)
+ return ERR_PTR(-ENOMEM);
+
+ mstate->mux = mux_get(dev, mux_name, &mstate->state);
+ if (IS_ERR(mstate->mux)) {
+ int err = PTR_ERR(mstate->mux);
+
+ kfree(mstate);
+ return ERR_PTR(err);
+ }
+
+ return mstate;
+}
+EXPORT_SYMBOL_GPL(mux_state_get);
+
/**
* mux_state_put() - Put away the mux-state for good.
* @mstate: The mux-state to put away.
@@ -705,25 +732,17 @@ struct mux_state *devm_mux_state_get(struct device *dev,
const char *mux_name)
{
struct mux_state **ptr, *mstate;
- struct mux_control *mux_ctrl;
- int state;
-
- mstate = devm_kzalloc(dev, sizeof(struct mux_state), GFP_KERNEL);
- if (!mstate)
- return ERR_PTR(-ENOMEM);

ptr = devres_alloc(devm_mux_state_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);

- mux_ctrl = mux_get(dev, mux_name, &state);
- if (IS_ERR(mux_ctrl)) {
+ mstate = mux_state_get(dev, mux_name);
+ if (IS_ERR(mstate)) {
devres_free(ptr);
- return (struct mux_state *)mux_ctrl;
+ return mstate;
}

- mstate->mux = mux_ctrl;
- mstate->state = state;
*ptr = mstate;
devres_add(dev, ptr);

diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
index babf2a744056..944678604549 100644
--- a/include/linux/mux/consumer.h
+++ b/include/linux/mux/consumer.h
@@ -54,6 +54,7 @@ int mux_control_deselect(struct mux_control *mux);
int mux_state_deselect(struct mux_state *mstate);

struct mux_control *mux_control_get(struct device *dev, const char *mux_name);
+struct mux_state *mux_state_get(struct device *dev, const char *mux_name);
void mux_control_put(struct mux_control *mux);
void mux_state_put(struct mux_state *mstate);

--
2.20.1



2021-12-20 06:57:29

by Aswath Govindraju

[permalink] [raw]
Subject: Re: [PATCH] mux: add missing mux_state_get


On 19/12/21 12:07 am, Peter Rosin wrote:
> And implement devm_mux_state_get in terms of the new function.
>
> Signed-off-by: Peter Rosin <[email protected]>

Tested-by: Aswath Govindraju <[email protected]>

Thanks,
Aswath

> ---
> drivers/mux/core.c | 41 ++++++++++++++++++++++++++----------
> include/linux/mux/consumer.h | 1 +
> 2 files changed, 31 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mux/core.c b/drivers/mux/core.c
> index 7d38e7c0c02e..90073ce01539 100644
> --- a/drivers/mux/core.c
> +++ b/drivers/mux/core.c
> @@ -673,6 +673,33 @@ struct mux_control *devm_mux_control_get(struct device *dev,
> }
> EXPORT_SYMBOL_GPL(devm_mux_control_get);
>
> +/**
> + * mux_state_get() - Get the mux-state for a device.
> + * @dev: The device that needs a mux-state.
> + * @mux_name: The name identifying the mux-state.
> + *
> + * Return: A pointer to the mux-state, or an ERR_PTR with a negative errno.
> + */
> +struct mux_state *mux_state_get(struct device *dev, const char *mux_name)
> +{
> + struct mux_state *mstate;
> +
> + mstate = kzalloc(sizeof(*mstate), GFP_KERNEL);
> + if (!mstate)
> + return ERR_PTR(-ENOMEM);
> +
> + mstate->mux = mux_get(dev, mux_name, &mstate->state);
> + if (IS_ERR(mstate->mux)) {
> + int err = PTR_ERR(mstate->mux);
> +
> + kfree(mstate);
> + return ERR_PTR(err);
> + }
> +
> + return mstate;
> +}
> +EXPORT_SYMBOL_GPL(mux_state_get);
> +
> /**
> * mux_state_put() - Put away the mux-state for good.
> * @mstate: The mux-state to put away.
> @@ -705,25 +732,17 @@ struct mux_state *devm_mux_state_get(struct device *dev,
> const char *mux_name)
> {
> struct mux_state **ptr, *mstate;
> - struct mux_control *mux_ctrl;
> - int state;
> -
> - mstate = devm_kzalloc(dev, sizeof(struct mux_state), GFP_KERNEL);
> - if (!mstate)
> - return ERR_PTR(-ENOMEM);
>
> ptr = devres_alloc(devm_mux_state_release, sizeof(*ptr), GFP_KERNEL);
> if (!ptr)
> return ERR_PTR(-ENOMEM);
>
> - mux_ctrl = mux_get(dev, mux_name, &state);
> - if (IS_ERR(mux_ctrl)) {
> + mstate = mux_state_get(dev, mux_name);
> + if (IS_ERR(mstate)) {
> devres_free(ptr);
> - return (struct mux_state *)mux_ctrl;
> + return mstate;
> }
>
> - mstate->mux = mux_ctrl;
> - mstate->state = state;
> *ptr = mstate;
> devres_add(dev, ptr);
>
> diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h
> index babf2a744056..944678604549 100644
> --- a/include/linux/mux/consumer.h
> +++ b/include/linux/mux/consumer.h
> @@ -54,6 +54,7 @@ int mux_control_deselect(struct mux_control *mux);
> int mux_state_deselect(struct mux_state *mstate);
>
> struct mux_control *mux_control_get(struct device *dev, const char *mux_name);
> +struct mux_state *mux_state_get(struct device *dev, const char *mux_name);
> void mux_control_put(struct mux_control *mux);
> void mux_state_put(struct mux_state *mstate);
>
>


2021-12-20 08:50:26

by Peter Rosin

[permalink] [raw]
Subject: Re: [PATCH] mux: add missing mux_state_get

On 2021-12-20 07:57, Aswath Govindraju wrote:
>
> On 19/12/21 12:07 am, Peter Rosin wrote:
>> And implement devm_mux_state_get in terms of the new function.
>>
>> Signed-off-by: Peter Rosin <[email protected]>
>
> Tested-by: Aswath Govindraju <[email protected]>

Thanks!

I added the commit to the for-next branch. I will pass these mux
patches on to Greg when they have been in linux-next for a couple
of days for the bots to chew on. I can't be sure this will make
5.17-rc1 though, when we're already at 5.16-rc6 and the hollidays
are coming up.

We'll see.

Cheers,
Peter