[PATCH 05/13] staging: comedi: pcmuio: remove subdevice private data

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ian Abbott <abbotti@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/staging/comedi/drivers/pcmuio.c | 106 ++++++++++++++------------------
 1 file changed, 46 insertions(+), 60 deletions(-)

diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 39afd94..82478ed 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -127,26 +127,15 @@ static const struct pcmuio_board pcmuio_boards[] = {
 	},
 };
 
-struct pcmuio_subdev_private {
-	/* The below is only used for intr subdevices */
+struct pcmuio_private {
 	struct {
-		/*
-		 * subdev-relative channel mask for channels
-		 * we are interested in
-		 */
+		spinlock_t pagelock;	/* protect r/w of page registers */
+		spinlock_t spinlock;
 		int enabled_mask;
 		int active;
 		int stop_count;
 		int continuous;
-		spinlock_t spinlock;
-	} intr;
-};
-
-struct pcmuio_private {
-	struct {
-		spinlock_t pagelock;	/* protect r/w of page registers */
 	} asics[PCMUIO_MAX_ASICS];
-	struct pcmuio_subdev_private *sprivs;
 };
 
 static void pcmuio_write(struct comedi_device *dev, unsigned int val,
@@ -283,11 +272,11 @@ static void pcmuio_reset(struct comedi_device *dev)
 static void pcmuio_stop_intr(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;
 
-	subpriv->intr.enabled_mask = 0;
-	subpriv->intr.active = 0;
+	devpriv->asics[asic].enabled_mask = 0;
+	devpriv->asics[asic].active = 0;
 	s->async->inttrig = NULL;
 
 	/* disable all intrs for this subdev.. */
@@ -298,23 +287,24 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
 				      struct comedi_subdevice *s,
 				      unsigned triggered)
 {
-	struct pcmuio_subdev_private *subpriv = s->private;
+	struct pcmuio_private *devpriv = dev->private;
 	unsigned int len = s->async->cmd.chanlist_len;
 	unsigned oldevents = s->async->events;
+	int asic = s->index / 2;
 	unsigned int val = 0;
 	unsigned long flags;
 	unsigned mytrig;
 	unsigned int i;
 
-	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+	spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
 
-	if (!subpriv->intr.active)
+	if (!devpriv->asics[asic].active)
 		goto done;
 
 	mytrig = triggered;
 	mytrig &= ((0x1 << s->n_chan) - 1);
 
-	if (!(mytrig & subpriv->intr.enabled_mask))
+	if (!(mytrig & devpriv->asics[asic].enabled_mask))
 		goto done;
 
 	for (i = 0; i < len; i++) {
@@ -334,11 +324,11 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
 	}
 
 	/* Check for end of acquisition. */
-	if (!subpriv->intr.continuous) {
+	if (!devpriv->asics[asic].continuous) {
 		/* stop_src == TRIG_COUNT */
-		if (subpriv->intr.stop_count > 0) {
-			subpriv->intr.stop_count--;
-			if (subpriv->intr.stop_count == 0) {
+		if (devpriv->asics[asic].stop_count > 0) {
+			devpriv->asics[asic].stop_count--;
+			if (devpriv->asics[asic].stop_count == 0) {
 				s->async->events |= COMEDI_CB_EOA;
 				/* TODO: STOP_ACQUISITION_CALL_HERE!! */
 				pcmuio_stop_intr(dev, s);
@@ -347,7 +337,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
 	}
 
 done:
-	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+	spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
 
 	if (oldevents != s->async->events)
 		comedi_event(dev, s);
@@ -390,20 +380,22 @@ static irqreturn_t pcmuio_interrupt(int irq, void *d)
 static int pcmuio_start_intr(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;
 
-	if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) {
+	if (!devpriv->asics[asic].continuous &&
+	    devpriv->asics[asic].stop_count == 0) {
 		/* An empty acquisition! */
 		s->async->events |= COMEDI_CB_EOA;
-		subpriv->intr.active = 0;
+		devpriv->asics[asic].active = 0;
 		return 1;
 	} else {
 		unsigned bits = 0, pol_bits = 0, n;
 		int asic = s->index / 2;
 		struct comedi_cmd *cmd = &s->async->cmd;
 
-		subpriv->intr.enabled_mask = 0;
-		subpriv->intr.active = 1;
+		devpriv->asics[asic].enabled_mask = 0;
+		devpriv->asics[asic].active = 1;
 		if (cmd->chanlist) {
 			for (n = 0; n < cmd->chanlist_len; n++) {
 				bits |= (1U << CR_CHAN(cmd->chanlist[n]));
@@ -414,7 +406,7 @@ static int pcmuio_start_intr(struct comedi_device *dev,
 			}
 		}
 		bits &= ((0x1 << s->n_chan) - 1);
-		subpriv->intr.enabled_mask = bits;
+		devpriv->asics[asic].enabled_mask = bits;
 
 		/* set pol and enab intrs for this subdev.. */
 		pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0);
@@ -425,13 +417,14 @@ static int pcmuio_start_intr(struct comedi_device *dev,
 
 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;
 	unsigned long flags;
 
-	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
-	if (subpriv->intr.active)
+	spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
+	if (devpriv->asics[asic].active)
 		pcmuio_stop_intr(dev, s);
-	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+	spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
 
 	return 0;
 }
@@ -443,19 +436,20 @@ static int
 pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
 			  unsigned int trignum)
 {
-	struct pcmuio_subdev_private *subpriv = s->private;
+	struct pcmuio_private *devpriv = dev->private;
+	int asic = s->index / 2;
 	unsigned long flags;
 	int event = 0;
 
 	if (trignum != 0)
 		return -EINVAL;
 
-	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+	spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
 	s->async->inttrig = NULL;
-	if (subpriv->intr.active)
+	if (devpriv->asics[asic].active)
 		event = pcmuio_start_intr(dev, s);
 
-	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+	spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
 
 	if (event)
 		comedi_event(dev, s);
@@ -468,24 +462,25 @@ pcmuio_inttrig_start_intr(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;
+	int asic = s->index / 2;
 	unsigned long flags;
 	int event = 0;
 
-	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
-	subpriv->intr.active = 1;
+	spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
+	devpriv->asics[asic].active = 1;
 
 	/* Set up end of acquisition. */
 	switch (cmd->stop_src) {
 	case TRIG_COUNT:
-		subpriv->intr.continuous = 0;
-		subpriv->intr.stop_count = cmd->stop_arg;
+		devpriv->asics[asic].continuous = 0;
+		devpriv->asics[asic].stop_count = cmd->stop_arg;
 		break;
 	default:
 		/* TRIG_NONE */
-		subpriv->intr.continuous = 1;
-		subpriv->intr.stop_count = 0;
+		devpriv->asics[asic].continuous = 1;
+		devpriv->asics[asic].stop_count = 0;
 		break;
 	}
 
@@ -499,7 +494,7 @@ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		event = pcmuio_start_intr(dev, s);
 		break;
 	}
-	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+	spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
 
 	if (event)
 		comedi_event(dev, s);
@@ -567,7 +562,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	const struct pcmuio_board *board = comedi_board(dev);
 	struct comedi_subdevice *s;
 	struct pcmuio_private *devpriv;
-	struct pcmuio_subdev_private *subpriv;
 	int sdev_no, n_subdevs, asic;
 	unsigned int irq;
 	int ret;
@@ -581,8 +575,10 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (!devpriv)
 		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);
+		spin_lock_init(&devpriv->asics[asic].spinlock);
+	}
 
 	pcmuio_reset(dev);
 
@@ -618,18 +614,12 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	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);
 	if (ret)
 		return ret;
 
 	for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
 		s = &dev->subdevices[sdev_no];
-		subpriv = &devpriv->sprivs[sdev_no];
-		s->private = subpriv;
 		s->maxdata = 1;
 		s->range_table = &range_digital;
 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
@@ -650,7 +640,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		} else {
 			s->len_chanlist = 1;
 		}
-		spin_lock_init(&subpriv->intr.spinlock);
 	}
 
 	return 0;
@@ -669,9 +658,6 @@ static void pcmuio_detach(struct comedi_device *dev)
 		dev->irq &= 0xff;
 		if (irq2 && irq2 != dev->irq)
 			free_irq(irq2, dev);
-
-		if (devpriv->sprivs)
-			kfree(devpriv->sprivs);
 	}
 	comedi_legacy_detach(dev);
 }
-- 
1.8.3.2

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux