arch/mips/pci/ops-rc32434.c

Source file repositories/reference/linux-study-clean/arch/mips/pci/ops-rc32434.c

File Facts

System
Linux kernel
Corpus path
arch/mips/pci/ops-rc32434.c
Extension
.c
Size
5288 bytes
Lines
207
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/delay.h>
#include <linux/io.h>
#include <linux/pci.h>
#include <linux/types.h>

#include <asm/cpu.h>
#include <asm/mach-rc32434/rc32434.h>
#include <asm/mach-rc32434/pci.h>

#define PCI_ACCESS_READ	 0
#define PCI_ACCESS_WRITE 1


#define PCI_CFG_SET(bus, slot, func, off) \
	(rc32434_pci->pcicfga = (0x80000000 | \
				((bus) << 16) | ((slot)<<11) | \
				((func)<<8) | (off)))

static inline int config_access(unsigned char access_type,
				struct pci_bus *bus, unsigned int devfn,
				unsigned char where, u32 *data)
{
	unsigned int slot = PCI_SLOT(devfn);
	u8 func = PCI_FUNC(devfn);

	/* Setup address */
	PCI_CFG_SET(bus->number, slot, func, where);
	rc32434_sync();

	if (access_type == PCI_ACCESS_WRITE)
		rc32434_pci->pcicfgd = *data;
	else
		*data = rc32434_pci->pcicfgd;

	rc32434_sync();

	return 0;
}


/*
 * We can't address 8 and 16 bit words directly.  Instead we have to
 * read/write a 32bit word and mask/modify the data we actually want.
 */
static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
			    int where, u8 *val)
{
	u32 data;
	int ret;

	ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
	*val = (data >> ((where & 3) << 3)) & 0xff;
	return ret;
}

static int read_config_word(struct pci_bus *bus, unsigned int devfn,
			    int where, u16 *val)
{
	u32 data;
	int ret;

	ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
	*val = (data >> ((where & 3) << 3)) & 0xffff;
	return ret;
}

static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
			     int where, u32 *val)
{
	int ret;
	int delay = 1;

	/*
	 * Don't scan too far, else there will be errors with plugged in
	 * daughterboard (rb564).
	 */
	if (bus->number == 0 && PCI_SLOT(devfn) > 21)
		return 0;

retry:
	ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);

	/*
	 * Certain devices react delayed at device scan time, this
	 * gives them time to settle
	 */
	if (where == PCI_VENDOR_ID) {
		if (*val == 0xffffffff || *val == 0x00000000 ||
		    *val == 0x0000ffff || *val == 0xffff0000) {
			if (delay > 4)

Annotation

Implementation Notes