Lines Matching refs:kcs_bmc

48 static inline u8 read_data(struct kcs_bmc *kcs_bmc)  in read_data()  argument
50 return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr); in read_data()
53 static inline void write_data(struct kcs_bmc *kcs_bmc, u8 data) in write_data() argument
55 kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data); in write_data()
58 static inline u8 read_status(struct kcs_bmc *kcs_bmc) in read_status() argument
60 return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.str); in read_status()
63 static inline void write_status(struct kcs_bmc *kcs_bmc, u8 data) in write_status() argument
65 kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data); in write_status()
68 static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8 val) in update_status_bits() argument
70 u8 tmp = read_status(kcs_bmc); in update_status_bits()
75 write_status(kcs_bmc, tmp); in update_status_bits()
78 static inline void set_state(struct kcs_bmc *kcs_bmc, u8 state) in set_state() argument
80 update_status_bits(kcs_bmc, KCS_STATUS_STATE_MASK, in set_state()
84 static void kcs_force_abort(struct kcs_bmc *kcs_bmc) in kcs_force_abort() argument
86 set_state(kcs_bmc, ERROR_STATE); in kcs_force_abort()
87 read_data(kcs_bmc); in kcs_force_abort()
88 write_data(kcs_bmc, KCS_ZERO_DATA); in kcs_force_abort()
90 kcs_bmc->phase = KCS_PHASE_ERROR; in kcs_force_abort()
91 kcs_bmc->data_in_avail = false; in kcs_force_abort()
92 kcs_bmc->data_in_idx = 0; in kcs_force_abort()
95 static void kcs_bmc_handle_data(struct kcs_bmc *kcs_bmc) in kcs_bmc_handle_data() argument
99 switch (kcs_bmc->phase) { in kcs_bmc_handle_data()
101 kcs_bmc->phase = KCS_PHASE_WRITE_DATA; in kcs_bmc_handle_data()
105 if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) { in kcs_bmc_handle_data()
106 set_state(kcs_bmc, WRITE_STATE); in kcs_bmc_handle_data()
107 write_data(kcs_bmc, KCS_ZERO_DATA); in kcs_bmc_handle_data()
108 kcs_bmc->data_in[kcs_bmc->data_in_idx++] = in kcs_bmc_handle_data()
109 read_data(kcs_bmc); in kcs_bmc_handle_data()
111 kcs_force_abort(kcs_bmc); in kcs_bmc_handle_data()
112 kcs_bmc->error = KCS_LENGTH_ERROR; in kcs_bmc_handle_data()
117 if (kcs_bmc->data_in_idx < KCS_MSG_BUFSIZ) { in kcs_bmc_handle_data()
118 set_state(kcs_bmc, READ_STATE); in kcs_bmc_handle_data()
119 kcs_bmc->data_in[kcs_bmc->data_in_idx++] = in kcs_bmc_handle_data()
120 read_data(kcs_bmc); in kcs_bmc_handle_data()
121 kcs_bmc->phase = KCS_PHASE_WRITE_DONE; in kcs_bmc_handle_data()
122 kcs_bmc->data_in_avail = true; in kcs_bmc_handle_data()
123 wake_up_interruptible(&kcs_bmc->queue); in kcs_bmc_handle_data()
125 kcs_force_abort(kcs_bmc); in kcs_bmc_handle_data()
126 kcs_bmc->error = KCS_LENGTH_ERROR; in kcs_bmc_handle_data()
131 if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) in kcs_bmc_handle_data()
132 set_state(kcs_bmc, IDLE_STATE); in kcs_bmc_handle_data()
134 data = read_data(kcs_bmc); in kcs_bmc_handle_data()
136 set_state(kcs_bmc, ERROR_STATE); in kcs_bmc_handle_data()
137 write_data(kcs_bmc, KCS_ZERO_DATA); in kcs_bmc_handle_data()
141 if (kcs_bmc->data_out_idx == kcs_bmc->data_out_len) { in kcs_bmc_handle_data()
142 write_data(kcs_bmc, KCS_ZERO_DATA); in kcs_bmc_handle_data()
143 kcs_bmc->phase = KCS_PHASE_IDLE; in kcs_bmc_handle_data()
147 write_data(kcs_bmc, in kcs_bmc_handle_data()
148 kcs_bmc->data_out[kcs_bmc->data_out_idx++]); in kcs_bmc_handle_data()
152 set_state(kcs_bmc, READ_STATE); in kcs_bmc_handle_data()
153 read_data(kcs_bmc); in kcs_bmc_handle_data()
154 write_data(kcs_bmc, kcs_bmc->error); in kcs_bmc_handle_data()
155 kcs_bmc->phase = KCS_PHASE_ABORT_ERROR2; in kcs_bmc_handle_data()
159 set_state(kcs_bmc, IDLE_STATE); in kcs_bmc_handle_data()
160 read_data(kcs_bmc); in kcs_bmc_handle_data()
161 write_data(kcs_bmc, KCS_ZERO_DATA); in kcs_bmc_handle_data()
162 kcs_bmc->phase = KCS_PHASE_IDLE; in kcs_bmc_handle_data()
166 kcs_force_abort(kcs_bmc); in kcs_bmc_handle_data()
171 static void kcs_bmc_handle_cmd(struct kcs_bmc *kcs_bmc) in kcs_bmc_handle_cmd() argument
175 set_state(kcs_bmc, WRITE_STATE); in kcs_bmc_handle_cmd()
176 write_data(kcs_bmc, KCS_ZERO_DATA); in kcs_bmc_handle_cmd()
178 cmd = read_data(kcs_bmc); in kcs_bmc_handle_cmd()
181 kcs_bmc->phase = KCS_PHASE_WRITE_START; in kcs_bmc_handle_cmd()
182 kcs_bmc->error = KCS_NO_ERROR; in kcs_bmc_handle_cmd()
183 kcs_bmc->data_in_avail = false; in kcs_bmc_handle_cmd()
184 kcs_bmc->data_in_idx = 0; in kcs_bmc_handle_cmd()
188 if (kcs_bmc->phase != KCS_PHASE_WRITE_DATA) { in kcs_bmc_handle_cmd()
189 kcs_force_abort(kcs_bmc); in kcs_bmc_handle_cmd()
193 kcs_bmc->phase = KCS_PHASE_WRITE_END_CMD; in kcs_bmc_handle_cmd()
197 if (kcs_bmc->error == KCS_NO_ERROR) in kcs_bmc_handle_cmd()
198 kcs_bmc->error = KCS_ABORTED_BY_COMMAND; in kcs_bmc_handle_cmd()
200 kcs_bmc->phase = KCS_PHASE_ABORT_ERROR1; in kcs_bmc_handle_cmd()
201 kcs_bmc->data_in_avail = false; in kcs_bmc_handle_cmd()
202 kcs_bmc->data_in_idx = 0; in kcs_bmc_handle_cmd()
206 kcs_force_abort(kcs_bmc); in kcs_bmc_handle_cmd()
207 kcs_bmc->error = KCS_ILLEGAL_CONTROL_CODE; in kcs_bmc_handle_cmd()
212 int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) in kcs_bmc_handle_event() argument
218 spin_lock_irqsave(&kcs_bmc->lock, flags); in kcs_bmc_handle_event()
220 status = read_status(kcs_bmc); in kcs_bmc_handle_event()
222 if (!kcs_bmc->running) in kcs_bmc_handle_event()
223 kcs_force_abort(kcs_bmc); in kcs_bmc_handle_event()
225 kcs_bmc_handle_cmd(kcs_bmc); in kcs_bmc_handle_event()
227 kcs_bmc_handle_data(kcs_bmc); in kcs_bmc_handle_event()
232 spin_unlock_irqrestore(&kcs_bmc->lock, flags); in kcs_bmc_handle_event()
238 static inline struct kcs_bmc *to_kcs_bmc(struct file *filp) in to_kcs_bmc()
240 return container_of(filp->private_data, struct kcs_bmc, miscdev); in to_kcs_bmc()
245 struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); in kcs_bmc_open() local
248 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_open()
249 if (!kcs_bmc->running) in kcs_bmc_open()
250 kcs_bmc->running = 1; in kcs_bmc_open()
253 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_open()
260 struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); in kcs_bmc_poll() local
263 poll_wait(filp, &kcs_bmc->queue, wait); in kcs_bmc_poll()
265 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_poll()
266 if (kcs_bmc->data_in_avail) in kcs_bmc_poll()
268 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_poll()
276 struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); in kcs_bmc_read() local
282 wait_event_interruptible(kcs_bmc->queue, in kcs_bmc_read()
283 kcs_bmc->data_in_avail); in kcs_bmc_read()
285 mutex_lock(&kcs_bmc->mutex); in kcs_bmc_read()
287 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_read()
288 data_avail = kcs_bmc->data_in_avail; in kcs_bmc_read()
290 data_len = kcs_bmc->data_in_idx; in kcs_bmc_read()
291 memcpy(kcs_bmc->kbuffer, kcs_bmc->data_in, data_len); in kcs_bmc_read()
293 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_read()
302 kcs_bmc->channel, data_len); in kcs_bmc_read()
304 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_read()
305 kcs_force_abort(kcs_bmc); in kcs_bmc_read()
306 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_read()
312 if (copy_to_user(buf, kcs_bmc->kbuffer, data_len)) { in kcs_bmc_read()
319 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_read()
320 if (kcs_bmc->phase == KCS_PHASE_WRITE_DONE) { in kcs_bmc_read()
321 kcs_bmc->phase = KCS_PHASE_WAIT_READ; in kcs_bmc_read()
322 kcs_bmc->data_in_avail = false; in kcs_bmc_read()
323 kcs_bmc->data_in_idx = 0; in kcs_bmc_read()
327 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_read()
330 mutex_unlock(&kcs_bmc->mutex); in kcs_bmc_read()
338 struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); in kcs_bmc_write() local
345 mutex_lock(&kcs_bmc->mutex); in kcs_bmc_write()
347 if (copy_from_user(kcs_bmc->kbuffer, buf, count)) { in kcs_bmc_write()
352 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_write()
353 if (kcs_bmc->phase == KCS_PHASE_WAIT_READ) { in kcs_bmc_write()
354 kcs_bmc->phase = KCS_PHASE_READ; in kcs_bmc_write()
355 kcs_bmc->data_out_idx = 1; in kcs_bmc_write()
356 kcs_bmc->data_out_len = count; in kcs_bmc_write()
357 memcpy(kcs_bmc->data_out, kcs_bmc->kbuffer, count); in kcs_bmc_write()
358 write_data(kcs_bmc, kcs_bmc->data_out[0]); in kcs_bmc_write()
363 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_write()
366 mutex_unlock(&kcs_bmc->mutex); in kcs_bmc_write()
374 struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); in kcs_bmc_ioctl() local
377 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_ioctl()
381 update_status_bits(kcs_bmc, KCS_STATUS_SMS_ATN, in kcs_bmc_ioctl()
386 update_status_bits(kcs_bmc, KCS_STATUS_SMS_ATN, in kcs_bmc_ioctl()
391 kcs_force_abort(kcs_bmc); in kcs_bmc_ioctl()
399 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_ioctl()
406 struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); in kcs_bmc_release() local
408 spin_lock_irq(&kcs_bmc->lock); in kcs_bmc_release()
409 kcs_bmc->running = 0; in kcs_bmc_release()
410 kcs_force_abort(kcs_bmc); in kcs_bmc_release()
411 spin_unlock_irq(&kcs_bmc->lock); in kcs_bmc_release()
426 struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel) in kcs_bmc_alloc()
428 struct kcs_bmc *kcs_bmc; in kcs_bmc_alloc() local
430 kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL); in kcs_bmc_alloc()
431 if (!kcs_bmc) in kcs_bmc_alloc()
434 spin_lock_init(&kcs_bmc->lock); in kcs_bmc_alloc()
435 kcs_bmc->channel = channel; in kcs_bmc_alloc()
437 mutex_init(&kcs_bmc->mutex); in kcs_bmc_alloc()
438 init_waitqueue_head(&kcs_bmc->queue); in kcs_bmc_alloc()
440 kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); in kcs_bmc_alloc()
441 kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); in kcs_bmc_alloc()
442 kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); in kcs_bmc_alloc()
444 kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; in kcs_bmc_alloc()
445 kcs_bmc->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%u", in kcs_bmc_alloc()
447 if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer || in kcs_bmc_alloc()
448 !kcs_bmc->miscdev.name) in kcs_bmc_alloc()
450 kcs_bmc->miscdev.fops = &kcs_bmc_fops; in kcs_bmc_alloc()
452 return kcs_bmc; in kcs_bmc_alloc()