1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | |
3 | /* SNI RM driver |
4 | * |
5 | * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com |
6 | **----------------------------------------------------------------------------- |
7 | ** |
8 | ** |
9 | **----------------------------------------------------------------------------- |
10 | */ |
11 | |
12 | /* |
13 | * Based on lasi700.c |
14 | */ |
15 | |
16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> |
18 | #include <linux/init.h> |
19 | #include <linux/types.h> |
20 | #include <linux/slab.h> |
21 | #include <linux/stat.h> |
22 | #include <linux/mm.h> |
23 | #include <linux/blkdev.h> |
24 | #include <linux/sched.h> |
25 | #include <linux/ioport.h> |
26 | #include <linux/dma-mapping.h> |
27 | #include <linux/platform_device.h> |
28 | |
29 | #include <asm/page.h> |
30 | #include <asm/irq.h> |
31 | #include <asm/delay.h> |
32 | |
33 | #include <scsi/scsi_host.h> |
34 | #include <scsi/scsi_device.h> |
35 | #include <scsi/scsi_transport.h> |
36 | #include <scsi/scsi_transport_spi.h> |
37 | |
38 | #include "53c700.h" |
39 | |
40 | MODULE_AUTHOR("Thomas Bogendörfer" ); |
41 | MODULE_DESCRIPTION("SNI RM 53c710 SCSI Driver" ); |
42 | MODULE_LICENSE("GPL" ); |
43 | MODULE_ALIAS("platform:snirm_53c710" ); |
44 | |
45 | #define SNIRM710_CLOCK 32 |
46 | |
47 | static struct scsi_host_template snirm710_template = { |
48 | .name = "SNI RM SCSI 53c710" , |
49 | .proc_name = "snirm_53c710" , |
50 | .this_id = 7, |
51 | .module = THIS_MODULE, |
52 | }; |
53 | |
54 | static int snirm710_probe(struct platform_device *dev) |
55 | { |
56 | unsigned long base; |
57 | struct NCR_700_Host_Parameters *hostdata; |
58 | struct Scsi_Host *host; |
59 | struct resource *res; |
60 | int rc; |
61 | |
62 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
63 | if (!res) |
64 | return -ENODEV; |
65 | |
66 | base = res->start; |
67 | hostdata = kzalloc(size: sizeof(*hostdata), GFP_KERNEL); |
68 | if (!hostdata) |
69 | return -ENOMEM; |
70 | |
71 | hostdata->dev = &dev->dev; |
72 | dma_set_mask(dev: &dev->dev, DMA_BIT_MASK(32)); |
73 | hostdata->base = ioremap(offset: base, size: 0x100); |
74 | hostdata->differential = 0; |
75 | |
76 | hostdata->clock = SNIRM710_CLOCK; |
77 | hostdata->force_le_on_be = 1; |
78 | hostdata->chip710 = 1; |
79 | hostdata->burst_length = 4; |
80 | |
81 | host = NCR_700_detect(&snirm710_template, hostdata, &dev->dev); |
82 | if (!host) |
83 | goto out_kfree; |
84 | host->this_id = 7; |
85 | host->base = base; |
86 | host->irq = rc = platform_get_irq(dev, 0); |
87 | if (rc < 0) |
88 | goto out_put_host; |
89 | if(request_irq(irq: host->irq, handler: NCR_700_intr, IRQF_SHARED, name: "snirm710" , dev: host)) { |
90 | printk(KERN_ERR "snirm710: request_irq failed!\n" ); |
91 | goto out_put_host; |
92 | } |
93 | |
94 | dev_set_drvdata(dev: &dev->dev, data: host); |
95 | scsi_scan_host(host); |
96 | |
97 | return 0; |
98 | |
99 | out_put_host: |
100 | scsi_host_put(t: host); |
101 | out_kfree: |
102 | iounmap(addr: hostdata->base); |
103 | kfree(objp: hostdata); |
104 | return -ENODEV; |
105 | } |
106 | |
107 | static void snirm710_driver_remove(struct platform_device *dev) |
108 | { |
109 | struct Scsi_Host *host = dev_get_drvdata(dev: &dev->dev); |
110 | struct NCR_700_Host_Parameters *hostdata = |
111 | (struct NCR_700_Host_Parameters *)host->hostdata[0]; |
112 | |
113 | scsi_remove_host(host); |
114 | NCR_700_release(host); |
115 | free_irq(host->irq, host); |
116 | iounmap(addr: hostdata->base); |
117 | kfree(objp: hostdata); |
118 | } |
119 | |
120 | static struct platform_driver snirm710_driver = { |
121 | .probe = snirm710_probe, |
122 | .remove_new = snirm710_driver_remove, |
123 | .driver = { |
124 | .name = "snirm_53c710" , |
125 | }, |
126 | }; |
127 | module_platform_driver(snirm710_driver); |
128 | |