diff options
author | Kyle McMartin <kyle@parisc-linux.org> | 2007-02-17 00:18:23 -0500 |
---|---|---|
committer | Kyle McMartin <kyle@parisc-linux.org> | 2007-02-17 00:18:23 -0500 |
commit | e7b3ca08549caccf5d6e1cf066780bf4f0ae77a7 (patch) | |
tree | 7e5745bea06675cfce60d6813ee3b4d5e19cbb56 /drivers | |
parent | 62d0cfcb27cf755cebdc93ca95dabc83608007cd (diff) | |
parent | cb6efb39163bfb6bb6475fa7c8a5e08e44dbf14a (diff) |
Merge branch 'parisc' from /home/kyle/repos/parisc-2.6.git
Conflicts:
arch/parisc/hpux/sys_hpux.c
arch/parisc/mm/ioremap.c
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/agp/parisc-agp.c | 2 | ||||
-rw-r--r-- | drivers/net/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/lasi_82596.c | 34 | ||||
-rw-r--r-- | drivers/parisc/hppb.c | 14 | ||||
-rw-r--r-- | drivers/parisc/iosapic_private.h | 2 | ||||
-rw-r--r-- | drivers/parisc/lba_pci.c | 34 | ||||
-rw-r--r-- | drivers/parisc/led.c | 12 | ||||
-rw-r--r-- | drivers/parisc/power.c | 4 | ||||
-rw-r--r-- | drivers/parisc/sba_iommu.c | 4 | ||||
-rw-r--r-- | drivers/serial/mux.c | 167 |
10 files changed, 180 insertions, 99 deletions
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index 17c50b0f83f0..30cc7aeae9ab 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c | |||
@@ -235,7 +235,7 @@ static int __init | |||
235 | agp_ioc_init(void __iomem *ioc_regs) | 235 | agp_ioc_init(void __iomem *ioc_regs) |
236 | { | 236 | { |
237 | struct _parisc_agp_info *info = &parisc_agp_info; | 237 | struct _parisc_agp_info *info = &parisc_agp_info; |
238 | u64 *iova_base, *io_pdir, io_tlb_ps; | 238 | u64 iova_base, *io_pdir, io_tlb_ps; |
239 | int io_tlb_shift; | 239 | int io_tlb_shift; |
240 | 240 | ||
241 | printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n"); | 241 | printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n"); |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 8aa8dd02b910..79eade7e9d91 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -440,10 +440,10 @@ config HPLANCE | |||
440 | 440 | ||
441 | config LASI_82596 | 441 | config LASI_82596 |
442 | tristate "Lasi ethernet" | 442 | tristate "Lasi ethernet" |
443 | depends on NET_ETHERNET && PARISC && GSC_LASI | 443 | depends on NET_ETHERNET && GSC |
444 | help | 444 | help |
445 | Say Y here to support the on-board Intel 82596 ethernet controller | 445 | Say Y here to support the builtin Intel 82596 ethernet controller |
446 | built into Hewlett-Packard PA-RISC machines. | 446 | found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet. |
447 | 447 | ||
448 | config MIPS_JAZZ_SONIC | 448 | config MIPS_JAZZ_SONIC |
449 | tristate "MIPS JAZZ onboard SONIC Ethernet support" | 449 | tristate "MIPS JAZZ onboard SONIC Ethernet support" |
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index ea392f2a5aa2..452863d5d498 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c | |||
@@ -384,7 +384,7 @@ struct i596_private { | |||
384 | struct device *dev; | 384 | struct device *dev; |
385 | }; | 385 | }; |
386 | 386 | ||
387 | static char init_setup[] = | 387 | static const char init_setup[] = |
388 | { | 388 | { |
389 | 0x8E, /* length, prefetch on */ | 389 | 0x8E, /* length, prefetch on */ |
390 | 0xC8, /* fifo to 8, monitor off */ | 390 | 0xC8, /* fifo to 8, monitor off */ |
@@ -683,7 +683,7 @@ static int init_i596_mem(struct net_device *dev) | |||
683 | enable_irq(dev->irq); /* enable IRQs from LAN */ | 683 | enable_irq(dev->irq); /* enable IRQs from LAN */ |
684 | 684 | ||
685 | DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name)); | 685 | DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name)); |
686 | memcpy(lp->cf_cmd.i596_config, init_setup, 14); | 686 | memcpy(lp->cf_cmd.i596_config, init_setup, sizeof(init_setup)); |
687 | lp->cf_cmd.cmd.command = CmdConfigure; | 687 | lp->cf_cmd.cmd.command = CmdConfigure; |
688 | CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd)); | 688 | CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd)); |
689 | i596_add_cmd(dev, &lp->cf_cmd.cmd); | 689 | i596_add_cmd(dev, &lp->cf_cmd.cmd); |
@@ -1156,32 +1156,12 @@ static int __devinit i82596_probe(struct net_device *dev, | |||
1156 | dma_addr_t dma_addr; | 1156 | dma_addr_t dma_addr; |
1157 | 1157 | ||
1158 | /* This lot is ensure things have been cache line aligned. */ | 1158 | /* This lot is ensure things have been cache line aligned. */ |
1159 | if (sizeof(struct i596_rfd) != 32) { | 1159 | BUILD_BUG_ON(sizeof(struct i596_rfd) != 32); |
1160 | printk("82596: sizeof(struct i596_rfd) = %d\n", | 1160 | BUILD_BUG_ON(sizeof(struct i596_rbd) & 31); |
1161 | (int)sizeof(struct i596_rfd)); | 1161 | BUILD_BUG_ON(sizeof(struct tx_cmd) & 31); |
1162 | return -ENODEV; | 1162 | BUILD_BUG_ON(sizeof(struct i596_tbd) != 32); |
1163 | } | ||
1164 | if ((sizeof(struct i596_rbd) % 32) != 0) { | ||
1165 | printk("82596: sizeof(struct i596_rbd) = %d\n", | ||
1166 | (int)sizeof(struct i596_rbd)); | ||
1167 | return -ENODEV; | ||
1168 | } | ||
1169 | if ((sizeof(struct tx_cmd) % 32) != 0) { | ||
1170 | printk("82596: sizeof(struct tx_cmd) = %d\n", | ||
1171 | (int)sizeof(struct tx_cmd)); | ||
1172 | return -ENODEV; | ||
1173 | } | ||
1174 | if (sizeof(struct i596_tbd) != 32) { | ||
1175 | printk("82596: sizeof(struct i596_tbd) = %d\n", | ||
1176 | (int)sizeof(struct i596_tbd)); | ||
1177 | return -ENODEV; | ||
1178 | } | ||
1179 | #ifndef __LP64__ | 1163 | #ifndef __LP64__ |
1180 | if (sizeof(struct i596_private) > 4096) { | 1164 | BUILD_BUG_ON(sizeof(struct i596_private) > 4096); |
1181 | printk("82596: sizeof(struct i596_private) = %d\n", | ||
1182 | (int)sizeof(struct i596_private)); | ||
1183 | return -ENODEV; | ||
1184 | } | ||
1185 | #endif | 1165 | #endif |
1186 | 1166 | ||
1187 | if (!dev->base_addr || !dev->irq) | 1167 | if (!dev->base_addr || !dev->irq) |
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 07dc2b6d4e93..9bb4db552f3c 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c | |||
@@ -10,10 +10,6 @@ | |||
10 | ** the Free Software Foundation; either version 2 of the License, or | 10 | ** the Free Software Foundation; either version 2 of the License, or |
11 | ** (at your option) any later version. | 11 | ** (at your option) any later version. |
12 | ** | 12 | ** |
13 | ** This Driver currently only supports the console (port 0) on the MUX. | ||
14 | ** Additional work will be needed on this driver to enable the full | ||
15 | ** functionality of the MUX. | ||
16 | ** | ||
17 | */ | 13 | */ |
18 | 14 | ||
19 | #include <linux/types.h> | 15 | #include <linux/types.h> |
@@ -67,7 +63,7 @@ static int hppb_probe(struct parisc_device *dev) | |||
67 | } | 63 | } |
68 | card = card->next; | 64 | card = card->next; |
69 | } | 65 | } |
70 | printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); | 66 | printk(KERN_INFO "Found GeckoBoa at 0x%x\n", dev->hpa.start); |
71 | 67 | ||
72 | card->hpa = dev->hpa.start; | 68 | card->hpa = dev->hpa.start; |
73 | card->mmio_region.name = "HP-PB Bus"; | 69 | card->mmio_region.name = "HP-PB Bus"; |
@@ -78,16 +74,18 @@ static int hppb_probe(struct parisc_device *dev) | |||
78 | 74 | ||
79 | status = ccio_request_resource(dev, &card->mmio_region); | 75 | status = ccio_request_resource(dev, &card->mmio_region); |
80 | if(status < 0) { | 76 | if(status < 0) { |
81 | printk(KERN_ERR "%s: failed to claim HP-PB bus space (%08lx, %08lx)\n", | 77 | printk(KERN_ERR "%s: failed to claim HP-PB bus space (%08x, %08x)\n", |
82 | __FILE__, card->mmio_region.start, card->mmio_region.end); | 78 | __FILE__, card->mmio_region.start, card->mmio_region.end); |
83 | } | 79 | } |
84 | 80 | ||
85 | return 0; | 81 | return 0; |
86 | } | 82 | } |
87 | 83 | ||
88 | |||
89 | static struct parisc_device_id hppb_tbl[] = { | 84 | static struct parisc_device_id hppb_tbl[] = { |
90 | { HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, | 85 | { HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, /* E25 and K */ |
86 | { HPHW_BCPORT, 0x0, 0x501, 0xc }, /* E35 */ | ||
87 | { HPHW_BCPORT, 0x0, 0x502, 0xc }, /* E45 */ | ||
88 | { HPHW_BCPORT, 0x0, 0x503, 0xc }, /* E55 */ | ||
91 | { 0, } | 89 | { 0, } |
92 | }; | 90 | }; |
93 | 91 | ||
diff --git a/drivers/parisc/iosapic_private.h b/drivers/parisc/iosapic_private.h index 41e7ec2a44aa..6e05e30a2450 100644 --- a/drivers/parisc/iosapic_private.h +++ b/drivers/parisc/iosapic_private.h | |||
@@ -132,7 +132,7 @@ struct iosapic_irt { | |||
132 | struct vector_info { | 132 | struct vector_info { |
133 | struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ | 133 | struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ |
134 | struct irt_entry *irte; /* IRT entry */ | 134 | struct irt_entry *irte; /* IRT entry */ |
135 | u32 *eoi_addr; /* precalculate EOI reg address */ | 135 | u32 __iomem *eoi_addr; /* precalculate EOI reg address */ |
136 | u32 eoi_data; /* IA64: ? PA: swapped txn_data */ | 136 | u32 eoi_data; /* IA64: ? PA: swapped txn_data */ |
137 | int txn_irq; /* virtual IRQ number for processor */ | 137 | int txn_irq; /* virtual IRQ number for processor */ |
138 | ulong txn_addr; /* IA64: id_eid PA: partial HPA */ | 138 | ulong txn_addr; /* IA64: id_eid PA: partial HPA */ |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index ba6769934c77..eae0812f01a5 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -980,7 +980,7 @@ LBA_PORT_IN(32, 0) | |||
980 | #define LBA_PORT_OUT(size, mask) \ | 980 | #define LBA_PORT_OUT(size, mask) \ |
981 | static void lba_pat_out##size (struct pci_hba_data *l, u16 addr, u##size val) \ | 981 | static void lba_pat_out##size (struct pci_hba_data *l, u16 addr, u##size val) \ |
982 | { \ | 982 | { \ |
983 | void *where = (void *) PIOP_TO_GMMIO(LBA_DEV(l), addr); \ | 983 | void __iomem *where = PIOP_TO_GMMIO(LBA_DEV(l), addr); \ |
984 | DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \ | 984 | DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \ |
985 | WRITE_REG##size(val, where); \ | 985 | WRITE_REG##size(val, where); \ |
986 | /* flush the I/O down to the elroy at least */ \ | 986 | /* flush the I/O down to the elroy at least */ \ |
@@ -1406,13 +1406,20 @@ lba_hw_init(struct lba_device *d) | |||
1406 | return 0; | 1406 | return 0; |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | 1409 | /* | |
1410 | * Unfortunately, when firmware numbers busses, it doesn't take into account | ||
1411 | * Cardbus bridges. So we have to renumber the busses to suit ourselves. | ||
1412 | * Elroy/Mercury don't actually know what bus number they're attached to; | ||
1413 | * we use bus 0 to indicate the directly attached bus and any other bus | ||
1414 | * number will be taken care of by the PCI-PCI bridge. | ||
1415 | */ | ||
1416 | static unsigned int lba_next_bus = 0; | ||
1410 | 1417 | ||
1411 | /* | 1418 | /* |
1412 | ** Determine if lba should claim this chip (return 0) or not (return 1). | 1419 | * Determine if lba should claim this chip (return 0) or not (return 1). |
1413 | ** If so, initialize the chip and tell other partners in crime they | 1420 | * If so, initialize the chip and tell other partners in crime they |
1414 | ** have work to do. | 1421 | * have work to do. |
1415 | */ | 1422 | */ |
1416 | static int __init | 1423 | static int __init |
1417 | lba_driver_probe(struct parisc_device *dev) | 1424 | lba_driver_probe(struct parisc_device *dev) |
1418 | { | 1425 | { |
@@ -1478,9 +1485,7 @@ lba_driver_probe(struct parisc_device *dev) | |||
1478 | return -ENODEV; | 1485 | return -ENODEV; |
1479 | } | 1486 | } |
1480 | 1487 | ||
1481 | /* | 1488 | /* Tell I/O SAPIC driver we have a IRQ handler/region. */ |
1482 | ** Tell I/O SAPIC driver we have a IRQ handler/region. | ||
1483 | */ | ||
1484 | tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE); | 1489 | tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE); |
1485 | 1490 | ||
1486 | /* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't | 1491 | /* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't |
@@ -1529,16 +1534,17 @@ lba_driver_probe(struct parisc_device *dev) | |||
1529 | lba_legacy_resources(dev, lba_dev); | 1534 | lba_legacy_resources(dev, lba_dev); |
1530 | } | 1535 | } |
1531 | 1536 | ||
1532 | /* | 1537 | if (lba_dev->hba.bus_num.start < lba_next_bus) |
1533 | ** Tell PCI support another PCI bus was found. | 1538 | lba_dev->hba.bus_num.start = lba_next_bus; |
1534 | ** Walks PCI bus for us too. | 1539 | |
1535 | */ | ||
1536 | dev->dev.platform_data = lba_dev; | 1540 | dev->dev.platform_data = lba_dev; |
1537 | lba_bus = lba_dev->hba.hba_bus = | 1541 | lba_bus = lba_dev->hba.hba_bus = |
1538 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, | 1542 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, |
1539 | cfg_ops, NULL); | 1543 | cfg_ops, NULL); |
1540 | if (lba_bus) | 1544 | if (lba_bus) { |
1545 | lba_next_bus = lba_bus->subordinate + 1; | ||
1541 | pci_bus_add_devices(lba_bus); | 1546 | pci_bus_add_devices(lba_bus); |
1547 | } | ||
1542 | 1548 | ||
1543 | /* This is in lieu of calling pci_assign_unassigned_resources() */ | 1549 | /* This is in lieu of calling pci_assign_unassigned_resources() */ |
1544 | if (is_pdc_pat()) { | 1550 | if (is_pdc_pat()) { |
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 8dac2ba82bb9..6818c10c0c46 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c | |||
@@ -66,8 +66,8 @@ static char lcd_text_default[32] __read_mostly; | |||
66 | 66 | ||
67 | 67 | ||
68 | static struct workqueue_struct *led_wq; | 68 | static struct workqueue_struct *led_wq; |
69 | static void led_work_func(void *); | 69 | static void led_work_func(struct work_struct *); |
70 | static DECLARE_WORK(led_task, led_work_func, NULL); | 70 | static DECLARE_DELAYED_WORK(led_task, led_work_func); |
71 | 71 | ||
72 | #if 0 | 72 | #if 0 |
73 | #define DPRINTK(x) printk x | 73 | #define DPRINTK(x) printk x |
@@ -136,7 +136,7 @@ static int start_task(void) | |||
136 | 136 | ||
137 | /* Create the work queue and queue the LED task */ | 137 | /* Create the work queue and queue the LED task */ |
138 | led_wq = create_singlethread_workqueue("led_wq"); | 138 | led_wq = create_singlethread_workqueue("led_wq"); |
139 | queue_work(led_wq, &led_task); | 139 | queue_delayed_work(led_wq, &led_task, 0); |
140 | 140 | ||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
@@ -443,7 +443,7 @@ static __inline__ int led_get_diskio_activity(void) | |||
443 | 443 | ||
444 | #define LED_UPDATE_INTERVAL (1 + (HZ*19/1000)) | 444 | #define LED_UPDATE_INTERVAL (1 + (HZ*19/1000)) |
445 | 445 | ||
446 | static void led_work_func (void *unused) | 446 | static void led_work_func (struct work_struct *unused) |
447 | { | 447 | { |
448 | static unsigned long last_jiffies; | 448 | static unsigned long last_jiffies; |
449 | static unsigned long count_HZ; /* counter in range 0..HZ */ | 449 | static unsigned long count_HZ; /* counter in range 0..HZ */ |
@@ -590,7 +590,7 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d | |||
590 | 590 | ||
591 | /* Ensure the work is queued */ | 591 | /* Ensure the work is queued */ |
592 | if (led_wq) { | 592 | if (led_wq) { |
593 | queue_work(led_wq, &led_task); | 593 | queue_delayed_work(led_wq, &led_task, 0); |
594 | } | 594 | } |
595 | 595 | ||
596 | return 0; | 596 | return 0; |
@@ -660,7 +660,7 @@ int lcd_print( char *str ) | |||
660 | 660 | ||
661 | /* re-queue the work */ | 661 | /* re-queue the work */ |
662 | if (led_wq) { | 662 | if (led_wq) { |
663 | queue_work(led_wq, &led_task); | 663 | queue_delayed_work(led_wq, &led_task, 0); |
664 | } | 664 | } |
665 | 665 | ||
666 | return lcd_info.lcd_width; | 666 | return lcd_info.lcd_width; |
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c index 97e9dc066f95..9228e210c3bb 100644 --- a/drivers/parisc/power.c +++ b/drivers/parisc/power.c | |||
@@ -82,7 +82,7 @@ | |||
82 | } ) | 82 | } ) |
83 | 83 | ||
84 | 84 | ||
85 | static void deferred_poweroff(void *dummy) | 85 | static void deferred_poweroff(struct work_struct *unused) |
86 | { | 86 | { |
87 | if (kill_cad_pid(SIGINT, 1)) { | 87 | if (kill_cad_pid(SIGINT, 1)) { |
88 | /* just in case killing init process failed */ | 88 | /* just in case killing init process failed */ |
@@ -96,7 +96,7 @@ static void deferred_poweroff(void *dummy) | |||
96 | * use schedule_work(). | 96 | * use schedule_work(). |
97 | */ | 97 | */ |
98 | 98 | ||
99 | static DECLARE_WORK(poweroff_work, deferred_poweroff, NULL); | 99 | static DECLARE_WORK(poweroff_work, deferred_poweroff); |
100 | 100 | ||
101 | static void poweroff(void) | 101 | static void poweroff(void) |
102 | { | 102 | { |
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index f1e7ccd5475b..26fece45e737 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -109,7 +109,7 @@ static unsigned long piranha_bad_128k = 0; | |||
109 | 109 | ||
110 | #ifdef SBA_AGP_SUPPORT | 110 | #ifdef SBA_AGP_SUPPORT |
111 | static int sba_reserve_agpgart = 1; | 111 | static int sba_reserve_agpgart = 1; |
112 | module_param(sba_reserve_agpgart, int, 1); | 112 | module_param(sba_reserve_agpgart, int, 0444); |
113 | MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART"); | 113 | MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART"); |
114 | #endif | 114 | #endif |
115 | 115 | ||
@@ -846,7 +846,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size, | |||
846 | if (!hwdev) { | 846 | if (!hwdev) { |
847 | /* only support PCI */ | 847 | /* only support PCI */ |
848 | *dma_handle = 0; | 848 | *dma_handle = 0; |
849 | return 0; | 849 | return NULL; |
850 | } | 850 | } |
851 | 851 | ||
852 | ret = (void *) __get_free_pages(gfp, get_order(size)); | 852 | ret = (void *) __get_free_pages(gfp, get_order(size)); |
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index ccb8fa1800a5..83211013deb8 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
@@ -51,7 +51,11 @@ | |||
51 | 51 | ||
52 | #define MUX_NR 256 | 52 | #define MUX_NR 256 |
53 | static unsigned int port_cnt __read_mostly; | 53 | static unsigned int port_cnt __read_mostly; |
54 | static struct uart_port mux_ports[MUX_NR]; | 54 | struct mux_port { |
55 | struct uart_port port; | ||
56 | int enabled; | ||
57 | }; | ||
58 | static struct mux_port mux_ports[MUX_NR]; | ||
55 | 59 | ||
56 | static struct uart_driver mux_driver = { | 60 | static struct uart_driver mux_driver = { |
57 | .owner = THIS_MODULE, | 61 | .owner = THIS_MODULE, |
@@ -66,7 +70,36 @@ static struct timer_list mux_timer; | |||
66 | 70 | ||
67 | #define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET) | 71 | #define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET) |
68 | #define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET) | 72 | #define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET) |
69 | #define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8 | 73 | |
74 | /** | ||
75 | * get_mux_port_count - Get the number of available ports on the Mux. | ||
76 | * @dev: The parisc device. | ||
77 | * | ||
78 | * This function is used to determine the number of ports the Mux | ||
79 | * supports. The IODC data reports the number of ports the Mux | ||
80 | * can support, but there are cases where not all the Mux ports | ||
81 | * are connected. This function can override the IODC and | ||
82 | * return the true port count. | ||
83 | */ | ||
84 | static int __init get_mux_port_count(struct parisc_device *dev) | ||
85 | { | ||
86 | int status; | ||
87 | u8 iodc_data[32]; | ||
88 | unsigned long bytecnt; | ||
89 | |||
90 | /* If this is the built-in Mux for the K-Class (Eole CAP/MUX), | ||
91 | * we only need to allocate resources for 1 port since the | ||
92 | * other 7 ports are not connected. | ||
93 | */ | ||
94 | if(dev->id.hversion == 0x15) | ||
95 | return 1; | ||
96 | |||
97 | status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32); | ||
98 | BUG_ON(status != PDC_OK); | ||
99 | |||
100 | /* Return the number of ports specified in the iodc data. */ | ||
101 | return ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8; | ||
102 | } | ||
70 | 103 | ||
71 | /** | 104 | /** |
72 | * mux_tx_empty - Check if the transmitter fifo is empty. | 105 | * mux_tx_empty - Check if the transmitter fifo is empty. |
@@ -250,7 +283,7 @@ static void mux_read(struct uart_port *port) | |||
250 | */ | 283 | */ |
251 | static int mux_startup(struct uart_port *port) | 284 | static int mux_startup(struct uart_port *port) |
252 | { | 285 | { |
253 | mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY); | 286 | mux_ports[port->line].enabled = 1; |
254 | return 0; | 287 | return 0; |
255 | } | 288 | } |
256 | 289 | ||
@@ -262,6 +295,7 @@ static int mux_startup(struct uart_port *port) | |||
262 | */ | 295 | */ |
263 | static void mux_shutdown(struct uart_port *port) | 296 | static void mux_shutdown(struct uart_port *port) |
264 | { | 297 | { |
298 | mux_ports[port->line].enabled = 0; | ||
265 | } | 299 | } |
266 | 300 | ||
267 | /** | 301 | /** |
@@ -319,7 +353,7 @@ static int mux_request_port(struct uart_port *port) | |||
319 | * @port: Ptr to the uart_port. | 353 | * @port: Ptr to the uart_port. |
320 | * @type: Bitmask of required configurations. | 354 | * @type: Bitmask of required configurations. |
321 | * | 355 | * |
322 | * Perform any autoconfiguration steps for the port. This functino is | 356 | * Perform any autoconfiguration steps for the port. This function is |
323 | * called if the UPF_BOOT_AUTOCONF flag is specified for the port. | 357 | * called if the UPF_BOOT_AUTOCONF flag is specified for the port. |
324 | * [Note: This is required for now because of a bug in the Serial core. | 358 | * [Note: This is required for now because of a bug in the Serial core. |
325 | * rmk has already submitted a patch to linus, should be available for | 359 | * rmk has already submitted a patch to linus, should be available for |
@@ -357,11 +391,11 @@ static void mux_poll(unsigned long unused) | |||
357 | int i; | 391 | int i; |
358 | 392 | ||
359 | for(i = 0; i < port_cnt; ++i) { | 393 | for(i = 0; i < port_cnt; ++i) { |
360 | if(!mux_ports[i].info) | 394 | if(!mux_ports[i].enabled) |
361 | continue; | 395 | continue; |
362 | 396 | ||
363 | mux_read(&mux_ports[i]); | 397 | mux_read(&mux_ports[i].port); |
364 | mux_write(&mux_ports[i]); | 398 | mux_write(&mux_ports[i].port); |
365 | } | 399 | } |
366 | 400 | ||
367 | mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY); | 401 | mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY); |
@@ -371,8 +405,17 @@ static void mux_poll(unsigned long unused) | |||
371 | #ifdef CONFIG_SERIAL_MUX_CONSOLE | 405 | #ifdef CONFIG_SERIAL_MUX_CONSOLE |
372 | static void mux_console_write(struct console *co, const char *s, unsigned count) | 406 | static void mux_console_write(struct console *co, const char *s, unsigned count) |
373 | { | 407 | { |
374 | while(count--) | 408 | /* Wait until the FIFO drains. */ |
375 | pdc_iodc_putc(*s++); | 409 | while(UART_GET_FIFO_CNT(&mux_ports[0].port)) |
410 | udelay(1); | ||
411 | |||
412 | while(count--) { | ||
413 | if(*s == '\n') { | ||
414 | UART_PUT_CHAR(&mux_ports[0].port, '\r'); | ||
415 | } | ||
416 | UART_PUT_CHAR(&mux_ports[0].port, *s++); | ||
417 | } | ||
418 | |||
376 | } | 419 | } |
377 | 420 | ||
378 | static int mux_console_setup(struct console *co, char *options) | 421 | static int mux_console_setup(struct console *co, char *options) |
@@ -428,19 +471,14 @@ static struct uart_ops mux_pops = { | |||
428 | */ | 471 | */ |
429 | static int __init mux_probe(struct parisc_device *dev) | 472 | static int __init mux_probe(struct parisc_device *dev) |
430 | { | 473 | { |
431 | int i, status, ports; | 474 | int i, status; |
432 | u8 iodc_data[32]; | ||
433 | unsigned long bytecnt; | ||
434 | struct uart_port *port; | ||
435 | 475 | ||
436 | status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32); | 476 | int port_count = get_mux_port_count(dev); |
437 | if(status != PDC_OK) { | 477 | printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.6\n", port_count); |
438 | printk(KERN_ERR "Serial mux: Unable to read IODC.\n"); | ||
439 | return 1; | ||
440 | } | ||
441 | 478 | ||
442 | ports = GET_MUX_PORTS(iodc_data); | 479 | dev_set_drvdata(&dev->dev, (void *)(long)port_count); |
443 | printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.3\n", ports); | 480 | request_mem_region(dev->hpa.start + MUX_OFFSET, |
481 | port_count * MUX_LINE_OFFSET, "Mux"); | ||
444 | 482 | ||
445 | if(!port_cnt) { | 483 | if(!port_cnt) { |
446 | mux_driver.cons = MUX_CONSOLE; | 484 | mux_driver.cons = MUX_CONSOLE; |
@@ -450,13 +488,10 @@ static int __init mux_probe(struct parisc_device *dev) | |||
450 | printk(KERN_ERR "Serial mux: Unable to register driver.\n"); | 488 | printk(KERN_ERR "Serial mux: Unable to register driver.\n"); |
451 | return 1; | 489 | return 1; |
452 | } | 490 | } |
453 | |||
454 | init_timer(&mux_timer); | ||
455 | mux_timer.function = mux_poll; | ||
456 | } | 491 | } |
457 | 492 | ||
458 | for(i = 0; i < ports; ++i, ++port_cnt) { | 493 | for(i = 0; i < port_count; ++i, ++port_cnt) { |
459 | port = &mux_ports[port_cnt]; | 494 | struct uart_port *port = &mux_ports[port_cnt].port; |
460 | port->iobase = 0; | 495 | port->iobase = 0; |
461 | port->mapbase = dev->hpa.start + MUX_OFFSET + | 496 | port->mapbase = dev->hpa.start + MUX_OFFSET + |
462 | (i * MUX_LINE_OFFSET); | 497 | (i * MUX_LINE_OFFSET); |
@@ -477,27 +512,73 @@ static int __init mux_probe(struct parisc_device *dev) | |||
477 | */ | 512 | */ |
478 | port->timeout = HZ / 50; | 513 | port->timeout = HZ / 50; |
479 | spin_lock_init(&port->lock); | 514 | spin_lock_init(&port->lock); |
515 | |||
480 | status = uart_add_one_port(&mux_driver, port); | 516 | status = uart_add_one_port(&mux_driver, port); |
481 | BUG_ON(status); | 517 | BUG_ON(status); |
482 | } | 518 | } |
483 | 519 | ||
484 | #ifdef CONFIG_SERIAL_MUX_CONSOLE | ||
485 | register_console(&mux_console); | ||
486 | #endif | ||
487 | return 0; | 520 | return 0; |
488 | } | 521 | } |
489 | 522 | ||
523 | static int __devexit mux_remove(struct parisc_device *dev) | ||
524 | { | ||
525 | int i, j; | ||
526 | int port_count = (long)dev_get_drvdata(&dev->dev); | ||
527 | |||
528 | /* Find Port 0 for this card in the mux_ports list. */ | ||
529 | for(i = 0; i < port_cnt; ++i) { | ||
530 | if(mux_ports[i].port.mapbase == dev->hpa.start + MUX_OFFSET) | ||
531 | break; | ||
532 | } | ||
533 | BUG_ON(i + port_count > port_cnt); | ||
534 | |||
535 | /* Release the resources associated with each port on the device. */ | ||
536 | for(j = 0; j < port_count; ++j, ++i) { | ||
537 | struct uart_port *port = &mux_ports[i].port; | ||
538 | |||
539 | uart_remove_one_port(&mux_driver, port); | ||
540 | if(port->membase) | ||
541 | iounmap(port->membase); | ||
542 | } | ||
543 | |||
544 | release_mem_region(dev->hpa.start + MUX_OFFSET, port_count * MUX_LINE_OFFSET); | ||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | /* Hack. This idea was taken from the 8250_gsc.c on how to properly order | ||
549 | * the serial port detection in the proper order. The idea is we always | ||
550 | * want the builtin mux to be detected before addin mux cards, so we | ||
551 | * specifically probe for the builtin mux cards first. | ||
552 | * | ||
553 | * This table only contains the parisc_device_id of known builtin mux | ||
554 | * devices. All other mux cards will be detected by the generic mux_tbl. | ||
555 | */ | ||
556 | static struct parisc_device_id builtin_mux_tbl[] = { | ||
557 | { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */ | ||
558 | { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */ | ||
559 | { 0, } | ||
560 | }; | ||
561 | |||
490 | static struct parisc_device_id mux_tbl[] = { | 562 | static struct parisc_device_id mux_tbl[] = { |
491 | { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D }, | 563 | { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D }, |
492 | { 0, } | 564 | { 0, } |
493 | }; | 565 | }; |
494 | 566 | ||
567 | MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl); | ||
495 | MODULE_DEVICE_TABLE(parisc, mux_tbl); | 568 | MODULE_DEVICE_TABLE(parisc, mux_tbl); |
496 | 569 | ||
570 | static struct parisc_driver builtin_serial_mux_driver = { | ||
571 | .name = "builtin_serial_mux", | ||
572 | .id_table = builtin_mux_tbl, | ||
573 | .probe = mux_probe, | ||
574 | .remove = __devexit_p(mux_remove), | ||
575 | }; | ||
576 | |||
497 | static struct parisc_driver serial_mux_driver = { | 577 | static struct parisc_driver serial_mux_driver = { |
498 | .name = "serial_mux", | 578 | .name = "serial_mux", |
499 | .id_table = mux_tbl, | 579 | .id_table = mux_tbl, |
500 | .probe = mux_probe, | 580 | .probe = mux_probe, |
581 | .remove = __devexit_p(mux_remove), | ||
501 | }; | 582 | }; |
502 | 583 | ||
503 | /** | 584 | /** |
@@ -507,7 +588,21 @@ static struct parisc_driver serial_mux_driver = { | |||
507 | */ | 588 | */ |
508 | static int __init mux_init(void) | 589 | static int __init mux_init(void) |
509 | { | 590 | { |
510 | return register_parisc_driver(&serial_mux_driver); | 591 | register_parisc_driver(&builtin_serial_mux_driver); |
592 | register_parisc_driver(&serial_mux_driver); | ||
593 | |||
594 | if(port_cnt > 0) { | ||
595 | /* Start the Mux timer */ | ||
596 | init_timer(&mux_timer); | ||
597 | mux_timer.function = mux_poll; | ||
598 | mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY); | ||
599 | |||
600 | #ifdef CONFIG_SERIAL_MUX_CONSOLE | ||
601 | register_console(&mux_console); | ||
602 | #endif | ||
603 | } | ||
604 | |||
605 | return 0; | ||
511 | } | 606 | } |
512 | 607 | ||
513 | /** | 608 | /** |
@@ -517,14 +612,16 @@ static int __init mux_init(void) | |||
517 | */ | 612 | */ |
518 | static void __exit mux_exit(void) | 613 | static void __exit mux_exit(void) |
519 | { | 614 | { |
520 | int i; | 615 | /* Delete the Mux timer. */ |
521 | 616 | if(port_cnt > 0) { | |
522 | for (i = 0; i < port_cnt; i++) { | 617 | del_timer(&mux_timer); |
523 | uart_remove_one_port(&mux_driver, &mux_ports[i]); | 618 | #ifdef CONFIG_SERIAL_MUX_CONSOLE |
524 | if (mux_ports[i].membase) | 619 | unregister_console(&mux_console); |
525 | iounmap(mux_ports[i].membase); | 620 | #endif |
526 | } | 621 | } |
527 | 622 | ||
623 | unregister_parisc_driver(&builtin_serial_mux_driver); | ||
624 | unregister_parisc_driver(&serial_mux_driver); | ||
528 | uart_unregister_driver(&mux_driver); | 625 | uart_unregister_driver(&mux_driver); |
529 | } | 626 | } |
530 | 627 | ||