| @@ -2479,6 +2479,348 @@ fail: · 2478 unmodified lines |
| 2479 | 2479 | return ret; |
| 2480 | 2480 | } |
| 2481 | 2481 | |
| 2482 | +/** |
| 2483 | + * ti_sci_cmd_proc_request() - Command to request a physical processor control |
| 2484 | + * @handle: Pointer to TI SCI handle |
| 2485 | + * @proc_id: Processor ID this request is for |
| 2486 | + * |
| 2487 | + * Return: 0 if all went well, else returns appropriate error value. |
| 2488 | + */ |
| 2489 | +static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, |
| 2490 | + u8 proc_id) |
| 2491 | +{ |
| 2492 | + struct ti_sci_msg_req_proc_request *req; |
| 2493 | + struct ti_sci_msg_hdr *resp; |
| 2494 | + struct ti_sci_info *info; |
| 2495 | + struct ti_sci_xfer *xfer; |
| 2496 | + struct device *dev; |
| 2497 | + int ret = 0; |
| 2498 | + |
| 2499 | + if (!handle) |
| 2500 | + return -EINVAL; |
| 2501 | + if (IS_ERR(handle)) |
| 2502 | + return PTR_ERR(handle); |
| 2503 | + |
| 2504 | + info = handle_to_ti_sci_info(handle); |
| 2505 | + dev = info->dev; |
| 2506 | + |
| 2507 | + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_REQUEST, |
| 2508 | + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, |
| 2509 | + sizeof(*req), sizeof(*resp)); |
| 2510 | + if (IS_ERR(xfer)) { |
| 2511 | + ret = PTR_ERR(xfer); |
| 2512 | + dev_err(dev, "Message alloc failed(%d)\n", ret); |
| 2513 | + return ret; |
| 2514 | + } |
| 2515 | + req = (struct ti_sci_msg_req_proc_request *)xfer->xfer_buf; |
| 2516 | + req->processor_id = proc_id; |
| 2517 | + |
| 2518 | + ret = ti_sci_do_xfer(info, xfer); |
| 2519 | + if (ret) { |
| 2520 | + dev_err(dev, "Mbox send fail %d\n", ret); |
| 2521 | + goto fail; |
| 2522 | + } |
| 2523 | + |
| 2524 | + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; |
| 2525 | + |
| 2526 | + ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; |
| 2527 | + |
| 2528 | +fail: |
| 2529 | + ti_sci_put_one_xfer(&info->minfo, xfer); |
| 2530 | + |
| 2531 | + return ret; |
| 2532 | +} |
| 2533 | + |
| 2534 | +/** |
| 2535 | + * ti_sci_cmd_proc_release() - Command to release a physical processor control |
| 2536 | + * @handle: Pointer to TI SCI handle |
| 2537 | + * @proc_id: Processor ID this request is for |
| 2538 | + * |
| 2539 | + * Return: 0 if all went well, else returns appropriate error value. |
| 2540 | + */ |
| 2541 | +static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, |
| 2542 | + u8 proc_id) |
| 2543 | +{ |
| 2544 | + struct ti_sci_msg_req_proc_release *req; |
| 2545 | + struct ti_sci_msg_hdr *resp; |
| 2546 | + struct ti_sci_info *info; |
| 2547 | + struct ti_sci_xfer *xfer; |
| 2548 | + struct device *dev; |
| 2549 | + int ret = 0; |
| 2550 | + |
| 2551 | + if (!handle) |
| 2552 | + return -EINVAL; |
| 2553 | + if (IS_ERR(handle)) |
| 2554 | + return PTR_ERR(handle); |
| 2555 | + |
| 2556 | + info = handle_to_ti_sci_info(handle); |
| 2557 | + dev = info->dev; |
| 2558 | + |
| 2559 | + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_RELEASE, |
| 2560 | + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, |
| 2561 | + sizeof(*req), sizeof(*resp)); |
| 2562 | + if (IS_ERR(xfer)) { |
| 2563 | + ret = PTR_ERR(xfer); |
| 2564 | + dev_err(dev, "Message alloc failed(%d)\n", ret); |
| 2565 | + return ret; |
| 2566 | + } |
| 2567 | + req = (struct ti_sci_msg_req_proc_release *)xfer->xfer_buf; |
| 2568 | + req->processor_id = proc_id; |
| 2569 | + |
| 2570 | + ret = ti_sci_do_xfer(info, xfer); |
| 2571 | + if (ret) { |
| 2572 | + dev_err(dev, "Mbox send fail %d\n", ret); |
| 2573 | + goto fail; |
| 2574 | + } |
| 2575 | + |
| 2576 | + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; |
| 2577 | + |
| 2578 | + ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; |
| 2579 | + |
| 2580 | +fail: |
| 2581 | + ti_sci_put_one_xfer(&info->minfo, xfer); |
| 2582 | + |
| 2583 | + return ret; |
| 2584 | +} |
| 2585 | + |
| 2586 | +/** |
| 2587 | + * ti_sci_cmd_proc_handover() - Command to handover a physical processor |
| 2588 | + * control to a host in the processor's access |
| 2589 | + * control list. |
| 2590 | + * @handle: Pointer to TI SCI handle |
| 2591 | + * @proc_id: Processor ID this request is for |
| 2592 | + * @host_id: Host ID to get the control of the processor |
| 2593 | + * |
| 2594 | + * Return: 0 if all went well, else returns appropriate error value. |
| 2595 | + */ |
| 2596 | +static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, |
| 2597 | + u8 proc_id, u8 host_id) |
| 2598 | +{ |
| 2599 | + struct ti_sci_msg_req_proc_handover *req; |
| 2600 | + struct ti_sci_msg_hdr *resp; |
| 2601 | + struct ti_sci_info *info; |
| 2602 | + struct ti_sci_xfer *xfer; |
| 2603 | + struct device *dev; |
| 2604 | + int ret = 0; |
| 2605 | + |
| 2606 | + if (!handle) |
| 2607 | + return -EINVAL; |
| 2608 | + if (IS_ERR(handle)) |
| 2609 | + return PTR_ERR(handle); |
| 2610 | + |
| 2611 | + info = handle_to_ti_sci_info(handle); |
| 2612 | + dev = info->dev; |
| 2613 | + |
| 2614 | + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_HANDOVER, |
| 2615 | + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, |
| 2616 | + sizeof(*req), sizeof(*resp)); |
| 2617 | + if (IS_ERR(xfer)) { |
| 2618 | + ret = PTR_ERR(xfer); |
| 2619 | + dev_err(dev, "Message alloc failed(%d)\n", ret); |
| 2620 | + return ret; |
| 2621 | + } |
| 2622 | + req = (struct ti_sci_msg_req_proc_handover *)xfer->xfer_buf; |
| 2623 | + req->processor_id = proc_id; |
| 2624 | + req->host_id = host_id; |
| 2625 | + |
| 2626 | + ret = ti_sci_do_xfer(info, xfer); |
| 2627 | + if (ret) { |
| 2628 | + dev_err(dev, "Mbox send fail %d\n", ret); |
| 2629 | + goto fail; |
| 2630 | + } |
| 2631 | + |
| 2632 | + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; |
| 2633 | + |
| 2634 | + ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; |
| 2635 | + |
| 2636 | +fail: |
| 2637 | + ti_sci_put_one_xfer(&info->minfo, xfer); |
| 2638 | + |
| 2639 | + return ret; |
| 2640 | +} |
| 2641 | + |
| 2642 | +/** |
| 2643 | + * ti_sci_cmd_proc_set_config() - Command to set the processor boot |
| 2644 | + * configuration flags |
| 2645 | + * @handle: Pointer to TI SCI handle |
| 2646 | + * @proc_id: Processor ID this request is for |
| 2647 | + * @config_flags_set: Configuration flags to be set |
| 2648 | + * @config_flags_clear: Configuration flags to be cleared. |
| 2649 | + * |
| 2650 | + * Return: 0 if all went well, else returns appropriate error value. |
| 2651 | + */ |
| 2652 | +static int ti_sci_cmd_proc_set_config(const struct ti_sci_handle *handle, |
| 2653 | + u8 proc_id, u64 bootvector, |
| 2654 | + u32 config_flags_set, |
| 2655 | + u32 config_flags_clear) |
| 2656 | +{ |
| 2657 | + struct ti_sci_msg_req_set_config *req; |
| 2658 | + struct ti_sci_msg_hdr *resp; |
| 2659 | + struct ti_sci_info *info; |
| 2660 | + struct ti_sci_xfer *xfer; |
| 2661 | + struct device *dev; |
| 2662 | + int ret = 0; |
| 2663 | + |
| 2664 | + if (!handle) |
| 2665 | + return -EINVAL; |
| 2666 | + if (IS_ERR(handle)) |
| 2667 | + return PTR_ERR(handle); |
| 2668 | + |
| 2669 | + info = handle_to_ti_sci_info(handle); |
| 2670 | + dev = info->dev; |
| 2671 | + |
| 2672 | + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CONFIG, |
| 2673 | + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, |
| 2674 | + sizeof(*req), sizeof(*resp)); |
| 2675 | + if (IS_ERR(xfer)) { |
| 2676 | + ret = PTR_ERR(xfer); |
| 2677 | + dev_err(dev, "Message alloc failed(%d)\n", ret); |
| 2678 | + return ret; |
| 2679 | + } |
| 2680 | + req = (struct ti_sci_msg_req_set_config *)xfer->xfer_buf; |
| 2681 | + req->processor_id = proc_id; |
| 2682 | + req->bootvector_low = bootvector & TI_SCI_ADDR_LOW_MASK; |
| 2683 | + req->bootvector_high = (bootvector & TI_SCI_ADDR_HIGH_MASK) >> |
| 2684 | + TI_SCI_ADDR_HIGH_SHIFT; |
| 2685 | + req->config_flags_set = config_flags_set; |
| 2686 | + req->config_flags_clear = config_flags_clear; |
| 2687 | + |
| 2688 | + ret = ti_sci_do_xfer(info, xfer); |
| 2689 | + if (ret) { |
| 2690 | + dev_err(dev, "Mbox send fail %d\n", ret); |
| 2691 | + goto fail; |
| 2692 | + } |
| 2693 | + |
| 2694 | + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; |
| 2695 | + |
| 2696 | + ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; |
| 2697 | + |
| 2698 | +fail: |
| 2699 | + ti_sci_put_one_xfer(&info->minfo, xfer); |
| 2700 | + |
| 2701 | + return ret; |
| 2702 | +} |
| 2703 | + |
| 2704 | +/** |
| 2705 | + * ti_sci_cmd_proc_set_control() - Command to set the processor boot |
| 2706 | + * control flags |
| 2707 | + * @handle: Pointer to TI SCI handle |
| 2708 | + * @proc_id: Processor ID this request is for |
| 2709 | + * @control_flags_set: Control flags to be set |
| 2710 | + * @control_flags_clear: Control flags to be cleared |
| 2711 | + * |
| 2712 | + * Return: 0 if all went well, else returns appropriate error value. |
| 2713 | + */ |
| 2714 | +static int ti_sci_cmd_proc_set_control(const struct ti_sci_handle *handle, |
| 2715 | + u8 proc_id, u32 control_flags_set, |
| 2716 | + u32 control_flags_clear) |
| 2717 | +{ |
| 2718 | + struct ti_sci_msg_req_set_ctrl *req; |
| 2719 | + struct ti_sci_msg_hdr *resp; |
| 2720 | + struct ti_sci_info *info; |
| 2721 | + struct ti_sci_xfer *xfer; |
| 2722 | + struct device *dev; |
| 2723 | + int ret = 0; |
| 2724 | + |
| 2725 | + if (!handle) |
| 2726 | + return -EINVAL; |
| 2727 | + if (IS_ERR(handle)) |
| 2728 | + return PTR_ERR(handle); |
| 2729 | + |
| 2730 | + info = handle_to_ti_sci_info(handle); |
| 2731 | + dev = info->dev; |
| 2732 | + |
| 2733 | + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CTRL, |
| 2734 | + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, |
| 2735 | + sizeof(*req), sizeof(*resp)); |
| 2736 | + if (IS_ERR(xfer)) { |
| 2737 | + ret = PTR_ERR(xfer); |
| 2738 | + dev_err(dev, "Message alloc failed(%d)\n", ret); |
| 2739 | + return ret; |
| 2740 | + } |
| 2741 | + req = (struct ti_sci_msg_req_set_ctrl *)xfer->xfer_buf; |
| 2742 | + req->processor_id = proc_id; |
| 2743 | + req->control_flags_set = control_flags_set; |
| 2744 | + req->control_flags_clear = control_flags_clear; |
| 2745 | + |
| 2746 | + ret = ti_sci_do_xfer(info, xfer); |
| 2747 | + if (ret) { |
| 2748 | + dev_err(dev, "Mbox send fail %d\n", ret); |
| 2749 | + goto fail; |
| 2750 | + } |
| 2751 | + |
| 2752 | + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; |
| 2753 | + |
| 2754 | + ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; |
| 2755 | + |
| 2756 | +fail: |
| 2757 | + ti_sci_put_one_xfer(&info->minfo, xfer); |
| 2758 | + |
| 2759 | + return ret; |
| 2760 | +} |
| 2761 | + |
| 2762 | +/** |
| 2763 | + * ti_sci_cmd_get_boot_status() - Command to get the processor boot status |
| 2764 | + * @handle: Pointer to TI SCI handle |
| 2765 | + * @proc_id: Processor ID this request is for |
| 2766 | + * |
| 2767 | + * Return: 0 if all went well, else returns appropriate error value. |
| 2768 | + */ |
| 2769 | +static int ti_sci_cmd_proc_get_status(const struct ti_sci_handle *handle, |
| 2770 | + u8 proc_id, u64 *bv, u32 *cfg_flags, |
| 2771 | + u32 *ctrl_flags, u32 *sts_flags) |
| 2772 | +{ |
| 2773 | + struct ti_sci_msg_resp_get_status *resp; |
| 2774 | + struct ti_sci_msg_req_get_status *req; |
| 2775 | + struct ti_sci_info *info; |
| 2776 | + struct ti_sci_xfer *xfer; |
| 2777 | + struct device *dev; |
| 2778 | + int ret = 0; |
| 2779 | + |
| 2780 | + if (!handle) |
| 2781 | + return -EINVAL; |
| 2782 | + if (IS_ERR(handle)) |
| 2783 | + return PTR_ERR(handle); |
| 2784 | + |
| 2785 | + info = handle_to_ti_sci_info(handle); |
| 2786 | + dev = info->dev; |
| 2787 | + |
| 2788 | + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_STATUS, |
| 2789 | + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, |
| 2790 | + sizeof(*req), sizeof(*resp)); |
| 2791 | + if (IS_ERR(xfer)) { |
| 2792 | + ret = PTR_ERR(xfer); |
| 2793 | + dev_err(dev, "Message alloc failed(%d)\n", ret); |
| 2794 | + return ret; |
| 2795 | + } |
| 2796 | + req = (struct ti_sci_msg_req_get_status *)xfer->xfer_buf; |
| 2797 | + req->processor_id = proc_id; |
| 2798 | + |
| 2799 | + ret = ti_sci_do_xfer(info, xfer); |
| 2800 | + if (ret) { |
| 2801 | + dev_err(dev, "Mbox send fail %d\n", ret); |
| 2802 | + goto fail; |
| 2803 | + } |
| 2804 | + |
| 2805 | + resp = (struct ti_sci_msg_resp_get_status *)xfer->tx_message.buf; |
| 2806 | + |
| 2807 | + if (!ti_sci_is_response_ack(resp)) { |
| 2808 | + ret = -ENODEV; |
| 2809 | + } else { |
| 2810 | + *bv = (resp->bootvector_low & TI_SCI_ADDR_LOW_MASK) | |
| 2811 | + (((u64)resp->bootvector_high << TI_SCI_ADDR_HIGH_SHIFT) & |
| 2812 | + TI_SCI_ADDR_HIGH_MASK); |
| 2813 | + *cfg_flags = resp->config_flags; |
| 2814 | + *ctrl_flags = resp->control_flags; |
| 2815 | + *sts_flags = resp->status_flags; |
| 2816 | + } |
| 2817 | + |
| 2818 | +fail: |
| 2819 | + ti_sci_put_one_xfer(&info->minfo, xfer); |
| 2820 | + |
| 2821 | + return ret; |
| 2822 | +} |
| 2823 | + |
| 2482 | 2824 | /* |
| 2483 | 2825 | * ti_sci_setup_ops() - Setup the operations structures |
| 2484 | 2826 | * @info: pointer to TISCI pointer |
| @@ -2494,6 +2836,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) · 9 unmodified lines |
| 2494 | 2836 | struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops; |
| 2495 | 2837 | struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops; |
| 2496 | 2838 | struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops; |
| 2839 | + struct ti_sci_proc_ops *pops = &ops->proc_ops; |
| 2497 | 2840 | |
| 2498 | 2841 | core_ops->reboot_device = ti_sci_cmd_core_reboot; |
| 2499 | 2842 | |
| @@ -2543,6 +2886,13 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) · 43 unmodified lines |
| 2543 | 2886 | udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg; |
| 2544 | 2887 | udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg; |
| 2545 | 2888 | udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg; |
| 2889 | + |
| 2890 | + pops->request = ti_sci_cmd_proc_request; |
| 2891 | + pops->release = ti_sci_cmd_proc_release; |
| 2892 | + pops->handover = ti_sci_cmd_proc_handover; |
| 2893 | + pops->set_config = ti_sci_cmd_proc_set_config; |
| 2894 | + pops->set_control = ti_sci_cmd_proc_set_control; |
| 2895 | + pops->get_status = ti_sci_cmd_proc_get_status; |
| 2546 | 2896 | } |
| 2547 | 2897 | |
| 2548 | 2898 | /** |