Permalink
Browse files

core: Consolidate uart clock gating

This consolidates clock gating of 8250, SCIF and HSCIF, and moves it over to
the Linux driver. From now on, we make the assumption that clocks of UART
devices are already gated once we enter the hypervisor.

Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
  • Loading branch information...
rralf authored and jan-kiszka committed Jun 27, 2018
1 parent 2e9bd37 commit 00e0473cab391c9d9712f1aef33cf2b4911b1bf4
View
@@ -350,6 +350,7 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
unsigned long remap_addr = 0;
void __iomem *console = NULL, *clock_reg = NULL;
unsigned long config_size;
unsigned int clock_gates;
const char *fw_name;
long max_cpus;
int err;
@@ -504,6 +505,27 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
goto error_unmap;
}
if (config->debug_console.clock_reg) {
clock_reg = ioremap(config->debug_console.clock_reg,
sizeof(clock_gates));
if (!clock_reg) {
err = -EINVAL;
pr_err("jailhouse: Unable to map clock register at "
"%08lx\n",
(unsigned long)config->debug_console.clock_reg);
goto error_unmap;
}
clock_gates = readl(clock_reg);
if (CON_HAS_INVERTED_GATE(config->debug_console.flags))
clock_gates &= ~(1 << config->debug_console.gate_nr);
else
clock_gates |= (1 << config->debug_console.gate_nr);
writel(clock_gates, clock_reg);
iounmap(clock_reg);
}
#ifdef JAILHOUSE_BORROW_ROOT_PT
if (CON_IS_MMIO(config->debug_console.flags)) {
console = ioremap(config->debug_console.address,
@@ -519,18 +541,6 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
* to enforce conversion. */
header->debug_console_base = (void * __force)console;
}
if (config->debug_console.clock_reg) {
clock_reg = ioremap(config->debug_console.clock_reg, 1);
if (!clock_reg) {
err = -EINVAL;
pr_err("jailhouse: Unable to map hypervisor debug "
"clock register at %08lx\n",
(unsigned long)config->debug_console.clock_reg);
goto error_unmap;
}
header->debug_clock_reg = (void * __force)clock_reg;
}
#endif
console_available = SYS_FLAGS_VIRTUAL_DEBUG_CONSOLE(config->flags);
@@ -567,8 +577,6 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
if (console)
iounmap(console);
if (clock_reg)
iounmap(clock_reg);
release_firmware(hypervisor);
@@ -591,8 +599,6 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
jailhouse_firmware_free();
if (console)
iounmap(console);
if (clock_reg)
iounmap(clock_reg);
error_release_memreg:
/* jailhouse_firmware_free() could have been called already and
@@ -41,7 +41,6 @@ void arch_dbg_write_init(void)
if (uart) {
uart->debug_console = &system_config->debug_console;
uart->virt_clock_reg = hypervisor_header.debug_clock_reg;
uart->virt_base = hypervisor_header.debug_console_base;
uart->init(uart);
arch_dbg_write = uart_write;
@@ -30,14 +30,8 @@
static void uart_init(struct uart_chip *chip)
{
void *clock_reg = (void*)(unsigned long)chip->virt_clock_reg;
unsigned int gate_nr = chip->debug_console->gate_nr;
u16 hsscr;
if (clock_reg)
mmio_write32(clock_reg,
mmio_read32(clock_reg) & ~(1 << gate_nr));
if (chip->debug_console->divider) {
hsscr = mmio_read16(chip->virt_base + HSCIF_HSSCR);
mmio_write16(chip->virt_base + HSCIF_HSSCR,
@@ -31,14 +31,8 @@
static void uart_init(struct uart_chip *chip)
{
void *clock_reg = (void*)(unsigned long)chip->virt_clock_reg;
unsigned int gate_nr = chip->debug_console->gate_nr;
u16 scascr;
if (clock_reg)
mmio_write32(clock_reg,
mmio_read32(clock_reg) & ~(1 << gate_nr));
if (chip->debug_console->divider) {
scascr = mmio_read16(chip->virt_base + SCIFA_SCASCR);
mmio_write16(chip->virt_base + SCIFA_SCASCR,
@@ -83,9 +83,6 @@ struct jailhouse_header {
/** Virtual base address of the debug console device (if used).
* @note Filled by Linux loader driver before entry. */
void *debug_console_base;
/** Virtual address of the clock gate register (if used).
* @note Filled by Linux loader driver before entry. */
void *debug_clock_reg;
/** Physical address of Linux's hyp-stubs.
* @note Filled by Linux loader driver before entry. */
@@ -15,7 +15,6 @@
struct uart_chip {
/* must be set by the caller */
void *virt_base;
void *virt_clock_reg;
struct jailhouse_console *debug_console;
/* driver selects defaults, if used */
View
@@ -621,17 +621,6 @@ int paging_init(void)
return err;
}
vaddr = (unsigned long)hypervisor_header.debug_clock_reg;
if (vaddr) {
err = paging_create(&hv_paging_structs,
system_config->debug_console.clock_reg,
1, vaddr,
PAGE_DEFAULT_FLAGS | PAGE_FLAG_DEVICE,
PAGING_NON_COHERENT);
if (err)
return err;
}
/* Make sure any remappings to the temporary regions can be performed
* without allocations of page table pages. */
return paging_create(&hv_paging_structs, 0,
View
@@ -47,15 +47,8 @@ static u32 reg_in_mmio32(struct uart_chip *chip, unsigned int reg)
static void uart_init(struct uart_chip *chip)
{
void *clock_reg = (void*)(unsigned long)chip->virt_clock_reg;
unsigned int gate_nr = chip->debug_console->gate_nr;
const u32 flags = system_config->debug_console.flags;
/* clock setting only implemented on ARM via 32-bit MMIO */
if (clock_reg)
mmio_write32(clock_reg,
mmio_read32(clock_reg) | (1 << gate_nr));
if (CON_IS_MMIO(flags) && CON_USES_REGDIST_1(flags)) {
chip->reg_out = reg_out_mmio8;
chip->reg_in = reg_in_mmio8;

0 comments on commit 00e0473

Please sign in to comment.