diff options
| author | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 2013-06-09 17:00:21 -0400 |
|---|---|---|
| committer | Helge Deller <deller@gmx.de> | 2013-06-18 14:29:07 -0400 |
| commit | 9a66d1869d90f13fbaf83dcce5b1aeec86fbc699 (patch) | |
| tree | 2df9a43c270fd2005761d4194eda9223cf153a2a /drivers | |
| parent | 91ea8207168793b365322be3c90a4ee9e8b03ed4 (diff) | |
parisc: fix serial ports on C8000 workstation
The C8000 workstation (64 bit kernel only) has a somewhat different
serial port configuration than other models.
Thomas Bogendoerfer sent a patch to fix this in September 2010, which
was now minimally modified by me.
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/parisc/iosapic.c | 66 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_gsc.c | 10 |
2 files changed, 75 insertions, 1 deletions
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 9544cdc0d1af..e79e006eb9ab 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
| @@ -811,6 +811,70 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev) | |||
| 811 | return pcidev->irq; | 811 | return pcidev->irq; |
| 812 | } | 812 | } |
| 813 | 813 | ||
| 814 | static struct iosapic_info *first_isi = NULL; | ||
| 815 | |||
| 816 | #ifdef CONFIG_64BIT | ||
| 817 | int iosapic_serial_irq(int num) | ||
| 818 | { | ||
| 819 | struct iosapic_info *isi = first_isi; | ||
| 820 | struct irt_entry *irte = NULL; /* only used if PAT PDC */ | ||
| 821 | struct vector_info *vi; | ||
| 822 | int isi_line; /* line used by device */ | ||
| 823 | |||
| 824 | /* lookup IRT entry for isi/slot/pin set */ | ||
| 825 | irte = &irt_cell[num]; | ||
| 826 | |||
| 827 | DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n", | ||
| 828 | irte, | ||
| 829 | irte->entry_type, | ||
| 830 | irte->entry_length, | ||
| 831 | irte->polarity_trigger, | ||
| 832 | irte->src_bus_irq_devno, | ||
| 833 | irte->src_bus_id, | ||
| 834 | irte->src_seg_id, | ||
| 835 | irte->dest_iosapic_intin, | ||
| 836 | (u32) irte->dest_iosapic_addr); | ||
| 837 | isi_line = irte->dest_iosapic_intin; | ||
| 838 | |||
| 839 | /* get vector info for this input line */ | ||
| 840 | vi = isi->isi_vector + isi_line; | ||
| 841 | DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", isi_line, vi); | ||
| 842 | |||
| 843 | /* If this IRQ line has already been setup, skip it */ | ||
| 844 | if (vi->irte) | ||
| 845 | goto out; | ||
| 846 | |||
| 847 | vi->irte = irte; | ||
| 848 | |||
| 849 | /* | ||
| 850 | * Allocate processor IRQ | ||
| 851 | * | ||
| 852 | * XXX/FIXME The txn_alloc_irq() code and related code should be | ||
| 853 | * moved to enable_irq(). That way we only allocate processor IRQ | ||
| 854 | * bits for devices that actually have drivers claiming them. | ||
| 855 | * Right now we assign an IRQ to every PCI device present, | ||
| 856 | * regardless of whether it's used or not. | ||
| 857 | */ | ||
| 858 | vi->txn_irq = txn_alloc_irq(8); | ||
| 859 | |||
| 860 | if (vi->txn_irq < 0) | ||
| 861 | panic("I/O sapic: couldn't get TXN IRQ\n"); | ||
| 862 | |||
| 863 | /* enable_irq() will use txn_* to program IRdT */ | ||
| 864 | vi->txn_addr = txn_alloc_addr(vi->txn_irq); | ||
| 865 | vi->txn_data = txn_alloc_data(vi->txn_irq); | ||
| 866 | |||
| 867 | vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI; | ||
| 868 | vi->eoi_data = cpu_to_le32(vi->txn_data); | ||
| 869 | |||
| 870 | cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi); | ||
| 871 | |||
| 872 | out: | ||
| 873 | |||
| 874 | return vi->txn_irq; | ||
| 875 | } | ||
| 876 | #endif | ||
| 877 | |||
| 814 | 878 | ||
| 815 | /* | 879 | /* |
| 816 | ** squirrel away the I/O Sapic Version | 880 | ** squirrel away the I/O Sapic Version |
| @@ -877,6 +941,8 @@ void *iosapic_register(unsigned long hpa) | |||
| 877 | vip->irqline = (unsigned char) cnt; | 941 | vip->irqline = (unsigned char) cnt; |
| 878 | vip->iosapic = isi; | 942 | vip->iosapic = isi; |
| 879 | } | 943 | } |
| 944 | if (!first_isi) | ||
| 945 | first_isi = isi; | ||
| 880 | return isi; | 946 | return isi; |
| 881 | } | 947 | } |
| 882 | 948 | ||
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index 097dff9c08ad..bb91b4713ebd 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c | |||
| @@ -30,6 +30,12 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
| 30 | unsigned long address; | 30 | unsigned long address; |
| 31 | int err; | 31 | int err; |
| 32 | 32 | ||
| 33 | #ifdef CONFIG_64BIT | ||
| 34 | extern int iosapic_serial_irq(int cellnum); | ||
| 35 | if (!dev->irq && (dev->id.sversion == 0xad)) | ||
| 36 | dev->irq = iosapic_serial_irq(dev->mod_index-1); | ||
| 37 | #endif | ||
| 38 | |||
| 33 | if (!dev->irq) { | 39 | if (!dev->irq) { |
| 34 | /* We find some unattached serial ports by walking native | 40 | /* We find some unattached serial ports by walking native |
| 35 | * busses. These should be silently ignored. Otherwise, | 41 | * busses. These should be silently ignored. Otherwise, |
| @@ -51,7 +57,8 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
| 51 | memset(&uart, 0, sizeof(uart)); | 57 | memset(&uart, 0, sizeof(uart)); |
| 52 | uart.port.iotype = UPIO_MEM; | 58 | uart.port.iotype = UPIO_MEM; |
| 53 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ | 59 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ |
| 54 | uart.port.uartclk = 7272727; | 60 | uart.port.uartclk = (dev->id.sversion != 0xad) ? |
| 61 | 7272727 : 1843200; | ||
| 55 | uart.port.mapbase = address; | 62 | uart.port.mapbase = address; |
| 56 | uart.port.membase = ioremap_nocache(address, 16); | 63 | uart.port.membase = ioremap_nocache(address, 16); |
| 57 | uart.port.irq = dev->irq; | 64 | uart.port.irq = dev->irq; |
| @@ -73,6 +80,7 @@ static struct parisc_device_id serial_tbl[] = { | |||
| 73 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, | 80 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, |
| 74 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, | 81 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, |
| 75 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, | 82 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, |
| 83 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad }, | ||
| 76 | { 0 } | 84 | { 0 } |
| 77 | }; | 85 | }; |
| 78 | 86 | ||
