cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

serdev.h (10051B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org>
      4 */
      5#ifndef _LINUX_SERDEV_H
      6#define _LINUX_SERDEV_H
      7
      8#include <linux/types.h>
      9#include <linux/device.h>
     10#include <linux/termios.h>
     11#include <linux/delay.h>
     12
     13struct serdev_controller;
     14struct serdev_device;
     15
     16/*
     17 * serdev device structures
     18 */
     19
     20/**
     21 * struct serdev_device_ops - Callback operations for a serdev device
     22 * @receive_buf:	Function called with data received from device;
     23 *			returns number of bytes accepted; may sleep.
     24 * @write_wakeup:	Function called when ready to transmit more data; must
     25 *			not sleep.
     26 */
     27struct serdev_device_ops {
     28	int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t);
     29	void (*write_wakeup)(struct serdev_device *);
     30};
     31
     32/**
     33 * struct serdev_device - Basic representation of an serdev device
     34 * @dev:	Driver model representation of the device.
     35 * @nr:		Device number on serdev bus.
     36 * @ctrl:	serdev controller managing this device.
     37 * @ops:	Device operations.
     38 * @write_comp	Completion used by serdev_device_write() internally
     39 * @write_lock	Lock to serialize access when writing data
     40 */
     41struct serdev_device {
     42	struct device dev;
     43	int nr;
     44	struct serdev_controller *ctrl;
     45	const struct serdev_device_ops *ops;
     46	struct completion write_comp;
     47	struct mutex write_lock;
     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
     73enum serdev_parity {
     74	SERDEV_PARITY_NONE,
     75	SERDEV_PARITY_EVEN,
     76	SERDEV_PARITY_ODD,
     77};
     78
     79/*
     80 * serdev controller structures
     81 */
     82struct serdev_controller_ops {
     83	int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t);
     84	void (*write_flush)(struct serdev_controller *);
     85	int (*write_room)(struct serdev_controller *);
     86	int (*open)(struct serdev_controller *);
     87	void (*close)(struct serdev_controller *);
     88	void (*set_flow_control)(struct serdev_controller *, bool);
     89	int (*set_parity)(struct serdev_controller *, enum serdev_parity);
     90	unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int);
     91	void (*wait_until_sent)(struct serdev_controller *, long);
     92	int (*get_tiocm)(struct serdev_controller *);
     93	int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int);
     94};
     95
     96/**
     97 * struct serdev_controller - interface to the serdev controller
     98 * @dev:	Driver model representation of the device.
     99 * @nr:		number identifier for this controller/bus.
    100 * @serdev:	Pointer to slave device for this controller.
    101 * @ops:	Controller operations.
    102 */
    103struct serdev_controller {
    104	struct device		dev;
    105	unsigned int		nr;
    106	struct serdev_device	*serdev;
    107	const struct serdev_controller_ops *ops;
    108};
    109
    110static inline struct serdev_controller *to_serdev_controller(struct device *d)
    111{
    112	return container_of(d, struct serdev_controller, dev);
    113}
    114
    115static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev)
    116{
    117	return dev_get_drvdata(&serdev->dev);
    118}
    119
    120static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data)
    121{
    122	dev_set_drvdata(&serdev->dev, data);
    123}
    124
    125/**
    126 * serdev_device_put() - decrement serdev device refcount
    127 * @serdev	serdev device.
    128 */
    129static inline void serdev_device_put(struct serdev_device *serdev)
    130{
    131	if (serdev)
    132		put_device(&serdev->dev);
    133}
    134
    135static inline void serdev_device_set_client_ops(struct serdev_device *serdev,
    136					      const struct serdev_device_ops *ops)
    137{
    138	serdev->ops = ops;
    139}
    140
    141static inline
    142void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl)
    143{
    144	return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL;
    145}
    146
    147static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl,
    148					       void *data)
    149{
    150	dev_set_drvdata(&ctrl->dev, data);
    151}
    152
    153/**
    154 * serdev_controller_put() - decrement controller refcount
    155 * @ctrl	serdev controller.
    156 */
    157static inline void serdev_controller_put(struct serdev_controller *ctrl)
    158{
    159	if (ctrl)
    160		put_device(&ctrl->dev);
    161}
    162
    163struct serdev_device *serdev_device_alloc(struct serdev_controller *);
    164int serdev_device_add(struct serdev_device *);
    165void serdev_device_remove(struct serdev_device *);
    166
    167struct serdev_controller *serdev_controller_alloc(struct device *, size_t);
    168int serdev_controller_add(struct serdev_controller *);
    169void serdev_controller_remove(struct serdev_controller *);
    170
    171static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl)
    172{
    173	struct serdev_device *serdev = ctrl->serdev;
    174
    175	if (!serdev || !serdev->ops->write_wakeup)
    176		return;
    177
    178	serdev->ops->write_wakeup(serdev);
    179}
    180
    181static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl,
    182					      const unsigned char *data,
    183					      size_t count)
    184{
    185	struct serdev_device *serdev = ctrl->serdev;
    186
    187	if (!serdev || !serdev->ops->receive_buf)
    188		return 0;
    189
    190	return serdev->ops->receive_buf(serdev, data, count);
    191}
    192
    193#if IS_ENABLED(CONFIG_SERIAL_DEV_BUS)
    194
    195int serdev_device_open(struct serdev_device *);
    196void serdev_device_close(struct serdev_device *);
    197int devm_serdev_device_open(struct device *, struct serdev_device *);
    198unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
    199void serdev_device_set_flow_control(struct serdev_device *, bool);
    200int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
    201void serdev_device_wait_until_sent(struct serdev_device *, long);
    202int serdev_device_get_tiocm(struct serdev_device *);
    203int serdev_device_set_tiocm(struct serdev_device *, int, int);
    204void serdev_device_write_wakeup(struct serdev_device *);
    205int serdev_device_write(struct serdev_device *, const unsigned char *, size_t, long);
    206void serdev_device_write_flush(struct serdev_device *);
    207int serdev_device_write_room(struct serdev_device *);
    208
    209/*
    210 * serdev device driver functions
    211 */
    212int __serdev_device_driver_register(struct serdev_device_driver *, struct module *);
    213#define serdev_device_driver_register(sdrv) \
    214	__serdev_device_driver_register(sdrv, THIS_MODULE)
    215
    216/**
    217 * serdev_device_driver_unregister() - unregister an serdev client driver
    218 * @sdrv:	the driver to unregister
    219 */
    220static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv)
    221{
    222	if (sdrv)
    223		driver_unregister(&sdrv->driver);
    224}
    225
    226#define module_serdev_device_driver(__serdev_device_driver) \
    227	module_driver(__serdev_device_driver, serdev_device_driver_register, \
    228			serdev_device_driver_unregister)
    229
    230#else
    231
    232static inline int serdev_device_open(struct serdev_device *sdev)
    233{
    234	return -ENODEV;
    235}
    236static inline void serdev_device_close(struct serdev_device *sdev) {}
    237static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate)
    238{
    239	return 0;
    240}
    241static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {}
    242static inline int serdev_device_write_buf(struct serdev_device *serdev,
    243					  const unsigned char *buf,
    244					  size_t count)
    245{
    246	return -ENODEV;
    247}
    248static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {}
    249static inline int serdev_device_get_tiocm(struct serdev_device *serdev)
    250{
    251	return -ENOTSUPP;
    252}
    253static inline int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
    254{
    255	return -ENOTSUPP;
    256}
    257static inline int serdev_device_write(struct serdev_device *sdev, const unsigned char *buf,
    258				      size_t count, unsigned long timeout)
    259{
    260	return -ENODEV;
    261}
    262static inline void serdev_device_write_flush(struct serdev_device *sdev) {}
    263static inline int serdev_device_write_room(struct serdev_device *sdev)
    264{
    265	return 0;
    266}
    267
    268#define serdev_device_driver_register(x)
    269#define serdev_device_driver_unregister(x)
    270
    271#endif /* CONFIG_SERIAL_DEV_BUS */
    272
    273static inline bool serdev_device_get_cts(struct serdev_device *serdev)
    274{
    275	int status = serdev_device_get_tiocm(serdev);
    276	return !!(status & TIOCM_CTS);
    277}
    278
    279static inline int serdev_device_wait_for_cts(struct serdev_device *serdev, bool state, int timeout_ms)
    280{
    281	unsigned long timeout;
    282	bool signal;
    283
    284	timeout = jiffies + msecs_to_jiffies(timeout_ms);
    285	while (time_is_after_jiffies(timeout)) {
    286		signal = serdev_device_get_cts(serdev);
    287		if (signal == state)
    288			return 0;
    289		usleep_range(1000, 2000);
    290	}
    291
    292	return -ETIMEDOUT;
    293}
    294
    295static inline int serdev_device_set_rts(struct serdev_device *serdev, bool enable)
    296{
    297	if (enable)
    298		return serdev_device_set_tiocm(serdev, TIOCM_RTS, 0);
    299	else
    300		return serdev_device_set_tiocm(serdev, 0, TIOCM_RTS);
    301}
    302
    303int serdev_device_set_parity(struct serdev_device *serdev,
    304			     enum serdev_parity parity);
    305
    306/*
    307 * serdev hooks into TTY core
    308 */
    309struct tty_port;
    310struct tty_driver;
    311
    312#ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT
    313struct device *serdev_tty_port_register(struct tty_port *port,
    314					struct device *parent,
    315					struct tty_driver *drv, int idx);
    316int serdev_tty_port_unregister(struct tty_port *port);
    317#else
    318static inline struct device *serdev_tty_port_register(struct tty_port *port,
    319					   struct device *parent,
    320					   struct tty_driver *drv, int idx)
    321{
    322	return ERR_PTR(-ENODEV);
    323}
    324static inline int serdev_tty_port_unregister(struct tty_port *port)
    325{
    326	return -ENODEV;
    327}
    328#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
    329
    330struct acpi_resource;
    331struct acpi_resource_uart_serialbus;
    332
    333#ifdef CONFIG_ACPI
    334bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
    335				   struct acpi_resource_uart_serialbus **uart);
    336#else
    337static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
    338						 struct acpi_resource_uart_serialbus **uart)
    339{
    340	return false;
    341}
    342#endif /* CONFIG_ACPI */
    343
    344#endif /*_LINUX_SERDEV_H */