Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 337229
b: refs/heads/master
c: cda8437
h: refs/heads/master
i:
  337227: a7d1fc9
v: v3
  • Loading branch information
Ian Abbott authored and Greg Kroah-Hartman committed Oct 24, 2012
1 parent a508916 commit a66a4a9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4bb4021762c33e65645244a965001454cbda6145
refs/heads/master: cda84375f337332421101e7a94f72d0512f8d742
93 changes: 45 additions & 48 deletions trunk/drivers/staging/comedi/drivers/amplc_dio200.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,20 +421,19 @@ struct dio200_private {
};

struct dio200_subdev_8254 {
unsigned long iobase; /* Counter base address */
unsigned long clk_sce_iobase; /* CLK_SCE base address */
unsigned long gat_sce_iobase; /* GAT_SCE base address */
int which; /* Bit 5 of CLK_SCE or GAT_SCE */
unsigned clock_src[3]; /* Current clock sources */
unsigned gate_src[3]; /* Current gate sources */
unsigned int ofs; /* Counter base offset */
unsigned int clk_sce_ofs; /* CLK_SCE base address */
unsigned int gat_sce_ofs; /* GAT_SCE base address */
int which; /* Bit 5 of CLK_SCE or GAT_SCE */
unsigned int clock_src[3]; /* Current clock sources */
unsigned int gate_src[3]; /* Current gate sources */
spinlock_t spinlock;
};

struct dio200_subdev_intr {
unsigned long iobase;
unsigned int ofs;
spinlock_t spinlock;
int active;
int has_int_sce;
unsigned int valid_isns;
unsigned int enabled_isns;
unsigned int stopcount;
Expand Down Expand Up @@ -502,11 +501,12 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;

if (subpriv->has_int_sce) {
if (layout->has_int_sce) {
/* Just read the interrupt status register. */
data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
data[1] = inb(dev->iobase + subpriv->ofs) & subpriv->valid_isns;
} else {
/* No interrupt status register. */
data[0] = 0;
Expand All @@ -521,12 +521,13 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev,
static void dio200_stop_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;

subpriv->active = 0;
subpriv->enabled_isns = 0;
if (subpriv->has_int_sce)
outb(0, subpriv->iobase);
if (layout->has_int_sce)
outb(0, dev->iobase + subpriv->ofs);
}

/*
Expand All @@ -537,6 +538,7 @@ static int dio200_start_intr(struct comedi_device *dev,
{
unsigned int n;
unsigned isn_bits;
const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;
struct comedi_cmd *cmd = &s->async->cmd;
int retval = 0;
Expand All @@ -556,8 +558,8 @@ static int dio200_start_intr(struct comedi_device *dev,
isn_bits &= subpriv->valid_isns;
/* Enable interrupt sources. */
subpriv->enabled_isns = isn_bits;
if (subpriv->has_int_sce)
outb(isn_bits, subpriv->iobase);
if (layout->has_int_sce)
outb(isn_bits, dev->iobase + subpriv->ofs);
}

return retval;
Expand Down Expand Up @@ -599,6 +601,7 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
static int dio200_handle_read_intr(struct comedi_device *dev,
struct comedi_subdevice *s)
{
const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv = s->private;
unsigned triggered;
unsigned intstat;
Expand All @@ -610,7 +613,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev,

spin_lock_irqsave(&subpriv->spinlock, flags);
oldevents = s->async->events;
if (subpriv->has_int_sce) {
if (layout->has_int_sce) {
/*
* Collect interrupt sources that have triggered and disable
* them temporarily. Loop around until no extra interrupt
Expand All @@ -622,11 +625,11 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
* loop in case of misconfiguration.
*/
cur_enabled = subpriv->enabled_isns;
while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
& ~triggered)) != 0) {
while ((intstat = (inb(dev->iobase + subpriv->ofs) &
subpriv->valid_isns & ~triggered)) != 0) {
triggered |= intstat;
cur_enabled &= ~triggered;
outb(cur_enabled, subpriv->iobase);
outb(cur_enabled, dev->iobase + subpriv->ofs);
}
} else {
/*
Expand All @@ -644,8 +647,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
* Reenable them NOW to minimize the time they are disabled.
*/
cur_enabled = subpriv->enabled_isns;
if (subpriv->has_int_sce)
outb(cur_enabled, subpriv->iobase);
if (layout->has_int_sce)
outb(cur_enabled, dev->iobase + subpriv->ofs);

if (subpriv->active) {
/*
Expand Down Expand Up @@ -851,28 +854,28 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev,
*/
static int
dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long iobase, unsigned valid_isns,
int has_int_sce)
unsigned int offset, unsigned valid_isns)
{
const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_intr *subpriv;

subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
if (!subpriv) {
dev_err(dev->class_dev, "error! out of memory!\n");
return -ENOMEM;
}
subpriv->iobase = iobase;
subpriv->has_int_sce = has_int_sce;
subpriv->ofs = offset;
subpriv->valid_isns = valid_isns;
spin_lock_init(&subpriv->spinlock);

if (has_int_sce)
outb(0, subpriv->iobase); /* Disable interrupt sources. */
if (layout->has_int_sce)
/* Disable interrupt sources. */
outb(0, dev->iobase + subpriv->ofs);

s->private = subpriv;
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
if (has_int_sce) {
if (layout->has_int_sce) {
s->n_chan = DIO200_MAX_ISNS;
s->len_chanlist = DIO200_MAX_ISNS;
} else {
Expand Down Expand Up @@ -936,7 +939,7 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long flags;

spin_lock_irqsave(&subpriv->spinlock, flags);
data[0] = i8254_read(subpriv->iobase, 0, chan);
data[0] = i8254_read(dev->iobase + subpriv->ofs, 0, chan);
spin_unlock_irqrestore(&subpriv->spinlock, flags);

return 1;
Expand All @@ -954,7 +957,7 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long flags;

spin_lock_irqsave(&subpriv->spinlock, flags);
i8254_write(subpriv->iobase, 0, chan, data[0]);
i8254_write(dev->iobase + subpriv->ofs, 0, chan, data[0]);
spin_unlock_irqrestore(&subpriv->spinlock, flags);

return 1;
Expand Down Expand Up @@ -982,7 +985,7 @@ dio200_subdev_8254_set_gate_src(struct comedi_device *dev,

subpriv->gate_src[counter_number] = gate_src;
byte = GAT_SCE(subpriv->which, counter_number, gate_src);
outb(byte, subpriv->gat_sce_iobase);
outb(byte, dev->iobase + subpriv->gat_sce_ofs);

return 0;
}
Expand Down Expand Up @@ -1028,7 +1031,7 @@ dio200_subdev_8254_set_clock_src(struct comedi_device *dev,

subpriv->clock_src[counter_number] = clock_src;
byte = CLK_SCE(subpriv->which, counter_number, clock_src);
outb(byte, subpriv->clk_sce_iobase);
outb(byte, dev->iobase + subpriv->clk_sce_ofs);

return 0;
}
Expand Down Expand Up @@ -1071,12 +1074,13 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
spin_lock_irqsave(&subpriv->spinlock, flags);
switch (data[0]) {
case INSN_CONFIG_SET_COUNTER_MODE:
ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
ret = i8254_set_mode(dev->iobase + subpriv->ofs, 0, chan,
data[1]);
if (ret < 0)
ret = -EINVAL;
break;
case INSN_CONFIG_8254_READ_STATUS:
data[1] = i8254_status(subpriv->iobase, 0, chan);
data[1] = i8254_status(dev->iobase + subpriv->ofs, 0, chan);
break;
case INSN_CONFIG_SET_GATE_SRC:
ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
Expand Down Expand Up @@ -1114,13 +1118,10 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,

/*
* This function initializes an '8254' counter subdevice.
*
* Note: iobase is the base address of the board, not the subdevice;
* offset is the offset to the 8254 chip.
*/
static int
dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long iobase, unsigned offset)
unsigned int offset)
{
const struct dio200_layout *layout = dio200_dev_layout(dev);
struct dio200_subdev_8254 *subpriv;
Expand All @@ -1142,20 +1143,18 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
s->insn_config = dio200_subdev_8254_config;

spin_lock_init(&subpriv->spinlock);
subpriv->iobase = offset + iobase;
subpriv->ofs = offset;
if (layout->has_clk_gat_sce) {
/* Derive CLK_SCE and GAT_SCE register offsets from
* 8254 offset. */
subpriv->clk_sce_iobase =
DIO200_XCLK_SCE + (offset >> 3) + iobase;
subpriv->gat_sce_iobase =
DIO200_XGAT_SCE + (offset >> 3) + iobase;
subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3);
subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3);
subpriv->which = (offset >> 2) & 1;
}

/* Initialize channels. */
for (chan = 0; chan < 3; chan++) {
i8254_set_mode(subpriv->iobase, 0, chan,
i8254_set_mode(dev->iobase + subpriv->ofs, 0, chan,
I8254_MODE0 | I8254_BINARY);
if (layout->has_clk_gat_sce) {
/* Gate source 0 is VCC (logic 1). */
Expand Down Expand Up @@ -1228,7 +1227,7 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase,
switch (layout->sdtype[n]) {
case sd_8254:
/* counter subdevice (8254) */
ret = dio200_subdev_8254_init(dev, s, iobase,
ret = dio200_subdev_8254_init(dev, s,
layout->sdinfo[n]);
if (ret < 0)
return ret;
Expand All @@ -1244,11 +1243,9 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase,
/* 'INTERRUPT' subdevice */
if (irq) {
ret = dio200_subdev_intr_init(dev, s,
iobase +
DIO200_INT_SCE,
layout->sdinfo[n],
layout->
has_int_sce);
layout->sdinfo[n]
);
if (ret < 0)
return ret;
devpriv->intr_sd = n;
Expand Down

0 comments on commit a66a4a9

Please sign in to comment.