|
|
@@ -61,6 +61,10 @@ module_param(default_ps_max_latency_us, ulong, 0644);
|
|
|
MODULE_PARM_DESC(default_ps_max_latency_us,
|
|
|
"max power saving latency for new devices; use PM QOS to change per device");
|
|
|
|
|
|
+static bool force_apst;
|
|
|
+module_param(force_apst, bool, 0644);
|
|
|
+MODULE_PARM_DESC(force_apst, "allow APST for newly enumerated devices even if quirked off");
|
|
|
+
|
|
|
static LIST_HEAD(nvme_ctrl_list);
|
|
|
static DEFINE_SPINLOCK(dev_list_lock);
|
|
|
|
|
|
@@ -1562,6 +1566,11 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (force_apst && (ctrl->quirks & NVME_QUIRK_NO_DEEPEST_PS)) {
|
|
|
+ dev_warn(ctrl->dev, "forcibly allowing all power states due to nvme_core.force_apst -- use at your own risk\n");
|
|
|
+ ctrl->quirks &= ~NVME_QUIRK_NO_DEEPEST_PS;
|
|
|
+ }
|
|
|
+
|
|
|
ctrl->oacs = le16_to_cpu(id->oacs);
|
|
|
ctrl->vid = le16_to_cpu(id->vid);
|
|
|
ctrl->oncs = le16_to_cpup(&id->oncs);
|
|
|
@@ -1584,7 +1593,16 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
|
|
|
|
|
|
ctrl->npss = id->npss;
|
|
|
prev_apsta = ctrl->apsta;
|
|
|
- ctrl->apsta = (ctrl->quirks & NVME_QUIRK_NO_APST) ? 0 : id->apsta;
|
|
|
+ if (ctrl->quirks & NVME_QUIRK_NO_APST) {
|
|
|
+ if (force_apst && id->apsta) {
|
|
|
+ dev_warn(ctrl->dev, "forcibly allowing APST due to nvme_core.force_apst -- use at your own risk\n");
|
|
|
+ ctrl->apsta = 1;
|
|
|
+ } else {
|
|
|
+ ctrl->apsta = 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ctrl->apsta = id->apsta;
|
|
|
+ }
|
|
|
memcpy(ctrl->psd, id->psd, sizeof(ctrl->psd));
|
|
|
|
|
|
if (ctrl->ops->is_fabrics) {
|