[PATCH] extcon: remove unused support for mutually exclusive cables

From: Heiner Kallweit

Date: Mon Mar 16 2026 - 19:01:13 EST


1fe189bfb0fa ("extcon: palmas: Remove the mutually_exclusive array")
removed the last user of the mutually exclusive cable support in 2015.
As no user has shown up in the last 11 yrs, let's drop support for
mutually exclusive cables.

Note: Removing the sysfs attributes is fine as they (incl. directory
"mutually_exclusive") were created only if a user declared
mutually exclusive cables. Means this doesn't break any userspace
application.

Signed-off-by: Heiner Kallweit <hkallweit1@xxxxxxxxx>
---
Documentation/ABI/testing/sysfs-class-extcon | 25 -----
drivers/extcon/extcon.c | 102 -------------------
drivers/extcon/extcon.h | 14 ---
3 files changed, 141 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-extcon b/Documentation/ABI/testing/sysfs-class-extcon
index f8e705375..782505efa 100644
--- a/Documentation/ABI/testing/sysfs-class-extcon
+++ b/Documentation/ABI/testing/sysfs-class-extcon
@@ -15,10 +15,6 @@ Description:
may have both HDMI and Charger attached, or analog audio,
video, and USB cables attached simultaneously.

- If there are cables mutually exclusive with each other,
- such binary relations may be expressed with extcon_dev's
- mutually_exclusive array.
-
What: /sys/class/extcon/.../name
Date: February 2012
Contact: MyungJoo Ham <myungjoo.ham@xxxxxxxxxxx>
@@ -57,8 +53,6 @@ Description:
# echo 0xHEX > state

This updates the whole state of the extcon device.
- Inputs of all the methods are required to meet the
- mutually_exclusive conditions if they exist.

It is recommended to use this "global" state interface if
you need to set the value atomically. The later state
@@ -80,22 +74,3 @@ Description:
state of cable "X" (integer between 0 and 31) of an extcon
device. The state value is either 0 (detached) or 1
(attached).
-
-What: /sys/class/extcon/.../mutually_exclusive/...
-Date: December 2011
-Contact: MyungJoo Ham <myungjoo.ham@xxxxxxxxxxx>
-Description:
- Shows the relations of mutually exclusiveness. For example,
- if the mutually_exclusive array of extcon device is
- {0x3, 0x5, 0xC, 0x0}, then the output is::
-
- # ls mutually_exclusive/
- 0x3
- 0x5
- 0xc
- #
-
- Note that mutually_exclusive is a sub-directory of the extcon
- device and the file names under the mutually_exclusive
- directory show the mutually-exclusive sets, not the contents
- of the files.
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index 98d85cc11..a0bcea0c4 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -243,26 +243,6 @@ static DEFINE_IDA(extcon_dev_ids);
static LIST_HEAD(extcon_dev_list);
static DEFINE_MUTEX(extcon_dev_list_lock);

-static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state)
-{
- int i;
-
- if (!edev->mutually_exclusive)
- return 0;
-
- for (i = 0; edev->mutually_exclusive[i]; i++) {
- int weight;
- u32 correspondants = new_state & edev->mutually_exclusive[i];
-
- /* calculate the total number of bits set */
- weight = hweight32(correspondants);
- if (weight > 1)
- return i + 1;
- }
-
- return 0;
-}
-
static int find_cable_index_by_id(struct extcon_dev *edev, const unsigned int id)
{
int i;
@@ -558,12 +538,6 @@ int extcon_set_state(struct extcon_dev *edev, unsigned int id, bool state)
if (!is_extcon_changed(edev, index, state))
goto out;

- if (check_mutually_exclusive(edev,
- (edev->state & ~BIT(index)) | (state & BIT(index)))) {
- ret = -EPERM;
- goto out;
- }
-
/*
* Initialize the value of extcon property before setting
* the detached state for an external connector.
@@ -1037,7 +1011,6 @@ static void extcon_dev_release(struct device *dev)
{
}

-static const char *muex_name = "mutually_exclusive";
static void dummy_sysfs_dev_release(struct device *dev)
{
}
@@ -1138,59 +1111,6 @@ static int extcon_alloc_cables(struct extcon_dev *edev)
return 0;
}

-/**
- * extcon_alloc_muex() - alloc the mutual exclusive for extcon device
- * @edev: extcon device
- *
- * Returns 0 if success or error number if fail.
- */
-static int extcon_alloc_muex(struct extcon_dev *edev)
-{
- char *name;
- int index;
-
- if (!edev)
- return -EINVAL;
-
- if (!(edev->max_supported && edev->mutually_exclusive))
- return 0;
-
- /* Count the size of mutually_exclusive array */
- for (index = 0; edev->mutually_exclusive[index]; index++)
- ;
-
- edev->attrs_muex = kzalloc_objs(*edev->attrs_muex, index + 1);
- if (!edev->attrs_muex)
- return -ENOMEM;
-
- edev->d_attrs_muex = kzalloc_objs(*edev->d_attrs_muex, index);
- if (!edev->d_attrs_muex) {
- kfree(edev->attrs_muex);
- return -ENOMEM;
- }
-
- for (index = 0; edev->mutually_exclusive[index]; index++) {
- name = kasprintf(GFP_KERNEL, "0x%x",
- edev->mutually_exclusive[index]);
- if (!name) {
- for (index--; index >= 0; index--)
- kfree(edev->d_attrs_muex[index].attr.name);
-
- kfree(edev->d_attrs_muex);
- kfree(edev->attrs_muex);
- return -ENOMEM;
- }
- sysfs_attr_init(&edev->d_attrs_muex[index].attr);
- edev->d_attrs_muex[index].attr.name = name;
- edev->d_attrs_muex[index].attr.mode = 0000;
- edev->attrs_muex[index] = &edev->d_attrs_muex[index].attr;
- }
- edev->attr_g_muex.name = muex_name;
- edev->attr_g_muex.attrs = edev->attrs_muex;
-
- return 0;
-}
-
/**
* extcon_alloc_groups() - alloc the groups for extcon device
* @edev: extcon device
@@ -1218,9 +1138,6 @@ static int extcon_alloc_groups(struct extcon_dev *edev)
for (index = 0; index < edev->max_supported; index++)
edev->extcon_dev_type.groups[index] = &edev->cables[index].attr_g;

- if (edev->mutually_exclusive)
- edev->extcon_dev_type.groups[index] = &edev->attr_g_muex;
-
edev->dev.type = &edev->extcon_dev_type;

return 0;
@@ -1280,10 +1197,6 @@ int extcon_dev_register(struct extcon_dev *edev)
if (ret < 0)
goto err_alloc_cables;

- ret = extcon_alloc_muex(edev);
- if (ret < 0)
- goto err_alloc_muex;
-
ret = extcon_alloc_groups(edev);
if (ret < 0)
goto err_alloc_groups;
@@ -1325,13 +1238,6 @@ int extcon_dev_register(struct extcon_dev *edev)
if (edev->max_supported)
kfree(edev->extcon_dev_type.groups);
err_alloc_groups:
- if (edev->max_supported && edev->mutually_exclusive) {
- for (index = 0; edev->mutually_exclusive[index]; index++)
- kfree(edev->d_attrs_muex[index].attr.name);
- kfree(edev->d_attrs_muex);
- kfree(edev->attrs_muex);
- }
-err_alloc_muex:
for (index = 0; index < edev->max_supported; index++)
kfree(edev->cables[index].attr_g.name);
if (edev->max_supported)
@@ -1370,14 +1276,6 @@ void extcon_dev_unregister(struct extcon_dev *edev)

ida_free(&extcon_dev_ids, edev->id);

- if (edev->mutually_exclusive && edev->max_supported) {
- for (index = 0; edev->mutually_exclusive[index];
- index++)
- kfree(edev->d_attrs_muex[index].attr.name);
- kfree(edev->d_attrs_muex);
- kfree(edev->attrs_muex);
- }
-
for (index = 0; index < edev->max_supported; index++)
kfree(edev->cables[index].attr_g.name);

diff --git a/drivers/extcon/extcon.h b/drivers/extcon/extcon.h
index 946182687..ac87b7083 100644
--- a/drivers/extcon/extcon.h
+++ b/drivers/extcon/extcon.h
@@ -11,14 +11,6 @@
* @supported_cable: Array of supported cable names ending with EXTCON_NONE.
* If supported_cable is NULL, cable name related APIs
* are disabled.
- * @mutually_exclusive: Array of mutually exclusive set of cables that cannot
- * be attached simultaneously. The array should be
- * ending with 0 or be NULL (no mutually exclusive cables).
- * For example, if it is {0x7, 0x30, 0}, then,
- * {0, 1}, {0, 1, 2}, {0, 2}, {1, 2}, or {4, 5} cannot
- * be attached simulataneously. {0x7, 0} is equivalent to
- * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there
- * can be no simultaneous connections.
* @dev: Device of this extcon.
* @id: Unique device ID of this extcon.
* @state: Attach/detach state of this extcon. Do not provide at
@@ -43,7 +35,6 @@ struct extcon_dev {
/* Optional user initializing data */
const char *name;
const unsigned int *supported_cable;
- const u32 *mutually_exclusive;

/* Internal data. Please do not set. */
struct device dev;
@@ -58,11 +49,6 @@ struct extcon_dev {
/* /sys/class/extcon/.../cable.n/... */
struct device_type extcon_dev_type;
struct extcon_cable *cables;
-
- /* /sys/class/extcon/.../mutually_exclusive/... */
- struct attribute_group attr_g_muex;
- struct attribute **attrs_muex;
- struct device_attribute *d_attrs_muex;
};

#endif /* __LINUX_EXTCON_INTERNAL_H__ */
--
2.53.0