Linux Audio

Check our new training course

Loading...
v4.17
  1/*
  2 * Copyright (C) 2012 CERN (www.cern.ch)
  3 * Author: Alessandro Rubini <rubini@gnudd.com>
  4 *
  5 * Released according to the GNU GPL, version 2 or any later version.
  6 *
  7 * This work is part of the White Rabbit project, a research effort led
  8 * by CERN, the European Institute for Nuclear Research.
  9 */
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/slab.h>
 13#include <linux/init.h>
 14#include <linux/device.h>
 15#include <linux/fmc.h>
 16#include <linux/fmc-sdb.h>
 17
 18#include "fmc-private.h"
 19
 20static int fmc_check_version(unsigned long version, const char *name)
 21{
 22	if (__FMC_MAJOR(version) != FMC_MAJOR) {
 23		pr_err("%s: \"%s\" has wrong major (has %li, expected %i)\n",
 24		       __func__, name, __FMC_MAJOR(version), FMC_MAJOR);
 25		return -EINVAL;
 26	}
 27
 28	if (__FMC_MINOR(version) != FMC_MINOR)
 29		pr_info("%s: \"%s\" has wrong minor (has %li, expected %i)\n",
 30		       __func__, name, __FMC_MINOR(version), FMC_MINOR);
 31	return 0;
 32}
 33
 34static int fmc_uevent(struct device *dev, struct kobj_uevent_env *env)
 35{
 36	/* struct fmc_device *fdev = to_fmc_device(dev); */
 37
 38	/* FIXME: The MODALIAS */
 39	add_uevent_var(env, "MODALIAS=%s", "fmc");
 40	return 0;
 41}
 42
 43static int fmc_probe(struct device *dev)
 44{
 45	struct fmc_driver *fdrv = to_fmc_driver(dev->driver);
 46	struct fmc_device *fdev = to_fmc_device(dev);
 47
 48	return fdrv->probe(fdev);
 49}
 50
 51static int fmc_remove(struct device *dev)
 52{
 53	struct fmc_driver *fdrv = to_fmc_driver(dev->driver);
 54	struct fmc_device *fdev = to_fmc_device(dev);
 55
 56	return fdrv->remove(fdev);
 57}
 58
 59static void fmc_shutdown(struct device *dev)
 60{
 61	/* not implemented but mandatory */
 62}
 63
 64static struct bus_type fmc_bus_type = {
 65	.name = "fmc",
 66	.match = fmc_match,
 67	.uevent = fmc_uevent,
 68	.probe = fmc_probe,
 69	.remove = fmc_remove,
 70	.shutdown = fmc_shutdown,
 71};
 72
 73static void fmc_release(struct device *dev)
 74{
 75	struct fmc_device *fmc = container_of(dev, struct fmc_device, dev);
 76
 77	kfree(fmc);
 78}
 79
 80/*
 81 * The eeprom is exported in sysfs, through a binary attribute
 82 */
 83
 84static ssize_t fmc_read_eeprom(struct file *file, struct kobject *kobj,
 85			   struct bin_attribute *bin_attr,
 86			   char *buf, loff_t off, size_t count)
 87{
 88	struct device *dev;
 89	struct fmc_device *fmc;
 90	int eelen;
 91
 92	dev = container_of(kobj, struct device, kobj);
 93	fmc = container_of(dev, struct fmc_device, dev);
 94	eelen = fmc->eeprom_len;
 95	if (off > eelen)
 96		return -ESPIPE;
 97	if (off == eelen)
 98		return 0; /* EOF */
 99	if (off + count > eelen)
100		count = eelen - off;
101	memcpy(buf, fmc->eeprom + off, count);
102	return count;
103}
104
105static ssize_t fmc_write_eeprom(struct file *file, struct kobject *kobj,
106				struct bin_attribute *bin_attr,
107				char *buf, loff_t off, size_t count)
108{
109	struct device *dev;
110	struct fmc_device *fmc;
111
112	dev = container_of(kobj, struct device, kobj);
113	fmc = container_of(dev, struct fmc_device, dev);
114	return fmc->op->write_ee(fmc, off, buf, count);
115}
116
117static struct bin_attribute fmc_eeprom_attr = {
118	.attr = { .name = "eeprom", .mode = S_IRUGO | S_IWUSR, },
119	.size = 8192, /* more or less standard */
120	.read = fmc_read_eeprom,
121	.write = fmc_write_eeprom,
122};
123
124int fmc_irq_request(struct fmc_device *fmc, irq_handler_t h,
125		    char *name, int flags)
126{
127	if (fmc->op->irq_request)
128		return fmc->op->irq_request(fmc, h, name, flags);
129	return -EPERM;
130}
131EXPORT_SYMBOL(fmc_irq_request);
132
133void fmc_irq_free(struct fmc_device *fmc)
134{
135	if (fmc->op->irq_free)
136		fmc->op->irq_free(fmc);
137}
138EXPORT_SYMBOL(fmc_irq_free);
139
140void fmc_irq_ack(struct fmc_device *fmc)
141{
142	if (likely(fmc->op->irq_ack))
143		fmc->op->irq_ack(fmc);
144}
145EXPORT_SYMBOL(fmc_irq_ack);
146
147int fmc_validate(struct fmc_device *fmc, struct fmc_driver *drv)
148{
149	if (fmc->op->validate)
150		return fmc->op->validate(fmc, drv);
151	return -EPERM;
152}
153EXPORT_SYMBOL(fmc_validate);
154
155int fmc_gpio_config(struct fmc_device *fmc, struct fmc_gpio *gpio, int ngpio)
156{
157	if (fmc->op->gpio_config)
158		return fmc->op->gpio_config(fmc, gpio, ngpio);
159	return -EPERM;
160}
161EXPORT_SYMBOL(fmc_gpio_config);
162
163int fmc_read_ee(struct fmc_device *fmc, int pos, void *d, int l)
164{
165	if (fmc->op->read_ee)
166		return fmc->op->read_ee(fmc, pos, d, l);
167	return -EPERM;
168}
169EXPORT_SYMBOL(fmc_read_ee);
170
171int fmc_write_ee(struct fmc_device *fmc, int pos, const void *d, int l)
172{
173	if (fmc->op->write_ee)
174		return fmc->op->write_ee(fmc, pos, d, l);
175	return -EPERM;
176}
177EXPORT_SYMBOL(fmc_write_ee);
178
179/*
180 * Functions for client modules follow
181 */
182
183int fmc_driver_register(struct fmc_driver *drv)
184{
185	if (fmc_check_version(drv->version, drv->driver.name))
186		return -EINVAL;
187	drv->driver.bus = &fmc_bus_type;
188	return driver_register(&drv->driver);
189}
190EXPORT_SYMBOL(fmc_driver_register);
191
192void fmc_driver_unregister(struct fmc_driver *drv)
193{
194	driver_unregister(&drv->driver);
195}
196EXPORT_SYMBOL(fmc_driver_unregister);
197
198/*
199 * When a device set is registered, all eeproms must be read
200 * and all FRUs must be parsed
201 */
202int fmc_device_register_n_gw(struct fmc_device **devs, int n,
203			  struct fmc_gateware *gw)
204{
205	struct fmc_device *fmc, **devarray;
206	uint32_t device_id;
207	int i, ret = 0;
208
209	if (n < 1)
210		return 0;
211
212	/* Check the version of the first data structure (function prints) */
213	if (fmc_check_version(devs[0]->version, devs[0]->carrier_name))
214		return -EINVAL;
215
216	devarray = kmemdup(devs, n * sizeof(*devs), GFP_KERNEL);
217	if (!devarray)
218		return -ENOMEM;
219
220	/* Make all other checks before continuing, for all devices */
221	for (i = 0; i < n; i++) {
222		fmc = devarray[i];
223		if (!fmc->hwdev) {
224			pr_err("%s: device nr. %i has no hwdev pointer\n",
225			       __func__, i);
226			ret = -EINVAL;
227			break;
228		}
229		if (fmc->flags & FMC_DEVICE_NO_MEZZANINE) {
230			dev_info(fmc->hwdev, "absent mezzanine in slot %d\n",
231				 fmc->slot_id);
232			continue;
233		}
234		if (!fmc->eeprom) {
235			dev_err(fmc->hwdev, "no eeprom provided for slot %i\n",
236				fmc->slot_id);
237			ret = -EINVAL;
238		}
239		if (!fmc->eeprom_addr) {
240			dev_err(fmc->hwdev, "no eeprom_addr for slot %i\n",
241				fmc->slot_id);
242			ret = -EINVAL;
243		}
244		if (!fmc->carrier_name || !fmc->carrier_data ||
245		    !fmc->device_id) {
246			dev_err(fmc->hwdev,
247				"device nr %i: carrier name, "
248				"data or dev_id not set\n", i);
249			ret = -EINVAL;
250		}
251		if (ret)
252			break;
253
254	}
255	if (ret) {
256		kfree(devarray);
257		return ret;
258	}
259
260	/* Validation is ok. Now init and register the devices */
261	for (i = 0; i < n; i++) {
262		fmc = devarray[i];
263
264		fmc->nr_slots = n; /* each slot must know how many are there */
265		fmc->devarray = devarray;
266
267		device_initialize(&fmc->dev);
268		fmc->dev.release = fmc_release;
269		fmc->dev.parent = fmc->hwdev;
270
271		/* Fill the identification stuff (may fail) */
272		fmc_fill_id_info(fmc);
273
274		fmc->dev.bus = &fmc_bus_type;
275
276		/* Name from mezzanine info or carrier info. Or 0,1,2.. */
277		device_id = fmc->device_id;
278		if (!fmc->mezzanine_name)
279			dev_set_name(&fmc->dev, "fmc-%04x", device_id);
280		else
281			dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name,
282				     device_id);
283
284		if (gw) {
285			/*
286			 * The carrier already know the bitstream to load
287			 * for this set of FMC mezzanines.
288			 */
289			ret = fmc->op->reprogram_raw(fmc, NULL,
290						     gw->bitstream, gw->len);
291			if (ret) {
292				dev_warn(fmc->hwdev,
293					 "Invalid gateware for FMC mezzanine\n");
294				goto out;
295			}
296		}
297
298		ret = device_add(&fmc->dev);
299		if (ret < 0) {
300			dev_err(fmc->hwdev, "Slot %i: Failed in registering "
301				"\"%s\"\n", fmc->slot_id, fmc->dev.kobj.name);
302			goto out;
303		}
304		ret = sysfs_create_bin_file(&fmc->dev.kobj, &fmc_eeprom_attr);
305		if (ret < 0) {
306			dev_err(&fmc->dev, "Failed in registering eeprom\n");
307			goto out1;
308		}
309		/* This device went well, give information to the user */
310		fmc_dump_eeprom(fmc);
311		fmc_debug_init(fmc);
312	}
313	return 0;
314
315out1:
316	device_del(&fmc->dev);
317out:
 
 
 
