Skip to content

Commit 7f016b3

Browse files
basuamdJiri Kosina
authored andcommitted
HID: amd_sfh: Add interrupt handler to process interrupts
On newer AMD platforms with SFH, it is observed that random interrupts get generated on the SFH hardware and until this is cleared the firmware sensor processing is stalled, resulting in no data been received to driver side. Add routines to handle these interrupts, so that firmware operations are not stalled. Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
1 parent fb75a37 commit 7f016b3

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

drivers/hid/amd-sfh-hid/amd_sfh_pcie.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,30 @@ static void amd_sfh_clear_intr(struct amd_mp2_dev *privdata)
106106
privdata->mp2_ops->clear_intr(privdata);
107107
}
108108

109+
static irqreturn_t amd_sfh_irq_handler(int irq, void *data)
110+
{
111+
amd_sfh_clear_intr(data);
112+
113+
return IRQ_HANDLED;
114+
}
115+
116+
static int amd_sfh_irq_init_v2(struct amd_mp2_dev *privdata)
117+
{
118+
int rc;
119+
120+
pci_intx(privdata->pdev, true);
121+
122+
rc = devm_request_irq(&privdata->pdev->dev, privdata->pdev->irq,
123+
amd_sfh_irq_handler, 0, DRIVER_NAME, privdata);
124+
if (rc) {
125+
dev_err(&privdata->pdev->dev, "failed to request irq %d err=%d\n",
126+
privdata->pdev->irq, rc);
127+
return rc;
128+
}
129+
130+
return 0;
131+
}
132+
109133
void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
110134
{
111135
union sfh_cmd_param cmd_param;
@@ -210,6 +234,7 @@ static void amd_mp2_pci_remove(void *privdata)
210234
struct amd_mp2_dev *mp2 = privdata;
211235
amd_sfh_hid_client_deinit(privdata);
212236
mp2->mp2_ops->stop_all(mp2);
237+
pci_intx(mp2->pdev, false);
213238
amd_sfh_clear_intr(mp2);
214239
}
215240

@@ -219,6 +244,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = {
219244
.stop_all = amd_stop_all_sensor_v2,
220245
.response = amd_sfh_wait_response_v2,
221246
.clear_intr = amd_sfh_clear_intr_v2,
247+
.init_intr = amd_sfh_irq_init_v2,
222248
};
223249

224250
static const struct amd_mp2_ops amd_sfh_ops = {
@@ -244,6 +270,14 @@ static void mp2_select_ops(struct amd_mp2_dev *privdata)
244270
}
245271
}
246272

273+
static int amd_sfh_irq_init(struct amd_mp2_dev *privdata)
274+
{
275+
if (privdata->mp2_ops->init_intr)
276+
return privdata->mp2_ops->init_intr(privdata);
277+
278+
return 0;
279+
}
280+
247281
static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
248282
{
249283
struct amd_mp2_dev *privdata;
@@ -280,6 +314,12 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
280314

281315
mp2_select_ops(privdata);
282316

317+
rc = amd_sfh_irq_init(privdata);
318+
if (rc) {
319+
dev_err(&pdev->dev, "amd_sfh_irq_init failed\n");
320+
return rc;
321+
}
322+
283323
rc = amd_sfh_hid_client_init(privdata);
284324
if (rc) {
285325
amd_sfh_clear_intr(privdata);

drivers/hid/amd-sfh-hid/amd_sfh_pcie.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,6 @@ struct amd_mp2_ops {
142142
void (*stop_all)(struct amd_mp2_dev *privdata);
143143
int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
144144
void (*clear_intr)(struct amd_mp2_dev *privdata);
145+
int (*init_intr)(struct amd_mp2_dev *privdata);
145146
};
146147
#endif

0 commit comments

Comments
 (0)