diff options
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r-- | drivers/pci/pci-sysfs.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 85ebd02a64a7..0f6382f090ee 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -916,6 +916,24 @@ int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev) | |||
916 | return 0; | 916 | return 0; |
917 | } | 917 | } |
918 | 918 | ||
919 | static ssize_t reset_store(struct device *dev, | ||
920 | struct device_attribute *attr, const char *buf, | ||
921 | size_t count) | ||
922 | { | ||
923 | struct pci_dev *pdev = to_pci_dev(dev); | ||
924 | unsigned long val; | ||
925 | ssize_t result = strict_strtoul(buf, 0, &val); | ||
926 | |||
927 | if (result < 0) | ||
928 | return result; | ||
929 | |||
930 | if (val != 1) | ||
931 | return -EINVAL; | ||
932 | return pci_reset_function(pdev); | ||
933 | } | ||
934 | |||
935 | static struct device_attribute reset_attr = __ATTR(reset, 0200, NULL, reset_store); | ||
936 | |||
919 | static int pci_create_capabilities_sysfs(struct pci_dev *dev) | 937 | static int pci_create_capabilities_sysfs(struct pci_dev *dev) |
920 | { | 938 | { |
921 | int retval; | 939 | int retval; |
@@ -943,7 +961,22 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev) | |||
943 | /* Active State Power Management */ | 961 | /* Active State Power Management */ |
944 | pcie_aspm_create_sysfs_dev_files(dev); | 962 | pcie_aspm_create_sysfs_dev_files(dev); |
945 | 963 | ||
964 | if (!pci_probe_reset_function(dev)) { | ||
965 | retval = device_create_file(&dev->dev, &reset_attr); | ||
966 | if (retval) | ||
967 | goto error; | ||
968 | dev->reset_fn = 1; | ||
969 | } | ||
946 | return 0; | 970 | return 0; |
971 | |||
972 | error: | ||
973 | pcie_aspm_remove_sysfs_dev_files(dev); | ||
974 | if (dev->vpd && dev->vpd->attr) { | ||
975 | sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr); | ||
976 | kfree(dev->vpd->attr); | ||
977 | } | ||
978 | |||
979 | return retval; | ||
947 | } | 980 | } |
948 | 981 | ||
949 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | 982 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) |
@@ -1037,6 +1070,10 @@ static void pci_remove_capabilities_sysfs(struct pci_dev *dev) | |||
1037 | } | 1070 | } |
1038 | 1071 | ||
1039 | pcie_aspm_remove_sysfs_dev_files(dev); | 1072 | pcie_aspm_remove_sysfs_dev_files(dev); |
1073 | if (dev->reset_fn) { | ||
1074 | device_remove_file(&dev->dev, &reset_attr); | ||
1075 | dev->reset_fn = 0; | ||
1076 | } | ||
1040 | } | 1077 | } |
1041 | 1078 | ||
1042 | /** | 1079 | /** |