Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org>
0004  */
0005 #ifndef _LINUX_SERDEV_H
0006 #define _LINUX_SERDEV_H
0007 
0008 #include <linux/types.h>
0009 #include <linux/device.h>
0010 #include <linux/termios.h>
0011 #include <linux/delay.h>
0012 
0013 struct serdev_controller;
0014 struct serdev_device;
0015 
0016 /*
0017  * serdev device structures
0018  */
0019 
0020 /**
0021  * struct serdev_device_ops - Callback operations for a serdev device
0022  * @receive_buf:    Function called with data received from device;
0023  *          returns number of bytes accepted; may sleep.
0024  * @write_wakeup:   Function called when ready to transmit more data; must
0025  *          not sleep.
0026  */
0027 struct serdev_device_ops {
0028     int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t);
0029     void (*write_wakeup)(struct serdev_device *);
0030 };
0031 
0032 /**
0033  * struct serdev_device - Basic representation of an serdev device
0034  * @dev:    Driver model representation of the device.
0035  * @nr:     Device number on serdev bus.
0036  * @ctrl:   serdev controller managing this device.
0037  * @ops:    Device operations.
0038  * @write_comp  Completion used by serdev_device_write() internally
0039  * @write_lock  Lock to serialize access when writing data
0040  */
0041 struct serdev_device {
0042     struct device dev;
0043     int nr;
0044     struct serdev_controller *ctrl;
0045     const struct serdev_device_ops *ops;
0046     struct completion write_comp;
0047     struct mutex write_lock;
0048 };
0049 
0050 static inline struct serdev_device *to_serdev_device(struct device *d)
0051 {
0052     return container_of(d, struct serdev_device, dev);
0053 }
0054 
0055 /**
0056  * struct serdev_device_driver - serdev slave device driver
0057  * @driver: serdev device drivers should initialize name field of this
0058  *      structure.
0059  * @probe:  binds this driver to a serdev device.
0060  * @remove: unbinds this driver from the serdev device.
0061  */
0062 struct serdev_device_driver {
0063     struct device_driver driver;
0064     int (*probe)(struct serdev_device *);
0065     void    (*remove)(struct serdev_device *);
0066 };
0067 
0068 static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d)
0069 {
0070     return container_of(d, struct serdev_device_driver, driver);
0071 }
0072 
0073 enum serdev_parity {
0074     SERDEV_PARITY_NONE,
0075     SERDEV_PARITY_EVEN,
0076     SERDEV_PARITY_ODD,
0077 };
0078 
0079 /*
0080  * serdev controller structures
0081  */
0082 struct serdev_controller_ops {
0083     int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t);
0084     void (*write_flush)(struct serdev_controller *);
0085     int (*write_room)(struct serdev_controller *);
0086     int (*open)(struct serdev_controller *);
0087     void (*close)(struct serdev_controller *);
0088     void (*set_flow_control)(struct serdev_controller *, bool);
0089     int (*set_parity)(struct serdev_controller *, enum serdev_parity);
0090     unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int);
0091     void (*wait_until_sent)(struct serdev_controller *, long);
0092     int (*get_tiocm)(struct serdev_controller *);
0093     int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int);
0094 };
0095 
0096 /**
0097  * struct serdev_controller - interface to the serdev controller
0098  * @dev:    Driver model representation of the device.
0099  * @nr:     number identifier for this controller/bus.
0100  * @serdev: Pointer to slave device for this controller.
0101  * @ops:    Controller operations.
0102  */
0103 struct serdev_controller {
0104     struct device       dev;
0105     unsigned int        nr;
0106     struct serdev_device    *serdev;
0107     const struct serdev_controller_ops *ops;
0108 };
0109 
0110 static inline struct serdev_controller *to_serdev_controller(struct device *d)
0111 {
0112     return container_of(d, struct serdev_controller, dev);
0113 }
0114 
0115 static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev)
0116 {
0117     return dev_get_drvdata(&serdev->dev);
0118 }
0119 
0120 static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data)
0121 {
0122     dev_set_drvdata(&serdev->dev, data);
0123 }
0124 
0125 /**
0126  * serdev_device_put() - decrement serdev device refcount
0127  * @serdev  serdev device.
0128  */
0129 static inline void serdev_device_put(struct serdev_device *serdev)
0130 {
0131     if (serdev)
0132         put_device(&serdev->dev);
0133 }
0134 
0135 static inline void serdev_device_set_client_ops(struct serdev_device *serdev,
0136                           const struct serdev_device_ops *ops)
0137 {
0138     serdev->ops = ops;
0139 }
0140 
0141 static inline
0142 void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl)
0143 {
0144     return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL;
0145 }
0146 
0147 static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl,
0148                            void *data)
0149 {
0150     dev_set_drvdata(&ctrl->dev, data);
0151 }
0152 
0153 /**
0154  * serdev_controller_put() - decrement controller refcount
0155  * @ctrl    serdev controller.
0156  */
0157 static inline void serdev_controller_put(struct serdev_controller *ctrl)
0158 {
0159     if (ctrl)
0160         put_device(&ctrl->dev);
0161 }
0162 
0163 struct serdev_device *serdev_device_alloc(struct serdev_controller *);
0164 int serdev_device_add(struct serdev_device *);
0165 void serdev_device_remove(struct serdev_device *);
0166 
0167 struct serdev_controller *serdev_controller_alloc(struct device *, size_t);
0168 int serdev_controller_add(struct serdev_controller *);
0169 void serdev_controller_remove(struct serdev_controller *);
0170 
0171 static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl)
0172 {
0173     struct serdev_device *serdev = ctrl->serdev;
0174 
0175     if (!serdev || !serdev->ops->write_wakeup)
0176         return;
0177 
0178     serdev->ops->write_wakeup(serdev);
0179 }
0180 
0181 static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl,
0182                           const unsigned char *data,
0183                           size_t count)
0184 {
0185     struct serdev_device *serdev = ctrl->serdev;
0186 
0187     if (!serdev || !serdev->ops->receive_buf)
0188         return 0;
0189 
0190     return serdev->ops->receive_buf(serdev, data, count);
0191 }
0192 
0193 #if IS_ENABLED(CONFIG_SERIAL_DEV_BUS)
0194 
0195 int serdev_device_open(struct serdev_device *);
0196 void serdev_device_close(struct serdev_device *);
0197 int devm_serdev_device_open(struct device *, struct serdev_device *);
0198 unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
0199 void serdev_device_set_flow_control(struct serdev_device *, bool);
0200 int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
0201 void serdev_device_wait_until_sent(struct serdev_device *, long);
0202 int serdev_device_get_tiocm(struct serdev_device *);
0203 int serdev_device_set_tiocm(struct serdev_device *, int, int);
0204 void serdev_device_write_wakeup(struct serdev_device *);
0205 int serdev_device_write(struct serdev_device *, const unsigned char *, size_t, long);
0206 void serdev_device_write_flush(struct serdev_device *);
0207 int serdev_device_write_room(struct serdev_device *);
0208 
0209 /*
0210  * serdev device driver functions
0211  */
0212 int __serdev_device_driver_register(struct serdev_device_driver *, struct module *);
0213 #define serdev_device_driver_register(sdrv) \
0214     __serdev_device_driver_register(sdrv, THIS_MODULE)
0215 
0216 /**
0217  * serdev_device_driver_unregister() - unregister an serdev client driver
0218  * @sdrv:   the driver to unregister
0219  */
0220 static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv)
0221 {
0222     if (sdrv)
0223         driver_unregister(&sdrv->driver);
0224 }
0225 
0226 #define module_serdev_device_driver(__serdev_device_driver) \
0227     module_driver(__serdev_device_driver, serdev_device_driver_register, \
0228             serdev_device_driver_unregister)
0229 
0230 #else
0231 
0232 static inline int serdev_device_open(struct serdev_device *sdev)
0233 {
0234     return -ENODEV;
0235 }
0236 static inline void serdev_device_close(struct serdev_device *sdev) {}
0237 static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate)
0238 {
0239     return 0;
0240 }
0241 static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {}
0242 static inline int serdev_device_write_buf(struct serdev_device *serdev,
0243                       const unsigned char *buf,
0244                       size_t count)
0245 {
0246     return -ENODEV;
0247 }
0248 static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {}
0249 static inline int serdev_device_get_tiocm(struct serdev_device *serdev)
0250 {
0251     return -ENOTSUPP;
0252 }
0253 static inline int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
0254 {
0255     return -ENOTSUPP;
0256 }
0257 static inline int serdev_device_write(struct serdev_device *sdev, const unsigned char *buf,
0258                       size_t count, unsigned long timeout)
0259 {
0260     return -ENODEV;
0261 }
0262 static inline void serdev_device_write_flush(struct serdev_device *sdev) {}
0263 static inline int serdev_device_write_room(struct serdev_device *sdev)
0264 {
0265     return 0;
0266 }
0267 
0268 #define serdev_device_driver_register(x)
0269 #define serdev_device_driver_unregister(x)
0270 
0271 #endif /* CONFIG_SERIAL_DEV_BUS */
0272 
0273 static inline bool serdev_device_get_cts(struct serdev_device *serdev)
0274 {
0275     int status = serdev_device_get_tiocm(serdev);
0276     return !!(status & TIOCM_CTS);
0277 }
0278 
0279 static inline int serdev_device_wait_for_cts(struct serdev_device *serdev, bool state, int timeout_ms)
0280 {
0281     unsigned long timeout;
0282     bool signal;
0283 
0284     timeout = jiffies + msecs_to_jiffies(timeout_ms);
0285     while (time_is_after_jiffies(timeout)) {
0286         signal = serdev_device_get_cts(serdev);
0287         if (signal == state)
0288             return 0;
0289         usleep_range(1000, 2000);
0290     }
0291 
0292     return -ETIMEDOUT;
0293 }
0294 
0295 static inline int serdev_device_set_rts(struct serdev_device *serdev, bool enable)
0296 {
0297     if (enable)
0298         return serdev_device_set_tiocm(serdev, TIOCM_RTS, 0);
0299     else
0300         return serdev_device_set_tiocm(serdev, 0, TIOCM_RTS);
0301 }
0302 
0303 int serdev_device_set_parity(struct serdev_device *serdev,
0304                  enum serdev_parity parity);
0305 
0306 /*
0307  * serdev hooks into TTY core
0308  */
0309 struct tty_port;
0310 struct tty_driver;
0311 
0312 #ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT
0313 struct device *serdev_tty_port_register(struct tty_port *port,
0314                     struct device *parent,
0315                     struct tty_driver *drv, int idx);
0316 int serdev_tty_port_unregister(struct tty_port *port);
0317 #else
0318 static inline struct device *serdev_tty_port_register(struct tty_port *port,
0319                        struct device *parent,
0320                        struct tty_driver *drv, int idx)
0321 {
0322     return ERR_PTR(-ENODEV);
0323 }
0324 static inline int serdev_tty_port_unregister(struct tty_port *port)
0325 {
0326     return -ENODEV;
0327 }
0328 #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
0329 
0330 struct acpi_resource;
0331 struct acpi_resource_uart_serialbus;
0332 
0333 #ifdef CONFIG_ACPI
0334 bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
0335                    struct acpi_resource_uart_serialbus **uart);
0336 #else
0337 static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
0338                          struct acpi_resource_uart_serialbus **uart)
0339 {
0340     return false;
0341 }
0342 #endif /* CONFIG_ACPI */
0343 
0344 #endif /*_LINUX_SERDEV_H */