History

PM, libnvdimm: Add runtime firmware activation support

Abstract platform specific mechanics for nvdimm firmware activation behind a handful of generic ops. At the bus level ->activate_state() indicates the unified state (idle, busy, armed) of all DIMMs on the bus, and ->capability() indicates the system state expectations for activate. At the DIMM level ->activate_state() indicates the per-DIMM state, ->activate_result() indicates the outcome of the last activation attempt, and ->arm() attempts to transition the DIMM from 'idle' to 'armed'. A new hibernate_quiet_exec() facility is added to support firmware activation in an OS defined system quiesce state. It leverages the fact that the hibernate-freeze state wants to assert that a memory hibernation snapshot can be taken. This is in contrast to a platform firmware defined quiesce state that may forcefully quiet the memory controller independent of whether an individual device-driver properly supports hibernate-freeze. The libnvdimm sysfs interface is extended to support detection of a firmware activate capability. The mechanism supports enumeration and triggering of firmware activate, optionally in the hibernate_quiet_exec() context. [rafael: hibernate_quiet_exec() proposal] [vishal: fix up sparse warning, grammar in Documentation/]

Dan Williams committed 6 years ago

Commit 48001ea1 parent 5cf81ce8 files · +500 −0Browse files

Showing the changes to include/linux (2 of 8 files). Show all

Unified · Split

2 files
  1. include/linux/libnvdimm.h +44 −0
  2. include/linux/suspend.h +6 −0
include/linux/libnvdimm.h+44−0
@@ -86,6 +86,7 @@ struct nvdimm_bus_descriptor { · 85 unmodified lines
8686 int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);
8787 int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc,
8888 struct nvdimm *nvdimm, unsigned int cmd, void *data);
89+ const struct nvdimm_bus_fw_ops *fw_ops;
8990 };
9091
9192 struct nd_cmd_desc {
@@ -200,6 +201,49 @@ struct nvdimm_security_ops { · 108 unmodified lines
200201 int (*query_overwrite)(struct nvdimm *nvdimm);
201202 };
202203
204+enum nvdimm_fwa_state {
205+ NVDIMM_FWA_INVALID,
206+ NVDIMM_FWA_IDLE,
207+ NVDIMM_FWA_ARMED,
208+ NVDIMM_FWA_BUSY,
209+ NVDIMM_FWA_ARM_OVERFLOW,
210+};
211+
212+enum nvdimm_fwa_trigger {
213+ NVDIMM_FWA_ARM,
214+ NVDIMM_FWA_DISARM,
215+};
216+
217+enum nvdimm_fwa_capability {
218+ NVDIMM_FWA_CAP_INVALID,
219+ NVDIMM_FWA_CAP_NONE,
220+ NVDIMM_FWA_CAP_QUIESCE,
221+ NVDIMM_FWA_CAP_LIVE,
222+};
223+
224+enum nvdimm_fwa_result {
225+ NVDIMM_FWA_RESULT_INVALID,
226+ NVDIMM_FWA_RESULT_NONE,
227+ NVDIMM_FWA_RESULT_SUCCESS,
228+ NVDIMM_FWA_RESULT_NOTSTAGED,
229+ NVDIMM_FWA_RESULT_NEEDRESET,
230+ NVDIMM_FWA_RESULT_FAIL,
231+};
232+
233+struct nvdimm_bus_fw_ops {
234+ enum nvdimm_fwa_state (*activate_state)
235+ (struct nvdimm_bus_descriptor *nd_desc);
236+ enum nvdimm_fwa_capability (*capability)
237+ (struct nvdimm_bus_descriptor *nd_desc);
238+ int (*activate)(struct nvdimm_bus_descriptor *nd_desc);
239+};
240+
241+struct nvdimm_fw_ops {
242+ enum nvdimm_fwa_state (*activate_state)(struct nvdimm *nvdimm);
243+ enum nvdimm_fwa_result (*activate_result)(struct nvdimm *nvdimm);
244+ int (*arm)(struct nvdimm *nvdimm, enum nvdimm_fwa_trigger arg);
245+};
246+
203247 void badrange_init(struct badrange *badrange);
204248 int badrange_add(struct badrange *badrange, u64 addr, u64 length);
205249 void badrange_forget(struct badrange *badrange, phys_addr_t start,
include/linux/suspend.h+6−0
@@ -453,6 +453,8 @@ extern bool hibernation_available(void); · 452 unmodified lines
453453 asmlinkage int swsusp_save(void);
454454 extern struct pbe *restore_pblist;
455455 int pfn_is_nosave(unsigned long pfn);
456+
457+int hibernate_quiet_exec(int (*func)(void *data), void *data);
456458 #else /* CONFIG_HIBERNATION */
457459 static inline void register_nosave_region(unsigned long b, unsigned long e) {}
458460 static inline void register_nosave_region_late(unsigned long b, unsigned long e) {}
@@ -464,6 +466,10 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op · 5 unmodified lines
464466 static inline int hibernate(void) { return -ENOSYS; }
465467 static inline bool system_entering_hibernation(void) { return false; }
466468 static inline bool hibernation_available(void) { return false; }
469+
470+static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) {
471+ return -ENOTSUPP;
472+}
467473 #endif /* CONFIG_HIBERNATION */
468474
469475 #ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t