197fb5e8dSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2cd6484e1SRob Herring /* 3cd6484e1SRob Herring * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <[email protected]> 4cd6484e1SRob Herring */ 5cd6484e1SRob Herring #ifndef _LINUX_SERDEV_H 6cd6484e1SRob Herring #define _LINUX_SERDEV_H 7cd6484e1SRob Herring 8cd6484e1SRob Herring #include <linux/types.h> 9cd6484e1SRob Herring #include <linux/device.h> 10*89bbeb7eSAl Viro #include <linux/uaccess.h> 115659dab2SSebastian Reichel #include <linux/termios.h> 12756db778SSebastian Reichel #include <linux/delay.h> 13cd6484e1SRob Herring 14cd6484e1SRob Herring struct serdev_controller; 15cd6484e1SRob Herring struct serdev_device; 16cd6484e1SRob Herring 17cd6484e1SRob Herring /* 18cd6484e1SRob Herring * serdev device structures 19cd6484e1SRob Herring */ 20cd6484e1SRob Herring 21cd6484e1SRob Herring /** 22cd6484e1SRob Herring * struct serdev_device_ops - Callback operations for a serdev device 2310f9e033SJohan Hovold * @receive_buf: Function called with data received from device; 2410f9e033SJohan Hovold * returns number of bytes accepted; may sleep. 2510f9e033SJohan Hovold * @write_wakeup: Function called when ready to transmit more data; must 2610f9e033SJohan Hovold * not sleep. 27cd6484e1SRob Herring */ 28cd6484e1SRob Herring struct serdev_device_ops { 29cd6484e1SRob Herring int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t); 30cd6484e1SRob Herring void (*write_wakeup)(struct serdev_device *); 31cd6484e1SRob Herring }; 32cd6484e1SRob Herring 33cd6484e1SRob Herring /** 34cd6484e1SRob Herring * struct serdev_device - Basic representation of an serdev device 35cd6484e1SRob Herring * @dev: Driver model representation of the device. 36cd6484e1SRob Herring * @nr: Device number on serdev bus. 37cd6484e1SRob Herring * @ctrl: serdev controller managing this device. 38cd6484e1SRob Herring * @ops: Device operations. 396fe729c4SAndrey Smirnov * @write_comp Completion used by serdev_device_write() internally 406fe729c4SAndrey Smirnov * @write_lock Lock to serialize access when writing data 41cd6484e1SRob Herring */ 42cd6484e1SRob Herring struct serdev_device { 43cd6484e1SRob Herring struct device dev; 44cd6484e1SRob Herring int nr; 45cd6484e1SRob Herring struct serdev_controller *ctrl; 46cd6484e1SRob Herring const struct serdev_device_ops *ops; 476fe729c4SAndrey Smirnov struct completion write_comp; 486fe729c4SAndrey Smirnov struct mutex write_lock; 49cd6484e1SRob Herring }; 50cd6484e1SRob Herring 51cd6484e1SRob Herring static inline struct serdev_device *to_serdev_device(struct device *d) 52cd6484e1SRob Herring { 53cd6484e1SRob Herring return container_of(d, struct serdev_device, dev); 54cd6484e1SRob Herring } 55cd6484e1SRob Herring 56cd6484e1SRob Herring /** 57cd6484e1SRob Herring * struct serdev_device_driver - serdev slave device driver 58cd6484e1SRob Herring * @driver: serdev device drivers should initialize name field of this 59cd6484e1SRob Herring * structure. 60cd6484e1SRob Herring * @probe: binds this driver to a serdev device. 61cd6484e1SRob Herring * @remove: unbinds this driver from the serdev device. 62cd6484e1SRob Herring */ 63cd6484e1SRob Herring struct serdev_device_driver { 64cd6484e1SRob Herring struct device_driver driver; 65cd6484e1SRob Herring int (*probe)(struct serdev_device *); 66cd6484e1SRob Herring void (*remove)(struct serdev_device *); 67cd6484e1SRob Herring }; 68cd6484e1SRob Herring 69cd6484e1SRob Herring static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) 70cd6484e1SRob Herring { 71cd6484e1SRob Herring return container_of(d, struct serdev_device_driver, driver); 72cd6484e1SRob Herring } 73cd6484e1SRob Herring 743a19cfccSUlrich Hecht enum serdev_parity { 753a19cfccSUlrich Hecht SERDEV_PARITY_NONE, 763a19cfccSUlrich Hecht SERDEV_PARITY_EVEN, 773a19cfccSUlrich Hecht SERDEV_PARITY_ODD, 783a19cfccSUlrich Hecht }; 793a19cfccSUlrich Hecht 80cd6484e1SRob Herring /* 81cd6484e1SRob Herring * serdev controller structures 82cd6484e1SRob Herring */ 83cd6484e1SRob Herring struct serdev_controller_ops { 84cd6484e1SRob Herring int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t); 85cd6484e1SRob Herring void (*write_flush)(struct serdev_controller *); 86cd6484e1SRob Herring int (*write_room)(struct serdev_controller *); 87cd6484e1SRob Herring int (*open)(struct serdev_controller *); 88cd6484e1SRob Herring void (*close)(struct serdev_controller *); 89cd6484e1SRob Herring void (*set_flow_control)(struct serdev_controller *, bool); 903a19cfccSUlrich Hecht int (*set_parity)(struct serdev_controller *, enum serdev_parity); 91cd6484e1SRob Herring unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int); 92b3f80c8fSSebastian Reichel void (*wait_until_sent)(struct serdev_controller *, long); 935659dab2SSebastian Reichel int (*get_tiocm)(struct serdev_controller *); 945659dab2SSebastian Reichel int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int); 95cd6484e1SRob Herring }; 96cd6484e1SRob Herring 97cd6484e1SRob Herring /** 98cd6484e1SRob Herring * struct serdev_controller - interface to the serdev controller 99cd6484e1SRob Herring * @dev: Driver model representation of the device. 100cd6484e1SRob Herring * @nr: number identifier for this controller/bus. 101cd6484e1SRob Herring * @serdev: Pointer to slave device for this controller. 102cd6484e1SRob Herring * @ops: Controller operations. 103cd6484e1SRob Herring */ 104cd6484e1SRob Herring struct serdev_controller { 105cd6484e1SRob Herring struct device dev; 106cd6484e1SRob Herring unsigned int nr; 107cd6484e1SRob Herring struct serdev_device *serdev; 108cd6484e1SRob Herring const struct serdev_controller_ops *ops; 109cd6484e1SRob Herring }; 110cd6484e1SRob Herring 111cd6484e1SRob Herring static inline struct serdev_controller *to_serdev_controller(struct device *d) 112cd6484e1SRob Herring { 113cd6484e1SRob Herring return container_of(d, struct serdev_controller, dev); 114cd6484e1SRob Herring } 115cd6484e1SRob Herring 116cd6484e1SRob Herring static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev) 117cd6484e1SRob Herring { 118cd6484e1SRob Herring return dev_get_drvdata(&serdev->dev); 119cd6484e1SRob Herring } 120cd6484e1SRob Herring 121cd6484e1SRob Herring static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data) 122cd6484e1SRob Herring { 123cd6484e1SRob Herring dev_set_drvdata(&serdev->dev, data); 124cd6484e1SRob Herring } 125cd6484e1SRob Herring 126cd6484e1SRob Herring /** 127cd6484e1SRob Herring * serdev_device_put() - decrement serdev device refcount 128cd6484e1SRob Herring * @serdev serdev device. 129cd6484e1SRob Herring */ 130cd6484e1SRob Herring static inline void serdev_device_put(struct serdev_device *serdev) 131cd6484e1SRob Herring { 132cd6484e1SRob Herring if (serdev) 133cd6484e1SRob Herring put_device(&serdev->dev); 134cd6484e1SRob Herring } 135cd6484e1SRob Herring 136cd6484e1SRob Herring static inline void serdev_device_set_client_ops(struct serdev_device *serdev, 137cd6484e1SRob Herring const struct serdev_device_ops *ops) 138cd6484e1SRob Herring { 139cd6484e1SRob Herring serdev->ops = ops; 140cd6484e1SRob Herring } 141cd6484e1SRob Herring 142cd6484e1SRob Herring static inline 143cd6484e1SRob Herring void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl) 144cd6484e1SRob Herring { 145cd6484e1SRob Herring return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL; 146cd6484e1SRob Herring } 147cd6484e1SRob Herring 148cd6484e1SRob Herring static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl, 149cd6484e1SRob Herring void *data) 150cd6484e1SRob Herring { 151cd6484e1SRob Herring dev_set_drvdata(&ctrl->dev, data); 152cd6484e1SRob Herring } 153cd6484e1SRob Herring 154cd6484e1SRob Herring /** 155cd6484e1SRob Herring * serdev_controller_put() - decrement controller refcount 156cd6484e1SRob Herring * @ctrl serdev controller. 157cd6484e1SRob Herring */ 158cd6484e1SRob Herring static inline void serdev_controller_put(struct serdev_controller *ctrl) 159cd6484e1SRob Herring { 160cd6484e1SRob Herring if (ctrl) 161cd6484e1SRob Herring put_device(&ctrl->dev); 162cd6484e1SRob Herring } 163cd6484e1SRob Herring 164cd6484e1SRob Herring struct serdev_device *serdev_device_alloc(struct serdev_controller *); 165cd6484e1SRob Herring int serdev_device_add(struct serdev_device *); 166cd6484e1SRob Herring void serdev_device_remove(struct serdev_device *); 167cd6484e1SRob Herring 168cd6484e1SRob Herring struct serdev_controller *serdev_controller_alloc(struct device *, size_t); 169cd6484e1SRob Herring int serdev_controller_add(struct serdev_controller *); 170cd6484e1SRob Herring void serdev_controller_remove(struct serdev_controller *); 171cd6484e1SRob Herring 172cd6484e1SRob Herring static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl) 173cd6484e1SRob Herring { 174cd6484e1SRob Herring struct serdev_device *serdev = ctrl->serdev; 175cd6484e1SRob Herring 176cd6484e1SRob Herring if (!serdev || !serdev->ops->write_wakeup) 177cd6484e1SRob Herring return; 178cd6484e1SRob Herring 1799d1d994dSAndrey Smirnov serdev->ops->write_wakeup(serdev); 180cd6484e1SRob Herring } 181cd6484e1SRob Herring 182cd6484e1SRob Herring static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl, 183cd6484e1SRob Herring const unsigned char *data, 184cd6484e1SRob Herring size_t count) 185cd6484e1SRob Herring { 186cd6484e1SRob Herring struct serdev_device *serdev = ctrl->serdev; 187cd6484e1SRob Herring 188cd6484e1SRob Herring if (!serdev || !serdev->ops->receive_buf) 189fd00cf81SJohan Hovold return 0; 190cd6484e1SRob Herring 1919d1d994dSAndrey Smirnov return serdev->ops->receive_buf(serdev, data, count); 192cd6484e1SRob Herring } 193cd6484e1SRob Herring 194cd6484e1SRob Herring #if IS_ENABLED(CONFIG_SERIAL_DEV_BUS) 195cd6484e1SRob Herring 196cd6484e1SRob Herring int serdev_device_open(struct serdev_device *); 197cd6484e1SRob Herring void serdev_device_close(struct serdev_device *); 1982cb67d20SAndrey Smirnov int devm_serdev_device_open(struct device *, struct serdev_device *); 199cd6484e1SRob Herring unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); 200cd6484e1SRob Herring void serdev_device_set_flow_control(struct serdev_device *, bool); 2016bdc00d0SStefan Wahren int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); 202b3f80c8fSSebastian Reichel void serdev_device_wait_until_sent(struct serdev_device *, long); 2035659dab2SSebastian Reichel int serdev_device_get_tiocm(struct serdev_device *); 2045659dab2SSebastian Reichel int serdev_device_set_tiocm(struct serdev_device *, int, int); 2056fe729c4SAndrey Smirnov void serdev_device_write_wakeup(struct serdev_device *); 20670d18804SJohan Hovold int serdev_device_write(struct serdev_device *, const unsigned char *, size_t, long); 207cd6484e1SRob Herring void serdev_device_write_flush(struct serdev_device *); 208cd6484e1SRob Herring int serdev_device_write_room(struct serdev_device *); 209cd6484e1SRob Herring 210cd6484e1SRob Herring /* 211cd6484e1SRob Herring * serdev device driver functions 212cd6484e1SRob Herring */ 213cd6484e1SRob Herring int __serdev_device_driver_register(struct serdev_device_driver *, struct module *); 214cd6484e1SRob Herring #define serdev_device_driver_register(sdrv) \ 215cd6484e1SRob Herring __serdev_device_driver_register(sdrv, THIS_MODULE) 216cd6484e1SRob Herring 217cd6484e1SRob Herring /** 218cd6484e1SRob Herring * serdev_device_driver_unregister() - unregister an serdev client driver 219cd6484e1SRob Herring * @sdrv: the driver to unregister 220cd6484e1SRob Herring */ 221cd6484e1SRob Herring static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv) 222cd6484e1SRob Herring { 223cd6484e1SRob Herring if (sdrv) 224cd6484e1SRob Herring driver_unregister(&sdrv->driver); 225cd6484e1SRob Herring } 226cd6484e1SRob Herring 227cd6484e1SRob Herring #define module_serdev_device_driver(__serdev_device_driver) \ 228cd6484e1SRob Herring module_driver(__serdev_device_driver, serdev_device_driver_register, \ 229cd6484e1SRob Herring serdev_device_driver_unregister) 230cd6484e1SRob Herring 231cd6484e1SRob Herring #else 232cd6484e1SRob Herring 233cd6484e1SRob Herring static inline int serdev_device_open(struct serdev_device *sdev) 234cd6484e1SRob Herring { 235cd6484e1SRob Herring return -ENODEV; 236cd6484e1SRob Herring } 237cd6484e1SRob Herring static inline void serdev_device_close(struct serdev_device *sdev) {} 238cd6484e1SRob Herring static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate) 239cd6484e1SRob Herring { 240cd6484e1SRob Herring return 0; 241cd6484e1SRob Herring } 242cd6484e1SRob Herring static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} 2436bdc00d0SStefan Wahren static inline int serdev_device_write_buf(struct serdev_device *serdev, 2446bdc00d0SStefan Wahren const unsigned char *buf, 2456bdc00d0SStefan Wahren size_t count) 2466bdc00d0SStefan Wahren { 2476bdc00d0SStefan Wahren return -ENODEV; 2486bdc00d0SStefan Wahren } 249b3f80c8fSSebastian Reichel static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {} 2505659dab2SSebastian Reichel static inline int serdev_device_get_tiocm(struct serdev_device *serdev) 2515659dab2SSebastian Reichel { 2525659dab2SSebastian Reichel return -ENOTSUPP; 2535659dab2SSebastian Reichel } 2545659dab2SSebastian Reichel static inline int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear) 2555659dab2SSebastian Reichel { 2565659dab2SSebastian Reichel return -ENOTSUPP; 2575659dab2SSebastian Reichel } 2586fe729c4SAndrey Smirnov static inline int serdev_device_write(struct serdev_device *sdev, const unsigned char *buf, 2596fe729c4SAndrey Smirnov size_t count, unsigned long timeout) 260cd6484e1SRob Herring { 261cd6484e1SRob Herring return -ENODEV; 262cd6484e1SRob Herring } 263cd6484e1SRob Herring static inline void serdev_device_write_flush(struct serdev_device *sdev) {} 264cd6484e1SRob Herring static inline int serdev_device_write_room(struct serdev_device *sdev) 265cd6484e1SRob Herring { 266cd6484e1SRob Herring return 0; 267cd6484e1SRob Herring } 268cd6484e1SRob Herring 269cd6484e1SRob Herring #define serdev_device_driver_register(x) 270cd6484e1SRob Herring #define serdev_device_driver_unregister(x) 271cd6484e1SRob Herring 272cd6484e1SRob Herring #endif /* CONFIG_SERIAL_DEV_BUS */ 273cd6484e1SRob Herring 274756db778SSebastian Reichel static inline bool serdev_device_get_cts(struct serdev_device *serdev) 275756db778SSebastian Reichel { 276756db778SSebastian Reichel int status = serdev_device_get_tiocm(serdev); 277756db778SSebastian Reichel return !!(status & TIOCM_CTS); 278756db778SSebastian Reichel } 279756db778SSebastian Reichel 280756db778SSebastian Reichel static inline int serdev_device_wait_for_cts(struct serdev_device *serdev, bool state, int timeout_ms) 281756db778SSebastian Reichel { 282756db778SSebastian Reichel unsigned long timeout; 283756db778SSebastian Reichel bool signal; 284756db778SSebastian Reichel 285756db778SSebastian Reichel timeout = jiffies + msecs_to_jiffies(timeout_ms); 286756db778SSebastian Reichel while (time_is_after_jiffies(timeout)) { 287756db778SSebastian Reichel signal = serdev_device_get_cts(serdev); 288756db778SSebastian Reichel if (signal == state) 289756db778SSebastian Reichel return 0; 290756db778SSebastian Reichel usleep_range(1000, 2000); 291756db778SSebastian Reichel } 292756db778SSebastian Reichel 293756db778SSebastian Reichel return -ETIMEDOUT; 294756db778SSebastian Reichel } 295756db778SSebastian Reichel 296756db778SSebastian Reichel static inline int serdev_device_set_rts(struct serdev_device *serdev, bool enable) 297756db778SSebastian Reichel { 298756db778SSebastian Reichel if (enable) 299756db778SSebastian Reichel return serdev_device_set_tiocm(serdev, TIOCM_RTS, 0); 300756db778SSebastian Reichel else 301756db778SSebastian Reichel return serdev_device_set_tiocm(serdev, 0, TIOCM_RTS); 302756db778SSebastian Reichel } 303756db778SSebastian Reichel 3043a19cfccSUlrich Hecht int serdev_device_set_parity(struct serdev_device *serdev, 3053a19cfccSUlrich Hecht enum serdev_parity parity); 3063a19cfccSUlrich Hecht 307bed35c6dSRob Herring /* 308bed35c6dSRob Herring * serdev hooks into TTY core 309bed35c6dSRob Herring */ 310bed35c6dSRob Herring struct tty_port; 311bed35c6dSRob Herring struct tty_driver; 312bed35c6dSRob Herring 313bed35c6dSRob Herring #ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT 314bed35c6dSRob Herring struct device *serdev_tty_port_register(struct tty_port *port, 315bed35c6dSRob Herring struct device *parent, 316bed35c6dSRob Herring struct tty_driver *drv, int idx); 3178cde11b2SJohan Hovold int serdev_tty_port_unregister(struct tty_port *port); 318bed35c6dSRob Herring #else 319bed35c6dSRob Herring static inline struct device *serdev_tty_port_register(struct tty_port *port, 320bed35c6dSRob Herring struct device *parent, 321bed35c6dSRob Herring struct tty_driver *drv, int idx) 322bed35c6dSRob Herring { 323bed35c6dSRob Herring return ERR_PTR(-ENODEV); 324bed35c6dSRob Herring } 3258cde11b2SJohan Hovold static inline int serdev_tty_port_unregister(struct tty_port *port) 3268cde11b2SJohan Hovold { 3278cde11b2SJohan Hovold return -ENODEV; 3288cde11b2SJohan Hovold } 329bed35c6dSRob Herring #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 330bed35c6dSRob Herring 3310a732d7dSAndy Shevchenko struct acpi_resource; 3320a732d7dSAndy Shevchenko struct acpi_resource_uart_serialbus; 3330a732d7dSAndy Shevchenko 3340a732d7dSAndy Shevchenko #ifdef CONFIG_ACPI 3350a732d7dSAndy Shevchenko bool serdev_acpi_get_uart_resource(struct acpi_resource *ares, 3360a732d7dSAndy Shevchenko struct acpi_resource_uart_serialbus **uart); 3370a732d7dSAndy Shevchenko #else 3380a732d7dSAndy Shevchenko static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares, 3390a732d7dSAndy Shevchenko struct acpi_resource_uart_serialbus **uart) 3400a732d7dSAndy Shevchenko { 3410a732d7dSAndy Shevchenko return false; 3420a732d7dSAndy Shevchenko } 3430a732d7dSAndy Shevchenko #endif /* CONFIG_ACPI */ 3440a732d7dSAndy Shevchenko 345cd6484e1SRob Herring #endif /*_LINUX_SERDEV_H */ 346