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 */ 43 struct serdev_device { 44 struct device dev; 45 int nr; 46 struct serdev_controller *ctrl; 47 const struct serdev_device_ops *ops; 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 /* 74 * serdev controller structures 75 */ 76 struct serdev_controller_ops { 77 int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t); 78 void (*write_flush)(struct serdev_controller *); 79 int (*write_room)(struct serdev_controller *); 80 int (*open)(struct serdev_controller *); 81 void (*close)(struct serdev_controller *); 82 void (*set_flow_control)(struct serdev_controller *, bool); 83 unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int); 84 }; 85 86 /** 87 * struct serdev_controller - interface to the serdev controller 88 * @dev: Driver model representation of the device. 89 * @nr: number identifier for this controller/bus. 90 * @serdev: Pointer to slave device for this controller. 91 * @ops: Controller operations. 92 */ 93 struct serdev_controller { 94 struct device dev; 95 unsigned int nr; 96 struct serdev_device *serdev; 97 const struct serdev_controller_ops *ops; 98 }; 99 100 static inline struct serdev_controller *to_serdev_controller(struct device *d) 101 { 102 return container_of(d, struct serdev_controller, dev); 103 } 104 105 static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev) 106 { 107 return dev_get_drvdata(&serdev->dev); 108 } 109 110 static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data) 111 { 112 dev_set_drvdata(&serdev->dev, data); 113 } 114 115 /** 116 * serdev_device_put() - decrement serdev device refcount 117 * @serdev serdev device. 118 */ 119 static inline void serdev_device_put(struct serdev_device *serdev) 120 { 121 if (serdev) 122 put_device(&serdev->dev); 123 } 124 125 static inline void serdev_device_set_client_ops(struct serdev_device *serdev, 126 const struct serdev_device_ops *ops) 127 { 128 serdev->ops = ops; 129 } 130 131 static inline 132 void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl) 133 { 134 return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL; 135 } 136 137 static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl, 138 void *data) 139 { 140 dev_set_drvdata(&ctrl->dev, data); 141 } 142 143 /** 144 * serdev_controller_put() - decrement controller refcount 145 * @ctrl serdev controller. 146 */ 147 static inline void serdev_controller_put(struct serdev_controller *ctrl) 148 { 149 if (ctrl) 150 put_device(&ctrl->dev); 151 } 152 153 struct serdev_device *serdev_device_alloc(struct serdev_controller *); 154 int serdev_device_add(struct serdev_device *); 155 void serdev_device_remove(struct serdev_device *); 156 157 struct serdev_controller *serdev_controller_alloc(struct device *, size_t); 158 int serdev_controller_add(struct serdev_controller *); 159 void serdev_controller_remove(struct serdev_controller *); 160 161 static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl) 162 { 163 struct serdev_device *serdev = ctrl->serdev; 164 165 if (!serdev || !serdev->ops->write_wakeup) 166 return; 167 168 serdev->ops->write_wakeup(ctrl->serdev); 169 } 170 171 static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl, 172 const unsigned char *data, 173 size_t count) 174 { 175 struct serdev_device *serdev = ctrl->serdev; 176 177 if (!serdev || !serdev->ops->receive_buf) 178 return -EINVAL; 179 180 return serdev->ops->receive_buf(ctrl->serdev, data, count); 181 } 182 183 #if IS_ENABLED(CONFIG_SERIAL_DEV_BUS) 184 185 int serdev_device_open(struct serdev_device *); 186 void serdev_device_close(struct serdev_device *); 187 unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); 188 void serdev_device_set_flow_control(struct serdev_device *, bool); 189 int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); 190 void serdev_device_write_flush(struct serdev_device *); 191 int serdev_device_write_room(struct serdev_device *); 192 193 /* 194 * serdev device driver functions 195 */ 196 int __serdev_device_driver_register(struct serdev_device_driver *, struct module *); 197 #define serdev_device_driver_register(sdrv) \ 198 __serdev_device_driver_register(sdrv, THIS_MODULE) 199 200 /** 201 * serdev_device_driver_unregister() - unregister an serdev client driver 202 * @sdrv: the driver to unregister 203 */ 204 static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv) 205 { 206 if (sdrv) 207 driver_unregister(&sdrv->driver); 208 } 209 210 #define module_serdev_device_driver(__serdev_device_driver) \ 211 module_driver(__serdev_device_driver, serdev_device_driver_register, \ 212 serdev_device_driver_unregister) 213 214 #else 215 216 static inline int serdev_device_open(struct serdev_device *sdev) 217 { 218 return -ENODEV; 219 } 220 static inline void serdev_device_close(struct serdev_device *sdev) {} 221 static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate) 222 { 223 return 0; 224 } 225 static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} 226 static inline int serdev_device_write_buf(struct serdev_device *sdev, const unsigned char *buf, size_t count) 227 { 228 return -ENODEV; 229 } 230 static inline void serdev_device_write_flush(struct serdev_device *sdev) {} 231 static inline int serdev_device_write_room(struct serdev_device *sdev) 232 { 233 return 0; 234 } 235 236 #define serdev_device_driver_register(x) 237 #define serdev_device_driver_unregister(x) 238 239 #endif /* CONFIG_SERIAL_DEV_BUS */ 240 241 /* 242 * serdev hooks into TTY core 243 */ 244 struct tty_port; 245 struct tty_driver; 246 247 #ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT 248 struct device *serdev_tty_port_register(struct tty_port *port, 249 struct device *parent, 250 struct tty_driver *drv, int idx); 251 void serdev_tty_port_unregister(struct tty_port *port); 252 #else 253 static inline struct device *serdev_tty_port_register(struct tty_port *port, 254 struct device *parent, 255 struct tty_driver *drv, int idx) 256 { 257 return ERR_PTR(-ENODEV); 258 } 259 static inline void serdev_tty_port_unregister(struct tty_port *port) {} 260 #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 261 262 #endif /*_LINUX_SERDEV_H */ 263