linux/drivers/spi/spidev.c
<<
>>
Prefs
   1/*
   2 * Simple synchronous userspace interface to SPI devices
   3 *
   4 * Copyright (C) 2006 SWAPP
   5 *      Andrea Paterniani <a.paterniani@swapp-eng.it>
   6 * Copyright (C) 2007 David Brownell (simplification, cleanup)
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21 */
  22
  23#include <linux/init.h>
  24#include <linux/module.h>
  25#include <linux/ioctl.h>
  26#include <linux/fs.h>
  27#include <linux/device.h>
  28#include <linux/err.h>
  29#include <linux/list.h>
  30#include <linux/errno.h>
  31#include <linux/mutex.h>
  32#include <linux/slab.h>
  33#include <linux/compat.h>
  34#include <linux/of.h>
  35#include <linux/of_device.h>
  36
  37#include <linux/spi/spi.h>
  38#include <linux/spi/spidev.h>
  39
  40#include <asm/uaccess.h>
  41
  42
  43/*
  44 * This supports access to SPI devices using normal userspace I/O calls.
  45 * Note that while traditional UNIX/POSIX I/O semantics are half duplex,
  46 * and often mask message boundaries, full SPI support requires full duplex
  47 * transfers.  There are several kinds of internal message boundaries to
  48 * handle chipselect management and other protocol options.
  49 *
  50 * SPI has a character major number assigned.  We allocate minor numbers
  51 * dynamically using a bitmask.  You must use hotplug tools, such as udev
  52 * (or mdev with busybox) to create and destroy the /dev/spidevB.C device
  53 * nodes, since there is no fixed association of minor numbers with any
  54 * particular SPI bus or device.
  55 */
  56#define SPIDEV_MAJOR                    153     /* assigned */
  57#define N_SPI_MINORS                    32      /* ... up to 256 */
  58
  59static DECLARE_BITMAP(minors, N_SPI_MINORS);
  60
  61
  62/* Bit masks for spi_device.mode management.  Note that incorrect
  63 * settings for some settings can cause *lots* of trouble for other
  64 * devices on a shared bus:
  65 *
  66 *  - CS_HIGH ... this device will be active when it shouldn't be
  67 *  - 3WIRE ... when active, it won't behave as it should
  68 *  - NO_CS ... there will be no explicit message boundaries; this
  69 *      is completely incompatible with the shared bus model
  70 *  - READY ... transfers may proceed when they shouldn't.
  71 *
  72 * REVISIT should changing those flags be privileged?
  73 */
  74#define SPI_MODE_MASK           (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \
  75                                | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \
  76                                | SPI_NO_CS | SPI_READY)
  77
  78struct spidev_data {
  79        dev_t                   devt;
  80        spinlock_t              spi_lock;
  81        struct spi_device       *spi;
  82        struct list_head        device_entry;
  83
  84        /* buffer is NULL unless this device is open (users > 0) */
  85        struct mutex            buf_lock;
  86        unsigned                users;
  87        u8                      *buffer;
  88};
  89
  90static LIST_HEAD(device_list);
  91static DEFINE_MUTEX(device_list_lock);
  92
  93static unsigned bufsiz = 4096;
  94module_param(bufsiz, uint, S_IRUGO);
  95MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
  96
  97/*-------------------------------------------------------------------------*/
  98
  99/*
 100 * We can't use the standard synchronous wrappers for file I/O; we
 101 * need to protect against async removal of the underlying spi_device.
 102 */
 103static void spidev_complete(void *arg)
 104{
 105        complete(arg);
 106}
 107
 108static ssize_t
 109spidev_sync(struct spidev_data *spidev, struct spi_message *message)
 110{
 111        DECLARE_COMPLETION_ONSTACK(done);
 112        int status;
 113
 114        message->complete = spidev_complete;
 115        message->context = &done;
 116
 117        spin_lock_irq(&spidev->spi_lock);
 118        if (spidev->spi == NULL)
 119                status = -ESHUTDOWN;
 120        else
 121                status = spi_async(spidev->spi, message);
 122        spin_unlock_irq(&spidev->spi_lock);
 123
 124        if (status == 0) {
 125                wait_for_completion(&done);
 126                status = message->status;
 127                if (status == 0)
 128                        status = message->actual_length;
 129        }
 130        return status;
 131}
 132
 133static inline ssize_t
 134spidev_sync_write(struct spidev_data *spidev, size_t len)
 135{
 136        struct spi_transfer     t = {
 137                        .tx_buf         = spidev->buffer,
 138                        .len            = len,
 139                };
 140        struct spi_message      m;
 141
 142        spi_message_init(&m);
 143        spi_message_add_tail(&t, &m);
 144        return spidev_sync(spidev, &m);
 145}
 146
 147static inline ssize_t
 148spidev_sync_read(struct spidev_data *spidev, size_t len)
 149{
 150        struct spi_transfer     t = {
 151                        .rx_buf         = spidev->buffer,
 152                        .len            = len,
 153                };
 154        struct spi_message      m;
 155
 156        spi_message_init(&m);
 157        spi_message_add_tail(&t, &m);
 158        return spidev_sync(spidev, &m);
 159}
 160
 161/*-------------------------------------------------------------------------*/
 162
 163/* Read-only message with current device setup */
 164static ssize_t
 165spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
 166{
 167        struct spidev_data      *spidev;
 168        ssize_t                 status = 0;
 169
 170        /* chipselect only toggles at start or end of operation */
 171        if (count > bufsiz)
 172                return -EMSGSIZE;
 173
 174        spidev = filp->private_data;
 175
 176        mutex_lock(&spidev->buf_lock);
 177        status = spidev_sync_read(spidev, count);
 178        if (status > 0) {
 179                unsigned long   missing;
 180
 181                missing = copy_to_user(buf, spidev->buffer, status);
 182                if (missing == status)
 183                        status = -EFAULT;
 184                else
 185                        status = status - missing;
 186        }
 187        mutex_unlock(&spidev->buf_lock);
 188
 189        return status;
 190}
 191
 192/* Write-only message with current device setup */
 193static ssize_t
 194spidev_write(struct file *filp, const char __user *buf,
 195                size_t count, loff_t *f_pos)
 196{
 197        struct spidev_data      *spidev;
 198        ssize_t                 status = 0;
 199        unsigned long           missing;
 200
 201        /* chipselect only toggles at start or end of operation */
 202        if (count > bufsiz)
 203                return -EMSGSIZE;
 204
 205        spidev = filp->private_data;
 206
 207        mutex_lock(&spidev->buf_lock);
 208        missing = copy_from_user(spidev->buffer, buf, count);
 209        if (missing == 0) {
 210                status = spidev_sync_write(spidev, count);
 211        } else
 212                status = -EFAULT;
 213        mutex_unlock(&spidev->buf_lock);
 214
 215        return status;
 216}
 217
 218static int spidev_message(struct spidev_data *spidev,
 219                struct spi_ioc_transfer *u_xfers, unsigned n_xfers)
 220{
 221        struct spi_message      msg;
 222        struct spi_transfer     *k_xfers;
 223        struct spi_transfer     *k_tmp;
 224        struct spi_ioc_transfer *u_tmp;
 225        unsigned                n, total;
 226        u8                      *buf;
 227        int                     status = -EFAULT;
 228
 229        spi_message_init(&msg);
 230        k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL);
 231        if (k_xfers == NULL)
 232                return -ENOMEM;
 233
 234        /* Construct spi_message, copying any tx data to bounce buffer.
 235         * We walk the array of user-provided transfers, using each one
 236         * to initialize a kernel version of the same transfer.
 237         */
 238        buf = spidev->buffer;
 239        total = 0;
 240        for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
 241                        n;
 242                        n--, k_tmp++, u_tmp++) {
 243                k_tmp->len = u_tmp->len;
 244
 245                total += k_tmp->len;
 246                if (total > bufsiz) {
 247                        status = -EMSGSIZE;
 248                        goto done;
 249                }
 250
 251                if (u_tmp->rx_buf) {
 252                        k_tmp->rx_buf = buf;
 253                        if (!access_ok(VERIFY_WRITE, (u8 __user *)
 254                                                (uintptr_t) u_tmp->rx_buf,
 255                                                u_tmp->len))
 256                                goto done;
 257                }
 258                if (u_tmp->tx_buf) {
 259                        k_tmp->tx_buf = buf;
 260                        if (copy_from_user(buf, (const u8 __user *)
 261                                                (uintptr_t) u_tmp->tx_buf,
 262                                        u_tmp->len))
 263                                goto done;
 264                }
 265                buf += k_tmp->len;
 266
 267                k_tmp->cs_change = !!u_tmp->cs_change;
 268                k_tmp->bits_per_word = u_tmp->bits_per_word;
 269                k_tmp->delay_usecs = u_tmp->delay_usecs;
 270                k_tmp->speed_hz = u_tmp->speed_hz;
 271#ifdef VERBOSE
 272                dev_dbg(&spidev->spi->dev,
 273                        "  xfer len %zd %s%s%s%dbits %u usec %uHz\n",
 274                        u_tmp->len,
 275                        u_tmp->rx_buf ? "rx " : "",
 276                        u_tmp->tx_buf ? "tx " : "",
 277                        u_tmp->cs_change ? "cs " : "",
 278                        u_tmp->bits_per_word ? : spidev->spi->bits_per_word,
 279                        u_tmp->delay_usecs,
 280                        u_tmp->speed_hz ? : spidev->spi->max_speed_hz);
 281#endif
 282                spi_message_add_tail(k_tmp, &msg);
 283        }
 284
 285        status = spidev_sync(spidev, &msg);
 286        if (status < 0)
 287                goto done;
 288
 289        /* copy any rx data out of bounce buffer */
 290        buf = spidev->buffer;
 291        for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {
 292                if (u_tmp->rx_buf) {
 293                        if (__copy_to_user((u8 __user *)
 294                                        (uintptr_t) u_tmp->rx_buf, buf,
 295                                        u_tmp->len)) {
 296                                status = -EFAULT;
 297                                goto done;
 298                        }
 299                }
 300                buf += u_tmp->len;
 301        }
 302        status = total;
 303
 304done:
 305        kfree(k_xfers);
 306        return status;
 307}
 308
 309static long
 310spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 311{
 312        int                     err = 0;
 313        int                     retval = 0;
 314        struct spidev_data      *spidev;
 315        struct spi_device       *spi;
 316        u32                     tmp;
 317        unsigned                n_ioc;
 318        struct spi_ioc_transfer *ioc;
 319
 320        /* Check type and command number */
 321        if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC)
 322                return -ENOTTY;
 323
 324        /* Check access direction once here; don't repeat below.
 325         * IOC_DIR is from the user perspective, while access_ok is
 326         * from the kernel perspective; so they look reversed.
 327         */
 328        if (_IOC_DIR(cmd) & _IOC_READ)
 329                err = !access_ok(VERIFY_WRITE,
 330                                (void __user *)arg, _IOC_SIZE(cmd));
 331        if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE)
 332                err = !access_ok(VERIFY_READ,
 333                                (void __user *)arg, _IOC_SIZE(cmd));
 334        if (err)
 335                return -EFAULT;
 336
 337        /* guard against device removal before, or while,
 338         * we issue this ioctl.
 339         */
 340        spidev = filp->private_data;
 341        spin_lock_irq(&spidev->spi_lock);
 342        spi = spi_dev_get(spidev->spi);
 343        spin_unlock_irq(&spidev->spi_lock);
 344
 345        if (spi == NULL)
 346                return -ESHUTDOWN;
 347
 348        /* use the buffer lock here for triple duty:
 349         *  - prevent I/O (from us) so calling spi_setup() is safe;
 350         *  - prevent concurrent SPI_IOC_WR_* from morphing
 351         *    data fields while SPI_IOC_RD_* reads them;
 352         *  - SPI_IOC_MESSAGE needs the buffer locked "normally".
 353         */
 354        mutex_lock(&spidev->buf_lock);
 355
 356        switch (cmd) {
 357        /* read requests */
 358        case SPI_IOC_RD_MODE:
 359                retval = __put_user(spi->mode & SPI_MODE_MASK,
 360                                        (__u8 __user *)arg);
 361                break;
 362        case SPI_IOC_RD_LSB_FIRST:
 363                retval = __put_user((spi->mode & SPI_LSB_FIRST) ?  1 : 0,
 364                                        (__u8 __user *)arg);
 365                break;
 366        case SPI_IOC_RD_BITS_PER_WORD:
 367                retval = __put_user(spi->bits_per_word, (__u8 __user *)arg);
 368                break;
 369        case SPI_IOC_RD_MAX_SPEED_HZ:
 370                retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg);
 371                break;
 372
 373        /* write requests */
 374        case SPI_IOC_WR_MODE:
 375                retval = __get_user(tmp, (u8 __user *)arg);
 376                if (retval == 0) {
 377                        u8      save = spi->mode;
 378
 379                        if (tmp & ~SPI_MODE_MASK) {
 380                                retval = -EINVAL;
 381                                break;
 382                        }
 383
 384                        tmp |= spi->mode & ~SPI_MODE_MASK;
 385                        spi->mode = (u8)tmp;
 386                        retval = spi_setup(spi);
 387                        if (retval < 0)
 388                                spi->mode = save;
 389                        else
 390                                dev_dbg(&spi->dev, "spi mode %02x\n", tmp);
 391                }
 392                break;
 393        case SPI_IOC_WR_LSB_FIRST:
 394                retval = __get_user(tmp, (__u8 __user *)arg);
 395                if (retval == 0) {
 396                        u8      save = spi->mode;
 397
 398                        if (tmp)
 399                                spi->mode |= SPI_LSB_FIRST;
 400                        else
 401                                spi->mode &= ~SPI_LSB_FIRST;
 402                        retval = spi_setup(spi);
 403                        if (retval < 0)
 404                                spi->mode = save;
 405                        else
 406                                dev_dbg(&spi->dev, "%csb first\n",
 407                                                tmp ? 'l' : 'm');
 408                }
 409                break;
 410        case SPI_IOC_WR_BITS_PER_WORD:
 411                retval = __get_user(tmp, (__u8 __user *)arg);
 412                if (retval == 0) {
 413                        u8      save = spi->bits_per_word;
 414
 415                        spi->bits_per_word = tmp;
 416                        retval = spi_setup(spi);
 417                        if (retval < 0)
 418                                spi->bits_per_word = save;
 419                        else
 420                                dev_dbg(&spi->dev, "%d bits per word\n", tmp);
 421                }
 422                break;
 423        case SPI_IOC_WR_MAX_SPEED_HZ:
 424                retval = __get_user(tmp, (__u32 __user *)arg);
 425                if (retval == 0) {
 426                        u32     save = spi->max_speed_hz;
 427
 428                        spi->max_speed_hz = tmp;
 429                        retval = spi_setup(spi);
 430                        if (retval < 0)
 431                                spi->max_speed_hz = save;
 432                        else
 433                                dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
 434                }
 435                break;
 436
 437        default:
 438                /* segmented and/or full-duplex I/O request */
 439                if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0))
 440                                || _IOC_DIR(cmd) != _IOC_WRITE) {
 441                        retval = -ENOTTY;
 442                        break;
 443                }
 444
 445                tmp = _IOC_SIZE(cmd);
 446                if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) {
 447                        retval = -EINVAL;
 448                        break;
 449                }
 450                n_ioc = tmp / sizeof(struct spi_ioc_transfer);
 451                if (n_ioc == 0)
 452                        break;
 453
 454                /* copy into scratch area */
 455                ioc = kmalloc(tmp, GFP_KERNEL);
 456                if (!ioc) {
 457                        retval = -ENOMEM;
 458                        break;
 459                }
 460                if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
 461                        kfree(ioc);
 462                        retval = -EFAULT;
 463                        break;
 464                }
 465
 466                /* translate to spi_message, execute */
 467                retval = spidev_message(spidev, ioc, n_ioc);
 468                kfree(ioc);
 469                break;
 470        }
 471
 472        mutex_unlock(&spidev->buf_lock);
 473        spi_dev_put(spi);
 474        return retval;
 475}
 476
 477#ifdef CONFIG_COMPAT
 478static long
 479spidev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 480{
 481        return spidev_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
 482}
 483#else
 484#define spidev_compat_ioctl NULL
 485#endif /* CONFIG_COMPAT */
 486
 487static int spidev_open(struct inode *inode, struct file *filp)
 488{
 489        struct spidev_data      *spidev;
 490        int                     status = -ENXIO;
 491
 492        mutex_lock(&device_list_lock);
 493
 494        list_for_each_entry(spidev, &device_list, device_entry) {
 495                if (spidev->devt == inode->i_rdev) {
 496                        status = 0;
 497                        break;
 498                }
 499        }
 500        if (status == 0) {
 501                if (!spidev->buffer) {
 502                        spidev->buffer = kmalloc(bufsiz, GFP_KERNEL);
 503                        if (!spidev->buffer) {
 504                                dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
 505                                status = -ENOMEM;
 506                        }
 507                }
 508                if (status == 0) {
 509                        spidev->users++;
 510                        filp->private_data = spidev;
 511                        nonseekable_open(inode, filp);
 512                }
 513        } else
 514                pr_debug("spidev: nothing for minor %d\n", iminor(inode));
 515
 516        mutex_unlock(&device_list_lock);
 517        return status;
 518}
 519
 520static int spidev_release(struct inode *inode, struct file *filp)
 521{
 522        struct spidev_data      *spidev;
 523        int                     status = 0;
 524
 525        mutex_lock(&device_list_lock);
 526        spidev = filp->private_data;
 527        filp->private_data = NULL;
 528
 529        /* last close? */
 530        spidev->users--;
 531        if (!spidev->users) {
 532                int             dofree;
 533
 534                kfree(spidev->buffer);
 535                spidev->buffer = NULL;
 536
 537                /* ... after we unbound from the underlying device? */
 538                spin_lock_irq(&spidev->spi_lock);
 539                dofree = (spidev->spi == NULL);
 540                spin_unlock_irq(&spidev->spi_lock);
 541
 542                if (dofree)
 543                        kfree(spidev);
 544        }
 545        mutex_unlock(&device_list_lock);
 546
 547        return status;
 548}
 549
 550static const struct file_operations spidev_fops = {
 551        .owner =        THIS_MODULE,
 552        /* REVISIT switch to aio primitives, so that userspace
 553         * gets more complete API coverage.  It'll simplify things
 554         * too, except for the locking.
 555         */
 556        .write =        spidev_write,
 557        .read =         spidev_read,
 558        .unlocked_ioctl = spidev_ioctl,
 559        .compat_ioctl = spidev_compat_ioctl,
 560        .open =         spidev_open,
 561        .release =      spidev_release,
 562        .llseek =       no_llseek,
 563};
 564
 565/*-------------------------------------------------------------------------*/
 566
 567/* The main reason to have this class is to make mdev/udev create the
 568 * /dev/spidevB.C character device nodes exposing our userspace API.
 569 * It also simplifies memory management.
 570 */
 571
 572static struct class *spidev_class;
 573
 574/*-------------------------------------------------------------------------*/
 575
 576static int spidev_probe(struct spi_device *spi)
 577{
 578        struct spidev_data      *spidev;
 579        int                     status;
 580        unsigned long           minor;
 581
 582        /* Allocate driver data */
 583        spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
 584        if (!spidev)
 585                return -ENOMEM;
 586
 587        /* Initialize the driver data */
 588        spidev->spi = spi;
 589        spin_lock_init(&spidev->spi_lock);
 590        mutex_init(&spidev->buf_lock);
 591
 592        INIT_LIST_HEAD(&spidev->device_entry);
 593
 594        /* If we can allocate a minor number, hook up this device.
 595         * Reusing minors is fine so long as udev or mdev is working.
 596         */
 597        mutex_lock(&device_list_lock);
 598        minor = find_first_zero_bit(minors, N_SPI_MINORS);
 599        if (minor < N_SPI_MINORS) {
 600                struct device *dev;
 601
 602                spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
 603                dev = device_create(spidev_class, &spi->dev, spidev->devt,
 604                                    spidev, "spidev%d.%d",
 605                                    spi->master->bus_num, spi->chip_select);
 606                status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
 607        } else {
 608                dev_dbg(&spi->dev, "no minor number available!\n");
 609                status = -ENODEV;
 610        }
 611        if (status == 0) {
 612                set_bit(minor, minors);
 613                list_add(&spidev->device_entry, &device_list);
 614        }
 615        mutex_unlock(&device_list_lock);
 616
 617        if (status == 0)
 618                spi_set_drvdata(spi, spidev);
 619        else
 620                kfree(spidev);
 621
 622        return status;
 623}
 624
 625static int spidev_remove(struct spi_device *spi)
 626{
 627        struct spidev_data      *spidev = spi_get_drvdata(spi);
 628
 629        /* make sure ops on existing fds can abort cleanly */
 630        spin_lock_irq(&spidev->spi_lock);
 631        spidev->spi = NULL;
 632        spi_set_drvdata(spi, NULL);
 633        spin_unlock_irq(&spidev->spi_lock);
 634
 635        /* prevent new opens */
 636        mutex_lock(&device_list_lock);
 637        list_del(&spidev->device_entry);
 638        device_destroy(spidev_class, spidev->devt);
 639        clear_bit(MINOR(spidev->devt), minors);
 640        if (spidev->users == 0)
 641                kfree(spidev);
 642        mutex_unlock(&device_list_lock);
 643
 644        return 0;
 645}
 646
 647static const struct of_device_id spidev_dt_ids[] = {
 648        { .compatible = "rohm,dh2228fv" },
 649        {},
 650};
 651
 652MODULE_DEVICE_TABLE(of, spidev_dt_ids);
 653
 654static struct spi_driver spidev_spi_driver = {
 655        .driver = {
 656                .name =         "spidev",
 657                .owner =        THIS_MODULE,
 658                .of_match_table = of_match_ptr(spidev_dt_ids),
 659        },
 660        .probe =        spidev_probe,
 661        .remove =       spidev_remove,
 662
 663        /* NOTE:  suspend/resume methods are not necessary here.
 664         * We don't do anything except pass the requests to/from
 665         * the underlying controller.  The refrigerator handles
 666         * most issues; the controller driver handles the rest.
 667         */
 668};
 669
 670/*-------------------------------------------------------------------------*/
 671
 672static int __init spidev_init(void)
 673{
 674        int status;
 675
 676        /* Claim our 256 reserved device numbers.  Then register a class
 677         * that will key udev/mdev to add/remove /dev nodes.  Last, register
 678         * the driver which manages those device numbers.
 679         */
 680        BUILD_BUG_ON(N_SPI_MINORS > 256);
 681        status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
 682        if (status < 0)
 683                return status;
 684
 685        spidev_class = class_create(THIS_MODULE, "spidev");
 686        if (IS_ERR(spidev_class)) {
 687                unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
 688                return PTR_ERR(spidev_class);
 689        }
 690
 691        status = spi_register_driver(&spidev_spi_driver);
 692        if (status < 0) {
 693                class_destroy(spidev_class);
 694                unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
 695        }
 696        return status;
 697}
 698module_init(spidev_init);
 699
 700static void __exit spidev_exit(void)
 701{
 702        spi_unregister_driver(&spidev_spi_driver);
 703        class_destroy(spidev_class);
 704        unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
 705}
 706module_exit(spidev_exit);
 707
 708MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>");
 709MODULE_DESCRIPTION("User mode SPI device interface");
 710MODULE_LICENSE("GPL");
 711MODULE_ALIAS("spi:spidev");
 712
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.