drivers/mtd/spi-nor/controllers/hisi-sfc.c

Source file repositories/reference/linux-study-clean/drivers/mtd/spi-nor/controllers/hisi-sfc.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/spi-nor/controllers/hisi-sfc.c
Extension
.c
Size
12094 bytes
Lines
493
Domain
Driver Families
Bucket
drivers/mtd
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct hifmc_priv {
	u32 chipselect;
	u32 clkrate;
	struct hifmc_host *host;
};

#define HIFMC_MAX_CHIP_NUM		2
struct hifmc_host {
	struct device *dev;
	struct mutex lock;

	void __iomem *regbase;
	void __iomem *iobase;
	struct clk *clk;
	void *buffer;
	dma_addr_t dma_buffer;

	struct spi_nor	*nor[HIFMC_MAX_CHIP_NUM];
	u32 num_chip;
};

static inline int hisi_spi_nor_wait_op_finish(struct hifmc_host *host)
{
	u32 reg;

	return readl_poll_timeout(host->regbase + FMC_INT, reg,
		(reg & FMC_INT_OP_DONE), 0, FMC_WAIT_TIMEOUT);
}

static int hisi_spi_nor_get_if_type(enum spi_nor_protocol proto)
{
	enum hifmc_iftype if_type;

	switch (proto) {
	case SNOR_PROTO_1_1_2:
		if_type = IF_TYPE_DUAL;
		break;
	case SNOR_PROTO_1_2_2:
		if_type = IF_TYPE_DIO;
		break;
	case SNOR_PROTO_1_1_4:
		if_type = IF_TYPE_QUAD;
		break;
	case SNOR_PROTO_1_4_4:
		if_type = IF_TYPE_QIO;
		break;
	case SNOR_PROTO_1_1_1:
	default:
		if_type = IF_TYPE_STD;
		break;
	}

	return if_type;
}

static void hisi_spi_nor_init(struct hifmc_host *host)
{
	u32 reg;

	reg = TIMING_CFG_TCSH(CS_HOLD_TIME)
		| TIMING_CFG_TCSS(CS_SETUP_TIME)
		| TIMING_CFG_TSHSL(CS_DESELECT_TIME);
	writel(reg, host->regbase + FMC_SPI_TIMING_CFG);
}

static int hisi_spi_nor_prep(struct spi_nor *nor)
{
	struct hifmc_priv *priv = nor->priv;
	struct hifmc_host *host = priv->host;
	int ret;

	mutex_lock(&host->lock);

	ret = clk_set_rate(host->clk, priv->clkrate);
	if (ret)
		goto out;

	ret = clk_prepare_enable(host->clk);
	if (ret)
		goto out;

	return 0;

out:
	mutex_unlock(&host->lock);
	return ret;
}

static void hisi_spi_nor_unprep(struct spi_nor *nor)
{

Annotation

Implementation Notes