static void handle_rx(struct uart_port *port, unsigned int misr) { struct tty_struct *tty = port->state->port.tty; unsigned int vid; unsigned int sr; int count = 0; struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); vid = msm_hsl_port->ver_id; if ((msm_hsl_read(port, regmap[vid][UARTDM_SR]) & UARTDM_SR_OVERRUN_BMSK)) { port->icount.overrun++; tty_insert_flip_char(tty, 0, TTY_OVERRUN); msm_hsl_write(port, RESET_ERROR_STATUS, regmap[vid][UARTDM_CR]); } if (misr & UARTDM_ISR_RXSTALE_BMSK) { count = msm_hsl_read(port, regmap[vid][UARTDM_RX_TOTAL_SNAP]) - msm_hsl_port->old_snap_state; msm_hsl_port->old_snap_state = 0; } else { count = 4 * (msm_hsl_read(port, regmap[vid][UARTDM_RFWR])); msm_hsl_port->old_snap_state += count; } while (count > 0) { unsigned int c; char flag = TTY_NORMAL; sr = msm_hsl_read(port, regmap[vid][UARTDM_SR]); if ((sr & UARTDM_SR_RXRDY_BMSK) == 0) { msm_hsl_port->old_snap_state -= count; break; } c = msm_hsl_read(port, regmap[vid][UARTDM_RF]); if (sr & UARTDM_SR_RX_BREAK_BMSK) { port->icount.brk++; if (uart_handle_break(port)) continue; } else if (sr & UARTDM_SR_PAR_FRAME_BMSK) { port->icount.frame++; } else { port->icount.rx++; } sr &= port->read_status_mask; if (sr & UARTDM_SR_RX_BREAK_BMSK) flag = TTY_BREAK; else if (sr & UARTDM_SR_PAR_FRAME_BMSK) flag = TTY_FRAME; tty_insert_flip_string(tty, (char *) &c, (count > 4) ? 4 : count); count -= 4; } tty_flip_buffer_push(tty); }
static unsigned int msm_serial_hsl_has_gsbi(struct uart_port *port) { D("%s: cir uart port[%d] is_uartdm=%d\n", __func__, (port)->line, UART_TO_MSM(port)->is_uartdm); return UART_TO_MSM(port)->is_uartdm; }
static int __devinit msm_serial_hsl_probe_cir(struct platform_device *pdev) { struct msm_hsl_port *msm_hsl_port; struct resource *uart_resource; struct resource *gsbi_resource; struct uart_port *port; const struct of_device_id *match; struct cir_platform_data *pdata; int ret; if (pdev->id == -1) pdev->id = atomic_inc_return(&msm_serial_hsl_next_id) - 1; if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial_cir: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; pdata = pdev->dev.platform_data; if (!pdata) { E("%s: Assign platform_data error!!\n", __func__); return -ENXIO; } msm_hsl_port = UART_TO_MSM(port); msm_hsl_port->cir_set_path= pdata->cir_set_path; msm_hsl_port->cir_reset = pdata->cir_reset; msm_hsl_port->cir_power = pdata->cir_power; if (msm_hsl_port->cir_set_path) msm_hsl_port->cir_set_path(PATH_CIR); if (msm_hsl_port->cir_power) msm_hsl_port->cir_power(1); htc_cir_port = msm_hsl_port; cir_enable_flg = PATH_CIR; match = of_match_device(msm_hsl_match_table, &pdev->dev); if (!match) msm_hsl_port->ver_id = UARTDM_VERSION_11_13; else { D("%s () match:port->line %d, ir\n", __func__, port->line); msm_hsl_port->ver_id = (unsigned int)match->data; } gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"); if (!gsbi_resource) { gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1); D("%s () gsbi_resourc:port->line %d, ir\n", __func__, port->line); } msm_hsl_port->clk = clk_get(&pdev->dev, "core_clk"); if (gsbi_resource) { printk(KERN_INFO "msm_serial_cir: get gsbi_uart_clk and gsbi_pclk\n"); msm_hsl_port->is_uartdm = 1; msm_hsl_port->pclk = clk_get(&pdev->dev, "iface_clk"); } else { printk(KERN_INFO "msm_serial_cir: get uartdm_clk\n"); msm_hsl_port->is_uartdm = 0; msm_hsl_port->pclk = NULL; } if (unlikely(IS_ERR(msm_hsl_port->clk))) { printk(KERN_ERR "%s: Error getting clk\n", __func__); return PTR_ERR(msm_hsl_port->clk); } if (unlikely(IS_ERR(msm_hsl_port->pclk))) { printk(KERN_ERR "%s: Error getting pclk\n", __func__); return PTR_ERR(msm_hsl_port->pclk); } uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uartdm_resource"); if (!uart_resource) uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!uart_resource)||(!uart_resource)) { printk(KERN_ERR "getting uartdm_resource failed\n"); return -ENXIO; } port->mapbase = uart_resource->start; printk(KERN_INFO "msm_serial_hsl: port[%d] mapbase:%x\n", port->line, port->mapbase); port->irq = platform_get_irq(pdev, 0); if (unlikely((int)port->irq < 0)) { printk(KERN_ERR "%s: getting irq failed\n", __func__); return -ENXIO; } device_set_wakeup_capable(&pdev->dev, 1); platform_set_drvdata(pdev, port); pm_runtime_enable(port->dev); #ifdef CONFIG_SERIAL_MSM_HSL_CONSOLE ret = device_create_file(&pdev->dev, &dev_attr_console); D("%s () device_create_file, port->line %d, ir\n", __func__, port->line); if (unlikely(ret)) E("%s():Can't create console attribute\n", __func__); #endif msm_hsl_debugfs_init(msm_hsl_port, pdev->id); if (msm_hsl_port->pclk) { clk_prepare_enable(msm_hsl_port->pclk); D("%s () clk_enable, port->line %d, ir\n", __func__, port->line); } ret = uart_add_one_port(&msm_hsl_uart_driver, port); if (msm_hsl_port->pclk) { D("%s () clk_disabl, port->line %d, ir\n", __func__, port->line); clk_disable_unprepare(msm_hsl_port->pclk); } D("%s ():port->line %d, ir\n", __func__, port->line); msm_hsl_port->irda_class = class_create(THIS_MODULE, "htc_irda"); if (IS_ERR(msm_hsl_port->irda_class)) { ret = PTR_ERR(msm_hsl_port->irda_class); msm_hsl_port->irda_class = NULL; return -ENXIO; } msm_hsl_port->irda_dev = device_create(msm_hsl_port->irda_class, NULL, 0, "%s", "irda"); if (unlikely(IS_ERR(msm_hsl_port->irda_dev))) { ret = PTR_ERR(msm_hsl_port->irda_dev); msm_hsl_port->irda_dev = NULL; goto err_create_ls_device; } ret = device_create_file(msm_hsl_port->irda_dev, &dev_attr_enable_irda); if (ret) goto err_create_ls_device_file; msm_hsl_port->cir_class = class_create(THIS_MODULE, "htc_cir"); if (IS_ERR(msm_hsl_port->cir_class)) { ret = PTR_ERR(msm_hsl_port->cir_class); msm_hsl_port->cir_class = NULL; return -ENXIO; } msm_hsl_port->cir_dev = device_create(msm_hsl_port->cir_class, NULL, 0, "%s", "cir"); if (unlikely(IS_ERR(msm_hsl_port->cir_dev))) { ret = PTR_ERR(msm_hsl_port->cir_dev); msm_hsl_port->cir_dev = NULL; goto err_create_ls_device; } ret = device_create_file(msm_hsl_port->cir_dev, &dev_attr_enable_cir); if (ret) goto err_create_ls_device_file; ret = device_create_file(msm_hsl_port->cir_dev, &dev_attr_reset_cir); if (ret) goto err_create_ls_device_file; return ret; err_create_ls_device_file: device_unregister(msm_hsl_port->cir_dev); err_create_ls_device: class_destroy(msm_hsl_port->cir_class); return ret; return ret; }
static int __init msm_serial_probe(struct platform_device *pdev) { struct msm_port *msm_port; struct resource *resource; struct uart_port *port; #if defined(CONFIG_KERNEL_MOTOROLA) struct vreg *vreg; #endif /* defined(CONFIG_KERNEL_MOTOROLA) */ if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial: detected port #%d\n", pdev->id); #ifdef CONFIG_MACH_CALGARY /* Calgary uses VREG_USIM (RUIM1) for the UART3 block */ if (pdev->id == 2) { vreg = vreg_get(0, "ruim"); if (IS_ERR(vreg)) printk(KERN_ERR "%s: vreg get failed for VREG_RUIM\n", __func__); else if (vreg_set_level(vreg, 2200)) printk(KERN_ERR "%s: vreg set level failed for VREG_RUIM\n", __func__); else if (vreg_enable(vreg)) printk(KERN_ERR "%s: vreg enable failed for VREG_RUIM\n", __func__); else printk(KERN_INFO "%s: VREG_RUIM enabled for RS232\n", __func__); } #endif #if defined(CONFIG_KERNEL_MOTOROLA) /* Calgary uses VREG_USIM (RUIM1) for the UART3 block */ if (pdev->id == 2) { vreg = vreg_get(0, "ruim"); if (IS_ERR(vreg)) printk(KERN_ERR "%s: vreg get failed for VREG_RUIM\n", __func__); else if (vreg_set_level(vreg, 2200)) printk(KERN_ERR "%s: vreg set level failed for VREG_RUIM\n", __func__); else if (vreg_enable(vreg)) printk(KERN_ERR "%s: vreg enable failed for VREG_RUIM\n", __func__); else printk(KERN_INFO "%s: VREG_RUIM enabled for RS232\n", __func__); } #endif /* defined(CONFIG_KERNEL_MOTOROLA) */ port = get_port_from_line(pdev->id); port->dev = &pdev->dev; msm_port = UART_TO_MSM(port); msm_port->clk = clk_get(&pdev->dev, "uart_clk"); if (unlikely(IS_ERR(msm_port->clk))) return PTR_ERR(msm_port->clk); port->uartclk = clk_get_rate(msm_port->clk); resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) return -ENXIO; port->mapbase = resource->start; port->irq = platform_get_irq(pdev, 0); if (unlikely(port->irq < 0)) return -ENXIO; platform_set_drvdata(pdev, port); if (unlikely(set_irq_wake(port->irq, 1))) return -ENXIO; #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP if (port->line == 0) /* BT is serial device 0 */ if (unlikely(set_irq_wake(MSM_GPIO_TO_INT(45), 1))) return -ENXIO; #endif #ifdef CONFIG_SERIAL_MSM_CLOCK_CONTROL msm_port->clk_state = MSM_CLK_PORT_OFF; hrtimer_init(&msm_port->clk_off_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); msm_port->clk_off_timer.function = msm_serial_clock_off; msm_port->clk_off_delay = ktime_set(0, 1000000); /* 1 ms */ #endif return uart_add_one_port(&msm_uart_driver, port); }
static void msm_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; unsigned int baud, mr; struct msm_port *msm_port = UART_TO_MSM(port); if (!termios->c_cflag) return; spin_lock_irqsave(&port->lock, flags); clk_enable(msm_port->clk); /* calculate and set baud rate */ baud = uart_get_baud_rate(port, termios, old, 300, 115200); msm_set_baud_rate(port, baud); /* calculate parity */ mr = msm_read(port, UART_MR2); mr &= ~UART_MR2_PARITY_MODE; if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) mr |= UART_MR2_PARITY_MODE_ODD; else if (termios->c_cflag & CMSPAR) mr |= UART_MR2_PARITY_MODE_SPACE; else mr |= UART_MR2_PARITY_MODE_EVEN; } /* calculate bits per char */ mr &= ~UART_MR2_BITS_PER_CHAR; switch (termios->c_cflag & CSIZE) { case CS5: mr |= UART_MR2_BITS_PER_CHAR_5; break; case CS6: mr |= UART_MR2_BITS_PER_CHAR_6; break; case CS7: mr |= UART_MR2_BITS_PER_CHAR_7; break; case CS8: default: mr |= UART_MR2_BITS_PER_CHAR_8; break; } /* calculate stop bits */ mr &= ~(UART_MR2_STOP_BIT_LEN_ONE | UART_MR2_STOP_BIT_LEN_TWO); if (termios->c_cflag & CSTOPB) mr |= UART_MR2_STOP_BIT_LEN_TWO; else mr |= UART_MR2_STOP_BIT_LEN_ONE; /* set parity, bits per char, and stop bit */ msm_write(port, mr, UART_MR2); /* calculate and set hardware flow control */ mr = msm_read(port, UART_MR1); mr &= ~(UART_MR1_CTS_CTL | UART_MR1_RX_RDY_CTL); if (termios->c_cflag & CRTSCTS) { mr |= UART_MR1_CTS_CTL; mr |= UART_MR1_RX_RDY_CTL; } msm_write(port, mr, UART_MR1); /* Configure status bits to ignore based on termio flags. */ port->read_status_mask = 0; if (termios->c_iflag & INPCK) port->read_status_mask |= UART_SR_PAR_FRAME_ERR; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= UART_SR_RX_BREAK; uart_update_timeout(port, termios->c_cflag, baud); clk_disable(msm_port->clk); spin_unlock_irqrestore(&port->lock, flags); }
static void msm_hsl_set_termios_cir(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; unsigned int baud, mr; unsigned int vid; spin_lock_irqsave(&port->lock, flags); baud = uart_get_baud_rate(port, termios, old, 300, 460800); msm_hsl_set_baud_rate(port, baud); vid = UART_TO_MSM(port)->ver_id; mr = msm_hsl_read(port, regmap[vid][UARTDM_MR2]); mr &= ~UARTDM_MR2_PARITY_MODE_BMSK; if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) mr |= ODD_PARITY; else if (termios->c_cflag & CMSPAR) mr |= SPACE_PARITY; else mr |= EVEN_PARITY; } mr &= ~UARTDM_MR2_BITS_PER_CHAR_BMSK; switch (termios->c_cflag & CSIZE) { case CS5: mr |= FIVE_BPC; break; case CS6: mr |= SIX_BPC; break; case CS7: mr |= SEVEN_BPC; break; case CS8: default: mr |= EIGHT_BPC; break; } mr &= ~(STOP_BIT_ONE | STOP_BIT_TWO); if (termios->c_cflag & CSTOPB) mr |= STOP_BIT_TWO; else mr |= STOP_BIT_ONE; msm_hsl_write(port, mr, regmap[vid][UARTDM_MR2]); mr = msm_hsl_read(port, regmap[vid][UARTDM_MR1]); mr &= ~(UARTDM_MR1_CTS_CTL_BMSK | UARTDM_MR1_RX_RDY_CTL_BMSK); if (termios->c_cflag & CRTSCTS) { mr |= UARTDM_MR1_CTS_CTL_BMSK; mr |= UARTDM_MR1_RX_RDY_CTL_BMSK; } msm_hsl_write(port, mr, regmap[vid][UARTDM_MR1]); port->read_status_mask = 0; if (termios->c_iflag & INPCK) port->read_status_mask |= UARTDM_SR_PAR_FRAME_BMSK; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= UARTDM_SR_RX_BREAK_BMSK; uart_update_timeout(port, termios->c_cflag, baud); spin_unlock_irqrestore(&port->lock, flags); D("%s: cir MR is 0x%x\n", __func__, mr); D("%s: cir baud is %d\n", __func__, baud); }
static int msm_serial_hsl_probe(struct platform_device *pdev) { struct msm_hsl_port *msm_hsl_port; struct resource *uart_resource; struct resource *gsbi_resource; struct uart_port *port; struct msm_serial_hslite_platform_data *pdata = pdev->dev.platform_data; int ret; if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial_hsl: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; msm_hsl_port = UART_TO_MSM(port); if (pdata && pdata->config_gpio) { ret = gpio_request(pdata->uart_tx_gpio, "UART_TX_GPIO"); if (unlikely(ret)) { printk(KERN_ERR "%s: gpio request failed for:" "%d\n", __func__, pdata->uart_tx_gpio); return ret; } ret = gpio_request(pdata->uart_rx_gpio, "UART_RX_GPIO"); if (unlikely(ret)) { printk(KERN_ERR "%s: gpio request failed for:" "%d\n", __func__, pdata->uart_rx_gpio); gpio_free(pdata->uart_tx_gpio); return ret; } } if (msm_serial_hsl_has_gsbi()) { gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"); if (unlikely(!gsbi_resource)) return -ENXIO; msm_hsl_port->clk = clk_get(&pdev->dev, "gsbi_uart_clk"); msm_hsl_port->pclk = clk_get(&pdev->dev, "gsbi_pclk"); } else { msm_hsl_port->clk = clk_get(&pdev->dev, "uartdm_clk"); msm_hsl_port->pclk = NULL; } if (unlikely(IS_ERR(msm_hsl_port->clk))) { printk(KERN_ERR "%s: Error getting clk\n", __func__); return PTR_ERR(msm_hsl_port->clk); } if (unlikely(IS_ERR(msm_hsl_port->pclk))) { printk(KERN_ERR "%s: Error getting pclk\n", __func__); return PTR_ERR(msm_hsl_port->pclk); } /* Set up the MREG/NREG/DREG/MNDREG */ ret = clk_set_rate(msm_hsl_port->clk, 7372800); if (ret) { printk(KERN_WARNING "Error setting clock rate on UART\n"); return ret; } uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uartdm_resource"); if (unlikely(!uart_resource)) { printk(KERN_ERR "getting uartdm_resource failed\n"); return -ENXIO; } port->mapbase = uart_resource->start; port->irq = platform_get_irq(pdev, 0); if (unlikely(port->irq < 0)) { printk(KERN_ERR "%s: getting irq failed\n", __func__); return -ENXIO; } device_set_wakeup_capable(&pdev->dev, 1); platform_set_drvdata(pdev, port); pm_runtime_enable(port->dev); ret = uart_add_one_port(&msm_hsl_uart_driver, port); return ret; }
static int msm_startup(struct uart_port *port) { struct msm_port *msm_port = UART_TO_MSM(port); unsigned int data, rfr_level; int ret; snprintf(msm_port->name, sizeof(msm_port->name), "msm_serial%d", port->line); ret = request_irq(port->irq, msm_irq, IRQF_TRIGGER_HIGH, msm_port->name, port); if (unlikely(ret)) return ret; msm_init_clock(port); if (likely(port->fifosize > 12)) rfr_level = port->fifosize - 12; else rfr_level = port->fifosize; /* set automatic RFR level */ data = msm_read(port, UART_MR1); data &= ~UART_MR1_AUTO_RFR_LEVEL1; data &= ~UART_MR1_AUTO_RFR_LEVEL0; data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2); data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level; msm_write(port, data, UART_MR1); /* make sure that RXSTALE count is non-zero */ data = msm_read(port, UART_IPR); if (unlikely(!data)) { data |= UART_IPR_RXSTALE_LAST; data |= UART_IPR_STALE_LSB; msm_write(port, data, UART_IPR); } data = 0; if (!port->cons || (port->cons && !(port->cons->flags & CON_ENABLED))) { msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR); msm_reset(port); data = UART_CR_TX_ENABLE; } data |= UART_CR_RX_ENABLE; msm_write(port, data, UART_CR); /* enable TX & RX */ /* Make sure IPR is not 0 to start with*/ if (msm_port->is_uartdm) msm_write(port, UART_IPR_STALE_LSB, UART_IPR); /* turn on RX and CTS interrupts */ msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE | UART_IMR_CURRENT_CTS; if (msm_port->is_uartdm) { msm_write(port, 0xFFFFFF, UARTDM_DMRX); msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR); } msm_write(port, msm_port->imr, UART_IMR); return 0; }
static int msm_hsl_startup_cir(struct uart_port *port) { struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); unsigned int data, rfr_level; unsigned int vid; int ret; unsigned long flags; snprintf(msm_hsl_port->name, sizeof(msm_hsl_port->name), "msm_serial_hsl%d", port->line); pr_info("%s () :port->line %d, ir\n", __func__, port->line); if (!(is_console(port)) || (!port->cons) || (port->cons && (!(port->cons->flags & CON_ENABLED)))) { if (msm_serial_hsl_has_gsbi(port)) { pr_info("%s () serial_hsl_has_gsbi:port->line %d, ir\n", __func__, port->line); if ((ioread32(msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR) & GSBI_PROTOCOL_I2C_UART) != GSBI_PROTOCOL_I2C_UART){ pr_info("%s: iowrite32i:port->line %d, i2c + uart\n", __func__, port->line); iowrite32(GSBI_PROTOCOL_I2C_UART, msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR); } } } #ifndef CONFIG_PM_RUNTIME msm_hsl_init_clock(port); #endif pm_runtime_get_sync(port->dev); if (likely(port->fifosize > 48)) rfr_level = port->fifosize - 16; else rfr_level = port->fifosize; rfr_level = (rfr_level / 4); spin_lock_irqsave(&port->lock, flags); vid = msm_hsl_port->ver_id; data = msm_hsl_read(port, regmap[vid][UARTDM_MR1]); data &= ~UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK; data &= ~UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK; data |= UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK & (rfr_level << 2); data |= UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK & rfr_level; msm_hsl_write(port, data, regmap[vid][UARTDM_MR1]); spin_unlock_irqrestore(&port->lock, flags); ret = request_irq(port->irq, msm_hsl_irq, IRQF_TRIGGER_HIGH, msm_hsl_port->name, port); if (unlikely(ret)) { printk(KERN_ERR "%s: failed to request_irq\n", __func__); return ret; } pr_info("%s ()ok:port->line %d, ir\n", __func__, port->line); return 0; }
static int msm_hsl_startup(struct uart_port *port) { struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); struct platform_device *pdev = to_platform_device(port->dev); const struct msm_serial_hslite_platform_data *pdata = pdev->dev.platform_data; unsigned int data, rfr_level; int ret; unsigned long flags; snprintf(msm_hsl_port->name, sizeof(msm_hsl_port->name), "msm_serial_hsl%d", port->line); if (!(is_console(port)) || (!port->cons) || (port->cons && (!(port->cons->flags & CON_ENABLED)))) { if (msm_serial_hsl_has_gsbi()) if ((ioread32(msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR) & GSBI_PROTOCOL_I2C_UART) != GSBI_PROTOCOL_I2C_UART) iowrite32(GSBI_PROTOCOL_I2C_UART, msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR); if (pdata && pdata->config_gpio) { ret = gpio_request(pdata->uart_tx_gpio, "UART_TX_GPIO"); if (unlikely(ret)) { pr_err("%s: gpio request failed for:%d\n", __func__, pdata->uart_tx_gpio); return ret; } ret = gpio_request(pdata->uart_rx_gpio, "UART_RX_GPIO"); if (unlikely(ret)) { pr_err("%s: gpio request failed for:%d\n", __func__, pdata->uart_rx_gpio); gpio_free(pdata->uart_tx_gpio); return ret; } } } #ifndef CONFIG_PM_RUNTIME msm_hsl_init_clock(port); #endif pm_runtime_get_sync(port->dev); if (likely(port->fifosize > 12)) rfr_level = port->fifosize - 12; else rfr_level = port->fifosize; spin_lock_irqsave(&port->lock, flags); /* set automatic RFR level */ data = msm_hsl_read(port, UARTDM_MR1_ADDR); data &= ~UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK; data &= ~UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK; data |= UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK & (rfr_level << 2); data |= UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK & rfr_level; msm_hsl_write(port, data, UARTDM_MR1_ADDR); spin_unlock_irqrestore(&port->lock, flags); ret = request_irq(port->irq, msm_hsl_irq, IRQF_TRIGGER_HIGH, msm_hsl_port->name, port); if (unlikely(ret)) { printk(KERN_ERR "%s: failed to request_irq\n", __func__); return ret; } return 0; }
static int msm_set_baud_rate(struct uart_port *port, unsigned int baud) { unsigned int baud_code, rxstale, watermark; struct msm_port *msm_port = UART_TO_MSM(port); switch (baud) { case 300: baud_code = UART_CSR_300; rxstale = 1; break; case 600: baud_code = UART_CSR_600; rxstale = 1; break; case 1200: baud_code = UART_CSR_1200; rxstale = 1; break; case 2400: baud_code = UART_CSR_2400; rxstale = 1; break; case 4800: baud_code = UART_CSR_4800; rxstale = 1; break; case 9600: baud_code = UART_CSR_9600; rxstale = 2; break; case 14400: baud_code = UART_CSR_14400; rxstale = 3; break; case 19200: baud_code = UART_CSR_19200; rxstale = 4; break; case 28800: baud_code = UART_CSR_28800; rxstale = 6; break; case 38400: baud_code = UART_CSR_38400; rxstale = 8; break; case 57600: baud_code = UART_CSR_57600; rxstale = 16; break; case 115200: default: baud_code = UART_CSR_115200; baud = 115200; rxstale = 31; break; } if (msm_port->is_uartdm) msm_write(port, UART_CR_CMD_RESET_RX, UART_CR); msm_write(port, baud_code, UART_CSR); /* RX stale watermark */ watermark = UART_IPR_STALE_LSB & rxstale; watermark |= UART_IPR_RXSTALE_LAST; watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2); msm_write(port, watermark, UART_IPR); /* set RX watermark */ watermark = (port->fifosize * 3) / 4; msm_write(port, watermark, UART_RFWR); /* set TX watermark */ msm_write(port, 10, UART_TFWR); if (msm_port->is_uartdm) { msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); msm_write(port, 0xFFFFFF, UARTDM_DMRX); msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR); } return baud; }
static void msm_hsl_set_baud_rate(struct uart_port *port, unsigned int baud) { unsigned int baud_code, rxstale, watermark; unsigned int data; struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); switch (baud) { case 300: baud_code = UARTDM_CSR_75; rxstale = 1; break; case 600: baud_code = UARTDM_CSR_150; rxstale = 1; break; case 1200: baud_code = UARTDM_CSR_300; rxstale = 1; break; case 2400: baud_code = UARTDM_CSR_600; rxstale = 1; break; case 4800: baud_code = UARTDM_CSR_1200; rxstale = 1; break; case 9600: baud_code = UARTDM_CSR_2400; rxstale = 2; break; case 14400: baud_code = UARTDM_CSR_3600; rxstale = 3; break; case 19200: baud_code = UARTDM_CSR_4800; rxstale = 4; break; case 28800: baud_code = UARTDM_CSR_7200; rxstale = 6; break; case 38400: baud_code = UARTDM_CSR_9600; rxstale = 8; break; case 57600: baud_code = UARTDM_CSR_14400; rxstale = 16; break; case 115200: baud_code = UARTDM_CSR_28800; rxstale = 31; break; case 230400: baud_code = UARTDM_CSR_57600; rxstale = 31; break; case 460800: baud_code = UARTDM_CSR_115200; rxstale = 31; break; default: /* 115200 baud rate */ baud_code = UARTDM_CSR_28800; rxstale = 31; break; } msm_hsl_write(port, baud_code, UARTDM_CSR_ADDR); /* RX stale watermark */ watermark = UARTDM_IPR_STALE_LSB_BMSK & rxstale; watermark |= UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK & (rxstale << 2); msm_hsl_write(port, watermark, UARTDM_IPR_ADDR); /* set RX watermark * Configure Rx Watermark as 3/4 size of Rx FIFO. * RFWR register takes value in Words for UARTDM Core * whereas it is consider to be in Bytes for UART Core. * Hence configuring Rx Watermark as 12 Words. */ watermark = (port->fifosize * 3) / (4 * 4); msm_hsl_write(port, watermark, UARTDM_RFWR_ADDR); /* set TX watermark */ msm_hsl_write(port, 0, UARTDM_TFWR_ADDR); msm_hsl_write(port, CR_PROTECTION_EN, UARTDM_CR_ADDR); msm_hsl_reset(port); data = UARTDM_CR_TX_EN_BMSK; data |= UARTDM_CR_RX_EN_BMSK; /* enable TX & RX */ msm_hsl_write(port, data, UARTDM_CR_ADDR); msm_hsl_write(port, RESET_STALE_INT, UARTDM_CR_ADDR); /* turn on RX and CTS interrupts */ msm_hsl_port->imr = UARTDM_ISR_RXSTALE_BMSK | UARTDM_ISR_DELTA_CTS_BMSK | UARTDM_ISR_RXLEV_BMSK; msm_hsl_write(port, msm_hsl_port->imr, UARTDM_IMR_ADDR); msm_hsl_write(port, 6500, UARTDM_DMRX_ADDR); msm_hsl_write(port, STALE_EVENT_ENABLE, UARTDM_CR_ADDR); }
static int __devinit msm_serial_hsl_probe(struct platform_device *pdev) { struct msm_hsl_port *msm_hsl_port; struct resource *uart_resource; struct resource *gsbi_resource; struct uart_port *port; int ret; if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial_hsl: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; msm_hsl_port = UART_TO_MSM(port); if (msm_serial_hsl_has_gsbi()) { gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"); if (unlikely(!gsbi_resource)) return -ENXIO; msm_hsl_port->clk = clk_get(&pdev->dev, "gsbi_uart_clk"); msm_hsl_port->pclk = clk_get(&pdev->dev, "gsbi_pclk"); } else { msm_hsl_port->clk = clk_get(&pdev->dev, "uartdm_clk"); msm_hsl_port->pclk = NULL; } if (unlikely(IS_ERR(msm_hsl_port->clk))) { printk(KERN_ERR "%s: Error getting clk\n", __func__); return PTR_ERR(msm_hsl_port->clk); } if (unlikely(IS_ERR(msm_hsl_port->pclk))) { printk(KERN_ERR "%s: Error getting pclk\n", __func__); return PTR_ERR(msm_hsl_port->pclk); } uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uartdm_resource"); if (unlikely(!uart_resource)) { printk(KERN_ERR "getting uartdm_resource failed\n"); return -ENXIO; } port->mapbase = uart_resource->start; port->irq = platform_get_irq(pdev, 0); if (unlikely(port->irq < 0)) { printk(KERN_ERR "%s: getting irq failed\n", __func__); return -ENXIO; } device_set_wakeup_capable(&pdev->dev, 1); platform_set_drvdata(pdev, port); pm_runtime_enable(port->dev); msm_hsl_debugfs_init(msm_hsl_port, pdev->id); ret = uart_add_one_port(&msm_hsl_uart_driver, port); return ret; }
static int __init msm_serial_probe(struct platform_device *pdev) { struct msm_port *msm_port; struct resource *resource; struct uart_port *port; int irq; #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP struct msm_serial_platform_data *pdata = pdev->dev.platform_data; #endif if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; msm_port = UART_TO_MSM(port); msm_port->clk = clk_get(&pdev->dev, "uart_clk"); if (unlikely(IS_ERR(msm_port->clk))) return PTR_ERR(msm_port->clk); port->uartclk = clk_get_rate(msm_port->clk); // BEGIN 0010274: [email protected] 2010-10-27 // Fixed a problem that system don't go to sleep mode. #if defined(CONFIG_MACH_LGE_BRYCE) if(uart_det_flag){ clk_enable(msm_port->clk); msm_uart_driver.cons = NULL; } #endif // END 0010274: [email protected] 2010-10-27 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) return -ENXIO; port->mapbase = resource->start; irq = platform_get_irq(pdev, 0); if (unlikely(irq < 0)) return -ENXIO; port->irq = irq; platform_set_drvdata(pdev, port); if (unlikely(set_irq_wake(port->irq, 1))) return -ENXIO; #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP if (pdata == NULL) msm_port->wakeup.irq = -1; else { msm_port->wakeup.irq = pdata->wakeup_irq; msm_port->wakeup.ignore = 1; msm_port->wakeup.inject_rx = pdata->inject_rx_on_wakeup; msm_port->wakeup.rx_to_inject = pdata->rx_to_inject; if (unlikely(msm_port->wakeup.irq <= 0)) return -EINVAL; } #endif #ifdef CONFIG_SERIAL_MSM_CLOCK_CONTROL msm_port->clk_state = MSM_CLK_PORT_OFF; hrtimer_init(&msm_port->clk_off_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); msm_port->clk_off_timer.function = msm_serial_clock_off; msm_port->clk_off_delay = ktime_set(0, 1000000); /* 1 ms */ #endif pm_runtime_enable(port->dev); return uart_add_one_port(&msm_uart_driver, port); }
static void handle_tx(struct uart_port *port) { struct circ_buf *xmit = &port->state->xmit; int sent_tx; int tx_count; int x; unsigned int tf_pointer = 0; unsigned int vid; vid = UART_TO_MSM(port)->ver_id; tx_count = uart_circ_chars_pending(xmit); if (tx_count > (UART_XMIT_SIZE - xmit->tail)) tx_count = UART_XMIT_SIZE - xmit->tail; if (tx_count >= port->fifosize) tx_count = port->fifosize; if (port->x_char) { wait_for_xmitr(port, UARTDM_ISR_TX_READY_BMSK); msm_hsl_write(port, tx_count + 1, regmap[vid][UARTDM_NCF_TX]); msm_hsl_write(port, port->x_char, regmap[vid][UARTDM_TF]); port->icount.tx++; port->x_char = 0; } else if (tx_count) { wait_for_xmitr(port, UARTDM_ISR_TX_READY_BMSK); msm_hsl_write(port, tx_count, regmap[vid][UARTDM_NCF_TX]); } if (!tx_count) { msm_hsl_stop_tx_cir(port); return; } while (tf_pointer < tx_count) { if (unlikely(!(msm_hsl_read(port, regmap[vid][UARTDM_SR]) & UARTDM_SR_TXRDY_BMSK))) continue; switch (tx_count - tf_pointer) { case 1: { x = xmit->buf[xmit->tail]; port->icount.tx++; break; } case 2: { x = xmit->buf[xmit->tail] | xmit->buf[xmit->tail+1] << 8; port->icount.tx += 2; break; } case 3: { x = xmit->buf[xmit->tail] | xmit->buf[xmit->tail+1] << 8 | xmit->buf[xmit->tail + 2] << 16; port->icount.tx += 3; break; } default: { x = *((int *)&(xmit->buf[xmit->tail])); port->icount.tx += 4; break; } } msm_hsl_write(port, x, regmap[vid][UARTDM_TF]); xmit->tail = ((tx_count - tf_pointer < 4) ? (tx_count - tf_pointer + xmit->tail) : (xmit->tail + 4)) & (UART_XMIT_SIZE - 1); tf_pointer += 4; sent_tx = 1; } if (uart_circ_empty(xmit)) msm_hsl_stop_tx_cir(port); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); }
static int msm_hsl_startup(struct uart_port *port) { struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); unsigned int data, rfr_level; int ret; unsigned long flags; snprintf(msm_hsl_port->name, sizeof(msm_hsl_port->name), "msm_serial_hsl%d", port->line); #ifndef CONFIG_PM_RUNTIME msm_hsl_init_clock(port); #endif pm_runtime_get_sync(port->dev); if (likely(port->fifosize > 12)) rfr_level = port->fifosize - 12; else rfr_level = port->fifosize; spin_lock_irqsave(&port->lock, flags); /* set automatic RFR level */ data = msm_hsl_read(port, UARTDM_MR1_ADDR); data &= ~UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK; data &= ~UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK; data |= UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK & (rfr_level << 2); data |= UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK & rfr_level; msm_hsl_write(port, data, UARTDM_MR1_ADDR); /* Make sure IPR is not 0 to start with*/ msm_hsl_write(port, UARTDM_IPR_STALE_LSB_BMSK, UARTDM_IPR_ADDR); data = 0; msm_hsl_write(port, RESET_RX, UARTDM_CR_ADDR); if (!(is_console(port)) || (!port->cons) || (port->cons && (!(port->cons->flags & CON_ENABLED)))) { msm_hsl_write(port, CR_PROTECTION_EN, UARTDM_CR_ADDR); msm_hsl_write(port, UARTDM_MR2_BITS_PER_CHAR_8 | STOP_BIT_ONE, UARTDM_MR2_ADDR); /* 8N1 */ msm_hsl_reset(port); data = UARTDM_CR_TX_EN_BMSK; } data |= UARTDM_CR_RX_EN_BMSK; msm_hsl_write(port, data, UARTDM_CR_ADDR); /* enable TX & RX */ /* turn on RX and CTS interrupts */ msm_hsl_port->imr = UARTDM_ISR_RXSTALE_BMSK | UARTDM_ISR_DELTA_CTS_BMSK | UARTDM_ISR_RXLEV_BMSK; spin_unlock_irqrestore(&port->lock, flags); ret = request_irq(port->irq, msm_hsl_irq, IRQF_TRIGGER_HIGH, msm_hsl_port->name, port); if (unlikely(ret)) { printk(KERN_ERR "%s: failed to request_irq\n", __func__); return ret; } spin_lock_irqsave(&port->lock, flags); msm_hsl_write(port, RESET_STALE_INT, UARTDM_CR_ADDR); msm_hsl_write(port, 6500, UARTDM_DMRX_ADDR); msm_hsl_write(port, STALE_EVENT_ENABLE, UARTDM_CR_ADDR); msm_hsl_write(port, msm_hsl_port->imr, UARTDM_IMR_ADDR); spin_unlock_irqrestore(&port->lock, flags); return 0; }
static void msm_hsl_set_baud_rate(struct uart_port *port, unsigned int baud) { unsigned int baud_code, rxstale, watermark; unsigned int data; unsigned int vid; struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); if (port->line == 2) { if (force_baud_1 == 96) baud = 9600; else if (force_baud_1 == 1152) baud = 115200; } D("%s ()baud %d:port->line %d, ir\n", __func__, baud, port->line); switch (baud) { case 300: baud_code = UARTDM_CSR_75; rxstale = 1; break; case 600: baud_code = UARTDM_CSR_150; rxstale = 1; break; case 1200: baud_code = UARTDM_CSR_300; rxstale = 1; break; case 2400: baud_code = UARTDM_CSR_600; rxstale = 1; break; case 4800: baud_code = UARTDM_CSR_1200; rxstale = 1; break; case 9600: baud_code = UARTDM_CSR_2400; rxstale = 2; break; case 14400: baud_code = UARTDM_CSR_3600; rxstale = 3; break; case 19200: baud_code = UARTDM_CSR_4800; rxstale = 4; break; case 28800: baud_code = UARTDM_CSR_7200; rxstale = 6; break; case 38400: baud_code = UARTDM_CSR_9600; rxstale = 8; break; case 57600: baud_code = UARTDM_CSR_14400; rxstale = 16; break; case 115200: baud_code = UARTDM_CSR_28800; rxstale = 31; break; case 230400: baud_code = UARTDM_CSR_57600; rxstale = 31; break; case 460800: baud_code = UARTDM_CSR_115200; rxstale = 31; break; default: baud_code = UARTDM_CSR_28800; rxstale = 31; break; } vid = msm_hsl_port->ver_id; msm_hsl_write(port, baud_code, regmap[vid][UARTDM_CSR]); watermark = UARTDM_IPR_STALE_LSB_BMSK & rxstale; watermark |= UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK & (rxstale << 2); msm_hsl_write(port, watermark, regmap[vid][UARTDM_IPR]); watermark = (port->fifosize * 3) / (4*4); msm_hsl_write(port, watermark, regmap[vid][UARTDM_RFWR]); msm_hsl_write(port, 0, regmap[vid][UARTDM_TFWR]); msm_hsl_write(port, CR_PROTECTION_EN, regmap[vid][UARTDM_CR]); msm_hsl_reset(port); data = UARTDM_CR_TX_EN_BMSK; data |= UARTDM_CR_RX_EN_BMSK; msm_hsl_write(port, data, regmap[vid][UARTDM_CR]); msm_hsl_write(port, RESET_STALE_INT, regmap[vid][UARTDM_CR]); msm_hsl_port->imr = UARTDM_ISR_RXSTALE_BMSK | UARTDM_ISR_DELTA_CTS_BMSK | UARTDM_ISR_RXLEV_BMSK; msm_hsl_write(port, msm_hsl_port->imr, regmap[vid][UARTDM_IMR]); msm_hsl_write(port, 6500, regmap[vid][UARTDM_DMRX]); msm_hsl_write(port, STALE_EVENT_ENABLE, regmap[vid][UARTDM_CR]); }
static int __init msm_serial_probe(struct platform_device *pdev) { struct msm_port *msm_port; struct resource *resource; struct uart_port *port; int irq; #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP struct msm_serial_platform_data *pdata = pdev->dev.platform_data; #endif if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) return -ENXIO; printk(KERN_INFO "msm_serial: detected port #%d\n", pdev->id); port = get_port_from_line(pdev->id); port->dev = &pdev->dev; msm_port = UART_TO_MSM(port); msm_port->clk = clk_get(&pdev->dev, "core_clk"); if (unlikely(IS_ERR(msm_port->clk))) return PTR_ERR(msm_port->clk); port->uartclk = clk_get_rate(msm_port->clk); if (!port->uartclk) port->uartclk = 19200000; resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) return -ENXIO; port->mapbase = resource->start; irq = platform_get_irq(pdev, 0); if (unlikely(irq < 0)) return -ENXIO; port->irq = irq; platform_set_drvdata(pdev, port); #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP if (pdata == NULL) msm_port->wakeup.irq = -1; else { msm_port->wakeup.irq = pdata->wakeup_irq; msm_port->wakeup.ignore = 1; msm_port->wakeup.inject_rx = pdata->inject_rx_on_wakeup; msm_port->wakeup.rx_to_inject = pdata->rx_to_inject; if (unlikely(msm_port->wakeup.irq <= 0)) return -EINVAL; } #endif #ifdef CONFIG_SERIAL_MSM_CLOCK_CONTROL msm_port->clk_state = MSM_CLK_PORT_OFF; hrtimer_init(&msm_port->clk_off_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); msm_port->clk_off_timer.function = msm_serial_clock_off; msm_port->clk_off_delay = ktime_set(0, 1000000); /* 1 ms */ #endif pm_runtime_enable(port->dev); return uart_add_one_port(&msm_uart_driver, port); }
static int msm_hsl_request_port_cir(struct uart_port *port) { struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); struct platform_device *pdev = to_platform_device(port->dev); struct resource *uart_resource; struct resource *gsbi_resource; resource_size_t size; uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uartdm_resource"); if (!uart_resource) { D("%s ():uart_resource :port->line %d, ir\n", __func__, port->line); uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); } if (unlikely(!uart_resource)||(!uart_resource)) { E("%s: can't get uartdm resource\n", __func__); return -ENXIO; } size = uart_resource->end - uart_resource->start + 1; if (unlikely(!request_mem_region(port->mapbase, size, "msm_serial_cir"))) { E("%s: can't get mem region for uartdm\n", __func__); return -EBUSY; } port->membase = ioremap(port->mapbase, size); if (!port->membase) { release_mem_region(port->mapbase, size); return -EBUSY; } D("%s: memory map for base 0x%x\n", __func__, port->mapbase); D("%s ():uart_resource :port->line %d, memory map for base 0x%x ir\n", __func__, port->line, port->mapbase); if (msm_serial_hsl_has_gsbi(port)) { gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"); if (!gsbi_resource) { gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1); D("%s ():gsbi_resource :port->line %d, ir\n", __func__, port->line); } if (unlikely(!gsbi_resource)||(!gsbi_resource)) { E("%s: can't get gsbi resource\n", __func__); return -ENXIO; } D("%s: get gsbi_resource for port[%d]\n", __func__, port->line); size = gsbi_resource->end - gsbi_resource->start + 1; msm_hsl_port->mapped_gsbi = ioremap(gsbi_resource->start, size); if (!msm_hsl_port->mapped_gsbi) return -EBUSY; } D("%s () ok:port->line %d, ir\n", __func__, port->line); return 0; }
static int msm_startup(struct uart_port *port) { struct msm_port *msm_port = UART_TO_MSM(port); unsigned int data, rfr_level; int ret; snprintf(msm_port->name, sizeof(msm_port->name), "msm_serial%d", port->line); ret = request_irq(port->irq, msm_irq, IRQF_TRIGGER_HIGH, msm_port->name, port); if (unlikely(ret)) return ret; if (unlikely(irq_set_irq_wake(port->irq, 1))) { free_irq(port->irq, port); return -ENXIO; } #ifndef CONFIG_PM_RUNTIME msm_init_clock(port); #endif pm_runtime_get_sync(port->dev); if (likely(port->fifosize > 12)) rfr_level = port->fifosize - 12; else rfr_level = port->fifosize; /* set automatic RFR level */ data = msm_read(port, UART_MR1); data &= ~UART_MR1_AUTO_RFR_LEVEL1; data &= ~UART_MR1_AUTO_RFR_LEVEL0; data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2); data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level; msm_write(port, data, UART_MR1); /* make sure that RXSTALE count is non-zero */ data = msm_read(port, UART_IPR); if (unlikely(!data)) { data |= UART_IPR_RXSTALE_LAST; data |= UART_IPR_STALE_LSB; msm_write(port, data, UART_IPR); } msm_reset(port); msm_write(port, 0x05, UART_CR); /* enable TX & RX */ /* turn on RX and CTS interrupts */ msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE | UART_IMR_CURRENT_CTS; msm_write(port, msm_port->imr, UART_IMR); #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP if (use_low_power_wakeup(msm_port)) { ret = irq_set_irq_wake(msm_port->wakeup.irq, 1); if (unlikely(ret)) return ret; ret = request_irq(msm_port->wakeup.irq, msm_rx_irq, IRQF_TRIGGER_FALLING, "msm_serial_wakeup", msm_port); if (unlikely(ret)) return ret; disable_irq(msm_port->wakeup.irq); } #endif return 0; }
static void handle_rx(struct uart_port *port, unsigned int misr) { struct tty_struct *tty = port->state->port.tty; unsigned int sr; int count = 0; struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); /* * Handle overrun. My understanding of the hardware is that overrun * is not tied to the RX buffer, so we handle the case out of band. */ if ((msm_hsl_read(port, UARTDM_SR_ADDR) & UARTDM_SR_OVERRUN_BMSK)) { port->icount.overrun++; tty_insert_flip_char(tty, 0, TTY_OVERRUN); msm_hsl_write(port, RESET_ERROR_STATUS, UARTDM_CR_ADDR); } if (misr & UARTDM_ISR_RXSTALE_BMSK) { count = msm_hsl_read(port, UARTDM_RX_TOTAL_SNAP_ADDR) - msm_hsl_port->old_snap_state; msm_hsl_port->old_snap_state = 0; } else { count = 4 * (msm_hsl_read(port, UARTDM_RFWR_ADDR)); msm_hsl_port->old_snap_state += count; } /* and now the main RX loop */ while (count > 0) { unsigned int c; char flag = TTY_NORMAL; sr = msm_hsl_read(port, UARTDM_SR_ADDR); if ((sr & UARTDM_SR_RXRDY_BMSK) == 0) { msm_hsl_port->old_snap_state -= count; break; } c = msm_hsl_read(port, UARTDM_RF_ADDR); if (sr & UARTDM_SR_RX_BREAK_BMSK) { port->icount.brk++; if (uart_handle_break(port)) continue; } else if (sr & UARTDM_SR_PAR_FRAME_BMSK) { port->icount.frame++; } else { port->icount.rx++; } /* Mask conditions we're ignorning. */ sr &= port->read_status_mask; if (sr & UARTDM_SR_RX_BREAK_BMSK) flag = TTY_BREAK; else if (sr & UARTDM_SR_PAR_FRAME_BMSK) flag = TTY_FRAME; /* TODO: handle sysrq */ /* if (!uart_handle_sysrq_char(port, c)) */ tty_insert_flip_string(tty, (char *) &c, (count > 4) ? 4 : count); count -= 4; } tty_flip_buffer_push(tty); }
static int msm_hsl_startup(struct uart_port *port) { struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port); struct platform_device *pdev = to_platform_device(port->dev); struct msm_serial_hslite_platform_data *pdata = pdev->dev.platform_data; unsigned int data, rfr_level; int ret; unsigned long flags; snprintf(msm_hsl_port->name, sizeof(msm_hsl_port->name), "msm_serial_hsl%d", port->line); if (!(is_console(port)) || (!port->cons) || (port->cons && (!(port->cons->flags & CON_ENABLED)))) { if (msm_serial_hsl_has_gsbi()) if ((ioread32(msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR) & GSBI_PROTOCOL_I2C_UART) != GSBI_PROTOCOL_I2C_UART) iowrite32(GSBI_PROTOCOL_I2C_UART, msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR); if (pdata && pdata->config_gpio) { ret = gpio_request(pdata->uart_tx_gpio, "UART_TX_GPIO"); if (unlikely(ret)) { pr_err("%s: gpio request failed for:%d\n", __func__, pdata->uart_tx_gpio); return ret; } ret = gpio_request(pdata->uart_rx_gpio, "UART_RX_GPIO"); if (unlikely(ret)) { pr_err("%s: gpio request failed for:%d\n", __func__, pdata->uart_rx_gpio); gpio_free(pdata->uart_tx_gpio); return ret; } } } #ifndef CONFIG_PM_RUNTIME msm_hsl_init_clock(port); #endif pm_runtime_get_sync(port->dev); if (likely(port->fifosize > 12)) rfr_level = port->fifosize - 12; else rfr_level = port->fifosize; spin_lock_irqsave(&port->lock, flags); /* set automatic RFR level */ data = msm_hsl_read(port, UARTDM_MR1_ADDR); data &= ~UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK; data &= ~UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK; data |= UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK & (rfr_level << 2); data |= UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK & rfr_level; msm_hsl_write(port, data, UARTDM_MR1_ADDR); /* Make sure IPR is not 0 to start with*/ msm_hsl_write(port, UARTDM_IPR_STALE_LSB_BMSK, UARTDM_IPR_ADDR); data = 0; if (!(is_console(port)) || (!port->cons) || (port->cons && (!(port->cons->flags & CON_ENABLED)))) { msm_hsl_write(port, CR_PROTECTION_EN, UARTDM_CR_ADDR); msm_hsl_write(port, UARTDM_MR2_BITS_PER_CHAR_8 | STOP_BIT_ONE, UARTDM_MR2_ADDR); /* 8N1 */ msm_hsl_reset(port); data = UARTDM_CR_TX_EN_BMSK; } data |= UARTDM_CR_RX_EN_BMSK; msm_hsl_write(port, data, UARTDM_CR_ADDR); /* enable TX & RX */ /* turn on RX and CTS interrupts */ msm_hsl_port->imr = UARTDM_ISR_RXSTALE_BMSK | UARTDM_ISR_DELTA_CTS_BMSK | UARTDM_ISR_RXLEV_BMSK; spin_unlock_irqrestore(&port->lock, flags); ret = request_irq(port->irq, msm_hsl_irq, IRQF_TRIGGER_HIGH, msm_hsl_port->name, port); if (unlikely(ret)) { printk(KERN_ERR "%s: failed to request_irq\n", __func__); return ret; } spin_lock_irqsave(&port->lock, flags); msm_hsl_write(port, RESET_STALE_INT, UARTDM_CR_ADDR); msm_hsl_write(port, 6500, UARTDM_DMRX_ADDR); msm_hsl_write(port, STALE_EVENT_ENABLE, UARTDM_CR_ADDR); msm_hsl_write(port, msm_hsl_port->imr, UARTDM_IMR_ADDR); spin_unlock_irqrestore(&port->lock, flags); return 0; }