Exemplo n.º 1
0
/*
 * Setup one port structure after probing, HW is down at this point,
 * Unlike sunzilog, we don't need to pre-init the spinlock as we don't
 * register our console before uart_add_one_port() is called
 */
static int __init pmz_init_port(struct uart_pmac_port *uap)
{
	struct device_node *np = uap->node;
	const char *conn;
	const struct slot_names_prop {
		int	count;
		char	name[1];
	} *slots;
	int len;
	struct resource r_ports, r_rxdma, r_txdma;

	/*
	 * Request & map chip registers
	 */
	if (of_address_to_resource(np, 0, &r_ports))
		return -ENODEV;
	uap->port.mapbase = r_ports.start;
	uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
      
	uap->control_reg = uap->port.membase;
	uap->data_reg = uap->control_reg + 0x10;
	
	/*
	 * Request & map DBDMA registers
	 */
#ifdef HAS_DBDMA
	if (of_address_to_resource(np, 1, &r_txdma) == 0 &&
	    of_address_to_resource(np, 2, &r_rxdma) == 0)
		uap->flags |= PMACZILOG_FLAG_HAS_DMA;
#else
	memset(&r_txdma, 0, sizeof(struct resource));
	memset(&r_rxdma, 0, sizeof(struct resource));
#endif	
	if (ZS_HAS_DMA(uap)) {
		uap->tx_dma_regs = ioremap(r_txdma.start, 0x100);
		if (uap->tx_dma_regs == NULL) {	
			uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
			goto no_dma;
		}
		uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100);
		if (uap->rx_dma_regs == NULL) {	
			iounmap(uap->tx_dma_regs);
			uap->tx_dma_regs = NULL;
			uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
			goto no_dma;
		}
		uap->tx_dma_irq = irq_of_parse_and_map(np, 1);
		uap->rx_dma_irq = irq_of_parse_and_map(np, 2);
	}
no_dma:

	/*
	 * Detect port type
	 */
	if (of_device_is_compatible(np, "cobalt"))
		uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
	conn = of_get_property(np, "AAPL,connector", &len);
	if (conn && (strcmp(conn, "infrared") == 0))
		uap->flags |= PMACZILOG_FLAG_IS_IRDA;
	uap->port_type = PMAC_SCC_ASYNC;
	/* 1999 Powerbook G3 has slot-names property instead */
	slots = of_get_property(np, "slot-names", &len);
	if (slots && slots->count > 0) {
		if (strcmp(slots->name, "IrDA") == 0)
			uap->flags |= PMACZILOG_FLAG_IS_IRDA;
		else if (strcmp(slots->name, "Modem") == 0)
			uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
	}
	if (ZS_IS_IRDA(uap))
		uap->port_type = PMAC_SCC_IRDA;
	if (ZS_IS_INTMODEM(uap)) {
		struct device_node* i2c_modem =
			of_find_node_by_name(NULL, "i2c-modem");
		if (i2c_modem) {
			const char* mid =
				of_get_property(i2c_modem, "modem-id", NULL);
			if (mid) switch(*mid) {
			case 0x04 :
			case 0x05 :
			case 0x07 :
			case 0x08 :
			case 0x0b :
			case 0x0c :
				uap->port_type = PMAC_SCC_I2S1;
			}
			printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n",
				mid ? (*mid) : 0);
			of_node_put(i2c_modem);
		} else {
			printk(KERN_INFO "pmac_zilog: serial modem detected\n");
		}
	}

	/*
	 * Init remaining bits of "port" structure
	 */
	uap->port.iotype = UPIO_MEM;
	uap->port.irq = irq_of_parse_and_map(np, 0);
	uap->port.uartclk = ZS_CLOCK;
	uap->port.fifosize = 1;
	uap->port.ops = &pmz_pops;
	uap->port.type = PORT_PMAC_ZILOG;
	uap->port.flags = 0;

	/* Setup some valid baud rate information in the register
	 * shadows so we don't write crap there before baud rate is
	 * first initialized.
	 */
	pmz_convert_to_zs(uap, CS8, 0, 9600);

	return 0;
}
Exemplo n.º 2
0
/*
 * Setup one port structure after probing, HW is down at this point,
 * Unlike sunzilog, we don't need to pre-init the spinlock as we don't
 * register our console before uart_add_one_port() is called
 */
