linux/drivers/bus/hisi_lpc.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017 Hisilicon Limited, All Rights Reserved.
 * Author: Zhichang Yuan <[email protected]>
 * Author: Zou Rongrong <[email protected]>
 * Author: John Garry <[email protected]>
 */

#include <linux/acpi.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/logic_pio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>

#define DRV_NAME

/*
 * Setting this bit means each IO operation will target a different port
 * address; 0 means repeated IO operations will use the same port,
 * such as BT.
 */
#define FG_INCRADDR_LPC

struct lpc_cycle_para {};

struct hisi_lpc_dev {};

/* The max IO cycle counts supported is four per operation at maximum */
#define LPC_MAX_DWIDTH

#define LPC_REG_STARTUP_SIGNAL
#define LPC_REG_STARTUP_SIGNAL_START
#define LPC_REG_OP_STATUS
#define LPC_REG_OP_STATUS_IDLE
#define LPC_REG_OP_STATUS_FINISHED
#define LPC_REG_OP_LEN
#define LPC_REG_CMD
#define LPC_REG_CMD_OP
#define LPC_REG_CMD_SAMEADDR
#define LPC_REG_ADDR
#define LPC_REG_WDATA
#define LPC_REG_RDATA

/* The minimal nanosecond interval for each query on LPC cycle status */
#define LPC_NSEC_PERWAIT

/*
 * The maximum waiting time is about 128us.  It is specific for stream I/O,
 * such as ins.
 *
 * The fastest IO cycle time is about 390ns, but the worst case will wait
 * for extra 256 lpc clocks, so (256 + 13) * 30ns = 8 us. The maximum burst
 * cycles is 16. So, the maximum waiting time is about 128us under worst
 * case.
 *
 * Choose 1300 as the maximum.
 */
#define LPC_MAX_WAITCNT

/* About 10us. This is specific for single IO operations, such as inb */
#define LPC_PEROP_WAITCNT

static int wait_lpc_idle(void __iomem *mbase, unsigned int waitcnt)
{}

/*
 * hisi_lpc_target_in - trigger a series of LPC cycles for read operation
 * @lpcdev: pointer to hisi lpc device
 * @para: some parameters used to control the lpc I/O operations
 * @addr: the lpc I/O target port address
 * @buf: where the read back data is stored
 * @opcnt: how many I/O operations required, i.e. data width
 *
 * Returns 0 on success, non-zero on fail.
 */
static int hisi_lpc_target_in(struct hisi_lpc_dev *lpcdev,
			      struct lpc_cycle_para *para, unsigned long addr,
			      unsigned char *buf, unsigned long opcnt)
{}

/*
 * hisi_lpc_target_out - trigger a series of LPC cycles for write operation
 * @lpcdev: pointer to hisi lpc device
 * @para: some parameters used to control the lpc I/O operations
 * @addr: the lpc I/O target port address
 * @buf: where the data to be written is stored
 * @opcnt: how many I/O operations required, i.e. data width
 *
 * Returns 0 on success, non-zero on fail.
 */
static int hisi_lpc_target_out(struct hisi_lpc_dev *lpcdev,
			       struct lpc_cycle_para *para, unsigned long addr,
			       const unsigned char *buf, unsigned long opcnt)
{}

static unsigned long hisi_lpc_pio_to_addr(struct hisi_lpc_dev *lpcdev,
					  unsigned long pio)
{}

/*
 * hisi_lpc_comm_in - input the data in a single operation
 * @hostdata: pointer to the device information relevant to LPC controller
 * @pio: the target I/O port address
 * @dwidth: the data length required to read from the target I/O port
 *
 * When success, data is returned. Otherwise, ~0 is returned.
 */
static u32 hisi_lpc_comm_in(void *hostdata, unsigned long pio, size_t dwidth)
{}

/*
 * hisi_lpc_comm_out - output the data in a single operation
 * @hostdata: pointer to the device information relevant to LPC controller
 * @pio: the target I/O port address
 * @val: a value to be output from caller, maximum is four bytes
 * @dwidth: the data width required writing to the target I/O port
 *
 * This function corresponds to out(b,w,l) only.
 */
