blob: 0a656ed07eb6d9a33f3df510da1a09ff20cc5902 [file] [log] [blame]
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include "commonmhitest.h"
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/sched.h>
#define DEFAULT_FW_FILE_NAME "qcn9000/amss.bin"
int mhitest_ss_powerup(struct rproc *subsys_desc)
{
int ret;
struct mhitest_platform *temp;
MHITEST_LOG("Enter\n");
temp = subsys_desc->priv;
if (!temp) {
MHITEST_ERR("Error not dev data\n");
return -EINVAL;
}
MHITEST_VERB("temp:[%p]\n", temp);
if (!temp->pci_dev) {
pr_mhitest2("temp->pci_Dev is NULL\n");
return -ENODEV;
}
snprintf(temp->fw_name, sizeof(temp->fw_name),
DEFAULT_FW_FILE_NAME);
ret = mhitest_prepare_pci_mhi_msi(temp);
if (ret) {
MHITEST_ERR("Error prep. pci_mhi_msi ret:%d\n", ret);
return ret;
}
ret = mhitest_prepare_start_mhi(temp);
if (ret) {
MHITEST_ERR("Error preapare start mhi ret:%d\n", ret);
return ret;
}
MHITEST_LOG("Exit\n");
return 0;
}
int mhitest_ss_shutdown(struct rproc *subsys_desc)
{
struct mhitest_platform *mplat;
MHITEST_VERB("Going for shutdown\n");
mplat = subsys_desc->priv;
mhitest_pci_set_mhi_state(mplat, MHI_POWER_OFF);
mhitest_pci_set_mhi_state(mplat, MHI_DEINIT);
mhitest_pci_remove_all(mplat);
return 0;
}
void mhitest_ss_crash_shutdown(struct rproc *subsys_desc)
{
int crash_d_instance;
int ret;
struct mhitest_platform *temp;
if (!strncmp(subsys_desc->name, "mhitest-ss-0",
strlen("mhitest-ss-0"))) {
crash_d_instance = 0;
} else if (!strncmp(subsys_desc->name, "mhitest-ss-1",
strlen("mhitest-ss-1"))) {
crash_d_instance = 1;
} else {
MHITEST_ERR("Error: subsys desc name: %s is not matching with any subsystem\n",
subsys_desc->name);
return;
}
temp = get_mhitest_mplat(crash_d_instance);
MHITEST_LOG("Going for shutdown temp:%p\n", temp);
if (!temp)
return;
if ((strcmp(temp->mhitest_ss_desc_name, subsys_desc->name))) {
MHITEST_ERR("Error: not the same subsystem\n");
return;
}
ret = mhitest_dump_info(temp, true);
if (ret) {
MHITEST_ERR("Error: ret = %d\n", ret);
return;
}
}
int mhitest_ss_dummy_load(struct rproc *subsys_desc,
const struct firmware *fw)
{
/* no firmware load it will taken care by pci and mhi */
return 0;
}
int mhitest_ss_add_ramdump_callback(struct rproc *subsys_desc,
const struct firmware *firmware)
{
MHITEST_LOG("Dummy callback, returning 0...\n");
return 0;
}
const struct rproc_ops mhitest_rproc_ops = {
.start = mhitest_ss_powerup,
.stop = mhitest_ss_shutdown,
.load = mhitest_ss_dummy_load,
.parse_fw = mhitest_ss_add_ramdump_callback,
.report_panic = mhitest_ss_crash_shutdown,
};
int mhitest_subsystem_register(struct mhitest_platform *mplat)
{
MHITEST_VERB("Going for ss_reg.\n");
if (mplat->d_instance == 0)
mplat->mhitest_ss_desc_name = "mhitest-ss-0";
else
mplat->mhitest_ss_desc_name = "mhitest-ss-1";
MHITEST_VERB("SS name :%s\n", mplat->mhitest_ss_desc_name);
MHITEST_VERB("Doing rproc alloc..\n");
mplat->subsys_handle = rproc_alloc(&mplat->plat_dev->dev,
mplat->mhitest_ss_desc_name,
&mhitest_rproc_ops,
DEFAULT_FW_FILE_NAME, 0);
if (!mplat->subsys_handle) {
MHITEST_ERR("rproc_alloc returned NULL..\n");
return -EINVAL;
}
mplat->subsys_handle->priv = mplat;
mplat->subsys_handle->auto_boot = false;
MHITEST_VERB("Doing rproc add..\n");
if (rproc_add(mplat->subsys_handle))
return -EINVAL;
if (!mplat->subsys_handle->dev.parent) {
MHITEST_ERR("dev is null\n");
return -ENODEV;
}
MHITEST_VERB("Doing rproc boot..\n");
if (rproc_boot(mplat->subsys_handle))
return -EINVAL;
return 0;
}
void mhitest_subsystem_unregister(struct mhitest_platform *mplat)
{
if (!mplat) {
MHITEST_ERR("mplat is null, no subsystem unregister\n");
return;
}
if (mplat->subsys_handle)
rproc_shutdown(mplat->subsys_handle);
else
MHITEST_ERR("mplat->subsys_handle is NULL\n");
mplat->subsys_handle = NULL;
}