at v4.11-rc4 7.7 kB view raw
1/* 2 * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org> 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 19struct serdev_controller; 20struct 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 */ 31struct 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 */ 43struct serdev_device { 44 struct device dev; 45 int nr; 46 struct serdev_controller *ctrl; 47 const struct serdev_device_ops *ops; 48}; 49 50static 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 */ 62struct serdev_device_driver { 63 struct device_driver driver; 64 int (*probe)(struct serdev_device *); 65 void (*remove)(struct serdev_device *); 66}; 67 68static 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 */ 76struct 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 */ 93struct serdev_controller { 94 struct device dev; 95 unsigned int nr; 96 struct serdev_device *serdev; 97 const struct serdev_controller_ops *ops; 98}; 99 100static inline struct serdev_controller *to_serdev_controller(struct device *d) 101{ 102 return container_of(d, struct serdev_controller, dev); 103} 104 105static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev) 106{ 107 return dev_get_drvdata(&serdev->dev); 108} 109 110static 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 */ 119static inline void serdev_device_put(struct serdev_device *serdev) 120{ 121 if (serdev) 122 put_device(&serdev->dev); 123} 124 125static 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 131static inline 132void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl) 133{ 134 return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL; 135} 136 137static 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 */ 147static inline void serdev_controller_put(struct serdev_controller *ctrl) 148{ 149 if (ctrl) 150 put_device(&ctrl->dev); 151} 152 153struct serdev_device *serdev_device_alloc(struct serdev_controller *); 154int serdev_device_add(struct serdev_device *); 155void serdev_device_remove(struct serdev_device *); 156 157struct serdev_controller *serdev_controller_alloc(struct device *, size_t); 158int serdev_controller_add(struct serdev_controller *); 159void serdev_controller_remove(struct serdev_controller *); 160 161static 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 171static 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 185int serdev_device_open(struct serdev_device *); 186void serdev_device_close(struct serdev_device *); 187unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); 188void serdev_device_set_flow_control(struct serdev_device *, bool); 189int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); 190void serdev_device_write_flush(struct serdev_device *); 191int serdev_device_write_room(struct serdev_device *); 192 193/* 194 * serdev device driver functions 195 */ 196int __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 */ 204static 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 216static inline int serdev_device_open(struct serdev_device *sdev) 217{ 218 return -ENODEV; 219} 220static inline void serdev_device_close(struct serdev_device *sdev) {} 221static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate) 222{ 223 return 0; 224} 225static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} 226static inline int serdev_device_write_buf(struct serdev_device *sdev, const unsigned char *buf, size_t count) 227{ 228 return -ENODEV; 229} 230static inline void serdev_device_write_flush(struct serdev_device *sdev) {} 231static 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 */ 244struct tty_port; 245struct tty_driver; 246 247#ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT 248struct device *serdev_tty_port_register(struct tty_port *port, 249 struct device *parent, 250 struct tty_driver *drv, int idx); 251void serdev_tty_port_unregister(struct tty_port *port); 252#else 253static 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} 259static inline void serdev_tty_port_unregister(struct tty_port *port) {} 260#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 261 262#endif /*_LINUX_SERDEV_H */