Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 651944d1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss: remove dummy code to reduce the device initialization latency"

parents 6bd3239a e61815f3
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
# Makefile for CNSS platform driver

obj-$(CONFIG_CNSS)	+= cnss_pci.o
obj-$(CONFIG_CNSS)	+= cnss_sdio.o
obj-$(CONFIG_CNSS_LOGGER)	+= logger/

obj-$(CONFIG_CNSS_PCI)	+= cnss_pci.o
obj-$(CONFIG_CNSS_SDIO)	+= cnss_sdio.o
obj-$(CONFIG_CNSS)	+= cnss_common.o
obj-$(CONFIG_CNSS_LOGGER)	+= logger/
+46 −127
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -263,186 +263,105 @@ void cnss_dump_stack(struct task_struct *task)
}
EXPORT_SYMBOL(cnss_dump_stack);

enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
struct cnss_dev_platform_ops *cnss_get_platform_ops(struct device *dev)
{
	if (!dev)
		return CNSS_BUS_NONE;

	if (!dev->bus)
		return CNSS_BUS_NONE;

	if (memcmp(dev->bus->name, "sdio", 4) == 0)
		return CNSS_BUS_SDIO;
	else if (memcmp(dev->bus->name, "pci", 3) == 0)
		return CNSS_BUS_PCI;
		return NULL;
	else
		return CNSS_BUS_NONE;
		return dev->platform_data;
}

int cnss_common_request_bus_bandwidth(struct device *dev, int bandwidth)
{
	int ret;

	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_SDIO:
		ret = cnss_sdio_request_bus_bandwidth(bandwidth);
		break;
	case CNSS_BUS_PCI:
		ret = cnss_pci_request_bus_bandwidth(bandwidth);
		break;
	default:
		pr_debug("%s: Invalid device type\n", __func__);
		ret = -EINVAL;
		break;
	}
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	return ret;
	if (pf_ops && pf_ops->request_bus_bandwidth)
		return pf_ops->request_bus_bandwidth(bandwidth);
	else
		return -EINVAL;
}
EXPORT_SYMBOL(cnss_common_request_bus_bandwidth);

void *cnss_common_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
{
	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_SDIO:
		return cnss_sdio_get_virt_ramdump_mem(size);
	case CNSS_BUS_PCI:
		return cnss_pci_get_virt_ramdump_mem(size);
	default:
		pr_debug("%s: Invalid device type\n", __func__);
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	if (pf_ops && pf_ops->get_virt_ramdump_mem)
		return pf_ops->get_virt_ramdump_mem(size);
	else
		return NULL;
}
}
EXPORT_SYMBOL(cnss_common_get_virt_ramdump_mem);

void cnss_common_device_self_recovery(struct device *dev)
{
	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_SDIO:
		cnss_sdio_device_self_recovery();
		break;
	case CNSS_BUS_PCI:
		cnss_pci_device_self_recovery();
		break;
	default:
		pr_debug("%s: Invalid device type\n", __func__);
		break;
	}
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	if (pf_ops && pf_ops->device_self_recovery)
		pf_ops->device_self_recovery();
}
EXPORT_SYMBOL(cnss_common_device_self_recovery);

void cnss_common_schedule_recovery_work(struct device *dev)
{
	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_SDIO:
		cnss_sdio_schedule_recovery_work();
		break;
	case CNSS_BUS_PCI:
		cnss_pci_schedule_recovery_work();
		break;
	default:
		pr_debug("%s: Invalid device type\n", __func__);
		break;
	}
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	if (pf_ops && pf_ops->schedule_recovery_work)
		pf_ops->schedule_recovery_work();
}
EXPORT_SYMBOL(cnss_common_schedule_recovery_work);

void cnss_common_device_crashed(struct device *dev)
{
	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_SDIO:
		cnss_sdio_device_crashed();
		break;
	case CNSS_BUS_PCI:
		cnss_pci_device_crashed();
		break;
	default:
		pr_debug("%s: Invalid device type\n", __func__);
		break;
	}
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	if (pf_ops && pf_ops->device_crashed)
		pf_ops->device_crashed();
}
EXPORT_SYMBOL(cnss_common_device_crashed);

