1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

Update extcon next for v6.14

Detailed description for this pull request:
 - Fix null pointer check of memory allocation on extcon-rtk-type-c.c.
 - Add EXTCON subsystem documentation including the detailed description/example.
 - Drop unneeded init of struct i2c_device_id:driver_data on extcon-fsa9480/pth5150.c.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEsSpuqBtbWtRe4rLGnM3fLN7rz1MFAmeCWgcACgkQnM3fLN7r
 z1Modg/9H5XR49+8pFZm69eGSvqWQqS5nbRDJoIDZvSpaib+zWN0VIpMRECj7n/6
 ZFqAiLrXi0r7JW3zss6O+nh5EoOM5GlpHBs2GtEPTEuLS8IDW1FTDZKvyEBG9Fzh
 FyPA1CKJEKoWe+6caivVR2s6ifaZDDx7gp8k6NhpXK1FVop+IhLv//yCCaR5jIN1
 WqyVme2iFbjR237CiRY4QccBgvuM4gCQEzswxmJZI8IZxjyjNXTRT7E5kUDu8Z8j
 IqYzGubqgoWVPUKCRmi0aw+WZ6EcjBjC8MuJJhopF6QiW4NG+EWF6ZXscVzTOys2
 6h24fypyaxM9cA76KbtXue2j/zVNHE62wfy+44IG1x58aT5U9tMWh3UVo9/PG3nJ
 jXwbAot0iV0yJtqK28Dcj1BE0oFEgWcluo2mNWO1H+i91AGzSl0APvm03Xrja9Mf
 k6zTbVixo9EKNM9Se9IQE9SyuvhD9C6UgVks3nG3doge8WmcXcyNnQAPF9dbNTBg
 Fc9t3biT2Du1bja7rCWhg5+4aX//NT54WxSNawm8AN4zMPBwxqmx5HcmvpNAMDDR
 8U6MH2mIhfP2cTSPi+BelveL9fj4cz7y7nCnPs4y9wyYJA6VIjUKiSJo5F3CrXFd
 uhR7gtTHpgVTluiGJbv3IskYUzqitnihKfUk62DNoB1oHktF/dQ=
 =tjVp
 -----END PGP SIGNATURE-----

Merge tag 'extcon-next-for-6.14' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon into char-misc-next

Pull extcon updates from Chanwoo:

Update extcon next for v6.14

Detailed description for this pull request:
- Fix null pointer check of memory allocation on extcon-rtk-type-c.c.
- Add EXTCON subsystem documentation including the detailed description/example.
- Drop unneeded init of struct i2c_device_id:driver_data on extcon-fsa9480/pth5150.c.

* tag 'extcon-next-for-6.14' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon:
  extcon: Drop explicit initialization of struct i2c_device_id::driver_data to 0
  Documentation: extcon: add documentation for Extcon subsystem
  extcon: realtek: fix NULL deref check in extcon_rtk_type_c_probe
This commit is contained in:
Greg Kroah-Hartman 2025-01-12 13:44:27 +01:00
commit b8ae08db7a
6 changed files with 261 additions and 2 deletions

View file

