diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/8250_pci.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index c43de35a6c9d..7ca07651c10c 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -63,6 +63,8 @@ struct pciserial_board { | |||
63 | unsigned int first_offset; | 63 | unsigned int first_offset; |
64 | }; | 64 | }; |
65 | 65 | ||
66 | struct serial_private; | ||
67 | |||
66 | /* | 68 | /* |
67 | * init function returns: | 69 | * init function returns: |
68 | * > 0 - number of ports | 70 | * > 0 - number of ports |
@@ -75,7 +77,7 @@ struct pci_serial_quirk { | |||
75 | u32 subvendor; | 77 | u32 subvendor; |
76 | u32 subdevice; | 78 | u32 subdevice; |
77 | int (*init)(struct pci_dev *dev); | 79 | int (*init)(struct pci_dev *dev); |
78 | int (*setup)(struct pci_dev *dev, struct pciserial_board *, | 80 | int (*setup)(struct serial_private *, struct pciserial_board *, |
79 | struct uart_port *port, int idx); | 81 | struct uart_port *port, int idx); |
80 | void (*exit)(struct pci_dev *dev); | 82 | void (*exit)(struct pci_dev *dev); |
81 | }; | 83 | }; |
@@ -83,6 +85,7 @@ struct pci_serial_quirk { | |||
83 | #define PCI_NUM_BAR_RESOURCES 6 | 85 | #define PCI_NUM_BAR_RESOURCES 6 |
84 | 86 | ||
85 | struct serial_private { | 87 | struct serial_private { |
88 | struct pci_dev *dev; | ||
86 | unsigned int nr; | 89 | unsigned int nr; |
87 | void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; | 90 | void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; |
88 | struct pci_serial_quirk *quirk; | 91 | struct pci_serial_quirk *quirk; |
@@ -101,10 +104,10 @@ static void moan_device(const char *str, struct pci_dev *dev) | |||
101 | } | 104 | } |
102 | 105 | ||
103 | static int | 106 | static int |
104 | setup_port(struct pci_dev *dev, struct uart_port *port, | 107 | setup_port(struct serial_private *priv, struct uart_port *port, |
105 | int bar, int offset, int regshift) | 108 | int bar, int offset, int regshift) |
106 | { | 109 | { |
107 | struct serial_private *priv = pci_get_drvdata(dev); | 110 | struct pci_dev *dev = priv->dev; |
108 | unsigned long base, len; | 111 | unsigned long base, len; |
109 | 112 | ||
110 | if (bar >= PCI_NUM_BAR_RESOURCES) | 113 | if (bar >= PCI_NUM_BAR_RESOURCES) |
@@ -140,7 +143,7 @@ setup_port(struct pci_dev *dev, struct uart_port *port, | |||
140 | * Not that ugly ;) -- HW | 143 | * Not that ugly ;) -- HW |
141 | */ | 144 | */ |
142 | static int | 145 | static int |
143 | afavlab_setup(struct pci_dev *dev, struct pciserial_board *board, | 146 | afavlab_setup(struct serial_private *priv, struct pciserial_board *board, |
144 | struct uart_port *port, int idx) | 147 | struct uart_port *port, int idx) |
145 | { | 148 | { |
146 | unsigned int bar, offset = board->first_offset; | 149 | unsigned int bar, offset = board->first_offset; |
@@ -153,7 +156,7 @@ afavlab_setup(struct pci_dev *dev, struct pciserial_board *board, | |||
153 | offset += (idx - 4) * board->uart_offset; | 156 | offset += (idx - 4) * board->uart_offset; |
154 | } | 157 | } |
155 | 158 | ||
156 | return setup_port(dev, port, bar, offset, board->reg_shift); | 159 | return setup_port(priv, port, bar, offset, board->reg_shift); |
157 | } | 160 | } |
158 | 161 | ||
159 | /* | 162 | /* |
@@ -193,13 +196,13 @@ static int __devinit pci_hp_diva_init(struct pci_dev *dev) | |||
193 | * some serial ports are supposed to be hidden on certain models. | 196 | * some serial ports are supposed to be hidden on certain models. |
194 | */ | 197 | */ |
195 | static int | 198 | static int |
196 | pci_hp_diva_setup(struct pci_dev *dev, struct pciserial_board *board, | 199 | pci_hp_diva_setup(struct serial_private *priv, struct pciserial_board *board, |
197 | struct uart_port *port, int idx) | 200 | struct uart_port *port, int idx) |
198 | { | 201 | { |
199 | unsigned int offset = board->first_offset; | 202 | unsigned int offset = board->first_offset; |
200 | unsigned int bar = FL_GET_BASE(board->flags); | 203 | unsigned int bar = FL_GET_BASE(board->flags); |
201 | 204 | ||
202 | switch (dev->subsystem_device) { | 205 | switch (priv->dev->subsystem_device) { |
203 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: | 206 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: |
204 | if (idx == 3) | 207 | if (idx == 3) |
205 | idx++; | 208 | idx++; |
@@ -216,7 +219,7 @@ pci_hp_diva_setup(struct pci_dev *dev, struct pciserial_board *board, | |||
216 | 219 | ||
217 | offset += idx * board->uart_offset; | 220 | offset += idx * board->uart_offset; |
218 | 221 | ||
219 | return setup_port(dev, port, bar, offset, board->reg_shift); | 222 | return setup_port(priv, port, bar, offset, board->reg_shift); |
220 | } | 223 | } |
221 | 224 | ||
222 | /* | 225 | /* |
@@ -311,7 +314,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev) | |||
311 | 314 | ||
312 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ | 315 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ |
313 | static int | 316 | static int |
314 | sbs_setup(struct pci_dev *dev, struct pciserial_board *board, | 317 | sbs_setup(struct serial_private *priv, struct pciserial_board *board, |
315 | struct uart_port *port, int idx) | 318 | struct uart_port *port, int idx) |
316 | { | 319 | { |
317 | unsigned int bar, offset = board->first_offset; | 320 | unsigned int bar, offset = board->first_offset; |
@@ -327,7 +330,7 @@ sbs_setup(struct pci_dev *dev, struct pciserial_board *board, | |||
327 | } else /* we have only 8 ports on PMC-OCTALPRO */ | 330 | } else /* we have only 8 ports on PMC-OCTALPRO */ |
328 | return 1; | 331 | return 1; |
329 | 332 | ||
330 | return setup_port(dev, port, bar, offset, board->reg_shift); | 333 | return setup_port(priv, port, bar, offset, board->reg_shift); |
331 | } | 334 | } |
332 | 335 | ||
333 | /* | 336 | /* |
@@ -543,7 +546,7 @@ static int __devinit pci_timedia_init(struct pci_dev *dev) | |||
543 | * Ugh, this is ugly as all hell --- TYT | 546 | * Ugh, this is ugly as all hell --- TYT |
544 | */ | 547 | */ |
545 | static int | 548 | static int |
546 | pci_timedia_setup(struct pci_dev *dev, struct pciserial_board *board, | 549 | pci_timedia_setup(struct serial_private *priv, struct pciserial_board *board, |
547 | struct uart_port *port, int idx) | 550 | struct uart_port *port, int idx) |
548 | { | 551 | { |
549 | unsigned int bar = 0, offset = board->first_offset; | 552 | unsigned int bar = 0, offset = board->first_offset; |
@@ -569,14 +572,14 @@ pci_timedia_setup(struct pci_dev *dev, struct pciserial_board *board, | |||
569 | bar = idx - 2; | 572 | bar = idx - 2; |
570 | } | 573 | } |
571 | 574 | ||
572 | return setup_port(dev, port, bar, offset, board->reg_shift); | 575 | return setup_port(priv, port, bar, offset, board->reg_shift); |
573 | } | 576 | } |
574 | 577 | ||
575 | /* | 578 | /* |
576 | * Some Titan cards are also a little weird | 579 | * Some Titan cards are also a little weird |
577 | */ | 580 | */ |
578 | static int | 581 | static int |
579 | titan_400l_800l_setup(struct pci_dev *dev, | 582 | titan_400l_800l_setup(struct serial_private *priv, |
580 | struct pciserial_board *board, | 583 | struct pciserial_board *board, |
581 | struct uart_port *port, int idx) | 584 | struct uart_port *port, int idx) |
582 | { | 585 | { |
@@ -594,7 +597,7 @@ titan_400l_800l_setup(struct pci_dev *dev, | |||
594 | offset = (idx - 2) * board->uart_offset; | 597 | offset = (idx - 2) * board->uart_offset; |
595 | } | 598 | } |
596 | 599 | ||
597 | return setup_port(dev, port, bar, offset, board->reg_shift); | 600 | return setup_port(priv, port, bar, offset, board->reg_shift); |
598 | } | 601 | } |
599 | 602 | ||
600 | static int __devinit pci_xircom_init(struct pci_dev *dev) | 603 | static int __devinit pci_xircom_init(struct pci_dev *dev) |
@@ -614,7 +617,7 @@ static int __devinit pci_netmos_init(struct pci_dev *dev) | |||
614 | } | 617 | } |
615 | 618 | ||
616 | static int | 619 | static int |
617 | pci_default_setup(struct pci_dev *dev, struct pciserial_board *board, | 620 | pci_default_setup(struct serial_private *priv, struct pciserial_board *board, |
618 | struct uart_port *port, int idx) | 621 | struct uart_port *port, int idx) |
619 | { | 622 | { |
620 | unsigned int bar, offset = board->first_offset, maxnr; | 623 | unsigned int bar, offset = board->first_offset, maxnr; |
@@ -625,13 +628,13 @@ pci_default_setup(struct pci_dev *dev, struct pciserial_board *board, | |||
625 | else | 628 | else |
626 | offset += idx * board->uart_offset; | 629 | offset += idx * board->uart_offset; |
627 | 630 | ||
628 | maxnr = (pci_resource_len(dev, bar) - board->first_offset) / | 631 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) / |
629 | (8 << board->reg_shift); | 632 | (8 << board->reg_shift); |
630 | 633 | ||
631 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) | 634 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) |
632 | return 1; | 635 | return 1; |
633 | 636 | ||
634 | return setup_port(dev, port, bar, offset, board->reg_shift); | 637 | return setup_port(priv, port, bar, offset, board->reg_shift); |
635 | } | 638 | } |
636 | 639 | ||
637 | /* This should be in linux/pci_ids.h */ | 640 | /* This should be in linux/pci_ids.h */ |
@@ -1612,6 +1615,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1612 | memset(priv, 0, sizeof(struct serial_private) + | 1615 | memset(priv, 0, sizeof(struct serial_private) + |
1613 | sizeof(unsigned int) * nr_ports); | 1616 | sizeof(unsigned int) * nr_ports); |
1614 | 1617 | ||
1618 | priv->dev = dev; | ||
1615 | priv->quirk = quirk; | 1619 | priv->quirk = quirk; |
1616 | pci_set_drvdata(dev, priv); | 1620 | pci_set_drvdata(dev, priv); |
1617 | 1621 | ||
@@ -1622,7 +1626,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1622 | serial_port.dev = &dev->dev; | 1626 | serial_port.dev = &dev->dev; |
1623 | 1627 | ||
1624 | for (i = 0; i < nr_ports; i++) { | 1628 | for (i = 0; i < nr_ports; i++) { |
1625 | if (quirk->setup(dev, board, &serial_port, i)) | 1629 | if (quirk->setup(priv, board, &serial_port, i)) |
1626 | break; | 1630 | break; |
1627 | 1631 | ||
1628 | #ifdef SERIAL_DEBUG_PCI | 1632 | #ifdef SERIAL_DEBUG_PCI |