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