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