drivers/phy/samsung/phy-samsung-ufs.c
Source file repositories/reference/linux-study-clean/drivers/phy/samsung/phy-samsung-ufs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/phy/samsung/phy-samsung-ufs.c- Extension
.c- Size
- 9553 bytes
- Lines
- 389
- Domain
- Driver Families
- Bucket
- drivers/phy
- 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.
- 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/of.hlinux/io.hlinux/iopoll.hlinux/mfd/syscon.hlinux/module.hlinux/phy/phy.hlinux/platform_device.hlinux/regmap.hphy-samsung-ufs.h
Detected Declarations
function samsung_ufs_phy_configfunction samsung_ufs_phy_wait_for_lock_acqfunction samsung_ufs_phy_calibratefunction for_each_phy_cfgfunction for_each_phy_lanefunction samsung_ufs_phy_clks_initfunction samsung_ufs_phy_initfunction samsung_ufs_phy_power_onfunction samsung_ufs_phy_power_offfunction samsung_ufs_phy_set_modefunction samsung_ufs_phy_notify_statefunction for_each_phy_cfgfunction samsung_ufs_phy_exitfunction samsung_ufs_phy_probe
Annotated Snippet
for_each_phy_lane(ufs_phy, i) {
samsung_ufs_phy_config(ufs_phy, cfg, i);
}
}
for_each_phy_lane(ufs_phy, i) {
if (ufs_phy->ufs_phy_state == CFG_PRE_INIT &&
ufs_phy->drvdata->wait_for_cal) {
err = ufs_phy->drvdata->wait_for_cal(phy, i);
if (err)
goto out;
}
if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS &&
ufs_phy->drvdata->wait_for_cdr) {
err = ufs_phy->drvdata->wait_for_cdr(phy, i);
if (err)
goto out;
}
}
/**
* In Samsung ufshci, PHY need to be calibrated at different
* stages / state mainly before Linkstartup, after Linkstartup,
* before power mode change and after power mode change.
* Below state machine to make sure to calibrate PHY in each
* state. Here after configuring PHY in a given state, will
* change the state to next state so that next state phy
* calibration value can be programed
*/
out:
switch (ufs_phy->ufs_phy_state) {
case CFG_PRE_INIT:
ufs_phy->ufs_phy_state = CFG_POST_INIT;
break;
case CFG_POST_INIT:
ufs_phy->ufs_phy_state = CFG_PRE_PWR_HS;
break;
case CFG_PRE_PWR_HS:
ufs_phy->ufs_phy_state = CFG_POST_PWR_HS;
break;
case CFG_POST_PWR_HS:
/* Change back to INIT state */
ufs_phy->ufs_phy_state = CFG_PRE_INIT;
break;
default:
dev_err(ufs_phy->dev, "wrong state for phy calibration\n");
}
return err;
}
static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy)
{
int i;
const struct samsung_ufs_phy_drvdata *drvdata = phy->drvdata;
int num_clks = drvdata->num_clks;
phy->clks = devm_kcalloc(phy->dev, num_clks, sizeof(*phy->clks),
GFP_KERNEL);
if (!phy->clks)
return -ENOMEM;
for (i = 0; i < num_clks; i++)
phy->clks[i].id = drvdata->clk_list[i];
return devm_clk_bulk_get(phy->dev, num_clks, phy->clks);
}
static int samsung_ufs_phy_init(struct phy *phy)
{
struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
ss_phy->lane_cnt = phy->attrs.bus_width;
ss_phy->ufs_phy_state = CFG_PRE_INIT;
return 0;
}
static int samsung_ufs_phy_power_on(struct phy *phy)
{
struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
int ret;
samsung_ufs_phy_ctrl_isol(ss_phy, false);
ret = clk_bulk_prepare_enable(ss_phy->drvdata->num_clks, ss_phy->clks);
if (ret) {
dev_err(ss_phy->dev, "failed to enable ufs phy clocks\n");
return ret;
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/err.h`, `linux/of.h`, `linux/io.h`, `linux/iopoll.h`, `linux/mfd/syscon.h`, `linux/module.h`.
- Detected declarations: `function samsung_ufs_phy_config`, `function samsung_ufs_phy_wait_for_lock_acq`, `function samsung_ufs_phy_calibrate`, `function for_each_phy_cfg`, `function for_each_phy_lane`, `function samsung_ufs_phy_clks_init`, `function samsung_ufs_phy_init`, `function samsung_ufs_phy_power_on`, `function samsung_ufs_phy_power_off`, `function samsung_ufs_phy_set_mode`.
- Atlas domain: Driver Families / drivers/phy.
- Implementation status: source implementation candidate.
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.