Showing error 1735

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: drivers/misc/c2port/core.c
Line in file: 988
Project: Linux Kernel
Project version: 2.6.28
Confirmation: Fixed by 22ea71d7f49c3115e3a9ced5eac109fef26d3559
Tools: Smatch (1.59)
Entered: 2013-09-10 20:24:52 UTC


Source:

   1/*
   2 *  Silicon Labs C2 port core Linux support
   3 *
   4 *  Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
   5 *  Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/init.h>
  14#include <linux/device.h>
  15#include <linux/errno.h>
  16#include <linux/err.h>
  17#include <linux/kernel.h>
  18#include <linux/ctype.h>
  19#include <linux/delay.h>
  20#include <linux/idr.h>
  21#include <linux/sched.h>
  22
  23#include <linux/c2port.h>
  24
  25#define DRIVER_NAME             "c2port"
  26#define DRIVER_VERSION          "0.51.0"
  27
  28static DEFINE_SPINLOCK(c2port_idr_lock);
  29static DEFINE_IDR(c2port_idr);
  30
  31/*
  32 * Local variables
  33 */
  34
  35static struct class *c2port_class;
  36
  37/*
  38 * C2 registers & commands defines
  39 */
  40
  41/* C2 registers */
  42#define C2PORT_DEVICEID                0x00
  43#define C2PORT_REVID                0x01
  44#define C2PORT_FPCTL                0x02
  45#define C2PORT_FPDAT                0xB4
  46
  47/* C2 interface commands */
  48#define C2PORT_GET_VERSION        0x01
  49#define C2PORT_DEVICE_ERASE        0x03
  50#define C2PORT_BLOCK_READ        0x06
  51#define C2PORT_BLOCK_WRITE        0x07
  52#define C2PORT_PAGE_ERASE        0x08
  53
  54/* C2 status return codes */
  55#define C2PORT_INVALID_COMMAND        0x00
  56#define C2PORT_COMMAND_FAILED        0x02
  57#define C2PORT_COMMAND_OK        0x0d
  58
  59/*
  60 * C2 port low level signal managements
  61 */
  62
  63static void c2port_reset(struct c2port_device *dev)
  64{
  65        struct c2port_ops *ops = dev->ops;
  66
  67        /* To reset the device we have to keep clock line low for at least
  68         * 20us.
  69         */
  70        local_irq_disable();
  71        ops->c2ck_set(dev, 0);
  72        udelay(25);
  73        ops->c2ck_set(dev, 1);
  74        local_irq_enable();
  75
  76        udelay(1);
  77}
  78
  79static void c2port_strobe_ck(struct c2port_device *dev)
  80{
  81        struct c2port_ops *ops = dev->ops;
  82
  83        /* During hi-low-hi transition we disable local IRQs to avoid
  84         * interructions since C2 port specification says that it must be
  85         * shorter than 5us, otherwise the microcontroller may consider
  86         * it as a reset signal!
  87         */
  88        local_irq_disable();
  89        ops->c2ck_set(dev, 0);
  90        udelay(1);
  91        ops->c2ck_set(dev, 1);
  92        local_irq_enable();
  93
  94        udelay(1);
  95}
  96
  97/*
  98 * C2 port basic functions
  99 */
 100
 101static void c2port_write_ar(struct c2port_device *dev, u8 addr)
 102{
 103        struct c2port_ops *ops = dev->ops;
 104        int i;
 105
 106        /* START field */
 107        c2port_strobe_ck(dev);
 108
 109        /* INS field (11b, LSB first) */
 110        ops->c2d_dir(dev, 0);
 111        ops->c2d_set(dev, 1);
 112        c2port_strobe_ck(dev);
 113        ops->c2d_set(dev, 1);
 114        c2port_strobe_ck(dev);
 115
 116        /* ADDRESS field */
 117        for (i = 0; i < 8; i++) {
 118                ops->c2d_set(dev, addr & 0x01);
 119                c2port_strobe_ck(dev);
 120
 121                addr >>= 1;
 122        }
 123
 124        /* STOP field */
 125        ops->c2d_dir(dev, 1);
 126        c2port_strobe_ck(dev);
 127}
 128
 129static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
 130{
 131        struct c2port_ops *ops = dev->ops;
 132        int i;
 133
 134        /* START field */
 135        c2port_strobe_ck(dev);
 136
 137        /* INS field (10b, LSB first) */
 138        ops->c2d_dir(dev, 0);
 139        ops->c2d_set(dev, 0);
 140        c2port_strobe_ck(dev);
 141        ops->c2d_set(dev, 1);
 142        c2port_strobe_ck(dev);
 143
 144        /* ADDRESS field */
 145        ops->c2d_dir(dev, 1);
 146        *addr = 0;
 147        for (i = 0; i < 8; i++) {
 148                *addr >>= 1;        /* shift in 8-bit ADDRESS field LSB first */
 149
 150                c2port_strobe_ck(dev);
 151                if (ops->c2d_get(dev))
 152                        *addr |= 0x80;
 153        }
 154
 155        /* STOP field */
 156        c2port_strobe_ck(dev);
 157
 158        return 0;
 159}
 160
 161static int c2port_write_dr(struct c2port_device *dev, u8 data)
 162{
 163        struct c2port_ops *ops = dev->ops;
 164        int timeout, i;
 165
 166        /* START field */
 167        c2port_strobe_ck(dev);
 168
 169        /* INS field (01b, LSB first) */
 170        ops->c2d_dir(dev, 0);
 171        ops->c2d_set(dev, 1);
 172        c2port_strobe_ck(dev);
 173        ops->c2d_set(dev, 0);
 174        c2port_strobe_ck(dev);
 175
 176        /* LENGTH field (00b, LSB first -> 1 byte) */
 177        ops->c2d_set(dev, 0);
 178        c2port_strobe_ck(dev);
 179        ops->c2d_set(dev, 0);
 180        c2port_strobe_ck(dev);
 181
 182        /* DATA field */
 183        for (i = 0; i < 8; i++) {
 184                ops->c2d_set(dev, data & 0x01);
 185                c2port_strobe_ck(dev);
 186
 187                data >>= 1;
 188        }
 189
 190        /* WAIT field */
 191        ops->c2d_dir(dev, 1);
 192        timeout = 20;
 193        do {
 194                c2port_strobe_ck(dev);
 195                if (ops->c2d_get(dev))
 196                        break;
 197
 198                udelay(1);
 199        } while (--timeout > 0);
 200        if (timeout == 0)
 201                return -EIO;
 202
 203        /* STOP field */
 204        c2port_strobe_ck(dev);
 205
 206        return 0;
 207}
 208
 209static int c2port_read_dr(struct c2port_device *dev, u8 *data)
 210{
 211        struct c2port_ops *ops = dev->ops;
 212        int timeout, i;
 213
 214        /* START field */
 215        c2port_strobe_ck(dev);
 216
 217        /* INS field (00b, LSB first) */
 218        ops->c2d_dir(dev, 0);
 219        ops->c2d_set(dev, 0);
 220        c2port_strobe_ck(dev);
 221        ops->c2d_set(dev, 0);
 222        c2port_strobe_ck(dev);
 223
 224        /* LENGTH field (00b, LSB first -> 1 byte) */
 225        ops->c2d_set(dev, 0);
 226        c2port_strobe_ck(dev);
 227        ops->c2d_set(dev, 0);
 228        c2port_strobe_ck(dev);
 229
 230        /* WAIT field */
 231        ops->c2d_dir(dev, 1);
 232        timeout = 20;
 233        do {
 234                c2port_strobe_ck(dev);
 235                if (ops->c2d_get(dev))
 236                        break;
 237
 238                udelay(1);
 239        } while (--timeout > 0);
 240        if (timeout == 0)
 241                return -EIO;
 242
 243        /* DATA field */
 244        *data = 0;
 245        for (i = 0; i < 8; i++) {
 246                *data >>= 1;        /* shift in 8-bit DATA field LSB first */
 247
 248                c2port_strobe_ck(dev);
 249                if (ops->c2d_get(dev))
 250                        *data |= 0x80;
 251        }
 252
 253        /* STOP field */
 254        c2port_strobe_ck(dev);
 255
 256        return 0;
 257}
 258
 259static int c2port_poll_in_busy(struct c2port_device *dev)
 260{
 261        u8 addr;
 262        int ret, timeout = 20;
 263
 264        do {
 265                ret = (c2port_read_ar(dev, &addr));
 266                if (ret < 0)
 267                        return -EIO;
 268
 269                if (!(addr & 0x02))
 270                        break;
 271
 272                udelay(1);
 273        } while (--timeout > 0);
 274        if (timeout == 0)
 275                return -EIO;
 276
 277        return 0;
 278}
 279
 280static int c2port_poll_out_ready(struct c2port_device *dev)
 281{
 282        u8 addr;
 283        int ret, timeout = 10000; /* erase flash needs long time... */
 284
 285        do {
 286                ret = (c2port_read_ar(dev, &addr));
 287                if (ret < 0)
 288                        return -EIO;
 289
 290                if (addr & 0x01)
 291                        break;
 292
 293                udelay(1);
 294        } while (--timeout > 0);
 295        if (timeout == 0)
 296                return -EIO;
 297
 298        return 0;
 299}
 300
 301/*
 302 * sysfs methods
 303 */
 304
 305static ssize_t c2port_show_name(struct device *dev,
 306                                struct device_attribute *attr, char *buf)
 307{
 308        struct c2port_device *c2dev = dev_get_drvdata(dev);
 309
 310        return sprintf(buf, "%s\n", c2dev->name);
 311}
 312
 313static ssize_t c2port_show_flash_blocks_num(struct device *dev,
 314                                struct device_attribute *attr, char *buf)
 315{
 316        struct c2port_device *c2dev = dev_get_drvdata(dev);
 317        struct c2port_ops *ops = c2dev->ops;
 318
 319        return sprintf(buf, "%d\n", ops->blocks_num);
 320}
 321
 322static ssize_t c2port_show_flash_block_size(struct device *dev,
 323                                struct device_attribute *attr, char *buf)
 324{
 325        struct c2port_device *c2dev = dev_get_drvdata(dev);
 326        struct c2port_ops *ops = c2dev->ops;
 327
 328        return sprintf(buf, "%d\n", ops->block_size);
 329}
 330
 331static ssize_t c2port_show_flash_size(struct device *dev,
 332                                struct device_attribute *attr, char *buf)
 333{
 334        struct c2port_device *c2dev = dev_get_drvdata(dev);
 335        struct c2port_ops *ops = c2dev->ops;
 336
 337        return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
 338}
 339
 340static ssize_t c2port_show_access(struct device *dev,
 341                                struct device_attribute *attr, char *buf)
 342{
 343        struct c2port_device *c2dev = dev_get_drvdata(dev);
 344
 345        return sprintf(buf, "%d\n", c2dev->access);
 346}
 347
 348static ssize_t c2port_store_access(struct device *dev,
 349                                struct device_attribute *attr,
 350                                const char *buf, size_t count)
 351{
 352        struct c2port_device *c2dev = dev_get_drvdata(dev);
 353        struct c2port_ops *ops = c2dev->ops;
 354        int status, ret;
 355
 356        ret = sscanf(buf, "%d", &status);
 357        if (ret != 1)
 358                return -EINVAL;
 359
 360        mutex_lock(&c2dev->mutex);
 361
 362        c2dev->access = !!status;
 363
 364        /* If access is "on" clock should be HIGH _before_ setting the line
 365         * as output and data line should be set as INPUT anyway */
 366        if (c2dev->access)
 367                ops->c2ck_set(c2dev, 1);
 368        ops->access(c2dev, c2dev->access);
 369        if (c2dev->access)
 370                ops->c2d_dir(c2dev, 1);
 371
 372        mutex_unlock(&c2dev->mutex);
 373
 374        return count;
 375}
 376
 377static ssize_t c2port_store_reset(struct device *dev,
 378                                struct device_attribute *attr,
 379                                const char *buf, size_t count)
 380{
 381        struct c2port_device *c2dev = dev_get_drvdata(dev);
 382
 383        /* Check the device access status */
 384        if (!c2dev->access)
 385                return -EBUSY;
 386
 387        mutex_lock(&c2dev->mutex);
 388
 389        c2port_reset(c2dev);
 390        c2dev->flash_access = 0;
 391
 392        mutex_unlock(&c2dev->mutex);
 393
 394        return count;
 395}
 396
 397static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
 398{
 399        u8 data;
 400        int ret;
 401
 402        /* Select DEVICEID register for C2 data register accesses */
 403        c2port_write_ar(dev, C2PORT_DEVICEID);
 404
 405        /* Read and return the device ID register */
 406        ret = c2port_read_dr(dev, &data);
 407        if (ret < 0)
 408                return ret;
 409
 410        return sprintf(buf, "%d\n", data);
 411}
 412
 413static ssize_t c2port_show_dev_id(struct device *dev,
 414                                struct device_attribute *attr, char *buf)
 415{
 416        struct c2port_device *c2dev = dev_get_drvdata(dev);
 417        ssize_t ret;
 418
 419        /* Check the device access status */
 420        if (!c2dev->access)
 421                return -EBUSY;
 422
 423        mutex_lock(&c2dev->mutex);
 424        ret = __c2port_show_dev_id(c2dev, buf);
 425        mutex_unlock(&c2dev->mutex);
 426
 427        if (ret < 0)
 428                dev_err(dev, "cannot read from %s\n", c2dev->name);
 429
 430        return ret;
 431}
 432
 433static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
 434{
 435        u8 data;
 436        int ret;
 437
 438        /* Select REVID register for C2 data register accesses */
 439        c2port_write_ar(dev, C2PORT_REVID);
 440
 441        /* Read and return the revision ID register */
 442        ret = c2port_read_dr(dev, &data);
 443        if (ret < 0)
 444                return ret;
 445
 446        return sprintf(buf, "%d\n", data);
 447}
 448
 449static ssize_t c2port_show_rev_id(struct device *dev,
 450                                struct device_attribute *attr, char *buf)
 451{
 452        struct c2port_device *c2dev = dev_get_drvdata(dev);
 453        ssize_t ret;
 454
 455        /* Check the device access status */
 456        if (!c2dev->access)
 457                return -EBUSY;
 458
 459        mutex_lock(&c2dev->mutex);
 460        ret = __c2port_show_rev_id(c2dev, buf);
 461        mutex_unlock(&c2dev->mutex);
 462
 463        if (ret < 0)
 464                dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
 465
 466        return ret;
 467}
 468
 469static ssize_t c2port_show_flash_access(struct device *dev,
 470                                struct device_attribute *attr, char *buf)
 471{
 472        struct c2port_device *c2dev = dev_get_drvdata(dev);
 473
 474        return sprintf(buf, "%d\n", c2dev->flash_access);
 475}
 476
 477static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
 478                                                int status)
 479{
 480        int ret;
 481
 482        /* Check the device access status */
 483        if (!dev->access)
 484                return -EBUSY;
 485
 486        dev->flash_access = !!status;
 487
 488        /* If flash_access is off we have nothing to do... */
 489        if (dev->flash_access == 0)
 490                return 0;
 491
 492        /* Target the C2 flash programming control register for C2 data
 493         * register access */
 494        c2port_write_ar(dev, C2PORT_FPCTL);
 495
 496        /* Write the first keycode to enable C2 Flash programming */
 497        ret = c2port_write_dr(dev, 0x02);
 498        if (ret < 0)
 499                return ret;
 500
 501        /* Write the second keycode to enable C2 Flash programming */
 502        ret = c2port_write_dr(dev, 0x01);
 503        if (ret < 0)
 504                return ret;
 505
 506        /* Delay for at least 20ms to ensure the target is ready for
 507         * C2 flash programming */
 508        mdelay(25);
 509
 510        return 0;
 511}
 512
 513static ssize_t c2port_store_flash_access(struct device *dev,
 514                                struct device_attribute *attr,
 515                                const char *buf, size_t count)
 516{
 517        struct c2port_device *c2dev = dev_get_drvdata(dev);
 518        int status;
 519        ssize_t ret;
 520
 521        ret = sscanf(buf, "%d", &status);
 522        if (ret != 1)
 523                return -EINVAL;
 524
 525        mutex_lock(&c2dev->mutex);
 526        ret = __c2port_store_flash_access(c2dev, status);
 527        mutex_unlock(&c2dev->mutex);
 528
 529        if (ret < 0) {
 530                dev_err(c2dev->dev, "cannot enable %s flash programming\n",
 531                        c2dev->name);
 532                return ret;
 533        }
 534
 535        return count;
 536}
 537
 538static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
 539{
 540        u8 status;
 541        int ret;
 542
 543        /* Target the C2 flash programming data register for C2 data register
 544         * access.
 545         */
 546        c2port_write_ar(dev, C2PORT_FPDAT);
 547
 548        /* Send device erase command */
 549        c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
 550
 551        /* Wait for input acknowledge */
 552        ret = c2port_poll_in_busy(dev);
 553        if (ret < 0)
 554                return ret;
 555
 556        /* Should check status before starting FLASH access sequence */
 557
 558        /* Wait for status information */
 559        ret = c2port_poll_out_ready(dev);
 560        if (ret < 0)
 561                return ret;
 562
 563        /* Read flash programming interface status */
 564        ret = c2port_read_dr(dev, &status);
 565        if (ret < 0)
 566                return ret;
 567        if (status != C2PORT_COMMAND_OK)
 568                return -EBUSY;
 569
 570        /* Send a three-byte arming sequence to enable the device erase.
 571         * If the sequence is not received correctly, the command will be
 572         * ignored.
 573         * Sequence is: 0xde, 0xad, 0xa5.
 574         */
 575        c2port_write_dr(dev, 0xde);
 576        ret = c2port_poll_in_busy(dev);
 577        if (ret < 0)
 578                return ret;
 579        c2port_write_dr(dev, 0xad);
 580        ret = c2port_poll_in_busy(dev);
 581        if (ret < 0)
 582                return ret;
 583        c2port_write_dr(dev, 0xa5);
 584        ret = c2port_poll_in_busy(dev);
 585        if (ret < 0)
 586                return ret;
 587
 588        ret = c2port_poll_out_ready(dev);
 589        if (ret < 0)
 590                return ret;
 591
 592        return 0;
 593}
 594
 595static ssize_t c2port_store_flash_erase(struct device *dev,
 596                                struct device_attribute *attr,
 597                                const char *buf, size_t count)
 598{
 599        struct c2port_device *c2dev = dev_get_drvdata(dev);
 600        int ret;
 601
 602        /* Check the device and flash access status */
 603        if (!c2dev->access || !c2dev->flash_access)
 604                return -EBUSY;
 605
 606        mutex_lock(&c2dev->mutex);
 607        ret = __c2port_write_flash_erase(c2dev);
 608        mutex_unlock(&c2dev->mutex);
 609
 610        if (ret < 0) {
 611                dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
 612                return ret;
 613        }
 614
 615        return count;
 616}
 617
 618static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
 619                                char *buffer, loff_t offset, size_t count)
 620{
 621        struct c2port_ops *ops = dev->ops;
 622        u8 status, nread = 128;
 623        int i, ret;
 624
 625        /* Check for flash end */
 626        if (offset >= ops->block_size * ops->blocks_num)
 627                return 0;
 628
 629        if (ops->block_size * ops->blocks_num - offset < nread)
 630                nread = ops->block_size * ops->blocks_num - offset;
 631        if (count < nread)
 632                nread = count;
 633        if (nread == 0)
 634                return nread;
 635
 636        /* Target the C2 flash programming data register for C2 data register
 637         * access */
 638        c2port_write_ar(dev, C2PORT_FPDAT);
 639
 640        /* Send flash block read command */
 641        c2port_write_dr(dev, C2PORT_BLOCK_READ);
 642
 643        /* Wait for input acknowledge */
 644        ret = c2port_poll_in_busy(dev);
 645        if (ret < 0)
 646                return ret;
 647
 648        /* Should check status before starting FLASH access sequence */
 649
 650        /* Wait for status information */
 651        ret = c2port_poll_out_ready(dev);
 652        if (ret < 0)
 653                return ret;
 654
 655        /* Read flash programming interface status */
 656        ret = c2port_read_dr(dev, &status);
 657        if (ret < 0)
 658                return ret;
 659        if (status != C2PORT_COMMAND_OK)
 660                return -EBUSY;
 661
 662        /* Send address high byte */
 663        c2port_write_dr(dev, offset >> 8);
 664        ret = c2port_poll_in_busy(dev);
 665        if (ret < 0)
 666                return ret;
 667
 668        /* Send address low byte */
 669        c2port_write_dr(dev, offset & 0x00ff);
 670        ret = c2port_poll_in_busy(dev);
 671        if (ret < 0)
 672                return ret;
 673
 674        /* Send address block size */
 675        c2port_write_dr(dev, nread);
 676        ret = c2port_poll_in_busy(dev);
 677        if (ret < 0)
 678                return ret;
 679
 680        /* Should check status before reading FLASH block */
 681
 682        /* Wait for status information */
 683        ret = c2port_poll_out_ready(dev);
 684        if (ret < 0)
 685                return ret;
 686
 687        /* Read flash programming interface status */
 688        ret = c2port_read_dr(dev, &status);
 689        if (ret < 0)
 690                return ret;
 691        if (status != C2PORT_COMMAND_OK)
 692                return -EBUSY;
 693
 694        /* Read flash block */
 695        for (i = 0; i < nread; i++) {
 696                ret = c2port_poll_out_ready(dev);
 697                if (ret < 0)
 698                        return ret;
 699
 700                ret = c2port_read_dr(dev, buffer+i);
 701                if (ret < 0)
 702                        return ret;
 703        }
 704
 705        return nread;
 706}
 707
 708static ssize_t c2port_read_flash_data(struct kobject *kobj,
 709                                struct bin_attribute *attr,
 710                                char *buffer, loff_t offset, size_t count)
 711{
 712        struct c2port_device *c2dev =
 713                        dev_get_drvdata(container_of(kobj,
 714                                                struct device, kobj));
 715        ssize_t ret;
 716
 717        /* Check the device and flash access status */
 718        if (!c2dev->access || !c2dev->flash_access)
 719                return -EBUSY;
 720
 721        mutex_lock(&c2dev->mutex);
 722        ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
 723        mutex_unlock(&c2dev->mutex);
 724
 725        if (ret < 0)
 726                dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
 727
 728        return ret;
 729}
 730
 731static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
 732                                char *buffer, loff_t offset, size_t count)
 733{
 734        struct c2port_ops *ops = dev->ops;
 735        u8 status, nwrite = 128;
 736        int i, ret;
 737
 738        if (nwrite > count)
 739                nwrite = count;
 740        if (ops->block_size * ops->blocks_num - offset < nwrite)
 741                nwrite = ops->block_size * ops->blocks_num - offset;
 742
 743        /* Check for flash end */
 744        if (offset >= ops->block_size * ops->blocks_num)
 745                return -EINVAL;
 746
 747        /* Target the C2 flash programming data register for C2 data register
 748         * access */
 749        c2port_write_ar(dev, C2PORT_FPDAT);
 750
 751        /* Send flash block write command */
 752        c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
 753
 754        /* Wait for input acknowledge */
 755        ret = c2port_poll_in_busy(dev);
 756        if (ret < 0)
 757                return ret;
 758
 759        /* Should check status before starting FLASH access sequence */
 760
 761        /* Wait for status information */
 762        ret = c2port_poll_out_ready(dev);
 763        if (ret < 0)
 764                return ret;
 765
 766        /* Read flash programming interface status */
 767        ret = c2port_read_dr(dev, &status);
 768        if (ret < 0)
 769                return ret;
 770        if (status != C2PORT_COMMAND_OK)
 771                return -EBUSY;
 772
 773        /* Send address high byte */
 774        c2port_write_dr(dev, offset >> 8);
 775        ret = c2port_poll_in_busy(dev);
 776        if (ret < 0)
 777                return ret;
 778
 779        /* Send address low byte */
 780        c2port_write_dr(dev, offset & 0x00ff);
 781        ret = c2port_poll_in_busy(dev);
 782        if (ret < 0)
 783                return ret;
 784
 785        /* Send address block size */
 786        c2port_write_dr(dev, nwrite);
 787        ret = c2port_poll_in_busy(dev);
 788        if (ret < 0)
 789                return ret;
 790
 791        /* Should check status before writing FLASH block */
 792
 793        /* Wait for status information */
 794        ret = c2port_poll_out_ready(dev);
 795        if (ret < 0)
 796                return ret;
 797
 798        /* Read flash programming interface status */
 799        ret = c2port_read_dr(dev, &status);
 800        if (ret < 0)
 801                return ret;
 802        if (status != C2PORT_COMMAND_OK)
 803                return -EBUSY;
 804
 805        /* Write flash block */
 806        for (i = 0; i < nwrite; i++) {
 807                ret = c2port_write_dr(dev, *(buffer+i));
 808                if (ret < 0)
 809                        return ret;
 810
 811                ret = c2port_poll_in_busy(dev);
 812                if (ret < 0)
 813                        return ret;
 814
 815        }
 816
 817        /* Wait for last flash write to complete */
 818        ret = c2port_poll_out_ready(dev);
 819        if (ret < 0)
 820                return ret;
 821
 822        return nwrite;
 823}
 824
 825static ssize_t c2port_write_flash_data(struct kobject *kobj,
 826                                struct bin_attribute *attr,
 827                                char *buffer, loff_t offset, size_t count)
 828{
 829        struct c2port_device *c2dev =
 830                        dev_get_drvdata(container_of(kobj,
 831                                                struct device, kobj));
 832        int ret;
 833
 834        /* Check the device access status */
 835        if (!c2dev->access || !c2dev->flash_access)
 836                return -EBUSY;
 837
 838        mutex_lock(&c2dev->mutex);
 839        ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
 840        mutex_unlock(&c2dev->mutex);
 841
 842        if (ret < 0)
 843                dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
 844
 845        return ret;
 846}
 847
 848/*
 849 * Class attributes
 850 */
 851
 852static struct device_attribute c2port_attrs[] = {
 853        __ATTR(name, 0444, c2port_show_name, NULL),
 854        __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL),
 855        __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL),
 856        __ATTR(flash_size, 0444, c2port_show_flash_size, NULL),
 857        __ATTR(access, 0644, c2port_show_access, c2port_store_access),
 858        __ATTR(reset, 0200, NULL, c2port_store_reset),
 859        __ATTR(dev_id, 0444, c2port_show_dev_id, NULL),
 860        __ATTR(rev_id, 0444, c2port_show_rev_id, NULL),
 861
 862        __ATTR(flash_access, 0644, c2port_show_flash_access,
 863                                        c2port_store_flash_access),
 864        __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase),
 865        __ATTR_NULL,
 866};
 867
 868static struct bin_attribute c2port_bin_attrs = {
 869        .attr        = {
 870                .name        = "flash_data",
 871                .mode        = 0644
 872        },
 873        .read        = c2port_read_flash_data,
 874        .write        = c2port_write_flash_data,
 875        /* .size is computed at run-time */
 876};
 877
 878/*
 879 * Exported functions
 880 */
 881
 882struct c2port_device *c2port_device_register(char *name,
 883                                        struct c2port_ops *ops, void *devdata)
 884{
 885        struct c2port_device *c2dev;
 886        int id, ret;
 887
 888        if (unlikely(!ops) || unlikely(!ops->access) || \
 889                unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
 890                unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
 891                return ERR_PTR(-EINVAL);
 892
 893        c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL);
 894        if (unlikely(!c2dev))
 895                return ERR_PTR(-ENOMEM);
 896
 897        ret = idr_pre_get(&c2port_idr, GFP_KERNEL);
 898        if (!ret) {
 899                ret = -ENOMEM;
 900                goto error_idr_get_new;
 901        }
 902
 903        spin_lock_irq(&c2port_idr_lock);
 904        ret = idr_get_new(&c2port_idr, c2dev, &id);
 905        spin_unlock_irq(&c2port_idr_lock);
 906
 907        if (ret < 0)
 908                goto error_idr_get_new;
 909        c2dev->id = id;
 910
 911        c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
 912                                        "c2port%d", id);
 913        if (unlikely(!c2dev->dev)) {
 914                ret = -ENOMEM;
 915                goto error_device_create;
 916        }
 917        dev_set_drvdata(c2dev->dev, c2dev);
 918
 919        strncpy(c2dev->name, name, C2PORT_NAME_LEN);
 920        c2dev->ops = ops;
 921        mutex_init(&c2dev->mutex);
 922
 923        /* Create binary file */
 924        c2port_bin_attrs.size = ops->blocks_num * ops->block_size;
 925        ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs);
 926        if (unlikely(ret))
 927                goto error_device_create_bin_file;
 928
 929        /* By default C2 port access is off */
 930        c2dev->access = c2dev->flash_access = 0;
 931        ops->access(c2dev, 0);
 932
 933        dev_info(c2dev->dev, "C2 port %s added\n", name);
 934        dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
 935                                "(%d bytes total)\n",
 936                                name, ops->blocks_num, ops->block_size,
 937                                ops->blocks_num * ops->block_size);
 938
 939        return c2dev;
 940
 941error_device_create_bin_file:
 942        device_destroy(c2port_class, 0);
 943
 944error_device_create:
 945        spin_lock_irq(&c2port_idr_lock);
 946        idr_remove(&c2port_idr, id);
 947        spin_unlock_irq(&c2port_idr_lock);
 948
 949error_idr_get_new:
 950        kfree(c2dev);
 951
 952        return ERR_PTR(ret);
 953}
 954EXPORT_SYMBOL(c2port_device_register);
 955
 956void c2port_device_unregister(struct c2port_device *c2dev)
 957{
 958        if (!c2dev)
 959                return;
 960
 961        dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
 962
 963        device_remove_bin_file(c2dev->dev, &c2port_bin_attrs);
 964        spin_lock_irq(&c2port_idr_lock);
 965        idr_remove(&c2port_idr, c2dev->id);
 966        spin_unlock_irq(&c2port_idr_lock);
 967
 968        device_destroy(c2port_class, c2dev->id);
 969
 970        kfree(c2dev);
 971}
 972EXPORT_SYMBOL(c2port_device_unregister);
 973
 974/*
 975 * Module stuff
 976 */
 977
 978static int __init c2port_init(void)
 979{
 980        printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
 981                " - (C) 2007 Rodolfo Giometti\n");
 982
 983        c2port_class = class_create(THIS_MODULE, "c2port");
 984        if (!c2port_class) {
 985                printk(KERN_ERR "c2port: failed to allocate class\n");
 986                return -ENOMEM;
 987        }
 988        c2port_class->dev_attrs = c2port_attrs;
 989
 990        return 0;
 991}
 992
 993static void __exit c2port_exit(void)
 994{
 995        class_destroy(c2port_class);
 996}
 997
 998module_init(c2port_init);
 999module_exit(c2port_exit);
1000
1001MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
1002MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
1003MODULE_LICENSE("GPL");