diff options
author | Tomas Hlavacek <tmshlvck@gmail.com> | 2012-09-05 21:17:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-06 12:22:04 -0400 |
commit | 6915c0e487c822e2436683e14302c0b8a6155cc7 (patch) | |
tree | 3ef744c612c40517ed64d4f370a14c6c51eaab2f /drivers/tty/tty_io.c | |
parent | d83b54250988758cd3b9d21c242f98ae61fa1435 (diff) |
tty: uartclk value from serial_core exposed to sysfs
Added file /sys/devices/.../tty/ttySX/uartclk to allow reading
uartclk value in struct uart_port in serial_core via sysfs.
tty_register_device() has been generalized and refactored in order
to add support for setting drvdata and attribute_group to the device.
Signed-off-by: Tomas Hlavacek <tmshlvck@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d3bf91a29303..dcb30d55d39c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -3041,9 +3041,39 @@ static int tty_cdev_add(struct tty_driver *driver, dev_t dev, | |||
3041 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, | 3041 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, |
3042 | struct device *device) | 3042 | struct device *device) |
3043 | { | 3043 | { |
3044 | struct device *ret; | 3044 | return tty_register_device_attr(driver, index, device, NULL, NULL); |
3045 | } | ||
3046 | EXPORT_SYMBOL(tty_register_device); | ||
3047 | |||
3048 | /** | ||
3049 | * tty_register_device_attr - register a tty device | ||
3050 | * @driver: the tty driver that describes the tty device | ||
3051 | * @index: the index in the tty driver for this tty device | ||
3052 | * @device: a struct device that is associated with this tty device. | ||
3053 | * This field is optional, if there is no known struct device | ||
3054 | * for this tty device it can be set to NULL safely. | ||
3055 | * @drvdata: Driver data to be set to device. | ||
3056 | * @attr_grp: Attribute group to be set on device. | ||
3057 | * | ||
3058 | * Returns a pointer to the struct device for this tty device | ||
3059 | * (or ERR_PTR(-EFOO) on error). | ||
3060 | * | ||
3061 | * This call is required to be made to register an individual tty device | ||
3062 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If | ||
3063 | * that bit is not set, this function should not be called by a tty | ||
3064 | * driver. | ||
3065 | * | ||
3066 | * Locking: ?? | ||
3067 | */ | ||
3068 | struct device *tty_register_device_attr(struct tty_driver *driver, | ||
3069 | unsigned index, struct device *device, | ||
3070 | void *drvdata, | ||
3071 | const struct attribute_group **attr_grp) | ||
3072 | { | ||
3045 | char name[64]; | 3073 | char name[64]; |
3046 | dev_t dev = MKDEV(driver->major, driver->minor_start) + index; | 3074 | dev_t devt = MKDEV(driver->major, driver->minor_start) + index; |
3075 | struct device *dev = NULL; | ||
3076 | int retval = -ENODEV; | ||
3047 | bool cdev = false; | 3077 | bool cdev = false; |
3048 | 3078 | ||
3049 | if (index >= driver->num) { | 3079 | if (index >= driver->num) { |
@@ -3058,19 +3088,38 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, | |||
3058 | tty_line_name(driver, index, name); | 3088 | tty_line_name(driver, index, name); |
3059 | 3089 | ||
3060 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { | 3090 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { |
3061 | int error = tty_cdev_add(driver, dev, index, 1); | 3091 | retval = tty_cdev_add(driver, devt, index, 1); |
3062 | if (error) | 3092 | if (retval) |
3063 | return ERR_PTR(error); | 3093 | goto error; |
3064 | cdev = true; | 3094 | cdev = true; |
3065 | } | 3095 | } |
3066 | 3096 | ||
3067 | ret = device_create(tty_class, device, dev, NULL, name); | 3097 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
3068 | if (IS_ERR(ret) && cdev) | 3098 | if (!dev) { |
3069 | cdev_del(&driver->cdevs[index]); | 3099 | retval = -ENOMEM; |
3100 | goto error; | ||
3101 | } | ||
3070 | 3102 | ||
3071 | return ret; | 3103 | dev->devt = devt; |
3104 | dev->class = tty_class; | ||
3105 | dev->parent = device; | ||
3106 | dev_set_name(dev, "%s", name); | ||
3107 | dev->groups = attr_grp; | ||
3108 | dev_set_drvdata(dev, drvdata); | ||
3109 | |||
3110 | retval = device_register(dev); | ||
3111 | if (retval) | ||
3112 | goto error; | ||
3113 | |||
3114 | return dev; | ||
3115 | |||
3116 | error: | ||
3117 | put_device(dev); | ||
3118 | if (cdev) | ||
3119 | cdev_del(&driver->cdevs[index]); | ||
3120 | return ERR_PTR(retval); | ||
3072 | } | 3121 | } |
3073 | EXPORT_SYMBOL(tty_register_device); | 3122 | EXPORT_SYMBOL_GPL(tty_register_device_attr); |
3074 | 3123 | ||
3075 | /** | 3124 | /** |
3076 | * tty_unregister_device - unregister a tty device | 3125 | * tty_unregister_device - unregister a tty device |