Merge "ipa: save registers on graceful shutdown"

This commit is contained in:
qctecmdr 2021-04-26 22:59:16 -07:00 • committed by Gerrit - the friendly Code Review server
commit de476aa837
4 changed files with 77 additions and 14 deletions

View file

@ -1820,6 +1820,7 @@ int gsi_alloc_evt_ring(struct gsi_evt_ring_props *props, unsigned long dev_hdl,
((op << GSI_EE_n_EV_CH_CMD_OPCODE_SHFT) &
GSI_EE_n_EV_CH_CMD_OPCODE_BMSK));
ee = gsi_ctx->per.ee;
GSIDBG("Sending alloc evt command for %lu\n", evt_id);
gsi_writel(val, gsi_ctx->base +
GSI_EE_n_EV_CH_CMD_OFFS(ee));
res = wait_for_completion_timeout(&ctx->compl, GSI_CMD_TIMEOUT);
@ -3035,7 +3036,14 @@ EXPORT_SYMBOL(gsi_query_channel_db_addr);
int gsi_pending_irq_type(void)
{
int ee = gsi_ctx->per.ee;
int ee;
if (!gsi_ctx->per_registered) {
GSIERR("no client registered\n");
return 0;
}
ee = gsi_ctx->per.ee;
return gsi_readl(gsi_ctx->base +
GSI_EE_n_CNTXT_TYPE_IRQ_OFFS(ee));

View file

@ -154,6 +154,7 @@ static struct clk *ipa3_clk;
struct ipa3_context *ipa3_ctx = NULL;
void ipa3_plat_drv_shutdown(struct platform_device *pdev_p);
int ipa3_plat_drv_probe(struct platform_device *pdev_p);
int ipa3_pci_drv_probe(
struct pci_dev *pci_dev,
@ -443,6 +444,7 @@ static const struct dev_pm_ops ipa_pm_ops = {
static struct platform_driver ipa_plat_drv = {
.probe = ipa3_plat_drv_probe,
.shutdown = ipa3_plat_drv_shutdown,
.driver = {
.name = DRV_NAME,
.pm = &ipa_pm_ops,
@ -6542,6 +6544,8 @@ fail_teth_bridge_driver_init:
ipa3_teardown_apps_pipes();
fail_alloc_gsi_channel:
fail_setup_apps_pipes:
ipahal_print_all_regs(false);
ipa_save_registers();
gsi_deregister_device(ipa3_ctx->gsi_dev_hdl, false);
fail_register_device:
ipa3_destroy_flt_tbl_idrs();
@ -9038,6 +9042,17 @@ static void ipa_smmu_update_fw_loader(void)
}
}
void ipa3_plat_drv_shutdown(struct platform_device *pdev_p)
{
pr_debug("ipa: driver shutdown invoked for %s\n",
pdev_p->dev.of_node->name);
if (ipa3_ctx && atomic_read(&ipa3_ctx->ipa_clk_vote)) {
ipahal_print_all_regs(false);
ipa_save_registers();
}
return;
}
int ipa3_plat_drv_probe(struct platform_device *pdev_p)
{
int result;

View file

@ -617,8 +617,9 @@ static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_ip_v4_filter_init(
static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_dummy(
enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
{
IPAHAL_ERR("no construct function for IMM_CMD=%s, IPA ver %d\n",
ipahal_imm_cmd_name_str(cmd), ipahal_ctx->hw_type);
IPAHAL_ERR("no construct function for IMM_CMD=%s IPA ver=%d\n",
ipahal_imm_cmd_name_str(cmd), ipahal_ctx?ipahal_ctx->hw_type:-1);
WARN_ON(1);
return NULL;
}
@ -779,6 +780,11 @@ static u16 ipahal_imm_cmd_get_opcode(enum ipahal_imm_cmd_name cmd)
{
u32 opcode;
if (!ipahal_ctx) {
IPAHAL_ERR("Invalid ctx\n");
return -EFAULT;
}
if (cmd >= IPA_IMM_CMD_MAX) {
IPAHAL_ERR("Invalid immediate command imm_cmd=%u\n", cmd);
ipa_assert();
@ -813,8 +819,8 @@ struct ipahal_imm_cmd_pyld *ipahal_construct_imm_cmd(
return NULL;
}
if (cmd >= IPA_IMM_CMD_MAX) {
IPAHAL_ERR("Invalid immediate command %u\n", cmd);
if (!ipahal_ctx || cmd >= IPA_IMM_CMD_MAX) {
IPAHAL_ERR("Invalid ctx/immediate command %u\n", cmd);
return NULL;
}
@ -1196,7 +1202,7 @@ u32 ipahal_pkt_status_get_size(void)
void ipahal_pkt_status_parse(const void *unparsed_status,
struct ipahal_pkt_status *status)
{
if (!unparsed_status || !status) {
if (!ipahal_ctx || !unparsed_status || !status) {
IPAHAL_ERR("Input Error: unparsed_status=%pK status=%pK\n",
unparsed_status, status);
return;
@ -1218,7 +1224,7 @@ void ipahal_pkt_status_parse(const void *unparsed_status,
void ipahal_pkt_status_parse_thin(const void *unparsed_status,
struct ipahal_pkt_status_thin *status)
{
if (!unparsed_status || !status) {
if (!ipahal_ctx || !unparsed_status || !status) {
IPAHAL_ERR("Input Error: unparsed_status=%pK status=%pK\n",
unparsed_status, status);
return;

View file

@ -3068,8 +3068,11 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
ipareg_construct_single_ndp_mode, ipareg_parse_single_ndp_mode,
-1, 0, 0, 0, 0},
[IPA_HW_v4_0][IPA_QSB_MAX_READS] = {
ipareg_construct_qsb_max_reads_v4_0, ipareg_parse_dummy,
ipareg_construct_qsb_max_reads_v4_0, ipareg_parse_qsb_max_reads,
0x00000078, 0, 0, 0, 0},
[IPA_HW_v4_0][IPA_QSB_MAX_WRITES] = {
ipareg_construct_qsb_max_writes, ipareg_parse_qsb_max_writes,
0x00000074, 0, 0, 0, 0},
[IPA_HW_v4_0][IPA_FILT_ROUT_HASH_FLUSH] = {
ipareg_construct_dummy, ipareg_parse_dummy,
0x0000014c, 0, 0, 0, 0},
@ -3629,15 +3632,16 @@ void ipahal_print_all_regs(bool print_to_dmesg)
int i, j;
struct ipahal_reg_obj *reg;
IPAHAL_DBG("Printing all registers for ipa_hw_type %d\n",
ipahal_ctx->hw_type);
if ((ipahal_ctx->hw_type < IPA_HW_v4_0) ||
if (!ipahal_ctx || (ipahal_ctx->hw_type < IPA_HW_v4_0) ||
(ipahal_ctx->hw_type >= IPA_HW_MAX)) {
IPAHAL_ERR("invalid IPA HW type (%d)\n", ipahal_ctx->hw_type);
IPAHAL_ERR("invalid IPA HW type (%d)\n",
ipahal_ctx?ipahal_ctx->hw_type:-1);
return;
}
IPAHAL_DBG("Printing all registers for ipa_hw_type %d\n",
ipahal_ctx->hw_type);
for (i = 0; i < IPA_REG_MAX ; i++) {
reg = &(ipahal_reg_objs[ipahal_ctx->hw_type][i]);
@ -3753,6 +3757,11 @@ u32 ipahal_read_reg_n(enum ipahal_reg_name reg, u32 n)
{
u32 offset;
if (!ipahal_ctx) {
IPAHAL_DBG("Invalid ipahal context\n");
return -EINVAL;
}
if (reg >= IPA_REG_MAX) {
IPAHAL_ERR("Invalid register reg=%u\n", reg);
WARN_ON(1);
@ -3780,6 +3789,11 @@ u32 ipahal_read_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n)
{
u32 offset;
if (!ipahal_ctx) {
IPAHAL_DBG("Invalid ipahal context\n");
return -EINVAL;
}
if (reg >= IPA_REG_MAX) {
IPAHAL_ERR("Invalid register reg=%u\n", reg);
WARN_ON(1);
@ -3813,6 +3827,11 @@ void ipahal_write_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n, u32 val)
{
u32 offset;
if (!ipahal_ctx) {
IPAHAL_DBG("Invalid ipahal context\n");
return;
}
if (reg >= IPA_REG_MAX) {
IPAHAL_ERR("Invalid register reg=%u\n", reg);
WARN_ON(1);
@ -3847,6 +3866,11 @@ u32 ipahal_read_reg_n_fields(enum ipahal_reg_name reg, u32 n, void *fields)
u32 val = 0;
u32 offset;
if (!ipahal_ctx) {
IPAHAL_DBG("Invalid ipahal context\n");
return -EINVAL;
}
if (!fields) {
IPAHAL_ERR("Input error fields\n");
WARN_ON(1);
@ -3884,6 +3908,11 @@ void ipahal_write_reg_n_fields(enum ipahal_reg_name reg, u32 n,
u32 val = 0;
u32 offset;
if (!ipahal_ctx) {
IPAHAL_DBG("Invalid ipahal context\n");
return;
}
if (!fields) {
IPAHAL_ERR("Input error fields=%pK\n", fields);
WARN_ON(1);
@ -3918,6 +3947,11 @@ u32 ipahal_get_reg_mn_ofst(enum ipahal_reg_name reg, u32 m, u32 n)
{
u32 offset;
if (!ipahal_ctx) {
IPAHAL_DBG("Invalid ipahal context\n");
return -EINVAL;
}
if (reg >= IPA_REG_MAX) {
IPAHAL_ERR("Invalid register reg=%u\n", reg);
WARN_ON(1);
@ -3967,7 +4001,7 @@ void ipahal_get_aggr_force_close_valmask(int ep_idx,
u32 shft = 0;
u32 bmsk = 0;
if (!valmask) {
if (!ipahal_ctx || !valmask) {
IPAHAL_ERR("Input error\n");
return;
}