Loading Documentation/devicetree/bindings/cnss/cnss-wlan.txt +4 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ Optional properties: - qcom,wlan-en-vreg-support: Boolean property to decide the whether the WLAN_EN pin is a gpio or fixed regulator. - qcom,mhi: phandle to indicate the device which needs MHI support. - qcom,cap-tsf-gpio: WLAN_TSF_CAPTURED GPIO signal specified by the chip specifications, should be drived depending on products Example: Loading @@ -66,4 +69,5 @@ Example: qcom,wlan-rc-num = <0>; qcom,wlan-smmu-iova-address = <0 0x10000000>; qcom,mhi = <&mhi_wlan>; qcom,cap-tsf-gpio = <&tlmm 126 1>; }; arch/arm/boot/dts/qcom/apq8017-rome.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -16,5 +16,6 @@ compatible = "qcom,cnss_sdio"; qcom,wlan-ramdump-dynamic = <0x200000>; subsys-name = "AR6320"; qcom,cap-tsf-gpio = <&tlmm 126 1>; }; }; drivers/net/wireless/cnss/cnss_common.c +24 −0 Original line number Diff line number Diff line Loading @@ -410,3 +410,27 @@ const char *cnss_wlan_get_evicted_data_file(void) { return FW_FILES_QCA6174_FW_3_0.evicted_data; } int cnss_common_register_tsf_captured_handler(struct device *dev, irq_handler_t handler, void *ctx) { struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); if (pf_ops && pf_ops->register_tsf_captured_handler) return pf_ops->register_tsf_captured_handler(handler, ctx); else return -EINVAL; } EXPORT_SYMBOL(cnss_common_register_tsf_captured_handler); int cnss_common_unregister_tsf_captured_handler(struct device *dev, void *ctx) { struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); if (pf_ops && pf_ops->unregister_tsf_captured_handler) return pf_ops->unregister_tsf_captured_handler(ctx); else return -EINVAL; } EXPORT_SYMBOL(cnss_common_unregister_tsf_captured_handler); drivers/net/wireless/cnss/cnss_common.h +9 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,12 @@ /* max 20mhz channel count */ #define CNSS_MAX_CH_NUM 45 struct cnss_cap_tsf_info { int irq_num; void *context; irq_handler_t irq_handler; }; struct cnss_dev_platform_ops { int (*request_bus_bandwidth)(int bandwidth); void* (*get_virt_ramdump_mem)(unsigned long *size); Loading @@ -26,6 +32,9 @@ struct cnss_dev_platform_ops { int (*set_wlan_mac_address)(const u8 *in, uint32_t len); int (*power_up)(struct device *dev); int (*power_down)(struct device *dev); int (*register_tsf_captured_handler)(irq_handler_t handler, void *adapter); int (*unregister_tsf_captured_handler)(void *adapter); }; int cnss_pci_request_bus_bandwidth(int bandwidth); Loading drivers/net/wireless/cnss/cnss_sdio.c +117 −1 Original line number Diff line number Diff line Loading @@ -38,11 +38,15 @@ #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC #include <net/cnss_prealloc.h> #endif #include <linux/gpio.h> #include <linux/of_gpio.h> #define WLAN_VREG_NAME "vdd-wlan" #define WLAN_VREG_DSRC_NAME "vdd-wlan-dsrc" #define WLAN_VREG_IO_NAME "vdd-wlan-io" #define WLAN_VREG_XTAL_NAME "vdd-wlan-xtal" #define WLAN_GPIO_CAPTSF_NAME "qcom,cap-tsf-gpio" #define WLAN_VREG_IO_MAX 1800000 #define WLAN_VREG_IO_MIN 1800000 Loading Loading @@ -76,6 +80,7 @@ struct cnss_sdio_info { const struct sdio_device_id *id; bool skip_wlan_en_toggle; bool cnss_hw_state; struct cnss_cap_tsf_info cap_tsf_info; }; struct cnss_ssr_info { Loading Loading @@ -686,6 +691,109 @@ int cnss_get_restart_level(void) } EXPORT_SYMBOL(cnss_get_restart_level); static inline int cnss_get_tsf_cap_irq(struct device *dev) { int irq = -EINVAL; int gpio; if (!dev) return -ENODEV; gpio = of_get_named_gpio(dev->of_node, WLAN_GPIO_CAPTSF_NAME, 0); if (gpio >= 0) irq = gpio_to_irq(gpio); return irq; } static int cnss_sdio_register_tsf_captured_handler(irq_handler_t handler, void *ctx) { struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return -ENODEV; tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; if (tsf_info->irq_num < 0) return -ENOTSUPP; tsf_info->irq_handler = handler; tsf_info->context = ctx; return 0; } static int cnss_sdio_unregister_tsf_captured_handler(void *ctx) { struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return -ENODEV; tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; if (tsf_info->irq_num < 0) return -ENOTSUPP; if (ctx == tsf_info->context) { tsf_info->irq_handler = NULL; tsf_info->context = NULL; } return 0; } static irqreturn_t cnss_sdio_tsf_captured_handler(int irq, void *ctx) { struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return IRQ_HANDLED; tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; if (tsf_info->irq_num < 0 || tsf_info->irq_num != irq || !tsf_info->irq_handler || !tsf_info->context) return IRQ_HANDLED; return tsf_info->irq_handler(irq, tsf_info->context); } static void cnss_sdio_tsf_init(struct device *dev, struct cnss_cap_tsf_info *tsf_info) { int ret, irq; tsf_info->irq_num = -EINVAL; tsf_info->irq_handler = NULL; tsf_info->context = NULL; irq = cnss_get_tsf_cap_irq(dev); if (irq < 0) { dev_err(dev, "%s: fail to get irq: %d\n", __func__, irq); return; } ret = request_irq(irq, cnss_sdio_tsf_captured_handler, IRQF_SHARED | IRQF_TRIGGER_RISING, dev_name(dev), (void *)tsf_info); dev_err(dev, "%s: request irq[%d] for dev: %s, result: %d\n", __func__, irq, dev_name(dev), ret); if (!ret) tsf_info->irq_num = irq; } static void cnss_sdio_tsf_deinit(struct cnss_cap_tsf_info *tsf_info) { int irq = tsf_info->irq_num; if (irq < 0) return; free_irq(irq, (void *)tsf_info); tsf_info->irq_num = -EINVAL; tsf_info->irq_handler = NULL; tsf_info->context = NULL; } static void cnss_sdio_set_platform_ops(struct device *dev) { struct cnss_dev_platform_ops *pf_ops = &cnss_pdata->platform_ops; Loading @@ -699,7 +807,10 @@ static void cnss_sdio_set_platform_ops(struct device *dev) 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; pf_ops->register_tsf_captured_handler = cnss_sdio_register_tsf_captured_handler; pf_ops->unregister_tsf_captured_handler = cnss_sdio_unregister_tsf_captured_handler; dev->platform_data = pf_ops; } Loading Loading @@ -1338,6 +1449,8 @@ static int cnss_sdio_probe(struct platform_device *pdev) "qcom,skip-wlan-en-toggle"); info->cnss_hw_state = CNSS_HW_ACTIVE; cnss_sdio_tsf_init(dev, &info->cap_tsf_info); error = cnss_sdio_wlan_init(); if (error) { dev_err(&pdev->dev, "cnss wlan init failed error=%d\n", error); Loading Loading @@ -1389,12 +1502,15 @@ err_wlan_enable_regulator: static int cnss_sdio_remove(struct platform_device *pdev) { struct cnss_sdio_info *info; struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return -ENODEV; info = &cnss_pdata->cnss_sdio_info; tsf_info = &info->cap_tsf_info; cnss_sdio_tsf_deinit(tsf_info); cnss_sdio_deinit_bus_bandwidth(); cnss_sdio_wlan_exit(); cnss_subsys_exit(); Loading Loading
Documentation/devicetree/bindings/cnss/cnss-wlan.txt +4 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ Optional properties: - qcom,wlan-en-vreg-support: Boolean property to decide the whether the WLAN_EN pin is a gpio or fixed regulator. - qcom,mhi: phandle to indicate the device which needs MHI support. - qcom,cap-tsf-gpio: WLAN_TSF_CAPTURED GPIO signal specified by the chip specifications, should be drived depending on products Example: Loading @@ -66,4 +69,5 @@ Example: qcom,wlan-rc-num = <0>; qcom,wlan-smmu-iova-address = <0 0x10000000>; qcom,mhi = <&mhi_wlan>; qcom,cap-tsf-gpio = <&tlmm 126 1>; };
arch/arm/boot/dts/qcom/apq8017-rome.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -16,5 +16,6 @@ compatible = "qcom,cnss_sdio"; qcom,wlan-ramdump-dynamic = <0x200000>; subsys-name = "AR6320"; qcom,cap-tsf-gpio = <&tlmm 126 1>; }; };
drivers/net/wireless/cnss/cnss_common.c +24 −0 Original line number Diff line number Diff line Loading @@ -410,3 +410,27 @@ const char *cnss_wlan_get_evicted_data_file(void) { return FW_FILES_QCA6174_FW_3_0.evicted_data; } int cnss_common_register_tsf_captured_handler(struct device *dev, irq_handler_t handler, void *ctx) { struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); if (pf_ops && pf_ops->register_tsf_captured_handler) return pf_ops->register_tsf_captured_handler(handler, ctx); else return -EINVAL; } EXPORT_SYMBOL(cnss_common_register_tsf_captured_handler); int cnss_common_unregister_tsf_captured_handler(struct device *dev, void *ctx) { struct cnss_dev_platform_ops *pf_ops = cnss_get_platform_ops(dev); if (pf_ops && pf_ops->unregister_tsf_captured_handler) return pf_ops->unregister_tsf_captured_handler(ctx); else return -EINVAL; } EXPORT_SYMBOL(cnss_common_unregister_tsf_captured_handler);
drivers/net/wireless/cnss/cnss_common.h +9 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,12 @@ /* max 20mhz channel count */ #define CNSS_MAX_CH_NUM 45 struct cnss_cap_tsf_info { int irq_num; void *context; irq_handler_t irq_handler; }; struct cnss_dev_platform_ops { int (*request_bus_bandwidth)(int bandwidth); void* (*get_virt_ramdump_mem)(unsigned long *size); Loading @@ -26,6 +32,9 @@ struct cnss_dev_platform_ops { int (*set_wlan_mac_address)(const u8 *in, uint32_t len); int (*power_up)(struct device *dev); int (*power_down)(struct device *dev); int (*register_tsf_captured_handler)(irq_handler_t handler, void *adapter); int (*unregister_tsf_captured_handler)(void *adapter); }; int cnss_pci_request_bus_bandwidth(int bandwidth); Loading
drivers/net/wireless/cnss/cnss_sdio.c +117 −1 Original line number Diff line number Diff line Loading @@ -38,11 +38,15 @@ #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC #include <net/cnss_prealloc.h> #endif #include <linux/gpio.h> #include <linux/of_gpio.h> #define WLAN_VREG_NAME "vdd-wlan" #define WLAN_VREG_DSRC_NAME "vdd-wlan-dsrc" #define WLAN_VREG_IO_NAME "vdd-wlan-io" #define WLAN_VREG_XTAL_NAME "vdd-wlan-xtal" #define WLAN_GPIO_CAPTSF_NAME "qcom,cap-tsf-gpio" #define WLAN_VREG_IO_MAX 1800000 #define WLAN_VREG_IO_MIN 1800000 Loading Loading @@ -76,6 +80,7 @@ struct cnss_sdio_info { const struct sdio_device_id *id; bool skip_wlan_en_toggle; bool cnss_hw_state; struct cnss_cap_tsf_info cap_tsf_info; }; struct cnss_ssr_info { Loading Loading @@ -686,6 +691,109 @@ int cnss_get_restart_level(void) } EXPORT_SYMBOL(cnss_get_restart_level); static inline int cnss_get_tsf_cap_irq(struct device *dev) { int irq = -EINVAL; int gpio; if (!dev) return -ENODEV; gpio = of_get_named_gpio(dev->of_node, WLAN_GPIO_CAPTSF_NAME, 0); if (gpio >= 0) irq = gpio_to_irq(gpio); return irq; } static int cnss_sdio_register_tsf_captured_handler(irq_handler_t handler, void *ctx) { struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return -ENODEV; tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; if (tsf_info->irq_num < 0) return -ENOTSUPP; tsf_info->irq_handler = handler; tsf_info->context = ctx; return 0; } static int cnss_sdio_unregister_tsf_captured_handler(void *ctx) { struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return -ENODEV; tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; if (tsf_info->irq_num < 0) return -ENOTSUPP; if (ctx == tsf_info->context) { tsf_info->irq_handler = NULL; tsf_info->context = NULL; } return 0; } static irqreturn_t cnss_sdio_tsf_captured_handler(int irq, void *ctx) { struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return IRQ_HANDLED; tsf_info = &cnss_pdata->cnss_sdio_info.cap_tsf_info; if (tsf_info->irq_num < 0 || tsf_info->irq_num != irq || !tsf_info->irq_handler || !tsf_info->context) return IRQ_HANDLED; return tsf_info->irq_handler(irq, tsf_info->context); } static void cnss_sdio_tsf_init(struct device *dev, struct cnss_cap_tsf_info *tsf_info) { int ret, irq; tsf_info->irq_num = -EINVAL; tsf_info->irq_handler = NULL; tsf_info->context = NULL; irq = cnss_get_tsf_cap_irq(dev); if (irq < 0) { dev_err(dev, "%s: fail to get irq: %d\n", __func__, irq); return; } ret = request_irq(irq, cnss_sdio_tsf_captured_handler, IRQF_SHARED | IRQF_TRIGGER_RISING, dev_name(dev), (void *)tsf_info); dev_err(dev, "%s: request irq[%d] for dev: %s, result: %d\n", __func__, irq, dev_name(dev), ret); if (!ret) tsf_info->irq_num = irq; } static void cnss_sdio_tsf_deinit(struct cnss_cap_tsf_info *tsf_info) { int irq = tsf_info->irq_num; if (irq < 0) return; free_irq(irq, (void *)tsf_info); tsf_info->irq_num = -EINVAL; tsf_info->irq_handler = NULL; tsf_info->context = NULL; } static void cnss_sdio_set_platform_ops(struct device *dev) { struct cnss_dev_platform_ops *pf_ops = &cnss_pdata->platform_ops; Loading @@ -699,7 +807,10 @@ static void cnss_sdio_set_platform_ops(struct device *dev) 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; pf_ops->register_tsf_captured_handler = cnss_sdio_register_tsf_captured_handler; pf_ops->unregister_tsf_captured_handler = cnss_sdio_unregister_tsf_captured_handler; dev->platform_data = pf_ops; } Loading Loading @@ -1338,6 +1449,8 @@ static int cnss_sdio_probe(struct platform_device *pdev) "qcom,skip-wlan-en-toggle"); info->cnss_hw_state = CNSS_HW_ACTIVE; cnss_sdio_tsf_init(dev, &info->cap_tsf_info); error = cnss_sdio_wlan_init(); if (error) { dev_err(&pdev->dev, "cnss wlan init failed error=%d\n", error); Loading Loading @@ -1389,12 +1502,15 @@ err_wlan_enable_regulator: static int cnss_sdio_remove(struct platform_device *pdev) { struct cnss_sdio_info *info; struct cnss_cap_tsf_info *tsf_info; if (!cnss_pdata) return -ENODEV; info = &cnss_pdata->cnss_sdio_info; tsf_info = &info->cap_tsf_info; cnss_sdio_tsf_deinit(tsf_info); cnss_sdio_deinit_bus_bandwidth(); cnss_sdio_wlan_exit(); cnss_subsys_exit(); Loading