linux/drivers/tty/serdev/core.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <[email protected]>
 *
 * Based on drivers/spmi/spmi.c:
 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 */

#include <linux/acpi.h>
#include <linux/errno.h>
#include <linux/idr.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/sched.h>
#include <linux/serdev.h>
#include <linux/slab.h>

#include <linux/platform_data/x86/apple.h>

static bool is_registered;
static DEFINE_IDA(ctrl_ida);

static ssize_t modalias_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(modalias);

static struct attribute *serdev_device_attrs[] =;
ATTRIBUTE_GROUPS();

static int serdev_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
{}

static void serdev_device_release(struct device *dev)
{}

static const struct device_type serdev_device_type =;

static bool is_serdev_device(const struct device *dev)
{}

static void serdev_ctrl_release(struct device *dev)
{}

static const struct device_type serdev_ctrl_type =;

static int serdev_device_match(struct device *dev, const struct device_driver *drv)
{}

/**
 * serdev_device_add() - add a device previously constructed via serdev_device_alloc()
 * @serdev:	serdev_device to be added
 */
int serdev_device_add(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * serdev_device_remove(): remove an serdev device
 * @serdev:	serdev_device to be removed
 */
void serdev_device_remove(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

int serdev_device_open(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

void serdev_device_close(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

static void devm_serdev_device_close(void *serdev)
{}

int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

void serdev_device_write_wakeup(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * serdev_device_write_buf() - write data asynchronously
 * @serdev:	serdev device
 * @buf:	data to be written
 * @count:	number of bytes to write
 *
 * Write data to the device asynchronously.
 *
 * Note that any accepted data has only been buffered by the controller; use
 * serdev_device_wait_until_sent() to make sure the controller write buffer
 * has actually been emptied.
 *
 * Return: The number of bytes written (less than count if not enough room in
 * the write buffer), or a negative errno on errors.
 */
int serdev_device_write_buf(struct serdev_device *serdev, const u8 *buf, size_t count)
{}
EXPORT_SYMBOL_GPL();

/**
 * serdev_device_write() - write data synchronously
 * @serdev:	serdev device
 * @buf:	data to be written
 * @count:	number of bytes to write
 * @timeout:	timeout in jiffies, or 0 to wait indefinitely
 *
 * Write data to the device synchronously by repeatedly calling
 * serdev_device_write() until the controller has accepted all data (unless
 * interrupted by a timeout or a signal).
 *
 * Note that any accepted data has only been buffered by the controller; use
 * serdev_device_wait_until_sent() to make sure the controller write buffer
 * has actually been emptied.
 *
 * Note that this function depends on serdev_device_write_wakeup() being
 * called in the serdev driver write_wakeup() callback.
 *
 * Return: The number of bytes written (less than count if interrupted),
 * -ETIMEDOUT or -ERESTARTSYS if interrupted before any bytes were written, or
 * a negative errno on errors.
 */
ssize_t serdev_device_write(struct serdev_device *serdev, const u8 *buf,
			    size_t count, long timeout)
{}
EXPORT_SYMBOL_GPL();

void serdev_device_write_flush(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

int serdev_device_write_room(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

unsigned int serdev_device_set_baudrate(struct serdev_device *serdev, unsigned int speed)
{}
EXPORT_SYMBOL_GPL();

void serdev_device_set_flow_control(struct serdev_device *serdev, bool enable)
{}
EXPORT_SYMBOL_GPL();

int serdev_device_set_parity(struct serdev_device *serdev,
			     enum serdev_parity parity)
{}
EXPORT_SYMBOL_GPL();

void serdev_device_wait_until_sent(struct serdev_device *serdev, long timeout)
{}
EXPORT_SYMBOL_GPL();

int serdev_device_get_tiocm(struct serdev_device *serdev)
{}
EXPORT_SYMBOL_GPL();

int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
{}
EXPORT_SYMBOL_GPL();

int serdev_device_break_ctl(struct serdev_device *serdev, int break_state)
{}
EXPORT_SYMBOL_GPL();

static int serdev_drv_probe(struct device *dev)
{}

static void serdev_drv_remove(struct device *dev)
{}

static const struct bus_type serdev_bus_type =;

/**
 * serdev_device_alloc() - Allocate a new serdev device
 * @ctrl:	associated controller
 *
 * Caller is responsible for either calling serdev_device_add() to add the
 * newly allocated controller, or calling serdev_device_put() to discard it.
 */
struct serdev_device *serdev_device_alloc(struct serdev_controller *ctrl)
{}
EXPORT_SYMBOL_GPL();

/**
 * serdev_controller_alloc() - Allocate a new serdev controller
 * @host:	serial port hardware controller device
 * @parent:	parent device
 * @size:	size of private data
 *
 * Caller is responsible for either calling serdev_controller_add() to add the
 * newly allocated controller, or calling serdev_controller_put() to discard it.
 * The allocated private data region may be accessed via
 * serdev_controller_get_drvdata()
 */
struct serdev_controller *serdev_controller_alloc(struct device *host,
						  struct device *parent,
						  size_t size)
{}
EXPORT_SYMBOL_GPL();

static int of_serdev_register_devices(struct serdev_controller *ctrl)
{}

#ifdef CONFIG_ACPI

#define SERDEV_ACPI_MAX_SCAN_DEPTH

struct acpi_serdev_lookup {};

/**
 * serdev_acpi_get_uart_resource - Gets UARTSerialBus resource if type matches
 * @ares:	ACPI resource
 * @uart:	Pointer to UARTSerialBus resource will be returned here
 *
 * Checks if the given ACPI resource is of type UARTSerialBus.
 * In this case, returns a pointer to it to the caller.
 *
 * Return: True if resource type is of UARTSerialBus, otherwise false.
 */
bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
				   struct acpi_resource_uart_serialbus **uart)
{}
EXPORT_SYMBOL_GPL();

static int acpi_serdev_parse_resource(struct acpi_resource *ares, void *data)
{}

static int acpi_serdev_do_lookup(struct acpi_device *adev,
                                 struct acpi_serdev_lookup *lookup)
{}

static int acpi_serdev_check_resources(struct serdev_controller *ctrl,
				       struct acpi_device *adev)
{}

static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
					       struct acpi_device *adev)
{}

static const struct acpi_device_id serdev_acpi_devices_blacklist[] =;

static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level,
					  void *data, void **return_value)
{}


static int acpi_serdev_register_devices(struct serdev_controller *ctrl)
{}
#else
static inline int acpi_serdev_register_devices(struct serdev_controller *ctrl)
{
	return -ENODEV;
}
#endif /* CONFIG_ACPI */

/**
 * serdev_controller_add() - Add an serdev controller
 * @ctrl:	controller to be registered.
 *
 * Register a controller previously allocated via serdev_controller_alloc() with
 * the serdev core.
 */
int serdev_controller_add(struct serdev_controller *ctrl)
{
	int ret_of, ret_acpi, ret;

	/* Can't register until after driver model init */
	if (WARN_ON(!is_registered))
		return -EAGAIN;

	ret = device_add(&ctrl->dev);
	if (ret)
		return ret;

	pm_runtime_enable(&ctrl->dev);

	ret_of = of_serdev_register_devices(ctrl);
	ret_acpi = acpi_serdev_register_devices(ctrl);
	if (ret_of && ret_acpi) {
		dev_dbg(&ctrl->dev, "no devices registered: of:%pe acpi:%pe\n",
			ERR_PTR(ret_of), ERR_PTR(ret_acpi));
		ret = -ENODEV;
		goto err_rpm_disable;
	}

	dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n",
		ctrl->nr, &ctrl->dev);
	return 0;

err_rpm_disable:
	pm_runtime_disable(&ctrl->dev);
	device_del(&ctrl->dev);
	return ret;
};
EXPORT_SYMBOL_GPL();

/* Remove a device associated with a controller */
static int serdev_remove_device(struct device *dev, void *data)
{}

/**
 * serdev_controller_remove(): remove an serdev controller
 * @ctrl:	controller to remove
 *
 * Remove a serdev controller.  Caller is responsible for calling
 * serdev_controller_put() to discard the allocated controller.
 */
void serdev_controller_remove(struct serdev_controller *ctrl)
{}
EXPORT_SYMBOL_GPL();

/**
 * __serdev_device_driver_register() - Register client driver with serdev core
 * @sdrv:	client driver to be associated with client-device.
 * @owner:	client driver owner to set.
 *
 * This API will register the client driver with the serdev framework.
 * It is typically called from the driver's module-init function.
 */
int __serdev_device_driver_register(struct serdev_device_driver *sdrv, struct module *owner)
{}
EXPORT_SYMBOL_GPL();

static void __exit serdev_exit(void)
{}
module_exit(serdev_exit);

static int __init serdev_init(void)
{}
/* Must be before serial drivers register */
postcore_initcall(serdev_init);

MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_DESCRIPTION();