static int __devinit
sw_serial_probe(struct platform_device *dev)
{
    struct sw_serial_port *sport;
	int ret;
    
	sport = kzalloc(sizeof(struct sw_serial_port), GFP_KERNEL);
	if (!sport)
		return -ENOMEM;
    sport->port_no  = dev->id;
    sport->pdev     = dev;
    
    ret = sw_serial_get_config(sport, dev->id);
    if (ret) {
        printk(KERN_ERR "Failed to get config information\n");
        goto free_dev;
    }
    
    ret = sw_serial_get_resource(sport);
    if (ret) {
        printk(KERN_ERR "Failed to get resource\n");
        goto free_dev;
    }
    platform_set_drvdata(dev, sport);

    sport->port.irq     = sport->irq;
    sport->port.fifosize= 64;
	sport->port.regshift= 2;
    sport->port.iotype  = UPIO_DWAPB32;
    sport->port.flags   = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
    sport->port.uartclk = sport->sclk;
    sport->port.pm      = sw_serial_pm;
    sport->port.dev     = &dev->dev;
    
    sport->port.mapbase = sport->mmres->start;
    sw_serial[sport->port_no] = serial8250_register_port(&sport->port);
    UART_MSG("serial probe %d, membase %p irq %d mapbase 0x%08x\n", 
             dev->id, sport->port.membase, sport->port.irq, sport->port.mapbase);
    
	return 0;
free_dev:
    kfree(sport);
    sport = NULL;
    return ret;
}
static int __devinit
sw_serial_probe(struct platform_device *dev)
{
    struct sw_serial_port *sport;
    struct sw_serial_data *sdata;
    int ret;

    UART_INF("%s: uart%d probe\n", __func__, dev->id);
    sport = kzalloc(sizeof(struct sw_serial_port), GFP_KERNEL);
    if (!sport) {
		UART_ERR("%s: uart%d alloc memory for sw_serial port failed\n",
                __func__, dev->id);
        return -ENOMEM;
    }

    sdata = devm_kzalloc(&dev->dev, sizeof(*sdata), GFP_KERNEL);
    if (!sdata) {
		UART_ERR("%s: uart%d alloc memory for sdata failed\n", __func__,
                dev->id);
        return -ENOMEM;
    }
    sw_serial_uart[dev->id] = sport;
    sport->port_no  = dev->id;
    sport->pdev     = dev;

    ret = sw_serial_get_config(sport, dev->id);
    if (ret) {
        UART_ERR("%s: uart%d failed to get config information\n",
                __func__, sport->port_no);
        goto free_dev;
    }

    platform_set_drvdata(dev, sport);

    ret = sw_serial_get_resource(sport);
    if (ret) {
        UART_ERR("%s: uart%d failed to get resource\n", __func__,
                sport->port_no);
        goto free_dev;
    }

    sport->port.private_data = sdata;
    spin_lock_init(&sport->port.lock);
    sport->port.irq         = sport->irq;
    sport->port.fifosize    = 64;
    sport->port.regshift    = 2;
    sport->port.iotype      = UPIO_MEM32;
    sport->port.type        = PORT_U6_16550A;
    sport->port.flags       = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
    sport->port.serial_in   = sunxi_serial_in;
    sport->port.serial_out  = sunxi_serial_out;
    sport->port.uartclk     = sport->sclk;
    sport->port.pm          = sw_serial_pm;
    sport->port.dev         = &dev->dev;
    sport->port.membase     = (unsigned char __iomem *)sport->mmres->start + OFFSET;
    sport->port.mapbase     = sport->mmres->start;
    if (sport->irq != AW_IRQ_UART0)
        sdata->line = serial8250_register_port(&sport->port);
    else {
        UART_INF("%s: uart%d have been register as console\n", __func__,
                sport->port_no);
        sdata->line = 0;
    }
    if (sdata->line < 0) {
        ret = sdata->line;
        goto free_dev;
    }

    if (sdata->line) {
        clk_reset(sport->mod_clk, AW_CCU_CLK_RESET);
        clk_disable(sport->mod_clk);
        clk_disable(sport->bus_clk);
    }

	UART_INF("%s: uart%d probe done\n", __func__, sport->port_no);
    return 0;
free_dev:
    kfree(sport);
    kfree(sdata);
    sport = NULL;
    sdata = NULL;
    return ret;
}