Skip to content

Commit 8cde11b

Browse files
jhovoldgregkh
authored andcommitted
tty/serdev: add serdev registration interface
Add a new interface for registering a serdev controller and clients, and a helper function to deregister serdev devices (or a tty device) that were previously registered using the new interface. Once every driver currently using the tty_port_register_device() helpers have been vetted and converted to use the new serdev registration interface (at least for deregistration), we can move serdev registration to the current helpers and get rid of the serdev-specific functions. Reviewed-by: Rob Herring <robh@kernel.org> Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6bdc00d commit 8cde11b

File tree

4 files changed

+93
-4
lines changed

4 files changed

+93
-4
lines changed

drivers/tty/serdev/serdev-ttyport.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,16 +250,18 @@ struct device *serdev_tty_port_register(struct tty_port *port,
250250
return ERR_PTR(ret);
251251
}
252252

253-
void serdev_tty_port_unregister(struct tty_port *port)
253+
int serdev_tty_port_unregister(struct tty_port *port)
254254
{
255255
struct serdev_controller *ctrl = port->client_data;
256256
struct serport *serport = serdev_controller_get_drvdata(ctrl);
257257

258258
if (!serport)
259-
return;
259+
return -ENODEV;
260260

261261
serdev_controller_remove(ctrl);
262262
port->client_ops = NULL;
263263
port->client_data = NULL;
264264
serdev_controller_put(ctrl);
265+
266+
return 0;
265267
}

drivers/tty/tty_port.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/bitops.h>
1717
#include <linux/delay.h>
1818
#include <linux/module.h>
19+
#include <linux/serdev.h>
1920

2021
static int tty_port_default_receive_buf(struct tty_port *port,
2122
const unsigned char *p,
@@ -136,6 +137,80 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
136137
}
137138
EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
138139

140+
/**
141+
* tty_port_register_device_attr_serdev - register tty or serdev device
142+
* @port: tty_port of the device
143+
* @driver: tty_driver for this device
144+
* @index: index of the tty
145+
* @device: parent if exists, otherwise NULL
146+
* @drvdata: driver data for the device
147+
* @attr_grp: attribute group for the device
148+
*
149+
* Register a serdev or tty device depending on if the parent device has any
150+
* defined serdev clients or not.
151+
*/
152+
struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
153+
struct tty_driver *driver, unsigned index,
154+
struct device *device, void *drvdata,
155+
const struct attribute_group **attr_grp)
156+
{
157+
struct device *dev;
158+
159+
tty_port_link_device(port, driver, index);
160+
161+
dev = serdev_tty_port_register(port, device, driver, index);
162+
if (PTR_ERR(dev) != -ENODEV) {
163+
/* Skip creating cdev if we registered a serdev device */
164+
return dev;
165+
}
166+
167+
return tty_register_device_attr(driver, index, device, drvdata,
168+
attr_grp);
169+
}
170+
EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
171+
172+
/**
173+
* tty_port_register_device_serdev - register tty or serdev device
174+
* @port: tty_port of the device
175+
* @driver: tty_driver for this device
176+
* @index: index of the tty
177+
* @device: parent if exists, otherwise NULL
178+
*
179+
* Register a serdev or tty device depending on if the parent device has any
180+
* defined serdev clients or not.
181+
*/
182+
struct device *tty_port_register_device_serdev(struct tty_port *port,
183+
struct tty_driver *driver, unsigned index,
184+
struct device *device)
185+
{
186+
return tty_port_register_device_attr_serdev(port, driver, index,
187+
device, NULL, NULL);
188+
}
189+
EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
190+
191+
/**
192+
* tty_port_unregister_device - deregister a tty or serdev device
193+
* @port: tty_port of the device
194+
* @driver: tty_driver for this device
195+
* @index: index of the tty
196+
*
197+
* If a tty or serdev device is registered with a call to
198+
* tty_port_register_device_serdev() then this function must be called when
199+
* the device is gone.
200+
*/
201+
void tty_port_unregister_device(struct tty_port *port,
202+
struct tty_driver *driver, unsigned index)
203+
{
204+
int ret;
205+
206+
ret = serdev_tty_port_unregister(port);
207+
if (ret == 0)
208+
return;
209+
210+
tty_unregister_device(driver, index);
211+
}
212+
EXPORT_SYMBOL_GPL(tty_port_unregister_device);
213+
139214
int tty_port_alloc_xmit_buf(struct tty_port *port)
140215
{
141216
/* We may sleep in get_zeroed_page() */

include/linux/serdev.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,18 @@ struct tty_driver;
308308
struct device *serdev_tty_port_register(struct tty_port *port,
309309
struct device *parent,
310310
struct tty_driver *drv, int idx);
311-
void serdev_tty_port_unregister(struct tty_port *port);
311+
int serdev_tty_port_unregister(struct tty_port *port);
312312
#else
313313
static inline struct device *serdev_tty_port_register(struct tty_port *port,
314314
struct device *parent,
315315
struct tty_driver *drv, int idx)
316316
{
317317
return ERR_PTR(-ENODEV);
318318
}
319-
static inline void serdev_tty_port_unregister(struct tty_port *port) {}
319+
static inline int serdev_tty_port_unregister(struct tty_port *port)
320+
{
321+
return -ENODEV;
322+
}
320323
#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
321324

322325
#endif /*_LINUX_SERDEV_H */

include/linux/tty.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,15 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port,
558558
struct tty_driver *driver, unsigned index,
559559
struct device *device, void *drvdata,
560560
const struct attribute_group **attr_grp);
561+
extern struct device *tty_port_register_device_serdev(struct tty_port *port,
562+
struct tty_driver *driver, unsigned index,
563+
struct device *device);
564+
extern struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
565+
struct tty_driver *driver, unsigned index,
566+
struct device *device, void *drvdata,
567+
const struct attribute_group **attr_grp);
568+
extern void tty_port_unregister_device(struct tty_port *port,
569+
struct tty_driver *driver, unsigned index);
561570
extern int tty_port_alloc_xmit_buf(struct tty_port *port);
562571
extern void tty_port_free_xmit_buf(struct tty_port *port);
563572
extern void tty_port_destroy(struct tty_port *port);

0 commit comments

Comments
 (0)