* [PATCH 0/2] usb: typec: hd3ss3220: Add sysfs interface for role state
@ 2026-02-27 18:50 Venkata Swamy Kassa
2026-02-27 18:50 ` [PATCH 1/2] kcsan: test: Adjust "expect" allocation type for kmalloc_obj Venkata Swamy Kassa
2026-02-27 18:50 ` [PATCH 2/2] usb-typec-hd3ss3220-Add-sysfs-attribute-for-USB-role Venkata Swamy Kassa
0 siblings, 2 replies; 5+ messages in thread
From: Venkata Swamy Kassa @ 2026-02-27 18:50 UTC (permalink / raw)
To: heikki.krogerus, gregkh; +Cc: linux-usb, linux-kernel
This patch series adds a sysfs interface to the HD3SS3220 Type-C controller
driver, allowing userspace to query the current USB role state.
Background
==========
The HD3SS3220 is a Type-C DRP (Dual Role Port) controller that detects cable
attachment and determines the port role based on CC pin logic. The driver
correctly propagates role changes to the USB controller via usb_role_switch,
but there is no mechanism for userspace to query the current state.
Problem
=======
When implementing udev rules to automatically start/stop USB gadget functions
based on cable connection:
1. In older kernels (5.15.x), the UDC subsystem emitted distinct "add" and
"remove" events that could be used to distinguish connect vs disconnect.
2. In newer kernels (6.6.x), only "change" events are emitted on the usb_role
subsystem, with no way to distinguish the actual role from the event itself.
Userspace needs to read the current role to determine the appropriate action
(start gadget for "device" role, stop gadget for "none" or "host" role).
Solution
========
Patch 1: Add a 'usb_role' sysfs attribute that exposes the current role as
a string. Also call sysfs_notify() and kobject_uevent() on role
changes to enable poll() and udev notifications.
Patch 2: Document the new sysfs attribute in Documentation/ABI/testing/.
Testing
=======
Tested on Variscite VAR-SOM-MX8M-PLUS with TI HD3SS3220 Type-C controller.
Cable connect/disconnect events correctly update the sysfs attribute and
trigger udev rules.
Venkata Swamy Kassa (2):
usb: typec: hd3ss3220: Add sysfs attribute for USB role state
Documentation: ABI: Add usb_role sysfs for hd3ss3220
Documentation/ABI/testing/sysfs-driver-hd3ss3220 | 14 ++++++++
drivers/usb/typec/hd3ss3220.c | 32 +++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-driver-hd3ss3220
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] kcsan: test: Adjust "expect" allocation type for kmalloc_obj
2026-02-27 18:50 [PATCH 0/2] usb: typec: hd3ss3220: Add sysfs interface for role state Venkata Swamy Kassa
@ 2026-02-27 18:50 ` Venkata Swamy Kassa
2026-02-27 20:27 ` Greg KH
2026-02-27 18:50 ` [PATCH 2/2] usb-typec-hd3ss3220-Add-sysfs-attribute-for-USB-role Venkata Swamy Kassa
1 sibling, 1 reply; 5+ messages in thread
From: Venkata Swamy Kassa @ 2026-02-27 18:50 UTC (permalink / raw)
To: heikki.krogerus, gregkh
Cc: linux-usb, linux-kernel, Kees Cook, Nathan Chancellor
From: Kees Cook <kees@kernel.org>
The call to kmalloc_obj(observed.lines) returns "char (*)[3][512]",
a pointer to the whole 2D array. But "expect" wants to be "char (*)[512]",
the decayed pointer type, as if it were observed.lines itself (though
without the "3" bounds). This produces the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':
../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]'
[-Wincompatible-pointer-types]
171 | expect = kmalloc_obj(observed.lines);
| ^
Instead of changing the "expect" type to "char (*)[3][512]" and
requiring a dereference at each use (e.g. "(expect*)[0]"), just
explicitly cast the return to the desired type.
Note that I'm intentionally not switching back to byte-based "kmalloc"
here because I cannot find a way for the Coccinelle script (which will
be used going forward to catch future conversions) to exclude this case.
Tested with:
$ ./tools/testing/kunit/kunit.py run \
--kconfig_add CONFIG_DEBUG_KERNEL=y \
--kconfig_add CONFIG_KCSAN=y \
--kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \
--arch=x86_64 --qemu_args '-smp 2' kcsan
Reported-by: Nathan Chancellor <nathan@kernel.org>
Fixes: 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")
Signed-off-by: Kees Cook <kees@kernel.org>
---
kernel/kcsan/kcsan_test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/kcsan/kcsan_test.c b/kernel/kcsan/kcsan_test.c
index 79e655ea4ca1..ae758150ccb9 100644
--- a/kernel/kcsan/kcsan_test.c
+++ b/kernel/kcsan/kcsan_test.c
@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)
if (!report_available())
return false;
- expect = kmalloc_obj(observed.lines);
+ expect = (typeof(expect))kmalloc_obj(observed.lines);
if (WARN_ON(!expect))
return false;
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] usb-typec-hd3ss3220-Add-sysfs-attribute-for-USB-role
2026-02-27 18:50 [PATCH 0/2] usb: typec: hd3ss3220: Add sysfs interface for role state Venkata Swamy Kassa
2026-02-27 18:50 ` [PATCH 1/2] kcsan: test: Adjust "expect" allocation type for kmalloc_obj Venkata Swamy Kassa
@ 2026-02-27 18:50 ` Venkata Swamy Kassa
2026-02-27 20:26 ` Greg KH
1 sibling, 1 reply; 5+ messages in thread
From: Venkata Swamy Kassa @ 2026-02-27 18:50 UTC (permalink / raw)
To: heikki.krogerus, gregkh; +Cc: linux-usb, linux-kernel, Venkata Swamy Kassa
Signed-off-by: Venkata Swamy Kassa <venkata.swamy.kassa@hexagon.com>
---
drivers/usb/typec/hd3ss3220.c | 207 +++++++++++++++++++++-------------
1 file changed, 128 insertions(+), 79 deletions(-)
diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c
index 3e39b800e6b5..9c8e1e9dadc2 100644
--- a/drivers/usb/typec/hd3ss3220.c
+++ b/drivers/usb/typec/hd3ss3220.c
@@ -5,66 +5,86 @@
* Copyright (C) 2019 Renesas Electronics Corp.
*/
-#include <linux/module.h>
#include <linux/i2c.h>
+#include <linux/usb/typec.h>
#include <linux/usb/role.h>
-#include <linux/irqreturn.h>
-#include <linux/interrupt.h>
#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <linux/usb/typec.h>
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
-#include <linux/of_graph.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/of.h>
-#define HD3SS3220_REG_CN_STAT 0x08
-#define HD3SS3220_REG_CN_STAT_CTRL 0x09
-#define HD3SS3220_REG_GEN_CTRL 0x0A
-#define HD3SS3220_REG_DEV_REV 0xA0
+#define HD3SS3220_REG_CN_STAT 0x08
+#define HD3SS3220_REG_CN_STAT_CTRL 0x09
+#define HD3SS3220_REG_GEN_CTRL 0x0A
+#define HD3SS3220_REG_DEV_REV 0xA0
/* Register HD3SS3220_REG_CN_STAT */
-#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MASK (BIT(7) | BIT(6))
-#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_DEFAULT 0x00
-#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MID BIT(6)
-#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_HIGH BIT(7)
+#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MASK (BIT(7) | BIT(6))
+#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_DEFAULT 0x00
+#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MID BIT(6)
+#define HD3SS3220_REG_CN_STAT_CURRENT_MODE_HIGH BIT(7)
/* Register HD3SS3220_REG_CN_STAT_CTRL*/
-#define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6))
-#define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6)
-#define HD3SS3220_REG_CN_STAT_CTRL_AS_UFP BIT(7)
-#define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY (BIT(7) | BIT(6))
-#define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS BIT(4)
+#define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6))
+#define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6)
+#define HD3SS3220_REG_CN_STAT_CTRL_AS_UFP BIT(7)
+#define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY (BIT(7) | BIT(6))
+#define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS BIT(4)
/* Register HD3SS3220_REG_GEN_CTRL*/
-#define HD3SS3220_REG_GEN_CTRL_DISABLE_TERM BIT(0)
-#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1))
-#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT 0x00
-#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK BIT(1)
-#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC (BIT(2) | BIT(1))
-#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_MASK (BIT(5) | BIT(4))
-#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DEFAULT 0x00
-#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DFP BIT(5)
-#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_UFP BIT(4)
-#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DRP (BIT(5) | BIT(4))
+#define HD3SS3220_REG_GEN_CTRL_DISABLE_TERM BIT(0)
+#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1))
+#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT 0x00
+#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK BIT(1)
+#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC (BIT(2) | BIT(1))
+#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_MASK (BIT(5) | BIT(4))
+#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DEFAULT 0x00
+#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DFP BIT(5)
+#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_UFP BIT(4)
+#define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DRP (BIT(5) | BIT(4))
struct hd3ss3220 {
struct device *dev;
struct regmap *regmap;
- struct usb_role_switch *role_sw;
+ struct usb_role_switch *role_sw;
struct typec_port *port;
struct delayed_work output_poll_work;
enum usb_role role_state;
bool poll;
-
struct gpio_desc *id_gpiod;
int id_irq;
-
struct regulator *vbus;
};
-static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opmode)
+/*
+ * Sysfs attribute to show current USB role (device/host/none)
+ */
+static ssize_t usb_role_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct hd3ss3220 *hd3ss3220 = dev_get_drvdata(dev);
+ const char *role_str = usb_role_string(hd3ss3220->role_state);
+
+ return sysfs_emit(buf, "%s\n", role_str);
+}
+static DEVICE_ATTR_RO(usb_role);
+
+static struct attribute *hd3ss3220_attrs[] = {
+ &dev_attr_usb_role.attr,
+ NULL
+};
+
+static const struct attribute_group hd3ss3220_attr_group = {
+ .attrs = hd3ss3220_attrs,
+};
+
+static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220,
+ int power_opmode)
{
int current_mode;
@@ -78,9 +98,11 @@ static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opm
case TYPEC_PWR_MODE_3_0A:
current_mode = HD3SS3220_REG_CN_STAT_CURRENT_MODE_HIGH;
break;
- case TYPEC_PWR_MODE_PD: /* Power delivery not supported */
+ case TYPEC_PWR_MODE_PD:
+ /* Power delivery not supported */
default:
- dev_err(hd3ss3220->dev, "bad power operation mode: %d\n", power_opmode);
+ dev_err(hd3ss3220->dev, "bad power operation mode: %d\n",
+ power_opmode);
return -EINVAL;
}
@@ -108,12 +130,15 @@ static int hd3ss3220_set_port_type(struct hd3ss3220 *hd3ss3220, int type)
return -EINVAL;
}
- /* Disable termination before changing MODE_SELECT as required by datasheet */
+ /* Disable termination before changing MODE_SELECT as required by
+ * datasheet
+ */
err = regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
HD3SS3220_REG_GEN_CTRL_DISABLE_TERM,
HD3SS3220_REG_GEN_CTRL_DISABLE_TERM);
if (err < 0) {
- dev_err(hd3ss3220->dev, "Failed to disable port for mode change: %d\n", err);
+ dev_err(hd3ss3220->dev,
+ "Failed to disable port for mode change: %d\n", err);
return err;
}
@@ -130,12 +155,15 @@ static int hd3ss3220_set_port_type(struct hd3ss3220 *hd3ss3220, int type)
err = regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
HD3SS3220_REG_GEN_CTRL_DISABLE_TERM, 0);
if (err < 0)
- dev_err(hd3ss3220->dev, "Failed to re-enable port after mode change: %d\n", err);
+ dev_err(hd3ss3220->dev,
+ "Failed to re-enable port after mode change: %d\n",
+ err);
return err;
}
-static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int prefer_role)
+static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220,
+ int prefer_role)
{
int src_pref;
@@ -150,7 +178,8 @@ static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int prefer_rol
src_pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC;
break;
default:
- dev_err(hd3ss3220->dev, "bad role preference: %d\n", prefer_role);
+ dev_err(hd3ss3220->dev, "bad role preference: %d\n",
+ prefer_role);
return -EINVAL;
}
@@ -192,7 +221,8 @@ static int hd3ss3220_try_role(struct typec_port *port, int role)
return hd3ss3220_set_source_pref(hd3ss3220, role);
}
-static int hd3ss3220_port_type_set(struct typec_port *port, enum typec_port_type type)
+static int hd3ss3220_port_type_set(struct typec_port *port,
+ enum typec_port_type type)
{
struct hd3ss3220 *hd3ss3220 = typec_get_drvdata(port);
@@ -217,8 +247,8 @@ static void hd3ss3220_regulator_control(struct hd3ss3220 *hd3ss3220, bool on)
ret = regulator_disable(hd3ss3220->vbus);
if (ret)
- dev_err(hd3ss3220->dev,
- "vbus regulator %s failed: %d\n", on ? "disable" : "enable", ret);
+ dev_err(hd3ss3220->dev, "vbus regulator %s failed: %d\n",
+ on ? "disable" : "enable", ret);
}
static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220)
@@ -239,9 +269,14 @@ static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220)
}
if (hd3ss3220->vbus && !hd3ss3220->id_gpiod)
- hd3ss3220_regulator_control(hd3ss3220, role_state == USB_ROLE_HOST);
+ hd3ss3220_regulator_control(hd3ss3220,
+ role_state == USB_ROLE_HOST);
hd3ss3220->role_state = role_state;
+
+ /* Notify userspace of usb_role change */
+ sysfs_notify(&hd3ss3220->dev->kobj, NULL, "usb_role");
+ kobject_uevent(&hd3ss3220->dev->kobj, KOBJ_CHANGE);
}
static void output_poll_execute(struct work_struct *work)
@@ -263,9 +298,10 @@ static irqreturn_t hd3ss3220_irq(struct hd3ss3220 *hd3ss3220)
int err;
hd3ss3220_set_role(hd3ss3220);
+
err = regmap_write_bits(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL,
- HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS,
- HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
+ HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS,
+ HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
if (err < 0)
return IRQ_NONE;
@@ -283,17 +319,17 @@ static irqreturn_t hd3ss3220_irq_handler(int irq, void *data)
static int hd3ss3220_configure_power_opmode(struct hd3ss3220 *hd3ss3220,
struct fwnode_handle *connector)
{
- /*
- * Supported power operation mode can be configured through device tree
- */
+ /* Supported power operation mode can be configured through device tree */
const char *cap_str;
int ret, power_opmode;
- ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str);
+ ret = fwnode_property_read_string(connector, "typec-power-opmode",
+ &cap_str);
if (ret)
return 0;
power_opmode = typec_find_pwr_opmode(cap_str);
+
return hd3ss3220_set_power_opmode(hd3ss3220, power_opmode);
}
@@ -301,9 +337,7 @@ static int hd3ss3220_configure_port_type(struct hd3ss3220 *hd3ss3220,
struct fwnode_handle *connector,
struct typec_capability *cap)
{
- /*
- * Port type can be configured through device tree
- */
+ /* Port type can be configured through device tree */
const char *cap_str;
int ret;
@@ -316,6 +350,7 @@ static int hd3ss3220_configure_port_type(struct hd3ss3220 *hd3ss3220,
return ret;
cap->type = ret;
+
return hd3ss3220_set_port_type(hd3ss3220, cap->type);
}
@@ -323,13 +358,12 @@ static int hd3ss3220_configure_source_pref(struct hd3ss3220 *hd3ss3220,
struct fwnode_handle *connector,
struct typec_capability *cap)
{
- /*
- * Preferred role can be configured through device tree
- */
+ /* Preferred role can be configured through device tree */
const char *cap_str;
int ret;
- ret = fwnode_property_read_string(connector, "try-power-role", &cap_str);
+ ret = fwnode_property_read_string(connector, "try-power-role",
+ &cap_str);
if (ret)
return 0;
@@ -338,6 +372,7 @@ static int hd3ss3220_configure_source_pref(struct hd3ss3220 *hd3ss3220,
return ret;
cap->prefer_role = ret;
+
return hd3ss3220_set_source_pref(hd3ss3220, cap->prefer_role);
}
@@ -373,8 +408,8 @@ static int hd3ss3220_probe(struct i2c_client *client)
return -ENOMEM;
i2c_set_clientdata(client, hd3ss3220);
-
hd3ss3220->dev = &client->dev;
+
hd3ss3220->regmap = devm_regmap_init_i2c(client, &config);
if (IS_ERR(hd3ss3220->regmap))
return PTR_ERR(hd3ss3220->regmap);
@@ -384,13 +419,16 @@ static int hd3ss3220_probe(struct i2c_client *client)
if (connector) {
hd3ss3220->role_sw = fwnode_usb_role_switch_get(connector);
} else {
- ep = fwnode_graph_get_next_endpoint(dev_fwnode(hd3ss3220->dev), NULL);
+ ep = fwnode_graph_get_next_endpoint(dev_fwnode(hd3ss3220->dev),
+ NULL);
if (!ep)
return -ENODEV;
+
connector = fwnode_graph_get_remote_port_parent(ep);
fwnode_handle_put(ep);
if (!connector)
return -ENODEV;
+
hd3ss3220->role_sw = usb_role_switch_get(hd3ss3220->dev);
}
@@ -400,8 +438,7 @@ static int hd3ss3220_probe(struct i2c_client *client)
}
vbus = devm_of_regulator_get_optional(hd3ss3220->dev,
- to_of_node(connector),
- "vbus");
+ to_of_node(connector), "vbus");
if (IS_ERR(vbus) && vbus != ERR_PTR(-ENODEV)) {
ret = PTR_ERR(vbus);
dev_err(hd3ss3220->dev, "failed to get vbus: %d", ret);
@@ -412,8 +449,7 @@ static int hd3ss3220_probe(struct i2c_client *client)
if (hd3ss3220->vbus) {
hd3ss3220->id_gpiod = devm_gpiod_get_optional(hd3ss3220->dev,
- "id",
- GPIOD_IN);
+ "id", GPIOD_IN);
if (IS_ERR(hd3ss3220->id_gpiod)) {
ret = PTR_ERR(hd3ss3220->id_gpiod);
goto err_put_fwnode;
@@ -424,8 +460,7 @@ static int hd3ss3220_probe(struct i2c_client *client)
hd3ss3220->id_irq = gpiod_to_irq(hd3ss3220->id_gpiod);
if (hd3ss3220->id_irq < 0) {
ret = hd3ss3220->id_irq;
- dev_err(hd3ss3220->dev,
- "failed to get ID gpio: %d\n",
+ dev_err(hd3ss3220->dev, "failed to get ID gpio: %d\n",
hd3ss3220->id_irq);
goto err_put_fwnode;
}
@@ -434,10 +469,13 @@ static int hd3ss3220_probe(struct i2c_client *client)
hd3ss3220->id_irq, NULL,
hd3ss3220_id_isr,
IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- dev_name(hd3ss3220->dev), hd3ss3220);
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ dev_name(hd3ss3220->dev),
+ hd3ss3220);
if (ret < 0) {
- dev_err(hd3ss3220->dev, "failed to get ID irq: %d\n", ret);
+ dev_err(hd3ss3220->dev, "failed to get ID irq: %d\n",
+ ret);
goto err_put_fwnode;
}
}
@@ -467,28 +505,37 @@ static int hd3ss3220_probe(struct i2c_client *client)
if (ret < 0)
goto err_unreg_port;
+ ret = devm_device_add_group(&client->dev, &hd3ss3220_attr_group);
+ if (ret) {
+ dev_err(&client->dev,
+ "Failed to create sysfs attributes: %d\n", ret);
+ goto err_unreg_port;
+ }
+
hd3ss3220_set_role(hd3ss3220);
+
ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, &data);
if (ret < 0)
goto err_unreg_port;
if (data & HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS) {
- ret = regmap_write(hd3ss3220->regmap,
- HD3SS3220_REG_CN_STAT_CTRL,
- data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
+ ret = regmap_write(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL,
+ data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
if (ret < 0)
goto err_unreg_port;
}
if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
- hd3ss3220_irq_handler,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "hd3ss3220", &client->dev);
+ hd3ss3220_irq_handler,
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ "hd3ss3220", &client->dev);
if (ret)
goto err_unreg_port;
} else {
- INIT_DELAYED_WORK(&hd3ss3220->output_poll_work, output_poll_execute);
+ INIT_DELAYED_WORK(&hd3ss3220->output_poll_work,
+ output_poll_execute);
hd3ss3220->poll = true;
}
@@ -504,6 +551,7 @@ static int hd3ss3220_probe(struct i2c_client *client)
dev_info(&client->dev, "probed revision=0x%x\n", ret);
return 0;
+
err_unreg_port:
typec_unregister_port(hd3ss3220->port);
err_put_role:
@@ -526,7 +574,7 @@ static void hd3ss3220_remove(struct i2c_client *client)
}
static const struct of_device_id dev_ids[] = {
- { .compatible = "ti,hd3ss3220"},
+ { .compatible = "ti,hd3ss3220" },
{}
};
MODULE_DEVICE_TABLE(of, dev_ids);
@@ -545,3 +593,4 @@ module_i2c_driver(hd3ss3220_driver);
MODULE_AUTHOR("Biju Das <biju.das@bp.renesas.com>");
MODULE_DESCRIPTION("TI HD3SS3220 DRP Port Controller Driver");
MODULE_LICENSE("GPL");
+
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] usb-typec-hd3ss3220-Add-sysfs-attribute-for-USB-role
2026-02-27 18:50 ` [PATCH 2/2] usb-typec-hd3ss3220-Add-sysfs-attribute-for-USB-role Venkata Swamy Kassa
@ 2026-02-27 20:26 ` Greg KH
0 siblings, 0 replies; 5+ messages in thread
From: Greg KH @ 2026-02-27 20:26 UTC (permalink / raw)
To: Venkata Swamy Kassa
Cc: heikki.krogerus, linux-usb, linux-kernel, Venkata Swamy Kassa
On Fri, Feb 27, 2026 at 06:50:21PM +0000, Venkata Swamy Kassa wrote:
> Signed-off-by: Venkata Swamy Kassa <venkata.swamy.kassa@hexagon.com>
> ---
> drivers/usb/typec/hd3ss3220.c | 207 +++++++++++++++++++++-------------
> 1 file changed, 128 insertions(+), 79 deletions(-)
I don't think you ment to send this as it's obviously not correct :(
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] kcsan: test: Adjust "expect" allocation type for kmalloc_obj
2026-02-27 18:50 ` [PATCH 1/2] kcsan: test: Adjust "expect" allocation type for kmalloc_obj Venkata Swamy Kassa
@ 2026-02-27 20:27 ` Greg KH
0 siblings, 0 replies; 5+ messages in thread
From: Greg KH @ 2026-02-27 20:27 UTC (permalink / raw)
To: Venkata Swamy Kassa
Cc: heikki.krogerus, linux-usb, linux-kernel, Kees Cook,
Nathan Chancellor
On Fri, Feb 27, 2026 at 06:50:20PM +0000, Venkata Swamy Kassa wrote:
> From: Kees Cook <kees@kernel.org>
>
> The call to kmalloc_obj(observed.lines) returns "char (*)[3][512]",
> a pointer to the whole 2D array. But "expect" wants to be "char (*)[512]",
> the decayed pointer type, as if it were observed.lines itself (though
> without the "3" bounds). This produces the following build error:
>
> ../kernel/kcsan/kcsan_test.c: In function '__report_matches':
> ../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]'
> [-Wincompatible-pointer-types]
> 171 | expect = kmalloc_obj(observed.lines);
> | ^
>
> Instead of changing the "expect" type to "char (*)[3][512]" and
> requiring a dereference at each use (e.g. "(expect*)[0]"), just
> explicitly cast the return to the desired type.
>
> Note that I'm intentionally not switching back to byte-based "kmalloc"
> here because I cannot find a way for the Coccinelle script (which will
> be used going forward to catch future conversions) to exclude this case.
>
> Tested with:
>
> $ ./tools/testing/kunit/kunit.py run \
> --kconfig_add CONFIG_DEBUG_KERNEL=y \
> --kconfig_add CONFIG_KCSAN=y \
> --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \
> --arch=x86_64 --qemu_args '-smp 2' kcsan
>
> Reported-by: Nathan Chancellor <nathan@kernel.org>
> Fixes: 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")
> Signed-off-by: Kees Cook <kees@kernel.org>
> ---
> kernel/kcsan/kcsan_test.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/kcsan/kcsan_test.c b/kernel/kcsan/kcsan_test.c
> index 79e655ea4ca1..ae758150ccb9 100644
> --- a/kernel/kcsan/kcsan_test.c
> +++ b/kernel/kcsan/kcsan_test.c
> @@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)
> if (!report_available())
> return false;
>
> - expect = kmalloc_obj(observed.lines);
> + expect = (typeof(expect))kmalloc_obj(observed.lines);
> if (WARN_ON(!expect))
> return false;
>
> --
> 2.43.0
>
>
Why was this part of a usb patch series?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-02-27 20:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-27 18:50 [PATCH 0/2] usb: typec: hd3ss3220: Add sysfs interface for role state Venkata Swamy Kassa
2026-02-27 18:50 ` [PATCH 1/2] kcsan: test: Adjust "expect" allocation type for kmalloc_obj Venkata Swamy Kassa
2026-02-27 20:27 ` Greg KH
2026-02-27 18:50 ` [PATCH 2/2] usb-typec-hd3ss3220-Add-sysfs-attribute-for-USB-role Venkata Swamy Kassa
2026-02-27 20:26 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox