diff options
Diffstat (limited to 'arch/powerpc/kernel/legacy_serial.c')
| -rw-r--r-- | arch/powerpc/kernel/legacy_serial.c | 57 | 
1 files changed, 33 insertions, 24 deletions
| diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 4cf0b971976b..7e98e778b52f 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -28,6 +28,7 @@ static struct legacy_serial_info {  	struct device_node		*np;  	unsigned int			speed;  	unsigned int			clock; +	int				irq_check_parent;  	phys_addr_t			taddr;  } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];  static unsigned int legacy_serial_count; @@ -36,7 +37,7 @@ static int legacy_serial_console = -1;  static int __init add_legacy_port(struct device_node *np, int want_index,  				  int iotype, phys_addr_t base,  				  phys_addr_t taddr, unsigned long irq, -				  upf_t flags) +				  upf_t flags, int irq_check_parent)  {  	u32 *clk, *spd, clock = BASE_BAUD * 16;  	int index; @@ -68,7 +69,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,  	if (legacy_serial_infos[index].np != 0) {  		/* if we still have some room, move it, else override */  		if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) { -			printk(KERN_INFO "Moved legacy port %d -> %d\n", +			printk(KERN_DEBUG "Moved legacy port %d -> %d\n",  			       index, legacy_serial_count);  			legacy_serial_ports[legacy_serial_count] =  				legacy_serial_ports[index]; @@ -76,7 +77,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,  				legacy_serial_infos[index];  			legacy_serial_count++;  		} else { -			printk(KERN_INFO "Replacing legacy port %d\n", index); +			printk(KERN_DEBUG "Replacing legacy port %d\n", index);  		}  	} @@ -95,10 +96,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index,  	legacy_serial_infos[index].np = of_node_get(np);  	legacy_serial_infos[index].clock = clock;  	legacy_serial_infos[index].speed = spd ? *spd : 0; +	legacy_serial_infos[index].irq_check_parent = irq_check_parent; -	printk(KERN_INFO "Found legacy serial port %d for %s\n", +	printk(KERN_DEBUG "Found legacy serial port %d for %s\n",  	       index, np->full_name); -	printk(KERN_INFO "  %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", +	printk(KERN_DEBUG "  %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",  	       (iotype == UPIO_PORT) ? "port" : "mem",  	       (unsigned long long)base, (unsigned long long)taddr, irq,  	       legacy_serial_ports[index].uartclk, @@ -126,11 +128,13 @@ static int __init add_legacy_soc_port(struct device_node *np,  		return -1;  	addr = of_translate_address(soc_dev, addrp); +	if (addr == OF_BAD_ADDR) +		return -1;  	/* Add port, irq will be dealt with later. We passed a translated  	 * IO port value. It will be fixed up later along with the irq  	 */ -	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags); +	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);  }  static int __init add_legacy_isa_port(struct device_node *np, @@ -141,6 +145,8 @@ static int __init add_legacy_isa_port(struct device_node *np,  	int index = -1;  	phys_addr_t taddr; +	DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); +  	/* Get the ISA port number */  	reg = (u32 *)get_property(np, "reg", NULL);  	if (reg == NULL) @@ -161,9 +167,12 @@ static int __init add_legacy_isa_port(struct device_node *np,  	/* Translate ISA address */  	taddr = of_translate_address(np, reg); +	if (taddr == OF_BAD_ADDR) +		return -1;  	/* Add port, irq will be dealt with later */ -	return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF); +	return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, +			       NO_IRQ, UPF_BOOT_AUTOCONF, 0);  } @@ -176,6 +185,8 @@ static int __init add_legacy_pci_port(struct device_node *np,  	unsigned int flags;  	int iotype, index = -1, lindex = 0; +	DBG(" -> add_legacy_pci_port(%s)\n", np->full_name); +  	/* We only support ports that have a clock frequency properly  	 * encoded in the device-tree (that is have an fcode). Anything  	 * else can't be used that early and will be normally probed by @@ -194,6 +205,8 @@ static int __init add_legacy_pci_port(struct device_node *np,  	/* We only support BAR 0 for now */  	iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;  	addr = of_translate_address(pci_dev, addrp); +	if (addr == OF_BAD_ADDR) +		return -1;  	/* Set the IO base to the same as the translated address for MMIO,  	 * or to the domain local IO base for PIO (it will be fixed up later) @@ -231,7 +244,8 @@ static int __init add_legacy_pci_port(struct device_node *np,  	/* Add port, irq will be dealt with later. We passed a translated  	 * IO port value. It will be fixed up later along with the irq  	 */ -	return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF); +	return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, +			       UPF_BOOT_AUTOCONF, np != pci_dev);  }  #endif @@ -362,27 +376,22 @@ static void __init fixup_port_irq(int index,  				  struct device_node *np,  				  struct plat_serial8250_port *port)  { +	unsigned int virq; +  	DBG("fixup_port_irq(%d)\n", index); -	/* Check for interrupts in that node */ -	if (np->n_intrs > 0) { -		port->irq = np->intrs[0].line; -		DBG(" port %d (%s), irq=%d\n", -		    index, np->full_name, port->irq); -		return; +	virq = irq_of_parse_and_map(np, 0); +	if (virq == NO_IRQ && legacy_serial_infos[index].irq_check_parent) { +		np = of_get_parent(np); +		if (np == NULL) +			return; +		virq = irq_of_parse_and_map(np, 0); +		of_node_put(np);  	} - -	/* Check for interrupts in the parent */ -	np = of_get_parent(np); -	if (np == NULL) +	if (virq == NO_IRQ)  		return; -	if (np->n_intrs > 0) { -		port->irq = np->intrs[0].line; -		DBG(" port %d (%s), irq=%d\n", -		    index, np->full_name, port->irq); -	} -	of_node_put(np); +	port->irq = virq;  }  static void __init fixup_port_pio(int index, | 
