qcacld-3.0: Add PLD layer for iWCN architecture

Add PLD layer and introdue IPCI bus type for iWCN architecture.

Change-Id: Ia0164314c539df84205263de16432eec0eb7fb34
Šī revīzija ir iekļauta:
Naman Padhiar
2019-12-09 23:01:12 +05:30
revīziju iesūtīja nshrivas
vecāks 73061b9180
revīzija 07f0c719e2
5 mainīti faili ar 731 papildinājumiem un 3 dzēšanām

Parādīt failu

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -51,6 +51,7 @@
* @PLD_BUS_TYPE_USB : USB bus
* @PLD_BUS_TYPE_SNOC_FW_SIM : SNOC FW SIM bus
* @PLD_BUS_TYPE_PCIE_FW_SIM : PCIE FW SIM bus
* @PLD_BUS_TYPE_IPCI : IPCI bus
*/
enum pld_bus_type {
PLD_BUS_TYPE_NONE = -1,
@@ -60,6 +61,7 @@ enum pld_bus_type {
PLD_BUS_TYPE_USB,
PLD_BUS_TYPE_SNOC_FW_SIM,
PLD_BUS_TYPE_PCIE_FW_SIM,
PLD_BUS_TYPE_IPCI,
};
#define PLD_MAX_FIRMWARE_SIZE (1 * 1024 * 1024)

Parādīt failu

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -34,8 +34,12 @@
#ifdef CONFIG_PLD_SNOC_ICNSS
#include <soc/qcom/icnss.h>
#endif
#ifdef CONFIG_PLD_IPCI_ICNSS
#include <soc/qcom/icnss2.h>
#endif
#include "pld_pcie.h"
#include "pld_ipci.h"
#include "pld_pcie_fw_sim.h"
#include "pld_snoc_fw_sim.h"
#include "pld_snoc.h"
@@ -49,6 +53,8 @@
#define PLD_USB_REGISTERED BIT(3)
#define PLD_SNOC_FW_SIM_REGISTERED BIT(4)
#define PLD_PCIE_FW_SIM_REGISTERED BIT(5)
#define PLD_IPCI_REGISTERED BIT(6)
#define PLD_BUS_MASK 0xf
static struct pld_context *pld_ctx;
@@ -313,8 +319,17 @@ int pld_register_driver(struct pld_driver_ops *ops)
}
pld_context->pld_driver_state |= PLD_USB_REGISTERED;
ret = pld_ipci_register_driver();
if (ret) {
pr_err("Fail to register ipci driver\n");
goto fail_ipci;
}
pld_context->pld_driver_state |= PLD_IPCI_REGISTERED;
return ret;
fail_ipci:
pld_usb_unregister_driver();
fail_usb:
pld_pcie_fw_sim_unregister_driver();
fail_pcie_fw_sim:
@@ -363,6 +378,7 @@ void pld_unregister_driver(void)
pld_snoc_unregister_driver();
pld_sdio_unregister_driver();
pld_usb_unregister_driver();
pld_ipci_unregister_driver();
pld_context->pld_driver_state = 0;
@@ -410,6 +426,9 @@ int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
ret = pld_usb_wlan_enable(ifdev, config, mode,
QWLAN_VERSIONSTR);
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_wlan_enable(dev, config, mode, QWLAN_VERSIONSTR);
break;
default:
ret = -EINVAL;
break;
@@ -447,6 +466,9 @@ int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_wlan_disable(dev, mode);
break;
default:
ret = -EINVAL;
break;
@@ -480,6 +502,9 @@ int pld_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_set_fw_log_mode(dev, fw_log_mode);
break;
default:
ret = -EINVAL;
break;
@@ -543,6 +568,7 @@ int pld_get_fw_files_for_target(struct device *dev,
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
ret = pld_sdio_get_fw_files_for_target(pfw_files,
@@ -580,6 +606,7 @@ void pld_is_pci_link_down(struct device *dev)
break;
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
@@ -606,6 +633,7 @@ void pld_schedule_recovery_work(struct device *dev,
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
@@ -639,6 +667,8 @@ int pld_wlan_pm_control(struct device *dev, bool vote)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
ret = -EINVAL;
break;
@@ -665,6 +695,7 @@ void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
mem = pld_sdio_get_virt_ramdump_mem(dev, size);
@@ -686,6 +717,7 @@ void pld_release_virt_ramdump_mem(struct device *dev, void *address)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
pld_sdio_release_virt_ramdump_mem(address);
@@ -715,6 +747,8 @@ void pld_device_crashed(struct device *dev)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
pld_sdio_device_crashed(dev);
break;
@@ -742,6 +776,8 @@ void pld_device_self_recovery(struct device *dev,
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
pld_sdio_device_self_recovery(dev);
break;
@@ -768,6 +804,7 @@ void pld_intr_notify_q6(struct device *dev)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
@@ -794,6 +831,8 @@ void pld_request_pm_qos(struct device *dev, u32 qos_val)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
/* To do Add call cns API */
break;
@@ -823,6 +862,8 @@ void pld_remove_pm_qos(struct device *dev)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
/* To do Add call cns API */
break;
@@ -854,6 +895,8 @@ int pld_request_bus_bandwidth(struct device *dev, int bandwidth)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
/* To do Add call cns API */
break;
@@ -889,6 +932,8 @@ int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
default:
@@ -926,6 +971,8 @@ int pld_get_sha_hash(struct device *dev, const u8 *data,
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
default:
@@ -953,6 +1000,7 @@ void *pld_get_fw_ptr(struct device *dev)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
@@ -983,6 +1031,8 @@ int pld_auto_suspend(struct device *dev)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
default:
@@ -1012,6 +1062,8 @@ int pld_auto_resume(struct device *dev)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
default:
@@ -1043,6 +1095,7 @@ int pld_force_wake_request(struct device *dev)
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type %d\n", type);
@@ -1075,6 +1128,7 @@ int pld_is_device_awake(struct device *dev)
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type %d\n", type);
@@ -1106,6 +1160,7 @@ int pld_force_wake_release(struct device *dev)
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type %d\n", type);
@@ -1146,6 +1201,8 @@ int pld_ce_request_irq(struct device *dev, unsigned int ce_id,
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_PCIE:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
ret = -EINVAL;
break;
@@ -1177,6 +1234,8 @@ int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_PCIE:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
ret = -EINVAL;
break;
@@ -1203,6 +1262,7 @@ void pld_enable_irq(struct device *dev, unsigned int ce_id)
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_PCIE:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
@@ -1230,6 +1290,7 @@ void pld_disable_irq(struct device *dev, unsigned int ce_id)
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_PCIE:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
@@ -1268,6 +1329,9 @@ int pld_get_soc_info(struct device *dev, struct pld_soc_info *info)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_get_soc_info(dev, info);
break;
default:
ret = -EINVAL;
break;
@@ -1299,6 +1363,8 @@ int pld_get_ce_id(struct device *dev, int irq)
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
ret = -EINVAL;
break;
@@ -1325,6 +1391,8 @@ int pld_get_irq(struct device *dev, int ce_id)
case PLD_BUS_TYPE_SNOC_FW_SIM:
ret = pld_snoc_fw_sim_get_irq(dev, ce_id);
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_PCIE:
default:
@@ -1350,6 +1418,7 @@ void pld_lock_pm_sem(struct device *dev)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
@@ -1376,6 +1445,7 @@ void pld_release_pm_sem(struct device *dev)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
@@ -1405,6 +1475,7 @@ void pld_lock_reg_window(struct device *dev, unsigned long *flags)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
@@ -1434,6 +1505,7 @@ void pld_unlock_reg_window(struct device *dev, unsigned long *flags)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
break;
@@ -1469,6 +1541,9 @@ int pld_power_on(struct device *dev)
case PLD_BUS_TYPE_SNOC:
ret = pld_snoc_power_on(dev);
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_power_on(dev);
break;
default:
pr_err("Invalid device type\n");
break;
@@ -1501,6 +1576,9 @@ int pld_power_off(struct device *dev)
case PLD_BUS_TYPE_SNOC:
ret = pld_snoc_power_off(dev);
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_power_off(dev);
break;
default:
pr_err("Invalid device type\n");
break;
@@ -1539,6 +1617,7 @@ int pld_athdiag_read(struct device *dev, uint32_t offset,
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_IPCI:
break;
default:
ret = -EINVAL;
@@ -1578,6 +1657,7 @@ int pld_athdiag_write(struct device *dev, uint32_t offset,
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_IPCI:
break;
default:
ret = -EINVAL;
@@ -1609,6 +1689,8 @@ void *pld_smmu_get_domain(struct device *dev)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
pr_err("Not supported on type %d\n", type);
@@ -1639,6 +1721,8 @@ void *pld_smmu_get_mapping(struct device *dev)
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_PCIE:
ptr = pld_pcie_smmu_get_mapping(dev);
break;
@@ -1674,6 +1758,8 @@ int pld_smmu_map(struct device *dev, phys_addr_t paddr,
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_PCIE:
ret = pld_pcie_smmu_map(dev, paddr, iova_addr, size);
break;
@@ -1725,6 +1811,12 @@ int pld_get_user_msi_assignment(struct device *dev, char *user_name,
pr_err("Not supported on type %d\n", type);
ret = -ENODEV;
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_get_user_msi_assignment(dev, user_name,
num_vectors,
user_base_data,
base_vector);
break;
default:
pr_err("Invalid device type %d\n", type);
ret = -EINVAL;
@@ -1770,6 +1862,8 @@ int pld_srng_request_irq(struct device *dev, int irq, irq_handler_t handler,
pr_err("Not supported on type %d\n", type);
ret = -ENODEV;
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type %d\n", type);
ret = -EINVAL;
@@ -1810,6 +1904,8 @@ int pld_srng_free_irq(struct device *dev, int irq, void *dev_data)
pr_err("Not supported on type %d\n", type);
ret = -ENODEV;
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type %d\n", type);
ret = -EINVAL;
@@ -1840,6 +1936,8 @@ void pld_srng_enable_irq(struct device *dev, int irq)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
break;
@@ -1867,6 +1965,8 @@ void pld_srng_disable_irq(struct device *dev, int irq)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
break;
@@ -1892,6 +1992,8 @@ int pld_pci_read_config_word(struct pci_dev *pdev, int offset, uint16_t *val)
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_PCIE:
ret = pci_read_config_word(pdev, offset, val);
break;
@@ -1929,6 +2031,8 @@ int pld_pci_write_config_word(struct pci_dev *pdev, int offset, uint16_t val)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
break;
@@ -1961,6 +2065,8 @@ int pld_pci_read_config_dword(struct pci_dev *pdev, int offset, uint32_t *val)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
break;
@@ -1993,6 +2099,8 @@ int pld_pci_write_config_dword(struct pci_dev *pdev, int offset, uint32_t val)
break;
case PLD_BUS_TYPE_SDIO:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type\n");
break;
@@ -2028,6 +2136,9 @@ int pld_get_msi_irq(struct device *dev, unsigned int vector)
pr_err("Not supported on type %d\n", type);
ret = -ENODEV;
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_get_msi_irq(dev, vector);
break;
default:
pr_err("Invalid device type %d\n", type);
ret = -EINVAL;
@@ -2064,6 +2175,9 @@ void pld_get_msi_address(struct device *dev, uint32_t *msi_addr_low,
case PLD_BUS_TYPE_SNOC_FW_SIM:
pr_err("Not supported on type %d\n", type);
break;
case PLD_BUS_TYPE_IPCI:
pld_ipci_get_msi_address(dev, msi_addr_low, msi_addr_high);
break;
default:
pr_err("Invalid device type %d\n", type);
break;
@@ -2092,6 +2206,7 @@ int pld_is_drv_connected(struct device *dev)
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type %d\n", type);
@@ -2123,6 +2238,8 @@ unsigned int pld_socinfo_get_serial_number(struct device *dev)
break;
case PLD_BUS_TYPE_SNOC_FW_SIM:
break;
case PLD_BUS_TYPE_IPCI:
break;
default:
pr_err("Invalid device type %d\n", type);
break;
@@ -2150,6 +2267,8 @@ int pld_is_qmi_disable(struct device *dev)
break;
case PLD_BUS_TYPE_SNOC_FW_SIM:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_PCIE:
case PLD_BUS_TYPE_SDIO:
@@ -2200,6 +2319,9 @@ int pld_is_fw_down(struct device *dev)
ifdev = pld_get_if_dev(dev);
ret = pld_usb_is_fw_down(ifdev);
break;
case PLD_BUS_TYPE_IPCI:
ret = pld_ipci_is_fw_down(dev);
break;
default:
pr_err("Invalid device type %d\n", type);
ret = -EINVAL;
@@ -2232,6 +2354,8 @@ int pld_force_assert_target(struct device *dev)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SDIO:
return -EINVAL;
case PLD_BUS_TYPE_IPCI:
return pld_ipci_force_assert_target(dev);
default:
pr_err("Invalid device type %d\n", type);
return -EINVAL;
@@ -2258,6 +2382,7 @@ int pld_collect_rddm(struct device *dev)
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
return 0;
default:
pr_err("Invalid device type %d\n", type);
@@ -2285,6 +2410,7 @@ int pld_qmi_send_get(struct device *dev)
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
return 0;
default:
pr_err("Invalid device type %d\n", type);
@@ -2312,6 +2438,7 @@ int pld_qmi_send_put(struct device *dev)
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
return 0;
default:
pr_err("Invalid device type %d\n", type);
@@ -2345,6 +2472,7 @@ int pld_qmi_send(struct device *dev, int type, void *cmd,
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_IPCI:
return -EINVAL;
default:
pr_err("Invalid device type %d\n", bus_type);
@@ -2372,6 +2500,7 @@ bool pld_is_fw_dump_skipped(struct device *dev)
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_IPCI:
default:
break;
}
@@ -2389,6 +2518,7 @@ int pld_is_pdr(struct device *dev)
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_IPCI:
default:
break;
}
@@ -2406,6 +2536,7 @@ int pld_is_fw_rejuvenate(struct device *dev)
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_IPCI:
default:
break;
}
@@ -2426,6 +2557,8 @@ bool pld_have_platform_driver_support(struct device *dev)
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_SNOC:
break;
case PLD_BUS_TYPE_IPCI:
break;
case PLD_BUS_TYPE_SDIO:
ret = pld_sdio_platform_driver_support();
break;
@@ -2462,6 +2595,9 @@ int pld_idle_shutdown(struct device *dev,
case PLD_BUS_TYPE_SNOC_FW_SIM:
errno = pld_snoc_fw_sim_idle_shutdown(dev);
break;
case PLD_BUS_TYPE_IPCI:
errno = pld_ipci_idle_shutdown(dev);
break;
default:
pr_err("Invalid device type %d\n", type);
break;
@@ -2495,6 +2631,9 @@ int pld_idle_restart(struct device *dev,
case PLD_BUS_TYPE_SNOC_FW_SIM:
errno = pld_snoc_fw_sim_idle_restart(dev);
break;
case PLD_BUS_TYPE_IPCI:
errno = pld_ipci_idle_restart(dev);
break;
default:
pr_err("Invalid device type %d\n", type);
break;

406
core/pld/src/pld_ipci.c Parasts fails
Parādīt failu

@@ -0,0 +1,406 @@
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/list.h>
#include <linux/slab.h>
#ifdef CONFIG_PLD_IPCI_ICNSS
#include <soc/qcom/icnss2.h>
#endif
#include "pld_internal.h"
#include "pld_ipci.h"
#ifdef CONFIG_PLD_IPCI_ICNSS
/**
* pld_ipci_probe() - Probe function for platform driver
* @dev: device
*
* The probe function will be called when platform device
* is detected.
*
* Return: int
*/
static int pld_ipci_probe(struct device *dev)
{
struct pld_context *pld_context;
int ret = 0;
pld_context = pld_get_global_context();
if (!pld_context) {
ret = -ENODEV;
goto out;
}
ret = pld_add_dev(pld_context, dev, NULL, PLD_BUS_TYPE_IPCI);
if (ret)
goto out;
return pld_context->ops->probe(dev, PLD_BUS_TYPE_IPCI,
NULL, NULL);
out:
return ret;
}
/**
* pld_ipci_remove() - Remove function for platform device
* @dev: device
*
* The remove function will be called when platform device
* is disconnected
*
* Return: void
*/
static void pld_ipci_remove(struct device *dev)
{
struct pld_context *pld_context;
pld_context = pld_get_global_context();
if (!pld_context)
return;
pld_context->ops->remove(dev, PLD_BUS_TYPE_SNOC);
pld_del_dev(pld_context, dev);
}
/**
* pld_ipci_reinit() - SSR re-initialize function for platform device
* @dev: device
*
* During subsystem restart(SSR), this function will be called to
* re-initialize platform device.
*
* Return: int
*/
static int pld_ipci_reinit(struct device *dev)
{
struct pld_context *pld_context;
pld_context = pld_get_global_context();
if (pld_context->ops->reinit)
return pld_context->ops->reinit(dev, PLD_BUS_TYPE_IPCI,
NULL, NULL);
return -ENODEV;
}
/**
* pld_ipci_shutdown() - SSR shutdown function for platform device
* @dev: device
*
* During SSR, this function will be called to shutdown platform device.
*
* Return: void
*/
static void pld_ipci_shutdown(struct device *dev)
{
struct pld_context *pld_context;
pld_context = pld_get_global_context();
if (pld_context->ops->shutdown)
pld_context->ops->shutdown(dev, PLD_BUS_TYPE_IPCI);
}
/**
* pld_ipci_crash_shutdown() - Crash shutdown function for platform device
* @dev: device
*
* This function will be called when a crash is detected, it will shutdown
* platform device.
*
* Return: void
*/
static void pld_ipci_crash_shutdown(void *dev)
{
struct pld_context *pld_context;
pld_context = pld_get_global_context();
if (pld_context->ops->crash_shutdown)
pld_context->ops->crash_shutdown(dev, PLD_BUS_TYPE_IPCI);
}
/**
* pld_ipci_pm_suspend() - PM suspend callback function for power management
* @dev: device
*
* This function is to suspend the platform device when power management
* is enabled.
*
* Return: void
*/
static int pld_ipci_pm_suspend(struct device *dev)
{
struct pld_context *pld_context;
pm_message_t state;
state.event = PM_EVENT_SUSPEND;
pld_context = pld_get_global_context();
return pld_context->ops->suspend(dev, PLD_BUS_TYPE_IPCI, state);
}
/**
* pld_ipci_pm_resume() - PM resume callback function for power management
* @pdev: device
*
* This function is to resume the platform device when power management
* is enabled.
*
* Return: void
*/
static int pld_ipci_pm_resume(struct device *dev)
{
struct pld_context *pld_context;
pld_context = pld_get_global_context();
return pld_context->ops->resume(dev, PLD_BUS_TYPE_IPCI);
}
/**
* pld_ipci_suspend_noirq() - Complete the actions started by suspend()
* @dev: device
*
* Complete the actions started by suspend(). Carry out any
* additional operations required for suspending the device that might be
* racing with its driver's interrupt handler, which is guaranteed not to
* run while suspend_noirq() is being executed.
*
* Return: 0 for success
* Non zero failure code for errors
*/
static int pld_ipci_suspend_noirq(struct device *dev)
{
struct pld_context *pld_context;
pld_context = pld_get_global_context();
if (!pld_context)
return -EINVAL;
if (pld_context->ops->suspend_noirq)
return pld_context->ops->suspend_noirq(dev, PLD_BUS_TYPE_IPCI);
return 0;
}
/**
* pld_ipci_resume_noirq() - Prepare for the execution of resume()
* @pdev: device
*
* Prepare for the execution of resume() by carrying out any
* operations required for resuming the device that might be racing with
* its driver's interrupt handler, which is guaranteed not to run while
* resume_noirq() is being executed.
*
* Return: 0 for success
* Non zero failure code for errors
*/
static int pld_ipci_resume_noirq(struct device *dev)
{
struct pld_context *pld_context;
pld_context = pld_get_global_context();
if (!pld_context)
return -EINVAL;
if (pld_context->ops->resume_noirq)
return pld_context->ops->resume_noirq(dev, PLD_BUS_TYPE_IPCI);
return 0;
}
static int pld_ipci_uevent(struct device *dev,
struct icnss_uevent_data *uevent)
{
struct pld_context *pld_context;
struct icnss_uevent_fw_down_data *uevent_data = NULL;
struct pld_uevent_data data;
pld_context = pld_get_global_context();
if (!pld_context)
return -EINVAL;
if (!pld_context->ops->uevent)
goto out;
if (!uevent)
return -EINVAL;
switch (uevent->uevent) {
case ICNSS_UEVENT_FW_CRASHED:
data.uevent = PLD_FW_CRASHED;
break;
case ICNSS_UEVENT_FW_DOWN:
if (!uevent->data)
return -EINVAL;
uevent_data = (struct icnss_uevent_fw_down_data *)uevent->data;
data.uevent = PLD_FW_DOWN;
data.fw_down.crashed = uevent_data->crashed;
break;
default:
goto out;
}
pld_context->ops->uevent(dev, &data);
out:
return 0;
}
#ifdef MULTI_IF_NAME
#define PLD_IPCI_OPS_NAME "pld_ipci_" MULTI_IF_NAME
#else
#define PLD_IPCI_OPS_NAME "pld_ipci"
#endif
struct icnss_driver_ops pld_ipci_ops = {
.name = PLD_IPCI_OPS_NAME,
.probe = pld_ipci_probe,
.remove = pld_ipci_remove,
.shutdown = pld_ipci_shutdown,
.reinit = pld_ipci_reinit,
.crash_shutdown = pld_ipci_crash_shutdown,
.pm_suspend = pld_ipci_pm_suspend,
.pm_resume = pld_ipci_pm_resume,
.suspend_noirq = pld_ipci_suspend_noirq,
.resume_noirq = pld_ipci_resume_noirq,
.uevent = pld_ipci_uevent,
};
/**
* pld_ipci_register_driver() - Register platform device callback functions
*
* Return: int
*/
int pld_ipci_register_driver(void)
{
return icnss_register_driver(&pld_ipci_ops);
}
/**
* pld_ipci_unregister_driver() - Unregister platform device callback functions
*
* Return: void
*/
void pld_ipci_unregister_driver(void)
{
icnss_unregister_driver(&pld_ipci_ops);
}
/**
* pld_ipci_wlan_enable() - Enable WLAN
* @dev: device
* @config: WLAN configuration data
* @mode: WLAN mode
* @host_version: host software version
*
* This function enables WLAN FW. It passed WLAN configuration data,
* WLAN mode and host software version to FW.
*
* Return: 0 for success
* Non zero failure code for errors
*/
int pld_ipci_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
enum pld_driver_mode mode, const char *host_version)
{
struct icnss_wlan_enable_cfg cfg;
enum icnss_driver_mode icnss_mode;
if (!dev)
return -ENODEV;
cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg;
cfg.ce_tgt_cfg = (struct ce_tgt_pipe_cfg *)
config->ce_tgt_cfg;
cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg;
cfg.ce_svc_cfg = (struct ce_svc_pipe_cfg *)
config->ce_svc_cfg;
cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg;
cfg.shadow_reg_cfg = (struct icnss_shadow_reg_cfg *)
config->shadow_reg_cfg;
switch (mode) {
case PLD_FTM:
icnss_mode = ICNSS_FTM;
break;
case PLD_EPPING:
icnss_mode = ICNSS_EPPING;
break;
default:
icnss_mode = ICNSS_MISSION;
break;
}
return icnss_wlan_enable(dev, &cfg, icnss_mode, host_version);
}
/**
* pld_ipci_wlan_disable() - Disable WLAN
* @dev: device
* @mode: WLAN mode
*
* This function disables WLAN FW. It passes WLAN mode to FW.
*
* Return: 0 for success
* Non zero failure code for errors
*/
int pld_ipci_wlan_disable(struct device *dev, enum pld_driver_mode mode)
{
if (!dev)
return -ENODEV;
return icnss_wlan_disable(dev, ICNSS_OFF);
}
/**
* pld_ipci_get_soc_info() - Get SOC information
* @dev: device
* @info: buffer to SOC information
*
* Return SOC info to the buffer.
*
* Return: 0 for success
* Non zero failure code for errors
*/
int pld_ipci_get_soc_info(struct device *dev, struct pld_soc_info *info)
{
int errno;
struct icnss_soc_info icnss_info = {0};
if (!info || !dev)
return -ENODEV;
errno = icnss_get_soc_info(dev, &icnss_info);
if (errno)
return errno;
info->v_addr = icnss_info.v_addr;
info->p_addr = icnss_info.p_addr;
info->chip_id = icnss_info.chip_id;
info->chip_family = icnss_info.chip_family;
info->board_id = icnss_info.board_id;
info->soc_id = icnss_info.soc_id;
info->fw_version = icnss_info.fw_version;
strlcpy(info->fw_build_timestamp, icnss_info.fw_build_timestamp,
sizeof(info->fw_build_timestamp));
return 0;
}
#endif

179
core/pld/src/pld_ipci.h Parasts fails
Parādīt failu

@@ -0,0 +1,179 @@
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __PLD_IPCI_H__
#define __PLD_IPCI_H__
#ifdef CONFIG_PLD_IPCI_ICNSS
#include <soc/qcom/icnss2.h>
#endif
#include "pld_internal.h"
#ifndef CONFIG_PLD_IPCI_ICNSS
static inline int pld_ipci_register_driver(void)
{
return 0;
}
static inline void pld_ipci_unregister_driver(void)
{
}
static inline int pld_ipci_wlan_enable(struct device *dev,
struct pld_wlan_enable_cfg *config,
enum pld_driver_mode mode,
const char *host_version)
{
return 0;
}
static inline int pld_ipci_wlan_disable(struct device *dev,
enum pld_driver_mode mode)
{
return 0;
}
static inline int pld_ipci_get_soc_info(struct device *dev,
struct pld_soc_info *info)
{
return 0;
}
static inline int pld_ipci_power_on(struct device *dev)
{
return 0;
}
static inline int pld_ipci_power_off(struct device *dev)
{
return 0;
}
static inline int pld_ipci_idle_restart(struct device *dev)
{
return 0;
}
static inline int pld_ipci_idle_shutdown(struct device *dev)
{
return 0;
}
static inline int pld_ipci_force_assert_target(struct device *dev)
{
return -EINVAL;
}
static inline int pld_ipci_get_user_msi_assignment(struct device *dev,
char *user_name,
int *num_vectors,
uint32_t *user_base_data,
uint32_t *base_vector)
{
return 0;
}
static inline int pld_ipci_get_msi_irq(struct device *dev, unsigned int vector)
{
return 0;
}
static inline void pld_ipci_get_msi_address(struct device *dev,
uint32_t *msi_addr_low,
uint32_t *msi_addr_high)
{
}
static inline int pld_ipci_is_fw_down(struct device *dev)
{
return 0;
}
static inline int pld_ipci_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
{
return 0;
}
#else
int pld_ipci_register_driver(void);
void pld_ipci_unregister_driver(void);
int pld_ipci_wlan_enable(struct device *dev,
struct pld_wlan_enable_cfg *config,
enum pld_driver_mode mode, const char *host_version);
int pld_ipci_wlan_disable(struct device *dev, enum pld_driver_mode mode);
int pld_ipci_get_soc_info(struct device *dev, struct pld_soc_info *info);
static inline int pld_ipci_power_on(struct device *dev)
{
return icnss_power_on(dev);
}
static inline int pld_ipci_power_off(struct device *dev)
{
return icnss_power_off(dev);
}
static inline int pld_ipci_idle_restart(struct device *dev)
{
return icnss_idle_restart(dev);
}
static inline int pld_ipci_idle_shutdown(struct device *dev)
{
return icnss_idle_shutdown(dev);
}
static inline int pld_ipci_force_assert_target(struct device *dev)
{
return icnss_trigger_recovery(dev);
}
static inline int pld_ipci_get_user_msi_assignment(struct device *dev,
char *user_name,
int *num_vectors,
uint32_t *user_base_data,
uint32_t *base_vector)
{
return icnss_get_user_msi_assignment(dev, user_name, num_vectors,
user_base_data, base_vector);
}
static inline int pld_ipci_get_msi_irq(struct device *dev, unsigned int vector)
{
return icnss_get_msi_irq(dev, vector);
}
static inline void pld_ipci_get_msi_address(struct device *dev,
uint32_t *msi_addr_low,
uint32_t *msi_addr_high)
{
icnss_get_msi_address(dev, msi_addr_low, msi_addr_high);
}
static inline int pld_ipci_is_fw_down(struct device *dev)
{
return icnss_is_fw_down();
}
static inline int pld_ipci_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
{
return icnss_set_fw_log_mode(dev, fw_log_mode);
}
#endif
#endif