libchip: SMP support for NS16550

This commit is contained in:
Sebastian Huber
2014-04-15 13:33:42 +02:00
parent 509040f0af
commit 598f39cd87

View File

@@ -58,6 +58,9 @@
#endif #endif
#endif #endif
static rtems_interrupt_lock ns16550_lock =
RTEMS_INTERRUPT_LOCK_INITIALIZER("NS16550");
/* /*
* Flow control is only supported when using interrupts * Flow control is only supported when using interrupts
*/ */
@@ -271,7 +274,7 @@ void ns16550_outch_polled(console_tbl *c, char out)
getRegister_f get = c->getRegister; getRegister_f get = c->getRegister;
setRegister_f set = c->setRegister; setRegister_f set = c->setRegister;
uint32_t status = 0; uint32_t status = 0;
rtems_interrupt_level level; rtems_interrupt_lock_context lock_context;
/* Save port interrupt mask */ /* Save port interrupt mask */
uint32_t interrupt_mask = get( port, NS16550_INTERRUPT_ENABLE); uint32_t interrupt_mask = get( port, NS16550_INTERRUPT_ENABLE);
@@ -281,7 +284,7 @@ void ns16550_outch_polled(console_tbl *c, char out)
while (true) { while (true) {
/* Try to transmit the character in a critical section */ /* Try to transmit the character in a critical section */
rtems_interrupt_disable( level); rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
/* Read the transmitter holding register and check it */ /* Read the transmitter holding register and check it */
status = get( port, NS16550_LINE_STATUS); status = get( port, NS16550_LINE_STATUS);
@@ -290,10 +293,10 @@ void ns16550_outch_polled(console_tbl *c, char out)
set( port, NS16550_TRANSMIT_BUFFER, out); set( port, NS16550_TRANSMIT_BUFFER, out);
/* Finished */ /* Finished */
rtems_interrupt_enable( level); rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
break; break;
} else { } else {
rtems_interrupt_enable( level); rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
} }
/* Wait for transmitter holding register to be empty */ /* Wait for transmitter holding register to be empty */
@@ -324,7 +327,7 @@ void ns16550_write_polled(int minor, char out)
NS16550_STATIC int ns16550_assert_RTS(int minor) NS16550_STATIC int ns16550_assert_RTS(int minor)
{ {
uint32_t pNS16550; uint32_t pNS16550;
uint32_t Irql; rtems_interrupt_lock_context lock_context;
ns16550_context *pns16550Context; ns16550_context *pns16550Context;
setRegister_f setReg; setRegister_f setReg;
@@ -336,10 +339,10 @@ NS16550_STATIC int ns16550_assert_RTS(int minor)
/* /*
* Assert RTS * Assert RTS
*/ */
rtems_interrupt_disable(Irql); rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
pns16550Context->ucModemCtrl|=SP_MODEM_RTS; pns16550Context->ucModemCtrl|=SP_MODEM_RTS;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl); (*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql); rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
return 0; return 0;
} }
@@ -350,7 +353,7 @@ NS16550_STATIC int ns16550_assert_RTS(int minor)
NS16550_STATIC int ns16550_negate_RTS(int minor) NS16550_STATIC int ns16550_negate_RTS(int minor)
{ {
uint32_t pNS16550; uint32_t pNS16550;
uint32_t Irql; rtems_interrupt_lock_context lock_context;
ns16550_context *pns16550Context; ns16550_context *pns16550Context;
setRegister_f setReg; setRegister_f setReg;
@@ -362,10 +365,10 @@ NS16550_STATIC int ns16550_negate_RTS(int minor)
/* /*
* Negate RTS * Negate RTS
*/ */
rtems_interrupt_disable(Irql); rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
pns16550Context->ucModemCtrl&=~SP_MODEM_RTS; pns16550Context->ucModemCtrl&=~SP_MODEM_RTS;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl); (*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql); rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
return 0; return 0;
} }
@@ -381,7 +384,7 @@ NS16550_STATIC int ns16550_negate_RTS(int minor)
NS16550_STATIC int ns16550_assert_DTR(int minor) NS16550_STATIC int ns16550_assert_DTR(int minor)
{ {
uint32_t pNS16550; uint32_t pNS16550;
uint32_t Irql; rtems_interrupt_lock_context lock_context;
ns16550_context *pns16550Context; ns16550_context *pns16550Context;
setRegister_f setReg; setRegister_f setReg;
@@ -393,10 +396,10 @@ NS16550_STATIC int ns16550_assert_DTR(int minor)
/* /*
* Assert DTR * Assert DTR
*/ */
rtems_interrupt_disable(Irql); rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
pns16550Context->ucModemCtrl|=SP_MODEM_DTR; pns16550Context->ucModemCtrl|=SP_MODEM_DTR;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl); (*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql); rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
return 0; return 0;
} }
@@ -407,7 +410,7 @@ NS16550_STATIC int ns16550_assert_DTR(int minor)
NS16550_STATIC int ns16550_negate_DTR(int minor) NS16550_STATIC int ns16550_negate_DTR(int minor)
{ {
uint32_t pNS16550; uint32_t pNS16550;
uint32_t Irql; rtems_interrupt_lock_context lock_context;
ns16550_context *pns16550Context; ns16550_context *pns16550Context;
setRegister_f setReg; setRegister_f setReg;
@@ -419,10 +422,10 @@ NS16550_STATIC int ns16550_negate_DTR(int minor)
/* /*
* Negate DTR * Negate DTR
*/ */
rtems_interrupt_disable(Irql); rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
pns16550Context->ucModemCtrl&=~SP_MODEM_DTR; pns16550Context->ucModemCtrl&=~SP_MODEM_DTR;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL,pns16550Context->ucModemCtrl); (*setReg)(pNS16550, NS16550_MODEM_CONTROL,pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql); rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
return 0; return 0;
} }
@@ -443,7 +446,7 @@ int ns16550_set_attributes(
uint8_t ucLineControl; uint8_t ucLineControl;
uint32_t baud_requested; uint32_t baud_requested;
setRegister_f setReg; setRegister_f setReg;
uint32_t Irql; rtems_interrupt_lock_context lock_context;
const console_tbl *c = Console_Port_Tbl [minor]; const console_tbl *c = Console_Port_Tbl [minor];
pNS16550 = c->ulCtrlPort1; pNS16550 = c->ulCtrlPort1;
@@ -497,7 +500,7 @@ int ns16550_set_attributes(
* Now actually set the chip * Now actually set the chip
*/ */
rtems_interrupt_disable(Irql); rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
/* /*
* Set the baud rate * Set the baud rate
@@ -516,7 +519,7 @@ int ns16550_set_attributes(
*/ */
(*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl ); (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl );
rtems_interrupt_enable(Irql); rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
return 0; return 0;
} }