arch/powerpc/kernel/legacy_serial.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/legacy_serial.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/legacy_serial.c
Extension
.c
Size
19454 bytes
Lines
691
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

device_initcall(serial_dev_init);


#ifdef CONFIG_SERIAL_8250_CONSOLE
/*
 * This is called very early, as part of console_init() (typically just after
 * time_init()). This function is respondible for trying to find a good
 * default console on serial ports. It tries to match the open firmware
 * default output with one of the available serial console drivers that have
 * been probed earlier by find_legacy_serial_ports()
 */
static int __init check_legacy_serial_console(void)
{
	struct device_node *prom_stdout = NULL;
	int i, speed = 0, offset = 0;
	const char *name;
	const __be32 *spd;

	DBG(" -> check_legacy_serial_console()\n");

	/* The user has requested a console so this is already set up. */
	if (strstr(boot_command_line, "console=")) {
		DBG(" console was specified !\n");
		return -EBUSY;
	}

	if (!of_chosen) {
		DBG(" of_chosen is NULL !\n");
		return -ENODEV;
	}

	if (legacy_serial_console < 0) {
		DBG(" legacy_serial_console not found !\n");
		return -ENODEV;
	}
	/* We are getting a weird phandle from OF ... */
	/* ... So use the full path instead */
	name = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (name == NULL)
		name = of_get_property(of_chosen, "stdout-path", NULL);
	if (name == NULL) {
		DBG(" no stdout-path !\n");
		return -ENODEV;
	}
	prom_stdout = of_find_node_by_path(name);
	if (!prom_stdout) {
		DBG(" can't find stdout package %s !\n", name);
		return -ENODEV;
	}
	DBG("stdout is %pOF\n", prom_stdout);

	name = of_get_property(prom_stdout, "name", NULL);
	if (!name) {
		DBG(" stdout package has no name !\n");
		goto not_found;
	}
	spd = of_get_property(prom_stdout, "current-speed", NULL);
	if (spd)
		speed = be32_to_cpup(spd);

	if (strcmp(name, "serial") != 0)
		goto not_found;

	/* Look for it in probed array */
	for (i = 0; i < legacy_serial_count; i++) {
		if (prom_stdout != legacy_serial_infos[i].np)
			continue;
		offset = i;
		speed = legacy_serial_infos[i].speed;
		break;
	}
	if (i >= legacy_serial_count)
		goto not_found;

	of_node_put(prom_stdout);

	DBG("Found serial console at ttyS%d\n", offset);

	if (speed) {
		static char __initdata opt[16];
		sprintf(opt, "%d", speed);
		return add_preferred_console("ttyS", offset, opt);
	} else
		return add_preferred_console("ttyS", offset, NULL);

 not_found:
	DBG("No preferred console found !\n");
	of_node_put(prom_stdout);
	return -ENODEV;
}

Annotation

Implementation Notes