Loading arch/arm64/boot/dts/qcom/kona-mhi.dtsi +9 −0 Original line number Diff line number Diff line Loading @@ -623,6 +623,15 @@ mhi,rsc-parent = <&mhi_netdev_0>; }; mhi_qdss_dev_0 { mhi,chan = "QDSS"; mhi,default-channel; }; mhi_qdss_dev_1 { mhi,chan = "IP_HW_QDSS"; }; mhi_qrtr { mhi,chan = "IPCR"; qcom,net-id = <3>; Loading drivers/soc/qcom/qdss_bridge.c +62 −6 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #define KMSG_COMPONENT "QDSS diag bridge" Loading @@ -21,14 +21,20 @@ #include "qdss_bridge.h" #define MODULE_NAME "qdss_bridge" #define QDSS_BUF_SIZE (16*1024) #define MHI_CLIENT_QDSS_IN 9 #define INIT_STATUS -1 /* Max number of objects needed */ static int poolsize = 32; static struct class *mhi_class; static enum mhi_dev_state dev_state = INIT_STATUS; static enum mhi_ch curr_chan; static const char * const str_mhi_curr_chan[] = { [QDSS] = "QDSS", [QDSS_HW] = "IP_HW_QDSS", [EMPTY] = "EMPTY", }; static const char * const str_mhi_transfer_mode[] = { [MHI_TRANSFER_TYPE_USB] = "usb", Loading Loading @@ -152,7 +158,6 @@ static void qdss_del_buf_tbl_entry(struct qdss_bridge_drvdata *drvdata, return; } } spin_unlock_bh(&drvdata->lock); } Loading Loading @@ -206,6 +211,14 @@ static ssize_t mode_show(struct device *dev, str_mhi_transfer_mode[drvdata->mode]); } static ssize_t curr_chan_show(struct device *dev, struct device_attribute *attr, char *buf) { if (curr_chan < QDSS || curr_chan > EMPTY) return -EINVAL; return scnprintf(buf, PAGE_SIZE, "%s\n", str_mhi_curr_chan[curr_chan]); } static ssize_t mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) Loading Loading @@ -275,6 +288,7 @@ static ssize_t mode_store(struct device *dev, } static DEVICE_ATTR_RW(mode); static DEVICE_ATTR_RO(curr_chan); static void mhi_read_work_fn(struct work_struct *work) { Loading Loading @@ -776,6 +790,13 @@ static void qdss_mhi_remove(struct mhi_device *mhi_dev) drvdata = mhi_dev->priv_data; if (!drvdata) return; pr_debug("remove dev state: %d\n", mhi_dev->mhi_cntrl->dev_state); dev_state = mhi_dev->mhi_cntrl->dev_state; if (mhi_dev->mhi_cntrl->dev_state != MHI_STATE_RESET) curr_chan = EMPTY; spin_lock_bh(&drvdata->lock); if (drvdata->opened == ENABLE) { drvdata->opened = SSR; Loading Loading @@ -823,11 +844,40 @@ static int qdss_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { int ret; bool def = false; unsigned int baseminor = 0; unsigned int count = 1; struct qdss_bridge_drvdata *drvdata; struct device_node *of_node = mhi_dev->dev.of_node; dev_t dev; pr_debug("probe dev state: %d chan: %s curr_chan: %d\n", mhi_dev->mhi_cntrl->dev_state, id->chan, curr_chan); def = of_property_read_bool(of_node, "mhi,default-channel"); if (dev_state == INIT_STATUS) { if (!def) return -EINVAL; if (!strcmp(id->chan, "QDSS")) curr_chan = QDSS; if (!strcmp(id->chan, "QDSS_HW")) curr_chan = QDSS_HW; } else if (dev_state == MHI_STATE_RESET) { if (strcmp(id->chan, str_mhi_curr_chan[curr_chan])) return -EINVAL; } else { if (curr_chan != EMPTY) { pr_err("Need unbind another channel before bind.\n"); return -EINVAL; } if (!strcmp(id->chan, "QDSS")) curr_chan = QDSS; if (!strcmp(id->chan, "QDSS_HW")) curr_chan = QDSS_HW; } drvdata = devm_kzalloc(&mhi_dev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { ret = -ENOMEM; Loading Loading @@ -865,7 +915,12 @@ static int qdss_mhi_probe(struct mhi_device *mhi_dev, ret = device_create_file(drvdata->dev, &dev_attr_mode); if (ret) { pr_err("sysfs node create failed error:%d\n", ret); pr_err("mode sysfs node create failed error:%d\n", ret); goto exit_destroy_device; } ret = device_create_file(drvdata->dev, &dev_attr_curr_chan); if (ret) { pr_err("curr_chan sysfs node create failed error:%d\n", ret); goto exit_destroy_device; } Loading @@ -891,6 +946,7 @@ static int qdss_mhi_probe(struct mhi_device *mhi_dev, static const struct mhi_device_id qdss_mhi_match_table[] = { { .chan = "QDSS", .driver_data = 0x4000 }, { .chan = "IP_HW_QDSS", .driver_data = 0x4000 }, {}, }; Loading drivers/soc/qcom/qdss_bridge.h +7 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef _QDSS_BRIDGE_H Loading Loading @@ -30,6 +30,12 @@ enum open_status { SSR, }; enum mhi_ch { QDSS, QDSS_HW, EMPTY, }; struct qdss_bridge_drvdata { int alias; enum open_status opened; Loading Loading
arch/arm64/boot/dts/qcom/kona-mhi.dtsi +9 −0 Original line number Diff line number Diff line Loading @@ -623,6 +623,15 @@ mhi,rsc-parent = <&mhi_netdev_0>; }; mhi_qdss_dev_0 { mhi,chan = "QDSS"; mhi,default-channel; }; mhi_qdss_dev_1 { mhi,chan = "IP_HW_QDSS"; }; mhi_qrtr { mhi,chan = "IPCR"; qcom,net-id = <3>; Loading
drivers/soc/qcom/qdss_bridge.c +62 −6 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #define KMSG_COMPONENT "QDSS diag bridge" Loading @@ -21,14 +21,20 @@ #include "qdss_bridge.h" #define MODULE_NAME "qdss_bridge" #define QDSS_BUF_SIZE (16*1024) #define MHI_CLIENT_QDSS_IN 9 #define INIT_STATUS -1 /* Max number of objects needed */ static int poolsize = 32; static struct class *mhi_class; static enum mhi_dev_state dev_state = INIT_STATUS; static enum mhi_ch curr_chan; static const char * const str_mhi_curr_chan[] = { [QDSS] = "QDSS", [QDSS_HW] = "IP_HW_QDSS", [EMPTY] = "EMPTY", }; static const char * const str_mhi_transfer_mode[] = { [MHI_TRANSFER_TYPE_USB] = "usb", Loading Loading @@ -152,7 +158,6 @@ static void qdss_del_buf_tbl_entry(struct qdss_bridge_drvdata *drvdata, return; } } spin_unlock_bh(&drvdata->lock); } Loading Loading @@ -206,6 +211,14 @@ static ssize_t mode_show(struct device *dev, str_mhi_transfer_mode[drvdata->mode]); } static ssize_t curr_chan_show(struct device *dev, struct device_attribute *attr, char *buf) { if (curr_chan < QDSS || curr_chan > EMPTY) return -EINVAL; return scnprintf(buf, PAGE_SIZE, "%s\n", str_mhi_curr_chan[curr_chan]); } static ssize_t mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) Loading Loading @@ -275,6 +288,7 @@ static ssize_t mode_store(struct device *dev, } static DEVICE_ATTR_RW(mode); static DEVICE_ATTR_RO(curr_chan); static void mhi_read_work_fn(struct work_struct *work) { Loading Loading @@ -776,6 +790,13 @@ static void qdss_mhi_remove(struct mhi_device *mhi_dev) drvdata = mhi_dev->priv_data; if (!drvdata) return; pr_debug("remove dev state: %d\n", mhi_dev->mhi_cntrl->dev_state); dev_state = mhi_dev->mhi_cntrl->dev_state; if (mhi_dev->mhi_cntrl->dev_state != MHI_STATE_RESET) curr_chan = EMPTY; spin_lock_bh(&drvdata->lock); if (drvdata->opened == ENABLE) { drvdata->opened = SSR; Loading Loading @@ -823,11 +844,40 @@ static int qdss_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { int ret; bool def = false; unsigned int baseminor = 0; unsigned int count = 1; struct qdss_bridge_drvdata *drvdata; struct device_node *of_node = mhi_dev->dev.of_node; dev_t dev; pr_debug("probe dev state: %d chan: %s curr_chan: %d\n", mhi_dev->mhi_cntrl->dev_state, id->chan, curr_chan); def = of_property_read_bool(of_node, "mhi,default-channel"); if (dev_state == INIT_STATUS) { if (!def) return -EINVAL; if (!strcmp(id->chan, "QDSS")) curr_chan = QDSS; if (!strcmp(id->chan, "QDSS_HW")) curr_chan = QDSS_HW; } else if (dev_state == MHI_STATE_RESET) { if (strcmp(id->chan, str_mhi_curr_chan[curr_chan])) return -EINVAL; } else { if (curr_chan != EMPTY) { pr_err("Need unbind another channel before bind.\n"); return -EINVAL; } if (!strcmp(id->chan, "QDSS")) curr_chan = QDSS; if (!strcmp(id->chan, "QDSS_HW")) curr_chan = QDSS_HW; } drvdata = devm_kzalloc(&mhi_dev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { ret = -ENOMEM; Loading Loading @@ -865,7 +915,12 @@ static int qdss_mhi_probe(struct mhi_device *mhi_dev, ret = device_create_file(drvdata->dev, &dev_attr_mode); if (ret) { pr_err("sysfs node create failed error:%d\n", ret); pr_err("mode sysfs node create failed error:%d\n", ret); goto exit_destroy_device; } ret = device_create_file(drvdata->dev, &dev_attr_curr_chan); if (ret) { pr_err("curr_chan sysfs node create failed error:%d\n", ret); goto exit_destroy_device; } Loading @@ -891,6 +946,7 @@ static int qdss_mhi_probe(struct mhi_device *mhi_dev, static const struct mhi_device_id qdss_mhi_match_table[] = { { .chan = "QDSS", .driver_data = 0x4000 }, { .chan = "IP_HW_QDSS", .driver_data = 0x4000 }, {}, }; Loading
drivers/soc/qcom/qdss_bridge.h +7 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef _QDSS_BRIDGE_H Loading Loading @@ -30,6 +30,12 @@ enum open_status { SSR, }; enum mhi_ch { QDSS, QDSS_HW, EMPTY, }; struct qdss_bridge_drvdata { int alias; enum open_status opened; Loading