Skip to content

Commit

Permalink
HID: amd_sfh: Add functionality to clear interrupts
Browse files Browse the repository at this point in the history
[ Upstream commit fb75a37 ]

Newer AMD platforms with SFH may generate interrupts on some events
which are unwarranted. Until this is cleared the actual MP2 data
processing maybe stalled in some cases.

Add a mechanism to clear the pending interrupts (if any) during the
driver initialization and sensor command operations.

Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Basavaraj Natikar authored and gregkh committed Mar 8, 2022
1 parent 2144e45 commit 316a1c7
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
25 changes: 24 additions & 1 deletion drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
Expand Up @@ -89,6 +89,20 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0);
}

static void amd_sfh_clear_intr_v2(struct amd_mp2_dev *privdata)
{
if (readl(privdata->mmio + AMD_P2C_MSG(4))) {
writel(0, privdata->mmio + AMD_P2C_MSG(4));
writel(0xf, privdata->mmio + AMD_P2C_MSG(5));
}
}

static void amd_sfh_clear_intr(struct amd_mp2_dev *privdata)
{
if (privdata->mp2_ops->clear_intr)
privdata->mp2_ops->clear_intr(privdata);
}

void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
{
union sfh_cmd_param cmd_param;
Expand Down Expand Up @@ -193,13 +207,15 @@ static void amd_mp2_pci_remove(void *privdata)
struct amd_mp2_dev *mp2 = privdata;
amd_sfh_hid_client_deinit(privdata);
mp2->mp2_ops->stop_all(mp2);
amd_sfh_clear_intr(mp2);
}

static const struct amd_mp2_ops amd_sfh_ops_v2 = {
.start = amd_start_sensor_v2,
.stop = amd_stop_sensor_v2,
.stop_all = amd_stop_all_sensor_v2,
.response = amd_sfh_wait_response_v2,
.clear_intr = amd_sfh_clear_intr_v2,
};

static const struct amd_mp2_ops amd_sfh_ops = {
Expand Down Expand Up @@ -262,8 +278,13 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
mp2_select_ops(privdata);

rc = amd_sfh_hid_client_init(privdata);
if (rc)
if (rc) {
amd_sfh_clear_intr(privdata);
dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n");
return rc;
}

amd_sfh_clear_intr(privdata);

return devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata);
}
Expand Down Expand Up @@ -291,6 +312,7 @@ static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
}

schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
amd_sfh_clear_intr(mp2);

return 0;
}
Expand All @@ -315,6 +337,7 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
}

cancel_delayed_work_sync(&cl_data->work_buffer);
amd_sfh_clear_intr(mp2);

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
Expand Up @@ -141,5 +141,6 @@ struct amd_mp2_ops {
void (*stop)(struct amd_mp2_dev *privdata, u16 sensor_idx);
void (*stop_all)(struct amd_mp2_dev *privdata);
int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
void (*clear_intr)(struct amd_mp2_dev *privdata);
};
#endif

0 comments on commit 316a1c7

Please sign in to comment.