Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8ec5a566
Commit
8ec5a566
authored
May 14, 2003
by
Christoph Hellwig
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
acpi serial stuff
parent
29b25594
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
459 additions
and
10 deletions
+459
-10
drivers/serial/8250.c
drivers/serial/8250.c
+4
-2
drivers/serial/8250_acpi.c
drivers/serial/8250_acpi.c
+110
-0
drivers/serial/8250_hcdp.c
drivers/serial/8250_hcdp.c
+249
-0
drivers/serial/8250_hcdp.h
drivers/serial/8250_hcdp.h
+79
-0
drivers/serial/Kconfig
drivers/serial/Kconfig
+9
-0
drivers/serial/Makefile
drivers/serial/Makefile
+3
-0
include/linux/acpi_serial.h
include/linux/acpi_serial.h
+2
-0
include/linux/serial.h
include/linux/serial.h
+3
-8
No files found.
drivers/serial/8250.c
View file @
8ec5a566
...
...
@@ -2064,9 +2064,11 @@ int register_serial(struct serial_struct *req)
return
__register_serial
(
req
,
-
1
);
}
int
__init
early_serial_setup
(
struct
serial_struct
*
req
)
int
__init
early_serial_setup
(
struct
uart_port
*
port
)
{
__register_serial
(
req
,
req
->
line
);
serial8250_isa_init_ports
();
serial8250_ports
[
port
->
line
].
port
=
*
port
;
serial8250_ports
[
port
->
line
].
port
.
ops
=
&
serial8250_pops
;
return
0
;
}
...
...
drivers/serial/8250_acpi.c
0 → 100644
View file @
8ec5a566
/*
* serial/acpi.c
* Copyright (c) 2002-2003 Matthew Wilcox for Hewlett-Packard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/serial.h>
#include <acpi/acpi_bus.h>
#include <asm/io.h>
#include <asm/serial.h>
static
void
acpi_serial_address
(
struct
serial_struct
*
req
,
struct
acpi_resource_address32
*
addr32
)
{
unsigned
long
size
;
size
=
addr32
->
max_address_range
-
addr32
->
min_address_range
+
1
;
req
->
iomap_base
=
addr32
->
min_address_range
;
req
->
iomem_base
=
ioremap
(
req
->
iomap_base
,
size
);
req
->
io_type
=
SERIAL_IO_MEM
;
}
static
void
acpi_serial_irq
(
struct
serial_struct
*
req
,
struct
acpi_resource_ext_irq
*
ext_irq
)
{
if
(
ext_irq
->
number_of_interrupts
>
0
)
{
#ifdef CONFIG_IA64
req
->
irq
=
acpi_register_irq
(
ext_irq
->
interrupts
[
0
],
ext_irq
->
active_high_low
,
ext_irq
->
edge_level
);
#else
req
->
irq
=
ext_irq
->
interrupts
[
0
];
#endif
}
}
static
int
acpi_serial_add
(
struct
acpi_device
*
device
)
{
acpi_status
result
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
struct
serial_struct
serial_req
;
int
line
,
offset
=
0
;
memset
(
&
serial_req
,
0
,
sizeof
(
serial_req
));
result
=
acpi_get_current_resources
(
device
->
handle
,
&
buffer
);
if
(
ACPI_FAILURE
(
result
))
{
result
=
-
ENODEV
;
goto
out
;
}
while
(
offset
<=
buffer
.
length
)
{
struct
acpi_resource
*
res
=
buffer
.
pointer
+
offset
;
if
(
res
->
length
==
0
)
break
;
offset
+=
res
->
length
;
if
(
res
->
id
==
ACPI_RSTYPE_ADDRESS32
)
{
acpi_serial_address
(
&
serial_req
,
&
res
->
data
.
address32
);
}
else
if
(
res
->
id
==
ACPI_RSTYPE_EXT_IRQ
)
{
acpi_serial_irq
(
&
serial_req
,
&
res
->
data
.
extended_irq
);
}
}
serial_req
.
baud_base
=
BASE_BAUD
;
serial_req
.
flags
=
ASYNC_SKIP_TEST
|
ASYNC_BOOT_AUTOCONF
|
ASYNC_AUTO_IRQ
;
result
=
0
;
line
=
register_serial
(
&
serial_req
);
if
(
line
<
0
)
result
=
-
ENODEV
;
out:
acpi_os_free
(
buffer
.
pointer
);
return
result
;
}
static
int
acpi_serial_remove
(
struct
acpi_device
*
device
,
int
type
)
{
return
0
;
}
static
struct
acpi_driver
acpi_serial_driver
=
{
.
name
=
"serial"
,
.
class
=
""
,
.
ids
=
"PNP0501"
,
.
ops
=
{
.
add
=
acpi_serial_add
,
.
remove
=
acpi_serial_remove
,
},
};
static
int
__init
acpi_serial_init
(
void
)
{
return
acpi_bus_register_driver
(
&
acpi_serial_driver
);
}
static
void
__exit
acpi_serial_exit
(
void
)
{
acpi_bus_unregister_driver
(
&
acpi_serial_driver
);
}
module_init
(
acpi_serial_init
);
module_exit
(
acpi_serial_exit
);
drivers/serial/8250_hcdp.c
0 → 100644
View file @
8ec5a566
/*
* linux/drivers/char/hcdp_serial.c
*
* Copyright (C) 2002 Hewlett-Packard Co.
* Khalid Aziz <khalid_aziz@hp.com>
*
* Parse the EFI HCDP table to locate serial console and debug ports and
* initialize them.
*
* 2002/08/29 davidm Adjust it to new 2.5 serial driver infrastructure.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/efi.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/types.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <asm/serial.h>
#include <asm/acpi.h>
#include "8250_hcdp.h"
#undef SERIAL_DEBUG_HCDP
/*
* Parse the HCDP table to find descriptions for headless console and debug
* serial ports and add them to rs_table[]. A pointer to HCDP table is
* passed as parameter. This function should be called before
* serial_console_init() is called to make sure the HCDP serial console will
* be available for use. IA-64 kernel calls this function from setup_arch()
* after the EFI and ACPI tables have been parsed.
*/
void
__init
setup_serial_hcdp
(
void
*
tablep
)
{
hcdp_dev_t
*
hcdp_dev
;
struct
uart_port
port
;
unsigned
long
iobase
;
hcdp_t
hcdp
;
int
gsi
,
nr
;
#if 0
static int shift_once = 1;
#endif
#ifdef SERIAL_DEBUG_HCDP
printk
(
"Entering setup_serial_hcdp()
\n
"
);
#endif
/* Verify we have a valid table pointer */
if
(
!
tablep
)
return
;
memset
(
&
port
,
0
,
sizeof
(
port
));
/*
* Don't trust firmware to give us a table starting at an aligned
* address. Make a local copy of the HCDP table with aligned
* structures.
*/
memcpy
(
&
hcdp
,
tablep
,
sizeof
(
hcdp
));
/*
* Perform a sanity check on the table. Table should have a signature
* of "HCDP" and it should be atleast 82 bytes long to have any
* useful information.
*/
if
((
strncmp
(
hcdp
.
signature
,
HCDP_SIGNATURE
,
HCDP_SIG_LEN
)
!=
0
))
return
;
if
(
hcdp
.
len
<
82
)
return
;
#ifdef SERIAL_DEBUG_HCDP
printk
(
"setup_serial_hcdp(): table pointer = 0x%p, sig = '%.4s'
\n
"
,
tablep
,
hcdp
.
signature
);
printk
(
" length = %d, rev = %d, "
,
hcdp
.
len
,
hcdp
.
rev
);
printk
(
"OEM ID = %.6s, # of entries = %d
\n
"
,
hcdp
.
oemid
,
hcdp
.
num_entries
);
#endif
/*
* Parse each device entry
*/
for
(
nr
=
0
;
nr
<
hcdp
.
num_entries
;
nr
++
)
{
hcdp_dev
=
hcdp
.
hcdp_dev
+
nr
;
/*
* We will parse only the primary console device which is
* the first entry for these devices. We will ignore rest
* of the entries for the same type device that has already
* been parsed and initialized
*/
if
(
hcdp_dev
->
type
!=
HCDP_DEV_CONSOLE
)
continue
;
iobase
=
((
u64
)
hcdp_dev
->
base_addr
.
addrhi
<<
32
)
|
hcdp_dev
->
base_addr
.
addrlo
;
gsi
=
hcdp_dev
->
global_int
;
/* See PCI spec v2.2, Appendix D (Class Codes): */
switch
(
hcdp_dev
->
pci_prog_intfc
)
{
case
0x00
:
port
.
type
=
PORT_8250
;
break
;
case
0x01
:
port
.
type
=
PORT_16450
;
break
;
case
0x02
:
port
.
type
=
PORT_16550
;
break
;
case
0x03
:
port
.
type
=
PORT_16650
;
break
;
case
0x04
:
port
.
type
=
PORT_16750
;
break
;
case
0x05
:
port
.
type
=
PORT_16850
;
break
;
case
0x06
:
port
.
type
=
PORT_16C950
;
break
;
default:
printk
(
KERN_WARNING
"warning: EFI HCDP table reports "
"unknown serial programming interface 0x%02x; "
"will autoprobe.
\n
"
,
hcdp_dev
->
pci_prog_intfc
);
port
.
type
=
PORT_UNKNOWN
;
break
;
}
#ifdef SERIAL_DEBUG_HCDP
printk
(
" type = %s, uart = %d
\n
"
,
((
hcdp_dev
->
type
==
HCDP_DEV_CONSOLE
)
?
"Headless Console"
:
((
hcdp_dev
->
type
==
HCDP_DEV_DEBUG
)
?
"Debug port"
:
"Huh????"
)),
port
.
type
);
printk
(
" base address space = %s, base address = 0x%lx
\n
"
,
((
hcdp_dev
->
base_addr
.
space_id
==
ACPI_MEM_SPACE
)
?
"Memory Space"
:
((
hcdp_dev
->
base_addr
.
space_id
==
ACPI_IO_SPACE
)
?
"I/O space"
:
"PCI space"
)),
iobase
);
printk
(
" gsi = %d, baud rate = %lu, bits = %d, clock = %d
\n
"
,
gsi
,
(
unsigned
long
)
hcdp_dev
->
baud
,
hcdp_dev
->
bits
,
hcdp_dev
->
clock_rate
);
if
(
hcdp_dev
->
base_addr
.
space_id
==
ACPI_PCICONF_SPACE
)
printk
(
" PCI id: %02x:%02x:%02x, vendor ID=0x%x, "
"dev ID=0x%x
\n
"
,
hcdp_dev
->
pci_seg
,
hcdp_dev
->
pci_bus
,
hcdp_dev
->
pci_dev
,
hcdp_dev
->
pci_vendor_id
,
hcdp_dev
->
pci_dev_id
);
#endif
/*
* Now fill in a port structure to update the 8250 port table..
*/
if
(
hcdp_dev
->
clock_rate
)
port
.
uartclk
=
hcdp_dev
->
clock_rate
;
else
port
.
uartclk
=
BASE_BAUD
*
16
;
/*
* Check if this is an I/O mapped address or a memory mapped
* address
*/
if
(
hcdp_dev
->
base_addr
.
space_id
==
ACPI_MEM_SPACE
)
{
port
.
iobase
=
0
;
port
.
mapbase
=
iobase
;
port
.
membase
=
ioremap
(
iobase
,
64
);
port
.
iotype
=
SERIAL_IO_MEM
;
}
else
if
(
hcdp_dev
->
base_addr
.
space_id
==
ACPI_IO_SPACE
)
{
port
.
iobase
=
iobase
;
port
.
mapbase
=
0
;
port
.
membase
=
NULL
;
port
.
iotype
=
SERIAL_IO_PORT
;
}
else
if
(
hcdp_dev
->
base_addr
.
space_id
==
ACPI_PCICONF_SPACE
)
{
printk
(
KERN_WARNING
"warning: No support for PCI serial console
\n
"
);
return
;
}
#ifdef CONFIG_IA64
port
.
irq
=
acpi_register_irq
(
gsi
,
ACPI_ACTIVE_HIGH
,
ACPI_EDGE_SENSITIVE
);
#else
port
.
irq
=
gsi
;
#endif
port
.
flags
=
UPF_SKIP_TEST
|
UPF_BOOT_AUTOCONF
;
if
(
gsi
)
port
.
flags
|=
ASYNC_AUTO_IRQ
;
/*
* Note: the above memset() initializes port.line to 0,
* so we register this port as ttyS0.
*/
if
(
early_serial_setup
(
&
port
)
<
0
)
{
printk
(
"setup_serial_hcdp(): early_serial_setup() "
"for HCDP serial console port failed. "
"Will try any additional consoles in HCDP.
\n
"
);
continue
;
}
break
;
}
#ifdef SERIAL_DEBUG_HCDP
printk
(
"Leaving setup_serial_hcdp()
\n
"
);
#endif
}
#ifdef CONFIG_IA64_EARLY_PRINTK_UART
unsigned
long
hcdp_early_uart
(
void
)
{
efi_system_table_t
*
systab
;
efi_config_table_t
*
config_tables
;
unsigned
long
addr
=
0
;
hcdp_t
*
hcdp
=
0
;
hcdp_dev_t
*
dev
;
int
i
;
systab
=
(
efi_system_table_t
*
)
ia64_boot_param
->
efi_systab
;
if
(
!
systab
)
return
0
;
systab
=
__va
(
systab
);
config_tables
=
(
efi_config_table_t
*
)
systab
->
tables
;
if
(
!
config_tables
)
return
0
;
config_tables
=
__va
(
config_tables
);
for
(
i
=
0
;
i
<
systab
->
nr_tables
;
i
++
)
{
if
(
efi_guidcmp
(
config_tables
[
i
].
guid
,
HCDP_TABLE_GUID
)
==
0
)
{
hcdp
=
(
hcdp_t
*
)
config_tables
[
i
].
table
;
break
;
}
}
if
(
!
hcdp
)
return
0
;
hcdp
=
__va
(
hcdp
);
for
(
i
=
0
,
dev
=
hcdp
->
hcdp_dev
;
i
<
hcdp
->
num_entries
;
i
++
,
dev
++
)
{
if
(
dev
->
type
==
HCDP_DEV_CONSOLE
)
{
addr
=
(
u64
)
dev
->
base_addr
.
addrhi
<<
32
|
dev
->
base_addr
.
addrlo
;
break
;
}
}
return
addr
;
}
#endif
/* CONFIG_IA64_EARLY_PRINTK_UART */
drivers/serial/8250_hcdp.h
0 → 100644
View file @
8ec5a566
/*
* drivers/serial/8250_hcdp.h
*
* Copyright (C) 2002 Hewlett-Packard Co.
* Khalid Aziz <khalid_aziz@hp.com>
*
* Definitions for HCDP defined serial ports (Serial console and debug
* ports)
*/
/* ACPI table signatures */
#define HCDP_SIG_LEN 4
#define HCDP_SIGNATURE "HCDP"
/* Space ID as defined in ACPI generic address structure */
#define ACPI_MEM_SPACE 0
#define ACPI_IO_SPACE 1
#define ACPI_PCICONF_SPACE 2
/*
* Maximum number of HCDP devices we want to read in
*/
#define MAX_HCDP_DEVICES 6
/*
* Default UART clock rate if clock rate is 0 in HCDP table.
*/
#define DEFAULT_UARTCLK 115200
/*
* ACPI Generic Address Structure
*/
typedef
struct
{
u8
space_id
;
u8
bit_width
;
u8
bit_offset
;
u8
resv
;
u32
addrlo
;
u32
addrhi
;
}
acpi_gen_addr
;
/* HCDP Device descriptor entry types */
#define HCDP_DEV_CONSOLE 0
#define HCDP_DEV_DEBUG 1
/* HCDP Device descriptor type */
typedef
struct
{
u8
type
;
u8
bits
;
u8
parity
;
u8
stop_bits
;
u8
pci_seg
;
u8
pci_bus
;
u8
pci_dev
;
u8
pci_func
;
u64
baud
;
acpi_gen_addr
base_addr
;
u16
pci_dev_id
;
u16
pci_vendor_id
;
u32
global_int
;
u32
clock_rate
;
u8
pci_prog_intfc
;
u8
resv
;
}
hcdp_dev_t
;
/* HCDP Table format */
typedef
struct
{
u8
signature
[
4
];
u32
len
;
u8
rev
;
u8
chksum
;
u8
oemid
[
6
];
u8
oem_tabid
[
8
];
u32
oem_rev
;
u8
creator_id
[
4
];
u32
creator_rev
;
u32
num_entries
;
hcdp_dev_t
hcdp_dev
[
MAX_HCDP_DEVICES
];
}
hcdp_t
;
drivers/serial/Kconfig
View file @
8ec5a566
...
...
@@ -77,6 +77,15 @@ config SERIAL_8250_CS
a module, say M here and read <file:Documentation/modules.txt>.
If unsure, say N.
config SERIAL_HCDP
bool "8250/16550 device discovery support via EFI HCDP table"
depends on IA64
---help---
If you wish to make the serial console port described by the EFI
HCDP table available for use as serial console or general
purpose port, say Y here. See
<http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf>.
config SERIAL_8250_EXTENDED
bool "Extended 8250/16550 serial driver options"
depends on SERIAL_8250
...
...
drivers/serial/Makefile
View file @
8ec5a566
...
...
@@ -8,6 +8,9 @@ serial-8250-y :=
serial-8250-$(CONFIG_GSC)
+=
8250_gsc.o
serial-8250-$(CONFIG_PCI)
+=
8250_pci.o
serial-8250-$(CONFIG_PNP)
+=
8250_pnp.o
serial-8250-$(CONFIG_ACPI)
+=
acpi.o
serial-8250-$(CONFIG_SERIAL_HCDP)
+=
8250_hcdp.o
obj-$(CONFIG_SERIAL_CORE)
+=
core.o
obj-$(CONFIG_SERIAL_21285)
+=
21285.o
obj-$(CONFIG_SERIAL_8250)
+=
8250.o
$
(
serial-8250-y
)
...
...
include/linux/acpi_serial.h
View file @
8ec5a566
...
...
@@ -9,6 +9,8 @@
*
*/
#include <linux/serial.h>
extern
void
setup_serial_acpi
(
void
*
);
#define ACPI_SIG_LEN 4
...
...
include/linux/serial.h
View file @
8ec5a566
...
...
@@ -180,14 +180,9 @@ struct serial_icounter_struct {
extern
int
register_serial
(
struct
serial_struct
*
req
);
extern
void
unregister_serial
(
int
line
);
/* Allow complicated architectures to specify rs_table[] at run time */
extern
int
early_serial_setup
(
struct
serial_struct
*
req
);
#ifdef CONFIG_ACPI
/* tty ports reserved for the ACPI serial console port and debug port */
#define ACPI_SERIAL_CONSOLE_PORT 4
#define ACPI_SERIAL_DEBUG_PORT 5
#endif
/* Allow architectures to override entries in serial8250_ports[] at run time: */
struct
uart_port
;
/* forward declaration */
extern
int
early_serial_setup
(
struct
uart_port
*
port
);
#endif
/* __KERNEL__ */
#endif
/* _LINUX_SERIAL_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment