Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org>
4 */
5#ifndef _LINUX_SERDEV_H
6#define _LINUX_SERDEV_H
7
8#include <linux/types.h>
9#include <linux/device.h>
10#include <linux/iopoll.h>
11#include <linux/uaccess.h>
12#include <linux/termios.h>
13#include <linux/delay.h>
14
15struct serdev_controller;
16struct serdev_device;
17
18/*
19 * serdev device structures
20 */
21
22/**
23 * struct serdev_device_ops - Callback operations for a serdev device
24 * @receive_buf: Function called with data received from device;
25 * returns number of bytes accepted; may sleep.
26 * @write_wakeup: Function called when ready to transmit more data; must
27 * not sleep.
28 */
29struct serdev_device_ops {
30 size_t (*receive_buf)(struct serdev_device *, const u8 *, size_t);
31 void (*write_wakeup)(struct serdev_device *);
32};
33
34/**
35 * struct serdev_device - Basic representation of an serdev device
36 * @dev: Driver model representation of the device.
37 * @nr: Device number on serdev bus.
38 * @ctrl: serdev controller managing this device.
39 * @ops: Device operations.
40 * @write_comp: Completion used by serdev_device_write() internally
41 * @write_lock: Lock to serialize access when writing data
42 */
43struct serdev_device {
44 struct device dev;
45 int nr;
46 struct serdev_controller *ctrl;
47 const struct serdev_device_ops *ops;
48 struct completion write_comp;
49 struct mutex write_lock;
50};
51
52#define to_serdev_device(d) container_of_const(d, struct serdev_device, dev)
53
54/**
55 * struct serdev_device_driver - serdev slave device driver
56 * @driver: serdev device drivers should initialize name field of this
57 * structure.
58 * @probe: binds this driver to a serdev device.
59 * @remove: unbinds this driver from the serdev device.
60 * @shutdown: shut down this serdev device.
61 */
62struct serdev_device_driver {
63 struct device_driver driver;
64 int (*probe)(struct serdev_device *);
65 void (*remove)(struct serdev_device *);
66 void (*shutdown)(struct serdev_device *);
67};
68
69#define to_serdev_device_driver(d) container_of_const(d, struct serdev_device_driver, driver)
70
71enum serdev_parity {
72 SERDEV_PARITY_NONE,
73 SERDEV_PARITY_EVEN,
74 SERDEV_PARITY_ODD,
75};
76
77/*
78 * serdev controller structures
79 */
80struct serdev_controller_ops {
81 ssize_t (*write_buf)(struct serdev_controller *, const u8 *, size_t);
82 void (*write_flush)(struct serdev_controller *);
83 int (*open)(struct serdev_controller *);
84 void (*close)(struct serdev_controller *);
85 void (*set_flow_control)(struct serdev_controller *, bool);
86 int (*set_parity)(struct serdev_controller *, enum serdev_parity);
87 unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int);
88 void (*wait_until_sent)(struct serdev_controller *, long);
89 int (*get_tiocm)(struct serdev_controller *);
90 int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int);
91 int (*break_ctl)(struct serdev_controller *ctrl, unsigned int break_state);
92};
93
94/**
95 * struct serdev_controller - interface to the serdev controller
96 * @dev: Driver model representation of the device.
97 * @host: Serial port hardware controller device
98 * @nr: number identifier for this controller/bus.
99 * @serdev: Pointer to slave device for this controller.
100 * @ops: Controller operations.
101 */
102struct serdev_controller {
103 struct device dev;
104 struct device *host;
105 unsigned int nr;
106 struct serdev_device *serdev;
107 const struct serdev_controller_ops *ops;
108};
109
110#define to_serdev_controller(d) container_of_const(d, struct serdev_controller, dev)
111
112static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev)
113{
114 return dev_get_drvdata(&serdev->dev);
115}
116
117static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data)
118{
119 dev_set_drvdata(&serdev->dev, data);
120}
121
122/**
123 * serdev_device_put() - decrement serdev device refcount
124 * @serdev: serdev device.
125 */
126static inline void serdev_device_put(struct serdev_device *serdev)
127{
128 if (serdev)
129 put_device(&serdev->dev);
130}
131
132static inline void serdev_device_set_client_ops(struct serdev_device *serdev,
133 const struct serdev_device_ops *ops)
134{
135 serdev->ops = ops;
136}
137
138static inline
139void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl)
140{
141 return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL;
142}
143
144static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl,
145 void *data)
146{
147 dev_set_drvdata(&ctrl->dev, data);
148}
149
150/**
151 * serdev_controller_put() - decrement controller refcount
152 * @ctrl: serdev controller.
153 */
154static inline void serdev_controller_put(struct serdev_controller *ctrl)
155{
156 if (ctrl)
157 put_device(&ctrl->dev);
158}
159
160struct serdev_device *serdev_device_alloc(struct serdev_controller *);
161int serdev_device_add(struct serdev_device *);
162void serdev_device_remove(struct serdev_device *);
163
164struct serdev_controller *serdev_controller_alloc(struct device *host,
165 struct device *parent,
166 size_t size);
167int serdev_controller_add(struct serdev_controller *);
168void serdev_controller_remove(struct serdev_controller *);
169
170static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl)
171{
172 struct serdev_device *serdev = ctrl->serdev;
173
174 if (!serdev || !serdev->ops->write_wakeup)
175 return;
176
177 serdev->ops->write_wakeup(serdev);
178}
179
180static inline size_t serdev_controller_receive_buf(struct serdev_controller *ctrl,
181 const u8 *data,
182 size_t count)
183{
184 struct serdev_device *serdev = ctrl->serdev;
185
186 if (!serdev || !serdev->ops->receive_buf)
187 return 0;
188
189 return serdev->ops->receive_buf(serdev, data, count);
190}
191
192#if IS_ENABLED(CONFIG_SERIAL_DEV_BUS)
193
194int serdev_device_open(struct serdev_device *);
195void serdev_device_close(struct serdev_device *);
196int devm_serdev_device_open(struct device *, struct serdev_device *);
197unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
198void serdev_device_set_flow_control(struct serdev_device *, bool);
199int serdev_device_write_buf(struct serdev_device *, const u8 *, size_t);
200void serdev_device_wait_until_sent(struct serdev_device *, long);
201int serdev_device_get_tiocm(struct serdev_device *);
202int serdev_device_set_tiocm(struct serdev_device *, int, int);
203int serdev_device_break_ctl(struct serdev_device *serdev, int break_state);
204void serdev_device_write_wakeup(struct serdev_device *);
205ssize_t serdev_device_write(struct serdev_device *, const u8 *, size_t, long);
206void serdev_device_write_flush(struct serdev_device *);
207
208/*
209 * serdev device driver functions
210 */
211int __serdev_device_driver_register(struct serdev_device_driver *, struct module *);
212#define serdev_device_driver_register(sdrv) \
213 __serdev_device_driver_register(sdrv, THIS_MODULE)
214
215/**
216 * serdev_device_driver_unregister() - unregister an serdev client driver
217 * @sdrv: the driver to unregister
218 */
219static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv)
220{
221 if (sdrv)
222 driver_unregister(&sdrv->driver);
223}
224
225#define module_serdev_device_driver(__serdev_device_driver) \
226 module_driver(__serdev_device_driver, serdev_device_driver_register, \
227 serdev_device_driver_unregister)
228
229#else
230
231static inline int serdev_device_open(struct serdev_device *sdev)
232{
233 return -ENODEV;
234}
235static inline void serdev_device_close(struct serdev_device *sdev) {}
236static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate)
237{
238 return 0;
239}
240static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {}
241static inline int serdev_device_write_buf(struct serdev_device *serdev,
242 const u8 *buf,
243 size_t count)
244{
245 return -ENODEV;
246}
247static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {}
248static inline int serdev_device_get_tiocm(struct serdev_device *serdev)
249{
250 return -EOPNOTSUPP;
251}
252static inline int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
253{
254 return -EOPNOTSUPP;
255}
256static inline int serdev_device_break_ctl(struct serdev_device *serdev, int break_state)
257{
258 return -EOPNOTSUPP;
259}
260static inline ssize_t serdev_device_write(struct serdev_device *sdev,
261 const u8 *buf, size_t count,
262 unsigned long timeout)
263{
264 return -ENODEV;
265}
266static inline void serdev_device_write_flush(struct serdev_device *sdev) {}
267
268#define serdev_device_driver_register(x)
269#define serdev_device_driver_unregister(x)
270
271#endif /* CONFIG_SERIAL_DEV_BUS */
272
273static inline bool serdev_device_get_cts(struct serdev_device *serdev)
274{
275 int status = serdev_device_get_tiocm(serdev);
276 return !!(status & TIOCM_CTS);
277}
278
279static inline int serdev_device_wait_for_cts(struct serdev_device *serdev, bool state, int timeout_ms)
280{
281 bool signal;
282
283 return readx_poll_timeout(serdev_device_get_cts, serdev, signal, signal == state,
284 2000, timeout_ms * 1000);
285}
286
287static inline int serdev_device_set_rts(struct serdev_device *serdev, bool enable)
288{
289 if (enable)
290 return serdev_device_set_tiocm(serdev, TIOCM_RTS, 0);
291 else
292 return serdev_device_set_tiocm(serdev, 0, TIOCM_RTS);
293}
294
295int serdev_device_set_parity(struct serdev_device *serdev,
296 enum serdev_parity parity);
297
298/*
299 * serdev hooks into TTY core
300 */
301struct tty_port;
302struct tty_driver;
303
304#ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT
305struct device *serdev_tty_port_register(struct tty_port *port,
306 struct device *host,
307 struct device *parent,
308 struct tty_driver *drv, int idx);
309int serdev_tty_port_unregister(struct tty_port *port);
310#else
311static inline struct device *serdev_tty_port_register(struct tty_port *port,
312 struct device *host,
313 struct device *parent,
314 struct tty_driver *drv, int idx)
315{
316 return ERR_PTR(-ENODEV);
317}
318static inline int serdev_tty_port_unregister(struct tty_port *port)
319{
320 return -ENODEV;
321}
322#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
323
324struct acpi_resource;
325struct acpi_resource_uart_serialbus;
326
327#ifdef CONFIG_ACPI
328bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
329 struct acpi_resource_uart_serialbus **uart);
330#else
331static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
332 struct acpi_resource_uart_serialbus **uart)
333{
334 return false;
335}
336#endif /* CONFIG_ACPI */
337
338#ifdef CONFIG_OF
339struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node);
340#else
341static inline struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
342{
343 return NULL;
344}
345#endif /* CONFIG_OF */
346
347#endif /*_LINUX_SERDEV_H */