diff options
author | Brent Casavant <bcasavan@sgi.com> | 2005-06-21 20:16:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 21:46:32 -0400 |
commit | d4c477ca5448f19afaaf6c0cfd655009ea9e614d (patch) | |
tree | 75571ad144ff904afbd39b1b24766461255396ac /drivers/serial | |
parent | e5d310b349b2cbcc0dab31139c92201f332695bb (diff) |
[PATCH] ioc4: PCI bus speed detection
Several hardware features of SGI's IOC4 I/O controller chip require
timing-related driver calculations dependent upon the PCI bus speed. This
patch enables the core IOC4 driver code to detect the actual bus speed and
store a value that can later be used by the IOC4 subdrivers as needed.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/ioc4_serial.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index da5f10eb4845..793c3a7cbe47 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -299,7 +299,6 @@ struct ioc4_serial { | |||
299 | } ioc4_serial; | 299 | } ioc4_serial; |
300 | 300 | ||
301 | /* UART clock speed */ | 301 | /* UART clock speed */ |
302 | #define IOC4_SER_XIN_CLK IOC4_SER_XIN_CLK_66 | ||
303 | #define IOC4_SER_XIN_CLK_66 66666667 | 302 | #define IOC4_SER_XIN_CLK_66 66666667 |
304 | #define IOC4_SER_XIN_CLK_33 33333333 | 303 | #define IOC4_SER_XIN_CLK_33 33333333 |
305 | 304 | ||
@@ -1012,21 +1011,20 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) | |||
1012 | * ioc4_attach_local - Device initialization. | 1011 | * ioc4_attach_local - Device initialization. |
1013 | * Called at *_attach() time for each | 1012 | * Called at *_attach() time for each |
1014 | * IOC4 with serial ports in the system. | 1013 | * IOC4 with serial ports in the system. |
1015 | * @control: ioc4_control ptr | 1014 | * @idd: Master module data for this IOC4 |
1016 | * @pdev: PCI handle for this device | ||
1017 | * @soft: soft struct for this device | ||
1018 | * @ioc4: ioc4 mem space | ||
1019 | */ | 1015 | */ |
1020 | static int inline ioc4_attach_local(struct pci_dev *pdev, | 1016 | static int inline ioc4_attach_local(struct ioc4_driver_data *idd) |
1021 | struct ioc4_control *control, | ||
1022 | struct ioc4_soft *soft, void __iomem *ioc4_misc, | ||
1023 | void __iomem *ioc4_serial) | ||
1024 | { | 1017 | { |
1025 | struct ioc4_port *port; | 1018 | struct ioc4_port *port; |
1026 | struct ioc4_port *ports[IOC4_NUM_SERIAL_PORTS]; | 1019 | struct ioc4_port *ports[IOC4_NUM_SERIAL_PORTS]; |
1027 | int port_number; | 1020 | int port_number; |
1028 | uint16_t ioc4_revid_min = 62; | 1021 | uint16_t ioc4_revid_min = 62; |
1029 | uint16_t ioc4_revid; | 1022 | uint16_t ioc4_revid; |
1023 | struct pci_dev *pdev = idd->idd_pdev; | ||
1024 | struct ioc4_control* control = idd->idd_serial_data; | ||
1025 | struct ioc4_soft *soft = control->ic_soft; | ||
1026 | void __iomem *ioc4_misc = idd->idd_misc_regs; | ||
1027 | void __iomem *ioc4_serial = soft->is_ioc4_serial_addr; | ||
1030 | 1028 | ||
1031 | /* IOC4 firmware must be at least rev 62 */ | 1029 | /* IOC4 firmware must be at least rev 62 */ |
1032 | pci_read_config_word(pdev, PCI_COMMAND_SPECIAL, &ioc4_revid); | 1030 | pci_read_config_word(pdev, PCI_COMMAND_SPECIAL, &ioc4_revid); |
@@ -1063,7 +1061,15 @@ static int inline ioc4_attach_local(struct pci_dev *pdev, | |||
1063 | port->ip_ioc4_soft = soft; | 1061 | port->ip_ioc4_soft = soft; |
1064 | port->ip_pdev = pdev; | 1062 | port->ip_pdev = pdev; |
1065 | port->ip_ienb = 0; | 1063 | port->ip_ienb = 0; |
1066 | port->ip_pci_bus_speed = IOC4_SER_XIN_CLK; | 1064 | /* Use baud rate calculations based on detected PCI |
1065 | * bus speed. Simply test whether the PCI clock is | ||
1066 | * running closer to 66MHz or 33MHz. | ||
1067 | */ | ||
1068 | if (idd->count_period/IOC4_EXTINT_COUNT_DIVISOR < 20) { | ||
1069 | port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_66; | ||
1070 | } else { | ||
1071 | port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_33; | ||
1072 | } | ||
1067 | port->ip_baud = 9600; | 1073 | port->ip_baud = 9600; |
1068 | port->ip_control = control; | 1074 | port->ip_control = control; |
1069 | port->ip_mem = ioc4_misc; | 1075 | port->ip_mem = ioc4_misc; |
@@ -2733,9 +2739,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) | |||
2733 | "%s : request_irq fails for IRQ 0x%x\n ", | 2739 | "%s : request_irq fails for IRQ 0x%x\n ", |
2734 | __FUNCTION__, idd->idd_pdev->irq); | 2740 | __FUNCTION__, idd->idd_pdev->irq); |
2735 | } | 2741 | } |
2736 | if ((ret = ioc4_attach_local(idd->idd_pdev, control, soft, | 2742 | ret = ioc4_attach_local(idd); |
2737 | soft->is_ioc4_misc_addr, | 2743 | if (ret) |
2738 | soft->is_ioc4_serial_addr))) | ||
2739 | goto out4; | 2744 | goto out4; |
2740 | 2745 | ||
2741 | /* register port with the serial core */ | 2746 | /* register port with the serial core */ |