fix potens not being set in ttyFB* device
[lunaix-os.git] / lunaix-os / hal / char / uart / 16x50_isa.c
1 #include <lunaix/device.h>
2 #include <lunaix/syslog.h>
3
4 #include <asm/x86_pmio.h>
5
6 #include "16x50.h"
7
8 LOG_MODULE("16x50-isa");
9
10 static DEFINE_LLIST(com_ports);
11
12 static void
13 com_irq_handler(irq_t irq, const struct hart_state* hstate)
14 {
15     uart_handle_irq_overlap(irq, &com_ports);
16 }
17
18 int
19 isa16x50_create_once(struct device_def* def)
20 {
21     int irq3 = 3, irq4 = 4;
22     u16_t ioports[] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
23     int* irqs[] = { &irq4, &irq3, &irq4, &irq3 };
24
25     struct uart16550* uart = NULL;
26     struct serial_dev* sdev;
27     ptr_t base;
28
29     // COM 1...4
30     for (size_t i = 0; i < 4; i++) {
31
32         base = ioports[i];
33         uart = uart16x50_pmio_create(base);
34         if (!uart) {
35             WARN("port 0x%x not accessible", base);
36             continue;
37         }
38
39         sdev = uart_create_serial(uart, &def->class, &com_ports, "S");
40         
41         int irq = *irqs[i];
42         if (irq) {
43             /*
44              *  Since these irqs are overlapped, this particular setup is needed
45              * to avoid double-bind
46              */
47             uart->irq = irq_declare_line(com_irq_handler, irq);
48             irq_assign(irq_owning_domain(sdev->dev), uart->irq, NULL);
49             *((volatile int*)irqs[i]) = 0;
50         }
51         
52         INFO("base: 0x%x, irq=%d", base, irq);
53     }
54
55     return 0;
56 }