mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	The imx SC api strongly assumes that messages are composed out of
4-bytes words but some of our message structs have odd sizeofs.
This produces many oopses with CONFIG_KASAN=y.
Fix by marking with __aligned(4).
Fixes: d90bf296ae ("firmware: imx: Add support to start/stop a CPU")
Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
		
	
			
		
			
				
	
	
		
			137 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0+
 | 
						|
/*
 | 
						|
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 | 
						|
 * Copyright 2017~2018 NXP
 | 
						|
 *  Author: Dong Aisheng <aisheng.dong@nxp.com>
 | 
						|
 *
 | 
						|
 * File containing client-side RPC functions for the MISC service. These
 | 
						|
 * function are ported to clients that communicate to the SC.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/firmware/imx/svc/misc.h>
 | 
						|
 | 
						|
struct imx_sc_msg_req_misc_set_ctrl {
 | 
						|
	struct imx_sc_rpc_msg hdr;
 | 
						|
	u32 ctrl;
 | 
						|
	u32 val;
 | 
						|
	u16 resource;
 | 
						|
} __packed __aligned(4);
 | 
						|
 | 
						|
struct imx_sc_msg_req_cpu_start {
 | 
						|
	struct imx_sc_rpc_msg hdr;
 | 
						|
	u32 address_hi;
 | 
						|
	u32 address_lo;
 | 
						|
	u16 resource;
 | 
						|
	u8 enable;
 | 
						|
} __packed __aligned(4);
 | 
						|
 | 
						|
struct imx_sc_msg_req_misc_get_ctrl {
 | 
						|
	struct imx_sc_rpc_msg hdr;
 | 
						|
	u32 ctrl;
 | 
						|
	u16 resource;
 | 
						|
} __packed __aligned(4);
 | 
						|
 | 
						|
struct imx_sc_msg_resp_misc_get_ctrl {
 | 
						|
	struct imx_sc_rpc_msg hdr;
 | 
						|
	u32 val;
 | 
						|
} __packed __aligned(4);
 | 
						|
 | 
						|
/*
 | 
						|
 * This function sets a miscellaneous control value.
 | 
						|
 *
 | 
						|
 * @param[in]     ipc         IPC handle
 | 
						|
 * @param[in]     resource    resource the control is associated with
 | 
						|
 * @param[in]     ctrl        control to change
 | 
						|
 * @param[in]     val         value to apply to the control
 | 
						|
 *
 | 
						|
 * @return Returns 0 for success and < 0 for errors.
 | 
						|
 */
 | 
						|
 | 
						|
int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource,
 | 
						|
			    u8 ctrl, u32 val)
 | 
						|
{
 | 
						|
	struct imx_sc_msg_req_misc_set_ctrl msg;
 | 
						|
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
 | 
						|
 | 
						|
	hdr->ver = IMX_SC_RPC_VERSION;
 | 
						|
	hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC;
 | 
						|
	hdr->func = (uint8_t)IMX_SC_MISC_FUNC_SET_CONTROL;
 | 
						|
	hdr->size = 4;
 | 
						|
 | 
						|
	msg.ctrl = ctrl;
 | 
						|
	msg.val = val;
 | 
						|
	msg.resource = resource;
 | 
						|
 | 
						|
	return imx_scu_call_rpc(ipc, &msg, true);
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(imx_sc_misc_set_control);
 | 
						|
 | 
						|
/*
 | 
						|
 * This function gets a miscellaneous control value.
 | 
						|
 *
 | 
						|
 * @param[in]     ipc         IPC handle
 | 
						|
 * @param[in]     resource    resource the control is associated with
 | 
						|
 * @param[in]     ctrl        control to get
 | 
						|
 * @param[out]    val         pointer to return the control value
 | 
						|
 *
 | 
						|
 * @return Returns 0 for success and < 0 for errors.
 | 
						|
 */
 | 
						|
 | 
						|
int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource,
 | 
						|
			    u8 ctrl, u32 *val)
 | 
						|
{
 | 
						|
	struct imx_sc_msg_req_misc_get_ctrl msg;
 | 
						|
	struct imx_sc_msg_resp_misc_get_ctrl *resp;
 | 
						|
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
 | 
						|
	int ret;
 | 
						|
 | 
						|
	hdr->ver = IMX_SC_RPC_VERSION;
 | 
						|
	hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC;
 | 
						|
	hdr->func = (uint8_t)IMX_SC_MISC_FUNC_GET_CONTROL;
 | 
						|
	hdr->size = 3;
 | 
						|
 | 
						|
	msg.ctrl = ctrl;
 | 
						|
	msg.resource = resource;
 | 
						|
 | 
						|
	ret = imx_scu_call_rpc(ipc, &msg, true);
 | 
						|
	if (ret)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	resp = (struct imx_sc_msg_resp_misc_get_ctrl *)&msg;
 | 
						|
	if (val != NULL)
 | 
						|
		*val = resp->val;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(imx_sc_misc_get_control);
 | 
						|
 | 
						|
/*
 | 
						|
 * This function starts/stops a CPU identified by @resource
 | 
						|
 *
 | 
						|
 * @param[in]     ipc         IPC handle
 | 
						|
 * @param[in]     resource    resource the control is associated with
 | 
						|
 * @param[in]     enable      true for start, false for stop
 | 
						|
 * @param[in]     phys_addr   initial instruction address to be executed
 | 
						|
 *
 | 
						|
 * @return Returns 0 for success and < 0 for errors.
 | 
						|
 */
 | 
						|
int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource,
 | 
						|
			bool enable, u64 phys_addr)
 | 
						|
{
 | 
						|
	struct imx_sc_msg_req_cpu_start msg;
 | 
						|
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
 | 
						|
 | 
						|
	hdr->ver = IMX_SC_RPC_VERSION;
 | 
						|
	hdr->svc = IMX_SC_RPC_SVC_PM;
 | 
						|
	hdr->func = IMX_SC_PM_FUNC_CPU_START;
 | 
						|
	hdr->size = 4;
 | 
						|
 | 
						|
	msg.address_hi = phys_addr >> 32;
 | 
						|
	msg.address_lo = phys_addr;
 | 
						|
	msg.resource = resource;
 | 
						|
	msg.enable = enable;
 | 
						|
 | 
						|
	return imx_scu_call_rpc(ipc, &msg, true);
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(imx_sc_pm_cpu_start);
 |