u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num)
{
	u8 *ret;
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_SDIO:
		ret = cnss_sdio_get_wlan_mac_address(num);
		break;
	case CNSS_BUS_PCI:
		ret = cnss_pci_get_wlan_mac_address(num);
		break;
	default:
		pr_debug("%s: Invalid device type\n", __func__);
		ret = NULL;
		break;
	}
	return ret;
	if (pf_ops && pf_ops->get_wlan_mac_address)
		return pf_ops->get_wlan_mac_address(num);
	else
		return NULL;
}
EXPORT_SYMBOL(cnss_common_get_wlan_mac_address);

int cnss_common_set_wlan_mac_address(
		struct device *dev, const u8 *in, uint32_t len)
{
	int ret;
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_SDIO:
		ret = cnss_sdio_set_wlan_mac_address(in, len);
		break;
	case CNSS_BUS_PCI:
		ret = cnss_pcie_set_wlan_mac_address(in, len);
		break;
	default:
		pr_debug("%s: Invalid device type\n", __func__);
		ret = -EINVAL;
		break;
	}

	return ret;
	if (pf_ops && pf_ops->set_wlan_mac_address)
		return pf_ops->set_wlan_mac_address(in, len);
	else
		return -EINVAL;
}
EXPORT_SYMBOL(cnss_common_set_wlan_mac_address);

int cnss_power_up(struct device *dev)
{
	int ret;
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_PCI:
		ret = cnss_pcie_power_up(dev);
		break;
	case CNSS_BUS_SDIO:
		ret = cnss_sdio_power_up(dev);
		break;
	default:
		pr_err("%s: Invalid Bus Type\n", __func__);
		ret = -EINVAL;
		break;
	}

	return ret;
	if (pf_ops && pf_ops->power_up)
		return pf_ops->power_up(dev);
	else
		return -EINVAL;
}
EXPORT_SYMBOL(cnss_power_up);

int cnss_power_down(struct device *dev)
{
	int ret;
	struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev);

	switch (cnss_get_dev_bus_type(dev)) {
	case CNSS_BUS_PCI:
		ret = cnss_pcie_power_down(dev);
		break;
	case CNSS_BUS_SDIO:
		ret = cnss_sdio_power_down(dev);
		break;
	default:
		pr_err("%s: Invalid Bus Type\n", __func__);
		ret = -EINVAL;
		break;
	}

	return ret;
	if (pf_ops && pf_ops->power_down)
		return pf_ops->power_down(dev);
	else
		return -EINVAL;
}
EXPORT_SYMBOL(cnss_power_down);

+13 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -16,6 +16,18 @@
/* max 20mhz channel count */
#define CNSS_MAX_CH_NUM		45

struct cnss_dev_platform_ops {
	int (*request_bus_bandwidth)(int bandwidth);
	void* (*get_virt_ramdump_mem)(unsigned long *size);
	void (*device_self_recovery)(void);
	void (*schedule_recovery_work)(void);
	void (*device_crashed)(void);
	u8 * (*get_wlan_mac_address)(uint32_t *num);
	int (*set_wlan_mac_address)(const u8 *in, uint32_t len);
	int (*power_up)(struct device *dev);
	int (*power_down)(struct device *dev);
};

int cnss_pci_request_bus_bandwidth(int bandwidth);
int cnss_sdio_request_bus_bandwidth(int bandwidth);

+30 −33
Original line number Diff line number Diff line
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -29,7 +29,6 @@
#include <linux/pm_qos.h>
#include <linux/pm_runtime.h>
#include <linux/esoc_client.h>
#include <linux/pinctrl/consumer.h>
#include <linux/firmware.h>
#include <linux/dma-mapping.h>
#include <linux/msm-bus.h>
@@ -123,7 +122,6 @@
#define PCIE_ENABLE_DELAY	100
#define WLAN_BOOTSTRAP_DELAY	10
#define EVICT_BIN_MAX_SIZE      (512*1024)
#define CNSS_PINCTRL_STATE_ACTIVE "default"

