acpi_serial.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/char/acpi_serial.c
  3.  *
  4.  *  Copyright (C) 2000  Hewlett-Packard Co.
  5.  *  Copyright (C) 2000  Khalid Aziz <khalid_aziz@hp.com>
  6.  *
  7.  *  Detect and initialize the headless console serial port defined in 
  8.  *  SPCR table and debug serial port defined in DBGP table
  9.  *
  10.  */
  11. #include <linux/kernel.h>
  12. #include <linux/types.h>
  13. #include <linux/pci.h>
  14. #include <linux/pm.h>
  15. #include <linux/acpi.h>
  16. #include <linux/init.h>
  17. #include <linux/serial.h>
  18. #include <asm/serial.h>
  19. #include <asm/io.h>
  20. #include <linux/acpi_serial.h>
  21. /*#include <asm/acpi-ext.h>*/
  22. #undef SERIAL_DEBUG_ACPI
  23. /*
  24.  * Query ACPI tables for a debug and a headless console serial
  25.  * port. If found, add them to rs_table[]. A pointer to either SPCR
  26.  * or DBGP table is passed as parameter. This function should be called 
  27.  * before serial_console_init() is called to make sure the SPCR serial 
  28.  * console will be available for use. IA-64 kernel calls this function
  29.  * from within acpi.c when it encounters SPCR or DBGP tables as it parses 
  30.  * the ACPI 2.0 tables during bootup.
  31.  *
  32.  */
  33. void __init setup_serial_acpi(void *tablep) 
  34. {
  35. acpi_ser_t *acpi_ser_p;
  36. struct serial_struct serial_req;
  37. unsigned long iobase;
  38. int global_sys_irq;
  39. #ifdef SERIAL_DEBUG_ACPI
  40. printk("Entering setup_serial_acpi()n");
  41. #endif
  42. /* Now get the table */
  43. if (tablep == NULL) {
  44. return;
  45. }
  46. acpi_ser_p = (acpi_ser_t *)tablep;
  47. /*
  48.  * Perform a sanity check on the table. Table should have a 
  49.  * signature of "SPCR" or "DBGP" and it should be atleast 52 bytes
  50.  * long.
  51.  */
  52. if ((strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE, 
  53. ACPI_SIG_LEN) != 0) && 
  54. (strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, 
  55. ACPI_SIG_LEN) != 0)) {
  56. return;
  57. }
  58. if (acpi_ser_p->length < 52) {
  59. return;
  60. }
  61. iobase = (((u64) acpi_ser_p->base_addr.addrh) << 32) | acpi_ser_p->base_addr.addrl;
  62. global_sys_irq = (acpi_ser_p->global_int[3] << 24) | 
  63. (acpi_ser_p->global_int[2] << 16) |
  64. (acpi_ser_p->global_int[1] << 8) |
  65. acpi_ser_p->global_int[0];
  66. #ifdef SERIAL_DEBUG_ACPI
  67. printk("setup_serial_acpi(): table pointer = 0x%pn", acpi_ser_p);
  68. printk("                     sig = '%c%c%c%c'n",
  69. acpi_ser_p->signature[0],
  70. acpi_ser_p->signature[1],
  71. acpi_ser_p->signature[2],
  72. acpi_ser_p->signature[3]);
  73. printk("                     length = %dn", acpi_ser_p->length);
  74. printk("                     Rev = %dn", acpi_ser_p->rev);
  75. printk("                     Interface type = %dn", acpi_ser_p->intfc_type);
  76. printk("                     Base address = 0x%lXn", iobase);
  77. printk("                     IRQ = %dn", acpi_ser_p->irq);
  78. printk("                     Global System Int = %dn", global_sys_irq);
  79. printk("                     Baud rate = ");
  80. switch (acpi_ser_p->baud) {
  81. case ACPI_SERIAL_BAUD_9600:
  82. printk("9600n");
  83. break;
  84. case ACPI_SERIAL_BAUD_19200:
  85. printk("19200n");
  86. break;
  87. case ACPI_SERIAL_BAUD_57600:
  88. printk("57600n");
  89. break;
  90. case ACPI_SERIAL_BAUD_115200:
  91. printk("115200n");
  92. break;
  93. default:
  94. printk("Huh (%d)n", acpi_ser_p->baud);
  95. break;
  96. }
  97. if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) {
  98. printk("                     PCI serial port:n");
  99. printk("                         Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%xn",
  100. acpi_ser_p->pci_bus, acpi_ser_p->pci_dev,
  101. acpi_ser_p->pci_vendor_id, acpi_ser_p->pci_dev_id);
  102. }
  103. #endif
  104. /* 
  105.  * Now build a serial_req structure to update the entry in
  106.  * rs_table for the headless console port.
  107.  */
  108. switch (acpi_ser_p->intfc_type) {
  109.   case ACPI_SERIAL_INTFC_16550:
  110. serial_req.type = PORT_16550;
  111. serial_req.baud_base = BASE_BAUD;
  112. break;
  113.   case ACPI_SERIAL_INTFC_16450:
  114. serial_req.type = PORT_16450;
  115. serial_req.baud_base = BASE_BAUD;
  116. break;
  117. default:
  118. serial_req.type = PORT_UNKNOWN;
  119. break;
  120. }
  121. if (strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE,
  122. ACPI_SIG_LEN) == 0) {
  123. serial_req.line = ACPI_SERIAL_CONSOLE_PORT;
  124. }
  125. else if (strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, 
  126. ACPI_SIG_LEN) == 0) {
  127. serial_req.line = ACPI_SERIAL_DEBUG_PORT;
  128. }
  129. /*
  130.  * Check if this is an I/O mapped address or a memory mapped address
  131.  */
  132. if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_MEM_SPACE) {
  133. serial_req.port = 0;
  134. serial_req.port_high = 0;
  135. serial_req.iomem_base = (void *)ioremap(iobase, 64);
  136. serial_req.io_type = SERIAL_IO_MEM;
  137. }
  138. else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_IO_SPACE) {
  139. serial_req.port = (unsigned long) iobase & 0xffffffff;
  140. serial_req.port_high = (unsigned long)(((u64)iobase) >> 32);
  141. serial_req.iomem_base = NULL;
  142. serial_req.io_type = SERIAL_IO_PORT;
  143. }
  144. else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) {
  145. printk("WARNING: No support for PCI serial consolen");
  146. return;
  147. }
  148. /*
  149.  * If the table does not have IRQ information, use 0 for IRQ. 
  150.  * This will force rs_init() to probe for IRQ. 
  151.  */
  152. if (acpi_ser_p->length < 53) {
  153. serial_req.irq = 0;
  154. }
  155. else {
  156. serial_req.flags = ASYNC_SKIP_TEST | ASYNC_BOOT_AUTOCONF | 
  157. ASYNC_AUTO_IRQ;
  158. if (acpi_ser_p->int_type & 
  159. (ACPI_SERIAL_INT_APIC | ACPI_SERIAL_INT_SAPIC)) {
  160. serial_req.irq = global_sys_irq;
  161. }
  162. else if (acpi_ser_p->int_type & ACPI_SERIAL_INT_PCAT) {
  163. serial_req.irq = acpi_ser_p->irq;
  164. }
  165. else {
  166. /*
  167.  * IRQ type not being set would mean UART will
  168.  * run in polling mode. Do not probe for IRQ in
  169.  * that case.
  170.  */
  171. serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF;
  172. }
  173. }
  174. serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
  175. serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
  176. serial_req.iomem_reg_shift = 0;
  177. if (early_serial_setup(&serial_req) < 0) {
  178. printk("early_serial_setup() for ACPI serial console port failedn");
  179. return;
  180. }
  181. #ifdef SERIAL_DEBUG_ACPI
  182. printk("Leaving setup_serial_acpi()n");
  183. #endif
  184. }