patch-2.4.21 linux-2.4.21/arch/cris/drivers/sync_serial.c
Next file: linux-2.4.21/arch/cris/kernel/entry.S
Previous file: linux-2.4.21/arch/cris/drivers/serial.c
Back to the patch index
Back to the overall index
- Lines: 247
- Date:
2003-06-13 07:51:29.000000000 -0700
- Orig file:
linux-2.4.20/arch/cris/drivers/sync_serial.c
- Orig date:
2002-11-28 15:53:09.000000000 -0800
diff -urN linux-2.4.20/arch/cris/drivers/sync_serial.c linux-2.4.21/arch/cris/drivers/sync_serial.c
@@ -64,13 +64,13 @@
#define DEFAULT_FRAME_RATE 0
#define DEFAULT_WORD_RATE 7
-#define DEBUG(x)
+#define DEBUG(x)
/* Define some macros to access ETRAX 100 registers */
-#define SETF(var, reg, field, val) var = (var & ~IO_MASK(##reg##, field)) | \
- IO_FIELD(##reg##, field, val)
-#define SETS(var, reg, field, val) var = (var & ~IO_MASK(##reg##, field)) | \
- IO_STATE(##reg##, field, val)
+#define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
+ IO_FIELD_(reg##_, field##_, val)
+#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
+ IO_STATE_(reg##_, field##_, _##val)
typedef struct sync_port
{
@@ -107,8 +107,7 @@
char in_buffer[IN_BUFFER_SIZE];
volatile char* readp; /* Next byte to be read by application */
volatile char* writep; /* Next byte to be written by etrax */
- int odd_output; /* 1 if writing odd nible in 12 bit mode */
- int odd_input; /* 1 if reading odd nible in 12 bit mode */
+ int started; /* 1 if port has been started */
} sync_port;
@@ -221,7 +220,6 @@
IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr, do);
*R_IRQ_MASK2_SET =
IO_STATE(R_IRQ_MASK2_SET, dma8_eop, set) |
- IO_STATE(R_IRQ_MASK2_SET, dma8_descr, set) |
IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
start_dma_in(&ports[0]);
#else
@@ -229,7 +227,6 @@
initialize_port(0);
if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[0]))
panic("Can't allocate sync serial manual irq");
- *R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser1_data, set);
#endif
#endif
@@ -252,7 +249,6 @@
IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr, do);
*R_IRQ_MASK2_SET =
IO_STATE(R_IRQ_MASK2_SET, dma4_eop, set) |
- IO_STATE(R_IRQ_MASK2_SET, dma4_descr, set) |
IO_STATE(R_IRQ_MASK2_SET, dma5_descr, set);
start_dma_in(&ports[1]);
#else
@@ -263,7 +259,6 @@
if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1]))
panic("Can't allocate sync serial manual irq");
}
- *R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser3_data, set);
#endif
#endif
@@ -292,12 +287,12 @@
struct sync_port* port = &ports[portnbr];
DEBUG(printk("Init sync serial port %d\n", portnbr));
-
+
+ port->started = 0;
port->port_nbr = portnbr;
port->busy = 0;
port->readp = port->in_buffer;
- port->writep = port->in_buffer + IN_BUFFER_SIZE/2;
- port->odd_input = 0;
+ port->writep = port->in_buffer;
init_waitqueue_head(&port->out_wait_q);
init_waitqueue_head(&port->in_wait_q);
@@ -422,6 +417,10 @@
case SSP_MODE:
if (arg > 5)
return -EINVAL;
+ if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)
+ *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit;
+ else
+ *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg);
break;
case SSP_FRAME_SYNC:
@@ -466,8 +465,8 @@
if (arg & CLOCK_NOT_GATED)
SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal);
else if (arg & CLOCK_GATED)
- SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated);
-
+ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated);
+
break;
case SSP_IPOLARITY:
if (arg & CLOCK_NORMAL)
@@ -553,11 +552,10 @@
copy_from_user(port->out_buffer, buf, count);
port->outp = port->out_buffer;
port->out_count = count;
- port->odd_output = 1;
add_wait_queue(&port->out_wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
- *R_IRQ_MASK1_SET = 1 << port->ready_irq_bit; /* transmitter ready IRQ on */
send_word(port); /* Start sender by sending first word */
+ *R_IRQ_MASK1_SET = 1 << port->ready_irq_bit; /* transmitter ready IRQ on */
schedule();
set_current_state(TASK_RUNNING);
remove_wait_queue(&port->out_wait_q, &wait);
@@ -586,9 +584,15 @@
count = count > OUT_BUFFER_SIZE ? OUT_BUFFER_SIZE : count;
- /* Make sure transmitter is running */
- SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
- SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
+ /* Make sure transmitter/receiver is running */
+ if (!port->started)
+ {
+ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
+ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
+ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
+ port->started = 1;
+ }
+
*port->ctrl_data = port->ctrl_data_shadow;
if (!port->use_dma)
@@ -629,9 +633,14 @@
DEBUG(printk("Read dev %d count %d\n", dev, count));
- /* Make sure receiver is running */
- SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
- SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
+ if (!port->started)
+ {
+ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
+ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
+ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
+ port->started = 1;
+ }
+
*port->ctrl_data = port->ctrl_data_shadow;
/* Calculate number of available bytes */
@@ -680,13 +689,12 @@
*port->data_out = *port->outp++;
break;
case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
- port->out_count--;
- if (port->odd_output)
- *port->data_out = ((*port->outp) << 16) | (*(unsigned short *)(port->outp + 1));
- else
- *port->data_out = ((*(unsigned short *)port->outp) << 8) | (*(port->outp + 1));
- port->odd_output = !port->odd_output;
- port->outp++;
+ {
+ int data = (*port->outp++) << 8;
+ data |= *port->outp++;
+ port->out_count-=2;
+ *port->data_out = data;
+ }
break;
case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
port->out_count-=2;
@@ -710,7 +718,7 @@
{
port->out_descr.hw_len = 0;
port->out_descr.next = 0;
- port->out_descr.ctrl = d_int | d_eol | d_eop | d_wait;
+ port->out_descr.ctrl = d_eol | d_eop | d_wait;
port->out_descr.sw_len = count;
port->out_descr.buf = virt_to_phys(port->out_buffer);
port->out_descr.status = 0;
@@ -765,6 +773,9 @@
for (i = 0; i < NUMBER_OF_PORTS; i++)
{
sync_port *port = &ports[i];
+ if (!port->enabled)
+ continue;
+
if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */
{
/* Clear IRQ */
@@ -783,19 +794,15 @@
for (i = 0; i < NUMBER_OF_PORTS; i++)
{
- int update = 0;
sync_port *port = &ports[i];
if (!port->enabled)
- {
continue;
- }
if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */
{
/* DMA has reached end of descriptor */
*port->input_dma_clr_irq =
- IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) |
IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
/* Find out which descriptor that is ready */
@@ -847,18 +854,9 @@
case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
{
int data = *(unsigned short *)port->data_in;
- if (port->odd_input)
- {
- *port->writep |= (data & 0x0f00) >> 8;
- *(port->writep + 1) = data & 0xff;
- }
- else
- {
- *port->writep = (data & 0x0ff0) >> 4;
- *(port->writep + 1) = (data & 0x0f) << 4;
- }
- port->odd_input = !port->odd_input;
- port->writep+=1;
+ *port->writep = (data & 0x0ff0) >> 4;
+ *(port->writep + 1) = data & 0x0f;
+ port->writep+=2;
}
break;
case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
@@ -875,14 +873,14 @@
break;
}
- if (port->writep > port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */
+ if (port->writep >= port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */
port->writep = port->in_buffer;
wake_up_interruptible(&port->in_wait_q); /* Wake up application */
}
if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */
{
- if (port->out_count) /* More data to send */
+ if (port->out_count > 0) /* More data to send */
send_word(port);
else /* transmission finished */
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)