Commit d7cb8fb7 authored by Michał Mirosław's avatar Michał Mirosław Committed by Felipe Balbi
Browse files

usb: gadget: u_serial: allow more console gadget ports



Allow configuring more than one console using USB serial or ACM gadget.

By default, only first (ttyGS0) is a console, but this may be changed
using function's new "console" attribute.

Signed-off-by: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent b417343c
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -771,6 +771,24 @@ static struct configfs_item_operations acm_item_ops = {
	.release                = acm_attr_release,
};

#ifdef CONFIG_U_SERIAL_CONSOLE

static ssize_t f_acm_console_store(struct config_item *item,
		const char *page, size_t count)
{
	return gserial_set_console(to_f_serial_opts(item)->port_num,
				   page, count);
}

static ssize_t f_acm_console_show(struct config_item *item, char *page)
{
	return gserial_get_console(to_f_serial_opts(item)->port_num, page);
}

CONFIGFS_ATTR(f_acm_, console);

#endif /* CONFIG_U_SERIAL_CONSOLE */

static ssize_t f_acm_port_num_show(struct config_item *item, char *page)
{
	return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
@@ -779,6 +797,9 @@ static ssize_t f_acm_port_num_show(struct config_item *item, char *page)
CONFIGFS_ATTR_RO(f_acm_, port_num);

static struct configfs_attribute *acm_attrs[] = {
#ifdef CONFIG_U_SERIAL_CONSOLE
	&f_acm_attr_console,
#endif
	&f_acm_attr_port_num,
	NULL,
};
+21 −0
Original line number Diff line number Diff line
@@ -266,6 +266,24 @@ static struct configfs_item_operations serial_item_ops = {
	.release	= serial_attr_release,
};

#ifdef CONFIG_U_SERIAL_CONSOLE

static ssize_t f_serial_console_store(struct config_item *item,
		const char *page, size_t count)
{
	return gserial_set_console(to_f_serial_opts(item)->port_num,
				   page, count);
}

static ssize_t f_serial_console_show(struct config_item *item, char *page)
{
	return gserial_get_console(to_f_serial_opts(item)->port_num, page);
}

CONFIGFS_ATTR(f_serial_, console);

#endif /* CONFIG_U_SERIAL_CONSOLE */

static ssize_t f_serial_port_num_show(struct config_item *item, char *page)
{
	return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
@@ -274,6 +292,9 @@ static ssize_t f_serial_port_num_show(struct config_item *item, char *page)
CONFIGFS_ATTR_RO(f_serial_, port_num);

static struct configfs_attribute *acm_attrs[] = {
#ifdef CONFIG_U_SERIAL_CONSOLE
	&f_serial_attr_console,
#endif
	&f_serial_attr_port_num,
	NULL,
};
+48 −0
Original line number Diff line number Diff line
@@ -1081,6 +1081,54 @@ static void gs_console_exit(struct gs_port *port)
	port->console = NULL;
}

ssize_t gserial_set_console(unsigned char port_num, const char *page, size_t count)
{
	struct gs_port *port;
	bool enable;
	int ret;

	ret = strtobool(page, &enable);
	if (ret)
		return ret;

	mutex_lock(&ports[port_num].lock);
	port = ports[port_num].port;

	if (WARN_ON(port == NULL)) {
		ret = -ENXIO;
		goto out;
	}

	if (enable)
		ret = gs_console_init(port);
	else
		gs_console_exit(port);
out:
	mutex_unlock(&ports[port_num].lock);

	return ret < 0 ? ret : count;
}
EXPORT_SYMBOL_GPL(gserial_set_console);

ssize_t gserial_get_console(unsigned char port_num, char *page)
{
	struct gs_port *port;
	ssize_t ret;

	mutex_lock(&ports[port_num].lock);
	port = ports[port_num].port;

	if (WARN_ON(port == NULL))
		ret = -ENXIO;
	else
		ret = sprintf(page, "%u\n", !!port->console);

	mutex_unlock(&ports[port_num].lock);

	return ret;
}
EXPORT_SYMBOL_GPL(gserial_get_console);

#else

static int gs_console_connect(struct gs_port *port)
+7 −0
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@ int gserial_alloc_line_no_console(unsigned char *port_line);
int gserial_alloc_line(unsigned char *port_line);
void gserial_free_line(unsigned char port_line);

#ifdef CONFIG_U_SERIAL_CONSOLE

ssize_t gserial_set_console(unsigned char port_num, const char *page, size_t count);
ssize_t gserial_get_console(unsigned char port_num, char *page);

#endif /* CONFIG_U_SERIAL_CONSOLE */

/* connect/disconnect is handled by individual functions */
int gserial_connect(struct gserial *, u8 port_num);
void gserial_disconnect(struct gserial *);