drivers/usb/chipidea/otg.c
Source file repositories/reference/linux-study-clean/drivers/usb/chipidea/otg.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/chipidea/otg.c- Extension
.c- Size
- 6052 bytes
- Lines
- 276
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/usb/otg.hlinux/usb/gadget.hlinux/usb/chipidea.hci.hbits.hotg.hotg_fsm.h
Detected Declarations
function Copyrightfunction hw_write_otgscfunction ci_otg_rolefunction ci_handle_vbus_changefunction hw_wait_vbus_lower_bsvfunction ci_handle_id_switchfunction ci_otg_workfunction ci_hdrc_otg_initfunction ci_hdrc_otg_destroy
Annotated Snippet
if (data & mask & OTGSC_BSVIE) {
cable->enabled = true;
data &= ~OTGSC_BSVIE;
} else if (mask & OTGSC_BSVIE) {
cable->enabled = false;
}
}
cable = &ci->platdata->id_extcon;
if (!IS_ERR(cable->edev) || ci->role_switch) {
if (data & mask & OTGSC_IDIS)
cable->changed = false;
/* Don't enable id interrupt if using external notifier */
if (data & mask & OTGSC_IDIE) {
cable->enabled = true;
data &= ~OTGSC_IDIE;
} else if (mask & OTGSC_IDIE) {
cable->enabled = false;
}
}
hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
}
/**
* ci_otg_role - pick role based on ID pin state
* @ci: the controller
*/
enum ci_role ci_otg_role(struct ci_hdrc *ci)
{
enum ci_role role = hw_read_otgsc(ci, OTGSC_ID)
? CI_ROLE_GADGET
: CI_ROLE_HOST;
return role;
}
void ci_handle_vbus_change(struct ci_hdrc *ci)
{
if (ci->role != CI_ROLE_GADGET)
return;
if (!ci->is_otg) {
if (ci->platdata->flags & CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS)
usb_gadget_vbus_connect(&ci->gadget);
return;
}
if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active)
usb_gadget_vbus_connect(&ci->gadget);
else if (!hw_read_otgsc(ci, OTGSC_BSV) && ci->vbus_active)
usb_gadget_vbus_disconnect(&ci->gadget);
}
/**
* hw_wait_vbus_lower_bsv - When we switch to device mode, the vbus value
* should be lower than OTGSC_BSV before connecting
* to host.
*
* @ci: the controller
*
* This function returns an error code if timeout
*/
static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci)
{
unsigned long elapse = jiffies + msecs_to_jiffies(5000);
u32 mask = OTGSC_BSV;
while (hw_read_otgsc(ci, mask)) {
if (time_after(jiffies, elapse)) {
dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
mask);
return -ETIMEDOUT;
}
msleep(20);
}
return 0;
}
void ci_handle_id_switch(struct ci_hdrc *ci)
{
enum ci_role role;
mutex_lock(&ci->mutex);
role = ci_otg_role(ci);
if (role != ci->role) {
dev_dbg(ci->dev, "switching from %s to %s\n",
ci_role(ci)->name, ci->roles[role]->name);
Annotation
- Immediate include surface: `linux/usb/otg.h`, `linux/usb/gadget.h`, `linux/usb/chipidea.h`, `ci.h`, `bits.h`, `otg.h`, `otg_fsm.h`.
- Detected declarations: `function Copyright`, `function hw_write_otgsc`, `function ci_otg_role`, `function ci_handle_vbus_change`, `function hw_wait_vbus_lower_bsv`, `function ci_handle_id_switch`, `function ci_otg_work`, `function ci_hdrc_otg_init`, `function ci_hdrc_otg_destroy`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.