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
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
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]>
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)
{
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)
> {
>
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)
>> {
>>
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
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);
>
>
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