diff options
Diffstat (limited to 'drivers/rapidio/rio.c')
| -rw-r--r-- | drivers/rapidio/rio.c | 307 |
1 files changed, 55 insertions, 252 deletions
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 38d949405618..46daf32ea13b 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * RapidIO interconnect services * (RapidIO Interconnect Specification, http://www.rapidio.org) @@ -7,11 +8,6 @@ * * Copyright 2009 - 2013 Integrated Device Technology, Inc. * Alex Bounine <alexandre.bounine@idt.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/types.h> @@ -81,6 +77,7 @@ u16 rio_local_get_device_id(struct rio_mport *port) return (RIO_GET_DID(port->sys_size, result)); } +EXPORT_SYMBOL_GPL(rio_local_get_device_id); /** * rio_query_mport - Query mport device attributes @@ -110,9 +107,8 @@ EXPORT_SYMBOL(rio_query_mport); */ struct rio_net *rio_alloc_net(struct rio_mport *mport) { - struct rio_net *net; + struct rio_net *net = kzalloc(sizeof(*net), GFP_KERNEL); - net = kzalloc(sizeof(struct rio_net), GFP_KERNEL); if (net) { INIT_LIST_HEAD(&net->node); INIT_LIST_HEAD(&net->devices); @@ -243,18 +239,17 @@ int rio_request_inb_mbox(struct rio_mport *mport, int rc = -ENOSYS; struct resource *res; - if (mport->ops->open_inb_mbox == NULL) + if (!mport->ops->open_inb_mbox) goto out; - res = kzalloc(sizeof(struct resource), GFP_KERNEL); - + res = kzalloc(sizeof(*res), GFP_KERNEL); if (res) { rio_init_mbox_res(res, mbox, mbox); /* Make sure this mailbox isn't in use */ - if ((rc = - request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE], - res)) < 0) { + rc = request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE], + res); + if (rc < 0) { kfree(res); goto out; } @@ -277,6 +272,7 @@ int rio_request_inb_mbox(struct rio_mport *mport, out: return rc; } +EXPORT_SYMBOL_GPL(rio_request_inb_mbox); /** * rio_release_inb_mbox - release inbound mailbox message service @@ -305,6 +301,7 @@ int rio_release_inb_mbox(struct rio_mport *mport, int mbox) return 0; } +EXPORT_SYMBOL_GPL(rio_release_inb_mbox); /** * rio_request_outb_mbox - request outbound mailbox service @@ -326,18 +323,17 @@ int rio_request_outb_mbox(struct rio_mport *mport, int rc = -ENOSYS; struct resource *res; - if (mport->ops->open_outb_mbox == NULL) + if (!mport->ops->open_outb_mbox) goto out; - res = kzalloc(sizeof(struct resource), GFP_KERNEL); - + res = kzalloc(sizeof(*res), GFP_KERNEL); if (res) { rio_init_mbox_res(res, mbox, mbox); /* Make sure this outbound mailbox isn't in use */ - if ((rc = - request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE], - res)) < 0) { + rc = request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE], + res); + if (rc < 0) { kfree(res); goto out; } @@ -360,6 +356,7 @@ int rio_request_outb_mbox(struct rio_mport *mport, out: return rc; } +EXPORT_SYMBOL_GPL(rio_request_outb_mbox); /** * rio_release_outb_mbox - release outbound mailbox message service @@ -388,6 +385,7 @@ int rio_release_outb_mbox(struct rio_mport *mport, int mbox) return 0; } +EXPORT_SYMBOL_GPL(rio_release_outb_mbox); /** * rio_setup_inb_dbell - bind inbound doorbell callback @@ -405,13 +403,10 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res, void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst, u16 info)) { - int rc = 0; - struct rio_dbell *dbell; + struct rio_dbell *dbell = kmalloc(sizeof(*dbell), GFP_KERNEL); - if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) { - rc = -ENOMEM; - goto out; - } + if (!dbell) + return -ENOMEM; dbell->res = res; dbell->dinb = dinb; @@ -420,9 +415,7 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res, mutex_lock(&mport->lock); list_add_tail(&dbell->node, &mport->dbells); mutex_unlock(&mport->lock); - - out: - return rc; + return 0; } /** @@ -444,17 +437,16 @@ int rio_request_inb_dbell(struct rio_mport *mport, void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst, u16 info)) { - int rc = 0; - - struct resource *res = kzalloc(sizeof(struct resource), GFP_KERNEL); + int rc; + struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); if (res) { rio_init_dbell_res(res, start, end); /* Make sure these doorbells aren't in use */ - if ((rc = - request_resource(&mport->riores[RIO_DOORBELL_RESOURCE], - res)) < 0) { + rc = request_resource(&mport->riores[RIO_DOORBELL_RESOURCE], + res); + if (rc < 0) { kfree(res); goto out; } @@ -467,6 +459,7 @@ int rio_request_inb_dbell(struct rio_mport *mport, out: return rc; } +EXPORT_SYMBOL_GPL(rio_request_inb_dbell); /** * rio_release_inb_dbell - release inbound doorbell message service @@ -508,6 +501,7 @@ int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end) out: return rc; } +EXPORT_SYMBOL_GPL(rio_release_inb_dbell); /** * rio_request_outb_dbell - request outbound doorbell message range @@ -536,6 +530,7 @@ struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start, return res; } +EXPORT_SYMBOL_GPL(rio_request_outb_dbell); /** * rio_release_outb_dbell - release outbound doorbell message range @@ -553,6 +548,7 @@ int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res) return rc; } +EXPORT_SYMBOL_GPL(rio_release_outb_dbell); /** * rio_add_mport_pw_handler - add port-write message handler into the list @@ -567,22 +563,17 @@ int rio_add_mport_pw_handler(struct rio_mport *mport, void *context, int (*pwcback)(struct rio_mport *mport, void *context, union rio_pw_msg *msg, int step)) { - int rc = 0; - struct rio_pwrite *pwrite; + struct rio_pwrite *pwrite = kzalloc(sizeof(*pwrite), GFP_KERNEL); - pwrite = kzalloc(sizeof(struct rio_pwrite), GFP_KERNEL); - if (!pwrite) { - rc = -ENOMEM; - goto out; - } + if (!pwrite) + return -ENOMEM; pwrite->pwcback = pwcback; pwrite->context = context; mutex_lock(&mport->lock); list_add_tail(&pwrite->node, &mport->pwrites); mutex_unlock(&mport->lock); -out: - return rc; + return 0; } EXPORT_SYMBOL_GPL(rio_add_mport_pw_handler); @@ -632,7 +623,7 @@ int rio_request_inb_pwrite(struct rio_dev *rdev, int rc = 0; spin_lock(&rio_global_list_lock); - if (rdev->pwcback != NULL) + if (rdev->pwcback) rc = -ENOMEM; else rdev->pwcback = pwcback; @@ -698,7 +689,7 @@ EXPORT_SYMBOL_GPL(rio_pw_enable); int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local, u64 rbase, u32 size, u32 rflags) { - int rc = 0; + int rc; unsigned long flags; if (!mport->ops->map_inb) @@ -742,7 +733,7 @@ EXPORT_SYMBOL_GPL(rio_unmap_inb_region); int rio_map_outb_region(struct rio_mport *mport, u16 destid, u64 rbase, u32 size, u32 rflags, dma_addr_t *local) { - int rc = 0; + int rc; unsigned long flags; if (!mport->ops->map_outb) @@ -758,7 +749,7 @@ int rio_map_outb_region(struct rio_mport *mport, u16 destid, u64 rbase, EXPORT_SYMBOL_GPL(rio_map_outb_region); /** - * rio_unmap_inb_region -- Unmap the inbound memory region + * rio_unmap_outb_region -- Unmap the inbound memory region * @mport: Master port * @destid: destination id mapping points to * @rstart: RIO base address window translates to @@ -975,7 +966,7 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) rdev = rdev->prev; } - if (prev == NULL) + if (!prev) goto err_out; p_port = prev->rswitch->route_table[rdev->destid]; @@ -1054,7 +1045,7 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) RIO_MNT_REQ_CMD_IS); /* Exit if the response is not expected */ - if (lnkresp == NULL) + if (!lnkresp) return 0; checkcount = 3; @@ -1411,7 +1402,9 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid, ext_ftr_ptr, &ftr_header); if (RIO_GET_BLOCK_ID(ftr_header) == ftr) return ext_ftr_ptr; - if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header))) + + ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header); + if (!ext_ftr_ptr) break; } @@ -1420,69 +1413,6 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid, EXPORT_SYMBOL_GPL(rio_mport_get_feature); /** - * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did - * @vid: RIO vid to match or %RIO_ANY_ID to match all vids - * @did: RIO did to match or %RIO_ANY_ID to match all dids - * @asm_vid: RIO asm_vid to match or %RIO_ANY_ID to match all asm_vids - * @asm_did: RIO asm_did to match or %RIO_ANY_ID to match all asm_dids - * @from: Previous RIO device found in search, or %NULL for new search - * - * Iterates through the list of known RIO devices. If a RIO device is - * found with a matching @vid, @did, @asm_vid, @asm_did, the reference - * count to the device is incrememted and a pointer to its device - * structure is returned. Otherwise, %NULL is returned. A new search - * is initiated by passing %NULL to the @from argument. Otherwise, if - * @from is not %NULL, searches continue from next device on the global - * list. The reference count for @from is always decremented if it is - * not %NULL. - */ -struct rio_dev *rio_get_asm(u16 vid, u16 did, - u16 asm_vid, u16 asm_did, struct rio_dev *from) -{ - struct list_head *n; - struct rio_dev *rdev; - - WARN_ON(in_interrupt()); - spin_lock(&rio_global_list_lock); - n = from ? from->global_list.next : rio_devices.next; - - while (n && (n != &rio_devices)) { - rdev = rio_dev_g(n); - if ((vid == RIO_ANY_ID || rdev->vid == vid) && - (did == RIO_ANY_ID || rdev->did == did) && - (asm_vid == RIO_ANY_ID || rdev->asm_vid == asm_vid) && - (asm_did == RIO_ANY_ID || rdev->asm_did == asm_did)) - goto exit; - n = n->next; - } - rdev = NULL; - exit: - rio_dev_put(from); - rdev = rio_dev_get(rdev); - spin_unlock(&rio_global_list_lock); - return rdev; -} - -/** - * rio_get_device - Begin or continue searching for a RIO device by vid/did - * @vid: RIO vid to match or %RIO_ANY_ID to match all vids - * @did: RIO did to match or %RIO_ANY_ID to match all dids - * @from: Previous RIO device found in search, or %NULL for new search - * - * Iterates through the list of known RIO devices. If a RIO device is - * found with a matching @vid and @did, the reference count to the - * device is incrememted and a pointer to its device structure is returned. - * Otherwise, %NULL is returned. A new search is initiated by passing %NULL - * to the @from argument. Otherwise, if @from is not %NULL, searches - * continue from next device on the global list. The reference count for - * @from is always decremented if it is not %NULL. - */ -struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from) -{ - return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from); -} - -/** * rio_std_route_add_entry - Add switch route table entry using standard * registers defined in RIO specification rev.1.3 * @mport: Master port to issue transaction @@ -1696,7 +1626,7 @@ int rio_route_add_entry(struct rio_dev *rdev, spin_lock(&rdev->rswitch->lock); - if (ops == NULL || ops->add_entry == NULL) { + if (!ops || !ops->add_entry) { rc = rio_std_route_add_entry(rdev->net->hport, rdev->destid, rdev->hopcount, table, route_destid, route_port); @@ -1749,7 +1679,7 @@ int rio_route_get_entry(struct rio_dev *rdev, u16 table, spin_lock(&rdev->rswitch->lock); - if (ops == NULL || ops->get_entry == NULL) { + if (!ops || !ops->get_entry) { rc = rio_std_route_get_entry(rdev->net->hport, rdev->destid, rdev->hopcount, table, route_destid, route_port); @@ -1797,7 +1727,7 @@ int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock) spin_lock(&rdev->rswitch->lock); - if (ops == NULL || ops->clr_table == NULL) { + if (!ops || !ops->clr_table) { rc = rio_std_route_clr_table(rdev->net->hport, rdev->destid, rdev->hopcount, table); } else if (try_module_get(ops->owner)) { @@ -1845,19 +1775,6 @@ struct dma_chan *rio_request_mport_dma(struct rio_mport *mport) EXPORT_SYMBOL_GPL(rio_request_mport_dma); /** - * rio_request_dma - request RapidIO capable DMA channel that supports - * specified target RapidIO device. - * @rdev: RIO device associated with DMA transfer - * - * Returns pointer to allocated DMA channel or NULL if failed. - */ -struct dma_chan *rio_request_dma(struct rio_dev *rdev) -{ - return rio_request_mport_dma(rdev->net->hport); -} -EXPORT_SYMBOL_GPL(rio_request_dma); - -/** * rio_release_dma - release specified DMA channel * @dchan: DMA channel to release */ @@ -1889,7 +1806,7 @@ struct dma_async_tx_descriptor *rio_dma_prep_xfer(struct dma_chan *dchan, { struct rio_dma_ext rio_ext; - if (dchan->device->device_prep_slave_sg == NULL) { + if (!dchan->device->device_prep_slave_sg) { pr_err("%s: prep_rio_sg == NULL\n", __func__); return NULL; } @@ -1904,57 +1821,9 @@ struct dma_async_tx_descriptor *rio_dma_prep_xfer(struct dma_chan *dchan, } EXPORT_SYMBOL_GPL(rio_dma_prep_xfer); -/** - * rio_dma_prep_slave_sg - RapidIO specific wrapper - * for device_prep_slave_sg callback defined by DMAENGINE. - * @rdev: RIO device control structure - * @dchan: DMA channel to configure - * @data: RIO specific data descriptor - * @direction: DMA data transfer direction (TO or FROM the device) - * @flags: dmaengine defined flags - * - * Initializes RapidIO capable DMA channel for the specified data transfer. - * Uses DMA channel private extension to pass information related to remote - * target RIO device. - * - * Returns: pointer to DMA transaction descriptor if successful, - * error-valued pointer or NULL if failed. - */ -struct dma_async_tx_descriptor *rio_dma_prep_slave_sg(struct rio_dev *rdev, - struct dma_chan *dchan, struct rio_dma_data *data, - enum dma_transfer_direction direction, unsigned long flags) -{ - return rio_dma_prep_xfer(dchan, rdev->destid, data, direction, flags); -} -EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg); - #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ /** - * rio_find_mport - find RIO mport by its ID - * @mport_id: number (ID) of mport device - * - * Given a RIO mport number, the desired mport is located - * in the global list of mports. If the mport is found, a pointer to its - * data structure is returned. If no mport is found, %NULL is returned. - */ -struct rio_mport *rio_find_mport(int mport_id) -{ - struct rio_mport *port; - - mutex_lock(&rio_mport_list_lock); - list_for_each_entry(port, &rio_mports, node) { - if (port->id == mport_id) - goto found; - } - port = NULL; -found: - mutex_unlock(&rio_mport_list_lock); - - return port; -} - -/** * rio_register_scan - enumeration/discovery method registration interface * @mport_id: mport device ID for which fabric scan routine has to be set * (RIO_MPORT_ANY = set for all available mports) @@ -2032,48 +1901,6 @@ err_out: EXPORT_SYMBOL_GPL(rio_register_scan); /** - * rio_unregister_scan - removes enumeration/discovery method from mport - * @mport_id: mport device ID for which fabric scan routine has to be - * unregistered (RIO_MPORT_ANY = apply to all mports that use - * the specified scan_ops) - * @scan_ops: enumeration/discovery operations structure - * - * Removes enumeration or discovery method assigned to the specified mport - * device. If RIO_MPORT_ANY is specified, removes the specified operations from - * all mports that have them attached. - */ -int rio_unregister_scan(int mport_id, struct rio_scan *scan_ops) -{ - struct rio_mport *port; - struct rio_scan_node *scan; - - pr_debug("RIO: %s for mport_id=%d\n", __func__, mport_id); - - if (mport_id != RIO_MPORT_ANY && mport_id >= RIO_MAX_MPORTS) - return -EINVAL; - - mutex_lock(&rio_mport_list_lock); - - list_for_each_entry(port, &rio_mports, node) - if (port->id == mport_id || - (mport_id == RIO_MPORT_ANY && port->nscan == scan_ops)) - port->nscan = NULL; - - list_for_each_entry(scan, &rio_scans, node) { - if (scan->mport_id == mport_id) { - list_del(&scan->node); - kfree(scan); - break; - } - } - - mutex_unlock(&rio_mport_list_lock); - - return 0; -} -EXPORT_SYMBOL_GPL(rio_unregister_scan); - -/** * rio_mport_scan - execute enumeration/discovery on the specified mport * @mport_id: number (ID) of mport device */ @@ -2111,20 +1938,6 @@ found: return rc; } -static void rio_fixup_device(struct rio_dev *dev) -{ -} - -static int rio_init(void) -{ - struct rio_dev *dev = NULL; - - while ((dev = rio_get_device(RIO_ANY_ID, RIO_ANY_ID, dev)) != NULL) { - rio_fixup_device(dev); - } - return 0; -} - static struct workqueue_struct *rio_wq; struct rio_disc_work { @@ -2189,7 +2002,6 @@ int rio_init_mports(void) work = kcalloc(n, sizeof *work, GFP_KERNEL); if (!work) { - pr_err("RIO: no memory for work struct\n"); destroy_workqueue(rio_wq); goto no_disc; } @@ -2212,10 +2024,9 @@ int rio_init_mports(void) kfree(work); no_disc: - rio_init(); - return 0; } +EXPORT_SYMBOL_GPL(rio_init_mports); static int rio_get_hdid(int index) { @@ -2272,11 +2083,16 @@ int rio_register_mport(struct rio_mport *port) atomic_set(&port->state, RIO_DEVICE_RUNNING); res = device_register(&port->dev); - if (res) + if (res) { dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n", port->id, res); - else + mutex_lock(&rio_mport_list_lock); + list_del(&port->node); + mutex_unlock(&rio_mport_list_lock); + put_device(&port->dev); + } else { dev_dbg(&port->dev, "RIO: registered mport%d\n", port->id); + } return res; } @@ -2330,16 +2146,3 @@ int rio_unregister_mport(struct rio_mport *port) return 0; } EXPORT_SYMBOL_GPL(rio_unregister_mport); - -EXPORT_SYMBOL_GPL(rio_local_get_device_id); -EXPORT_SYMBOL_GPL(rio_get_device); -EXPORT_SYMBOL_GPL(rio_get_asm); -EXPORT_SYMBOL_GPL(rio_request_inb_dbell); -EXPORT_SYMBOL_GPL(rio_release_inb_dbell); -EXPORT_SYMBOL_GPL(rio_request_outb_dbell); -EXPORT_SYMBOL_GPL(rio_release_outb_dbell); -EXPORT_SYMBOL_GPL(rio_request_inb_mbox); -EXPORT_SYMBOL_GPL(rio_release_inb_mbox); -EXPORT_SYMBOL_GPL(rio_request_outb_mbox); -EXPORT_SYMBOL_GPL(rio_release_outb_mbox); -EXPORT_SYMBOL_GPL(rio_init_mports); |
