linux/drivers/fmc/fmc-core.c
<<
>>
Prefs
   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                                "deivce 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");
 390