Loading Documentation/devicetree/bindings/mhi/msm_mhi.txt +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ Main node properties: Definition: "qcom,mhi" - qcom,pci-dev_id Usage: required Usage: optional Value type: <u32> Definition: Device id reported by modem Loading drivers/platform/msm/mhi/mhi_iface.c +28 −21 Original line number Diff line number Diff line Loading @@ -153,16 +153,19 @@ static int mhi_pci_probe(struct pci_dev *pcie_device, u32 slot = PCI_SLOT(pcie_device->devfn); unsigned long msi_requested, msi_required; struct msm_pcie_register_event *mhi_pci_link_event; struct pcie_core_info *core; int i; char node[32]; /* Find correct device context based on bdf & dev_id */ mutex_lock(&mhi_device_drv->lock); list_for_each_entry(itr, &mhi_device_drv->head, node) { struct pcie_core_info *core = &itr->core; if (core->domain == domain && core->bus == bus && core->dev_id == dev_id && core = &itr->core; if (core->domain == domain && core->bus == bus && (core->dev_id == PCI_ANY_ID || (core->dev_id == dev_id)) && core->slot == slot) { /* change default dev_id to actual dev_id */ core->dev_id = dev_id; mhi_dev_ctxt = itr; break; } Loading @@ -171,6 +174,11 @@ static int mhi_pci_probe(struct pci_dev *pcie_device, if (!mhi_dev_ctxt) return -EPROBE_DEFER; snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u", core->dev_id, core->domain, core->bus, core->slot); mhi_dev_ctxt->mhi_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES, node, 0); mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Processing Domain:%02u Bus:%04u dev:0x%04x slot:%04u\n", domain, bus, dev_id, slot); Loading Loading @@ -280,9 +288,22 @@ static int mhi_pci_probe(struct pci_dev *pcie_device, mutex_lock(&mhi_dev_ctxt->pm_lock); write_lock_irq(&mhi_dev_ctxt->pm_xfer_lock); mhi_dev_ctxt->mhi_pm_state = MHI_PM_POR; ret_val = set_mhi_base_state(mhi_dev_ctxt); write_unlock_irq(&mhi_dev_ctxt->pm_xfer_lock); /* notify all registered clients we probed */ for (i = 0; i < MHI_MAX_CHANNELS; i++) { struct mhi_client_handle *client_handle = mhi_dev_ctxt->client_handle_list[i]; if (!client_handle) continue; client_handle->dev_id = core->dev_id; mhi_notify_client(client_handle, MHI_CB_MHI_PROBED); } write_lock_irq(&mhi_dev_ctxt->pm_xfer_lock); ret_val = set_mhi_base_state(mhi_dev_ctxt); write_unlock_irq(&mhi_dev_ctxt->pm_xfer_lock); if (ret_val) { mhi_log(mhi_dev_ctxt, MHI_MSG_ERROR, Loading Loading @@ -344,7 +365,6 @@ static int mhi_plat_probe(struct platform_device *pdev) int r = 0, len; struct mhi_device_ctxt *mhi_dev_ctxt; struct pcie_core_info *core; char node[32]; struct device_node *of_node = pdev->dev.of_node; u64 address_window[2]; Loading Loading @@ -377,7 +397,7 @@ static int mhi_plat_probe(struct platform_device *pdev) core = &mhi_dev_ctxt->core; r = of_property_read_u32(of_node, "qcom,pci-dev_id", &core->dev_id); if (r) return r; core->dev_id = PCI_ANY_ID; r = of_property_read_u32(of_node, "qcom,pci-slot", &core->slot); if (r) Loading @@ -391,14 +411,6 @@ static int mhi_plat_probe(struct platform_device *pdev) if (r) return r; snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u", core->dev_id, core->domain, core->bus, core->slot); mhi_dev_ctxt->mhi_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES, node, 0); if (!mhi_dev_ctxt->mhi_ipc_log) pr_err("%s: Error creating ipc_log buffer\n", __func__); r = of_property_read_u32(of_node, "qcom,mhi-ready-timeout", &mhi_dev_ctxt->poll_reset_timeout_ms); if (r) Loading @@ -407,10 +419,6 @@ static int mhi_plat_probe(struct platform_device *pdev) mhi_dev_ctxt->dev_space.start_win_addr = address_window[0]; mhi_dev_ctxt->dev_space.end_win_addr = address_window[1]; mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Start Addr:0x%llx End_Addr:0x%llx\n", mhi_dev_ctxt->dev_space.start_win_addr, mhi_dev_ctxt->dev_space.end_win_addr); r = of_property_read_u32(of_node, "qcom,bhi-alignment", &mhi_dev_ctxt->bhi_ctxt.alignment); Loading Loading @@ -471,7 +479,6 @@ static int mhi_plat_probe(struct platform_device *pdev) mutex_lock(&mhi_device_drv->lock); list_add_tail(&mhi_dev_ctxt->node, &mhi_device_drv->head); mutex_unlock(&mhi_device_drv->lock); mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Exited\n"); return 0; } Loading drivers/platform/msm/mhi/mhi_main.c +27 −11 Original line number Diff line number Diff line Loading @@ -563,6 +563,7 @@ int mhi_register_channel(struct mhi_client_handle **client_handle, (*client_handle)->domain = mhi_dev_ctxt->core.domain; (*client_handle)->bus = mhi_dev_ctxt->core.bus; (*client_handle)->slot = mhi_dev_ctxt->core.slot; (*client_handle)->enabled = false; client_config = (*client_handle)->client_config; client_config->mhi_dev_ctxt = mhi_dev_ctxt; client_config->user_data = client_info->user_data; Loading @@ -589,11 +590,8 @@ int mhi_register_channel(struct mhi_client_handle **client_handle, } if (mhi_dev_ctxt->dev_exec_env == MHI_EXEC_ENV_AMSS && mhi_dev_ctxt->flags.mhi_initialized) { mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Exec env is AMSS notify client now chan:%u\n", chan); mhi_notify_client(*client_handle, MHI_CB_MHI_ENABLED); } mhi_dev_ctxt->flags.mhi_initialized) (*client_handle)->enabled = true; mhi_log(mhi_dev_ctxt, MHI_MSG_VERBOSE, "Successfuly registered chan:%u\n", chan); Loading Loading @@ -1790,6 +1788,8 @@ int mhi_register_device(struct mhi_device *mhi_device, u32 dev_id = pci_dev->device; u32 slot = PCI_SLOT(pci_dev->devfn); int ret, i; char node[32]; struct pcie_core_info *core; of_node = of_parse_phandle(mhi_device->dev->of_node, node_name, 0); if (!of_node) Loading @@ -1802,13 +1802,13 @@ int mhi_register_device(struct mhi_device *mhi_device, mutex_lock(&mhi_device_drv->lock); list_for_each_entry(itr, &mhi_device_drv->head, node) { struct platform_device *pdev = itr->plat_dev; struct pcie_core_info *core = &itr->core; if (pdev->dev.of_node == of_node && core->domain == domain && core->bus == bus && core->dev_id == dev_id && core->slot == slot) { core = &itr->core; if (pdev->dev.of_node == of_node && core->domain == domain && core->bus == bus && core->slot == slot && (core->dev_id == PCI_ANY_ID || (core->dev_id == dev_id))) { /* change default dev_id to current dev_id */ core->dev_id = dev_id; mhi_dev_ctxt = itr; break; } Loading @@ -1819,6 +1819,11 @@ int mhi_register_device(struct mhi_device *mhi_device, if (!mhi_dev_ctxt) return -EPROBE_DEFER; snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u", core->dev_id, core->domain, core->bus, core->slot); mhi_dev_ctxt->mhi_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES, node, 0); mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Registering Domain:%02u Bus:%04u dev:0x%04x slot:%04u\n", domain, bus, dev_id, slot); Loading Loading @@ -1900,6 +1905,17 @@ int mhi_register_device(struct mhi_device *mhi_device, mhi_dev_ctxt->bhi_ctxt.rddm_size); } /* notify all the registered clients we probed */ for (i = 0; i < MHI_MAX_CHANNELS; i++) { struct mhi_client_handle *client_handle = mhi_dev_ctxt->client_handle_list[i]; if (!client_handle) continue; client_handle->dev_id = core->dev_id; mhi_notify_client(client_handle, MHI_CB_MHI_PROBED); } mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Exit success\n"); return 0; } Loading drivers/platform/msm/mhi/mhi_states.c +11 −11 Original line number Diff line number Diff line Loading @@ -593,24 +593,24 @@ static void enable_clients(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_EXEC_ENV exec_env) { struct mhi_client_handle *client_handle = NULL; struct mhi_cb_info cb_info; int i = 0, r = 0; struct mhi_chan_info chan_info; cb_info.cb_reason = MHI_CB_MHI_ENABLED; struct mhi_chan_info *chan_info; int i = 0; mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Enabling Clients, exec env %d.\n", exec_env); for (i = 0; i < MHI_MAX_CHANNELS; ++i) { if (!VALID_CHAN_NR(i)) if (!mhi_dev_ctxt->client_handle_list[i]) continue; client_handle = mhi_dev_ctxt->client_handle_list[i]; r = get_chan_props(mhi_dev_ctxt, i, &chan_info); if (!r && client_handle && exec_env == GET_CHAN_PROPS(CHAN_BRINGUP_STAGE, chan_info.flags)) chan_info = &client_handle->client_config->chan_info; if (exec_env == GET_CHAN_PROPS(CHAN_BRINGUP_STAGE, chan_info->flags)) { client_handle->enabled = true; mhi_notify_client(client_handle, MHI_CB_MHI_ENABLED); } } mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Done.\n"); } Loading drivers/platform/msm/mhi_uci/mhi_uci.c +98 −102 Original line number Diff line number Diff line Loading @@ -122,6 +122,7 @@ struct uci_client { atomic_t out_pkt_pend_ack; atomic_t completion_ack; struct mhi_uci_ctxt_t *uci_ctxt; struct cdev cdev; bool enabled; void *uci_ipc_log; }; Loading @@ -132,7 +133,6 @@ struct mhi_uci_ctxt_t { struct uci_client client_handles[MHI_SOFTWARE_CLIENT_LIMIT]; dev_t dev_t; struct mutex ctrl_mutex; struct cdev cdev[MHI_SOFTWARE_CLIENT_LIMIT]; struct uci_client *ctrl_client; }; Loading Loading @@ -246,6 +246,7 @@ static int mhi_uci_client_release(struct inode *mhi_inode, static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait); static long mhi_uci_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static int mhi_uci_create_device(struct uci_client *uci_client); static struct mhi_uci_drv_ctxt mhi_uci_drv_ctxt; Loading Loading @@ -1174,6 +1175,14 @@ static void uci_xfer_cb(struct mhi_cb_info *cb_info) uci_handle = cb_info->result->user_data; switch (cb_info->cb_reason) { case MHI_CB_MHI_PROBED: /* If it's outbound channel create the node */ mutex_lock(&uci_handle->client_lock); if (!uci_handle->dev && cb_info->chan == uci_handle->out_attr.chan_id) mhi_uci_create_device(uci_handle); mutex_unlock(&uci_handle->client_lock); break; case MHI_CB_MHI_ENABLED: uci_log(uci_handle->uci_ipc_log, UCI_DBG_INFO, "MHI enabled CB received for chan %d\n", Loading Loading @@ -1295,17 +1304,65 @@ static const struct file_operations mhi_uci_client_fops = { .unlocked_ioctl = mhi_uci_ctl_ioctl, }; static int mhi_uci_create_device(struct uci_client *uci_client) { struct mhi_uci_ctxt_t *uci_ctxt = uci_client->uci_ctxt; char node_name[32]; int index = uci_client - uci_ctxt->client_handles; int ret; uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Creating dev node %04x_%02u.%02u.%02u_pipe%d\n", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, uci_client->out_attr.chan_id); cdev_init(&uci_client->cdev, &mhi_uci_client_fops); uci_client->cdev.owner = THIS_MODULE; ret = cdev_add(&uci_client->cdev, uci_ctxt->dev_t + index, 1); if (ret) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d, ret:%d\n", index, ret); return ret; } uci_client->dev = device_create(mhi_uci_drv_ctxt.mhi_uci_class, NULL, uci_ctxt->dev_t + index, NULL, DEVICE_NAME "_%04x_%02u.%02u.%02u%s%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, "_pipe_", uci_client->out_attr.chan_id); if (IS_ERR(uci_client->dev)) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d\n", IS_ERR(uci_client->dev)); cdev_del(&uci_client->cdev); return -EIO; } /* dev node created successfully, create logging buffer */ snprintf(node_name, sizeof(node_name), "mhi_uci_%04x_%02u.%02u.%02u_%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, uci_client->out_attr.chan_id); uci_client->uci_ipc_log = ipc_log_context_create(MHI_UCI_IPC_LOG_PAGES, node_name, 0); return 0; } static int mhi_uci_probe(struct platform_device *pdev) { struct mhi_uci_ctxt_t *uci_ctxt; int ret_val; int i; char node_name[32]; uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Entered with pdev:%p\n", pdev); uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Entered\n"); if (mhi_is_device_ready(&pdev->dev, "qcom,mhi") == false) return -EPROBE_DEFER; Loading @@ -1326,128 +1383,67 @@ static int mhi_uci_probe(struct platform_device *pdev) uci_ctxt->pdev = pdev; mutex_init(&uci_ctxt->ctrl_mutex); uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Setting up channel attributes\n"); ret_val = uci_init_client_attributes(uci_ctxt, pdev->dev.of_node); if (ret_val) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to init client attributes\n"); return -EIO; } uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Allocating char devices\n"); ret_val = alloc_chrdev_region(&uci_ctxt->dev_t, 0, MHI_SOFTWARE_CLIENT_LIMIT, DEVICE_NAME); if (IS_ERR_VALUE(ret_val)) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to alloc char devs, ret 0x%x\n", ret_val); return ret_val; } uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Registering for MHI events\n"); for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; ++i) { struct uci_client *uci_client = &uci_ctxt->client_handles[i]; uci_client->uci_ctxt = uci_ctxt; mutex_init(&uci_client->client_lock); if (uci_client->in_attr.uci_ownership) { ret_val = mhi_register_client(uci_client, &pdev->dev); if (!uci_client->in_attr.uci_ownership) continue; ret_val = mhi_register_client(uci_client, &pdev->dev); if (ret_val) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_CRITICAL, "Failed to reg client %d ret %d\n", ret_val, i); ret_val, i); return -EIO; } snprintf(node_name, sizeof(node_name), "mhi_uci_%04x_%02u.%02u.%02u_%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, uci_client->out_attr.chan_id); uci_client->uci_ipc_log = ipc_log_context_create (MHI_UCI_IPC_LOG_PAGES, node_name, 0); } } uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Allocating char devices\n"); ret_val = alloc_chrdev_region(&uci_ctxt->dev_t, 0, MHI_SOFTWARE_CLIENT_LIMIT, DEVICE_NAME); if (IS_ERR_VALUE(ret_val)) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to alloc char devs, ret 0x%x\n", ret_val); goto failed_char_alloc; } mutex_lock(&uci_client->client_lock); /* If we have device id, create the node now */ if (uci_client->out_attr.mhi_handle->dev_id != PCI_ANY_ID) { ret_val = mhi_uci_create_device(uci_client); if (ret_val) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Setting up device nodes. for dev_t: 0x%x major:0x%x\n", uci_ctxt->dev_t, MAJOR(uci_ctxt->dev_t)); for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; ++i) { struct uci_client *uci_client = &uci_ctxt->client_handles[i]; if (uci_client->in_attr.uci_ownership) { cdev_init(&uci_ctxt->cdev[i], &mhi_uci_client_fops); uci_ctxt->cdev[i].owner = THIS_MODULE; ret_val = cdev_add(&uci_ctxt->cdev[i], uci_ctxt->dev_t + i , 1); if (IS_ERR_VALUE(ret_val)) { uci_log(uci_client->uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d, ret 0x%x\n", i, ret_val); goto failed_char_add; } uci_client->dev = device_create(mhi_uci_drv_ctxt.mhi_uci_class, NULL, uci_ctxt->dev_t + i, NULL, DEVICE_NAME "_%04x_%02u.%02u.%02u%s%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, "_pipe_", uci_client->out_attr.chan_id); if (IS_ERR(uci_client->dev)) { uci_log(uci_client->uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d\n", i); cdev_del(&uci_ctxt->cdev[i]); ret_val = -EIO; goto failed_device_create; UCI_DBG_CRITICAL, "Failed to create device node, ret:%d\n", ret_val); mutex_unlock(&uci_client->client_lock); return -EIO; } } mutex_unlock(&uci_client->client_lock); } platform_set_drvdata(pdev, uci_ctxt); mutex_lock(&mhi_uci_drv_ctxt.list_lock); list_add_tail(&uci_ctxt->node, &mhi_uci_drv_ctxt.head); mutex_unlock(&mhi_uci_drv_ctxt.list_lock); return 0; failed_char_add: failed_device_create: while (--i >= 0) { cdev_del(&uci_ctxt->cdev[i]); device_destroy(mhi_uci_drv_ctxt.mhi_uci_class, MKDEV(MAJOR(uci_ctxt->dev_t), i)); }; unregister_chrdev_region(MAJOR(uci_ctxt->dev_t), MHI_SOFTWARE_CLIENT_LIMIT); failed_char_alloc: return ret_val; return 0; }; static int mhi_uci_remove(struct platform_device *pdev) Loading @@ -1462,7 +1458,7 @@ static int mhi_uci_remove(struct platform_device *pdev) if (uci_client->in_attr.uci_ownership) { mhi_deregister_channel(uci_client->out_attr.mhi_handle); mhi_deregister_channel(uci_client->in_attr.mhi_handle); cdev_del(&uci_ctxt->cdev[i]); cdev_del(&uci_client->cdev); device_destroy(mhi_uci_drv_ctxt.mhi_uci_class, MKDEV(MAJOR(uci_ctxt->dev_t), i)); } Loading Loading
Documentation/devicetree/bindings/mhi/msm_mhi.txt +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ Main node properties: Definition: "qcom,mhi" - qcom,pci-dev_id Usage: required Usage: optional Value type: <u32> Definition: Device id reported by modem Loading
drivers/platform/msm/mhi/mhi_iface.c +28 −21 Original line number Diff line number Diff line Loading @@ -153,16 +153,19 @@ static int mhi_pci_probe(struct pci_dev *pcie_device, u32 slot = PCI_SLOT(pcie_device->devfn); unsigned long msi_requested, msi_required; struct msm_pcie_register_event *mhi_pci_link_event; struct pcie_core_info *core; int i; char node[32]; /* Find correct device context based on bdf & dev_id */ mutex_lock(&mhi_device_drv->lock); list_for_each_entry(itr, &mhi_device_drv->head, node) { struct pcie_core_info *core = &itr->core; if (core->domain == domain && core->bus == bus && core->dev_id == dev_id && core = &itr->core; if (core->domain == domain && core->bus == bus && (core->dev_id == PCI_ANY_ID || (core->dev_id == dev_id)) && core->slot == slot) { /* change default dev_id to actual dev_id */ core->dev_id = dev_id; mhi_dev_ctxt = itr; break; } Loading @@ -171,6 +174,11 @@ static int mhi_pci_probe(struct pci_dev *pcie_device, if (!mhi_dev_ctxt) return -EPROBE_DEFER; snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u", core->dev_id, core->domain, core->bus, core->slot); mhi_dev_ctxt->mhi_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES, node, 0); mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Processing Domain:%02u Bus:%04u dev:0x%04x slot:%04u\n", domain, bus, dev_id, slot); Loading Loading @@ -280,9 +288,22 @@ static int mhi_pci_probe(struct pci_dev *pcie_device, mutex_lock(&mhi_dev_ctxt->pm_lock); write_lock_irq(&mhi_dev_ctxt->pm_xfer_lock); mhi_dev_ctxt->mhi_pm_state = MHI_PM_POR; ret_val = set_mhi_base_state(mhi_dev_ctxt); write_unlock_irq(&mhi_dev_ctxt->pm_xfer_lock); /* notify all registered clients we probed */ for (i = 0; i < MHI_MAX_CHANNELS; i++) { struct mhi_client_handle *client_handle = mhi_dev_ctxt->client_handle_list[i]; if (!client_handle) continue; client_handle->dev_id = core->dev_id; mhi_notify_client(client_handle, MHI_CB_MHI_PROBED); } write_lock_irq(&mhi_dev_ctxt->pm_xfer_lock); ret_val = set_mhi_base_state(mhi_dev_ctxt); write_unlock_irq(&mhi_dev_ctxt->pm_xfer_lock); if (ret_val) { mhi_log(mhi_dev_ctxt, MHI_MSG_ERROR, Loading Loading @@ -344,7 +365,6 @@ static int mhi_plat_probe(struct platform_device *pdev) int r = 0, len; struct mhi_device_ctxt *mhi_dev_ctxt; struct pcie_core_info *core; char node[32]; struct device_node *of_node = pdev->dev.of_node; u64 address_window[2]; Loading Loading @@ -377,7 +397,7 @@ static int mhi_plat_probe(struct platform_device *pdev) core = &mhi_dev_ctxt->core; r = of_property_read_u32(of_node, "qcom,pci-dev_id", &core->dev_id); if (r) return r; core->dev_id = PCI_ANY_ID; r = of_property_read_u32(of_node, "qcom,pci-slot", &core->slot); if (r) Loading @@ -391,14 +411,6 @@ static int mhi_plat_probe(struct platform_device *pdev) if (r) return r; snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u", core->dev_id, core->domain, core->bus, core->slot); mhi_dev_ctxt->mhi_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES, node, 0); if (!mhi_dev_ctxt->mhi_ipc_log) pr_err("%s: Error creating ipc_log buffer\n", __func__); r = of_property_read_u32(of_node, "qcom,mhi-ready-timeout", &mhi_dev_ctxt->poll_reset_timeout_ms); if (r) Loading @@ -407,10 +419,6 @@ static int mhi_plat_probe(struct platform_device *pdev) mhi_dev_ctxt->dev_space.start_win_addr = address_window[0]; mhi_dev_ctxt->dev_space.end_win_addr = address_window[1]; mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Start Addr:0x%llx End_Addr:0x%llx\n", mhi_dev_ctxt->dev_space.start_win_addr, mhi_dev_ctxt->dev_space.end_win_addr); r = of_property_read_u32(of_node, "qcom,bhi-alignment", &mhi_dev_ctxt->bhi_ctxt.alignment); Loading Loading @@ -471,7 +479,6 @@ static int mhi_plat_probe(struct platform_device *pdev) mutex_lock(&mhi_device_drv->lock); list_add_tail(&mhi_dev_ctxt->node, &mhi_device_drv->head); mutex_unlock(&mhi_device_drv->lock); mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Exited\n"); return 0; } Loading
drivers/platform/msm/mhi/mhi_main.c +27 −11 Original line number Diff line number Diff line Loading @@ -563,6 +563,7 @@ int mhi_register_channel(struct mhi_client_handle **client_handle, (*client_handle)->domain = mhi_dev_ctxt->core.domain; (*client_handle)->bus = mhi_dev_ctxt->core.bus; (*client_handle)->slot = mhi_dev_ctxt->core.slot; (*client_handle)->enabled = false; client_config = (*client_handle)->client_config; client_config->mhi_dev_ctxt = mhi_dev_ctxt; client_config->user_data = client_info->user_data; Loading @@ -589,11 +590,8 @@ int mhi_register_channel(struct mhi_client_handle **client_handle, } if (mhi_dev_ctxt->dev_exec_env == MHI_EXEC_ENV_AMSS && mhi_dev_ctxt->flags.mhi_initialized) { mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Exec env is AMSS notify client now chan:%u\n", chan); mhi_notify_client(*client_handle, MHI_CB_MHI_ENABLED); } mhi_dev_ctxt->flags.mhi_initialized) (*client_handle)->enabled = true; mhi_log(mhi_dev_ctxt, MHI_MSG_VERBOSE, "Successfuly registered chan:%u\n", chan); Loading Loading @@ -1790,6 +1788,8 @@ int mhi_register_device(struct mhi_device *mhi_device, u32 dev_id = pci_dev->device; u32 slot = PCI_SLOT(pci_dev->devfn); int ret, i; char node[32]; struct pcie_core_info *core; of_node = of_parse_phandle(mhi_device->dev->of_node, node_name, 0); if (!of_node) Loading @@ -1802,13 +1802,13 @@ int mhi_register_device(struct mhi_device *mhi_device, mutex_lock(&mhi_device_drv->lock); list_for_each_entry(itr, &mhi_device_drv->head, node) { struct platform_device *pdev = itr->plat_dev; struct pcie_core_info *core = &itr->core; if (pdev->dev.of_node == of_node && core->domain == domain && core->bus == bus && core->dev_id == dev_id && core->slot == slot) { core = &itr->core; if (pdev->dev.of_node == of_node && core->domain == domain && core->bus == bus && core->slot == slot && (core->dev_id == PCI_ANY_ID || (core->dev_id == dev_id))) { /* change default dev_id to current dev_id */ core->dev_id = dev_id; mhi_dev_ctxt = itr; break; } Loading @@ -1819,6 +1819,11 @@ int mhi_register_device(struct mhi_device *mhi_device, if (!mhi_dev_ctxt) return -EPROBE_DEFER; snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u", core->dev_id, core->domain, core->bus, core->slot); mhi_dev_ctxt->mhi_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES, node, 0); mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Registering Domain:%02u Bus:%04u dev:0x%04x slot:%04u\n", domain, bus, dev_id, slot); Loading Loading @@ -1900,6 +1905,17 @@ int mhi_register_device(struct mhi_device *mhi_device, mhi_dev_ctxt->bhi_ctxt.rddm_size); } /* notify all the registered clients we probed */ for (i = 0; i < MHI_MAX_CHANNELS; i++) { struct mhi_client_handle *client_handle = mhi_dev_ctxt->client_handle_list[i]; if (!client_handle) continue; client_handle->dev_id = core->dev_id; mhi_notify_client(client_handle, MHI_CB_MHI_PROBED); } mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Exit success\n"); return 0; } Loading
drivers/platform/msm/mhi/mhi_states.c +11 −11 Original line number Diff line number Diff line Loading @@ -593,24 +593,24 @@ static void enable_clients(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_EXEC_ENV exec_env) { struct mhi_client_handle *client_handle = NULL; struct mhi_cb_info cb_info; int i = 0, r = 0; struct mhi_chan_info chan_info; cb_info.cb_reason = MHI_CB_MHI_ENABLED; struct mhi_chan_info *chan_info; int i = 0; mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Enabling Clients, exec env %d.\n", exec_env); for (i = 0; i < MHI_MAX_CHANNELS; ++i) { if (!VALID_CHAN_NR(i)) if (!mhi_dev_ctxt->client_handle_list[i]) continue; client_handle = mhi_dev_ctxt->client_handle_list[i]; r = get_chan_props(mhi_dev_ctxt, i, &chan_info); if (!r && client_handle && exec_env == GET_CHAN_PROPS(CHAN_BRINGUP_STAGE, chan_info.flags)) chan_info = &client_handle->client_config->chan_info; if (exec_env == GET_CHAN_PROPS(CHAN_BRINGUP_STAGE, chan_info->flags)) { client_handle->enabled = true; mhi_notify_client(client_handle, MHI_CB_MHI_ENABLED); } } mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Done.\n"); } Loading
drivers/platform/msm/mhi_uci/mhi_uci.c +98 −102 Original line number Diff line number Diff line Loading @@ -122,6 +122,7 @@ struct uci_client { atomic_t out_pkt_pend_ack; atomic_t completion_ack; struct mhi_uci_ctxt_t *uci_ctxt; struct cdev cdev; bool enabled; void *uci_ipc_log; }; Loading @@ -132,7 +133,6 @@ struct mhi_uci_ctxt_t { struct uci_client client_handles[MHI_SOFTWARE_CLIENT_LIMIT]; dev_t dev_t; struct mutex ctrl_mutex; struct cdev cdev[MHI_SOFTWARE_CLIENT_LIMIT]; struct uci_client *ctrl_client; }; Loading Loading @@ -246,6 +246,7 @@ static int mhi_uci_client_release(struct inode *mhi_inode, static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait); static long mhi_uci_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static int mhi_uci_create_device(struct uci_client *uci_client); static struct mhi_uci_drv_ctxt mhi_uci_drv_ctxt; Loading Loading @@ -1174,6 +1175,14 @@ static void uci_xfer_cb(struct mhi_cb_info *cb_info) uci_handle = cb_info->result->user_data; switch (cb_info->cb_reason) { case MHI_CB_MHI_PROBED: /* If it's outbound channel create the node */ mutex_lock(&uci_handle->client_lock); if (!uci_handle->dev && cb_info->chan == uci_handle->out_attr.chan_id) mhi_uci_create_device(uci_handle); mutex_unlock(&uci_handle->client_lock); break; case MHI_CB_MHI_ENABLED: uci_log(uci_handle->uci_ipc_log, UCI_DBG_INFO, "MHI enabled CB received for chan %d\n", Loading Loading @@ -1295,17 +1304,65 @@ static const struct file_operations mhi_uci_client_fops = { .unlocked_ioctl = mhi_uci_ctl_ioctl, }; static int mhi_uci_create_device(struct uci_client *uci_client) { struct mhi_uci_ctxt_t *uci_ctxt = uci_client->uci_ctxt; char node_name[32]; int index = uci_client - uci_ctxt->client_handles; int ret; uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Creating dev node %04x_%02u.%02u.%02u_pipe%d\n", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, uci_client->out_attr.chan_id); cdev_init(&uci_client->cdev, &mhi_uci_client_fops); uci_client->cdev.owner = THIS_MODULE; ret = cdev_add(&uci_client->cdev, uci_ctxt->dev_t + index, 1); if (ret) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d, ret:%d\n", index, ret); return ret; } uci_client->dev = device_create(mhi_uci_drv_ctxt.mhi_uci_class, NULL, uci_ctxt->dev_t + index, NULL, DEVICE_NAME "_%04x_%02u.%02u.%02u%s%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, "_pipe_", uci_client->out_attr.chan_id); if (IS_ERR(uci_client->dev)) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d\n", IS_ERR(uci_client->dev)); cdev_del(&uci_client->cdev); return -EIO; } /* dev node created successfully, create logging buffer */ snprintf(node_name, sizeof(node_name), "mhi_uci_%04x_%02u.%02u.%02u_%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, uci_client->out_attr.chan_id); uci_client->uci_ipc_log = ipc_log_context_create(MHI_UCI_IPC_LOG_PAGES, node_name, 0); return 0; } static int mhi_uci_probe(struct platform_device *pdev) { struct mhi_uci_ctxt_t *uci_ctxt; int ret_val; int i; char node_name[32]; uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Entered with pdev:%p\n", pdev); uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Entered\n"); if (mhi_is_device_ready(&pdev->dev, "qcom,mhi") == false) return -EPROBE_DEFER; Loading @@ -1326,128 +1383,67 @@ static int mhi_uci_probe(struct platform_device *pdev) uci_ctxt->pdev = pdev; mutex_init(&uci_ctxt->ctrl_mutex); uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Setting up channel attributes\n"); ret_val = uci_init_client_attributes(uci_ctxt, pdev->dev.of_node); if (ret_val) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to init client attributes\n"); return -EIO; } uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Allocating char devices\n"); ret_val = alloc_chrdev_region(&uci_ctxt->dev_t, 0, MHI_SOFTWARE_CLIENT_LIMIT, DEVICE_NAME); if (IS_ERR_VALUE(ret_val)) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to alloc char devs, ret 0x%x\n", ret_val); return ret_val; } uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Registering for MHI events\n"); for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; ++i) { struct uci_client *uci_client = &uci_ctxt->client_handles[i]; uci_client->uci_ctxt = uci_ctxt; mutex_init(&uci_client->client_lock); if (uci_client->in_attr.uci_ownership) { ret_val = mhi_register_client(uci_client, &pdev->dev); if (!uci_client->in_attr.uci_ownership) continue; ret_val = mhi_register_client(uci_client, &pdev->dev); if (ret_val) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_CRITICAL, "Failed to reg client %d ret %d\n", ret_val, i); ret_val, i); return -EIO; } snprintf(node_name, sizeof(node_name), "mhi_uci_%04x_%02u.%02u.%02u_%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, uci_client->out_attr.chan_id); uci_client->uci_ipc_log = ipc_log_context_create (MHI_UCI_IPC_LOG_PAGES, node_name, 0); } } uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Allocating char devices\n"); ret_val = alloc_chrdev_region(&uci_ctxt->dev_t, 0, MHI_SOFTWARE_CLIENT_LIMIT, DEVICE_NAME); if (IS_ERR_VALUE(ret_val)) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_ERROR, "Failed to alloc char devs, ret 0x%x\n", ret_val); goto failed_char_alloc; } mutex_lock(&uci_client->client_lock); /* If we have device id, create the node now */ if (uci_client->out_attr.mhi_handle->dev_id != PCI_ANY_ID) { ret_val = mhi_uci_create_device(uci_client); if (ret_val) { uci_log(mhi_uci_drv_ctxt.mhi_uci_ipc_log, UCI_DBG_INFO, "Setting up device nodes. for dev_t: 0x%x major:0x%x\n", uci_ctxt->dev_t, MAJOR(uci_ctxt->dev_t)); for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; ++i) { struct uci_client *uci_client = &uci_ctxt->client_handles[i]; if (uci_client->in_attr.uci_ownership) { cdev_init(&uci_ctxt->cdev[i], &mhi_uci_client_fops); uci_ctxt->cdev[i].owner = THIS_MODULE; ret_val = cdev_add(&uci_ctxt->cdev[i], uci_ctxt->dev_t + i , 1); if (IS_ERR_VALUE(ret_val)) { uci_log(uci_client->uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d, ret 0x%x\n", i, ret_val); goto failed_char_add; } uci_client->dev = device_create(mhi_uci_drv_ctxt.mhi_uci_class, NULL, uci_ctxt->dev_t + i, NULL, DEVICE_NAME "_%04x_%02u.%02u.%02u%s%d", uci_client->out_attr.mhi_handle->dev_id, uci_client->out_attr.mhi_handle->domain, uci_client->out_attr.mhi_handle->bus, uci_client->out_attr.mhi_handle->slot, "_pipe_", uci_client->out_attr.chan_id); if (IS_ERR(uci_client->dev)) { uci_log(uci_client->uci_ipc_log, UCI_DBG_ERROR, "Failed to add cdev %d\n", i); cdev_del(&uci_ctxt->cdev[i]); ret_val = -EIO; goto failed_device_create; UCI_DBG_CRITICAL, "Failed to create device node, ret:%d\n", ret_val); mutex_unlock(&uci_client->client_lock); return -EIO; } } mutex_unlock(&uci_client->client_lock); } platform_set_drvdata(pdev, uci_ctxt); mutex_lock(&mhi_uci_drv_ctxt.list_lock); list_add_tail(&uci_ctxt->node, &mhi_uci_drv_ctxt.head); mutex_unlock(&mhi_uci_drv_ctxt.list_lock); return 0; failed_char_add: failed_device_create: while (--i >= 0) { cdev_del(&uci_ctxt->cdev[i]); device_destroy(mhi_uci_drv_ctxt.mhi_uci_class, MKDEV(MAJOR(uci_ctxt->dev_t), i)); }; unregister_chrdev_region(MAJOR(uci_ctxt->dev_t), MHI_SOFTWARE_CLIENT_LIMIT); failed_char_alloc: return ret_val; return 0; }; static int mhi_uci_remove(struct platform_device *pdev) Loading @@ -1462,7 +1458,7 @@ static int mhi_uci_remove(struct platform_device *pdev) if (uci_client->in_attr.uci_ownership) { mhi_deregister_channel(uci_client->out_attr.mhi_handle); mhi_deregister_channel(uci_client->in_attr.mhi_handle); cdev_del(&uci_ctxt->cdev[i]); cdev_del(&uci_client->cdev); device_destroy(mhi_uci_drv_ctxt.mhi_uci_class, MKDEV(MAJOR(uci_ctxt->dev_t), i)); } Loading