Subject: linux-next: manual merge of the pinctrl tree with the mmc tree

From: Mark Brown <[email-masked]>
Date: Fri, 10 Apr 2026 14:27:48 +0100

Hi all,

Today's linux-next merge of the pinctrl tree got extensive and
concerning conflicts in:

  include/linux/mux/consumer.h
  drivers/mux/core.c

between commit:

  993bcaf32c4940 ("mux: Add helper functions for getting optional and selected mux-state")

from the mmc tree and commit:

  bb23f1b8c28be9 ("mux: add devm_mux_control_get_from_np() to get mux from child node")

from the pinctrl tree, I'm not convinced that the latter commit is ready
as devm_get_mux_control_from_np() appears to ignore the np parameter.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

This fixup is very quick and hacky, I don't have huge confidence in it.
Indeed since making it I see more failures due to devm_mux_control_get()
not being exported, I have a hard time seeing how exactly
devm_get_mux_control_from_np() is intended to work given that it ignores
the np parameter and is just a straight rename/reprototype of that
function.

diff --cc drivers/mux/core.c
index 23538de2c91b41,9ca16b37d389b2..00000000000000
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@@ -532,15 -522,15 +532,17 @@@ static struct mux_chip *of_find_mux_chi
   * @mux_name: The name identifying the mux-control.
   * @state: Pointer to where the requested state is returned, or NULL when
   *         the required multiplexer states are handled by other means.
 + * @optional: Whether to return NULL and silence errors when mux doesn't exist.
+  * @node: the device nodes, use dev->of_node if it is NULL.
   *
 - * Return: A pointer to the mux-control, or an ERR_PTR with a negative errno.
 + * Return: Pointer to the mux-control on success, an ERR_PTR with a negative
 + * errno on error, or NULL if optional is true and mux doesn't exist.
   */
  static struct mux_control *mux_get(struct device *dev, const char *mux_name,
- 				   unsigned int *state, bool optional)
 -				   unsigned int *state,
++				   unsigned int *state, bool optional,
+ 				   struct device_node *node)
  {
- 	struct device_node *np = dev->of_node;
+ 	struct device_node *np = node ? node : dev->of_node;
  	struct of_phandle_args args;
  	struct mux_chip *mux_chip;
  	unsigned int controller;
@@@ -635,29 -619,10 +637,29 @@@
   */
  struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
  {
- 	struct mux_control *mux = mux_get(dev, mux_name, NULL, false);
 -	return mux_get(dev, mux_name, NULL, NULL);
++	struct mux_control *mux = mux_get(dev, mux_name, NULL, false, NULL);
 +
 +	if (!mux)
 +		return ERR_PTR(-ENOENT);
 +
 +	return mux;
  }
  EXPORT_SYMBOL_GPL(mux_control_get);
  
 +/**
 + * mux_control_get_optional() - Get the optional mux-control for a device.
 + * @dev: The device that needs a mux-control.
 + * @mux_name: The name identifying the mux-control.
 + *
 + * Return: Pointer to the mux-control on success, an ERR_PTR with a negative
 + * errno on error, or NULL if mux doesn't exist.
 + */
 +struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name)
 +{
- 	return mux_get(dev, mux_name, NULL, true);
++	return mux_get(dev, mux_name, NULL, true, NULL);
 +}
 +EXPORT_SYMBOL_GPL(mux_control_get_optional);
 +
  /**
   * mux_control_put() - Put away the mux-control for good.
   * @mux: The mux-control to put away.
@@@ -705,18 -672,18 +709,20 @@@ devm_mux_control_get_from_np(struct dev
  
  	return mux;
  }
- EXPORT_SYMBOL_GPL(devm_mux_control_get);
+ EXPORT_SYMBOL_GPL(devm_mux_control_get_from_np);
  
 -/*
 +/**
   * 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.
 + * @optional: Whether to return NULL and silence errors when mux doesn't exist.
+  * @np: the device nodes, use dev->of_node if it is NULL.
   *
 - * Return: A pointer to the mux-state, or an ERR_PTR with a negative errno.
 + * Return: Pointer to the mux-state on success, an ERR_PTR with a negative
 + * errno on error, or NULL if optional is true and mux doesn't exist.
   */
