/* * This is usually used to read data from SPIC RX FIFO, which doesn't * need any delay like flushing character out. * * Return how many valide bytes are read back */ static int max3110_read_multi(struct uart_max3110 *max) { void *buf; u16 *obuf, *ibuf; int ret, blen; blen = M3110_RX_FIFO_DEPTH * sizeof(u16); buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); if (!buf) { pr_warning(PR_FMT "%s(): fail to alloc dma buffer\n", __func__); return 0; } /* tx/rx always have the same length */ obuf = buf; ibuf = buf + blen; if (max3110_write_then_read(max, obuf, ibuf, blen, 1)) { kfree(buf); return 0; } ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH); kfree(buf); return ret; }
/* * This is usually used to read data from SPIC RX FIFO, which doesn't * need any delay like flushing character out. It returns how many * valide bytes are read back */ static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf) { u16 out[MAX_READ_LEN], in[MAX_READ_LEN]; u8 *pbuf, valid_str[MAX_READ_LEN]; int i, j, bytelen; if (len > MAX_READ_LEN) { pr_err(PR_FMT "read len %d is too large\n", len); return 0; } bytelen = len * 2; memset(out, 0, bytelen); memset(in, 0, bytelen); if (max3110_write_then_read(max, (u8 *)out, (u8 *)in, bytelen, 1)) return 0; /* If caller don't provide a buffer, then handle received char */ pbuf = buf ? buf : valid_str; for (i = 0, j = 0; i < len; i++) { if (in[i] & MAX3110_READ_DATA_AVAILABLE) pbuf[j++] = (u8)(in[i] & 0xff); } if (j && (pbuf == valid_str)) receive_chars(max, valid_str, j); return j; }
/* Write a 16b word to the device */ static int max3110_out(struct uart_max3110 *max, const u16 out) { void *buf; u16 *obuf, *ibuf; int ret; buf = kzalloc(8, GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; obuf = buf; ibuf = buf + 4; *obuf = out; ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); if (ret) { pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n", __func__, ret, out); goto exit; } receive_chars(max, ibuf, 1); exit: kfree(buf); return ret; }
/* Write a 16b word to the device */ static int max3110_out(struct uart_max3110 *max, const u16 out) { void *buf; u16 *obuf, *ibuf; u8 ch; int ret; buf = kzalloc(8, GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; obuf = buf; ibuf = buf + 4; *obuf = out; ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); if (ret) { pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n", __func__, ret, out); goto exit; } /* If some valid data is read back */ if (*ibuf & MAX3110_READ_DATA_AVAILABLE) { ch = *ibuf & 0xff; receive_chars(max, &ch, 1); } exit: kfree(buf); return ret; }
static void send_circ_buf(struct uart_max3110 *max, struct circ_buf *xmit) { void *buf; u16 *obuf, *ibuf; u8 valid_str[WORDS_PER_XFER]; int i, j, len, blen, dma_size, left, ret = 0; dma_size = WORDS_PER_XFER * sizeof(u16) * 2; buf = kzalloc(dma_size, GFP_KERNEL | GFP_DMA); if (!buf) return; obuf = buf; ibuf = buf + dma_size/2; while (!uart_circ_empty(xmit)) { left = uart_circ_chars_pending(xmit); while (left) { len = min(left, WORDS_PER_XFER); blen = len * sizeof(u16); memset(ibuf, 0, blen); for (i = 0; i < len; i++) { obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); } /* Fail to send msg to console is not very critical */ ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); if (ret) pr_warning(PR_FMT "%s(): get err msg %d\n", __func__, ret); for (i = 0, j = 0; i < len; i++) { if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) valid_str[j++] = ibuf[i] & 0xff; } if (j) receive_chars(max, valid_str, j); max->port.icount.tx += len; left -= len; } } kfree(buf); }
/* Write a u16 to the device, and return one u16 read back */ int max3110_out(struct uart_max3110 *max, const u16 out) { u16 tmp; int ret; ret = max3110_write_then_read(max, (u8 *)&out, (u8 *)&tmp, 2, 1); if (ret) return ret; /* If some valid data is read back */ if (tmp & MAX3110_READ_DATA_AVAILABLE) receive_char(max, (tmp & 0xff)); return ret; }
static void send_circ_buf(struct uart_max3110 *max, struct circ_buf *xmit) { void *buf; u16 *obuf, *ibuf; int i, len, blen, dma_size, left, ret = 0; dma_size = M3110_RX_FIFO_DEPTH * sizeof(u16) * 2; buf = kzalloc(dma_size, GFP_KERNEL | GFP_DMA); if (!buf) return; obuf = buf; ibuf = buf + dma_size/2; while (!uart_circ_empty(xmit)) { left = uart_circ_chars_pending(xmit); while (left) { len = min(left, M3110_RX_FIFO_DEPTH); blen = len * sizeof(u16); memset(ibuf, 0, blen); for (i = 0; i < len; i++) { obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); } /* Fail to send msg to console is not very critical */ ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); if (ret) pr_warning(PR_FMT "%s(): get err msg %d\n", __func__, ret); receive_chars(max, ibuf, len); max->port.icount.tx += len; left -= len; } } kfree(buf); }
/* * This is usually used to read data from SPIC RX FIFO, which doesn't * need any delay like flushing character out. * * Return how many valide bytes are read back */ static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf) { void *buf; u16 *obuf, *ibuf; u8 *pbuf, valid_str[M3110_RX_FIFO_DEPTH]; int i, j, blen; blen = M3110_RX_FIFO_DEPTH * sizeof(u16); buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); if (!buf) { pr_warning(PR_FMT "%s(): fail to alloc dma buffer\n", __func__); return 0; } /* tx/rx always have the same length */ obuf = buf; ibuf = buf + blen; if (max3110_write_then_read(max, obuf, ibuf, blen, 1)) { kfree(buf); return 0; } /* If caller doesn't provide a buffer, then handle received char */ pbuf = rxbuf ? rxbuf : valid_str; for (i = 0, j = 0; i < M3110_RX_FIFO_DEPTH; i++) { if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) pbuf[j++] = ibuf[i] & 0xff; } if (j && (pbuf == valid_str)) receive_chars(max, valid_str, j); kfree(buf); return j; }
static inline void send_circ_buf(struct uart_max3110 *max, struct circ_buf *xmit) { int len, left = 0; u16 obuf[WORDS_PER_XFER], ibuf[WORDS_PER_XFER]; u8 valid_str[WORDS_PER_XFER]; int i, j; while (!uart_circ_empty(xmit)) { left = uart_circ_chars_pending(xmit); while (left) { len = (left >= WORDS_PER_XFER) ? WORDS_PER_XFER : left; memset(obuf, 0, len * 2); memset(ibuf, 0, len * 2); for (i = 0; i < len; i++) { obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); } max3110_write_then_read(max, (u8 *)obuf, (u8 *)ibuf, len * 2, 0); for (i = 0, j = 0; i < len; i++) { if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) valid_str[j++] = (u8)(ibuf[i] & 0xff); } if (j) receive_chars(max, valid_str, j); max->port.icount.tx += len; left -= len; } } }
static int serial_m3110_probe(struct spi_device *spi) { struct uart_max3110 *max; int ret; unsigned char *buffer; u16 res; max = kzalloc(sizeof(*max), GFP_KERNEL); if (!max) return -ENOMEM; /* set spi info */ spi->mode = SPI_MODE_0; spi->bits_per_word = 16; max->clock = MAX3110_HIGH_CLK; spi->controller_data = &spi0_uart; spi_setup(spi); max->port.type = PORT_PXA; /* need apply for a max3110 type */ max->port.fifosize = 2; /* only have 16b buffer */ max->port.ops = &serial_m3110_ops; max->port.line = 0; max->port.dev = &spi->dev; max->port.uartclk = 115200; max->spi = spi; max->name = spi->modalias; /* use spi name as the name */ max->irq = (u16)spi->irq; mutex_init(&max->thread_mutex); max->word_7bits = 0; max->parity = 0; max->baud = 0; max->cur_conf = 0; max->uart_flags = 0; /* Check if reading configuration register returns something sane */ res = RC_TAG; ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); if (ret < 0 || res == 0 || res == 0xffff) { printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)", res); ret = -ENODEV; goto err_get_page; } buffer = (unsigned char *)__get_free_page(GFP_KERNEL); if (!buffer) { ret = -ENOMEM; goto err_get_page; } max->con_xmit.buf = (unsigned char *)buffer; max->con_xmit.head = max->con_xmit.tail = 0; max->main_thread = kthread_run(max3110_main_thread, max, "max3110_main"); if (IS_ERR(max->main_thread)) { ret = PTR_ERR(max->main_thread); goto err_kthread; } pmax = max; /* give membase a psudo value to pass serial_core's check */ max->port.membase = (void *)0xff110000; uart_add_one_port(&serial_m3110_reg, &max->port); return 0; err_kthread: free_page((unsigned long)buffer); err_get_page: pmax = NULL; kfree(max); return ret; }
static int serial_m3110_probe(struct spi_device *spi) { struct uart_max3110 *max; void *buffer; u16 res; int ret = 0; struct plat_max3110 *pdata = spi->dev.platform_data; if (!pdata) return -EINVAL; max = kzalloc(sizeof(*max), GFP_KERNEL); if (!max) return -ENOMEM; /* Set spi info */ spi->bits_per_word = 16; max->clock = MAX3110_HIGH_CLK; spi_setup(spi); max->port.type = PORT_MAX3100; max->port.fifosize = 2; /* Only have 16b buffer */ max->port.ops = &serial_m3110_ops; max->port.line = 0; max->port.dev = &spi->dev; max->port.uartclk = 115200; max->spi = spi; strcpy(max->name, spi->modalias); max->irq = (u16)spi->irq; mutex_init(&max->thread_mutex); mutex_init(&max->io_mutex); max->word_7bits = 0; max->parity = 0; max->baud = 0; max->cur_conf = 0; max->uart_flags = 0; /* Check if reading configuration register returns something sane */ res = RC_TAG; ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); if (ret < 0 || res == 0 || res == 0xffff) { dev_dbg(&spi->dev, "MAX3111 deemed not present (conf reg %04x)", res); ret = -ENODEV; goto err_get_page; } buffer = (void *)__get_free_page(GFP_KERNEL); if (!buffer) { ret = -ENOMEM; goto err_get_page; } max->con_xmit.buf = buffer; max->con_xmit.head = 0; max->con_xmit.tail = 0; init_waitqueue_head(&max->wq); max->main_thread = kthread_run(max3110_main_thread, max, "max3110_main"); if (IS_ERR(max->main_thread)) { ret = PTR_ERR(max->main_thread); goto err_kthread; } max->irq_edge_triggered = pdata->irq_edge_triggered; if (max->irq > 0) { if (max->irq_edge_triggered) { ret = request_irq(max->irq, serial_m3110_irq, IRQ_TYPE_EDGE_FALLING, "max3110", max); } else { ret = request_threaded_irq(max->irq, NULL, serial_m3110_irq, IRQF_ONESHOT, "max3110", max); } if (ret) { max->irq = 0; dev_warn(&spi->dev, "unable to allocate IRQ, will use polling method\n"); } } spi_set_drvdata(spi, max); pmax = max; /* Give membase a psudo value to pass serial_core's check */ max->port.membase = (void *)0xff110000; uart_add_one_port(&serial_m3110_reg, &max->port); return 0; err_kthread: free_page((unsigned long)buffer); err_get_page: kfree(max); return ret; }