17831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox/* 27831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * 37831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * Copyright (C) 2008 Christian Pellegrin <chripell@evolware.org> 47831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * 57831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * This program is free software; you can redistribute it and/or modify 67831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * it under the terms of the GNU General Public License as published by 77831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * the Free Software Foundation; either version 2 of the License, or 87831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * (at your option) any later version. 97831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * 107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * 117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * Notes: the MAX3100 doesn't provide an interrupt on CTS so we have 127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * to use polling for flow control. TX empty IRQ is unusable, since 137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * writing conf clears FIFO buffer and we cannot have this interrupt 147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * always asking us for attention. 157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * 167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * Example platform data: 177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox static struct plat_max3100 max3100_plat_data = { 197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .loopback = 0, 207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .crystal = 0, 217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .poll_time = 100, 227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox }; 237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox static struct spi_board_info spi_board_info[] = { 257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox { 267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .modalias = "max3100", 277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .platform_data = &max3100_plat_data, 287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .irq = IRQ_EINT12, 297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .max_speed_hz = 5*1000*1000, 307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .chip_select = 0, 317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox }, 327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox }; 337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * The initial minor number is 209 in the low-density serial port: 357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * mknod /dev/ttyMAX0 c 204 209 367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox */ 377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_MAJOR 204 397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_MINOR 209 407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox/* 4 MAX3100s should be enough for everyone */ 417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX_MAX3100 4 427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#include <linux/delay.h> 445a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#include <linux/device.h> 46578b9ce0095ff3dd2c3b94508407c3be8fcce68dPaul Gortmaker#include <linux/module.h> 477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#include <linux/serial_core.h> 487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#include <linux/serial.h> 497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#include <linux/spi/spi.h> 507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#include <linux/freezer.h> 51ee160a38eee357ed2572cf41437d5814ce53c839Jiri Slaby#include <linux/tty.h> 52ee160a38eee357ed2572cf41437d5814ce53c839Jiri Slaby#include <linux/tty_flip.h> 537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#include <linux/serial_max3100.h> 557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_C (1<<14) 577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_D (0<<14) 587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_W (1<<15) 597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RX (0<<15) 607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_WC (MAX3100_W | MAX3100_C) 627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RC (MAX3100_RX | MAX3100_C) 637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_WD (MAX3100_W | MAX3100_D) 647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RD (MAX3100_RX | MAX3100_D) 657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_CMD (3 << 14) 667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_T (1<<14) 687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_R (1<<15) 697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_FEN (1<<13) 717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_SHDN (1<<12) 727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_TM (1<<11) 737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RM (1<<10) 747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_PM (1<<9) 757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RAM (1<<8) 767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_IR (1<<7) 777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_ST (1<<6) 787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_PE (1<<5) 797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_L (1<<4) 807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_BAUD (0xf) 817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_TE (1<<10) 837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RAFE (1<<10) 847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RTS (1<<9) 857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_CTS (1<<9) 867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_PT (1<<8) 877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_DATA (0xff) 887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RT (MAX3100_R | MAX3100_T) 907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_RTC (MAX3100_RT | MAX3100_CTS | MAX3100_RAFE) 917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox/* the following simulate a status reg for ignore_status_mask */ 937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_STATUS_PE 1 947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_STATUS_FE 2 957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_STATUS_OE 4 967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstruct max3100_port { 987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct uart_port port; 997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct spi_device *spi; 1007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int cts; /* last CTS received for flow ctrl */ 1027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int tx_empty; /* last TX empty bit */ 1037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spinlock_t conf_lock; /* shared data */ 1057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int conf_commit; /* need to make changes */ 1067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int conf; /* configuration for the MAX31000 1077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox * (bits 0-7, bits 8-11 are irqs) */ 1087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int rts_commit; /* need to change rts */ 1097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int rts; /* rts status */ 1107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int baud; /* current baud rate */ 1117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int parity; /* keeps track if we should send parity */ 1137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_PARITY_ON 1 1147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_PARITY_ODD 2 1157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define MAX3100_7BIT 4 1167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int rx_enabled; /* if we should rx chars */ 1177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int irq; /* irq assigned to the max3100 */ 1197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int minor; /* minor number */ 1217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int crystal; /* 1 if 3.6864Mhz crystal 0 for 1.8432 */ 1227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int loopback; /* 1 if we are in loopback mode */ 1237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* for handling irqs: need workqueue since we do spi_sync */ 1257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct workqueue_struct *workqueue; 1267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct work_struct work; 1277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* set to 1 to make the workhandler exit as soon as possible */ 1287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int force_end_work; 1297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* need to know we are suspending to avoid deadlock on workqueue */ 1307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int suspending; 1317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* hook for suspending MAX3100 via dedicated pin */ 1337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox void (*max3100_hw_suspend) (int suspend); 1347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* poll time (in ms) for ctrl lines */ 1367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int poll_time; 1377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* and its timer */ 1387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct timer_list timer; 1397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox}; 1407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic struct max3100_port *max3100s[MAX_MAX3100]; /* the chips */ 1427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic DEFINE_MUTEX(max3100s_lock); /* race on probe */ 1437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_do_parity(struct max3100_port *s, u16 c) 1457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 1467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int parity; 1477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->parity & MAX3100_PARITY_ODD) 1497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity = 1; 1507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else 1517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity = 0; 1527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->parity & MAX3100_7BIT) 1547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox c &= 0x7f; 1557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else 1567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox c &= 0xff; 1577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity = parity ^ (hweight8(c) & 1); 1597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return parity; 1607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 1617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_check_parity(struct max3100_port *s, u16 c) 1637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 1647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return max3100_do_parity(s, c) == ((c >> 8) & 1); 1657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 1667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_calc_parity(struct max3100_port *s, u16 *c) 1687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 1697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->parity & MAX3100_7BIT) 1707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox *c &= 0x7f; 1717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else 1727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox *c &= 0xff; 1737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->parity & MAX3100_PARITY_ON) 1757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox *c |= max3100_do_parity(s, *c) << 8; 1767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 1777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_work(struct work_struct *w); 1797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_dowork(struct max3100_port *s) 1817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 1827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (!s->force_end_work && !work_pending(&s->work) && 1837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox !freezing(current) && !s->suspending) 1847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox queue_work(s->workqueue, &s->work); 1857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 1867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_timeout(unsigned long data) 1887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 1897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = (struct max3100_port *)data; 1907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 191ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox if (s->port.state) { 1927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 1937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mod_timer(&s->timer, jiffies + s->poll_time); 1947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 1957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 1967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 1977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx) 1987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 1997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct spi_message message; 2007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox u16 etx, erx; 2017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int status; 2027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct spi_transfer tran = { 2037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .tx_buf = &etx, 2047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .rx_buf = &erx, 2057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .len = 2, 2067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox }; 2077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox etx = cpu_to_be16(tx); 2097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spi_message_init(&message); 2107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spi_message_add_tail(&tran, &message); 2117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox status = spi_sync(s->spi, &message); 2127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (status) { 2137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_warn(&s->spi->dev, "error while calling spi_sync\n"); 2147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return -EIO; 2157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 2167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox *rx = be16_to_cpu(erx); 2177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->tx_empty = (*rx & MAX3100_T) > 0; 2187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%04x - %04x\n", tx, *rx); 2197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 2207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 2217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_handlerx(struct max3100_port *s, u16 rx) 2237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 2247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox unsigned int ch, flg, status = 0; 2257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int ret = 0, cts; 2267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (rx & MAX3100_R && s->rx_enabled) { 2287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 2297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox ch = rx & (s->parity & MAX3100_7BIT ? 0x7f : 0xff); 2307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (rx & MAX3100_RAFE) { 2317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.icount.frame++; 2327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox flg = TTY_FRAME; 2337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox status |= MAX3100_STATUS_FE; 2347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } else { 2357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->parity & MAX3100_PARITY_ON) { 2367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (max3100_check_parity(s, rx)) { 2377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.icount.rx++; 2387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox flg = TTY_NORMAL; 2397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } else { 2407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.icount.parity++; 2417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox flg = TTY_PARITY; 2427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox status |= MAX3100_STATUS_PE; 2437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 2447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } else { 2457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.icount.rx++; 2467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox flg = TTY_NORMAL; 2477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 2487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 2497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_insert_char(&s->port, status, MAX3100_STATUS_OE, ch, flg); 2507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox ret = 1; 2517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 2527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox cts = (rx & MAX3100_CTS) > 0; 2547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->cts != cts) { 2557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->cts = cts; 2567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_handle_cts_change(&s->port, cts ? TIOCM_CTS : 0); 2577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 2587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return ret; 2607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 2617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_work(struct work_struct *w) 2637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 2647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(w, struct max3100_port, work); 2657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int rxchars; 2667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox u16 tx, rx; 2677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int conf, cconf, rts, crts; 268ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox struct circ_buf *xmit = &s->port.state->xmit; 2697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 2717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox rxchars = 0; 2737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox do { 2747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_lock(&s->conf_lock); 2757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox conf = s->conf; 2767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox cconf = s->conf_commit; 2777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf_commit = 0; 2787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox rts = s->rts; 2797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox crts = s->rts_commit; 2807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->rts_commit = 0; 2817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_unlock(&s->conf_lock); 2827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (cconf) 2837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(s, MAX3100_WC | conf, &rx); 2847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (crts) { 2857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(s, MAX3100_WD | MAX3100_TE | 2867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox (s->rts ? MAX3100_RTS : 0), &rx); 2877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox rxchars += max3100_handlerx(s, rx); 2887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 2897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(s, MAX3100_RD, &rx); 2917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox rxchars += max3100_handlerx(s, rx); 2927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 2937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (rx & MAX3100_T) { 2947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx = 0xffff; 2957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->port.x_char) { 2967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx = s->port.x_char; 2977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.icount.tx++; 2987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.x_char = 0; 2997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } else if (!uart_circ_empty(xmit) && 3007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox !uart_tx_stopped(&s->port)) { 3017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx = xmit->buf[xmit->tail]; 3027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox xmit->tail = (xmit->tail + 1) & 3037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox (UART_XMIT_SIZE - 1); 3047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.icount.tx++; 3057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 3067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (tx != 0xffff) { 3077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_calc_parity(s, &tx); 3087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx |= MAX3100_WD | (s->rts ? MAX3100_RTS : 0); 3097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(s, tx, &rx); 3107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox rxchars += max3100_handlerx(s, rx); 3117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 3127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 3137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 314ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox if (rxchars > 16 && s->port.state->port.tty != NULL) { 315ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox tty_flip_buffer_push(s->port.state->port.tty); 3167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox rxchars = 0; 3177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 3187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 3197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_write_wakeup(&s->port); 3207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } while (!s->force_end_work && 3227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox !freezing(current) && 3237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox ((rx & MAX3100_R) || 3247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox (!uart_circ_empty(xmit) && 3257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox !uart_tx_stopped(&s->port)))); 3267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 327ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox if (rxchars > 0 && s->port.state->port.tty != NULL) 328ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox tty_flip_buffer_push(s->port.state->port.tty); 3297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 3307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic irqreturn_t max3100_irq(int irqno, void *dev_id) 3327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 3337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = dev_id; 3347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 3367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 3387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return IRQ_HANDLED; 3397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 3407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_enable_ms(struct uart_port *port) 3427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 3437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 3447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 3457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 3467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->poll_time > 0) 3487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mod_timer(&s->timer, jiffies); 3497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 3507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 3517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_start_tx(struct uart_port *port) 3537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 3547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 3557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 3567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 3577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 3597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 3617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 3627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_stop_rx(struct uart_port *port) 3647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 3657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 3667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 3677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 3687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 3707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->rx_enabled = 0; 3727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_lock(&s->conf_lock); 3737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf &= ~MAX3100_RM; 3747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf_commit = 1; 3757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_unlock(&s->conf_lock); 3767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 3777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 3787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic unsigned int max3100_tx_empty(struct uart_port *port) 3807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 3817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 3827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 3837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 3847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 3867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* may not be truly up-to-date */ 3887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 3897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return s->tx_empty; 3907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 3917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic unsigned int max3100_get_mctrl(struct uart_port *port) 3937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 3947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 3957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 3967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 3977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 3987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 3997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* may not be truly up-to-date */ 4017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 4027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* always assert DCD and DSR since these lines are not wired */ 4037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return (s->cts ? TIOCM_CTS : 0) | TIOCM_DSR | TIOCM_CAR; 4047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 4057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_set_mctrl(struct uart_port *port, unsigned int mctrl) 4077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 4087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 4097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 4107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 4117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int rts; 4127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 4147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox rts = (mctrl & TIOCM_RTS) > 0; 4167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_lock(&s->conf_lock); 4187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->rts != rts) { 4197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->rts = rts; 4207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->rts_commit = 1; 4217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 4227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 4237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_unlock(&s->conf_lock); 4247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 4257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void 4277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxmax3100_set_termios(struct uart_port *port, struct ktermios *termios, 4287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct ktermios *old) 4297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 4307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 4317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 4327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 4337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int baud = 0; 4347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox unsigned cflag; 4357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox u32 param_new, param_mask, parity = 0; 4367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 4387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox cflag = termios->c_cflag; 4407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 0; 4417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_mask = 0; 4427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 443eab4f5af6b07009d1fc48bac5f3215c0cbfb2fc3Alan Cox baud = tty_termios_baud_rate(termios); 4447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = s->conf & MAX3100_BAUD; 4457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox switch (baud) { 4467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 300: 4477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->crystal) 4487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox baud = s->baud; 4497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else 4507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 15; 4517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 600: 4537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 14 + s->crystal; 4547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 1200: 4567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 13 + s->crystal; 4577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 2400: 4597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 12 + s->crystal; 4607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 4800: 4627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 11 + s->crystal; 4637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 9600: 4657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 10 + s->crystal; 4667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 19200: 4687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 9 + s->crystal; 4697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 38400: 4717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 8 + s->crystal; 4727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 57600: 4747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 1 + s->crystal; 4757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 115200: 4777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 0 + s->crystal; 4787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox case 230400: 4807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->crystal) 4817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new = 0; 4827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else 4837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox baud = s->baud; 4847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 4857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox default: 4867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox baud = s->baud; 4877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 488eab4f5af6b07009d1fc48bac5f3215c0cbfb2fc3Alan Cox tty_termios_encode_baud_rate(termios, baud, baud); 4897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->baud = baud; 4907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_mask |= MAX3100_BAUD; 4917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 4927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if ((cflag & CSIZE) == CS8) { 4937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new &= ~MAX3100_L; 4947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity &= ~MAX3100_7BIT; 4957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } else { 4967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new |= MAX3100_L; 4977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity |= MAX3100_7BIT; 4987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox cflag = (cflag & ~CSIZE) | CS7; 4997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 5007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_mask |= MAX3100_L; 5017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (cflag & CSTOPB) 5037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new |= MAX3100_ST; 5047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else 5057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new &= ~MAX3100_ST; 5067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_mask |= MAX3100_ST; 5077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (cflag & PARENB) { 5097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new |= MAX3100_PE; 5107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity |= MAX3100_PARITY_ON; 5117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } else { 5127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_new &= ~MAX3100_PE; 5137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity &= ~MAX3100_PARITY_ON; 5147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 5157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox param_mask |= MAX3100_PE; 5167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (cflag & PARODD) 5187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity |= MAX3100_PARITY_ODD; 5197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else 5207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox parity &= ~MAX3100_PARITY_ODD; 5217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* mask termios capabilities we don't support */ 5237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox cflag &= ~CMSPAR; 5247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox termios->c_cflag = cflag; 5257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.ignore_status_mask = 0; 5277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (termios->c_iflag & IGNPAR) 5287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.ignore_status_mask |= 5297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox MAX3100_STATUS_PE | MAX3100_STATUS_FE | 5307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox MAX3100_STATUS_OE; 5317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* we are sending char from a workqueue so enable */ 533ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox s->port.state->port.tty->low_latency = 1; 5347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->poll_time > 0) 5367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox del_timer_sync(&s->timer); 5377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_update_timeout(port, termios->c_cflag, baud); 5397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_lock(&s->conf_lock); 5417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf = (s->conf & ~param_mask) | (param_new & param_mask); 5427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf_commit = 1; 5437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->parity = parity; 5447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_unlock(&s->conf_lock); 5457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 5467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (UART_ENABLE_MS(&s->port, termios->c_cflag)) 5487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_enable_ms(&s->port); 5497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 5507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_shutdown(struct uart_port *port) 5527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 5537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 5547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 5557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 5567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 5587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->suspending) 5607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return; 5617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->force_end_work = 1; 5637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->poll_time > 0) 5657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox del_timer_sync(&s->timer); 5667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->workqueue) { 5687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox flush_workqueue(s->workqueue); 5697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox destroy_workqueue(s->workqueue); 5707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->workqueue = NULL; 5717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 5727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->irq) 5737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox free_irq(s->irq, s); 5747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* set shutdown mode to save power */ 5767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->max3100_hw_suspend) 5777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->max3100_hw_suspend(1); 5787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else { 5797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox u16 tx, rx; 5807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx = MAX3100_WC | MAX3100_SHDN; 5827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(s, tx, &rx); 5837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 5847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 5857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_startup(struct uart_port *port) 5877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 5887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 5897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 5907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 5917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox char b[12]; 5927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 5947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf = MAX3100_RM; 5967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->baud = s->crystal ? 230400 : 115200; 5977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->rx_enabled = 1; 5987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 5997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->suspending) 6007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 6017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->force_end_work = 0; 6037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->parity = 0; 6047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->rts = 0; 6057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox sprintf(b, "max3100-%d", s->minor); 60758a69cb47ec6991bf006a3e5d202e8571b0327a4Tejun Heo s->workqueue = create_freezable_workqueue(b); 6087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (!s->workqueue) { 6097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_warn(&s->spi->dev, "cannot create workqueue\n"); 6107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return -EBUSY; 6117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 6127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox INIT_WORK(&s->work, max3100_work); 6137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (request_irq(s->irq, max3100_irq, 6157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox IRQF_TRIGGER_FALLING, "max3100", s) < 0) { 6167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_warn(&s->spi->dev, "cannot allocate irq %d\n", s->irq); 6177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->irq = 0; 6187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox destroy_workqueue(s->workqueue); 6197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->workqueue = NULL; 6207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return -EBUSY; 6217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 6227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->loopback) { 6247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox u16 tx, rx; 6257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx = 0x4001; 6267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(s, tx, &rx); 6277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 6287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->max3100_hw_suspend) 6307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->max3100_hw_suspend(0); 6317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf_commit = 1; 6327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 6337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* wait for clock to settle */ 6347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox msleep(50); 6357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_enable_ms(&s->port); 6377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 6397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 6407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic const char *max3100_type(struct uart_port *port) 6427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 6437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 6447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 6457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 6467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 6487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return s->port.type == PORT_MAX3100 ? "MAX3100" : NULL; 6507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 6517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_release_port(struct uart_port *port) 6537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 6547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 6557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 6567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 6577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 6597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 6607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_config_port(struct uart_port *port, int flags) 6627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 6637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 6647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 6657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 6667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 6687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (flags & UART_CONFIG_TYPE) 6707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->port.type = PORT_MAX3100; 6717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 6727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_verify_port(struct uart_port *port, 6747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct serial_struct *ser) 6757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 6767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 6777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 6787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 6797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int ret = -EINVAL; 6807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 6827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3100) 6847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox ret = 0; 6857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return ret; 6867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 6877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_stop_tx(struct uart_port *port) 6897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 6907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 6917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 6927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 6937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 6957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 6967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 6977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_request_port(struct uart_port *port) 6987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 6997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 7007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 7017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 7027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 7047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 7057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 7067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void max3100_break_ctl(struct uart_port *port, int break_state) 7087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 7097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = container_of(port, 7107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port, 7117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox port); 7127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 7147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 7157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic struct uart_ops max3100_ops = { 7177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .tx_empty = max3100_tx_empty, 7187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .set_mctrl = max3100_set_mctrl, 7197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .get_mctrl = max3100_get_mctrl, 7207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .stop_tx = max3100_stop_tx, 7217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .start_tx = max3100_start_tx, 7227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .stop_rx = max3100_stop_rx, 7237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .enable_ms = max3100_enable_ms, 7247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .break_ctl = max3100_break_ctl, 7257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .startup = max3100_startup, 7267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .shutdown = max3100_shutdown, 7277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .set_termios = max3100_set_termios, 7287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .type = max3100_type, 7297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .release_port = max3100_release_port, 7307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .request_port = max3100_request_port, 7317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .config_port = max3100_config_port, 7327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .verify_port = max3100_verify_port, 7337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox}; 7347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic struct uart_driver max3100_uart_driver = { 7367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .owner = THIS_MODULE, 7377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .driver_name = "ttyMAX", 7387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .dev_name = "ttyMAX", 7397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .major = MAX3100_MAJOR, 7407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .minor = MAX3100_MINOR, 7417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .nr = MAX_MAX3100, 7427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox}; 7437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int uart_driver_registered; 7447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int __devinit max3100_probe(struct spi_device *spi) 7467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 7477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int i, retval; 7487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct plat_max3100 *pdata; 7497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox u16 tx, rx; 7507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_lock(&max3100s_lock); 7527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (!uart_driver_registered) { 7547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_driver_registered = 1; 7557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox retval = uart_register_driver(&max3100_uart_driver); 7567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (retval) { 7577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox printk(KERN_ERR "Couldn't register max3100 uart driver\n"); 7587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_unlock(&max3100s_lock); 7597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return retval; 7607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 7617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 7627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox for (i = 0; i < MAX_MAX3100; i++) 7647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (!max3100s[i]) 7657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 7667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (i == MAX_MAX3100) { 7677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_warn(&spi->dev, "too many MAX3100 chips\n"); 7687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_unlock(&max3100s_lock); 7697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return -ENOMEM; 7707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 7717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i] = kzalloc(sizeof(struct max3100_port), GFP_KERNEL); 7737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (!max3100s[i]) { 7747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_warn(&spi->dev, 7757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox "kmalloc for max3100 structure %d failed!\n", i); 7767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_unlock(&max3100s_lock); 7777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return -ENOMEM; 7787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 7797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->spi = spi; 7807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->irq = spi->irq; 7817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spin_lock_init(&max3100s[i]->conf_lock); 7827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_set_drvdata(&spi->dev, max3100s[i]); 7837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox pdata = spi->dev.platform_data; 7847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->crystal = pdata->crystal; 7857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->loopback = pdata->loopback; 7867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->poll_time = pdata->poll_time * HZ / 1000; 7877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (pdata->poll_time > 0 && max3100s[i]->poll_time == 0) 7887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->poll_time = 1; 7897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->max3100_hw_suspend = pdata->max3100_hw_suspend; 7907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->minor = i; 7917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox init_timer(&max3100s[i]->timer); 7927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->timer.function = max3100_timeout; 7937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->timer.data = (unsigned long) max3100s[i]; 7947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 7957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&spi->dev, "%s: adding port %d\n", __func__, i); 7967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.irq = max3100s[i]->irq; 7977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.uartclk = max3100s[i]->crystal ? 3686400 : 1843200; 7987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.fifosize = 16; 7997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.ops = &max3100_ops; 8007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; 8017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.line = i; 8027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.type = PORT_MAX3100; 8037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->port.dev = &spi->dev; 8047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox retval = uart_add_one_port(&max3100_uart_driver, &max3100s[i]->port); 8057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (retval < 0) 8067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_warn(&spi->dev, 8077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox "uart_add_one_port failed for line %d with error %d\n", 8087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox i, retval); 8097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* set shutdown mode to save power. Will be woken-up on open */ 8117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (max3100s[i]->max3100_hw_suspend) 8127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i]->max3100_hw_suspend(1); 8137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else { 8147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx = MAX3100_WC | MAX3100_SHDN; 8157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(max3100s[i], tx, &rx); 8167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 8177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_unlock(&max3100s_lock); 8187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 8197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 8207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int __devexit max3100_remove(struct spi_device *spi) 8227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 8237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = dev_get_drvdata(&spi->dev); 8247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox int i; 8257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_lock(&max3100s_lock); 8277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8287831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* find out the index for the chip we are removing */ 8297831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox for (i = 0; i < MAX_MAX3100; i++) 8307831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (max3100s[i] == s) 8317831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox break; 8327831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8337831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&spi->dev, "%s: removing port %d\n", __func__, i); 8347831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_remove_one_port(&max3100_uart_driver, &max3100s[i]->port); 8357831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox kfree(max3100s[i]); 8367831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100s[i] = NULL; 8377831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8387831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* check if this is the last chip we have */ 8397831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox for (i = 0; i < MAX_MAX3100; i++) 8407831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (max3100s[i]) { 8417831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_unlock(&max3100s_lock); 8427831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 8437831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 8447831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox pr_debug("removing max3100 driver\n"); 8457831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_unregister_driver(&max3100_uart_driver); 8467831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8477831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox mutex_unlock(&max3100s_lock); 8487831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 8497831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 8507831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8517831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#ifdef CONFIG_PM 8527831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8537831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_suspend(struct spi_device *spi, pm_message_t state) 8547831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 8557831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = dev_get_drvdata(&spi->dev); 8567831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8577831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 8587831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8597831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox disable_irq(s->irq); 8607831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8617831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->suspending = 1; 8627831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_suspend_port(&max3100_uart_driver, &s->port); 8637831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8647831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->max3100_hw_suspend) 8657831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->max3100_hw_suspend(1); 8667831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox else { 8677831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox /* no HW suspend, so do SW one */ 8687831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox u16 tx, rx; 8697831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8707831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox tx = MAX3100_WC | MAX3100_SHDN; 8717831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_sr(s, tx, &rx); 8727831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox } 8737831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 8747831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 8757831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8767831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int max3100_resume(struct spi_device *spi) 8777831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 8787831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox struct max3100_port *s = dev_get_drvdata(&spi->dev); 8797831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8807831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox dev_dbg(&s->spi->dev, "%s\n", __func__); 8817831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8827831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->max3100_hw_suspend) 8837831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->max3100_hw_suspend(0); 8847831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox uart_resume_port(&max3100_uart_driver, &s->port); 8857831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->suspending = 0; 8867831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8877831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox enable_irq(s->irq); 8887831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8897831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox s->conf_commit = 1; 8907831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox if (s->workqueue) 8917831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox max3100_dowork(s); 8927831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8937831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return 0; 8947831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 8957831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 8967831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#else 8977831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define max3100_suspend NULL 8987831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#define max3100_resume NULL 8997831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox#endif 9007831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 9017831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic struct spi_driver max3100_driver = { 9027831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .driver = { 9037831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .name = "max3100", 9047831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .owner = THIS_MODULE, 9057831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox }, 9067831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 9077831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .probe = max3100_probe, 9087831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .remove = __devexit_p(max3100_remove), 9097831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .suspend = max3100_suspend, 9107831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox .resume = max3100_resume, 9117831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox}; 9127831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 9137831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic int __init max3100_init(void) 9147831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 9157831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox return spi_register_driver(&max3100_driver); 9167831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 9177831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxmodule_init(max3100_init); 9187831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 9197831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxstatic void __exit max3100_exit(void) 9207831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox{ 9217831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox spi_unregister_driver(&max3100_driver); 9227831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox} 9237831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Coxmodule_exit(max3100_exit); 9247831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan Cox 9257831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan CoxMODULE_DESCRIPTION("MAX3100 driver"); 9267831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan CoxMODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); 9277831d56b0a3544cbb6f82f76c34ca95e24d5b676Alan CoxMODULE_LICENSE("GPL"); 928e0626e3844e8f430fc1a4417f523a00797df7ca6Anton VorontsovMODULE_ALIAS("spi:max3100"); 929