0
  +   ˆl–Ü4ý( ©³( 	Å€fàB¦-ÿÁ„¿_†I|¥�+ÁÀ (R    /* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org>
 */
#ifndef _LINUX_SERDEV_H
#define _LINUX_SERDEV_H

#include <linux/types.h>
#include <linux/device.h>
#include <linux/termios.h>
#include <linux/delay.h>

struct serdev_controller;
struct serdev_device;

/*
 * serdev device structures
 */

/**
 * struct serdev_device_ops - Callback operations for a serdev device
 * @receive_buf:	Function called with data received from device;
 *			returns number of bytes accepted; may sleep.
 * @write_wakeup:	Function called when ready to transmit more data; must
 *			not sleep.
 */
struct serdev_device_ops {
	int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t);
	void (*write_wakeup)(struct serdev_device *);
};

/**
 * struct serdev_device - Basic representation of an serdev device
 * @dev:	Driver model representation of the device.
 * @nr:		Device number on serdev bus.
 * @ctrl:	serdev controller managing this device.
 * @ops:	Device operations.
 * @write_comp	Completion used by serdev_device_write() internally
 * @write_lock	Lock to serialize access when writing data
 */
struct serdev_device {
	struct device dev;
	int nr;
	struct serdev_controller *ctrl;
	const struct serdev_device_ops *ops;
	struct completion write_comp;
	struct mutex write_lock;
};

static inline struct serdev_device *to_serdev_device(struct device *d)
{
	return container_of(d, struct serdev_device, dev);
}

/**
 * struct serdev_device_driver - serdev slave device driver
 * @driver:	serdev device drivers should initialize name field of this
 *		structure.
 * @probe:	binds this driver to a serdev device.
 * @remove:	unbinds this driver from the serdev device.
 */
struct serdev_device_driver {
	struct device_driver driver;
	int	(*probe)(struct serdev_device *);
	void	(*remove)(struct serdev_device *);
};

static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d)
{
	return container_of(d, struct serdev_device_driver, driver);
}

enum serdev_parity {
	SERDEV_PARITY_NONE,
	SERDEV_PARITY_EVEN,
	SERDEV_PARITY_ODD,
};

/*
 * serdev controller structures
 */
struct serdev_controller_ops {
	int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t);
	void (*write_flush)(struct serdev_controller *);
	int (*write_room)(struct serdev_controller *);
	int (*open)(struct serdev_controller *);
	void (*close)(struct serdev_controller *);
	void (*set_flow_control)(struct serdev_controller *, bool);
	int (*set_parity)(struct serdev_controller *, enum serdev_parity);
	unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int);
	void (*wait_until_sent)(struct serdev_controller *, long);
	int (*get_tiocm)(struct serdev_controller *);
	int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int);
	int (*break_ctl)(struct serdev_controller *ctrl, unsigned int break_state);
};

/**
 * struct serdev_controller - interface to the serdev controller
 * @dev:	Driver model representation of the device.
 * @nr:		number identifier for this controller/bus.
 * @serdev:	Pointer to slave device for this controller.
 * @ops:	Controller operations.
 */
struct serdev_controller {
	struct device		dev;
	unsigned int		nr;
	struct serdev_device	*serdev;
	const struct serdev_controller_ops *ops;
};

static inline struct serdev_controller *to_serdev_controller(struct device *d)
{
	return container_of(d, struct serdev_controller, dev);
}

static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev)
{
	return dev_get_drvdata(&serdev->dev);
}

static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data)
{
	dev_set_drvdata(&serdev->dev, data);
}

/**
 * serdev_device_put() - decrement serdev device refcount
 * @serdev	serdev device.
 */
static inline void serdev_device_put(struct serdev_device *serdev)
{
	if (serdev)
		put_device(&serdev->dev);
}

static inline void serdev_device_set_client_ops(struct serdev_device *serdev,
					      const struct