Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-ip22

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-ip22:
Convert SGI IP22 and specific drivers to platform_device.

+387 -202
+1 -1
arch/mips/sgi-ip22/Makefile
··· 4 4 # 5 5 6 6 obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ 7 - ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o 7 + ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o 8 8 9 9 obj-$(CONFIG_EISA) += ip22-eisa.o
+177
arch/mips/sgi-ip22/ip22-platform.c
··· 1 + #include <linux/init.h> 2 + #include <linux/if_ether.h> 3 + #include <linux/kernel.h> 4 + #include <linux/platform_device.h> 5 + 6 + #include <asm/paccess.h> 7 + #include <asm/sgi/ip22.h> 8 + #include <asm/sgi/hpc3.h> 9 + #include <asm/sgi/mc.h> 10 + #include <asm/sgi/seeq.h> 11 + #include <asm/sgi/wd.h> 12 + 13 + static struct resource sgiwd93_0_resources[] = { 14 + { 15 + .name = "eth0 irq", 16 + .start = SGI_WD93_0_IRQ, 17 + .end = SGI_WD93_0_IRQ, 18 + .flags = IORESOURCE_IRQ 19 + } 20 + }; 21 + 22 + static struct sgiwd93_platform_data sgiwd93_0_pd = { 23 + .unit = 0, 24 + .irq = SGI_WD93_0_IRQ, 25 + }; 26 + 27 + static struct platform_device sgiwd93_0_device = { 28 + .name = "sgiwd93", 29 + .id = 0, 30 + .num_resources = ARRAY_SIZE(sgiwd93_0_resources), 31 + .resource = sgiwd93_0_resources, 32 + .dev = { 33 + .platform_data = &sgiwd93_0_pd, 34 + }, 35 + }; 36 + 37 + static struct resource sgiwd93_1_resources[] = { 38 + { 39 + .name = "eth0 irq", 40 + .start = SGI_WD93_1_IRQ, 41 + .end = SGI_WD93_1_IRQ, 42 + .flags = IORESOURCE_IRQ 43 + } 44 + }; 45 + 46 + static struct sgiwd93_platform_data sgiwd93_1_pd = { 47 + .unit = 1, 48 + .irq = SGI_WD93_1_IRQ, 49 + }; 50 + 51 + static struct platform_device sgiwd93_1_device = { 52 + .name = "sgiwd93", 53 + .id = 1, 54 + .num_resources = ARRAY_SIZE(sgiwd93_1_resources), 55 + .resource = sgiwd93_1_resources, 56 + .dev = { 57 + .platform_data = &sgiwd93_1_pd, 58 + }, 59 + }; 60 + 61 + /* 62 + * Create a platform device for the GPI port that receives the 63 + * image data from the embedded camera. 64 + */ 65 + static int __init sgiwd93_devinit(void) 66 + { 67 + int res; 68 + 69 + sgiwd93_0_pd.hregs = &hpc3c0->scsi_chan0; 70 + sgiwd93_0_pd.wdregs = (unsigned char *) hpc3c0->scsi0_ext; 71 + 72 + res = platform_device_register(&sgiwd93_0_device); 73 + if (res) 74 + return res; 75 + 76 + if (!ip22_is_fullhouse()) 77 + return 0; 78 + 79 + sgiwd93_1_pd.hregs = &hpc3c0->scsi_chan1; 80 + sgiwd93_1_pd.wdregs = (unsigned char *) hpc3c0->scsi1_ext; 81 + 82 + return platform_device_register(&sgiwd93_1_device); 83 + } 84 + 85 + device_initcall(sgiwd93_devinit); 86 + 87 + static struct resource sgiseeq_0_resources[] = { 88 + { 89 + .name = "eth0 irq", 90 + .start = SGI_ENET_IRQ, 91 + .end = SGI_ENET_IRQ, 92 + .flags = IORESOURCE_IRQ 93 + } 94 + }; 95 + 96 + static struct sgiseeq_platform_data eth0_pd; 97 + 98 + static struct platform_device eth0_device = { 99 + .name = "sgiseeq", 100 + .id = 0, 101 + .num_resources = ARRAY_SIZE(sgiseeq_0_resources), 102 + .resource = sgiseeq_0_resources, 103 + .dev = { 104 + .platform_data = &eth0_pd, 105 + }, 106 + }; 107 + 108 + static struct resource sgiseeq_1_resources[] = { 109 + { 110 + .name = "eth1 irq", 111 + .start = SGI_GIO_0_IRQ, 112 + .end = SGI_GIO_0_IRQ, 113 + .flags = IORESOURCE_IRQ 114 + } 115 + }; 116 + 117 + static struct sgiseeq_platform_data eth1_pd; 118 + 119 + static struct platform_device eth1_device = { 120 + .name = "sgiseeq", 121 + .id = 1, 122 + .num_resources = ARRAY_SIZE(sgiseeq_1_resources), 123 + .resource = sgiseeq_1_resources, 124 + .dev = { 125 + .platform_data = &eth1_pd, 126 + }, 127 + }; 128 + 129 + /* 130 + * Create a platform device for the GPI port that receives the 131 + * image data from the embedded camera. 132 + */ 133 + static int __init sgiseeq_devinit(void) 134 + { 135 + unsigned int tmp; 136 + int res, i; 137 + 138 + eth0_pd.hpc = hpc3c0; 139 + eth0_pd.irq = SGI_ENET_IRQ; 140 + #define EADDR_NVOFS 250 141 + for (i = 0; i < 3; i++) { 142 + unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); 143 + 144 + eth0_pd.mac[2 * i] = tmp >> 8; 145 + eth0_pd.mac[2 * i + 1] = tmp & 0xff; 146 + } 147 + 148 + res = platform_device_register(&eth0_device); 149 + if (res) 150 + return res; 151 + 152 + /* Second HPC is missing? */ 153 + if (ip22_is_fullhouse() || 154 + !get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1])) 155 + return 0; 156 + 157 + sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 | 158 + SGIMC_GIOPAR_HPC264; 159 + hpc3c1->pbus_piocfg[0][0] = 0x3ffff; 160 + /* interrupt/config register on Challenge S Mezz board */ 161 + hpc3c1->pbus_extregs[0][0] = 0x30; 162 + 163 + eth1_pd.hpc = hpc3c1; 164 + eth1_pd.irq = SGI_GIO_0_IRQ; 165 + #define EADDR_NVOFS 250 166 + for (i = 0; i < 3; i++) { 167 + unsigned short tmp = ip22_eeprom_read(&hpc3c1->eeprom, 168 + EADDR_NVOFS / 2 + i); 169 + 170 + eth1_pd.mac[2 * i] = tmp >> 8; 171 + eth1_pd.mac[2 * i + 1] = tmp & 0xff; 172 + } 173 + 174 + return platform_device_register(&eth1_device); 175 + } 176 + 177 + device_initcall(sgiseeq_devinit);
+38 -47
drivers/net/sgiseeq.c
··· 16 16 #include <linux/string.h> 17 17 #include <linux/delay.h> 18 18 #include <linux/netdevice.h> 19 + #include <linux/platform_device.h> 19 20 #include <linux/etherdevice.h> 20 21 #include <linux/skbuff.h> 21 22 22 23 #include <asm/sgi/hpc3.h> 23 24 #include <asm/sgi/ip22.h> 25 + #include <asm/sgi/seeq.h> 24 26 25 27 #include "sgiseeq.h" 26 28 ··· 94 92 95 93 struct net_device_stats stats; 96 94 97 - struct net_device *next_module; 98 95 spinlock_t tx_lock; 99 96 }; 100 - 101 - /* A list of all installed seeq devices, for removing the driver module. */ 102 - static struct net_device *root_sgiseeq_dev; 103 97 104 98 static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) 105 99 { ··· 622 624 623 625 #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) 624 626 625 - static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) 627 + static int __init sgiseeq_probe(struct platform_device *pdev) 626 628 { 629 + struct sgiseeq_platform_data *pd = pdev->dev.platform_data; 630 + struct hpc3_regs *hpcregs = pd->hpc; 627 631 struct sgiseeq_init_block *sr; 632 + unsigned int irq = pd->irq; 628 633 struct sgiseeq_private *sp; 629 634 struct net_device *dev; 630 635 int err, i; ··· 638 637 err = -ENOMEM; 639 638 goto err_out; 640 639 } 640 + 641 + platform_set_drvdata(pdev, dev); 641 642 sp = netdev_priv(dev); 642 643 643 644 /* Make private data page aligned */ ··· 651 648 } 652 649 sp->srings = sr; 653 650 654 - #define EADDR_NVOFS 250 655 - for (i = 0; i < 3; i++) { 656 - unsigned short tmp = has_eeprom ? 657 - ip22_eeprom_read(&hpcregs->eeprom, EADDR_NVOFS / 2+i) : 658 - ip22_nvram_read(EADDR_NVOFS / 2+i); 659 - 660 - dev->dev_addr[2 * i] = tmp >> 8; 661 - dev->dev_addr[2 * i + 1] = tmp & 0xff; 662 - } 651 + memcpy(dev->dev_addr, pd->mac, ETH_ALEN); 663 652 664 653 #ifdef DEBUG 665 654 gpriv = sp; ··· 715 720 for (i = 0; i < 6; i++) 716 721 printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); 717 722 718 - sp->next_module = root_sgiseeq_dev; 719 - root_sgiseeq_dev = dev; 720 - 721 723 return 0; 722 724 723 725 err_out_free_page: ··· 726 734 return err; 727 735 } 728 736 729 - static int __init sgiseeq_probe(void) 737 + static void __exit sgiseeq_remove(struct platform_device *pdev) 730 738 { 731 - unsigned int tmp, ret1, ret2 = 0; 739 + struct net_device *dev = platform_get_drvdata(pdev); 740 + struct sgiseeq_private *sp = netdev_priv(dev); 732 741 733 - /* On board adapter on 1st HPC is always present */ 734 - ret1 = sgiseeq_init(hpc3c0, SGI_ENET_IRQ, 0); 735 - /* Let's see if second HPC is there */ 736 - if (!(ip22_is_fullhouse()) && 737 - get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]) == 0) { 738 - sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | 739 - SGIMC_GIOPAR_EXP164 | 740 - SGIMC_GIOPAR_HPC264; 741 - hpc3c1->pbus_piocfg[0][0] = 0x3ffff; 742 - /* interrupt/config register on Challenge S Mezz board */ 743 - hpc3c1->pbus_extregs[0][0] = 0x30; 744 - ret2 = sgiseeq_init(hpc3c1, SGI_GIO_0_IRQ, 1); 745 - } 746 - 747 - return (ret1 & ret2) ? ret1 : 0; 742 + unregister_netdev(dev); 743 + free_page((unsigned long) sp->srings); 744 + free_netdev(dev); 745 + platform_set_drvdata(pdev, NULL); 748 746 } 749 747 750 - static void __exit sgiseeq_exit(void) 751 - { 752 - struct net_device *next, *dev; 753 - struct sgiseeq_private *sp; 754 - 755 - for (dev = root_sgiseeq_dev; dev; dev = next) { 756 - sp = (struct sgiseeq_private *) netdev_priv(dev); 757 - next = sp->next_module; 758 - unregister_netdev(dev); 759 - free_page((unsigned long) sp->srings); 760 - free_netdev(dev); 748 + static struct platform_driver sgiseeq_driver = { 749 + .probe = sgiseeq_probe, 750 + .remove = __devexit_p(sgiseeq_remove), 751 + .driver = { 752 + .name = "sgiseeq" 761 753 } 754 + }; 755 + 756 + static int __init sgiseeq_module_init(void) 757 + { 758 + if (platform_driver_register(&sgiseeq_driver)) { 759 + printk(KERN_ERR "Driver registration failed\n"); 760 + return -ENODEV; 761 + } 762 + 763 + return 0; 762 764 } 763 765 764 - module_init(sgiseeq_probe); 765 - module_exit(sgiseeq_exit); 766 + static void __exit sgiseeq_module_exit(void) 767 + { 768 + platform_driver_unregister(&sgiseeq_driver); 769 + } 770 + 771 + module_init(sgiseeq_module_init); 772 + module_exit(sgiseeq_module_exit); 766 773 767 774 MODULE_DESCRIPTION("SGI Seeq 8003 driver"); 768 775 MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
+130 -154
drivers/scsi/sgiwd93.c
··· 6 6 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 7 7 * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) 8 8 * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org) 9 - * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) 9 + * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org) 10 10 * 11 11 * (In all truth, Jed Schimmel wrote all this code.) 12 12 */ 13 - #include <linux/init.h> 14 - #include <linux/interrupt.h> 15 - #include <linux/types.h> 16 - #include <linux/mm.h> 17 - #include <linux/blkdev.h> 13 + 14 + #undef DEBUG 15 + 18 16 #include <linux/delay.h> 19 17 #include <linux/dma-mapping.h> 18 + #include <linux/gfp.h> 19 + #include <linux/interrupt.h> 20 + #include <linux/init.h> 21 + #include <linux/kernel.h> 22 + #include <linux/types.h> 23 + #include <linux/module.h> 24 + #include <linux/platform_device.h> 20 25 #include <linux/spinlock.h> 21 26 22 - #include <asm/page.h> 23 - #include <asm/pgtable.h> 24 - #include <asm/sgialib.h> 25 - #include <asm/sgi/sgi.h> 26 - #include <asm/sgi/mc.h> 27 27 #include <asm/sgi/hpc3.h> 28 28 #include <asm/sgi/ip22.h> 29 - #include <asm/irq.h> 30 - #include <asm/io.h> 29 + #include <asm/sgi/wd.h> 31 30 32 31 #include "scsi.h" 33 - #include <scsi/scsi_host.h> 34 32 #include "wd33c93.h" 35 - 36 - #include <linux/stat.h> 37 - 38 - #if 0 39 - #define DPRINTK(args...) printk(args) 40 - #else 41 - #define DPRINTK(args...) 42 - #endif 43 - 44 - #define HDATA(ptr) ((struct ip22_hostdata *)((ptr)->hostdata)) 45 33 46 34 struct ip22_hostdata { 47 35 struct WD33C93_hostdata wh; 48 36 struct hpc_data { 49 37 dma_addr_t dma; 50 - void * cpu; 38 + void *cpu; 51 39 } hd; 52 40 }; 41 + 42 + #define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata)) 53 43 54 44 struct hpc_chunk { 55 45 struct hpc_dma_desc desc; 56 46 u32 _padding; /* align to quadword boundary */ 57 47 }; 58 48 59 - struct Scsi_Host *sgiwd93_host; 60 - struct Scsi_Host *sgiwd93_host1; 61 - 62 - /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */ 63 - static inline void write_wd33c93_count(const wd33c93_regs regs, 64 - unsigned long value) 65 - { 66 - *regs.SASR = WD_TRANSFER_COUNT_MSB; 67 - mb(); 68 - *regs.SCMD = ((value >> 16) & 0xff); 69 - *regs.SCMD = ((value >> 8) & 0xff); 70 - *regs.SCMD = ((value >> 0) & 0xff); 71 - mb(); 72 - } 73 - 74 - static inline unsigned long read_wd33c93_count(const wd33c93_regs regs) 75 - { 76 - unsigned long value; 77 - 78 - *regs.SASR = WD_TRANSFER_COUNT_MSB; 79 - mb(); 80 - value = ((*regs.SCMD & 0xff) << 16); 81 - value |= ((*regs.SCMD & 0xff) << 8); 82 - value |= ((*regs.SCMD & 0xff) << 0); 83 - mb(); 84 - return value; 85 - } 86 - 87 49 static irqreturn_t sgiwd93_intr(int irq, void *dev_id) 88 50 { 89 - struct Scsi_Host * host = (struct Scsi_Host *) dev_id; 51 + struct Scsi_Host * host = dev_id; 90 52 unsigned long flags; 91 53 92 54 spin_lock_irqsave(host->host_lock, flags); ··· 93 131 94 132 static int dma_setup(struct scsi_cmnd *cmd, int datainp) 95 133 { 96 - struct ip22_hostdata *hdata = HDATA(cmd->device->host); 134 + struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host); 97 135 struct hpc3_scsiregs *hregs = 98 136 (struct hpc3_scsiregs *) cmd->device->host->base; 99 137 struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; 100 138 101 - DPRINTK("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); 139 + pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); 102 140 103 141 hdata->wh.dma_dir = datainp; 104 142 ··· 113 151 114 152 fill_hpc_entries(hcp, cmd, datainp); 115 153 116 - DPRINTK(" HPCGO\n"); 154 + pr_debug(" HPCGO\n"); 117 155 118 156 /* Start up the HPC. */ 119 157 hregs->ndptr = hdata->hd.dma; ··· 128 166 static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 129 167 int status) 130 168 { 131 - struct ip22_hostdata *hdata = HDATA(instance); 169 + struct ip22_hostdata *hdata = host_to_hostdata(instance); 132 170 struct hpc3_scsiregs *hregs; 133 171 134 172 if (!SCpnt) ··· 136 174 137 175 hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; 138 176 139 - DPRINTK("dma_stop: status<%d> ", status); 177 + pr_debug("dma_stop: status<%d> ", status); 140 178 141 179 /* First stop the HPC and flush it's FIFO. */ 142 180 if (hdata->wh.dma_dir) { ··· 148 186 dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, 149 187 SCpnt->sc_data_direction); 150 188 151 - DPRINTK("\n"); 189 + pr_debug("\n"); 152 190 } 153 191 154 192 void sgiwd93_reset(unsigned long base) ··· 178 216 hcp->desc.pnext = hd->dma; 179 217 } 180 218 181 - static struct Scsi_Host * __init sgiwd93_setup_scsi( 182 - struct scsi_host_template *SGIblows, int unit, int irq, 183 - struct hpc3_scsiregs *hregs, unsigned char *wdregs) 184 - { 185 - struct ip22_hostdata *hdata; 186 - struct Scsi_Host *host; 187 - wd33c93_regs regs; 188 - 189 - host = scsi_register(SGIblows, sizeof(struct ip22_hostdata)); 190 - if (!host) 191 - return NULL; 192 - 193 - host->base = (unsigned long) hregs; 194 - host->irq = irq; 195 - 196 - hdata = HDATA(host); 197 - hdata->hd.cpu = dma_alloc_coherent(NULL, PAGE_SIZE, &hdata->hd.dma, 198 - GFP_KERNEL); 199 - if (!hdata->hd.cpu) { 200 - printk(KERN_WARNING "sgiwd93: Could not allocate memory for " 201 - "host %d buffer.\n", unit); 202 - goto out_unregister; 203 - } 204 - init_hpc_chain(&hdata->hd); 205 - 206 - regs.SASR = wdregs + 3; 207 - regs.SCMD = wdregs + 7; 208 - 209 - wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20)); 210 - 211 - if (hdata->wh.no_sync == 0xff) 212 - hdata->wh.no_sync = 0; 213 - 214 - if (request_irq(irq, sgiwd93_intr, 0, "SGI WD93", (void *) host)) { 215 - printk(KERN_WARNING "sgiwd93: Could not register irq %d " 216 - "for host %d.\n", irq, unit); 217 - goto out_free; 218 - } 219 - return host; 220 - 221 - out_free: 222 - dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); 223 - wd33c93_release(); 224 - 225 - out_unregister: 226 - scsi_unregister(host); 227 - 228 - return NULL; 229 - } 230 - 231 - static int __init sgiwd93_detect(struct scsi_host_template *SGIblows) 232 - { 233 - int found = 0; 234 - 235 - SGIblows->proc_name = "SGIWD93"; 236 - sgiwd93_host = sgiwd93_setup_scsi(SGIblows, 0, SGI_WD93_0_IRQ, 237 - &hpc3c0->scsi_chan0, 238 - (unsigned char *)hpc3c0->scsi0_ext); 239 - if (sgiwd93_host) 240 - found++; 241 - 242 - /* Set up second controller on the Indigo2 */ 243 - if (ip22_is_fullhouse()) { 244 - sgiwd93_host1 = sgiwd93_setup_scsi(SGIblows, 1, SGI_WD93_1_IRQ, 245 - &hpc3c0->scsi_chan1, 246 - (unsigned char *)hpc3c0->scsi1_ext); 247 - if (sgiwd93_host1) 248 - found++; 249 - } 250 - 251 - return found; 252 - } 253 - 254 - static int sgiwd93_release(struct Scsi_Host *instance) 255 - { 256 - struct ip22_hostdata *hdata = HDATA(instance); 257 - int irq = 0; 258 - 259 - if (sgiwd93_host && sgiwd93_host == instance) 260 - irq = SGI_WD93_0_IRQ; 261 - else if (sgiwd93_host1 && sgiwd93_host1 == instance) 262 - irq = SGI_WD93_1_IRQ; 263 - 264 - free_irq(irq, sgiwd93_intr); 265 - dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); 266 - wd33c93_release(); 267 - 268 - return 1; 269 - } 270 - 271 219 static int sgiwd93_bus_reset(struct scsi_cmnd *cmd) 272 220 { 273 221 /* FIXME perform bus-specific reset */ ··· 197 325 * arguments not with pointers. So this is going to blow up beautyfully 198 326 * on 64-bit systems with memory outside the compat address spaces. 199 327 */ 200 - static struct scsi_host_template driver_template = { 328 + static struct scsi_host_template sgiwd93_template = { 329 + .module = THIS_MODULE, 201 330 .proc_name = "SGIWD93", 202 331 .name = "SGI WD93", 203 - .detect = sgiwd93_detect, 204 - .release = sgiwd93_release, 205 332 .queuecommand = wd33c93_queuecommand, 206 333 .eh_abort_handler = wd33c93_abort, 207 334 .eh_bus_reset_handler = sgiwd93_bus_reset, ··· 211 340 .cmd_per_lun = 8, 212 341 .use_clustering = DISABLE_CLUSTERING, 213 342 }; 214 - #include "scsi_module.c" 343 + 344 + static int __init sgiwd93_probe(struct platform_device *pdev) 345 + { 346 + struct sgiwd93_platform_data *pd = pdev->dev.platform_data; 347 + unsigned char *wdregs = pd->wdregs; 348 + struct hpc3_scsiregs *hregs = pd->hregs; 349 + struct ip22_hostdata *hdata; 350 + struct Scsi_Host *host; 351 + wd33c93_regs regs; 352 + unsigned int unit = pd->unit; 353 + unsigned int irq = pd->irq; 354 + int err; 355 + 356 + host = scsi_host_alloc(&sgiwd93_template, sizeof(struct ip22_hostdata)); 357 + if (!host) { 358 + err = -ENOMEM; 359 + goto out; 360 + } 361 + 362 + host->base = (unsigned long) hregs; 363 + host->irq = irq; 364 + 365 + hdata = host_to_hostdata(host); 366 + hdata->hd.cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, 367 + &hdata->hd.dma, GFP_KERNEL); 368 + if (!hdata->hd.cpu) { 369 + printk(KERN_WARNING "sgiwd93: Could not allocate memory for " 370 + "host %d buffer.\n", unit); 371 + err = -ENOMEM; 372 + goto out_put; 373 + } 374 + 375 + init_hpc_chain(&hdata->hd); 376 + 377 + regs.SASR = wdregs + 3; 378 + regs.SCMD = wdregs + 7; 379 + 380 + wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20)); 381 + 382 + if (hdata->wh.no_sync == 0xff) 383 + hdata->wh.no_sync = 0; 384 + 385 + err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host); 386 + if (err) { 387 + printk(KERN_WARNING "sgiwd93: Could not register irq %d " 388 + "for host %d.\n", irq, unit); 389 + goto out_free; 390 + } 391 + 392 + platform_set_drvdata(pdev, host); 393 + 394 + err = scsi_add_host(host, NULL); 395 + if (err) 396 + goto out_irq; 397 + 398 + scsi_scan_host(host); 399 + 400 + return 0; 401 + 402 + out_irq: 403 + free_irq(irq, host); 404 + out_free: 405 + dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); 406 + out_put: 407 + scsi_host_put(host); 408 + out: 409 + 410 + return err; 411 + } 412 + 413 + static void __exit sgiwd93_remove(struct platform_device *pdev) 414 + { 415 + struct Scsi_Host *host = platform_get_drvdata(pdev); 416 + struct ip22_hostdata *hdata = (struct ip22_hostdata *) host->hostdata; 417 + struct sgiwd93_platform_data *pd = pdev->dev.platform_data; 418 + 419 + scsi_remove_host(host); 420 + free_irq(pd->irq, host); 421 + dma_free_coherent(&pdev->dev, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); 422 + scsi_host_put(host); 423 + } 424 + 425 + static struct platform_driver sgiwd93_driver = { 426 + .probe = sgiwd93_probe, 427 + .remove = __devexit_p(sgiwd93_remove), 428 + .driver = { 429 + .name = "sgiwd93" 430 + } 431 + }; 432 + 433 + static int __init sgiwd93_module_init(void) 434 + { 435 + return platform_driver_register(&sgiwd93_driver); 436 + } 437 + 438 + static void __exit sgiwd93_module_exit(void) 439 + { 440 + return platform_driver_unregister(&sgiwd93_driver); 441 + } 442 + 443 + module_init(sgiwd93_module_init); 444 + module_exit(sgiwd93_module_exit); 445 + 446 + MODULE_DESCRIPTION("SGI WD33C93 driver"); 447 + MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>"); 448 + MODULE_LICENSE("GPL");
+21
include/asm-mips/sgi/seeq.h
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file "COPYING" in the main directory of this archive 4 + * for more details. 5 + * 6 + * Copyright (C) 2007 by Ralf Baechle 7 + */ 8 + #ifndef __ASM_SGI_SEEQ_H 9 + #define __ASM_SGI_SEEQ_H 10 + 11 + #include <linux/if_ether.h> 12 + 13 + #include <asm/sgi/hpc3.h> 14 + 15 + struct sgiseeq_platform_data { 16 + struct hpc3_regs *hpc; 17 + unsigned int irq; 18 + unsigned char mac[ETH_ALEN]; 19 + }; 20 + 21 + #endif /* __ASM_SGI_SEEQ_H */
+20
include/asm-mips/sgi/wd.h
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file "COPYING" in the main directory of this archive 4 + * for more details. 5 + * 6 + * Copyright (C) 2007 by Ralf Baechle 7 + */ 8 + #ifndef __ASM_SGI_WD_H 9 + #define __ASM_SGI_WD_H 10 + 11 + #include <asm/sgi/hpc3.h> 12 + 13 + struct sgiwd93_platform_data { 14 + unsigned int unit; 15 + unsigned int irq; 16 + struct hpc3_scsiregs *hregs; 17 + unsigned char *wdregs; 18 + }; 19 + 20 + #endif /* __ASM_SGI_WD_H */