[PARPORT] disable/elable_irq() in parport_claim/release().


Andrea Arcangeli (andrea@e-mind.com)
Tue, 23 Feb 1999 22:17:30 +0100 (CET)


I looked at the parport_share changes only now (I am been very busy with
two exames at University these days but the good news is that I passed
both of them so now I'll have some bit more of spare time ;)).

The reason of the enable_irq() in parport_release() was only to undo the
disable_irq() that I was doing a bit before changing the cad if the next
cad was not using irqs. disabling irqs I was avoiding the irq handler to
run and return doing nothing.

I agree that we could drop the enable_irq() completly in claim/restore.

Also the use of the port->ops->disable_irq() should be not needed at every
claim/release since I think we should make the save_state and
restore_state parport_lowlevel operations to just save and restore the
right state for the irq masking/unmasking register of the peripheral. This
is automagically done in the parport_pc only saving/restoring the control
port.

So I see completly not needed to call the enable/disable_irq()
parport_lowlevel operations while claiming the port. That should be done
only at once in the lowlevel init_state operation.

So basically I think we should do something like this. Patch against
tim-2.2.1-1284-15:

Index: drivers/misc/parport_ax.c
===================================================================
RCS file: /var/cvs/linux/drivers/misc/parport_ax.c,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 parport_ax.c
--- parport_ax.c 1999/02/23 20:42:54 1.1.2.3
+++ linux/drivers/misc/parport_ax.c 1999/02/23 21:05:56
@@ -224,8 +224,6 @@
                 if ((err = request_irq(p->irq, parport_ax_interrupt,
                                        0, p->name, p)) != 0)
                         return err;
- else
- parport_ax_enable_irq(p);
 
         request_region(p->base, p->size, p->name);
         if (p->modes & PARPORT_MODE_PCECR)
@@ -236,24 +234,39 @@
 }
 
 void
-parport_ax_init_state(struct parport_state *s)
+parport_ax_init_state(struct pardevice *dev, struct parport_state *s)
 {
- s->u.pc.ctr = 0xc;
- s->u.pc.ecr = 0x0;
+ struct linux_ebus_dma *dma = dev->port->private_data;
+
+ s->u.ax.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
+ s->u.ax.ecr = 0x0;
+
+ if (dev->irq_func)
+ s->u.ax.dcsr = (readl((unsigned long)&dma->dcsr)
+ | EBUS_DCSR_INT_EN);
+ else
+ s->u.ax.dcsr = (readl((unsigned long)&dma->dcsr)
+ & ~EBUS_DCSR_INT_EN);
 }
 
 void
 parport_ax_save_state(struct parport *p, struct parport_state *s)
 {
- s->u.pc.ctr = parport_ax_read_control(p);
- s->u.pc.ecr = parport_ax_read_econtrol(p);
+ struct linux_ebus_dma *dma = p->private_data;
+
+ s->u.ax.ctr = parport_ax_read_control(p);
+ s->u.ax.ecr = parport_ax_read_econtrol(p);
+ s->u.ax.dcsr = readl((unsigned long)&dma->dcsr);
 }
 
 void
 parport_ax_restore_state(struct parport *p, struct parport_state *s)
 {
- parport_ax_write_control(p, s->u.pc.ctr);
- parport_ax_write_econtrol(p, s->u.pc.ecr);
+ struct linux_ebus_dma *dma = p->private_data;
+
+ parport_ax_write_control(p, s->u.ax.ctr);
+ parport_ax_write_econtrol(p, s->u.ax.ecr);
+ writel(s->u.ax.dcsr, (unsigned long)&dma->dcsr);
 }
 
 void
Index: drivers/misc/parport_pc.c
===================================================================
RCS file: /var/cvs/linux/drivers/misc/parport_pc.c,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 parport_pc.c
--- parport_pc.c 1999/02/23 20:42:55 1.1.2.5
+++ linux/drivers/misc/parport_pc.c 1999/02/23 21:05:07
@@ -296,9 +296,9 @@
         return 0;
 }
 
-void parport_pc_init_state(struct parport_state *s)
+void parport_pc_init_state(struct pardevice *dev, struct parport_state *s)
 {
- s->u.pc.ctr = 0xc;
+ s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
         s->u.pc.ecr = 0x0;
 }
 
