1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Linux ARCnet driver - "RIM I" (entirely mem-mapped) cards
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Written 1994-1999 by Avery Pennarun.
5*4882a593Smuzhiyun * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
6*4882a593Smuzhiyun * Derived from skeleton.c by Donald Becker.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
9*4882a593Smuzhiyun * for sponsoring the further development of this driver.
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * **********************
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * The original copyright of skeleton.c was as follows:
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * skeleton.c Written 1993 by Donald Becker.
16*4882a593Smuzhiyun * Copyright 1993 United States Government as represented by the
17*4882a593Smuzhiyun * Director, National Security Agency. This software may only be used
18*4882a593Smuzhiyun * and distributed according to the terms of the GNU General Public License as
19*4882a593Smuzhiyun * modified by SRC, incorporated herein by reference.
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * **********************
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * For more details, see drivers/net/arcnet.c
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * **********************
26*4882a593Smuzhiyun */
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include <linux/kernel.h>
31*4882a593Smuzhiyun #include <linux/module.h>
32*4882a593Smuzhiyun #include <linux/moduleparam.h>
33*4882a593Smuzhiyun #include <linux/ioport.h>
34*4882a593Smuzhiyun #include <linux/delay.h>
35*4882a593Smuzhiyun #include <linux/netdevice.h>
36*4882a593Smuzhiyun #include <linux/memblock.h>
37*4882a593Smuzhiyun #include <linux/init.h>
38*4882a593Smuzhiyun #include <linux/interrupt.h>
39*4882a593Smuzhiyun #include <linux/io.h>
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #include "arcdevice.h"
42*4882a593Smuzhiyun #include "com9026.h"
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* Internal function declarations */
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun static int arcrimi_probe(struct net_device *dev);
47*4882a593Smuzhiyun static int arcrimi_found(struct net_device *dev);
48*4882a593Smuzhiyun static void arcrimi_command(struct net_device *dev, int command);
49*4882a593Smuzhiyun static int arcrimi_status(struct net_device *dev);
50*4882a593Smuzhiyun static void arcrimi_setmask(struct net_device *dev, int mask);
51*4882a593Smuzhiyun static int arcrimi_reset(struct net_device *dev, int really_reset);
52*4882a593Smuzhiyun static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
53*4882a593Smuzhiyun void *buf, int count);
54*4882a593Smuzhiyun static void arcrimi_copy_from_card(struct net_device *dev, int bufnum,
55*4882a593Smuzhiyun int offset, void *buf, int count);
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* Handy defines for ARCnet specific stuff */
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /* Amount of I/O memory used by the card */
60*4882a593Smuzhiyun #define BUFFER_SIZE (512)
61*4882a593Smuzhiyun #define MIRROR_SIZE (BUFFER_SIZE * 4)
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun /* We cannot probe for a RIM I card; one reason is I don't know how to reset
64*4882a593Smuzhiyun * them. In fact, we can't even get their node ID automatically. So, we
65*4882a593Smuzhiyun * need to be passed a specific shmem address, IRQ, and node ID.
66*4882a593Smuzhiyun */
arcrimi_probe(struct net_device * dev)67*4882a593Smuzhiyun static int __init arcrimi_probe(struct net_device *dev)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun if (BUGLVL(D_NORMAL)) {
70*4882a593Smuzhiyun pr_info("%s\n", "RIM I (entirely mem-mapped) support");
71*4882a593Smuzhiyun pr_info("E-mail me if you actually test the RIM I driver, please!\n");
72*4882a593Smuzhiyun pr_info("Given: node %02Xh, shmem %lXh, irq %d\n",
73*4882a593Smuzhiyun dev->dev_addr[0], dev->mem_start, dev->irq);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun if (dev->mem_start <= 0 || dev->irq <= 0) {
77*4882a593Smuzhiyun if (BUGLVL(D_NORMAL))
78*4882a593Smuzhiyun pr_err("No autoprobe for RIM I; you must specify the shmem and irq!\n");
79*4882a593Smuzhiyun return -ENODEV;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun if (dev->dev_addr[0] == 0) {
82*4882a593Smuzhiyun if (BUGLVL(D_NORMAL))
83*4882a593Smuzhiyun pr_err("You need to specify your card's station ID!\n");
84*4882a593Smuzhiyun return -ENODEV;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun /* Grab the memory region at mem_start for MIRROR_SIZE bytes.
87*4882a593Smuzhiyun * Later in arcrimi_found() the real size will be determined
88*4882a593Smuzhiyun * and this reserve will be released and the correct size
89*4882a593Smuzhiyun * will be taken.
90*4882a593Smuzhiyun */
91*4882a593Smuzhiyun if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) {
92*4882a593Smuzhiyun if (BUGLVL(D_NORMAL))
93*4882a593Smuzhiyun pr_notice("Card memory already allocated\n");
94*4882a593Smuzhiyun return -ENODEV;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun return arcrimi_found(dev);
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
check_mirror(unsigned long addr,size_t size)99*4882a593Smuzhiyun static int check_mirror(unsigned long addr, size_t size)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun void __iomem *p;
102*4882a593Smuzhiyun int res = -1;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun if (!request_mem_region(addr, size, "arcnet (90xx)"))
105*4882a593Smuzhiyun return -1;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun p = ioremap(addr, size);
108*4882a593Smuzhiyun if (p) {
109*4882a593Smuzhiyun if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue)
110*4882a593Smuzhiyun res = 1;
111*4882a593Smuzhiyun else
112*4882a593Smuzhiyun res = 0;
113*4882a593Smuzhiyun iounmap(p);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun release_mem_region(addr, size);
117*4882a593Smuzhiyun return res;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* Set up the struct net_device associated with this card.
121*4882a593Smuzhiyun * Called after probing succeeds.
122*4882a593Smuzhiyun */
arcrimi_found(struct net_device * dev)123*4882a593Smuzhiyun static int __init arcrimi_found(struct net_device *dev)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun struct arcnet_local *lp;
126*4882a593Smuzhiyun unsigned long first_mirror, last_mirror, shmem;
127*4882a593Smuzhiyun void __iomem *p;
128*4882a593Smuzhiyun int mirror_size;
129*4882a593Smuzhiyun int err;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun p = ioremap(dev->mem_start, MIRROR_SIZE);
132*4882a593Smuzhiyun if (!p) {
133*4882a593Smuzhiyun release_mem_region(dev->mem_start, MIRROR_SIZE);
134*4882a593Smuzhiyun arc_printk(D_NORMAL, dev, "Can't ioremap\n");
135*4882a593Smuzhiyun return -ENODEV;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun /* reserve the irq */
139*4882a593Smuzhiyun if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
140*4882a593Smuzhiyun iounmap(p);
141*4882a593Smuzhiyun release_mem_region(dev->mem_start, MIRROR_SIZE);
142*4882a593Smuzhiyun arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq);
143*4882a593Smuzhiyun return -ENODEV;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun shmem = dev->mem_start;
147*4882a593Smuzhiyun arcnet_writeb(TESTvalue, p, COM9026_REG_W_INTMASK);
148*4882a593Smuzhiyun arcnet_writeb(TESTvalue, p, COM9026_REG_W_COMMAND);
149*4882a593Smuzhiyun /* actually the station/node ID */
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* find the real shared memory start/end points, including mirrors */
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /* guess the actual size of one "memory mirror" - the number of
154*4882a593Smuzhiyun * bytes between copies of the shared memory. On most cards, it's
155*4882a593Smuzhiyun * 2k (or there are no mirrors at all) but on some, it's 4k.
156*4882a593Smuzhiyun */
157*4882a593Smuzhiyun mirror_size = MIRROR_SIZE;
158*4882a593Smuzhiyun if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue &&
159*4882a593Smuzhiyun check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
160*4882a593Smuzhiyun check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
161*4882a593Smuzhiyun mirror_size = 2 * MIRROR_SIZE;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun first_mirror = shmem - mirror_size;
164*4882a593Smuzhiyun while (check_mirror(first_mirror, mirror_size) == 1)
165*4882a593Smuzhiyun first_mirror -= mirror_size;
166*4882a593Smuzhiyun first_mirror += mirror_size;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun last_mirror = shmem + mirror_size;
169*4882a593Smuzhiyun while (check_mirror(last_mirror, mirror_size) == 1)
170*4882a593Smuzhiyun last_mirror += mirror_size;
171*4882a593Smuzhiyun last_mirror -= mirror_size;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun dev->mem_start = first_mirror;
174*4882a593Smuzhiyun dev->mem_end = last_mirror + MIRROR_SIZE - 1;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /* initialize the rest of the device structure. */
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun lp = netdev_priv(dev);
179*4882a593Smuzhiyun lp->card_name = "RIM I";
180*4882a593Smuzhiyun lp->hw.command = arcrimi_command;
181*4882a593Smuzhiyun lp->hw.status = arcrimi_status;
182*4882a593Smuzhiyun lp->hw.intmask = arcrimi_setmask;
183*4882a593Smuzhiyun lp->hw.reset = arcrimi_reset;
184*4882a593Smuzhiyun lp->hw.owner = THIS_MODULE;
185*4882a593Smuzhiyun lp->hw.copy_to_card = arcrimi_copy_to_card;
186*4882a593Smuzhiyun lp->hw.copy_from_card = arcrimi_copy_from_card;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun /* re-reserve the memory region - arcrimi_probe() alloced this reqion
189*4882a593Smuzhiyun * but didn't know the real size. Free that region and then re-get
190*4882a593Smuzhiyun * with the correct size. There is a VERY slim chance this could
191*4882a593Smuzhiyun * fail.
192*4882a593Smuzhiyun */
193*4882a593Smuzhiyun iounmap(p);
194*4882a593Smuzhiyun release_mem_region(shmem, MIRROR_SIZE);
195*4882a593Smuzhiyun if (!request_mem_region(dev->mem_start,
196*4882a593Smuzhiyun dev->mem_end - dev->mem_start + 1,
197*4882a593Smuzhiyun "arcnet (90xx)")) {
198*4882a593Smuzhiyun arc_printk(D_NORMAL, dev, "Card memory already allocated\n");
199*4882a593Smuzhiyun goto err_free_irq;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun lp->mem_start = ioremap(dev->mem_start,
203*4882a593Smuzhiyun dev->mem_end - dev->mem_start + 1);
204*4882a593Smuzhiyun if (!lp->mem_start) {
205*4882a593Smuzhiyun arc_printk(D_NORMAL, dev, "Can't remap device memory!\n");
206*4882a593Smuzhiyun goto err_release_mem;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /* get and check the station ID from offset 1 in shmem */
210*4882a593Smuzhiyun dev->dev_addr[0] = arcnet_readb(lp->mem_start, COM9026_REG_R_STATION);
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun arc_printk(D_NORMAL, dev, "ARCnet RIM I: station %02Xh found at IRQ %d, ShMem %lXh (%ld*%d bytes)\n",
213*4882a593Smuzhiyun dev->dev_addr[0],
214*4882a593Smuzhiyun dev->irq, dev->mem_start,
215*4882a593Smuzhiyun (dev->mem_end - dev->mem_start + 1) / mirror_size,
216*4882a593Smuzhiyun mirror_size);
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun err = register_netdev(dev);
219*4882a593Smuzhiyun if (err)
220*4882a593Smuzhiyun goto err_unmap;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun return 0;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun err_unmap:
225*4882a593Smuzhiyun iounmap(lp->mem_start);
226*4882a593Smuzhiyun err_release_mem:
227*4882a593Smuzhiyun release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
228*4882a593Smuzhiyun err_free_irq:
229*4882a593Smuzhiyun free_irq(dev->irq, dev);
230*4882a593Smuzhiyun return -EIO;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /* Do a hardware reset on the card, and set up necessary registers.
234*4882a593Smuzhiyun *
235*4882a593Smuzhiyun * This should be called as little as possible, because it disrupts the
236*4882a593Smuzhiyun * token on the network (causes a RECON) and requires a significant delay.
237*4882a593Smuzhiyun *
238*4882a593Smuzhiyun * However, it does make sure the card is in a defined state.
239*4882a593Smuzhiyun */
arcrimi_reset(struct net_device * dev,int really_reset)240*4882a593Smuzhiyun static int arcrimi_reset(struct net_device *dev, int really_reset)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun struct arcnet_local *lp = netdev_priv(dev);
243*4882a593Smuzhiyun void __iomem *ioaddr = lp->mem_start + 0x800;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n",
246*4882a593Smuzhiyun dev->name, arcnet_readb(ioaddr, COM9026_REG_R_STATUS));
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun if (really_reset) {
249*4882a593Smuzhiyun arcnet_writeb(TESTvalue, ioaddr, -0x800); /* fake reset */
250*4882a593Smuzhiyun return 0;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun /* clear flags & end reset */
253*4882a593Smuzhiyun arcnet_writeb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
254*4882a593Smuzhiyun arcnet_writeb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun /* enable extended (512-byte) packets */
257*4882a593Smuzhiyun arcnet_writeb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun /* done! return success. */
260*4882a593Smuzhiyun return 0;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
arcrimi_setmask(struct net_device * dev,int mask)263*4882a593Smuzhiyun static void arcrimi_setmask(struct net_device *dev, int mask)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun struct arcnet_local *lp = netdev_priv(dev);
266*4882a593Smuzhiyun void __iomem *ioaddr = lp->mem_start + 0x800;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun arcnet_writeb(mask, ioaddr, COM9026_REG_W_INTMASK);
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
arcrimi_status(struct net_device * dev)271*4882a593Smuzhiyun static int arcrimi_status(struct net_device *dev)
272*4882a593Smuzhiyun {
273*4882a593Smuzhiyun struct arcnet_local *lp = netdev_priv(dev);
274*4882a593Smuzhiyun void __iomem *ioaddr = lp->mem_start + 0x800;
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun return arcnet_readb(ioaddr, COM9026_REG_R_STATUS);
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
arcrimi_command(struct net_device * dev,int cmd)279*4882a593Smuzhiyun static void arcrimi_command(struct net_device *dev, int cmd)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun struct arcnet_local *lp = netdev_priv(dev);
282*4882a593Smuzhiyun void __iomem *ioaddr = lp->mem_start + 0x800;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun arcnet_writeb(cmd, ioaddr, COM9026_REG_W_COMMAND);
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
arcrimi_copy_to_card(struct net_device * dev,int bufnum,int offset,void * buf,int count)287*4882a593Smuzhiyun static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
288*4882a593Smuzhiyun void *buf, int count)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun struct arcnet_local *lp = netdev_priv(dev);
291*4882a593Smuzhiyun void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun TIME(dev, "memcpy_toio", count, memcpy_toio(memaddr, buf, count));
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun
arcrimi_copy_from_card(struct net_device * dev,int bufnum,int offset,void * buf,int count)296*4882a593Smuzhiyun static void arcrimi_copy_from_card(struct net_device *dev, int bufnum,
297*4882a593Smuzhiyun int offset, void *buf, int count)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun struct arcnet_local *lp = netdev_priv(dev);
300*4882a593Smuzhiyun void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun TIME(dev, "memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun static int node;
306*4882a593Smuzhiyun static int io; /* use the insmod io= irq= node= options */
307*4882a593Smuzhiyun static int irq;
308*4882a593Smuzhiyun static char device[9]; /* use eg. device=arc1 to change name */
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun module_param(node, int, 0);
311*4882a593Smuzhiyun module_param(io, int, 0);
312*4882a593Smuzhiyun module_param(irq, int, 0);
313*4882a593Smuzhiyun module_param_string(device, device, sizeof(device), 0);
314*4882a593Smuzhiyun MODULE_LICENSE("GPL");
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun static struct net_device *my_dev;
317*4882a593Smuzhiyun
arc_rimi_init(void)318*4882a593Smuzhiyun static int __init arc_rimi_init(void)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun struct net_device *dev;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun dev = alloc_arcdev(device);
323*4882a593Smuzhiyun if (!dev)
324*4882a593Smuzhiyun return -ENOMEM;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun if (node && node != 0xff)
327*4882a593Smuzhiyun dev->dev_addr[0] = node;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun dev->mem_start = io;
330*4882a593Smuzhiyun dev->irq = irq;
331*4882a593Smuzhiyun if (dev->irq == 2)
332*4882a593Smuzhiyun dev->irq = 9;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun if (arcrimi_probe(dev)) {
335*4882a593Smuzhiyun free_arcdev(dev);
336*4882a593Smuzhiyun return -EIO;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun my_dev = dev;
340*4882a593Smuzhiyun return 0;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
arc_rimi_exit(void)343*4882a593Smuzhiyun static void __exit arc_rimi_exit(void)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun struct net_device *dev = my_dev;
346*4882a593Smuzhiyun struct arcnet_local *lp = netdev_priv(dev);
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun unregister_netdev(dev);
349*4882a593Smuzhiyun iounmap(lp->mem_start);
350*4882a593Smuzhiyun release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
351*4882a593Smuzhiyun free_irq(dev->irq, dev);
352*4882a593Smuzhiyun free_arcdev(dev);
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun #ifndef MODULE
arcrimi_setup(char * s)356*4882a593Smuzhiyun static int __init arcrimi_setup(char *s)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun int ints[8];
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun s = get_options(s, 8, ints);
361*4882a593Smuzhiyun if (!ints[0])
362*4882a593Smuzhiyun return 1;
363*4882a593Smuzhiyun switch (ints[0]) {
364*4882a593Smuzhiyun default: /* ERROR */
365*4882a593Smuzhiyun pr_err("Too many arguments\n");
366*4882a593Smuzhiyun fallthrough;
367*4882a593Smuzhiyun case 3: /* Node ID */
368*4882a593Smuzhiyun node = ints[3];
369*4882a593Smuzhiyun fallthrough;
370*4882a593Smuzhiyun case 2: /* IRQ */
371*4882a593Smuzhiyun irq = ints[2];
372*4882a593Smuzhiyun fallthrough;
373*4882a593Smuzhiyun case 1: /* IO address */
374*4882a593Smuzhiyun io = ints[1];
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun if (*s)
377*4882a593Smuzhiyun snprintf(device, sizeof(device), "%s", s);
378*4882a593Smuzhiyun return 1;
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun __setup("arcrimi=", arcrimi_setup);
381*4882a593Smuzhiyun #endif /* MODULE */
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun module_init(arc_rimi_init)
384*4882a593Smuzhiyun module_exit(arc_rimi_exit)
385