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 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/atomic.h> | 19 | #include <linux/atomic.h> |
| 20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
| 21 | #include <linux/pm_runtime.h> | ||
| 21 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
| 22 | #include <linux/security.h> | 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 | struct debugfs_regset32 *regset = s->private; | 1062 | struct debugfs_regset32 *regset = s->private; |
| 1062 | 1063 | ||
| 1064 | if (regset->dev) | ||
| 1065 | pm_runtime_get_sync(regset->dev); | ||
| 1066 | |||
| 1063 | debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, ""); | 1067 | debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, ""); |
| 1068 | |||
| 1069 | if (regset->dev) | ||
| 1070 | pm_runtime_put(regset->dev); | ||
| 1071 | |||
| 1064 | return 0; | 1072 | return 0; |
| 1065 | } | 1073 | } |
| 1066 | 1074 | ||
| @@ -35,6 +35,7 @@ struct debugfs_regset32 { · 34 unmodified lines | |||
| 35 | const struct debugfs_reg32 *regs; | 35 | const struct debugfs_reg32 *regs; |
| 36 | int nregs; | 36 | int nregs; |
| 37 | void __iomem *base; | 37 | void __iomem *base; |
| 38 | struct device *dev; /* Optional device for Runtime PM */ | ||
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | extern struct dentry *arch_debugfs_dir; | 41 | extern struct dentry *arch_debugfs_dir; |