static DEFINE_SPINLOCK(pci_link_down_lock);

@@ -153,8 +151,6 @@ struct cnss_wlan_gpio_info {
	bool state;
	bool init;
	bool prop;
	struct pinctrl *pinctrl;
	struct pinctrl_state *gpio_state_default;
};

struct cnss_wlan_vreg_info {
@@ -288,6 +284,7 @@ static struct cnss_data {
	atomic_t auto_suspended;
	bool monitor_wake_intr;
	struct cnss_dual_wifi dual_wifi_info;
	struct cnss_dev_platform_ops platform_ops;
} *penv;

static unsigned int pcie_link_down_panic;
@@ -603,30 +600,6 @@ static int cnss_configure_wlan_en_gpio(bool state)
	return ret;
}

static int cnss_pinctrl_init(struct cnss_wlan_gpio_info *gpio_info,
			     struct platform_device *pdev)
{
	int ret;

	gpio_info->pinctrl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR_OR_NULL(gpio_info->pinctrl)) {
		pr_err("%s: Failed to get pinctrl!\n", __func__);
		return PTR_ERR(gpio_info->pinctrl);
	}

	gpio_info->gpio_state_default = pinctrl_lookup_state(gpio_info->pinctrl,
		CNSS_PINCTRL_STATE_ACTIVE);
	if (IS_ERR_OR_NULL(gpio_info->gpio_state_default)) {
		pr_err("%s: Can not get active pin state!\n", __func__);
		return PTR_ERR(gpio_info->gpio_state_default);
	}

	ret = pinctrl_select_state(gpio_info->pinctrl,
				   gpio_info->gpio_state_default);

	return ret;
}

static void cnss_disable_xtal_ldo(struct platform_device *pdev)
{
	struct cnss_wlan_vreg_info *info = &penv->vreg_info;
@@ -734,10 +707,6 @@ static int cnss_get_wlan_enable_gpio(
			"can't get gpio %s ret %d", gpio_info->name, ret);
	}

	ret = cnss_pinctrl_init(gpio_info, pdev);
	if (ret)
		pr_debug("%s: pinctrl init failed!\n", __func__);

	ret = cnss_wlan_gpio_init(gpio_info);
	if (ret)
		pr_err("gpio init failed\n");
@@ -1608,6 +1577,31 @@ int cnss_msm_pcie_enumerate(u32 rc_idx)
}
#endif

static void cnss_pcie_set_platform_ops(struct device *dev)
{
	struct cnss_dev_platform_ops *pf_ops = &penv->platform_ops;

	pf_ops->request_bus_bandwidth = cnss_pci_request_bus_bandwidth;
	pf_ops->get_virt_ramdump_mem = cnss_pci_get_virt_ramdump_mem;
	pf_ops->device_self_recovery = cnss_pci_device_self_recovery;
	pf_ops->schedule_recovery_work = cnss_pci_schedule_recovery_work;
	pf_ops->device_crashed = cnss_pci_device_crashed;
	pf_ops->get_wlan_mac_address = cnss_pci_get_wlan_mac_address;
	pf_ops->set_wlan_mac_address = cnss_pcie_set_wlan_mac_address;
	pf_ops->power_up = cnss_pcie_power_up;
	pf_ops->power_down = cnss_pcie_power_down;

	dev->platform_data = pf_ops;
}

static void cnss_pcie_reset_platform_ops(struct device *dev)
{
	struct cnss_dev_platform_ops *pf_ops = &penv->platform_ops;

	memset(pf_ops, 0, sizeof(struct cnss_dev_platform_ops));
	dev->platform_data = NULL;
}

static int cnss_wlan_pci_probe(struct pci_dev *pdev,
			       const struct pci_device_id *id)
{
@@ -1618,6 +1612,7 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev,
	struct codeswap_codeseg_info *cnss_seg_info = NULL;
	struct device *dev = &pdev->dev;

	cnss_pcie_set_platform_ops(dev);
	penv->pdev = pdev;
	penv->id = id;
	penv->fw_available = false;
@@ -1726,6 +1721,7 @@ end_dma_alloc:
err_unknown:
err_pcie_suspend:
smmu_init_fail:
	cnss_pcie_reset_platform_ops(dev);
	return ret;
}

@@ -1737,6 +1733,7 @@ static void cnss_wlan_pci_remove(struct pci_dev *pdev)
		return;

	dev = &penv->pldev->dev;
	cnss_pcie_reset_platform_ops(dev);
	device_remove_file(dev, &dev_attr_wlan_setup);

	if (penv->smmu_mapping)
+35 −3
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -112,6 +112,7 @@ static struct cnss_sdio_data {
	struct pm_qos_request qos_request;
	struct cnss_wlan_pinctrl_info pinctrl_info;
	struct cnss_sdio_bus_bandwidth bus_bandwidth;
	struct cnss_dev_platform_ops platform_ops;
} *cnss_pdata;

#define WLAN_RECOVERY_DELAY 1
@@ -685,6 +686,23 @@ int cnss_get_restart_level(void)
}
EXPORT_SYMBOL(cnss_get_restart_level);

static void cnss_sdio_set_platform_ops(struct device *dev)
{
	struct cnss_dev_platform_ops *pf_ops = &cnss_pdata->platform_ops;

	pf_ops->power_up = cnss_sdio_power_up;
	pf_ops->power_down = cnss_sdio_power_down;
	pf_ops->device_crashed = cnss_sdio_device_crashed;
	pf_ops->get_virt_ramdump_mem = cnss_sdio_get_virt_ramdump_mem;
	pf_ops->device_self_recovery = cnss_sdio_device_self_recovery;
	pf_ops->get_wlan_mac_address = cnss_sdio_get_wlan_mac_address;
	pf_ops->set_wlan_mac_address = cnss_sdio_set_wlan_mac_address;
	pf_ops->schedule_recovery_work = cnss_sdio_schedule_recovery_work;
	pf_ops->request_bus_bandwidth = cnss_sdio_request_bus_bandwidth;

	dev->platform_data = pf_ops;
}

static int cnss_sdio_wlan_inserted(struct sdio_func *func,
				   const struct sdio_device_id *id)
{
@@ -700,6 +718,7 @@ static int cnss_sdio_wlan_inserted(struct sdio_func *func,
	info->host = func->card->host;
	info->id = id;
	info->dev = &func->dev;
	cnss_sdio_set_platform_ops(info->dev);

	cnss_put_hw_resources(cnss_pdata->cnss_sdio_info.dev);

@@ -993,15 +1012,27 @@ int cnss_wlan_unregister_oob_irq_handler(void *pm_oob)
}
EXPORT_SYMBOL(cnss_wlan_unregister_oob_irq_handler);

static void cnss_sdio_reset_platform_ops(void)
{
	struct cnss_dev_platform_ops *pf_ops = &cnss_pdata->platform_ops;
	struct cnss_sdio_info *sdio_info = &cnss_pdata->cnss_sdio_info;

	memset(pf_ops, 0, sizeof(struct cnss_dev_platform_ops));
	if (sdio_info->dev)
		sdio_info->dev->platform_data = NULL;
}

static int cnss_sdio_wlan_init(void)
{
	int error = 0;

	error = sdio_register_driver(&cnss_ar6k_driver);
	if (error)
	if (error) {
		cnss_sdio_reset_platform_ops();
		pr_err("registered fail error=%d\n", error);
	else
	} else {
		pr_debug("registered success\n");
	}

	return error;
}
@@ -1011,6 +1042,7 @@ static void cnss_sdio_wlan_exit(void)
	if (!cnss_pdata)
		return;

	cnss_sdio_reset_platform_ops();
	sdio_unregister_driver(&cnss_ar6k_driver);
}