diff options
Diffstat (limited to 'drivers/cdx/cdx.c')
-rw-r--r-- | drivers/cdx/cdx.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c index b74d76afccb6..7811aa734053 100644 --- a/drivers/cdx/cdx.c +++ b/drivers/cdx/cdx.c @@ -56,6 +56,7 @@ */ #include <linux/init.h> +#include <linux/irqdomain.h> #include <linux/kernel.h> #include <linux/of.h> #include <linux/of_device.h> @@ -261,10 +262,10 @@ EXPORT_SYMBOL_GPL(cdx_clear_master); * * Return: true on success, false otherwise. */ -static int cdx_bus_match(struct device *dev, struct device_driver *drv) +static int cdx_bus_match(struct device *dev, const struct device_driver *drv) { struct cdx_device *cdx_dev = to_cdx_device(dev); - struct cdx_driver *cdx_drv = to_cdx_driver(drv); + const struct cdx_driver *cdx_drv = to_cdx_driver(drv); const struct cdx_device_id *found_id = NULL; const struct cdx_device_id *ids; @@ -302,8 +303,19 @@ static int cdx_probe(struct device *dev) { struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); struct cdx_device *cdx_dev = to_cdx_device(dev); + struct cdx_controller *cdx = cdx_dev->cdx; int error; + /* + * Setup MSI device data so that generic MSI alloc/free can + * be used by the device driver. + */ + if (cdx->msi_domain) { + error = msi_setup_device_data(&cdx_dev->dev); + if (error) + return error; + } + error = cdx_drv->probe(cdx_dev); if (error) { dev_err_probe(dev, error, "%s failed\n", __func__); @@ -326,7 +338,10 @@ static void cdx_shutdown(struct device *dev) { struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); struct cdx_device *cdx_dev = to_cdx_device(dev); + struct cdx_controller *cdx = cdx_dev->cdx; + if (cdx_dev->is_bus && cdx_dev->enabled && cdx->ops->bus_disable) + cdx->ops->bus_disable(cdx, cdx_dev->bus_num); if (cdx_drv && cdx_drv->shutdown) cdx_drv->shutdown(cdx_dev); } @@ -458,8 +473,12 @@ static ssize_t driver_override_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cdx_device *cdx_dev = to_cdx_device(dev); + ssize_t len; - return sysfs_emit(buf, "%s\n", cdx_dev->driver_override); + device_lock(dev); + len = sysfs_emit(buf, "%s\n", cdx_dev->driver_override); + device_unlock(dev); + return len; } static DEVICE_ATTR_RW(driver_override); @@ -695,7 +714,7 @@ static const struct vm_operations_struct cdx_phys_vm_ops = { * Return: true on success, false otherwise. */ static int cdx_mmap_resource(struct file *fp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { struct cdx_device *cdx_dev = to_cdx_device(kobj_to_dev(kobj)); @@ -787,6 +806,7 @@ int cdx_device_add(struct cdx_dev_params *dev_params) /* Populate CDX dev params */ cdx_dev->req_id = dev_params->req_id; + cdx_dev->msi_dev_id = dev_params->msi_dev_id; cdx_dev->vendor = dev_params->vendor; cdx_dev->device = dev_params->device; cdx_dev->subsystem_vendor = dev_params->subsys_vendor; @@ -804,12 +824,19 @@ int cdx_device_add(struct cdx_dev_params *dev_params) cdx_dev->dev.bus = &cdx_bus_type; cdx_dev->dev.dma_mask = &cdx_dev->dma_mask; cdx_dev->dev.release = cdx_device_release; + cdx_dev->msi_write_pending = false; + mutex_init(&cdx_dev->irqchip_lock); /* Set Name */ dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x", ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (cdx_dev->bus_num & CDX_BUS_NUM_MASK)), cdx_dev->dev_num); + if (cdx->msi_domain) { + cdx_dev->num_msi = dev_params->num_msi; + dev_set_msi_domain(&cdx_dev->dev, cdx->msi_domain); + } + ret = device_add(&cdx_dev->dev); if (ret) { dev_err(&cdx_dev->dev, @@ -848,7 +875,7 @@ fail: return ret; } -EXPORT_SYMBOL_NS_GPL(cdx_device_add, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_device_add, "CDX_BUS_CONTROLLER"); struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num) { @@ -895,7 +922,7 @@ device_add_fail: return NULL; } -EXPORT_SYMBOL_NS_GPL(cdx_bus_add, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_bus_add, "CDX_BUS_CONTROLLER"); int cdx_register_controller(struct cdx_controller *cdx) { @@ -920,7 +947,7 @@ int cdx_register_controller(struct cdx_controller *cdx) return 0; } -EXPORT_SYMBOL_NS_GPL(cdx_register_controller, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_register_controller, "CDX_BUS_CONTROLLER"); void cdx_unregister_controller(struct cdx_controller *cdx) { @@ -935,7 +962,7 @@ void cdx_unregister_controller(struct cdx_controller *cdx) mutex_unlock(&cdx_controller_lock); } -EXPORT_SYMBOL_NS_GPL(cdx_unregister_controller, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_unregister_controller, "CDX_BUS_CONTROLLER"); static int __init cdx_bus_init(void) { |