00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <types.h>
00031 #include <lib.h>
00032 #include <spinlock.h>
00033 #include <platform/bus.h>
00034 #include <lamebus/lser.h>
00035 #include "autoconf.h"
00036
00037
00038 #define LSER_REG_CHAR 0
00039 #define LSER_REG_WIRQ 4
00040 #define LSER_REG_RIRQ 8
00041
00042
00043 #define LSER_IRQ_ENABLE 1
00044 #define LSER_IRQ_ACTIVE 2
00045
00046 void
00047 lser_irq(void *vsc)
00048 {
00049 struct lser_softc *sc = vsc;
00050 uint32_t x;
00051 bool clear_to_write = false;
00052 bool got_a_read = false;
00053 uint32_t ch = 0;
00054
00055 spinlock_acquire(&sc->ls_lock);
00056
00057 x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_WIRQ);
00058 if (x & LSER_IRQ_ACTIVE) {
00059 x = LSER_IRQ_ENABLE;
00060 sc->ls_wbusy = 0;
00061 clear_to_write = true;
00062 bus_write_register(sc->ls_busdata, sc->ls_buspos,
00063 LSER_REG_WIRQ, x);
00064 }
00065
00066 x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_RIRQ);
00067 if (x & LSER_IRQ_ACTIVE) {
00068 x = LSER_IRQ_ENABLE;
00069 ch = bus_read_register(sc->ls_busdata, sc->ls_buspos,
00070 LSER_REG_CHAR);
00071 got_a_read = true;
00072 bus_write_register(sc->ls_busdata, sc->ls_buspos,
00073 LSER_REG_RIRQ, x);
00074 }
00075
00076 spinlock_release(&sc->ls_lock);
00077
00078 if (clear_to_write && sc->ls_start != NULL) {
00079 sc->ls_start(sc->ls_devdata);
00080 }
00081 if (got_a_read && sc->ls_input != NULL) {
00082 sc->ls_input(sc->ls_devdata, ch);
00083 }
00084 }
00085
00086 void
00087 lser_write(void *vls, int ch)
00088 {
00089 struct lser_softc *ls = vls;
00090
00091 spinlock_acquire(&ls->ls_lock);
00092
00093 if (ls->ls_wbusy) {
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 panic("lser: Not clear to write\n");
00106 }
00107 ls->ls_wbusy = true;
00108
00109 bus_write_register(ls->ls_busdata, ls->ls_buspos, LSER_REG_CHAR, ch);
00110
00111 spinlock_release(&ls->ls_lock);
00112 }
00113
00114 static
00115 void
00116 lser_poll_until_write(struct lser_softc *sc)
00117 {
00118 uint32_t val;
00119
00120 KASSERT(spinlock_do_i_hold(&sc->ls_lock));
00121
00122 do {
00123 val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
00124 LSER_REG_WIRQ);
00125 }
00126 while ((val & LSER_IRQ_ACTIVE) == 0);
00127 }
00128
00129 void
00130 lser_writepolled(void *vsc, int ch)
00131 {
00132 struct lser_softc *sc = vsc;
00133 bool irqpending = false;
00134
00135 spinlock_acquire(&sc->ls_lock);
00136
00137 if (sc->ls_wbusy) {
00138 irqpending = true;
00139 lser_poll_until_write(sc);
00140
00141 bus_write_register(sc->ls_busdata, sc->ls_buspos,
00142 LSER_REG_WIRQ, LSER_IRQ_ENABLE);
00143 }
00144
00145
00146 bus_write_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_CHAR, ch);
00147
00148
00149 lser_poll_until_write(sc);
00150
00151
00152
00153
00154
00155
00156 if (!irqpending) {
00157 bus_write_register(sc->ls_busdata, sc->ls_buspos,
00158 LSER_REG_WIRQ, LSER_IRQ_ENABLE);
00159 }
00160
00161 spinlock_release(&sc->ls_lock);
00162 }
00163
00164
00165
00166
00167
00168
00169 void
00170 lser_startpolling(void *vsc)
00171 {
00172 struct lser_softc *sc = vsc;
00173 sc->ls_maskinterrupt(sc->ls_busdata, sc->ls_buspos);
00174 }
00175
00176 void
00177 lser_endpolling(void *vsc)
00178 {
00179 struct lser_softc *sc = vsc;
00180 sc->ls_unmaskinterrupt(sc->ls_busdata, sc->ls_buspos);
00181 }
00182
00183 int
00184 config_lser(struct lser_softc *sc, int lserno)
00185 {
00186 (void)lserno;
00187
00188
00189
00190
00191
00192 spinlock_init(&sc->ls_lock);
00193 sc->ls_wbusy = false;
00194
00195 bus_write_register(sc->ls_busdata, sc->ls_buspos,
00196 LSER_REG_RIRQ, LSER_IRQ_ENABLE);
00197 bus_write_register(sc->ls_busdata, sc->ls_buspos,
00198 LSER_REG_WIRQ, LSER_IRQ_ENABLE);
00199
00200 return 0;
00201 }