@ -0,0 +1,255 @@
=======================
Extcon Device Subsystem
=======================
Overview
========
The Extcon (External Connector) subsystem provides a unified framework for
managing external connectors in Linux systems. It allows drivers to report
the state of external connectors and provides a standardized interface for
userspace to query and monitor these states.
Extcon is particularly useful in modern devices with multiple connectivity
options, such as smartphones, tablets, and laptops. It helps manage various
types of connectors, including:
1. USB connectors (e.g., USB-C, micro-USB)
2. Charging ports (e.g., fast charging, wireless charging)
3. Audio jacks (e.g., 3.5mm headphone jack)
4. Video outputs (e.g., HDMI, DisplayPort)
5. Docking stations
Real-world examples:
1. Smartphone USB-C port:
A single USB-C port on a smartphone can serve multiple functions. Extcon
can manage the different states of this port, such as:
- USB data connection
- Charging (various types like fast charging, USB Power Delivery)
- Audio output (USB-C headphones)
- Video output (USB-C to HDMI adapter)
2. Laptop docking station:
When a laptop is connected to a docking station, multiple connections are
made simultaneously. Extcon can handle the state changes for:
- Power delivery
- External displays
- USB hub connections
- Ethernet connectivity
3. Wireless charging pad:
Extcon can manage the state of a wireless charging connection, allowing
the system to respond appropriately when a device is placed on or removed
from the charging pad.
4. Smart TV HDMI ports:
In a smart TV, Extcon can manage multiple HDMI ports, detecting when
devices are connected or disconnected, and potentially identifying the
type of device (e.g., gaming console, set-top box, Blu-ray player).
The Extcon framework simplifies the development of drivers for these complex
scenarios by providing a standardized way to report and query connector
states, handle mutually exclusive connections, and manage connector
properties. This allows for more robust and flexible handling of external
connections in modern devices.
Key Components
==============
extcon_dev
----------
The core structure representing an Extcon device::
struct extcon_dev {
const char *name;
const unsigned int *supported_cable;
const u32 *mutually_exclusive;
/* Internal data */
struct device dev;
unsigned int id;
struct raw_notifier_head nh_all;
struct raw_notifier_head *nh;
struct list_head entry;
int max_supported;
spinlock_t lock;
u32 state;
/* Sysfs related */
struct device_type extcon_dev_type;
struct extcon_cable *cables;
struct attribute_group attr_g_muex;
struct attribute **attrs_muex;
struct device_attribute *d_attrs_muex;
};
Key fields:
- ``name``: Name of the Extcon device
- ``supported_cable``: Array of supported cable types
- ``mutually_exclusive``: Array defining mutually exclusive cable types
This field is crucial for enforcing hardware constraints. It's an array of
32-bit unsigned integers, where each element represents a set of mutually
exclusive cable types. The array should be terminated with a 0.
For example:
::
static const u32 mutually_exclusive[] = {
BIT(0) | BIT(1), /* Cable 0 and 1 are mutually exclusive */
BIT(2) | BIT(3) | BIT(4), /* Cables 2, 3, and 4 are mutually exclusive */
0 /* Terminator */
};
In this example, cables 0 and 1 cannot be connected simultaneously, and
cables 2, 3, and 4 are also mutually exclusive. This is useful for
scenarios like a single port that can either be USB or HDMI, but not both
at the same time.
The Extcon core uses this information to prevent invalid combinations of
cable states, ensuring that the reported states are always consistent
with the hardware capabilities.
- ``state``: Current state of the device (bitmap of connected cables)
extcon_cable
------------
Represents an individual cable managed by an Extcon device::
struct extcon_cable {
struct extcon_dev *edev;
int cable_index;
struct attribute_group attr_g;
struct device_attribute attr_name;
struct device_attribute attr_state;
struct attribute *attrs[3];
union extcon_property_value usb_propval[EXTCON_PROP_USB_CNT];
union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT];
union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT];
union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT];
DECLARE_BITMAP(usb_bits, EXTCON_PROP_USB_CNT);
DECLARE_BITMAP(chg_bits, EXTCON_PROP_CHG_CNT);
DECLARE_BITMAP(jack_bits, EXTCON_PROP_JACK_CNT);
DECLARE_BITMAP(disp_bits, EXTCON_PROP_DISP_CNT);
};
Core Functions
==============
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_get_state
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_set_state
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_set_state_sync
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_get_property
Sysfs Interface
===============
Extcon devices expose the following sysfs attributes:
- ``name``: Name of the Extcon device
- ``state``: Current state of all supported cables
- ``cable.N/name``: Name of the Nth supported cable
- ``cable.N/state``: State of the Nth supported cable
Usage Example
-------------
.. code-block:: c
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/extcon.h>
struct my_extcon_data {
struct extcon_dev *edev;
struct device *dev;
};
static const unsigned int my_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_NONE,
};
static int my_extcon_probe(struct platform_device *pdev)
{
struct my_extcon_data *data;
int ret;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->dev = &pdev->dev;
/* Initialize extcon device */
data->edev = devm_extcon_dev_allocate(data->dev, my_extcon_cable);
if (IS_ERR(data->edev)) {
dev_err(data->dev, "Failed to allocate extcon device\n");
return PTR_ERR(data->edev);
}
/* Register extcon device */
ret = devm_extcon_dev_register(data->dev, data->edev);
if (ret < 0) {
dev_err(data->dev, "Failed to register extcon device\n");
return ret;
}
platform_set_drvdata(pdev, data);
/* Example: Set initial state */
extcon_set_state_sync(data->edev, EXTCON_USB, true);
dev_info(data->dev, "My extcon driver probed successfully\n");
return 0;
}
static int my_extcon_remove(struct platform_device *pdev)
{
struct my_extcon_data *data = platform_get_drvdata(pdev);
/* Example: Clear state before removal */
extcon_set_state_sync(data->edev, EXTCON_USB, false);
dev_info(data->dev, "My extcon driver removed\n");
return 0;
}
static const struct of_device_id my_extcon_of_match[] = {
{ .compatible = "my,extcon-device", },
{ },
};
MODULE_DEVICE_TABLE(of, my_extcon_of_match);
static struct platform_driver my_extcon_driver = {
.driver = {
.name = "my-extcon-driver",
.of_match_table = my_extcon_of_match,
},
.probe = my_extcon_probe,
.remove = my_extcon_remove,
};
module_platform_driver(my_extcon_driver);
This example demonstrates:
---------------------------
- Defining supported cable types (USB and USB Host in this case).
- Allocating and registering an extcon device.
- Setting an initial state for a cable (USB connected in this example).
- Clearing the state when the driver is removed.

View file

@ -86,6 +86,7 @@ Subsystem-specific APIs
dmaengine/index
dpll
edac
extcon
firmware/index
fpga/index
frame-buffer

View file

@ -8637,6 +8637,7 @@ L: linux-kernel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git
F: Documentation/devicetree/bindings/extcon/
F: Documentation/driver-api/extcon.rst
F: Documentation/firmware-guide/acpi/extcon-intel-int3496.rst
F: drivers/extcon/
F: include/linux/extcon.h

View file

@ -350,7 +350,7 @@ static const struct dev_pm_ops fsa9480_pm_ops = {
};
static const struct i2c_device_id fsa9480_id[] = {
{ "fsa9480", 0 },
{ "fsa9480" },
{}
};
MODULE_DEVICE_TABLE(i2c, fsa9480_id);

View file

@ -338,7 +338,7 @@ static const struct of_device_id ptn5150_dt_match[] = {
MODULE_DEVICE_TABLE(of, ptn5150_dt_match);
static const struct i2c_device_id ptn5150_i2c_id[] = {
{ "ptn5150", 0 },
{ "ptn5150" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ptn5150_i2c_id);

View file

@ -1369,6 +1369,8 @@ static int extcon_rtk_type_c_probe(struct platform_device *pdev)
}
type_c->type_c_cfg = devm_kzalloc(dev, sizeof(*type_c_cfg), GFP_KERNEL);
if (!type_c->type_c_cfg)
return -ENOMEM;
memcpy(type_c->type_c_cfg, type_c_cfg, sizeof(*type_c_cfg));