patch-2.4.0-test12 linux/drivers/parport/parport_amiga.c
Next file: linux/drivers/parport/parport_atari.c
Previous file: linux/drivers/parport/Makefile
Back to the patch index
Back to the overall index
- Lines: 214
- Date:
Mon Nov 27 17:11:26 2000
- Orig file:
v2.4.0-test11/linux/drivers/parport/parport_amiga.c
- Orig date:
Mon Jun 19 13:42:38 2000
diff -u --recursive --new-file v2.4.0-test11/linux/drivers/parport/parport_amiga.c linux/drivers/parport/parport_amiga.c
@@ -1,4 +1,4 @@
-/* Low-level parallel port routines for the Amiga buildin port
+/* Low-level parallel port routines for the Amiga built-in port
*
* Author: Joerg Dorchain <joerg@dorchain.net>
*
@@ -6,9 +6,9 @@
* lp_intern. code.
*
* The built-in Amiga parallel port provides one port at a fixed address
- * with 8 bisdirecttional data lines (D0 - D7) and 3 bidirectional status
- * lines (BUSY, POUT, SEL), 1 output control line /STROBE (raised automatically in
- * hardware when the data register is accessed), and 1 input control line
+ * with 8 bidirectional data lines (D0 - D7) and 3 bidirectional status
+ * lines (BUSY, POUT, SEL), 1 output control line /STROBE (raised automatically
+ * in hardware when the data register is accessed), and 1 input control line
* /ACK, able to cause an interrupt, but both not directly settable by
* software.
*/
@@ -20,22 +20,24 @@
#include <asm/setup.h>
#include <asm/amigahw.h>
#include <asm/irq.h>
+#include <asm/io.h>
#include <asm/amigaints.h>
#undef DEBUG
#ifdef DEBUG
#define DPRINTK printk
#else
-static inline void DPRINTK(void *nothing, ...) {}
+#define DPRINTK(x...) do { } while (0)
#endif
static struct parport *this_port = NULL;
static void amiga_write_data(struct parport *p, unsigned char data)
{
-DPRINTK("write_data %c\n",data);
+ DPRINTK("write_data %c\n",data);
/* Triggers also /STROBE. This behavior cannot be changed */
ciaa.prb = data;
+ mb();
}
static unsigned char amiga_read_data(struct parport *p)
@@ -71,13 +73,13 @@
static void amiga_write_control(struct parport *p, unsigned char control)
{
-DPRINTK("write_control %02x\n",control);
+ DPRINTK("write_control %02x\n",control);
/* No implementation possible */
}
static unsigned char amiga_read_control( struct parport *p)
{
-DPRINTK("read_control \n");
+ DPRINTK("read_control \n");
return control_amiga_to_pc(0);
}
@@ -85,7 +87,7 @@
{
unsigned char old;
-DPRINTK("frob_control mask %02x, value %02x\n",mask,val);
+ DPRINTK("frob_control mask %02x, value %02x\n",mask,val);
old = amiga_read_control(p);
amiga_write_control(p, (old & ~mask) ^ val);
return old;
@@ -130,7 +132,7 @@
unsigned char status;
status = status_amiga_to_pc(ciab.pra & 7);
-DPRINTK("read_status %02x\n", status);
+ DPRINTK("read_status %02x\n", status);
return status;
}
@@ -154,12 +156,14 @@
{
DPRINTK("forward\n");
ciaa.ddrb = 0xff; /* all pins output */
+ mb();
}
static void amiga_data_reverse(struct parport *p)
{
DPRINTK("reverse\n");
ciaa.ddrb = 0; /* all pins input */
+ mb();
}
static void amiga_init_state(struct pardevice *dev, struct parport_state *s)
@@ -172,18 +176,22 @@
static void amiga_save_state(struct parport *p, struct parport_state *s)
{
+ mb();
s->u.amiga.data = ciaa.prb;
s->u.amiga.datadir = ciaa.ddrb;
s->u.amiga.status = ciab.pra & 7;
s->u.amiga.statusdir = ciab.ddra & 7;
+ mb();
}
static void amiga_restore_state(struct parport *p, struct parport_state *s)
{
+ mb();
ciaa.prb = s->u.amiga.data;
ciaa.ddrb = s->u.amiga.datadir;
ciab.pra |= (ciab.pra & 0xf8) | s->u.amiga.status;
ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir;
+ mb();
}
static void amiga_inc_use_count(void)
@@ -238,56 +246,58 @@
int __init parport_amiga_init(void)
{
struct parport *p;
+ int err;
- if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_PARALLEL)) {
- if (!request_mem_region(CIAA_PHYSADDR+0x100, 1, "parallel"))
- return 0;
- ciaa.ddrb = 0xff;
- ciab.ddra &= 0xf8;
- if (!(p = parport_register_port((unsigned long)&ciaa.prb,
- IRQ_AMIGA_CIAA_FLG, PARPORT_DMA_NONE,
- &pp_amiga_ops))) {
- release_mem_region(CIAA_PHYSADDR+0x100, 1);
- return 0;
- }
- if (!request_irq(IRQ_AMIGA_CIAA_FLG, amiga_interrupt, 0, p->name, p)) {
- parport_unregister_port (p);
- release_mem_region(CIAA_PHYSADDR+0x100, 1);
- return 0;
- }
-
- this_port = p;
- printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name);
- /* XXX: set operating mode */
- parport_proc_register(p);
+ if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_PARALLEL))
+ return -ENODEV;
- parport_announce_port(p);
+ err = -EBUSY;
+ if (!request_mem_region(CIAA_PHYSADDR-1+0x100, 0x100, "parallel"))
+ goto out_mem;
+
+ ciaa.ddrb = 0xff;
+ ciab.ddra &= 0xf8;
+ mb();
+
+ p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG,
+ PARPORT_DMA_NONE, &pp_amiga_ops);
+ if (!p)
+ goto out_port;
+
+ err = request_irq(IRQ_AMIGA_CIAA_FLG, amiga_interrupt, 0, p->name, p);
+ if (err)
+ goto out_irq;
+
+ this_port = p;
+ printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name);
+ /* XXX: set operating mode */
+ parport_proc_register(p);
- return 1;
+ parport_announce_port(p);
- }
return 0;
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
-MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
-MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
-int init_module(void)
-{
- return ! parport_amiga_init();
+out_irq:
+ parport_unregister_port(p);
+out_port:
+ release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
+out_mem:
+ return err;
}
-void cleanup_module(void)
+void __exit parport_amiga_exit(void)
{
if (this_port->irq != PARPORT_IRQ_NONE)
free_irq(IRQ_AMIGA_CIAA_FLG, this_port);
parport_proc_unregister(this_port);
parport_unregister_port(this_port);
- release_mem_region(CIAA_PHYSADDR+0x100, 1);
+ release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
}
-#endif
+MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
+MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
+MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
+
+module_init(parport_amiga_init)
+module_exit(parport_amiga_exit)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)