* [PATCH v2 0/2] Add support for Infineon/Intel XMM6260 modem
@ 2026-05-23 8:44 Svyatoslav Ryhel
2026-05-23 8:44 ` [PATCH v2 1/2] dt-bindings: net: Document " Svyatoslav Ryhel
2026-05-23 8:44 ` [PATCH v2 2/2] net: usb: Add Infineon XMM6260 Baseband modem support Svyatoslav Ryhel
0 siblings, 2 replies; 4+ messages in thread
From: Svyatoslav Ryhel @ 2026-05-23 8:44 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Svyatoslav Ryhel
Cc: netdev, devicetree, linux-kernel, linux-usb
The Infineon/Intel XMM6260 is a 3G-focused, slim modem platform designed
for smartphones, data cards, and Machine-to-Machine (M2M) applications.
The modem is typically connected via the application processor's USB line
in HSIC mode. To function correctly, the modem must control this line, as
it requires precise timing to initiate or de-initialize the USB connection.
This control is necessary to successfully enumerate the next stage of the
USB device loader (moving from firmware loading to the actual device
interface for example).
Patchset adds support for the generic portion of the Infineon XMM6260
baseband modem, which was used in many Tegra-, OMAP-, and Exynos-based
devices circa 2012. This driver provides generic power sequences,
manages initial communication with the application processor, handles the
SoC-specific modem powersequence, and verifies that the modem USB device
appears correctly.
While current support is relatively basic, this configuration already
allows the modem device to appear in the dmesg of my device
(LG Optimus Vu (P895)):
[ 9.427014] ci_hdrc ci_hdrc.1: EHCI Host Controller
[ 9.431488] ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus number 1
[ 9.457197] ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00
[ 9.460370] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.16
[ 9.468470] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 9.475597] usb usb1: Product: EHCI Host Controller
[ 9.480508] usb usb1: Manufacturer: Linux 6.16.0+ ehci_hcd
[ 9.485913] usb usb1: SerialNumber: ci_hdrc.1
[ 9.490862] hub 1-0:1.0: USB hub found
[ 9.494005] hub 1-0:1.0: 1 port detected
[ 9.657191] usb 1-1: new high-speed USB device number 2 using ci_hdrc
[ 9.844726] usb 1-1: New USB device found, idVendor=1519, idProduct=0020, bcdDevice=12.74
[ 9.850530] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 9.857594] usb 1-1: Product: HSIC Device
[ 9.861606] usb 1-1: Manufacturer: Comneon
[ 9.865627] usb 1-1: SerialNumber: 0123456789
[ 9.908739] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
This patchset is a part of larger series aiming to bring XMM6260 modem
support for Tegra devices:
https://lore.kernel.org/lkml/20260511135703.62470-1-clamor95@gmail.com/
---
Changes in v2:
- changed phy to pwrseq in schema
- adjusted Kconfig dependencies
- implemented bitmap for modem state tracking
- switched from phy to power sequencing
- in notifier added chech to filter only USB events
- in notifier added USB_DEVICE_REMOVE
- added tracking for regulator, rfkill access, usb device
presence and poweroff calls using bitops
- moved pseq on call from work to irq handler
- improved rfkill registration logic
---
Svyatoslav Ryhel (2):
dt-bindings: net: Document Infineon/Intel XMM6260 modem
net: usb: Add Infineon XMM6260 Baseband modem support
.../bindings/net/infineon,xmm6260.yaml | 74 ++++
drivers/net/usb/Kconfig | 15 +
drivers/net/usb/Makefile | 1 +
drivers/net/usb/baseband-xmm6260.c | 378 ++++++++++++++++++
4 files changed, 468 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/infineon,xmm6260.yaml
create mode 100644 drivers/net/usb/baseband-xmm6260.c
--
2.51.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] dt-bindings: net: Document Infineon/Intel XMM6260 modem
2026-05-23 8:44 [PATCH v2 0/2] Add support for Infineon/Intel XMM6260 modem Svyatoslav Ryhel
@ 2026-05-23 8:44 ` Svyatoslav Ryhel
2026-05-23 8:44 ` [PATCH v2 2/2] net: usb: Add Infineon XMM6260 Baseband modem support Svyatoslav Ryhel
1 sibling, 0 replies; 4+ messages in thread
From: Svyatoslav Ryhel @ 2026-05-23 8:44 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Svyatoslav Ryhel
Cc: netdev, devicetree, linux-kernel, linux-usb
Describe the Infineon/Intel XMM6260, a 3G-focused, slim modem platform
designed for smartphones, data cards, and Machine-to-Machine (M2M)
applications.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../bindings/net/infineon,xmm6260.yaml | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/infineon,xmm6260.yaml
diff --git a/Documentation/devicetree/bindings/net/infineon,xmm6260.yaml b/Documentation/devicetree/bindings/net/infineon,xmm6260.yaml
new file mode 100644
index 000000000000..ffff58e479ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/infineon,xmm6260.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/infineon,xmm6260.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Infineon/Intel XMM6260 embedded USB modem
+
+description:
+ The Infineon/Intel XMM6260 is a 3G-focused, slim modem platform designed
+ for smartphones, data cards, and Machine-to-Machine (M2M) applications.
+ The modem is usually connected via the application processor's USB line
+ in HSIC mode; however, to work properly, the modem must control this line.
+
+maintainers:
+ - Svyatoslav Ryhel <clamor95@gmail.com>
+
+properties:
+ compatible:
+ const: infineon,xmm6260
+
+ interrupts:
+ maxItems: 1
+
+ enable-gpios:
+ description: GPIO connected to the ON1 pin
+ maxItems: 1
+
+ reset-gpios:
+ description: GPIO connected to the RESET_PWRDWN_N pin
+ maxItems: 1
+
+ ap-wake-gpios:
+ description: GPIO connected to the EINT3 pin
+ maxItems: 1
+
+ cp-wake-gpios:
+ description: GPIO connected to the EINT2 pin
+ maxItems: 1
+
+ vbat-supply:
+ description: Supply connected to the VBAT lines.
+
+ infineon,modem-pwrseq:
+ description:
+ Contains phandle pointing to the modem's power sequence.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+required:
+ - compatible
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ modem {
+ compatible = "infineon,xmm6260";
+
+ interrupt-parent = <&gpio>;
+ interrupts = <168 IRQ_TYPE_EDGE_BOTH>;
+
+ enable-gpios = <&gpio 112 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio 169 GPIO_ACTIVE_LOW>;
+
+ cp-wake-gpios = <&gpio 151 GPIO_ACTIVE_HIGH>;
+ ap-wake-gpios = <&gpio 168 GPIO_ACTIVE_HIGH>;
+
+ infineon,modem-pwrseq = <&xmm6260_modem_pwrseq>;
+ vbat-supply = <&vdd_3v3_vbat>;
+ };
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] net: usb: Add Infineon XMM6260 Baseband modem support
2026-05-23 8:44 [PATCH v2 0/2] Add support for Infineon/Intel XMM6260 modem Svyatoslav Ryhel
2026-05-23 8:44 ` [PATCH v2 1/2] dt-bindings: net: Document " Svyatoslav Ryhel
@ 2026-05-23 8:44 ` Svyatoslav Ryhel
2026-05-27 0:38 ` Jakub Kicinski
1 sibling, 1 reply; 4+ messages in thread
From: Svyatoslav Ryhel @ 2026-05-23 8:44 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Svyatoslav Ryhel
Cc: netdev, devicetree, linux-kernel, linux-usb
The Infineon/Intel XMM6260 is a 3G-focused, slim modem platform designed
for smartphones, data cards, and Machine-to-Machine (M2M) applications.
The modem is usually connected via the application processor's USB line
in HSIC mode; however, to work properly, the modem must control this line
Dmesg with modem appearing on LG Optimus Vu (P895):
[ 9.427014] ci_hdrc ci_hdrc.1: EHCI Host Controller
[ 9.431488] ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus number 1
[ 9.457197] ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00
[ 9.460370] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.16
[ 9.468470] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 9.475597] usb usb1: Product: EHCI Host Controller
[ 9.480508] usb usb1: Manufacturer: Linux 6.16.0+ ehci_hcd
[ 9.485913] usb usb1: SerialNumber: ci_hdrc.1
[ 9.490862] hub 1-0:1.0: USB hub found
[ 9.494005] hub 1-0:1.0: 1 port detected
[ 9.657191] usb 1-1: new high-speed USB device number 2 using ci_hdrc
[ 9.844726] usb 1-1: New USB device found, idVendor=1519, idProduct=0020, bcdDevice=12.74
[ 9.850530] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 9.857594] usb 1-1: Product: HSIC Device
[ 9.861606] usb 1-1: Manufacturer: Comneon
[ 9.865627] usb 1-1: SerialNumber: 0123456789
[ 9.908739] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/net/usb/Kconfig | 15 ++
drivers/net/usb/Makefile | 1 +
drivers/net/usb/baseband-xmm6260.c | 378 +++++++++++++++++++++++++++++
3 files changed, 394 insertions(+)
create mode 100644 drivers/net/usb/baseband-xmm6260.c
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 52a5c0922c79..d54d8db752df 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -642,4 +642,19 @@ config USB_RTL8153_ECM
CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
supported by r8152 driver.
+config USB_NET_XMM6260
+ tristate "Infineon XMM626X Baseband HSPA/HSUPA modem"
+ depends on USB_CHIPIDEA && (RFKILL || RFKILL=n)
+ help
+ Select this if you want to use an Infineon XMM626X modem, found in
+ devices such as the LG Optimus 4X P880, LG Optimus Vu P895, Samsung
+ Galaxy S II (GT-I9100), and Galaxy Nexus (GT-I9250). This driver
+ handles the modem configuration and provides a stable way to expose
+ the modem's USB interface. To establish a connection, you will first
+ need a userspace program to send the correct commands to the modem
+ through its CDC ACM port, as well as a DHCP client.
+
+ To compile this driver as a module, choose M here: the module will
+ be called baseband-xmm6260.
+
endif # USB_NET_DRIVERS
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 4964f7b326fb..ffa532c7d7d6 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_USB_NET_CDC_MBIM) += cdc_mbim.o
obj-$(CONFIG_USB_NET_CH9200) += ch9200.o
obj-$(CONFIG_USB_NET_AQC111) += aqc111.o
obj-$(CONFIG_USB_RTL8153_ECM) += r8153_ecm.o
+obj-$(CONFIG_USB_NET_XMM6260) += baseband-xmm6260.o
diff --git a/drivers/net/usb/baseband-xmm6260.c b/drivers/net/usb/baseband-xmm6260.c
new file mode 100644
index 000000000000..557ec79f5e2a
--- /dev/null
+++ b/drivers/net/usb/baseband-xmm6260.c
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2011 NVIDIA Corporation
+ * Copyright (C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/pwrseq/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/rfkill.h>
+#include <linux/usb.h>
+
+#define BASEBAND_XMM_INIT_DELAY 5000
+
+#define BASEBAND_PRODUCT_ID_XMM6260 0x0020
+#define BASEBAND_VENDOR_ID_COMNEON 0x1519
+
+/*
+ * Starting from ver 1145 modem starts in the IPC_AP_WAKE_IRQ_READY state.
+ * AP wake interrupt keeps low util CP starts to initiate its HSIC hw. AP wake
+ * interrupt goes up during CP HSIC init (BASEBAND_XMM_IPC_AP_WAKE_INIT1 state)
+ * at this point Host USB bus must be configured in order for modem to set
+ * properly. Then interrupt goes down when CP HSIC is ready
+ * (BASEBAND_XMM_IPC_AP_WAKE_INIT2 state) and at this point XMM6260 USB device
+ * should appear and be accessible for further work. In case it does not, the
+ * cycle must repeat.
+ */
+
+/* bits [0:2] */
+enum baseband_xmm_ipc_ap_wake_state {
+ BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY,
+ BASEBAND_XMM_IPC_AP_WAKE_INIT1,
+ BASEBAND_XMM_IPC_AP_WAKE_INIT2,
+ BASEBAND_XMM_IPC_AP_WAKE_L,
+ BASEBAND_XMM_IPC_AP_WAKE_H,
+ BASEBAND_XMM_IPC_AP_WAKE_UNINIT,
+ BASEBAND_XMM_IPC_AP_WAKE_MASK = 7,
+};
+
+#define BASEBAND_XMM_IPC_AP_WAKE_MAX 3
+
+#define BASEBAND_XMM_STATE_POWERED 3 /* Tracks regulator state */
+#define BASEBAND_XMM_STATE_PROTECTED 4 /* Prevents rfkill from access */
+#define BASEBAND_XMM_STATE_PRESENT 5 /* Tracks USB device presence */
+#define BASEBAND_XMM_STATE_POWEROFF 6 /* Prevents poweroff recursive call */
+#define BASEBAND_XMM_STATE_MAX 8
+
+struct baseband_xmm_data {
+ struct device *dev;
+ struct rfkill *rfkill_dev;
+ struct pwrseq_desc *pwrseq;
+
+ DECLARE_BITMAP(state, BASEBAND_XMM_STATE_MAX);
+ int irq;
+
+ struct gpio_desc *reset_gpio;
+ struct gpio_desc *enable_gpio;
+
+ struct gpio_desc *ipc_cp_gpio;
+ struct gpio_desc *ipc_ap_gpio;
+
+ struct regulator *vbat_supply;
+
+ struct delayed_work modem_work;
+ struct notifier_block nb;
+};
+
+static int get_ipc_ap_wake(struct baseband_xmm_data *priv)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < BASEBAND_XMM_IPC_AP_WAKE_MAX; i++)
+ ret |= (test_bit(i, priv->state) << i);
+
+ return ret;
+}
+
+static void set_ipc_ap_wake(struct baseband_xmm_data *priv,
+ enum baseband_xmm_ipc_ap_wake_state state)
+{
+ for (int i = 0; i < BASEBAND_XMM_IPC_AP_WAKE_MAX; i++)
+ if (state & BIT(i))
+ set_bit(i, priv->state);
+ else
+ clear_bit(i, priv->state);
+}
+
+static void baseband_xmm_reset(struct baseband_xmm_data *priv)
+{
+ int ret;
+
+ set_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
+
+ if (!test_bit(BASEBAND_XMM_STATE_POWERED, priv->state)) {
+ ret = regulator_enable(priv->vbat_supply);
+ if (ret)
+ dev_err(priv->dev,
+ "failed to enable vbat power supply\n");
+
+ set_bit(BASEBAND_XMM_STATE_POWERED, priv->state);
+ }
+
+ gpiod_set_value_cansleep(priv->enable_gpio, 0);
+ msleep(50);
+
+ gpiod_set_value_cansleep(priv->reset_gpio, 1);
+ msleep(200);
+ gpiod_set_value_cansleep(priv->reset_gpio, 0);
+
+ msleep(50);
+
+ /* falling edge trigger to CP */
+ gpiod_set_value_cansleep(priv->enable_gpio, 1);
+ usleep_range(50, 100);
+ gpiod_set_value_cansleep(priv->enable_gpio, 0);
+ msleep(20);
+}
+
+static void baseband_xmm_poweroff(struct baseband_xmm_data *priv)
+{
+ /*
+ * The test_bit check prevents poweroff from being recursively
+ * called during USB device deregistration. USB device
+ * deregistration can be triggered by the driver by calling this
+ * function or by some external event. The first case will cause
+ * a recursive call by the notifier if not handled, while the
+ * second case requires this call to handle the USB controller
+ * properly.
+ */
+ if (test_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state))
+ return;
+
+ set_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
+ set_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state);
+
+ pwrseq_power_off(priv->pwrseq);
+ gpiod_set_value_cansleep(priv->reset_gpio, 1);
+
+ if (test_bit(BASEBAND_XMM_STATE_POWERED, priv->state)) {
+ regulator_disable(priv->vbat_supply);
+ clear_bit(BASEBAND_XMM_STATE_POWERED, priv->state);
+ }
+ set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY);
+
+ clear_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
+ clear_bit(BASEBAND_XMM_STATE_PRESENT, priv->state);
+ clear_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state);
+}
+
+static int baseband_xmm_usb_notifier_call(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct baseband_xmm_data *priv =
+ container_of(nb, struct baseband_xmm_data, nb);
+ struct usb_device *udev;
+ u16 product, vendor;
+
+ if (action == USB_BUS_ADD || action == USB_BUS_REMOVE)
+ return NOTIFY_OK;
+
+ udev = data;
+ product = le16_to_cpu(udev->descriptor.idProduct);
+ vendor = le16_to_cpu(udev->descriptor.idVendor);
+
+ switch (action) {
+ case USB_DEVICE_ADD:
+ /* Infineon XMM6260 ID 1519:0020 */
+ if (vendor == BASEBAND_VENDOR_ID_COMNEON &&
+ product == BASEBAND_PRODUCT_ID_XMM6260) {
+ cancel_delayed_work_sync(&priv->modem_work);
+ clear_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
+ set_bit(BASEBAND_XMM_STATE_PRESENT, priv->state);
+ }
+ break;
+
+ case USB_DEVICE_REMOVE:
+ /* Infineon XMM6260 ID 1519:0020 */
+ if (vendor == BASEBAND_VENDOR_ID_COMNEON &&
+ product == BASEBAND_PRODUCT_ID_XMM6260)
+ baseband_xmm_poweroff(priv);
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static int baseband_xmm_set_block(void *data, bool blocked)
+{
+ struct baseband_xmm_data *priv = data;
+
+ if (test_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state))
+ return -EBUSY;
+
+ if (blocked && test_bit(BASEBAND_XMM_STATE_PRESENT, priv->state))
+ baseband_xmm_poweroff(priv);
+ else if (!blocked && !test_bit(BASEBAND_XMM_STATE_PRESENT, priv->state))
+ baseband_xmm_reset(priv);
+
+ return 0;
+}
+
+static const struct rfkill_ops baseband_xmm_rfkill_ops = {
+ .set_block = baseband_xmm_set_block,
+};
+
+static void baseband_xmm_work(struct work_struct *work)
+{
+ struct baseband_xmm_data *priv =
+ container_of(work, struct baseband_xmm_data, modem_work.work);
+
+ baseband_xmm_poweroff(priv);
+};
+
+static irqreturn_t baseband_hostwake_interrupt(int irq, void *dev_id)
+{
+ struct baseband_xmm_data *priv = dev_id;
+ int state = gpiod_get_value(priv->ipc_ap_gpio);
+
+ switch (get_ipc_ap_wake(priv)) {
+ case BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY:
+ if (!state) {
+ set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_INIT1);
+ pwrseq_power_on(priv->pwrseq);
+ }
+ break;
+
+ case BASEBAND_XMM_IPC_AP_WAKE_INIT1:
+ if (state) {
+ set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_INIT2);
+ schedule_delayed_work(&priv->modem_work,
+ msecs_to_jiffies(BASEBAND_XMM_INIT_DELAY));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int baseband_xmm_probe(struct platform_device *pdev)
+{
+ struct baseband_xmm_data *priv;
+ struct device *dev = &pdev->dev;
+ unsigned long irqflags;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = dev;
+ platform_set_drvdata(pdev, priv);
+
+ priv->vbat_supply = devm_regulator_get(dev, "vbat");
+ if (IS_ERR(priv->vbat_supply))
+ return dev_err_probe(dev, PTR_ERR(priv->vbat_supply),
+ "failed to get vbat regulator\n");
+
+ /* Own modem gpios */
+ priv->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(priv->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(priv->reset_gpio),
+ "failed to get reset GPIO\n");
+
+ priv->enable_gpio = devm_gpiod_get_optional(dev, "enable",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(priv->enable_gpio))
+ return dev_err_probe(dev, PTR_ERR(priv->enable_gpio),
+ "failed to get enable GPIO\n");
+
+ /* CP - AP connections */
+ priv->ipc_cp_gpio = devm_gpiod_get_optional(dev, "cp-wake",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(priv->ipc_cp_gpio))
+ return dev_err_probe(dev, PTR_ERR(priv->ipc_cp_gpio),
+ "failed to get CP wake GPIO\n");
+
+ priv->ipc_ap_gpio = devm_gpiod_get_optional(dev, "ap-wake", GPIOD_IN);
+ if (IS_ERR(priv->ipc_ap_gpio))
+ return dev_err_probe(dev, PTR_ERR(priv->ipc_ap_gpio),
+ "failed to get AP wake GPIO\n");
+
+ /* Modem power sequence */
+ priv->pwrseq = devm_pwrseq_get(dev, "modem-power");
+ if (IS_ERR(priv->pwrseq))
+ return dev_err_probe(dev, PTR_ERR(priv->pwrseq),
+ "failed to get modem pwrseq");
+
+ bitmap_zero(priv->state, BASEBAND_XMM_STATE_MAX);
+ INIT_DELAYED_WORK(&priv->modem_work, baseband_xmm_work);
+
+ priv->irq = platform_get_irq(pdev, 0);
+ if (priv->irq < 0)
+ return dev_err_probe(dev, priv->irq, "failed to get IRQ\n");
+
+ /*
+ * Systems using device tree should set up interrupt via DT,
+ * the rest will use the default edge both interrupt.
+ */
+ irqflags = dev->of_node ? 0 : IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
+
+ ret = devm_request_threaded_irq(dev, priv->irq, NULL,
+ &baseband_hostwake_interrupt,
+ IRQF_ONESHOT | irqflags,
+ "modem-hostwake", priv);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to register IRQ %d\n", priv->irq);
+
+ priv->rfkill_dev = rfkill_alloc("xmm-modem", dev, RFKILL_TYPE_WWAN,
+ &baseband_xmm_rfkill_ops, priv);
+ if (!priv->rfkill_dev)
+ return -ENOMEM;
+
+ ret = rfkill_register(priv->rfkill_dev);
+ if (ret) {
+ rfkill_destroy(priv->rfkill_dev);
+ return dev_err_probe(dev, ret,
+ "failed to register WWAN rfkill\n");
+ }
+
+ priv->nb.notifier_call = baseband_xmm_usb_notifier_call;
+ usb_register_notify(&priv->nb);
+
+ return 0;
+}
+
+static void baseband_xmm_remove(struct platform_device *pdev)
+{
+ struct baseband_xmm_data *priv = platform_get_drvdata(pdev);
+
+ rfkill_unregister(priv->rfkill_dev);
+ rfkill_destroy(priv->rfkill_dev);
+
+ disable_irq(priv->irq);
+ cancel_delayed_work_sync(&priv->modem_work);
+
+ usb_unregister_notify(&priv->nb);
+ baseband_xmm_poweroff(priv);
+}
+
+static const struct of_device_id baseband_xmm_match[] = {
+ { .compatible = "infineon,xmm6260" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, baseband_xmm_match);
+
+static struct platform_driver baseband_xmm_driver = {
+ .driver = {
+ .name = "baseband-xmm6260",
+ .of_match_table = baseband_xmm_match,
+ },
+ .probe = baseband_xmm_probe,
+ .remove = baseband_xmm_remove,
+};
+module_platform_driver(baseband_xmm_driver);
+
+MODULE_AUTHOR("Svyatolsav Ryhel <clamor95@gmail.com>");
+MODULE_DESCRIPTION("Baseband Infineon XMM6260 driver");
+MODULE_LICENSE("GPL");
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 2/2] net: usb: Add Infineon XMM6260 Baseband modem support
2026-05-23 8:44 ` [PATCH v2 2/2] net: usb: Add Infineon XMM6260 Baseband modem support Svyatoslav Ryhel
@ 2026-05-27 0:38 ` Jakub Kicinski
0 siblings, 0 replies; 4+ messages in thread
From: Jakub Kicinski @ 2026-05-27 0:38 UTC (permalink / raw)
To: clamor95
Cc: Jakub Kicinski, andrew+netdev, davem, edumazet, pabeni, robh,
krzk+dt, conor+dt, netdev, devicetree, linux-kernel, linux-usb
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net: usb: Add Infineon XMM6260 Baseband modem support
This patch adds a platform driver for the Infineon/Intel XMM6260
3G modem. The driver toggles GPIOs and a regulator, drives a pwrseq
provider, and uses the global USB notifier plus rfkill to react to
the modem's HSIC USB enumeration.
A few observations on the commit message and overall placement before
the inline comments:
[Low]
The commit message tail reads:
The modem is usually connected via the application processor's USB
line in HSIC mode; however, to work properly, the modem must control
this line
The sentence stops there with no completion. Since this is the central
justification for adding a custom driver, can the explanation of what
"control this line" entails and why an existing solution does not work
be added?
[Low]
The driver is placed under drivers/net/usb/ but does not implement a
net_device (no register_netdev / alloc_netdev / netdev_ops, no usbnet
binding, no tx/rx callbacks). The dmesg in the commit message and the
Kconfig help confirm the modem enumerates as cdc_acm and that data
goes over ttyACM0 with a userspace DHCP client.
Would drivers/usb/misc/ or drivers/power/ be a more natural home, both
for routing the patch to the right maintainers and to avoid this
appearing alongside actual USB net drivers?
[Low]
Could the design be re-expressed as a pure pwrseq provider attached to
the USB device's hub-port DT node, letting the USB core gate
enumeration? The current driver pulls in pwrseq for part of the work
but keeps regulator + GPIO toggling, an rfkill instance, a global USB
notifier, and an ad-hoc bitmap state machine alongside it.
> diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
> index 52a5c0922c79..d54d8db752df 100644
> --- a/drivers/net/usb/Kconfig
> +++ b/drivers/net/usb/Kconfig
> @@ -642,4 +642,19 @@ config USB_RTL8153_ECM
> CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
> supported by r8152 driver.
>
> +config USB_NET_XMM6260
> + tristate "Infineon XMM626X Baseband HSPA/HSUPA modem"
[Low]
The title says "XMM626X" (suggesting a family), but the USB notifier
hard-codes a single VID:PID 0x1519:0x0020 for XMM6260 only. Other
626X variants such as XMM6262 will not be matched. Should the title
be narrowed to XMM6260, or the match table extended?
> + depends on USB_CHIPIDEA && (RFKILL || RFKILL=n)
[Low]
Does the driver actually have a software dependency on USB_CHIPIDEA?
The XMM6260 driver does not call any chipidea-specific API; it only
reacts to USB enumeration via the generic USB notifier and toggles
GPIOs/regulators/pwrseq. Tying this to USB_CHIPIDEA prevents using
the driver on other HSIC-/USB-capable SoCs even though nothing in the
code is HCD-specific.
[ ... ]
> diff --git a/drivers/net/usb/baseband-xmm6260.c b/drivers/net/usb/baseband-xmm6260.c
> new file mode 100644
> index 000000000000..6710e46f4170
> --- /dev/null
> +++ b/drivers/net/usb/baseband-xmm6260.c
> @@ -0,0 +1,378 @@
[ ... ]
> +/* bits [0:2] */
> +enum baseband_xmm_ipc_ap_wake_state {
> + BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY,
> + BASEBAND_XMM_IPC_AP_WAKE_INIT1,
> + BASEBAND_XMM_IPC_AP_WAKE_INIT2,
> + BASEBAND_XMM_IPC_AP_WAKE_L,
> + BASEBAND_XMM_IPC_AP_WAKE_H,
> + BASEBAND_XMM_IPC_AP_WAKE_UNINIT,
> + BASEBAND_XMM_IPC_AP_WAKE_MASK = 7,
> +};
> +
> +#define BASEBAND_XMM_IPC_AP_WAKE_MAX 3
> +
> +#define BASEBAND_XMM_STATE_POWERED 3 /* Tracks regulator state */
> +#define BASEBAND_XMM_STATE_PROTECTED 4 /* Prevents rfkill from access */
> +#define BASEBAND_XMM_STATE_PRESENT 5 /* Tracks USB device presence */
> +#define BASEBAND_XMM_STATE_POWEROFF 6 /* Prevents poweroff recursive call */
> +#define BASEBAND_XMM_STATE_MAX 8
[Low]
The ipc_ap_wake_state enum reaches UNINIT=5 and MASK=7, but
BASEBAND_XMM_IPC_AP_WAKE_MAX=3 caps the encode/decode loops at three
bits. Bits 3..6 of priv->state are then repurposed as orthogonal
STATE_POWERED / PROTECTED / PRESENT / POWEROFF flags. Nothing
asserts that the wake-state value fits in three bits, so a future
enum entry past 7, or a typo widening WAKE_MAX, would silently
overwrite the STATE_* flags. Could a BUILD_BUG_ON or static_assert
guard this invariant?
The L / H / UNINIT / MASK enumerators are also dead today; they only
appear at their declarations. The block comment above the enum
describes a multi-state protocol with a retry cycle, but the IRQ
handler implements only IRQ_READY and INIT1. Should the unused
values be removed, or should the handler be completed?
[ ... ]
> +static void set_ipc_ap_wake(struct baseband_xmm_data *priv,
> + enum baseband_xmm_ipc_ap_wake_state state)
> +{
> + for (int i = 0; i < BASEBAND_XMM_IPC_AP_WAKE_MAX; i++)
> + if (state & BIT(i))
> + set_bit(i, priv->state);
> + else
> + clear_bit(i, priv->state);
> +}
> +
> +static void baseband_xmm_reset(struct baseband_xmm_data *priv)
> +{
> + int ret;
> +
> + set_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
> +
> + if (!test_bit(BASEBAND_XMM_STATE_POWERED, priv->state)) {
> + ret = regulator_enable(priv->vbat_supply);
> + if (ret)
> + dev_err(priv->dev,
> + "failed to enable vbat power supply\n");
> +
> + set_bit(BASEBAND_XMM_STATE_POWERED, priv->state);
> + }
[High]
On regulator_enable() failure, ret is logged but STATE_POWERED is
still set unconditionally. When baseband_xmm_poweroff() later
observes STATE_POWERED it will call regulator_disable() without a
matching enable, which trips WARN_ON in the regulator core for a
negative use_count and corrupts the disable count for every other
consumer of vbat. Should the set_bit() be moved inside an "if (!ret)"
branch, or should the function bail out on enable failure?
> +
> + gpiod_set_value_cansleep(priv->enable_gpio, 0);
> + msleep(50);
> +
> + gpiod_set_value_cansleep(priv->reset_gpio, 1);
> + msleep(200);
> + gpiod_set_value_cansleep(priv->reset_gpio, 0);
> +
> + msleep(50);
> +
> + /* falling edge trigger to CP */
> + gpiod_set_value_cansleep(priv->enable_gpio, 1);
> + usleep_range(50, 100);
> + gpiod_set_value_cansleep(priv->enable_gpio, 0);
> + msleep(20);
> +}
> +
> +static void baseband_xmm_poweroff(struct baseband_xmm_data *priv)
> +{
> + /*
> + * The test_bit check prevents poweroff from being recursively
> + * called during USB device deregistration. USB device
> + * deregistration can be triggered by the driver by calling this
> + * function or by some external event. The first case will cause
> + * a recursive call by the notifier if not handled, while the
> + * second case requires this call to handle the USB controller
> + * properly.
> + */
> + if (test_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state))
> + return;
> +
> + set_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
> + set_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state);
> +
> + pwrseq_power_off(priv->pwrseq);
> + gpiod_set_value_cansleep(priv->reset_gpio, 1);
> +
> + if (test_bit(BASEBAND_XMM_STATE_POWERED, priv->state)) {
> + regulator_disable(priv->vbat_supply);
> + clear_bit(BASEBAND_XMM_STATE_POWERED, priv->state);
> + }
> + set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY);
> +
> + clear_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
> + clear_bit(BASEBAND_XMM_STATE_PRESENT, priv->state);
> + clear_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state);
> +}
[High]
Are STATE_PROTECTED / STATE_POWEROFF / STATE_PRESENT being used here
as ad-hoc locks rather than as state? The pattern is set on entry,
cleared on exit:
if (test_bit(STATE_POWEROFF, priv->state))
return;
set_bit(STATE_PROTECTED, ...);
set_bit(STATE_POWEROFF, ...);
...
clear_bit(STATE_PROTECTED, ...);
clear_bit(STATE_PRESENT, ...);
clear_bit(STATE_POWEROFF, ...);
test_bit() followed by set_bit() is not atomic, so two callers (the
USB_DEVICE_REMOVE notifier on one CPU, the rfkill set_block callback,
the delayed work, or remove() on another) can both observe POWEROFF=0
and both proceed, calling pwrseq_power_off() twice and (when
STATE_POWERED is set) regulator_disable() twice.
The same concern applies to baseband_xmm_set_block(), which reads
STATE_PROTECTED and STATE_PRESENT outside of any lock, and to the
three separate set_bit/clear_bit operations inside set_ipc_ap_wake()
that the IRQ handler reads back via three separate test_bit() calls
(potential torn read across bits 0..2).
The networking subsystem documentation calls this pattern out
explicitly: "any pattern where a flag, atomic variable, or bit
operation appears to guard a section of code rather than express
state ... is a bug". Could a real mutex (or spinlock for the IRQ
handler reads) be used instead?
> +
> +static int baseband_xmm_usb_notifier_call(struct notifier_block *nb,
> + unsigned long action, void *data)
> +{
> + struct baseband_xmm_data *priv =
> + container_of(nb, struct baseband_xmm_data, nb);
> + struct usb_device *udev;
> + u16 product, vendor;
> +
> + if (action == USB_BUS_ADD || action == USB_BUS_REMOVE)
> + return NOTIFY_OK;
> +
> + udev = data;
> + product = le16_to_cpu(udev->descriptor.idProduct);
> + vendor = le16_to_cpu(udev->descriptor.idVendor);
> +
> + switch (action) {
> + case USB_DEVICE_ADD:
> + /* Infineon XMM6260 ID 1519:0020 */
> + if (vendor == BASEBAND_VENDOR_ID_COMNEON &&
> + product == BASEBAND_PRODUCT_ID_XMM6260) {
> + cancel_delayed_work_sync(&priv->modem_work);
> + clear_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state);
> + set_bit(BASEBAND_XMM_STATE_PRESENT, priv->state);
> + }
> + break;
[Low]
Match is purely on VID:PID via the global USB notifier, with no
binding between this platform_device instance and the USB device that
enumerates. If two XMM6260 modems are present in the system, both
driver instances react to either modem's add/remove. Would binding a
USB device driver to that VID:PID, or routing the lifecycle through a
pwrseq attached to the hub-port node, give a stable per-instance
association?
> +
> + case USB_DEVICE_REMOVE:
> + /* Infineon XMM6260 ID 1519:0020 */
> + if (vendor == BASEBAND_VENDOR_ID_COMNEON &&
> + product == BASEBAND_PRODUCT_ID_XMM6260)
> + baseband_xmm_poweroff(priv);
> + break;
> +
> + default:
> + break;
> + }
> +
> + return NOTIFY_OK;
> +}
[ ... ]
> +static irqreturn_t baseband_hostwake_interrupt(int irq, void *dev_id)
> +{
> + struct baseband_xmm_data *priv = dev_id;
> + int state = gpiod_get_value(priv->ipc_ap_gpio);
[Medium]
This handler is registered with devm_request_threaded_irq(..., NULL,
&baseband_hostwake_interrupt, IRQF_ONESHOT | irqflags, ...), so it
runs in threaded (sleepable) context. Should this read use
gpiod_get_value_cansleep() instead of gpiod_get_value()? If ap-wake
is sourced from a sleeping GPIO controller (I2C/SPI expander, PMIC),
gpiod_get_value() will trip the WARN_ON(desc->gdev->can_sleep) in
gpiolib on every interrupt. All other GPIO accesses in the driver
already use the *_cansleep variants.
> +
> + switch (get_ipc_ap_wake(priv)) {
> + case BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY:
> + if (!state) {
> + set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_INIT1);
> + pwrseq_power_on(priv->pwrseq);
> + }
> + break;
> +
> + case BASEBAND_XMM_IPC_AP_WAKE_INIT1:
> + if (state) {
> + set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_INIT2);
> + schedule_delayed_work(&priv->modem_work,
> + msecs_to_jiffies(BASEBAND_XMM_INIT_DELAY));
> + }
> + break;
> +
> + default:
> + break;
> + }
> +
> + return IRQ_HANDLED;
> +}
[Medium]
Is the polarity of the IRQ_READY -> INIT1 transition consistent with
the comment above the enum? The block comment states:
AP wake interrupt keeps low util CP starts to initiate its HSIC hw.
AP wake interrupt goes up during CP HSIC init
(BASEBAND_XMM_IPC_AP_WAKE_INIT1 state)
So entering INIT1 corresponds to a rising edge (line goes high). But
the handler enters INIT1 only when "!state" (line is low) and that's
where it calls pwrseq_power_on(). Either the comment is describing
the protocol incorrectly or the conditional checks the wrong polarity;
if the comment is accurate, the modem would never power on. Could
this be clarified?
[Low]
For the non-DT path, irqflags is set to
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING and the handler decides
which transition occurred by re-reading the GPIO. The value seen in
the handler is the current level, not necessarily the level that
triggered the IRQ. A coalesced fast L->H->L sequence (or a noisy
edge) can cause the handler to read a state that does not correspond
to the triggering edge, missing the INIT1 -> INIT2 transition or
jumping over states. Should each edge be latched (e.g. by remembering
the previous level) instead of re-sampled?
> +
> +static int baseband_xmm_probe(struct platform_device *pdev)
> +{
[ ... ]
> + bitmap_zero(priv->state, BASEBAND_XMM_STATE_MAX);
> + INIT_DELAYED_WORK(&priv->modem_work, baseband_xmm_work);
> +
> + priv->irq = platform_get_irq(pdev, 0);
> + if (priv->irq < 0)
> + return dev_err_probe(dev, priv->irq, "failed to get IRQ\n");
> +
> + /*
> + * Systems using device tree should set up interrupt via DT,
> + * the rest will use the default edge both interrupt.
> + */
> + irqflags = dev->of_node ? 0 : IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
> +
> + ret = devm_request_threaded_irq(dev, priv->irq, NULL,
> + &baseband_hostwake_interrupt,
> + IRQF_ONESHOT | irqflags,
> + "modem-hostwake", priv);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to register IRQ %d\n", priv->irq);
> +
> + priv->rfkill_dev = rfkill_alloc("xmm-modem", dev, RFKILL_TYPE_WWAN,
> + &baseband_xmm_rfkill_ops, priv);
> + if (!priv->rfkill_dev)
> + return -ENOMEM;
> +
> + ret = rfkill_register(priv->rfkill_dev);
> + if (ret) {
> + rfkill_destroy(priv->rfkill_dev);
> + return dev_err_probe(dev, ret,
> + "failed to register WWAN rfkill\n");
> + }
[High]
Once devm_request_threaded_irq() succeeds, the IRQ is live and the
handler can already step through IRQ_READY -> INIT1 (calling
pwrseq_power_on()) and on the next edge INIT1 -> INIT2, where it does:
schedule_delayed_work(&priv->modem_work,
msecs_to_jiffies(BASEBAND_XMM_INIT_DELAY));
If rfkill_alloc() returns NULL or rfkill_register() fails, probe
returns an error. devres releases the IRQ but does not cancel the
queued delayed work, and the devm_kzalloc()'d priv is then freed.
Five seconds later baseband_xmm_work() runs and dereferences priv
(priv->pwrseq, priv->state, priv->reset_gpio, priv->vbat_supply).
Should the error paths after devm_request_threaded_irq() call
cancel_delayed_work_sync(&priv->modem_work), or should the cancel be
registered via devm_add_action_or_reset()?
> +
> + priv->nb.notifier_call = baseband_xmm_usb_notifier_call;
> + usb_register_notify(&priv->nb);
> +
> + return 0;
> +}
[High]
The ordering here is rfkill_register() first, usb_register_notify()
second. rfkill_register() schedules sync_work, which runs the
set_block callback asynchronously. Since this driver does not set
rfkill->persistent, the default state is unblocked, so set_block(false)
calls baseband_xmm_reset() -> regulator_enable() + GPIO toggling, and
the IRQ handler can step through IRQ_READY -> INIT1 -> INIT2 and
pwrseq_power_on() the modem, which then enumerates on USB.
If usb_register_notify() has not yet run when USB enumeration
completes, the USB_DEVICE_ADD notification is missed: STATE_PRESENT
is never set, the cancel_delayed_work_sync() in the notifier never
runs, and the 5-second watchdog work then calls baseband_xmm_poweroff()
on a working modem.
Should usb_register_notify() be called before rfkill_register()?
> +
> +static void baseband_xmm_remove(struct platform_device *pdev)
> +{
> + struct baseband_xmm_data *priv = platform_get_drvdata(pdev);
> +
> + rfkill_unregister(priv->rfkill_dev);
> + rfkill_destroy(priv->rfkill_dev);
> +
> + disable_irq(priv->irq);
> + cancel_delayed_work_sync(&priv->modem_work);
> +
> + usb_unregister_notify(&priv->nb);
> + baseband_xmm_poweroff(priv);
> +}
[Medium]
Between cancel_delayed_work_sync() and usb_unregister_notify(), a
USB_DEVICE_REMOVE notification can still be in flight on another CPU
and call baseband_xmm_poweroff(). usb_unregister_notify() then waits
for that callback to complete, and immediately afterwards remove()
itself calls baseband_xmm_poweroff(). Combined with the
ad-hoc-locking concern above, this can result in pwrseq_power_off()
running twice and possibly regulator_disable() running twice.
Would unregistering the notifier first (before disable_irq /
cancel_delayed_work_sync) close that window?
[ ... ]
> +module_platform_driver(baseband_xmm_driver);
> +
> +MODULE_AUTHOR("Svyatolsav Ryhel <clamor95@gmail.com>");
[Low]
The name spelling here (Svyatolsav) does not match the file copyright
header or the patch's Signed-off-by ("Svyatoslav"); the 's' and 'l'
are transposed.
> +MODULE_DESCRIPTION("Baseband Infineon XMM6260 driver");
> +MODULE_LICENSE("GPL");
--
pw-bot: cr
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-27 0:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-23 8:44 [PATCH v2 0/2] Add support for Infineon/Intel XMM6260 modem Svyatoslav Ryhel
2026-05-23 8:44 ` [PATCH v2 1/2] dt-bindings: net: Document " Svyatoslav Ryhel
2026-05-23 8:44 ` [PATCH v2 2/2] net: usb: Add Infineon XMM6260 Baseband modem support Svyatoslav Ryhel
2026-05-27 0:38 ` Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox