1352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer/* jazz_esp.c: ESP front-end for MIPS JAZZ systems. 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3d36b691077dc59c74efec0d54ed21b86f7a2a21aAl Viro * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende) 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 75a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 9352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <linux/module.h> 10352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <linux/init.h> 11352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <linux/interrupt.h> 12352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <linux/platform_device.h> 13352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <linux/dma-mapping.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 16352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <asm/io.h> 17352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <asm/dma.h> 18352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/jazz.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/jazzdma.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include <scsi/scsi_host.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#include "esp_scsi.h" 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#define DRV_MODULE_NAME "jazz_esp" 27352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#define PFX DRV_MODULE_NAME ": " 28352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#define DRV_VERSION "1.000" 29352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer#define DRV_MODULE_RELDATE "May 19, 2007" 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 33352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer *(volatile u8 *)(esp->regs + reg) = val; 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 36352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic u8 jazz_esp_read8(struct esp *esp, unsigned long reg) 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 38352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return *(volatile u8 *)(esp->regs + reg); 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf, 42352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer size_t sz, int dir) 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 44352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return dma_map_single(esp->dev, buf, sz, dir); 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg, 48352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer int num_sg, int dir) 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 50352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return dma_map_sg(esp->dev, sg, num_sg, dir); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr, 54352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer size_t sz, int dir) 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 56352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer dma_unmap_single(esp->dev, addr, sz, dir); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, 60352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer int num_sg, int dir) 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 62352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer dma_unmap_sg(esp->dev, sg, num_sg, dir); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 65352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic int jazz_esp_irq_pending(struct esp *esp) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 67352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR) 68352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return 1; 69352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return 0; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 72352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void jazz_esp_reset_dma(struct esp *esp) 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 74352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_disable ((int)esp->dma_regs); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 77352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void jazz_esp_dma_drain(struct esp *esp) 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 79352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer /* nothing to do */ 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 82352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void jazz_esp_dma_invalidate(struct esp *esp) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 84352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_disable ((int)esp->dma_regs); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 87352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void jazz_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, 88352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer u32 dma_count, int write, u8 cmd) 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 90352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer BUG_ON(!(cmd & ESP_CMD_DMA)); 91352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 92352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer jazz_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); 93352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer jazz_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); 94352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_disable ((int)esp->dma_regs); 95352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (write) 96352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_set_mode ((int)esp->dma_regs, DMA_MODE_READ); 97352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer else 98352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_set_mode ((int)esp->dma_regs, DMA_MODE_WRITE); 99352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 100352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_set_addr ((int)esp->dma_regs, addr); 101352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_set_count ((int)esp->dma_regs, dma_count); 102352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer vdma_enable ((int)esp->dma_regs); 103352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 104352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer scsi_esp_cmd(esp, cmd); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 107352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic int jazz_esp_dma_error(struct esp *esp) 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 109352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer u32 enable = vdma_get_enable((int)esp->dma_regs); 110352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 111352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (enable & (R4030_MEM_INTR|R4030_ADDR_INTR)) 112352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return 1; 113352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 114352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return 0; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 117352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic const struct esp_driver_ops jazz_esp_ops = { 118352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .esp_write8 = jazz_esp_write8, 119352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .esp_read8 = jazz_esp_read8, 120352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .map_single = jazz_esp_map_single, 121352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .map_sg = jazz_esp_map_sg, 122352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .unmap_single = jazz_esp_unmap_single, 123352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .unmap_sg = jazz_esp_unmap_sg, 124352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .irq_pending = jazz_esp_irq_pending, 125352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .reset_dma = jazz_esp_reset_dma, 126352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .dma_drain = jazz_esp_dma_drain, 127352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .dma_invalidate = jazz_esp_dma_invalidate, 128352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .send_dma_cmd = jazz_esp_send_dma_cmd, 129352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .dma_error = jazz_esp_dma_error, 130352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer}; 131352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 1326f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_jazz_probe(struct platform_device *dev) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 134352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer struct scsi_host_template *tpnt = &scsi_esp_template; 135352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer struct Scsi_Host *host; 136352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer struct esp *esp; 137352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer struct resource *res; 138352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer int err; 139352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 140352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer host = scsi_host_alloc(tpnt, sizeof(struct esp)); 141352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 142352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer err = -ENOMEM; 143352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (!host) 144352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer goto fail; 145352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 146352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer host->max_id = 8; 1472b14ec787869707843a14164a3ba91930a076031Christoph Hellwig esp = shost_priv(host); 148352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 149352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->host = host; 150352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->dev = dev; 151352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->ops = &jazz_esp_ops; 152352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 153352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer res = platform_get_resource(dev, IORESOURCE_MEM, 0); 154352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (!res) 155352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer goto fail_unlink; 156352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 157352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->regs = (void __iomem *)res->start; 158352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (!esp->regs) 159352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer goto fail_unlink; 160352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 161352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer res = platform_get_resource(dev, IORESOURCE_MEM, 1); 162352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (!res) 163352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer goto fail_unlink; 164352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 165352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->dma_regs = (void __iomem *)res->start; 166352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 167352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->command_block = dma_alloc_coherent(esp->dev, 16, 168352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer &esp->command_block_dma, 169352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer GFP_KERNEL); 170352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (!esp->command_block) 171352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer goto fail_unmap_regs; 172352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 173352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer host->irq = platform_get_irq(dev, 0); 174352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp); 175352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (err < 0) 176352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer goto fail_unmap_command_block; 177352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 178352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->scsi_id = 7; 179352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->host->this_id = esp->scsi_id; 180352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->scsi_id_mask = (1 << esp->scsi_id); 181352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->cfreq = 40000000; 182352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 183352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer dev_set_drvdata(&dev->dev, esp); 184352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 185352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer err = scsi_esp_register(esp, &dev->dev); 186352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer if (err) 187352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer goto fail_free_irq; 188352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 189352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return 0; 190352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 191352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferfail_free_irq: 192352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer free_irq(host->irq, esp); 193352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferfail_unmap_command_block: 194352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer dma_free_coherent(esp->dev, 16, 195352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->command_block, 196352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->command_block_dma); 197352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferfail_unmap_regs: 198352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferfail_unlink: 199352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer scsi_host_put(host); 200352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferfail: 201352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return err; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2046f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_jazz_remove(struct platform_device *dev) 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 206352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer struct esp *esp = dev_get_drvdata(&dev->dev); 207352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer unsigned int irq = esp->host->irq; 208352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 209352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer scsi_esp_unregister(esp); 210352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 211352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer free_irq(irq, esp); 212352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer dma_free_coherent(esp->dev, 16, 213352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->command_block, 214352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer esp->command_block_dma); 215352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 216352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer scsi_host_put(esp->host); 217352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 218352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return 0; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221ecc1241e80a0bdc854b1602a44be3ad106753d4fKay Sievers/* work with hotplug and coldplug */ 222ecc1241e80a0bdc854b1602a44be3ad106753d4fKay SieversMODULE_ALIAS("platform:jazz_esp"); 223ecc1241e80a0bdc854b1602a44be3ad106753d4fKay Sievers 224352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic struct platform_driver esp_jazz_driver = { 225352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .probe = esp_jazz_probe, 2266f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartman .remove = esp_jazz_remove, 227352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .driver = { 228352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer .name = "jazz_esp", 229ecc1241e80a0bdc854b1602a44be3ad106753d4fKay Sievers .owner = THIS_MODULE, 230352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer }, 231352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer}; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 233352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic int __init jazz_esp_init(void) 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 235352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer return platform_driver_register(&esp_jazz_driver); 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 238352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerferstatic void __exit jazz_esp_exit(void) 239352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer{ 240352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer platform_driver_unregister(&esp_jazz_driver); 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 243352e921f0dd42f79652cdb50dd91122d068d7209Thomas BogendoerferMODULE_DESCRIPTION("JAZZ ESP SCSI driver"); 244352e921f0dd42f79652cdb50dd91122d068d7209Thomas BogendoerferMODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)"); 245352e921f0dd42f79652cdb50dd91122d068d7209Thomas BogendoerferMODULE_LICENSE("GPL"); 246352e921f0dd42f79652cdb50dd91122d068d7209Thomas BogendoerferMODULE_VERSION(DRV_VERSION); 247352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfer 248352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfermodule_init(jazz_esp_init); 249352e921f0dd42f79652cdb50dd91122d068d7209Thomas Bogendoerfermodule_exit(jazz_esp_exit); 250