Loading Documentation/devicetree/bindings/mhi/msm_mhi.txt +18 −4 Original line number Diff line number Diff line Loading @@ -7,6 +7,10 @@ signals. Required properties: - compatible: should be "qcom,mhi" - qcom,pci-dev_id: device id reported by modem - qcom,pci-domain: pci root complex device connected to - qcom,pci-bus: pci bus device connected to - qcom,pci-slot: pci slot device connected to - Refer to "Documentation/devicetree/bindings/esoc/esoc_client.txt" for below properties: - esoc-names Loading @@ -24,13 +28,24 @@ Required properties: C = event ring associated with channel D = flags defined by mhi_macros.h GET_CHAN_PROPS - mhi-event-cfg-#: mhi event ring configuration parameters for platform defined as below <A B C D E>: A = maximum event descriptors B = MSI associated with event C = interrupt moderation (see MHI specification) D = Associated channel E = flags defined by mhi_macros.h GET_EV_PROPS - mhi-event-rings: number of event rings supported by platform - mhi-dev-address-win-size: size of the MHI device addressing window - qcom,mhi-address-window: range of the MHI device addressing window Example: mhi: qcom,mhi { compatible = "qcom,mhi"; qcom,pci-dev_id = <0x0301>; qcom,pci-domain = <2>; qcom,pci-bus = <4>; qcom,pci-slot = <0>; qcom,mhi-address-window = <0x0 0x80000000 0x0 0xbfffffff>; esoc-names = "mdm"; esoc-0 = <&mdm1>; qcom,msm-bus,name = "mhi"; Loading @@ -39,8 +54,7 @@ Example: qcom,msm-bus,vectors-KBps = <100 512 0 0>, <100 512 1200000000 1200000000>; mhi-event-rings = <6>; mhi-event-rings = <1>; mhi-chan-cfg-102 = <0x66 0x80 0x5 0x62>; mhi-event-cfg-0 = <0x80 0x0 0x0 0x11>; mhi-dev-address-win-size= <0x10 0x00000000>; mhi-event-cfg-0 = <0x80 0x0 0x0 0x0 0x11>; }; Documentation/devicetree/bindings/platform/msm/msm_mhi_uci.txt 0 → 100644 +55 −0 Original line number Diff line number Diff line MSM MHI UCI interface device MHI userpace control interface (UCI) enables userspace software clients to communicate with device using MHI protocol. ============== Node Structure ============== Main node properties: - compatible Usage: required Value type: <string> Definition: "qcom,mhi-uci" - qcom,mhi-uci-channels Usage: required Value type: Array of <u32> Definition: Array tuples which define the channel configuration parameters. Each tuple is of length 2, 1st value represent channel, and 2nd value represent maximum payload supported. Maximum payload supported is 64 bytes. Number of tuples must be even value. Max # of tuples is 46. - qcom,mhi-uci-ctrlchan Usage: optional Value type: <u32> Definition: Channel that will be handling flow control (DTR/RTS) signals. ======= Example ======= qcom,mhi-uci@0 { compatible = "qcom,mhi-uci"; qcom,mhi-uci-channels = <0 0x1000>, <1 0x1000>, <2 0x1000>, <3 0xffff>, <10 0x1000>, <11 0x1000>, <14 0x1000>, <15 0x1000>, <16 0x1000>, <17 0x1000>, <18 0x1000>, <19 0x1000>, <24 0x1000>, <25 0x1000>, <32 0x1000>, <33 0x1000>; qcom,mhi-uci-ctrlchan = <18>; status = "ok"; }; drivers/char/diag/diagfwd_mhi.c +1 −2 Original line number Diff line number Diff line Loading @@ -665,8 +665,7 @@ static int diag_mhi_register_ch(int id, struct diag_mhi_ch_t *ch) atomic_set(&(ch->opened), 0); ctxt = SET_CH_CTXT(id, ch->type); ch->client_info.mhi_client_cb = mhi_notifier; return mhi_register_channel(&ch->hdl, ch->chan, 0, &ch->client_info, (void *)(uintptr_t)ctxt); return mhi_register_channel(&ch->hdl, NULL); } int diag_mhi_init() Loading drivers/net/ethernet/msm/msm_rmnet_mhi.c +83 −19 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <linux/device.h> #include <linux/errno.h> #include <linux/of_device.h> #include <linux/rtnetlink.h> #define RMNET_MHI_DRIVER_NAME "rmnet_mhi" #define RMNET_MHI_DEV_NAME "rmnet_mhi%d" Loading Loading @@ -79,6 +80,7 @@ struct __packed mhi_skb_priv { struct rmnet_mhi_private { struct list_head node; u32 dev_id; struct mhi_client_handle *tx_client_handle; struct mhi_client_handle *rx_client_handle; enum MHI_CLIENT_CHANNEL tx_channel; Loading Loading @@ -792,6 +794,8 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) int ret = 0; struct rmnet_mhi_private **rmnet_mhi_ctxt = NULL; int r = 0; char ifalias[IFALIASZ]; struct mhi_client_handle *client_handle = NULL; rmnet_log(rmnet_mhi_ptr, MSG_INFO, "Entered.\n"); Loading Loading @@ -825,6 +829,7 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) } else { rmnet_mhi_ptr->tx_enabled = 1; } client_handle = rmnet_mhi_ptr->tx_client_handle; } if (rmnet_mhi_ptr->rx_client_handle != NULL) { rmnet_log(rmnet_mhi_ptr, Loading @@ -840,7 +845,26 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) } else { rmnet_mhi_ptr->rx_enabled = 1; } /* Both tx & rx client handle contain same device info */ client_handle = rmnet_mhi_ptr->rx_client_handle; } if (!client_handle) { ret = -EINVAL; goto net_dev_alloc_fail; } snprintf(ifalias, sizeof(ifalias), "%s_%04x_%02u.%02u.%02u_%u", RMNET_MHI_DRIVER_NAME, client_handle->dev_id, client_handle->domain, client_handle->bus, client_handle->slot, rmnet_mhi_ptr->dev_id); rtnl_lock(); rmnet_mhi_ptr->dev = alloc_netdev(sizeof(struct rmnet_mhi_private *), RMNET_MHI_DEV_NAME, Loading @@ -853,7 +877,9 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) goto net_dev_alloc_fail; } SET_NETDEV_DEV(rmnet_mhi_ptr->dev, &rmnet_mhi_ptr->pdev->dev); dev_set_alias(rmnet_mhi_ptr->dev, ifalias, strlen(ifalias)); rmnet_mhi_ctxt = netdev_priv(rmnet_mhi_ptr->dev); rtnl_unlock(); *rmnet_mhi_ctxt = rmnet_mhi_ptr; ret = dma_set_mask(&(rmnet_mhi_ptr->dev->dev), Loading Loading @@ -980,17 +1006,16 @@ static void rmnet_mhi_cb(struct mhi_cb_info *cb_info) } } static struct mhi_client_info_t rmnet_mhi_info = {rmnet_mhi_cb}; #ifdef CONFIG_DEBUG_FS struct dentry *dentry = NULL; static void rmnet_mhi_create_debugfs(struct rmnet_mhi_private *rmnet_mhi_ptr) { char node_name[15]; char node_name[32]; int i; const umode_t mode = (S_IRUSR | S_IWUSR); struct dentry *file; struct mhi_client_handle *client_handle; const struct { char *name; Loading Loading @@ -1046,8 +1071,20 @@ static void rmnet_mhi_create_debugfs(struct rmnet_mhi_private *rmnet_mhi_ptr) }, }; snprintf(node_name, sizeof(node_name), "%s%d", RMNET_MHI_DRIVER_NAME, rmnet_mhi_ptr->pdev->id); /* Both tx & rx client handle contain same device info */ client_handle = rmnet_mhi_ptr->rx_client_handle; if (!client_handle) client_handle = rmnet_mhi_ptr->tx_client_handle; snprintf(node_name, sizeof(node_name), "%s_%04x_%02u.%02u.%02u_%u", RMNET_MHI_DRIVER_NAME, client_handle->dev_id, client_handle->domain, client_handle->bus, client_handle->slot, rmnet_mhi_ptr->dev_id); if (IS_ERR_OR_NULL(dentry)) return; Loading Loading @@ -1108,11 +1145,16 @@ static int rmnet_mhi_probe(struct platform_device *pdev) int rc; u32 channel; struct rmnet_mhi_private *rmnet_mhi_ptr; char node_name[15]; struct mhi_client_handle *client_handle = NULL; char node_name[32]; struct mhi_client_info_t client_info; if (unlikely(pdev->dev.of_node == NULL)) return -ENODEV; if (!mhi_is_device_ready(&pdev->dev, "qcom,mhi")) return -EPROBE_DEFER; pdev->id = of_alias_get_id(pdev->dev.of_node, "mhi_rmnet"); if (unlikely(pdev->id < 0)) return -ENODEV; Loading @@ -1133,16 +1175,30 @@ static int rmnet_mhi_probe(struct platform_device *pdev) goto probe_fail; } rc = of_property_read_u32(pdev->dev.of_node, "cell-index", &rmnet_mhi_ptr->dev_id); if (unlikely(rc)) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, "failed to get valid 'cell-index'\n"); goto probe_fail; } client_info.dev = &pdev->dev; client_info.node_name = "qcom,mhi"; client_info.mhi_client_cb = rmnet_mhi_cb; client_info.user_data = rmnet_mhi_ptr; rc = of_property_read_u32(pdev->dev.of_node, "qcom,mhi-tx-channel", &channel); if (rc == 0) { rmnet_mhi_ptr->tx_channel = channel; client_info.chan = channel; rc = mhi_register_channel(&rmnet_mhi_ptr->tx_client_handle, rmnet_mhi_ptr->tx_channel, 0, &rmnet_mhi_info, rmnet_mhi_ptr); &client_info); if (unlikely(rc)) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, Loading @@ -1151,6 +1207,7 @@ static int rmnet_mhi_probe(struct platform_device *pdev) rc); goto probe_fail; } client_handle = rmnet_mhi_ptr->tx_client_handle; } rc = of_property_read_u32(pdev->dev.of_node, Loading @@ -1158,11 +1215,9 @@ static int rmnet_mhi_probe(struct platform_device *pdev) &channel); if (rc == 0) { rmnet_mhi_ptr->rx_channel = channel; client_info.chan = channel; rc = mhi_register_channel(&rmnet_mhi_ptr->rx_client_handle, rmnet_mhi_ptr->rx_channel, 0, &rmnet_mhi_info, rmnet_mhi_ptr); &client_info); if (unlikely(rc)) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, Loading @@ -1171,22 +1226,31 @@ static int rmnet_mhi_probe(struct platform_device *pdev) rc); goto probe_fail; } /* overwriting tx_client_handle is ok because dev_id and * bdf are same for both channels */ client_handle = rmnet_mhi_ptr->rx_client_handle; INIT_WORK(&rmnet_mhi_ptr->alloc_work, rmnet_mhi_alloc_work); spin_lock_init(&rmnet_mhi_ptr->alloc_lock); } /* We must've have @ least one valid channel */ if (rmnet_mhi_ptr->rx_client_handle == NULL && rmnet_mhi_ptr->tx_client_handle == NULL) { if (!client_handle) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, "No registered channels\n"); rc = -ENODEV; goto probe_fail; } snprintf(node_name, sizeof(node_name), "%s%d", RMNET_MHI_DRIVER_NAME, pdev->id); snprintf(node_name, sizeof(node_name), "%s_%04x_%02u.%02u.%02u_%u", RMNET_MHI_DRIVER_NAME, client_handle->dev_id, client_handle->domain, client_handle->bus, client_handle->slot, rmnet_mhi_ptr->dev_id); rmnet_mhi_ptr->rmnet_ipc_log = ipc_log_context_create(RMNET_IPC_LOG_PAGES, node_name, 0); Loading drivers/platform/msm/mhi/mhi.h +43 −30 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ #include <linux/list.h> #include <linux/dma-mapping.h> extern struct mhi_pcie_devices mhi_devices; struct mhi_device_ctxt; enum MHI_DEBUG_LEVEL { Loading @@ -49,11 +48,13 @@ struct pcie_core_info { u32 mhi_ver; void __iomem *bar0_base; void __iomem *bar0_end; void __iomem *bar2_base; void __iomem *bar2_end; u32 irq_base; u32 max_nr_msis; u32 domain; u32 bus; u32 slot; struct pci_saved_state *pcie_state; bool pci_master; }; struct bhi_ctxt_t { Loading @@ -64,7 +65,6 @@ struct bhi_ctxt_t { void *unaligned_image_loc; dev_t bhi_dev; struct cdev cdev; struct class *bhi_class; struct device *dev; }; Loading Loading @@ -206,6 +206,7 @@ enum MHI_PKT_TYPE { MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21, MHI_PKT_TYPE_TX_EVENT = 0x22, MHI_PKT_TYPE_EE_EVENT = 0x40, MHI_PKT_TYPE_STALE_EVENT, /* Internal event */ MHI_PKT_TYPE_SYS_ERR_EVENT = 0xFF, }; Loading Loading @@ -310,6 +311,7 @@ struct mhi_ring { uintptr_t el_size; u32 overwrite_en; enum MHI_CHAN_DIR dir; enum MHI_CHAN_STATE ch_state; struct db_mode db_mode; u32 msi_disable_cntr; u32 msi_enable_cntr; Loading Loading @@ -380,7 +382,7 @@ struct mhi_chan_cfg { union mhi_cmd_pkt cmd_pkt; }; struct mhi_client_handle { struct mhi_client_config { struct mhi_chan_info chan_info; struct mhi_device_ctxt *mhi_dev_ctxt; struct mhi_client_info_t client_info; Loading Loading @@ -432,6 +434,8 @@ struct mhi_counters { atomic_t events_pending; u32 *msi_counter; u32 mhi_reset_cntr; u32 link_down_cntr; u32 link_up_cntr; }; struct mhi_flags { Loading Loading @@ -484,13 +488,17 @@ struct mhi_dev_space { }; struct mhi_device_ctxt { struct list_head node; struct pcie_core_info core; struct msm_pcie_register_event mhi_pci_link_event; struct pci_dev *pcie_device; struct bhi_ctxt_t bhi_ctxt; struct platform_device *plat_dev; enum MHI_PM_STATE mhi_pm_state; /* Host driver state */ enum MHI_STATE mhi_state; /* protocol state */ enum MHI_EXEC_ENV dev_exec_env; struct mhi_dev_space dev_space; struct mhi_pcie_dev_info *dev_info; struct pcie_core_info *dev_props; struct mhi_ring chan_bb_list[MHI_MAX_CHANNELS]; struct mhi_ring mhi_local_chan_ctxt[MHI_MAX_CHANNELS]; Loading @@ -498,7 +506,6 @@ struct mhi_device_ctxt { struct mhi_ring mhi_local_cmd_ctxt[NR_OF_CMD_RINGS]; struct mhi_chan_cfg mhi_chan_cfg[MHI_MAX_CHANNELS]; struct mhi_client_handle *client_handle_list[MHI_MAX_CHANNELS]; struct mhi_event_ring_cfg *ev_ring_props; struct task_struct *event_thread_handle; Loading @@ -515,7 +522,9 @@ struct mhi_device_ctxt { struct hrtimer m1_timer; ktime_t m1_timeout; u32 poll_reset_timeout_ms; struct notifier_block mhi_ssr_nb; struct esoc_desc *esoc_handle; void *esoc_ssr_handle; Loading @@ -532,30 +541,30 @@ struct mhi_device_ctxt { struct wakeup_source w_lock; char *chan_info; struct dentry *mhi_parent_folder; }; struct mhi_pcie_dev_info { struct pcie_core_info core; struct mhi_device_ctxt mhi_ctxt; struct msm_pcie_register_event mhi_pci_link_event; struct pci_dev *pcie_device; struct pci_driver *mhi_pcie_driver; struct bhi_ctxt_t bhi_ctxt; struct platform_device *plat_dev; u32 link_down_cntr; u32 link_up_cntr; struct dentry *child; struct dentry *parent; void *mhi_ipc_log; /* Shadow functions since not all device supports runtime pm */ void (*runtime_get)(struct mhi_device_ctxt *mhi_dev_ctxt); void (*runtime_put)(struct mhi_device_ctxt *mhi_dev_ctxt); void (*assert_wake)(struct mhi_device_ctxt *mhi_dev_ctxt, bool force_set); void (*deassert_wake)(struct mhi_device_ctxt *mhi_dev_ctxt); }; struct mhi_pcie_devices { struct mhi_pcie_dev_info device_list[MHI_MAX_SUPPORTED_DEVICES]; s32 nr_of_devices; struct mhi_device_driver { struct mutex lock; struct list_head head; struct class *mhi_bhi_class; struct dentry *parent; }; struct mhi_event_ring_cfg { u32 nr_desc; u32 msi_vec; u32 intmod; enum MHI_CLIENT_CHANNEL chan; u32 flags; enum MHI_RING_CLASS class; enum MHI_EVENT_RING_STATE state; Loading @@ -568,18 +577,20 @@ struct mhi_data_buf { u32 bounce_flag; }; extern struct mhi_device_driver *mhi_device_drv; irqreturn_t mhi_msi_ipa_handlr(int irq_number, void *dev_id); int mhi_reset_all_thread_queues( struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_add_elements_to_event_rings( struct mhi_device_ctxt *mhi_dev_ctxt, enum STATE_TRANSITION new_state); int get_nr_avail_ring_elements(struct mhi_ring *ring); int get_nr_avail_ring_elements(struct mhi_device_ctxt *mhi_dev_ctxt, struct mhi_ring *ring); int get_nr_enclosed_el(struct mhi_ring *ring, void *loc_1, void *loc_2, u32 *nr_el); int mhi_init_mmio(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_device_ctxt(struct mhi_pcie_dev_info *dev_info, struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_device_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_local_event_ring(struct mhi_device_ctxt *mhi_dev_ctxt, u32 nr_ev_el, u32 event_ring_index); int mhi_send_cmd(struct mhi_device_ctxt *dest_device, Loading Loading @@ -630,11 +641,11 @@ int mhi_wait_for_mdm(struct mhi_device_ctxt *mhi_dev_ctxt); enum hrtimer_restart mhi_initiate_m1(struct hrtimer *timer); int mhi_pci_suspend(struct device *dev); int mhi_pci_resume(struct device *dev); int mhi_init_pcie_device(struct mhi_pcie_dev_info *mhi_pcie_dev); int mhi_init_pcie_device(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_pm_sysfs(struct device *dev); void mhi_rem_pm_sysfs(struct device *dev); void mhi_pci_remove(struct pci_dev *mhi_device); int mhi_ctxt_init(struct mhi_pcie_dev_info *mhi_pcie_dev); int mhi_ctxt_init(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_get_chan_max_buffers(u32 chan); int mhi_esoc_register(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_link_state_cb(struct msm_pcie_notify *notify); Loading @@ -642,6 +653,8 @@ void mhi_notify_clients(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_CB_REASON reason); void mhi_notify_client(struct mhi_client_handle *client_handle, enum MHI_CB_REASON reason); void mhi_runtime_get(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_runtime_put(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_deassert_device_wake(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_assert_device_wake(struct mhi_device_ctxt *mhi_dev_ctxt, bool force_set); Loading Loading @@ -689,7 +702,7 @@ void init_event_ctxt_array(struct mhi_device_ctxt *mhi_dev_ctxt); int create_local_ev_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt); enum MHI_STATE mhi_get_m_state(struct mhi_device_ctxt *mhi_dev_ctxt); void process_m1_transition(struct work_struct *work); int set_mhi_base_state(struct mhi_pcie_dev_info *mhi_pcie_dev); int set_mhi_base_state(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_set_m_state(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_STATE new_state); const char *state_transition_str(enum STATE_TRANSITION state); Loading Loading
Documentation/devicetree/bindings/mhi/msm_mhi.txt +18 −4 Original line number Diff line number Diff line Loading @@ -7,6 +7,10 @@ signals. Required properties: - compatible: should be "qcom,mhi" - qcom,pci-dev_id: device id reported by modem - qcom,pci-domain: pci root complex device connected to - qcom,pci-bus: pci bus device connected to - qcom,pci-slot: pci slot device connected to - Refer to "Documentation/devicetree/bindings/esoc/esoc_client.txt" for below properties: - esoc-names Loading @@ -24,13 +28,24 @@ Required properties: C = event ring associated with channel D = flags defined by mhi_macros.h GET_CHAN_PROPS - mhi-event-cfg-#: mhi event ring configuration parameters for platform defined as below <A B C D E>: A = maximum event descriptors B = MSI associated with event C = interrupt moderation (see MHI specification) D = Associated channel E = flags defined by mhi_macros.h GET_EV_PROPS - mhi-event-rings: number of event rings supported by platform - mhi-dev-address-win-size: size of the MHI device addressing window - qcom,mhi-address-window: range of the MHI device addressing window Example: mhi: qcom,mhi { compatible = "qcom,mhi"; qcom,pci-dev_id = <0x0301>; qcom,pci-domain = <2>; qcom,pci-bus = <4>; qcom,pci-slot = <0>; qcom,mhi-address-window = <0x0 0x80000000 0x0 0xbfffffff>; esoc-names = "mdm"; esoc-0 = <&mdm1>; qcom,msm-bus,name = "mhi"; Loading @@ -39,8 +54,7 @@ Example: qcom,msm-bus,vectors-KBps = <100 512 0 0>, <100 512 1200000000 1200000000>; mhi-event-rings = <6>; mhi-event-rings = <1>; mhi-chan-cfg-102 = <0x66 0x80 0x5 0x62>; mhi-event-cfg-0 = <0x80 0x0 0x0 0x11>; mhi-dev-address-win-size= <0x10 0x00000000>; mhi-event-cfg-0 = <0x80 0x0 0x0 0x0 0x11>; };
Documentation/devicetree/bindings/platform/msm/msm_mhi_uci.txt 0 → 100644 +55 −0 Original line number Diff line number Diff line MSM MHI UCI interface device MHI userpace control interface (UCI) enables userspace software clients to communicate with device using MHI protocol. ============== Node Structure ============== Main node properties: - compatible Usage: required Value type: <string> Definition: "qcom,mhi-uci" - qcom,mhi-uci-channels Usage: required Value type: Array of <u32> Definition: Array tuples which define the channel configuration parameters. Each tuple is of length 2, 1st value represent channel, and 2nd value represent maximum payload supported. Maximum payload supported is 64 bytes. Number of tuples must be even value. Max # of tuples is 46. - qcom,mhi-uci-ctrlchan Usage: optional Value type: <u32> Definition: Channel that will be handling flow control (DTR/RTS) signals. ======= Example ======= qcom,mhi-uci@0 { compatible = "qcom,mhi-uci"; qcom,mhi-uci-channels = <0 0x1000>, <1 0x1000>, <2 0x1000>, <3 0xffff>, <10 0x1000>, <11 0x1000>, <14 0x1000>, <15 0x1000>, <16 0x1000>, <17 0x1000>, <18 0x1000>, <19 0x1000>, <24 0x1000>, <25 0x1000>, <32 0x1000>, <33 0x1000>; qcom,mhi-uci-ctrlchan = <18>; status = "ok"; };
drivers/char/diag/diagfwd_mhi.c +1 −2 Original line number Diff line number Diff line Loading @@ -665,8 +665,7 @@ static int diag_mhi_register_ch(int id, struct diag_mhi_ch_t *ch) atomic_set(&(ch->opened), 0); ctxt = SET_CH_CTXT(id, ch->type); ch->client_info.mhi_client_cb = mhi_notifier; return mhi_register_channel(&ch->hdl, ch->chan, 0, &ch->client_info, (void *)(uintptr_t)ctxt); return mhi_register_channel(&ch->hdl, NULL); } int diag_mhi_init() Loading
drivers/net/ethernet/msm/msm_rmnet_mhi.c +83 −19 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <linux/device.h> #include <linux/errno.h> #include <linux/of_device.h> #include <linux/rtnetlink.h> #define RMNET_MHI_DRIVER_NAME "rmnet_mhi" #define RMNET_MHI_DEV_NAME "rmnet_mhi%d" Loading Loading @@ -79,6 +80,7 @@ struct __packed mhi_skb_priv { struct rmnet_mhi_private { struct list_head node; u32 dev_id; struct mhi_client_handle *tx_client_handle; struct mhi_client_handle *rx_client_handle; enum MHI_CLIENT_CHANNEL tx_channel; Loading Loading @@ -792,6 +794,8 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) int ret = 0; struct rmnet_mhi_private **rmnet_mhi_ctxt = NULL; int r = 0; char ifalias[IFALIASZ]; struct mhi_client_handle *client_handle = NULL; rmnet_log(rmnet_mhi_ptr, MSG_INFO, "Entered.\n"); Loading Loading @@ -825,6 +829,7 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) } else { rmnet_mhi_ptr->tx_enabled = 1; } client_handle = rmnet_mhi_ptr->tx_client_handle; } if (rmnet_mhi_ptr->rx_client_handle != NULL) { rmnet_log(rmnet_mhi_ptr, Loading @@ -840,7 +845,26 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) } else { rmnet_mhi_ptr->rx_enabled = 1; } /* Both tx & rx client handle contain same device info */ client_handle = rmnet_mhi_ptr->rx_client_handle; } if (!client_handle) { ret = -EINVAL; goto net_dev_alloc_fail; } snprintf(ifalias, sizeof(ifalias), "%s_%04x_%02u.%02u.%02u_%u", RMNET_MHI_DRIVER_NAME, client_handle->dev_id, client_handle->domain, client_handle->bus, client_handle->slot, rmnet_mhi_ptr->dev_id); rtnl_lock(); rmnet_mhi_ptr->dev = alloc_netdev(sizeof(struct rmnet_mhi_private *), RMNET_MHI_DEV_NAME, Loading @@ -853,7 +877,9 @@ static int rmnet_mhi_enable_iface(struct rmnet_mhi_private *rmnet_mhi_ptr) goto net_dev_alloc_fail; } SET_NETDEV_DEV(rmnet_mhi_ptr->dev, &rmnet_mhi_ptr->pdev->dev); dev_set_alias(rmnet_mhi_ptr->dev, ifalias, strlen(ifalias)); rmnet_mhi_ctxt = netdev_priv(rmnet_mhi_ptr->dev); rtnl_unlock(); *rmnet_mhi_ctxt = rmnet_mhi_ptr; ret = dma_set_mask(&(rmnet_mhi_ptr->dev->dev), Loading Loading @@ -980,17 +1006,16 @@ static void rmnet_mhi_cb(struct mhi_cb_info *cb_info) } } static struct mhi_client_info_t rmnet_mhi_info = {rmnet_mhi_cb}; #ifdef CONFIG_DEBUG_FS struct dentry *dentry = NULL; static void rmnet_mhi_create_debugfs(struct rmnet_mhi_private *rmnet_mhi_ptr) { char node_name[15]; char node_name[32]; int i; const umode_t mode = (S_IRUSR | S_IWUSR); struct dentry *file; struct mhi_client_handle *client_handle; const struct { char *name; Loading Loading @@ -1046,8 +1071,20 @@ static void rmnet_mhi_create_debugfs(struct rmnet_mhi_private *rmnet_mhi_ptr) }, }; snprintf(node_name, sizeof(node_name), "%s%d", RMNET_MHI_DRIVER_NAME, rmnet_mhi_ptr->pdev->id); /* Both tx & rx client handle contain same device info */ client_handle = rmnet_mhi_ptr->rx_client_handle; if (!client_handle) client_handle = rmnet_mhi_ptr->tx_client_handle; snprintf(node_name, sizeof(node_name), "%s_%04x_%02u.%02u.%02u_%u", RMNET_MHI_DRIVER_NAME, client_handle->dev_id, client_handle->domain, client_handle->bus, client_handle->slot, rmnet_mhi_ptr->dev_id); if (IS_ERR_OR_NULL(dentry)) return; Loading Loading @@ -1108,11 +1145,16 @@ static int rmnet_mhi_probe(struct platform_device *pdev) int rc; u32 channel; struct rmnet_mhi_private *rmnet_mhi_ptr; char node_name[15]; struct mhi_client_handle *client_handle = NULL; char node_name[32]; struct mhi_client_info_t client_info; if (unlikely(pdev->dev.of_node == NULL)) return -ENODEV; if (!mhi_is_device_ready(&pdev->dev, "qcom,mhi")) return -EPROBE_DEFER; pdev->id = of_alias_get_id(pdev->dev.of_node, "mhi_rmnet"); if (unlikely(pdev->id < 0)) return -ENODEV; Loading @@ -1133,16 +1175,30 @@ static int rmnet_mhi_probe(struct platform_device *pdev) goto probe_fail; } rc = of_property_read_u32(pdev->dev.of_node, "cell-index", &rmnet_mhi_ptr->dev_id); if (unlikely(rc)) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, "failed to get valid 'cell-index'\n"); goto probe_fail; } client_info.dev = &pdev->dev; client_info.node_name = "qcom,mhi"; client_info.mhi_client_cb = rmnet_mhi_cb; client_info.user_data = rmnet_mhi_ptr; rc = of_property_read_u32(pdev->dev.of_node, "qcom,mhi-tx-channel", &channel); if (rc == 0) { rmnet_mhi_ptr->tx_channel = channel; client_info.chan = channel; rc = mhi_register_channel(&rmnet_mhi_ptr->tx_client_handle, rmnet_mhi_ptr->tx_channel, 0, &rmnet_mhi_info, rmnet_mhi_ptr); &client_info); if (unlikely(rc)) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, Loading @@ -1151,6 +1207,7 @@ static int rmnet_mhi_probe(struct platform_device *pdev) rc); goto probe_fail; } client_handle = rmnet_mhi_ptr->tx_client_handle; } rc = of_property_read_u32(pdev->dev.of_node, Loading @@ -1158,11 +1215,9 @@ static int rmnet_mhi_probe(struct platform_device *pdev) &channel); if (rc == 0) { rmnet_mhi_ptr->rx_channel = channel; client_info.chan = channel; rc = mhi_register_channel(&rmnet_mhi_ptr->rx_client_handle, rmnet_mhi_ptr->rx_channel, 0, &rmnet_mhi_info, rmnet_mhi_ptr); &client_info); if (unlikely(rc)) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, Loading @@ -1171,22 +1226,31 @@ static int rmnet_mhi_probe(struct platform_device *pdev) rc); goto probe_fail; } /* overwriting tx_client_handle is ok because dev_id and * bdf are same for both channels */ client_handle = rmnet_mhi_ptr->rx_client_handle; INIT_WORK(&rmnet_mhi_ptr->alloc_work, rmnet_mhi_alloc_work); spin_lock_init(&rmnet_mhi_ptr->alloc_lock); } /* We must've have @ least one valid channel */ if (rmnet_mhi_ptr->rx_client_handle == NULL && rmnet_mhi_ptr->tx_client_handle == NULL) { if (!client_handle) { rmnet_log(rmnet_mhi_ptr, MSG_CRITICAL, "No registered channels\n"); rc = -ENODEV; goto probe_fail; } snprintf(node_name, sizeof(node_name), "%s%d", RMNET_MHI_DRIVER_NAME, pdev->id); snprintf(node_name, sizeof(node_name), "%s_%04x_%02u.%02u.%02u_%u", RMNET_MHI_DRIVER_NAME, client_handle->dev_id, client_handle->domain, client_handle->bus, client_handle->slot, rmnet_mhi_ptr->dev_id); rmnet_mhi_ptr->rmnet_ipc_log = ipc_log_context_create(RMNET_IPC_LOG_PAGES, node_name, 0); Loading
drivers/platform/msm/mhi/mhi.h +43 −30 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ #include <linux/list.h> #include <linux/dma-mapping.h> extern struct mhi_pcie_devices mhi_devices; struct mhi_device_ctxt; enum MHI_DEBUG_LEVEL { Loading @@ -49,11 +48,13 @@ struct pcie_core_info { u32 mhi_ver; void __iomem *bar0_base; void __iomem *bar0_end; void __iomem *bar2_base; void __iomem *bar2_end; u32 irq_base; u32 max_nr_msis; u32 domain; u32 bus; u32 slot; struct pci_saved_state *pcie_state; bool pci_master; }; struct bhi_ctxt_t { Loading @@ -64,7 +65,6 @@ struct bhi_ctxt_t { void *unaligned_image_loc; dev_t bhi_dev; struct cdev cdev; struct class *bhi_class; struct device *dev; }; Loading Loading @@ -206,6 +206,7 @@ enum MHI_PKT_TYPE { MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21, MHI_PKT_TYPE_TX_EVENT = 0x22, MHI_PKT_TYPE_EE_EVENT = 0x40, MHI_PKT_TYPE_STALE_EVENT, /* Internal event */ MHI_PKT_TYPE_SYS_ERR_EVENT = 0xFF, }; Loading Loading @@ -310,6 +311,7 @@ struct mhi_ring { uintptr_t el_size; u32 overwrite_en; enum MHI_CHAN_DIR dir; enum MHI_CHAN_STATE ch_state; struct db_mode db_mode; u32 msi_disable_cntr; u32 msi_enable_cntr; Loading Loading @@ -380,7 +382,7 @@ struct mhi_chan_cfg { union mhi_cmd_pkt cmd_pkt; }; struct mhi_client_handle { struct mhi_client_config { struct mhi_chan_info chan_info; struct mhi_device_ctxt *mhi_dev_ctxt; struct mhi_client_info_t client_info; Loading Loading @@ -432,6 +434,8 @@ struct mhi_counters { atomic_t events_pending; u32 *msi_counter; u32 mhi_reset_cntr; u32 link_down_cntr; u32 link_up_cntr; }; struct mhi_flags { Loading Loading @@ -484,13 +488,17 @@ struct mhi_dev_space { }; struct mhi_device_ctxt { struct list_head node; struct pcie_core_info core; struct msm_pcie_register_event mhi_pci_link_event; struct pci_dev *pcie_device; struct bhi_ctxt_t bhi_ctxt; struct platform_device *plat_dev; enum MHI_PM_STATE mhi_pm_state; /* Host driver state */ enum MHI_STATE mhi_state; /* protocol state */ enum MHI_EXEC_ENV dev_exec_env; struct mhi_dev_space dev_space; struct mhi_pcie_dev_info *dev_info; struct pcie_core_info *dev_props; struct mhi_ring chan_bb_list[MHI_MAX_CHANNELS]; struct mhi_ring mhi_local_chan_ctxt[MHI_MAX_CHANNELS]; Loading @@ -498,7 +506,6 @@ struct mhi_device_ctxt { struct mhi_ring mhi_local_cmd_ctxt[NR_OF_CMD_RINGS]; struct mhi_chan_cfg mhi_chan_cfg[MHI_MAX_CHANNELS]; struct mhi_client_handle *client_handle_list[MHI_MAX_CHANNELS]; struct mhi_event_ring_cfg *ev_ring_props; struct task_struct *event_thread_handle; Loading @@ -515,7 +522,9 @@ struct mhi_device_ctxt { struct hrtimer m1_timer; ktime_t m1_timeout; u32 poll_reset_timeout_ms; struct notifier_block mhi_ssr_nb; struct esoc_desc *esoc_handle; void *esoc_ssr_handle; Loading @@ -532,30 +541,30 @@ struct mhi_device_ctxt { struct wakeup_source w_lock; char *chan_info; struct dentry *mhi_parent_folder; }; struct mhi_pcie_dev_info { struct pcie_core_info core; struct mhi_device_ctxt mhi_ctxt; struct msm_pcie_register_event mhi_pci_link_event; struct pci_dev *pcie_device; struct pci_driver *mhi_pcie_driver; struct bhi_ctxt_t bhi_ctxt; struct platform_device *plat_dev; u32 link_down_cntr; u32 link_up_cntr; struct dentry *child; struct dentry *parent; void *mhi_ipc_log; /* Shadow functions since not all device supports runtime pm */ void (*runtime_get)(struct mhi_device_ctxt *mhi_dev_ctxt); void (*runtime_put)(struct mhi_device_ctxt *mhi_dev_ctxt); void (*assert_wake)(struct mhi_device_ctxt *mhi_dev_ctxt, bool force_set); void (*deassert_wake)(struct mhi_device_ctxt *mhi_dev_ctxt); }; struct mhi_pcie_devices { struct mhi_pcie_dev_info device_list[MHI_MAX_SUPPORTED_DEVICES]; s32 nr_of_devices; struct mhi_device_driver { struct mutex lock; struct list_head head; struct class *mhi_bhi_class; struct dentry *parent; }; struct mhi_event_ring_cfg { u32 nr_desc; u32 msi_vec; u32 intmod; enum MHI_CLIENT_CHANNEL chan; u32 flags; enum MHI_RING_CLASS class; enum MHI_EVENT_RING_STATE state; Loading @@ -568,18 +577,20 @@ struct mhi_data_buf { u32 bounce_flag; }; extern struct mhi_device_driver *mhi_device_drv; irqreturn_t mhi_msi_ipa_handlr(int irq_number, void *dev_id); int mhi_reset_all_thread_queues( struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_add_elements_to_event_rings( struct mhi_device_ctxt *mhi_dev_ctxt, enum STATE_TRANSITION new_state); int get_nr_avail_ring_elements(struct mhi_ring *ring); int get_nr_avail_ring_elements(struct mhi_device_ctxt *mhi_dev_ctxt, struct mhi_ring *ring); int get_nr_enclosed_el(struct mhi_ring *ring, void *loc_1, void *loc_2, u32 *nr_el); int mhi_init_mmio(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_device_ctxt(struct mhi_pcie_dev_info *dev_info, struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_device_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_local_event_ring(struct mhi_device_ctxt *mhi_dev_ctxt, u32 nr_ev_el, u32 event_ring_index); int mhi_send_cmd(struct mhi_device_ctxt *dest_device, Loading Loading @@ -630,11 +641,11 @@ int mhi_wait_for_mdm(struct mhi_device_ctxt *mhi_dev_ctxt); enum hrtimer_restart mhi_initiate_m1(struct hrtimer *timer); int mhi_pci_suspend(struct device *dev); int mhi_pci_resume(struct device *dev); int mhi_init_pcie_device(struct mhi_pcie_dev_info *mhi_pcie_dev); int mhi_init_pcie_device(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_init_pm_sysfs(struct device *dev); void mhi_rem_pm_sysfs(struct device *dev); void mhi_pci_remove(struct pci_dev *mhi_device); int mhi_ctxt_init(struct mhi_pcie_dev_info *mhi_pcie_dev); int mhi_ctxt_init(struct mhi_device_ctxt *mhi_dev_ctxt); int mhi_get_chan_max_buffers(u32 chan); int mhi_esoc_register(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_link_state_cb(struct msm_pcie_notify *notify); Loading @@ -642,6 +653,8 @@ void mhi_notify_clients(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_CB_REASON reason); void mhi_notify_client(struct mhi_client_handle *client_handle, enum MHI_CB_REASON reason); void mhi_runtime_get(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_runtime_put(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_deassert_device_wake(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_assert_device_wake(struct mhi_device_ctxt *mhi_dev_ctxt, bool force_set); Loading Loading @@ -689,7 +702,7 @@ void init_event_ctxt_array(struct mhi_device_ctxt *mhi_dev_ctxt); int create_local_ev_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt); enum MHI_STATE mhi_get_m_state(struct mhi_device_ctxt *mhi_dev_ctxt); void process_m1_transition(struct work_struct *work); int set_mhi_base_state(struct mhi_pcie_dev_info *mhi_pcie_dev); int set_mhi_base_state(struct mhi_device_ctxt *mhi_dev_ctxt); void mhi_set_m_state(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_STATE new_state); const char *state_transition_str(enum STATE_TRANSITION state); Loading