drivers/phy/allwinner/phy-sun4i-usb.c
Source file repositories/reference/linux-study-clean/drivers/phy/allwinner/phy-sun4i-usb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/phy/allwinner/phy-sun4i-usb.c- Extension
.c- Size
- 27893 bytes
- Lines
- 1051
- Domain
- Driver Families
- Bucket
- drivers/phy
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/clk.hlinux/delay.hlinux/err.hlinux/extcon-provider.hlinux/gpio/consumer.hlinux/io.hlinux/interrupt.hlinux/kernel.hlinux/module.hlinux/mutex.hlinux/of.hlinux/phy/phy.hlinux/phy/phy-sun4i-usb.hlinux/platform_device.hlinux/power_supply.hlinux/regulator/consumer.hlinux/reset.hlinux/spinlock.hlinux/usb/of.hlinux/workqueue.h
Detected Declarations
struct sun4i_usb_phy_cfgstruct sun4i_usb_phy_datastruct sun4i_usb_phyfunction sun4i_usb_phy0_update_iscrfunction sun4i_usb_phy0_set_id_detectfunction sun4i_usb_phy0_set_vbus_detectfunction sun4i_usb_phy_writefunction sun4i_usb_phy_passbyfunction sun4i_usb_phy_initfunction sun4i_usb_phy_exitfunction sun4i_usb_phy0_get_id_detfunction sun4i_usb_phy0_get_vbus_detfunction sun4i_usb_phy0_have_vbus_detfunction sun4i_usb_phy0_pollfunction sun4i_usb_phy_power_onfunction sun4i_usb_phy_power_offfunction sun4i_usb_phy_set_modefunction sun4i_usb_phy_set_squelch_detectfunction sun4i_usb_phy0_reroutefunction sun4i_usb_phy0_id_vbus_det_scanfunction sun4i_usb_phy0_id_vbus_det_irqfunction sun4i_usb_phy0_vbus_notifyfunction sun4i_usb_phy_removefunction sun4i_usb_phy_probeexport sun4i_usb_phy_set_squelch_detect
Annotated Snippet
struct sun4i_usb_phy_cfg {
int hsic_index;
u32 disc_thresh;
u32 hci_phy_ctl_clear;
u8 phyctl_offset;
bool dedicated_clocks;
bool phy0_dual_route;
bool needs_phy2_siddq;
bool siddq_in_base;
bool poll_vbusen;
int missing_phys;
};
struct sun4i_usb_phy_data {
void __iomem *base;
const struct sun4i_usb_phy_cfg *cfg;
enum usb_dr_mode dr_mode;
spinlock_t reg_lock; /* guard access to phyctl reg */
int num_phys;
struct sun4i_usb_phy {
struct phy *phy;
void __iomem *pmu;
struct regulator *vbus;
struct reset_control *reset;
struct clk *clk;
struct clk *clk2;
bool regulator_on;
int index;
} phys[MAX_PHYS];
/* phy0 / otg related variables */
struct extcon_dev *extcon;
bool phy0_init;
struct gpio_desc *id_det_gpio;
struct gpio_desc *vbus_det_gpio;
struct power_supply *vbus_power_supply;
struct notifier_block vbus_power_nb;
bool vbus_power_nb_registered;
bool force_session_end;
int id_det_irq;
int vbus_det_irq;
int id_det;
int vbus_det;
struct delayed_work detect;
};
#define to_sun4i_usb_phy_data(phy) \
container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
static void sun4i_usb_phy0_update_iscr(struct phy *_phy, u32 clr, u32 set)
{
struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
u32 iscr;
iscr = readl(data->base + REG_ISCR);
iscr &= ~clr;
iscr |= set;
writel(iscr, data->base + REG_ISCR);
}
static void sun4i_usb_phy0_set_id_detect(struct phy *phy, u32 val)
{
if (val)
val = ISCR_FORCE_ID_HIGH;
else
val = ISCR_FORCE_ID_LOW;
sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_ID_MASK, val);
}
static void sun4i_usb_phy0_set_vbus_detect(struct phy *phy, u32 val)
{
if (val)
val = ISCR_FORCE_VBUS_HIGH;
else
val = ISCR_FORCE_VBUS_LOW;
sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_VBUS_MASK, val);
}
static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
int len)
{
struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
u32 temp, usbc_bit = BIT(phy->index * 2);
void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
unsigned long flags;
int i;
spin_lock_irqsave(&phy_data->reg_lock, flags);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/err.h`, `linux/extcon-provider.h`, `linux/gpio/consumer.h`, `linux/io.h`, `linux/interrupt.h`, `linux/kernel.h`.
- Detected declarations: `struct sun4i_usb_phy_cfg`, `struct sun4i_usb_phy_data`, `struct sun4i_usb_phy`, `function sun4i_usb_phy0_update_iscr`, `function sun4i_usb_phy0_set_id_detect`, `function sun4i_usb_phy0_set_vbus_detect`, `function sun4i_usb_phy_write`, `function sun4i_usb_phy_passby`, `function sun4i_usb_phy_init`, `function sun4i_usb_phy_exit`.
- Atlas domain: Driver Families / drivers/phy.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.