aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-05-18 11:33:00 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-18 11:38:24 -0400
commit8cde11b2baa1d02eb2eb955dfd47d9f2a12f12cf (patch)
treefbe1c16cdebe360663da4943753be96e87c5a193
parent6bdc00d01e202ae11fa1cae0dacbef895434483d (diff)
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>
-rw-r--r--drivers/tty/serdev/serdev-ttyport.c6
-rw-r--r--drivers/tty/tty_port.c75
-rw-r--r--include/linux/serdev.h7
-rw-r--r--include/linux/tty.h9
4 files changed, 93 insertions, 4 deletions
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index 013efffd2e82..d0a021c93986 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -250,16 +250,18 @@ err_reset_data:
250 return ERR_PTR(ret); 250 return ERR_PTR(ret);
251} 251}
252 252
253void serdev_tty_port_unregister(struct tty_port *port) 253int serdev_tty_port_unregister(struct tty_port *port)
254{ 254{
255 struct serdev_controller *ctrl = port->client_data; 255 struct serdev_controller *ctrl = port->client_data;
256 struct serport *serport = serdev_controller_get_drvdata(ctrl); 256 struct serport *serport = serdev_controller_get_drvdata(ctrl);
257 257
258 if (!serport) 258 if (!serport)
259 return; 259 return -ENODEV;
260 260
261 serdev_controller_remove(ctrl); 261 serdev_controller_remove(ctrl);
262 port->client_ops = NULL; 262 port->client_ops = NULL;
263 port->client_data = NULL; 263 port->client_data = NULL;
264 serdev_controller_put(ctrl); 264 serdev_controller_put(ctrl);
265
266 return 0;
265} 267}
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 88dac3b79369..4fb3165384c4 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -16,6 +16,7 @@
16#include <linux/bitops.h> 16#include <linux/bitops.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/serdev.h>
19 20
20static int tty_port_default_receive_buf(struct tty_port *port, 21static int tty_port_default_receive_buf(struct tty_port *port,
21 const unsigned char *p, 22 const unsigned char *p,
@@ -136,6 +137,80 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
136} 137}
137EXPORT_SYMBOL_GPL(tty_port_register_device_attr); 138EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
138 139
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 */
152struct 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}
170EXPORT_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 */
182struct 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}
189EXPORT_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 */
201void 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}
212EXPORT_SYMBOL_GPL(tty_port_unregister_device);
213
139int tty_port_alloc_xmit_buf(struct tty_port *port) 214int tty_port_alloc_xmit_buf(struct tty_port *port)
140{ 215{
141 /* We may sleep in get_zeroed_page() */ 216 /* We may sleep in get_zeroed_page() */
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index e2a225bf716d..e69402d4a8ae 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -308,7 +308,7 @@ struct tty_driver;
308struct device *serdev_tty_port_register(struct tty_port *port, 308struct device *serdev_tty_port_register(struct tty_port *port,
309 struct device *parent, 309 struct device *parent,
310 struct tty_driver *drv, int idx); 310 struct tty_driver *drv, int idx);
311void serdev_tty_port_unregister(struct tty_port *port); 311int serdev_tty_port_unregister(struct tty_port *port);
312#else 312#else
313static inline struct device *serdev_tty_port_register(struct tty_port *port, 313static inline struct device *serdev_tty_port_register(struct tty_port *port,
314 struct device *parent, 314 struct device *parent,
@@ -316,7 +316,10 @@ static inline struct device *serdev_tty_port_register(struct tty_port *port,
316{ 316{
317 return ERR_PTR(-ENODEV); 317 return ERR_PTR(-ENODEV);
318} 318}
319static inline void serdev_tty_port_unregister(struct tty_port *port) {} 319static inline int serdev_tty_port_unregister(struct tty_port *port)
320{
321 return -ENODEV;
322}
320#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 323#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
321 324
322#endif /*_LINUX_SERDEV_H */ 325#endif /*_LINUX_SERDEV_H */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index d07cd2105a6c..eccb4ec30a8a 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -558,6 +558,15 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port,
558 struct tty_driver *driver, unsigned index, 558 struct tty_driver *driver, unsigned index,
559 struct device *device, void *drvdata, 559 struct device *device, void *drvdata,
560 const struct attribute_group **attr_grp); 560 const struct attribute_group **attr_grp);
561extern struct device *tty_port_register_device_serdev(struct tty_port *port,
562 struct tty_driver *driver, unsigned index,
563 struct device *device);
564extern 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);
568extern void tty_port_unregister_device(struct tty_port *port,
569 struct tty_driver *driver, unsigned index);
561extern int tty_port_alloc_xmit_buf(struct tty_port *port); 570extern int tty_port_alloc_xmit_buf(struct tty_port *port);
562extern void tty_port_free_xmit_buf(struct tty_port *port); 571extern void tty_port_free_xmit_buf(struct tty_port *port);
563extern void tty_port_destroy(struct tty_port *port); 572extern void tty_port_destroy(struct tty_port *port);