- static struct mux_state *mux_state_get(struct device *dev, const char *mux_name, bool optional)
+ static struct mux_state *
 -mux_state_get(struct device *dev, const char *mux_name, struct device_node *np)
++mux_state_get(struct device *dev, const char *mux_name, bool optional, struct device_node *np)
  {
  	struct mux_state *mstate;
  
@@@ -724,7 -691,7 +730,7 @@@
  	if (!mstate)
  		return ERR_PTR(-ENOMEM);
  
- 	mstate->mux = mux_get(dev, mux_name, &mstate->state, optional);
 -	mstate->mux = mux_get(dev, mux_name, &mstate->state, np);
++	mstate->mux = mux_get(dev, mux_name, &mstate->state, optional, np);
  	if (IS_ERR(mstate->mux)) {
  		int err = PTR_ERR(mstate->mux);
  
@@@ -752,139 -716,43 +758,162 @@@ static void mux_state_put(struct mux_st
  
  static void devm_mux_state_release(struct device *dev, void *res)
  {
 -	struct mux_state *mstate = *(struct mux_state **)res;
 +	struct devm_mux_state_state *devm_state = res;
  
 +	if (devm_state->exit)
 +		devm_state->exit(devm_state->mstate);
 +
 +	mux_state_put(devm_state->mstate);
 +}
 +
 +/**
 + * __devm_mux_state_get() - Get the optional mux-state for a device,
 + *			    with resource management.
 + * @dev: The device that needs a mux-state.
 + * @mux_name: The name identifying the mux-state.
 + * @optional: Whether to return NULL and silence errors when mux doesn't exist.
 + * @init: Optional function pointer for mux-state object initialisation.
 + * @exit: Optional function pointer for mux-state object cleanup on release.
 + *
 + * Return: Pointer to the mux-state on success, an ERR_PTR with a negative
 + * errno on error, or NULL if optional is true and mux doesn't exist.
 + */
 +static struct mux_state *__devm_mux_state_get(struct device *dev, const char *mux_name,
 +					      bool optional,
 +					      int (*init)(struct mux_state *mstate),
 +					      int (*exit)(struct mux_state *mstate))
 +{
 +	struct devm_mux_state_state *devm_state;
 +	struct mux_state *mstate;
 +	int ret;
 +
- 	mstate = mux_state_get(dev, mux_name, optional);
++	mstate = mux_state_get(dev, mux_name, optional, NULL);
 +	if (IS_ERR(mstate))
 +		return ERR_CAST(mstate);
 +	else if (optional && !mstate)
 +		return NULL;
 +	else if (!mstate)
 +		return ERR_PTR(-ENOENT);
 +
 +	devm_state = devres_alloc(devm_mux_state_release, sizeof(*devm_state), GFP_KERNEL);
 +	if (!devm_state) {
 +		ret = -ENOMEM;
 +		goto err_devres_alloc;
 +	}
 +
 +	if (init) {
 +		ret = init(mstate);
 +		if (ret)
 +			goto err_mux_state_init;
 +	}
 +
 +	devm_state->mstate = mstate;
 +	devm_state->exit = exit;
 +	devres_add(dev, devm_state);
 +
 +	return mstate;
 +
 +err_mux_state_init:
 +	devres_free(devm_state);
 +err_devres_alloc:
  	mux_state_put(mstate);
 +	return ERR_PTR(ret);
 +}
 +
++struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
++{
++	return __devm_mux_state_get(dev, mux_name, false, NULL, NULL);
+ }
+ 
  /**
-  * devm_mux_state_get() - Get the mux-state for a device, with resource
-  *			  management.
+  * devm_mux_state_get_from_np() - Get the mux-state for a device, with resource
+  *				  management.
   * @dev: The device that needs a mux-control.
   * @mux_name: The name identifying the mux-control.
+  * @np: the device nodes, use dev->of_node if it is NULL.
   *
   * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
 + *
 + * The mux-state will automatically be freed on release.
   */
- struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
+ struct mux_state *
+ devm_mux_state_get_from_np(struct device *dev, const char *mux_name,
+ 			   struct device_node *np)
  {
- 	return __devm_mux_state_get(dev, mux_name, false, NULL, NULL);
+ 	struct mux_state **ptr, *mstate;
+ 
+ 	ptr = devres_alloc(devm_mux_state_release, sizeof(*ptr), GFP_KERNEL);
+ 	if (!ptr)
+ 		return ERR_PTR(-ENOMEM);
+ 
 -	mstate = mux_state_get(dev, mux_name, np);
++	mstate = mux_state_get(dev, mux_name, false, np);
+ 	if (IS_ERR(mstate)) {
+ 		devres_free(ptr);
+ 		return mstate;
+ 	}
+ 
+ 	*ptr = mstate;
+ 	devres_add(dev, ptr);
+ 
+ 	return mstate;
  }
- EXPORT_SYMBOL_GPL(devm_mux_state_get);
+ EXPORT_SYMBOL_GPL(devm_mux_state_get_from_np);
  
 +/**
 + * devm_mux_state_get_optional() - Get the optional mux-state for a device,
 + *				   with resource management.
 + * @dev: The device that needs a mux-state.
 + * @mux_name: The name identifying the mux-state.
 + *
 + * Return: Pointer to the mux-state on success, an ERR_PTR with a negative
 + * errno on error, or NULL if mux doesn't exist.
 + *
 + * The mux-state will automatically be freed on release.
 + */
 +struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 +{
 +	return __devm_mux_state_get(dev, mux_name, true, NULL, NULL);
 +}
 +EXPORT_SYMBOL_GPL(devm_mux_state_get_optional);
 +
 +/**
 + * devm_mux_state_get_selected() - Get the mux-state for a device, with
 + *				   resource management.
 + * @dev: The device that needs a mux-state.
 + * @mux_name: The name identifying the mux-state.
 + *
 + * Return: Pointer to the mux-state, or an ERR_PTR with a negative errno.
 + *
 + * The returned mux-state (if valid) is already selected.
 + *
 + * The mux-state will automatically be deselected and freed on release.
 + */
 +struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name)
 +{
 +	return __devm_mux_state_get(dev, mux_name, false, mux_state_select, mux_state_deselect);
 +}
 +EXPORT_SYMBOL_GPL(devm_mux_state_get_selected);
 +
 +/**
 + * devm_mux_state_get_optional_selected() - Get the optional mux-state for
 + *					    a device, with resource management.
 + * @dev: The device that needs a mux-state.
 + * @mux_name: The name identifying the mux-state.
 + *
 + * Return: Pointer to the mux-state on success, an ERR_PTR with a negative
 + * errno on error, or NULL if mux doesn't exist.
 + *
 + * The returned mux-state (if valid) is already selected.
 + *
 + * The mux-state will automatically be deselected and freed on release.
 + */
 +struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
 +						       const char *mux_name)
 +{
 +	return __devm_mux_state_get(dev, mux_name, true, mux_state_select, mux_state_deselect);
 +}
 +EXPORT_SYMBOL_GPL(devm_mux_state_get_optional_selected);
 +
  /*
   * Using subsys_initcall instead of module_init here to try to ensure - for
   * the non-modular case - that the subsystem is initialized when mux consumers
diff --cc include/linux/mux/consumer.h
index a961861a503b33,6300e091035323..00000000000000
--- a/include/linux/mux/consumer.h
+++ b/include/linux/mux/consumer.h
@@@ -55,110 -53,20 +55,118 @@@ static inline int __must_check mux_stat
  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);
 -void mux_control_put(struct mux_control *mux);
 -
+ struct mux_control *
+ devm_mux_control_get_from_np(struct device *dev, const char *mux_name,
+ 			     struct device_node *np);
+ 
 -#define devm_mux_control_get(dev, mux_name)		\
 -	devm_mux_control_get_from_np(dev, mux_name, NULL)
 -
+ struct mux_state *
+ devm_mux_state_get_from_np(struct device *dev, const char *mux_name,
+ 			   struct device_node *np);
 -#define devm_mux_state_get(dev, mux_name)		\
 -	devm_mux_state_get_from_np(dev, mux_name, NULL)
++
 +struct mux_control *mux_control_get(struct device *dev, const char *mux_name);
 +struct mux_control *mux_control_get_optional(struct device *dev, const char *mux_name);
 +void mux_control_put(struct mux_control *mux);
 +
 +struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name);
 +struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name);
 +struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name);
 +struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name);
 +struct mux_state *devm_mux_state_get_optional_selected(struct device *dev, const char *mux_name);
 +
 +#else
 +
 +static inline unsigned int mux_control_states(struct mux_control *mux)
 +{
 +	return 0;
 +}
 +static inline int __must_check mux_control_select_delay(struct mux_control *mux,
 +							unsigned int state, unsigned int delay_us)
 +{
 +	return -EOPNOTSUPP;
 +}
 +static inline int __must_check mux_state_select_delay(struct mux_state *mstate,
 +						      unsigned int delay_us)
 +{
 +	return -EOPNOTSUPP;
 +}
 +static inline int __must_check mux_control_try_select_delay(struct mux_control *mux,
 +							    unsigned int state,
 +							    unsigned int delay_us)
 +{
 +	return -EOPNOTSUPP;
 +}
 +static inline int __must_check mux_state_try_select_delay(struct mux_state *mstate,
 +							  unsigned int delay_us)
 +{
 +	return -EOPNOTSUPP;
 +}
 +
 +static inline int __must_check mux_control_select(struct mux_control *mux,
 +						  unsigned int state)
 +{
 +	return -EOPNOTSUPP;
 +}
 +
 +static inline int __must_check mux_state_select(struct mux_state *mstate)
 +{
 +	return -EOPNOTSUPP;
 +}
 +
 +static inline int __must_check mux_control_try_select(struct mux_control *mux,
 +						      unsigned int state)
 +{
 +	return -EOPNOTSUPP;
 +}
 +
 +static inline int __must_check mux_state_try_select(struct mux_state *mstate)
 +{
 +	return -EOPNOTSUPP;
 +}
 +
 +static inline int mux_control_deselect(struct mux_control *mux)
 +{
 +	return -EOPNOTSUPP;
 +}
 +static inline int mux_state_deselect(struct mux_state *mstate)
 +{
 +	return -EOPNOTSUPP;
 +}
 +
 +static inline struct mux_control *mux_control_get(struct device *dev, const char *mux_name)
 +{
 +	return ERR_PTR(-EOPNOTSUPP);
 +}
 +static inline struct mux_control *mux_control_get_optional(struct device *dev,
 +							   const char *mux_name)
 +{
 +	return NULL;
 +}
 +static inline void mux_control_put(struct mux_control *mux) {}
 +
 +static inline struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name)
 +{
 +	return ERR_PTR(-EOPNOTSUPP);
 +}
 +static inline struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name)
 +{
 +	return ERR_PTR(-EOPNOTSUPP);
 +}
 +static inline struct mux_state *devm_mux_state_get_optional(struct device *dev,
 +							    const char *mux_name)
 +{
 +	return NULL;
 +}
 +static inline struct mux_state *devm_mux_state_get_selected(struct device *dev,
 +							    const char *mux_name)
 +{
 +	return ERR_PTR(-EOPNOTSUPP);
 +}
 +static inline struct mux_state *devm_mux_state_get_optional_selected(struct device *dev,
 +								     const char *mux_name)
 +{
 +	return NULL;
 +}
 +
 +#endif /* CONFIG_MULTIPLEXER */
  
  #endif /* _LINUX_MUX_CONSUMER_H */