/* Riva crash handler */
static void riva_crash_shutdown(const struct subsys_data *subsys)
{
	pr_err("%s: crash shutdown : %d\n", MODULE_NAME, riva_crash);

    //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
    ASUSEvtlog("[wcnss]: riva_crash_shutdown (%d).\n", riva_crash);
    //ASUS_BSP--- "for /data/log/ASUSEvtlog"

//ASUS_BSP+++ "Qualcomm  (1-Wait_for_WCNSS_to_finish_its_error_fatal_routines_during_SSR.patch)"
//ASUS_BSP+++ "Qualcomm  (2-wcnss_fix_panic_leading_to_WD_bark.patch)"
#if 0
	if (riva_crash != true)
		smsm_riva_reset();
#else
    if (riva_crash != true) {
        smsm_riva_reset();
        /* give sufficient time for wcnss to finish it's error
         * fatal routine */
        pr_err("wcnss_8960: mdelay(3000), give sufficient time for wcnss.\n");
        mdelay(3000);
    }
#endif
//ASUS_BSP--- "Qualcomm  (2-wcnss_fix_panic_leading_to_WD_bark.patch)"
//ASUS_BSP--- "Qualcomm  (1-Wait_for_WCNSS_to_finish_its_error_fatal_routines_during_SSR.patch)"
}
static void wcnss_post_bootup(struct work_struct *work)
{
	pr_info("%s: Cancel APPS vote for Iris & Riva\n", __func__);

    //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
    ASUSEvtlog("[wcnss]: wcnss_post_bootup, Cancel APPS vote for Iris & Riva.\n");
    //ASUS_BSP--- "for /data/log/ASUSEvtlog"

	/* Since Riva is up, cancel any APPS vote for Iris & Riva VREGs  */
	wcnss_wlan_power(&penv->pdev->dev, &penv->wlan_config,
		WCNSS_WLAN_SWITCH_OFF);
}
static void smsm_state_cb_hdlr(void *data, uint32_t old_state,
					uint32_t new_state)
{
	char *smem_reset_reason;
	char buffer[MAX_BUF_SIZE];
	unsigned smem_reset_size;
	unsigned size;

	riva_crash = true;

	pr_err("%s: smsm state changed\n", MODULE_NAME);

	if (!(new_state & SMSM_RESET))
		return;

	if (ss_restart_inprogress) {
		pr_err("%s: Ignoring smsm reset req, restart in progress\n",
						MODULE_NAME);
		return;
	}

    pr_info(MODULE_NAME ": smsm_state_cb_hdlr, enable_riva_ssr=%d.\n", enable_riva_ssr);

    //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
    ASUSEvtlog("[wcnss]: smsm_state_cb_hdlr, enable_riva_ssr=%d.\n", enable_riva_ssr);
    //ASUS_BSP--- "for /data/log/ASUSEvtlog"

	if (!enable_riva_ssr)
		panic(MODULE_NAME ": SMSM reset request received from Riva");

	smem_reset_reason = smem_get_entry(SMEM_SSR_REASON_WCNSS0,
			&smem_reset_size);

	if (!smem_reset_reason || !smem_reset_size) {
		pr_err("%s: wcnss subsystem failure reason: %s\n",
				__func__, "(unknown, smem_get_entry failed)");
	} else if (!smem_reset_reason[0]) {
		pr_err("%s: wcnss subsystem failure reason: %s\n",
				__func__, "(unknown, init string found)");
	} else {
		size = smem_reset_size < MAX_BUF_SIZE ? smem_reset_size :
			(MAX_BUF_SIZE - 1);
		memcpy(buffer, smem_reset_reason, size);
		buffer[size] = '\0';
		pr_err("%s: wcnss subsystem failure reason: %s\n",
				__func__, buffer);
		memset(smem_reset_reason, 0, smem_reset_size);
		wmb();
	}

	ss_restart_inprogress = true;
	subsystem_restart("riva");
}
/* SMSM reset Riva */
static void smsm_riva_reset(void)
{
    pr_info(MODULE_NAME ": smsm_riva_reset, smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET).\n");

    //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
    ASUSEvtlog("[wcnss]: smsm_riva_reset, smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET).\n");
    //ASUS_BSP--- "for /data/log/ASUSEvtlog"

	/* per SS reset request bit is not available now,
	 * all SS host modules are setting this bit
	 * This is still under discussion*/
	smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET);
}
static void riva_post_bootup(struct work_struct *work)
{
	struct platform_device *pdev = wcnss_get_platform_device();
	struct wcnss_wlan_config *pwlanconfig = wcnss_get_wlan_config();

    pr_debug(MODULE_NAME ": riva_post_bootup, Cancel APPS vote for Iris & Riva\n");

    //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
    ASUSEvtlog("[wcnss]: riva_post_bootup, Cancel APPS vote for Iris & Riva.\n");
    //ASUS_BSP--- "for /data/log/ASUSEvtlog"

	wcnss_wlan_power(&pdev->dev, pwlanconfig,
		WCNSS_WLAN_SWITCH_OFF);
}
/* Subsystem handlers */
static int riva_shutdown(const struct subsys_data *subsys)
{
    pr_info(MODULE_NAME ": riva_shutdown.\n");

    //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
    ASUSEvtlog("[wcnss]: riva_shutdown.\n");
    //ASUS_BSP--- "for /data/log/ASUSEvtlog"

	pil_force_shutdown("wcnss");
	flush_delayed_work(&cancel_vote_work);
	wcnss_flush_delayed_boot_votes();
	disable_irq_nosync(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);

	return 0;
}
Пример #7
0
static void mdm_restart_reason_fn(struct work_struct *work)
{
	int ret, ntries = 0;
	char sfr_buf[RD_BUF_SIZE];

	do {
		msleep(SFR_RETRY_INTERVAL);
		ret = sysmon_get_reason(SYSMON_SS_EXT_MODEM,
					sfr_buf, sizeof(sfr_buf));
		if (ret) {
			/*
			 * The sysmon device may not have been probed as yet
			 * after the restart.
			 */
			pr_err("%s: Error retrieving mdm restart reason, ret = %d, "
					"%d/%d tries\n", __func__, ret,
					ntries + 1,	SFR_MAX_RETRIES);
		} else {
// ASUS_BSP+++ Wenli "Modify for modem restart"
#ifndef ASUS_SHIP_BUILD
			int file_handle;
			mm_segment_t oldfs;

			oldfs = get_fs();
			set_fs(KERNEL_DS);
			file_handle = sys_open("/data/log/modem_crash.log", O_CREAT|O_WRONLY|O_SYNC|O_TRUNC, 0644);
			if(!IS_ERR((const void *)file_handle))
			{
				ret = sys_write(file_handle, sfr_buf, strlen(sfr_buf));
				sys_close(file_handle);
			}
			// Save reason on 
			file_handle = sys_open("/data/log/RAMDump0/reason.log", O_CREAT|O_WRONLY|O_SYNC|O_TRUNC, 0644);
			if(!IS_ERR((const void *)file_handle))
			{
				ret = sys_write(file_handle, sfr_buf, strlen(sfr_buf));
				sys_close(file_handle);
			}
			set_fs(oldfs);
#endif
// ASUS_BSP--- Wenli "Modify for modem restart"
			ASUSEvtlog("SSR %s\n", sfr_buf);
			pr_err("mdm restart reason: %s\n", sfr_buf);
			break;
		}
	} while (++ntries < SFR_MAX_RETRIES);
}
static irqreturn_t riva_wdog_bite_irq_hdlr(int irq, void *dev_id)
{
    pr_info(MODULE_NAME ": riva_wdog_bite_irq_hdlr, enable_riva_ssr=%d.\n", enable_riva_ssr);

    //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
    ASUSEvtlog("[wcnss]: riva_wdog_bite_irq_hdlr, enable_riva_ssr=%d.\n", enable_riva_ssr);
    //ASUS_BSP--- "for /data/log/ASUSEvtlog"

	riva_crash = true;

	if (ss_restart_inprogress) {
		pr_err("%s: Ignoring riva bite irq, restart in progress\n",
						MODULE_NAME);
		return IRQ_HANDLED;
	}

	if (!enable_riva_ssr)
		panic(MODULE_NAME ": Watchdog bite received from Riva");

	ss_restart_inprogress = true;
	subsystem_restart("riva");

	return IRQ_HANDLED;
}
static int
wcnss_trigger_config(struct platform_device *pdev)
{
	int ret;
	struct qcom_wcnss_opts *pdata;

	/* make sure we are only triggered once */
	if (penv->triggered)
		return 0;
	penv->triggered = 1;

	/* initialize the WCNSS device configuration */
	pdata = pdev->dev.platform_data;
	if (WCNSS_CONFIG_UNSPECIFIED == has_48mhz_xo)
		has_48mhz_xo = pdata->has_48mhz_xo;

    pr_info("[wcnss]: has_48mhz_xo=%d.\n", has_48mhz_xo);

	penv->wlan_config.use_48mhz_xo = has_48mhz_xo;

	penv->thermal_mitigation = 0;

	penv->gpios_5wire = platform_get_resource_byname(pdev, IORESOURCE_IO,
							"wcnss_gpios_5wire");

	/* allocate 5-wire GPIO resources */
	if (!penv->gpios_5wire) {
		dev_err(&pdev->dev, "insufficient IO resources\n");
		ret = -ENOENT;
		goto fail_gpio_res;
	}

	/* Configure 5 wire GPIOs */
	ret = wcnss_gpios_config(penv->gpios_5wire, true);
	if (ret) {
		dev_err(&pdev->dev, "WCNSS gpios config failed.\n");
		goto fail_gpio_res;
	}

	/* power up the WCNSS */
	ret = wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
					WCNSS_WLAN_SWITCH_ON);
	if (ret) {
		dev_err(&pdev->dev, "WCNSS Power-up failed.\n");
		goto fail_power;
	}

	/* trigger initialization of the WCNSS */
	penv->pil = pil_get(WCNSS_PIL_DEVICE);
	if (IS_ERR(penv->pil)) {
		dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n");

        //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
        ASUSEvtlog("[wcnss]: Load WCNSS failed.\n");
        //ASUS_BSP--- "for /data/log/ASUSEvtlog"

		ret = PTR_ERR(penv->pil);
		penv->pil = NULL;
		goto fail_pil;
	}
    else {
        pr_info("[wcnss]: Load WCNSS image ok.\n");

        //ASUS_BSP+++ "for /data/log/ASUSEvtlog"
        ASUSEvtlog("[wcnss]: Load WCNSS image ok.\n");
        //ASUS_BSP--- "for /data/log/ASUSEvtlog"
    }

	/* allocate resources */
	penv->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							"wcnss_mmio");
	penv->tx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
							"wcnss_wlantx_irq");
	penv->rx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
							"wcnss_wlanrx_irq");

	if (!(penv->mmio_res && penv->tx_irq_res && penv->rx_irq_res)) {
		dev_err(&pdev->dev, "insufficient resources\n");
		ret = -ENOENT;
		goto fail_res;
	}

	/* register sysfs entries */
	ret = wcnss_create_sysfs(&pdev->dev);
	if (ret)
		goto fail_sysfs;

	return 0;

fail_sysfs:
fail_res:
	if (penv->pil)
		pil_put(penv->pil);
fail_pil:
	wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
				WCNSS_WLAN_SWITCH_OFF);
fail_power:
	wcnss_gpios_config(penv->gpios_5wire, false);
fail_gpio_res:
	kfree(penv);
	penv = NULL;
	return ret;
}