xref: /linux/drivers/net/wwan/iosm/iosm_ipc_devlink.c (revision 8bea96efa7c0c57dc0c9ec4518ed61e3d5e9261c)
14dcd183fSM Chetan Kumar // SPDX-License-Identifier: GPL-2.0-only
24dcd183fSM Chetan Kumar /*
34dcd183fSM Chetan Kumar  * Copyright (C) 2020-2021 Intel Corporation.
44dcd183fSM Chetan Kumar  */
54dcd183fSM Chetan Kumar 
64dcd183fSM Chetan Kumar #include "iosm_ipc_chnl_cfg.h"
74dcd183fSM Chetan Kumar #include "iosm_ipc_coredump.h"
84dcd183fSM Chetan Kumar #include "iosm_ipc_devlink.h"
94dcd183fSM Chetan Kumar #include "iosm_ipc_flash.h"
104dcd183fSM Chetan Kumar 
114dcd183fSM Chetan Kumar /* Coredump list */
124dcd183fSM Chetan Kumar static struct iosm_coredump_file_info list[IOSM_NOF_CD_REGION] = {
134dcd183fSM Chetan Kumar 	{"report.json", REPORT_JSON_SIZE,},
144dcd183fSM Chetan Kumar 	{"coredump.fcd", COREDUMP_FCD_SIZE,},
154dcd183fSM Chetan Kumar 	{"cdd.log", CDD_LOG_SIZE,},
164dcd183fSM Chetan Kumar 	{"eeprom.bin", EEPROM_BIN_SIZE,},
174dcd183fSM Chetan Kumar 	{"bootcore_trace.bin", BOOTCORE_TRC_BIN_SIZE,},
184dcd183fSM Chetan Kumar 	{"bootcore_prev_trace.bin", BOOTCORE_PREV_TRC_BIN_SIZE,},
194dcd183fSM Chetan Kumar };
204dcd183fSM Chetan Kumar 
214dcd183fSM Chetan Kumar /* Get the param values for the specific param ID's */
224dcd183fSM Chetan Kumar static int ipc_devlink_get_param(struct devlink *dl, u32 id,
234dcd183fSM Chetan Kumar 				 struct devlink_param_gset_ctx *ctx)
244dcd183fSM Chetan Kumar {
254dcd183fSM Chetan Kumar 	struct iosm_devlink *ipc_devlink = devlink_priv(dl);
264dcd183fSM Chetan Kumar 	int rc = 0;
274dcd183fSM Chetan Kumar 
284dcd183fSM Chetan Kumar 	switch (id) {
294dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH:
304dcd183fSM Chetan Kumar 		ctx->val.vu8 = ipc_devlink->param.erase_full_flash;
314dcd183fSM Chetan Kumar 		break;
324dcd183fSM Chetan Kumar 
334dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION:
344dcd183fSM Chetan Kumar 		ctx->val.vu8 = ipc_devlink->param.download_region;
354dcd183fSM Chetan Kumar 		break;
364dcd183fSM Chetan Kumar 
374dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_ADDRESS:
384dcd183fSM Chetan Kumar 		ctx->val.vu32 = ipc_devlink->param.address;
394dcd183fSM Chetan Kumar 		break;
404dcd183fSM Chetan Kumar 
414dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_REGION_COUNT:
424dcd183fSM Chetan Kumar 		ctx->val.vu8 = ipc_devlink->param.region_count;
434dcd183fSM Chetan Kumar 		break;
444dcd183fSM Chetan Kumar 
454dcd183fSM Chetan Kumar 	default:
464dcd183fSM Chetan Kumar 		rc = -EOPNOTSUPP;
474dcd183fSM Chetan Kumar 		break;
484dcd183fSM Chetan Kumar 	}
494dcd183fSM Chetan Kumar 
504dcd183fSM Chetan Kumar 	return rc;
514dcd183fSM Chetan Kumar }
524dcd183fSM Chetan Kumar 
534dcd183fSM Chetan Kumar /* Set the param values for the specific param ID's */
544dcd183fSM Chetan Kumar static int ipc_devlink_set_param(struct devlink *dl, u32 id,
554dcd183fSM Chetan Kumar 				 struct devlink_param_gset_ctx *ctx)
564dcd183fSM Chetan Kumar {
574dcd183fSM Chetan Kumar 	struct iosm_devlink *ipc_devlink = devlink_priv(dl);
584dcd183fSM Chetan Kumar 	int rc = 0;
594dcd183fSM Chetan Kumar 
604dcd183fSM Chetan Kumar 	switch (id) {
614dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH:
624dcd183fSM Chetan Kumar 		ipc_devlink->param.erase_full_flash = ctx->val.vu8;
634dcd183fSM Chetan Kumar 		break;
644dcd183fSM Chetan Kumar 
654dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION:
664dcd183fSM Chetan Kumar 		ipc_devlink->param.download_region = ctx->val.vu8;
674dcd183fSM Chetan Kumar 		break;
684dcd183fSM Chetan Kumar 
694dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_ADDRESS:
704dcd183fSM Chetan Kumar 		ipc_devlink->param.address = ctx->val.vu32;
714dcd183fSM Chetan Kumar 		break;
724dcd183fSM Chetan Kumar 
734dcd183fSM Chetan Kumar 	case IOSM_DEVLINK_PARAM_ID_REGION_COUNT:
744dcd183fSM Chetan Kumar 		ipc_devlink->param.region_count = ctx->val.vu8;
754dcd183fSM Chetan Kumar 		break;
764dcd183fSM Chetan Kumar 
774dcd183fSM Chetan Kumar 	default:
784dcd183fSM Chetan Kumar 		rc = -EOPNOTSUPP;
794dcd183fSM Chetan Kumar 		break;
804dcd183fSM Chetan Kumar 	}
814dcd183fSM Chetan Kumar 
824dcd183fSM Chetan Kumar 	return rc;
834dcd183fSM Chetan Kumar }
844dcd183fSM Chetan Kumar 
854dcd183fSM Chetan Kumar /* Devlink param structure array */
864dcd183fSM Chetan Kumar static const struct devlink_param iosm_devlink_params[] = {
874dcd183fSM Chetan Kumar 	DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH,
884dcd183fSM Chetan Kumar 			     "erase_full_flash", DEVLINK_PARAM_TYPE_BOOL,
894dcd183fSM Chetan Kumar 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
904dcd183fSM Chetan Kumar 			     ipc_devlink_get_param, ipc_devlink_set_param,
914dcd183fSM Chetan Kumar 			     NULL),
924dcd183fSM Chetan Kumar 	DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION,
934dcd183fSM Chetan Kumar 			     "download_region", DEVLINK_PARAM_TYPE_BOOL,
944dcd183fSM Chetan Kumar 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
954dcd183fSM Chetan Kumar 			     ipc_devlink_get_param, ipc_devlink_set_param,
964dcd183fSM Chetan Kumar 			     NULL),
974dcd183fSM Chetan Kumar 	DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_ADDRESS,
984dcd183fSM Chetan Kumar 			     "address", DEVLINK_PARAM_TYPE_U32,
994dcd183fSM Chetan Kumar 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1004dcd183fSM Chetan Kumar 			     ipc_devlink_get_param, ipc_devlink_set_param,
1014dcd183fSM Chetan Kumar 			     NULL),
1024dcd183fSM Chetan Kumar 	DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_REGION_COUNT,
1034dcd183fSM Chetan Kumar 			     "region_count", DEVLINK_PARAM_TYPE_U8,
1044dcd183fSM Chetan Kumar 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1054dcd183fSM Chetan Kumar 			     ipc_devlink_get_param, ipc_devlink_set_param,
1064dcd183fSM Chetan Kumar 			     NULL),
1074dcd183fSM Chetan Kumar };
1084dcd183fSM Chetan Kumar 
1094dcd183fSM Chetan Kumar /* Get devlink flash component type */
1104dcd183fSM Chetan Kumar static enum iosm_flash_comp_type
1114dcd183fSM Chetan Kumar ipc_devlink_get_flash_comp_type(const char comp_str[], u32 len)
1124dcd183fSM Chetan Kumar {
1134dcd183fSM Chetan Kumar 	enum iosm_flash_comp_type fls_type;
1144dcd183fSM Chetan Kumar 
1154dcd183fSM Chetan Kumar 	if (!strncmp("PSI", comp_str, len))
1164dcd183fSM Chetan Kumar 		fls_type = FLASH_COMP_TYPE_PSI;
1174dcd183fSM Chetan Kumar 	else if (!strncmp("EBL", comp_str, len))
1184dcd183fSM Chetan Kumar 		fls_type = FLASH_COMP_TYPE_EBL;
1194dcd183fSM Chetan Kumar 	else if (!strncmp("FLS", comp_str, len))
1204dcd183fSM Chetan Kumar 		fls_type = FLASH_COMP_TYPE_FLS;
1214dcd183fSM Chetan Kumar 	else
1224dcd183fSM Chetan Kumar 		fls_type = FLASH_COMP_TYPE_INVAL;
1234dcd183fSM Chetan Kumar 
1244dcd183fSM Chetan Kumar 	return fls_type;
1254dcd183fSM Chetan Kumar }
1264dcd183fSM Chetan Kumar 
1274dcd183fSM Chetan Kumar /* Function triggered on devlink flash command
1284dcd183fSM Chetan Kumar  * Flash update function which calls multiple functions based on
1294dcd183fSM Chetan Kumar  * component type specified in the flash command
1304dcd183fSM Chetan Kumar  */
1314dcd183fSM Chetan Kumar static int ipc_devlink_flash_update(struct devlink *devlink,
1324dcd183fSM Chetan Kumar 				    struct devlink_flash_update_params *params,
1334dcd183fSM Chetan Kumar 				    struct netlink_ext_ack *extack)
1344dcd183fSM Chetan Kumar {
1354dcd183fSM Chetan Kumar 	struct iosm_devlink *ipc_devlink = devlink_priv(devlink);
1364dcd183fSM Chetan Kumar 	enum iosm_flash_comp_type fls_type;
137*8bea96efSM Chetan Kumar 	int rc = -EINVAL;
1384dcd183fSM Chetan Kumar 	u8 *mdm_rsp;
1394dcd183fSM Chetan Kumar 
1404dcd183fSM Chetan Kumar 	if (!params->component)
141*8bea96efSM Chetan Kumar 		return -EINVAL;
1424dcd183fSM Chetan Kumar 
1434dcd183fSM Chetan Kumar 	mdm_rsp = kzalloc(IOSM_EBL_DW_PACK_SIZE, GFP_KERNEL);
1444dcd183fSM Chetan Kumar 	if (!mdm_rsp)
1454dcd183fSM Chetan Kumar 		return -ENOMEM;
1464dcd183fSM Chetan Kumar 
1474dcd183fSM Chetan Kumar 	fls_type = ipc_devlink_get_flash_comp_type(params->component,
1484dcd183fSM Chetan Kumar 						   strlen(params->component));
1494dcd183fSM Chetan Kumar 
1504dcd183fSM Chetan Kumar 	switch (fls_type) {
1514dcd183fSM Chetan Kumar 	case FLASH_COMP_TYPE_PSI:
1524dcd183fSM Chetan Kumar 		rc = ipc_flash_boot_psi(ipc_devlink, params->fw);
1534dcd183fSM Chetan Kumar 		break;
1544dcd183fSM Chetan Kumar 	case FLASH_COMP_TYPE_EBL:
1554dcd183fSM Chetan Kumar 		rc = ipc_flash_boot_ebl(ipc_devlink, params->fw);
156*8bea96efSM Chetan Kumar 		if (rc)
157*8bea96efSM Chetan Kumar 			break;
158*8bea96efSM Chetan Kumar 		rc = ipc_flash_boot_set_capabilities(ipc_devlink, mdm_rsp);
159*8bea96efSM Chetan Kumar 		if (rc)
160*8bea96efSM Chetan Kumar 			break;
1614dcd183fSM Chetan Kumar 		rc = ipc_flash_read_swid(ipc_devlink, mdm_rsp);
1624dcd183fSM Chetan Kumar 		break;
1634dcd183fSM Chetan Kumar 	case FLASH_COMP_TYPE_FLS:
1644dcd183fSM Chetan Kumar 		rc = ipc_flash_send_fls(ipc_devlink, params->fw, mdm_rsp);
1654dcd183fSM Chetan Kumar 		break;
1664dcd183fSM Chetan Kumar 	default:
1674dcd183fSM Chetan Kumar 		devlink_flash_update_status_notify(devlink, "Invalid component",
1684dcd183fSM Chetan Kumar 						   params->component, 0, 0);
1694dcd183fSM Chetan Kumar 		break;
1704dcd183fSM Chetan Kumar 	}
1714dcd183fSM Chetan Kumar 
1724dcd183fSM Chetan Kumar 	if (!rc)
1734dcd183fSM Chetan Kumar 		devlink_flash_update_status_notify(devlink, "Flashing success",
1744dcd183fSM Chetan Kumar 						   params->component, 0, 0);
1754dcd183fSM Chetan Kumar 	else
1764dcd183fSM Chetan Kumar 		devlink_flash_update_status_notify(devlink, "Flashing failed",
1774dcd183fSM Chetan Kumar 						   params->component, 0, 0);
1784dcd183fSM Chetan Kumar 
1794dcd183fSM Chetan Kumar 	kfree(mdm_rsp);
1804dcd183fSM Chetan Kumar 	return rc;
1814dcd183fSM Chetan Kumar }
1824dcd183fSM Chetan Kumar 
1834dcd183fSM Chetan Kumar /* Call back function for devlink ops */
1844dcd183fSM Chetan Kumar static const struct devlink_ops devlink_flash_ops = {
1854dcd183fSM Chetan Kumar 	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT,
1864dcd183fSM Chetan Kumar 	.flash_update = ipc_devlink_flash_update,
1874dcd183fSM Chetan Kumar };
1884dcd183fSM Chetan Kumar 
189*8bea96efSM Chetan Kumar /**
190*8bea96efSM Chetan Kumar  * ipc_devlink_send_cmd - Send command to Modem
191*8bea96efSM Chetan Kumar  * @ipc_devlink: Pointer to struct iosm_devlink
192*8bea96efSM Chetan Kumar  * @cmd:         Command to be sent to modem
193*8bea96efSM Chetan Kumar  * @entry:       Command entry number
194*8bea96efSM Chetan Kumar  *
195*8bea96efSM Chetan Kumar  * Returns:      0 on success and failure value on error
196*8bea96efSM Chetan Kumar  */
1974dcd183fSM Chetan Kumar int ipc_devlink_send_cmd(struct iosm_devlink *ipc_devlink, u16 cmd, u32 entry)
1984dcd183fSM Chetan Kumar {
1994dcd183fSM Chetan Kumar 	struct iosm_rpsi_cmd rpsi_cmd;
2004dcd183fSM Chetan Kumar 
2014dcd183fSM Chetan Kumar 	rpsi_cmd.param.dword = cpu_to_le32(entry);
2024dcd183fSM Chetan Kumar 	rpsi_cmd.cmd = cpu_to_le16(cmd);
2034dcd183fSM Chetan Kumar 	rpsi_cmd.crc = rpsi_cmd.param.word[0] ^ rpsi_cmd.param.word[1] ^
2044dcd183fSM Chetan Kumar 		       rpsi_cmd.cmd;
2054dcd183fSM Chetan Kumar 
2064dcd183fSM Chetan Kumar 	return ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&rpsi_cmd,
2074dcd183fSM Chetan Kumar 					  sizeof(rpsi_cmd));
2084dcd183fSM Chetan Kumar }
2094dcd183fSM Chetan Kumar 
210*8bea96efSM Chetan Kumar /* Function to create snapshot */
2114dcd183fSM Chetan Kumar static int ipc_devlink_coredump_snapshot(struct devlink *dl,
2124dcd183fSM Chetan Kumar 					 const struct devlink_region_ops *ops,
2134dcd183fSM Chetan Kumar 					 struct netlink_ext_ack *extack,
2144dcd183fSM Chetan Kumar 					 u8 **data)
2154dcd183fSM Chetan Kumar {
2164dcd183fSM Chetan Kumar 	struct iosm_devlink *ipc_devlink = devlink_priv(dl);
2174dcd183fSM Chetan Kumar 	struct iosm_coredump_file_info *cd_list = ops->priv;
2184dcd183fSM Chetan Kumar 	u32 region_size;
2194dcd183fSM Chetan Kumar 	int rc;
2204dcd183fSM Chetan Kumar 
2214dcd183fSM Chetan Kumar 	dev_dbg(ipc_devlink->dev, "Region:%s, ID:%d", ops->name,
2224dcd183fSM Chetan Kumar 		cd_list->entry);
2234dcd183fSM Chetan Kumar 	region_size = cd_list->default_size;
2244dcd183fSM Chetan Kumar 	rc = ipc_coredump_collect(ipc_devlink, data, cd_list->entry,
2254dcd183fSM Chetan Kumar 				  region_size);
2264dcd183fSM Chetan Kumar 	if (rc) {
2274dcd183fSM Chetan Kumar 		dev_err(ipc_devlink->dev, "Fail to create snapshot,err %d", rc);
2284dcd183fSM Chetan Kumar 		goto coredump_collect_err;
2294dcd183fSM Chetan Kumar 	}
2304dcd183fSM Chetan Kumar 
2314dcd183fSM Chetan Kumar 	/* Send coredump end cmd indicating end of coredump collection */
2324dcd183fSM Chetan Kumar 	if (cd_list->entry == (IOSM_NOF_CD_REGION - 1))
2334dcd183fSM Chetan Kumar 		ipc_coredump_get_list(ipc_devlink, rpsi_cmd_coredump_end);
2344dcd183fSM Chetan Kumar 
235*8bea96efSM Chetan Kumar 	return 0;
236*8bea96efSM Chetan Kumar 
2374dcd183fSM Chetan Kumar coredump_collect_err:
2384dcd183fSM Chetan Kumar 	ipc_coredump_get_list(ipc_devlink, rpsi_cmd_coredump_end);
2394dcd183fSM Chetan Kumar 	return rc;
2404dcd183fSM Chetan Kumar }
2414dcd183fSM Chetan Kumar 
2424dcd183fSM Chetan Kumar /* To create regions for coredump files */
2434dcd183fSM Chetan Kumar static int ipc_devlink_create_region(struct iosm_devlink *devlink)
2444dcd183fSM Chetan Kumar {
2454dcd183fSM Chetan Kumar 	struct devlink_region_ops *mdm_coredump;
2464dcd183fSM Chetan Kumar 	int rc = 0;
2474dcd183fSM Chetan Kumar 	int i;
2484dcd183fSM Chetan Kumar 
2494dcd183fSM Chetan Kumar 	mdm_coredump = devlink->iosm_devlink_mdm_coredump;
2504dcd183fSM Chetan Kumar 	for (i = 0; i < IOSM_NOF_CD_REGION; i++) {
2514dcd183fSM Chetan Kumar 		mdm_coredump[i].name = list[i].filename;
2524dcd183fSM Chetan Kumar 		mdm_coredump[i].snapshot = ipc_devlink_coredump_snapshot;
2534dcd183fSM Chetan Kumar 		mdm_coredump[i].destructor = vfree;
2544dcd183fSM Chetan Kumar 		devlink->cd_regions[i] =
2554dcd183fSM Chetan Kumar 			devlink_region_create(devlink->devlink_ctx,
2564dcd183fSM Chetan Kumar 					      &mdm_coredump[i], MAX_SNAPSHOTS,
2574dcd183fSM Chetan Kumar 					      list[i].default_size);
2584dcd183fSM Chetan Kumar 
2594dcd183fSM Chetan Kumar 		if (IS_ERR(devlink->cd_regions[i])) {
2604dcd183fSM Chetan Kumar 			rc = PTR_ERR(devlink->cd_regions[i]);
2614dcd183fSM Chetan Kumar 			dev_err(devlink->dev, "Devlink region fail,err %d", rc);
2624dcd183fSM Chetan Kumar 			/* Delete previously created regions */
2634dcd183fSM Chetan Kumar 			for ( ; i >= 0; i--)
2644dcd183fSM Chetan Kumar 				devlink_region_destroy(devlink->cd_regions[i]);
2654dcd183fSM Chetan Kumar 			goto region_create_fail;
2664dcd183fSM Chetan Kumar 		}
2674dcd183fSM Chetan Kumar 		list[i].entry = i;
2684dcd183fSM Chetan Kumar 		mdm_coredump[i].priv = list + i;
2694dcd183fSM Chetan Kumar 	}
2704dcd183fSM Chetan Kumar region_create_fail:
2714dcd183fSM Chetan Kumar 	return rc;
2724dcd183fSM Chetan Kumar }
2734dcd183fSM Chetan Kumar 
2744dcd183fSM Chetan Kumar /* To Destroy devlink regions */
2754dcd183fSM Chetan Kumar static void ipc_devlink_destroy_region(struct iosm_devlink *ipc_devlink)
2764dcd183fSM Chetan Kumar {
2774dcd183fSM Chetan Kumar 	u8 i;
2784dcd183fSM Chetan Kumar 
2794dcd183fSM Chetan Kumar 	for (i = 0; i < IOSM_NOF_CD_REGION; i++)
2804dcd183fSM Chetan Kumar 		devlink_region_destroy(ipc_devlink->cd_regions[i]);
2814dcd183fSM Chetan Kumar }
2824dcd183fSM Chetan Kumar 
283*8bea96efSM Chetan Kumar /**
284*8bea96efSM Chetan Kumar  * ipc_devlink_init - Initialize/register devlink to IOSM driver
285*8bea96efSM Chetan Kumar  * @ipc_imem:   Pointer to struct iosm_imem
286*8bea96efSM Chetan Kumar  *
287*8bea96efSM Chetan Kumar  * Returns:     Pointer to iosm_devlink on success and NULL on failure
288*8bea96efSM Chetan Kumar  */
2894dcd183fSM Chetan Kumar struct iosm_devlink *ipc_devlink_init(struct iosm_imem *ipc_imem)
2904dcd183fSM Chetan Kumar {
2914dcd183fSM Chetan Kumar 	struct ipc_chnl_cfg chnl_cfg_flash = { 0 };
2924dcd183fSM Chetan Kumar 	struct iosm_devlink *ipc_devlink;
2934dcd183fSM Chetan Kumar 	struct devlink *devlink_ctx;
2944dcd183fSM Chetan Kumar 	int rc;
2954dcd183fSM Chetan Kumar 
2964dcd183fSM Chetan Kumar 	devlink_ctx = devlink_alloc(&devlink_flash_ops,
2974dcd183fSM Chetan Kumar 				    sizeof(struct iosm_devlink),
2984dcd183fSM Chetan Kumar 				    ipc_imem->dev);
2994dcd183fSM Chetan Kumar 	if (!devlink_ctx) {
3004dcd183fSM Chetan Kumar 		dev_err(ipc_imem->dev, "devlink_alloc failed");
3014dcd183fSM Chetan Kumar 		goto devlink_alloc_fail;
3024dcd183fSM Chetan Kumar 	}
3034dcd183fSM Chetan Kumar 
3044dcd183fSM Chetan Kumar 	ipc_devlink = devlink_priv(devlink_ctx);
3054dcd183fSM Chetan Kumar 	ipc_devlink->devlink_ctx = devlink_ctx;
3064dcd183fSM Chetan Kumar 	ipc_devlink->pcie = ipc_imem->pcie;
3074dcd183fSM Chetan Kumar 	ipc_devlink->dev = ipc_imem->dev;
308db4278c5SLeon Romanovsky 	devlink_register(devlink_ctx);
3094dcd183fSM Chetan Kumar 
3104dcd183fSM Chetan Kumar 	rc = devlink_params_register(devlink_ctx, iosm_devlink_params,
3114dcd183fSM Chetan Kumar 				     ARRAY_SIZE(iosm_devlink_params));
3124dcd183fSM Chetan Kumar 	if (rc) {
3134dcd183fSM Chetan Kumar 		dev_err(ipc_devlink->dev,
3144dcd183fSM Chetan Kumar 			"devlink_params_register failed. rc %d", rc);
3154dcd183fSM Chetan Kumar 		goto param_reg_fail;
3164dcd183fSM Chetan Kumar 	}
3174dcd183fSM Chetan Kumar 
3184dcd183fSM Chetan Kumar 	devlink_params_publish(devlink_ctx);
3194dcd183fSM Chetan Kumar 	ipc_devlink->cd_file_info = list;
3204dcd183fSM Chetan Kumar 
3214dcd183fSM Chetan Kumar 	rc = ipc_devlink_create_region(ipc_devlink);
3224dcd183fSM Chetan Kumar 	if (rc) {
3234dcd183fSM Chetan Kumar 		dev_err(ipc_devlink->dev, "Devlink Region create failed, rc %d",
3244dcd183fSM Chetan Kumar 			rc);
3254dcd183fSM Chetan Kumar 		goto region_create_fail;
3264dcd183fSM Chetan Kumar 	}
3274dcd183fSM Chetan Kumar 
3284dcd183fSM Chetan Kumar 	if (ipc_chnl_cfg_get(&chnl_cfg_flash, IPC_MEM_CTRL_CHL_ID_7) < 0)
3294dcd183fSM Chetan Kumar 		goto chnl_get_fail;
3304dcd183fSM Chetan Kumar 
3314dcd183fSM Chetan Kumar 	ipc_imem_channel_init(ipc_imem, IPC_CTYPE_CTRL,
3324dcd183fSM Chetan Kumar 			      chnl_cfg_flash, IRQ_MOD_OFF);
3334dcd183fSM Chetan Kumar 
3344dcd183fSM Chetan Kumar 	init_completion(&ipc_devlink->devlink_sio.read_sem);
3354dcd183fSM Chetan Kumar 	skb_queue_head_init(&ipc_devlink->devlink_sio.rx_list);
3364dcd183fSM Chetan Kumar 
3374dcd183fSM Chetan Kumar 	dev_dbg(ipc_devlink->dev, "iosm devlink register success");
3384dcd183fSM Chetan Kumar 
3394dcd183fSM Chetan Kumar 	return ipc_devlink;
3404dcd183fSM Chetan Kumar 
3414dcd183fSM Chetan Kumar chnl_get_fail:
3424dcd183fSM Chetan Kumar 	ipc_devlink_destroy_region(ipc_devlink);
3434dcd183fSM Chetan Kumar region_create_fail:
3444dcd183fSM Chetan Kumar 	devlink_params_unpublish(devlink_ctx);
3454dcd183fSM Chetan Kumar 	devlink_params_unregister(devlink_ctx, iosm_devlink_params,
3464dcd183fSM Chetan Kumar 				  ARRAY_SIZE(iosm_devlink_params));
3474dcd183fSM Chetan Kumar param_reg_fail:
3484dcd183fSM Chetan Kumar 	devlink_free(devlink_ctx);
3494dcd183fSM Chetan Kumar devlink_alloc_fail:
3504dcd183fSM Chetan Kumar 	return NULL;
3514dcd183fSM Chetan Kumar }
3524dcd183fSM Chetan Kumar 
353*8bea96efSM Chetan Kumar /**
354*8bea96efSM Chetan Kumar  * ipc_devlink_deinit - To unintialize the devlink from IOSM driver.
355*8bea96efSM Chetan Kumar  * @ipc_devlink:        Devlink instance
356*8bea96efSM Chetan Kumar  */
3574dcd183fSM Chetan Kumar void ipc_devlink_deinit(struct iosm_devlink *ipc_devlink)
3584dcd183fSM Chetan Kumar {
3594dcd183fSM Chetan Kumar 	struct devlink *devlink_ctx = ipc_devlink->devlink_ctx;
3604dcd183fSM Chetan Kumar 
3614dcd183fSM Chetan Kumar 	ipc_devlink_destroy_region(ipc_devlink);
3624dcd183fSM Chetan Kumar 	devlink_params_unpublish(devlink_ctx);
3634dcd183fSM Chetan Kumar 	devlink_params_unregister(devlink_ctx, iosm_devlink_params,
3644dcd183fSM Chetan Kumar 				  ARRAY_SIZE(iosm_devlink_params));
3654dcd183fSM Chetan Kumar 	if (ipc_devlink->devlink_sio.devlink_read_pend) {
3664dcd183fSM Chetan Kumar 		complete(&ipc_devlink->devlink_sio.read_sem);
3674dcd183fSM Chetan Kumar 		complete(&ipc_devlink->devlink_sio.channel->ul_sem);
3684dcd183fSM Chetan Kumar 	}
3694dcd183fSM Chetan Kumar 	if (!ipc_devlink->devlink_sio.devlink_read_pend)
3704dcd183fSM Chetan Kumar 		skb_queue_purge(&ipc_devlink->devlink_sio.rx_list);
3714dcd183fSM Chetan Kumar 
3724dcd183fSM Chetan Kumar 	ipc_imem_sys_devlink_close(ipc_devlink);
3734dcd183fSM Chetan Kumar 	devlink_unregister(devlink_ctx);
3744dcd183fSM Chetan Kumar 	devlink_free(devlink_ctx);
3754dcd183fSM Chetan Kumar }
376