brintos

brintos / linux-shallow public Read only

0
0
Text · 28.1 KiB · 6b7471d Raw
1167 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * SDIO UART/GPS driver4 *5 * Based on drivers/serial/8250.c and drivers/serial/serial_core.c6 * by Russell King.7 *8 * Author:	Nicolas Pitre9 * Created:	June 15, 200710 * Copyright:	MontaVista Software, Inc.11 */12 13/*14 * Note: Although this driver assumes a 16550A-like UART implementation,15 * it is not possible to leverage the common 8250/16550 driver, nor the16 * core UART infrastructure, as they assumes direct access to the hardware17 * registers, often under a spinlock.  This is not possible in the SDIO18 * context as SDIO access functions must be able to sleep.19 *20 * Because we need to lock the SDIO host to ensure an exclusive access to21 * the card, we simply rely on that lock to also prevent and serialize22 * concurrent access to the same port.23 */24 25#include <linux/module.h>26#include <linux/init.h>27#include <linux/kernel.h>28#include <linux/sched.h>29#include <linux/mutex.h>30#include <linux/seq_file.h>31#include <linux/serial.h>32#include <linux/serial_reg.h>33#include <linux/circ_buf.h>34#include <linux/tty.h>35#include <linux/tty_flip.h>36#include <linux/kfifo.h>37#include <linux/slab.h>38 39#include <linux/mmc/core.h>40#include <linux/mmc/card.h>41#include <linux/mmc/sdio_func.h>42#include <linux/mmc/sdio_ids.h>43 44 45#define UART_NR		8	/* Number of UARTs this driver can handle */46 47 48#define FIFO_SIZE	PAGE_SIZE49#define WAKEUP_CHARS	25650 51struct uart_icount {52	__u32	cts;53	__u32	dsr;54	__u32	rng;55	__u32	dcd;56	__u32	rx;57	__u32	tx;58	__u32	frame;59	__u32	overrun;60	__u32	parity;61	__u32	brk;62};63 64struct sdio_uart_port {65	struct tty_port		port;66	unsigned int		index;67	struct sdio_func	*func;68	struct mutex		func_lock;69	struct task_struct	*in_sdio_uart_irq;70	unsigned int		regs_offset;71	struct kfifo		xmit_fifo;72	spinlock_t		write_lock;73	struct uart_icount	icount;74	unsigned int		uartclk;75	unsigned int		mctrl;76	unsigned int		rx_mctrl;77	unsigned int		read_status_mask;78	unsigned int		ignore_status_mask;79	unsigned char		x_char;80	unsigned char           ier;81	unsigned char           lcr;82};83 84static struct sdio_uart_port *sdio_uart_table[UART_NR];85static DEFINE_SPINLOCK(sdio_uart_table_lock);86 87static int sdio_uart_add_port(struct sdio_uart_port *port)88{89	int index, ret = -EBUSY;90 91	mutex_init(&port->func_lock);92	spin_lock_init(&port->write_lock);93	if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))94		return -ENOMEM;95 96	spin_lock(&sdio_uart_table_lock);97	for (index = 0; index < UART_NR; index++) {98		if (!sdio_uart_table[index]) {99			port->index = index;100			sdio_uart_table[index] = port;101			ret = 0;102			break;103		}104	}105	spin_unlock(&sdio_uart_table_lock);106 107	return ret;108}109 110static struct sdio_uart_port *sdio_uart_port_get(unsigned index)111{112	struct sdio_uart_port *port;113 114	if (index >= UART_NR)115		return NULL;116 117	spin_lock(&sdio_uart_table_lock);118	port = sdio_uart_table[index];119	if (port)120		tty_port_get(&port->port);121	spin_unlock(&sdio_uart_table_lock);122 123	return port;124}125 126static void sdio_uart_port_put(struct sdio_uart_port *port)127{128	tty_port_put(&port->port);129}130 131static void sdio_uart_port_remove(struct sdio_uart_port *port)132{133	struct sdio_func *func;134 135	spin_lock(&sdio_uart_table_lock);136	sdio_uart_table[port->index] = NULL;137	spin_unlock(&sdio_uart_table_lock);138 139	/*140	 * We're killing a port that potentially still is in use by141	 * the tty layer. Be careful to prevent any further access142	 * to the SDIO function and arrange for the tty layer to143	 * give up on that port ASAP.144	 * Beware: the lock ordering is critical.145	 */146	mutex_lock(&port->port.mutex);147	mutex_lock(&port->func_lock);148	func = port->func;149	sdio_claim_host(func);150	port->func = NULL;151	mutex_unlock(&port->func_lock);152	/* tty_hangup is async so is this safe as is ?? */153	tty_port_tty_hangup(&port->port, false);154	mutex_unlock(&port->port.mutex);155	sdio_release_irq(func);156	sdio_disable_func(func);157	sdio_release_host(func);158 159	sdio_uart_port_put(port);160}161 162static int sdio_uart_claim_func(struct sdio_uart_port *port)163{164	mutex_lock(&port->func_lock);165	if (unlikely(!port->func)) {166		mutex_unlock(&port->func_lock);167		return -ENODEV;168	}169	if (likely(port->in_sdio_uart_irq != current))170		sdio_claim_host(port->func);171	mutex_unlock(&port->func_lock);172	return 0;173}174 175static inline void sdio_uart_release_func(struct sdio_uart_port *port)176{177	if (likely(port->in_sdio_uart_irq != current))178		sdio_release_host(port->func);179}180 181static inline u8 sdio_in(struct sdio_uart_port *port, int offset)182{183	return sdio_readb(port->func, port->regs_offset + offset, NULL);184}185 186static inline void sdio_out(struct sdio_uart_port *port, int offset, int value)187{188	sdio_writeb(port->func, value, port->regs_offset + offset, NULL);189}190 191static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port)192{193	unsigned int ret;194	u8 status;195 196	/* FIXME: What stops this losing the delta bits and breaking197	   sdio_uart_check_modem_status ? */198	status = sdio_in(port, UART_MSR);199 200	ret = 0;201	if (status & UART_MSR_DCD)202		ret |= TIOCM_CAR;203	if (status & UART_MSR_RI)204		ret |= TIOCM_RNG;205	if (status & UART_MSR_DSR)206		ret |= TIOCM_DSR;207	if (status & UART_MSR_CTS)208		ret |= TIOCM_CTS;209	return ret;210}211 212static void sdio_uart_write_mctrl(struct sdio_uart_port *port,213				  unsigned int mctrl)214{215	unsigned char mcr = 0;216 217	if (mctrl & TIOCM_RTS)218		mcr |= UART_MCR_RTS;219	if (mctrl & TIOCM_DTR)220		mcr |= UART_MCR_DTR;221	if (mctrl & TIOCM_OUT1)222		mcr |= UART_MCR_OUT1;223	if (mctrl & TIOCM_OUT2)224		mcr |= UART_MCR_OUT2;225	if (mctrl & TIOCM_LOOP)226		mcr |= UART_MCR_LOOP;227 228	sdio_out(port, UART_MCR, mcr);229}230 231static inline void sdio_uart_update_mctrl(struct sdio_uart_port *port,232					  unsigned int set, unsigned int clear)233{234	unsigned int old;235 236	old = port->mctrl;237	port->mctrl = (old & ~clear) | set;238	if (old != port->mctrl)239		sdio_uart_write_mctrl(port, port->mctrl);240}241 242#define sdio_uart_set_mctrl(port, x)	sdio_uart_update_mctrl(port, x, 0)243#define sdio_uart_clear_mctrl(port, x)	sdio_uart_update_mctrl(port, 0, x)244 245static void sdio_uart_change_speed(struct sdio_uart_port *port,246				   struct ktermios *termios,247				   const struct ktermios *old)248{249	unsigned char cval, fcr = 0;250	unsigned int baud, quot;251 252	cval = UART_LCR_WLEN(tty_get_char_size(termios->c_cflag));253 254	if (termios->c_cflag & CSTOPB)255		cval |= UART_LCR_STOP;256	if (termios->c_cflag & PARENB)257		cval |= UART_LCR_PARITY;258	if (!(termios->c_cflag & PARODD))259		cval |= UART_LCR_EPAR;260 261	for (;;) {262		baud = tty_termios_baud_rate(termios);263		if (baud == 0)264			baud = 9600;  /* Special case: B0 rate. */265		if (baud <= port->uartclk)266			break;267		/*268		 * Oops, the quotient was zero.  Try again with the old269		 * baud rate if possible, otherwise default to 9600.270		 */271		termios->c_cflag &= ~CBAUD;272		if (old) {273			termios->c_cflag |= old->c_cflag & CBAUD;274			old = NULL;275		} else276			termios->c_cflag |= B9600;277	}278	quot = (2 * port->uartclk + baud) / (2 * baud);279 280	if (baud < 2400)281		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;282	else283		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;284 285	port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;286	if (termios->c_iflag & INPCK)287		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;288	if (termios->c_iflag & (BRKINT | PARMRK))289		port->read_status_mask |= UART_LSR_BI;290 291	/*292	 * Characters to ignore293	 */294	port->ignore_status_mask = 0;295	if (termios->c_iflag & IGNPAR)296		port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;297	if (termios->c_iflag & IGNBRK) {298		port->ignore_status_mask |= UART_LSR_BI;299		/*300		 * If we're ignoring parity and break indicators,301		 * ignore overruns too (for real raw support).302		 */303		if (termios->c_iflag & IGNPAR)304			port->ignore_status_mask |= UART_LSR_OE;305	}306 307	/*308	 * ignore all characters if CREAD is not set309	 */310	if ((termios->c_cflag & CREAD) == 0)311		port->ignore_status_mask |= UART_LSR_DR;312 313	/*314	 * CTS flow control flag and modem status interrupts315	 */316	port->ier &= ~UART_IER_MSI;317	if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL))318		port->ier |= UART_IER_MSI;319 320	port->lcr = cval;321 322	sdio_out(port, UART_IER, port->ier);323	sdio_out(port, UART_LCR, cval | UART_LCR_DLAB);324	sdio_out(port, UART_DLL, quot & 0xff);325	sdio_out(port, UART_DLM, quot >> 8);326	sdio_out(port, UART_LCR, cval);327	sdio_out(port, UART_FCR, fcr);328 329	sdio_uart_write_mctrl(port, port->mctrl);330}331 332static void sdio_uart_start_tx(struct sdio_uart_port *port)333{334	if (!(port->ier & UART_IER_THRI)) {335		port->ier |= UART_IER_THRI;336		sdio_out(port, UART_IER, port->ier);337	}338}339 340static void sdio_uart_stop_tx(struct sdio_uart_port *port)341{342	if (port->ier & UART_IER_THRI) {343		port->ier &= ~UART_IER_THRI;344		sdio_out(port, UART_IER, port->ier);345	}346}347 348static void sdio_uart_stop_rx(struct sdio_uart_port *port)349{350	port->ier &= ~UART_IER_RLSI;351	port->read_status_mask &= ~UART_LSR_DR;352	sdio_out(port, UART_IER, port->ier);353}354 355static void sdio_uart_receive_chars(struct sdio_uart_port *port, u8 *status)356{357	int max_count = 256;358 359	do {360		u8 ch = sdio_in(port, UART_RX);361		u8 flag = TTY_NORMAL;362		port->icount.rx++;363 364		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |365					UART_LSR_FE | UART_LSR_OE))) {366			/*367			 * For statistics only368			 */369			if (*status & UART_LSR_BI) {370				*status &= ~(UART_LSR_FE | UART_LSR_PE);371				port->icount.brk++;372			} else if (*status & UART_LSR_PE)373				port->icount.parity++;374			else if (*status & UART_LSR_FE)375				port->icount.frame++;376			if (*status & UART_LSR_OE)377				port->icount.overrun++;378 379			/*380			 * Mask off conditions which should be ignored.381			 */382			*status &= port->read_status_mask;383			if (*status & UART_LSR_BI)384				flag = TTY_BREAK;385			else if (*status & UART_LSR_PE)386				flag = TTY_PARITY;387			else if (*status & UART_LSR_FE)388				flag = TTY_FRAME;389		}390 391		if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)392			tty_insert_flip_char(&port->port, ch, flag);393 394		/*395		 * Overrun is special.  Since it's reported immediately,396		 * it doesn't affect the current character.397		 */398		if (*status & ~port->ignore_status_mask & UART_LSR_OE)399			tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);400 401		*status = sdio_in(port, UART_LSR);402	} while ((*status & UART_LSR_DR) && (max_count-- > 0));403 404	tty_flip_buffer_push(&port->port);405}406 407static void sdio_uart_transmit_chars(struct sdio_uart_port *port)408{409	struct kfifo *xmit = &port->xmit_fifo;410	int count;411	struct tty_struct *tty;412	u8 iobuf[16];413	int len;414 415	if (port->x_char) {416		sdio_out(port, UART_TX, port->x_char);417		port->icount.tx++;418		port->x_char = 0;419		return;420	}421 422	tty = tty_port_tty_get(&port->port);423 424	if (tty == NULL || !kfifo_len(xmit) ||425				tty->flow.stopped || tty->hw_stopped) {426		sdio_uart_stop_tx(port);427		tty_kref_put(tty);428		return;429	}430 431	len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock);432	for (count = 0; count < len; count++) {433		sdio_out(port, UART_TX, iobuf[count]);434		port->icount.tx++;435	}436 437	len = kfifo_len(xmit);438	if (len < WAKEUP_CHARS) {439		tty_wakeup(tty);440		if (len == 0)441			sdio_uart_stop_tx(port);442	}443	tty_kref_put(tty);444}445 446static void sdio_uart_check_modem_status(struct sdio_uart_port *port)447{448	struct tty_struct *tty;449	u8 status;450 451	status = sdio_in(port, UART_MSR);452 453	if ((status & UART_MSR_ANY_DELTA) == 0)454		return;455 456	if (status & UART_MSR_TERI)457		port->icount.rng++;458	if (status & UART_MSR_DDSR)459		port->icount.dsr++;460	if (status & UART_MSR_DDCD) {461		port->icount.dcd++;462		/* DCD raise - wake for open */463		if (status & UART_MSR_DCD)464			wake_up_interruptible(&port->port.open_wait);465		else {466			/* DCD drop - hang up if tty attached */467			tty_port_tty_hangup(&port->port, false);468		}469	}470	if (status & UART_MSR_DCTS) {471		port->icount.cts++;472		tty = tty_port_tty_get(&port->port);473		if (tty && C_CRTSCTS(tty)) {474			int cts = (status & UART_MSR_CTS);475			if (tty->hw_stopped) {476				if (cts) {477					tty->hw_stopped = false;478					sdio_uart_start_tx(port);479					tty_wakeup(tty);480				}481			} else {482				if (!cts) {483					tty->hw_stopped = true;484					sdio_uart_stop_tx(port);485				}486			}487		}488		tty_kref_put(tty);489	}490}491 492/*493 * This handles the interrupt from one port.494 */495static void sdio_uart_irq(struct sdio_func *func)496{497	struct sdio_uart_port *port = sdio_get_drvdata(func);498	u8 iir, lsr;499 500	/*501	 * In a few places sdio_uart_irq() is called directly instead of502	 * waiting for the actual interrupt to be raised and the SDIO IRQ503	 * thread scheduled in order to reduce latency.  However, some504	 * interaction with the tty core may end up calling us back505	 * (serial echo, flow control, etc.) through those same places506	 * causing undesirable effects.  Let's stop the recursion here.507	 */508	if (unlikely(port->in_sdio_uart_irq == current))509		return;510 511	iir = sdio_in(port, UART_IIR);512	if (iir & UART_IIR_NO_INT)513		return;514 515	port->in_sdio_uart_irq = current;516	lsr = sdio_in(port, UART_LSR);517	if (lsr & UART_LSR_DR)518		sdio_uart_receive_chars(port, &lsr);519	sdio_uart_check_modem_status(port);520	if (lsr & UART_LSR_THRE)521		sdio_uart_transmit_chars(port);522	port->in_sdio_uart_irq = NULL;523}524 525static bool uart_carrier_raised(struct tty_port *tport)526{527	struct sdio_uart_port *port =528			container_of(tport, struct sdio_uart_port, port);529	unsigned int ret = sdio_uart_claim_func(port);530	if (ret)	/* Missing hardware shouldn't block for carrier */531		return 1;532	ret = sdio_uart_get_mctrl(port);533	sdio_uart_release_func(port);534 535	return ret & TIOCM_CAR;536}537 538/**539 *	uart_dtr_rts		-	 port helper to set uart signals540 *	@tport: tty port to be updated541 *	@active: set to turn on DTR/RTS542 *543 *	Called by the tty port helpers when the modem signals need to be544 *	adjusted during an open, close and hangup.545 */546 547static void uart_dtr_rts(struct tty_port *tport, bool active)548{549	struct sdio_uart_port *port =550			container_of(tport, struct sdio_uart_port, port);551	int ret = sdio_uart_claim_func(port);552	if (ret)553		return;554	if (!active)555		sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);556	else557		sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);558	sdio_uart_release_func(port);559}560 561/**562 *	sdio_uart_activate	-	start up hardware563 *	@tport: tty port to activate564 *	@tty: tty bound to this port565 *566 *	Activate a tty port. The port locking guarantees us this will be567 *	run exactly once per set of opens, and if successful will see the568 *	shutdown method run exactly once to match. Start up and shutdown are569 *	protected from each other by the internal locking and will not run570 *	at the same time even during a hangup event.571 *572 *	If we successfully start up the port we take an extra kref as we573 *	will keep it around until shutdown when the kref is dropped.574 */575 576static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)577{578	struct sdio_uart_port *port =579			container_of(tport, struct sdio_uart_port, port);580	int ret;581 582	/*583	 * Set the TTY IO error marker - we will only clear this584	 * once we have successfully opened the port.585	 */586	set_bit(TTY_IO_ERROR, &tty->flags);587 588	kfifo_reset(&port->xmit_fifo);589 590	ret = sdio_uart_claim_func(port);591	if (ret)592		return ret;593	ret = sdio_enable_func(port->func);594	if (ret)595		goto err1;596	ret = sdio_claim_irq(port->func, sdio_uart_irq);597	if (ret)598		goto err2;599 600	/*601	 * Clear the FIFO buffers and disable them.602	 * (they will be reenabled in sdio_change_speed())603	 */604	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);605	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |606		       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);607	sdio_out(port, UART_FCR, 0);608 609	/*610	 * Clear the interrupt registers.611	 */612	(void) sdio_in(port, UART_LSR);613	(void) sdio_in(port, UART_RX);614	(void) sdio_in(port, UART_IIR);615	(void) sdio_in(port, UART_MSR);616 617	/*618	 * Now, initialize the UART619	 */620	sdio_out(port, UART_LCR, UART_LCR_WLEN8);621 622	port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;623	port->mctrl = TIOCM_OUT2;624 625	sdio_uart_change_speed(port, &tty->termios, NULL);626 627	if (C_BAUD(tty))628		sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);629 630	if (C_CRTSCTS(tty))631		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))632			tty->hw_stopped = true;633 634	clear_bit(TTY_IO_ERROR, &tty->flags);635 636	/* Kick the IRQ handler once while we're still holding the host lock */637	sdio_uart_irq(port->func);638 639	sdio_uart_release_func(port);640	return 0;641 642err2:643	sdio_disable_func(port->func);644err1:645	sdio_uart_release_func(port);646	return ret;647}648 649/**650 *	sdio_uart_shutdown	-	stop hardware651 *	@tport: tty port to shut down652 *653 *	Deactivate a tty port. The port locking guarantees us this will be654 *	run only if a successful matching activate already ran. The two are655 *	protected from each other by the internal locking and will not run656 *	at the same time even during a hangup event.657 */658 659static void sdio_uart_shutdown(struct tty_port *tport)660{661	struct sdio_uart_port *port =662			container_of(tport, struct sdio_uart_port, port);663	int ret;664 665	ret = sdio_uart_claim_func(port);666	if (ret)667		return;668 669	sdio_uart_stop_rx(port);670 671	/* Disable interrupts from this port */672	sdio_release_irq(port->func);673	port->ier = 0;674	sdio_out(port, UART_IER, 0);675 676	sdio_uart_clear_mctrl(port, TIOCM_OUT2);677 678	/* Disable break condition and FIFOs. */679	port->lcr &= ~UART_LCR_SBC;680	sdio_out(port, UART_LCR, port->lcr);681	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |682				 UART_FCR_CLEAR_RCVR |683				 UART_FCR_CLEAR_XMIT);684	sdio_out(port, UART_FCR, 0);685 686	sdio_disable_func(port->func);687 688	sdio_uart_release_func(port);689}690 691static void sdio_uart_port_destroy(struct tty_port *tport)692{693	struct sdio_uart_port *port =694		container_of(tport, struct sdio_uart_port, port);695	kfifo_free(&port->xmit_fifo);696	kfree(port);697}698 699/**700 *	sdio_uart_install	-	install method701 *	@driver: the driver in use (sdio_uart in our case)702 *	@tty: the tty being bound703 *704 *	Look up and bind the tty and the driver together. Initialize705 *	any needed private data (in our case the termios)706 */707 708static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)709{710	int idx = tty->index;711	struct sdio_uart_port *port = sdio_uart_port_get(idx);712	int ret = tty_standard_install(driver, tty);713 714	if (ret == 0)715		/* This is the ref sdio_uart_port get provided */716		tty->driver_data = port;717	else718		sdio_uart_port_put(port);719	return ret;720}721 722/**723 *	sdio_uart_cleanup	-	called on the last tty kref drop724 *	@tty: the tty being destroyed725 *726 *	Called asynchronously when the last reference to the tty is dropped.727 *	We cannot destroy the tty->driver_data port kref until this point728 */729 730static void sdio_uart_cleanup(struct tty_struct *tty)731{732	struct sdio_uart_port *port = tty->driver_data;733	tty->driver_data = NULL;	/* Bug trap */734	sdio_uart_port_put(port);735}736 737/*738 *	Open/close/hangup is now entirely boilerplate739 */740 741static int sdio_uart_open(struct tty_struct *tty, struct file *filp)742{743	struct sdio_uart_port *port = tty->driver_data;744	return tty_port_open(&port->port, tty, filp);745}746 747static void sdio_uart_close(struct tty_struct *tty, struct file * filp)748{749	struct sdio_uart_port *port = tty->driver_data;750	tty_port_close(&port->port, tty, filp);751}752 753static void sdio_uart_hangup(struct tty_struct *tty)754{755	struct sdio_uart_port *port = tty->driver_data;756	tty_port_hangup(&port->port);757}758 759static ssize_t sdio_uart_write(struct tty_struct *tty, const u8 *buf,760			      size_t count)761{762	struct sdio_uart_port *port = tty->driver_data;763	int ret;764 765	if (!port->func)766		return -ENODEV;767 768	ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock);769	if (!(port->ier & UART_IER_THRI)) {770		int err = sdio_uart_claim_func(port);771		if (!err) {772			sdio_uart_start_tx(port);773			sdio_uart_irq(port->func);774			sdio_uart_release_func(port);775		} else776			ret = err;777	}778 779	return ret;780}781 782static unsigned int sdio_uart_write_room(struct tty_struct *tty)783{784	struct sdio_uart_port *port = tty->driver_data;785	return FIFO_SIZE - kfifo_len(&port->xmit_fifo);786}787 788static unsigned int sdio_uart_chars_in_buffer(struct tty_struct *tty)789{790	struct sdio_uart_port *port = tty->driver_data;791	return kfifo_len(&port->xmit_fifo);792}793 794static void sdio_uart_send_xchar(struct tty_struct *tty, u8 ch)795{796	struct sdio_uart_port *port = tty->driver_data;797 798	port->x_char = ch;799	if (ch && !(port->ier & UART_IER_THRI)) {800		if (sdio_uart_claim_func(port) != 0)801			return;802		sdio_uart_start_tx(port);803		sdio_uart_irq(port->func);804		sdio_uart_release_func(port);805	}806}807 808static void sdio_uart_throttle(struct tty_struct *tty)809{810	struct sdio_uart_port *port = tty->driver_data;811 812	if (!I_IXOFF(tty) && !C_CRTSCTS(tty))813		return;814 815	if (sdio_uart_claim_func(port) != 0)816		return;817 818	if (I_IXOFF(tty)) {819		port->x_char = STOP_CHAR(tty);820		sdio_uart_start_tx(port);821	}822 823	if (C_CRTSCTS(tty))824		sdio_uart_clear_mctrl(port, TIOCM_RTS);825 826	sdio_uart_irq(port->func);827	sdio_uart_release_func(port);828}829 830static void sdio_uart_unthrottle(struct tty_struct *tty)831{832	struct sdio_uart_port *port = tty->driver_data;833 834	if (!I_IXOFF(tty) && !C_CRTSCTS(tty))835		return;836 837	if (sdio_uart_claim_func(port) != 0)838		return;839 840	if (I_IXOFF(tty)) {841		if (port->x_char) {842			port->x_char = 0;843		} else {844			port->x_char = START_CHAR(tty);845			sdio_uart_start_tx(port);846		}847	}848 849	if (C_CRTSCTS(tty))850		sdio_uart_set_mctrl(port, TIOCM_RTS);851 852	sdio_uart_irq(port->func);853	sdio_uart_release_func(port);854}855 856static void sdio_uart_set_termios(struct tty_struct *tty,857				  const struct ktermios *old_termios)858{859	struct sdio_uart_port *port = tty->driver_data;860	unsigned int cflag = tty->termios.c_cflag;861 862	if (sdio_uart_claim_func(port) != 0)863		return;864 865	sdio_uart_change_speed(port, &tty->termios, old_termios);866 867	/* Handle transition to B0 status */868	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))869		sdio_uart_clear_mctrl(port, TIOCM_RTS | TIOCM_DTR);870 871	/* Handle transition away from B0 status */872	if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {873		unsigned int mask = TIOCM_DTR;874		if (!(cflag & CRTSCTS) || !tty_throttled(tty))875			mask |= TIOCM_RTS;876		sdio_uart_set_mctrl(port, mask);877	}878 879	/* Handle turning off CRTSCTS */880	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {881		tty->hw_stopped = false;882		sdio_uart_start_tx(port);883	}884 885	/* Handle turning on CRTSCTS */886	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {887		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) {888			tty->hw_stopped = true;889			sdio_uart_stop_tx(port);890		}891	}892 893	sdio_uart_release_func(port);894}895 896static int sdio_uart_break_ctl(struct tty_struct *tty, int break_state)897{898	struct sdio_uart_port *port = tty->driver_data;899	int result;900 901	result = sdio_uart_claim_func(port);902	if (result != 0)903		return result;904 905	if (break_state == -1)906		port->lcr |= UART_LCR_SBC;907	else908		port->lcr &= ~UART_LCR_SBC;909	sdio_out(port, UART_LCR, port->lcr);910 911	sdio_uart_release_func(port);912	return 0;913}914 915static int sdio_uart_tiocmget(struct tty_struct *tty)916{917	struct sdio_uart_port *port = tty->driver_data;918	int result;919 920	result = sdio_uart_claim_func(port);921	if (!result) {922		result = port->mctrl | sdio_uart_get_mctrl(port);923		sdio_uart_release_func(port);924	}925 926	return result;927}928 929static int sdio_uart_tiocmset(struct tty_struct *tty,930			      unsigned int set, unsigned int clear)931{932	struct sdio_uart_port *port = tty->driver_data;933	int result;934 935	result = sdio_uart_claim_func(port);936	if (!result) {937		sdio_uart_update_mctrl(port, set, clear);938		sdio_uart_release_func(port);939	}940 941	return result;942}943 944static int sdio_uart_proc_show(struct seq_file *m, void *v)945{946	int i;947 948	seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",949		       "", "", "");950	for (i = 0; i < UART_NR; i++) {951		struct sdio_uart_port *port = sdio_uart_port_get(i);952		if (port) {953			seq_printf(m, "%d: uart:SDIO", i);954			if (capable(CAP_SYS_ADMIN)) {955				seq_printf(m, " tx:%d rx:%d",956					      port->icount.tx, port->icount.rx);957				if (port->icount.frame)958					seq_printf(m, " fe:%d",959						      port->icount.frame);960				if (port->icount.parity)961					seq_printf(m, " pe:%d",962						      port->icount.parity);963				if (port->icount.brk)964					seq_printf(m, " brk:%d",965						      port->icount.brk);966				if (port->icount.overrun)967					seq_printf(m, " oe:%d",968						      port->icount.overrun);969				if (port->icount.cts)970					seq_printf(m, " cts:%d",971						      port->icount.cts);972				if (port->icount.dsr)973					seq_printf(m, " dsr:%d",974						      port->icount.dsr);975				if (port->icount.rng)976					seq_printf(m, " rng:%d",977						      port->icount.rng);978				if (port->icount.dcd)979					seq_printf(m, " dcd:%d",980						      port->icount.dcd);981			}982			sdio_uart_port_put(port);983			seq_putc(m, '\n');984		}985	}986	return 0;987}988 989static const struct tty_port_operations sdio_uart_port_ops = {990	.dtr_rts = uart_dtr_rts,991	.carrier_raised = uart_carrier_raised,992	.shutdown = sdio_uart_shutdown,993	.activate = sdio_uart_activate,994	.destruct = sdio_uart_port_destroy,995};996 997static const struct tty_operations sdio_uart_ops = {998	.open			= sdio_uart_open,999	.close			= sdio_uart_close,1000	.write			= sdio_uart_write,1001	.write_room		= sdio_uart_write_room,1002	.chars_in_buffer	= sdio_uart_chars_in_buffer,1003	.send_xchar		= sdio_uart_send_xchar,1004	.throttle		= sdio_uart_throttle,1005	.unthrottle		= sdio_uart_unthrottle,1006	.set_termios		= sdio_uart_set_termios,1007	.hangup			= sdio_uart_hangup,1008	.break_ctl		= sdio_uart_break_ctl,1009	.tiocmget		= sdio_uart_tiocmget,1010	.tiocmset		= sdio_uart_tiocmset,1011	.install		= sdio_uart_install,1012	.cleanup		= sdio_uart_cleanup,1013	.proc_show		= sdio_uart_proc_show,1014};1015 1016static struct tty_driver *sdio_uart_tty_driver;1017 1018static int sdio_uart_probe(struct sdio_func *func,1019			   const struct sdio_device_id *id)1020{1021	struct sdio_uart_port *port;1022	int ret;1023 1024	port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL);1025	if (!port)1026		return -ENOMEM;1027 1028	if (func->class == SDIO_CLASS_UART) {1029		pr_warn("%s: need info on UART class basic setup\n",1030			sdio_func_id(func));1031		kfree(port);1032		return -ENOSYS;1033	} else if (func->class == SDIO_CLASS_GPS) {1034		/*1035		 * We need tuple 0x91.  It contains SUBTPL_SIOREG1036		 * and SUBTPL_RCVCAPS.1037		 */1038		struct sdio_func_tuple *tpl;1039		for (tpl = func->tuples; tpl; tpl = tpl->next) {1040			if (tpl->code != 0x91)1041				continue;1042			if (tpl->size < 10)1043				continue;1044			if (tpl->data[1] == 0)  /* SUBTPL_SIOREG */1045				break;1046		}1047		if (!tpl) {1048			pr_warn("%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",1049				sdio_func_id(func));1050			kfree(port);1051			return -EINVAL;1052		}1053		pr_debug("%s: Register ID = 0x%02x, Exp ID = 0x%02x\n",1054		       sdio_func_id(func), tpl->data[2], tpl->data[3]);1055		port->regs_offset = (tpl->data[4] << 0) |1056				    (tpl->data[5] << 8) |1057				    (tpl->data[6] << 16);1058		pr_debug("%s: regs offset = 0x%x\n",1059		       sdio_func_id(func), port->regs_offset);1060		port->uartclk = tpl->data[7] * 115200;1061		if (port->uartclk == 0)1062			port->uartclk = 115200;1063		pr_debug("%s: clk %d baudcode %u 4800-div %u\n",1064		       sdio_func_id(func), port->uartclk,1065		       tpl->data[7], tpl->data[8] | (tpl->data[9] << 8));1066	} else {1067		kfree(port);1068		return -EINVAL;1069	}1070 1071	port->func = func;1072	sdio_set_drvdata(func, port);1073	tty_port_init(&port->port);1074	port->port.ops = &sdio_uart_port_ops;1075 1076	ret = sdio_uart_add_port(port);1077	if (ret) {1078		kfree(port);1079	} else {1080		struct device *dev;1081		dev = tty_port_register_device(&port->port,1082				sdio_uart_tty_driver, port->index, &func->dev);1083		if (IS_ERR(dev)) {1084			sdio_uart_port_remove(port);1085			ret = PTR_ERR(dev);1086		}1087	}1088 1089	return ret;1090}1091 1092static void sdio_uart_remove(struct sdio_func *func)1093{1094	struct sdio_uart_port *port = sdio_get_drvdata(func);1095 1096	tty_unregister_device(sdio_uart_tty_driver, port->index);1097	sdio_uart_port_remove(port);1098}1099 1100static const struct sdio_device_id sdio_uart_ids[] = {1101	{ SDIO_DEVICE_CLASS(SDIO_CLASS_UART)		},1102	{ SDIO_DEVICE_CLASS(SDIO_CLASS_GPS)		},1103	{ /* end: all zeroes */				},1104};1105 1106MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);1107 1108static struct sdio_driver sdio_uart_driver = {1109	.probe		= sdio_uart_probe,1110	.remove		= sdio_uart_remove,1111	.name		= "sdio_uart",1112	.id_table	= sdio_uart_ids,1113};1114 1115static int __init sdio_uart_init(void)1116{1117	int ret;1118	struct tty_driver *tty_drv;1119 1120	sdio_uart_tty_driver = tty_drv = tty_alloc_driver(UART_NR,1121			TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);1122	if (IS_ERR(tty_drv))1123		return PTR_ERR(tty_drv);1124 1125	tty_drv->driver_name = "sdio_uart";1126	tty_drv->name =   "ttySDIO";1127	tty_drv->major = 0;  /* dynamically allocated */1128	tty_drv->minor_start = 0;1129	tty_drv->type = TTY_DRIVER_TYPE_SERIAL;1130	tty_drv->subtype = SERIAL_TYPE_NORMAL;1131	tty_drv->init_termios = tty_std_termios;1132	tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;1133	tty_drv->init_termios.c_ispeed = 4800;1134	tty_drv->init_termios.c_ospeed = 4800;1135	tty_set_operations(tty_drv, &sdio_uart_ops);1136 1137	ret = tty_register_driver(tty_drv);1138	if (ret)1139		goto err1;1140 1141	ret = sdio_register_driver(&sdio_uart_driver);1142	if (ret)1143		goto err2;1144 1145	return 0;1146 1147err2:1148	tty_unregister_driver(tty_drv);1149err1:1150	tty_driver_kref_put(tty_drv);1151	return ret;1152}1153 1154static void __exit sdio_uart_exit(void)1155{1156	sdio_unregister_driver(&sdio_uart_driver);1157	tty_unregister_driver(sdio_uart_tty_driver);1158	tty_driver_kref_put(sdio_uart_tty_driver);1159}1160 1161module_init(sdio_uart_init);1162module_exit(sdio_uart_exit);1163 1164MODULE_AUTHOR("Nicolas Pitre");1165MODULE_DESCRIPTION("SDIO UART/GPS driver");1166MODULE_LICENSE("GPL");1167