xref: /OK3568_Linux_fs/kernel/include/linux/ipack.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Industry-pack bus.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2011-2012 CERN (www.cern.ch)
6*4882a593Smuzhiyun  * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/mod_devicetable.h>
10*4882a593Smuzhiyun #include <linux/device.h>
11*4882a593Smuzhiyun #include <linux/interrupt.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_I			0x01
14*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_P			0x03
15*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_A			0x05
16*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_C			0x07
17*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_MANUFACTURER_ID	0x09
18*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_MODEL		0x0B
19*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_REVISION		0x0D
20*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_RESERVED		0x0F
21*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_DRIVER_ID_L		0x11
22*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_DRIVER_ID_H		0x13
23*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_NUM_BYTES		0x15
24*4882a593Smuzhiyun #define IPACK_IDPROM_OFFSET_CRC			0x17
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun  * IndustryPack Fromat, Vendor and Device IDs.
28*4882a593Smuzhiyun  */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* ID section format versions */
31*4882a593Smuzhiyun #define IPACK_ID_VERSION_INVALID	0x00
32*4882a593Smuzhiyun #define IPACK_ID_VERSION_1		0x01
33*4882a593Smuzhiyun #define IPACK_ID_VERSION_2		0x02
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /* Vendors and devices. Sort key: vendor first, device next. */
36*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_RESERVED1	0x00
37*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_RESERVED2	0xFF
38*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED01	0x01
39*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED02	0x02
40*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED03	0x03
41*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED04	0x04
42*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED05	0x05
43*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED06	0x06
44*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED07	0x07
45*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED08	0x08
46*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED09	0x09
47*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED10	0x0A
48*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED11	0x0B
49*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED12	0x0C
50*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED13	0x0D
51*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED14	0x0E
52*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_UNREGISTRED15	0x0F
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define IPACK1_VENDOR_ID_SBS            0xF0
55*4882a593Smuzhiyun #define IPACK1_DEVICE_ID_SBS_OCTAL_232  0x22
56*4882a593Smuzhiyun #define IPACK1_DEVICE_ID_SBS_OCTAL_422  0x2A
57*4882a593Smuzhiyun #define IPACK1_DEVICE_ID_SBS_OCTAL_485  0x48
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun struct ipack_bus_ops;
60*4882a593Smuzhiyun struct ipack_driver;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun enum ipack_space {
63*4882a593Smuzhiyun 	IPACK_IO_SPACE    = 0,
64*4882a593Smuzhiyun 	IPACK_ID_SPACE,
65*4882a593Smuzhiyun 	IPACK_INT_SPACE,
66*4882a593Smuzhiyun 	IPACK_MEM8_SPACE,
67*4882a593Smuzhiyun 	IPACK_MEM16_SPACE,
68*4882a593Smuzhiyun 	/* Dummy for counting the number of entries.  Must remain the last
69*4882a593Smuzhiyun 	 * entry */
70*4882a593Smuzhiyun 	IPACK_SPACE_COUNT,
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /**
74*4882a593Smuzhiyun  */
75*4882a593Smuzhiyun struct ipack_region {
76*4882a593Smuzhiyun 	phys_addr_t start;
77*4882a593Smuzhiyun 	size_t      size;
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /**
81*4882a593Smuzhiyun  *	struct ipack_device
82*4882a593Smuzhiyun  *
83*4882a593Smuzhiyun  *	@slot: Slot where the device is plugged in the carrier board
84*4882a593Smuzhiyun  *	@bus: ipack_bus_device where the device is plugged to.
85*4882a593Smuzhiyun  *	@id_space: Virtual address to ID space.
86*4882a593Smuzhiyun  *	@io_space: Virtual address to IO space.
87*4882a593Smuzhiyun  *	@mem_space: Virtual address to MEM space.
88*4882a593Smuzhiyun  *	@dev: device in kernel representation.
89*4882a593Smuzhiyun  *
90*4882a593Smuzhiyun  * Warning: Direct access to mapped memory is possible but the endianness
91*4882a593Smuzhiyun  * is not the same with PCI carrier or VME carrier. The endianness is managed
92*4882a593Smuzhiyun  * by the carrier board throught bus->ops.
93*4882a593Smuzhiyun  */
94*4882a593Smuzhiyun struct ipack_device {
95*4882a593Smuzhiyun 	unsigned int slot;
96*4882a593Smuzhiyun 	struct ipack_bus_device *bus;
97*4882a593Smuzhiyun 	struct device dev;
98*4882a593Smuzhiyun 	void (*release) (struct ipack_device *dev);
99*4882a593Smuzhiyun 	struct ipack_region      region[IPACK_SPACE_COUNT];
100*4882a593Smuzhiyun 	u8                      *id;
101*4882a593Smuzhiyun 	size_t			 id_avail;
102*4882a593Smuzhiyun 	u32			 id_vendor;
103*4882a593Smuzhiyun 	u32			 id_device;
104*4882a593Smuzhiyun 	u8			 id_format;
105*4882a593Smuzhiyun 	unsigned int		 id_crc_correct:1;
106*4882a593Smuzhiyun 	unsigned int		 speed_8mhz:1;
107*4882a593Smuzhiyun 	unsigned int		 speed_32mhz:1;
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /**
111*4882a593Smuzhiyun  * struct ipack_driver_ops -- Callbacks to IPack device driver
112*4882a593Smuzhiyun  *
113*4882a593Smuzhiyun  * @probe:  Probe function
114*4882a593Smuzhiyun  * @remove: Prepare imminent removal of the device.  Services provided by the
115*4882a593Smuzhiyun  *          device should be revoked.
116*4882a593Smuzhiyun  */
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun struct ipack_driver_ops {
119*4882a593Smuzhiyun 	int (*probe) (struct ipack_device *dev);
120*4882a593Smuzhiyun 	void (*remove) (struct ipack_device *dev);
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun /**
124*4882a593Smuzhiyun  * struct ipack_driver -- Specific data to each ipack device driver
125*4882a593Smuzhiyun  *
126*4882a593Smuzhiyun  * @driver: Device driver kernel representation
127*4882a593Smuzhiyun  * @ops:    Callbacks provided by the IPack device driver
128*4882a593Smuzhiyun  */
129*4882a593Smuzhiyun struct ipack_driver {
130*4882a593Smuzhiyun 	struct device_driver driver;
131*4882a593Smuzhiyun 	const struct ipack_device_id *id_table;
132*4882a593Smuzhiyun 	const struct ipack_driver_ops *ops;
133*4882a593Smuzhiyun };
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun /**
136*4882a593Smuzhiyun  *	struct ipack_bus_ops - available operations on a bridge module
137*4882a593Smuzhiyun  *
138*4882a593Smuzhiyun  *	@map_space: map IP address space
139*4882a593Smuzhiyun  *	@unmap_space: unmap IP address space
140*4882a593Smuzhiyun  *	@request_irq: request IRQ
141*4882a593Smuzhiyun  *	@free_irq: free IRQ
142*4882a593Smuzhiyun  *	@get_clockrate: Returns the clockrate the carrier is currently
143*4882a593Smuzhiyun  *		communicating with the device at.
144*4882a593Smuzhiyun  *	@set_clockrate: Sets the clock-rate for carrier / module communication.
145*4882a593Smuzhiyun  *		Should return -EINVAL if the requested speed is not supported.
146*4882a593Smuzhiyun  *	@get_error: Returns the error state for the slot the device is attached
147*4882a593Smuzhiyun  *		to.
148*4882a593Smuzhiyun  *	@get_timeout: Returns 1 if the communication with the device has
149*4882a593Smuzhiyun  *		previously timed out.
150*4882a593Smuzhiyun  *	@reset_timeout: Resets the state returned by get_timeout.
151*4882a593Smuzhiyun  */
152*4882a593Smuzhiyun struct ipack_bus_ops {
153*4882a593Smuzhiyun 	int (*request_irq) (struct ipack_device *dev,
154*4882a593Smuzhiyun 			    irqreturn_t (*handler)(void *), void *arg);
155*4882a593Smuzhiyun 	int (*free_irq) (struct ipack_device *dev);
156*4882a593Smuzhiyun 	int (*get_clockrate) (struct ipack_device *dev);
157*4882a593Smuzhiyun 	int (*set_clockrate) (struct ipack_device *dev, int mherz);
158*4882a593Smuzhiyun 	int (*get_error) (struct ipack_device *dev);
159*4882a593Smuzhiyun 	int (*get_timeout) (struct ipack_device *dev);
160*4882a593Smuzhiyun 	int (*reset_timeout) (struct ipack_device *dev);
161*4882a593Smuzhiyun };
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun /**
164*4882a593Smuzhiyun  *	struct ipack_bus_device
165*4882a593Smuzhiyun  *
166*4882a593Smuzhiyun  *	@dev: pointer to carrier device
167*4882a593Smuzhiyun  *	@slots: number of slots available
168*4882a593Smuzhiyun  *	@bus_nr: ipack bus number
169*4882a593Smuzhiyun  *	@ops: bus operations for the mezzanine drivers
170*4882a593Smuzhiyun  */
171*4882a593Smuzhiyun struct ipack_bus_device {
172*4882a593Smuzhiyun 	struct module *owner;
173*4882a593Smuzhiyun 	struct device *parent;
174*4882a593Smuzhiyun 	int slots;
175*4882a593Smuzhiyun 	int bus_nr;
176*4882a593Smuzhiyun 	const struct ipack_bus_ops *ops;
177*4882a593Smuzhiyun };
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun /**
180*4882a593Smuzhiyun  *	ipack_bus_register -- register a new ipack bus
181*4882a593Smuzhiyun  *
182*4882a593Smuzhiyun  * @parent: pointer to the parent device, if any.
183*4882a593Smuzhiyun  * @slots: number of slots available in the bus device.
184*4882a593Smuzhiyun  * @ops: bus operations for the mezzanine drivers.
185*4882a593Smuzhiyun  *
186*4882a593Smuzhiyun  * The carrier board device should call this function to register itself as
187*4882a593Smuzhiyun  * available bus device in ipack.
188*4882a593Smuzhiyun  */
189*4882a593Smuzhiyun struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
190*4882a593Smuzhiyun 					    const struct ipack_bus_ops *ops,
191*4882a593Smuzhiyun 					    struct module *owner);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun /**
194*4882a593Smuzhiyun  *	ipack_bus_unregister -- unregister an ipack bus
195*4882a593Smuzhiyun  */
196*4882a593Smuzhiyun int ipack_bus_unregister(struct ipack_bus_device *bus);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun /**
199*4882a593Smuzhiyun  * ipack_driver_register -- Register a new ipack device driver
200*4882a593Smuzhiyun  *
201*4882a593Smuzhiyun  * Called by a ipack driver to register itself as a driver
202*4882a593Smuzhiyun  * that can manage ipack devices.
203*4882a593Smuzhiyun  */
204*4882a593Smuzhiyun int ipack_driver_register(struct ipack_driver *edrv, struct module *owner,
205*4882a593Smuzhiyun 			  const char *name);
206*4882a593Smuzhiyun void ipack_driver_unregister(struct ipack_driver *edrv);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /**
209*4882a593Smuzhiyun  *	ipack_device_init -- initialize an IPack device
210*4882a593Smuzhiyun  * @dev: the new device to initialize.
211*4882a593Smuzhiyun  *
212*4882a593Smuzhiyun  * Initialize a new IPack device ("module" in IndustryPack jargon). The call
213*4882a593Smuzhiyun  * is done by the carrier driver.  The carrier should populate the fields
214*4882a593Smuzhiyun  * bus and slot as well as the region array of @dev prior to calling this
215*4882a593Smuzhiyun  * function.  The rest of the fields will be allocated and populated
216*4882a593Smuzhiyun  * during initalization.
217*4882a593Smuzhiyun  *
218*4882a593Smuzhiyun  * Return zero on success or error code on failure.
219*4882a593Smuzhiyun  *
220*4882a593Smuzhiyun  * NOTE: _Never_ directly free @dev after calling this function, even
221*4882a593Smuzhiyun  * if it returned an error! Always use ipack_put_device() to give up the
222*4882a593Smuzhiyun  * reference initialized in this function instead.
223*4882a593Smuzhiyun  */
224*4882a593Smuzhiyun int ipack_device_init(struct ipack_device *dev);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun /**
227*4882a593Smuzhiyun  *	ipack_device_add -- Add an IPack device
228*4882a593Smuzhiyun  * @dev: the new device to add.
229*4882a593Smuzhiyun  *
230*4882a593Smuzhiyun  * Add a new IPack device. The call is done by the carrier driver
231*4882a593Smuzhiyun  * after calling ipack_device_init().
232*4882a593Smuzhiyun  *
233*4882a593Smuzhiyun  * Return zero on success or error code on failure.
234*4882a593Smuzhiyun  *
235*4882a593Smuzhiyun  * NOTE: _Never_ directly free @dev after calling this function, even
236*4882a593Smuzhiyun  * if it returned an error! Always use ipack_put_device() to give up the
237*4882a593Smuzhiyun  * reference initialized in this function instead.
238*4882a593Smuzhiyun  */
239*4882a593Smuzhiyun int ipack_device_add(struct ipack_device *dev);
240*4882a593Smuzhiyun void ipack_device_del(struct ipack_device *dev);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun void ipack_get_device(struct ipack_device *dev);
243*4882a593Smuzhiyun void ipack_put_device(struct ipack_device *dev);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun /**
246*4882a593Smuzhiyun  * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table
247*4882a593Smuzhiyun  * @_table: device table name
248*4882a593Smuzhiyun  *
249*4882a593Smuzhiyun  * This macro is used to create a struct ipack_device_id array (a device table)
250*4882a593Smuzhiyun  * in a generic manner.
251*4882a593Smuzhiyun  */
252*4882a593Smuzhiyun #define DEFINE_IPACK_DEVICE_TABLE(_table) \
253*4882a593Smuzhiyun 	const struct ipack_device_id _table[]
254*4882a593Smuzhiyun /**
255*4882a593Smuzhiyun  * IPACK_DEVICE - macro used to describe a specific IndustryPack device
256*4882a593Smuzhiyun  * @_format: the format version (currently either 1 or 2, 8 bit value)
257*4882a593Smuzhiyun  * @vend:    the 8 or 24 bit IndustryPack Vendor ID
258*4882a593Smuzhiyun  * @dev:     the 8 or 16  bit IndustryPack Device ID
259*4882a593Smuzhiyun  *
260*4882a593Smuzhiyun  * This macro is used to create a struct ipack_device_id that matches a specific
261*4882a593Smuzhiyun  * device.
262*4882a593Smuzhiyun  */
263*4882a593Smuzhiyun #define IPACK_DEVICE(_format, vend, dev) \
264*4882a593Smuzhiyun 	 .format = (_format), \
265*4882a593Smuzhiyun 	 .vendor = (vend), \
266*4882a593Smuzhiyun 	 .device = (dev)
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun /**
269*4882a593Smuzhiyun  * ipack_get_carrier - it increase the carrier ref. counter of
270*4882a593Smuzhiyun  *                     the carrier module
271*4882a593Smuzhiyun  * @dev: mezzanine device which wants to get the carrier
272*4882a593Smuzhiyun  */
ipack_get_carrier(struct ipack_device * dev)273*4882a593Smuzhiyun static inline int ipack_get_carrier(struct ipack_device *dev)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	return try_module_get(dev->bus->owner);
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun /**
279*4882a593Smuzhiyun  * ipack_get_carrier - it decrease the carrier ref. counter of
280*4882a593Smuzhiyun  *                     the carrier module
281*4882a593Smuzhiyun  * @dev: mezzanine device which wants to get the carrier
282*4882a593Smuzhiyun  */
ipack_put_carrier(struct ipack_device * dev)283*4882a593Smuzhiyun static inline void ipack_put_carrier(struct ipack_device *dev)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	module_put(dev->bus->owner);
286*4882a593Smuzhiyun }
287