Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da8cadb3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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.
parents 02ec96be 0de56d1a
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -476,7 +476,7 @@ static inline void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpuma
 */
static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
{
	u64 pstate, ver;
	u64 pstate, ver, busy_mask;
	int nack_busy_id, is_jbus, need_more;

	if (cpus_empty(mask))
@@ -508,14 +508,20 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
			       "i" (ASI_INTR_W));

	nack_busy_id = 0;
	busy_mask = 0;
	{
		int i;

		for_each_cpu_mask(i, mask) {
			u64 target = (i << 14) | 0x70;

			if (!is_jbus)
			if (is_jbus) {
				busy_mask |= (0x1UL << (i * 2));
			} else {
				target |= (nack_busy_id << 24);
				busy_mask |= (0x1UL <<
					      (nack_busy_id * 2));
			}
			__asm__ __volatile__(
				"stxa	%%g0, [%0] %1\n\t"
				"membar	#Sync\n\t"
@@ -531,15 +537,16 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas

	/* Now, poll for completion. */
	{
		u64 dispatch_stat;
		u64 dispatch_stat, nack_mask;
		long stuck;

		stuck = 100000 * nack_busy_id;
		nack_mask = busy_mask << 1;
		do {
			__asm__ __volatile__("ldxa	[%%g0] %1, %0"
					     : "=r" (dispatch_stat)
					     : "i" (ASI_INTR_DISPATCH_STAT));
			if (dispatch_stat == 0UL) {
			if (!(dispatch_stat & (busy_mask | nack_mask))) {
				__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
						     : : "r" (pstate));
				if (unlikely(need_more)) {
@@ -556,12 +563,12 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
			}
			if (!--stuck)
				break;
		} while (dispatch_stat & 0x5555555555555555UL);
		} while (dispatch_stat & busy_mask);

		__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
				     : : "r" (pstate));

		if ((dispatch_stat & ~(0x5555555555555555UL)) == 0) {
		if (dispatch_stat & busy_mask) {
			/* Busy bits will not clear, continue instead
			 * of freezing up on this cpu.
			 */
+28 −5
Original line number Diff line number Diff line
@@ -23,11 +23,36 @@

#include "suncore.h"

int sunserial_current_minor = 64;
static int sunserial_current_minor = 64;

EXPORT_SYMBOL(sunserial_current_minor);
int sunserial_register_minors(struct uart_driver *drv, int count)
{
	int err = 0;

	drv->minor = sunserial_current_minor;
	drv->nr += count;
	/* Register the driver on the first call */
	if (drv->nr == count)
		err = uart_register_driver(drv);
	if (err == 0) {
		sunserial_current_minor += count;
		drv->tty_driver->name_base = drv->minor - 64;
	}
	return err;
}
EXPORT_SYMBOL(sunserial_register_minors);

void sunserial_unregister_minors(struct uart_driver *drv, int count)
{
	drv->nr -= count;
	sunserial_current_minor -= count;

	if (drv->nr == 0)
		uart_unregister_driver(drv);
}
EXPORT_SYMBOL(sunserial_unregister_minors);

int sunserial_console_match(struct console *con, struct device_node *dp,
int __init sunserial_console_match(struct console *con, struct device_node *dp,
			    struct uart_driver *drv, int line)
{
	int off;
@@ -133,8 +158,6 @@ sunserial_console_termios(struct console *con)
	con->cflag = cflag;
}

EXPORT_SYMBOL(sunserial_console_termios);

/* Sun serial MOUSE auto baud rate detection.  */
static struct mouse_baud_cflag {
	int baud;
+2 −1
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@
extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *);
extern int suncore_mouse_baud_detection(unsigned char, int);

extern int sunserial_current_minor;
extern int sunserial_register_minors(struct uart_driver *, int);
extern void sunserial_unregister_minors(struct uart_driver *, int);

extern int sunserial_console_match(struct console *, struct device_node *,
				   struct uart_driver *, int);
+3 −11
Original line number Diff line number Diff line
@@ -562,16 +562,10 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m

	port->dev = &op->dev;

	sunhv_reg.minor = sunserial_current_minor;
	sunhv_reg.nr = 1;

	err = uart_register_driver(&sunhv_reg);
	err = sunserial_register_minors(&sunhv_reg, 1);
	if (err)
		goto out_free_con_read_page;

	sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64;
	sunserial_current_minor += 1;

	sunserial_console_match(&sunhv_console, op->node,
				&sunhv_reg, port->line);

@@ -591,8 +585,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
	uart_remove_one_port(&sunhv_reg, port);

out_unregister_driver:
	sunserial_current_minor -= 1;
	uart_unregister_driver(&sunhv_reg);
	sunserial_unregister_minors(&sunhv_reg, 1);

out_free_con_read_page:
	kfree(con_read_page);
@@ -614,8 +607,7 @@ static int __devexit hv_remove(struct of_device *dev)

	uart_remove_one_port(&sunhv_reg, port);

	sunserial_current_minor -= 1;
	uart_unregister_driver(&sunhv_reg);
	sunserial_unregister_minors(&sunhv_reg, 1);

	kfree(port);
	sunhv_port = NULL;
+4 −12
Original line number Diff line number Diff line
@@ -832,7 +832,6 @@ static struct uart_driver sunsab_reg = {
};

static struct uart_sunsab_port *sunsab_ports;
static int num_channels;

#ifdef CONFIG_SERIAL_SUNSAB_CONSOLE

@@ -1102,8 +1101,8 @@ static int __init sunsab_init(void)
{
	struct device_node *dp;
	int err;
	int num_channels = 0;

	num_channels = 0;
	for_each_node_by_name(dp, "se")
		num_channels += 2;
	for_each_node_by_name(dp, "serial") {
@@ -1117,20 +1116,14 @@ static int __init sunsab_init(void)
		if (!sunsab_ports)
			return -ENOMEM;

		sunsab_reg.minor = sunserial_current_minor;
		sunsab_reg.nr = num_channels;
		sunsab_reg.cons = SUNSAB_CONSOLE();

		err = uart_register_driver(&sunsab_reg);
		err = sunserial_register_minors(&sunsab_reg, num_channels);
		if (err) {
			kfree(sunsab_ports);
			sunsab_ports = NULL;

			return err;
		}

		sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64;
		sunserial_current_minor += num_channels;
	}

	return of_register_driver(&sab_driver, &of_bus_type);
@@ -1139,9 +1132,8 @@ static int __init sunsab_init(void)
static void __exit sunsab_exit(void)
{
	of_unregister_driver(&sab_driver);
	if (num_channels) {
		sunserial_current_minor -= num_channels;
		uart_unregister_driver(&sunsab_reg);
	if (sunsab_reg.nr) {
		sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr);
	}

	kfree(sunsab_ports);
Loading