Loading...
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 175 176 177 178 179 180 181 182 183 | /*
* Industry-pack bus.
*
* (C) 2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN
* (C) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia
*
* 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; version 2 of the License.
*/
#include <linux/device.h>
#define IPACK_IDPROM_OFFSET_I 0x01
#define IPACK_IDPROM_OFFSET_P 0x03
#define IPACK_IDPROM_OFFSET_A 0x05
#define IPACK_IDPROM_OFFSET_C 0x07
#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09
#define IPACK_IDPROM_OFFSET_MODEL 0x0B
#define IPACK_IDPROM_OFFSET_REVISION 0x0D
#define IPACK_IDPROM_OFFSET_RESERVED 0x0F
#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11
#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13
#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15
#define IPACK_IDPROM_OFFSET_CRC 0x17
struct ipack_bus_ops;
struct ipack_driver;
enum ipack_space {
IPACK_IO_SPACE = 0,
IPACK_ID_SPACE = 1,
IPACK_MEM_SPACE = 2,
};
/**
* struct ipack_addr_space - Virtual address space mapped for a specified type.
*
* @address: virtual address
* @size: size of the mapped space
*/
struct ipack_addr_space {
void __iomem *address;
unsigned int size;
};
/**
* struct ipack_device
*
* @bus_nr: IP bus number where the device is plugged
* @slot: Slot where the device is plugged in the carrier board
* @irq: IRQ vector
* @driver: Pointer to the ipack_driver that manages the device
* @bus: ipack_bus_device where the device is plugged to.
* @id_space: Virtual address to ID space.
* @io_space: Virtual address to IO space.
* @mem_space: Virtual address to MEM space.
* @dev: device in kernel representation.
*
* Warning: Direct access to mapped memory is possible but the endianness
* is not the same with PCI carrier or VME carrier. The endianness is managed
* by the carrier board throught bus->ops.
*/
struct ipack_device {
unsigned int bus_nr;
unsigned int slot;
unsigned int irq;
struct ipack_driver *driver;
struct ipack_bus_device *bus;
struct ipack_addr_space id_space;
struct ipack_addr_space io_space;
struct ipack_addr_space mem_space;
struct device dev;
};
/**
* struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device
*
* @match: Match function
* @probe: Probe function
* @remove: tell the driver that the carrier board wants to remove one device
*/
struct ipack_driver_ops {
int (*match) (struct ipack_device *dev);
int (*probe) (struct ipack_device *dev);
void (*remove) (struct ipack_device *dev);
};
/**
* struct ipack_driver -- Specific data to each ipack board driver
*
* @driver: Device driver kernel representation
* @ops: Mezzanine driver operations specific for the ipack bus.
*/
struct ipack_driver {
struct device_driver driver;
struct ipack_driver_ops *ops;
};
/**
* struct ipack_bus_ops - available operations on a bridge module
*
* @map_space: map IP address space
* @unmap_space: unmap IP address space
* @request_irq: request IRQ
* @free_irq: free IRQ
* @read8: read unsigned char
* @read16: read unsigned short
* @read32: read unsigned int
* @write8: read unsigned char
* @write16: read unsigned short
* @write32: read unsigned int
* @remove_device: tell the bridge module that the device has been removed
*/
struct ipack_bus_ops {
int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space);
int (*unmap_space) (struct ipack_device *dev, int space);
int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg);
int (*free_irq) (struct ipack_device *dev);
int (*read8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char *value);
int (*read16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short *value);
int (*read32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int *value);
int (*write8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char value);
int (*write16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short value);
int (*write32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int value);
int (*remove_device) (struct ipack_device *dev);
};
/**
* struct ipack_bus_device
*
* @dev: pointer to carrier device
* @slots: number of slots available
* @bus_nr: ipack bus number
* @ops: bus operations for the mezzanine drivers
*/
struct ipack_bus_device {
struct device *parent;
int slots;
int bus_nr;
struct ipack_bus_ops *ops;
};
/**
* ipack_bus_register -- register a new ipack bus
*
* @parent: pointer to the parent device, if any.
* @slots: number of slots available in the bus device.
* @ops: bus operations for the mezzanine drivers.
*
* The carrier board device should call this function to register itself as
* available bus device in ipack.
*/
struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
struct ipack_bus_ops *ops);
/**
* ipack_bus_unregister -- unregister an ipack bus
*/
int ipack_bus_unregister(struct ipack_bus_device *bus);
/**
* ipack_driver_register -- Register a new driver
*
* Called by a ipack driver to register itself as a driver
* that can manage ipack devices.
*/
int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, char *name);
void ipack_driver_unregister(struct ipack_driver *edrv);
/**
* ipack_device_register -- register a new mezzanine device
*
* @bus: ipack bus device it is plugged to.
* @slot: slot position in the bus device.
* @irqv: IRQ vector for the mezzanine.
*
* Register a new ipack device (mezzanine device). The call is done by
* the carrier device driver.
*/
struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot, int irqv);
void ipack_device_unregister(struct ipack_device *dev);
|