static int __init pmz_init_port(struct uart_pmac_port *uap)
{
	struct device_node *np = uap->node;
	char *conn;
	struct slot_names_prop {
		int	count;
		char	name[1];
	} *slots;
	int len;

	/*
	 * Request & map chip registers
	 */
	uap->port.mapbase = np->addrs[0].address;
	uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
      
	uap->control_reg = (volatile u8 *)uap->port.membase;
	uap->data_reg = uap->control_reg + 0x10;
	
	/*
	 * Request & map DBDMA registers
	 */
#ifdef HAS_DBDMA
	if (np->n_addrs >= 3 && np->n_intrs >= 3)
		uap->flags |= PMACZILOG_FLAG_HAS_DMA;
#endif	
	if (ZS_HAS_DMA(uap)) {
		uap->tx_dma_regs = (volatile struct dbdma_regs *)
			ioremap(np->addrs[np->n_addrs - 2].address, 0x1000);
		if (uap->tx_dma_regs == NULL) {	
			uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
			goto no_dma;
		}
		uap->rx_dma_regs = (volatile struct dbdma_regs *)
			ioremap(np->addrs[np->n_addrs - 1].address, 0x1000);
		if (uap->rx_dma_regs == NULL) {	
			iounmap((void *)uap->tx_dma_regs);
			uap->tx_dma_regs = NULL;
			uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
			goto no_dma;
		}
		uap->tx_dma_irq = np->intrs[1].line;
		uap->rx_dma_irq = np->intrs[2].line;
	}
no_dma:

	/*
	 * Detect port type
	 */
	if (device_is_compatible(np, "cobalt"))
		uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
	conn = get_property(np, "AAPL,connector", &len);
	if (conn && (strcmp(conn, "infrared") == 0))
		uap->flags |= PMACZILOG_FLAG_IS_IRDA;
	uap->port_type = PMAC_SCC_ASYNC;
	/* 1999 Powerbook G3 has slot-names property instead */
	slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
	if (slots && slots->count > 0) {
		if (strcmp(slots->name, "IrDA") == 0)
			uap->flags |= PMACZILOG_FLAG_IS_IRDA;
		else if (strcmp(slots->name, "Modem") == 0)
			uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
	}
	if (ZS_IS_IRDA(uap))
		uap->port_type = PMAC_SCC_IRDA;
	if (ZS_IS_INTMODEM(uap)) {
		struct device_node* i2c_modem = find_devices("i2c-modem");
		if (i2c_modem) {
			char* mid = get_property(i2c_modem, "modem-id", NULL);
			if (mid) switch(*mid) {
			case 0x04 :
			case 0x05 :
			case 0x07 :
			case 0x08 :
			case 0x0b :
			case 0x0c :
				uap->port_type = PMAC_SCC_I2S1;
			}
			printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n",
				mid ? (*mid) : 0);
		} else {
			printk(KERN_INFO "pmac_zilog: serial modem detected\n");
		}
	}

	/*
	 * Init remaining bits of "port" structure
	 */
	uap->port.iotype = SERIAL_IO_MEM;
	uap->port.irq = np->intrs[0].line;
	uap->port.uartclk = ZS_CLOCK;
	uap->port.fifosize = 1;
	uap->port.ops = &pmz_pops;
	uap->port.type = PORT_PMAC_ZILOG;
	uap->port.flags = 0;

	/* Setup some valid baud rate information in the register
	 * shadows so we don't write crap there before baud rate is
	 * first initialized.
	 */
	pmz_convert_to_zs(uap, CS8, 0, 9600);

	return 0;
}