Commit fb75a379 authored by Basavaraj Natikar's avatar Basavaraj Natikar Committed by Jiri Kosina

HID: amd_sfh: Add functionality to clear interrupts

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: default avatarBasavaraj Natikar <Basavaraj.Natikar@amd.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent b300667b
...@@ -92,6 +92,20 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata) ...@@ -92,6 +92,20 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); 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) void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
{ {
union sfh_cmd_param cmd_param; union sfh_cmd_param cmd_param;
...@@ -196,6 +210,7 @@ static void amd_mp2_pci_remove(void *privdata) ...@@ -196,6 +210,7 @@ static void amd_mp2_pci_remove(void *privdata)
struct amd_mp2_dev *mp2 = privdata; struct amd_mp2_dev *mp2 = privdata;
amd_sfh_hid_client_deinit(privdata); amd_sfh_hid_client_deinit(privdata);
mp2->mp2_ops->stop_all(mp2); mp2->mp2_ops->stop_all(mp2);
amd_sfh_clear_intr(mp2);
} }
static const struct amd_mp2_ops amd_sfh_ops_v2 = { static const struct amd_mp2_ops amd_sfh_ops_v2 = {
...@@ -203,6 +218,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = { ...@@ -203,6 +218,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = {
.stop = amd_stop_sensor_v2, .stop = amd_stop_sensor_v2,
.stop_all = amd_stop_all_sensor_v2, .stop_all = amd_stop_all_sensor_v2,
.response = amd_sfh_wait_response_v2, .response = amd_sfh_wait_response_v2,
.clear_intr = amd_sfh_clear_intr_v2,
}; };
static const struct amd_mp2_ops amd_sfh_ops = { static const struct amd_mp2_ops amd_sfh_ops = {
...@@ -265,8 +281,13 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i ...@@ -265,8 +281,13 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
mp2_select_ops(privdata); mp2_select_ops(privdata);
rc = amd_sfh_hid_client_init(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; return rc;
}
amd_sfh_clear_intr(privdata);
return devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata); return devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata);
} }
...@@ -294,6 +315,7 @@ static int __maybe_unused amd_mp2_pci_resume(struct device *dev) ...@@ -294,6 +315,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)); schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
amd_sfh_clear_intr(mp2);
return 0; return 0;
} }
...@@ -318,6 +340,7 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev) ...@@ -318,6 +340,7 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
} }
cancel_delayed_work_sync(&cl_data->work_buffer); cancel_delayed_work_sync(&cl_data->work_buffer);
amd_sfh_clear_intr(mp2);
return 0; return 0;
} }
......
...@@ -141,5 +141,6 @@ struct amd_mp2_ops { ...@@ -141,5 +141,6 @@ struct amd_mp2_ops {
void (*stop)(struct amd_mp2_dev *privdata, u16 sensor_idx); void (*stop)(struct amd_mp2_dev *privdata, u16 sensor_idx);
void (*stop_all)(struct amd_mp2_dev *privdata); void (*stop_all)(struct amd_mp2_dev *privdata);
int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts); int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
void (*clear_intr)(struct amd_mp2_dev *privdata);
}; };
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment