* @IPA_LOADER_DEFER: System not ready; try again later
* @IPA_LOADER_SELF: AP loads GSI firmware
* @IPA_LOADER_MODEM: Modem loads GSI firmware, signals when done
+ * @IPA_LOADER_INVALID: GSI firmware loader specification is invalid
*/
enum ipa_firmware_loader {
IPA_LOADER_DEFER,
IPA_LOADER_SELF,
IPA_LOADER_MODEM,
+ IPA_LOADER_INVALID,
};
/**
static enum ipa_firmware_loader ipa_firmware_loader(struct device *dev)
{
- if (of_property_read_bool(dev->of_node, "modem-init"))
+ bool modem_init;
+ const char *str;
+ int ret;
+
+ /* Look up the old and new properties by name */
+ modem_init = of_property_read_bool(dev->of_node, "modem-init");
+ ret = of_property_read_string(dev->of_node, "qcom,gsi-loader", &str);
+
+ /* If the new property doesn't exist, it's legacy behavior */
+ if (ret == -EINVAL) {
+ if (modem_init)
+ return IPA_LOADER_MODEM;
+ goto out_self;
+ }
+
+ /* Any other error on the new property means it's poorly defined */
+ if (ret)
+ return IPA_LOADER_INVALID;
+
+ /* New property value exists; if old one does too, that's invalid */
+ if (modem_init)
+ return IPA_LOADER_INVALID;
+
+ /* Modem loads GSI firmware for "modem" */
+ if (!strcmp(str, "modem"))
return IPA_LOADER_MODEM;
+ /* Any value other than "self" is an error */
+ if (strcmp(str, "self"))
+ return IPA_LOADER_INVALID;
+out_self:
/* We need Trust Zone to load firmware; make sure it's available */
if (qcom_scm_is_available())
return IPA_LOADER_SELF;
}
loader = ipa_firmware_loader(dev);
+ if (loader == IPA_LOADER_INVALID)
+ return -EINVAL;
if (loader == IPA_LOADER_DEFER)
return -EPROBE_DEFER;
dev_info(dev, "IPA driver initialized");
- /* If the modem is doing early initialization, it will trigger a
- * call to ipa_setup() when it has finished. In that case we're
- * done here.
+ /* If the modem is loading GSI firmware, it will trigger a call to
+ * ipa_setup() when it has finished. In that case we're done here.
*/
if (loader == IPA_LOADER_MODEM)
goto done;
- /* Otherwise we need to load the firmware and have Trust Zone validate
- * and install it. If that succeeds we can proceed with setup.
- */
+ /* The AP is loading GSI firmware; do so now */
ret = ipa_firmware_load(dev);
if (ret)
goto err_deconfig;
+ /* GSI firmware is loaded; proceed to setup */
ret = ipa_setup(ipa);
if (ret)
goto err_deconfig;