Commit 74489a91dd43aecd638709d34a2f58b91cfda5cf

Authored by Grant Likely
Committed by Linus Torvalds
1 parent 99121c0da3

Add support for Xilinx SystemACE CompactFlash interface

Tested on Xilinx Virtex ppc405, Katmai 440SPe, and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Stefan Roese <sr@denx.de>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: John William <jwilliams@itee.uq.edu.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 1173 additions and 0 deletions Side-by-side Diff

drivers/block/Kconfig
... ... @@ -421,5 +421,11 @@
421 421  
422 422 source "drivers/s390/block/Kconfig"
423 423  
  424 +config XILINX_SYSACE
  425 + tristate "Xilinx SystemACE support"
  426 + depends on 4xx
  427 + help
  428 + Include support for the Xilinx SystemACE CompactFlash interface
  429 +
424 430 endif # BLK_DEV
drivers/block/Makefile
... ... @@ -17,6 +17,7 @@
17 17 obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o
18 18 obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o
19 19 obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o
  20 +obj-$(CONFIG_XILINX_SYSACE) += xsysace.o
20 21 obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o
21 22 obj-$(CONFIG_SUNVDC) += sunvdc.o
22 23  
drivers/block/xsysace.c
Changes suppressed. Click to show
  1 +/*
  2 + * Xilinx SystemACE device driver
  3 + *
  4 + * Copyright 2007 Secret Lab Technologies Ltd.
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of the GNU General Public License version 2 as published
  8 + * by the Free Software Foundation.
  9 + */
  10 +
  11 +/*
  12 + * The SystemACE chip is designed to configure FPGAs by loading an FPGA
  13 + * bitstream from a file on a CF card and squirting it into FPGAs connected
  14 + * to the SystemACE JTAG chain. It also has the advantage of providing an
  15 + * MPU interface which can be used to control the FPGA configuration process
  16 + * and to use the attached CF card for general purpose storage.
  17 + *
  18 + * This driver is a block device driver for the SystemACE.
  19 + *
  20 + * Initialization:
  21 + * The driver registers itself as a platform_device driver at module
  22 + * load time. The platform bus will take care of calling the
  23 + * ace_probe() method for all SystemACE instances in the system. Any
  24 + * number of SystemACE instances are supported. ace_probe() calls
  25 + * ace_setup() which initialized all data structures, reads the CF
  26 + * id structure and registers the device.
  27 + *
  28 + * Processing:
  29 + * Just about all of the heavy lifting in this driver is performed by
  30 + * a Finite State Machine (FSM). The driver needs to wait on a number
  31 + * of events; some raised by interrupts, some which need to be polled
  32 + * for. Describing all of the behaviour in a FSM seems to be the
  33 + * easiest way to keep the complexity low and make it easy to
  34 + * understand what the driver is doing. If the block ops or the
  35 + * request function need to interact with the hardware, then they
  36 + * simply need to flag the request and kick of FSM processing.
  37 + *
  38 + * The FSM itself is atomic-safe code which can be run from any
  39 + * context. The general process flow is:
  40 + * 1. obtain the ace->lock spinlock.
  41 + * 2. loop on ace_fsm_dostate() until the ace->fsm_continue flag is
  42 + * cleared.
  43 + * 3. release the lock.
  44 + *
  45 + * Individual states do not sleep in any way. If a condition needs to
  46 + * be waited for then the state much clear the fsm_continue flag and
  47 + * either schedule the FSM to be run again at a later time, or expect
  48 + * an interrupt to call the FSM when the desired condition is met.
  49 + *
  50 + * In normal operation, the FSM is processed at interrupt context
  51 + * either when the driver's tasklet is scheduled, or when an irq is
  52 + * raised by the hardware. The tasklet can be scheduled at any time.
  53 + * The request method in particular schedules the tasklet when a new
  54 + * request has been indicated by the block layer. Once started, the
  55 + * FSM proceeds as far as it can processing the request until it
  56 + * needs on a hardware event. At this point, it must yield execution.
  57 + *
  58 + * A state has two options when yielding execution:
  59 + * 1. ace_fsm_yield()
  60 + * - Call if need to poll for event.
  61 + * - clears the fsm_continue flag to exit the processing loop
  62 + * - reschedules the tasklet to run again as soon as possible
  63 + * 2. ace_fsm_yieldirq()
  64 + * - Call if an irq is expected from the HW
  65 + * - clears the fsm_continue flag to exit the processing loop
  66 + * - does not reschedule the tasklet so the FSM will not be processed
  67 + * again until an irq is received.
  68 + * After calling a yield function, the state must return control back
  69 + * to the FSM main loop.
  70 + *
  71 + * Additionally, the driver maintains a kernel timer which can process
  72 + * the FSM. If the FSM gets stalled, typically due to a missed
  73 + * interrupt, then the kernel timer will expire and the driver can
  74 + * continue where it left off.
  75 + *
  76 + * To Do:
  77 + * - Add FPGA configuration control interface.
  78 + * - Request major number from lanana
  79 + */
  80 +
  81 +#undef DEBUG
  82 +
  83 +#include <linux/module.h>
  84 +#include <linux/ctype.h>
  85 +#include <linux/init.h>
  86 +#include <linux/interrupt.h>
  87 +#include <linux/errno.h>
  88 +#include <linux/kernel.h>
  89 +#include <linux/delay.h>
  90 +#include <linux/slab.h>
  91 +#include <linux/blkdev.h>
  92 +#include <linux/hdreg.h>
  93 +#include <linux/platform_device.h>
  94 +
  95 +MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
  96 +MODULE_DESCRIPTION("Xilinx SystemACE device driver");
  97 +MODULE_LICENSE("GPL");
  98 +
  99 +/* SystemACE register definitions */
  100 +#define ACE_BUSMODE (0x00)
  101 +
  102 +#define ACE_STATUS (0x04)
  103 +#define ACE_STATUS_CFGLOCK (0x00000001)
  104 +#define ACE_STATUS_MPULOCK (0x00000002)
  105 +#define ACE_STATUS_CFGERROR (0x00000004) /* config controller error */
  106 +#define ACE_STATUS_CFCERROR (0x00000008) /* CF controller error */
  107 +#define ACE_STATUS_CFDETECT (0x00000010)
  108 +#define ACE_STATUS_DATABUFRDY (0x00000020)
  109 +#define ACE_STATUS_DATABUFMODE (0x00000040)
  110 +#define ACE_STATUS_CFGDONE (0x00000080)
  111 +#define ACE_STATUS_RDYFORCFCMD (0x00000100)
  112 +#define ACE_STATUS_CFGMODEPIN (0x00000200)
  113 +#define ACE_STATUS_CFGADDR_MASK (0x0000e000)
  114 +#define ACE_STATUS_CFBSY (0x00020000)
  115 +#define ACE_STATUS_CFRDY (0x00040000)
  116 +#define ACE_STATUS_CFDWF (0x00080000)
  117 +#define ACE_STATUS_CFDSC (0x00100000)
  118 +#define ACE_STATUS_CFDRQ (0x00200000)
  119 +#define ACE_STATUS_CFCORR (0x00400000)
  120 +#define ACE_STATUS_CFERR (0x00800000)
  121 +
  122 +#define ACE_ERROR (0x08)
  123 +#define ACE_CFGLBA (0x0c)
  124 +#define ACE_MPULBA (0x10)
  125 +
  126 +#define ACE_SECCNTCMD (0x14)
  127 +#define ACE_SECCNTCMD_RESET (0x0100)
  128 +#define ACE_SECCNTCMD_IDENTIFY (0x0200)
  129 +#define ACE_SECCNTCMD_READ_DATA (0x0300)
  130 +#define ACE_SECCNTCMD_WRITE_DATA (0x0400)
  131 +#define ACE_SECCNTCMD_ABORT (0x0600)
  132 +
  133 +#define ACE_VERSION (0x16)
  134 +#define ACE_VERSION_REVISION_MASK (0x00FF)
  135 +#define ACE_VERSION_MINOR_MASK (0x0F00)
  136 +#define ACE_VERSION_MAJOR_MASK (0xF000)
  137 +
  138 +#define ACE_CTRL (0x18)
  139 +#define ACE_CTRL_FORCELOCKREQ (0x0001)
  140 +#define ACE_CTRL_LOCKREQ (0x0002)
  141 +#define ACE_CTRL_FORCECFGADDR (0x0004)
  142 +#define ACE_CTRL_FORCECFGMODE (0x0008)
  143 +#define ACE_CTRL_CFGMODE (0x0010)
  144 +#define ACE_CTRL_CFGSTART (0x0020)
  145 +#define ACE_CTRL_CFGSEL (0x0040)
  146 +#define ACE_CTRL_CFGRESET (0x0080)
  147 +#define ACE_CTRL_DATABUFRDYIRQ (0x0100)
  148 +#define ACE_CTRL_ERRORIRQ (0x0200)
  149 +#define ACE_CTRL_CFGDONEIRQ (0x0400)
  150 +#define ACE_CTRL_RESETIRQ (0x0800)
  151 +#define ACE_CTRL_CFGPROG (0x1000)
  152 +#define ACE_CTRL_CFGADDR_MASK (0xe000)
  153 +
  154 +#define ACE_FATSTAT (0x1c)
  155 +
  156 +#define ACE_NUM_MINORS 16
  157 +#define ACE_SECTOR_SIZE (512)
  158 +#define ACE_FIFO_SIZE (32)
  159 +#define ACE_BUF_PER_SECTOR (ACE_SECTOR_SIZE / ACE_FIFO_SIZE)
  160 +
  161 +struct ace_reg_ops;
  162 +
  163 +struct ace_device {
  164 + /* driver state data */
  165 + int id;
  166 + int media_change;
  167 + int users;
  168 + struct list_head list;
  169 +
  170 + /* finite state machine data */
  171 + struct tasklet_struct fsm_tasklet;
  172 + uint fsm_task; /* Current activity (ACE_TASK_*) */
  173 + uint fsm_state; /* Current state (ACE_FSM_STATE_*) */
  174 + uint fsm_continue_flag; /* cleared to exit FSM mainloop */
  175 + uint fsm_iter_num;
  176 + struct timer_list stall_timer;
  177 +
  178 + /* Transfer state/result, use for both id and block request */
  179 + struct request *req; /* request being processed */
  180 + void *data_ptr; /* pointer to I/O buffer */
  181 + int data_count; /* number of buffers remaining */
  182 + int data_result; /* Result of transfer; 0 := success */
  183 +
  184 + int id_req_count; /* count of id requests */
  185 + int id_result;
  186 + struct completion id_completion; /* used when id req finishes */
  187 + int in_irq;
  188 +
  189 + /* Details of hardware device */
  190 + unsigned long physaddr;
  191 + void *baseaddr;
  192 + int irq;
  193 + int bus_width; /* 0 := 8 bit; 1 := 16 bit */
  194 + struct ace_reg_ops *reg_ops;
  195 + int lock_count;
  196 +
  197 + /* Block device data structures */
  198 + spinlock_t lock;
  199 + struct device *dev;
  200 + struct request_queue *queue;
  201 + struct gendisk *gd;
  202 +
  203 + /* Inserted CF card parameters */
  204 + struct hd_driveid cf_id;
  205 +};
  206 +
  207 +static int ace_major;
  208 +
  209 +/* ---------------------------------------------------------------------
  210 + * Low level register access
  211 + */
  212 +
  213 +struct ace_reg_ops {
  214 + u16(*in) (struct ace_device * ace, int reg);
  215 + void (*out) (struct ace_device * ace, int reg, u16 val);
  216 + void (*datain) (struct ace_device * ace);
  217 + void (*dataout) (struct ace_device * ace);
  218 +};
  219 +
  220 +/* 8 Bit bus width */
  221 +static u16 ace_in_8(struct ace_device *ace, int reg)
  222 +{
  223 + void *r = ace->baseaddr + reg;
  224 + return in_8(r) | (in_8(r + 1) << 8);
  225 +}
  226 +
  227 +static void ace_out_8(struct ace_device *ace, int reg, u16 val)
  228 +{
  229 + void *r = ace->baseaddr + reg;
  230 + out_8(r, val);
  231 + out_8(r + 1, val >> 8);
  232 +}
  233 +
  234 +static void ace_datain_8(struct ace_device *ace)
  235 +{
  236 + void *r = ace->baseaddr + 0x40;
  237 + u8 *dst = ace->data_ptr;
  238 + int i = ACE_FIFO_SIZE;
  239 + while (i--)
  240 + *dst++ = in_8(r++);
  241 + ace->data_ptr = dst;
  242 +}
  243 +
  244 +static void ace_dataout_8(struct ace_device *ace)
  245 +{
  246 + void *r = ace->baseaddr + 0x40;
  247 + u8 *src = ace->data_ptr;
  248 + int i = ACE_FIFO_SIZE;
  249 + while (i--)
  250 + out_8(r++, *src++);
  251 + ace->data_ptr = src;
  252 +}
  253 +
  254 +static struct ace_reg_ops ace_reg_8_ops = {
  255 + .in = ace_in_8,
  256 + .out = ace_out_8,
  257 + .datain = ace_datain_8,
  258 + .dataout = ace_dataout_8,
  259 +};
  260 +
  261 +/* 16 bit big endian bus attachment */
  262 +static u16 ace_in_be16(struct ace_device *ace, int reg)
  263 +{
  264 + return in_be16(ace->baseaddr + reg);
  265 +}
  266 +
  267 +static void ace_out_be16(struct ace_device *ace, int reg, u16 val)
  268 +{
  269 + out_be16(ace->baseaddr + reg, val);
  270 +}
  271 +
  272 +static void ace_datain_be16(struct ace_device *ace)
  273 +{
  274 + int i = ACE_FIFO_SIZE / 2;
  275 + u16 *dst = ace->data_ptr;
  276 + while (i--)
  277 + *dst++ = in_le16(ace->baseaddr + 0x40);
  278 + ace->data_ptr = dst;
  279 +}
  280 +
  281 +static void ace_dataout_be16(struct ace_device *ace)
  282 +{
  283 + int i = ACE_FIFO_SIZE / 2;
  284 + u16 *src = ace->data_ptr;
  285 + while (i--)
  286 + out_le16(ace->baseaddr + 0x40, *src++);
  287 + ace->data_ptr = src;
  288 +}
  289 +
  290 +/* 16 bit little endian bus attachment */
  291 +static u16 ace_in_le16(struct ace_device *ace, int reg)
  292 +{
  293 + return in_le16(ace->baseaddr + reg);
  294 +}
  295 +
  296 +static void ace_out_le16(struct ace_device *ace, int reg, u16 val)
  297 +{
  298 + out_le16(ace->baseaddr + reg, val);
  299 +}
  300 +
  301 +static void ace_datain_le16(struct ace_device *ace)
  302 +{
  303 + int i = ACE_FIFO_SIZE / 2;
  304 + u16 *dst = ace->data_ptr;
  305 + while (i--)
  306 + *dst++ = in_be16(ace->baseaddr + 0x40);
  307 + ace->data_ptr = dst;
  308 +}
  309 +
  310 +static void ace_dataout_le16(struct ace_device *ace)
  311 +{
  312 + int i = ACE_FIFO_SIZE / 2;
  313 + u16 *src = ace->data_ptr;
  314 + while (i--)
  315 + out_be16(ace->baseaddr + 0x40, *src++);
  316 + ace->data_ptr = src;
  317 +}
  318 +
  319 +static struct ace_reg_ops ace_reg_be16_ops = {
  320 + .in = ace_in_be16,
  321 + .out = ace_out_be16,
  322 + .datain = ace_datain_be16,
  323 + .dataout = ace_dataout_be16,
  324 +};
  325 +
  326 +static struct ace_reg_ops ace_reg_le16_ops = {
  327 + .in = ace_in_le16,
  328 + .out = ace_out_le16,
  329 + .datain = ace_datain_le16,
  330 + .dataout = ace_dataout_le16,
  331 +};
  332 +
  333 +static inline u16 ace_in(struct ace_device *ace, int reg)
  334 +{
  335 + return ace->reg_ops->in(ace, reg);
  336 +}
  337 +
  338 +static inline u32 ace_in32(struct ace_device *ace, int reg)
  339 +{
  340 + return ace_in(ace, reg) | (ace_in(ace, reg + 2) << 16);
  341 +}
  342 +
  343 +static inline void ace_out(struct ace_device *ace, int reg, u16 val)
  344 +{
  345 + ace->reg_ops->out(ace, reg, val);
  346 +}
  347 +
  348 +static inline void ace_out32(struct ace_device *ace, int reg, u32 val)
  349 +{
  350 + ace_out(ace, reg, val);
  351 + ace_out(ace, reg + 2, val >> 16);
  352 +}
  353 +
  354 +/* ---------------------------------------------------------------------
  355 + * Debug support functions
  356 + */
  357 +
  358 +#if defined(DEBUG)
  359 +static void ace_dump_mem(void *base, int len)
  360 +{
  361 + const char *ptr = base;
  362 + int i, j;
  363 +
  364 + for (i = 0; i < len; i += 16) {
  365 + printk(KERN_INFO "%.8x:", i);
  366 + for (j = 0; j < 16; j++) {
  367 + if (!(j % 4))
  368 + printk(" ");
  369 + printk("%.2x", ptr[i + j]);
  370 + }
  371 + printk(" ");
  372 + for (j = 0; j < 16; j++)
  373 + printk("%c", isprint(ptr[i + j]) ? ptr[i + j] : '.');
  374 + printk("\n");
  375 + }
  376 +}
  377 +#else
  378 +static inline void ace_dump_mem(void *base, int len)
  379 +{
  380 +}
  381 +#endif
  382 +
  383 +static void ace_dump_regs(struct ace_device *ace)
  384 +{
  385 + dev_info(ace->dev, " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n"
  386 + " status:%.8x mpu_lba:%.8x busmode:%4x\n"
  387 + " error: %.8x cfg_lba:%.8x fatstat:%.4x\n",
  388 + ace_in32(ace, ACE_CTRL),
  389 + ace_in(ace, ACE_SECCNTCMD),
  390 + ace_in(ace, ACE_VERSION),
  391 + ace_in32(ace, ACE_STATUS),
  392 + ace_in32(ace, ACE_MPULBA),
  393 + ace_in(ace, ACE_BUSMODE),
  394 + ace_in32(ace, ACE_ERROR),
  395 + ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));
  396 +}
  397 +
  398 +void ace_fix_driveid(struct hd_driveid *id)
  399 +{
  400 +#if defined(__BIG_ENDIAN)
  401 + u16 *buf = (void *)id;
  402 + int i;
  403 +
  404 + /* All half words have wrong byte order; swap the bytes */
  405 + for (i = 0; i < sizeof(struct hd_driveid); i += 2, buf++)
  406 + *buf = le16_to_cpu(*buf);
  407 +
  408 + /* Some of the data values are 32bit; swap the half words */
  409 + id->lba_capacity = ((id->lba_capacity >> 16) & 0x0000FFFF) |
  410 + ((id->lba_capacity << 16) & 0xFFFF0000);
  411 + id->spg = ((id->spg >> 16) & 0x0000FFFF) |
  412 + ((id->spg << 16) & 0xFFFF0000);
  413 +#endif
  414 +}
  415 +
  416 +/* ---------------------------------------------------------------------
  417 + * Finite State Machine (FSM) implementation
  418 + */
  419 +
  420 +/* FSM tasks; used to direct state transitions */
  421 +#define ACE_TASK_IDLE 0
  422 +#define ACE_TASK_IDENTIFY 1
  423 +#define ACE_TASK_READ 2
  424 +#define ACE_TASK_WRITE 3
  425 +#define ACE_FSM_NUM_TASKS 4
  426 +
  427 +/* FSM state definitions */
  428 +#define ACE_FSM_STATE_IDLE 0
  429 +#define ACE_FSM_STATE_REQ_LOCK 1
  430 +#define ACE_FSM_STATE_WAIT_LOCK 2
  431 +#define ACE_FSM_STATE_WAIT_CFREADY 3
  432 +#define ACE_FSM_STATE_IDENTIFY_PREPARE 4
  433 +#define ACE_FSM_STATE_IDENTIFY_TRANSFER 5
  434 +#define ACE_FSM_STATE_IDENTIFY_COMPLETE 6
  435 +#define ACE_FSM_STATE_REQ_PREPARE 7
  436 +#define ACE_FSM_STATE_REQ_TRANSFER 8
  437 +#define ACE_FSM_STATE_REQ_COMPLETE 9
  438 +#define ACE_FSM_STATE_ERROR 10
  439 +#define ACE_FSM_NUM_STATES 11
  440 +
  441 +/* Set flag to exit FSM loop and reschedule tasklet */
  442 +static inline void ace_fsm_yield(struct ace_device *ace)
  443 +{
  444 + dev_dbg(ace->dev, "ace_fsm_yield()\n");
  445 + tasklet_schedule(&ace->fsm_tasklet);
  446 + ace->fsm_continue_flag = 0;
  447 +}
  448 +
  449 +/* Set flag to exit FSM loop and wait for IRQ to reschedule tasklet */
  450 +static inline void ace_fsm_yieldirq(struct ace_device *ace)
  451 +{
  452 + dev_dbg(ace->dev, "ace_fsm_yieldirq()\n");
  453 +
  454 + if (ace->irq == NO_IRQ)
  455 + /* No IRQ assigned, so need to poll */
  456 + tasklet_schedule(&ace->fsm_tasklet);
  457 + ace->fsm_continue_flag = 0;
  458 +}
  459 +
  460 +/* Get the next read/write request; ending requests that we don't handle */
  461 +struct request *ace_get_next_request(request_queue_t * q)
  462 +{
  463 + struct request *req;
  464 +
  465 + while ((req = elv_next_request(q)) != NULL) {
  466 + if (blk_fs_request(req))
  467 + break;
  468 + end_request(req, 0);
  469 + }
  470 + return req;
  471 +}
  472 +
  473 +static void ace_fsm_dostate(struct ace_device *ace)
  474 +{
  475 + struct request *req;
  476 + u32 status;
  477 + u16 val;
  478 + int count;
  479 + int i;
  480 +
  481 +#if defined(DEBUG)
  482 + dev_dbg(ace->dev, "fsm_state=%i, id_req_count=%i\n",
  483 + ace->fsm_state, ace->id_req_count);
  484 +#endif
  485 +
  486 + switch (ace->fsm_state) {
  487 + case ACE_FSM_STATE_IDLE:
  488 + /* See if there is anything to do */
  489 + if (ace->id_req_count || ace_get_next_request(ace->queue)) {
  490 + ace->fsm_iter_num++;
  491 + ace->fsm_state = ACE_FSM_STATE_REQ_LOCK;
  492 + mod_timer(&ace->stall_timer, jiffies + HZ);
  493 + if (!timer_pending(&ace->stall_timer))
  494 + add_timer(&ace->stall_timer);
  495 + break;
  496 + }
  497 + del_timer(&ace->stall_timer);
  498 + ace->fsm_continue_flag = 0;
  499 + break;
  500 +
  501 + case ACE_FSM_STATE_REQ_LOCK:
  502 + if (ace_in(ace, ACE_STATUS) & ACE_STATUS_MPULOCK) {
  503 + /* Already have the lock, jump to next state */
  504 + ace->fsm_state = ACE_FSM_STATE_WAIT_CFREADY;
  505 + break;
  506 + }
  507 +
  508 + /* Request the lock */
  509 + val = ace_in(ace, ACE_CTRL);
  510 + ace_out(ace, ACE_CTRL, val | ACE_CTRL_LOCKREQ);
  511 + ace->fsm_state = ACE_FSM_STATE_WAIT_LOCK;
  512 + break;
  513 +
  514 + case ACE_FSM_STATE_WAIT_LOCK:
  515 + if (ace_in(ace, ACE_STATUS) & ACE_STATUS_MPULOCK) {
  516 + /* got the lock; move to next state */
  517 + ace->fsm_state = ACE_FSM_STATE_WAIT_CFREADY;
  518 + break;
  519 + }
  520 +
  521 + /* wait a bit for the lock */
  522 + ace_fsm_yield(ace);
  523 + break;
  524 +
  525 + case ACE_FSM_STATE_WAIT_CFREADY:
  526 + status = ace_in32(ace, ACE_STATUS);
  527 + if (!(status & ACE_STATUS_RDYFORCFCMD) ||
  528 + (status & ACE_STATUS_CFBSY)) {
  529 + /* CF card isn't ready; it needs to be polled */
  530 + ace_fsm_yield(ace);
  531 + break;
  532 + }
  533 +
  534 + /* Device is ready for command; determine what to do next */
  535 + if (ace->id_req_count)
  536 + ace->fsm_state = ACE_FSM_STATE_IDENTIFY_PREPARE;
  537 + else
  538 + ace->fsm_state = ACE_FSM_STATE_REQ_PREPARE;
  539 + break;
  540 +
  541 + case ACE_FSM_STATE_IDENTIFY_PREPARE:
  542 + /* Send identify command */
  543 + ace->fsm_task = ACE_TASK_IDENTIFY;
  544 + ace->data_ptr = &ace->cf_id;
  545 + ace->data_count = ACE_BUF_PER_SECTOR;
  546 + ace_out(ace, ACE_SECCNTCMD, ACE_SECCNTCMD_IDENTIFY);
  547 +
  548 + /* As per datasheet, put config controller in reset */
  549 + val = ace_in(ace, ACE_CTRL);
  550 + ace_out(ace, ACE_CTRL, val | ACE_CTRL_CFGRESET);
  551 +
  552 + /* irq handler takes over from this point; wait for the
  553 + * transfer to complete */
  554 + ace->fsm_state = ACE_FSM_STATE_IDENTIFY_TRANSFER;
  555 + ace_fsm_yieldirq(ace);
  556 + break;
  557 +
  558 + case ACE_FSM_STATE_IDENTIFY_TRANSFER:
  559 + /* Check that the sysace is ready to receive data */
  560 + status = ace_in32(ace, ACE_STATUS);
  561 + if (status & ACE_STATUS_CFBSY) {
  562 + dev_dbg(ace->dev, "CFBSY set; t=%i iter=%i dc=%i\n",
  563 + ace->fsm_task, ace->fsm_iter_num,
  564 + ace->data_count);
  565 + ace_fsm_yield(ace);
  566 + break;
  567 + }
  568 + if (!(status & ACE_STATUS_DATABUFRDY)) {
  569 + ace_fsm_yield(ace);
  570 + break;
  571 + }
  572 +
  573 + /* Transfer the next buffer */
  574 + ace->reg_ops->datain(ace);
  575 + ace->data_count--;
  576 +
  577 + /* If there are still buffers to be transfers; jump out here */
  578 + if (ace->data_count != 0) {
  579 + ace_fsm_yieldirq(ace);
  580 + break;
  581 + }
  582 +
  583 + /* transfer finished; kick state machine */
  584 + dev_dbg(ace->dev, "identify finished\n");
  585 + ace->fsm_state = ACE_FSM_STATE_IDENTIFY_COMPLETE;
  586 + break;
  587 +
  588 + case ACE_FSM_STATE_IDENTIFY_COMPLETE:
  589 + ace_fix_driveid(&ace->cf_id);
  590 + ace_dump_mem(&ace->cf_id, 512); /* Debug: Dump out disk ID */
  591 +
  592 + if (ace->data_result) {
  593 + /* Error occured, disable the disk */
  594 + ace->media_change = 1;
  595 + set_capacity(ace->gd, 0);
  596 + dev_err(ace->dev, "error fetching CF id (%i)\n",
  597 + ace->data_result);
  598 + } else {
  599 + ace->media_change = 0;
  600 +
  601 + /* Record disk parameters */
  602 + set_capacity(ace->gd, ace->cf_id.lba_capacity);
  603 + dev_info(ace->dev, "capacity: %i sectors\n",
  604 + ace->cf_id.lba_capacity);
  605 + }
  606 +
  607 + /* We're done, drop to IDLE state and notify waiters */
  608 + ace->fsm_state = ACE_FSM_STATE_IDLE;
  609 + ace->id_result = ace->data_result;
  610 + while (ace->id_req_count) {
  611 + complete(&ace->id_completion);
  612 + ace->id_req_count--;
  613 + }
  614 + break;
  615 +
  616 + case ACE_FSM_STATE_REQ_PREPARE:
  617 + req = ace_get_next_request(ace->queue);
  618 + if (!req) {
  619 + ace->fsm_state = ACE_FSM_STATE_IDLE;
  620 + break;
  621 + }
  622 +
  623 + /* Okay, it's a data request, set it up for transfer */
  624 + dev_dbg(ace->dev,
  625 + "request: sec=%lx hcnt=%lx, ccnt=%x, dir=%i\n",
  626 + req->sector, req->hard_nr_sectors,
  627 + req->current_nr_sectors, rq_data_dir(req));
  628 +
  629 + ace->req = req;
  630 + ace->data_ptr = req->buffer;
  631 + ace->data_count = req->current_nr_sectors * ACE_BUF_PER_SECTOR;
  632 + ace_out32(ace, ACE_MPULBA, req->sector & 0x0FFFFFFF);
  633 +
  634 + count = req->hard_nr_sectors;
  635 + if (rq_data_dir(req)) {
  636 + /* Kick off write request */
  637 + dev_dbg(ace->dev, "write data\n");
  638 + ace->fsm_task = ACE_TASK_WRITE;
  639 + ace_out(ace, ACE_SECCNTCMD,
  640 + count | ACE_SECCNTCMD_WRITE_DATA);
  641 + } else {
  642 + /* Kick off read request */
  643 + dev_dbg(ace->dev, "read data\n");
  644 + ace->fsm_task = ACE_TASK_READ;
  645 + ace_out(ace, ACE_SECCNTCMD,
  646 + count | ACE_SECCNTCMD_READ_DATA);
  647 + }
  648 +
  649 + /* As per datasheet, put config controller in reset */
  650 + val = ace_in(ace, ACE_CTRL);
  651 + ace_out(ace, ACE_CTRL, val | ACE_CTRL_CFGRESET);
  652 +
  653 + /* Move to the transfer state. The systemace will raise
  654 + * an interrupt once there is something to do
  655 + */
  656 + ace->fsm_state = ACE_FSM_STATE_REQ_TRANSFER;
  657 + if (ace->fsm_task == ACE_TASK_READ)
  658 + ace_fsm_yieldirq(ace); /* wait for data ready */
  659 + break;
  660 +
  661 + case ACE_FSM_STATE_REQ_TRANSFER:
  662 + /* Check that the sysace is ready to receive data */
  663 + status = ace_in32(ace, ACE_STATUS);
  664 + if (status & ACE_STATUS_CFBSY) {
  665 + dev_dbg(ace->dev,
  666 + "CFBSY set; t=%i iter=%i c=%i dc=%i irq=%i\n",
  667 + ace->fsm_task, ace->fsm_iter_num,
  668 + ace->req->current_nr_sectors * 16,
  669 + ace->data_count, ace->in_irq);
  670 + ace_fsm_yield(ace); /* need to poll CFBSY bit */
  671 + break;
  672 + }
  673 + if (!(status & ACE_STATUS_DATABUFRDY)) {
  674 + dev_dbg(ace->dev,
  675 + "DATABUF not set; t=%i iter=%i c=%i dc=%i irq=%i\n",
  676 + ace->fsm_task, ace->fsm_iter_num,
  677 + ace->req->current_nr_sectors * 16,
  678 + ace->data_count, ace->in_irq);
  679 + ace_fsm_yieldirq(ace);
  680 + break;
  681 + }
  682 +
  683 + /* Transfer the next buffer */
  684 + i = 16;
  685 + if (ace->fsm_task == ACE_TASK_WRITE)
  686 + ace->reg_ops->dataout(ace);
  687 + else
  688 + ace->reg_ops->datain(ace);
  689 + ace->data_count--;
  690 +
  691 + /* If there are still buffers to be transfers; jump out here */
  692 + if (ace->data_count != 0) {
  693 + ace_fsm_yieldirq(ace);
  694 + break;
  695 + }
  696 +
  697 + /* bio finished; is there another one? */
  698 + i = ace->req->current_nr_sectors;
  699 + if (end_that_request_first(ace->req, 1, i)) {
  700 + /* dev_dbg(ace->dev, "next block; h=%li c=%i\n",
  701 + * ace->req->hard_nr_sectors,
  702 + * ace->req->current_nr_sectors);
  703 + */
  704 + ace->data_ptr = ace->req->buffer;
  705 + ace->data_count = ace->req->current_nr_sectors * 16;
  706 + ace_fsm_yieldirq(ace);
  707 + break;
  708 + }
  709 +
  710 + ace->fsm_state = ACE_FSM_STATE_REQ_COMPLETE;
  711 + break;
  712 +
  713 + case ACE_FSM_STATE_REQ_COMPLETE:
  714 + /* Complete the block request */
  715 + blkdev_dequeue_request(ace->req);
  716 + end_that_request_last(ace->req, 1);
  717 + ace->req = NULL;
  718 +
  719 + /* Finished request; go to idle state */
  720 + ace->fsm_state = ACE_FSM_STATE_IDLE;
  721 + break;
  722 +
  723 + default:
  724 + ace->fsm_state = ACE_FSM_STATE_IDLE;
  725 + break;
  726 + }
  727 +}
  728 +
  729 +static void ace_fsm_tasklet(unsigned long data)
  730 +{
  731 + struct ace_device *ace = (void *)data;
  732 + unsigned long flags;
  733 +
  734 + spin_lock_irqsave(&ace->lock, flags);
  735 +
  736 + /* Loop over state machine until told to stop */
  737 + ace->fsm_continue_flag = 1;
  738 + while (ace->fsm_continue_flag)
  739 + ace_fsm_dostate(ace);
  740 +
  741 + spin_unlock_irqrestore(&ace->lock, flags);
  742 +}
  743 +
  744 +static void ace_stall_timer(unsigned long data)
  745 +{
  746 + struct ace_device *ace = (void *)data;
  747 + unsigned long flags;
  748 +
  749 + dev_warn(ace->dev,
  750 + "kicking stalled fsm; state=%i task=%i iter=%i dc=%i\n",
  751 + ace->fsm_state, ace->fsm_task, ace->fsm_iter_num,
  752 + ace->data_count);
  753 + spin_lock_irqsave(&ace->lock, flags);
  754 +
  755 + /* Rearm the stall timer *before* entering FSM (which may then
  756 + * delete the timer) */
  757 + mod_timer(&ace->stall_timer, jiffies + HZ);
  758 +
  759 + /* Loop over state machine until told to stop */
  760 + ace->fsm_continue_flag = 1;
  761 + while (ace->fsm_continue_flag)
  762 + ace_fsm_dostate(ace);
  763 +
  764 + spin_unlock_irqrestore(&ace->lock, flags);
  765 +}
  766 +
  767 +/* ---------------------------------------------------------------------
  768 + * Interrupt handling routines
  769 + */
  770 +static int ace_interrupt_checkstate(struct ace_device *ace)
  771 +{
  772 + u32 sreg = ace_in32(ace, ACE_STATUS);
  773 + u16 creg = ace_in(ace, ACE_CTRL);
  774 +
  775 + /* Check for error occurance */
  776 + if ((sreg & (ACE_STATUS_CFGERROR | ACE_STATUS_CFCERROR)) &&
  777 + (creg & ACE_CTRL_ERRORIRQ)) {
  778 + dev_err(ace->dev, "transfer failure\n");
  779 + ace_dump_regs(ace);
  780 + return -EIO;
  781 + }
  782 +
  783 + return 0;
  784 +}
  785 +
  786 +static irqreturn_t ace_interrupt(int irq, void *dev_id)
  787 +{
  788 + u16 creg;
  789 + struct ace_device *ace = dev_id;
  790 +
  791 + /* be safe and get the lock */
  792 + spin_lock(&ace->lock);
  793 + ace->in_irq = 1;
  794 +
  795 + /* clear the interrupt */
  796 + creg = ace_in(ace, ACE_CTRL);
  797 + ace_out(ace, ACE_CTRL, creg | ACE_CTRL_RESETIRQ);
  798 + ace_out(ace, ACE_CTRL, creg);
  799 +
  800 + /* check for IO failures */
  801 + if (ace_interrupt_checkstate(ace))
  802 + ace->data_result = -EIO;
  803 +
  804 + if (ace->fsm_task == 0) {
  805 + dev_err(ace->dev,
  806 + "spurious irq; stat=%.8x ctrl=%.8x cmd=%.4x\n",
  807 + ace_in32(ace, ACE_STATUS), ace_in32(ace, ACE_CTRL),
  808 + ace_in(ace, ACE_SECCNTCMD));
  809 + dev_err(ace->dev, "fsm_task=%i fsm_state=%i data_count=%i\n",
  810 + ace->fsm_task, ace->fsm_state, ace->data_count);
  811 + }
  812 +
  813 + /* Loop over state machine until told to stop */
  814 + ace->fsm_continue_flag = 1;
  815 + while (ace->fsm_continue_flag)
  816 + ace_fsm_dostate(ace);
  817 +
  818 + /* done with interrupt; drop the lock */
  819 + ace->in_irq = 0;
  820 + spin_unlock(&ace->lock);
  821 +
  822 + return IRQ_HANDLED;
  823 +}
  824 +
  825 +/* ---------------------------------------------------------------------
  826 + * Block ops
  827 + */
  828 +static void ace_request(request_queue_t * q)
  829 +{
  830 + struct request *req;
  831 + struct ace_device *ace;
  832 +
  833 + req = ace_get_next_request(q);
  834 +
  835 + if (req) {
  836 + ace = req->rq_disk->private_data;
  837 + tasklet_schedule(&ace->fsm_tasklet);
  838 + }
  839 +}
  840 +
  841 +static int ace_media_changed(struct gendisk *gd)
  842 +{
  843 + struct ace_device *ace = gd->private_data;
  844 + dev_dbg(ace->dev, "ace_media_changed(): %i\n", ace->media_change);
  845 +
  846 + return ace->media_change;
  847 +}
  848 +
  849 +static int ace_revalidate_disk(struct gendisk *gd)
  850 +{
  851 + struct ace_device *ace = gd->private_data;
  852 + unsigned long flags;
  853 +
  854 + dev_dbg(ace->dev, "ace_revalidate_disk()\n");
  855 +
  856 + if (ace->media_change) {
  857 + dev_dbg(ace->dev, "requesting cf id and scheduling tasklet\n");
  858 +
  859 + spin_lock_irqsave(&ace->lock, flags);
  860 + ace->id_req_count++;
  861 + spin_unlock_irqrestore(&ace->lock, flags);
  862 +
  863 + tasklet_schedule(&ace->fsm_tasklet);
  864 + wait_for_completion(&ace->id_completion);
  865 + }
  866 +
  867 + dev_dbg(ace->dev, "revalidate complete\n");
  868 + return ace->id_result;
  869 +}
  870 +
  871 +static int ace_open(struct inode *inode, struct file *filp)
  872 +{
  873 + struct ace_device *ace = inode->i_bdev->bd_disk->private_data;
  874 + unsigned long flags;
  875 +
  876 + dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1);
  877 +
  878 + filp->private_data = ace;
  879 + spin_lock_irqsave(&ace->lock, flags);
  880 + ace->users++;
  881 + spin_unlock_irqrestore(&ace->lock, flags);
  882 +
  883 + check_disk_change(inode->i_bdev);
  884 + return 0;
  885 +}
  886 +
  887 +static int ace_release(struct inode *inode, struct file *filp)
  888 +{
  889 + struct ace_device *ace = inode->i_bdev->bd_disk->private_data;
  890 + unsigned long flags;
  891 + u16 val;
  892 +
  893 + dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1);
  894 +
  895 + spin_lock_irqsave(&ace->lock, flags);
  896 + ace->users--;
  897 + if (ace->users == 0) {
  898 + val = ace_in(ace, ACE_CTRL);
  899 + ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ);
  900 + }
  901 + spin_unlock_irqrestore(&ace->lock, flags);
  902 + return 0;
  903 +}
  904 +
  905 +static int ace_ioctl(struct inode *inode, struct file *filp,
  906 + unsigned int cmd, unsigned long arg)
  907 +{
  908 + struct ace_device *ace = inode->i_bdev->bd_disk->private_data;
  909 + struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;
  910 + struct hd_geometry g;
  911 + dev_dbg(ace->dev, "ace_ioctl()\n");
  912 +
  913 + switch (cmd) {
  914 + case HDIO_GETGEO:
  915 + g.heads = ace->cf_id.heads;
  916 + g.sectors = ace->cf_id.sectors;
  917 + g.cylinders = ace->cf_id.cyls;
  918 + g.start = 0;
  919 + return copy_to_user(geo, &g, sizeof(g)) ? -EFAULT : 0;
  920 +
  921 + default:
  922 + return -ENOTTY;
  923 + }
  924 + return -ENOTTY;
  925 +}
  926 +
  927 +static struct block_device_operations ace_fops = {
  928 + .owner = THIS_MODULE,
  929 + .open = ace_open,
  930 + .release = ace_release,
  931 + .media_changed = ace_media_changed,
  932 + .revalidate_disk = ace_revalidate_disk,
  933 + .ioctl = ace_ioctl,
  934 +};
  935 +
  936 +/* --------------------------------------------------------------------
  937 + * SystemACE device setup/teardown code
  938 + */
  939 +static int __devinit ace_setup(struct ace_device *ace)
  940 +{
  941 + u16 version;
  942 + u16 val;
  943 +
  944 + int rc;
  945 +
  946 + spin_lock_init(&ace->lock);
  947 + init_completion(&ace->id_completion);
  948 +
  949 + /*
  950 + * Map the device
  951 + */
  952 + ace->baseaddr = ioremap(ace->physaddr, 0x80);
  953 + if (!ace->baseaddr)
  954 + goto err_ioremap;
  955 +
  956 + if (ace->irq != NO_IRQ) {
  957 + rc = request_irq(ace->irq, ace_interrupt, 0, "systemace", ace);
  958 + if (rc) {
  959 + /* Failure - fall back to polled mode */
  960 + dev_err(ace->dev, "request_irq failed\n");
  961 + ace->irq = NO_IRQ;
  962 + }
  963 + }
  964 +
  965 + /*
  966 + * Initialize the state machine tasklet and stall timer
  967 + */
  968 + tasklet_init(&ace->fsm_tasklet, ace_fsm_tasklet, (unsigned long)ace);
  969 + setup_timer(&ace->stall_timer, ace_stall_timer, (unsigned long)ace);
  970 +
  971 + /*
  972 + * Initialize the request queue
  973 + */
  974 + ace->queue = blk_init_queue(ace_request, &ace->lock);
  975 + if (ace->queue == NULL)
  976 + goto err_blk_initq;
  977 + blk_queue_hardsect_size(ace->queue, 512);
  978 +
  979 + /*
  980 + * Allocate and initialize GD structure
  981 + */
  982 + ace->gd = alloc_disk(ACE_NUM_MINORS);
  983 + if (!ace->gd)
  984 + goto err_alloc_disk;
  985 +
  986 + ace->gd->major = ace_major;
  987 + ace->gd->first_minor = ace->id * ACE_NUM_MINORS;
  988 + ace->gd->fops = &ace_fops;
  989 + ace->gd->queue = ace->queue;
  990 + ace->gd->private_data = ace;
  991 + snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a');
  992 +
  993 + /* set bus width */
  994 + if (ace->bus_width == 1) {
  995 + /* 0x0101 should work regardless of endianess */
  996 + ace_out_le16(ace, ACE_BUSMODE, 0x0101);
  997 +
  998 + /* read it back to determine endianess */
  999 + if (ace_in_le16(ace, ACE_BUSMODE) == 0x0001)
  1000 + ace->reg_ops = &ace_reg_le16_ops;
  1001 + else
  1002 + ace->reg_ops = &ace_reg_be16_ops;
  1003 + } else {
  1004 + ace_out_8(ace, ACE_BUSMODE, 0x00);
  1005 + ace->reg_ops = &ace_reg_8_ops;
  1006 + }
  1007 +
  1008 + /* Make sure version register is sane */
  1009 + version = ace_in(ace, ACE_VERSION);
  1010 + if ((version == 0) || (version == 0xFFFF))
  1011 + goto err_read;
  1012 +
  1013 + /* Put sysace in a sane state by clearing most control reg bits */
  1014 + ace_out(ace, ACE_CTRL, ACE_CTRL_FORCECFGMODE |
  1015 + ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ);
  1016 +
  1017 + /* Enable interrupts */
  1018 + val = ace_in(ace, ACE_CTRL);
  1019 + val |= ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ;
  1020 + ace_out(ace, ACE_CTRL, val);
  1021 +
  1022 + /* Print the identification */
  1023 + dev_info(ace->dev, "Xilinx SystemACE revision %i.%i.%i\n",
  1024 + (version >> 12) & 0xf, (version >> 8) & 0x0f, version & 0xff);
  1025 + dev_dbg(ace->dev, "physaddr 0x%lx, mapped to 0x%p, irq=%i\n",
  1026 + ace->physaddr, ace->baseaddr, ace->irq);
  1027 +
  1028 + ace->media_change = 1;
  1029 + ace_revalidate_disk(ace->gd);
  1030 +
  1031 + /* Make the sysace device 'live' */
  1032 + add_disk(ace->gd);
  1033 +
  1034 + return 0;
  1035 +
  1036 + err_read:
  1037 + put_disk(ace->gd);
  1038 + err_alloc_disk:
  1039 + blk_cleanup_queue(ace->queue);
  1040 + err_blk_initq:
  1041 + iounmap(ace->baseaddr);
  1042 + if (ace->irq != NO_IRQ)
  1043 + free_irq(ace->irq, ace);
  1044 + err_ioremap:
  1045 + printk(KERN_INFO "xsysace: error initializing device at 0x%lx\n",
  1046 + ace->physaddr);
  1047 + return -ENOMEM;
  1048 +}
  1049 +
  1050 +static void __devexit ace_teardown(struct ace_device *ace)
  1051 +{
  1052 + if (ace->gd) {
  1053 + del_gendisk(ace->gd);
  1054 + put_disk(ace->gd);
  1055 + }
  1056 +
  1057 + if (ace->queue)
  1058 + blk_cleanup_queue(ace->queue);
  1059 +
  1060 + tasklet_kill(&ace->fsm_tasklet);
  1061 +
  1062 + if (ace->irq != NO_IRQ)
  1063 + free_irq(ace->irq, ace);
  1064 +
  1065 + iounmap(ace->baseaddr);
  1066 +}
  1067 +
  1068 +/* ---------------------------------------------------------------------
  1069 + * Platform Bus Support
  1070 + */
  1071 +
  1072 +static int __devinit ace_probe(struct device *device)
  1073 +{
  1074 + struct platform_device *dev = to_platform_device(device);
  1075 + struct ace_device *ace;
  1076 + int i;
  1077 +
  1078 + dev_dbg(device, "ace_probe(%p)\n", device);
  1079 +
  1080 + /*
  1081 + * Allocate the ace device structure
  1082 + */
  1083 + ace = kzalloc(sizeof(struct ace_device), GFP_KERNEL);
  1084 + if (!ace)
  1085 + goto err_alloc;
  1086 +
  1087 + ace->dev = device;
  1088 + ace->id = dev->id;
  1089 + ace->irq = NO_IRQ;
  1090 +
  1091 + for (i = 0; i < dev->num_resources; i++) {
  1092 + if (dev->resource[i].flags & IORESOURCE_MEM)
  1093 + ace->physaddr = dev->resource[i].start;
  1094 + if (dev->resource[i].flags & IORESOURCE_IRQ)
  1095 + ace->irq = dev->resource[i].start;
  1096 + }
  1097 +
  1098 + /* FIXME: Should get bus_width from the platform_device struct */
  1099 + ace->bus_width = 1;
  1100 +
  1101 + dev_set_drvdata(&dev->dev, ace);
  1102 +
  1103 + /* Call the bus-independant setup code */
  1104 + if (ace_setup(ace) != 0)
  1105 + goto err_setup;
  1106 +
  1107 + return 0;
  1108 +
  1109 + err_setup:
  1110 + dev_set_drvdata(&dev->dev, NULL);
  1111 + kfree(ace);
  1112 + err_alloc:
  1113 + printk(KERN_ERR "xsysace: could not initialize device\n");
  1114 + return -ENOMEM;
  1115 +}
  1116 +
  1117 +/*
  1118 + * Platform bus remove() method
  1119 + */
  1120 +static int __devexit ace_remove(struct device *device)
  1121 +{
  1122 + struct ace_device *ace = dev_get_drvdata(device);
  1123 +
  1124 + dev_dbg(device, "ace_remove(%p)\n", device);
  1125 +
  1126 + if (ace) {
  1127 + ace_teardown(ace);
  1128 + kfree(ace);
  1129 + }
  1130 +
  1131 + return 0;
  1132 +}
  1133 +
  1134 +static struct device_driver ace_driver = {
  1135 + .name = "xsysace",
  1136 + .bus = &platform_bus_type,
  1137 + .probe = ace_probe,
  1138 + .remove = __devexit_p(ace_remove),
  1139 +};
  1140 +
  1141 +/* ---------------------------------------------------------------------
  1142 + * Module init/exit routines
  1143 + */
  1144 +static int __init ace_init(void)
  1145 +{
  1146 + ace_major = register_blkdev(ace_major, "xsysace");
  1147 + if (ace_major <= 0) {
  1148 + printk(KERN_WARNING "xsysace: register_blkdev() failed\n");
  1149 + return ace_major;
  1150 + }
  1151 +
  1152 + pr_debug("Registering Xilinx SystemACE driver, major=%i\n", ace_major);
  1153 + return driver_register(&ace_driver);
  1154 +}
  1155 +
  1156 +static void __exit ace_exit(void)
  1157 +{
  1158 + pr_debug("Unregistering Xilinx SystemACE driver\n");
  1159 + driver_unregister(&ace_driver);
  1160 + if (unregister_blkdev(ace_major, "xsysace"))
  1161 + printk(KERN_WARNING "systemace unregister_blkdev(%i) failed\n",
  1162 + ace_major);
  1163 +}
  1164 +
  1165 +module_init(ace_init);
  1166 +module_exit(ace_exit);