drivers/firewire/init_ohci1394_dma.c

Source file repositories/reference/linux-study-clean/drivers/firewire/init_ohci1394_dma.c

File Facts

System
Linux kernel
Corpus path
drivers/firewire/init_ohci1394_dma.c
Extension
.c
Size
9477 bytes
Lines
307
Domain
Driver Families
Bucket
drivers/firewire
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 ohci {
	void __iomem *registers;
};

static inline void reg_write(const struct ohci *ohci, int offset, u32 data)
{
	writel(data, ohci->registers + offset);
}

static inline u32 reg_read(const struct ohci *ohci, int offset)
{
	return readl(ohci->registers + offset);
}

#define OHCI_LOOP_COUNT		100	/* Number of loops for reg read waits */

/* Reads a PHY register of an OHCI-1394 controller */
static inline u8 __init get_phy_reg(struct ohci *ohci, u8 addr)
{
	int i;
	u32 r;

	reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000);

	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
		if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000)
			break;
		mdelay(1);
	}
	r = reg_read(ohci, OHCI1394_PhyControl);

	return (r & 0x00ff0000) >> 16;
}

/* Writes to a PHY register of an OHCI-1394 controller */
static inline void __init set_phy_reg(struct ohci *ohci, u8 addr, u8 data)
{
	int i;

	reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000);

	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
		if (!(reg_read(ohci, OHCI1394_PhyControl) & 0x00004000))
			break;
		mdelay(1);
	}
}

/* Resets an OHCI-1394 controller (for sane state before initialization) */
static inline void __init init_ohci1394_soft_reset(struct ohci *ohci)
{
	int i;

	reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);

	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
		if (!(reg_read(ohci, OHCI1394_HCControlSet)
				   & OHCI1394_HCControl_softReset))
			break;
		mdelay(1);
	}
}

#define OHCI1394_MAX_AT_REQ_RETRIES	0xf
#define OHCI1394_MAX_AT_RESP_RETRIES	0x2
#define OHCI1394_MAX_PHYS_RESP_RETRIES	0x8

/* Basic OHCI-1394 register and port inititalization */
static inline void __init init_ohci1394_initialize(struct ohci *ohci)
{
	u32 bus_options;
	int num_ports, i;

	/* Put some defaults to these undefined bus options */
	bus_options = reg_read(ohci, OHCI1394_BusOptions);
	bus_options |=  0x60000000; /* Enable CMC and ISC */
	bus_options &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */
	bus_options &= ~0x18000000; /* Disable PMC and BMC */
	reg_write(ohci, OHCI1394_BusOptions, bus_options);

	/* Set the bus number */
	reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);

	/* Enable posted writes */
	reg_write(ohci, OHCI1394_HCControlSet,
			OHCI1394_HCControl_postedWriteEnable);

	/* Clear link control register */
	reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);

Annotation

Implementation Notes