drivers/mmc/host/cb710-mmc.c

Source file repositories/reference/linux-study-clean/drivers/mmc/host/cb710-mmc.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/cb710-mmc.c
Extension
.c
Size
22040 bytes
Lines
784
Domain
Driver Families
Bucket
drivers/mmc
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 (!--limit) {
			cb710_dump_regs(cb710_slot_to_chip(slot),
				CB710_DUMP_REGS_MMC);
			err = -ETIMEDOUT;
			break;
		}
		udelay(1);
	}

#ifdef CONFIG_CB710_DEBUG
	x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);

	limit = 2000000 - limit;
	if (limit > 100)
		dev_dbg(cb710_slot_dev(slot),
			"WAIT10: waited %d loops, what %d, entry val %08X, exit val %08X\n",
			limit, what, e, x);
#endif
	return err < 0 ? err : 0;
}


static int cb710_wait_while_busy(struct cb710_slot *slot, uint8_t mask)
{
	unsigned limit = 500000;	/* FIXME: real timeout */
	int err = 0;

#ifdef CONFIG_CB710_DEBUG
	u32 e, x;
	e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
#endif

	while (cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & mask) {
		if (!--limit) {
			cb710_dump_regs(cb710_slot_to_chip(slot),
				CB710_DUMP_REGS_MMC);
			err = -ETIMEDOUT;
			break;
		}
		udelay(1);
	}

#ifdef CONFIG_CB710_DEBUG
	x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);

	limit = 500000 - limit;
	if (limit > 100)
		dev_dbg(cb710_slot_dev(slot),
			"WAIT12: waited %d loops, mask %02X, entry val %08X, exit val %08X\n",
			limit, mask, e, x);
#endif
	return err;
}

static void cb710_mmc_set_transfer_size(struct cb710_slot *slot,
	size_t count, size_t blocksize)
{
	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	cb710_write_port_32(slot, CB710_MMC_TRANSFER_SIZE_PORT,
		((count - 1) << 16)|(blocksize - 1));

	dev_vdbg(cb710_slot_dev(slot), "set up for %zu block%s of %zu bytes\n",
		count, str_plural(count), blocksize);
}

static void cb710_mmc_fifo_hack(struct cb710_slot *slot)
{
	/* without this, received data is prepended with 8-bytes of zeroes */
	u32 r1, r2;
	int ok = 0;

	r1 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
	r2 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
	if (cb710_read_port_8(slot, CB710_MMC_STATUS0_PORT)
	    & CB710_MMC_S0_FIFO_UNDERFLOW) {
		cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
			CB710_MMC_S0_FIFO_UNDERFLOW);
		ok = 1;
	}

	dev_dbg(cb710_slot_dev(slot),
		"FIFO-read-hack: expected STATUS0 bit was %s\n",
		ok ? "set." : "NOT SET!");
	dev_dbg(cb710_slot_dev(slot),
		"FIFO-read-hack: dwords ignored: %08X %08X - %s\n",
		r1, r2, (r1|r2) ? "BAD (NOT ZERO)!" : "ok");
}

static int cb710_mmc_receive_pio(struct cb710_slot *slot,
	struct sg_mapping_iter *miter, size_t dw_count)

Annotation

Implementation Notes