Re: [PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
> + /* > + * Check value: baud_base has to be more than 9600 > + * and uartclock = baud_base * 16 . > + */ > + if (val >= 153600) > + state->uart_port->uartclk = val; > + > + mutex_unlock(>port.mutex); > + > + return count; This breaks if for example the port is in use. Fixing that looks pretty horrible as you need a valid tty pointer to stop and restart the pot. It's also not calling the verfy method of the port as is expected. At minimum I think you need to be able to do the same work uart_get_info/uart_set_info perform and with the same checks on ->verify etc. I'm not 100% sure the drvdata on the tty_dev is clear to use. It does seem to be in all the drivers I looked at. I'd rather however it pointed to the tty_port that each tty device has (or very soon will be required to have). You can still find the uart_foo structs from that but it means we can do the dev_set_drvdata() in a consistent manner for all tty devices in the kernel. That in turn means we can make some of the sysfs valid the same way. I want to have think about the setting side of it. Can you submit a revised version that just allows the user to read the value this way but does the drvdata setting etc and sysfs node create/delete. I'll merge that and we can throw it over the parapet and see if anything explodes. To make the setting part work properly I think I need to sort out uart_get_info/set_info so the core part of it can be called with kernel space structures and the caller handling locks. Alan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
+ /* + * Check value: baud_base has to be more than 9600 + * and uartclock = baud_base * 16 . + */ + if (val = 153600) + state-uart_port-uartclk = val; + + mutex_unlock(state-port.mutex); + + return count; This breaks if for example the port is in use. Fixing that looks pretty horrible as you need a valid tty pointer to stop and restart the pot. It's also not calling the verfy method of the port as is expected. At minimum I think you need to be able to do the same work uart_get_info/uart_set_info perform and with the same checks on -verify etc. I'm not 100% sure the drvdata on the tty_dev is clear to use. It does seem to be in all the drivers I looked at. I'd rather however it pointed to the tty_port that each tty device has (or very soon will be required to have). You can still find the uart_foo structs from that but it means we can do the dev_set_drvdata() in a consistent manner for all tty devices in the kernel. That in turn means we can make some of the sysfs valid the same way. I want to have think about the setting side of it. Can you submit a revised version that just allows the user to read the value this way but does the drvdata setting etc and sysfs node create/delete. I'll merge that and we can throw it over the parapet and see if anything explodes. To make the setting part work properly I think I need to sort out uart_get_info/set_info so the core part of it can be called with kernel space structures and the caller handling locks. Alan -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
Hello Marek, On Tue, Aug 14, 2012 at 2:50 PM, Marek Vasut wrote: > Dear Tomas Hlavacek, > >> +static ssize_t get_attr_uartclk(struct device *dev, >> + struct device_attribute *attr, char *buf) >> +{ >> + int ret; >> + >> + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); > > You don't need this cast here. Yes, you are right. Thanks. > >> + mutex_lock(>port.mutex); >> + ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk); > > Do you really need such a large buffer (PAGE_SIZE) ? Well no, but I believe that I get the buffer of length equal to PAGE_SIZE anyway. Documentation/filesystems/sysfs.txt says so on line 179. > >> + mutex_unlock(>port.mutex); >> + return ret; >> +} >> + >> +static ssize_t set_attr_uartclk(struct device *dev, >> + struct device_attribute *attr, const char *buf, size_t count) >> +{ >> + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); >> + unsigned int val; >> + int ret; >> + >> + ret = kstrtouint(buf, 10, ); >> + if (ret) >> + return ret; >> + >> + mutex_lock(>port.mutex); >> + >> + /* >> + * Check value: baud_base has to be more than 9600 >> + * and uartclock = baud_base * 16 . >> + */ >> + if (val >= 153600) >> + state->uart_port->uartclk = val; > > This magic value here would use some documentation. OK. Do you think this would be sufficient comment?: /* * Check value: baud_base does not make sense to be set below 9600 * and since uartclock = (baud_base * 16) it has to be equal or greater than * 9600 * 16 = 153600. */ PATCHv2 follows. Tomas -- Tomáš Hlaváček -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
Hello Marek, On Tue, Aug 14, 2012 at 2:50 PM, Marek Vasut marek.va...@gmail.com wrote: Dear Tomas Hlavacek, +static ssize_t get_attr_uartclk(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); You don't need this cast here. Yes, you are right. Thanks. + mutex_lock(state-port.mutex); + ret = snprintf(buf, PAGE_SIZE, %d\n, state-uart_port-uartclk); Do you really need such a large buffer (PAGE_SIZE) ? Well no, but I believe that I get the buffer of length equal to PAGE_SIZE anyway. Documentation/filesystems/sysfs.txt says so on line 179. + mutex_unlock(state-port.mutex); + return ret; +} + +static ssize_t set_attr_uartclk(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); + unsigned int val; + int ret; + + ret = kstrtouint(buf, 10, val); + if (ret) + return ret; + + mutex_lock(state-port.mutex); + + /* + * Check value: baud_base has to be more than 9600 + * and uartclock = baud_base * 16 . + */ + if (val = 153600) + state-uart_port-uartclk = val; This magic value here would use some documentation. OK. Do you think this would be sufficient comment?: /* * Check value: baud_base does not make sense to be set below 9600 * and since uartclock = (baud_base * 16) it has to be equal or greater than * 9600 * 16 = 153600. */ PATCHv2 follows. Tomas -- Tomáš Hlaváček tmshl...@gmail.com -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
Dear Tomas Hlavacek, > Support for read/modify of uartclk via sysfs added. > It may prove useful with some no-name cards that > has different oscillator speeds and no distinguishing > PCI IDs to allow autodetection. It allows better integration > with udev and/or init scripts. > > Signed-off-by: Tomas Hlavacek > --- > drivers/tty/serial/serial_core.c | 54 > ++ drivers/tty/tty_io.c | > 17 > include/linux/tty.h |2 ++ > 3 files changed, 73 insertions(+) > > diff --git a/drivers/tty/serial/serial_core.c > b/drivers/tty/serial/serial_core.c index a21dc8e..059b438 100644 > --- a/drivers/tty/serial/serial_core.c > +++ b/drivers/tty/serial/serial_core.c > @@ -2293,6 +2293,46 @@ struct tty_driver *uart_console_device(struct > console *co, int *index) return p->tty_driver; > } > > +static ssize_t get_attr_uartclk(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + int ret; > + > + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); You don't need this cast here. > + mutex_lock(>port.mutex); > + ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk); Do you really need such a large buffer (PAGE_SIZE) ? > + mutex_unlock(>port.mutex); > + return ret; > +} > + > +static ssize_t set_attr_uartclk(struct device *dev, > + struct device_attribute *attr, const char *buf, size_t count) > +{ > + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); > + unsigned int val; > + int ret; > + > + ret = kstrtouint(buf, 10, ); > + if (ret) > + return ret; > + > + mutex_lock(>port.mutex); > + > + /* > + * Check value: baud_base has to be more than 9600 > + * and uartclock = baud_base * 16 . > + */ > + if (val >= 153600) > + state->uart_port->uartclk = val; This magic value here would use some documentation. > + mutex_unlock(>port.mutex); > + > + return count; > +} > + > +static DEVICE_ATTR(uartclk, S_IRUGO | S_IWUSR, get_attr_uartclk, > + set_attr_uartclk); > + > /** > * uart_add_one_port - attach a driver-defined port structure > * @drv: pointer to the uart low level driver structure for this port > @@ -2355,6 +2395,14 @@ int uart_add_one_port(struct uart_driver *drv, > struct uart_port *uport) } > > /* > + * Expose uartclk in sysfs. Use driverdata of the tty device for > + * referencing the UART port. > + */ > + dev_set_drvdata(tty_dev, state); > + if (device_create_file(tty_dev, _attr_uartclk) < 0) > + dev_err(tty_dev, "Failed to add uartclk attr\n"); > + > + /* >* Ensure UPF_DEAD is not set. >*/ > uport->flags &= ~UPF_DEAD; > @@ -2397,6 +2445,12 @@ int uart_remove_one_port(struct uart_driver *drv, > struct uart_port *uport) mutex_unlock(>mutex); > > /* > + * Remove uartclk file from sysfs. > + */ > + device_remove_file(tty_lookup_device(drv->tty_driver, uport->line), > + _attr_uartclk); > + > + /* >* Remove the devices from the tty layer >*/ > tty_unregister_device(drv->tty_driver, uport->line); > diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c > index b425c79..8ea8622 100644 > --- a/drivers/tty/tty_io.c > +++ b/drivers/tty/tty_io.c > @@ -3049,6 +3049,23 @@ void tty_unregister_device(struct tty_driver > *driver, unsigned index) } > EXPORT_SYMBOL(tty_unregister_device); > > +/* > + * tty_lookup_device - lookup a tty device > + * @driver: the tty driver that describes the tty device > + * @index: the index in the tty driver for this tty device > + * > + * This function returns a struct device pointer when device has > + * been found and NULL otherwise. > + * > + * Locking: ?? > + */ > +struct device *tty_lookup_device(struct tty_driver *driver, unsigned > index) +{ > + dev_t devt = MKDEV(driver->major, driver->minor_start) + index; > + return class_find_device(tty_class, NULL, , dev_match_devt); > +} > +EXPORT_SYMBOL(tty_lookup_device); > + > struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) > { > struct tty_driver *driver; > diff --git a/include/linux/tty.h b/include/linux/tty.h > index 9f47ab5..5d408a1 100644 > --- a/include/linux/tty.h > +++ b/include/linux/tty.h > @@ -410,6 +410,8 @@ extern int tty_register_driver(struct tty_driver > *driver); extern int tty_unregister_driver(struct tty_driver *driver); > extern struct device *tty_register_device(struct tty_driver *driver, > unsigned index, struct device *dev); > +extern struct device *tty_lookup_device(struct tty_driver *driver, > + unsigned index); > extern void tty_unregister_device(struct tty_driver *driver, unsigned > index); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char >
[PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
Support for read/modify of uartclk via sysfs added. It may prove useful with some no-name cards that has different oscillator speeds and no distinguishing PCI IDs to allow autodetection. It allows better integration with udev and/or init scripts. Signed-off-by: Tomas Hlavacek --- drivers/tty/serial/serial_core.c | 54 ++ drivers/tty/tty_io.c | 17 include/linux/tty.h |2 ++ 3 files changed, 73 insertions(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a21dc8e..059b438 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2293,6 +2293,46 @@ struct tty_driver *uart_console_device(struct console *co, int *index) return p->tty_driver; } +static ssize_t get_attr_uartclk(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); + mutex_lock(>port.mutex); + ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk); + mutex_unlock(>port.mutex); + return ret; +} + +static ssize_t set_attr_uartclk(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); + unsigned int val; + int ret; + + ret = kstrtouint(buf, 10, ); + if (ret) + return ret; + + mutex_lock(>port.mutex); + + /* +* Check value: baud_base has to be more than 9600 +* and uartclock = baud_base * 16 . +*/ + if (val >= 153600) + state->uart_port->uartclk = val; + + mutex_unlock(>port.mutex); + + return count; +} + +static DEVICE_ATTR(uartclk, S_IRUGO | S_IWUSR, get_attr_uartclk, + set_attr_uartclk); + /** * uart_add_one_port - attach a driver-defined port structure * @drv: pointer to the uart low level driver structure for this port @@ -2355,6 +2395,14 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) } /* +* Expose uartclk in sysfs. Use driverdata of the tty device for +* referencing the UART port. +*/ + dev_set_drvdata(tty_dev, state); + if (device_create_file(tty_dev, _attr_uartclk) < 0) + dev_err(tty_dev, "Failed to add uartclk attr\n"); + + /* * Ensure UPF_DEAD is not set. */ uport->flags &= ~UPF_DEAD; @@ -2397,6 +2445,12 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) mutex_unlock(>mutex); /* +* Remove uartclk file from sysfs. +*/ + device_remove_file(tty_lookup_device(drv->tty_driver, uport->line), + _attr_uartclk); + + /* * Remove the devices from the tty layer */ tty_unregister_device(drv->tty_driver, uport->line); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79..8ea8622 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3049,6 +3049,23 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) } EXPORT_SYMBOL(tty_unregister_device); +/* + * tty_lookup_device - lookup a tty device + * @driver: the tty driver that describes the tty device + * @index: the index in the tty driver for this tty device + * + * This function returns a struct device pointer when device has + * been found and NULL otherwise. + * + * Locking: ?? + */ +struct device *tty_lookup_device(struct tty_driver *driver, unsigned index) +{ + dev_t devt = MKDEV(driver->major, driver->minor_start) + index; + return class_find_device(tty_class, NULL, , dev_match_devt); +} +EXPORT_SYMBOL(tty_lookup_device); + struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) { struct tty_driver *driver; diff --git a/include/linux/tty.h b/include/linux/tty.h index 9f47ab5..5d408a1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -410,6 +410,8 @@ extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); extern struct device *tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev); +extern struct device *tty_lookup_device(struct tty_driver *driver, + unsigned index); extern void tty_unregister_device(struct tty_driver *driver, unsigned index); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ
[PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
Support for read/modify of uartclk via sysfs added. It may prove useful with some no-name cards that has different oscillator speeds and no distinguishing PCI IDs to allow autodetection. It allows better integration with udev and/or init scripts. Signed-off-by: Tomas Hlavacek tmshl...@gmail.com --- drivers/tty/serial/serial_core.c | 54 ++ drivers/tty/tty_io.c | 17 include/linux/tty.h |2 ++ 3 files changed, 73 insertions(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a21dc8e..059b438 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2293,6 +2293,46 @@ struct tty_driver *uart_console_device(struct console *co, int *index) return p-tty_driver; } +static ssize_t get_attr_uartclk(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); + mutex_lock(state-port.mutex); + ret = snprintf(buf, PAGE_SIZE, %d\n, state-uart_port-uartclk); + mutex_unlock(state-port.mutex); + return ret; +} + +static ssize_t set_attr_uartclk(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); + unsigned int val; + int ret; + + ret = kstrtouint(buf, 10, val); + if (ret) + return ret; + + mutex_lock(state-port.mutex); + + /* +* Check value: baud_base has to be more than 9600 +* and uartclock = baud_base * 16 . +*/ + if (val = 153600) + state-uart_port-uartclk = val; + + mutex_unlock(state-port.mutex); + + return count; +} + +static DEVICE_ATTR(uartclk, S_IRUGO | S_IWUSR, get_attr_uartclk, + set_attr_uartclk); + /** * uart_add_one_port - attach a driver-defined port structure * @drv: pointer to the uart low level driver structure for this port @@ -2355,6 +2395,14 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) } /* +* Expose uartclk in sysfs. Use driverdata of the tty device for +* referencing the UART port. +*/ + dev_set_drvdata(tty_dev, state); + if (device_create_file(tty_dev, dev_attr_uartclk) 0) + dev_err(tty_dev, Failed to add uartclk attr\n); + + /* * Ensure UPF_DEAD is not set. */ uport-flags = ~UPF_DEAD; @@ -2397,6 +2445,12 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) mutex_unlock(port-mutex); /* +* Remove uartclk file from sysfs. +*/ + device_remove_file(tty_lookup_device(drv-tty_driver, uport-line), + dev_attr_uartclk); + + /* * Remove the devices from the tty layer */ tty_unregister_device(drv-tty_driver, uport-line); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79..8ea8622 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3049,6 +3049,23 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) } EXPORT_SYMBOL(tty_unregister_device); +/* + * tty_lookup_device - lookup a tty device + * @driver: the tty driver that describes the tty device + * @index: the index in the tty driver for this tty device + * + * This function returns a struct device pointer when device has + * been found and NULL otherwise. + * + * Locking: ?? + */ +struct device *tty_lookup_device(struct tty_driver *driver, unsigned index) +{ + dev_t devt = MKDEV(driver-major, driver-minor_start) + index; + return class_find_device(tty_class, NULL, devt, dev_match_devt); +} +EXPORT_SYMBOL(tty_lookup_device); + struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) { struct tty_driver *driver; diff --git a/include/linux/tty.h b/include/linux/tty.h index 9f47ab5..5d408a1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -410,6 +410,8 @@ extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); extern struct device *tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev); +extern struct device *tty_lookup_device(struct tty_driver *driver, + unsigned index); extern void tty_unregister_device(struct tty_driver *driver, unsigned index); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at
Re: [PATCH 1/1] [RFC] uartclk from serial_core exposed to sysfs
Dear Tomas Hlavacek, Support for read/modify of uartclk via sysfs added. It may prove useful with some no-name cards that has different oscillator speeds and no distinguishing PCI IDs to allow autodetection. It allows better integration with udev and/or init scripts. Signed-off-by: Tomas Hlavacek tmshl...@gmail.com --- drivers/tty/serial/serial_core.c | 54 ++ drivers/tty/tty_io.c | 17 include/linux/tty.h |2 ++ 3 files changed, 73 insertions(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a21dc8e..059b438 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2293,6 +2293,46 @@ struct tty_driver *uart_console_device(struct console *co, int *index) return p-tty_driver; } +static ssize_t get_attr_uartclk(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); You don't need this cast here. + mutex_lock(state-port.mutex); + ret = snprintf(buf, PAGE_SIZE, %d\n, state-uart_port-uartclk); Do you really need such a large buffer (PAGE_SIZE) ? + mutex_unlock(state-port.mutex); + return ret; +} + +static ssize_t set_attr_uartclk(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct uart_state *state = (struct uart_state *)(dev_get_drvdata(dev)); + unsigned int val; + int ret; + + ret = kstrtouint(buf, 10, val); + if (ret) + return ret; + + mutex_lock(state-port.mutex); + + /* + * Check value: baud_base has to be more than 9600 + * and uartclock = baud_base * 16 . + */ + if (val = 153600) + state-uart_port-uartclk = val; This magic value here would use some documentation. + mutex_unlock(state-port.mutex); + + return count; +} + +static DEVICE_ATTR(uartclk, S_IRUGO | S_IWUSR, get_attr_uartclk, + set_attr_uartclk); + /** * uart_add_one_port - attach a driver-defined port structure * @drv: pointer to the uart low level driver structure for this port @@ -2355,6 +2395,14 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) } /* + * Expose uartclk in sysfs. Use driverdata of the tty device for + * referencing the UART port. + */ + dev_set_drvdata(tty_dev, state); + if (device_create_file(tty_dev, dev_attr_uartclk) 0) + dev_err(tty_dev, Failed to add uartclk attr\n); + + /* * Ensure UPF_DEAD is not set. */ uport-flags = ~UPF_DEAD; @@ -2397,6 +2445,12 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) mutex_unlock(port-mutex); /* + * Remove uartclk file from sysfs. + */ + device_remove_file(tty_lookup_device(drv-tty_driver, uport-line), + dev_attr_uartclk); + + /* * Remove the devices from the tty layer */ tty_unregister_device(drv-tty_driver, uport-line); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79..8ea8622 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3049,6 +3049,23 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) } EXPORT_SYMBOL(tty_unregister_device); +/* + * tty_lookup_device - lookup a tty device + * @driver: the tty driver that describes the tty device + * @index: the index in the tty driver for this tty device + * + * This function returns a struct device pointer when device has + * been found and NULL otherwise. + * + * Locking: ?? + */ +struct device *tty_lookup_device(struct tty_driver *driver, unsigned index) +{ + dev_t devt = MKDEV(driver-major, driver-minor_start) + index; + return class_find_device(tty_class, NULL, devt, dev_match_devt); +} +EXPORT_SYMBOL(tty_lookup_device); + struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) { struct tty_driver *driver; diff --git a/include/linux/tty.h b/include/linux/tty.h index 9f47ab5..5d408a1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -410,6 +410,8 @@ extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); extern struct device *tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev); +extern struct device *tty_lookup_device(struct tty_driver *driver, + unsigned index); extern void tty_unregister_device(struct tty_driver *driver, unsigned index); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the