| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/08 11:34 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"USB_SUPPORT",
"USB_PHY",
"NOP_USB_XCEIV"
],
"FocusSymbols": [
"usb_phy_notify_charger_work",
"usb_add_phy_dev",
"usb_phy_set_charger_state",
"usb_phy_set_charger_current"
],
"KMSANReasoning": "The patch refactors the USB PHY uevent notification by sending the environment variables directly from `usb_phy_notify_charger_work()` using `kobject_uevent_env()` rather than via a `device_type.uevent` callback. \n\nAll stack buffers introduced in this patch (`uchger_state`, `uchger_type`, and `envp`) are explicitly zero-initialized (`= { 0 }` / explicit initialization with NULL terminator) before string formatting via `snprintf()` and being passed to `kobject_uevent_env()`. There are no uninitialized variables, struct padding leaks, or uninitialized memory read risks. Any potential issues with array indexing (e.g. `usb_chger_type`) are bounds check / out-of-bounds read concerns detectable by KASAN, not uninitialized memory issues. Thus, a dedicated KMSAN session is not required.",
"NeedsKMSAN": false,
"Reasoning": "The patch refactors the uevent reporting mechanism for USB PHY charger events in drivers/usb/phy/phy.c. Instead of modifying the device type and implementing a custom uevent callback, environment variables for charger state and type are now constructed and passed directly via kobject_uevent_env() within usb_phy_notify_charger_work(). This touches reachable USB PHY core logic and is worth fuzzing.",
"WorthFuzzing": true
} |
| 1/1 | 2026/09/08 11:34 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 86efd571c3d2117a886dd7d1d448a5bc06aaff2f\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Sep 8 11:34:29 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c\nindex 5a9b9353f343d..7c85c7ca1d309 100644\n--- a/drivers/usb/phy/phy.c\n+++ b/drivers/usb/phy/phy.c\n@@ -42,12 +42,6 @@ static const char *const usb_chger_type[] = {\n \t[ACA_TYPE]\t\t\t= \"USB_CHARGER_ACA_TYPE\",\n };\n \n-static const char *const usb_chger_state[] = {\n-\t[USB_CHARGER_DEFAULT]\t= \"USB_CHARGER_DEFAULT\",\n-\t[USB_CHARGER_PRESENT]\t= \"USB_CHARGER_PRESENT\",\n-\t[USB_CHARGER_ABSENT]\t= \"USB_CHARGER_ABSENT\",\n-};\n-\n static struct usb_phy *__usb_find_phy(struct list_head *list,\n \tenum usb_phy_type type)\n {\n@@ -80,18 +74,6 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)\n \treturn ERR_PTR(-EPROBE_DEFER);\n }\n \n-static struct usb_phy *__device_to_usb_phy(const struct device *dev)\n-{\n-\tstruct usb_phy *usb_phy;\n-\n-\tlist_for_each_entry(usb_phy, \u0026phy_list, head) {\n-\t\tif (usb_phy-\u003edev == dev)\n-\t\t\treturn usb_phy;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n static void usb_phy_set_default_current(struct usb_phy *usb_phy)\n {\n \tusb_phy-\u003echg_cur.sdp_min = DEFAULT_SDP_CUR_MIN;\n@@ -123,6 +105,9 @@ static void usb_phy_set_default_current(struct usb_phy *usb_phy)\n static void usb_phy_notify_charger_work(struct work_struct *work)\n {\n \tstruct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work);\n+\tchar uchger_state[50] = { 0 };\n+\tchar uchger_type[50] = { 0 };\n+\tchar *envp[] = { uchger_state, uchger_type, NULL };\n \tunsigned int min, max;\n \n \tswitch (usb_phy-\u003echg_state) {\n@@ -130,11 +115,15 @@ static void usb_phy_notify_charger_work(struct work_struct *work)\n \t\tusb_phy_get_charger_current(usb_phy, \u0026min, \u0026max);\n \n \t\tatomic_notifier_call_chain(\u0026usb_phy-\u003enotifier, max, usb_phy);\n+\t\tsnprintf(uchger_state, ARRAY_SIZE(uchger_state),\n+\t\t\t \"USB_CHARGER_STATE=%s\", \"USB_CHARGER_PRESENT\");\n \t\tbreak;\n \tcase USB_CHARGER_ABSENT:\n \t\tusb_phy_set_default_current(usb_phy);\n \n \t\tatomic_notifier_call_chain(\u0026usb_phy-\u003enotifier, 0, usb_phy);\n+\t\tsnprintf(uchger_state, ARRAY_SIZE(uchger_state),\n+\t\t\t \"USB_CHARGER_STATE=%s\", \"USB_CHARGER_ABSENT\");\n \t\tbreak;\n \tdefault:\n \t\tdev_warn(usb_phy-\u003edev, \"Unknown USB charger state: %d\\n\",\n@@ -142,36 +131,9 @@ static void usb_phy_notify_charger_work(struct work_struct *work)\n \t\treturn;\n \t}\n \n-\tkobject_uevent(\u0026usb_phy-\u003edev-\u003ekobj, KOBJ_CHANGE);\n-}\n-\n-static int usb_phy_uevent(const struct device *dev, struct kobj_uevent_env *env)\n-{\n-\tconst struct usb_phy *usb_phy;\n-\tchar uchger_state[50] = { 0 };\n-\tchar uchger_type[50] = { 0 };\n-\tunsigned long flags;\n-\n-\tspin_lock_irqsave(\u0026phy_lock, flags);\n-\tusb_phy = __device_to_usb_phy(dev);\n-\tspin_unlock_irqrestore(\u0026phy_lock, flags);\n-\n-\tif (!usb_phy)\n-\t\treturn -ENODEV;\n-\n-\tsnprintf(uchger_state, ARRAY_SIZE(uchger_state),\n-\t\t \"USB_CHARGER_STATE=%s\", usb_chger_state[usb_phy-\u003echg_state]);\n-\n \tsnprintf(uchger_type, ARRAY_SIZE(uchger_type),\n \t\t \"USB_CHARGER_TYPE=%s\", usb_chger_type[usb_phy-\u003echg_type]);\n-\n-\tif (add_uevent_var(env, uchger_state))\n-\t\treturn -ENOMEM;\n-\n-\tif (add_uevent_var(env, uchger_type))\n-\t\treturn -ENOMEM;\n-\n-\treturn 0;\n+\tkobject_uevent_env(\u0026usb_phy-\u003edev-\u003ekobj, KOBJ_CHANGE, envp);\n }\n \n static void __usb_phy_get_charger_type(struct usb_phy *usb_phy)\n@@ -675,11 +637,6 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)\n }\n EXPORT_SYMBOL_GPL(usb_add_phy);\n \n-static const struct device_type usb_phy_dev_type = {\n-\t.name = \"usb_phy\",\n-\t.uevent = usb_phy_uevent,\n-};\n-\n /**\n * usb_add_phy_dev - declare the USB PHY\n * @x: the USB phy to be used; or NULL\n@@ -705,8 +662,6 @@ int usb_add_phy_dev(struct usb_phy *x)\n \tif (ret)\n \t\treturn ret;\n \n-\tx-\u003edev-\u003etype = \u0026usb_phy_dev_type;\n-\n \tATOMIC_INIT_NOTIFIER_HEAD(\u0026x-\u003enotifier);\n \n \tspin_lock_irqsave(\u0026phy_lock, flags);\n"
} |
| 2/1 | 2026/09/08 11:34 | agent | patch-evaluator |
0mModel:core Args: null Results: {
"EnableConfigs": [
"USB_SUPPORT",
"USB_PHY",
"NOP_USB_XCEIV"
],
"FocusSymbols": [
"usb_phy_notify_charger_work",
"usb_add_phy_dev",
"usb_phy_set_charger_state",
"usb_phy_set_charger_current"
],
"Reasoning": "The patch refactors the uevent reporting mechanism for USB PHY charger events in drivers/usb/phy/phy.c. Instead of modifying the device type and implementing a custom uevent callback, environment variables for charger state and type are now constructed and passed directly via kobject_uevent_env() within usb_phy_notify_charger_work(). This touches reachable USB PHY core logic and is worth fuzzing.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 86efd571c3d2117a886dd7d1d448a5bc06aaff2f
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Sep 8 11:34:29 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 5a9b9353f343d..7c85c7ca1d309 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -42,12 +42,6 @@ static const char *const usb_chger_type[] = {
[ACA_TYPE] = "USB_CHARGER_ACA_TYPE",
};
-static const char *const usb_chger_state[] = {
- [USB_CHARGER_DEFAULT] = "USB_CHARGER_DEFAULT",
- [USB_CHARGER_PRESENT] = "USB_CHARGER_PRESENT",
- [USB_CHARGER_ABSENT] = "USB_CHARGER_ABSENT",
-};
-
static struct usb_phy *__usb_find_phy(struct list_head *list,
enum usb_phy_type type)
{
@@ -80,18 +74,6 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)
return ERR_PTR(-EPROBE_DEFER);
}
-static struct usb_phy *__device_to_usb_phy(const struct device *dev)
-{
- struct usb_phy *usb_phy;
-
- list_for_each_entry(usb_phy, &phy_list, head) {
- if (usb_phy->dev == dev)
- return usb_phy;
- }
-
- return NULL;
-}
-
static void usb_phy_set_default_current(struct usb_phy *usb_phy)
{
usb_phy->chg_cur.sdp_min = DEFAULT_SDP_CUR_MIN;
@@ -123,6 +105,9 @@ static void usb_phy_set_default_current(struct usb_phy *usb_phy)
static void usb_phy_notify_charger_work(struct work_struct *work)
{
struct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work);
+ char uchger_state[50] = { 0 };
+ char uchger_type[50] = { 0 };
+ char *envp[] = { uchger_state, uchger_type, NULL };
unsigned int min, max;
switch (usb_phy->chg_state) {
@@ -130,11 +115,15 @@ static void usb_phy_notify_charger_work(struct work_struct *work)
usb_phy_get_charger_current(usb_phy, &min, &max);
atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy);
+ snprintf(uchger_state, ARRAY_SIZE(uchger_state),
+ "USB_CHARGER_STATE=%s", "USB_CHARGER_PRESENT");
break;
case USB_CHARGER_ABSENT:
usb_phy_set_default_current(usb_phy);
atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy);
+ snprintf(uchger_state, ARRAY_SIZE(uchger_state),
+ "USB_CHARGER_STATE=%s", "USB_CHARGER_ABSENT");
break;
default:
dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n",
@@ -142,36 +131,9 @@ static void usb_phy_notify_charger_work(struct work_struct *work)
return;
}
- kobject_uevent(&usb_phy->dev->kobj, KOBJ_CHANGE);
-}
-
-static int usb_phy_uevent(const struct device *dev, struct kobj_uevent_env *env)
-{
- const struct usb_phy *usb_phy;
- char uchger_state[50] = { 0 };
- char uchger_type[50] = { 0 };
- unsigned long flags;
-
- spin_lock_irqsave(&phy_lock, flags);
- usb_phy = __device_to_usb_phy(dev);
- spin_unlock_irqrestore(&phy_lock, flags);
-
- if (!usb_phy)
- return -ENODEV;
-
- snprintf(uchger_state, ARRAY_SIZE(uchger_state),
- "USB_CHARGER_STATE=%s", usb_chger_state[usb_phy->chg_state]);
-
snprintf(uchger_type, ARRAY_SIZE(uchger_type),
"USB_CHARGER_TYPE=%s", usb_chger_type[usb_phy->chg_type]);
-
- if (add_uevent_var(env, uchger_state))
- return -ENOMEM;
-
- if (add_uevent_var(env, uchger_type))
- return -ENOMEM;
-
- return 0;
+ kobject_uevent_env(&usb_phy->dev->kobj, KOBJ_CHANGE, envp);
}
static void __usb_phy_get_charger_type(struct usb_phy *usb_phy)
@@ -675,11 +637,6 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
}
EXPORT_SYMBOL_GPL(usb_add_phy);
-static const struct device_type usb_phy_dev_type = {
- .name = "usb_phy",
- .uevent = usb_phy_uevent,
-};
-
/**
* usb_add_phy_dev - declare the USB PHY
* @x: the USB phy to be used; or NULL
@@ -705,8 +662,6 @@ int usb_add_phy_dev(struct usb_phy *x)
if (ret)
return ret;
- x->dev->type = &usb_phy_dev_type;
-
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
spin_lock_irqsave(&phy_lock, flags);
|
| 3/2 | 2026/09/08 11:34 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 4248 output: 36 thoughts: 62 Thoughts: **Analyzing the USB PHY Patch** Okay, let's dive into this. My first move is always to methodically break down the patch and its instructions. Gotta understand the scope before I even think about potential integration. The focus is clearly on the USB PHY, so I need to establish a precise understanding of the changes. My initial focus will be on the specific modifications made to `drivers/usb/phy/phy.c`. I need to thoroughly dissect the code diff, paying close attention to any functions altered, additions, or removals. I also want to cross-reference the `Kconfig` file within `drivers/usb/phy/`. I'll be looking for any changes in configuration options or dependencies that this patch might introduce, as these always require careful consideration during integration, especially considering the project's current USB PHY implementation. I need to understand if the patch adds new features, fixes bugs, or simply refactors existing code. |
| 4/2 | 2026/09/08 11:34 | tool | grepper |
0mArgs:{
"Expression": "NOP_USB_XCEIV|USB_PHY",
"PathPrefix": "drivers/usb/phy"
}Results: {
"Output": "drivers/usb/phy/Kconfig=5=menu \"USB Physical Layer drivers\"\ndrivers/usb/phy/Kconfig-6-\ndrivers/usb/phy/Kconfig:7:config USB_PHY\ndrivers/usb/phy/Kconfig-8-\tselect EXTCON\n--\ndrivers/usb/phy/Kconfig=14=config AB8500_USB\n--\ndrivers/usb/phy/Kconfig-16-\tdepends on AB8500_CORE\ndrivers/usb/phy/Kconfig:17:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-18-\thelp\n--\ndrivers/usb/phy/Kconfig=23=config FSL_USB2_OTG\n--\ndrivers/usb/phy/Kconfig-26-\tdepends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'\ndrivers/usb/phy/Kconfig:27:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-28-\thelp\n--\ndrivers/usb/phy/Kconfig-30-\ndrivers/usb/phy/Kconfig:31:config KEYSTONE_USB_PHY\ndrivers/usb/phy/Kconfig-32-\ttristate \"Keystone USB PHY Driver\"\ndrivers/usb/phy/Kconfig-33-\tdepends on ARCH_KEYSTONE || COMPILE_TEST\ndrivers/usb/phy/Kconfig:34:\tdepends on NOP_USB_XCEIV\ndrivers/usb/phy/Kconfig-35-\thelp\n--\ndrivers/usb/phy/Kconfig-39-\ndrivers/usb/phy/Kconfig:40:config NOP_USB_XCEIV\ndrivers/usb/phy/Kconfig-41-\ttristate \"NOP USB Transceiver Driver\"\ndrivers/usb/phy/Kconfig-42-\tdepends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, NOP can't be built-in\ndrivers/usb/phy/Kconfig:43:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-44-\thelp\n--\ndrivers/usb/phy/Kconfig=52=config AM335X_PHY_USB\n--\ndrivers/usb/phy/Kconfig-54-\tdepends on ARM || COMPILE_TEST\ndrivers/usb/phy/Kconfig:55:\tdepends on NOP_USB_XCEIV\ndrivers/usb/phy/Kconfig:56:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-57-\tselect AM335X_CONTROL_USB\n--\ndrivers/usb/phy/Kconfig=75=config USB_GPIO_VBUS\n--\ndrivers/usb/phy/Kconfig-79-\tdepends on !USB_CONN_GPIO\ndrivers/usb/phy/Kconfig:80:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-81-\thelp\n--\ndrivers/usb/phy/Kconfig=100=config TAHVO_USB\n--\ndrivers/usb/phy/Kconfig-103-\tdepends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'\ndrivers/usb/phy/Kconfig:104:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-105-\thelp\n--\ndrivers/usb/phy/Kconfig=116=config USB_ISP1301\n--\ndrivers/usb/phy/Kconfig-119-\tdepends on I2C\ndrivers/usb/phy/Kconfig:120:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-121-\thelp\n--\ndrivers/usb/phy/Kconfig=129=config USB_MXS_PHY\n--\ndrivers/usb/phy/Kconfig-132-\tselect STMP_DEVICE\ndrivers/usb/phy/Kconfig:133:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-134-\thelp\n--\ndrivers/usb/phy/Kconfig=139=config USB_TEGRA_PHY\n--\ndrivers/usb/phy/Kconfig-142-\tselect USB_COMMON\ndrivers/usb/phy/Kconfig:143:\tselect USB_PHY\ndrivers/usb/phy/Kconfig-144-\tselect USB_ULPI\n--\ndrivers/usb/phy/Makefile-4-#\ndrivers/usb/phy/Makefile:5:obj-$(CONFIG_USB_PHY)\t\t\t+= phy.o\ndrivers/usb/phy/Makefile-6-obj-$(CONFIG_OF)\t\t\t+= of.o\n--\ndrivers/usb/phy/Makefile=11=obj-$(CONFIG_FSL_USB2_OTG)\t\t+= phy-fsl-usb.o\ndrivers/usb/phy/Makefile:12:obj-$(CONFIG_NOP_USB_XCEIV)\t\t+= phy-generic.o\ndrivers/usb/phy/Makefile-13-obj-$(CONFIG_TAHVO_USB)\t\t\t+= phy-tahvo.o\n--\ndrivers/usb/phy/Makefile=23=obj-$(CONFIG_USB_ULPI_VIEWPORT)\t\t+= phy-ulpi-viewport.o\ndrivers/usb/phy/Makefile:24:obj-$(CONFIG_KEYSTONE_USB_PHY)\t\t+= phy-keystone.o\n--\ndrivers/usb/phy/phy-ab8500-usb.c-31-#define AB8505_USB_LINE_STAT_REG 0x94\ndrivers/usb/phy/phy-ab8500-usb.c:32:#define AB8500_USB_PHY_CTRL_REG 0x8A\ndrivers/usb/phy/phy-ab8500-usb.c-33-\n--\ndrivers/usb/phy/phy-ab8500-usb.c-37-/* Bank AB8500_DEBUG */\ndrivers/usb/phy/phy-ab8500-usb.c:38:#define AB8500_USB_PHY_TUNE1 0x05\ndrivers/usb/phy/phy-ab8500-usb.c:39:#define AB8500_USB_PHY_TUNE2 0x06\ndrivers/usb/phy/phy-ab8500-usb.c:40:#define AB8500_USB_PHY_TUNE3 0x07\ndrivers/usb/phy/phy-ab8500-usb.c-41-\n--\ndrivers/usb/phy/phy-ab8500-usb.c=240=static void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-244-\t\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:245:\t\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-246-\t\t\t\tbit, bit);\n--\ndrivers/usb/phy/phy-ab8500-usb.c=251=static void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-267-\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:268:\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-269-\t\t\tbit, bit);\n--\ndrivers/usb/phy/phy-ab8500-usb.c=272=static void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-280-\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:281:\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-282-\t\t\tbit, 0);\n--\ndrivers/usb/phy/phy-ab8500-usb.c=562=static irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-597-\t\t\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:598:\t\t\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-599-\t\t\t\t\tAB8500_BIT_PHY_CTRL_DEVICE_EN, 0);\n--\ndrivers/usb/phy/phy-ab8500-usb.c=682=static void ab8500_usb_restart_phy(struct ab8500_usb *ab)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-684-\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:685:\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-686-\t\t\tAB8500_BIT_PHY_CTRL_DEVICE_EN,\n--\ndrivers/usb/phy/phy-ab8500-usb.c-691-\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:692:\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-693-\t\t\tAB8500_BIT_PHY_CTRL_DEVICE_EN,\n--\ndrivers/usb/phy/phy-ab8500-usb.c-696-\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:697:\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-698-\t\t\tAB8500_BIT_PHY_CTRL_HOST_EN,\n--\ndrivers/usb/phy/phy-ab8500-usb.c-703-\tabx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:704:\t\t\tAB8500_USB, AB8500_USB_PHY_CTRL_REG,\ndrivers/usb/phy/phy-ab8500-usb.c-705-\t\t\tAB8500_BIT_PHY_CTRL_HOST_EN,\n--\ndrivers/usb/phy/phy-ab8500-usb.c=788=static void ab8500_usb_set_ab8500_tuning_values(struct ab8500_usb *ab)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-799-\terr = abx500_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:800:\t\t\tAB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8);\ndrivers/usb/phy/phy-ab8500-usb.c-801-\tif (err \u003c 0)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-805-\terr = abx500_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:806:\t\t\tAB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00);\ndrivers/usb/phy/phy-ab8500-usb.c-807-\tif (err \u003c 0)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-811-\terr = abx500_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:812:\t\t\tAB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78);\ndrivers/usb/phy/phy-ab8500-usb.c-813-\tif (err \u003c 0)\n--\ndrivers/usb/phy/phy-ab8500-usb.c=825=static void ab8500_usb_set_ab8505_tuning_values(struct ab8500_usb *ab)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-837-\terr = abx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:838:\t\t\tAB8500_DEBUG, AB8500_USB_PHY_TUNE1,\ndrivers/usb/phy/phy-ab8500-usb.c-839-\t\t\t0xC8, 0xC8);\n--\ndrivers/usb/phy/phy-ab8500-usb.c-844-\terr = abx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:845:\t\t\tAB8500_DEBUG, AB8500_USB_PHY_TUNE2,\ndrivers/usb/phy/phy-ab8500-usb.c-846-\t\t\t0x60, 0x60);\n--\ndrivers/usb/phy/phy-ab8500-usb.c-851-\terr = abx500_mask_and_set_register_interruptible(ab-\u003edev,\ndrivers/usb/phy/phy-ab8500-usb.c:852:\t\t\tAB8500_DEBUG, AB8500_USB_PHY_TUNE3,\ndrivers/usb/phy/phy-ab8500-usb.c-853-\t\t\t0xFC, 0x80);\n--\ndrivers/usb/phy/phy-ab8500-usb.c=868=static int ab8500_usb_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-938-\ndrivers/usb/phy/phy-ab8500-usb.c:939:\terr = usb_add_phy(\u0026ab-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-ab8500-usb.c-940-\tif (err) {\n--\ndrivers/usb/phy/phy-fsl-usb.c=773=static int fsl_otg_conf(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-fsl-usb.c-817-\t/* Store the otg transceiver */\ndrivers/usb/phy/phy-fsl-usb.c:818:\tstatus = usb_add_phy(\u0026fsl_otg_tc-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-fsl-usb.c-819-\tif (status) {\n--\ndrivers/usb/phy/phy-fsl-usb.c=833=static int usb_otg_start(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-fsl-usb.c-835-\tstruct fsl_otg *p_otg;\ndrivers/usb/phy/phy-fsl-usb.c:836:\tstruct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-fsl-usb.c-837-\tstruct otg_fsm *fsm;\n--\ndrivers/usb/phy/phy-generic.c=196=int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop)\ndrivers/usb/phy/phy-generic.c-197-{\ndrivers/usb/phy/phy-generic.c:198:\tenum usb_phy_type type = USB_PHY_TYPE_USB2;\ndrivers/usb/phy/phy-generic.c-199-\tint err = 0;\n--\ndrivers/usb/phy/phy-gpio-vbus-usb.c=231=static int gpio_vbus_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-gpio-vbus-usb.c-315-\t/* only active when a gadget is registered */\ndrivers/usb/phy/phy-gpio-vbus-usb.c:316:\terr = usb_add_phy(\u0026gpio_vbus-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-gpio-vbus-usb.c-317-\tif (err) {\n--\ndrivers/usb/phy/phy-isp1301.c=95=static int isp1301_probe(struct i2c_client *client)\n--\ndrivers/usb/phy/phy-isp1301.c-111-\tphy-\u003eset_vbus = isp1301_phy_set_vbus;\ndrivers/usb/phy/phy-isp1301.c:112:\tphy-\u003etype = USB_PHY_TYPE_USB2;\ndrivers/usb/phy/phy-isp1301.c-113-\n--\ndrivers/usb/phy/phy-keystone.c-18-/* USB PHY control register offsets */\ndrivers/usb/phy/phy-keystone.c:19:#define USB_PHY_CTL_UTMI\t\t0x0000\ndrivers/usb/phy/phy-keystone.c:20:#define USB_PHY_CTL_PIPE\t\t0x0004\ndrivers/usb/phy/phy-keystone.c:21:#define USB_PHY_CTL_PARAM_1\t\t0x0008\ndrivers/usb/phy/phy-keystone.c:22:#define USB_PHY_CTL_PARAM_2\t\t0x000c\ndrivers/usb/phy/phy-keystone.c:23:#define USB_PHY_CTL_CLOCK\t\t0x0010\ndrivers/usb/phy/phy-keystone.c:24:#define USB_PHY_CTL_PLL\t\t\t0x0014\ndrivers/usb/phy/phy-keystone.c-25-\n--\ndrivers/usb/phy/phy-keystone.c=44=static int keystone_usbphy_init(struct usb_phy *phy)\n--\ndrivers/usb/phy/phy-keystone.c-48-\ndrivers/usb/phy/phy-keystone.c:49:\tval = keystone_usbphy_readl(k_phy-\u003ephy_ctrl, USB_PHY_CTL_CLOCK);\ndrivers/usb/phy/phy-keystone.c:50:\tkeystone_usbphy_writel(k_phy-\u003ephy_ctrl, USB_PHY_CTL_CLOCK,\ndrivers/usb/phy/phy-keystone.c-51-\t\t\t\tval | PHY_REF_SSP_EN);\n--\ndrivers/usb/phy/phy-keystone.c=55=static void keystone_usbphy_shutdown(struct usb_phy *phy)\n--\ndrivers/usb/phy/phy-keystone.c-59-\ndrivers/usb/phy/phy-keystone.c:60:\tval = keystone_usbphy_readl(k_phy-\u003ephy_ctrl, USB_PHY_CTL_CLOCK);\ndrivers/usb/phy/phy-keystone.c:61:\tkeystone_usbphy_writel(k_phy-\u003ephy_ctrl, USB_PHY_CTL_CLOCK,\ndrivers/usb/phy/phy-keystone.c-62-\t\t\t\tval \u0026 ~PHY_REF_SSP_EN);\n--\ndrivers/usb/phy/phy-mxs-usb.c-126-\ndrivers/usb/phy/phy-mxs-usb.c:127:#define USB_PHY_VLLS_WAKEUP_EN\t\t\tBIT(0)\ndrivers/usb/phy/phy-mxs-usb.c-128-\n--\ndrivers/usb/phy/phy-mxs-usb.c=758=static int mxs_phy_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-mxs-usb.c-845-\tmxs_phy-\u003ephy.notify_disconnect\t= mxs_phy_on_disconnect;\ndrivers/usb/phy/phy-mxs-usb.c:846:\tmxs_phy-\u003ephy.type\t\t= USB_PHY_TYPE_USB2;\ndrivers/usb/phy/phy-mxs-usb.c-847-\tmxs_phy-\u003ephy.set_wakeup\t\t= mxs_phy_set_wakeup;\n--\ndrivers/usb/phy/phy-mxs-usb.c=879=static void mxs_phy_wakeup_enable(struct mxs_phy *mxs_phy, bool on)\ndrivers/usb/phy/phy-mxs-usb.c-880-{\ndrivers/usb/phy/phy-mxs-usb.c:881:\tu32 mask = USB_PHY_VLLS_WAKEUP_EN;\ndrivers/usb/phy/phy-mxs-usb.c-882-\n--\ndrivers/usb/phy/phy-tahvo.c=319=static int tahvo_usb_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-tahvo.c-383-\ndrivers/usb/phy/phy-tahvo.c:384:\tret = usb_add_phy(\u0026tu-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-tahvo.c-385-\tif (ret \u003c 0) {\n--\ndrivers/usb/phy/phy-tegra-usb.c-60-#define USB_SUSP_CLR\t\t\t\tBIT(5)\ndrivers/usb/phy/phy-tegra-usb.c:61:#define USB_PHY_CLK_VALID\t\t\tBIT(7)\ndrivers/usb/phy/phy-tegra-usb.c-62-#define UTMIP_RESET\t\t\t\tBIT(11)\n--\ndrivers/usb/phy/phy-tegra-usb.c-69-\ndrivers/usb/phy/phy-tegra-usb.c:70:#define USB_PHY_VBUS_SENSORS\t\t\t0x404\ndrivers/usb/phy/phy-tegra-usb.c-71-#define B_SESS_VLD_WAKEUP_EN\t\t\tBIT(14)\n--\ndrivers/usb/phy/phy-tegra-usb.c-74-\ndrivers/usb/phy/phy-tegra-usb.c:75:#define USB_PHY_VBUS_WAKEUP_ID\t\t\t0x408\ndrivers/usb/phy/phy-tegra-usb.c-76-#define ID_INT_EN\t\t\t\tBIT(0)\n--\ndrivers/usb/phy/phy-tegra-usb.c=484=static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)\n--\ndrivers/usb/phy/phy-tegra-usb.c-493-\t */\ndrivers/usb/phy/phy-tegra-usb.c:494:\tif (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) == 0)\ndrivers/usb/phy/phy-tegra-usb.c-495-\t\treturn;\n--\ndrivers/usb/phy/phy-tegra-usb.c-510-\ndrivers/usb/phy/phy-tegra-usb.c:511:\tif (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0))\ndrivers/usb/phy/phy-tegra-usb.c-512-\t\tdev_err(phy-\u003eu_phy.dev,\n--\ndrivers/usb/phy/phy-tegra-usb.c=516=static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)\n--\ndrivers/usb/phy/phy-tegra-usb.c-525-\t */\ndrivers/usb/phy/phy-tegra-usb.c:526:\tif (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,\ndrivers/usb/phy/phy-tegra-usb.c:527:\t\t\t USB_PHY_CLK_VALID) == 0)\ndrivers/usb/phy/phy-tegra-usb.c-528-\t\treturn;\n--\ndrivers/usb/phy/phy-tegra-usb.c-543-\ndrivers/usb/phy/phy-tegra-usb.c:544:\tif (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,\ndrivers/usb/phy/phy-tegra-usb.c:545:\t\t\t USB_PHY_CLK_VALID))\ndrivers/usb/phy/phy-tegra-usb.c-546-\t\tdev_err(phy-\u003eu_phy.dev,\n--\ndrivers/usb/phy/phy-tegra-usb.c=550=static int utmi_phy_power_on(struct tegra_usb_phy *phy)\n--\ndrivers/usb/phy/phy-tegra-usb.c-615-\ndrivers/usb/phy/phy-tegra-usb.c:616:\t\tval = readl_relaxed(base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-617-\t\tval \u0026= ~VBUS_WAKEUP_WAKEUP_EN;\ndrivers/usb/phy/phy-tegra-usb.c-618-\t\tval \u0026= ~(ID_CHG_DET | VBUS_WAKEUP_CHG_DET);\ndrivers/usb/phy/phy-tegra-usb.c:619:\t\twritel_relaxed(val, base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-620-\ndrivers/usb/phy/phy-tegra-usb.c:621:\t\tval = readl_relaxed(base + USB_PHY_VBUS_SENSORS);\ndrivers/usb/phy/phy-tegra-usb.c-622-\t\tval \u0026= ~(A_VBUS_VLD_WAKEUP_EN | A_SESS_VLD_WAKEUP_EN);\ndrivers/usb/phy/phy-tegra-usb.c-623-\t\tval \u0026= ~(B_SESS_VLD_WAKEUP_EN);\ndrivers/usb/phy/phy-tegra-usb.c:624:\t\twritel_relaxed(val, base + USB_PHY_VBUS_SENSORS);\ndrivers/usb/phy/phy-tegra-usb.c-625-\n--\ndrivers/usb/phy/phy-tegra-usb.c=716=static int utmi_phy_power_off(struct tegra_usb_phy *phy)\n--\ndrivers/usb/phy/phy-tegra-usb.c-725-\tif (phy-\u003ewakeup_enabled \u0026\u0026 phy-\u003emode != USB_DR_MODE_HOST)\ndrivers/usb/phy/phy-tegra-usb.c:726:\t\treadl_relaxed_poll_timeout(base + USB_PHY_VBUS_WAKEUP_ID,\ndrivers/usb/phy/phy-tegra-usb.c-727-\t\t\t\t\t val, !(val \u0026 VBUS_WAKEUP_STS),\n--\ndrivers/usb/phy/phy-tegra-usb.c-766-\t\tif (phy-\u003emode != USB_DR_MODE_HOST) {\ndrivers/usb/phy/phy-tegra-usb.c:767:\t\t\tval = readl_relaxed(base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-768-\t\t\tval |= VBUS_WAKEUP_WAKEUP_EN;\ndrivers/usb/phy/phy-tegra-usb.c-769-\t\t\tval \u0026= ~(ID_CHG_DET | VBUS_WAKEUP_CHG_DET);\ndrivers/usb/phy/phy-tegra-usb.c:770:\t\t\twritel_relaxed(val, base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-771-\ndrivers/usb/phy/phy-tegra-usb.c:772:\t\t\tval = readl_relaxed(base + USB_PHY_VBUS_SENSORS);\ndrivers/usb/phy/phy-tegra-usb.c-773-\t\t\tval |= A_VBUS_VLD_WAKEUP_EN;\ndrivers/usb/phy/phy-tegra-usb.c:774:\t\t\twritel_relaxed(val, base + USB_PHY_VBUS_SENSORS);\ndrivers/usb/phy/phy-tegra-usb.c-775-\t\t}\n--\ndrivers/usb/phy/phy-tegra-usb.c=889=static int uhsic_phy_power_on(struct tegra_usb_phy *phy)\n--\ndrivers/usb/phy/phy-tegra-usb.c-977-\ndrivers/usb/phy/phy-tegra-usb.c:978:\terr = utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,\ndrivers/usb/phy/phy-tegra-usb.c:979:\t\t\t\t USB_PHY_CLK_VALID);\ndrivers/usb/phy/phy-tegra-usb.c-980-\n--\ndrivers/usb/phy/phy-tegra-usb.c=1099=static irqreturn_t tegra_usb_phy_isr(int irq, void *data)\n--\ndrivers/usb/phy/phy-tegra-usb.c-1109-\t */\ndrivers/usb/phy/phy-tegra-usb.c:1110:\tval = readl_relaxed(base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c:1111:\twritel_relaxed(val, base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-1112-\n--\ndrivers/usb/phy/phy-tegra-usb.c=1116=static int tegra_usb_phy_set_wakeup(struct usb_phy *u_phy, bool enable)\n--\ndrivers/usb/phy/phy-tegra-usb.c-1126-\ndrivers/usb/phy/phy-tegra-usb.c:1127:\t\tval = readl_relaxed(base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-1128-\t\tval \u0026= ~(ID_INT_EN | VBUS_WAKEUP_INT_EN);\ndrivers/usb/phy/phy-tegra-usb.c:1129:\t\twritel_relaxed(val, base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-1130-\n--\ndrivers/usb/phy/phy-tegra-usb.c-1148-\t\t\t */\ndrivers/usb/phy/phy-tegra-usb.c:1149:\t\t\tval = readl_relaxed(base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-1150-\t\t\tval |= ID_INT_EN | VBUS_WAKEUP_INT_EN;\ndrivers/usb/phy/phy-tegra-usb.c:1151:\t\t\twritel_relaxed(val, base + USB_PHY_VBUS_WAKEUP_ID);\ndrivers/usb/phy/phy-tegra-usb.c-1152-\n--\ndrivers/usb/phy/phy.c=600=int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)\n--\ndrivers/usb/phy/phy.c-605-\ndrivers/usb/phy/phy.c:606:\tif (x-\u003etype != USB_PHY_TYPE_UNDEFINED) {\ndrivers/usb/phy/phy.c-607-\t\tdev_err(x-\u003edev, \"not accepting initialized PHY %s\\n\", x-\u003elabel);\n"
} |
| 5/2 | 2026/09/08 11:34 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 12912 output: 36 thoughts: 51 Thoughts: Here's my understanding, as if I were the one thinking it: **Diving into USB PHY Charger Implementation** Alright, let's get down to brass tacks. I need to understand how these USB PHY chargers are implemented. The best place to start is definitely `drivers/usb/phy/phy.c`, specifically looking at the recent modifications. I'm focusing on the interaction between `usb_phy_notify_charger_work` and `usb_add_phy_dev`, because that's where the core of the charger functionality probably resides. I need to see *how* these functions are coordinated – what triggers them, what data they exchange, and what resources they manage. Understanding this interplay will give me the most critical insights into the design. Then I'll be able to tell what's correct, and maybe see some areas for improvement. Time to dig in and see how they've structured the driver. |
| 6/2 | 2026/09/08 11:34 | tool | read-file |
0mArgs:{
"File": "drivers/usb/phy/phy.c",
"FirstLine": 1,
"LineCount": 100
}Results: {
"Contents": " 1:\t// SPDX-License-Identifier: GPL-2.0+\n 2:\t/*\n 3:\t * phy.c -- USB phy handling\n 4:\t *\n 5:\t * Copyright (C) 2004-2013 Texas Instruments\n 6:\t */\n 7:\t#include \u003clinux/kernel.h\u003e\n 8:\t#include \u003clinux/export.h\u003e\n 9:\t#include \u003clinux/err.h\u003e\n 10:\t#include \u003clinux/device.h\u003e\n 11:\t#include \u003clinux/module.h\u003e\n 12:\t#include \u003clinux/slab.h\u003e\n 13:\t#include \u003clinux/of.h\u003e\n 14:\t\n 15:\t#include \u003clinux/usb/phy.h\u003e\n 16:\t\n 17:\t/* Default current range by charger type. */\n 18:\t#define DEFAULT_SDP_CUR_MIN\t2\n 19:\t#define DEFAULT_SDP_CUR_MAX\t500\n 20:\t#define DEFAULT_SDP_CUR_MIN_SS\t150\n 21:\t#define DEFAULT_SDP_CUR_MAX_SS\t900\n 22:\t#define DEFAULT_DCP_CUR_MIN\t500\n 23:\t#define DEFAULT_DCP_CUR_MAX\t5000\n 24:\t#define DEFAULT_CDP_CUR_MIN\t1500\n 25:\t#define DEFAULT_CDP_CUR_MAX\t5000\n 26:\t#define DEFAULT_ACA_CUR_MIN\t1500\n 27:\t#define DEFAULT_ACA_CUR_MAX\t5000\n 28:\t\n 29:\tstatic LIST_HEAD(phy_list);\n 30:\tstatic DEFINE_SPINLOCK(phy_lock);\n 31:\t\n 32:\tstruct phy_devm {\n 33:\t\tstruct usb_phy *phy;\n 34:\t\tstruct notifier_block *nb;\n 35:\t};\n 36:\t\n 37:\tstatic const char *const usb_chger_type[] = {\n 38:\t\t[UNKNOWN_TYPE]\t\t\t= \"USB_CHARGER_UNKNOWN_TYPE\",\n 39:\t\t[SDP_TYPE]\t\t\t= \"USB_CHARGER_SDP_TYPE\",\n 40:\t\t[CDP_TYPE]\t\t\t= \"USB_CHARGER_CDP_TYPE\",\n 41:\t\t[DCP_TYPE]\t\t\t= \"USB_CHARGER_DCP_TYPE\",\n 42:\t\t[ACA_TYPE]\t\t\t= \"USB_CHARGER_ACA_TYPE\",\n 43:\t};\n 44:\t\n 45:\tstatic struct usb_phy *__usb_find_phy(struct list_head *list,\n 46:\t\tenum usb_phy_type type)\n 47:\t{\n 48:\t\tstruct usb_phy *phy = NULL;\n 49:\t\n 50:\t\tlist_for_each_entry(phy, list, head) {\n 51:\t\t\tif (phy-\u003etype != type)\n 52:\t\t\t\tcontinue;\n 53:\t\n 54:\t\t\treturn phy;\n 55:\t\t}\n 56:\t\n 57:\t\treturn ERR_PTR(-ENODEV);\n 58:\t}\n 59:\t\n 60:\tstatic struct usb_phy *__of_usb_find_phy(struct device_node *node)\n 61:\t{\n 62:\t\tstruct usb_phy *phy;\n 63:\t\n 64:\t\tif (!of_device_is_available(node))\n 65:\t\t\treturn ERR_PTR(-ENODEV);\n 66:\t\n 67:\t\tlist_for_each_entry(phy, \u0026phy_list, head) {\n 68:\t\t\tif (node != phy-\u003edev-\u003eof_node)\n 69:\t\t\t\tcontinue;\n 70:\t\n 71:\t\t\treturn phy;\n 72:\t\t}\n 73:\t\n 74:\t\treturn ERR_PTR(-EPROBE_DEFER);\n 75:\t}\n 76:\t\n 77:\tstatic void usb_phy_set_default_current(struct usb_phy *usb_phy)\n 78:\t{\n 79:\t\tusb_phy-\u003echg_cur.sdp_min = DEFAULT_SDP_CUR_MIN;\n 80:\t\tusb_phy-\u003echg_cur.sdp_max = DEFAULT_SDP_CUR_MAX;\n 81:\t\tusb_phy-\u003echg_cur.dcp_min = DEFAULT_DCP_CUR_MIN;\n 82:\t\tusb_phy-\u003echg_cur.dcp_max = DEFAULT_DCP_CUR_MAX;\n 83:\t\tusb_phy-\u003echg_cur.cdp_min = DEFAULT_CDP_CUR_MIN;\n 84:\t\tusb_phy-\u003echg_cur.cdp_max = DEFAULT_CDP_CUR_MAX;\n 85:\t\tusb_phy-\u003echg_cur.aca_min = DEFAULT_ACA_CUR_MIN;\n 86:\t\tusb_phy-\u003echg_cur.aca_max = DEFAULT_ACA_CUR_MAX;\n 87:\t}\n 88:\t\n 89:\t/**\n 90:\t * usb_phy_notify_charger_work - notify the USB charger state\n 91:\t * @work: the charger work to notify the USB charger state\n 92:\t *\n 93:\t * This work can be issued when USB charger state has been changed or\n 94:\t * USB charger current has been changed, then we can notify the current\n 95:\t * what can be drawn to power user and the charger state to userspace.\n 96:\t *\n 97:\t * If we get the charger type from extcon subsystem, we can notify the\n 98:\t * charger state to power user automatically by usb_phy_get_charger_type()\n 99:\t * issuing from extcon subsystem.\n 100:\t *\n"
} |
| 7/2 | 2026/09/08 11:34 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 14716 output: 38 thoughts: 18 Thoughts: Okay, here's my interpretation of what's going through my mind as I approach this task, rendered in the first person: **Diving into `drivers/usb/phy/phy.c`** Alright, time to dig into `drivers/usb/phy/phy.c`. This is where the USB PHY (Physical Layer) drivers reside, the crucial bridge between the digital world of the USB controller and the analog signals zipping across the USB cable. I'm already anticipating some interesting implementation details here, given the often complex requirements of these low-level interfaces. I'll be looking for the standard structure definitions, the PHY initialization and de-initialization sequences, and of course, the interrupt handlers that respond to USB events at the physical layer. I'll likely be checking for clock configuration, power management considerations, and potentially even specific hardware quirks or errata workarounds that are common in this kind of driver. Let's see how well it's structured, how clearly the abstraction is defined, and whether it aligns with the device's documentation. I'll be particularly interested in whether there are any vendor-specific extensions and how they're managed. Let's see what we've got! |
| 8/2 | 2026/09/08 11:34 | tool | read-file |
0mArgs:{
"File": "drivers/usb/phy/phy.c",
"FirstLine": 101,
"LineCount": 100
}Results: {
"Contents": " 101:\t * If we get the charger type from -\u003echarger_detect() instead of extcon\n 102:\t * subsystem, the usb phy driver should issue usb_phy_set_charger_state()\n 103:\t * to set charger state when the charger state has been changed.\n 104:\t */\n 105:\tstatic void usb_phy_notify_charger_work(struct work_struct *work)\n 106:\t{\n 107:\t\tstruct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work);\n 108:\t\tchar uchger_state[50] = { 0 };\n 109:\t\tchar uchger_type[50] = { 0 };\n 110:\t\tchar *envp[] = { uchger_state, uchger_type, NULL };\n 111:\t\tunsigned int min, max;\n 112:\t\n 113:\t\tswitch (usb_phy-\u003echg_state) {\n 114:\t\tcase USB_CHARGER_PRESENT:\n 115:\t\t\tusb_phy_get_charger_current(usb_phy, \u0026min, \u0026max);\n 116:\t\n 117:\t\t\tatomic_notifier_call_chain(\u0026usb_phy-\u003enotifier, max, usb_phy);\n 118:\t\t\tsnprintf(uchger_state, ARRAY_SIZE(uchger_state),\n 119:\t\t\t\t \"USB_CHARGER_STATE=%s\", \"USB_CHARGER_PRESENT\");\n 120:\t\t\tbreak;\n 121:\t\tcase USB_CHARGER_ABSENT:\n 122:\t\t\tusb_phy_set_default_current(usb_phy);\n 123:\t\n 124:\t\t\tatomic_notifier_call_chain(\u0026usb_phy-\u003enotifier, 0, usb_phy);\n 125:\t\t\tsnprintf(uchger_state, ARRAY_SIZE(uchger_state),\n 126:\t\t\t\t \"USB_CHARGER_STATE=%s\", \"USB_CHARGER_ABSENT\");\n 127:\t\t\tbreak;\n 128:\t\tdefault:\n 129:\t\t\tdev_warn(usb_phy-\u003edev, \"Unknown USB charger state: %d\\n\",\n 130:\t\t\t\t usb_phy-\u003echg_state);\n 131:\t\t\treturn;\n 132:\t\t}\n 133:\t\n 134:\t\tsnprintf(uchger_type, ARRAY_SIZE(uchger_type),\n 135:\t\t\t \"USB_CHARGER_TYPE=%s\", usb_chger_type[usb_phy-\u003echg_type]);\n 136:\t\tkobject_uevent_env(\u0026usb_phy-\u003edev-\u003ekobj, KOBJ_CHANGE, envp);\n 137:\t}\n 138:\t\n 139:\tstatic void __usb_phy_get_charger_type(struct usb_phy *usb_phy)\n 140:\t{\n 141:\t\tif (extcon_get_state(usb_phy-\u003eedev, EXTCON_CHG_USB_SDP) \u003e 0) {\n 142:\t\t\tusb_phy-\u003echg_type = SDP_TYPE;\n 143:\t\t\tusb_phy-\u003echg_state = USB_CHARGER_PRESENT;\n 144:\t\t} else if (extcon_get_state(usb_phy-\u003eedev, EXTCON_CHG_USB_CDP) \u003e 0) {\n 145:\t\t\tusb_phy-\u003echg_type = CDP_TYPE;\n 146:\t\t\tusb_phy-\u003echg_state = USB_CHARGER_PRESENT;\n 147:\t\t} else if (extcon_get_state(usb_phy-\u003eedev, EXTCON_CHG_USB_DCP) \u003e 0) {\n 148:\t\t\tusb_phy-\u003echg_type = DCP_TYPE;\n 149:\t\t\tusb_phy-\u003echg_state = USB_CHARGER_PRESENT;\n 150:\t\t} else if (extcon_get_state(usb_phy-\u003eedev, EXTCON_CHG_USB_ACA) \u003e 0) {\n 151:\t\t\tusb_phy-\u003echg_type = ACA_TYPE;\n 152:\t\t\tusb_phy-\u003echg_state = USB_CHARGER_PRESENT;\n 153:\t\t} else {\n 154:\t\t\tusb_phy-\u003echg_type = UNKNOWN_TYPE;\n 155:\t\t\tusb_phy-\u003echg_state = USB_CHARGER_ABSENT;\n 156:\t\t}\n 157:\t\n 158:\t\tschedule_work(\u0026usb_phy-\u003echg_work);\n 159:\t}\n 160:\t\n 161:\t/**\n 162:\t * usb_phy_get_charger_type - get charger type from extcon subsystem\n 163:\t * @nb: the notifier block to determine charger type\n 164:\t * @state: the cable state\n 165:\t * @data: private data\n 166:\t *\n 167:\t * Determin the charger type from extcon subsystem which also means the\n 168:\t * charger state has been chaned, then we should notify this event.\n 169:\t */\n 170:\tstatic int usb_phy_get_charger_type(struct notifier_block *nb,\n 171:\t\t\t\t\t unsigned long state, void *data)\n 172:\t{\n 173:\t\tstruct usb_phy *usb_phy = container_of(nb, struct usb_phy, type_nb);\n 174:\t\n 175:\t\t__usb_phy_get_charger_type(usb_phy);\n 176:\t\treturn NOTIFY_OK;\n 177:\t}\n 178:\t\n 179:\t/**\n 180:\t * usb_phy_set_charger_current - set the USB charger current\n 181:\t * @usb_phy: the USB phy to be used\n 182:\t * @mA: the current need to be set\n 183:\t *\n 184:\t * Usually we only change the charger default current when USB finished the\n 185:\t * enumeration as one SDP charger. As one SDP charger, usb_phy_set_power()\n 186:\t * will issue this function to change charger current when after setting USB\n 187:\t * configuration, or suspend/resume USB. For other type charger, we should\n 188:\t * use the default charger current and we do not suggest to issue this function\n 189:\t * to change the charger current.\n 190:\t *\n 191:\t * When USB charger current has been changed, we need to notify the power users.\n 192:\t */\n 193:\tvoid usb_phy_set_charger_current(struct usb_phy *usb_phy, unsigned int mA)\n 194:\t{\n 195:\t\tswitch (usb_phy-\u003echg_type) {\n 196:\t\tcase SDP_TYPE:\n 197:\t\t\tif (usb_phy-\u003echg_cur.sdp_max == mA)\n 198:\t\t\t\treturn;\n 199:\t\n 200:\t\t\tusb_phy-\u003echg_cur.sdp_max = (mA \u003e DEFAULT_SDP_CUR_MAX_SS) ?\n"
} |
| 9/2 | 2026/09/08 11:34 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 16873 output: 45 thoughts: 466 Thoughts: **Analyzing the USB PHY Charger State Patch** Okay, let's dive back into this patch for `drivers/usb/phy/phy.c`. I need to fully understand the rationale behind these changes. Previously, here's how things worked: in `usb_add_phy_dev`, we assigned `x->dev->type = &usb_phy_dev_type`. This meant that the `uevent` function associated with that device type, `usb_phy_uevent`, would be called. Then, within `usb_phy_notify_charger_work`, we triggered a `kobject_uevent` to signal a change. This ultimately led to `usb_phy_uevent` being invoked, where we'd extract and add `USB_CHARGER_STATE` and `USB_CHARGER_TYPE` to the environment. Now, this patch is significantly refactoring that approach. They've eliminated `usb_chger_state`, `__device_to_usb_phy`, `usb_phy_uevent`, and `usb_phy_dev_type`. Instead, in `usb_phy_notify_charger_work`, they are constructing the `uchger_state` and `uchger_type` directly and using `kobject_uevent_env`. Plus, crucially, they removed the assignment of `x->dev->type = &usb_phy_dev_type` within `usb_add_phy_dev`. The stated reason is making sure we don't overwrite the original device type, or when uevent is generated directly from workqueue, it passes `envp` to `kobject_uevent_env`. This makes sense, because overwriting the device type can lead to unexpected behavior if another driver already set it, and this allows us to pass the environment directly to the `kobject_uevent`. Now, I need to verify that these changes are safe and the impact. Specifically, is the code in `drivers/usb/phy/phy.c` still reached? I should check all the callers of the functions that have been modified: `usb_phy_notify_charger_work`, `usb_phy_set_charger_state`, `usb_add_phy_dev`, and `usb_add_phy`. I also need to identify all the modules that depend on `drivers/usb/phy/phy.c` to understand the broader impact. |
| 10/2 | 2026/09/08 11:34 | tool | grepper |
0mArgs:{
"Expression": "usb_add_phy_dev|usb_add_phy|usb_phy_set_charger_state",
"PathPrefix": "drivers/"
}Results: {
"Output": "drivers/phy/motorola/phy-cpcap-usb.c=608=static int cpcap_usb_phy_probe(struct platform_device *pdev)\n--\ndrivers/phy/motorola/phy-cpcap-usb.c-675-\ndrivers/phy/motorola/phy-cpcap-usb.c:676:\tusb_add_phy_dev(\u0026ddata-\u003ephy);\ndrivers/phy/motorola/phy-cpcap-usb.c-677-\tatomic_set(\u0026ddata-\u003eactive, 1);\n--\ndrivers/phy/phy-lgm-usb.c=187=static int phy_probe(struct platform_device *pdev)\n--\ndrivers/phy/phy-lgm-usb.c-251-\ndrivers/phy/phy-lgm-usb.c:252:\treturn usb_add_phy_dev(phy);\ndrivers/phy/phy-lgm-usb.c-253-}\n--\ndrivers/phy/tegra/xusb.c=660=static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)\n--\ndrivers/phy/tegra/xusb.c-714-\ndrivers/phy/tegra/xusb.c:715:\terr = usb_add_phy_dev(\u0026port-\u003eusb_phy);\ndrivers/phy/tegra/xusb.c-716-\tif (err \u003c 0) {\n--\ndrivers/phy/ti/phy-dm816x-usb.c=171=static int dm816x_usb_phy_probe(struct platform_device *pdev)\n--\ndrivers/phy/ti/phy-dm816x-usb.c-240-\ndrivers/phy/ti/phy-dm816x-usb.c:241:\tusb_add_phy_dev(\u0026phy-\u003ephy);\ndrivers/phy/ti/phy-dm816x-usb.c-242-\n--\ndrivers/phy/ti/phy-omap-usb2.c=373=static int omap_usb2_probe(struct platform_device *pdev)\n--\ndrivers/phy/ti/phy-omap-usb2.c-511-\ndrivers/phy/ti/phy-omap-usb2.c:512:\tusb_add_phy_dev(\u0026phy-\u003ephy);\ndrivers/phy/ti/phy-omap-usb2.c-513-\n--\ndrivers/phy/ti/phy-twl4030-usb.c=683=static int twl4030_usb_probe(struct platform_device *pdev)\n--\ndrivers/phy/ti/phy-twl4030-usb.c-748-\t}\ndrivers/phy/ti/phy-twl4030-usb.c:749:\tusb_add_phy_dev(\u0026twl-\u003ephy);\ndrivers/phy/ti/phy-twl4030-usb.c-750-\n--\ndrivers/usb/chipidea/udc.c=1897=static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)\n--\ndrivers/usb/chipidea/udc.c-1907-\tif (ci-\u003eusb_phy)\ndrivers/usb/chipidea/udc.c:1908:\t\tusb_phy_set_charger_state(ci-\u003eusb_phy, is_active ?\ndrivers/usb/chipidea/udc.c-1909-\t\t\tUSB_CHARGER_PRESENT : USB_CHARGER_ABSENT);\n--\ndrivers/usb/phy/phy-ab8500-usb.c=868=static int ab8500_usb_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-ab8500-usb.c-938-\ndrivers/usb/phy/phy-ab8500-usb.c:939:\terr = usb_add_phy(\u0026ab-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-ab8500-usb.c-940-\tif (err) {\n--\ndrivers/usb/phy/phy-am335x.c=38=static int am335x_phy_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-am335x.c-81-\ndrivers/usb/phy/phy-am335x.c:82:\treturn usb_add_phy_dev(\u0026am_phy-\u003eusb_phy_gen.phy);\ndrivers/usb/phy/phy-am335x.c-83-}\n--\ndrivers/usb/phy/phy-fsl-usb.c=773=static int fsl_otg_conf(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-fsl-usb.c-817-\t/* Store the otg transceiver */\ndrivers/usb/phy/phy-fsl-usb.c:818:\tstatus = usb_add_phy(\u0026fsl_otg_tc-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-fsl-usb.c-819-\tif (status) {\n--\ndrivers/usb/phy/phy-generic.c=264=static int usb_phy_generic_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-generic.c-294-\ndrivers/usb/phy/phy-generic.c:295:\terr = usb_add_phy_dev(\u0026nop-\u003ephy);\ndrivers/usb/phy/phy-generic.c-296-\tif (err)\n--\ndrivers/usb/phy/phy-gpio-vbus-usb.c=231=static int gpio_vbus_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-gpio-vbus-usb.c-315-\t/* only active when a gadget is registered */\ndrivers/usb/phy/phy-gpio-vbus-usb.c:316:\terr = usb_add_phy(\u0026gpio_vbus-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-gpio-vbus-usb.c-317-\tif (err) {\n--\ndrivers/usb/phy/phy-isp1301.c=95=static int isp1301_probe(struct i2c_client *client)\n--\ndrivers/usb/phy/phy-isp1301.c-114-\ti2c_set_clientdata(client, isp);\ndrivers/usb/phy/phy-isp1301.c:115:\tusb_add_phy_dev(phy);\ndrivers/usb/phy/phy-isp1301.c-116-\n--\ndrivers/usb/phy/phy-keystone.c=65=static int keystone_usbphy_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-keystone.c-87-\ndrivers/usb/phy/phy-keystone.c:88:\treturn usb_add_phy_dev(\u0026k_phy-\u003eusb_phy_gen.phy);\ndrivers/usb/phy/phy-keystone.c-89-}\n--\ndrivers/usb/phy/phy-mxs-usb.c=758=static int mxs_phy_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-mxs-usb.c-867-\ndrivers/usb/phy/phy-mxs-usb.c:868:\treturn usb_add_phy_dev(\u0026mxs_phy-\u003ephy);\ndrivers/usb/phy/phy-mxs-usb.c-869-}\n--\ndrivers/usb/phy/phy-tahvo.c=319=static int tahvo_usb_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-tahvo.c-383-\ndrivers/usb/phy/phy-tahvo.c:384:\tret = usb_add_phy(\u0026tu-\u003ephy, USB_PHY_TYPE_USB2);\ndrivers/usb/phy/phy-tahvo.c-385-\tif (ret \u003c 0) {\n--\ndrivers/usb/phy/phy-tegra-usb.c=1490=static int tegra_usb_phy_probe(struct platform_device *pdev)\n--\ndrivers/usb/phy/phy-tegra-usb.c-1633-\ndrivers/usb/phy/phy-tegra-usb.c:1634:\treturn usb_add_phy_dev(\u0026tegra_phy-\u003eu_phy);\ndrivers/usb/phy/phy-tegra-usb.c-1635-}\n--\ndrivers/usb/phy/phy.c=77=static void usb_phy_set_default_current(struct usb_phy *usb_phy)\n--\ndrivers/usb/phy/phy.c-101- * If we get the charger type from -\u003echarger_detect() instead of extcon\ndrivers/usb/phy/phy.c:102: * subsystem, the usb phy driver should issue usb_phy_set_charger_state()\ndrivers/usb/phy/phy.c-103- * to set charger state when the charger state has been changed.\n--\ndrivers/usb/phy/phy.c=268=EXPORT_SYMBOL_GPL(usb_phy_get_charger_current);\n--\ndrivers/usb/phy/phy.c-270-/**\ndrivers/usb/phy/phy.c:271: * usb_phy_set_charger_state - set the USB charger state\ndrivers/usb/phy/phy.c-272- * @usb_phy: the USB phy to be used\n--\ndrivers/usb/phy/phy.c-278- */\ndrivers/usb/phy/phy.c:279:void usb_phy_set_charger_state(struct usb_phy *usb_phy,\ndrivers/usb/phy/phy.c-280-\t\t\t enum usb_charger_state state)\n--\ndrivers/usb/phy/phy.c-292-}\ndrivers/usb/phy/phy.c:293:EXPORT_SYMBOL_GPL(usb_phy_set_charger_state);\ndrivers/usb/phy/phy.c-294-\n--\ndrivers/usb/phy/phy.c=589=EXPORT_SYMBOL_GPL(usb_put_phy);\n--\ndrivers/usb/phy/phy.c-591-/**\ndrivers/usb/phy/phy.c:592: * usb_add_phy: declare the USB PHY\ndrivers/usb/phy/phy.c-593- * @x: the USB phy to be used; or NULL\n--\ndrivers/usb/phy/phy.c-599- */\ndrivers/usb/phy/phy.c:600:int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)\ndrivers/usb/phy/phy.c-601-{\n--\ndrivers/usb/phy/phy.c-637-}\ndrivers/usb/phy/phy.c:638:EXPORT_SYMBOL_GPL(usb_add_phy);\ndrivers/usb/phy/phy.c-639-\ndrivers/usb/phy/phy.c-640-/**\ndrivers/usb/phy/phy.c:641: * usb_add_phy_dev - declare the USB PHY\ndrivers/usb/phy/phy.c-642- * @x: the USB phy to be used; or NULL\n--\ndrivers/usb/phy/phy.c-647- */\ndrivers/usb/phy/phy.c:648:int usb_add_phy_dev(struct usb_phy *x)\ndrivers/usb/phy/phy.c-649-{\n--\ndrivers/usb/phy/phy.c-672-}\ndrivers/usb/phy/phy.c:673:EXPORT_SYMBOL_GPL(usb_add_phy_dev);\ndrivers/usb/phy/phy.c-674-\n--\ndrivers/usb/phy/phy.c-678- *\ndrivers/usb/phy/phy.c:679: * This reverts the effects of usb_add_phy\ndrivers/usb/phy/phy.c-680- */\n"
} |
| 11/2 | 2026/09/08 11:34 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 20965 output: 30 thoughts: 64 Thoughts: **Analyzing USB PHY Selection and Instantiation** Okay, let's break this down. It looks like the `USB_PHY` is a key component here, and multiple drivers, including `NOP_USB_XCEIV`, are involved in its selection. The crucial question now is, can we actually probe or instantiate this `NOP_USB_XCEIV`? I need to understand if it's a concrete entity or more of an abstract representation of a generic USB PHY. Time to dig into `phy-generic.c`. That should hold the key to understanding how this generic PHY is handled at the driver level, and whether we can directly interact with it. I'm hoping to find the implementation details of the generic USB transceiver logic within that file. |
| 12/2 | 2026/09/08 11:34 | tool | grepper |
0mArgs:{
"Expression": "usb_phy_generic",
"PathPrefix": "drivers/usb/phy"
}Results: {
"Output": "drivers/usb/phy/phy-am335x.c-5-#include \u003clinux/usb/otg.h\u003e\ndrivers/usb/phy/phy-am335x.c:6:#include \u003clinux/usb/usb_phy_generic.h\u003e\ndrivers/usb/phy/phy-am335x.c-7-#include \u003clinux/slab.h\u003e\n--\ndrivers/usb/phy/phy-am335x.c=16=struct am335x_phy {\ndrivers/usb/phy/phy-am335x.c:17:\tstruct usb_phy_generic usb_phy_gen;\ndrivers/usb/phy/phy-am335x.c-18-\tstruct phy_control *phy_ctrl;\n--\ndrivers/usb/phy/phy-generic.c-18-#include \u003clinux/usb/otg.h\u003e\ndrivers/usb/phy/phy-generic.c:19:#include \u003clinux/usb/usb_phy_generic.h\u003e\ndrivers/usb/phy/phy-generic.c-20-#include \u003clinux/slab.h\u003e\n--\ndrivers/usb/phy/phy-generic.c-32-\ndrivers/usb/phy/phy-generic.c:33:struct platform_device *usb_phy_generic_register(void)\ndrivers/usb/phy/phy-generic.c-34-{\ndrivers/usb/phy/phy-generic.c:35:\treturn platform_device_register_simple(\"usb_phy_generic\",\ndrivers/usb/phy/phy-generic.c-36-\t\t\tPLATFORM_DEVID_AUTO, NULL, 0);\ndrivers/usb/phy/phy-generic.c-37-}\ndrivers/usb/phy/phy-generic.c:38:EXPORT_SYMBOL_GPL(usb_phy_generic_register);\ndrivers/usb/phy/phy-generic.c-39-\ndrivers/usb/phy/phy-generic.c:40:void usb_phy_generic_unregister(struct platform_device *pdev)\ndrivers/usb/phy/phy-generic.c-41-{\n--\ndrivers/usb/phy/phy-generic.c-43-}\ndrivers/usb/phy/phy-generic.c:44:EXPORT_SYMBOL_GPL(usb_phy_generic_unregister);\ndrivers/usb/phy/phy-generic.c-45-\ndrivers/usb/phy/phy-generic.c=46=static int nop_set_suspend(struct usb_phy *x, int suspend)\ndrivers/usb/phy/phy-generic.c-47-{\ndrivers/usb/phy/phy-generic.c:48:\tstruct usb_phy_generic *nop = dev_get_drvdata(x-\u003edev);\ndrivers/usb/phy/phy-generic.c-49-\tint ret = 0;\n--\ndrivers/usb/phy/phy-generic.c-63-\ndrivers/usb/phy/phy-generic.c:64:static void nop_reset(struct usb_phy_generic *nop)\ndrivers/usb/phy/phy-generic.c-65-{\n--\ndrivers/usb/phy/phy-generic.c=76=static int nop_set_vbus(struct usb_otg *otg, bool enable)\n--\ndrivers/usb/phy/phy-generic.c-78-\tint ret = 0;\ndrivers/usb/phy/phy-generic.c:79:\tstruct usb_phy_generic *nop = dev_get_drvdata(otg-\u003eusb_phy-\u003edev);\ndrivers/usb/phy/phy-generic.c-80-\n--\ndrivers/usb/phy/phy-generic.c=99=static irqreturn_t nop_gpio_vbus_thread(int irq, void *data)\ndrivers/usb/phy/phy-generic.c-100-{\ndrivers/usb/phy/phy-generic.c:101:\tstruct usb_phy_generic *nop = data;\ndrivers/usb/phy/phy-generic.c-102-\tstruct usb_otg *otg = nop-\u003ephy.otg;\n--\ndrivers/usb/phy/phy-generic.c=128=int usb_gen_phy_init(struct usb_phy *phy)\ndrivers/usb/phy/phy-generic.c-129-{\ndrivers/usb/phy/phy-generic.c:130:\tstruct usb_phy_generic *nop = dev_get_drvdata(phy-\u003edev);\ndrivers/usb/phy/phy-generic.c-131-\tint ret;\n--\ndrivers/usb/phy/phy-generic.c=148=void usb_gen_phy_shutdown(struct usb_phy *phy)\ndrivers/usb/phy/phy-generic.c-149-{\ndrivers/usb/phy/phy-generic.c:150:\tstruct usb_phy_generic *nop = dev_get_drvdata(phy-\u003edev);\ndrivers/usb/phy/phy-generic.c-151-\n--\ndrivers/usb/phy/phy-generic.c=182=static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)\n--\ndrivers/usb/phy/phy-generic.c-195-\ndrivers/usb/phy/phy-generic.c:196:int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop)\ndrivers/usb/phy/phy-generic.c-197-{\n--\ndrivers/usb/phy/phy-generic.c=262=EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy);\ndrivers/usb/phy/phy-generic.c-263-\ndrivers/usb/phy/phy-generic.c:264:static int usb_phy_generic_probe(struct platform_device *pdev)\ndrivers/usb/phy/phy-generic.c-265-{\ndrivers/usb/phy/phy-generic.c-266-\tstruct device *dev = \u0026pdev-\u003edev;\ndrivers/usb/phy/phy-generic.c:267:\tstruct usb_phy_generic\t*nop;\ndrivers/usb/phy/phy-generic.c-268-\tint err;\n--\ndrivers/usb/phy/phy-generic.c-306-\ndrivers/usb/phy/phy-generic.c:307:static void usb_phy_generic_remove(struct platform_device *pdev)\ndrivers/usb/phy/phy-generic.c-308-{\ndrivers/usb/phy/phy-generic.c:309:\tstruct usb_phy_generic *nop = platform_get_drvdata(pdev);\ndrivers/usb/phy/phy-generic.c-310-\n--\ndrivers/usb/phy/phy-generic.c=322=MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids);\ndrivers/usb/phy/phy-generic.c-323-\ndrivers/usb/phy/phy-generic.c:324:static struct platform_driver usb_phy_generic_driver = {\ndrivers/usb/phy/phy-generic.c:325:\t.probe\t\t= usb_phy_generic_probe,\ndrivers/usb/phy/phy-generic.c:326:\t.remove\t\t= usb_phy_generic_remove,\ndrivers/usb/phy/phy-generic.c-327-\t.driver\t\t= {\ndrivers/usb/phy/phy-generic.c:328:\t\t.name\t= \"usb_phy_generic\",\ndrivers/usb/phy/phy-generic.c-329-\t\t.of_match_table = nop_xceiv_dt_ids,\n--\ndrivers/usb/phy/phy-generic.c-332-\ndrivers/usb/phy/phy-generic.c:333:static int __init usb_phy_generic_init(void)\ndrivers/usb/phy/phy-generic.c-334-{\ndrivers/usb/phy/phy-generic.c:335:\treturn platform_driver_register(\u0026usb_phy_generic_driver);\ndrivers/usb/phy/phy-generic.c-336-}\ndrivers/usb/phy/phy-generic.c:337:subsys_initcall(usb_phy_generic_init);\ndrivers/usb/phy/phy-generic.c-338-\ndrivers/usb/phy/phy-generic.c:339:static void __exit usb_phy_generic_exit(void)\ndrivers/usb/phy/phy-generic.c-340-{\ndrivers/usb/phy/phy-generic.c:341:\tplatform_driver_unregister(\u0026usb_phy_generic_driver);\ndrivers/usb/phy/phy-generic.c-342-}\ndrivers/usb/phy/phy-generic.c:343:module_exit(usb_phy_generic_exit);\ndrivers/usb/phy/phy-generic.c-344-\ndrivers/usb/phy/phy-generic.c:345:MODULE_ALIAS(\"platform:usb_phy_generic\");\ndrivers/usb/phy/phy-generic.c-346-MODULE_AUTHOR(\"Texas Instruments Inc\");\n--\ndrivers/usb/phy/phy-generic.h-4-\ndrivers/usb/phy/phy-generic.h:5:#include \u003clinux/usb/usb_phy_generic.h\u003e\ndrivers/usb/phy/phy-generic.h-6-#include \u003clinux/gpio/consumer.h\u003e\n--\ndrivers/usb/phy/phy-generic.h-8-\ndrivers/usb/phy/phy-generic.h:9:struct usb_phy_generic {\ndrivers/usb/phy/phy-generic.h-10-\tstruct usb_phy phy;\n--\ndrivers/usb/phy/phy-generic.h=23=void usb_gen_phy_shutdown(struct usb_phy *phy);\ndrivers/usb/phy/phy-generic.h-24-\ndrivers/usb/phy/phy-generic.h:25:int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop);\ndrivers/usb/phy/phy-generic.h-26-\n--\ndrivers/usb/phy/phy-keystone.c-11-#include \u003clinux/platform_device.h\u003e\ndrivers/usb/phy/phy-keystone.c:12:#include \u003clinux/usb/usb_phy_generic.h\u003e\ndrivers/usb/phy/phy-keystone.c-13-#include \u003clinux/io.h\u003e\n--\ndrivers/usb/phy/phy-keystone.c=28=struct keystone_usbphy {\ndrivers/usb/phy/phy-keystone.c:29:\tstruct usb_phy_generic\tusb_phy_gen;\ndrivers/usb/phy/phy-keystone.c-30-\tvoid __iomem\t\t\t*phy_ctrl;\n"
} |
| 13/2 | 2026/09/08 11:34 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 23871 output: 40 thoughts: 90 Thoughts: Okay, let's break this down. **Investigating the `USB_PHY` Dependency and Charger State** Right, so `USB_PHY` is predictably going to be in any kernel build that includes USB PHY drivers. I'd expect it to be linked in when something like the generic, ChipIdea, or gadget PHY drivers are configured. That makes sense, a very common dependency in a lot of builds, pretty straightforward. Now, my real interest lies in how this affects the charger state notification, specifically how `usb_phy_notify_charger_work` gets invoked. Time to dig into the call chain. I'll need to find where `usb_phy_set_charger_state` is being called and then trace how that leads to the workqueue. Let's see, a quick `grep` for those terms, maybe also `chg_work` or `type_nb` just in case, should point me in the right direction. That should give me the relevant code paths pretty quickly. |
| 14/2 | 2026/09/08 11:34 | tool | grepper |
0mArgs:{
"Expression": "chg_work|usb_phy_set_charger_state|type_nb",
"PathPrefix": "drivers/"
}Results: {
"Output": "drivers/block/drbd/drbd_state.c-21-\ndrivers/block/drbd/drbd_state.c:22:struct after_state_chg_work {\ndrivers/block/drbd/drbd_state.c-23-\tstruct drbd_work w;\n--\ndrivers/block/drbd/drbd_state.c=1263=_drbd_set_state(struct drbd_device *device, union drbd_state ns,\n--\ndrivers/block/drbd/drbd_state.c-1270-\tenum sanitize_state_warnings ssw;\ndrivers/block/drbd/drbd_state.c:1271:\tstruct after_state_chg_work *ascw;\ndrivers/block/drbd/drbd_state.c-1272-\tstruct drbd_state_change *state_change;\n--\ndrivers/block/drbd/drbd_state.c=1489=static int w_after_state_ch(struct drbd_work *w, int unused)\ndrivers/block/drbd/drbd_state.c-1490-{\ndrivers/block/drbd/drbd_state.c:1491:\tstruct after_state_chg_work *ascw =\ndrivers/block/drbd/drbd_state.c:1492:\t\tcontainer_of(w, struct after_state_chg_work, w);\ndrivers/block/drbd/drbd_state.c-1493-\tstruct drbd_device *device = ascw-\u003edevice;\n--\ndrivers/block/drbd/drbd_state.c=1708=static void after_state_ch(struct drbd_device *device, union drbd_state os,\n--\ndrivers/block/drbd/drbd_state.c-2036-\ndrivers/block/drbd/drbd_state.c:2037:struct after_conn_state_chg_work {\ndrivers/block/drbd/drbd_state.c-2038-\tstruct drbd_work w;\n--\ndrivers/block/drbd/drbd_state.c=2047=static int w_after_conn_state_ch(struct drbd_work *w, int unused)\ndrivers/block/drbd/drbd_state.c-2048-{\ndrivers/block/drbd/drbd_state.c:2049:\tstruct after_conn_state_chg_work *acscw =\ndrivers/block/drbd/drbd_state.c:2050:\t\tcontainer_of(w, struct after_conn_state_chg_work, w);\ndrivers/block/drbd/drbd_state.c-2051-\tstruct drbd_connection *connection = acscw-\u003econnection;\n--\ndrivers/block/drbd/drbd_state.c=2293=_conn_request_state(struct drbd_connection *connection, union drbd_state mask, union drbd_state val,\n--\ndrivers/block/drbd/drbd_state.c-2296-\tenum drbd_state_rv rv = SS_SUCCESS;\ndrivers/block/drbd/drbd_state.c:2297:\tstruct after_conn_state_chg_work *acscw;\ndrivers/block/drbd/drbd_state.c-2298-\tenum drbd_conns oc = connection-\u003ecstate;\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c=178=struct rockchip_usb2phy_cfg {\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-200- * @mutex: for register updating in sm_work.\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c:201: * @chg_work: charge detect work.\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-202- * @otg_sm_work: OTG state machine work.\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c=209=struct rockchip_usb2phy_port {\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-219-\tstruct mutex\tmutex;\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c:220:\tstruct\t\tdelayed_work chg_work;\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-221-\tstruct\t\tdelayed_work otg_sm_work;\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c=650=static int rockchip_usb2phy_exit(struct phy *phy)\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-657-\t\tcancel_delayed_work_sync(\u0026rport-\u003eotg_sm_work);\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c:658:\t\tcancel_delayed_work_sync(\u0026rport-\u003echg_work);\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-659-\t} else if (rport-\u003eport_id == USB2PHY_PORT_HOST)\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c=673=static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-707-\t\t\tcase USB_CHG_STATE_UNDEFINED:\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c:708:\t\t\t\tschedule_delayed_work(\u0026rport-\u003echg_work, 0);\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-709-\t\t\t\treturn;\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c=826=static void rockchip_chg_detect_work(struct work_struct *work)\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-828-\tstruct rockchip_usb2phy_port *rport =\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c:829:\t\tcontainer_of(work, struct rockchip_usb2phy_port, chg_work.work);\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-830-\tstruct rockchip_usb2phy *rphy = dev_get_drvdata(rport-\u003ephy-\u003edev.parent);\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-916-\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c:917:\tschedule_delayed_work(\u0026rport-\u003echg_work, delay);\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-918-}\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c=1290=static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,\n--\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-1317-\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c:1318:\tINIT_DELAYED_WORK(\u0026rport-\u003echg_work, rockchip_chg_detect_work);\ndrivers/phy/rockchip/phy-rockchip-inno-usb2.c-1319-\tINIT_DELAYED_WORK(\u0026rport-\u003eotg_sm_work, rockchip_usb2phy_otg_sm_work);\n--\ndrivers/power/supply/pf1550-charger.c=180=static void pf1550_chg_bat_work(struct work_struct *work)\n--\ndrivers/power/supply/pf1550-charger.c-216-\ndrivers/power/supply/pf1550-charger.c:217:static void pf1550_chg_chg_work(struct work_struct *work)\ndrivers/power/supply/pf1550-charger.c-218-{\n--\ndrivers/power/supply/pf1550-charger.c=549=static int pf1550_charger_probe(struct platform_device *pdev)\n--\ndrivers/power/supply/pf1550-charger.c-575-\tret = devm_delayed_work_autocancel(chg-\u003edev, \u0026chg-\u003echg_sense_work,\ndrivers/power/supply/pf1550-charger.c:576:\t\t\t\t\t pf1550_chg_chg_work);\ndrivers/power/supply/pf1550-charger.c-577-\tif (ret)\n--\ndrivers/usb/chipidea/ci_hdrc_imx.c=313=static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)\n--\ndrivers/usb/chipidea/ci_hdrc_imx.c-342-\t\tif (ci-\u003eusb_phy)\ndrivers/usb/chipidea/ci_hdrc_imx.c:343:\t\t\tschedule_work(\u0026ci-\u003eusb_phy-\u003echg_work);\ndrivers/usb/chipidea/ci_hdrc_imx.c-344-\t\tbreak;\n--\ndrivers/usb/chipidea/udc.c=1897=static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)\n--\ndrivers/usb/chipidea/udc.c-1907-\tif (ci-\u003eusb_phy)\ndrivers/usb/chipidea/udc.c:1908:\t\tusb_phy_set_charger_state(ci-\u003eusb_phy, is_active ?\ndrivers/usb/chipidea/udc.c-1909-\t\t\tUSB_CHARGER_PRESENT : USB_CHARGER_ABSENT);\n--\ndrivers/usb/phy/phy.c=77=static void usb_phy_set_default_current(struct usb_phy *usb_phy)\n--\ndrivers/usb/phy/phy.c-101- * If we get the charger type from -\u003echarger_detect() instead of extcon\ndrivers/usb/phy/phy.c:102: * subsystem, the usb phy driver should issue usb_phy_set_charger_state()\ndrivers/usb/phy/phy.c-103- * to set charger state when the charger state has been changed.\n--\ndrivers/usb/phy/phy.c=105=static void usb_phy_notify_charger_work(struct work_struct *work)\ndrivers/usb/phy/phy.c-106-{\ndrivers/usb/phy/phy.c:107:\tstruct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work);\ndrivers/usb/phy/phy.c-108-\tchar uchger_state[50] = { 0 };\n--\ndrivers/usb/phy/phy.c=139=static void __usb_phy_get_charger_type(struct usb_phy *usb_phy)\n--\ndrivers/usb/phy/phy.c-157-\ndrivers/usb/phy/phy.c:158:\tschedule_work(\u0026usb_phy-\u003echg_work);\ndrivers/usb/phy/phy.c-159-}\n--\ndrivers/usb/phy/phy.c=170=static int usb_phy_get_charger_type(struct notifier_block *nb,\n--\ndrivers/usb/phy/phy.c-172-{\ndrivers/usb/phy/phy.c:173:\tstruct usb_phy *usb_phy = container_of(nb, struct usb_phy, type_nb);\ndrivers/usb/phy/phy.c-174-\n--\ndrivers/usb/phy/phy.c=193=void usb_phy_set_charger_current(struct usb_phy *usb_phy, unsigned int mA)\n--\ndrivers/usb/phy/phy.c-227-\ndrivers/usb/phy/phy.c:228:\tschedule_work(\u0026usb_phy-\u003echg_work);\ndrivers/usb/phy/phy.c-229-}\n--\ndrivers/usb/phy/phy.c=268=EXPORT_SYMBOL_GPL(usb_phy_get_charger_current);\n--\ndrivers/usb/phy/phy.c-270-/**\ndrivers/usb/phy/phy.c:271: * usb_phy_set_charger_state - set the USB charger state\ndrivers/usb/phy/phy.c-272- * @usb_phy: the USB phy to be used\n--\ndrivers/usb/phy/phy.c-278- */\ndrivers/usb/phy/phy.c:279:void usb_phy_set_charger_state(struct usb_phy *usb_phy,\ndrivers/usb/phy/phy.c-280-\t\t\t enum usb_charger_state state)\n--\ndrivers/usb/phy/phy.c-290-\ndrivers/usb/phy/phy.c:291:\tschedule_work(\u0026usb_phy-\u003echg_work);\ndrivers/usb/phy/phy.c-292-}\ndrivers/usb/phy/phy.c:293:EXPORT_SYMBOL_GPL(usb_phy_set_charger_state);\ndrivers/usb/phy/phy.c-294-\n--\ndrivers/usb/phy/phy.c=311=static void usb_charger_init(struct usb_phy *usb_phy)\n--\ndrivers/usb/phy/phy.c-315-\tusb_phy_set_default_current(usb_phy);\ndrivers/usb/phy/phy.c:316:\tINIT_WORK(\u0026usb_phy-\u003echg_work, usb_phy_notify_charger_work);\ndrivers/usb/phy/phy.c-317-}\n--\ndrivers/usb/phy/phy.c=319=static int usb_add_extcon(struct usb_phy *x)\n--\ndrivers/usb/phy/phy.c-343-\t\t} else {\ndrivers/usb/phy/phy.c:344:\t\t\tx-\u003etype_nb.notifier_call = usb_phy_get_charger_type;\ndrivers/usb/phy/phy.c-345-\n--\ndrivers/usb/phy/phy.c-347-\t\t\t\t\t\t\t EXTCON_CHG_USB_SDP,\ndrivers/usb/phy/phy.c:348:\t\t\t\t\t\t\t \u0026x-\u003etype_nb);\ndrivers/usb/phy/phy.c-349-\t\t\tif (ret) {\n--\ndrivers/usb/phy/phy.c-356-\t\t\t\t\t\t\t EXTCON_CHG_USB_CDP,\ndrivers/usb/phy/phy.c:357:\t\t\t\t\t\t\t \u0026x-\u003etype_nb);\ndrivers/usb/phy/phy.c-358-\t\t\tif (ret) {\n--\ndrivers/usb/phy/phy.c-365-\t\t\t\t\t\t\t EXTCON_CHG_USB_DCP,\ndrivers/usb/phy/phy.c:366:\t\t\t\t\t\t\t \u0026x-\u003etype_nb);\ndrivers/usb/phy/phy.c-367-\t\t\tif (ret) {\n--\ndrivers/usb/phy/phy.c-374-\t\t\t\t\t\t\t EXTCON_CHG_USB_ACA,\ndrivers/usb/phy/phy.c:375:\t\t\t\t\t\t\t \u0026x-\u003etype_nb);\ndrivers/usb/phy/phy.c-376-\t\t\tif (ret) {\n--\ndrivers/usb/phy/phy.c-401-\ndrivers/usb/phy/phy.c:402:\tif (x-\u003etype_nb.notifier_call)\ndrivers/usb/phy/phy.c-403-\t\t__usb_phy_get_charger_type(x);\n"
} |
| 15/2 | 2026/09/08 11:34 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 28227 output: 33 thoughts: 255 Thoughts: **My Analysis of USB PHY Configuration** Okay, let's break this down. First, I see that we're dealing with the `USB_PHY`, and I need to figure out how it can be built, especially if it's feasible on x86/amd64 architectures. The code suggests I need to investigate the Kconfig options, specifically `NOP_USB_XCEIV` and `USB_PHY` themselves. Looking at `drivers/usb/phy/Kconfig`, I can see a dependency: `USB_PHY` defaults to `y` (yes) if `EXTCON` is enabled, and importantly, selects `EXTCON`. `NOP_USB_XCEIV` is a tristate option and depends on either `USB_GADGET` or the negation of `USB_GADGET`, so if the latter is modular, `NOP_USB_XCEIV` can't be built-in. It also *selects* `USB_PHY`. This indicates a potential hierarchy or relationship where `NOP_USB_XCEIV` can use the underlying `USB_PHY`. Then, the `Makefile` in the same directory reinforces the build logic: `obj-$(CONFIG_USB_PHY) += phy.o` means if `USB_PHY` is enabled, `phy.o` is built. Similarly, `obj-$(CONFIG_NOP_USB_XCEIV) += phy-generic.o` builds `phy-generic.o` when `NOP_USB_XCEIV` is selected. So, the key configuration flags I need to consider are `USB_PHY` and `NOP_USB_XCEIV`. I should now explore dependencies like `USB_SUPPORT` and `USB_PHY` in the Kconfig files to determine the bigger picture of what needs to be enabled for this PHY to be built. |
| 16/2 | 2026/09/08 11:35 | tool | grepper |
0mArgs:{
"Expression": "menuconfig USB_SUPPORT|config USB_PHY",
"PathPrefix": "drivers/usb"
}Results: {
"Output": "drivers/usb/Kconfig=26=config USB_UHCI_BIG_ENDIAN_DESC\n--\ndrivers/usb/Kconfig-28-\ndrivers/usb/Kconfig:29:menuconfig USB_SUPPORT\ndrivers/usb/Kconfig-30-\tbool \"USB support\"\n--\ndrivers/usb/phy/Kconfig=5=menu \"USB Physical Layer drivers\"\ndrivers/usb/phy/Kconfig-6-\ndrivers/usb/phy/Kconfig:7:config USB_PHY\ndrivers/usb/phy/Kconfig-8-\tselect EXTCON\n"
} |
| 17/2 | 2026/09/08 11:35 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 29057 output: 34 thoughts: 22 Thoughts: Here's my summary, as if I were thinking these thoughts: **Examining USB PHY Configuration Options** Okay, time to dive into the `drivers/usb/phy/Kconfig` file. I need to get a handle on the USB PHY configuration options, specifically the first 50 lines. I anticipate this will cover the core options, perhaps including those related to the architecture and vendor-specific PHY support. I'm expecting to see things like the selection of different PHY types (OTG, host, device), power management options, and possibly some basic device-tree related configurations if they are defined that early in the file. I also suspect there will be checks for any dependencies on other configurations within the kernel. Let's see what's what. This should quickly give me a good baseline for understanding the available USB PHY features within the build system. |
| 18/2 | 2026/09/08 11:35 | tool | read-file |
0mArgs:{
"File": "drivers/usb/phy/Kconfig",
"FirstLine": 1,
"LineCount": 50
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0\n 2:\t#\n 3:\t# Physical Layer USB driver configuration\n 4:\t#\n 5:\tmenu \"USB Physical Layer drivers\"\n 6:\t\n 7:\tconfig USB_PHY\n 8:\t\tselect EXTCON\n 9:\t\tdef_bool n\n 10:\t\n 11:\t#\n 12:\t# USB Transceiver Drivers\n 13:\t#\n 14:\tconfig AB8500_USB\n 15:\t\ttristate \"AB8500 USB Transceiver Driver\"\n 16:\t\tdepends on AB8500_CORE\n 17:\t\tselect USB_PHY\n 18:\t\thelp\n 19:\t\t Enable this to support the USB OTG transceiver in AB8500 chip.\n 20:\t\t This transceiver supports high and full speed devices plus,\n 21:\t\t in host mode, low speed.\n 22:\t\n 23:\tconfig FSL_USB2_OTG\n 24:\t\ttristate \"Freescale USB OTG Transceiver Driver\"\n 25:\t\tdepends on USB_EHCI_FSL \u0026\u0026 USB_FSL_USB2 \u0026\u0026 USB_OTG_FSM=y \u0026\u0026 PM\n 26:\t\tdepends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'\n 27:\t\tselect USB_PHY\n 28:\t\thelp\n 29:\t\t Enable this to support Freescale USB OTG transceiver.\n 30:\t\n 31:\tconfig KEYSTONE_USB_PHY\n 32:\t\ttristate \"Keystone USB PHY Driver\"\n 33:\t\tdepends on ARCH_KEYSTONE || COMPILE_TEST\n 34:\t\tdepends on NOP_USB_XCEIV\n 35:\t\thelp\n 36:\t\t Enable this to support Keystone USB phy. This driver provides\n 37:\t\t interface to interact with USB 2.0 and USB 3.0 PHY that is part\n 38:\t\t of the Keystone SOC.\n 39:\t\n 40:\tconfig NOP_USB_XCEIV\n 41:\t\ttristate \"NOP USB Transceiver Driver\"\n 42:\t\tdepends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, NOP can't be built-in\n 43:\t\tselect USB_PHY\n 44:\t\thelp\n 45:\t\t This driver is to be used by all the usb transceiver which are either\n 46:\t\t built-in with usb ip or which are autonomous and doesn't require any\n 47:\t\t phy programming such as ISP1x04 etc.\n 48:\t\n 49:\tconfig AM335X_CONTROL_USB\n 50:\t\ttristate\n"
} |
| 19/2 | 2026/09/08 11:35 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 30000 output: 182 thoughts: 653 Thoughts: **My Analysis of the USB PHY Refactoring** Okay, let's break this down. It looks like we're dealing with a refactoring of the USB PHY code, specifically within `drivers/usb/phy/phy.c`. My initial thought is to trace the connections: `USB_PHY` is triggered by a whole slew of configurations like `NOP_USB_XCEIV`, `USB_GPIO_VBUS`, `USB_ISP1301`, and so on, all nested under the umbrella of `USB_SUPPORT`. That's the baseline. Now, the changes are centered around how charger notifications and device type information are handled. Specifically: * `usb_phy_notify_charger_work`: This is where the uevent generation is now handled using `kobject_uevent_env()` instead of the old `kobject_uevent()` method. * `usb_add_phy_dev`: The setting of `x->dev->type` to `&usb_phy_dev_type` has been removed. * `usb_phy_uevent` and `__device_to_usb_phy` are deleted. Before I go any further, I am following my core triage philosophy. The reachability analysis is key, and it appears the changes are *executable kernel code* reachable through various means. Specifically, `NOP_USB_XCEIV` and the USB PHY framework are loadable/compilable into the kernel, with USB gadget, chipidea, or extcon potentially triggering charger work or adding the PHY. So, standard virtualized environments like QEMU or GCE are relevant. So, this is a code refactoring that impacts how charger events and device data are exposed. We have key functions - `usb_phy_notify_charger_work`, `usb_add_phy_dev`, `usb_phy_set_charger_state`, `usb_phy_set_charger_current`. The relevant configs are: `USB_SUPPORT`, `USB_PHY`, and `NOP_USB_XCEIV`. In essence, the patch is modernizing the uevent system within the USB PHY, switching from assigning the `dev->type` and a custom uevent function to a more direct `kobject_uevent_env()` call. This streamlines the event handling for charger notifications and device initialization. This is a refactoring of executable code, which impacts how events are generated by the kernel. Because this is refactoring and touch uevents, fuzzing to check for regressions is an absolute must! Let's log the findings using `set-results`. |
| 20/2 | 2026/09/08 11:35 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"USB_SUPPORT",
"USB_PHY",
"NOP_USB_XCEIV"
],
"FocusSymbols": [
"usb_phy_notify_charger_work",
"usb_add_phy_dev",
"usb_phy_set_charger_state",
"usb_phy_set_charger_current"
],
"Reasoning": "The patch refactors the uevent reporting mechanism for USB PHY charger events in drivers/usb/phy/phy.c. Instead of modifying the device type and implementing a custom uevent callback, environment variables for charger state and type are now constructed and passed directly via kobject_uevent_env() within usb_phy_notify_charger_work(). This touches reachable USB PHY core logic and is worth fuzzing.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"USB_SUPPORT",
"USB_PHY",
"NOP_USB_XCEIV"
],
"FocusSymbols": [
"usb_phy_notify_charger_work",
"usb_add_phy_dev",
"usb_phy_set_charger_state",
"usb_phy_set_charger_current"
],
"Reasoning": "The patch refactors the uevent reporting mechanism for USB PHY charger events in drivers/usb/phy/phy.c. Instead of modifying the device type and implementing a custom uevent callback, environment variables for charger state and type are now constructed and passed directly via kobject_uevent_env() within usb_phy_notify_charger_work(). This touches reachable USB PHY core logic and is worth fuzzing.",
"WorthFuzzing": true
} |
| 21/1 | 2026/09/08 11:35 | action | If |
0mArgs:{
"WorthFuzzing": true
}Results: null |
| 22/2 | 2026/09/08 11:35 | agent | kmsan-evaluator |
0mModel:core Args: null Results: {
"KMSANReasoning": "The patch refactors the USB PHY uevent notification by sending the environment variables directly from `usb_phy_notify_charger_work()` using `kobject_uevent_env()` rather than via a `device_type.uevent` callback. \n\nAll stack buffers introduced in this patch (`uchger_state`, `uchger_type`, and `envp`) are explicitly zero-initialized (`= { 0 }` / explicit initialization with NULL terminator) before string formatting via `snprintf()` and being passed to `kobject_uevent_env()`. There are no uninitialized variables, struct padding leaks, or uninitialized memory read risks. Any potential issues with array indexing (e.g. `usb_chger_type`) are bounds check / out-of-bounds read concerns detectable by KASAN, not uninitialized memory issues. Thus, a dedicated KMSAN session is not required.",
"NeedsKMSAN": false
}Instruction: You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.
CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
a comprehensive suite of debugging tools and sanitizers, including KASAN
(out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
(locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
or page allocations) and kernel-to-user memory info-leaks.
Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.
Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.
Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
attributes, ioctl output arguments, socket options, or BPF buffers) where fields
or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
uninitialized bytes of existing buffers.
Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
dereferences, locking deadlocks, or use-after-free bugs (these are already caught
by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.
Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 86efd571c3d2117a886dd7d1d448a5bc06aaff2f
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Sep 8 11:34:29 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 5a9b9353f343d..7c85c7ca1d309 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -42,12 +42,6 @@ static const char *const usb_chger_type[] = {
[ACA_TYPE] = "USB_CHARGER_ACA_TYPE",
};
-static const char *const usb_chger_state[] = {
- [USB_CHARGER_DEFAULT] = "USB_CHARGER_DEFAULT",
- [USB_CHARGER_PRESENT] = "USB_CHARGER_PRESENT",
- [USB_CHARGER_ABSENT] = "USB_CHARGER_ABSENT",
-};
-
static struct usb_phy *__usb_find_phy(struct list_head *list,
enum usb_phy_type type)
{
@@ -80,18 +74,6 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)
return ERR_PTR(-EPROBE_DEFER);
}
-static struct usb_phy *__device_to_usb_phy(const struct device *dev)
-{
- struct usb_phy *usb_phy;
-
- list_for_each_entry(usb_phy, &phy_list, head) {
- if (usb_phy->dev == dev)
- return usb_phy;
- }
-
- return NULL;
-}
-
static void usb_phy_set_default_current(struct usb_phy *usb_phy)
{
usb_phy->chg_cur.sdp_min = DEFAULT_SDP_CUR_MIN;
@@ -123,6 +105,9 @@ static void usb_phy_set_default_current(struct usb_phy *usb_phy)
static void usb_phy_notify_charger_work(struct work_struct *work)
{
struct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work);
+ char uchger_state[50] = { 0 };
+ char uchger_type[50] = { 0 };
+ char *envp[] = { uchger_state, uchger_type, NULL };
unsigned int min, max;
switch (usb_phy->chg_state) {
@@ -130,11 +115,15 @@ static void usb_phy_notify_charger_work(struct work_struct *work)
usb_phy_get_charger_current(usb_phy, &min, &max);
atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy);
+ snprintf(uchger_state, ARRAY_SIZE(uchger_state),
+ "USB_CHARGER_STATE=%s", "USB_CHARGER_PRESENT");
break;
case USB_CHARGER_ABSENT:
usb_phy_set_default_current(usb_phy);
atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy);
+ snprintf(uchger_state, ARRAY_SIZE(uchger_state),
+ "USB_CHARGER_STATE=%s", "USB_CHARGER_ABSENT");
break;
default:
dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n",
@@ -142,36 +131,9 @@ static void usb_phy_notify_charger_work(struct work_struct *work)
return;
}
- kobject_uevent(&usb_phy->dev->kobj, KOBJ_CHANGE);
-}
-
-static int usb_phy_uevent(const struct device *dev, struct kobj_uevent_env *env)
-{
- const struct usb_phy *usb_phy;
- char uchger_state[50] = { 0 };
- char uchger_type[50] = { 0 };
- unsigned long flags;
-
- spin_lock_irqsave(&phy_lock, flags);
- usb_phy = __device_to_usb_phy(dev);
- spin_unlock_irqrestore(&phy_lock, flags);
-
- if (!usb_phy)
- return -ENODEV;
-
- snprintf(uchger_state, ARRAY_SIZE(uchger_state),
- "USB_CHARGER_STATE=%s", usb_chger_state[usb_phy->chg_state]);
-
snprintf(uchger_type, ARRAY_SIZE(uchger_type),
"USB_CHARGER_TYPE=%s", usb_chger_type[usb_phy->chg_type]);
-
- if (add_uevent_var(env, uchger_state))
- return -ENOMEM;
-
- if (add_uevent_var(env, uchger_type))
- return -ENOMEM;
-
- return 0;
+ kobject_uevent_env(&usb_phy->dev->kobj, KOBJ_CHANGE, envp);
}
static void __usb_phy_get_charger_type(struct usb_phy *usb_phy)
@@ -675,11 +637,6 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
}
EXPORT_SYMBOL_GPL(usb_add_phy);
-static const struct device_type usb_phy_dev_type = {
- .name = "usb_phy",
- .uevent = usb_phy_uevent,
-};
-
/**
* usb_add_phy_dev - declare the USB PHY
* @x: the USB phy to be used; or NULL
@@ -705,8 +662,6 @@ int usb_add_phy_dev(struct usb_phy *x)
if (ret)
return ret;
- x->dev->type = &usb_phy_dev_type;
-
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
spin_lock_irqsave(&phy_lock, flags);
|
| 23/3 | 2026/09/08 11:35 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 3460 output: 36 thoughts: 467 Thoughts: **KMSAN Fuzzing Evaluation - USB PHY Patch** Okay, let's break this down. My goal is to determine if this kernel patch necessitates a KMSAN fuzzing session. I'm going to carefully analyze the changes and the surrounding context to see if there are any potential memory safety vulnerabilities that KMSAN could expose. First, I see that the patch touches `drivers/usb/phy/phy.c`. It looks like it's removing some old uevent-related code, specifically `usb_phy_uevent` and `usb_phy_dev_type`, which was setting the `dev->type`. That's not inherently worrisome, but the replacement is where my attention needs to go. Now, instead of the old method, the patch introduces a new function called `usb_phy_notify_charger_work`. Inside this function, it allocates some stack arrays: `uchger_state` and `uchger_type`, both 50 bytes. Then, it creates an `envp` array pointing to these character arrays, which is then passed to `kobject_uevent_env`. The core logic involves a switch statement based on `usb_phy->chg_state`. Based on the state, it populates `uchger_state` with strings indicating charger presence or absence using `snprintf`. After the switch, it populates `uchger_type` similarly, based on `usb_chger_type` and `usb_phy->chg_type`. Finally, it calls `kobject_uevent_env`. My immediate concern is around potential uninitialized memory reads, out-of-bounds writes, or other memory safety issues. I need to make sure everything is properly initialized and that there's no risk of reading uninitialized stack data. I also need to ensure that the `snprintf` calls are safe. So, I need to check the definition and usage of `usb_chger_type` and the implications of `usb_phy->chg_type`, to make sure these values are bounded and well controlled. I'm going to dig deeper into the code around lines 30-150 in `drivers/usb/phy/phy.c` to understand the context and how these variables are set and used, especially considering the array indexing. Based on this deeper dive, I can determine if this warrants KMSAN fuzzing. |
| 24/3 | 2026/09/08 11:35 | tool | read-file |
0mArgs:{
"File": "drivers/usb/phy/phy.c",
"FirstLine": 25,
"LineCount": 80
}Results: {
"Contents": " 25:\t#define DEFAULT_CDP_CUR_MAX\t5000\n 26:\t#define DEFAULT_ACA_CUR_MIN\t1500\n 27:\t#define DEFAULT_ACA_CUR_MAX\t5000\n 28:\t\n 29:\tstatic LIST_HEAD(phy_list);\n 30:\tstatic DEFINE_SPINLOCK(phy_lock);\n 31:\t\n 32:\tstruct phy_devm {\n 33:\t\tstruct usb_phy *phy;\n 34:\t\tstruct notifier_block *nb;\n 35:\t};\n 36:\t\n 37:\tstatic const char *const usb_chger_type[] = {\n 38:\t\t[UNKNOWN_TYPE]\t\t\t= \"USB_CHARGER_UNKNOWN_TYPE\",\n 39:\t\t[SDP_TYPE]\t\t\t= \"USB_CHARGER_SDP_TYPE\",\n 40:\t\t[CDP_TYPE]\t\t\t= \"USB_CHARGER_CDP_TYPE\",\n 41:\t\t[DCP_TYPE]\t\t\t= \"USB_CHARGER_DCP_TYPE\",\n 42:\t\t[ACA_TYPE]\t\t\t= \"USB_CHARGER_ACA_TYPE\",\n 43:\t};\n 44:\t\n 45:\tstatic struct usb_phy *__usb_find_phy(struct list_head *list,\n 46:\t\tenum usb_phy_type type)\n 47:\t{\n 48:\t\tstruct usb_phy *phy = NULL;\n 49:\t\n 50:\t\tlist_for_each_entry(phy, list, head) {\n 51:\t\t\tif (phy-\u003etype != type)\n 52:\t\t\t\tcontinue;\n 53:\t\n 54:\t\t\treturn phy;\n 55:\t\t}\n 56:\t\n 57:\t\treturn ERR_PTR(-ENODEV);\n 58:\t}\n 59:\t\n 60:\tstatic struct usb_phy *__of_usb_find_phy(struct device_node *node)\n 61:\t{\n 62:\t\tstruct usb_phy *phy;\n 63:\t\n 64:\t\tif (!of_device_is_available(node))\n 65:\t\t\treturn ERR_PTR(-ENODEV);\n 66:\t\n 67:\t\tlist_for_each_entry(phy, \u0026phy_list, head) {\n 68:\t\t\tif (node != phy-\u003edev-\u003eof_node)\n 69:\t\t\t\tcontinue;\n 70:\t\n 71:\t\t\treturn phy;\n 72:\t\t}\n 73:\t\n 74:\t\treturn ERR_PTR(-EPROBE_DEFER);\n 75:\t}\n 76:\t\n 77:\tstatic void usb_phy_set_default_current(struct usb_phy *usb_phy)\n 78:\t{\n 79:\t\tusb_phy-\u003echg_cur.sdp_min = DEFAULT_SDP_CUR_MIN;\n 80:\t\tusb_phy-\u003echg_cur.sdp_max = DEFAULT_SDP_CUR_MAX;\n 81:\t\tusb_phy-\u003echg_cur.dcp_min = DEFAULT_DCP_CUR_MIN;\n 82:\t\tusb_phy-\u003echg_cur.dcp_max = DEFAULT_DCP_CUR_MAX;\n 83:\t\tusb_phy-\u003echg_cur.cdp_min = DEFAULT_CDP_CUR_MIN;\n 84:\t\tusb_phy-\u003echg_cur.cdp_max = DEFAULT_CDP_CUR_MAX;\n 85:\t\tusb_phy-\u003echg_cur.aca_min = DEFAULT_ACA_CUR_MIN;\n 86:\t\tusb_phy-\u003echg_cur.aca_max = DEFAULT_ACA_CUR_MAX;\n 87:\t}\n 88:\t\n 89:\t/**\n 90:\t * usb_phy_notify_charger_work - notify the USB charger state\n 91:\t * @work: the charger work to notify the USB charger state\n 92:\t *\n 93:\t * This work can be issued when USB charger state has been changed or\n 94:\t * USB charger current has been changed, then we can notify the current\n 95:\t * what can be drawn to power user and the charger state to userspace.\n 96:\t *\n 97:\t * If we get the charger type from extcon subsystem, we can notify the\n 98:\t * charger state to power user automatically by usb_phy_get_charger_type()\n 99:\t * issuing from extcon subsystem.\n 100:\t *\n 101:\t * If we get the charger type from -\u003echarger_detect() instead of extcon\n 102:\t * subsystem, the usb phy driver should issue usb_phy_set_charger_state()\n 103:\t * to set charger state when the charger state has been changed.\n 104:\t */\n"
} |
| 25/3 | 2026/09/08 11:35 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 5708 output: 216 thoughts: 695 Thoughts: **KMSAN Risk Assessment for USB Charger Uevent Refactor**
Okay, let's break this down. I'm looking at a patch that's refactoring the uevent generation for the USB charger state. Specifically, it's moving from the `device_type.uevent` callback to directly calling `kobject_uevent_env` within the `usb_phy_notify_charger_work` workqueue function. My primary concern, as always, is whether this introduces any risks related to uninitialized memory, which KMSAN would flag.
First, I see the code defines two character arrays, `uchger_state` and `uchger_type`, both stack-allocated with a size of 50 and initialized to zero (`= { 0 }`). It also initializes an environment pointer array `envp` containing pointers to these strings and a NULL terminator. Then, the code populates `uchger_state` and `uchger_type` using `snprintf`. The critical point here is that `kobject_uevent_env` is called with these formatted strings.
I need to confirm there's no way uninitialized memory is being read. Let's make sure.
* `uchger_state` and `uchger_type` are explicitly zero-initialized.
* `envp` is fully initialized, and NULL-terminated, which is essential to prevent read-outs.
* I considered an out-of-bounds access on `usb_phy->chg_type`, but that's a static const array, so KASAN would catch it.
* This is the same methodology as the old version, which used `uchger_state` and `uchger_type` initialized to `{ 0 }` to add to `env`
So, is there an uninitialized memory risk? Let me reiterate and be crystal clear. I see no issues.
1. There's no reading of uninitialized stack or heap memory.
2. The buffers exposed to userspace (via the uevent) are zero-initialized arrays, filled with `snprintf`, guaranteeing null-terminated strings.
3. No struct padding or uninitialized fields are leaked.
4. No branching decisions depend on uninitialized variables.
Now, let's cross-reference this against the KMSAN guidelines. We need to set `NeedsKMSAN=false` if all stack/heap structures introduced by the patch are fully initialized before being read or copied, and if the patch doesn't introduce any uninitialized memory risks or info leaks. Based on my analysis, this is clearly the case here. The patch initializes the buffers before writing data in them.
Therefore, after this review, it's my determination that this patch is safe and doesn't introduce any uninitialized memory risks. Let's call `set-results`.
|
| 26/3 | 2026/09/08 11:35 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch refactors the USB PHY uevent notification by sending the environment variables directly from `usb_phy_notify_charger_work()` using `kobject_uevent_env()` rather than via a `device_type.uevent` callback. \n\nAll stack buffers introduced in this patch (`uchger_state`, `uchger_type`, and `envp`) are explicitly zero-initialized (`= { 0 }` / explicit initialization with NULL terminator) before string formatting via `snprintf()` and being passed to `kobject_uevent_env()`. There are no uninitialized variables, struct padding leaks, or uninitialized memory read risks. Any potential issues with array indexing (e.g. `usb_chger_type`) are bounds check / out-of-bounds read concerns detectable by KASAN, not uninitialized memory issues. Thus, a dedicated KMSAN session is not required.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch refactors the USB PHY uevent notification by sending the environment variables directly from `usb_phy_notify_charger_work()` using `kobject_uevent_env()` rather than via a `device_type.uevent` callback. \n\nAll stack buffers introduced in this patch (`uchger_state`, `uchger_type`, and `envp`) are explicitly zero-initialized (`= { 0 }` / explicit initialization with NULL terminator) before string formatting via `snprintf()` and being passed to `kobject_uevent_env()`. There are no uninitialized variables, struct padding leaks, or uninitialized memory read risks. Any potential issues with array indexing (e.g. `usb_chger_type`) are bounds check / out-of-bounds read concerns detectable by KASAN, not uninitialized memory issues. Thus, a dedicated KMSAN session is not required.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|