]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/s390/pci/pci_sysfs.c
Merge tag 'pwm/for-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[karo-tx-linux.git] / arch / s390 / pci / pci_sysfs.c
1 /*
2  * Copyright IBM Corp. 2012
3  *
4  * Author(s):
5  *   Jan Glauber <jang@linux.vnet.ibm.com>
6  */
7
8 #define COMPONENT "zPCI"
9 #define pr_fmt(fmt) COMPONENT ": " fmt
10
11 #include <linux/kernel.h>
12 #include <linux/stat.h>
13 #include <linux/pci.h>
14
15 static ssize_t show_fid(struct device *dev, struct device_attribute *attr,
16                         char *buf)
17 {
18         struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
19
20         return sprintf(buf, "0x%08x\n", zdev->fid);
21 }
22 static DEVICE_ATTR(function_id, S_IRUGO, show_fid, NULL);
23
24 static ssize_t show_fh(struct device *dev, struct device_attribute *attr,
25                        char *buf)
26 {
27         struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
28
29         return sprintf(buf, "0x%08x\n", zdev->fh);
30 }
31 static DEVICE_ATTR(function_handle, S_IRUGO, show_fh, NULL);
32
33 static ssize_t show_pchid(struct device *dev, struct device_attribute *attr,
34                           char *buf)
35 {
36         struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
37
38         return sprintf(buf, "0x%04x\n", zdev->pchid);
39 }
40 static DEVICE_ATTR(pchid, S_IRUGO, show_pchid, NULL);
41
42 static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr,
43                           char *buf)
44 {
45         struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
46
47         return sprintf(buf, "0x%02x\n", zdev->pfgid);
48 }
49 static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL);
50
51 static ssize_t store_recover(struct device *dev, struct device_attribute *attr,
52                              const char *buf, size_t count)
53 {
54         struct pci_dev *pdev = to_pci_dev(dev);
55         struct zpci_dev *zdev = get_zdev(pdev);
56         int ret;
57
58         if (!device_remove_file_self(dev, attr))
59                 return count;
60
61         pci_stop_and_remove_bus_device(pdev);
62         ret = zpci_disable_device(zdev);
63         if (ret)
64                 return ret;
65
66         ret = zpci_enable_device(zdev);
67         if (ret)
68                 return ret;
69
70         pci_rescan_bus(zdev->bus);
71         return count;
72 }
73 static DEVICE_ATTR(recover, S_IWUSR, NULL, store_recover);
74
75 static struct device_attribute *zpci_dev_attrs[] = {
76         &dev_attr_function_id,
77         &dev_attr_function_handle,
78         &dev_attr_pchid,
79         &dev_attr_pfgid,
80         &dev_attr_recover,
81         NULL,
82 };
83
84 int zpci_sysfs_add_device(struct device *dev)
85 {
86         int i, rc = 0;
87
88         for (i = 0; zpci_dev_attrs[i]; i++) {
89                 rc = device_create_file(dev, zpci_dev_attrs[i]);
90                 if (rc)
91                         goto error;
92         }
93         return 0;
94
95 error:
96         while (--i >= 0)
97                 device_remove_file(dev, zpci_dev_attrs[i]);
98         return rc;
99 }
100
101 void zpci_sysfs_remove_device(struct device *dev)
102 {
103         int i;
104
105         for (i = 0; zpci_dev_attrs[i]; i++)
106                 device_remove_file(dev, zpci_dev_attrs[i]);
107 }