drivers/spi/spi-intel.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-intel.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-intel.c
Extension
.c
Size
41085 bytes
Lines
1525
Domain
Driver Families
Bucket
drivers/spi
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct intel_spi {
	struct device *dev;
	const struct intel_spi_boardinfo *info;
	void __iomem *base;
	void __iomem *pregs;
	void __iomem *sregs;
	struct spi_controller *host;
	size_t nregions;
	size_t pr_num;
	size_t chip0_size;
	bool locked;
	bool protected;
	bool bios_locked;
	bool swseq_reg;
	bool swseq_erase;
	u8 atomic_preopcode;
	u8 opcodes[8];
	const struct intel_spi_mem_op *mem_ops;
};

struct intel_spi_mem_op {
	struct spi_mem_op mem_op;
	u32 replacement_op;
	int (*exec_op)(struct intel_spi *ispi,
		       const struct spi_mem *mem,
		       const struct intel_spi_mem_op *iop,
		       const struct spi_mem_op *op);
};

static bool writeable;
module_param(writeable, bool, 0);
MODULE_PARM_DESC(writeable, "Enable write access to SPI flash chip (default=0)");
static bool ignore_protection_status;
module_param(ignore_protection_status, bool, 0);
MODULE_PARM_DESC(
	ignore_protection_status,
	"Do not block SPI flash chip write access even if it is write-protected (default=0)");

static void intel_spi_dump_regs(struct intel_spi *ispi)
{
	u32 value;
	int i;

	dev_dbg(ispi->dev, "BFPREG=0x%08x\n", readl(ispi->base + BFPREG));

	value = readl(ispi->base + HSFSTS_CTL);
	dev_dbg(ispi->dev, "HSFSTS_CTL=0x%08x\n", value);
	if (value & HSFSTS_CTL_FLOCKDN)
		dev_dbg(ispi->dev, "-> Locked\n");

	dev_dbg(ispi->dev, "FADDR=0x%08x\n", readl(ispi->base + FADDR));
	dev_dbg(ispi->dev, "DLOCK=0x%08x\n", readl(ispi->base + DLOCK));

	for (i = 0; i < 16; i++)
		dev_dbg(ispi->dev, "FDATA(%d)=0x%08x\n",
			i, readl(ispi->base + FDATA(i)));

	dev_dbg(ispi->dev, "FRACC=0x%08x\n", readl(ispi->base + FRACC));

	for (i = 0; i < ispi->nregions; i++)
		dev_dbg(ispi->dev, "FREG(%d)=0x%08x\n", i,
			readl(ispi->base + FREG(i)));
	for (i = 0; i < ispi->pr_num; i++)
		dev_dbg(ispi->dev, "PR(%d)=0x%08x\n", i,
			readl(ispi->pregs + PR(i)));

	if (ispi->sregs) {
		value = readl(ispi->sregs + SSFSTS_CTL);
		dev_dbg(ispi->dev, "SSFSTS_CTL=0x%08x\n", value);
		dev_dbg(ispi->dev, "PREOP_OPTYPE=0x%08x\n",
			readl(ispi->sregs + PREOP_OPTYPE));
		dev_dbg(ispi->dev, "OPMENU0=0x%08x\n",
			readl(ispi->sregs + OPMENU0));
		dev_dbg(ispi->dev, "OPMENU1=0x%08x\n",
			readl(ispi->sregs + OPMENU1));
	}

	dev_dbg(ispi->dev, "LVSCC=0x%08x\n", readl(ispi->base + LVSCC));
	dev_dbg(ispi->dev, "UVSCC=0x%08x\n", readl(ispi->base + UVSCC));

	dev_dbg(ispi->dev, "Protected regions:\n");
	for (i = 0; i < ispi->pr_num; i++) {
		u32 base, limit;

		value = readl(ispi->pregs + PR(i));
		if (!(value & (PR_WPE | PR_RPE)))
			continue;

		limit = (value & PR_LIMIT_MASK) >> PR_LIMIT_SHIFT;
		base = value & PR_BASE_MASK;

Annotation

Implementation Notes