aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parport
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parport')
-rw-r--r--drivers/parport/Kconfig19
-rw-r--r--drivers/parport/Makefile3
-rw-r--r--drivers/parport/daisy.c2
-rw-r--r--drivers/parport/parport_arc.c139
-rw-r--r--drivers/parport/parport_ax88796.c443
-rw-r--r--drivers/parport/parport_sunbpp.c134
-rw-r--r--drivers/parport/share.c2
7 files changed, 530 insertions, 212 deletions
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index f63c387976cf..c7fa28a28b9f 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -48,7 +48,7 @@ config PARPORT_PC
48 48
49config PARPORT_SERIAL 49config PARPORT_SERIAL
50 tristate "Multi-IO cards (parallel and serial)" 50 tristate "Multi-IO cards (parallel and serial)"
51 depends on SERIAL_8250 && PARPORT_PC && PCI 51 depends on SERIAL_8250_PCI && PARPORT_PC && PCI
52 help 52 help
53 This adds support for multi-IO PCI cards that have parallel and 53 This adds support for multi-IO PCI cards that have parallel and
54 serial ports. You should say Y or M here. If you say M, the module 54 serial ports. You should say Y or M here. If you say M, the module
@@ -85,11 +85,6 @@ config PARPORT_PC_PCMCIA
85config PARPORT_NOT_PC 85config PARPORT_NOT_PC
86 bool 86 bool
87 87
88config PARPORT_ARC
89 tristate "Archimedes hardware"
90 depends on ARM && PARPORT
91 select PARPORT_NOT_PC
92
93config PARPORT_IP32 88config PARPORT_IP32
94 tristate "SGI IP32 builtin port (EXPERIMENTAL)" 89 tristate "SGI IP32 builtin port (EXPERIMENTAL)"
95 depends on SGI_IP32 && PARPORT && EXPERIMENTAL 90 depends on SGI_IP32 && PARPORT && EXPERIMENTAL
@@ -141,6 +136,18 @@ config PARPORT_SUNBPP
141 found on many Sun machines. Note that many of the newer Ultras 136 found on many Sun machines. Note that many of the newer Ultras
142 actually have pc style hardware instead. 137 actually have pc style hardware instead.
143 138
139config PARPORT_AX88796
140 tristate "AX88796 Parallel Port"
141 depends on PARPORT
142 select PARPORT_NOT_PC
143 help
144 Say Y here if you need support for the parallel port hardware on
145 the AX88796 network controller chip. This code is also available
146 as a module (say M), called parport_ax88796.
147
148 The driver is not dependant on the AX88796 network driver, and
149 should not interfere with the networking functions of the chip.
150
144config PARPORT_1284 151config PARPORT_1284
145 bool "IEEE 1284 transfer modes" 152 bool "IEEE 1284 transfer modes"
146 depends on PARPORT 153 depends on PARPORT
diff --git a/drivers/parport/Makefile b/drivers/parport/Makefile
index a19de35f8de2..696b8d4ca887 100644
--- a/drivers/parport/Makefile
+++ b/drivers/parport/Makefile
@@ -17,4 +17,5 @@ obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o
17obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o 17obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o
18obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o 18obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o
19obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o 19obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o
20obj-$(CONFIG_PARPORT_IP32) += parport_ip32.o 20obj-$(CONFIG_PARPORT_AX88796) += parport_ax88796.o
21obj-$(CONFIG_PARPORT_IP32) += parport_ip32.o \ No newline at end of file
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c
index 9ee67321b630..fd41e28101ea 100644
--- a/drivers/parport/daisy.c
+++ b/drivers/parport/daisy.c
@@ -283,7 +283,7 @@ void parport_close (struct pardevice *dev)
283 * 283 *
284 * This tries to locate a device on the given parallel port, 284 * This tries to locate a device on the given parallel port,
285 * multiplexor port and daisy chain address, and returns its 285 * multiplexor port and daisy chain address, and returns its
286 * device number or -NXIO if no device with those coordinates 286 * device number or %-ENXIO if no device with those coordinates
287 * exists. 287 * exists.
288 **/ 288 **/
289 289
diff --git a/drivers/parport/parport_arc.c b/drivers/parport/parport_arc.c
deleted file mode 100644
index b35bb4f48d62..000000000000
--- a/drivers/parport/parport_arc.c
+++ /dev/null
@@ -1,139 +0,0 @@
1/* Low-level parallel port routines for Archimedes onboard hardware
2 *
3 * Author: Phil Blundell <philb@gnu.org>
4 */
5
6/* This driver is for the parallel port hardware found on Acorn's old
7 * range of Archimedes machines. The A5000 and newer systems have PC-style
8 * I/O hardware and should use the parport_pc driver instead.
9 *
10 * The Acorn printer port hardware is very simple. There is a single 8-bit
11 * write-only latch for the data port and control/status bits are handled
12 * with various auxilliary input and output lines. The port is not
13 * bidirectional, does not support any modes other than SPP, and has only
14 * a subset of the standard printer control lines connected.
15 */
16
17#include <linux/threads.h>
18#include <linux/delay.h>
19#include <linux/errno.h>
20#include <linux/interrupt.h>
21#include <linux/ioport.h>
22#include <linux/kernel.h>
23#include <linux/slab.h>
24#include <linux/parport.h>
25
26#include <asm/ptrace.h>
27#include <asm/io.h>
28#include <asm/arch/oldlatches.h>
29#include <asm/arch/irqs.h>
30
31#define DATA_ADDRESS 0x3350010
32
33/* This is equivalent to the above and only used for request_region. */
34#define PORT_BASE 0x80000000 | ((DATA_ADDRESS - IO_BASE) >> 2)
35
36/* The hardware can't read from the data latch, so we must use a soft
37 copy. */
38static unsigned char data_copy;
39
40/* These are pretty simple. We know the irq is never shared and the
41 kernel does all the magic that's required. */
42static void arc_enable_irq(struct parport *p)
43{
44 enable_irq(p->irq);
45}
46
47static void arc_disable_irq(struct parport *p)
48{
49 disable_irq(p->irq);
50}
51
52static void arc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
53{
54 parport_generic_irq(irq, (struct parport *) dev_id, regs);
55}
56
57static void arc_write_data(struct parport *p, unsigned char data)
58{
59 data_copy = data;
60 outb_t(data, DATA_LATCH);
61}
62
63static unsigned char arc_read_data(struct parport *p)
64{
65 return data_copy;
66}
67
68static struct parport_operations parport_arc_ops =
69{
70 .write_data = arc_write_data,
71 .read_data = arc_read_data,
72
73 .write_control = arc_write_control,
74 .read_control = arc_read_control,
75 .frob_control = arc_frob_control,
76
77 .read_status = arc_read_status,
78
79 .enable_irq = arc_enable_irq,
80 .disable_irq = arc_disable_irq,
81
82 .data_forward = arc_data_forward,
83 .data_reverse = arc_data_reverse,
84
85 .init_state = arc_init_state,
86 .save_state = arc_save_state,
87 .restore_state = arc_restore_state,
88
89 .epp_write_data = parport_ieee1284_epp_write_data,
90 .epp_read_data = parport_ieee1284_epp_read_data,
91 .epp_write_addr = parport_ieee1284_epp_write_addr,
92 .epp_read_addr = parport_ieee1284_epp_read_addr,
93
94 .ecp_write_data = parport_ieee1284_ecp_write_data,
95 .ecp_read_data = parport_ieee1284_ecp_read_data,
96 .ecp_write_addr = parport_ieee1284_ecp_write_addr,
97
98 .compat_write_data = parport_ieee1284_write_compat,
99 .nibble_read_data = parport_ieee1284_read_nibble,
100 .byte_read_data = parport_ieee1284_read_byte,
101
102 .owner = THIS_MODULE,
103};
104
105/* --- Initialisation code -------------------------------- */
106
107static int parport_arc_init(void)
108{
109 /* Archimedes hardware provides only one port, at a fixed address */
110 struct parport *p;
111 struct resource res;
112 char *fake_name = "parport probe");
113
114 res = request_region(PORT_BASE, 1, fake_name);
115 if (res == NULL)
116 return 0;
117
118 p = parport_register_port (PORT_BASE, IRQ_PRINTERACK,
119 PARPORT_DMA_NONE, &parport_arc_ops);
120
121 if (!p) {
122 release_region(PORT_BASE, 1);
123 return 0;
124 }
125
126 p->modes = PARPORT_MODE_ARCSPP;
127 p->size = 1;
128 rename_region(res, p->name);
129
130 printk(KERN_INFO "%s: Archimedes on-board port, using irq %d\n",
131 p->irq);
132
133 /* Tell the high-level drivers about the port. */
134 parport_announce_port (p);
135
136 return 1;
137}
138
139module_init(parport_arc_init)
diff --git a/drivers/parport/parport_ax88796.c b/drivers/parport/parport_ax88796.c
new file mode 100644
index 000000000000..4baa719439a2
--- /dev/null
+++ b/drivers/parport/parport_ax88796.c
@@ -0,0 +1,443 @@
1/* linux/drivers/parport/parport_ax88796.c
2 *
3 * (c) 2005,2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10*/
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/parport.h>
15#include <linux/interrupt.h>
16#include <linux/errno.h>
17#include <linux/platform_device.h>
18
19#include <asm/io.h>
20#include <asm/irq.h>
21
22#define AX_SPR_BUSY (1<<7)
23#define AX_SPR_ACK (1<<6)
24#define AX_SPR_PE (1<<5)
25#define AX_SPR_SLCT (1<<4)
26#define AX_SPR_ERR (1<<3)
27
28#define AX_CPR_nDOE (1<<5)
29#define AX_CPR_SLCTIN (1<<3)
30#define AX_CPR_nINIT (1<<2)
31#define AX_CPR_ATFD (1<<1)
32#define AX_CPR_STRB (1<<0)
33
34struct ax_drvdata {
35 struct parport *parport;
36 struct parport_state suspend;
37
38 struct device *dev;
39 struct resource *io;
40
41 unsigned char irq_enabled;
42
43 void __iomem *base;
44 void __iomem *spp_data;
45 void __iomem *spp_spr;
46 void __iomem *spp_cpr;
47};
48
49static inline struct ax_drvdata *pp_to_drv(struct parport *p)
50{
51 return p->private_data;
52}
53
54static unsigned char
55parport_ax88796_read_data(struct parport *p)
56{
57 struct ax_drvdata *dd = pp_to_drv(p);
58
59 return readb(dd->spp_data);
60}
61
62static void
63parport_ax88796_write_data(struct parport *p, unsigned char data)
64{
65 struct ax_drvdata *dd = pp_to_drv(p);
66
67 writeb(data, dd->spp_data);
68}
69
70static unsigned char
71parport_ax88796_read_control(struct parport *p)
72{
73 struct ax_drvdata *dd = pp_to_drv(p);
74 unsigned int cpr = readb(dd->spp_cpr);
75 unsigned int ret = 0;
76
77 if (!(cpr & AX_CPR_STRB))
78 ret |= PARPORT_CONTROL_STROBE;
79
80 if (!(cpr & AX_CPR_ATFD))
81 ret |= PARPORT_CONTROL_AUTOFD;
82
83 if (cpr & AX_CPR_nINIT)
84 ret |= PARPORT_CONTROL_INIT;
85
86 if (!(cpr & AX_CPR_SLCTIN))
87 ret |= PARPORT_CONTROL_SELECT;
88
89 return ret;
90}
91
92static void
93parport_ax88796_write_control(struct parport *p, unsigned char control)
94{
95 struct ax_drvdata *dd = pp_to_drv(p);
96 unsigned int cpr = readb(dd->spp_cpr);
97
98 cpr &= AX_CPR_nDOE;
99
100 if (!(control & PARPORT_CONTROL_STROBE))
101 cpr |= AX_CPR_STRB;
102
103 if (!(control & PARPORT_CONTROL_AUTOFD))
104 cpr |= AX_CPR_ATFD;
105
106 if (control & PARPORT_CONTROL_INIT)
107 cpr |= AX_CPR_nINIT;
108
109 if (!(control & PARPORT_CONTROL_SELECT))
110 cpr |= AX_CPR_SLCTIN;
111
112 dev_dbg(dd->dev, "write_control: ctrl=%02x, cpr=%02x\n", control, cpr);
113 writeb(cpr, dd->spp_cpr);
114
115 if (parport_ax88796_read_control(p) != control) {
116 dev_err(dd->dev, "write_control: read != set (%02x, %02x)\n",
117 parport_ax88796_read_control(p), control);
118 }
119}
120
121static unsigned char
122parport_ax88796_read_status(struct parport *p)
123{
124 struct ax_drvdata *dd = pp_to_drv(p);
125 unsigned int status = readb(dd->spp_spr);
126 unsigned int ret = 0;
127
128 if (status & AX_SPR_BUSY)
129 ret |= PARPORT_STATUS_BUSY;
130
131 if (status & AX_SPR_ACK)
132 ret |= PARPORT_STATUS_ACK;
133
134 if (status & AX_SPR_ERR)
135 ret |= PARPORT_STATUS_ERROR;
136
137 if (status & AX_SPR_SLCT)
138 ret |= PARPORT_STATUS_SELECT;
139
140 if (status & AX_SPR_PE)
141 ret |= PARPORT_STATUS_PAPEROUT;
142
143 return ret;
144}
145
146static unsigned char
147parport_ax88796_frob_control(struct parport *p, unsigned char mask,
148 unsigned char val)
149{
150 struct ax_drvdata *dd = pp_to_drv(p);
151 unsigned char old = parport_ax88796_read_control(p);
152
153 dev_dbg(dd->dev, "frob: mask=%02x, val=%02x, old=%02x\n",
154 mask, val, old);
155
156 parport_ax88796_write_control(p, (old & ~mask) | val);
157 return old;
158}
159
160static void
161parport_ax88796_enable_irq(struct parport *p)
162{
163 struct ax_drvdata *dd = pp_to_drv(p);
164 unsigned long flags;
165
166 local_irq_save(flags);
167 if (!dd->irq_enabled) {
168 enable_irq(p->irq);
169 dd->irq_enabled = 1;
170 }
171 local_irq_restore(flags);
172}
173
174static void
175parport_ax88796_disable_irq(struct parport *p)
176{
177 struct ax_drvdata *dd = pp_to_drv(p);
178 unsigned long flags;
179
180 local_irq_save(flags);
181 if (dd->irq_enabled) {
182 disable_irq(p->irq);
183 dd->irq_enabled = 0;
184 }
185 local_irq_restore(flags);
186}
187
188static void
189parport_ax88796_data_forward(struct parport *p)
190{
191 struct ax_drvdata *dd = pp_to_drv(p);
192 void __iomem *cpr = dd->spp_cpr;
193
194 writeb((readb(cpr) & ~AX_CPR_nDOE), cpr);
195}
196
197static void
198parport_ax88796_data_reverse(struct parport *p)
199{
200 struct ax_drvdata *dd = pp_to_drv(p);
201 void __iomem *cpr = dd->spp_cpr;
202
203 writeb(readb(cpr) | AX_CPR_nDOE, cpr);
204}
205
206static void
207parport_ax88796_init_state(struct pardevice *d, struct parport_state *s)
208{
209 struct ax_drvdata *dd = pp_to_drv(d->port);
210
211 memset(s, 0, sizeof(struct parport_state));
212
213 dev_dbg(dd->dev, "init_state: %p: state=%p\n", d, s);
214 s->u.ax88796.cpr = readb(dd->spp_cpr);
215}
216
217static void
218parport_ax88796_save_state(struct parport *p, struct parport_state *s)
219{
220 struct ax_drvdata *dd = pp_to_drv(p);
221
222 dev_dbg(dd->dev, "save_state: %p: state=%p\n", p, s);
223 s->u.ax88796.cpr = readb(dd->spp_cpr);
224}
225
226static void
227parport_ax88796_restore_state(struct parport *p, struct parport_state *s)
228{
229 struct ax_drvdata *dd = pp_to_drv(p);
230
231 dev_dbg(dd->dev, "restore_state: %p: state=%p\n", p, s);
232 writeb(s->u.ax88796.cpr, dd->spp_cpr);
233}
234
235static irqreturn_t
236parport_ax88796_interrupt(int irq, void *dev_id, struct pt_regs *regs)
237{
238 parport_generic_irq(irq, dev_id, regs);
239 return IRQ_HANDLED;
240}
241
242
243static struct parport_operations parport_ax88796_ops = {
244 .write_data = parport_ax88796_write_data,
245 .read_data = parport_ax88796_read_data,
246
247 .write_control = parport_ax88796_write_control,
248 .read_control = parport_ax88796_read_control,
249 .frob_control = parport_ax88796_frob_control,
250
251 .read_status = parport_ax88796_read_status,
252
253 .enable_irq = parport_ax88796_enable_irq,
254 .disable_irq = parport_ax88796_disable_irq,
255
256 .data_forward = parport_ax88796_data_forward,
257 .data_reverse = parport_ax88796_data_reverse,
258
259 .init_state = parport_ax88796_init_state,
260 .save_state = parport_ax88796_save_state,
261 .restore_state = parport_ax88796_restore_state,
262
263 .epp_write_data = parport_ieee1284_epp_write_data,
264 .epp_read_data = parport_ieee1284_epp_read_data,
265 .epp_write_addr = parport_ieee1284_epp_write_addr,
266 .epp_read_addr = parport_ieee1284_epp_read_addr,
267
268 .ecp_write_data = parport_ieee1284_ecp_write_data,
269 .ecp_read_data = parport_ieee1284_ecp_read_data,
270 .ecp_write_addr = parport_ieee1284_ecp_write_addr,
271
272 .compat_write_data = parport_ieee1284_write_compat,
273 .nibble_read_data = parport_ieee1284_read_nibble,
274 .byte_read_data = parport_ieee1284_read_byte,
275
276 .owner = THIS_MODULE,
277};
278
279static int parport_ax88796_probe(struct platform_device *pdev)
280{
281 struct device *_dev = &pdev->dev;
282 struct ax_drvdata *dd;
283 struct parport *pp = NULL;
284 struct resource *res;
285 unsigned long size;
286 int spacing;
287 int irq;
288 int ret;
289
290 dd = kzalloc(sizeof(struct ax_drvdata), GFP_KERNEL);
291 if (dd == NULL) {
292 dev_err(_dev, "no memory for private data\n");
293 return -ENOMEM;
294 }
295
296 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
297 if (res == NULL) {
298 dev_err(_dev, "no MEM specified\n");
299 ret = -ENXIO;
300 goto exit_mem;
301 }
302
303 size = (res->end - res->start) + 1;
304 spacing = size / 3;
305
306 dd->io = request_mem_region(res->start, size, pdev->name);
307 if (dd->io == NULL) {
308 dev_err(_dev, "cannot reserve memory\n");
309 ret = -ENXIO;
310 goto exit_mem;
311 }
312
313 dd->base = ioremap(res->start, size);
314 if (dd->base == NULL) {
315 dev_err(_dev, "cannot ioremap region\n");
316 ret = -ENXIO;
317 goto exit_res;
318 }
319
320 irq = platform_get_irq(pdev, 0);
321 if (irq <= 0)
322 irq = PARPORT_IRQ_NONE;
323
324 pp = parport_register_port((unsigned long)dd->base, irq,
325 PARPORT_DMA_NONE,
326 &parport_ax88796_ops);
327
328 if (pp == NULL) {
329 dev_err(_dev, "failed to register parallel port\n");
330 ret = -ENOMEM;
331 goto exit_unmap;
332 }
333
334 pp->private_data = dd;
335 dd->parport = pp;
336 dd->dev = _dev;
337
338 dd->spp_data = dd->base;
339 dd->spp_spr = dd->base + (spacing * 1);
340 dd->spp_cpr = dd->base + (spacing * 2);
341
342 /* initialise the port controls */
343 writeb(AX_CPR_STRB, dd->spp_cpr);
344
345 if (irq >= 0) {
346 /* request irq */
347 ret = request_irq(irq, parport_ax88796_interrupt,
348 SA_TRIGGER_FALLING, pdev->name, pp);
349
350 if (ret < 0)
351 goto exit_port;
352
353 dd->irq_enabled = 1;
354 }
355
356 platform_set_drvdata(pdev, pp);
357
358 dev_info(_dev, "attached parallel port driver\n");
359 parport_announce_port(pp);
360
361 return 0;
362
363 exit_port:
364 parport_remove_port(pp);
365 exit_unmap:
366 iounmap(dd->base);
367 exit_res:
368 release_resource(dd->io);
369 kfree(dd->io);
370 exit_mem:
371 kfree(dd);
372 return ret;
373}
374
375static int parport_ax88796_remove(struct platform_device *pdev)
376{
377 struct parport *p = platform_get_drvdata(pdev);
378 struct ax_drvdata *dd = pp_to_drv(p);
379
380 free_irq(p->irq, p);
381 parport_remove_port(p);
382 iounmap(dd->base);
383 release_resource(dd->io);
384 kfree(dd->io);
385 kfree(dd);
386
387 return 0;
388}
389
390#ifdef CONFIG_PM
391
392static int parport_ax88796_suspend(struct platform_device *dev,
393 pm_message_t state)
394{
395 struct parport *p = platform_get_drvdata(dev);
396 struct ax_drvdata *dd = pp_to_drv(p);
397
398 parport_ax88796_save_state(p, &dd->suspend);
399 writeb(AX_CPR_nDOE | AX_CPR_STRB, dd->spp_cpr);
400 return 0;
401}
402
403static int parport_ax88796_resume(struct platform_device *dev)
404{
405 struct parport *p = platform_get_drvdata(dev);
406 struct ax_drvdata *dd = pp_to_drv(p);
407
408 parport_ax88796_restore_state(p, &dd->suspend);
409 return 0;
410}
411
412#else
413#define parport_ax88796_suspend NULL
414#define parport_ax88796_resume NULL
415#endif
416
417static struct platform_driver axdrv = {
418 .driver = {
419 .name = "ax88796-pp",
420 .owner = THIS_MODULE,
421 },
422 .probe = parport_ax88796_probe,
423 .remove = parport_ax88796_remove,
424 .suspend = parport_ax88796_suspend,
425 .resume = parport_ax88796_resume,
426};
427
428static int __init parport_ax88796_init(void)
429{
430 return platform_driver_register(&axdrv);
431}
432
433static void __exit parport_ax88796_exit(void)
434{
435 platform_driver_unregister(&axdrv);
436}
437
438module_init(parport_ax88796_init)
439module_exit(parport_ax88796_exit)
440
441MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
442MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
443MODULE_LICENSE("GPL");
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
index 36a1556e64c7..69a4bbd4cbee 100644
--- a/drivers/parport/parport_sunbpp.c
+++ b/drivers/parport/parport_sunbpp.c
@@ -1,5 +1,4 @@
1/* $Id: parport_sunbpp.c,v 1.12 2001/05/26 03:01:42 davem Exp $ 1/* parport_sunbpp.c: Parallel-port routines for SBUS
2 * Parallel-port routines for Sun architecture
3 * 2 *
4 * Author: Derrick J. Brashear <shadow@dementia.org> 3 * Author: Derrick J. Brashear <shadow@dementia.org>
5 * 4 *
@@ -14,6 +13,9 @@
14 * Gus Baldauf (gbaldauf@ix.netcom.com) 13 * Gus Baldauf (gbaldauf@ix.netcom.com)
15 * Peter Zaitcev 14 * Peter Zaitcev
16 * Tom Dyas 15 * Tom Dyas
16 *
17 * Updated to new SBUS device framework: David S. Miller <davem@davemloft.net>
18 *
17 */ 19 */
18 20
19#include <linux/string.h> 21#include <linux/string.h>
@@ -287,14 +289,7 @@ static struct parport_operations parport_sunbpp_ops =
287 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
288}; 290};
289 291
290typedef struct { 292static int __devinit init_one_port(struct sbus_dev *sdev)
291 struct list_head list;
292 struct parport *port;
293} Node;
294/* no locks, everything's serialized */
295static LIST_HEAD(port_list);
296
297static int __init init_one_port(struct sbus_dev *sdev)
298{ 293{
299 struct parport *p; 294 struct parport *p;
300 /* at least in theory there may be a "we don't dma" case */ 295 /* at least in theory there may be a "we don't dma" case */
@@ -303,109 +298,120 @@ static int __init init_one_port(struct sbus_dev *sdev)
303 int irq, dma, err = 0, size; 298 int irq, dma, err = 0, size;
304 struct bpp_regs __iomem *regs; 299 struct bpp_regs __iomem *regs;
305 unsigned char value_tcr; 300 unsigned char value_tcr;
306 Node *node;
307
308 dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev));
309 node = kmalloc(sizeof(Node), GFP_KERNEL);
310 if (!node)
311 goto out0;
312 301
313 irq = sdev->irqs[0]; 302 irq = sdev->irqs[0];
314 base = sbus_ioremap(&sdev->resource[0], 0, 303 base = sbus_ioremap(&sdev->resource[0], 0,
315 sdev->reg_addrs[0].reg_size, 304 sdev->reg_addrs[0].reg_size,
316 "sunbpp"); 305 "sunbpp");
317 if (!base) 306 if (!base)
318 goto out1; 307 return -ENODEV;
319 308
320 size = sdev->reg_addrs[0].reg_size; 309 size = sdev->reg_addrs[0].reg_size;
321 dma = PARPORT_DMA_NONE; 310 dma = PARPORT_DMA_NONE;
322 311
323 dprintk(("alloc(ppops), ")); 312 ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
324 ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
325 if (!ops) 313 if (!ops)
326 goto out2; 314 goto out_unmap;
327 315
328 memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); 316 memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));
329 317
330 dprintk(("register_port\n")); 318 dprintk(("register_port\n"));
331 if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) 319 if (!(p = parport_register_port((unsigned long)base, irq, dma, ops)))
332 goto out3; 320 goto out_free_ops;
333 321
334 p->size = size; 322 p->size = size;
335 323
336 dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
337 p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p));
338 if ((err = request_irq(p->irq, parport_sunbpp_interrupt, 324 if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
339 SA_SHIRQ, p->name, p)) != 0) { 325 SA_SHIRQ, p->name, p)) != 0) {
340 dprintk(("ERROR %d\n", err)); 326 goto out_put_port;
341 goto out4;
342 } 327 }
343 dprintk(("OK\n")); 328
344 parport_sunbpp_enable_irq(p); 329 parport_sunbpp_enable_irq(p);
345 330
346 regs = (struct bpp_regs __iomem *)p->base; 331 regs = (struct bpp_regs __iomem *)p->base;
347 dprintk((KERN_DEBUG "forward\n")); 332
348 value_tcr = sbus_readb(&regs->p_tcr); 333 value_tcr = sbus_readb(&regs->p_tcr);
349 value_tcr &= ~P_TCR_DIR; 334 value_tcr &= ~P_TCR_DIR;
350 sbus_writeb(value_tcr, &regs->p_tcr); 335 sbus_writeb(value_tcr, &regs->p_tcr);
351 336
352 printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); 337 printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
353 node->port = p;
354 list_add(&node->list, &port_list);
355 parport_announce_port (p);
356 338
357 return 1; 339 dev_set_drvdata(&sdev->ofdev.dev, p);
340
341 parport_announce_port(p);
342
343 return 0;
358 344
359out4: 345out_put_port:
360 parport_put_port(p); 346 parport_put_port(p);
361out3: 347
348out_free_ops:
362 kfree(ops); 349 kfree(ops);
363out2: 350
351out_unmap:
364 sbus_iounmap(base, size); 352 sbus_iounmap(base, size);
365out1: 353
366 kfree(node);
367out0:
368 return err; 354 return err;
369} 355}
370 356
371static int __init parport_sunbpp_init(void) 357static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match)
372{ 358{
373 struct sbus_bus *sbus; 359 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
374 struct sbus_dev *sdev; 360
375 int count = 0; 361 return init_one_port(sdev);
376 362}
377 for_each_sbus(sbus) { 363
378 for_each_sbusdev(sdev, sbus) { 364static int __devexit bpp_remove(struct of_device *dev)
379 if (!strcmp(sdev->prom_name, "SUNW,bpp")) 365{
380 count += init_one_port(sdev); 366 struct parport *p = dev_get_drvdata(&dev->dev);
381 } 367 struct parport_operations *ops = p->ops;
368
369 parport_remove_port(p);
370
371 if (p->irq != PARPORT_IRQ_NONE) {
372 parport_sunbpp_disable_irq(p);
373 free_irq(p->irq, p);
382 } 374 }
383 return count ? 0 : -ENODEV; 375
376 sbus_iounmap((void __iomem *) p->base, p->size);
377 parport_put_port(p);
378 kfree(ops);
379
380 dev_set_drvdata(&dev->dev, NULL);
381
382 return 0;
383}
384
385static struct of_device_id bpp_match[] = {
386 {
387 .name = "SUNW,bpp",
388 },
389 {},
390};
391
392MODULE_DEVICE_TABLE(of, qec_sbus_match);
393
394static struct of_platform_driver bpp_sbus_driver = {
395 .name = "bpp",
396 .match_table = bpp_match,
397 .probe = bpp_probe,
398 .remove = __devexit_p(bpp_remove),
399};
400
401static int __init parport_sunbpp_init(void)
402{
403 return of_register_driver(&bpp_sbus_driver, &sbus_bus_type);
384} 404}
385 405
386static void __exit parport_sunbpp_exit(void) 406static void __exit parport_sunbpp_exit(void)
387{ 407{
388 while (!list_empty(&port_list)) { 408 of_unregister_driver(&bpp_sbus_driver);
389 Node *node = list_entry(port_list.next, Node, list);
390 struct parport *p = node->port;
391 struct parport_operations *ops = p->ops;
392 parport_remove_port(p);
393
394 if (p->irq != PARPORT_IRQ_NONE) {
395 parport_sunbpp_disable_irq(p);
396 free_irq(p->irq, p);
397 }
398 sbus_iounmap((void __iomem *)p->base, p->size);
399 parport_put_port(p);
400 kfree (ops);
401 list_del(&node->list);
402 kfree (node);
403 }
404} 409}
405 410
406MODULE_AUTHOR("Derrick J Brashear"); 411MODULE_AUTHOR("Derrick J Brashear");
407MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); 412MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port");
408MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); 413MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port");
414MODULE_VERSION("2.0");
409MODULE_LICENSE("GPL"); 415MODULE_LICENSE("GPL");
410 416
411module_init(parport_sunbpp_init) 417module_init(parport_sunbpp_init)
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index bbbfd79adbaf..2cb22c8d3357 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -218,7 +218,7 @@ static void free_port (struct parport *port)
218 * parport_get_port - increment a port's reference count 218 * parport_get_port - increment a port's reference count
219 * @port: the port 219 * @port: the port
220 * 220 *
221 * This ensure's that a struct parport pointer remains valid 221 * This ensures that a struct parport pointer remains valid
222 * until the matching parport_put_port() call. 222 * until the matching parport_put_port() call.
223 **/ 223 **/
224 224