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: Michał Mirosław <mirq-linux@rere.qmqm.pl> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
b417343c6a
commit
d7cb8fb7aa
@ -771,6 +771,24 @@ static struct configfs_item_operations acm_item_ops = {
|
|||||||
.release = acm_attr_release,
|
.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)
|
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);
|
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);
|
CONFIGFS_ATTR_RO(f_acm_, port_num);
|
||||||
|
|
||||||
static struct configfs_attribute *acm_attrs[] = {
|
static struct configfs_attribute *acm_attrs[] = {
|
||||||
|
#ifdef CONFIG_U_SERIAL_CONSOLE
|
||||||
|
&f_acm_attr_console,
|
||||||
|
#endif
|
||||||
&f_acm_attr_port_num,
|
&f_acm_attr_port_num,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -266,6 +266,24 @@ static struct configfs_item_operations serial_item_ops = {
|
|||||||
.release = serial_attr_release,
|
.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)
|
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);
|
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);
|
CONFIGFS_ATTR_RO(f_serial_, port_num);
|
||||||
|
|
||||||
static struct configfs_attribute *acm_attrs[] = {
|
static struct configfs_attribute *acm_attrs[] = {
|
||||||
|
#ifdef CONFIG_U_SERIAL_CONSOLE
|
||||||
|
&f_serial_attr_console,
|
||||||
|
#endif
|
||||||
&f_serial_attr_port_num,
|
&f_serial_attr_port_num,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -1081,6 +1081,54 @@ static void gs_console_exit(struct gs_port *port)
|
|||||||
port->console = NULL;
|
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
|
#else
|
||||||
|
|
||||||
static int gs_console_connect(struct gs_port *port)
|
static int gs_console_connect(struct gs_port *port)
|
||||||
|
@ -58,6 +58,13 @@ int gserial_alloc_line_no_console(unsigned char *port_line);
|
|||||||
int gserial_alloc_line(unsigned char *port_line);
|
int gserial_alloc_line(unsigned char *port_line);
|
||||||
void gserial_free_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 */
|
/* connect/disconnect is handled by individual functions */
|
||||||
int gserial_connect(struct gserial *, u8 port_num);
|
int gserial_connect(struct gserial *, u8 port_num);
|
||||||
void gserial_disconnect(struct gserial *);
|
void gserial_disconnect(struct gserial *);
|
||||||
|
Loading…
Reference in New Issue
Block a user