Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
Commits
975f957d
Commit
975f957d
authored
Aug 29, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge HEAD from master.kernel.org:/home/rmk/linux-2.6-serial.git
parents
2321fbd2
661299d9
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
380 additions
and
512 deletions
+380
-512
drivers/parport/parport_serial.c
drivers/parport/parport_serial.c
+166
-173
drivers/serial/8250_pci.c
drivers/serial/8250_pci.c
+177
-297
include/linux/8250_pci.h
include/linux/8250_pci.h
+37
-2
include/linux/serialP.h
include/linux/serialP.h
+0
-40
No files found.
drivers/parport/parport_serial.c
View file @
975f957d
...
@@ -23,13 +23,8 @@
...
@@ -23,13 +23,8 @@
#include <linux/pci.h>
#include <linux/pci.h>
#include <linux/parport.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#include <linux/parport_pc.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/list.h>
#include <linux/8250_pci.h>
#include <linux/8250_pci.h>
#include <asm/serial.h>
enum
parport_pc_pci_cards
{
enum
parport_pc_pci_cards
{
titan_110l
=
0
,
titan_110l
=
0
,
titan_210l
,
titan_210l
,
...
@@ -168,182 +163,147 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
...
@@ -168,182 +163,147 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
};
};
MODULE_DEVICE_TABLE
(
pci
,
parport_serial_pci_tbl
);
MODULE_DEVICE_TABLE
(
pci
,
parport_serial_pci_tbl
);
struct
pci_board_no_ids
{
/*
int
flags
;
* This table describes the serial "geometry" of these boards. Any
int
num_ports
;
* quirks for these can be found in drivers/serial/8250_pci.c
int
base_baud
;
*
int
uart_offset
;
* Cards not tested are marked n/t
int
reg_shift
;
* If you have one of these cards and it works for you, please tell me..
int
(
*
init_fn
)(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
int
enable
);
int
first_uart_offset
;
};
static
int
__devinit
siig10x_init_fn
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
int
enable
)
{
return
pci_siig10x_fn
(
dev
,
enable
);
}
static
int
__devinit
siig20x_init_fn
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
int
enable
)
{
return
pci_siig20x_fn
(
dev
,
enable
);
}
static
int
__devinit
netmos_serial_init
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
int
enable
)
{
board
->
num_ports
=
dev
->
subsystem_device
&
0xf
;
return
0
;
}
static
struct
pci_board_no_ids
pci_boards
[]
__devinitdata
=
{
/*
* PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
* Offset to get to next UART's registers,
* Register shift to use for memory-mapped I/O,
* Initialization function, first UART offset
*/
*/
static
struct
pciserial_board
pci_parport_serial_boards
[]
__devinitdata
=
{
// Cards not tested are marked n/t
[
titan_110l
]
=
{
// If you have one of these cards and it works for you, please tell me..
.
flags
=
FL_BASE1
|
FL_BASE_BARS
,
.
num_ports
=
1
,
/* titan_110l */
{
SPCI_FL_BASE1
|
SPCI_FL_BASE_TABLE
,
1
,
921600
},
.
base_baud
=
921600
,
/* titan_210l */
{
SPCI_FL_BASE1
|
SPCI_FL_BASE_TABLE
,
2
,
921600
},
.
uart_offset
=
8
,
/* netmos_9xx5_combo */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
,
0
,
0
,
netmos_serial_init
},
},
/* netmos_9855 */
{
SPCI_FL_BASE2
|
SPCI_FL_BASE_TABLE
,
1
,
115200
,
0
,
0
,
netmos_serial_init
},
[
titan_210l
]
=
{
/* avlab_1s1p (n/t) */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
flags
=
FL_BASE1
|
FL_BASE_BARS
,
/* avlab_1s1p_650 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
num_ports
=
2
,
/* avlab_1s1p_850 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
base_baud
=
921600
,
/* avlab_1s2p (n/t) */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
uart_offset
=
8
,
/* avlab_1s2p_650 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
},
/* avlab_1s2p_850 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
[
netmos_9xx5_combo
]
=
{
/* avlab_2s1p (n/t) */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
2
,
115200
},
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
/* avlab_2s1p_650 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
2
,
115200
},
.
num_ports
=
1
,
/* avlab_2s1p_850 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
2
,
115200
},
.
base_baud
=
115200
,
/* siig_1s1p_10x */
{
SPCI_FL_BASE2
,
1
,
460800
,
0
,
0
,
siig10x_init_fn
},
.
uart_offset
=
8
,
/* siig_2s1p_10x */
{
SPCI_FL_BASE2
,
1
,
921600
,
0
,
0
,
siig10x_init_fn
},
},
/* siig_2p1s_20x */
{
SPCI_FL_BASE0
,
1
,
921600
,
0
,
0
,
siig20x_init_fn
},
[
netmos_9855
]
=
{
/* siig_1s1p_20x */
{
SPCI_FL_BASE0
,
1
,
921600
,
0
,
0
,
siig20x_init_fn
},
.
flags
=
FL_BASE2
|
FL_BASE_BARS
,
/* siig_2s1p_20x */
{
SPCI_FL_BASE0
,
1
,
921600
,
0
,
0
,
siig20x_init_fn
},
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_1s1p
]
=
{
/* n/t */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_1s1p_650
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_1s1p_850
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_1s2p
]
=
{
/* n/t */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_1s2p_650
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_1s2p_850
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_2s1p
]
=
{
/* n/t */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
2
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_2s1p_650
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
2
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_2s1p_850
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
2
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
siig_1s1p_10x
]
=
{
.
flags
=
FL_BASE2
,
.
num_ports
=
1
,
.
base_baud
=
460800
,
.
uart_offset
=
8
,
},
[
siig_2s1p_10x
]
=
{
.
flags
=
FL_BASE2
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
[
siig_2p1s_20x
]
=
{
.
flags
=
FL_BASE0
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
[
siig_1s1p_20x
]
=
{
.
flags
=
FL_BASE0
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
[
siig_2s1p_20x
]
=
{
.
flags
=
FL_BASE0
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
};
};
struct
parport_serial_private
{
struct
parport_serial_private
{
int
num_ser
;
struct
serial_private
*
serial
;
int
line
[
20
];
struct
pci_board_no_ids
ser
;
int
num_par
;
int
num_par
;
struct
parport
*
port
[
PARPORT_MAX
];
struct
parport
*
port
[
PARPORT_MAX
];
struct
parport_pc_pci
par
;
struct
parport_pc_pci
par
;
};
};
static
int
__devinit
get_pci_port
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
struct
serial_struct
*
req
,
int
idx
)
{
unsigned
long
port
;
int
base_idx
;
int
max_port
;
int
offset
;
base_idx
=
SPCI_FL_GET_BASE
(
board
->
flags
);
if
(
board
->
flags
&
SPCI_FL_BASE_TABLE
)
base_idx
+=
idx
;
if
(
board
->
flags
&
SPCI_FL_REGION_SZ_CAP
)
{
max_port
=
pci_resource_len
(
dev
,
base_idx
)
/
8
;
if
(
idx
>=
max_port
)
return
1
;
}
offset
=
board
->
first_uart_offset
;
/* Timedia/SUNIX uses a mixture of BARs and offsets */
/* Ugh, this is ugly as all hell --- TYT */
if
(
dev
->
vendor
==
PCI_VENDOR_ID_TIMEDIA
)
/* 0x1409 */
switch
(
idx
)
{
case
0
:
base_idx
=
0
;
break
;
case
1
:
base_idx
=
0
;
offset
=
8
;
break
;
case
2
:
base_idx
=
1
;
break
;
case
3
:
base_idx
=
1
;
offset
=
8
;
break
;
case
4
:
/* BAR 2*/
case
5
:
/* BAR 3 */
case
6
:
/* BAR 4*/
case
7
:
base_idx
=
idx
-
2
;
/* BAR 5*/
}
port
=
pci_resource_start
(
dev
,
base_idx
)
+
offset
;
if
((
board
->
flags
&
SPCI_FL_BASE_TABLE
)
==
0
)
port
+=
idx
*
(
board
->
uart_offset
?
board
->
uart_offset
:
8
);
if
(
pci_resource_flags
(
dev
,
base_idx
)
&
IORESOURCE_IO
)
{
int
high_bits_offset
=
((
sizeof
(
long
)
-
sizeof
(
int
))
*
8
);
req
->
port
=
port
;
if
(
high_bits_offset
)
req
->
port_high
=
port
>>
high_bits_offset
;
else
req
->
port_high
=
0
;
return
0
;
}
req
->
io_type
=
SERIAL_IO_MEM
;
req
->
iomem_base
=
ioremap
(
port
,
board
->
uart_offset
);
req
->
iomem_reg_shift
=
board
->
reg_shift
;
req
->
port
=
0
;
return
req
->
iomem_base
?
0
:
1
;
}
/* Register the serial port(s) of a PCI card. */
/* Register the serial port(s) of a PCI card. */
static
int
__devinit
serial_register
(
struct
pci_dev
*
dev
,
static
int
__devinit
serial_register
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
id
)
const
struct
pci_device_id
*
id
)
{
{
struct
pci_board_no_ids
*
board
;
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
struct
serial_struct
serial_req
;
struct
pciserial_board
*
board
;
int
base_baud
;
struct
serial_private
*
serial
;
int
k
;
int
success
=
0
;
priv
->
ser
=
pci_boards
[
id
->
driver_data
];
board
=
&
priv
->
ser
;
if
(
board
->
init_fn
&&
((
board
->
init_fn
)
(
dev
,
board
,
1
)
!=
0
))
return
1
;
base_baud
=
board
->
base_baud
;
board
=
&
pci_parport_serial_boards
[
id
->
driver_data
];
if
(
!
base_baud
)
serial
=
pciserial_init_ports
(
dev
,
board
);
base_baud
=
BASE_BAUD
;
memset
(
&
serial_req
,
0
,
sizeof
(
serial_req
));
for
(
k
=
0
;
k
<
board
->
num_ports
;
k
++
)
{
if
(
IS_ERR
(
serial
))
int
line
;
return
PTR_ERR
(
serial
)
;
if
(
priv
->
num_ser
==
ARRAY_SIZE
(
priv
->
line
))
{
priv
->
serial
=
serial
;
printk
(
KERN_WARNING
return
0
;
"parport_serial: %s: only %u serial lines "
"supported (%d reported)
\n
"
,
pci_name
(
dev
),
ARRAY_SIZE
(
priv
->
line
),
board
->
num_ports
);
break
;
}
serial_req
.
irq
=
dev
->
irq
;
if
(
get_pci_port
(
dev
,
board
,
&
serial_req
,
k
))
break
;
serial_req
.
flags
=
ASYNC_SKIP_TEST
|
ASYNC_AUTOPROBE
;
serial_req
.
baud_base
=
base_baud
;
line
=
register_serial
(
&
serial_req
);
if
(
line
<
0
)
{
printk
(
KERN_DEBUG
"parport_serial: register_serial failed
\n
"
);
continue
;
}
priv
->
line
[
priv
->
num_ser
++
]
=
line
;
success
=
1
;
}
return
success
?
0
:
1
;
}
}
/* Register the parallel port(s) of a PCI card. */
/* Register the parallel port(s) of a PCI card. */
...
@@ -411,7 +371,7 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
...
@@ -411,7 +371,7 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
priv
=
kmalloc
(
sizeof
*
priv
,
GFP_KERNEL
);
priv
=
kmalloc
(
sizeof
*
priv
,
GFP_KERNEL
);
if
(
!
priv
)
if
(
!
priv
)
return
-
ENOMEM
;
return
-
ENOMEM
;
priv
->
num_ser
=
priv
->
num_par
=
0
;
memset
(
priv
,
0
,
sizeof
(
struct
parport_serial_private
))
;
pci_set_drvdata
(
dev
,
priv
);
pci_set_drvdata
(
dev
,
priv
);
err
=
pci_enable_device
(
dev
);
err
=
pci_enable_device
(
dev
);
...
@@ -444,14 +404,11 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
...
@@ -444,14 +404,11 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
int
i
;
int
i
;
// Serial ports
pci_set_drvdata
(
dev
,
NULL
);
for
(
i
=
0
;
i
<
priv
->
num_ser
;
i
++
)
{
unregister_serial
(
priv
->
line
[
i
]);
if
(
priv
->
ser
.
init_fn
)
// Serial ports
(
priv
->
ser
.
init_fn
)
(
dev
,
&
priv
->
ser
,
0
);
if
(
priv
->
serial
)
}
pciserial_remove_ports
(
priv
->
serial
);
pci_set_drvdata
(
dev
,
NULL
);
// Parallel ports
// Parallel ports
for
(
i
=
0
;
i
<
priv
->
num_par
;
i
++
)
for
(
i
=
0
;
i
<
priv
->
num_par
;
i
++
)
...
@@ -461,11 +418,47 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
...
@@ -461,11 +418,47 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
return
;
return
;
}
}
static
int
parport_serial_pci_suspend
(
struct
pci_dev
*
dev
,
pm_message_t
state
)
{
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
if
(
priv
->
serial
)
pciserial_suspend_ports
(
priv
->
serial
);
/* FIXME: What about parport? */
pci_save_state
(
dev
);
pci_set_power_state
(
dev
,
pci_choose_state
(
dev
,
state
));
return
0
;
}
static
int
parport_serial_pci_resume
(
struct
pci_dev
*
dev
)
{
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
pci_set_power_state
(
dev
,
PCI_D0
);
pci_restore_state
(
dev
);
/*
* The device may have been disabled. Re-enable it.
*/
pci_enable_device
(
dev
);
if
(
priv
->
serial
)
pciserial_resume_ports
(
priv
->
serial
);
/* FIXME: What about parport? */
return
0
;
}
static
struct
pci_driver
parport_serial_pci_driver
=
{
static
struct
pci_driver
parport_serial_pci_driver
=
{
.
name
=
"parport_serial"
,
.
name
=
"parport_serial"
,
.
id_table
=
parport_serial_pci_tbl
,
.
id_table
=
parport_serial_pci_tbl
,
.
probe
=
parport_serial_pci_probe
,
.
probe
=
parport_serial_pci_probe
,
.
remove
=
__devexit_p
(
parport_serial_pci_remove
),
.
remove
=
__devexit_p
(
parport_serial_pci_remove
),
.
suspend
=
parport_serial_pci_suspend
,
.
resume
=
parport_serial_pci_resume
,
};
};
...
...
drivers/serial/8250_pci.c
View file @
975f957d
...
@@ -33,36 +33,6 @@
...
@@ -33,36 +33,6 @@
#undef SERIAL_DEBUG_PCI
#undef SERIAL_DEBUG_PCI
/*
* Definitions for PCI support.
*/
#define FL_BASE_MASK 0x0007
#define FL_BASE0 0x0000
#define FL_BASE1 0x0001
#define FL_BASE2 0x0002
#define FL_BASE3 0x0003
#define FL_BASE4 0x0004
#define FL_GET_BASE(x) (x & FL_BASE_MASK)
/* Use successive BARs (PCI base address registers),
else use offset into some specified BAR */
#define FL_BASE_BARS 0x0008
/* do not assign an irq */
#define FL_NOIRQ 0x0080
/* Use the Base address register size to cap number of ports */
#define FL_REGION_SZ_CAP 0x0100
struct
pci_board
{
unsigned
int
flags
;
unsigned
int
num_ports
;
unsigned
int
base_baud
;
unsigned
int
uart_offset
;
unsigned
int
reg_shift
;
unsigned
int
first_offset
;
};
/*
/*
* init function returns:
* init function returns:
* > 0 - number of ports
* > 0 - number of ports
...
@@ -75,14 +45,15 @@ struct pci_serial_quirk {
...
@@ -75,14 +45,15 @@ struct pci_serial_quirk {
u32
subvendor
;
u32
subvendor
;
u32
subdevice
;
u32
subdevice
;
int
(
*
init
)(
struct
pci_dev
*
dev
);
int
(
*
init
)(
struct
pci_dev
*
dev
);
int
(
*
setup
)(
struct
pci_dev
*
dev
,
struct
pci_board
*
board
,
int
(
*
setup
)(
struct
serial_private
*
,
struct
pciserial_board
*
,
struct
uart_port
*
port
,
int
idx
);
struct
uart_port
*
,
int
);
void
(
*
exit
)(
struct
pci_dev
*
dev
);
void
(
*
exit
)(
struct
pci_dev
*
dev
);
};
};
#define PCI_NUM_BAR_RESOURCES 6
#define PCI_NUM_BAR_RESOURCES 6
struct
serial_private
{
struct
serial_private
{
struct
pci_dev
*
dev
;
unsigned
int
nr
;
unsigned
int
nr
;
void
__iomem
*
remapped_bar
[
PCI_NUM_BAR_RESOURCES
];
void
__iomem
*
remapped_bar
[
PCI_NUM_BAR_RESOURCES
];
struct
pci_serial_quirk
*
quirk
;
struct
pci_serial_quirk
*
quirk
;
...
@@ -101,17 +72,18 @@ static void moan_device(const char *str, struct pci_dev *dev)
...
@@ -101,17 +72,18 @@ static void moan_device(const char *str, struct pci_dev *dev)
}
}
static
int
static
int
setup_port
(
struct
pci_dev
*
de
v
,
struct
uart_port
*
port
,
setup_port
(
struct
serial_private
*
pri
v
,
struct
uart_port
*
port
,
int
bar
,
int
offset
,
int
regshift
)
int
bar
,
int
offset
,
int
regshift
)
{
{
struct
serial_private
*
priv
=
pci_get_drvdata
(
dev
)
;
struct
pci_dev
*
dev
=
priv
->
dev
;
unsigned
long
base
,
len
;
unsigned
long
base
,
len
;
if
(
bar
>=
PCI_NUM_BAR_RESOURCES
)
if
(
bar
>=
PCI_NUM_BAR_RESOURCES
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
pci_resource_flags
(
dev
,
bar
)
&
IORESOURCE_MEM
)
{
base
=
pci_resource_start
(
dev
,
bar
);
base
=
pci_resource_start
(
dev
,
bar
);
if
(
pci_resource_flags
(
dev
,
bar
)
&
IORESOURCE_MEM
)
{
len
=
pci_resource_len
(
dev
,
bar
);
len
=
pci_resource_len
(
dev
,
bar
);
if
(
!
priv
->
remapped_bar
[
bar
])
if
(
!
priv
->
remapped_bar
[
bar
])
...
@@ -120,13 +92,16 @@ setup_port(struct pci_dev *dev, struct uart_port *port,
...
@@ -120,13 +92,16 @@ setup_port(struct pci_dev *dev, struct uart_port *port,
return
-
ENOMEM
;
return
-
ENOMEM
;
port
->
iotype
=
UPIO_MEM
;
port
->
iotype
=
UPIO_MEM
;
port
->
iobase
=
0
;
port
->
mapbase
=
base
+
offset
;
port
->
mapbase
=
base
+
offset
;
port
->
membase
=
priv
->
remapped_bar
[
bar
]
+
offset
;
port
->
membase
=
priv
->
remapped_bar
[
bar
]
+
offset
;
port
->
regshift
=
regshift
;
port
->
regshift
=
regshift
;
}
else
{
}
else
{
base
=
pci_resource_start
(
dev
,
bar
)
+
offset
;
port
->
iotype
=
UPIO_PORT
;
port
->
iotype
=
UPIO_PORT
;
port
->
iobase
=
base
;
port
->
iobase
=
base
+
offset
;
port
->
mapbase
=
0
;
port
->
membase
=
NULL
;
port
->
regshift
=
0
;
}
}
return
0
;
return
0
;
}
}
...
@@ -136,7 +111,7 @@ setup_port(struct pci_dev *dev, struct uart_port *port,
...
@@ -136,7 +111,7 @@ setup_port(struct pci_dev *dev, struct uart_port *port,
* Not that ugly ;) -- HW
* Not that ugly ;) -- HW
*/
*/
static
int
static
int
afavlab_setup
(
struct
pci_dev
*
dev
,
struct
pci
_board
*
board
,
afavlab_setup
(
struct
serial_private
*
priv
,
struct
pciserial
_board
*
board
,
struct
uart_port
*
port
,
int
idx
)
struct
uart_port
*
port
,
int
idx
)
{
{
unsigned
int
bar
,
offset
=
board
->
first_offset
;
unsigned
int
bar
,
offset
=
board
->
first_offset
;
...
@@ -149,7 +124,7 @@ afavlab_setup(struct pci_dev *dev, struct pci_board *board,
...
@@ -149,7 +124,7 @@ afavlab_setup(struct pci_dev *dev, struct pci_board *board,
offset
+=
(
idx
-
4
)
*
board
->
uart_offset
;
offset
+=
(
idx
-
4
)
*
board
->
uart_offset
;
}
}
return
setup_port
(
de
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
return
setup_port
(
pri
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
}
}
/*
/*
...
@@ -189,13 +164,13 @@ static int __devinit pci_hp_diva_init(struct pci_dev *dev)
...
@@ -189,13 +164,13 @@ static int __devinit pci_hp_diva_init(struct pci_dev *dev)
* some serial ports are supposed to be hidden on certain models.
* some serial ports are supposed to be hidden on certain models.
*/
*/
static
int
static
int
pci_hp_diva_setup
(
struct
pci_dev
*
dev
,
struct
pci
_board
*
board
,
pci_hp_diva_setup
(
struct
serial_private
*
priv
,
struct
pciserial
_board
*
board
,
struct
uart_port
*
port
,
int
idx
)
struct
uart_port
*
port
,
int
idx
)
{
{
unsigned
int
offset
=
board
->
first_offset
;
unsigned
int
offset
=
board
->
first_offset
;
unsigned
int
bar
=
FL_GET_BASE
(
board
->
flags
);
unsigned
int
bar
=
FL_GET_BASE
(
board
->
flags
);
switch
(
dev
->
subsystem_device
)
{
switch
(
priv
->
dev
->
subsystem_device
)
{
case
PCI_DEVICE_ID_HP_DIVA_MAESTRO
:
case
PCI_DEVICE_ID_HP_DIVA_MAESTRO
:
if
(
idx
==
3
)
if
(
idx
==
3
)
idx
++
;
idx
++
;
...
@@ -212,7 +187,7 @@ pci_hp_diva_setup(struct pci_dev *dev, struct pci_board *board,
...
@@ -212,7 +187,7 @@ pci_hp_diva_setup(struct pci_dev *dev, struct pci_board *board,
offset
+=
idx
*
board
->
uart_offset
;
offset
+=
idx
*
board
->
uart_offset
;
return
setup_port
(
de
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
return
setup_port
(
pri
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
}
}
/*
/*
...
@@ -307,7 +282,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev)
...
@@ -307,7 +282,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev)
/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
static
int
static
int
sbs_setup
(
struct
pci_dev
*
dev
,
struct
pci
_board
*
board
,
sbs_setup
(
struct
serial_private
*
priv
,
struct
pciserial
_board
*
board
,
struct
uart_port
*
port
,
int
idx
)
struct
uart_port
*
port
,
int
idx
)
{
{
unsigned
int
bar
,
offset
=
board
->
first_offset
;
unsigned
int
bar
,
offset
=
board
->
first_offset
;
...
@@ -323,7 +298,7 @@ sbs_setup(struct pci_dev *dev, struct pci_board *board,
...
@@ -323,7 +298,7 @@ sbs_setup(struct pci_dev *dev, struct pci_board *board,
}
else
/* we have only 8 ports on PMC-OCTALPRO */
}
else
/* we have only 8 ports on PMC-OCTALPRO */
return
1
;
return
1
;
return
setup_port
(
de
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
return
setup_port
(
pri
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
}
}
/*
/*
...
@@ -389,6 +364,9 @@ static void __devexit sbs_exit(struct pci_dev *dev)
...
@@ -389,6 +364,9 @@ static void __devexit sbs_exit(struct pci_dev *dev)
* - 10x cards have control registers in IO and/or memory space;
* - 10x cards have control registers in IO and/or memory space;
* - 20x cards have control registers in standard PCI configuration space.
* - 20x cards have control registers in standard PCI configuration space.
*
*
* Note: all 10x cards have PCI device ids 0x10..
* all 20x cards have PCI device ids 0x20..
*
* There are also Quartet Serial cards which use Oxford Semiconductor
* There are also Quartet Serial cards which use Oxford Semiconductor
* 16954 quad UART PCI chip clocked by 18.432 MHz quartz.
* 16954 quad UART PCI chip clocked by 18.432 MHz quartz.
*
*
...
@@ -445,24 +423,18 @@ static int pci_siig20x_init(struct pci_dev *dev)
...
@@ -445,24 +423,18 @@ static int pci_siig20x_init(struct pci_dev *dev)
return
0
;
return
0
;
}
}
int
pci_siig10x_fn
(
struct
pci_dev
*
dev
,
int
enable
)
static
int
pci_siig_init
(
struct
pci_dev
*
dev
)
{
{
int
ret
=
0
;
unsigned
int
type
=
dev
->
device
&
0xff00
;
if
(
enable
)
ret
=
pci_siig10x_init
(
dev
);
return
ret
;
}
int
pci_siig20x_fn
(
struct
pci_dev
*
dev
,
int
enable
)
if
(
type
==
0x1000
)
{
return
pci_siig10x_init
(
dev
);
int
ret
=
0
;
else
if
(
type
==
0x2000
)
if
(
enable
)
return
pci_siig20x_init
(
dev
);
ret
=
pci_siig20x_init
(
dev
);
return
ret
;
}
EXPORT_SYMBOL
(
pci_siig10x_fn
);
moan_device
(
"Unknown SIIG card"
,
dev
);
EXPORT_SYMBOL
(
pci_siig20x_fn
);
return
-
ENODEV
;
}
/*
/*
* Timedia has an explosion of boards, and to avoid the PCI table from
* Timedia has an explosion of boards, and to avoid the PCI table from
...
@@ -523,7 +495,7 @@ static int __devinit pci_timedia_init(struct pci_dev *dev)
...
@@ -523,7 +495,7 @@ static int __devinit pci_timedia_init(struct pci_dev *dev)
* Ugh, this is ugly as all hell --- TYT
* Ugh, this is ugly as all hell --- TYT
*/
*/
static
int
static
int
pci_timedia_setup
(
struct
pci_dev
*
dev
,
struct
pci
_board
*
board
,
pci_timedia_setup
(
struct
serial_private
*
priv
,
struct
pciserial
_board
*
board
,
struct
uart_port
*
port
,
int
idx
)
struct
uart_port
*
port
,
int
idx
)
{
{
unsigned
int
bar
=
0
,
offset
=
board
->
first_offset
;
unsigned
int
bar
=
0
,
offset
=
board
->
first_offset
;
...
@@ -549,14 +521,15 @@ pci_timedia_setup(struct pci_dev *dev, struct pci_board *board,
...
@@ -549,14 +521,15 @@ pci_timedia_setup(struct pci_dev *dev, struct pci_board *board,
bar
=
idx
-
2
;
bar
=
idx
-
2
;
}
}
return
setup_port
(
de
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
return
setup_port
(
pri
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
}
}
/*
/*
* Some Titan cards are also a little weird
* Some Titan cards are also a little weird
*/
*/
static
int
static
int
titan_400l_800l_setup
(
struct
pci_dev
*
dev
,
struct
pci_board
*
board
,
titan_400l_800l_setup
(
struct
serial_private
*
priv
,
struct
pciserial_board
*
board
,
struct
uart_port
*
port
,
int
idx
)
struct
uart_port
*
port
,
int
idx
)
{
{
unsigned
int
bar
,
offset
=
board
->
first_offset
;
unsigned
int
bar
,
offset
=
board
->
first_offset
;
...
@@ -573,7 +546,7 @@ titan_400l_800l_setup(struct pci_dev *dev, struct pci_board *board,
...
@@ -573,7 +546,7 @@ titan_400l_800l_setup(struct pci_dev *dev, struct pci_board *board,
offset
=
(
idx
-
2
)
*
board
->
uart_offset
;
offset
=
(
idx
-
2
)
*
board
->
uart_offset
;
}
}
return
setup_port
(
de
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
return
setup_port
(
pri
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
}
}
static
int
__devinit
pci_xircom_init
(
struct
pci_dev
*
dev
)
static
int
__devinit
pci_xircom_init
(
struct
pci_dev
*
dev
)
...
@@ -593,7 +566,7 @@ static int __devinit pci_netmos_init(struct pci_dev *dev)
...
@@ -593,7 +566,7 @@ static int __devinit pci_netmos_init(struct pci_dev *dev)
}
}
static
int
static
int
pci_default_setup
(
struct
pci_dev
*
dev
,
struct
pci
_board
*
board
,
pci_default_setup
(
struct
serial_private
*
priv
,
struct
pciserial
_board
*
board
,
struct
uart_port
*
port
,
int
idx
)
struct
uart_port
*
port
,
int
idx
)
{
{
unsigned
int
bar
,
offset
=
board
->
first_offset
,
maxnr
;
unsigned
int
bar
,
offset
=
board
->
first_offset
,
maxnr
;
...
@@ -604,13 +577,13 @@ pci_default_setup(struct pci_dev *dev, struct pci_board *board,
...
@@ -604,13 +577,13 @@ pci_default_setup(struct pci_dev *dev, struct pci_board *board,
else
else
offset
+=
idx
*
board
->
uart_offset
;
offset
+=
idx
*
board
->
uart_offset
;
maxnr
=
(
pci_resource_len
(
dev
,
bar
)
-
board
->
first_offset
)
/
maxnr
=
(
pci_resource_len
(
priv
->
dev
,
bar
)
-
board
->
first_offset
)
/
(
8
<<
board
->
reg_shift
);
(
8
<<
board
->
reg_shift
);
if
(
board
->
flags
&
FL_REGION_SZ_CAP
&&
idx
>=
maxnr
)
if
(
board
->
flags
&
FL_REGION_SZ_CAP
&&
idx
>=
maxnr
)
return
1
;
return
1
;
return
setup_port
(
de
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
return
setup_port
(
pri
v
,
port
,
bar
,
offset
,
board
->
reg_shift
);
}
}
/* This should be in linux/pci_ids.h */
/* This should be in linux/pci_ids.h */
...
@@ -754,152 +727,15 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
...
@@ -754,152 +727,15 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
.
setup
=
sbs_setup
,
.
setup
=
sbs_setup
,
.
exit
=
__devexit_p
(
sbs_exit
),
.
exit
=
__devexit_p
(
sbs_exit
),
},
},
/*
/*
* SIIG cards.
* SIIG cards.
* It is not clear whether these could be collapsed.
*/
*/
{
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_1S_10x_550
,
.
device
=
PCI_ANY_ID
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_1S_10x_650
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_1S_10x_850
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_2S_10x_550
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_2S_10x_650
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_2S_10x_850
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_4S_10x_550
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_4S_10x_650
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_4S_10x_850
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig10x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_1S_20x_550
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_1S_20x_650
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_1S_20x_850
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_2S_20x_550
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_2S_20x_650
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_2S_20x_850
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_4S_20x_550
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_4S_20x_650
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig20x_init
,
.
setup
=
pci_default_setup
,
},
{
.
vendor
=
PCI_VENDOR_ID_SIIG
,
.
device
=
PCI_DEVICE_ID_SIIG_4S_20x_850
,
.
subvendor
=
PCI_ANY_ID
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
.
init
=
pci_siig
20x
_init
,
.
init
=
pci_siig_init
,
.
setup
=
pci_default_setup
,
.
setup
=
pci_default_setup
,
},
},
/*
/*
...
@@ -990,7 +826,7 @@ static struct pci_serial_quirk *find_quirk(struct pci_dev *dev)
...
@@ -990,7 +826,7 @@ static struct pci_serial_quirk *find_quirk(struct pci_dev *dev)
}
}
static
_INLINE_
int
static
_INLINE_
int
get_pci_irq
(
struct
pci_dev
*
dev
,
struct
pci
_board
*
board
,
int
idx
)
get_pci_irq
(
struct
pci_dev
*
dev
,
struct
pci
serial_board
*
board
)
{
{
if
(
board
->
flags
&
FL_NOIRQ
)
if
(
board
->
flags
&
FL_NOIRQ
)
return
0
;
return
0
;
...
@@ -1115,7 +951,7 @@ enum pci_board_num_t {
...
@@ -1115,7 +951,7 @@ enum pci_board_num_t {
* see first lines of serial_in() and serial_out() in 8250.c
* see first lines of serial_in() and serial_out() in 8250.c
*/
*/
static
struct
pci_board
pci_boards
[]
__devinitdata
=
{
static
struct
pci
serial
_board
pci_boards
[]
__devinitdata
=
{
[
pbn_default
]
=
{
[
pbn_default
]
=
{
.
flags
=
FL_BASE0
,
.
flags
=
FL_BASE0
,
.
num_ports
=
1
,
.
num_ports
=
1
,
...
@@ -1575,7 +1411,7 @@ static struct pci_board pci_boards[] __devinitdata = {
...
@@ -1575,7 +1411,7 @@ static struct pci_board pci_boards[] __devinitdata = {
* serial specs. Returns 0 on success, 1 on failure.
* serial specs. Returns 0 on success, 1 on failure.
*/
*/
static
int
__devinit
static
int
__devinit
serial_pci_guess_board
(
struct
pci_dev
*
dev
,
struct
pci_board
*
board
)
serial_pci_guess_board
(
struct
pci_dev
*
dev
,
struct
pci
serial
_board
*
board
)
{
{
int
num_iomem
,
num_port
,
first_port
=
-
1
,
i
;
int
num_iomem
,
num_port
,
first_port
=
-
1
,
i
;
...
@@ -1640,7 +1476,8 @@ serial_pci_guess_board(struct pci_dev *dev, struct pci_board *board)
...
@@ -1640,7 +1476,8 @@ serial_pci_guess_board(struct pci_dev *dev, struct pci_board *board)
}
}
static
inline
int
static
inline
int
serial_pci_matches
(
struct
pci_board
*
board
,
struct
pci_board
*
guessed
)
serial_pci_matches
(
struct
pciserial_board
*
board
,
struct
pciserial_board
*
guessed
)
{
{
return
return
board
->
num_ports
==
guessed
->
num_ports
&&
board
->
num_ports
==
guessed
->
num_ports
&&
...
@@ -1650,58 +1487,14 @@ serial_pci_matches(struct pci_board *board, struct pci_board *guessed)
...
@@ -1650,58 +1487,14 @@ serial_pci_matches(struct pci_board *board, struct pci_board *guessed)
board
->
first_offset
==
guessed
->
first_offset
;
board
->
first_offset
==
guessed
->
first_offset
;
}
}
/*
struct
serial_private
*
* Probe one serial board. Unfortunately, there is no rhyme nor reason
pciserial_init_ports
(
struct
pci_dev
*
dev
,
struct
pciserial_board
*
board
)
* to the arrangement of serial ports on a PCI card.
*/
static
int
__devinit
pciserial_init_one
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
ent
)
{
{
struct
uart_port
serial_port
;
struct
serial_private
*
priv
;
struct
serial_private
*
priv
;
struct
pci_board
*
board
,
tmp
;
struct
pci_serial_quirk
*
quirk
;
struct
pci_serial_quirk
*
quirk
;
int
rc
,
nr_ports
,
i
;
int
rc
,
nr_ports
,
i
;
if
(
ent
->
driver_data
>=
ARRAY_SIZE
(
pci_boards
))
{
printk
(
KERN_ERR
"pci_init_one: invalid driver_data: %ld
\n
"
,
ent
->
driver_data
);
return
-
EINVAL
;
}
board
=
&
pci_boards
[
ent
->
driver_data
];
rc
=
pci_enable_device
(
dev
);
if
(
rc
)
return
rc
;
if
(
ent
->
driver_data
==
pbn_default
)
{
/*
* Use a copy of the pci_board entry for this;
* avoid changing entries in the table.
*/
memcpy
(
&
tmp
,
board
,
sizeof
(
struct
pci_board
));
board
=
&
tmp
;
/*
* We matched one of our class entries. Try to
* determine the parameters of this board.
*/
rc
=
serial_pci_guess_board
(
dev
,
board
);
if
(
rc
)
goto
disable
;
}
else
{
/*
* We matched an explicit entry. If we are able to
* detect this boards settings with our heuristic,
* then we no longer need this entry.
*/
memcpy
(
&
tmp
,
&
pci_boards
[
pbn_default
],
sizeof
(
struct
pci_board
));
rc
=
serial_pci_guess_board
(
dev
,
&
tmp
);
if
(
rc
==
0
&&
serial_pci_matches
(
board
,
&
tmp
))
moan_device
(
"Redundant entry in serial pci_table."
,
dev
);
}
nr_ports
=
board
->
num_ports
;
nr_ports
=
board
->
num_ports
;
/*
/*
...
@@ -1718,8 +1511,10 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
...
@@ -1718,8 +1511,10 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
*/
*/
if
(
quirk
->
init
)
{
if
(
quirk
->
init
)
{
rc
=
quirk
->
init
(
dev
);
rc
=
quirk
->
init
(
dev
);
if
(
rc
<
0
)
if
(
rc
<
0
)
{
goto
disable
;
priv
=
ERR_PTR
(
rc
);
goto
err_out
;
}
if
(
rc
)
if
(
rc
)
nr_ports
=
rc
;
nr_ports
=
rc
;
}
}
...
@@ -1728,27 +1523,26 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
...
@@ -1728,27 +1523,26 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
sizeof
(
unsigned
int
)
*
nr_ports
,
sizeof
(
unsigned
int
)
*
nr_ports
,
GFP_KERNEL
);
GFP_KERNEL
);
if
(
!
priv
)
{
if
(
!
priv
)
{
rc
=
-
ENOMEM
;
priv
=
ERR_PTR
(
-
ENOMEM
)
;
goto
deinit
;
goto
err_
deinit
;
}
}
memset
(
priv
,
0
,
sizeof
(
struct
serial_private
)
+
memset
(
priv
,
0
,
sizeof
(
struct
serial_private
)
+
sizeof
(
unsigned
int
)
*
nr_ports
);
sizeof
(
unsigned
int
)
*
nr_ports
);
priv
->
dev
=
dev
;
priv
->
quirk
=
quirk
;
priv
->
quirk
=
quirk
;
pci_set_drvdata
(
dev
,
priv
);
for
(
i
=
0
;
i
<
nr_ports
;
i
++
)
{
struct
uart_port
serial_port
;
memset
(
&
serial_port
,
0
,
sizeof
(
struct
uart_port
));
memset
(
&
serial_port
,
0
,
sizeof
(
struct
uart_port
));
serial_port
.
flags
=
UPF_SKIP_TEST
|
UPF_BOOT_AUTOCONF
|
UPF_SHARE_IRQ
;
serial_port
.
flags
=
UPF_SKIP_TEST
|
UPF_BOOT_AUTOCONF
|
UPF_SHARE_IRQ
;
serial_port
.
uartclk
=
board
->
base_baud
*
16
;
serial_port
.
uartclk
=
board
->
base_baud
*
16
;
serial_port
.
irq
=
get_pci_irq
(
dev
,
board
,
i
);
serial_port
.
irq
=
get_pci_irq
(
dev
,
board
);
serial_port
.
dev
=
&
dev
->
dev
;
serial_port
.
dev
=
&
dev
->
dev
;
if
(
quirk
->
setup
(
dev
,
board
,
&
serial_port
,
i
))
for
(
i
=
0
;
i
<
nr_ports
;
i
++
)
{
if
(
quirk
->
setup
(
priv
,
board
,
&
serial_port
,
i
))
break
;
break
;
#ifdef SERIAL_DEBUG_PCI
#ifdef SERIAL_DEBUG_PCI
printk
(
"Setup PCI port: port %x, irq %d, type %d
\n
"
,
printk
(
"Setup PCI port: port %x, irq %d, type %d
\n
"
,
serial_port
.
iobase
,
serial_port
.
irq
,
serial_port
.
iotype
);
serial_port
.
iobase
,
serial_port
.
irq
,
serial_port
.
iotype
);
...
@@ -1763,24 +1557,21 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
...
@@ -1763,24 +1557,21 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
priv
->
nr
=
i
;
priv
->
nr
=
i
;
return
0
;
return
priv
;
deinit:
err_
deinit:
if
(
quirk
->
exit
)
if
(
quirk
->
exit
)
quirk
->
exit
(
dev
);
quirk
->
exit
(
dev
);
disable:
err_out:
pci_disable_device
(
dev
);
return
priv
;
return
rc
;
}
}
EXPORT_SYMBOL_GPL
(
pciserial_init_ports
);
static
void
__devexit
pciserial_remove_one
(
struct
pci_dev
*
de
v
)
void
pciserial_remove_ports
(
struct
serial_private
*
pri
v
)
{
{
struct
serial_private
*
priv
=
pci_get_drvdata
(
dev
);
struct
pci_serial_quirk
*
quirk
;
struct
pci_serial_quirk
*
quirk
;
int
i
;
int
i
;
pci_set_drvdata
(
dev
,
NULL
);
for
(
i
=
0
;
i
<
priv
->
nr
;
i
++
)
for
(
i
=
0
;
i
<
priv
->
nr
;
i
++
)
serial8250_unregister_port
(
priv
->
line
[
i
]);
serial8250_unregister_port
(
priv
->
line
[
i
]);
...
@@ -1793,25 +1584,123 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
...
@@ -1793,25 +1584,123 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
/*
/*
* Find the exit quirks.
* Find the exit quirks.
*/
*/
quirk
=
find_quirk
(
dev
);
quirk
=
find_quirk
(
priv
->
dev
);
if
(
quirk
->
exit
)
if
(
quirk
->
exit
)
quirk
->
exit
(
dev
);
quirk
->
exit
(
priv
->
dev
);
pci_disable_device
(
dev
);
kfree
(
priv
);
kfree
(
priv
);
}
}
EXPORT_SYMBOL_GPL
(
pciserial_remove_ports
);
static
int
pciserial_suspend_one
(
struct
pci_dev
*
dev
,
pm_message_t
state
)
void
pciserial_suspend_ports
(
struct
serial_private
*
priv
)
{
{
struct
serial_private
*
priv
=
pci_get_drvdata
(
dev
);
if
(
priv
)
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
priv
->
nr
;
i
++
)
for
(
i
=
0
;
i
<
priv
->
nr
;
i
++
)
if
(
priv
->
line
[
i
]
>=
0
)
serial8250_suspend_port
(
priv
->
line
[
i
]);
serial8250_suspend_port
(
priv
->
line
[
i
]);
}
EXPORT_SYMBOL_GPL
(
pciserial_suspend_ports
);
void
pciserial_resume_ports
(
struct
serial_private
*
priv
)
{
int
i
;
/*
* Ensure that the board is correctly configured.
*/
if
(
priv
->
quirk
->
init
)
priv
->
quirk
->
init
(
priv
->
dev
);
for
(
i
=
0
;
i
<
priv
->
nr
;
i
++
)
if
(
priv
->
line
[
i
]
>=
0
)
serial8250_resume_port
(
priv
->
line
[
i
]);
}
EXPORT_SYMBOL_GPL
(
pciserial_resume_ports
);
/*
* Probe one serial board. Unfortunately, there is no rhyme nor reason
* to the arrangement of serial ports on a PCI card.
*/
static
int
__devinit
pciserial_init_one
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
ent
)
{
struct
serial_private
*
priv
;
struct
pciserial_board
*
board
,
tmp
;
int
rc
;
if
(
ent
->
driver_data
>=
ARRAY_SIZE
(
pci_boards
))
{
printk
(
KERN_ERR
"pci_init_one: invalid driver_data: %ld
\n
"
,
ent
->
driver_data
);
return
-
EINVAL
;
}
board
=
&
pci_boards
[
ent
->
driver_data
];
rc
=
pci_enable_device
(
dev
);
if
(
rc
)
return
rc
;
if
(
ent
->
driver_data
==
pbn_default
)
{
/*
* Use a copy of the pci_board entry for this;
* avoid changing entries in the table.
*/
memcpy
(
&
tmp
,
board
,
sizeof
(
struct
pciserial_board
));
board
=
&
tmp
;
/*
* We matched one of our class entries. Try to
* determine the parameters of this board.
*/
rc
=
serial_pci_guess_board
(
dev
,
board
);
if
(
rc
)
goto
disable
;
}
else
{
/*
* We matched an explicit entry. If we are able to
* detect this boards settings with our heuristic,
* then we no longer need this entry.
*/
memcpy
(
&
tmp
,
&
pci_boards
[
pbn_default
],
sizeof
(
struct
pciserial_board
));
rc
=
serial_pci_guess_board
(
dev
,
&
tmp
);
if
(
rc
==
0
&&
serial_pci_matches
(
board
,
&
tmp
))
moan_device
(
"Redundant entry in serial pci_table."
,
dev
);
}
}
priv
=
pciserial_init_ports
(
dev
,
board
);
if
(
!
IS_ERR
(
priv
))
{
pci_set_drvdata
(
dev
,
priv
);
return
0
;
}
rc
=
PTR_ERR
(
priv
);
disable:
pci_disable_device
(
dev
);
return
rc
;
}
static
void
__devexit
pciserial_remove_one
(
struct
pci_dev
*
dev
)
{
struct
serial_private
*
priv
=
pci_get_drvdata
(
dev
);
pci_set_drvdata
(
dev
,
NULL
);
pciserial_remove_ports
(
priv
);
pci_disable_device
(
dev
);
}
static
int
pciserial_suspend_one
(
struct
pci_dev
*
dev
,
pm_message_t
state
)
{
struct
serial_private
*
priv
=
pci_get_drvdata
(
dev
);
if
(
priv
)
pciserial_suspend_ports
(
priv
);
pci_save_state
(
dev
);
pci_save_state
(
dev
);
pci_set_power_state
(
dev
,
pci_choose_state
(
dev
,
state
));
pci_set_power_state
(
dev
,
pci_choose_state
(
dev
,
state
));
return
0
;
return
0
;
...
@@ -1825,21 +1714,12 @@ static int pciserial_resume_one(struct pci_dev *dev)
...
@@ -1825,21 +1714,12 @@ static int pciserial_resume_one(struct pci_dev *dev)
pci_restore_state
(
dev
);
pci_restore_state
(
dev
);
if
(
priv
)
{
if
(
priv
)
{
int
i
;
/*
/*
* The device may have been disabled. Re-enable it.
* The device may have been disabled. Re-enable it.
*/
*/
pci_enable_device
(
dev
);
pci_enable_device
(
dev
);
/*
pciserial_resume_ports
(
priv
);
* Ensure that the board is correctly configured.
*/
if
(
priv
->
quirk
->
init
)
priv
->
quirk
->
init
(
dev
);
for
(
i
=
0
;
i
<
priv
->
nr
;
i
++
)
serial8250_resume_port
(
priv
->
line
[
i
]);
}
}
return
0
;
return
0
;
}
}
...
...
include/linux/8250_pci.h
View file @
975f957d
int
pci_siig10x_fn
(
struct
pci_dev
*
dev
,
int
enable
);
/*
int
pci_siig20x_fn
(
struct
pci_dev
*
dev
,
int
enable
);
* Definitions for PCI support.
*/
#define FL_BASE_MASK 0x0007
#define FL_BASE0 0x0000
#define FL_BASE1 0x0001
#define FL_BASE2 0x0002
#define FL_BASE3 0x0003
#define FL_BASE4 0x0004
#define FL_GET_BASE(x) (x & FL_BASE_MASK)
/* Use successive BARs (PCI base address registers),
else use offset into some specified BAR */
#define FL_BASE_BARS 0x0008
/* do not assign an irq */
#define FL_NOIRQ 0x0080
/* Use the Base address register size to cap number of ports */
#define FL_REGION_SZ_CAP 0x0100
struct
pciserial_board
{
unsigned
int
flags
;
unsigned
int
num_ports
;
unsigned
int
base_baud
;
unsigned
int
uart_offset
;
unsigned
int
reg_shift
;
unsigned
int
first_offset
;
};
struct
serial_private
;
struct
serial_private
*
pciserial_init_ports
(
struct
pci_dev
*
dev
,
struct
pciserial_board
*
board
);
void
pciserial_remove_ports
(
struct
serial_private
*
priv
);
void
pciserial_suspend_ports
(
struct
serial_private
*
priv
);
void
pciserial_resume_ports
(
struct
serial_private
*
priv
);
include/linux/serialP.h
View file @
975f957d
...
@@ -140,44 +140,4 @@ struct rs_multiport_struct {
...
@@ -140,44 +140,4 @@ struct rs_multiport_struct {
#define ALPHA_KLUDGE_MCR 0
#define ALPHA_KLUDGE_MCR 0
#endif
#endif
/*
* Definitions for PCI support.
*/
#define SPCI_FL_BASE_MASK 0x0007
#define SPCI_FL_BASE0 0x0000
#define SPCI_FL_BASE1 0x0001
#define SPCI_FL_BASE2 0x0002
#define SPCI_FL_BASE3 0x0003
#define SPCI_FL_BASE4 0x0004
#define SPCI_FL_GET_BASE(x) (x & SPCI_FL_BASE_MASK)
#define SPCI_FL_IRQ_MASK (0x0007 << 4)
#define SPCI_FL_IRQBASE0 (0x0000 << 4)
#define SPCI_FL_IRQBASE1 (0x0001 << 4)
#define SPCI_FL_IRQBASE2 (0x0002 << 4)
#define SPCI_FL_IRQBASE3 (0x0003 << 4)
#define SPCI_FL_IRQBASE4 (0x0004 << 4)
#define SPCI_FL_GET_IRQBASE(x) ((x & SPCI_FL_IRQ_MASK) >> 4)
/* Use successive BARs (PCI base address registers),
else use offset into some specified BAR */
#define SPCI_FL_BASE_TABLE 0x0100
/* Use successive entries in the irq resource table */
#define SPCI_FL_IRQ_TABLE 0x0200
/* Use the irq resource table instead of dev->irq */
#define SPCI_FL_IRQRESOURCE 0x0400
/* Use the Base address register size to cap number of ports */
#define SPCI_FL_REGION_SZ_CAP 0x0800
/* Do not use irq sharing for this device */
#define SPCI_FL_NO_SHIRQ 0x1000
/* This is a PNP device */
#define SPCI_FL_ISPNP 0x2000
#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE|SPCI_FL_ISPNP)
#endif
/* _LINUX_SERIAL_H */
#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