drivers/ufs/host/ufs-hisi.c
Source file repositories/reference/linux-study-clean/drivers/ufs/host/ufs-hisi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/ufs/host/ufs-hisi.c- Extension
.c- Size
- 17206 bytes
- Lines
- 606
- Domain
- Driver Families
- Bucket
- drivers/ufs
- 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/time.hlinux/delay.hlinux/module.hlinux/of.hlinux/of_address.hlinux/dma-mapping.hlinux/platform_device.hlinux/reset.hufs/ufshcd.hufshcd-pltfrm.hufs/unipro.hufs-hisi.hufs/ufshci.hufs/ufs_quirks.h
Detected Declarations
function Copyrightfunction ufs_hisi_clk_initfunction ufs_hisi_soc_initfunction ufs_hisi_link_startup_pre_changefunction ufs_hisi_link_startup_post_changefunction ufs_hisi_link_startup_notifyfunction ufs_hisi_set_dev_capfunction ufs_hisi_negotiate_pwr_modefunction ufs_hisi_pwr_change_pre_changefunction ufs_hisi_pwr_change_notifyfunction ufs_hisi_suspend_preparefunction ufs_hisi_suspendfunction ufs_hisi_resumefunction ufs_hisi_get_resourcefunction ufs_hisi_set_pm_lvlfunction ufs_hisi_init_commonfunction ufs_hi3660_initfunction ufs_hi3670_initfunction ufs_hisi_probefunction ufs_hisi_remove
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
/*
* HiSilicon Hixxxx UFS Driver
*
* Copyright (c) 2016-2017 Linaro Ltd.
* Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
*/
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <ufs/ufshcd.h>
#include "ufshcd-pltfrm.h"
#include <ufs/unipro.h>
#include "ufs-hisi.h"
#include <ufs/ufshci.h>
#include <ufs/ufs_quirks.h>
static int ufs_hisi_check_hibern8(struct ufs_hba *hba)
{
int err = 0;
u32 tx_fsm_val_0 = 0;
u32 tx_fsm_val_1 = 0;
unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
do {
err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
&tx_fsm_val_0);
err |= ufshcd_dme_get(hba,
UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1);
if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 &&
tx_fsm_val_1 == TX_FSM_HIBERN8))
break;
/* sleep for max. 200us */
usleep_range(100, 200);
} while (time_before(jiffies, timeout));
/*
* we might have scheduled out for long during polling so
* check the state again.
*/
if (time_after(jiffies, timeout)) {
err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
&tx_fsm_val_0);
err |= ufshcd_dme_get(hba,
UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 1), &tx_fsm_val_1);
}
if (err) {
dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
__func__, err);
} else if (tx_fsm_val_0 != TX_FSM_HIBERN8 ||
tx_fsm_val_1 != TX_FSM_HIBERN8) {
err = -1;
dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 = %d\n",
__func__, tx_fsm_val_0, tx_fsm_val_1);
}
return err;
}
static void ufs_hisi_clk_init(struct ufs_hba *hba)
{
struct ufs_hisi_host *host = ufshcd_get_variant(hba);
ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN)
mdelay(1);
/* use abb clk */
ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL);
ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN);
/* open mphy ref clk */
ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
}
static void ufs_hisi_soc_init(struct ufs_hba *hba)
{
struct ufs_hisi_host *host = ufshcd_get_variant(hba);
u32 reg;
if (!IS_ERR(host->rst))
reset_control_assert(host->rst);
Annotation
- Immediate include surface: `linux/time.h`, `linux/delay.h`, `linux/module.h`, `linux/of.h`, `linux/of_address.h`, `linux/dma-mapping.h`, `linux/platform_device.h`, `linux/reset.h`.
- Detected declarations: `function Copyright`, `function ufs_hisi_clk_init`, `function ufs_hisi_soc_init`, `function ufs_hisi_link_startup_pre_change`, `function ufs_hisi_link_startup_post_change`, `function ufs_hisi_link_startup_notify`, `function ufs_hisi_set_dev_cap`, `function ufs_hisi_negotiate_pwr_mode`, `function ufs_hisi_pwr_change_pre_change`, `function ufs_hisi_pwr_change_notify`.
- Atlas domain: Driver Families / drivers/ufs.
- 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.