aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-12 12:52:12 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-12 12:52:12 -0500
commitda8cadb31b82c9d41fc593c8deab6aa20b162d6b (patch)
tree5640a34aa485f254de503a17833046645ade47f6
parent02ec96be2b45d9f2712687ad107038ef390b24c2 (diff)
parent0de56d1ab83323d604d95ca193dcbd28388dbabb (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC64]: Fix endless loop in cheetah_xcall_deliver(). [SERIAL] sparc: Infrastructure to fix section mismatch bugs.
-rw-r--r--arch/sparc64/kernel/smp.c19
-rw-r--r--drivers/serial/suncore.c33
-rw-r--r--drivers/serial/suncore.h3
-rw-r--r--drivers/serial/sunhv.c14
-rw-r--r--drivers/serial/sunsab.c16
-rw-r--r--drivers/serial/sunsu.c16
-rw-r--r--drivers/serial/sunzilog.c41
7 files changed, 71 insertions, 71 deletions
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 894b506f9636..c39944927f1a 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -476,7 +476,7 @@ static inline void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpuma
476 */ 476 */
477static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) 477static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
478{ 478{
479 u64 pstate, ver; 479 u64 pstate, ver, busy_mask;
480 int nack_busy_id, is_jbus, need_more; 480 int nack_busy_id, is_jbus, need_more;
481 481
482 if (cpus_empty(mask)) 482 if (cpus_empty(mask))
@@ -508,14 +508,20 @@ retry:
508 "i" (ASI_INTR_W)); 508 "i" (ASI_INTR_W));
509 509
510 nack_busy_id = 0; 510 nack_busy_id = 0;
511 busy_mask = 0;
511 { 512 {
512 int i; 513 int i;
513 514
514 for_each_cpu_mask(i, mask) { 515 for_each_cpu_mask(i, mask) {
515 u64 target = (i << 14) | 0x70; 516 u64 target = (i << 14) | 0x70;
516 517
517 if (!is_jbus) 518 if (is_jbus) {
519 busy_mask |= (0x1UL << (i * 2));
520 } else {
518 target |= (nack_busy_id << 24); 521 target |= (nack_busy_id << 24);
522 busy_mask |= (0x1UL <<
523 (nack_busy_id * 2));
524 }
519 __asm__ __volatile__( 525 __asm__ __volatile__(
520 "stxa %%g0, [%0] %1\n\t" 526 "stxa %%g0, [%0] %1\n\t"
521 "membar #Sync\n\t" 527 "membar #Sync\n\t"
@@ -531,15 +537,16 @@ retry:
531 537
532 /* Now, poll for completion. */ 538 /* Now, poll for completion. */
533 { 539 {
534 u64 dispatch_stat; 540 u64 dispatch_stat, nack_mask;
535 long stuck; 541 long stuck;
536 542
537 stuck = 100000 * nack_busy_id; 543 stuck = 100000 * nack_busy_id;
544 nack_mask = busy_mask << 1;
538 do { 545 do {
539 __asm__ __volatile__("ldxa [%%g0] %1, %0" 546 __asm__ __volatile__("ldxa [%%g0] %1, %0"
540 : "=r" (dispatch_stat) 547 : "=r" (dispatch_stat)
541 : "i" (ASI_INTR_DISPATCH_STAT)); 548 : "i" (ASI_INTR_DISPATCH_STAT));
542 if (dispatch_stat == 0UL) { 549 if (!(dispatch_stat & (busy_mask | nack_mask))) {
543 __asm__ __volatile__("wrpr %0, 0x0, %%pstate" 550 __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
544 : : "r" (pstate)); 551 : : "r" (pstate));
545 if (unlikely(need_more)) { 552 if (unlikely(need_more)) {
@@ -556,12 +563,12 @@ retry:
556 } 563 }
557 if (!--stuck) 564 if (!--stuck)
558 break; 565 break;
559 } while (dispatch_stat & 0x5555555555555555UL); 566 } while (dispatch_stat & busy_mask);
560 567
561 __asm__ __volatile__("wrpr %0, 0x0, %%pstate" 568 __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
562 : : "r" (pstate)); 569 : : "r" (pstate));
563 570
564 if ((dispatch_stat & ~(0x5555555555555555UL)) == 0) { 571 if (dispatch_stat & busy_mask) {
565 /* Busy bits will not clear, continue instead 572 /* Busy bits will not clear, continue instead
566 * of freezing up on this cpu. 573 * of freezing up on this cpu.
567 */ 574 */
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index 70a09a3d5af0..707c5b03bce9 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -23,11 +23,36 @@
23 23
24#include "suncore.h" 24#include "suncore.h"
25 25
26int sunserial_current_minor = 64; 26static int sunserial_current_minor = 64;
27 27
28EXPORT_SYMBOL(sunserial_current_minor); 28int sunserial_register_minors(struct uart_driver *drv, int count)
29{
30 int err = 0;
31
32 drv->minor = sunserial_current_minor;
33 drv->nr += count;
34 /* Register the driver on the first call */
35 if (drv->nr == count)
36 err = uart_register_driver(drv);
37 if (err == 0) {
38 sunserial_current_minor += count;
39 drv->tty_driver->name_base = drv->minor - 64;
40 }
41 return err;
42}
43EXPORT_SYMBOL(sunserial_register_minors);
44
45void sunserial_unregister_minors(struct uart_driver *drv, int count)
46{
47 drv->nr -= count;
48 sunserial_current_minor -= count;
49
50 if (drv->nr == 0)
51 uart_unregister_driver(drv);
52}
53EXPORT_SYMBOL(sunserial_unregister_minors);
29 54
30int sunserial_console_match(struct console *con, struct device_node *dp, 55int __init sunserial_console_match(struct console *con, struct device_node *dp,
31 struct uart_driver *drv, int line) 56 struct uart_driver *drv, int line)
32{ 57{
33 int off; 58 int off;
@@ -133,8 +158,6 @@ sunserial_console_termios(struct console *con)
133 con->cflag = cflag; 158 con->cflag = cflag;
134} 159}
135 160
136EXPORT_SYMBOL(sunserial_console_termios);
137
138/* Sun serial MOUSE auto baud rate detection. */ 161/* Sun serial MOUSE auto baud rate detection. */
139static struct mouse_baud_cflag { 162static struct mouse_baud_cflag {
140 int baud; 163 int baud;
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h
index 829d7d65d6db..042668aa602e 100644
--- a/drivers/serial/suncore.h
+++ b/drivers/serial/suncore.h
@@ -22,7 +22,8 @@
22extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); 22extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *);
23extern int suncore_mouse_baud_detection(unsigned char, int); 23extern int suncore_mouse_baud_detection(unsigned char, int);
24 24
25extern int sunserial_current_minor; 25extern int sunserial_register_minors(struct uart_driver *, int);
26extern void sunserial_unregister_minors(struct uart_driver *, int);
26 27
27extern int sunserial_console_match(struct console *, struct device_node *, 28extern int sunserial_console_match(struct console *, struct device_node *,
28 struct uart_driver *, int); 29 struct uart_driver *, int);
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 8ff900b09811..be0fe152891b 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -562,16 +562,10 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
562 562
563 port->dev = &op->dev; 563 port->dev = &op->dev;
564 564
565 sunhv_reg.minor = sunserial_current_minor; 565 err = sunserial_register_minors(&sunhv_reg, 1);
566 sunhv_reg.nr = 1;
567
568 err = uart_register_driver(&sunhv_reg);
569 if (err) 566 if (err)
570 goto out_free_con_read_page; 567 goto out_free_con_read_page;
571 568
572 sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64;
573 sunserial_current_minor += 1;
574
575 sunserial_console_match(&sunhv_console, op->node, 569 sunserial_console_match(&sunhv_console, op->node,
576 &sunhv_reg, port->line); 570 &sunhv_reg, port->line);
577 571
@@ -591,8 +585,7 @@ out_remove_port:
591 uart_remove_one_port(&sunhv_reg, port); 585 uart_remove_one_port(&sunhv_reg, port);
592 586
593out_unregister_driver: 587out_unregister_driver:
594 sunserial_current_minor -= 1; 588 sunserial_unregister_minors(&sunhv_reg, 1);
595 uart_unregister_driver(&sunhv_reg);
596 589
597out_free_con_read_page: 590out_free_con_read_page:
598 kfree(con_read_page); 591 kfree(con_read_page);
@@ -614,8 +607,7 @@ static int __devexit hv_remove(struct of_device *dev)
614 607
615 uart_remove_one_port(&sunhv_reg, port); 608 uart_remove_one_port(&sunhv_reg, port);
616 609
617 sunserial_current_minor -= 1; 610 sunserial_unregister_minors(&sunhv_reg, 1);
618 uart_unregister_driver(&sunhv_reg);
619 611
620 kfree(port); 612 kfree(port);
621 sunhv_port = NULL; 613 sunhv_port = NULL;
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index ff610c23314b..543f93741e6f 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -832,7 +832,6 @@ static struct uart_driver sunsab_reg = {
832}; 832};
833 833
834static struct uart_sunsab_port *sunsab_ports; 834static struct uart_sunsab_port *sunsab_ports;
835static int num_channels;
836 835
837#ifdef CONFIG_SERIAL_SUNSAB_CONSOLE 836#ifdef CONFIG_SERIAL_SUNSAB_CONSOLE
838 837
@@ -1102,8 +1101,8 @@ static int __init sunsab_init(void)
1102{ 1101{
1103 struct device_node *dp; 1102 struct device_node *dp;
1104 int err; 1103 int err;
1104 int num_channels = 0;
1105 1105
1106 num_channels = 0;
1107 for_each_node_by_name(dp, "se") 1106 for_each_node_by_name(dp, "se")
1108 num_channels += 2; 1107 num_channels += 2;
1109 for_each_node_by_name(dp, "serial") { 1108 for_each_node_by_name(dp, "serial") {
@@ -1117,20 +1116,14 @@ static int __init sunsab_init(void)
1117 if (!sunsab_ports) 1116 if (!sunsab_ports)
1118 return -ENOMEM; 1117 return -ENOMEM;
1119 1118
1120 sunsab_reg.minor = sunserial_current_minor;
1121 sunsab_reg.nr = num_channels;
1122 sunsab_reg.cons = SUNSAB_CONSOLE(); 1119 sunsab_reg.cons = SUNSAB_CONSOLE();
1123 1120 err = sunserial_register_minors(&sunsab_reg, num_channels);
1124 err = uart_register_driver(&sunsab_reg);
1125 if (err) { 1121 if (err) {
1126 kfree(sunsab_ports); 1122 kfree(sunsab_ports);
1127 sunsab_ports = NULL; 1123 sunsab_ports = NULL;
1128 1124
1129 return err; 1125 return err;
1130 } 1126 }
1131
1132 sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64;
1133 sunserial_current_minor += num_channels;
1134 } 1127 }
1135 1128
1136 return of_register_driver(&sab_driver, &of_bus_type); 1129 return of_register_driver(&sab_driver, &of_bus_type);
@@ -1139,9 +1132,8 @@ static int __init sunsab_init(void)
1139static void __exit sunsab_exit(void) 1132static void __exit sunsab_exit(void)
1140{ 1133{
1141 of_unregister_driver(&sab_driver); 1134 of_unregister_driver(&sab_driver);
1142 if (num_channels) { 1135 if (sunsab_reg.nr) {
1143 sunserial_current_minor -= num_channels; 1136 sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr);
1144 uart_unregister_driver(&sunsab_reg);
1145 } 1137 }
1146 1138
1147 kfree(sunsab_ports); 1139 kfree(sunsab_ports);
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index e074943feff5..4e2302d43ab1 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1528,14 +1528,12 @@ static struct of_platform_driver su_driver = {
1528 .remove = __devexit_p(su_remove), 1528 .remove = __devexit_p(su_remove),
1529}; 1529};
1530 1530
1531static int num_uart;
1532
1533static int __init sunsu_init(void) 1531static int __init sunsu_init(void)
1534{ 1532{
1535 struct device_node *dp; 1533 struct device_node *dp;
1536 int err; 1534 int err;
1535 int num_uart = 0;
1537 1536
1538 num_uart = 0;
1539 for_each_node_by_name(dp, "su") { 1537 for_each_node_by_name(dp, "su") {
1540 if (su_get_type(dp) == SU_PORT_PORT) 1538 if (su_get_type(dp) == SU_PORT_PORT)
1541 num_uart++; 1539 num_uart++;
@@ -1552,26 +1550,22 @@ static int __init sunsu_init(void)
1552 } 1550 }
1553 1551
1554 if (num_uart) { 1552 if (num_uart) {
1555 sunsu_reg.minor = sunserial_current_minor; 1553 err = sunserial_register_minors(&sunsu_reg, num_uart);
1556 sunsu_reg.nr = num_uart;
1557 err = uart_register_driver(&sunsu_reg);
1558 if (err) 1554 if (err)
1559 return err; 1555 return err;
1560 sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
1561 sunserial_current_minor += num_uart;
1562 } 1556 }
1563 1557
1564 err = of_register_driver(&su_driver, &of_bus_type); 1558 err = of_register_driver(&su_driver, &of_bus_type);
1565 if (err && num_uart) 1559 if (err && num_uart)
1566 uart_unregister_driver(&sunsu_reg); 1560 sunserial_unregister_minors(&sunsu_reg, num_uart);
1567 1561
1568 return err; 1562 return err;
1569} 1563}
1570 1564
1571static void __exit sunsu_exit(void) 1565static void __exit sunsu_exit(void)
1572{ 1566{
1573 if (num_uart) 1567 if (sunsu_reg.nr)
1574 uart_unregister_driver(&sunsu_reg); 1568 sunserial_unregister_minors(&sunsu_reg, sunsu_reg.nr);
1575} 1569}
1576 1570
1577module_init(sunsu_init); 1571module_init(sunsu_init);
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 283bef0d24cb..cb2e40506379 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -63,10 +63,6 @@
63 readb(&((__channel)->control)) 63 readb(&((__channel)->control))
64#endif 64#endif
65 65
66static int num_sunzilog;
67#define NUM_SUNZILOG num_sunzilog
68#define NUM_CHANNELS (NUM_SUNZILOG * 2)
69
70#define ZS_CLOCK 4915200 /* Zilog input clock rate. */ 66#define ZS_CLOCK 4915200 /* Zilog input clock rate. */
71#define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ 67#define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */
72 68
@@ -1031,18 +1027,19 @@ static struct uart_driver sunzilog_reg = {
1031 .major = TTY_MAJOR, 1027 .major = TTY_MAJOR,
1032}; 1028};
1033 1029
1034static int __init sunzilog_alloc_tables(void) 1030static int __init sunzilog_alloc_tables(int num_sunzilog)
1035{ 1031{
1036 struct uart_sunzilog_port *up; 1032 struct uart_sunzilog_port *up;
1037 unsigned long size; 1033 unsigned long size;
1034 int num_channels = num_sunzilog * 2;
1038 int i; 1035 int i;
1039 1036
1040 size = NUM_CHANNELS * sizeof(struct uart_sunzilog_port); 1037 size = num_channels * sizeof(struct uart_sunzilog_port);
1041 sunzilog_port_table = kzalloc(size, GFP_KERNEL); 1038 sunzilog_port_table = kzalloc(size, GFP_KERNEL);
1042 if (!sunzilog_port_table) 1039 if (!sunzilog_port_table)
1043 return -ENOMEM; 1040 return -ENOMEM;
1044 1041
1045 for (i = 0; i < NUM_CHANNELS; i++) { 1042 for (i = 0; i < num_channels; i++) {
1046 up = &sunzilog_port_table[i]; 1043 up = &sunzilog_port_table[i];
1047 1044
1048 spin_lock_init(&up->port.lock); 1045 spin_lock_init(&up->port.lock);
@@ -1050,13 +1047,13 @@ static int __init sunzilog_alloc_tables(void)
1050 if (i == 0) 1047 if (i == 0)
1051 sunzilog_irq_chain = up; 1048 sunzilog_irq_chain = up;
1052 1049
1053 if (i < NUM_CHANNELS - 1) 1050 if (i < num_channels - 1)
1054 up->next = up + 1; 1051 up->next = up + 1;
1055 else 1052 else
1056 up->next = NULL; 1053 up->next = NULL;
1057 } 1054 }
1058 1055
1059 size = NUM_SUNZILOG * sizeof(struct zilog_layout __iomem *); 1056 size = num_sunzilog * sizeof(struct zilog_layout __iomem *);
1060 sunzilog_chip_regs = kzalloc(size, GFP_KERNEL); 1057 sunzilog_chip_regs = kzalloc(size, GFP_KERNEL);
1061 if (!sunzilog_chip_regs) { 1058 if (!sunzilog_chip_regs) {
1062 kfree(sunzilog_port_table); 1059 kfree(sunzilog_port_table);
@@ -1496,34 +1493,28 @@ static int __init sunzilog_init(void)
1496 struct device_node *dp; 1493 struct device_node *dp;
1497 int err, uart_count; 1494 int err, uart_count;
1498 int num_keybms; 1495 int num_keybms;
1496 int num_sunzilog = 0;
1499 1497
1500 NUM_SUNZILOG = 0;
1501 num_keybms = 0; 1498 num_keybms = 0;
1502 for_each_node_by_name(dp, "zs") { 1499 for_each_node_by_name(dp, "zs") {
1503 NUM_SUNZILOG++; 1500 num_sunzilog++;
1504 if (of_find_property(dp, "keyboard", NULL)) 1501 if (of_find_property(dp, "keyboard", NULL))
1505 num_keybms++; 1502 num_keybms++;
1506 } 1503 }
1507 1504
1508 uart_count = 0; 1505 uart_count = 0;
1509 if (NUM_SUNZILOG) { 1506 if (num_sunzilog) {
1510 int uart_count; 1507 int uart_count;
1511 1508
1512 err = sunzilog_alloc_tables(); 1509 err = sunzilog_alloc_tables(num_sunzilog);
1513 if (err) 1510 if (err)
1514 goto out; 1511 goto out;
1515 1512
1516 uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms); 1513 uart_count = (num_sunzilog * 2) - (2 * num_keybms);
1517 1514
1518 sunzilog_reg.nr = uart_count; 1515 err = sunserial_register_minors(&sunzilog_reg, uart_count);
1519 sunzilog_reg.minor = sunserial_current_minor;
1520 err = uart_register_driver(&sunzilog_reg);
1521 if (err) 1516 if (err)
1522 goto out_free_tables; 1517 goto out_free_tables;
1523
1524 sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
1525
1526 sunserial_current_minor += uart_count;
1527 } 1518 }
1528 1519
1529 err = of_register_driver(&zs_driver, &of_bus_type); 1520 err = of_register_driver(&zs_driver, &of_bus_type);
@@ -1557,8 +1548,8 @@ out_unregister_driver:
1557 of_unregister_driver(&zs_driver); 1548 of_unregister_driver(&zs_driver);
1558 1549
1559out_unregister_uart: 1550out_unregister_uart:
1560 if (NUM_SUNZILOG) { 1551 if (num_sunzilog) {
1561 uart_unregister_driver(&sunzilog_reg); 1552 sunserial_unregister_minors(&sunzilog_reg, num_sunzilog);
1562 sunzilog_reg.cons = NULL; 1553 sunzilog_reg.cons = NULL;
1563 } 1554 }
1564 1555
@@ -1590,8 +1581,8 @@ static void __exit sunzilog_exit(void)
1590 zilog_irq = -1; 1581 zilog_irq = -1;
1591 } 1582 }
1592 1583
1593 if (NUM_SUNZILOG) { 1584 if (sunzilog_reg.nr) {
1594 uart_unregister_driver(&sunzilog_reg); 1585 sunserial_unregister_minors(&sunzilog_reg, sunzilog_reg.nr);
1595 sunzilog_free_tables(); 1586 sunzilog_free_tables();
1596 } 1587 }
1597} 1588}