Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+261 -2
+255
Documentation/driver-api/extcon.rst
··· 1 + ======================= 2 + Extcon Device Subsystem 3 + ======================= 4 + 5 + Overview 6 + ======== 7 + 8 + The Extcon (External Connector) subsystem provides a unified framework for 9 + managing external connectors in Linux systems. It allows drivers to report 10 + the state of external connectors and provides a standardized interface for 11 + userspace to query and monitor these states. 12 + 13 + Extcon is particularly useful in modern devices with multiple connectivity 14 + options, such as smartphones, tablets, and laptops. It helps manage various 15 + types of connectors, including: 16 + 17 + 1. USB connectors (e.g., USB-C, micro-USB) 18 + 2. Charging ports (e.g., fast charging, wireless charging) 19 + 3. Audio jacks (e.g., 3.5mm headphone jack) 20 + 4. Video outputs (e.g., HDMI, DisplayPort) 21 + 5. Docking stations 22 + 23 + Real-world examples: 24 + 25 + 1. Smartphone USB-C port: 26 + A single USB-C port on a smartphone can serve multiple functions. Extcon 27 + can manage the different states of this port, such as: 28 + - USB data connection 29 + - Charging (various types like fast charging, USB Power Delivery) 30 + - Audio output (USB-C headphones) 31 + - Video output (USB-C to HDMI adapter) 32 + 33 + 2. Laptop docking station: 34 + When a laptop is connected to a docking station, multiple connections are 35 + made simultaneously. Extcon can handle the state changes for: 36 + - Power delivery 37 + - External displays 38 + - USB hub connections 39 + - Ethernet connectivity 40 + 41 + 3. Wireless charging pad: 42 + Extcon can manage the state of a wireless charging connection, allowing 43 + the system to respond appropriately when a device is placed on or removed 44 + from the charging pad. 45 + 46 + 4. Smart TV HDMI ports: 47 + In a smart TV, Extcon can manage multiple HDMI ports, detecting when 48 + devices are connected or disconnected, and potentially identifying the 49 + type of device (e.g., gaming console, set-top box, Blu-ray player). 50 + 51 + The Extcon framework simplifies the development of drivers for these complex 52 + scenarios by providing a standardized way to report and query connector 53 + states, handle mutually exclusive connections, and manage connector 54 + properties. This allows for more robust and flexible handling of external 55 + connections in modern devices. 56 + 57 + Key Components 58 + ============== 59 + 60 + extcon_dev 61 + ---------- 62 + 63 + The core structure representing an Extcon device:: 64 + 65 + struct extcon_dev { 66 + const char *name; 67 + const unsigned int *supported_cable; 68 + const u32 *mutually_exclusive; 69 + 70 + /* Internal data */ 71 + struct device dev; 72 + unsigned int id; 73 + struct raw_notifier_head nh_all; 74 + struct raw_notifier_head *nh; 75 + struct list_head entry; 76 + int max_supported; 77 + spinlock_t lock; 78 + u32 state; 79 + 80 + /* Sysfs related */ 81 + struct device_type extcon_dev_type; 82 + struct extcon_cable *cables; 83 + struct attribute_group attr_g_muex; 84 + struct attribute **attrs_muex; 85 + struct device_attribute *d_attrs_muex; 86 + }; 87 + 88 + Key fields: 89 + 90 + - ``name``: Name of the Extcon device 91 + - ``supported_cable``: Array of supported cable types 92 + - ``mutually_exclusive``: Array defining mutually exclusive cable types 93 + This field is crucial for enforcing hardware constraints. It's an array of 94 + 32-bit unsigned integers, where each element represents a set of mutually 95 + exclusive cable types. The array should be terminated with a 0. 96 + 97 + For example: 98 + 99 + :: 100 + 101 + static const u32 mutually_exclusive[] = { 102 + BIT(0) | BIT(1), /* Cable 0 and 1 are mutually exclusive */ 103 + BIT(2) | BIT(3) | BIT(4), /* Cables 2, 3, and 4 are mutually exclusive */ 104 + 0 /* Terminator */ 105 + }; 106 + 107 + In this example, cables 0 and 1 cannot be connected simultaneously, and 108 + cables 2, 3, and 4 are also mutually exclusive. This is useful for 109 + scenarios like a single port that can either be USB or HDMI, but not both 110 + at the same time. 111 + 112 + The Extcon core uses this information to prevent invalid combinations of 113 + cable states, ensuring that the reported states are always consistent 114 + with the hardware capabilities. 115 + 116 + - ``state``: Current state of the device (bitmap of connected cables) 117 + 118 + 119 + extcon_cable 120 + ------------ 121 + 122 + Represents an individual cable managed by an Extcon device:: 123 + 124 + struct extcon_cable { 125 + struct extcon_dev *edev; 126 + int cable_index; 127 + struct attribute_group attr_g; 128 + struct device_attribute attr_name; 129 + struct device_attribute attr_state; 130 + struct attribute *attrs[3]; 131 + union extcon_property_value usb_propval[EXTCON_PROP_USB_CNT]; 132 + union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT]; 133 + union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT]; 134 + union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT]; 135 + DECLARE_BITMAP(usb_bits, EXTCON_PROP_USB_CNT); 136 + DECLARE_BITMAP(chg_bits, EXTCON_PROP_CHG_CNT); 137 + DECLARE_BITMAP(jack_bits, EXTCON_PROP_JACK_CNT); 138 + DECLARE_BITMAP(disp_bits, EXTCON_PROP_DISP_CNT); 139 + }; 140 + 141 + Core Functions 142 + ============== 143 + 144 + .. kernel-doc:: drivers/extcon/extcon.c 145 + :identifiers: extcon_get_state 146 + 147 + .. kernel-doc:: drivers/extcon/extcon.c 148 + :identifiers: extcon_set_state 149 + 150 + .. kernel-doc:: drivers/extcon/extcon.c 151 + :identifiers: extcon_set_state_sync 152 + 153 + .. kernel-doc:: drivers/extcon/extcon.c 154 + :identifiers: extcon_get_property 155 + 156 + 157 + Sysfs Interface 158 + =============== 159 + 160 + Extcon devices expose the following sysfs attributes: 161 + 162 + - ``name``: Name of the Extcon device 163 + - ``state``: Current state of all supported cables 164 + - ``cable.N/name``: Name of the Nth supported cable 165 + - ``cable.N/state``: State of the Nth supported cable 166 + 167 + Usage Example 168 + ------------- 169 + 170 + .. code-block:: c 171 + 172 + #include <linux/module.h> 173 + #include <linux/platform_device.h> 174 + #include <linux/extcon.h> 175 + 176 + struct my_extcon_data { 177 + struct extcon_dev *edev; 178 + struct device *dev; 179 + }; 180 + 181 + static const unsigned int my_extcon_cable[] = { 182 + EXTCON_USB, 183 + EXTCON_USB_HOST, 184 + EXTCON_NONE, 185 + }; 186 + 187 + static int my_extcon_probe(struct platform_device *pdev) 188 + { 189 + struct my_extcon_data *data; 190 + int ret; 191 + 192 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 193 + if (!data) 194 + return -ENOMEM; 195 + 196 + data->dev = &pdev->dev; 197 + 198 + /* Initialize extcon device */ 199 + data->edev = devm_extcon_dev_allocate(data->dev, my_extcon_cable); 200 + if (IS_ERR(data->edev)) { 201 + dev_err(data->dev, "Failed to allocate extcon device\n"); 202 + return PTR_ERR(data->edev); 203 + } 204 + 205 + /* Register extcon device */ 206 + ret = devm_extcon_dev_register(data->dev, data->edev); 207 + if (ret < 0) { 208 + dev_err(data->dev, "Failed to register extcon device\n"); 209 + return ret; 210 + } 211 + 212 + platform_set_drvdata(pdev, data); 213 + 214 + /* Example: Set initial state */ 215 + extcon_set_state_sync(data->edev, EXTCON_USB, true); 216 + 217 + dev_info(data->dev, "My extcon driver probed successfully\n"); 218 + return 0; 219 + } 220 + 221 + static int my_extcon_remove(struct platform_device *pdev) 222 + { 223 + struct my_extcon_data *data = platform_get_drvdata(pdev); 224 + 225 + /* Example: Clear state before removal */ 226 + extcon_set_state_sync(data->edev, EXTCON_USB, false); 227 + 228 + dev_info(data->dev, "My extcon driver removed\n"); 229 + return 0; 230 + } 231 + 232 + static const struct of_device_id my_extcon_of_match[] = { 233 + { .compatible = "my,extcon-device", }, 234 + { }, 235 + }; 236 + MODULE_DEVICE_TABLE(of, my_extcon_of_match); 237 + 238 + static struct platform_driver my_extcon_driver = { 239 + .driver = { 240 + .name = "my-extcon-driver", 241 + .of_match_table = my_extcon_of_match, 242 + }, 243 + .probe = my_extcon_probe, 244 + .remove = my_extcon_remove, 245 + }; 246 + 247 + module_platform_driver(my_extcon_driver); 248 + 249 + This example demonstrates: 250 + --------------------------- 251 + 252 + - Defining supported cable types (USB and USB Host in this case). 253 + - Allocating and registering an extcon device. 254 + - Setting an initial state for a cable (USB connected in this example). 255 + - Clearing the state when the driver is removed.
+1
Documentation/driver-api/index.rst
··· 86 86 dmaengine/index 87 87 dpll 88 88 edac 89 + extcon 89 90 firmware/index 90 91 fpga/index 91 92 frame-buffer
+1
MAINTAINERS
··· 8637 8637 S: Maintained 8638 8638 T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git 8639 8639 F: Documentation/devicetree/bindings/extcon/ 8640 + F: Documentation/driver-api/extcon.rst 8640 8641 F: Documentation/firmware-guide/acpi/extcon-intel-int3496.rst 8641 8642 F: drivers/extcon/ 8642 8643 F: include/linux/extcon.h
+1 -1
drivers/extcon/extcon-fsa9480.c
··· 350 350 }; 351 351 352 352 static const struct i2c_device_id fsa9480_id[] = { 353 - { "fsa9480", 0 }, 353 + { "fsa9480" }, 354 354 {} 355 355 }; 356 356 MODULE_DEVICE_TABLE(i2c, fsa9480_id);
+1 -1
drivers/extcon/extcon-ptn5150.c
··· 338 338 MODULE_DEVICE_TABLE(of, ptn5150_dt_match); 339 339 340 340 static const struct i2c_device_id ptn5150_i2c_id[] = { 341 - { "ptn5150", 0 }, 341 + { "ptn5150" }, 342 342 { } 343 343 }; 344 344 MODULE_DEVICE_TABLE(i2c, ptn5150_i2c_id);
+2
drivers/extcon/extcon-rtk-type-c.c
··· 1369 1369 } 1370 1370 1371 1371 type_c->type_c_cfg = devm_kzalloc(dev, sizeof(*type_c_cfg), GFP_KERNEL); 1372 + if (!type_c->type_c_cfg) 1373 + return -ENOMEM; 1372 1374 1373 1375 memcpy(type_c->type_c_cfg, type_c_cfg, sizeof(*type_c_cfg)); 1374 1376