1 /* 2 * Copyright (c) 2012, Intel Corporation 3 * Copyright (c) 2015, Red Hat, Inc. 4 * Copyright (c) 2015, 2016 Linaro Ltd. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 */ 11 12 #define pr_fmt(fmt) "ACPI: SPCR: " fmt 13 14 #include <linux/acpi.h> 15 #include <linux/console.h> 16 #include <linux/kernel.h> 17 #include <linux/serial_core.h> 18 19 /** 20 * parse_spcr() - parse ACPI SPCR table and add preferred console 21 * 22 * @earlycon: set up earlycon for the console specified by the table 23 * 24 * For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be 25 * defined to parse ACPI SPCR table. As a result of the parsing preferred 26 * console is registered and if @earlycon is true, earlycon is set up. 27 * 28 * When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called 29 * from arch inintialization code as soon as the DT/ACPI decision is made. 30 * 31 */ 32 int __init parse_spcr(bool earlycon) 33 { 34 static char opts[64]; 35 struct acpi_table_spcr *table; 36 acpi_status status; 37 char *uart; 38 char *iotype; 39 int baud_rate; 40 int err; 41 42 if (acpi_disabled) 43 return -ENODEV; 44 45 status = acpi_get_table(ACPI_SIG_SPCR, 0, 46 (struct acpi_table_header **)&table); 47 48 if (ACPI_FAILURE(status)) 49 return -ENOENT; 50 51 if (table->header.revision < 2) { 52 err = -ENOENT; 53 pr_err("wrong table version\n"); 54 goto done; 55 } 56 57 iotype = table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY ? 58 "mmio" : "io"; 59 60 switch (table->interface_type) { 61 case ACPI_DBG2_ARM_SBSA_32BIT: 62 iotype = "mmio32"; 63 /* fall through */ 64 case ACPI_DBG2_ARM_PL011: 65 case ACPI_DBG2_ARM_SBSA_GENERIC: 66 case ACPI_DBG2_BCM2835: 67 uart = "pl011"; 68 break; 69 case ACPI_DBG2_16550_COMPATIBLE: 70 case ACPI_DBG2_16550_SUBSET: 71 uart = "uart"; 72 break; 73 default: 74 err = -ENOENT; 75 goto done; 76 } 77 78 switch (table->baud_rate) { 79 case 3: 80 baud_rate = 9600; 81 break; 82 case 4: 83 baud_rate = 19200; 84 break; 85 case 6: 86 baud_rate = 57600; 87 break; 88 case 7: 89 baud_rate = 115200; 90 break; 91 default: 92 err = -ENOENT; 93 goto done; 94 } 95 96 snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype, 97 table->serial_port.address, baud_rate); 98 99 pr_info("console: %s\n", opts); 100 101 if (earlycon) 102 setup_earlycon(opts); 103 104 err = add_preferred_console(uart, 0, opts + strlen(uart) + 1); 105 106 done: 107 acpi_put_table((struct acpi_table_header *)table); 108 return err; 109 } 110