Loading drivers/bus/mhi/core/mhi_init.c +42 −3 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) struct mhi_event *mhi_event; struct mhi_chan *mhi_chan; struct mhi_cmd *mhi_cmd; struct mhi_device *mhi_dev; if (!mhi_cntrl->of_node) return -EINVAL; Loading @@ -1082,8 +1083,10 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) mhi_cntrl->mhi_cmd = kcalloc(NR_OF_CMD_RINGS, sizeof(*mhi_cntrl->mhi_cmd), GFP_KERNEL); if (!mhi_cntrl->mhi_cmd) if (!mhi_cntrl->mhi_cmd) { ret = -ENOMEM; goto error_alloc_cmd; } INIT_LIST_HEAD(&mhi_cntrl->transition_list); mutex_init(&mhi_cntrl->pm_mutex); Loading Loading @@ -1138,31 +1141,59 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) mhi_cntrl->unmap_single = mhi_unmap_single_no_bb; } /* register controller with mhi_bus */ mhi_dev = mhi_alloc_device(mhi_cntrl); if (!mhi_dev) { ret = -ENOMEM; goto error_alloc_dev; } mhi_dev->dev_type = MHI_CONTROLLER_TYPE; mhi_dev->mhi_cntrl = mhi_cntrl; dev_set_name(&mhi_dev->dev, "%04x_%02u.%02u.%02u", mhi_dev->dev_id, mhi_dev->domain, mhi_dev->bus, mhi_dev->slot); ret = device_add(&mhi_dev->dev); if (ret) goto error_add_dev; mhi_cntrl->mhi_dev = mhi_dev; mhi_cntrl->parent = mhi_bus.dentry; mhi_cntrl->klog_lvl = MHI_MSG_LVL_ERROR; /* add to list */ /* adding it to this list only for debug purpose */ mutex_lock(&mhi_bus.lock); list_add_tail(&mhi_cntrl->node, &mhi_bus.controller_list); mutex_unlock(&mhi_bus.lock); return 0; error_add_dev: mhi_dealloc_device(mhi_cntrl, mhi_dev); error_alloc_dev: kfree(mhi_cntrl->mhi_cmd); error_alloc_cmd: kfree(mhi_cntrl->mhi_chan); kfree(mhi_cntrl->mhi_event); return -ENOMEM; return ret; }; EXPORT_SYMBOL(of_register_mhi_controller); void mhi_unregister_mhi_controller(struct mhi_controller *mhi_cntrl) { struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev; kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_event); kfree(mhi_cntrl->mhi_chan); kfree(mhi_cntrl->mhi_tsync); device_del(&mhi_dev->dev); put_device(&mhi_dev->dev); mutex_lock(&mhi_bus.lock); list_del(&mhi_cntrl->node); mutex_unlock(&mhi_bus.lock); Loading Loading @@ -1256,6 +1287,10 @@ static int mhi_match(struct device *dev, struct device_driver *drv) struct mhi_driver *mhi_drv = to_mhi_driver(drv); const struct mhi_device_id *id; /* if controller type there is no client driver associated with it */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) return 0; for (id = mhi_drv->id_table; id->chan; id++) if (!strcmp(mhi_dev->chan_name, id->chan)) { mhi_dev->id = id; Loading Loading @@ -1348,6 +1383,10 @@ static int mhi_driver_remove(struct device *dev) }; int dir; /* control device has no work to do */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) return 0; MHI_LOG("Removing device for chan:%s\n", mhi_dev->chan_name); /* reset both channels */ Loading drivers/bus/mhi/core/mhi_main.c +32 −6 Original line number Diff line number Diff line Loading @@ -559,6 +559,10 @@ int mhi_destroy_device(struct device *dev, void *data) mhi_dev = to_mhi_device(dev); mhi_cntrl = mhi_dev->mhi_cntrl; /* only destroying virtual devices thats attached to bus */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) return 0; MHI_LOG("destroy device for chan:%s\n", mhi_dev->chan_name); /* notify the client and remove the device from mhi bus */ Loading Loading @@ -1722,19 +1726,41 @@ int mhi_get_no_free_descriptors(struct mhi_device *mhi_dev, } EXPORT_SYMBOL(mhi_get_no_free_descriptors); static int __mhi_bdf_to_controller(struct device *dev, void *tmp) { struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_device *match = tmp; /* return any none-zero value if match */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE && mhi_dev->domain == match->domain && mhi_dev->bus == match->bus && mhi_dev->slot == match->slot && mhi_dev->dev_id == match->dev_id) return 1; return 0; } struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id) { struct mhi_controller *itr, *tmp; struct mhi_device tmp, *mhi_dev; struct device *dev; list_for_each_entry_safe(itr, tmp, &mhi_bus.controller_list, node) if (itr->domain == domain && itr->bus == bus && itr->slot == slot && itr->dev_id == dev_id) return itr; tmp.domain = domain; tmp.bus = bus; tmp.slot = slot; tmp.dev_id = dev_id; dev = bus_find_device(&mhi_bus_type, NULL, &tmp, __mhi_bdf_to_controller); if (!dev) return NULL; mhi_dev = to_mhi_device(dev); return mhi_dev->mhi_cntrl; } EXPORT_SYMBOL(mhi_bdf_to_controller); Loading include/linux/mhi.h +3 −0 Original line number Diff line number Diff line Loading @@ -64,10 +64,12 @@ enum MHI_FLAGS { * enum mhi_device_type - Device types * @MHI_XFER_TYPE: Handles data transfer * @MHI_TIMESYNC_TYPE: Use for timesync feature * @MHI_CONTROLLER_TYPE: Control device */ enum mhi_device_type { MHI_XFER_TYPE, MHI_TIMESYNC_TYPE, MHI_CONTROLLER_TYPE, }; /** Loading Loading @@ -130,6 +132,7 @@ struct image_info { */ struct mhi_controller { struct list_head node; struct mhi_device *mhi_dev; /* device node for iommu ops */ struct device *dev; Loading Loading
drivers/bus/mhi/core/mhi_init.c +42 −3 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) struct mhi_event *mhi_event; struct mhi_chan *mhi_chan; struct mhi_cmd *mhi_cmd; struct mhi_device *mhi_dev; if (!mhi_cntrl->of_node) return -EINVAL; Loading @@ -1082,8 +1083,10 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) mhi_cntrl->mhi_cmd = kcalloc(NR_OF_CMD_RINGS, sizeof(*mhi_cntrl->mhi_cmd), GFP_KERNEL); if (!mhi_cntrl->mhi_cmd) if (!mhi_cntrl->mhi_cmd) { ret = -ENOMEM; goto error_alloc_cmd; } INIT_LIST_HEAD(&mhi_cntrl->transition_list); mutex_init(&mhi_cntrl->pm_mutex); Loading Loading @@ -1138,31 +1141,59 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) mhi_cntrl->unmap_single = mhi_unmap_single_no_bb; } /* register controller with mhi_bus */ mhi_dev = mhi_alloc_device(mhi_cntrl); if (!mhi_dev) { ret = -ENOMEM; goto error_alloc_dev; } mhi_dev->dev_type = MHI_CONTROLLER_TYPE; mhi_dev->mhi_cntrl = mhi_cntrl; dev_set_name(&mhi_dev->dev, "%04x_%02u.%02u.%02u", mhi_dev->dev_id, mhi_dev->domain, mhi_dev->bus, mhi_dev->slot); ret = device_add(&mhi_dev->dev); if (ret) goto error_add_dev; mhi_cntrl->mhi_dev = mhi_dev; mhi_cntrl->parent = mhi_bus.dentry; mhi_cntrl->klog_lvl = MHI_MSG_LVL_ERROR; /* add to list */ /* adding it to this list only for debug purpose */ mutex_lock(&mhi_bus.lock); list_add_tail(&mhi_cntrl->node, &mhi_bus.controller_list); mutex_unlock(&mhi_bus.lock); return 0; error_add_dev: mhi_dealloc_device(mhi_cntrl, mhi_dev); error_alloc_dev: kfree(mhi_cntrl->mhi_cmd); error_alloc_cmd: kfree(mhi_cntrl->mhi_chan); kfree(mhi_cntrl->mhi_event); return -ENOMEM; return ret; }; EXPORT_SYMBOL(of_register_mhi_controller); void mhi_unregister_mhi_controller(struct mhi_controller *mhi_cntrl) { struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev; kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_event); kfree(mhi_cntrl->mhi_chan); kfree(mhi_cntrl->mhi_tsync); device_del(&mhi_dev->dev); put_device(&mhi_dev->dev); mutex_lock(&mhi_bus.lock); list_del(&mhi_cntrl->node); mutex_unlock(&mhi_bus.lock); Loading Loading @@ -1256,6 +1287,10 @@ static int mhi_match(struct device *dev, struct device_driver *drv) struct mhi_driver *mhi_drv = to_mhi_driver(drv); const struct mhi_device_id *id; /* if controller type there is no client driver associated with it */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) return 0; for (id = mhi_drv->id_table; id->chan; id++) if (!strcmp(mhi_dev->chan_name, id->chan)) { mhi_dev->id = id; Loading Loading @@ -1348,6 +1383,10 @@ static int mhi_driver_remove(struct device *dev) }; int dir; /* control device has no work to do */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) return 0; MHI_LOG("Removing device for chan:%s\n", mhi_dev->chan_name); /* reset both channels */ Loading
drivers/bus/mhi/core/mhi_main.c +32 −6 Original line number Diff line number Diff line Loading @@ -559,6 +559,10 @@ int mhi_destroy_device(struct device *dev, void *data) mhi_dev = to_mhi_device(dev); mhi_cntrl = mhi_dev->mhi_cntrl; /* only destroying virtual devices thats attached to bus */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) return 0; MHI_LOG("destroy device for chan:%s\n", mhi_dev->chan_name); /* notify the client and remove the device from mhi bus */ Loading Loading @@ -1722,19 +1726,41 @@ int mhi_get_no_free_descriptors(struct mhi_device *mhi_dev, } EXPORT_SYMBOL(mhi_get_no_free_descriptors); static int __mhi_bdf_to_controller(struct device *dev, void *tmp) { struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_device *match = tmp; /* return any none-zero value if match */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE && mhi_dev->domain == match->domain && mhi_dev->bus == match->bus && mhi_dev->slot == match->slot && mhi_dev->dev_id == match->dev_id) return 1; return 0; } struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id) { struct mhi_controller *itr, *tmp; struct mhi_device tmp, *mhi_dev; struct device *dev; list_for_each_entry_safe(itr, tmp, &mhi_bus.controller_list, node) if (itr->domain == domain && itr->bus == bus && itr->slot == slot && itr->dev_id == dev_id) return itr; tmp.domain = domain; tmp.bus = bus; tmp.slot = slot; tmp.dev_id = dev_id; dev = bus_find_device(&mhi_bus_type, NULL, &tmp, __mhi_bdf_to_controller); if (!dev) return NULL; mhi_dev = to_mhi_device(dev); return mhi_dev->mhi_cntrl; } EXPORT_SYMBOL(mhi_bdf_to_controller); Loading
include/linux/mhi.h +3 −0 Original line number Diff line number Diff line Loading @@ -64,10 +64,12 @@ enum MHI_FLAGS { * enum mhi_device_type - Device types * @MHI_XFER_TYPE: Handles data transfer * @MHI_TIMESYNC_TYPE: Use for timesync feature * @MHI_CONTROLLER_TYPE: Control device */ enum mhi_device_type { MHI_XFER_TYPE, MHI_TIMESYNC_TYPE, MHI_CONTROLLER_TYPE, }; /** Loading Loading @@ -130,6 +132,7 @@ struct image_info { */ struct mhi_controller { struct list_head node; struct mhi_device *mhi_dev; /* device node for iommu ops */ struct device *dev; Loading