drivers/phy/tegra/xusb.c
Source file repositories/reference/linux-study-clean/drivers/phy/tegra/xusb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/phy/tegra/xusb.c- Extension
.c- Size
- 36243 bytes
- Lines
- 1552
- Domain
- Driver Families
- Bucket
- drivers/phy
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/io.hlinux/mailbox_client.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/phy/phy.hlinux/phy/tegra/xusb.hlinux/platform_device.hlinux/regulator/consumer.hlinux/reset.hlinux/slab.hlinux/workqueue.hsoc/tegra/fuse.hxusb.h
Detected Declarations
function Copyrightfunction tegra_xusb_find_pad_nodefunction tegra_xusb_pad_find_phy_nodefunction tegra_xusb_lane_parse_dtfunction tegra_xusb_lane_destroyfunction tegra_xusb_pad_releasefunction tegra_xusb_pad_initfunction tegra_xusb_pad_registerfunction tegra_xusb_pad_unregisterfunction tegra_xusb_pad_createfunction __tegra_xusb_remove_padsfunction list_for_each_entry_safe_reversefunction tegra_xusb_remove_padsfunction tegra_xusb_lane_programfunction tegra_xusb_pad_programfunction tegra_xusb_setup_padsfunction tegra_xusb_lane_checkfunction list_for_each_entryfunction tegra_xusb_port_find_lanefunction tegra_xusb_find_port_nodefunction tegra_xusb_find_portfunction list_for_each_entryfunction tegra_xusb_find_usb2_portfunction tegra_xusb_find_usb3_portfunction tegra_xusb_port_releasefunction tegra_xusb_port_initfunction tegra_xusb_port_unregisterfunction to_usb_phy_eventfunction tegra_xusb_usb_phy_workfunction tegra_xusb_role_sw_setfunction tegra_xusb_set_peripheralfunction tegra_xusb_set_hostfunction tegra_xusb_setup_usb_role_switchfunction tegra_xusb_parse_usb_role_default_modefunction tegra_xusb_usb2_port_parse_dtfunction tegra_xusb_add_usb2_portfunction tegra_xusb_usb2_port_releasefunction tegra_xusb_usb2_port_removefunction tegra_xusb_ulpi_port_parse_dtfunction tegra_xusb_add_ulpi_portfunction tegra_xusb_ulpi_port_releasefunction tegra_xusb_hsic_port_parse_dtfunction tegra_xusb_add_hsic_portfunction tegra_xusb_hsic_port_releasefunction tegra_xusb_usb3_port_parse_dtfunction tegra_xusb_add_usb3_portfunction tegra_xusb_usb3_port_releasefunction __tegra_xusb_remove_ports
Annotated Snippet
sizeof(struct device_driver),
GFP_KERNEL);
if (!port->dev.driver)
return -ENOMEM;
port->dev.driver->owner = THIS_MODULE;
port->usb_role_sw = usb_role_switch_register(&port->dev,
&role_sx_desc);
if (IS_ERR(port->usb_role_sw)) {
err = PTR_ERR(port->usb_role_sw);
dev_err(&port->dev, "failed to register USB role switch: %d",
err);
return err;
}
INIT_WORK(&port->usb_phy_work, tegra_xusb_usb_phy_work);
usb_role_switch_set_drvdata(port->usb_role_sw, port);
port->usb_phy.otg = devm_kzalloc(&port->dev, sizeof(struct usb_otg),
GFP_KERNEL);
if (!port->usb_phy.otg)
return -ENOMEM;
lane = tegra_xusb_find_lane(port->padctl, "usb2", port->index);
if (IS_ERR(lane))
return PTR_ERR(lane);
/*
* Assign phy dev to usb-phy dev. Host/device drivers can use phy
* reference to retrieve usb-phy details.
*/
port->usb_phy.dev = &lane->pad->lanes[port->index]->dev;
port->usb_phy.dev->driver = port->dev.driver;
port->usb_phy.otg->usb_phy = &port->usb_phy;
port->usb_phy.otg->set_peripheral = tegra_xusb_set_peripheral;
port->usb_phy.otg->set_host = tegra_xusb_set_host;
err = usb_add_phy_dev(&port->usb_phy);
if (err < 0) {
dev_err(&port->dev, "Failed to add USB PHY: %d\n", err);
return err;
}
/* populate connector entry */
of_platform_populate(port->dev.of_node, NULL, NULL, &port->dev);
return err;
}
static void tegra_xusb_parse_usb_role_default_mode(struct tegra_xusb_port *port)
{
enum usb_role role = USB_ROLE_NONE;
enum usb_dr_mode mode = usb_get_role_switch_default_mode(&port->dev);
if (mode == USB_DR_MODE_HOST)
role = USB_ROLE_HOST;
else if (mode == USB_DR_MODE_PERIPHERAL)
role = USB_ROLE_DEVICE;
if (role != USB_ROLE_NONE) {
usb_role_switch_set_role(port->usb_role_sw, role);
dev_dbg(&port->dev, "usb role default mode is %s", modes[mode]);
}
}
static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
{
struct tegra_xusb_port *port = &usb2->base;
struct device_node *np = port->dev.of_node;
const char *mode;
int err;
usb2->internal = of_property_read_bool(np, "nvidia,internal");
if (!of_property_read_string(np, "mode", &mode)) {
int err = match_string(modes, ARRAY_SIZE(modes), mode);
if (err < 0) {
dev_err(&port->dev, "invalid value %s for \"mode\"\n",
mode);
usb2->mode = USB_DR_MODE_UNKNOWN;
} else {
usb2->mode = err;
}
} else {
usb2->mode = USB_DR_MODE_HOST;
}
/* usb-role-switch property is mandatory for OTG/Peripheral modes */
if (usb2->mode == USB_DR_MODE_PERIPHERAL ||
Annotation
- Immediate include surface: `linux/delay.h`, `linux/io.h`, `linux/mailbox_client.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/phy/phy.h`, `linux/phy/tegra/xusb.h`.
- Detected declarations: `function Copyright`, `function tegra_xusb_find_pad_node`, `function tegra_xusb_pad_find_phy_node`, `function tegra_xusb_lane_parse_dt`, `function tegra_xusb_lane_destroy`, `function tegra_xusb_pad_release`, `function tegra_xusb_pad_init`, `function tegra_xusb_pad_register`, `function tegra_xusb_pad_unregister`, `function tegra_xusb_pad_create`.
- Atlas domain: Driver Families / drivers/phy.
- Implementation status: pattern 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.