spcr.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. #define pr_fmt(fmt) "ACPI: SPCR: " fmt
  12. #include <linux/acpi.h>
  13. #include <linux/console.h>
  14. #include <linux/kernel.h>
  15. #include <linux/serial_core.h>
  16. /*
  17. * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
  18. * Detect them by examining the OEM fields in the SPCR header, similiar to PCI
  19. * quirk detection in pci_mcfg.c.
  20. */
  21. static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
  22. {
  23. if (memcmp(h->oem_id, "QCOM ", ACPI_OEM_ID_SIZE))
  24. return false;
  25. if (!memcmp(h->oem_table_id, "QDF2432 ", ACPI_OEM_TABLE_ID_SIZE))
  26. return true;
  27. if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) &&
  28. h->oem_revision == 1)
  29. return true;
  30. return false;
  31. }
  32. /**
  33. * parse_spcr() - parse ACPI SPCR table and add preferred console
  34. *
  35. * @earlycon: set up earlycon for the console specified by the table
  36. *
  37. * For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be
  38. * defined to parse ACPI SPCR table. As a result of the parsing preferred
  39. * console is registered and if @earlycon is true, earlycon is set up.
  40. *
  41. * When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called
  42. * from arch initialization code as soon as the DT/ACPI decision is made.
  43. *
  44. */
  45. int __init parse_spcr(bool earlycon)
  46. {
  47. static char opts[64];
  48. struct acpi_table_spcr *table;
  49. acpi_status status;
  50. char *uart;
  51. char *iotype;
  52. int baud_rate;
  53. int err;
  54. if (acpi_disabled)
  55. return -ENODEV;
  56. status = acpi_get_table(ACPI_SIG_SPCR, 0,
  57. (struct acpi_table_header **)&table);
  58. if (ACPI_FAILURE(status))
  59. return -ENOENT;
  60. if (table->header.revision < 2) {
  61. err = -ENOENT;
  62. pr_err("wrong table version\n");
  63. goto done;
  64. }
  65. iotype = table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY ?
  66. "mmio" : "io";
  67. switch (table->interface_type) {
  68. case ACPI_DBG2_ARM_SBSA_32BIT:
  69. iotype = "mmio32";
  70. /* fall through */
  71. case ACPI_DBG2_ARM_PL011:
  72. case ACPI_DBG2_ARM_SBSA_GENERIC:
  73. case ACPI_DBG2_BCM2835:
  74. uart = "pl011";
  75. break;
  76. case ACPI_DBG2_16550_COMPATIBLE:
  77. case ACPI_DBG2_16550_SUBSET:
  78. uart = "uart";
  79. break;
  80. default:
  81. err = -ENOENT;
  82. goto done;
  83. }
  84. switch (table->baud_rate) {
  85. case 3:
  86. baud_rate = 9600;
  87. break;
  88. case 4:
  89. baud_rate = 19200;
  90. break;
  91. case 6:
  92. baud_rate = 57600;
  93. break;
  94. case 7:
  95. baud_rate = 115200;
  96. break;
  97. default:
  98. err = -ENOENT;
  99. goto done;
  100. }
  101. if (qdf2400_erratum_44_present(&table->header))
  102. uart = "qdf2400_e44";
  103. snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype,
  104. table->serial_port.address, baud_rate);
  105. pr_info("console: %s\n", opts);
  106. if (earlycon)
  107. setup_earlycon(opts);
  108. err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
  109. done:
  110. acpi_put_table((struct acpi_table_header *)table);
  111. return err;
  112. }