aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-15 21:19:34 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-17 21:21:21 -0400
commit266dcff03eed0050b6af11aaf2a61ab837d7ba3f (patch)
tree3d11f566fe2c4712808577bdd02d1a83859c9299
parentc8b29f049eb2645dd21e40a6613c09f15c731650 (diff)
Serial: allow port drivers to have a default attribute group
Some serial drivers (like 8250), want to add sysfs files. We need to do so in a race-free way, so allow any port to be able to specify an attribute group that should be added at device creation time. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/serial_core.c24
-rw-r--r--include/linux/serial_core.h2
2 files changed, 19 insertions, 7 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index b70095e55df6..61529a84c3fc 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2564,12 +2564,6 @@ static const struct attribute_group tty_dev_attr_group = {
2564 .attrs = tty_dev_attrs, 2564 .attrs = tty_dev_attrs,
2565 }; 2565 };
2566 2566
2567static const struct attribute_group *tty_dev_attr_groups[] = {
2568 &tty_dev_attr_group,
2569 NULL
2570 };
2571
2572
2573/** 2567/**
2574 * uart_add_one_port - attach a driver-defined port structure 2568 * uart_add_one_port - attach a driver-defined port structure
2575 * @drv: pointer to the uart low level driver structure for this port 2569 * @drv: pointer to the uart low level driver structure for this port
@@ -2586,6 +2580,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
2586 struct tty_port *port; 2580 struct tty_port *port;
2587 int ret = 0; 2581 int ret = 0;
2588 struct device *tty_dev; 2582 struct device *tty_dev;
2583 int num_groups;
2589 2584
2590 BUG_ON(in_interrupt()); 2585 BUG_ON(in_interrupt());
2591 2586
@@ -2619,12 +2614,26 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
2619 2614
2620 uart_configure_port(drv, state, uport); 2615 uart_configure_port(drv, state, uport);
2621 2616
2617 num_groups = 2;
2618 if (uport->attr_group)
2619 num_groups++;
2620
2621 uport->tty_groups = kcalloc(num_groups, sizeof(**uport->tty_groups),
2622 GFP_KERNEL);
2623 if (!uport->tty_groups) {
2624 ret = -ENOMEM;
2625 goto out;
2626 }
2627 uport->tty_groups[0] = &tty_dev_attr_group;
2628 if (uport->attr_group)
2629 uport->tty_groups[1] = uport->attr_group;
2630
2622 /* 2631 /*
2623 * Register the port whether it's detected or not. This allows 2632 * Register the port whether it's detected or not. This allows
2624 * setserial to be used to alter this port's parameters. 2633 * setserial to be used to alter this port's parameters.
2625 */ 2634 */
2626 tty_dev = tty_port_register_device_attr(port, drv->tty_driver, 2635 tty_dev = tty_port_register_device_attr(port, drv->tty_driver,
2627 uport->line, uport->dev, port, tty_dev_attr_groups); 2636 uport->line, uport->dev, port, uport->tty_groups);
2628 if (likely(!IS_ERR(tty_dev))) { 2637 if (likely(!IS_ERR(tty_dev))) {
2629 device_set_wakeup_capable(tty_dev, 1); 2638 device_set_wakeup_capable(tty_dev, 1);
2630 } else { 2639 } else {
@@ -2703,6 +2712,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
2703 */ 2712 */
2704 if (uport->type != PORT_UNKNOWN) 2713 if (uport->type != PORT_UNKNOWN)
2705 uport->ops->release_port(uport); 2714 uport->ops->release_port(uport);
2715 kfree(uport->tty_groups);
2706 2716
2707 /* 2717 /*
2708 * Indicate that there isn't a port here anymore. 2718 * Indicate that there isn't a port here anymore.
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 5bbb809ee197..cf3a1e789bf5 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -199,6 +199,8 @@ struct uart_port {
199 unsigned char suspended; 199 unsigned char suspended;
200 unsigned char irq_wake; 200 unsigned char irq_wake;
201 unsigned char unused[2]; 201 unsigned char unused[2];
202 struct attribute_group *attr_group; /* port specific attributes */
203 const struct attribute_group **tty_groups; /* all attributes (serial core use only) */
202 void *private_data; /* generic platform data pointer */ 204 void *private_data; /* generic platform data pointer */
203}; 205};
204 206