brintos

brintos / linux-shallow public Read only

0
0
Text · 25.1 KiB · cdf4ebb Raw
1029 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * UART driver for the Greybus "generic" UART module.4 *5 * Copyright 2014 Google Inc.6 * Copyright 2014 Linaro Ltd.7 *8 * Heavily based on drivers/usb/class/cdc-acm.c and9 * drivers/usb/serial/usb-serial.c.10 */11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt12 13#include <linux/kernel.h>14#include <linux/errno.h>15#include <linux/module.h>16#include <linux/sched/signal.h>17#include <linux/wait.h>18#include <linux/slab.h>19#include <linux/uaccess.h>20#include <linux/mutex.h>21#include <linux/tty.h>22#include <linux/serial.h>23#include <linux/tty_driver.h>24#include <linux/tty_flip.h>25#include <linux/idr.h>26#include <linux/fs.h>27#include <linux/kdev_t.h>28#include <linux/kfifo.h>29#include <linux/workqueue.h>30#include <linux/completion.h>31#include <linux/greybus.h>32 33#include "gbphy.h"34 35#define GB_NUM_MINORS	16	/* 16 is more than enough */36#define GB_NAME		"ttyGB"37 38#define GB_UART_WRITE_FIFO_SIZE		PAGE_SIZE39#define GB_UART_WRITE_ROOM_MARGIN	1	/* leave some space in fifo */40#define GB_UART_FIRMWARE_CREDITS	409641#define GB_UART_CREDIT_WAIT_TIMEOUT_MSEC	1000042 43struct gb_tty {44	struct gbphy_device *gbphy_dev;45	struct tty_port port;46	void *buffer;47	size_t buffer_payload_max;48	struct gb_connection *connection;49	u16 cport_id;50	unsigned int minor;51	unsigned char clocal;52	bool disconnected;53	spinlock_t read_lock;54	spinlock_t write_lock;55	struct async_icount iocount;56	struct async_icount oldcount;57	wait_queue_head_t wioctl;58	struct mutex mutex;59	u8 ctrlin;	/* input control lines */60	u8 ctrlout;	/* output control lines */61	struct gb_uart_set_line_coding_request line_coding;62	struct work_struct tx_work;63	struct kfifo write_fifo;64	bool close_pending;65	unsigned int credits;66	struct completion credits_complete;67};68 69static struct tty_driver *gb_tty_driver;70static DEFINE_IDR(tty_minors);71static DEFINE_MUTEX(table_lock);72 73static int gb_uart_receive_data_handler(struct gb_operation *op)74{75	struct gb_connection *connection = op->connection;76	struct gb_tty *gb_tty = gb_connection_get_data(connection);77	struct tty_port *port = &gb_tty->port;78	struct gb_message *request = op->request;79	struct gb_uart_recv_data_request *receive_data;80	u16 recv_data_size;81	int count;82	unsigned long tty_flags = TTY_NORMAL;83 84	if (request->payload_size < sizeof(*receive_data)) {85		dev_err(&gb_tty->gbphy_dev->dev,86			"short receive-data request received (%zu < %zu)\n",87			request->payload_size, sizeof(*receive_data));88		return -EINVAL;89	}90 91	receive_data = op->request->payload;92	recv_data_size = le16_to_cpu(receive_data->size);93 94	if (recv_data_size != request->payload_size - sizeof(*receive_data)) {95		dev_err(&gb_tty->gbphy_dev->dev,96			"malformed receive-data request received (%u != %zu)\n",97			recv_data_size,98			request->payload_size - sizeof(*receive_data));99		return -EINVAL;100	}101 102	if (!recv_data_size)103		return -EINVAL;104 105	if (receive_data->flags) {106		if (receive_data->flags & GB_UART_RECV_FLAG_BREAK)107			tty_flags = TTY_BREAK;108		else if (receive_data->flags & GB_UART_RECV_FLAG_PARITY)109			tty_flags = TTY_PARITY;110		else if (receive_data->flags & GB_UART_RECV_FLAG_FRAMING)111			tty_flags = TTY_FRAME;112 113		/* overrun is special, not associated with a char */114		if (receive_data->flags & GB_UART_RECV_FLAG_OVERRUN)115			tty_insert_flip_char(port, 0, TTY_OVERRUN);116	}117	count = tty_insert_flip_string_fixed_flag(port, receive_data->data,118						  tty_flags, recv_data_size);119	if (count != recv_data_size) {120		dev_err(&gb_tty->gbphy_dev->dev,121			"UART: RX 0x%08x bytes only wrote 0x%08x\n",122			recv_data_size, count);123	}124	if (count)125		tty_flip_buffer_push(port);126	return 0;127}128 129static int gb_uart_serial_state_handler(struct gb_operation *op)130{131	struct gb_connection *connection = op->connection;132	struct gb_tty *gb_tty = gb_connection_get_data(connection);133	struct gb_message *request = op->request;134	struct gb_uart_serial_state_request *serial_state;135 136	if (request->payload_size < sizeof(*serial_state)) {137		dev_err(&gb_tty->gbphy_dev->dev,138			"short serial-state event received (%zu < %zu)\n",139			request->payload_size, sizeof(*serial_state));140		return -EINVAL;141	}142 143	serial_state = request->payload;144	gb_tty->ctrlin = serial_state->control;145 146	return 0;147}148 149static int gb_uart_receive_credits_handler(struct gb_operation *op)150{151	struct gb_connection *connection = op->connection;152	struct gb_tty *gb_tty = gb_connection_get_data(connection);153	struct gb_message *request = op->request;154	struct gb_uart_receive_credits_request *credit_request;155	unsigned long flags;156	unsigned int incoming_credits;157	int ret = 0;158 159	if (request->payload_size < sizeof(*credit_request)) {160		dev_err(&gb_tty->gbphy_dev->dev,161			"short receive_credits event received (%zu < %zu)\n",162			request->payload_size,163			sizeof(*credit_request));164		return -EINVAL;165	}166 167	credit_request = request->payload;168	incoming_credits = le16_to_cpu(credit_request->count);169 170	spin_lock_irqsave(&gb_tty->write_lock, flags);171	gb_tty->credits += incoming_credits;172	if (gb_tty->credits > GB_UART_FIRMWARE_CREDITS) {173		gb_tty->credits -= incoming_credits;174		ret = -EINVAL;175	}176	spin_unlock_irqrestore(&gb_tty->write_lock, flags);177 178	if (ret) {179		dev_err(&gb_tty->gbphy_dev->dev,180			"invalid number of incoming credits: %d\n",181			incoming_credits);182		return ret;183	}184 185	if (!gb_tty->close_pending)186		schedule_work(&gb_tty->tx_work);187 188	/*189	 * the port the tty layer may be waiting for credits190	 */191	tty_port_tty_wakeup(&gb_tty->port);192 193	if (gb_tty->credits == GB_UART_FIRMWARE_CREDITS)194		complete(&gb_tty->credits_complete);195 196	return ret;197}198 199static int gb_uart_request_handler(struct gb_operation *op)200{201	struct gb_connection *connection = op->connection;202	struct gb_tty *gb_tty = gb_connection_get_data(connection);203	int type = op->type;204	int ret;205 206	switch (type) {207	case GB_UART_TYPE_RECEIVE_DATA:208		ret = gb_uart_receive_data_handler(op);209		break;210	case GB_UART_TYPE_SERIAL_STATE:211		ret = gb_uart_serial_state_handler(op);212		break;213	case GB_UART_TYPE_RECEIVE_CREDITS:214		ret = gb_uart_receive_credits_handler(op);215		break;216	default:217		dev_err(&gb_tty->gbphy_dev->dev,218			"unsupported unsolicited request: 0x%02x\n", type);219		ret = -EINVAL;220	}221 222	return ret;223}224 225static void  gb_uart_tx_write_work(struct work_struct *work)226{227	struct gb_uart_send_data_request *request;228	struct gb_tty *gb_tty;229	unsigned long flags;230	unsigned int send_size;231	int ret;232 233	gb_tty = container_of(work, struct gb_tty, tx_work);234	request = gb_tty->buffer;235 236	while (1) {237		if (gb_tty->close_pending)238			break;239 240		spin_lock_irqsave(&gb_tty->write_lock, flags);241		send_size = gb_tty->buffer_payload_max;242		if (send_size > gb_tty->credits)243			send_size = gb_tty->credits;244 245		send_size = kfifo_out_peek(&gb_tty->write_fifo,246					   &request->data[0],247					   send_size);248		if (!send_size) {249			spin_unlock_irqrestore(&gb_tty->write_lock, flags);250			break;251		}252 253		gb_tty->credits -= send_size;254		spin_unlock_irqrestore(&gb_tty->write_lock, flags);255 256		request->size = cpu_to_le16(send_size);257		ret = gb_operation_sync(gb_tty->connection,258					GB_UART_TYPE_SEND_DATA,259					request, sizeof(*request) + send_size,260					NULL, 0);261		if (ret) {262			dev_err(&gb_tty->gbphy_dev->dev,263				"send data error: %d\n", ret);264			spin_lock_irqsave(&gb_tty->write_lock, flags);265			gb_tty->credits += send_size;266			spin_unlock_irqrestore(&gb_tty->write_lock, flags);267			if (!gb_tty->close_pending)268				schedule_work(work);269			return;270		}271 272		spin_lock_irqsave(&gb_tty->write_lock, flags);273		ret = kfifo_out(&gb_tty->write_fifo, &request->data[0],274				send_size);275		spin_unlock_irqrestore(&gb_tty->write_lock, flags);276 277		tty_port_tty_wakeup(&gb_tty->port);278	}279}280 281static int send_line_coding(struct gb_tty *tty)282{283	return gb_operation_sync(tty->connection, GB_UART_TYPE_SET_LINE_CODING,284				 &tty->line_coding, sizeof(tty->line_coding),285				 NULL, 0);286}287 288static int send_control(struct gb_tty *gb_tty, u8 control)289{290	struct gb_uart_set_control_line_state_request request;291 292	request.control = control;293	return gb_operation_sync(gb_tty->connection,294				 GB_UART_TYPE_SET_CONTROL_LINE_STATE,295				 &request, sizeof(request), NULL, 0);296}297 298static int send_break(struct gb_tty *gb_tty, u8 state)299{300	struct gb_uart_set_break_request request;301 302	if ((state != 0) && (state != 1)) {303		dev_err(&gb_tty->gbphy_dev->dev,304			"invalid break state of %d\n", state);305		return -EINVAL;306	}307 308	request.state = state;309	return gb_operation_sync(gb_tty->connection, GB_UART_TYPE_SEND_BREAK,310				 &request, sizeof(request), NULL, 0);311}312 313static int gb_uart_wait_for_all_credits(struct gb_tty *gb_tty)314{315	int ret;316 317	if (gb_tty->credits == GB_UART_FIRMWARE_CREDITS)318		return 0;319 320	ret = wait_for_completion_timeout(&gb_tty->credits_complete,321			msecs_to_jiffies(GB_UART_CREDIT_WAIT_TIMEOUT_MSEC));322	if (!ret) {323		dev_err(&gb_tty->gbphy_dev->dev,324			"time out waiting for credits\n");325		return -ETIMEDOUT;326	}327 328	return 0;329}330 331static int gb_uart_flush(struct gb_tty *gb_tty, u8 flags)332{333	struct gb_uart_serial_flush_request request;334 335	request.flags = flags;336	return gb_operation_sync(gb_tty->connection, GB_UART_TYPE_FLUSH_FIFOS,337				 &request, sizeof(request), NULL, 0);338}339 340static struct gb_tty *get_gb_by_minor(unsigned int minor)341{342	struct gb_tty *gb_tty;343 344	mutex_lock(&table_lock);345	gb_tty = idr_find(&tty_minors, minor);346	if (gb_tty) {347		mutex_lock(&gb_tty->mutex);348		if (gb_tty->disconnected) {349			mutex_unlock(&gb_tty->mutex);350			gb_tty = NULL;351		} else {352			tty_port_get(&gb_tty->port);353			mutex_unlock(&gb_tty->mutex);354		}355	}356	mutex_unlock(&table_lock);357	return gb_tty;358}359 360static int alloc_minor(struct gb_tty *gb_tty)361{362	int minor;363 364	mutex_lock(&table_lock);365	minor = idr_alloc(&tty_minors, gb_tty, 0, GB_NUM_MINORS, GFP_KERNEL);366	mutex_unlock(&table_lock);367	if (minor >= 0)368		gb_tty->minor = minor;369	return minor;370}371 372static void release_minor(struct gb_tty *gb_tty)373{374	int minor = gb_tty->minor;375 376	gb_tty->minor = 0;	/* Maybe should use an invalid value instead */377	mutex_lock(&table_lock);378	idr_remove(&tty_minors, minor);379	mutex_unlock(&table_lock);380}381 382static int gb_tty_install(struct tty_driver *driver, struct tty_struct *tty)383{384	struct gb_tty *gb_tty;385	int retval;386 387	gb_tty = get_gb_by_minor(tty->index);388	if (!gb_tty)389		return -ENODEV;390 391	retval = tty_standard_install(driver, tty);392	if (retval)393		goto error;394 395	tty->driver_data = gb_tty;396	return 0;397error:398	tty_port_put(&gb_tty->port);399	return retval;400}401 402static int gb_tty_open(struct tty_struct *tty, struct file *file)403{404	struct gb_tty *gb_tty = tty->driver_data;405 406	return tty_port_open(&gb_tty->port, tty, file);407}408 409static void gb_tty_close(struct tty_struct *tty, struct file *file)410{411	struct gb_tty *gb_tty = tty->driver_data;412 413	tty_port_close(&gb_tty->port, tty, file);414}415 416static void gb_tty_cleanup(struct tty_struct *tty)417{418	struct gb_tty *gb_tty = tty->driver_data;419 420	tty_port_put(&gb_tty->port);421}422 423static void gb_tty_hangup(struct tty_struct *tty)424{425	struct gb_tty *gb_tty = tty->driver_data;426 427	tty_port_hangup(&gb_tty->port);428}429 430static ssize_t gb_tty_write(struct tty_struct *tty, const u8 *buf, size_t count)431{432	struct gb_tty *gb_tty = tty->driver_data;433 434	count =  kfifo_in_spinlocked(&gb_tty->write_fifo, buf, count,435				     &gb_tty->write_lock);436	if (count && !gb_tty->close_pending)437		schedule_work(&gb_tty->tx_work);438 439	return count;440}441 442static unsigned int gb_tty_write_room(struct tty_struct *tty)443{444	struct gb_tty *gb_tty = tty->driver_data;445	unsigned long flags;446	int room;447 448	spin_lock_irqsave(&gb_tty->write_lock, flags);449	room = kfifo_avail(&gb_tty->write_fifo);450	spin_unlock_irqrestore(&gb_tty->write_lock, flags);451 452	room -= GB_UART_WRITE_ROOM_MARGIN;453	if (room < 0)454		return 0;455 456	return room;457}458 459static unsigned int gb_tty_chars_in_buffer(struct tty_struct *tty)460{461	struct gb_tty *gb_tty = tty->driver_data;462	unsigned long flags;463	unsigned int chars;464 465	spin_lock_irqsave(&gb_tty->write_lock, flags);466	chars = kfifo_len(&gb_tty->write_fifo);467	if (gb_tty->credits < GB_UART_FIRMWARE_CREDITS)468		chars += GB_UART_FIRMWARE_CREDITS - gb_tty->credits;469	spin_unlock_irqrestore(&gb_tty->write_lock, flags);470 471	return chars;472}473 474static int gb_tty_break_ctl(struct tty_struct *tty, int state)475{476	struct gb_tty *gb_tty = tty->driver_data;477 478	return send_break(gb_tty, state ? 1 : 0);479}480 481static void gb_tty_set_termios(struct tty_struct *tty,482			       const struct ktermios *termios_old)483{484	struct gb_uart_set_line_coding_request newline;485	struct gb_tty *gb_tty = tty->driver_data;486	struct ktermios *termios = &tty->termios;487	u8 newctrl = gb_tty->ctrlout;488 489	newline.rate = cpu_to_le32(tty_get_baud_rate(tty));490	newline.format = termios->c_cflag & CSTOPB ?491				GB_SERIAL_2_STOP_BITS : GB_SERIAL_1_STOP_BITS;492	newline.parity = termios->c_cflag & PARENB ?493				(termios->c_cflag & PARODD ? 1 : 2) +494				(termios->c_cflag & CMSPAR ? 2 : 0) : 0;495 496	newline.data_bits = tty_get_char_size(termios->c_cflag);497 498	/* FIXME: needs to clear unsupported bits in the termios */499	gb_tty->clocal = ((termios->c_cflag & CLOCAL) != 0);500 501	if (C_BAUD(tty) == B0) {502		newline.rate = gb_tty->line_coding.rate;503		newctrl &= ~(GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);504	} else if (termios_old && (termios_old->c_cflag & CBAUD) == B0) {505		newctrl |= (GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);506	}507 508	if (newctrl != gb_tty->ctrlout) {509		gb_tty->ctrlout = newctrl;510		send_control(gb_tty, newctrl);511	}512 513	if (C_CRTSCTS(tty) && C_BAUD(tty) != B0)514		newline.flow_control = GB_SERIAL_AUTO_RTSCTS_EN;515	else516		newline.flow_control = 0;517 518	if (memcmp(&gb_tty->line_coding, &newline, sizeof(newline))) {519		memcpy(&gb_tty->line_coding, &newline, sizeof(newline));520		send_line_coding(gb_tty);521	}522}523 524static int gb_tty_tiocmget(struct tty_struct *tty)525{526	struct gb_tty *gb_tty = tty->driver_data;527 528	return (gb_tty->ctrlout & GB_UART_CTRL_DTR ? TIOCM_DTR : 0) |529	       (gb_tty->ctrlout & GB_UART_CTRL_RTS ? TIOCM_RTS : 0) |530	       (gb_tty->ctrlin  & GB_UART_CTRL_DSR ? TIOCM_DSR : 0) |531	       (gb_tty->ctrlin  & GB_UART_CTRL_RI  ? TIOCM_RI  : 0) |532	       (gb_tty->ctrlin  & GB_UART_CTRL_DCD ? TIOCM_CD  : 0) |533	       TIOCM_CTS;534}535 536static int gb_tty_tiocmset(struct tty_struct *tty, unsigned int set,537			   unsigned int clear)538{539	struct gb_tty *gb_tty = tty->driver_data;540	u8 newctrl = gb_tty->ctrlout;541 542	set = (set & TIOCM_DTR ? GB_UART_CTRL_DTR : 0) |543	      (set & TIOCM_RTS ? GB_UART_CTRL_RTS : 0);544	clear = (clear & TIOCM_DTR ? GB_UART_CTRL_DTR : 0) |545		(clear & TIOCM_RTS ? GB_UART_CTRL_RTS : 0);546 547	newctrl = (newctrl & ~clear) | set;548	if (gb_tty->ctrlout == newctrl)549		return 0;550 551	gb_tty->ctrlout = newctrl;552	return send_control(gb_tty, newctrl);553}554 555static void gb_tty_throttle(struct tty_struct *tty)556{557	struct gb_tty *gb_tty = tty->driver_data;558	unsigned char stop_char;559	int retval;560 561	if (I_IXOFF(tty)) {562		stop_char = STOP_CHAR(tty);563		retval = gb_tty_write(tty, &stop_char, 1);564		if (retval <= 0)565			return;566	}567 568	if (tty->termios.c_cflag & CRTSCTS) {569		gb_tty->ctrlout &= ~GB_UART_CTRL_RTS;570		retval = send_control(gb_tty, gb_tty->ctrlout);571	}572}573 574static void gb_tty_unthrottle(struct tty_struct *tty)575{576	struct gb_tty *gb_tty = tty->driver_data;577	unsigned char start_char;578	int retval;579 580	if (I_IXOFF(tty)) {581		start_char = START_CHAR(tty);582		retval = gb_tty_write(tty, &start_char, 1);583		if (retval <= 0)584			return;585	}586 587	if (tty->termios.c_cflag & CRTSCTS) {588		gb_tty->ctrlout |= GB_UART_CTRL_RTS;589		retval = send_control(gb_tty, gb_tty->ctrlout);590	}591}592 593static int get_serial_info(struct tty_struct *tty,594			   struct serial_struct *ss)595{596	struct gb_tty *gb_tty = tty->driver_data;597 598	ss->line = gb_tty->minor;599	ss->close_delay = jiffies_to_msecs(gb_tty->port.close_delay) / 10;600	ss->closing_wait =601		gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?602		ASYNC_CLOSING_WAIT_NONE :603		jiffies_to_msecs(gb_tty->port.closing_wait) / 10;604 605	return 0;606}607 608static int set_serial_info(struct tty_struct *tty,609			   struct serial_struct *ss)610{611	struct gb_tty *gb_tty = tty->driver_data;612	unsigned int closing_wait;613	unsigned int close_delay;614	int retval = 0;615 616	close_delay = msecs_to_jiffies(ss->close_delay * 10);617	closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ?618			ASYNC_CLOSING_WAIT_NONE :619			msecs_to_jiffies(ss->closing_wait * 10);620 621	mutex_lock(&gb_tty->port.mutex);622	if (!capable(CAP_SYS_ADMIN)) {623		if ((close_delay != gb_tty->port.close_delay) ||624		    (closing_wait != gb_tty->port.closing_wait))625			retval = -EPERM;626	} else {627		gb_tty->port.close_delay = close_delay;628		gb_tty->port.closing_wait = closing_wait;629	}630	mutex_unlock(&gb_tty->port.mutex);631	return retval;632}633 634static int wait_serial_change(struct gb_tty *gb_tty, unsigned long arg)635{636	int retval = 0;637	DECLARE_WAITQUEUE(wait, current);638	struct async_icount old;639	struct async_icount new;640 641	if (!(arg & (TIOCM_DSR | TIOCM_RI | TIOCM_CD)))642		return -EINVAL;643 644	do {645		spin_lock_irq(&gb_tty->read_lock);646		old = gb_tty->oldcount;647		new = gb_tty->iocount;648		gb_tty->oldcount = new;649		spin_unlock_irq(&gb_tty->read_lock);650 651		if ((arg & TIOCM_DSR) && (old.dsr != new.dsr))652			break;653		if ((arg & TIOCM_CD) && (old.dcd != new.dcd))654			break;655		if ((arg & TIOCM_RI) && (old.rng != new.rng))656			break;657 658		add_wait_queue(&gb_tty->wioctl, &wait);659		set_current_state(TASK_INTERRUPTIBLE);660		schedule();661		remove_wait_queue(&gb_tty->wioctl, &wait);662		if (gb_tty->disconnected) {663			if (arg & TIOCM_CD)664				break;665			retval = -ENODEV;666		} else if (signal_pending(current)) {667			retval = -ERESTARTSYS;668		}669	} while (!retval);670 671	return retval;672}673 674static int gb_tty_get_icount(struct tty_struct *tty,675			     struct serial_icounter_struct *icount)676{677	struct gb_tty *gb_tty = tty->driver_data;678 679	icount->dsr = gb_tty->iocount.dsr;680	icount->rng = gb_tty->iocount.rng;681	icount->dcd = gb_tty->iocount.dcd;682	icount->frame = gb_tty->iocount.frame;683	icount->overrun = gb_tty->iocount.overrun;684	icount->parity = gb_tty->iocount.parity;685	icount->brk = gb_tty->iocount.brk;686 687	return 0;688}689 690static int gb_tty_ioctl(struct tty_struct *tty, unsigned int cmd,691			unsigned long arg)692{693	struct gb_tty *gb_tty = tty->driver_data;694 695	switch (cmd) {696	case TIOCMIWAIT:697		return wait_serial_change(gb_tty, arg);698	}699 700	return -ENOIOCTLCMD;701}702 703static void gb_tty_dtr_rts(struct tty_port *port, bool active)704{705	struct gb_tty *gb_tty;706	u8 newctrl;707 708	gb_tty = container_of(port, struct gb_tty, port);709	newctrl = gb_tty->ctrlout;710 711	if (active)712		newctrl |= (GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);713	else714		newctrl &= ~(GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);715 716	gb_tty->ctrlout = newctrl;717	send_control(gb_tty, newctrl);718}719 720static int gb_tty_port_activate(struct tty_port *port,721				struct tty_struct *tty)722{723	struct gb_tty *gb_tty;724 725	gb_tty = container_of(port, struct gb_tty, port);726 727	return gbphy_runtime_get_sync(gb_tty->gbphy_dev);728}729 730static void gb_tty_port_shutdown(struct tty_port *port)731{732	struct gb_tty *gb_tty;733	unsigned long flags;734	int ret;735 736	gb_tty = container_of(port, struct gb_tty, port);737 738	gb_tty->close_pending = true;739 740	cancel_work_sync(&gb_tty->tx_work);741 742	spin_lock_irqsave(&gb_tty->write_lock, flags);743	kfifo_reset_out(&gb_tty->write_fifo);744	spin_unlock_irqrestore(&gb_tty->write_lock, flags);745 746	if (gb_tty->credits == GB_UART_FIRMWARE_CREDITS)747		goto out;748 749	ret = gb_uart_flush(gb_tty, GB_SERIAL_FLAG_FLUSH_TRANSMITTER);750	if (ret) {751		dev_err(&gb_tty->gbphy_dev->dev,752			"error flushing transmitter: %d\n", ret);753	}754 755	gb_uart_wait_for_all_credits(gb_tty);756 757out:758	gb_tty->close_pending = false;759 760	gbphy_runtime_put_autosuspend(gb_tty->gbphy_dev);761}762 763static void gb_tty_port_destruct(struct tty_port *port)764{765	struct gb_tty *gb_tty = container_of(port, struct gb_tty, port);766 767	if (gb_tty->minor != GB_NUM_MINORS)768		release_minor(gb_tty);769	kfifo_free(&gb_tty->write_fifo);770	kfree(gb_tty->buffer);771	kfree(gb_tty);772}773 774static const struct tty_operations gb_ops = {775	.install =		gb_tty_install,776	.open =			gb_tty_open,777	.close =		gb_tty_close,778	.cleanup =		gb_tty_cleanup,779	.hangup =		gb_tty_hangup,780	.write =		gb_tty_write,781	.write_room =		gb_tty_write_room,782	.ioctl =		gb_tty_ioctl,783	.throttle =		gb_tty_throttle,784	.unthrottle =		gb_tty_unthrottle,785	.chars_in_buffer =	gb_tty_chars_in_buffer,786	.break_ctl =		gb_tty_break_ctl,787	.set_termios =		gb_tty_set_termios,788	.tiocmget =		gb_tty_tiocmget,789	.tiocmset =		gb_tty_tiocmset,790	.get_icount =		gb_tty_get_icount,791	.set_serial =		set_serial_info,792	.get_serial =		get_serial_info,793};794 795static const struct tty_port_operations gb_port_ops = {796	.dtr_rts =		gb_tty_dtr_rts,797	.activate =		gb_tty_port_activate,798	.shutdown =		gb_tty_port_shutdown,799	.destruct =		gb_tty_port_destruct,800};801 802static int gb_uart_probe(struct gbphy_device *gbphy_dev,803			 const struct gbphy_device_id *id)804{805	struct gb_connection *connection;806	size_t max_payload;807	struct gb_tty *gb_tty;808	struct device *tty_dev;809	int retval;810	int minor;811 812	connection = gb_connection_create(gbphy_dev->bundle,813					  le16_to_cpu(gbphy_dev->cport_desc->id),814					  gb_uart_request_handler);815	if (IS_ERR(connection))816		return PTR_ERR(connection);817 818	max_payload = gb_operation_get_payload_size_max(connection);819	if (max_payload < sizeof(struct gb_uart_send_data_request)) {820		retval = -EINVAL;821		goto exit_connection_destroy;822	}823 824	gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL);825	if (!gb_tty) {826		retval = -ENOMEM;827		goto exit_connection_destroy;828	}829 830	tty_port_init(&gb_tty->port);831	gb_tty->port.ops = &gb_port_ops;832	gb_tty->minor = GB_NUM_MINORS;833 834	gb_tty->buffer_payload_max = max_payload -835			sizeof(struct gb_uart_send_data_request);836 837	gb_tty->buffer = kzalloc(gb_tty->buffer_payload_max, GFP_KERNEL);838	if (!gb_tty->buffer) {839		retval = -ENOMEM;840		goto exit_put_port;841	}842 843	INIT_WORK(&gb_tty->tx_work, gb_uart_tx_write_work);844 845	retval = kfifo_alloc(&gb_tty->write_fifo, GB_UART_WRITE_FIFO_SIZE,846			     GFP_KERNEL);847	if (retval)848		goto exit_put_port;849 850	gb_tty->credits = GB_UART_FIRMWARE_CREDITS;851	init_completion(&gb_tty->credits_complete);852 853	minor = alloc_minor(gb_tty);854	if (minor < 0) {855		if (minor == -ENOSPC) {856			dev_err(&gbphy_dev->dev,857				"no more free minor numbers\n");858			retval = -ENODEV;859		} else {860			retval = minor;861		}862		goto exit_put_port;863	}864 865	gb_tty->minor = minor;866	spin_lock_init(&gb_tty->write_lock);867	spin_lock_init(&gb_tty->read_lock);868	init_waitqueue_head(&gb_tty->wioctl);869	mutex_init(&gb_tty->mutex);870 871	gb_tty->connection = connection;872	gb_tty->gbphy_dev = gbphy_dev;873	gb_connection_set_data(connection, gb_tty);874	gb_gbphy_set_data(gbphy_dev, gb_tty);875 876	retval = gb_connection_enable_tx(connection);877	if (retval)878		goto exit_put_port;879 880	send_control(gb_tty, gb_tty->ctrlout);881 882	/* initialize the uart to be 9600n81 */883	gb_tty->line_coding.rate = cpu_to_le32(9600);884	gb_tty->line_coding.format = GB_SERIAL_1_STOP_BITS;885	gb_tty->line_coding.parity = GB_SERIAL_NO_PARITY;886	gb_tty->line_coding.data_bits = 8;887	send_line_coding(gb_tty);888 889	retval = gb_connection_enable(connection);890	if (retval)891		goto exit_connection_disable;892 893	tty_dev = tty_port_register_device(&gb_tty->port, gb_tty_driver, minor,894					   &gbphy_dev->dev);895	if (IS_ERR(tty_dev)) {896		retval = PTR_ERR(tty_dev);897		goto exit_connection_disable;898	}899 900	gbphy_runtime_put_autosuspend(gbphy_dev);901	return 0;902 903exit_connection_disable:904	gb_connection_disable(connection);905exit_put_port:906	tty_port_put(&gb_tty->port);907exit_connection_destroy:908	gb_connection_destroy(connection);909 910	return retval;911}912 913static void gb_uart_remove(struct gbphy_device *gbphy_dev)914{915	struct gb_tty *gb_tty = gb_gbphy_get_data(gbphy_dev);916	struct gb_connection *connection = gb_tty->connection;917	struct tty_struct *tty;918	int ret;919 920	ret = gbphy_runtime_get_sync(gbphy_dev);921	if (ret)922		gbphy_runtime_get_noresume(gbphy_dev);923 924	mutex_lock(&gb_tty->mutex);925	gb_tty->disconnected = true;926 927	wake_up_all(&gb_tty->wioctl);928	mutex_unlock(&gb_tty->mutex);929 930	tty = tty_port_tty_get(&gb_tty->port);931	if (tty) {932		tty_vhangup(tty);933		tty_kref_put(tty);934	}935 936	gb_connection_disable_rx(connection);937	tty_unregister_device(gb_tty_driver, gb_tty->minor);938 939	gb_connection_disable(connection);940	gb_connection_destroy(connection);941 942	tty_port_put(&gb_tty->port);943}944 945static int gb_tty_init(void)946{947	int retval = 0;948 949	gb_tty_driver = tty_alloc_driver(GB_NUM_MINORS, 0);950	if (IS_ERR(gb_tty_driver)) {951		pr_err("Can not allocate tty driver\n");952		retval = -ENOMEM;953		goto fail_unregister_dev;954	}955 956	gb_tty_driver->driver_name = "gb";957	gb_tty_driver->name = GB_NAME;958	gb_tty_driver->major = 0;959	gb_tty_driver->minor_start = 0;960	gb_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;961	gb_tty_driver->subtype = SERIAL_TYPE_NORMAL;962	gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;963	gb_tty_driver->init_termios = tty_std_termios;964	gb_tty_driver->init_termios.c_cflag = B9600 | CS8 |965		CREAD | HUPCL | CLOCAL;966	tty_set_operations(gb_tty_driver, &gb_ops);967 968	retval = tty_register_driver(gb_tty_driver);969	if (retval) {970		pr_err("Can not register tty driver: %d\n", retval);971		goto fail_put_gb_tty;972	}973 974	return 0;975 976fail_put_gb_tty:977	tty_driver_kref_put(gb_tty_driver);978fail_unregister_dev:979	return retval;980}981 982static void gb_tty_exit(void)983{984	tty_unregister_driver(gb_tty_driver);985	tty_driver_kref_put(gb_tty_driver);986	idr_destroy(&tty_minors);987}988 989static const struct gbphy_device_id gb_uart_id_table[] = {990	{ GBPHY_PROTOCOL(GREYBUS_PROTOCOL_UART) },991	{ },992};993MODULE_DEVICE_TABLE(gbphy, gb_uart_id_table);994 995static struct gbphy_driver uart_driver = {996	.name		= "uart",997	.probe		= gb_uart_probe,998	.remove		= gb_uart_remove,999	.id_table	= gb_uart_id_table,1000};1001 1002static int gb_uart_driver_init(void)1003{1004	int ret;1005 1006	ret = gb_tty_init();1007	if (ret)1008		return ret;1009 1010	ret = gb_gbphy_register(&uart_driver);1011	if (ret) {1012		gb_tty_exit();1013		return ret;1014	}1015 1016	return 0;1017}1018module_init(gb_uart_driver_init);1019 1020static void gb_uart_driver_exit(void)1021{1022	gb_gbphy_deregister(&uart_driver);1023	gb_tty_exit();1024}1025 1026module_exit(gb_uart_driver_exit);1027MODULE_DESCRIPTION("UART driver for the Greybus 'generic' UART module");1028MODULE_LICENSE("GPL v2");1029