Lines Matching +full:rx +full:- +full:sched +full:- +full:sp

1 // SPDX-License-Identifier: GPL-2.0+
5 * Supervisory Processor(SP) MCU that is connected via dedicated UART
12 #include <linux/crc-itu-t.h>
18 #include <linux/mfd/rave-sp.h>
22 #include <linux/sched.h>
28 * - message to MCU => ACK response
29 * - event from MCU => event ACK
34 * - STX - is start of transmission character
35 * - ETX - end of transmission
36 * - DATA - payload
37 * - CHECKSUM - checksum calculated on <DATA>
52 * We don't store STX, ETX and unescaped bytes, so Rx is only
67 * enum rave_sp_deframer_state - Possible state for de-framer
69 * @RAVE_SP_EXPECT_SOF: Scanning input for start-of-frame marker
80 * struct rave_sp_deframer - Device protocol deframer
84 * @length: Number of bytes de-framed so far
93 * struct rave_sp_reply - Reply as per RAVE device protocol
110 * struct rave_sp_checksum - Variant specific checksum implementation details
150 * struct rave_sp_variant_cmds - Variant specific command routines
157 int (*get_status)(struct rave_sp *sp, struct rave_sp_status *);
161 * struct rave_sp_variant - RAVE supervisory processor core variant
173 * struct rave_sp - RAVE supervisory processor core
210 struct rave_sp *sp = dev_get_drvdata(dev->parent); in rave_sp_unregister_event_notifier() local
212 struct blocking_notifier_head *bnh = &sp->event_notifier_list; in rave_sp_unregister_event_notifier()
220 struct rave_sp *sp = dev_get_drvdata(dev->parent); in devm_rave_sp_register_event_notifier() local
227 return -ENOMEM; in devm_rave_sp_register_event_notifier()
229 ret = blocking_notifier_chain_register(&sp->event_notifier_list, nb); in devm_rave_sp_register_event_notifier()
244 size--; in csum_8b2c()
246 while (size--) in csum_8b2c()
257 * While the rest of the wire protocol is little-endian, in csum_ccitt()
258 * CCITT-16 CRC in RDU2 device is sent out in big-endian order. in csum_ccitt()
265 while (n--) { in stuff()
282 static int rave_sp_write(struct rave_sp *sp, const u8 *data, u8 data_size) in rave_sp_write() argument
284 const size_t checksum_length = sp->variant->checksum->length; in rave_sp_write()
291 return -ENOMEM; in rave_sp_write()
294 return -ENOMEM; in rave_sp_write()
296 sp->variant->checksum->subroutine(data, data_size, crc); in rave_sp_write()
303 length = dest - frame; in rave_sp_write()
305 print_hex_dump_debug("rave-sp tx: ", DUMP_PREFIX_NONE, in rave_sp_write()
308 return serdev_device_write(sp->serdev, frame, length, HZ); in rave_sp_write()
314 * There isn't a single rule that describes command code -> in rave_sp_reply_code()
342 int rave_sp_exec(struct rave_sp *sp, in rave_sp_exec() argument
355 command = sp->variant->cmd.translate(data[0]); in rave_sp_exec()
359 ackid = atomic_inc_return(&sp->ackid); in rave_sp_exec()
363 mutex_lock(&sp->bus_lock); in rave_sp_exec()
365 mutex_lock(&sp->reply_lock); in rave_sp_exec()
366 sp->reply = &reply; in rave_sp_exec()
367 mutex_unlock(&sp->reply_lock); in rave_sp_exec()
372 rave_sp_write(sp, data, data_size); in rave_sp_exec()
375 dev_err(&sp->serdev->dev, "Command timeout\n"); in rave_sp_exec()
376 ret = -ETIMEDOUT; in rave_sp_exec()
378 mutex_lock(&sp->reply_lock); in rave_sp_exec()
379 sp->reply = NULL; in rave_sp_exec()
380 mutex_unlock(&sp->reply_lock); in rave_sp_exec()
383 mutex_unlock(&sp->bus_lock); in rave_sp_exec()
388 static void rave_sp_receive_event(struct rave_sp *sp, in rave_sp_receive_event() argument
396 rave_sp_write(sp, cmd, sizeof(cmd)); in rave_sp_receive_event()
398 blocking_notifier_call_chain(&sp->event_notifier_list, in rave_sp_receive_event()
403 static void rave_sp_receive_reply(struct rave_sp *sp, in rave_sp_receive_reply() argument
406 struct device *dev = &sp->serdev->dev; in rave_sp_receive_reply()
408 const size_t payload_length = length - 2; in rave_sp_receive_reply()
410 mutex_lock(&sp->reply_lock); in rave_sp_receive_reply()
411 reply = sp->reply; in rave_sp_receive_reply()
414 if (reply->code == data[0] && reply->ackid == data[1] && in rave_sp_receive_reply()
415 payload_length >= reply->length) { in rave_sp_receive_reply()
417 * We are relying on memcpy(dst, src, 0) to be a no-op in rave_sp_receive_reply()
418 * when handling commands that have a no-payload reply in rave_sp_receive_reply()
420 memcpy(reply->data, &data[2], reply->length); in rave_sp_receive_reply()
421 complete(&reply->received); in rave_sp_receive_reply()
422 sp->reply = NULL; in rave_sp_receive_reply()
426 reply->code, data[0]); in rave_sp_receive_reply()
428 reply->ackid, data[1]); in rave_sp_receive_reply()
430 reply->length, payload_length); in rave_sp_receive_reply()
434 mutex_unlock(&sp->reply_lock); in rave_sp_receive_reply()
437 static void rave_sp_receive_frame(struct rave_sp *sp, in rave_sp_receive_frame() argument
441 const size_t checksum_length = sp->variant->checksum->length; in rave_sp_receive_frame()
442 const size_t payload_length = length - checksum_length; in rave_sp_receive_frame()
444 struct device *dev = &sp->serdev->dev; in rave_sp_receive_frame()
452 print_hex_dump_debug("rave-sp rx: ", DUMP_PREFIX_NONE, in rave_sp_receive_frame()
460 sp->variant->checksum->subroutine(data, payload_length, in rave_sp_receive_frame()
469 rave_sp_receive_event(sp, data, length); in rave_sp_receive_frame()
471 rave_sp_receive_reply(sp, data, length); in rave_sp_receive_frame()
477 struct device *dev = &serdev->dev; in rave_sp_receive_buf()
478 struct rave_sp *sp = dev_get_drvdata(dev); in rave_sp_receive_buf() local
479 struct rave_sp_deframer *deframer = &sp->deframer; in rave_sp_receive_buf()
486 switch (deframer->state) { in rave_sp_receive_buf()
489 deframer->state = RAVE_SP_EXPECT_DATA; in rave_sp_receive_buf()
498 rave_sp_receive_frame(sp, in rave_sp_receive_buf()
499 deframer->data, in rave_sp_receive_buf()
500 deframer->length); in rave_sp_receive_buf()
527 deframer->state = RAVE_SP_EXPECT_ESCAPED_DATA; in rave_sp_receive_buf()
540 * that we do to escaped data - collect it in in rave_sp_receive_buf()
547 if (deframer->length == sizeof(deframer->data)) { in rave_sp_receive_buf()
561 deframer->data[deframer->length++] = byte; in rave_sp_receive_buf()
567 deframer->state = RAVE_SP_EXPECT_DATA; in rave_sp_receive_buf()
584 * re-execute this handler with the remainder of the Rx bytes in rave_sp_receive_buf()
587 deframer->state = RAVE_SP_EXPECT_SOF; in rave_sp_receive_buf()
588 deframer->length = 0; in rave_sp_receive_buf()
590 return src - buf; in rave_sp_receive_buf()
599 return -EINVAL; in rave_sp_rdu1_cmd_translate()
644 return -EINVAL; in rave_sp_default_cmd_translate()
657 version->hardware, in devm_rave_sp_version()
658 le16_to_cpu(version->major), in devm_rave_sp_version()
659 version->minor, in devm_rave_sp_version()
660 version->letter[0], in devm_rave_sp_version()
661 version->letter[1]); in devm_rave_sp_version()
664 static int rave_sp_rdu1_get_status(struct rave_sp *sp, in rave_sp_rdu1_get_status() argument
672 return rave_sp_exec(sp, cmd, sizeof(cmd), status, sizeof(*status)); in rave_sp_rdu1_get_status()
675 static int rave_sp_emulated_get_status(struct rave_sp *sp, in rave_sp_emulated_get_status() argument
684 ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status->firmware_version, in rave_sp_emulated_get_status()
685 sizeof(status->firmware_version)); in rave_sp_emulated_get_status()
690 return rave_sp_exec(sp, cmd, sizeof(cmd), &status->bootloader_version, in rave_sp_emulated_get_status()
691 sizeof(status->bootloader_version)); in rave_sp_emulated_get_status()
694 static int rave_sp_get_status(struct rave_sp *sp) in rave_sp_get_status() argument
696 struct device *dev = &sp->serdev->dev; in rave_sp_get_status()
701 ret = sp->variant->cmd.get_status(sp, &status); in rave_sp_get_status()
707 return -ENOMEM; in rave_sp_get_status()
709 sp->part_number_firmware = version; in rave_sp_get_status()
713 return -ENOMEM; in rave_sp_get_status()
715 sp->part_number_bootloader = version; in rave_sp_get_status()
755 { .compatible = "zii,rave-sp-niu", .data = &rave_sp_legacy },
756 { .compatible = "zii,rave-sp-mezz", .data = &rave_sp_legacy },
757 { .compatible = "zii,rave-sp-esb", .data = &rave_sp_legacy },
758 { .compatible = "zii,rave-sp-rdu1", .data = &rave_sp_rdu1 },
759 { .compatible = "zii,rave-sp-rdu2", .data = &rave_sp_rdu2 },
770 struct device *dev = &serdev->dev; in rave_sp_probe()
772 struct rave_sp *sp; in rave_sp_probe() local
776 if (of_property_read_u32(dev->of_node, "current-speed", &baud)) { in rave_sp_probe()
778 "'current-speed' is not specified in device node\n"); in rave_sp_probe()
779 return -EINVAL; in rave_sp_probe()
782 sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL); in rave_sp_probe()
783 if (!sp) in rave_sp_probe()
784 return -ENOMEM; in rave_sp_probe()
786 sp->serdev = serdev; in rave_sp_probe()
787 dev_set_drvdata(dev, sp); in rave_sp_probe()
789 sp->variant = of_device_get_match_data(dev); in rave_sp_probe()
790 if (!sp->variant) in rave_sp_probe()
791 return -ENODEV; in rave_sp_probe()
793 mutex_init(&sp->bus_lock); in rave_sp_probe()
794 mutex_init(&sp->reply_lock); in rave_sp_probe()
795 BLOCKING_INIT_NOTIFIER_HEAD(&sp->event_notifier_list); in rave_sp_probe()
811 ret = rave_sp_get_status(sp); in rave_sp_probe()
814 sp->part_number_firmware = unknown; in rave_sp_probe()
815 sp->part_number_bootloader = unknown; in rave_sp_probe()
822 dev_info(dev, "Firmware version: %s", sp->part_number_firmware); in rave_sp_probe()
823 dev_info(dev, "Bootloader version: %s", sp->part_number_bootloader); in rave_sp_probe()
833 .name = "rave-sp",
843 MODULE_DESCRIPTION("RAVE SP core driver");