1 /* 2 * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <[email protected]> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 and 6 * only version 2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 #ifndef _LINUX_SERDEV_H 14 #define _LINUX_SERDEV_H 15 16 #include <linux/types.h> 17 #include <linux/device.h> 18 19 struct serdev_controller; 20 struct serdev_device; 21 22 /* 23 * serdev device structures 24 */ 25 26 /** 27 * struct serdev_device_ops - Callback operations for a serdev device 28 * @receive_buf: Function called with data received from device. 29 * @write_wakeup: Function called when ready to transmit more data. 30 */ 31 struct serdev_device_ops { 32 int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t); 33 void (*write_wakeup)(struct serdev_device *); 34 }; 35 36 /** 37 * struct serdev_device - Basic representation of an serdev device 38 * @dev: Driver model representation of the device. 39 * @nr: Device number on serdev bus. 40 * @ctrl: serdev controller managing this device. 41 * @ops: Device operations. 42 * @write_comp Completion used by serdev_device_write() internally 43 * @write_lock Lock to serialize access when writing data 44 */ 45 struct serdev_device { 46 struct device dev; 47 int nr; 48 struct serdev_controller *ctrl; 49 const struct serdev_device_ops *ops; 50 struct completion write_comp; 51 struct mutex write_lock; 52 }; 53 54 static inline struct serdev_device *to_serdev_device(struct device *d) 55 { 56 return container_of(d, struct serdev_device, dev); 57 } 58 59 /** 60 * struct serdev_device_driver - serdev slave device driver 61 * @driver: serdev device drivers should initialize name field of this 62 * structure. 63 * @probe: binds this driver to a serdev device. 64 * @remove: unbinds this driver from the serdev device. 65 */ 66 struct serdev_device_driver { 67 struct device_driver driver; 68 int (*probe)(struct serdev_device *); 69 void (*remove)(struct serdev_device *); 70 }; 71 72 static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) 73 { 74 return container_of(d, struct serdev_device_driver, driver); 75 } 76 77 /* 78 * serdev controller structures 79 */ 80 struct serdev_controller_ops { 81 int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t); 82 void (*write_flush)(struct serdev_controller *); 83 int (*write_room)(struct serdev_controller *); 84 int (*open)(struct serdev_controller *); 85 void (*close)(struct serdev_controller *); 86 void (*set_flow_control)(struct serdev_controller *, bool); 87 unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int); 88 }; 89 90 /** 91 * struct serdev_controller - interface to the serdev controller 92 * @dev: Driver model representation of the device. 93 * @nr: number identifier for this controller/bus. 94 * @serdev: Pointer to slave device for this controller. 95 * @ops: Controller operations. 96 */ 97 struct serdev_controller { 98 struct device dev; 99 unsigned int nr; 100 struct serdev_device *serdev; 101 const struct serdev_controller_ops *ops; 102 }; 103 104 static inline struct serdev_controller *to_serdev_controller(struct device *d) 105 { 106 return container_of(d, struct serdev_controller, dev); 107 } 108 109 static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev) 110 { 111 return dev_get_drvdata(&serdev->dev); 112 } 113 114 static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data) 115 { 116 dev_set_drvdata(&serdev->dev, data); 117 } 118 119 /** 120 * serdev_device_put() - decrement serdev device refcount 121 * @serdev serdev device. 122 */ 123 static inline void serdev_device_put(struct serdev_device *serdev) 124 { 125 if (serdev) 126 put_device(&serdev->dev); 127 } 128 129 static inline void serdev_device_set_client_ops(struct serdev_device *serdev, 130 const struct serdev_device_ops *ops) 131 { 132 serdev->ops = ops; 133 } 134 135 static inline 136 void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl) 137 { 138 return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL; 139 } 140 141 static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl, 142 void *data) 143 { 144 dev_set_drvdata(&ctrl->dev, data); 145 } 146 147 /** 148 * serdev_controller_put() - decrement controller refcount 149 * @ctrl serdev controller. 150 */ 151 static inline void serdev_controller_put(struct serdev_controller *ctrl) 152 { 153 if (ctrl) 154 put_device(&ctrl->dev); 155 } 156 157 struct serdev_device *serdev_device_alloc(struct serdev_controller *); 158 int serdev_device_add(struct serdev_device *); 159 void serdev_device_remove(struct serdev_device *); 160 161 struct serdev_controller *serdev_controller_alloc(struct device *, size_t); 162 int serdev_controller_add(struct serdev_controller *); 163 void serdev_controller_remove(struct serdev_controller *); 164 165 static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl) 166 { 167 struct serdev_device *serdev = ctrl->serdev; 168 169 if (!serdev || !serdev->ops->write_wakeup) 170 return; 171 172 serdev->ops->write_wakeup(serdev); 173 } 174 175 static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl, 176 const unsigned char *data, 177 size_t count) 178 { 179 struct serdev_device *serdev = ctrl->serdev; 180 181 if (!serdev || !serdev->ops->receive_buf) 182 return -EINVAL; 183 184 return serdev->ops->receive_buf(serdev, data, count); 185 } 186 187 #if IS_ENABLED(CONFIG_SERIAL_DEV_BUS) 188 189 int serdev_device_open(struct serdev_device *); 190 void serdev_device_close(struct serdev_device *); 191 unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); 192 void serdev_device_set_flow_control(struct serdev_device *, bool); 193 void serdev_device_write_wakeup(struct serdev_device *); 194 int serdev_device_write(struct serdev_device *, const unsigned char *, size_t, unsigned long); 195 void serdev_device_write_flush(struct serdev_device *); 196 int serdev_device_write_room(struct serdev_device *); 197 198 /* 199 * serdev device driver functions 200 */ 201 int __serdev_device_driver_register(struct serdev_device_driver *, struct module *); 202 #define serdev_device_driver_register(sdrv) \ 203 __serdev_device_driver_register(sdrv, THIS_MODULE) 204 205 /** 206 * serdev_device_driver_unregister() - unregister an serdev client driver 207 * @sdrv: the driver to unregister 208 */ 209 static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv) 210 { 211 if (sdrv) 212 driver_unregister(&sdrv->driver); 213 } 214 215 #define module_serdev_device_driver(__serdev_device_driver) \ 216 module_driver(__serdev_device_driver, serdev_device_driver_register, \ 217 serdev_device_driver_unregister) 218 219 #else 220 221 static inline int serdev_device_open(struct serdev_device *sdev) 222 { 223 return -ENODEV; 224 } 225 static inline void serdev_device_close(struct serdev_device *sdev) {} 226 static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate) 227 { 228 return 0; 229 } 230 static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} 231 static inline int serdev_device_write(struct serdev_device *sdev, const unsigned char *buf, 232 size_t count, unsigned long timeout) 233 { 234 return -ENODEV; 235 } 236 static inline void serdev_device_write_flush(struct serdev_device *sdev) {} 237 static inline int serdev_device_write_room(struct serdev_device *sdev) 238 { 239 return 0; 240 } 241 242 #define serdev_device_driver_register(x) 243 #define serdev_device_driver_unregister(x) 244 245 #endif /* CONFIG_SERIAL_DEV_BUS */ 246 247 /* 248 * serdev hooks into TTY core 249 */ 250 struct tty_port; 251 struct tty_driver; 252 253 #ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT 254 struct device *serdev_tty_port_register(struct tty_port *port, 255 struct device *parent, 256 struct tty_driver *drv, int idx); 257 void serdev_tty_port_unregister(struct tty_port *port); 258 #else 259 static inline struct device *serdev_tty_port_register(struct tty_port *port, 260 struct device *parent, 261 struct tty_driver *drv, int idx) 262 { 263 return ERR_PTR(-ENODEV); 264 } 265 static inline void serdev_tty_port_unregister(struct tty_port *port) {} 266 #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 267 268 static inline int serdev_device_write_buf(struct serdev_device *serdev, 269 const unsigned char *data, 270 size_t count) 271 { 272 return serdev_device_write(serdev, data, count, 0); 273 } 274 275 #endif /*_LINUX_SERDEV_H */ 276