summaryrefslogtreecommitdiff
path: root/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/amd-sfh-hid/amd_sfh_pcie.c')
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_pcie.c67
1 files changed, 61 insertions, 6 deletions
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index 9e97c26c4482..1c1fd63330c9 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -18,6 +18,7 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include "amd_sfh_pcie.h"
#include "sfh1_1/amd_sfh_init.h"
@@ -122,7 +123,7 @@ int amd_sfh_irq_init_v2(struct amd_mp2_dev *privdata)
{
int rc;
- pci_intx(privdata->pdev, true);
+ pcim_intx(privdata->pdev, true);
rc = devm_request_irq(&privdata->pdev->dev, privdata->pdev->irq,
amd_sfh_irq_handler, 0, DRIVER_NAME, privdata);
@@ -248,7 +249,7 @@ 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);
- pci_intx(mp2->pdev, false);
+ pcim_intx(mp2->pdev, false);
amd_sfh_clear_intr(mp2);
}
@@ -330,20 +331,73 @@ static const struct dmi_system_id dmi_nodevs[] = {
{ }
};
+static ssize_t hpd_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%s\n", str_enabled_disabled(mp2->dev_en.is_hpd_enabled));
+}
+
+static ssize_t hpd_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
+ bool enabled;
+ int ret;
+
+ ret = kstrtobool(buf, &enabled);
+ if (ret)
+ return ret;
+
+ mp2->sfh1_1_ops->toggle_hpd(mp2, enabled);
+
+ return count;
+}
+static DEVICE_ATTR_RW(hpd);
+
+static umode_t sfh_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
+
+ if (!mp2->sfh1_1_ops || !mp2->dev_en.is_hpd_present)
+ return 0;
+
+ return attr->mode;
+}
+
+static struct attribute *sfh_attrs[] = {
+ &dev_attr_hpd.attr,
+ NULL,
+};
+
+static struct attribute_group sfh_attr_group = {
+ .attrs = sfh_attrs,
+ .is_visible = sfh_attr_is_visible,
+};
+
+static const struct attribute_group *amd_sfh_groups[] = {
+ &sfh_attr_group,
+ NULL,
+};
+
static void sfh1_1_init_work(struct work_struct *work)
{
struct amd_mp2_dev *mp2 = container_of(work, struct amd_mp2_dev, work);
- struct pci_dev *pdev = mp2->pdev;
int rc;
rc = mp2->sfh1_1_ops->init(mp2);
- if (rc) {
- dev_err(&pdev->dev, "sfh1_1_init failed err %d\n", rc);
+ if (rc)
return;
- }
amd_sfh_clear_intr(mp2);
mp2->init_done = 1;
+
+ rc = sysfs_update_group(&mp2->pdev->dev.kobj, &sfh_attr_group);
+ if (rc)
+ dev_warn(&mp2->pdev->dev, "failed to update sysfs group\n");
+
}
static void sfh_init_work(struct work_struct *work)
@@ -490,6 +544,7 @@ static struct pci_driver amd_mp2_pci_driver = {
.driver.pm = &amd_mp2_pm_ops,
.shutdown = amd_sfh_shutdown,
.remove = amd_sfh_remove,
+ .dev_groups = amd_sfh_groups,
};
module_pci_driver(amd_mp2_pci_driver);