Commit 063b5904 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: pcmuio: remove subdevice private data

The subdevice private data is only needed for each 'asic' not for each
subdevice. Since the 'asic' can be calculated easily from the subdevice
we can merge the subdevice private data members directly into the
private data.

This removes the need to kcalloc/free the subdevice private data and
saves a bit of space.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0d1ead48
...@@ -127,26 +127,17 @@ static const struct pcmuio_board pcmuio_boards[] = { ...@@ -127,26 +127,17 @@ static const struct pcmuio_board pcmuio_boards[] = {
}, },
}; };
struct pcmuio_subdev_private { struct pcmuio_asic {
/* The below is only used for intr subdevices */ spinlock_t pagelock;
struct { spinlock_t spinlock;
/* int enabled_mask;
* subdev-relative channel mask for channels int active;
* we are interested in int stop_count;
*/ int continuous;
int enabled_mask;
int active;
int stop_count;
int continuous;
spinlock_t spinlock;
} intr;
}; };
struct pcmuio_private { struct pcmuio_private {
struct { struct pcmuio_asic asics[PCMUIO_MAX_ASICS];
spinlock_t pagelock;
} asics[PCMUIO_MAX_ASICS];
struct pcmuio_subdev_private *sprivs;
unsigned int irq2; unsigned int irq2;
}; };
...@@ -154,10 +145,11 @@ static void pcmuio_write(struct comedi_device *dev, unsigned int val, ...@@ -154,10 +145,11 @@ static void pcmuio_write(struct comedi_device *dev, unsigned int val,
int asic, int page, int port) int asic, int page, int port)
{ {
struct pcmuio_private *devpriv = dev->private; struct pcmuio_private *devpriv = dev->private;
struct pcmuio_asic *chip = &devpriv->asics[asic];
unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE);
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&devpriv->asics[asic].pagelock, flags); spin_lock_irqsave(&chip->pagelock, flags);
if (page == 0) { if (page == 0) {
/* Port registers are valid for any page */ /* Port registers are valid for any page */
outb(val & 0xff, iobase + PCMUIO_PORT_REG(port + 0)); outb(val & 0xff, iobase + PCMUIO_PORT_REG(port + 0));
...@@ -169,18 +161,19 @@ static void pcmuio_write(struct comedi_device *dev, unsigned int val, ...@@ -169,18 +161,19 @@ static void pcmuio_write(struct comedi_device *dev, unsigned int val,
outb((val >> 8) & 0xff, iobase + PCMUIO_PAGE_REG(1)); outb((val >> 8) & 0xff, iobase + PCMUIO_PAGE_REG(1));
outb((val >> 16) & 0xff, iobase + PCMUIO_PAGE_REG(2)); outb((val >> 16) & 0xff, iobase + PCMUIO_PAGE_REG(2));
} }
spin_unlock_irqrestore(&devpriv->asics[asic].pagelock, flags); spin_unlock_irqrestore(&chip->pagelock, flags);
} }
static unsigned int pcmuio_read(struct comedi_device *dev, static unsigned int pcmuio_read(struct comedi_device *dev,
int asic, int page, int port) int asic, int page, int port)
{ {
struct pcmuio_private *devpriv = dev->private; struct pcmuio_private *devpriv = dev->private;
struct pcmuio_asic *chip = &devpriv->asics[asic];
unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE);
unsigned long flags; unsigned long flags;
unsigned int val; unsigned int val;
spin_lock_irqsave(&devpriv->asics[asic].pagelock, flags); spin_lock_irqsave(&chip->pagelock, flags);
if (page == 0) { if (page == 0) {
/* Port registers are valid for any page */ /* Port registers are valid for any page */
val = inb(iobase + PCMUIO_PORT_REG(port + 0)); val = inb(iobase + PCMUIO_PORT_REG(port + 0));
...@@ -192,7 +185,7 @@ static unsigned int pcmuio_read(struct comedi_device *dev, ...@@ -192,7 +185,7 @@ static unsigned int pcmuio_read(struct comedi_device *dev,
val |= (inb(iobase + PCMUIO_PAGE_REG(1)) << 8); val |= (inb(iobase + PCMUIO_PAGE_REG(1)) << 8);
val |= (inb(iobase + PCMUIO_PAGE_REG(2)) << 16); val |= (inb(iobase + PCMUIO_PAGE_REG(2)) << 16);
} }
spin_unlock_irqrestore(&devpriv->asics[asic].pagelock, flags); spin_unlock_irqrestore(&chip->pagelock, flags);
return val; return val;
} }
...@@ -276,11 +269,12 @@ static void pcmuio_reset(struct comedi_device *dev) ...@@ -276,11 +269,12 @@ static void pcmuio_reset(struct comedi_device *dev)
static void pcmuio_stop_intr(struct comedi_device *dev, static void pcmuio_stop_intr(struct comedi_device *dev,
struct comedi_subdevice *s) struct comedi_subdevice *s)
{ {
struct pcmuio_subdev_private *subpriv = s->private; struct pcmuio_private *devpriv = dev->private;
int asic = s->index / 2; int asic = s->index / 2;
struct pcmuio_asic *chip = &devpriv->asics[asic];
subpriv->intr.enabled_mask = 0; chip->enabled_mask = 0;
subpriv->intr.active = 0; chip->active = 0;
s->async->inttrig = NULL; s->async->inttrig = NULL;
/* disable all intrs for this subdev.. */ /* disable all intrs for this subdev.. */
...@@ -291,7 +285,9 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, ...@@ -291,7 +285,9 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
unsigned triggered) unsigned triggered)
{ {
struct pcmuio_subdev_private *subpriv = s->private; struct pcmuio_private *devpriv = dev->private;
int asic = s->index / 2;
struct pcmuio_asic *chip = &devpriv->asics[asic];
unsigned int len = s->async->cmd.chanlist_len; unsigned int len = s->async->cmd.chanlist_len;
unsigned oldevents = s->async->events; unsigned oldevents = s->async->events;
unsigned int val = 0; unsigned int val = 0;
...@@ -299,15 +295,15 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, ...@@ -299,15 +295,15 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
unsigned mytrig; unsigned mytrig;
unsigned int i; unsigned int i;
spin_lock_irqsave(&subpriv->intr.spinlock, flags); spin_lock_irqsave(&chip->spinlock, flags);
if (!subpriv->intr.active) if (!chip->active)
goto done; goto done;
mytrig = triggered; mytrig = triggered;
mytrig &= ((0x1 << s->n_chan) - 1); mytrig &= ((0x1 << s->n_chan) - 1);
if (!(mytrig & subpriv->intr.enabled_mask)) if (!(mytrig & chip->enabled_mask))
goto done; goto done;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
...@@ -327,11 +323,11 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, ...@@ -327,11 +323,11 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
} }
/* Check for end of acquisition. */ /* Check for end of acquisition. */
if (!subpriv->intr.continuous) { if (!chip->continuous) {
/* stop_src == TRIG_COUNT */ /* stop_src == TRIG_COUNT */
if (subpriv->intr.stop_count > 0) { if (chip->stop_count > 0) {
subpriv->intr.stop_count--; chip->stop_count--;
if (subpriv->intr.stop_count == 0) { if (chip->stop_count == 0) {
s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_EOA;
/* TODO: STOP_ACQUISITION_CALL_HERE!! */ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
pcmuio_stop_intr(dev, s); pcmuio_stop_intr(dev, s);
...@@ -340,7 +336,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, ...@@ -340,7 +336,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
} }
done: done:
spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); spin_unlock_irqrestore(&chip->spinlock, flags);
if (oldevents != s->async->events) if (oldevents != s->async->events)
comedi_event(dev, s); comedi_event(dev, s);
...@@ -385,20 +381,21 @@ static irqreturn_t pcmuio_interrupt(int irq, void *d) ...@@ -385,20 +381,21 @@ static irqreturn_t pcmuio_interrupt(int irq, void *d)
static int pcmuio_start_intr(struct comedi_device *dev, static int pcmuio_start_intr(struct comedi_device *dev,
struct comedi_subdevice *s) struct comedi_subdevice *s)
{ {
struct pcmuio_subdev_private *subpriv = s->private; struct pcmuio_private *devpriv = dev->private;
int asic = s->index / 2;
struct pcmuio_asic *chip = &devpriv->asics[asic];
if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) { if (!chip->continuous && chip->stop_count == 0) {
/* An empty acquisition! */ /* An empty acquisition! */
s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_EOA;
subpriv->intr.active = 0; chip->active = 0;
return 1; return 1;
} else { } else {
struct comedi_cmd *cmd = &s->async->cmd; struct comedi_cmd *cmd = &s->async->cmd;
int asic = s->index / 2;
unsigned bits = 0, pol_bits = 0, n; unsigned bits = 0, pol_bits = 0, n;
subpriv->intr.enabled_mask = 0; chip->enabled_mask = 0;
subpriv->intr.active = 1; chip->active = 1;
if (cmd->chanlist) { if (cmd->chanlist) {
for (n = 0; n < cmd->chanlist_len; n++) { for (n = 0; n < cmd->chanlist_len; n++) {
bits |= (1U << CR_CHAN(cmd->chanlist[n])); bits |= (1U << CR_CHAN(cmd->chanlist[n]));
...@@ -409,7 +406,7 @@ static int pcmuio_start_intr(struct comedi_device *dev, ...@@ -409,7 +406,7 @@ static int pcmuio_start_intr(struct comedi_device *dev,
} }
} }
bits &= ((0x1 << s->n_chan) - 1); bits &= ((0x1 << s->n_chan) - 1);
subpriv->intr.enabled_mask = bits; chip->enabled_mask = bits;
/* set pol and enab intrs for this subdev.. */ /* set pol and enab intrs for this subdev.. */
pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0); pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0);
...@@ -420,13 +417,15 @@ static int pcmuio_start_intr(struct comedi_device *dev, ...@@ -420,13 +417,15 @@ static int pcmuio_start_intr(struct comedi_device *dev,
static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{ {
struct pcmuio_subdev_private *subpriv = s->private; struct pcmuio_private *devpriv = dev->private;
int asic = s->index / 2;
struct pcmuio_asic *chip = &devpriv->asics[asic];
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&subpriv->intr.spinlock, flags); spin_lock_irqsave(&chip->spinlock, flags);
if (subpriv->intr.active) if (chip->active)
pcmuio_stop_intr(dev, s); pcmuio_stop_intr(dev, s);
spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); spin_unlock_irqrestore(&chip->spinlock, flags);
return 0; return 0;
} }
...@@ -438,19 +437,21 @@ static int ...@@ -438,19 +437,21 @@ static int
pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum) unsigned int trignum)
{ {
struct pcmuio_subdev_private *subpriv = s->private; struct pcmuio_private *devpriv = dev->private;
int asic = s->index / 2;
struct pcmuio_asic *chip = &devpriv->asics[asic];
unsigned long flags; unsigned long flags;
int event = 0; int event = 0;
if (trignum != 0) if (trignum != 0)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&subpriv->intr.spinlock, flags); spin_lock_irqsave(&chip->spinlock, flags);
s->async->inttrig = NULL; s->async->inttrig = NULL;
if (subpriv->intr.active) if (chip->active)
event = pcmuio_start_intr(dev, s); event = pcmuio_start_intr(dev, s);
spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); spin_unlock_irqrestore(&chip->spinlock, flags);
if (event) if (event)
comedi_event(dev, s); comedi_event(dev, s);
...@@ -463,24 +464,26 @@ pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, ...@@ -463,24 +464,26 @@ pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
*/ */
static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{ {
struct pcmuio_subdev_private *subpriv = s->private; struct pcmuio_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd; struct comedi_cmd *cmd = &s->async->cmd;
int asic = s->index / 2;
struct pcmuio_asic *chip = &devpriv->asics[asic];
unsigned long flags; unsigned long flags;
int event = 0; int event = 0;
spin_lock_irqsave(&subpriv->intr.spinlock, flags); spin_lock_irqsave(&chip->spinlock, flags);
subpriv->intr.active = 1; chip->active = 1;
/* Set up end of acquisition. */ /* Set up end of acquisition. */
switch (cmd->stop_src) { switch (cmd->stop_src) {
case TRIG_COUNT: case TRIG_COUNT:
subpriv->intr.continuous = 0; chip->continuous = 0;
subpriv->intr.stop_count = cmd->stop_arg; chip->stop_count = cmd->stop_arg;
break; break;
default: default:
/* TRIG_NONE */ /* TRIG_NONE */
subpriv->intr.continuous = 1; chip->continuous = 1;
subpriv->intr.stop_count = 0; chip->stop_count = 0;
break; break;
} }
...@@ -494,7 +497,7 @@ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -494,7 +497,7 @@ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
event = pcmuio_start_intr(dev, s); event = pcmuio_start_intr(dev, s);
break; break;
} }
spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); spin_unlock_irqrestore(&chip->spinlock, flags);
if (event) if (event)
comedi_event(dev, s); comedi_event(dev, s);
...@@ -562,7 +565,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -562,7 +565,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct pcmuio_board *board = comedi_board(dev); const struct pcmuio_board *board = comedi_board(dev);
struct comedi_subdevice *s; struct comedi_subdevice *s;
struct pcmuio_private *devpriv; struct pcmuio_private *devpriv;
struct pcmuio_subdev_private *subpriv;
int sdev_no, n_subdevs, asic; int sdev_no, n_subdevs, asic;
int ret; int ret;
...@@ -575,8 +577,12 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -575,8 +577,12 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv) if (!devpriv)
return -ENOMEM; return -ENOMEM;
for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic) for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic) {
spin_lock_init(&devpriv->asics[asic].pagelock); struct pcmuio_asic *chip = &devpriv->asics[asic];
spin_lock_init(&chip->pagelock);
spin_lock_init(&chip->spinlock);
}
pcmuio_reset(dev); pcmuio_reset(dev);
...@@ -602,9 +608,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -602,9 +608,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
} }
n_subdevs = board->num_asics * 2; n_subdevs = board->num_asics * 2;
devpriv->sprivs = kcalloc(n_subdevs, sizeof(*subpriv), GFP_KERNEL);
if (!devpriv->sprivs)
return -ENOMEM;
ret = comedi_alloc_subdevices(dev, n_subdevs); ret = comedi_alloc_subdevices(dev, n_subdevs);
if (ret) if (ret)
...@@ -612,8 +615,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -612,8 +615,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
s = &dev->subdevices[sdev_no]; s = &dev->subdevices[sdev_no];
subpriv = &devpriv->sprivs[sdev_no];
s->private = subpriv;
s->maxdata = 1; s->maxdata = 1;
s->range_table = &range_digital; s->range_table = &range_digital;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
...@@ -635,7 +636,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -635,7 +636,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
} else { } else {
s->len_chanlist = 1; s->len_chanlist = 1;
} }
spin_lock_init(&subpriv->intr.spinlock);
} }
return 0; return 0;
...@@ -651,8 +651,6 @@ static void pcmuio_detach(struct comedi_device *dev) ...@@ -651,8 +651,6 @@ static void pcmuio_detach(struct comedi_device *dev)
/* free the 2nd irq if used, the core will free the 1st one */ /* free the 2nd irq if used, the core will free the 1st one */
if (devpriv->irq2 && devpriv->irq2 != dev->irq) if (devpriv->irq2 && devpriv->irq2 != dev->irq)
free_irq(devpriv->irq2, dev); free_irq(devpriv->irq2, dev);
kfree(devpriv->sprivs);
} }
comedi_legacy_detach(dev); comedi_legacy_detach(dev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment