drivers/pci/controller/pci-rcar-gen2.c

Source file repositories/reference/linux-study-clean/drivers/pci/controller/pci-rcar-gen2.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/pci-rcar-gen2.c
Extension
.c
Size
9855 bytes
Lines
343
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rcar_pci {
	struct device *dev;
	void __iomem *reg;
	struct resource mem_res;
	struct resource *cfg_res;
	int irq;
};

/* PCI configuration space operations */
static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
				       int where)
{
	struct rcar_pci *priv = bus->sysdata;
	int slot, val;

	if (!pci_is_root_bus(bus) || PCI_FUNC(devfn))
		return NULL;

	/* Only one EHCI/OHCI device built-in */
	slot = PCI_SLOT(devfn);
	if (slot > 2)
		return NULL;

	/* bridge logic only has registers to 0x40 */
	if (slot == 0x0 && where >= 0x40)
		return NULL;

	val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG :
		     RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;

	iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
	return priv->reg + (slot >> 1) * 0x100 + where;
}

#ifdef CONFIG_PCI_DEBUG
/* if debug enabled, then attach an error handler irq to the bridge */

static irqreturn_t rcar_pci_err_irq(int irq, void *pw)
{
	struct rcar_pci *priv = pw;
	struct device *dev = priv->dev;
	u32 status = ioread32(priv->reg + RCAR_PCI_INT_STATUS_REG);

	if (status & RCAR_PCI_INT_ALLERRORS) {
		dev_err(dev, "error irq: status %08x\n", status);

		/* clear the error(s) */
		iowrite32(status & RCAR_PCI_INT_ALLERRORS,
			  priv->reg + RCAR_PCI_INT_STATUS_REG);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

static void rcar_pci_setup_errirq(struct rcar_pci *priv)
{
	struct device *dev = priv->dev;
	int ret;
	u32 val;

	ret = devm_request_irq(dev, priv->irq, rcar_pci_err_irq,
			       IRQF_SHARED, "error irq", priv);
	if (ret) {
		dev_err(dev, "cannot claim IRQ for error handling\n");
		return;
	}

	val = ioread32(priv->reg + RCAR_PCI_INT_ENABLE_REG);
	val |= RCAR_PCI_INT_ALLERRORS;
	iowrite32(val, priv->reg + RCAR_PCI_INT_ENABLE_REG);
}
#else
static inline void rcar_pci_setup_errirq(struct rcar_pci *priv) { }
#endif

/* PCI host controller setup */
static void rcar_pci_setup(struct rcar_pci *priv)
{
	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(priv);
	struct device *dev = priv->dev;
	void __iomem *reg = priv->reg;
	struct resource_entry *entry;
	unsigned long window_size;
	unsigned long window_addr;
	unsigned long window_pci;
	u32 val;

	entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM);
	if (!entry) {

Annotation

Implementation Notes