318	kfree(devarray);
319	for (i--; i >= 0; i--) {
320		fmc_debug_exit(devs[i]);
321		sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
322		device_del(&devs[i]->dev);
323		fmc_free_id_info(devs[i]);
324		put_device(&devs[i]->dev);
325	}
326	return ret;
327
328}
329EXPORT_SYMBOL(fmc_device_register_n_gw);
330
331int fmc_device_register_n(struct fmc_device **devs, int n)
332{
333	return fmc_device_register_n_gw(devs, n, NULL);
334}
335EXPORT_SYMBOL(fmc_device_register_n);
336
337int fmc_device_register_gw(struct fmc_device *fmc, struct fmc_gateware *gw)
338{
339	return fmc_device_register_n_gw(&fmc, 1, gw);
340}
341EXPORT_SYMBOL(fmc_device_register_gw);
342
343int fmc_device_register(struct fmc_device *fmc)
344{
345	return fmc_device_register_n(&fmc, 1);
346}
347EXPORT_SYMBOL(fmc_device_register);
348
349void fmc_device_unregister_n(struct fmc_device **devs, int n)
350{
351	int i;
352
353	if (n < 1)
354		return;
355
356	/* Free devarray first, not used by the later loop */
357	kfree(devs[0]->devarray);
358
359	for (i = 0; i < n; i++) {
360		fmc_debug_exit(devs[i]);
361		sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
362		device_del(&devs[i]->dev);
363		fmc_free_id_info(devs[i]);
364		put_device(&devs[i]->dev);
365	}
366}
367EXPORT_SYMBOL(fmc_device_unregister_n);
368
369void fmc_device_unregister(struct fmc_device *fmc)
370{
371	fmc_device_unregister_n(&fmc, 1);
372}
373EXPORT_SYMBOL(fmc_device_unregister);
374
375/* Init and exit are trivial */
376static int fmc_init(void)
377{
378	return bus_register(&fmc_bus_type);
379}
380
381static void fmc_exit(void)
382{
383	bus_unregister(&fmc_bus_type);
384}
385
386module_init(fmc_init);
387module_exit(fmc_exit);
388
389MODULE_LICENSE("GPL");
v4.6
  1/*
  2 * Copyright (C) 2012 CERN (www.cern.ch)
  3 * Author: Alessandro Rubini <rubini@gnudd.com>
  4 *
  5 * Released according to the GNU GPL, version 2 or any later version.
  6 *
  7 * This work is part of the White Rabbit project, a research effort led
  8 * by CERN, the European Institute for Nuclear Research.
  9 */
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/slab.h>
 13#include <linux/init.h>
 14#include <linux/device.h>
 15#include <linux/fmc.h>
 
 
 
 16
 17static int fmc_check_version(unsigned long version, const char *name)
 18{
 19	if (__FMC_MAJOR(version) != FMC_MAJOR) {
 20		pr_err("%s: \"%s\" has wrong major (has %li, expected %i)\n",
 21		       __func__, name, __FMC_MAJOR(version), FMC_MAJOR);
 22		return -EINVAL;
 23	}
 24
 25	if (__FMC_MINOR(version) != FMC_MINOR)
 26		pr_info("%s: \"%s\" has wrong minor (has %li, expected %i)\n",
 27		       __func__, name, __FMC_MINOR(version), FMC_MINOR);
 28	return 0;
 29}
 30
 31static int fmc_uevent(struct device *dev, struct kobj_uevent_env *env)
 32{
 33	/* struct fmc_device *fdev = to_fmc_device(dev); */
 34
 35	/* FIXME: The MODALIAS */
 36	add_uevent_var(env, "MODALIAS=%s", "fmc");
 37	return 0;
 38}
 39
 40static int fmc_probe(struct device *dev)
 41{
 42	struct fmc_driver *fdrv = to_fmc_driver(dev->driver);
 43	struct fmc_device *fdev = to_fmc_device(dev);
 44
 45	return fdrv->probe(fdev);
 46}
 47
 48static int fmc_remove(struct device *dev)
 49{
 50	struct fmc_driver *fdrv = to_fmc_driver(dev->driver);
 51	struct fmc_device *fdev = to_fmc_device(dev);
 52
 53	return fdrv->remove(fdev);
 54}
 55
 56static void fmc_shutdown(struct device *dev)
 57{
 58	/* not implemented but mandatory */
 59}
 60
 61static struct bus_type fmc_bus_type = {
 62	.name = "fmc",
 63	.match = fmc_match,
 64	.uevent = fmc_uevent,
 65	.probe = fmc_probe,
 66	.remove = fmc_remove,
 67	.shutdown = fmc_shutdown,
 68};
 69
 70static void fmc_release(struct device *dev)
 71{
 72	struct fmc_device *fmc = container_of(dev, struct fmc_device, dev);
 73
 74	kfree(fmc);
 75}
 76
 77/*
 78 * The eeprom is exported in sysfs, through a binary attribute
 79 */
 80
 81static ssize_t fmc_read_eeprom(struct file *file, struct kobject *kobj,
 82			   struct bin_attribute *bin_attr,
 83			   char *buf, loff_t off, size_t count)
 84{
 85	struct device *dev;
 86	struct fmc_device *fmc;
 87	int eelen;
 88
 89	dev = container_of(kobj, struct device, kobj);
 90	fmc = container_of(dev, struct fmc_device, dev);
 91	eelen = fmc->eeprom_len;
 92	if (off > eelen)
 93		return -ESPIPE;
 94	if (off == eelen)
 95		return 0; /* EOF */
 96	if (off + count > eelen)
 97		count = eelen - off;
 98	memcpy(buf, fmc->eeprom + off, count);
 99	return count;
100}
101
102static ssize_t fmc_write_eeprom(struct file *file, struct kobject *kobj,
103				struct bin_attribute *bin_attr,
104				char *buf, loff_t off, size_t count)
105{
106	struct device *dev;
107	struct fmc_device *fmc;
108
109	dev = container_of(kobj, struct device, kobj);
110	fmc = container_of(dev, struct fmc_device, dev);
111	return fmc->op->write_ee(fmc, off, buf, count);
112}
113
114static struct bin_attribute fmc_eeprom_attr = {
115	.attr = { .name = "eeprom", .mode = S_IRUGO | S_IWUSR, },
116	.size = 8192, /* more or less standard */
117	.read = fmc_read_eeprom,
118	.write = fmc_write_eeprom,
119};
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121/*
122 * Functions for client modules follow
123 */
124
125int fmc_driver_register(struct fmc_driver *drv)
126{
127	if (fmc_check_version(drv->version, drv->driver.name))
128		return -EINVAL;
129	drv->driver.bus = &fmc_bus_type;
130	return driver_register(&drv->driver);
131}
132EXPORT_SYMBOL(fmc_driver_register);
133
134void fmc_driver_unregister(struct fmc_driver *drv)
135{
136	driver_unregister(&drv->driver);
137}
138EXPORT_SYMBOL(fmc_driver_unregister);
139
140/*
141 * When a device set is registered, all eeproms must be read
142 * and all FRUs must be parsed
143 */
144int fmc_device_register_n(struct fmc_device **devs, int n)
 
145{
146	struct fmc_device *fmc, **devarray;
147	uint32_t device_id;
148	int i, ret = 0;
149
150	if (n < 1)
151		return 0;
152
153	/* Check the version of the first data structure (function prints) */
154	if (fmc_check_version(devs[0]->version, devs[0]->carrier_name))
155		return -EINVAL;
156
157	devarray = kmemdup(devs, n * sizeof(*devs), GFP_KERNEL);
158	if (!devarray)
159		return -ENOMEM;
160
161	/* Make all other checks before continuing, for all devices */
162	for (i = 0; i < n; i++) {
163		fmc = devarray[i];
164		if (!fmc->hwdev) {
165			pr_err("%s: device nr. %i has no hwdev pointer\n",
166			       __func__, i);
167			ret = -EINVAL;
168			break;
169		}
170		if (fmc->flags & FMC_DEVICE_NO_MEZZANINE) {
171			dev_info(fmc->hwdev, "absent mezzanine in slot %d\n",
172				 fmc->slot_id);
173			continue;
174		}
175		if (!fmc->eeprom) {
176			dev_err(fmc->hwdev, "no eeprom provided for slot %i\n",
177				fmc->slot_id);
178			ret = -EINVAL;
179		}
180		if (!fmc->eeprom_addr) {
181			dev_err(fmc->hwdev, "no eeprom_addr for slot %i\n",
182				fmc->slot_id);
183			ret = -EINVAL;
184		}
185		if (!fmc->carrier_name || !fmc->carrier_data ||
186		    !fmc->device_id) {
187			dev_err(fmc->hwdev,
188				"deivce nr %i: carrier name, "
189				"data or dev_id not set\n", i);
190			ret = -EINVAL;
191		}
192		if (ret)
193			break;
194
195	}
196	if (ret) {
197		kfree(devarray);
198		return ret;
199	}
200
201	/* Validation is ok. Now init and register the devices */
202	for (i = 0; i < n; i++) {
203		fmc = devarray[i];
204
205		fmc->nr_slots = n; /* each slot must know how many are there */
206		fmc->devarray = devarray;
207
208		device_initialize(&fmc->dev);
209		fmc->dev.release = fmc_release;
210		fmc->dev.parent = fmc->hwdev;
211
212		/* Fill the identification stuff (may fail) */
213		fmc_fill_id_info(fmc);
214
215		fmc->dev.bus = &fmc_bus_type;
216
217		/* Name from mezzanine info or carrier info. Or 0,1,2.. */
218		device_id = fmc->device_id;
219		if (!fmc->mezzanine_name)
220			dev_set_name(&fmc->dev, "fmc-%04x", device_id);
221		else
222			dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name,
223				     device_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224		ret = device_add(&fmc->dev);
225		if (ret < 0) {
226			dev_err(fmc->hwdev, "Slot %i: Failed in registering "
227				"\"%s\"\n", fmc->slot_id, fmc->dev.kobj.name);
228			goto out;
229		}
230		ret = sysfs_create_bin_file(&fmc->dev.kobj, &fmc_eeprom_attr);
231		if (ret < 0) {
232			dev_err(&fmc->dev, "Failed in registering eeprom\n");
233			goto out1;
234		}
235		/* This device went well, give information to the user */
236		fmc_dump_eeprom(fmc);
237		fmc_dump_sdb(fmc);
238	}
239	return 0;
240
241out1:
242	device_del(&fmc->dev);
243out:
244	fmc_free_id_info(fmc);
245	put_device(&fmc->dev);
246
247	kfree(devarray);
248	for (i--; i >= 0; i--) {
 
249		sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
250		device_del(&devs[i]->dev);
251		fmc_free_id_info(devs[i]);
252		put_device(&devs[i]->dev);
253	}
254	return ret;
255
256}
 
 
 
 
 
 
257EXPORT_SYMBOL(fmc_device_register_n);
258
 
 
 
 
 
 
259int fmc_device_register(struct fmc_device *fmc)
260{
261	return fmc_device_register_n(&fmc, 1);
262}
263EXPORT_SYMBOL(fmc_device_register);
264
265void fmc_device_unregister_n(struct fmc_device **devs, int n)
266{
267	int i;
268
269	if (n < 1)
270		return;
271
272	/* Free devarray first, not used by the later loop */
273	kfree(devs[0]->devarray);
274
275	for (i = 0; i < n; i++) {
 
276		sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
277		device_del(&devs[i]->dev);
278		fmc_free_id_info(devs[i]);
279		put_device(&devs[i]->dev);
280	}
281}
282EXPORT_SYMBOL(fmc_device_unregister_n);
283
284void fmc_device_unregister(struct fmc_device *fmc)
285{
286	fmc_device_unregister_n(&fmc, 1);
287}
288EXPORT_SYMBOL(fmc_device_unregister);
289
290/* Init and exit are trivial */
291static int fmc_init(void)
292{
293	return bus_register(&fmc_bus_type);
294}
295
296static void fmc_exit(void)
297{
298	bus_unregister(&fmc_bus_type);
299}
300
301module_init(fmc_init);
302module_exit(fmc_exit);
303
304MODULE_LICENSE("GPL");