drivers/ssb/driver_mipscore.c

Source file repositories/reference/linux-study-clean/drivers/ssb/driver_mipscore.c

File Facts

System
Linux kernel
Corpus path
drivers/ssb/driver_mipscore.c
Extension
.c
Size
8982 bytes
Lines
357
Domain
Driver Families
Bucket
drivers/ssb
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

if ((ipsflag & ipsflag_irq_mask[irq]) != ipsflag_irq_mask[irq]) {
			u32 oldipsflag = (ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq];
			struct ssb_device *olddev = find_device(dev, oldipsflag);
			if (olddev)
				set_irq(olddev, 0);
		}
		irqflag <<= ipsflag_irq_shift[irq];
		irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]);
		ssb_write32(mdev, SSB_IPSFLAG, irqflag);
	}
	dev_dbg(dev->dev, "set_irq: core 0x%04x, irq %d => %d\n",
		dev->id.coreid, oldirq+2, irq+2);
}

static void print_irq(struct ssb_device *dev, unsigned int irq)
{
	static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
	dev_dbg(dev->dev,
		"core 0x%04x, irq : %s%s %s%s %s%s %s%s %s%s %s%s %s%s\n",
		dev->id.coreid,
		irq_name[0], irq == 0 ? "*" : " ",
		irq_name[1], irq == 1 ? "*" : " ",
		irq_name[2], irq == 2 ? "*" : " ",
		irq_name[3], irq == 3 ? "*" : " ",
		irq_name[4], irq == 4 ? "*" : " ",
		irq_name[5], irq == 5 ? "*" : " ",
		irq_name[6], irq == 6 ? "*" : " ");
}

static void dump_irq(struct ssb_bus *bus)
{
	int i;
	for (i = 0; i < bus->nr_devices; i++) {
		struct ssb_device *dev;
		dev = &(bus->devices[i]);
		print_irq(dev, ssb_mips_irq(dev));
	}
}

static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
{
	struct ssb_bus *bus = mcore->dev->bus;

	if (ssb_extif_available(&bus->extif))
		mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports);
	else if (ssb_chipco_available(&bus->chipco))
		mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
	else
		mcore->nr_serial_ports = 0;
}

static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
{
	struct ssb_bus *bus = mcore->dev->bus;
	struct ssb_sflash *sflash = &mcore->sflash;
	struct ssb_pflash *pflash = &mcore->pflash;

	/* When there is no chipcommon on the bus there is 4MB flash */
	if (!ssb_chipco_available(&bus->chipco)) {
		pflash->present = true;
		pflash->buswidth = 2;
		pflash->window = SSB_FLASH1;
		pflash->window_size = SSB_FLASH1_SZ;
		goto ssb_pflash;
	}

	/* There is ChipCommon, so use it to read info about flash */
	switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
	case SSB_CHIPCO_FLASHT_STSER:
	case SSB_CHIPCO_FLASHT_ATSER:
		dev_dbg(mcore->dev->dev, "Found serial flash\n");
		ssb_sflash_init(&bus->chipco);
		break;
	case SSB_CHIPCO_FLASHT_PARA:
		dev_dbg(mcore->dev->dev, "Found parallel flash\n");
		pflash->present = true;
		pflash->window = SSB_FLASH2;
		pflash->window_size = SSB_FLASH2_SZ;
		if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
		               & SSB_CHIPCO_CFG_DS16) == 0)
			pflash->buswidth = 1;
		else
			pflash->buswidth = 2;
		break;
	}

ssb_pflash:
	if (sflash->present) {
#ifdef CONFIG_BCM47XX
		bcm47xx_nvram_init_from_mem(sflash->window, sflash->size);

Annotation

Implementation Notes