Hardware registers of devices under control of power management cannot be accessed at all times. If such a device is suspended, register accesses may lead to undefined behavior, like reading bogus values, or causing exceptions or system lock-ups. Extend struct debugfs_regset32 with an optional field to let device drivers specify the device the registers in the set belong to. This allows debugfs_show_regset32() to make sure the device is resumed while its registers are being read.
Unified · Split
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/slab.h> |
| 19 | 19 | #include <linux/atomic.h> |
| 20 | 20 | #include <linux/device.h> |
| 21 | +#include <linux/pm_runtime.h> | |
| 21 | 22 | #include <linux/poll.h> |
| 22 | 23 | #include <linux/security.h> |
| 23 | 24 | |
| @@ -1060,7 +1061,14 @@ static int debugfs_show_regset32(struct seq_file *s, void *data) · 1036 unmodified lines | ||
| 1060 | 1061 | { |
| 1061 | 1062 | struct debugfs_regset32 *regset = s->private; |
| 1062 | 1063 | |
| 1064 | + if (regset->dev) | |
| 1065 | + pm_runtime_get_sync(regset->dev); | |
| 1066 | + | |
| 1063 | 1067 | debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, ""); |
| 1068 | + | |
| 1069 | + if (regset->dev) | |
| 1070 | + pm_runtime_put(regset->dev); | |
| 1071 | + | |
| 1064 | 1072 | return 0; |
| 1065 | 1073 | } |
| 1066 | 1074 | |
| @@ -35,6 +35,7 @@ struct debugfs_regset32 { · 34 unmodified lines | ||
| 35 | 35 | const struct debugfs_reg32 *regs; |
| 36 | 36 | int nregs; |
| 37 | 37 | void __iomem *base; |
| 38 | + struct device *dev; /* Optional device for Runtime PM */ | |
| 38 | 39 | }; |
| 39 | 40 | |
| 40 | 41 | extern struct dentry *arch_debugfs_dir; |