diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-15 21:19:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-17 21:21:21 -0400 |
commit | 266dcff03eed0050b6af11aaf2a61ab837d7ba3f (patch) | |
tree | 3d11f566fe2c4712808577bdd02d1a83859c9299 | |
parent | c8b29f049eb2645dd21e40a6613c09f15c731650 (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.c | 24 | ||||
-rw-r--r-- | include/linux/serial_core.h | 2 |
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 | ||
2567 | static 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 | ||