static void hisi_lpc_comm_out(void *hostdata, unsigned long pio,
			      u32 val, size_t dwidth)
{}

/*
 * hisi_lpc_comm_ins - input the data in the buffer in multiple operations
 * @hostdata: pointer to the device information relevant to LPC controller
 * @pio: the target I/O port address
 * @buffer: a buffer where read/input data bytes are stored
 * @dwidth: the data width required writing to the target I/O port
 * @count: how many data units whose length is dwidth will be read
 *
 * When success, the data read back is stored in buffer pointed by buffer.
 * Returns 0 on success, -errno otherwise.
 */
static u32 hisi_lpc_comm_ins(void *hostdata, unsigned long pio, void *buffer,
			     size_t dwidth, unsigned int count)
{}

/*
 * hisi_lpc_comm_outs - output the data in the buffer in multiple operations
 * @hostdata: pointer to the device information relevant to LPC controller
 * @pio: the target I/O port address
 * @buffer: a buffer where write/output data bytes are stored
 * @dwidth: the data width required writing to the target I/O port
 * @count: how many data units whose length is dwidth will be written
 */
static void hisi_lpc_comm_outs(void *hostdata, unsigned long pio,
			       const void *buffer, size_t dwidth,
			       unsigned int count)
{}

static const struct logic_pio_host_ops hisi_lpc_ops =;

#ifdef CONFIG_ACPI
static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
				     struct acpi_device *host,
				     struct resource *res)
{}

/*
 * Released firmware describes the IO port max address as 0x3fff, which is
 * the max host bus address. Fixup to a proper range. This will probably
 * never be fixed in firmware.
 */
static void hisi_lpc_acpi_fixup_child_resource(struct device *hostdev,
					       struct resource *r)
{}

/*
 * hisi_lpc_acpi_set_io_res - set the resources for a child
 * @adev: ACPI companion of the device node to be updated the I/O resource
 * @hostdev: the device node associated with host controller
 * @res: double pointer to be set to the address of translated resources
 * @num_res: pointer to variable to hold the number of translated resources
 *
 * Returns 0 when successful, and a negative value for failure.
 *
 * For a given host controller, each child device will have an associated
 * host-relative address resource.  This function will return the translated
 * logical PIO addresses for each child devices resources.
 */
static int hisi_lpc_acpi_set_io_res(struct acpi_device *adev,
				    struct device *hostdev,
				    const struct resource **res, int *num_res)
{}

static int hisi_lpc_acpi_remove_subdev(struct device *dev, void *unused)
{}

static int hisi_lpc_acpi_clear_enumerated(struct acpi_device *adev, void *not_used)
{}

struct hisi_lpc_acpi_cell {};

static void hisi_lpc_acpi_remove(struct device *hostdev)
{}

static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data)
{}

/*
 * hisi_lpc_acpi_probe - probe children for ACPI FW
 * @hostdev: LPC host device pointer
 *
 * Returns 0 when successful, and a negative value for failure.
 *
 * Create a platform device per child, fixing up the resources
 * from bus addresses to Logical PIO addresses.
 *
 */
static int hisi_lpc_acpi_probe(struct device *hostdev)
{}
#else
static int hisi_lpc_acpi_probe(struct device *dev)
{
	return -ENODEV;
}

static void hisi_lpc_acpi_remove(struct device *hostdev)
{
}
#endif // CONFIG_ACPI

/*
 * hisi_lpc_probe - the probe callback function for hisi lpc host,
 *		   will finish all the initialization.
 * @pdev: the platform device corresponding to hisi lpc host
 *
 * Returns 0 on success, non-zero on fail.
 */
static int hisi_lpc_probe(struct platform_device *pdev)
{}

static void hisi_lpc_remove(struct platform_device *pdev)
{}

static const struct of_device_id hisi_lpc_of_match[] =;

static const struct acpi_device_id hisi_lpc_acpi_match[] =;

static struct platform_driver hisi_lpc_driver =;
builtin_platform_driver();