0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/device.h>
0012 #include <linux/errno.h>
0013 #include <linux/err.h>
0014 #include <linux/kernel.h>
0015 #include <linux/ctype.h>
0016 #include <linux/delay.h>
0017 #include <linux/idr.h>
0018 #include <linux/sched.h>
0019 #include <linux/slab.h>
0020
0021 #include <linux/c2port.h>
0022
0023 #define DRIVER_NAME "c2port"
0024 #define DRIVER_VERSION "0.51.0"
0025
0026 static DEFINE_SPINLOCK(c2port_idr_lock);
0027 static DEFINE_IDR(c2port_idr);
0028
0029
0030
0031
0032
0033 static struct class *c2port_class;
0034
0035
0036
0037
0038
0039
0040 #define C2PORT_DEVICEID 0x00
0041 #define C2PORT_REVID 0x01
0042 #define C2PORT_FPCTL 0x02
0043 #define C2PORT_FPDAT 0xB4
0044
0045
0046 #define C2PORT_GET_VERSION 0x01
0047 #define C2PORT_DEVICE_ERASE 0x03
0048 #define C2PORT_BLOCK_READ 0x06
0049 #define C2PORT_BLOCK_WRITE 0x07
0050 #define C2PORT_PAGE_ERASE 0x08
0051
0052
0053 #define C2PORT_INVALID_COMMAND 0x00
0054 #define C2PORT_COMMAND_FAILED 0x02
0055 #define C2PORT_COMMAND_OK 0x0d
0056
0057
0058
0059
0060
0061 static void c2port_reset(struct c2port_device *dev)
0062 {
0063 struct c2port_ops *ops = dev->ops;
0064
0065
0066
0067
0068 local_irq_disable();
0069 ops->c2ck_set(dev, 0);
0070 udelay(25);
0071 ops->c2ck_set(dev, 1);
0072 local_irq_enable();
0073
0074 udelay(1);
0075 }
0076
0077 static void c2port_strobe_ck(struct c2port_device *dev)
0078 {
0079 struct c2port_ops *ops = dev->ops;
0080
0081
0082
0083
0084
0085
0086 local_irq_disable();
0087 ops->c2ck_set(dev, 0);
0088 udelay(1);
0089 ops->c2ck_set(dev, 1);
0090 local_irq_enable();
0091
0092 udelay(1);
0093 }
0094
0095
0096
0097
0098
0099 static void c2port_write_ar(struct c2port_device *dev, u8 addr)
0100 {
0101 struct c2port_ops *ops = dev->ops;
0102 int i;
0103
0104
0105 c2port_strobe_ck(dev);
0106
0107
0108 ops->c2d_dir(dev, 0);
0109 ops->c2d_set(dev, 1);
0110 c2port_strobe_ck(dev);
0111 ops->c2d_set(dev, 1);
0112 c2port_strobe_ck(dev);
0113
0114
0115 for (i = 0; i < 8; i++) {
0116 ops->c2d_set(dev, addr & 0x01);
0117 c2port_strobe_ck(dev);
0118
0119 addr >>= 1;
0120 }
0121
0122
0123 ops->c2d_dir(dev, 1);
0124 c2port_strobe_ck(dev);
0125 }
0126
0127 static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
0128 {
0129 struct c2port_ops *ops = dev->ops;
0130 int i;
0131
0132
0133 c2port_strobe_ck(dev);
0134
0135
0136 ops->c2d_dir(dev, 0);
0137 ops->c2d_set(dev, 0);
0138 c2port_strobe_ck(dev);
0139 ops->c2d_set(dev, 1);
0140 c2port_strobe_ck(dev);
0141
0142
0143 ops->c2d_dir(dev, 1);
0144 *addr = 0;
0145 for (i = 0; i < 8; i++) {
0146 *addr >>= 1;
0147
0148 c2port_strobe_ck(dev);
0149 if (ops->c2d_get(dev))
0150 *addr |= 0x80;
0151 }
0152
0153
0154 c2port_strobe_ck(dev);
0155
0156 return 0;
0157 }
0158
0159 static int c2port_write_dr(struct c2port_device *dev, u8 data)
0160 {
0161 struct c2port_ops *ops = dev->ops;
0162 int timeout, i;
0163
0164
0165 c2port_strobe_ck(dev);
0166
0167
0168 ops->c2d_dir(dev, 0);
0169 ops->c2d_set(dev, 1);
0170 c2port_strobe_ck(dev);
0171 ops->c2d_set(dev, 0);
0172 c2port_strobe_ck(dev);
0173
0174
0175 ops->c2d_set(dev, 0);
0176 c2port_strobe_ck(dev);
0177 ops->c2d_set(dev, 0);
0178 c2port_strobe_ck(dev);
0179
0180
0181 for (i = 0; i < 8; i++) {
0182 ops->c2d_set(dev, data & 0x01);
0183 c2port_strobe_ck(dev);
0184
0185 data >>= 1;
0186 }
0187
0188
0189 ops->c2d_dir(dev, 1);
0190 timeout = 20;
0191 do {
0192 c2port_strobe_ck(dev);
0193 if (ops->c2d_get(dev))
0194 break;
0195
0196 udelay(1);
0197 } while (--timeout > 0);
0198 if (timeout == 0)
0199 return -EIO;
0200
0201
0202 c2port_strobe_ck(dev);
0203
0204 return 0;
0205 }
0206
0207 static int c2port_read_dr(struct c2port_device *dev, u8 *data)
0208 {
0209 struct c2port_ops *ops = dev->ops;
0210 int timeout, i;
0211
0212
0213 c2port_strobe_ck(dev);
0214
0215
0216 ops->c2d_dir(dev, 0);
0217 ops->c2d_set(dev, 0);
0218 c2port_strobe_ck(dev);
0219 ops->c2d_set(dev, 0);
0220 c2port_strobe_ck(dev);
0221
0222
0223 ops->c2d_set(dev, 0);
0224 c2port_strobe_ck(dev);
0225 ops->c2d_set(dev, 0);
0226 c2port_strobe_ck(dev);
0227
0228
0229 ops->c2d_dir(dev, 1);
0230 timeout = 20;
0231 do {
0232 c2port_strobe_ck(dev);
0233 if (ops->c2d_get(dev))
0234 break;
0235
0236 udelay(1);
0237 } while (--timeout > 0);
0238 if (timeout == 0)
0239 return -EIO;
0240
0241
0242 *data = 0;
0243 for (i = 0; i < 8; i++) {
0244 *data >>= 1;
0245
0246 c2port_strobe_ck(dev);
0247 if (ops->c2d_get(dev))
0248 *data |= 0x80;
0249 }
0250
0251
0252 c2port_strobe_ck(dev);
0253
0254 return 0;
0255 }
0256
0257 static int c2port_poll_in_busy(struct c2port_device *dev)
0258 {
0259 u8 addr;
0260 int ret, timeout = 20;
0261
0262 do {
0263 ret = (c2port_read_ar(dev, &addr));
0264 if (ret < 0)
0265 return -EIO;
0266
0267 if (!(addr & 0x02))
0268 break;
0269
0270 udelay(1);
0271 } while (--timeout > 0);
0272 if (timeout == 0)
0273 return -EIO;
0274
0275 return 0;
0276 }
0277
0278 static int c2port_poll_out_ready(struct c2port_device *dev)
0279 {
0280 u8 addr;
0281 int ret, timeout = 10000;
0282
0283 do {
0284 ret = (c2port_read_ar(dev, &addr));
0285 if (ret < 0)
0286 return -EIO;
0287
0288 if (addr & 0x01)
0289 break;
0290
0291 udelay(1);
0292 } while (--timeout > 0);
0293 if (timeout == 0)
0294 return -EIO;
0295
0296 return 0;
0297 }
0298
0299
0300
0301
0302
0303 static ssize_t c2port_show_name(struct device *dev,
0304 struct device_attribute *attr, char *buf)
0305 {
0306 struct c2port_device *c2dev = dev_get_drvdata(dev);
0307
0308 return sprintf(buf, "%s\n", c2dev->name);
0309 }
0310 static DEVICE_ATTR(name, 0444, c2port_show_name, NULL);
0311
0312 static ssize_t c2port_show_flash_blocks_num(struct device *dev,
0313 struct device_attribute *attr, char *buf)
0314 {
0315 struct c2port_device *c2dev = dev_get_drvdata(dev);
0316 struct c2port_ops *ops = c2dev->ops;
0317
0318 return sprintf(buf, "%d\n", ops->blocks_num);
0319 }
0320 static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL);
0321
0322 static ssize_t c2port_show_flash_block_size(struct device *dev,
0323 struct device_attribute *attr, char *buf)
0324 {
0325 struct c2port_device *c2dev = dev_get_drvdata(dev);
0326 struct c2port_ops *ops = c2dev->ops;
0327
0328 return sprintf(buf, "%d\n", ops->block_size);
0329 }
0330 static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL);
0331
0332 static ssize_t c2port_show_flash_size(struct device *dev,
0333 struct device_attribute *attr, char *buf)
0334 {
0335 struct c2port_device *c2dev = dev_get_drvdata(dev);
0336 struct c2port_ops *ops = c2dev->ops;
0337
0338 return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
0339 }
0340 static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL);
0341
0342 static ssize_t access_show(struct device *dev, struct device_attribute *attr,
0343 char *buf)
0344 {
0345 struct c2port_device *c2dev = dev_get_drvdata(dev);
0346
0347 return sprintf(buf, "%d\n", c2dev->access);
0348 }
0349
0350 static ssize_t access_store(struct device *dev, struct device_attribute *attr,
0351 const char *buf, size_t count)
0352 {
0353 struct c2port_device *c2dev = dev_get_drvdata(dev);
0354 struct c2port_ops *ops = c2dev->ops;
0355 int status, ret;
0356
0357 ret = sscanf(buf, "%d", &status);
0358 if (ret != 1)
0359 return -EINVAL;
0360
0361 mutex_lock(&c2dev->mutex);
0362
0363 c2dev->access = !!status;
0364
0365
0366
0367 if (c2dev->access)
0368 ops->c2ck_set(c2dev, 1);
0369 ops->access(c2dev, c2dev->access);
0370 if (c2dev->access)
0371 ops->c2d_dir(c2dev, 1);
0372
0373 mutex_unlock(&c2dev->mutex);
0374
0375 return count;
0376 }
0377 static DEVICE_ATTR_RW(access);
0378
0379 static ssize_t c2port_store_reset(struct device *dev,
0380 struct device_attribute *attr,
0381 const char *buf, size_t count)
0382 {
0383 struct c2port_device *c2dev = dev_get_drvdata(dev);
0384
0385
0386 if (!c2dev->access)
0387 return -EBUSY;
0388
0389 mutex_lock(&c2dev->mutex);
0390
0391 c2port_reset(c2dev);
0392 c2dev->flash_access = 0;
0393
0394 mutex_unlock(&c2dev->mutex);
0395
0396 return count;
0397 }
0398 static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset);
0399
0400 static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
0401 {
0402 u8 data;
0403 int ret;
0404
0405
0406 c2port_write_ar(dev, C2PORT_DEVICEID);
0407
0408
0409 ret = c2port_read_dr(dev, &data);
0410 if (ret < 0)
0411 return ret;
0412
0413 return sprintf(buf, "%d\n", data);
0414 }
0415
0416 static ssize_t c2port_show_dev_id(struct device *dev,
0417 struct device_attribute *attr, char *buf)
0418 {
0419 struct c2port_device *c2dev = dev_get_drvdata(dev);
0420 ssize_t ret;
0421
0422
0423 if (!c2dev->access)
0424 return -EBUSY;
0425
0426 mutex_lock(&c2dev->mutex);
0427 ret = __c2port_show_dev_id(c2dev, buf);
0428 mutex_unlock(&c2dev->mutex);
0429
0430 if (ret < 0)
0431 dev_err(dev, "cannot read from %s\n", c2dev->name);
0432
0433 return ret;
0434 }
0435 static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL);
0436
0437 static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
0438 {
0439 u8 data;
0440 int ret;
0441
0442
0443 c2port_write_ar(dev, C2PORT_REVID);
0444
0445
0446 ret = c2port_read_dr(dev, &data);
0447 if (ret < 0)
0448 return ret;
0449
0450 return sprintf(buf, "%d\n", data);
0451 }
0452
0453 static ssize_t c2port_show_rev_id(struct device *dev,
0454 struct device_attribute *attr, char *buf)
0455 {
0456 struct c2port_device *c2dev = dev_get_drvdata(dev);
0457 ssize_t ret;
0458
0459
0460 if (!c2dev->access)
0461 return -EBUSY;
0462
0463 mutex_lock(&c2dev->mutex);
0464 ret = __c2port_show_rev_id(c2dev, buf);
0465 mutex_unlock(&c2dev->mutex);
0466
0467 if (ret < 0)
0468 dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
0469
0470 return ret;
0471 }
0472 static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL);
0473
0474 static ssize_t c2port_show_flash_access(struct device *dev,
0475 struct device_attribute *attr, char *buf)
0476 {
0477 struct c2port_device *c2dev = dev_get_drvdata(dev);
0478
0479 return sprintf(buf, "%d\n", c2dev->flash_access);
0480 }
0481
0482 static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
0483 int status)
0484 {
0485 int ret;
0486
0487
0488 if (!dev->access)
0489 return -EBUSY;
0490
0491 dev->flash_access = !!status;
0492
0493
0494 if (dev->flash_access == 0)
0495 return 0;
0496
0497
0498
0499 c2port_write_ar(dev, C2PORT_FPCTL);
0500
0501
0502 ret = c2port_write_dr(dev, 0x02);
0503 if (ret < 0)
0504 return ret;
0505
0506
0507 ret = c2port_write_dr(dev, 0x01);
0508 if (ret < 0)
0509 return ret;
0510
0511
0512
0513 mdelay(25);
0514
0515 return 0;
0516 }
0517
0518 static ssize_t c2port_store_flash_access(struct device *dev,
0519 struct device_attribute *attr,
0520 const char *buf, size_t count)
0521 {
0522 struct c2port_device *c2dev = dev_get_drvdata(dev);
0523 int status;
0524 ssize_t ret;
0525
0526 ret = sscanf(buf, "%d", &status);
0527 if (ret != 1)
0528 return -EINVAL;
0529
0530 mutex_lock(&c2dev->mutex);
0531 ret = __c2port_store_flash_access(c2dev, status);
0532 mutex_unlock(&c2dev->mutex);
0533
0534 if (ret < 0) {
0535 dev_err(c2dev->dev, "cannot enable %s flash programming\n",
0536 c2dev->name);
0537 return ret;
0538 }
0539
0540 return count;
0541 }
0542 static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access,
0543 c2port_store_flash_access);
0544
0545 static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
0546 {
0547 u8 status;
0548 int ret;
0549
0550
0551
0552
0553 c2port_write_ar(dev, C2PORT_FPDAT);
0554
0555
0556 c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
0557
0558
0559 ret = c2port_poll_in_busy(dev);
0560 if (ret < 0)
0561 return ret;
0562
0563
0564
0565
0566 ret = c2port_poll_out_ready(dev);
0567 if (ret < 0)
0568 return ret;
0569
0570
0571 ret = c2port_read_dr(dev, &status);
0572 if (ret < 0)
0573 return ret;
0574 if (status != C2PORT_COMMAND_OK)
0575 return -EBUSY;
0576
0577
0578
0579
0580
0581
0582 c2port_write_dr(dev, 0xde);
0583 ret = c2port_poll_in_busy(dev);
0584 if (ret < 0)
0585 return ret;
0586 c2port_write_dr(dev, 0xad);
0587 ret = c2port_poll_in_busy(dev);
0588 if (ret < 0)
0589 return ret;
0590 c2port_write_dr(dev, 0xa5);
0591 ret = c2port_poll_in_busy(dev);
0592 if (ret < 0)
0593 return ret;
0594
0595 ret = c2port_poll_out_ready(dev);
0596 if (ret < 0)
0597 return ret;
0598
0599 return 0;
0600 }
0601
0602 static ssize_t c2port_store_flash_erase(struct device *dev,
0603 struct device_attribute *attr,
0604 const char *buf, size_t count)
0605 {
0606 struct c2port_device *c2dev = dev_get_drvdata(dev);
0607 int ret;
0608
0609
0610 if (!c2dev->access || !c2dev->flash_access)
0611 return -EBUSY;
0612
0613 mutex_lock(&c2dev->mutex);
0614 ret = __c2port_write_flash_erase(c2dev);
0615 mutex_unlock(&c2dev->mutex);
0616
0617 if (ret < 0) {
0618 dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
0619 return ret;
0620 }
0621
0622 return count;
0623 }
0624 static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase);
0625
0626 static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
0627 char *buffer, loff_t offset, size_t count)
0628 {
0629 struct c2port_ops *ops = dev->ops;
0630 u8 status, nread = 128;
0631 int i, ret;
0632
0633
0634 if (offset >= ops->block_size * ops->blocks_num)
0635 return 0;
0636
0637 if (ops->block_size * ops->blocks_num - offset < nread)
0638 nread = ops->block_size * ops->blocks_num - offset;
0639 if (count < nread)
0640 nread = count;
0641 if (nread == 0)
0642 return nread;
0643
0644
0645
0646 c2port_write_ar(dev, C2PORT_FPDAT);
0647
0648
0649 c2port_write_dr(dev, C2PORT_BLOCK_READ);
0650
0651
0652 ret = c2port_poll_in_busy(dev);
0653 if (ret < 0)
0654 return ret;
0655
0656
0657
0658
0659 ret = c2port_poll_out_ready(dev);
0660 if (ret < 0)
0661 return ret;
0662
0663
0664 ret = c2port_read_dr(dev, &status);
0665 if (ret < 0)
0666 return ret;
0667 if (status != C2PORT_COMMAND_OK)
0668 return -EBUSY;
0669
0670
0671 c2port_write_dr(dev, offset >> 8);
0672 ret = c2port_poll_in_busy(dev);
0673 if (ret < 0)
0674 return ret;
0675
0676
0677 c2port_write_dr(dev, offset & 0x00ff);
0678 ret = c2port_poll_in_busy(dev);
0679 if (ret < 0)
0680 return ret;
0681
0682
0683 c2port_write_dr(dev, nread);
0684 ret = c2port_poll_in_busy(dev);
0685 if (ret < 0)
0686 return ret;
0687
0688
0689
0690
0691 ret = c2port_poll_out_ready(dev);
0692 if (ret < 0)
0693 return ret;
0694
0695
0696 ret = c2port_read_dr(dev, &status);
0697 if (ret < 0)
0698 return ret;
0699 if (status != C2PORT_COMMAND_OK)
0700 return -EBUSY;
0701
0702
0703 for (i = 0; i < nread; i++) {
0704 ret = c2port_poll_out_ready(dev);
0705 if (ret < 0)
0706 return ret;
0707
0708 ret = c2port_read_dr(dev, buffer+i);
0709 if (ret < 0)
0710 return ret;
0711 }
0712
0713 return nread;
0714 }
0715
0716 static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj,
0717 struct bin_attribute *attr,
0718 char *buffer, loff_t offset, size_t count)
0719 {
0720 struct c2port_device *c2dev = dev_get_drvdata(kobj_to_dev(kobj));
0721 ssize_t ret;
0722
0723
0724 if (!c2dev->access || !c2dev->flash_access)
0725 return -EBUSY;
0726
0727 mutex_lock(&c2dev->mutex);
0728 ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
0729 mutex_unlock(&c2dev->mutex);
0730
0731 if (ret < 0)
0732 dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
0733
0734 return ret;
0735 }
0736
0737 static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
0738 char *buffer, loff_t offset, size_t count)
0739 {
0740 struct c2port_ops *ops = dev->ops;
0741 u8 status, nwrite = 128;
0742 int i, ret;
0743
0744 if (nwrite > count)
0745 nwrite = count;
0746 if (ops->block_size * ops->blocks_num - offset < nwrite)
0747 nwrite = ops->block_size * ops->blocks_num - offset;
0748
0749
0750 if (offset >= ops->block_size * ops->blocks_num)
0751 return -EINVAL;
0752
0753
0754
0755 c2port_write_ar(dev, C2PORT_FPDAT);
0756
0757
0758 c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
0759
0760
0761 ret = c2port_poll_in_busy(dev);
0762 if (ret < 0)
0763 return ret;
0764
0765
0766
0767
0768 ret = c2port_poll_out_ready(dev);
0769 if (ret < 0)
0770 return ret;
0771
0772
0773 ret = c2port_read_dr(dev, &status);
0774 if (ret < 0)
0775 return ret;
0776 if (status != C2PORT_COMMAND_OK)
0777 return -EBUSY;
0778
0779
0780 c2port_write_dr(dev, offset >> 8);
0781 ret = c2port_poll_in_busy(dev);
0782 if (ret < 0)
0783 return ret;
0784
0785
0786 c2port_write_dr(dev, offset & 0x00ff);
0787 ret = c2port_poll_in_busy(dev);
0788 if (ret < 0)
0789 return ret;
0790
0791
0792 c2port_write_dr(dev, nwrite);
0793 ret = c2port_poll_in_busy(dev);
0794 if (ret < 0)
0795 return ret;
0796
0797
0798
0799
0800 ret = c2port_poll_out_ready(dev);
0801 if (ret < 0)
0802 return ret;
0803
0804
0805 ret = c2port_read_dr(dev, &status);
0806 if (ret < 0)
0807 return ret;
0808 if (status != C2PORT_COMMAND_OK)
0809 return -EBUSY;
0810
0811
0812 for (i = 0; i < nwrite; i++) {
0813 ret = c2port_write_dr(dev, *(buffer+i));
0814 if (ret < 0)
0815 return ret;
0816
0817 ret = c2port_poll_in_busy(dev);
0818 if (ret < 0)
0819 return ret;
0820
0821 }
0822
0823
0824 ret = c2port_poll_out_ready(dev);
0825 if (ret < 0)
0826 return ret;
0827
0828 return nwrite;
0829 }
0830
0831 static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj,
0832 struct bin_attribute *attr,
0833 char *buffer, loff_t offset, size_t count)
0834 {
0835 struct c2port_device *c2dev = dev_get_drvdata(kobj_to_dev(kobj));
0836 int ret;
0837
0838
0839 if (!c2dev->access || !c2dev->flash_access)
0840 return -EBUSY;
0841
0842 mutex_lock(&c2dev->mutex);
0843 ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
0844 mutex_unlock(&c2dev->mutex);
0845
0846 if (ret < 0)
0847 dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
0848
0849 return ret;
0850 }
0851
0852 static BIN_ATTR(flash_data, 0644, c2port_read_flash_data,
0853 c2port_write_flash_data, 0);
0854
0855
0856
0857
0858 static struct attribute *c2port_attrs[] = {
0859 &dev_attr_name.attr,
0860 &dev_attr_flash_blocks_num.attr,
0861 &dev_attr_flash_block_size.attr,
0862 &dev_attr_flash_size.attr,
0863 &dev_attr_access.attr,
0864 &dev_attr_reset.attr,
0865 &dev_attr_dev_id.attr,
0866 &dev_attr_rev_id.attr,
0867 &dev_attr_flash_access.attr,
0868 &dev_attr_flash_erase.attr,
0869 NULL,
0870 };
0871
0872 static struct bin_attribute *c2port_bin_attrs[] = {
0873 &bin_attr_flash_data,
0874 NULL,
0875 };
0876
0877 static const struct attribute_group c2port_group = {
0878 .attrs = c2port_attrs,
0879 .bin_attrs = c2port_bin_attrs,
0880 };
0881
0882 static const struct attribute_group *c2port_groups[] = {
0883 &c2port_group,
0884 NULL,
0885 };
0886
0887
0888
0889
0890
0891 struct c2port_device *c2port_device_register(char *name,
0892 struct c2port_ops *ops, void *devdata)
0893 {
0894 struct c2port_device *c2dev;
0895 int ret;
0896
0897 if (unlikely(!ops) || unlikely(!ops->access) || \
0898 unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
0899 unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
0900 return ERR_PTR(-EINVAL);
0901
0902 c2dev = kzalloc(sizeof(struct c2port_device), GFP_KERNEL);
0903 if (unlikely(!c2dev))
0904 return ERR_PTR(-ENOMEM);
0905
0906 idr_preload(GFP_KERNEL);
0907 spin_lock_irq(&c2port_idr_lock);
0908 ret = idr_alloc(&c2port_idr, c2dev, 0, 0, GFP_NOWAIT);
0909 spin_unlock_irq(&c2port_idr_lock);
0910 idr_preload_end();
0911
0912 if (ret < 0)
0913 goto error_idr_alloc;
0914 c2dev->id = ret;
0915
0916 bin_attr_flash_data.size = ops->blocks_num * ops->block_size;
0917
0918 c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
0919 "c2port%d", c2dev->id);
0920 if (IS_ERR(c2dev->dev)) {
0921 ret = PTR_ERR(c2dev->dev);
0922 goto error_device_create;
0923 }
0924 dev_set_drvdata(c2dev->dev, c2dev);
0925
0926 strncpy(c2dev->name, name, C2PORT_NAME_LEN - 1);
0927 c2dev->ops = ops;
0928 mutex_init(&c2dev->mutex);
0929
0930
0931 c2dev->access = c2dev->flash_access = 0;
0932 ops->access(c2dev, 0);
0933
0934 dev_info(c2dev->dev, "C2 port %s added\n", name);
0935 dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
0936 "(%d bytes total)\n",
0937 name, ops->blocks_num, ops->block_size,
0938 ops->blocks_num * ops->block_size);
0939
0940 return c2dev;
0941
0942 error_device_create:
0943 spin_lock_irq(&c2port_idr_lock);
0944 idr_remove(&c2port_idr, c2dev->id);
0945 spin_unlock_irq(&c2port_idr_lock);
0946
0947 error_idr_alloc:
0948 kfree(c2dev);
0949
0950 return ERR_PTR(ret);
0951 }
0952 EXPORT_SYMBOL(c2port_device_register);
0953
0954 void c2port_device_unregister(struct c2port_device *c2dev)
0955 {
0956 if (!c2dev)
0957 return;
0958
0959 dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
0960
0961 spin_lock_irq(&c2port_idr_lock);
0962 idr_remove(&c2port_idr, c2dev->id);
0963 spin_unlock_irq(&c2port_idr_lock);
0964
0965 device_destroy(c2port_class, c2dev->id);
0966
0967 kfree(c2dev);
0968 }
0969 EXPORT_SYMBOL(c2port_device_unregister);
0970
0971
0972
0973
0974
0975 static int __init c2port_init(void)
0976 {
0977 printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
0978 " - (C) 2007 Rodolfo Giometti\n");
0979
0980 c2port_class = class_create(THIS_MODULE, "c2port");
0981 if (IS_ERR(c2port_class)) {
0982 printk(KERN_ERR "c2port: failed to allocate class\n");
0983 return PTR_ERR(c2port_class);
0984 }
0985 c2port_class->dev_groups = c2port_groups;
0986
0987 return 0;
0988 }
0989
0990 static void __exit c2port_exit(void)
0991 {
0992 class_destroy(c2port_class);
0993 }
0994
0995 module_init(c2port_init);
0996 module_exit(c2port_exit);
0997
0998 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
0999 MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
1000 MODULE_LICENSE("GPL");