]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
platform: nvadsp: Reload firmware in recovery
authorAjay Nandakumar <anandakumarm@nvidia.com>
Wed, 13 Aug 2014 08:06:41 +0000 (13:36 +0530)
committerTom Cherry <tcherry@nvidia.com>
Mon, 18 Aug 2014 22:56:39 +0000 (15:56 -0700)
Reload firmware to memory when adsp os is restarting after a hang/crash. This
is done in order to make sure that the values in the data segment are restored
to their original values.

bug 200020631

Change-Id: Icf94e11eb1166de6db0d0673003f36af5bd0bacb
Signed-off-by: Ajay Nandakumar <anandakumarm@nvidia.com>
Reviewed-on: http://git-master/r/456015
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Nitin Kumbhar <nkumbhar@nvidia.com>
drivers/platform/tegra/nvadsp/os.c

index e565f9577244a43793418e9955d55a1ce8edd96b..1b6c059e784fb81e4e414d40458b4f0b9d8e9614 100644 (file)
@@ -112,6 +112,7 @@ struct nvadsp_os_data {
 #if !CONFIG_SYSTEM_FPGA
        void __iomem            *reset_reg;
 #endif
+       const struct firmware   *os_firmware;
        struct platform_device  *pdev;
        struct global_sym_info  *adsp_glo_sym_tbl;
        void __iomem            *misc_base;
@@ -671,6 +672,7 @@ int nvadsp_os_load(void)
        }
        ptr = get_mailbox_shared_region();
        update_nvadsp_app_shared_ptr(ptr);
+       priv.os_firmware = fw;
 
        return 0;
 
@@ -754,7 +756,9 @@ static void nvadsp_os_restart(struct work_struct *work)
 {
        struct nvadsp_os_data *data =
                container_of(work, struct nvadsp_os_data, restart_os_work);
+       const struct firmware *fw = data->os_firmware;
        struct device *dev = &data->pdev->dev;
+       int ret;
 
        data->adsp_num_crashes++;
        if (data->adsp_num_crashes >= ALLOWED_CRASHES) {
@@ -764,6 +768,13 @@ static void nvadsp_os_restart(struct work_struct *work)
                return;
        }
 
+       /* reload a fresh copy of the firmware*/
+       ret = nvadsp_os_elf_load(fw);
+       if (ret) {
+               dev_err(dev, "failed to load %s\n", NVADSP_FIRMWARE);
+               return;
+       }
+
        if (nvadsp_os_start())
                dev_crit(dev, "Unable to restart ADSP OS\n");
 }