Loading Documentation/devicetree/bindings/soc/qcom/bg_daemon.txt 0 → 100644 +14 −0 Original line number Diff line number Diff line Qualcomm Technologies Inc. bg-daemon BG-Daemon : When Modem goes down, to re-establish the connections, BG-Daemon toggles the bg-reset gpio to reset BG. Required properties: - compatible : should be "qcom,bg-daemon" - qcom,bg-reset-gpio : gpio for the apps processor use to soft reset BG Example: qcom,bg-daemon { compatible = "qcom,bg-daemon"; qcom,bg-reset-gpio = <&pm660_gpios 5 0>; }; drivers/soc/qcom/bg_rsb.c +5 −3 Original line number Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, 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 Loading Loading @@ -544,8 +544,6 @@ static void bgrsb_disable_rsb(struct work_struct *work) rsb_down_work); if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0) return; req.cmd_id = 0x02; req.data = 0x00; Loading @@ -555,6 +553,10 @@ static void bgrsb_disable_rsb(struct work_struct *work) pr_err("Failed to send disable command to BG\n"); return; } if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0) return; dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; pr_debug("RSB Disabled\n"); } Loading drivers/soc/qcom/bgcom_interface.c +68 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ #include <soc/qcom/subsystem_notif.h> #include "bgcom.h" #include "linux/bgcom_interface.h" #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/platform_device.h> #define BGCOM "bg_com_dev" Loading @@ -52,6 +57,8 @@ static char *ssr_domains[] = { "modem", }; static unsigned bgreset_gpio; static DEFINE_MUTEX(bg_char_mutex); static struct cdev bg_cdev; static struct class *bg_class; Loading Loading @@ -169,6 +176,15 @@ static int bgchar_write_cmd(struct bg_ui_data *fui_obj_msg, int type) return ret; } static int bg_soft_reset(void) { /*pull down reset gpio */ gpio_direction_output(bgreset_gpio, 0); msleep(50); gpio_set_value(bgreset_gpio, 1); return 0; } static long bg_com_ioctl(struct file *filp, unsigned int ui_bgcom_cmd, unsigned long arg) { Loading Loading @@ -205,6 +221,9 @@ static long bg_com_ioctl(struct file *filp, case SET_SPI_BUSY: ret = bgcom_set_spi_state(BGCOM_SPI_BUSY); break; case BG_SOFT_RESET: ret = bg_soft_reset(); break; default: ret = -ENOIOCTLCMD; } Loading @@ -222,6 +241,50 @@ static int bgcom_char_close(struct inode *inode, struct file *file) return ret; } static int bg_daemon_probe(struct platform_device *pdev) { struct device_node *node; unsigned reset_gpio; node = pdev->dev.of_node; reset_gpio = of_get_named_gpio(node, "qcom,bg-reset-gpio", 0); if (!gpio_is_valid(reset_gpio)) { pr_err("gpio %d found is not valid\n", reset_gpio); goto err_ret; } if (gpio_request(reset_gpio, "bg_reset_gpio")) { pr_err("gpio %d request failed\n", reset_gpio); goto err_ret; } if (gpio_direction_output(reset_gpio, 1)) { pr_err("gpio %d direction not set\n", reset_gpio); goto err_ret; } pr_info("bg-soft-reset gpio successfully requested\n"); bgreset_gpio = reset_gpio; err_ret: return 0; } static const struct of_device_id bg_daemon_of_match[] = { { .compatible = "qcom,bg-daemon", }, { } }; MODULE_DEVICE_TABLE(of, bg_daemon_of_match); static struct platform_driver bg_daemon_driver = { .probe = bg_daemon_probe, .driver = { .name = "bg-daemon", .of_match_table = bg_daemon_of_match, }, }; static const struct file_operations fops = { .owner = THIS_MODULE, .open = bgcom_char_open, Loading Loading @@ -261,6 +324,10 @@ static int __init init_bg_com_dev(void) pr_err("device create failed\n"); return PTR_ERR(dev_ret); } if (platform_driver_register(&bg_daemon_driver)) pr_err("%s: failed to register bg-daemon register\n", __func__); return 0; } Loading @@ -270,6 +337,7 @@ static void __exit exit_bg_com_dev(void) class_destroy(bg_class); cdev_del(&bg_cdev); unregister_chrdev_region(bg_dev, 1); platform_driver_unregister(&bg_daemon_driver); } /** Loading include/uapi/linux/bgcom_interface.h +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ #define BGCOM_SET_SPI_FREE 3 #define BGCOM_SET_SPI_BUSY 4 #define BGCOM_REG_WRITE 5 #define BGCOM_SOFT_RESET 6 #define EXCHANGE_CODE 'V' struct bg_ui_data { Loading Loading @@ -41,4 +42,7 @@ enum bg_event_type { #define REG_WRITE \ _IOWR(EXCHANGE_CODE, BGCOM_REG_WRITE, \ struct bg_ui_data) #define BG_SOFT_RESET \ _IOWR(EXCHANGE_CODE, BGCOM_SOFT_RESET, \ struct bg_ui_data) #endif Loading
Documentation/devicetree/bindings/soc/qcom/bg_daemon.txt 0 → 100644 +14 −0 Original line number Diff line number Diff line Qualcomm Technologies Inc. bg-daemon BG-Daemon : When Modem goes down, to re-establish the connections, BG-Daemon toggles the bg-reset gpio to reset BG. Required properties: - compatible : should be "qcom,bg-daemon" - qcom,bg-reset-gpio : gpio for the apps processor use to soft reset BG Example: qcom,bg-daemon { compatible = "qcom,bg-daemon"; qcom,bg-reset-gpio = <&pm660_gpios 5 0>; };
drivers/soc/qcom/bg_rsb.c +5 −3 Original line number Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, 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 Loading Loading @@ -544,8 +544,6 @@ static void bgrsb_disable_rsb(struct work_struct *work) rsb_down_work); if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) { if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0) return; req.cmd_id = 0x02; req.data = 0x00; Loading @@ -555,6 +553,10 @@ static void bgrsb_disable_rsb(struct work_struct *work) pr_err("Failed to send disable command to BG\n"); return; } if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0) return; dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED; pr_debug("RSB Disabled\n"); } Loading
drivers/soc/qcom/bgcom_interface.c +68 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ #include <soc/qcom/subsystem_notif.h> #include "bgcom.h" #include "linux/bgcom_interface.h" #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/platform_device.h> #define BGCOM "bg_com_dev" Loading @@ -52,6 +57,8 @@ static char *ssr_domains[] = { "modem", }; static unsigned bgreset_gpio; static DEFINE_MUTEX(bg_char_mutex); static struct cdev bg_cdev; static struct class *bg_class; Loading Loading @@ -169,6 +176,15 @@ static int bgchar_write_cmd(struct bg_ui_data *fui_obj_msg, int type) return ret; } static int bg_soft_reset(void) { /*pull down reset gpio */ gpio_direction_output(bgreset_gpio, 0); msleep(50); gpio_set_value(bgreset_gpio, 1); return 0; } static long bg_com_ioctl(struct file *filp, unsigned int ui_bgcom_cmd, unsigned long arg) { Loading Loading @@ -205,6 +221,9 @@ static long bg_com_ioctl(struct file *filp, case SET_SPI_BUSY: ret = bgcom_set_spi_state(BGCOM_SPI_BUSY); break; case BG_SOFT_RESET: ret = bg_soft_reset(); break; default: ret = -ENOIOCTLCMD; } Loading @@ -222,6 +241,50 @@ static int bgcom_char_close(struct inode *inode, struct file *file) return ret; } static int bg_daemon_probe(struct platform_device *pdev) { struct device_node *node; unsigned reset_gpio; node = pdev->dev.of_node; reset_gpio = of_get_named_gpio(node, "qcom,bg-reset-gpio", 0); if (!gpio_is_valid(reset_gpio)) { pr_err("gpio %d found is not valid\n", reset_gpio); goto err_ret; } if (gpio_request(reset_gpio, "bg_reset_gpio")) { pr_err("gpio %d request failed\n", reset_gpio); goto err_ret; } if (gpio_direction_output(reset_gpio, 1)) { pr_err("gpio %d direction not set\n", reset_gpio); goto err_ret; } pr_info("bg-soft-reset gpio successfully requested\n"); bgreset_gpio = reset_gpio; err_ret: return 0; } static const struct of_device_id bg_daemon_of_match[] = { { .compatible = "qcom,bg-daemon", }, { } }; MODULE_DEVICE_TABLE(of, bg_daemon_of_match); static struct platform_driver bg_daemon_driver = { .probe = bg_daemon_probe, .driver = { .name = "bg-daemon", .of_match_table = bg_daemon_of_match, }, }; static const struct file_operations fops = { .owner = THIS_MODULE, .open = bgcom_char_open, Loading Loading @@ -261,6 +324,10 @@ static int __init init_bg_com_dev(void) pr_err("device create failed\n"); return PTR_ERR(dev_ret); } if (platform_driver_register(&bg_daemon_driver)) pr_err("%s: failed to register bg-daemon register\n", __func__); return 0; } Loading @@ -270,6 +337,7 @@ static void __exit exit_bg_com_dev(void) class_destroy(bg_class); cdev_del(&bg_cdev); unregister_chrdev_region(bg_dev, 1); platform_driver_unregister(&bg_daemon_driver); } /** Loading
include/uapi/linux/bgcom_interface.h +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ #define BGCOM_SET_SPI_FREE 3 #define BGCOM_SET_SPI_BUSY 4 #define BGCOM_REG_WRITE 5 #define BGCOM_SOFT_RESET 6 #define EXCHANGE_CODE 'V' struct bg_ui_data { Loading Loading @@ -41,4 +42,7 @@ enum bg_event_type { #define REG_WRITE \ _IOWR(EXCHANGE_CODE, BGCOM_REG_WRITE, \ struct bg_ui_data) #define BG_SOFT_RESET \ _IOWR(EXCHANGE_CODE, BGCOM_SOFT_RESET, \ struct bg_ui_data) #endif