162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * IBM PowerPC Virtual I/O Infrastructure Support.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2003 IBM Corp.
662306a36Sopenharmony_ci *  Dave Engebretsen engebret@us.ibm.com
762306a36Sopenharmony_ci *  Santiago Leon santil@us.ibm.com
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef _ASM_POWERPC_VIO_H
1162306a36Sopenharmony_ci#define _ASM_POWERPC_VIO_H
1262306a36Sopenharmony_ci#ifdef __KERNEL__
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/errno.h>
1562306a36Sopenharmony_ci#include <linux/device.h>
1662306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1762306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
1862306a36Sopenharmony_ci#include <linux/scatterlist.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <asm/hvcall.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * Architecture-specific constants for drivers to
2462306a36Sopenharmony_ci * extract attributes of the device using vio_get_attribute()
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci#define VETH_MAC_ADDR "local-mac-address"
2762306a36Sopenharmony_ci#define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* End architecture-specific constants */
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define h_vio_signal(ua, mode) \
3262306a36Sopenharmony_ci  plpar_hcall_norets(H_VIO_SIGNAL, ua, mode)
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define VIO_IRQ_DISABLE		0UL
3562306a36Sopenharmony_ci#define VIO_IRQ_ENABLE		1UL
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/*
3862306a36Sopenharmony_ci * VIO CMO minimum entitlement for all devices and spare entitlement
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_ci#define VIO_CMO_MIN_ENT 1562624
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ciextern struct bus_type vio_bus_type;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistruct iommu_table;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/*
4762306a36Sopenharmony_ci * Platform Facilities Option (PFO)-specific data
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/* Starting unit address for PFO devices on the VIO BUS */
5162306a36Sopenharmony_ci#define VIO_BASE_PFO_UA	0x50000000
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/**
5462306a36Sopenharmony_ci * vio_pfo_op - PFO operation parameters
5562306a36Sopenharmony_ci *
5662306a36Sopenharmony_ci * @flags: h_call subfunctions and modifiers
5762306a36Sopenharmony_ci * @in: Input data block logical real address
5862306a36Sopenharmony_ci * @inlen: If non-negative, the length of the input data block.  If negative,
5962306a36Sopenharmony_ci *	the length of the input data descriptor list in bytes.
6062306a36Sopenharmony_ci * @out: Output data block logical real address
6162306a36Sopenharmony_ci * @outlen: If non-negative, the length of the input data block.  If negative,
6262306a36Sopenharmony_ci *	the length of the input data descriptor list in bytes.
6362306a36Sopenharmony_ci * @csbcpb: Logical real address of the 4k naturally-aligned storage block
6462306a36Sopenharmony_ci *	containing the CSB & optional FC field specific CPB
6562306a36Sopenharmony_ci * @timeout: # of milliseconds to retry h_call, 0 for no timeout.
6662306a36Sopenharmony_ci * @hcall_err: pointer to return the h_call return value, else NULL
6762306a36Sopenharmony_ci */
6862306a36Sopenharmony_cistruct vio_pfo_op {
6962306a36Sopenharmony_ci	u64 flags;
7062306a36Sopenharmony_ci	s64 in;
7162306a36Sopenharmony_ci	s64 inlen;
7262306a36Sopenharmony_ci	s64 out;
7362306a36Sopenharmony_ci	s64 outlen;
7462306a36Sopenharmony_ci	u64 csbcpb;
7562306a36Sopenharmony_ci	void *done;
7662306a36Sopenharmony_ci	unsigned long handle;
7762306a36Sopenharmony_ci	unsigned int timeout;
7862306a36Sopenharmony_ci	long hcall_err;
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/* End PFO specific data */
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cienum vio_dev_family {
8462306a36Sopenharmony_ci	VDEVICE,	/* The OF node is a child of /vdevice */
8562306a36Sopenharmony_ci	PFO,		/* The OF node is a child of /ibm,platform-facilities */
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/**
8962306a36Sopenharmony_ci * vio_dev - This structure is used to describe virtual I/O devices.
9062306a36Sopenharmony_ci *
9162306a36Sopenharmony_ci * @desired: set from return of driver's get_desired_dma() function
9262306a36Sopenharmony_ci * @entitled: bytes of IO data that has been reserved for this device.
9362306a36Sopenharmony_ci * @allocated: bytes of IO data currently in use by the device.
9462306a36Sopenharmony_ci * @allocs_failed: number of DMA failures due to insufficient entitlement.
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_cistruct vio_dev {
9762306a36Sopenharmony_ci	const char *name;
9862306a36Sopenharmony_ci	const char *type;
9962306a36Sopenharmony_ci	uint32_t unit_address;
10062306a36Sopenharmony_ci	uint32_t resource_id;
10162306a36Sopenharmony_ci	unsigned int irq;
10262306a36Sopenharmony_ci	struct {
10362306a36Sopenharmony_ci		size_t desired;
10462306a36Sopenharmony_ci		size_t entitled;
10562306a36Sopenharmony_ci		size_t allocated;
10662306a36Sopenharmony_ci		atomic_t allocs_failed;
10762306a36Sopenharmony_ci	} cmo;
10862306a36Sopenharmony_ci	enum vio_dev_family family;
10962306a36Sopenharmony_ci	struct device dev;
11062306a36Sopenharmony_ci};
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistruct vio_driver {
11362306a36Sopenharmony_ci	const char *name;
11462306a36Sopenharmony_ci	const struct vio_device_id *id_table;
11562306a36Sopenharmony_ci	int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
11662306a36Sopenharmony_ci	void (*remove)(struct vio_dev *dev);
11762306a36Sopenharmony_ci	void (*shutdown)(struct vio_dev *dev);
11862306a36Sopenharmony_ci	/* A driver must have a get_desired_dma() function to
11962306a36Sopenharmony_ci	 * be loaded in a CMO environment if it uses DMA.
12062306a36Sopenharmony_ci	 */
12162306a36Sopenharmony_ci	unsigned long (*get_desired_dma)(struct vio_dev *dev);
12262306a36Sopenharmony_ci	const struct dev_pm_ops *pm;
12362306a36Sopenharmony_ci	struct device_driver driver;
12462306a36Sopenharmony_ci};
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ciextern int __vio_register_driver(struct vio_driver *drv, struct module *owner,
12762306a36Sopenharmony_ci				 const char *mod_name);
12862306a36Sopenharmony_ci/*
12962306a36Sopenharmony_ci * vio_register_driver must be a macro so that KBUILD_MODNAME can be expanded
13062306a36Sopenharmony_ci */
13162306a36Sopenharmony_ci#define vio_register_driver(driver)		\
13262306a36Sopenharmony_ci	__vio_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
13362306a36Sopenharmony_ciextern void vio_unregister_driver(struct vio_driver *drv);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ciextern int vio_cmo_entitlement_update(size_t);
13662306a36Sopenharmony_ciextern void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired);
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ciextern void vio_unregister_device(struct vio_dev *dev);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ciextern int vio_h_cop_sync(struct vio_dev *vdev, struct vio_pfo_op *op);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistruct device_node;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ciextern struct vio_dev *vio_register_device_node(
14562306a36Sopenharmony_ci		struct device_node *node_vdev);
14662306a36Sopenharmony_ciextern const void *vio_get_attribute(struct vio_dev *vdev, char *which,
14762306a36Sopenharmony_ci		int *length);
14862306a36Sopenharmony_ci#ifdef CONFIG_PPC_PSERIES
14962306a36Sopenharmony_ciextern struct vio_dev *vio_find_node(struct device_node *vnode);
15062306a36Sopenharmony_ciextern int vio_enable_interrupts(struct vio_dev *dev);
15162306a36Sopenharmony_ciextern int vio_disable_interrupts(struct vio_dev *dev);
15262306a36Sopenharmony_ci#else
15362306a36Sopenharmony_cistatic inline int vio_enable_interrupts(struct vio_dev *dev)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	return 0;
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci#endif
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_cistatic inline struct vio_driver *to_vio_driver(struct device_driver *drv)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	return container_of(drv, struct vio_driver, driver);
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#define to_vio_dev(__dev)	container_of_const(__dev, struct vio_dev, dev)
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci#endif /* __KERNEL__ */
16762306a36Sopenharmony_ci#endif /* _ASM_POWERPC_VIO_H */
168