cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

core.c (21950B)


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