aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/include/asm/vio.h
blob: 68d0cc998b1baa5cee49b2a735f394354819492c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
 * IBM PowerPC Virtual I/O Infrastructure Support.
 *
 * Copyright (c) 2003 IBM Corp.
 *  Dave Engebretsen engebret@us.ibm.com
 *  Santiago Leon santil@us.ibm.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#ifndef _ASM_POWERPC_VIO_H
#define _ASM_POWERPC_VIO_H
#ifdef __KERNEL__

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/mod_devicetable.h>

#include <asm/hvcall.h>
#include <asm/scatterlist.h>

/*
 * Architecture-specific constants for drivers to
 * extract attributes of the device using vio_get_attribute()
 */
#define VETH_MAC_ADDR "local-mac-address"
#define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters"

/* End architecture-specific constants */

#define h_vio_signal(ua, mode) \
  plpar_hcall_norets(H_VIO_SIGNAL, ua, mode)

#define VIO_IRQ_DISABLE		0UL
#define VIO_IRQ_ENABLE		1UL

/*
 * VIO CMO minimum entitlement for all devices and spare entitlement
 */
#define VIO_CMO_MIN_ENT 1562624

extern struct bus_type vio_bus_type;

struct iommu_table;

/*
 * Platform Facilities Option (PFO)-specific data
 */

/* Starting unit address for PFO devices on the VIO BUS */
#define VIO_BASE_PFO_UA	0x50000000

/**
 * vio_pfo_op - PFO operation parameters
 *
 * @flags: h_call subfunctions and modifiers
 * @in: Input data block logical real address
 * @inlen: If non-negative, the length of the input data block.  If negative,
 *	the length of the input data descriptor list in bytes.
 * @out: Output data block logical real address
 * @outlen: If non-negative, the length of the input data block.  If negative,
 *	the length of the input data descriptor list in bytes.
 * @csbcpb: Logical real address of the 4k naturally-aligned storage block
 *	containing the CSB & optional FC field specific CPB
 * @timeout: # of milliseconds to retry h_call, 0 for no timeout.
 * @hcall_err: pointer to return the h_call return value, else NULL
 */
struct vio_pfo_op {
	u64 flags;
	s64 in;
	s64 inlen;
	s64 out;
	s64 outlen;
	u64 csbcpb;
	void *done;
	unsigned long handle;
	unsigned int timeout;
	long hcall_err;
};

/* End PFO specific data */

enum vio_dev_family {
	VDEVICE,	/* The OF node is a child of /vdevice */
	PFO,		/* The OF node is a child of /ibm,platform-facilities */
};

/**
 * vio_dev - This structure is used to describe virtual I/O devices.
 *
 * @desired: set from return of driver's get_desired_dma() function
 * @entitled: bytes of IO data that has been reserved for this device.
 * @allocated: bytes of IO data currently in use by the device.
 * @allocs_failed: number of DMA failures due to insufficient entitlement.
 */
struct vio_dev {
	const char *name;
	const char *type;
	uint32_t unit_address;
	uint32_t resource_id;
	unsigned int irq;
	struct {
		size_t desired;
		size_t entitled;
		size_t allocated;
		atomic_t allocs_failed;
	} cmo;
	enum vio_dev_family family;
	struct device dev;
};

struct vio_driver {
	const char *name;
	const struct vio_device_id *id_table;
	int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
	int (*remove)(struct vio_dev *dev);
	/* A driver must have a get_desired_dma() function to
	 * be loaded in a CMO environment if it uses DMA.
	 */
	unsigned long (*get_desired_dma)(struct vio_dev *dev);
	const struct dev_pm_ops *pm;
	struct device_driver driver;
};

extern int __vio_register_driver(struct vio_driver *drv, struct module *owner,
				 const char *mod_name);
/*
 * vio_register_driver must be a macro so that KBUILD_MODNAME can be expanded
 */
#define vio_register_driver(driver)		\
	__vio_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
extern void vio_unregister_driver(struct vio_driver *drv);

extern int vio_cmo_entitlement_update(size_t);
extern void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired);

extern void vio_unregister_device(struct vio_dev *dev);

extern int vio_h_cop_sync(struct vio_dev *vdev, struct vio_pfo_op *op);

struct device_node;

extern struct vio_dev *vio_register_device_node(
		struct device_node *node_vdev);
extern const void *vio_get_attribute(struct vio_dev *vdev, char *which,
		int *length);
#ifdef CONFIG_PPC_PSERIES
extern struct vio_dev *vio_find_node(struct device_node *vnode);
extern int vio_enable_interrupts(struct vio_dev *dev);
extern int vio_disable_interrupts(struct vio_dev *dev);
#else
static inline int vio_enable_interrupts(struct vio_dev *dev)
{
	return 0;
}
#endif

static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
{
	return container_of(drv, struct vio_driver, driver);
}

static inline struct vio_dev *to_vio_dev(struct device *dev)
{
	return container_of(dev, struct vio_dev, dev);
}

#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_VIO_H */