arch/sh/boards/mach-sdk7786/setup.c

Source file repositories/reference/linux-study-clean/arch/sh/boards/mach-sdk7786/setup.c

File Facts

System
Linux kernel
Corpus path
arch/sh/boards/mach-sdk7786/setup.c
Extension
.c
Size
6182 bytes
Lines
267
Domain
Architecture Layer
Bucket
arch/sh
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

device_initcall(sdk7786_devices_setup);

static int sdk7786_mode_pins(void)
{
	return fpga_read_reg(MODSWR);
}

/*
 * FPGA-driven PCIe clocks
 *
 * Historically these include the oscillator, clock B (slots 2/3/4) and
 * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove
 * everything under a single PCIe clocks enable bit that happens to map
 * to the same bit position as the oscillator bit for earlier FPGA
 * versions.
 *
 * Given that the legacy clocks have the side-effect of shutting the CPU
 * off through the FPGA along with the PCI slots, we simply leave them in
 * their initial state and don't bother registering them with the clock
 * framework.
 */
static int sdk7786_pcie_clk_enable(struct clk *clk)
{
	fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR);
	return 0;
}

static void sdk7786_pcie_clk_disable(struct clk *clk)
{
	fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
}

static struct sh_clk_ops sdk7786_pcie_clk_ops = {
	.enable		= sdk7786_pcie_clk_enable,
	.disable	= sdk7786_pcie_clk_disable,
};

static struct clk sdk7786_pcie_clk = {
	.ops		= &sdk7786_pcie_clk_ops,
};

static struct clk_lookup sdk7786_pcie_cl = {
	.con_id		= "pcie_plat_clk",
	.clk		= &sdk7786_pcie_clk,
};

static int sdk7786_clk_init(void)
{
	struct clk *clk;
	int ret;

	/*
	 * Only handle the EXTAL case, anyone interfacing a crystal
	 * resonator will need to provide their own input clock.
	 */
	if (test_mode_pin(MODE_PIN9))
		return -EINVAL;

	clk = clk_get(NULL, "extal");
	if (IS_ERR(clk))
		return PTR_ERR(clk);
	ret = clk_set_rate(clk, 33333333);
	clk_put(clk);

	/*
	 * Setup the FPGA clocks.
	 */
	ret = clk_register(&sdk7786_pcie_clk);
	if (unlikely(ret)) {
		pr_err("FPGA clock registration failed\n");
		return ret;
	}

	clkdev_add(&sdk7786_pcie_cl);

	return 0;
}

static void sdk7786_restart(char *cmd)
{
	fpga_write_reg(0xa5a5, SRSTR);
}

static void sdk7786_power_off(void)
{
	fpga_write_reg(fpga_read_reg(PWRCR) | PWRCR_PDWNREQ, PWRCR);

	/*
	 * It can take up to 20us for the R8C to do its job, back off and
	 * wait a bit until we've been shut off. Even though newer FPGA

Annotation

Implementation Notes