arch/powerpc/sysdev/cpm_common.c

Source file repositories/reference/linux-study-clean/arch/powerpc/sysdev/cpm_common.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/sysdev/cpm_common.c
Extension
.c
Size
5049 bytes
Lines
220
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration 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

subsys_initcall(cpm_init);

#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
static u32 __iomem *cpm_udbg_txdesc;
static u8 __iomem *cpm_udbg_txbuf;

static void udbg_putc_cpm(char c)
{
	if (c == '\n')
		udbg_putc_cpm('\r');

	while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
		;

	out_8(cpm_udbg_txbuf, c);
	out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
}

void __init udbg_init_cpm(void)
{
#ifdef CONFIG_PPC_8xx
	mmu_mapin_immr();

	cpm_udbg_txdesc = (u32 __iomem __force *)
			  (CONFIG_PPC_EARLY_DEBUG_CPM_ADDR - PHYS_IMMR_BASE +
			   VIRT_IMMR_BASE);
	cpm_udbg_txbuf = (u8 __iomem __force *)
			 (in_be32(&cpm_udbg_txdesc[1]) - PHYS_IMMR_BASE +
			  VIRT_IMMR_BASE);
#else
	cpm_udbg_txdesc = (u32 __iomem __force *)
			  CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
	cpm_udbg_txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
#endif

	if (cpm_udbg_txdesc) {
#ifdef CONFIG_CPM2
		setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
#endif
		udbg_putc = udbg_putc_cpm;
	}
}
#endif

#if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)

#include <linux/gpio/driver.h>

struct cpm2_ioports {
	u32 dir, par, sor, odr, dat;
	u32 res[3];
};

struct cpm2_gpio32_chip {
	struct gpio_chip gc;
	void __iomem *regs;
	spinlock_t lock;

	/* shadowed data register to clear/set bits safely */
	u32 cpdata;
};

static void cpm2_gpio32_save_regs(struct cpm2_gpio32_chip *cpm2_gc)
{
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;

	cpm2_gc->cpdata = in_be32(&iop->dat);
}

static int cpm2_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
{
	struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;
	u32 pin_mask;

	pin_mask = 1 << (31 - gpio);

	return !!(in_be32(&iop->dat) & pin_mask);
}

static void __cpm2_gpio32_set(struct cpm2_gpio32_chip *cpm2_gc, u32 pin_mask, int value)
{
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;

	if (value)
		cpm2_gc->cpdata |= pin_mask;
	else
		cpm2_gc->cpdata &= ~pin_mask;

	out_be32(&iop->dat, cpm2_gc->cpdata);

Annotation

Implementation Notes