Index: drivers/misc/parport_share.c
===================================================================
RCS file: /var/cvs/linux/drivers/misc/parport_share.c,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 parport_share.c
--- parport_share.c 1999/02/23 20:42:55 1.1.2.5
+++ linux/drivers/misc/parport_share.c 1999/02/23 21:07:27
@@ -250,7 +250,6 @@
         tmp->private = handle;
         tmp->flags = flags;
         tmp->irq_func = irq_func;
- port->ops->init_state(tmp->state);
         tmp->waiting = 0;
 
         /* Chain this onto the list */
@@ -287,6 +286,11 @@
         tmp->timeslice = PARPORT_DEFAULT_TIMESLICE;
         tmp->waitnext = tmp->waitprev = NULL;
 
+ /*
+ * This has to be run as last thing since init_state may need other
+ * pardevice fields. -arca
+ */
+ port->ops->init_state(tmp, tmp->state);
         return tmp;
 }
 
@@ -384,13 +388,6 @@
                 dev->waitprev = dev->waitnext = NULL;
         }
 
- if (port->irq != PARPORT_IRQ_NONE) {
- if (dev->irq_func)
- port->ops->enable_irq (port);
- else
- port->ops->disable_irq (port);
- }
-
         /* Now we do the change of devices */
         write_lock_irqsave(&port->cad_lock, flags);
         port->cad = dev;
@@ -482,14 +479,6 @@
         write_lock_irqsave(&port->cad_lock, flags);
         port->cad = NULL;
         write_unlock_irqrestore(&port->cad_lock, flags);
-
- /*
- * Reenable irq and so discard the eventually pending irq while
- * cad is NULL. -arca
- */
- /* @@@ Think this is bogus. Just lose it? --philb */
- if (port->irq != PARPORT_IRQ_NONE && !dev->irq_func)
- port->ops->enable_irq (port);
 
         /* Save control registers */
         port->ops->save_state(port, dev->state);
Index: include/linux/parport.h
===================================================================
RCS file: /var/cvs/linux/include/linux/parport.h,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 parport.h
--- parport.h 1999/02/23 20:42:56 1.1.2.4
+++ linux/include/linux/parport.h 1999/02/23 21:02:30
@@ -98,12 +98,19 @@
 
 /* Define this later. */
 struct parport;
+struct pardevice;
 
 struct pc_parport_state {
         unsigned int ctr;
         unsigned int ecr;
 };
 
+struct ax_parport_state {
+ unsigned int ctr;
+ unsigned int ecr;
+ unsigned int dcsr;
+};
+
 /* used by both parport_amiga and parport_mfc3 */
 struct amiga_parport_state {
        unsigned char data; /* ciaa.prb */
@@ -116,7 +123,7 @@
         union {
                 struct pc_parport_state pc;
                 /* ARC has no state. */
- /* AX uses same state information as PC */
+ struct ax_parport_state ax;
                 struct amiga_parport_state amiga;
                 /* Atari has not state. */
                 void *misc;
@@ -159,7 +166,7 @@
         unsigned char (*epp_read_addr)(struct parport *);
         int (*epp_check_timeout)(struct parport *);
 
- void (*init_state)(struct parport_state *);
+ void (*init_state)(struct pardevice *, struct parport_state *);
         void (*save_state)(struct parport *, struct parport_state *);
         void (*restore_state)(struct parport *, struct parport_state *);
 
Index: include/linux/parport_pc.h
===================================================================
RCS file: /var/cvs/linux/include/linux/parport_pc.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 parport_pc.h
--- parport_pc.h 1999/02/23 20:42:56 1.1.2.2
+++ linux/include/linux/parport_pc.h 1999/02/23 21:01:11
@@ -118,7 +118,7 @@
 
 extern int parport_pc_claim_resources(struct parport *p);
 
-extern void parport_pc_init_state(struct parport_state *s);
+extern void parport_pc_init_state(struct pardevice *, struct parport_state *s);
 
 extern void parport_pc_save_state(struct parport *p, struct parport_state *s);
 

It's completly untested but (at least ;) compile. I think it's the right
approch. Comments?

Andrea Arcangeli

-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --



This archive was generated by hypermail 2.0b3 on Tue 23 Feb 1999 - 16:20:11 EST