aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.4/7198-staging-fsl-mc-dpio-services-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.4/7198-staging-fsl-mc-dpio-services-driver.patch')
-rw-r--r--target/linux/layerscape/patches-4.4/7198-staging-fsl-mc-dpio-services-driver.patch8943
1 files changed, 0 insertions, 8943 deletions
diff --git a/target/linux/layerscape/patches-4.4/7198-staging-fsl-mc-dpio-services-driver.patch b/target/linux/layerscape/patches-4.4/7198-staging-fsl-mc-dpio-services-driver.patch
deleted file mode 100644
index 7613d0a631..0000000000
--- a/target/linux/layerscape/patches-4.4/7198-staging-fsl-mc-dpio-services-driver.patch
+++ /dev/null
@@ -1,8943 +0,0 @@
-From 331b26080961f0289c3a8a8e5e65f6524b23be19 Mon Sep 17 00:00:00 2001
-From: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
-Date: Tue, 7 Apr 2015 23:24:55 -0400
-Subject: [PATCH 198/226] staging: fsl-mc: dpio services driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is a commit of a squash of the cummulative dpio services patches
-in the sdk 2.0 kernel as of 3/7/2016.
-
-staging: fsl-mc: dpio: initial implementation of dpio services
-
-* Port from kernel 3.16 to 3.19
-* upgrade to match MC fw 7.0.0
-* return -EPROBE_DEFER if fsl_mc_portal_allocate() fails.
-* enable DPIO interrupt support
-* implement service FQDAN handling
-* DPIO service selects DPIO objects using crude algorithms for now, we
- will look to make this smarter later on.
-* Locks all DPIO ops that aren't innately lockless. Smarter selection
- logic may allow locking to be relaxed eventually.
-* Portable QBMan driver source (and low-level MC flib code for DPIO) is
- included and encapsulated within the DPIO driver.
-
-Signed-off-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
-Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
-Signed-off-by: Cristian Sovaiala <cristian.sovaiala@freescale.com>
-Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
-Signed-off-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
-[Stuart: resolved merge conflicts]
-Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
-
-dpio: Use locks when querying fq state
-
-merged from patch in 3.19-bringup branch.
-
-Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
-Signed-off-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
-Change-Id: Ia4d09f8a0cf4d8a4a2aa1cb39be789c34425286d
-Reviewed-on: http://git.am.freescale.net:8181/34707
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-qbman: Fix potential race in VDQCR handling
-
-Remove atomic_read() check of the VDQCR busy marker. These checks were racy
-as the flag could be incorrectly cleared if checked while another thread was
-starting a pull command. The check is unneeded since we can determine the
-owner of the outstanding pull command through other means.
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Change-Id: Icc64577c0a4ce6dadef208975e980adfc6796c86
-Reviewed-on: http://git.am.freescale.net:8181/34705
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-dpio: Fix IRQ handler and remove useless spinlock
-
-The IRQ handler for a threaded IRQ requires two parts: initally the handler
-should check status and inhibit the IRQ then the threaded portion should
-process and reenable.
-
-Also remove a spinlock that was redundant with the QMan driver and a debug
-check that could trigger under a race condition
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Signed-off-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
-Change-Id: I64926583af0be954228de94ae354fa005c8ec88a
-Reviewed-on: http://git.am.freescale.net:8181/34706
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-staging: fsl-mc: dpio: Implement polling if IRQ not available
-
-Temporarly add a polling mode to DPIO in the case that the IRQ
-registration fails
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Change-Id: Iebbd488fd14dd9878ef846e40f3ebcbcd0eb1e80
-Reviewed-on: http://git.am.freescale.net:8181/34775
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl-mc-dpio: Fix to make this work without interrupt
-
-Some additional fixes to make dpio driver work in poll mode.
-This is needed for direct assignment to KVM Guest.
-
-Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
-Change-Id: Icf66b8c0c7f7e1610118f78396534c067f594934
-Reviewed-on: http://git.am.freescale.net:8181/35333
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl-mc-dpio: Make QBMan token tracking internal
-
-Previousy the QBMan portal code required the caller to properly set and
-check for a token value used by the driver to detect when the QMan
-hardware had completed a dequeue. This patch simplifes the driver
-interface by internally dealing with token values. The driver will now
-set the token value to 0 once it has dequeued a frame while a token
-value of 1 indicates the HW has completed the dequeue but SW has not
-consumed the frame yet.
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Change-Id: If94d9728b0faa0fd79b47108f5cb05a425b89c18
-Reviewed-on: http://git.am.freescale.net:8181/35433
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl-mc-dpio: Distribute DPIO IRQs among cores
-
-Configure the DPIO IRQ affinities across all available cores
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Change-Id: Ib45968a070460b7e9410bfe6067b20ecd3524c54
-Reviewed-on: http://git.am.freescale.net:8181/35540
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
-Reviewed-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-dpio/qbman: add flush after finishing cena write
-
-Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
-Change-Id: I19537f101f7f5b443d60c0ad0e5d96c1dc302223
-Reviewed-on: http://git.am.freescale.net:8181/35854
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-dpio/qbman: rename qbman_dq_entry to qbman_result
-
-Currently qbman_dq_entry is used for both dq result in dqrr
-and memory, and notifications in dqrr and memory. It doesn't
-make sense to have dq_entry in name for those notifications
-which have nothing to do with dq. So we rename this as
-qbman_result which is meaningful for both cases.
-
-Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
-Change-Id: I62b3e729c571a1195e8802a9fab3fca97a14eae4
-Reviewed-on: http://git.am.freescale.net:8181/35535
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-dpio/qbman: add APIs to parse BPSCN and CGCU
-
-BPSCN and CGCU are notifications which can only be written to memory.
-We need to consider the host endianness while parsing these notification.
-Also modify the check of FQRN/CSCN_MEM with the same consideration.
-
-Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
-Change-Id: I572e0aa126107aed40e1ce326d5df7956882a939
-Reviewed-on: http://git.am.freescale.net:8181/35536
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-dpio/qbman: remove EXPORT_SYMBOL for qbman APIs
-
-because they are only used by dpio.
-
-Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
-Change-Id: I12e7b81c2d32f3c7b3df9fd73b742b1b675f4b8b
-Reviewed-on: http://git.am.freescale.net:8181/35537
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-dpio/qbman: add invalidate and prefetch support
-
-for cachable memory access.
-Also remove the redundant memory barriers.
-
-Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
-Change-Id: I452a768278d1c5ef37e5741e9b011d725cb57b30
-Reviewed-on: http://git.am.freescale.net:8181/35873
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-dpio-driver: Fix qman-portal interrupt masking in poll mode
-
-DPIO driver should mask qman-portal interrupt reporting When
-working in poll mode. has_irq flag is used for same, but
-interrupt maksing was happening before it was decided that
-system will work in poll mode of interrupt mode.
-
-This patch fixes the issue and not irq masking/enabling is
-happening after irq/poll mode is decided.
-
-Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
-Change-Id: I44de07b6142e80b3daea45e7d51a2d2799b2ed8d
-Reviewed-on: http://git.am.freescale.net:8181/37100
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-(cherry picked from commit 3579244250dcb287a0fe58bcc3b3780076d040a2)
-
-dpio: Add a function to query buffer pool depth
-
-Add a debug function thay allows users to query the number
-of buffers in a specific buffer pool
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Change-Id: Ie9a5f2e86d6a04ae61868bcc807121780c53cf6c
-Reviewed-on: http://git.am.freescale.net:8181/36069
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-(cherry picked from commit 3c749d860592f62f6b219232580ca35fd1075337)
-
-dpio: Use normal cachable non-shareable memory for qbman cena
-
-QBMan SWP CENA portal memory requires the memory to be cacheable,
-and non-shareable.
-
-Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
-Change-Id: I1c01cffe9ff2503fea2396d7cc761508f6e1ca85
-Reviewed-on: http://git.am.freescale.net:8181/35487
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-(cherry picked from commit 2a7e1ede7e155d9219006999893912e0b029ce4c)
-
-fsl-dpio: Process frames in IRQ context
-
-Stop using threaded IRQs and move back to hardirq top-halves.
-This is the first patch of a small series adapting the DPIO and Ethernet
-code to these changes.
-
-Signed-off-by: Roy Pledge <roy.pledge@freescale.com>
-Tested-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
-Tested-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-[Stuart: split out dpaa-eth part separately]
-Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl-dpio: Fast DPIO object selection
-
-The DPIO service code had a couple of problems with performance impact:
- - The DPIO service object was protected by a global lock, within
- functions called from the fast datapath on multiple CPUs.
- - The DPIO service code would iterate unnecessarily through its linked
- list, while most of the time it looks for CPU-bound objects.
-
-Add a fast-access array pointing to the same dpaa_io objects as the DPIO
-service's linked list, used in non-preemptible contexts.
-Avoid list access/reordering if a specific CPU was requested. This
-greatly limits contention on the global service lock.
-Make explicit calls for per-CPU DPIO service objects if the current
-context permits (which is the case on most of the Ethernet fastpath).
-
-These changes incidentally fix a functional problem, too: according to
-the specification of struct dpaa_io_notification_ctx, registration should
-fail if the specification of 'desired_cpu' cannot be observed. Instead,
-dpaa_io_service_register() would keep searching for non-affine DPIO
-objects, even when that was not requested.
-
-Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-Change-Id: I2dd78bc56179f97d3fd78052a653456e5f89ed82
-Reviewed-on: http://git.am.freescale.net:8181/37689
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-DPIO: Implement a missing lock in DPIO
-
-Implement missing DPIO service notification deregistration lock
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Change-Id: Ida9a4d00cc3a66bc215c260a8df2b197366736f7
-Reviewed-on: http://git.am.freescale.net:8181/38497
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-staging: fsl-mc: migrated dpio flibs for MC fw 8.0.0
-
-Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl_qbman: Ensure SDQCR is only enabled if a channel is selected
-
-QMan HW considers an SDQCR command that does not indicate any
-channels to dequeue from to be an error. This change ensures that
-a NULL command is set in the case no channels are selected for dequeue
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-Change-Id: I8861304881885db00df4a29d760848990d706c70
-Reviewed-on: http://git.am.freescale.net:8181/38498
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-flib: dpio: Fix compiler warning.
-
-Gcc takes the credit here.
-To be merged with other fixes on this branch.
-
-Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-Change-Id: If81f35ab3e8061aae1e03b72ab16a4c1dc390c3a
-Reviewed-on: http://git.am.freescale.net:8181/39148
-Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
-Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-staging: fsl-mc: dpio: remove programing of MSIs in dpio driver
-
-this is now handled in the bus driver
-
-Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl_qbman: Enable CDAN generation
-
-Enable CDAN notificiation registration in both QBMan and DPIO
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-fsl_dpio: Implement API to dequeue from a channel
-
-Implement an API that allows users to dequeue from a channel
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-fsl-dpio: Change dequeue command type
-
-For now CDANs don't work with priority precedence.
-
-Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
-
-fsl-dpio: Export FQD context getter function
-
-Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
-
-fsl_dpio: Fix DPIO polling thread logic
-
-Fix the logic for the DPIO polling logic and ensure the thread
-is not parked
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-[Stuart: fixed typo in comment]
-Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl-dpio,qbman: Export functions
-
-A few of the functions used by the Ethernet driver were not exported
-yet. Needed in order to compile Eth driver as a module.
-
-Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
-Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl_qbman: Use proper accessors when reading QBMan portals
-
-Use accessors that properly byteswap when accessing QBMan portals
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-fsl_qbman: Fix encoding of 64 byte values
-
-The QBMan driver encodes commands in 32 bit host endianess then
-coverts to little endian before sending to HW. This means 64
-byte values need to be encoded so that the values will be
-correctly swapped when the commands are written to HW.
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-dpaa_fd: Add functions for SG entries endianness conversions
-
-Scatter gather entries are little endian at the hardware level.
-Add functions for converting the SG entry structure to cpu
-endianness to avoid incorrect behaviour on BE kernels.
-
-Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
-
-fsl_dpaa: update header files with kernel-doc format
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-
-qbman: update header fiels to follow kernel-doc format
-
-Plus rename orp_id as opr_id based on the BG.
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-
-fsl/dpio: rename ldpaa to dpaa2
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-(Stuart: removed eth part out into separate patch)
-Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
-
-qbman_test: update qbman_test
-
-- Update to sync with latest change in qbman driver.
-- Add bpscn test case
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-
-fsl-dpio: add FLE (Frame List Entry) for FMT=dpaa_fd_list support
-
-Signed-off-by: Horia Geantă <horia.geanta@freescale.com>
-
-fsl-dpio: add accessors for FD[FRC]
-
-Signed-off-by: Horia Geantă <horia.geanta@freescale.com>
-
-fsl-dpio: add accessors for FD[FLC]
-
-Signed-off-by: Horia Geantă <horia.geanta@freescale.com>
-(Stuart: corrected typo in subject)
-Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
-
-fsl/dpio: dpaa2_fd: Add the comments for newly added APIs.
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-[Stuart: added fsl/dpio prefix on commit subject]
-Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
-
-fsl-dpio: rename dpaa_* structure to dpaa2_*
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-(Stuart: split eth and caam parts out into separate patches)
-Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
-
-fsl-dpio: update the header file with more description in comments
-
-plus fix some typos.
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-fsl-dpio: fix Klocwork issues.
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-
-fsl_dpio: Fix kernel doc issues and add an overview
-
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-fsl-dpio,qbman: Prefer affine portal to acquire/release buffers
-
-The FQ enqueue/dequeue DPIO code attempts to select an affine QBMan
-portal in order to minimize contention (under the assumption that most
-of the calling code runs in affine contexts). Doing the same now for
-buffer acquire/release.
-
-Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-
-fsl-dpio: prefer affine QBMan portal in dpaa2_io_service_enqueue_fq
-
-Commit 7b057d9bc3d31 ("fsl-dpio: Fast DPIO object selection")
-took care of dpaa2_io_service_enqueue_qd, missing
-dpaa2_io_service_enqueue_fq.
-
-Cc: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
-Signed-off-by: Horia Geantă <horia.geanta@freescale.com>
-
-fsl/dpio: update the dpio flib files from mc9.0.0 release
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-
-fsl/dpio: pass qman_version from dpio attributes to swp desc
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-
-fsl/dpio/qbman: Use qman version to determin dqrr size
-
-Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
-
-fsl-dpio: Fix dequeue type enum values
-
-enum qbman_pull_type_e did not follow the volatile dequeue command
-specification, for which VERB=b'00 is a valid value (but of no
-interest to us).
-
-Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-fsl-dpio: Volatile dequeue with priority precedence
-
-Use priority precedence to do volatile dequeue from channels, rather
-than active FQ precedence.
-
-Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
-Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
-
-Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
----
- drivers/staging/fsl-mc/bus/Kconfig | 16 +
- drivers/staging/fsl-mc/bus/Makefile | 3 +
- drivers/staging/fsl-mc/bus/dpio/Makefile | 9 +
- drivers/staging/fsl-mc/bus/dpio/dpio-drv.c | 405 +++++++
- drivers/staging/fsl-mc/bus/dpio/dpio-drv.h | 33 +
- drivers/staging/fsl-mc/bus/dpio/dpio.c | 468 ++++++++
- drivers/staging/fsl-mc/bus/dpio/dpio_service.c | 801 +++++++++++++
- drivers/staging/fsl-mc/bus/dpio/fsl_dpio.h | 460 ++++++++
- drivers/staging/fsl-mc/bus/dpio/fsl_dpio_cmd.h | 184 +++
- drivers/staging/fsl-mc/bus/dpio/fsl_qbman_base.h | 123 ++
- drivers/staging/fsl-mc/bus/dpio/fsl_qbman_portal.h | 753 ++++++++++++
- drivers/staging/fsl-mc/bus/dpio/qbman_debug.c | 846 ++++++++++++++
- drivers/staging/fsl-mc/bus/dpio/qbman_debug.h | 136 +++
- drivers/staging/fsl-mc/bus/dpio/qbman_portal.c | 1212 ++++++++++++++++++++
- drivers/staging/fsl-mc/bus/dpio/qbman_portal.h | 261 +++++
- drivers/staging/fsl-mc/bus/dpio/qbman_private.h | 173 +++
- drivers/staging/fsl-mc/bus/dpio/qbman_sys.h | 307 +++++
- drivers/staging/fsl-mc/bus/dpio/qbman_sys_decl.h | 86 ++
- drivers/staging/fsl-mc/bus/dpio/qbman_test.c | 664 +++++++++++
- drivers/staging/fsl-mc/include/fsl_dpaa2_fd.h | 774 +++++++++++++
- drivers/staging/fsl-mc/include/fsl_dpaa2_io.h | 619 ++++++++++
- 21 files changed, 8333 insertions(+)
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/Makefile
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio-drv.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio-drv.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/dpio_service.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/fsl_dpio.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/fsl_dpio_cmd.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/fsl_qbman_base.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/fsl_qbman_portal.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_debug.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_debug.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_portal.c
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_portal.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_private.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_sys.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_sys_decl.h
- create mode 100644 drivers/staging/fsl-mc/bus/dpio/qbman_test.c
- create mode 100644 drivers/staging/fsl-mc/include/fsl_dpaa2_fd.h
- create mode 100644 drivers/staging/fsl-mc/include/fsl_dpaa2_io.h
-
---- a/drivers/staging/fsl-mc/bus/Kconfig
-+++ b/drivers/staging/fsl-mc/bus/Kconfig
-@@ -28,3 +28,19 @@ config FSL_MC_RESTOOL
- help
- Driver that provides kernel support for the Freescale Management
- Complex resource manager user-space tool.
-+
-+config FSL_MC_DPIO
-+ tristate "Freescale Data Path I/O (DPIO) driver"
-+ depends on FSL_MC_BUS
-+ help
-+ Driver for Freescale Data Path I/O (DPIO) devices.
-+ A DPIO device provides queue and buffer management facilities
-+ for software to interact with other Data Path devices. This
-+ driver does not expose the DPIO device individually, but
-+ groups them under a service layer API.
-+
-+config FSL_QBMAN_DEBUG
-+ tristate "Freescale QBMAN Debug APIs"
-+ depends on FSL_MC_DPIO
-+ help
-+ QBMan debug assistant APIs.
---- a/drivers/staging/fsl-mc/bus/Makefile
-+++ b/drivers/staging/fsl-mc/bus/Makefile
-@@ -21,3 +21,6 @@ mc-bus-driver-objs := mc-bus.o \
-
- # MC restool kernel support
- obj-$(CONFIG_FSL_MC_RESTOOL) += mc-restool.o
-+
-+# MC DPIO driver
-+obj-$(CONFIG_FSL_MC_DPIO) += dpio/
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/Makefile
-@@ -0,0 +1,9 @@
-+#
-+# Freescale DPIO driver
-+#
-+
-+obj-$(CONFIG_FSL_MC_BUS) += fsl-dpio-drv.o
-+
-+fsl-dpio-drv-objs := dpio-drv.o dpio_service.o dpio.o qbman_portal.o
-+
-+obj-$(CONFIG_FSL_QBMAN_DEBUG) += qbman_debug.o
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/dpio-drv.c
-@@ -0,0 +1,405 @@
-+/* Copyright 2014 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/msi.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/kthread.h>
-+#include <linux/delay.h>
-+
-+#include "../../include/mc.h"
-+#include "../../include/fsl_dpaa2_io.h"
-+
-+#include "fsl_qbman_portal.h"
-+#include "fsl_dpio.h"
-+#include "fsl_dpio_cmd.h"
-+
-+#include "dpio-drv.h"
-+
-+#define DPIO_DESCRIPTION "DPIO Driver"
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-+MODULE_AUTHOR("Freescale Semiconductor, Inc");
-+MODULE_DESCRIPTION(DPIO_DESCRIPTION);
-+
-+#define MAX_DPIO_IRQ_NAME 16 /* Big enough for "FSL DPIO %d" */
-+
-+struct dpio_priv {
-+ struct dpaa2_io *io;
-+ char irq_name[MAX_DPIO_IRQ_NAME];
-+ struct task_struct *thread;
-+};
-+
-+static int dpio_thread(void *data)
-+{
-+ struct dpaa2_io *io = data;
-+
-+ while (!kthread_should_stop()) {
-+ int err = dpaa2_io_poll(io);
-+
-+ if (err) {
-+ pr_err("dpaa2_io_poll() failed\n");
-+ return err;
-+ }
-+ msleep(50);
-+ }
-+ return 0;
-+}
-+
-+static irqreturn_t dpio_irq_handler(int irq_num, void *arg)
-+{
-+ struct device *dev = (struct device *)arg;
-+ struct dpio_priv *priv = dev_get_drvdata(dev);
-+
-+ return dpaa2_io_irq(priv->io);
-+}
-+
-+static void unregister_dpio_irq_handlers(struct fsl_mc_device *ls_dev)
-+{
-+ int i;
-+ struct fsl_mc_device_irq *irq;
-+ int irq_count = ls_dev->obj_desc.irq_count;
-+
-+ for (i = 0; i < irq_count; i++) {
-+ irq = ls_dev->irqs[i];
-+ devm_free_irq(&ls_dev->dev, irq->msi_desc->irq, &ls_dev->dev);
-+ }
-+}
-+
-+static int register_dpio_irq_handlers(struct fsl_mc_device *ls_dev, int cpu)
-+{
-+ struct dpio_priv *priv;
-+ unsigned int i;
-+ int error;
-+ struct fsl_mc_device_irq *irq;
-+ unsigned int num_irq_handlers_registered = 0;
-+ int irq_count = ls_dev->obj_desc.irq_count;
-+ cpumask_t mask;
-+
-+ priv = dev_get_drvdata(&ls_dev->dev);
-+
-+ if (WARN_ON(irq_count != 1))
-+ return -EINVAL;
-+
-+ for (i = 0; i < irq_count; i++) {
-+ irq = ls_dev->irqs[i];
-+ error = devm_request_irq(&ls_dev->dev,
-+ irq->msi_desc->irq,
-+ dpio_irq_handler,
-+ 0,
-+ priv->irq_name,
-+ &ls_dev->dev);
-+ if (error < 0) {
-+ dev_err(&ls_dev->dev,
-+ "devm_request_irq() failed: %d\n",
-+ error);
-+ goto error_unregister_irq_handlers;
-+ }
-+
-+ /* Set the IRQ affinity */
-+ cpumask_clear(&mask);
-+ cpumask_set_cpu(cpu, &mask);
-+ if (irq_set_affinity(irq->msi_desc->irq, &mask))
-+ pr_err("irq_set_affinity failed irq %d cpu %d\n",
-+ irq->msi_desc->irq, cpu);
-+
-+ num_irq_handlers_registered++;
-+ }
-+
-+ return 0;
-+
-+error_unregister_irq_handlers:
-+ for (i = 0; i < num_irq_handlers_registered; i++) {
-+ irq = ls_dev->irqs[i];
-+ devm_free_irq(&ls_dev->dev, irq->msi_desc->irq,
-+ &ls_dev->dev);
-+ }
-+
-+ return error;
-+}
-+
-+static int __cold
-+dpaa2_dpio_probe(struct fsl_mc_device *ls_dev)
-+{
-+ struct dpio_attr dpio_attrs;
-+ struct dpaa2_io_desc desc;
-+ struct dpio_priv *priv;
-+ int err = -ENOMEM;
-+ struct device *dev = &ls_dev->dev;
-+ struct dpaa2_io *defservice;
-+ bool irq_allocated = false;
-+ static int next_cpu;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ goto err_priv_alloc;
-+
-+ dev_set_drvdata(dev, priv);
-+
-+ err = fsl_mc_portal_allocate(ls_dev, 0, &ls_dev->mc_io);
-+ if (err) {
-+ dev_err(dev, "MC portal allocation failed\n");
-+ err = -EPROBE_DEFER;
-+ goto err_mcportal;
-+ }
-+
-+ err = dpio_open(ls_dev->mc_io, 0, ls_dev->obj_desc.id,
-+ &ls_dev->mc_handle);
-+ if (err) {
-+ dev_err(dev, "dpio_open() failed\n");
-+ goto err_open;
-+ }
-+
-+ err = dpio_get_attributes(ls_dev->mc_io, 0, ls_dev->mc_handle,
-+ &dpio_attrs);
-+ if (err) {
-+ dev_err(dev, "dpio_get_attributes() failed %d\n", err);
-+ goto err_get_attr;
-+ }
-+ err = dpio_enable(ls_dev->mc_io, 0, ls_dev->mc_handle);
-+ if (err) {
-+ dev_err(dev, "dpio_enable() failed %d\n", err);
-+ goto err_get_attr;
-+ }
-+ pr_info("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n",
-+ ls_dev->regions[0].start,
-+ ls_dev->regions[1].start,
-+ dpio_attrs.qbman_portal_id,
-+ dpio_attrs.num_priorities);
-+
-+ pr_info("ce_size=0x%llx, ci_size=0x%llx\n",
-+ resource_size(&ls_dev->regions[0]),
-+ resource_size(&ls_dev->regions[1]));
-+
-+ desc.qman_version = dpio_attrs.qbman_version;
-+ /* Build DPIO driver object out of raw MC object */
-+ desc.receives_notifications = dpio_attrs.num_priorities ? 1 : 0;
-+ desc.has_irq = 1;
-+ desc.will_poll = 1;
-+ desc.has_8prio = dpio_attrs.num_priorities == 8 ? 1 : 0;
-+ desc.cpu = next_cpu;
-+ desc.stash_affinity = 1; /* TODO: Figure out how to determine
-+ this setting - will we ever have non-affine
-+ portals where we stash to a platform cache? */
-+ next_cpu = (next_cpu + 1) % num_active_cpus();
-+ desc.dpio_id = ls_dev->obj_desc.id;
-+ desc.regs_cena = ioremap_cache_ns(ls_dev->regions[0].start,
-+ resource_size(&ls_dev->regions[0]));
-+ desc.regs_cinh = ioremap(ls_dev->regions[1].start,
-+ resource_size(&ls_dev->regions[1]));
-+
-+ err = fsl_mc_allocate_irqs(ls_dev);
-+ if (err) {
-+ dev_err(dev, "DPIO fsl_mc_allocate_irqs failed\n");
-+ desc.has_irq = 0;
-+ } else {
-+ irq_allocated = true;
-+
-+ snprintf(priv->irq_name, MAX_DPIO_IRQ_NAME, "FSL DPIO %d",
-+ desc.dpio_id);
-+
-+ err = register_dpio_irq_handlers(ls_dev, desc.cpu);
-+ if (err)
-+ desc.has_irq = 0;
-+ }
-+
-+ priv->io = dpaa2_io_create(&desc);
-+ if (!priv->io) {
-+ dev_err(dev, "DPIO setup failed\n");
-+ goto err_dpaa2_io_create;
-+ }
-+
-+ /* If no irq then go to poll mode */
-+ if (desc.has_irq == 0) {
-+ dev_info(dev, "Using polling mode for DPIO %d\n",
-+ desc.dpio_id);
-+ /* goto err_register_dpio_irq; */
-+ /* TEMP: Start polling if IRQ could not
-+ be registered. This will go away once
-+ KVM support for MSI is present */
-+ if (irq_allocated == true)
-+ fsl_mc_free_irqs(ls_dev);
-+
-+ if (desc.stash_affinity)
-+ priv->thread = kthread_create_on_cpu(dpio_thread,
-+ priv->io,
-+ desc.cpu,
-+ "dpio_aff%u");
-+ else
-+ priv->thread =
-+ kthread_create(dpio_thread,
-+ priv->io,
-+ "dpio_non%u",
-+ dpio_attrs.qbman_portal_id);
-+ if (IS_ERR(priv->thread)) {
-+ dev_err(dev, "DPIO thread failure\n");
-+ err = PTR_ERR(priv->thread);
-+ goto err_dpaa_thread;
-+ }
-+ kthread_unpark(priv->thread);
-+ wake_up_process(priv->thread);
-+ }
-+
-+ defservice = dpaa2_io_default_service();
-+ err = dpaa2_io_service_add(defservice, priv->io);
-+ dpaa2_io_down(defservice);
-+ if (err) {
-+ dev_err(dev, "DPIO add-to-service failed\n");
-+ goto err_dpaa2_io_add;
-+ }
-+
-+ dev_info(dev, "dpio: probed object %d\n", ls_dev->obj_desc.id);
-+ dev_info(dev, " receives_notifications = %d\n",
-+ desc.receives_notifications);
-+ dev_info(dev, " has_irq = %d\n", desc.has_irq);
-+ dpio_close(ls_dev->mc_io, 0, ls_dev->mc_handle);
-+ fsl_mc_portal_free(ls_dev->mc_io);
-+ return 0;
-+
-+err_dpaa2_io_add:
-+ unregister_dpio_irq_handlers(ls_dev);
-+/* TEMP: To be restored once polling is removed
-+ err_register_dpio_irq:
-+ fsl_mc_free_irqs(ls_dev);
-+*/
-+err_dpaa_thread:
-+err_dpaa2_io_create:
-+ dpio_disable(ls_dev->mc_io, 0, ls_dev->mc_handle);
-+err_get_attr:
-+ dpio_close(ls_dev->mc_io, 0, ls_dev->mc_handle);
-+err_open:
-+ fsl_mc_portal_free(ls_dev->mc_io);
-+err_mcportal:
-+ dev_set_drvdata(dev, NULL);
-+ devm_kfree(dev, priv);
-+err_priv_alloc:
-+ return err;
-+}
-+
-+/*
-+ * Tear down interrupts for a given DPIO object
-+ */
-+static void dpio_teardown_irqs(struct fsl_mc_device *ls_dev)
-+{
-+ /* (void)disable_dpio_irqs(ls_dev); */
-+ unregister_dpio_irq_handlers(ls_dev);
-+ fsl_mc_free_irqs(ls_dev);
-+}
-+
-+static int __cold
-+dpaa2_dpio_remove(struct fsl_mc_device *ls_dev)
-+{
-+ struct device *dev;
-+ struct dpio_priv *priv;
-+ int err;
-+
-+ dev = &ls_dev->dev;
-+ priv = dev_get_drvdata(dev);
-+
-+ /* there is no implementation yet for pulling a DPIO object out of a
-+ * running service (and they're currently always running).
-+ */
-+ dev_crit(dev, "DPIO unplugging is broken, the service holds onto it\n");
-+
-+ if (priv->thread)
-+ kthread_stop(priv->thread);
-+ else
-+ dpio_teardown_irqs(ls_dev);
-+
-+ err = fsl_mc_portal_allocate(ls_dev, 0, &ls_dev->mc_io);
-+ if (err) {
-+ dev_err(dev, "MC portal allocation failed\n");
-+ goto err_mcportal;
-+ }
-+
-+ err = dpio_open(ls_dev->mc_io, 0, ls_dev->obj_desc.id,
-+ &ls_dev->mc_handle);
-+ if (err) {
-+ dev_err(dev, "dpio_open() failed\n");
-+ goto err_open;
-+ }
-+
-+ dev_set_drvdata(dev, NULL);
-+ dpaa2_io_down(priv->io);
-+
-+ err = 0;
-+
-+ dpio_disable(ls_dev->mc_io, 0, ls_dev->mc_handle);
-+ dpio_close(ls_dev->mc_io, 0, ls_dev->mc_handle);
-+err_open:
-+ fsl_mc_portal_free(ls_dev->mc_io);
-+err_mcportal:
-+ return err;
-+}
-+
-+static const struct fsl_mc_device_match_id dpaa2_dpio_match_id_table[] = {
-+ {
-+ .vendor = FSL_MC_VENDOR_FREESCALE,
-+ .obj_type = "dpio",
-+ .ver_major = DPIO_VER_MAJOR,
-+ .ver_minor = DPIO_VER_MINOR
-+ },
-+ { .vendor = 0x0 }
-+};
-+
-+static struct fsl_mc_driver dpaa2_dpio_driver = {
-+ .driver = {
-+ .name = KBUILD_MODNAME,
-+ .owner = THIS_MODULE,
-+ },
-+ .probe = dpaa2_dpio_probe,
-+ .remove = dpaa2_dpio_remove,
-+ .match_id_table = dpaa2_dpio_match_id_table
-+};
-+
-+static int dpio_driver_init(void)
-+{
-+ int err;
-+
-+ err = dpaa2_io_service_driver_init();
-+ if (!err) {
-+ err = fsl_mc_driver_register(&dpaa2_dpio_driver);
-+ if (err)
-+ dpaa2_io_service_driver_exit();
-+ }
-+ return err;
-+}
-+static void dpio_driver_exit(void)
-+{
-+ fsl_mc_driver_unregister(&dpaa2_dpio_driver);
-+ dpaa2_io_service_driver_exit();
-+}
-+module_init(dpio_driver_init);
-+module_exit(dpio_driver_exit);
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/dpio-drv.h
-@@ -0,0 +1,33 @@
-+/* Copyright 2014 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+int dpaa2_io_service_driver_init(void);
-+void dpaa2_io_service_driver_exit(void);
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/dpio.c
-@@ -0,0 +1,468 @@
-+/* Copyright 2013-2015 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of the above-listed copyright holders nor the
-+ * names of any contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#include "../../include/mc-sys.h"
-+#include "../../include/mc-cmd.h"
-+#include "fsl_dpio.h"
-+#include "fsl_dpio_cmd.h"
-+
-+int dpio_open(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ int dpio_id,
-+ uint16_t *token)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
-+ cmd_flags,
-+ 0);
-+ DPIO_CMD_OPEN(cmd, dpio_id);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
-+
-+ return 0;
-+}
-+
-+int dpio_close(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
-+ cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_create(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ const struct dpio_cfg *cfg,
-+ uint16_t *token)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CREATE,
-+ cmd_flags,
-+ 0);
-+ DPIO_CMD_CREATE(cmd, cfg);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
-+
-+ return 0;
-+}
-+
-+int dpio_destroy(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DESTROY,
-+ cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_enable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
-+ cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_disable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
-+ cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_is_enabled(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ int *en)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_IS_ENABLED, cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_IS_ENABLED(cmd, *en);
-+
-+ return 0;
-+}
-+
-+int dpio_reset(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
-+ cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_set_irq(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ struct dpio_irq_cfg *irq_cfg)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_IRQ,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_get_irq(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ int *type,
-+ struct dpio_irq_cfg *irq_cfg)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_IRQ,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_GET_IRQ(cmd, irq_index);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_GET_IRQ(cmd, *type, irq_cfg);
-+
-+ return 0;
-+}
-+
-+int dpio_set_irq_enable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint8_t en)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_IRQ_ENABLE,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_get_irq_enable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint8_t *en)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_IRQ_ENABLE,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_GET_IRQ_ENABLE(cmd, irq_index);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_GET_IRQ_ENABLE(cmd, *en);
-+
-+ return 0;
-+}
-+
-+int dpio_set_irq_mask(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t mask)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_IRQ_MASK,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_get_irq_mask(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t *mask)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_IRQ_MASK,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_GET_IRQ_MASK(cmd, irq_index);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_GET_IRQ_MASK(cmd, *mask);
-+
-+ return 0;
-+}
-+
-+int dpio_get_irq_status(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t *status)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_IRQ_STATUS,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_GET_IRQ_STATUS(cmd, *status);
-+
-+ return 0;
-+}
-+
-+int dpio_clear_irq_status(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t status)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLEAR_IRQ_STATUS,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_get_attributes(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ struct dpio_attr *attr)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
-+ cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_GET_ATTR(cmd, attr);
-+
-+ return 0;
-+}
-+
-+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t sdest)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_SET_STASHING_DEST,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_SET_STASHING_DEST(cmd, sdest);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t *sdest)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_STASHING_DEST,
-+ cmd_flags,
-+ token);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_GET_STASHING_DEST(cmd, *sdest);
-+
-+ return 0;
-+}
-+
-+int dpio_add_static_dequeue_channel(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ int dpcon_id,
-+ uint8_t *channel_index)
-+{
-+ struct mc_command cmd = { 0 };
-+ int err;
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ADD_STATIC_DEQUEUE_CHANNEL,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_ADD_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id);
-+
-+ /* send command to mc*/
-+ err = mc_send_command(mc_io, &cmd);
-+ if (err)
-+ return err;
-+
-+ /* retrieve response parameters */
-+ DPIO_RSP_ADD_STATIC_DEQUEUE_CHANNEL(cmd, *channel_index);
-+
-+ return 0;
-+}
-+
-+int dpio_remove_static_dequeue_channel(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ int dpcon_id)
-+{
-+ struct mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(
-+ DPIO_CMDID_REMOVE_STATIC_DEQUEUE_CHANNEL,
-+ cmd_flags,
-+ token);
-+ DPIO_CMD_REMOVE_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/dpio_service.c
-@@ -0,0 +1,801 @@
-+/* Copyright 2014 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#include <linux/types.h>
-+#include "fsl_qbman_portal.h"
-+#include "../../include/mc.h"
-+#include "../../include/fsl_dpaa2_io.h"
-+#include "fsl_dpio.h"
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/slab.h>
-+
-+#include "dpio-drv.h"
-+#include "qbman_debug.h"
-+
-+#define UNIMPLEMENTED() pr_err("FOO: %s unimplemented!\n", __func__)
-+
-+#define MAGIC_SERVICE 0xabcd9876
-+#define MAGIC_OBJECT 0x1234fedc
-+
-+struct dpaa2_io {
-+ /* If MAGIC_SERVICE, this is a group of objects, use the 'service' part
-+ * of the union. If MAGIC_OBJECT, use the 'object' part of the union. If
-+ * it's neither, something got corrupted. This is mainly to satisfy
-+ * dpaa2_io_from_registration(), which dereferences a caller-
-+ * instantiated struct and so warrants a bug-checking step - hence the
-+ * magic rather than a boolean.
-+ */
-+ unsigned int magic;
-+ atomic_t refs;
-+ union {
-+ struct dpaa2_io_service {
-+ spinlock_t lock;
-+ struct list_head list;
-+ /* for targeted dpaa2_io selection */
-+ struct dpaa2_io *objects_by_cpu[NR_CPUS];
-+ cpumask_t cpus_notifications;
-+ cpumask_t cpus_stashing;
-+ int has_nonaffine;
-+ /* slight hack. record the special case of the
-+ * "default service", because that's the case where we
-+ * need to avoid a kfree() ... */
-+ int is_defservice;
-+ } service;
-+ struct dpaa2_io_object {
-+ struct dpaa2_io_desc dpio_desc;
-+ struct qbman_swp_desc swp_desc;
-+ struct qbman_swp *swp;
-+ /* If the object is part of a service, this is it (and
-+ * 'node' is linked into the service's list) */
-+ struct dpaa2_io *service;
-+ struct list_head node;
-+ /* Interrupt mask, as used with
-+ * qbman_swp_interrupt_[gs]et_vanish(). This isn't
-+ * locked, because the higher layer is driving all
-+ * "ingress" processing. */
-+ uint32_t irq_mask;
-+ /* As part of simplifying assumptions, we provide an
-+ * irq-safe lock for each type of DPIO operation that
-+ * isn't innately lockless. The selection algorithms
-+ * (which are simplified) require this, whereas
-+ * eventually adherence to cpu-affinity will presumably
-+ * relax the locking requirements. */
-+ spinlock_t lock_mgmt_cmd;
-+ spinlock_t lock_notifications;
-+ struct list_head notifications;
-+ } object;
-+ };
-+};
-+
-+struct dpaa2_io_store {
-+ unsigned int max;
-+ dma_addr_t paddr;
-+ struct dpaa2_dq *vaddr;
-+ void *alloced_addr; /* the actual return from kmalloc as it may
-+ be adjusted for alignment purposes */
-+ unsigned int idx; /* position of the next-to-be-returned entry */
-+ struct qbman_swp *swp; /* portal used to issue VDQCR */
-+ struct device *dev; /* device used for DMA mapping */
-+};
-+
-+static struct dpaa2_io def_serv;
-+
-+/**********************/
-+/* Internal functions */
-+/**********************/
-+
-+static void service_init(struct dpaa2_io *d, int is_defservice)
-+{
-+ struct dpaa2_io_service *s = &d->service;
-+
-+ d->magic = MAGIC_SERVICE;
-+ atomic_set(&d->refs, 1);
-+ spin_lock_init(&s->lock);
-+ INIT_LIST_HEAD(&s->list);
-+ cpumask_clear(&s->cpus_notifications);
-+ cpumask_clear(&s->cpus_stashing);
-+ s->has_nonaffine = 0;
-+ s->is_defservice = is_defservice;
-+}
-+
-+/* Selection algorithms, stupid ones at that. These are to handle the case where
-+ * the given dpaa2_io is a service, by choosing the non-service dpaa2_io within
-+ * it to use.
-+ */
-+static struct dpaa2_io *_service_select_by_cpu_slow(struct dpaa2_io_service *ss,
-+ int cpu)
-+{
-+ struct dpaa2_io *o;
-+ unsigned long irqflags;
-+
-+ spin_lock_irqsave(&ss->lock, irqflags);
-+ /* TODO: this is about the dumbest and slowest selection algorithm you
-+ * could imagine. (We're looking for something working first, and
-+ * something efficient second...)
-+ */
-+ list_for_each_entry(o, &ss->list, object.node)
-+ if (o->object.dpio_desc.cpu == cpu)
-+ goto found;
-+
-+ /* No joy. Try the first nonaffine portal (bleurgh) */
-+ if (ss->has_nonaffine)
-+ list_for_each_entry(o, &ss->list, object.node)
-+ if (!o->object.dpio_desc.stash_affinity)
-+ goto found;
-+
-+ /* No joy. Try the first object. Told you it was horrible. */
-+ if (!list_empty(&ss->list))
-+ o = list_entry(ss->list.next, struct dpaa2_io, object.node);
-+ else
-+ o = NULL;
-+
-+found:
-+ spin_unlock_irqrestore(&ss->lock, irqflags);
-+ return o;
-+}
-+
-+static struct dpaa2_io *service_select_by_cpu(struct dpaa2_io *d, int cpu)
-+{
-+ struct dpaa2_io_service *ss;
-+ unsigned long irqflags;
-+
-+ if (!d)
-+ d = &def_serv;
-+ else if (d->magic == MAGIC_OBJECT)
-+ return d;
-+ BUG_ON(d->magic != MAGIC_SERVICE);
-+
-+ ss = &d->service;
-+
-+ /* If cpu==-1, choose the current cpu, with no guarantees about
-+ * potentially being migrated away.
-+ */
-+ if (unlikely(cpu < 0)) {
-+ spin_lock_irqsave(&ss->lock, irqflags);
-+ cpu = smp_processor_id();
-+ spin_unlock_irqrestore(&ss->lock, irqflags);
-+
-+ return _service_select_by_cpu_slow(ss, cpu);
-+ }
-+
-+ /* If a specific cpu was requested, pick it up immediately */
-+ return ss->objects_by_cpu[cpu];
-+}
-+
-+static inline struct dpaa2_io *service_select_any(struct dpaa2_io *d)
-+{
-+ struct dpaa2_io_service *ss;
-+ struct dpaa2_io *o;
-+ unsigned long irqflags;
-+
-+ if (!d)
-+ d = &def_serv;
-+ else if (d->magic == MAGIC_OBJECT)
-+ return d;
-+ BUG_ON(d->magic != MAGIC_SERVICE);
-+
-+ /*
-+ * Lock the service, looking for the first DPIO object in the list,
-+ * ignore everything else about that DPIO, and choose it to do the
-+ * operation! As a post-selection step, move the DPIO to the end of
-+ * the list. It should improve load-balancing a little, although it
-+ * might also incur a performance hit, given that the lock is *global*
-+ * and this may be called on the fast-path...
-+ */
-+ ss = &d->service;
-+ spin_lock_irqsave(&ss->lock, irqflags);
-+ if (!list_empty(&ss->list)) {
-+ o = list_entry(ss->list.next, struct dpaa2_io, object.node);
-+ list_del(&o->object.node);
-+ list_add_tail(&o->object.node, &ss->list);
-+ } else
-+ o = NULL;
-+ spin_unlock_irqrestore(&ss->lock, irqflags);
-+ return o;
-+}
-+
-+/* If the context is not preemptible, select the service affine to the
-+ * current cpu. Otherwise, "select any".
-+ */
-+static inline struct dpaa2_io *_service_select(struct dpaa2_io *d)
-+{
-+ struct dpaa2_io *temp = d;
-+
-+ if (likely(!preemptible())) {
-+ d = service_select_by_cpu(d, smp_processor_id());
-+ if (likely(d))
-+ return d;
-+ }
-+ return service_select_any(temp);
-+}
-+
-+/**********************/
-+/* Exported functions */
-+/**********************/
-+
-+struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc)
-+{
-+ struct dpaa2_io *ret = kmalloc(sizeof(*ret), GFP_KERNEL);
-+ struct dpaa2_io_object *o = &ret->object;
-+
-+ if (!ret)
-+ return NULL;
-+ ret->magic = MAGIC_OBJECT;
-+ atomic_set(&ret->refs, 1);
-+ o->dpio_desc = *desc;
-+ o->swp_desc.cena_bar = o->dpio_desc.regs_cena;
-+ o->swp_desc.cinh_bar = o->dpio_desc.regs_cinh;
-+ o->swp_desc.qman_version = o->dpio_desc.qman_version;
-+ o->swp = qbman_swp_init(&o->swp_desc);
-+ o->service = NULL;
-+ if (!o->swp) {
-+ kfree(ret);
-+ return NULL;
-+ }
-+ INIT_LIST_HEAD(&o->node);
-+ spin_lock_init(&o->lock_mgmt_cmd);
-+ spin_lock_init(&o->lock_notifications);
-+ INIT_LIST_HEAD(&o->notifications);
-+ if (!o->dpio_desc.has_irq)
-+ qbman_swp_interrupt_set_vanish(o->swp, 0xffffffff);
-+ else {
-+ /* For now only enable DQRR interrupts */
-+ qbman_swp_interrupt_set_trigger(o->swp,
-+ QBMAN_SWP_INTERRUPT_DQRI);
-+ }
-+ qbman_swp_interrupt_clear_status(o->swp, 0xffffffff);
-+ if (o->dpio_desc.receives_notifications)
-+ qbman_swp_push_set(o->swp, 0, 1);
-+ return ret;
-+}
-+EXPORT_SYMBOL(dpaa2_io_create);
-+
-+struct dpaa2_io *dpaa2_io_create_service(void)
-+{
-+ struct dpaa2_io *ret = kmalloc(sizeof(*ret), GFP_KERNEL);
-+
-+ if (ret)
-+ service_init(ret, 0);
-+ return ret;
-+}
-+EXPORT_SYMBOL(dpaa2_io_create_service);
-+
-+struct dpaa2_io *dpaa2_io_default_service(void)
-+{
-+ atomic_inc(&def_serv.refs);
-+ return &def_serv;
-+}
-+EXPORT_SYMBOL(dpaa2_io_default_service);
-+
-+void dpaa2_io_down(struct dpaa2_io *d)
-+{
-+ if (!atomic_dec_and_test(&d->refs))
-+ return;
-+ if (d->magic == MAGIC_SERVICE) {
-+ BUG_ON(!list_empty(&d->service.list));
-+ if (d->service.is_defservice)
-+ /* avoid the kfree()! */
-+ return;
-+ } else {
-+ BUG_ON(d->magic != MAGIC_OBJECT);
-+ BUG_ON(d->object.service);
-+ BUG_ON(!list_empty(&d->object.notifications));
-+ }
-+ kfree(d);
-+}
-+EXPORT_SYMBOL(dpaa2_io_down);
-+
-+int dpaa2_io_service_add(struct dpaa2_io *s, struct dpaa2_io *o)
-+{
-+ struct dpaa2_io_service *ss = &s->service;
-+ struct dpaa2_io_object *oo = &o->object;
-+ int res = -EINVAL;
-+
-+ if ((s->magic != MAGIC_SERVICE) || (o->magic != MAGIC_OBJECT))
-+ return res;
-+ atomic_inc(&o->refs);
-+ atomic_inc(&s->refs);
-+ spin_lock(&ss->lock);
-+ /* 'obj' must not already be associated with a service */
-+ if (!oo->service) {
-+ oo->service = s;
-+ list_add(&oo->node, &ss->list);
-+ if (oo->dpio_desc.receives_notifications) {
-+ cpumask_set_cpu(oo->dpio_desc.cpu,
-+ &ss->cpus_notifications);
-+ /* Update the fast-access array */
-+ ss->objects_by_cpu[oo->dpio_desc.cpu] =
-+ container_of(oo, struct dpaa2_io, object);
-+ }
-+ if (oo->dpio_desc.stash_affinity)
-+ cpumask_set_cpu(oo->dpio_desc.cpu,
-+ &ss->cpus_stashing);
-+ if (!oo->dpio_desc.stash_affinity)
-+ ss->has_nonaffine = 1;
-+ /* success */
-+ res = 0;
-+ }
-+ spin_unlock(&ss->lock);
-+ if (res) {
-+ dpaa2_io_down(s);
-+ dpaa2_io_down(o);
-+ }
-+ return res;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_add);
-+
-+int dpaa2_io_get_descriptor(struct dpaa2_io *obj, struct dpaa2_io_desc *desc)
-+{
-+ if (obj->magic == MAGIC_SERVICE)
-+ return -EINVAL;
-+ BUG_ON(obj->magic != MAGIC_OBJECT);
-+ *desc = obj->object.dpio_desc;
-+ return 0;
-+}
-+EXPORT_SYMBOL(dpaa2_io_get_descriptor);
-+
-+#define DPAA_POLL_MAX 32
-+
-+int dpaa2_io_poll(struct dpaa2_io *obj)
-+{
-+ const struct dpaa2_dq *dq;
-+ struct qbman_swp *swp;
-+ int max = 0;
-+
-+ if (obj->magic != MAGIC_OBJECT)
-+ return -EINVAL;
-+ swp = obj->object.swp;
-+ dq = qbman_swp_dqrr_next(swp);
-+ while (dq) {
-+ if (qbman_result_is_SCN(dq)) {
-+ struct dpaa2_io_notification_ctx *ctx;
-+ uint64_t q64;
-+
-+ q64 = qbman_result_SCN_ctx(dq);
-+ ctx = (void *)q64;
-+ ctx->cb(ctx);
-+ } else
-+ pr_crit("Unrecognised/ignored DQRR entry\n");
-+ qbman_swp_dqrr_consume(swp, dq);
-+ ++max;
-+ if (max > DPAA_POLL_MAX)
-+ return 0;
-+ dq = qbman_swp_dqrr_next(swp);
-+ }
-+ return 0;
-+}
-+EXPORT_SYMBOL(dpaa2_io_poll);
-+
-+int dpaa2_io_irq(struct dpaa2_io *obj)
-+{
-+ struct qbman_swp *swp;
-+ uint32_t status;
-+
-+ if (obj->magic != MAGIC_OBJECT)
-+ return -EINVAL;
-+ swp = obj->object.swp;
-+ status = qbman_swp_interrupt_read_status(swp);
-+ if (!status)
-+ return IRQ_NONE;
-+ dpaa2_io_poll(obj);
-+ qbman_swp_interrupt_clear_status(swp, status);
-+ qbman_swp_interrupt_set_inhibit(swp, 0);
-+ return IRQ_HANDLED;
-+}
-+EXPORT_SYMBOL(dpaa2_io_irq);
-+
-+int dpaa2_io_pause_poll(struct dpaa2_io *obj)
-+{
-+ UNIMPLEMENTED();
-+ return -EINVAL;
-+}
-+EXPORT_SYMBOL(dpaa2_io_pause_poll);
-+
-+int dpaa2_io_resume_poll(struct dpaa2_io *obj)
-+{
-+ UNIMPLEMENTED();
-+ return -EINVAL;
-+}
-+EXPORT_SYMBOL(dpaa2_io_resume_poll);
-+
-+void dpaa2_io_service_notifications(struct dpaa2_io *s, cpumask_t *mask)
-+{
-+ struct dpaa2_io_service *ss = &s->service;
-+
-+ BUG_ON(s->magic != MAGIC_SERVICE);
-+ cpumask_copy(mask, &ss->cpus_notifications);
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_notifications);
-+
-+void dpaa2_io_service_stashing(struct dpaa2_io *s, cpumask_t *mask)
-+{
-+ struct dpaa2_io_service *ss = &s->service;
-+
-+ BUG_ON(s->magic != MAGIC_SERVICE);
-+ cpumask_copy(mask, &ss->cpus_stashing);
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_stashing);
-+
-+int dpaa2_io_service_has_nonaffine(struct dpaa2_io *s)
-+{
-+ struct dpaa2_io_service *ss = &s->service;
-+
-+ BUG_ON(s->magic != MAGIC_SERVICE);
-+ return ss->has_nonaffine;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_has_nonaffine);
-+
-+int dpaa2_io_service_register(struct dpaa2_io *d,
-+ struct dpaa2_io_notification_ctx *ctx)
-+{
-+ unsigned long irqflags;
-+
-+ d = service_select_by_cpu(d, ctx->desired_cpu);
-+ if (!d)
-+ return -ENODEV;
-+ ctx->dpio_id = d->object.dpio_desc.dpio_id;
-+ ctx->qman64 = (uint64_t)ctx;
-+ ctx->dpio_private = d;
-+ spin_lock_irqsave(&d->object.lock_notifications, irqflags);
-+ list_add(&ctx->node, &d->object.notifications);
-+ spin_unlock_irqrestore(&d->object.lock_notifications, irqflags);
-+ if (ctx->is_cdan)
-+ /* Enable the generation of CDAN notifications */
-+ qbman_swp_CDAN_set_context_enable(d->object.swp,
-+ (uint16_t)ctx->id,
-+ ctx->qman64);
-+ return 0;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_register);
-+
-+int dpaa2_io_service_deregister(struct dpaa2_io *service,
-+ struct dpaa2_io_notification_ctx *ctx)
-+{
-+ struct dpaa2_io *d = ctx->dpio_private;
-+ unsigned long irqflags;
-+
-+ if (!service)
-+ service = &def_serv;
-+ BUG_ON((service != d) && (service != d->object.service));
-+ if (ctx->is_cdan)
-+ qbman_swp_CDAN_disable(d->object.swp,
-+ (uint16_t)ctx->id);
-+ spin_lock_irqsave(&d->object.lock_notifications, irqflags);
-+ list_del(&ctx->node);
-+ spin_unlock_irqrestore(&d->object.lock_notifications, irqflags);
-+ return 0;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_deregister);
-+
-+int dpaa2_io_service_rearm(struct dpaa2_io *d,
-+ struct dpaa2_io_notification_ctx *ctx)
-+{
-+ unsigned long irqflags;
-+ int err;
-+
-+ d = _service_select(d);
-+ if (!d)
-+ return -ENODEV;
-+ spin_lock_irqsave(&d->object.lock_mgmt_cmd, irqflags);
-+ if (ctx->is_cdan)
-+ err = qbman_swp_CDAN_enable(d->object.swp, (uint16_t)ctx->id);
-+ else
-+ err = qbman_swp_fq_schedule(d->object.swp, ctx->id);
-+ spin_unlock_irqrestore(&d->object.lock_mgmt_cmd, irqflags);
-+ return err;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_rearm);
-+
-+int dpaa2_io_from_registration(struct dpaa2_io_notification_ctx *ctx,
-+ struct dpaa2_io **io)
-+{
-+ struct dpaa2_io_notification_ctx *tmp;
-+ struct dpaa2_io *d = ctx->dpio_private;
-+ unsigned long irqflags;
-+ int ret = 0;
-+
-+ BUG_ON(d->magic != MAGIC_OBJECT);
-+ /* Iterate the notifications associated with 'd' looking for a match. If
-+ * not, we've been passed an unregistered ctx! */
-+ spin_lock_irqsave(&d->object.lock_notifications, irqflags);
-+ list_for_each_entry(tmp, &d->object.notifications, node)
-+ if (tmp == ctx)
-+ goto found;
-+ ret = -EINVAL;
-+found:
-+ spin_unlock_irqrestore(&d->object.lock_notifications, irqflags);
-+ if (!ret) {
-+ atomic_inc(&d->refs);
-+ *io = d;
-+ }
-+ return ret;
-+}
-+EXPORT_SYMBOL(dpaa2_io_from_registration);
-+
-+int dpaa2_io_service_get_persistent(struct dpaa2_io *service, int cpu,
-+ struct dpaa2_io **ret)
-+{
-+ if (cpu == -1)
-+ *ret = service_select_any(service);
-+ else
-+ *ret = service_select_by_cpu(service, cpu);
-+ if (*ret) {
-+ atomic_inc(&(*ret)->refs);
-+ return 0;
-+ }
-+ return -ENODEV;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_get_persistent);
-+
-+int dpaa2_io_service_pull_fq(struct dpaa2_io *d, uint32_t fqid,
-+ struct dpaa2_io_store *s)
-+{
-+ struct qbman_pull_desc pd;
-+ int err;
-+
-+ qbman_pull_desc_clear(&pd);
-+ qbman_pull_desc_set_storage(&pd, s->vaddr, s->paddr, 1);
-+ qbman_pull_desc_set_numframes(&pd, (uint8_t)s->max);
-+ qbman_pull_desc_set_fq(&pd, fqid);
-+ d = _service_select(d);
-+ if (!d)
-+ return -ENODEV;
-+ s->swp = d->object.swp;
-+ err = qbman_swp_pull(d->object.swp, &pd);
-+ if (err)
-+ s->swp = NULL;
-+ return err;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_pull_fq);
-+
-+int dpaa2_io_service_pull_channel(struct dpaa2_io *d, uint32_t channelid,
-+ struct dpaa2_io_store *s)
-+{
-+ struct qbman_pull_desc pd;
-+ int err;
-+
-+ qbman_pull_desc_clear(&pd);
-+ qbman_pull_desc_set_storage(&pd, s->vaddr, s->paddr, 1);
-+ qbman_pull_desc_set_numframes(&pd, (uint8_t)s->max);
-+ qbman_pull_desc_set_channel(&pd, channelid, qbman_pull_type_prio);
-+ d = _service_select(d);
-+ if (!d)
-+ return -ENODEV;
-+ s->swp = d->object.swp;
-+ err = qbman_swp_pull(d->object.swp, &pd);
-+ if (err)
-+ s->swp = NULL;
-+ return err;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_pull_channel);
-+
-+int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d,
-+ uint32_t fqid,
-+ const struct dpaa2_fd *fd)
-+{
-+ struct qbman_eq_desc ed;
-+
-+ d = _service_select(d);
-+ if (!d)
-+ return -ENODEV;
-+ qbman_eq_desc_clear(&ed);
-+ qbman_eq_desc_set_no_orp(&ed, 0);
-+ qbman_eq_desc_set_fq(&ed, fqid);
-+ return qbman_swp_enqueue(d->object.swp, &ed,
-+ (const struct qbman_fd *)fd);
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq);
-+
-+int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d,
-+ uint32_t qdid, uint8_t prio, uint16_t qdbin,
-+ const struct dpaa2_fd *fd)
-+{
-+ struct qbman_eq_desc ed;
-+
-+ d = _service_select(d);
-+ if (!d)
-+ return -ENODEV;
-+ qbman_eq_desc_clear(&ed);
-+ qbman_eq_desc_set_no_orp(&ed, 0);
-+ qbman_eq_desc_set_qd(&ed, qdid, qdbin, prio);
-+ return qbman_swp_enqueue(d->object.swp, &ed,
-+ (const struct qbman_fd *)fd);
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_enqueue_qd);
-+
-+int dpaa2_io_service_release(struct dpaa2_io *d,
-+ uint32_t bpid,
-+ const uint64_t *buffers,
-+ unsigned int num_buffers)
-+{
-+ struct qbman_release_desc rd;
-+
-+ d = _service_select(d);
-+ if (!d)
-+ return -ENODEV;
-+ qbman_release_desc_clear(&rd);
-+ qbman_release_desc_set_bpid(&rd, bpid);
-+ return qbman_swp_release(d->object.swp, &rd, buffers, num_buffers);
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_release);
-+
-+int dpaa2_io_service_acquire(struct dpaa2_io *d,
-+ uint32_t bpid,
-+ uint64_t *buffers,
-+ unsigned int num_buffers)
-+{
-+ unsigned long irqflags;
-+ int err;
-+
-+ d = _service_select(d);
-+ if (!d)
-+ return -ENODEV;
-+ spin_lock_irqsave(&d->object.lock_mgmt_cmd, irqflags);
-+ err = qbman_swp_acquire(d->object.swp, bpid, buffers, num_buffers);
-+ spin_unlock_irqrestore(&d->object.lock_mgmt_cmd, irqflags);
-+ return err;
-+}
-+EXPORT_SYMBOL(dpaa2_io_service_acquire);
-+
-+struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
-+ struct device *dev)
-+{
-+ struct dpaa2_io_store *ret = kmalloc(sizeof(*ret), GFP_KERNEL);
-+ size_t size;
-+
-+ BUG_ON(!max_frames || (max_frames > 16));
-+ if (!ret)
-+ return NULL;
-+ ret->max = max_frames;
-+ size = max_frames * sizeof(struct dpaa2_dq) + 64;
-+ ret->alloced_addr = kmalloc(size, GFP_KERNEL);
-+ if (!ret->alloced_addr) {
-+ kfree(ret);
-+ return NULL;
-+ }
-+ ret->vaddr = PTR_ALIGN(ret->alloced_addr, 64);
-+ ret->paddr = dma_map_single(dev, ret->vaddr,
-+ sizeof(struct dpaa2_dq) * max_frames,
-+ DMA_FROM_DEVICE);
-+ if (dma_mapping_error(dev, ret->paddr)) {
-+ kfree(ret->alloced_addr);
-+ kfree(ret);
-+ return NULL;
-+ }
-+ ret->idx = 0;
-+ ret->dev = dev;
-+ return ret;
-+}
-+EXPORT_SYMBOL(dpaa2_io_store_create);
-+
-+void dpaa2_io_store_destroy(struct dpaa2_io_store *s)
-+{
-+ dma_unmap_single(s->dev, s->paddr, sizeof(struct dpaa2_dq) * s->max,
-+ DMA_FROM_DEVICE);
-+ kfree(s->alloced_addr);
-+ kfree(s);
-+}
-+EXPORT_SYMBOL(dpaa2_io_store_destroy);
-+
-+struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last)
-+{
-+ int match;
-+ struct dpaa2_dq *ret = &s->vaddr[s->idx];
-+
-+ match = qbman_result_has_new_result(s->swp, ret);
-+ if (!match) {
-+ *is_last = 0;
-+ return NULL;
-+ }
-+ BUG_ON(!qbman_result_is_DQ(ret));
-+ s->idx++;
-+ if (dpaa2_dq_is_pull_complete(ret)) {
-+ *is_last = 1;
-+ s->idx = 0;
-+ /* If we get an empty dequeue result to terminate a zero-results
-+ * vdqcr, return NULL to the caller rather than expecting him to
-+ * check non-NULL results every time. */
-+ if (!(dpaa2_dq_flags(ret) & DPAA2_DQ_STAT_VALIDFRAME))
-+ ret = NULL;
-+ } else
-+ *is_last = 0;
-+ return ret;
-+}
-+EXPORT_SYMBOL(dpaa2_io_store_next);
-+
-+#ifdef CONFIG_FSL_QBMAN_DEBUG
-+int dpaa2_io_query_fq_count(struct dpaa2_io *d, uint32_t fqid,
-+ uint32_t *fcnt, uint32_t *bcnt)
-+{
-+ struct qbman_attr state;
-+ struct qbman_swp *swp;
-+ unsigned long irqflags;
-+ int ret;
-+
-+ d = service_select_any(d);
-+ if (!d)
-+ return -ENODEV;
-+
-+ swp = d->object.swp;
-+ spin_lock_irqsave(&d->object.lock_mgmt_cmd, irqflags);
-+ ret = qbman_fq_query_state(swp, fqid, &state);
-+ spin_unlock_irqrestore(&d->object.lock_mgmt_cmd, irqflags);
-+ if (ret)
-+ return ret;
-+ *fcnt = qbman_fq_state_frame_count(&state);
-+ *bcnt = qbman_fq_state_byte_count(&state);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(dpaa2_io_query_fq_count);
-+
-+int dpaa2_io_query_bp_count(struct dpaa2_io *d, uint32_t bpid,
-+ uint32_t *num)
-+{
-+ struct qbman_attr state;
-+ struct qbman_swp *swp;
-+ unsigned long irqflags;
-+ int ret;
-+
-+ d = service_select_any(d);
-+ if (!d)
-+ return -ENODEV;
-+
-+ swp = d->object.swp;
-+ spin_lock_irqsave(&d->object.lock_mgmt_cmd, irqflags);
-+ ret = qbman_bp_query(swp, bpid, &state);
-+ spin_unlock_irqrestore(&d->object.lock_mgmt_cmd, irqflags);
-+ if (ret)
-+ return ret;
-+ *num = qbman_bp_info_num_free_bufs(&state);
-+ return 0;
-+}
-+EXPORT_SYMBOL(dpaa2_io_query_bp_count);
-+
-+#endif
-+
-+/* module init/exit hooks called from dpio-drv.c. These are declared in
-+ * dpio-drv.h.
-+ */
-+int dpaa2_io_service_driver_init(void)
-+{
-+ service_init(&def_serv, 1);
-+ return 0;
-+}
-+
-+void dpaa2_io_service_driver_exit(void)
-+{
-+ if (atomic_read(&def_serv.refs) != 1)
-+ pr_err("default DPIO service leaves dangling DPIO objects!\n");
-+}
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/fsl_dpio.h
-@@ -0,0 +1,460 @@
-+/* Copyright 2013-2015 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of the above-listed copyright holders nor the
-+ * names of any contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#ifndef __FSL_DPIO_H
-+#define __FSL_DPIO_H
-+
-+/* Data Path I/O Portal API
-+ * Contains initialization APIs and runtime control APIs for DPIO
-+ */
-+
-+struct fsl_mc_io;
-+
-+/**
-+ * dpio_open() - Open a control session for the specified object
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @dpio_id: DPIO unique ID
-+ * @token: Returned token; use in subsequent API calls
-+ *
-+ * This function can be used to open a control session for an
-+ * already created object; an object may have been declared in
-+ * the DPL or by calling the dpio_create() function.
-+ * This function returns a unique authentication token,
-+ * associated with the specific object ID and the specific MC
-+ * portal; this token must be used in all subsequent commands for
-+ * this specific object.
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_open(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ int dpio_id,
-+ uint16_t *token);
-+
-+/**
-+ * dpio_close() - Close the control session of the object
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_close(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token);
-+
-+/**
-+ * enum dpio_channel_mode - DPIO notification channel mode
-+ * @DPIO_NO_CHANNEL: No support for notification channel
-+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
-+ * dedicated channel in the DPIO; user should point the queue's
-+ * destination in the relevant interface to this DPIO
-+ */
-+enum dpio_channel_mode {
-+ DPIO_NO_CHANNEL = 0,
-+ DPIO_LOCAL_CHANNEL = 1,
-+};
-+
-+/**
-+ * struct dpio_cfg - Structure representing DPIO configuration
-+ * @channel_mode: Notification channel mode
-+ * @num_priorities: Number of priorities for the notification channel (1-8);
-+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
-+ */
-+struct dpio_cfg {
-+ enum dpio_channel_mode channel_mode;
-+ uint8_t num_priorities;
-+};
-+
-+/**
-+ * dpio_create() - Create the DPIO object.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @cfg: Configuration structure
-+ * @token: Returned token; use in subsequent API calls
-+ *
-+ * Create the DPIO object, allocate required resources and
-+ * perform required initialization.
-+ *
-+ * The object can be created either by declaring it in the
-+ * DPL file, or by calling this function.
-+ *
-+ * This function returns a unique authentication token,
-+ * associated with the specific object ID and the specific MC
-+ * portal; this token must be used in all subsequent calls to
-+ * this specific object. For objects that are created using the
-+ * DPL file, call dpio_open() function to get an authentication
-+ * token first.
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_create(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ const struct dpio_cfg *cfg,
-+ uint16_t *token);
-+
-+/**
-+ * dpio_destroy() - Destroy the DPIO object and release all its resources.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ *
-+ * Return: '0' on Success; Error code otherwise
-+ */
-+int dpio_destroy(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token);
-+
-+/**
-+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ *
-+ * Return: '0' on Success; Error code otherwise
-+ */
-+int dpio_enable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token);
-+
-+/**
-+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ *
-+ * Return: '0' on Success; Error code otherwise
-+ */
-+int dpio_disable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token);
-+
-+/**
-+ * dpio_is_enabled() - Check if the DPIO is enabled.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @en: Returns '1' if object is enabled; '0' otherwise
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_is_enabled(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ int *en);
-+
-+/**
-+ * dpio_reset() - Reset the DPIO, returns the object to initial state.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_reset(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token);
-+
-+/**
-+ * dpio_set_stashing_destination() - Set the stashing destination.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @sdest: stashing destination value
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_set_stashing_destination(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t sdest);
-+
-+/**
-+ * dpio_get_stashing_destination() - Get the stashing destination..
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @sdest: Returns the stashing destination value
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_get_stashing_destination(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t *sdest);
-+
-+/**
-+ * dpio_add_static_dequeue_channel() - Add a static dequeue channel.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @dpcon_id: DPCON object ID
-+ * @channel_index: Returned channel index to be used in qbman API
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_add_static_dequeue_channel(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ int dpcon_id,
-+ uint8_t *channel_index);
-+
-+/**
-+ * dpio_remove_static_dequeue_channel() - Remove a static dequeue channel.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @dpcon_id: DPCON object ID
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_remove_static_dequeue_channel(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ int dpcon_id);
-+
-+/**
-+ * DPIO IRQ Index and Events
-+ */
-+
-+/**
-+ * Irq software-portal index
-+ */
-+#define DPIO_IRQ_SWP_INDEX 0
-+
-+/**
-+ * struct dpio_irq_cfg - IRQ configuration
-+ * @addr: Address that must be written to signal a message-based interrupt
-+ * @val: Value to write into irq_addr address
-+ * @irq_num: A user defined number associated with this IRQ
-+ */
-+struct dpio_irq_cfg {
-+ uint64_t addr;
-+ uint32_t val;
-+ int irq_num;
-+};
-+
-+/**
-+ * dpio_set_irq() - Set IRQ information for the DPIO to trigger an interrupt.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: Identifies the interrupt index to configure
-+ * @irq_cfg: IRQ configuration
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_set_irq(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ struct dpio_irq_cfg *irq_cfg);
-+
-+/**
-+ * dpio_get_irq() - Get IRQ information from the DPIO.
-+ *
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: The interrupt index to configure
-+ * @type: Interrupt type: 0 represents message interrupt
-+ * type (both irq_addr and irq_val are valid)
-+ * @irq_cfg: IRQ attributes
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_get_irq(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ int *type,
-+ struct dpio_irq_cfg *irq_cfg);
-+
-+/**
-+ * dpio_set_irq_enable() - Set overall interrupt state.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: The interrupt index to configure
-+ * @en: Interrupt state - enable = 1, disable = 0
-+ *
-+ * Allows GPP software to control when interrupts are generated.
-+ * Each interrupt can have up to 32 causes. The enable/disable control's the
-+ * overall interrupt state. if the interrupt is disabled no causes will cause
-+ * an interrupt.
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_set_irq_enable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint8_t en);
-+
-+/**
-+ * dpio_get_irq_enable() - Get overall interrupt state
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: The interrupt index to configure
-+ * @en: Returned interrupt state - enable = 1, disable = 0
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_get_irq_enable(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint8_t *en);
-+
-+/**
-+ * dpio_set_irq_mask() - Set interrupt mask.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: The interrupt index to configure
-+ * @mask: event mask to trigger interrupt;
-+ * each bit:
-+ * 0 = ignore event
-+ * 1 = consider event for asserting IRQ
-+ *
-+ * Every interrupt can have up to 32 causes and the interrupt model supports
-+ * masking/unmasking each cause independently
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_set_irq_mask(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t mask);
-+
-+/**
-+ * dpio_get_irq_mask() - Get interrupt mask.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: The interrupt index to configure
-+ * @mask: Returned event mask to trigger interrupt
-+ *
-+ * Every interrupt can have up to 32 causes and the interrupt model supports
-+ * masking/unmasking each cause independently
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_get_irq_mask(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t *mask);
-+
-+/**
-+ * dpio_get_irq_status() - Get the current status of any pending interrupts.
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: The interrupt index to configure
-+ * @status: Returned interrupts status - one bit per cause:
-+ * 0 = no interrupt pending
-+ * 1 = interrupt pending
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_get_irq_status(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t *status);
-+
-+/**
-+ * dpio_clear_irq_status() - Clear a pending interrupt's status
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @irq_index: The interrupt index to configure
-+ * @status: bits to clear (W1C) - one bit per cause:
-+ * 0 = don't change
-+ * 1 = clear status bit
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpio_clear_irq_status(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ uint8_t irq_index,
-+ uint32_t status);
-+
-+/**
-+ * struct dpio_attr - Structure representing DPIO attributes
-+ * @id: DPIO object ID
-+ * @version: DPIO version
-+ * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
-+ * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
-+ * @qbman_portal_id: Software portal ID
-+ * @channel_mode: Notification channel mode
-+ * @num_priorities: Number of priorities for the notification channel (1-8);
-+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
-+ * @qbman_version: QBMAN version
-+ */
-+struct dpio_attr {
-+ int id;
-+ /**
-+ * struct version - DPIO version
-+ * @major: DPIO major version
-+ * @minor: DPIO minor version
-+ */
-+ struct {
-+ uint16_t major;
-+ uint16_t minor;
-+ } version;
-+ uint64_t qbman_portal_ce_offset;
-+ uint64_t qbman_portal_ci_offset;
-+ uint16_t qbman_portal_id;
-+ enum dpio_channel_mode channel_mode;
-+ uint8_t num_priorities;
-+ uint32_t qbman_version;
-+};
-+
-+/**
-+ * dpio_get_attributes() - Retrieve DPIO attributes
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPIO object
-+ * @attr: Returned object's attributes
-+ *
-+ * Return: '0' on Success; Error code otherwise
-+ */
-+int dpio_get_attributes(struct fsl_mc_io *mc_io,
-+ uint32_t cmd_flags,
-+ uint16_t token,
-+ struct dpio_attr *attr);
-+#endif /* __FSL_DPIO_H */
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/fsl_dpio_cmd.h
-@@ -0,0 +1,184 @@
-+/* Copyright 2013-2015 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of the above-listed copyright holders nor the
-+ * names of any contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#ifndef _FSL_DPIO_CMD_H
-+#define _FSL_DPIO_CMD_H
-+
-+/* DPIO Version */
-+#define DPIO_VER_MAJOR 3
-+#define DPIO_VER_MINOR 2
-+
-+/* Command IDs */
-+#define DPIO_CMDID_CLOSE 0x800
-+#define DPIO_CMDID_OPEN 0x803
-+#define DPIO_CMDID_CREATE 0x903
-+#define DPIO_CMDID_DESTROY 0x900
-+
-+#define DPIO_CMDID_ENABLE 0x002
-+#define DPIO_CMDID_DISABLE 0x003
-+#define DPIO_CMDID_GET_ATTR 0x004
-+#define DPIO_CMDID_RESET 0x005
-+#define DPIO_CMDID_IS_ENABLED 0x006
-+
-+#define DPIO_CMDID_SET_IRQ 0x010
-+#define DPIO_CMDID_GET_IRQ 0x011
-+#define DPIO_CMDID_SET_IRQ_ENABLE 0x012
-+#define DPIO_CMDID_GET_IRQ_ENABLE 0x013
-+#define DPIO_CMDID_SET_IRQ_MASK 0x014
-+#define DPIO_CMDID_GET_IRQ_MASK 0x015
-+#define DPIO_CMDID_GET_IRQ_STATUS 0x016
-+#define DPIO_CMDID_CLEAR_IRQ_STATUS 0x017
-+
-+#define DPIO_CMDID_SET_STASHING_DEST 0x120
-+#define DPIO_CMDID_GET_STASHING_DEST 0x121
-+#define DPIO_CMDID_ADD_STATIC_DEQUEUE_CHANNEL 0x122
-+#define DPIO_CMDID_REMOVE_STATIC_DEQUEUE_CHANNEL 0x123
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_OPEN(cmd, dpio_id) \
-+ MC_CMD_OP(cmd, 0, 0, 32, int, dpio_id)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_CREATE(cmd, cfg) \
-+do { \
-+ MC_CMD_OP(cmd, 0, 16, 2, enum dpio_channel_mode, \
-+ cfg->channel_mode);\
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->num_priorities);\
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_IS_ENABLED(cmd, en) \
-+ MC_RSP_OP(cmd, 0, 0, 1, int, en)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
-+do { \
-+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
-+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
-+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
-+ MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_GET_IRQ(cmd, irq_index) \
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_GET_IRQ(cmd, type, irq_cfg) \
-+do { \
-+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \
-+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr); \
-+ MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
-+ MC_RSP_OP(cmd, 2, 32, 32, int, type); \
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \
-+do { \
-+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, en); \
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_GET_IRQ_ENABLE(cmd, en) \
-+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
-+do { \
-+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask); \
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_GET_IRQ_MASK(cmd, irq_index) \
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_GET_IRQ_MASK(cmd, mask) \
-+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
-+do { \
-+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_GET_IRQ_STATUS(cmd, status) \
-+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
-+do { \
-+ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
-+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_GET_ATTR(cmd, attr) \
-+do { \
-+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
-+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
-+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
-+ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
-+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\
-+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\
-+ MC_RSP_OP(cmd, 3, 0, 16, uint16_t, attr->version.major);\
-+ MC_RSP_OP(cmd, 3, 16, 16, uint16_t, attr->version.minor);\
-+ MC_RSP_OP(cmd, 3, 32, 32, uint32_t, attr->qbman_version);\
-+} while (0)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_SET_STASHING_DEST(cmd, sdest) \
-+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, sdest)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_GET_STASHING_DEST(cmd, sdest) \
-+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, sdest)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_ADD_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
-+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_RSP_ADD_STATIC_DEQUEUE_CHANNEL(cmd, channel_index) \
-+ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, channel_index)
-+
-+/* cmd, param, offset, width, type, arg_name */
-+#define DPIO_CMD_REMOVE_STATIC_DEQUEUE_CHANNEL(cmd, dpcon_id) \
-+ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
-+#endif /* _FSL_DPIO_CMD_H */
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/fsl_qbman_base.h
-@@ -0,0 +1,123 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#ifndef _FSL_QBMAN_BASE_H
-+#define _FSL_QBMAN_BASE_H
-+
-+/**
-+ * struct qbman_block_desc - qbman block descriptor structure
-+ *
-+ * Descriptor for a QBMan instance on the SoC. On partitions/targets that do not
-+ * control this QBMan instance, these values may simply be place-holders. The
-+ * idea is simply that we be able to distinguish between them, eg. so that SWP
-+ * descriptors can identify which QBMan instance they belong to.
-+ */
-+struct qbman_block_desc {
-+ void *ccsr_reg_bar; /* CCSR register map */
-+ int irq_rerr; /* Recoverable error interrupt line */
-+ int irq_nrerr; /* Non-recoverable error interrupt line */
-+};
-+
-+/**
-+ * struct qbman_swp_desc - qbman software portal descriptor structure
-+ *
-+ * Descriptor for a QBMan software portal, expressed in terms that make sense to
-+ * the user context. Ie. on MC, this information is likely to be true-physical,
-+ * and instantiated statically at compile-time. On GPP, this information is
-+ * likely to be obtained via "discovery" over a partition's "layerscape bus"
-+ * (ie. in response to a MC portal command), and would take into account any
-+ * virtualisation of the GPP user's address space and/or interrupt numbering.
-+ */
-+struct qbman_swp_desc {
-+ const struct qbman_block_desc *block; /* The QBMan instance */
-+ void *cena_bar; /* Cache-enabled portal register map */
-+ void *cinh_bar; /* Cache-inhibited portal register map */
-+ uint32_t qman_version;
-+};
-+
-+/* Driver object for managing a QBMan portal */
-+struct qbman_swp;
-+
-+/**
-+ * struct qbman_fd - basci structure for qbman frame descriptor
-+ *
-+ * Place-holder for FDs, we represent it via the simplest form that we need for
-+ * now. Different overlays may be needed to support different options, etc. (It
-+ * is impractical to define One True Struct, because the resulting encoding
-+ * routines (lots of read-modify-writes) would be worst-case performance whether
-+ * or not circumstances required them.)
-+ *
-+ * Note, as with all data-structures exchanged between software and hardware (be
-+ * they located in the portal register map or DMA'd to and from main-memory),
-+ * the driver ensures that the caller of the driver API sees the data-structures
-+ * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words
-+ * contained within this structure are represented in host-endianness, even if
-+ * hardware always treats them as little-endian. As such, if any of these fields
-+ * are interpreted in a binary (rather than numerical) fashion by hardware
-+ * blocks (eg. accelerators), then the user should be careful. We illustrate
-+ * with an example;
-+ *
-+ * Suppose the desired behaviour of an accelerator is controlled by the "frc"
-+ * field of the FDs that are sent to it. Suppose also that the behaviour desired
-+ * by the user corresponds to an "frc" value which is expressed as the literal
-+ * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit
-+ * value in which 0xfe is the first byte and 0xba is the last byte, and as
-+ * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If
-+ * the software is little-endian also, this can simply be achieved by setting
-+ * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set
-+ * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is
-+ * to treat the 32-bit words as numerical values, in which the offset of a field
-+ * from the beginning of the first byte (as required or generated by hardware)
-+ * is numerically encoded by a left-shift (ie. by raising the field to a
-+ * corresponding power of 2). Ie. in the current example, software could set
-+ * "frc" in the following way, and it would work correctly on both little-endian
-+ * and big-endian operation;
-+ * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24);
-+ */
-+struct qbman_fd {
-+ union {
-+ uint32_t words[8];
-+ struct qbman_fd_simple {
-+ uint32_t addr_lo;
-+ uint32_t addr_hi;
-+ uint32_t len;
-+ /* offset in the MS 16 bits, BPID in the LS 16 bits */
-+ uint32_t bpid_offset;
-+ uint32_t frc; /* frame context */
-+ /* "err", "va", "cbmt", "asal", [...] */
-+ uint32_t ctrl;
-+ /* flow context */
-+ uint32_t flc_lo;
-+ uint32_t flc_hi;
-+ } simple;
-+ };
-+};
-+
-+#endif /* !_FSL_QBMAN_BASE_H */
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/fsl_qbman_portal.h
-@@ -0,0 +1,753 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#ifndef _FSL_QBMAN_PORTAL_H
-+#define _FSL_QBMAN_PORTAL_H
-+
-+#include "fsl_qbman_base.h"
-+
-+/**
-+ * qbman_swp_init() - Create a functional object representing the given
-+ * QBMan portal descriptor.
-+ * @d: the given qbman swp descriptor
-+ *
-+ * Return qbman_swp portal object for success, NULL if the object cannot
-+ * be created.
-+ */
-+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
-+/**
-+ * qbman_swp_finish() - Create and destroy a functional object representing
-+ * the given QBMan portal descriptor.
-+ * @p: the qbman_swp object to be destroyed.
-+ *
-+ */
-+void qbman_swp_finish(struct qbman_swp *p);
-+
-+/**
-+ * qbman_swp_get_desc() - Get the descriptor of the given portal object.
-+ * @p: the given portal object.
-+ *
-+ * Return the descriptor for this portal.
-+ */
-+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p);
-+
-+ /**************/
-+ /* Interrupts */
-+ /**************/
-+
-+/* See the QBMan driver API documentation for details on the interrupt
-+ * mechanisms. */
-+#define QBMAN_SWP_INTERRUPT_EQRI ((uint32_t)0x00000001)
-+#define QBMAN_SWP_INTERRUPT_EQDI ((uint32_t)0x00000002)
-+#define QBMAN_SWP_INTERRUPT_DQRI ((uint32_t)0x00000004)
-+#define QBMAN_SWP_INTERRUPT_RCRI ((uint32_t)0x00000008)
-+#define QBMAN_SWP_INTERRUPT_RCDI ((uint32_t)0x00000010)
-+#define QBMAN_SWP_INTERRUPT_VDCI ((uint32_t)0x00000020)
-+
-+/**
-+ * qbman_swp_interrupt_get_vanish()
-+ * qbman_swp_interrupt_set_vanish() - Get/Set the data in software portal
-+ * interrupt status disable register.
-+ * @p: the given software portal object.
-+ * @mask: The mask to set in SWP_IDSR register.
-+ *
-+ * Return the settings in SWP_ISDR register for Get function.
-+ */
-+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p);
-+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask);
-+
-+/**
-+ * qbman_swp_interrupt_read_status()
-+ * qbman_swp_interrupt_clear_status() - Get/Set the data in software portal
-+ * interrupt status register.
-+ * @p: the given software portal object.
-+ * @mask: The mask to set in SWP_ISR register.
-+ *
-+ * Return the settings in SWP_ISR register for Get function.
-+ *
-+ */
-+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p);
-+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask);
-+
-+/**
-+ * qbman_swp_interrupt_get_trigger()
-+ * qbman_swp_interrupt_set_trigger() - Get/Set the data in software portal
-+ * interrupt enable register.
-+ * @p: the given software portal object.
-+ * @mask: The mask to set in SWP_IER register.
-+ *
-+ * Return the settings in SWP_IER register for Get function.
-+ */
-+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
-+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask);
-+
-+/**
-+ * qbman_swp_interrupt_get_inhibit()
-+ * qbman_swp_interrupt_set_inhibit() - Set/Set the data in software portal
-+ * interrupt inhibit register.
-+ * @p: the given software portal object.
-+ * @mask: The mask to set in SWP_IIR register.
-+ *
-+ * Return the settings in SWP_IIR register for Get function.
-+ */
-+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
-+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
-+
-+ /************/
-+ /* Dequeues */
-+ /************/
-+
-+/* See the QBMan driver API documentation for details on the enqueue
-+ * mechanisms. NB: the use of a 'dpaa2_' prefix for this type is because it is
-+ * primarily used by the "DPIO" layer that sits above (and hides) the QBMan
-+ * driver. The structure is defined in the DPIO interface, but to avoid circular
-+ * dependencies we just pre/re-declare it here opaquely. */
-+struct dpaa2_dq;
-+
-+/* ------------------- */
-+/* Push-mode dequeuing */
-+/* ------------------- */
-+
-+/**
-+ * qbman_swp_push_get() - Get the push dequeue setup.
-+ * @p: the software portal object.
-+ * @channel_idx: the channel index to query.
-+ * @enabled: returned boolean to show whether the push dequeue is enabled for
-+ * the given channel.
-+ */
-+void qbman_swp_push_get(struct qbman_swp *, uint8_t channel_idx, int *enabled);
-+/**
-+ * qbman_swp_push_set() - Enable or disable push dequeue.
-+ * @p: the software portal object.
-+ * @channel_idx: the channel index..
-+ * @enable: enable or disable push dequeue.
-+ *
-+ * The user of a portal can enable and disable push-mode dequeuing of up to 16
-+ * channels independently. It does not specify this toggling by channel IDs, but
-+ * rather by specifying the index (from 0 to 15) that has been mapped to the
-+ * desired channel.
-+ */
-+void qbman_swp_push_set(struct qbman_swp *, uint8_t channel_idx, int enable);
-+
-+/* ------------------- */
-+/* Pull-mode dequeuing */
-+/* ------------------- */
-+
-+/**
-+ * struct qbman_pull_desc - the structure for pull dequeue descriptor
-+ */
-+struct qbman_pull_desc {
-+ uint32_t dont_manipulate_directly[6];
-+};
-+
-+enum qbman_pull_type_e {
-+ /* dequeue with priority precedence, respect intra-class scheduling */
-+ qbman_pull_type_prio = 1,
-+ /* dequeue with active FQ precedence, respect ICS */
-+ qbman_pull_type_active,
-+ /* dequeue with active FQ precedence, no ICS */
-+ qbman_pull_type_active_noics
-+};
-+
-+/**
-+ * qbman_pull_desc_clear() - Clear the contents of a descriptor to
-+ * default/starting state.
-+ * @d: the pull dequeue descriptor to be cleared.
-+ */
-+void qbman_pull_desc_clear(struct qbman_pull_desc *d);
-+
-+/**
-+ * qbman_pull_desc_set_storage()- Set the pull dequeue storage
-+ * @d: the pull dequeue descriptor to be set.
-+ * @storage: the pointer of the memory to store the dequeue result.
-+ * @storage_phys: the physical address of the storage memory.
-+ * @stash: to indicate whether write allocate is enabled.
-+ *
-+ * If not called, or if called with 'storage' as NULL, the result pull dequeues
-+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
-+ * produced to the given memory location (using the physical/DMA address which
-+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
-+ * those writes to main-memory express a cache-warming attribute.
-+ */
-+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
-+ struct dpaa2_dq *storage,
-+ dma_addr_t storage_phys,
-+ int stash);
-+/**
-+ * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued.
-+ * @d: the pull dequeue descriptor to be set.
-+ * @numframes: number of frames to be set, must be between 1 and 16, inclusive.
-+ */
-+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *, uint8_t numframes);
-+
-+/**
-+ * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues.
-+ * @fqid: the frame queue index of the given FQ.
-+ *
-+ * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues.
-+ * @wqid: composed of channel id and wqid within the channel.
-+ * @dct: the dequeue command type.
-+ *
-+ * qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
-+ * dequeues.
-+ * @chid: the channel id to be dequeued.
-+ * @dct: the dequeue command type.
-+ *
-+ * Exactly one of the following descriptor "actions" should be set. (Calling any
-+ * one of these will replace the effect of any prior call to one of these.)
-+ * - pull dequeue from the given frame queue (FQ)
-+ * - pull dequeue from any FQ in the given work queue (WQ)
-+ * - pull dequeue from any FQ in any WQ in the given channel
-+ */
-+void qbman_pull_desc_set_fq(struct qbman_pull_desc *, uint32_t fqid);
-+void qbman_pull_desc_set_wq(struct qbman_pull_desc *, uint32_t wqid,
-+ enum qbman_pull_type_e dct);
-+void qbman_pull_desc_set_channel(struct qbman_pull_desc *, uint32_t chid,
-+ enum qbman_pull_type_e dct);
-+
-+/**
-+ * qbman_swp_pull() - Issue the pull dequeue command
-+ * @s: the software portal object.
-+ * @d: the software portal descriptor which has been configured with
-+ * the set of qbman_pull_desc_set_*() calls.
-+ *
-+ * Return 0 for success, and -EBUSY if the software portal is not ready
-+ * to do pull dequeue.
-+ */
-+int qbman_swp_pull(struct qbman_swp *, struct qbman_pull_desc *d);
-+
-+/* -------------------------------- */
-+/* Polling DQRR for dequeue results */
-+/* -------------------------------- */
-+
-+/**
-+ * qbman_swp_dqrr_next() - Get an valid DQRR entry.
-+ * @s: the software portal object.
-+ *
-+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
-+ * only once, so repeated calls can return a sequence of DQRR entries, without
-+ * requiring they be consumed immediately or in any particular order.
-+ */
-+const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s);
-+
-+/**
-+ * qbman_swp_dqrr_consume() - Consume DQRR entries previously returned from
-+ * qbman_swp_dqrr_next().
-+ * @s: the software portal object.
-+ * @dq: the DQRR entry to be consumed.
-+ */
-+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq);
-+
-+/* ------------------------------------------------- */
-+/* Polling user-provided storage for dequeue results */
-+/* ------------------------------------------------- */
-+/**
-+ * qbman_result_has_new_result() - Check and get the dequeue response from the
-+ * dq storage memory set in pull dequeue command
-+ * @s: the software portal object.
-+ * @dq: the dequeue result read from the memory.
-+ *
-+ * Only used for user-provided storage of dequeue results, not DQRR. For
-+ * efficiency purposes, the driver will perform any required endianness
-+ * conversion to ensure that the user's dequeue result storage is in host-endian
-+ * format (whether or not that is the same as the little-endian format that
-+ * hardware DMA'd to the user's storage). As such, once the user has called
-+ * qbman_result_has_new_result() and been returned a valid dequeue result,
-+ * they should not call it again on the same memory location (except of course
-+ * if another dequeue command has been executed to produce a new result to that
-+ * location).
-+ *
-+ * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
-+ * dequeue result.
-+ */
-+int qbman_result_has_new_result(struct qbman_swp *,
-+ const struct dpaa2_dq *);
-+
-+/* -------------------------------------------------------- */
-+/* Parsing dequeue entries (DQRR and user-provided storage) */
-+/* -------------------------------------------------------- */
-+
-+/**
-+ * qbman_result_is_DQ() - check the dequeue result is a dequeue response or not
-+ * @dq: the dequeue result to be checked.
-+ *
-+ * DQRR entries may contain non-dequeue results, ie. notifications
-+ */
-+int qbman_result_is_DQ(const struct dpaa2_dq *);
-+
-+/**
-+ * qbman_result_is_SCN() - Check the dequeue result is notification or not
-+ * @dq: the dequeue result to be checked.
-+ *
-+ * All the non-dequeue results (FQDAN/CDAN/CSCN/...) are "state change
-+ * notifications" of one type or another. Some APIs apply to all of them, of the
-+ * form qbman_result_SCN_***().
-+ */
-+static inline int qbman_result_is_SCN(const struct dpaa2_dq *dq)
-+{
-+ return !qbman_result_is_DQ(dq);
-+}
-+
-+/**
-+ * Recognise different notification types, only required if the user allows for
-+ * these to occur, and cares about them when they do.
-+ */
-+int qbman_result_is_FQDAN(const struct dpaa2_dq *);
-+ /* FQ Data Availability */
-+int qbman_result_is_CDAN(const struct dpaa2_dq *);
-+ /* Channel Data Availability */
-+int qbman_result_is_CSCN(const struct dpaa2_dq *);
-+ /* Congestion State Change */
-+int qbman_result_is_BPSCN(const struct dpaa2_dq *);
-+ /* Buffer Pool State Change */
-+int qbman_result_is_CGCU(const struct dpaa2_dq *);
-+ /* Congestion Group Count Update */
-+/* Frame queue state change notifications; (FQDAN in theory counts too as it
-+ * leaves a FQ parked, but it is primarily a data availability notification) */
-+int qbman_result_is_FQRN(const struct dpaa2_dq *); /* Retirement */
-+int qbman_result_is_FQRNI(const struct dpaa2_dq *);
-+ /* Retirement Immediate */
-+int qbman_result_is_FQPN(const struct dpaa2_dq *); /* Park */
-+
-+/* NB: for parsing dequeue results (when "is_DQ" is TRUE), use the higher-layer
-+ * dpaa2_dq_*() functions. */
-+
-+/* State-change notifications (FQDAN/CDAN/CSCN/...). */
-+/**
-+ * qbman_result_SCN_state() - Get the state field in State-change notification
-+ */
-+uint8_t qbman_result_SCN_state(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_SCN_rid() - Get the resource id in State-change notification
-+ */
-+uint32_t qbman_result_SCN_rid(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_SCN_ctx() - Get the context data in State-change notification
-+ */
-+uint64_t qbman_result_SCN_ctx(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_SCN_state_in_mem() - Get the state field in State-change
-+ * notification which is written to memory instead of DQRR.
-+ */
-+uint8_t qbman_result_SCN_state_in_mem(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_SCN_rid_in_mem() - Get the resource id in State-change
-+ * notification which is written to memory instead of DQRR.
-+ */
-+uint32_t qbman_result_SCN_rid_in_mem(const struct dpaa2_dq *);
-+
-+/* Type-specific "resource IDs". Mainly for illustration purposes, though it
-+ * also gives the appropriate type widths. */
-+#define qbman_result_FQDAN_fqid(dq) qbman_result_SCN_rid(dq)
-+#define qbman_result_FQRN_fqid(dq) qbman_result_SCN_rid(dq)
-+#define qbman_result_FQRNI_fqid(dq) qbman_result_SCN_rid(dq)
-+#define qbman_result_FQPN_fqid(dq) qbman_result_SCN_rid(dq)
-+#define qbman_result_CDAN_cid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
-+#define qbman_result_CSCN_cgid(dq) ((uint16_t)qbman_result_SCN_rid(dq))
-+
-+/**
-+ * qbman_result_bpscn_bpid() - Get the bpid from BPSCN
-+ *
-+ * Return the buffer pool id.
-+ */
-+uint16_t qbman_result_bpscn_bpid(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_bpscn_has_free_bufs() - Check whether there are free
-+ * buffers in the pool from BPSCN.
-+ *
-+ * Return the number of free buffers.
-+ */
-+int qbman_result_bpscn_has_free_bufs(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_bpscn_is_depleted() - Check BPSCN to see whether the
-+ * buffer pool is depleted.
-+ *
-+ * Return the status of buffer pool depletion.
-+ */
-+int qbman_result_bpscn_is_depleted(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_bpscn_is_surplus() - Check BPSCN to see whether the buffer
-+ * pool is surplus or not.
-+ *
-+ * Return the status of buffer pool surplus.
-+ */
-+int qbman_result_bpscn_is_surplus(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_bpscn_ctx() - Get the BPSCN CTX from BPSCN message
-+ *
-+ * Return the BPSCN context.
-+ */
-+uint64_t qbman_result_bpscn_ctx(const struct dpaa2_dq *);
-+
-+/* Parsing CGCU */
-+/**
-+ * qbman_result_cgcu_cgid() - Check CGCU resouce id, i.e. cgid
-+ *
-+ * Return the CGCU resource id.
-+ */
-+uint16_t qbman_result_cgcu_cgid(const struct dpaa2_dq *);
-+/**
-+ * qbman_result_cgcu_icnt() - Get the I_CNT from CGCU
-+ *
-+ * Return instantaneous count in the CGCU notification.
-+ */
-+uint64_t qbman_result_cgcu_icnt(const struct dpaa2_dq *);
-+
-+ /************/
-+ /* Enqueues */
-+ /************/
-+/**
-+ * struct qbman_eq_desc - structure of enqueue descriptor
-+ */
-+struct qbman_eq_desc {
-+ uint32_t dont_manipulate_directly[8];
-+};
-+
-+/**
-+ * struct qbman_eq_response - structure of enqueue response
-+ */
-+struct qbman_eq_response {
-+ uint32_t dont_manipulate_directly[16];
-+};
-+
-+/**
-+ * qbman_eq_desc_clear() - Clear the contents of a descriptor to
-+ * default/starting state.
-+ */
-+void qbman_eq_desc_clear(struct qbman_eq_desc *);
-+
-+/* Exactly one of the following descriptor "actions" should be set. (Calling
-+ * any one of these will replace the effect of any prior call to one of these.)
-+ * - enqueue without order-restoration
-+ * - enqueue with order-restoration
-+ * - fill a hole in the order-restoration sequence, without any enqueue
-+ * - advance NESN (Next Expected Sequence Number), without any enqueue
-+ * 'respond_success' indicates whether an enqueue response should be DMA'd
-+ * after success (otherwise a response is DMA'd only after failure).
-+ * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to
-+ * be enqueued.
-+ */
-+/**
-+ * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
-+ * @d: the enqueue descriptor.
-+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
-+ * rejections returned on a FQ.
-+ */
-+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
-+
-+/**
-+ * qbman_eq_desc_set_orp() - Set order-resotration in the enqueue descriptor
-+ * @d: the enqueue descriptor.
-+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
-+ * rejections returned on a FQ.
-+ * @opr_id: the order point record id.
-+ * @seqnum: the order restoration sequence number.
-+ * @incomplete: indiates whether this is the last fragments using the same
-+ * sequeue number.
-+ */
-+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
-+ uint32_t opr_id, uint32_t seqnum, int incomplete);
-+
-+/**
-+ * qbman_eq_desc_set_orp_hole() - fill a hole in the order-restoration sequence
-+ * without any enqueue
-+ * @d: the enqueue descriptor.
-+ * @opr_id: the order point record id.
-+ * @seqnum: the order restoration sequence number.
-+ */
-+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
-+ uint32_t seqnum);
-+
-+/**
-+ * qbman_eq_desc_set_orp_nesn() - advance NESN (Next Expected Sequence Number)
-+ * without any enqueue
-+ * @d: the enqueue descriptor.
-+ * @opr_id: the order point record id.
-+ * @seqnum: the order restoration sequence number.
-+ */
-+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
-+ uint32_t seqnum);
-+
-+/**
-+ * qbman_eq_desc_set_response() - Set the enqueue response info.
-+ * @d: the enqueue descriptor
-+ * @storage_phys: the physical address of the enqueue response in memory.
-+ * @stash: indicate that the write allocation enabled or not.
-+ *
-+ * In the case where an enqueue response is DMA'd, this determines where that
-+ * response should go. (The physical/DMA address is given for hardware's
-+ * benefit, but software should interpret it as a "struct qbman_eq_response"
-+ * data structure.) 'stash' controls whether or not the write to main-memory
-+ * expresses a cache-warming attribute.
-+ */
-+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
-+ dma_addr_t storage_phys,
-+ int stash);
-+/**
-+ * qbman_eq_desc_set_token() - Set token for the enqueue command
-+ * @d: the enqueue descriptor
-+ * @token: the token to be set.
-+ *
-+ * token is the value that shows up in an enqueue response that can be used to
-+ * detect when the results have been published. The easiest technique is to zero
-+ * result "storage" before issuing an enqueue, and use any non-zero 'token'
-+ * value.
-+ */
-+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token);
-+
-+/**
-+ * qbman_eq_desc_set_fq()
-+ * qbman_eq_desc_set_qd() - Set eithe FQ or Queuing Destination for the enqueue
-+ * command.
-+ * @d: the enqueue descriptor
-+ * @fqid: the id of the frame queue to be enqueued.
-+ * @qdid: the id of the queuing destination to be enqueued.
-+ * @qd_bin: the queuing destination bin
-+ * @qd_prio: the queuing destination priority.
-+ *
-+ * Exactly one of the following descriptor "targets" should be set. (Calling any
-+ * one of these will replace the effect of any prior call to one of these.)
-+ * - enqueue to a frame queue
-+ * - enqueue to a queuing destination
-+ * Note, that none of these will have any affect if the "action" type has been
-+ * set to "orp_hole" or "orp_nesn".
-+ */
-+void qbman_eq_desc_set_fq(struct qbman_eq_desc *, uint32_t fqid);
-+void qbman_eq_desc_set_qd(struct qbman_eq_desc *, uint32_t qdid,
-+ uint32_t qd_bin, uint32_t qd_prio);
-+
-+/**
-+ * qbman_eq_desc_set_eqdi() - enable/disable EQDI interrupt
-+ * @d: the enqueue descriptor
-+ * @enable: boolean to enable/disable EQDI
-+ *
-+ * Determines whether or not the portal's EQDI interrupt source should be
-+ * asserted after the enqueue command is completed.
-+ */
-+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *, int enable);
-+
-+/**
-+ * qbman_eq_desc_set_dca() - Set DCA mode in the enqueue command.
-+ * @d: the enqueue descriptor.
-+ * @enable: enabled/disable DCA mode.
-+ * @dqrr_idx: DCAP_CI, the DCAP consumer index.
-+ * @park: determine the whether park the FQ or not
-+ *
-+ * Determines whether or not a portal DQRR entry should be consumed once the
-+ * enqueue command is completed. (And if so, and the DQRR entry corresponds
-+ * to a held-active (order-preserving) FQ, whether the FQ should be parked
-+ * instead of being rescheduled.)
-+ */
-+void qbman_eq_desc_set_dca(struct qbman_eq_desc *, int enable,
-+ uint32_t dqrr_idx, int park);
-+
-+/**
-+ * qbman_swp_enqueue() - Issue an enqueue command.
-+ * @s: the software portal used for enqueue.
-+ * @d: the enqueue descriptor.
-+ * @fd: the frame descriptor to be enqueued.
-+ *
-+ * Please note that 'fd' should only be NULL if the "action" of the
-+ * descriptor is "orp_hole" or "orp_nesn".
-+ *
-+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
-+ */
-+int qbman_swp_enqueue(struct qbman_swp *, const struct qbman_eq_desc *,
-+ const struct qbman_fd *fd);
-+
-+/**
-+ * qbman_swp_enqueue_thresh() - Set the threshold for EQRI interrupt.
-+ *
-+ * An EQRI interrupt can be generated when the fill-level of EQCR falls below
-+ * the 'thresh' value set here. Setting thresh==0 (the default) disables.
-+ */
-+int qbman_swp_enqueue_thresh(struct qbman_swp *, unsigned int thresh);
-+
-+ /*******************/
-+ /* Buffer releases */
-+ /*******************/
-+/**
-+ * struct qbman_release_desc - The structure for buffer release descriptor
-+ */
-+struct qbman_release_desc {
-+ uint32_t dont_manipulate_directly[1];
-+};
-+
-+/**
-+ * qbman_release_desc_clear() - Clear the contents of a descriptor to
-+ * default/starting state.
-+ */
-+void qbman_release_desc_clear(struct qbman_release_desc *);
-+
-+/**
-+ * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
-+ */
-+void qbman_release_desc_set_bpid(struct qbman_release_desc *, uint32_t bpid);
-+
-+/**
-+ * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
-+ * interrupt source should be asserted after the release command is completed.
-+ */
-+void qbman_release_desc_set_rcdi(struct qbman_release_desc *, int enable);
-+
-+/**
-+ * qbman_swp_release() - Issue a buffer release command.
-+ * @s: the software portal object.
-+ * @d: the release descriptor.
-+ * @buffers: a pointer pointing to the buffer address to be released.
-+ * @num_buffers: number of buffers to be released, must be less than 8.
-+ *
-+ * Return 0 for success, -EBUSY if the release command ring is not ready.
-+ */
-+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
-+ const uint64_t *buffers, unsigned int num_buffers);
-+
-+ /*******************/
-+ /* Buffer acquires */
-+ /*******************/
-+
-+/**
-+ * qbman_swp_acquire() - Issue a buffer acquire command.
-+ * @s: the software portal object.
-+ * @bpid: the buffer pool index.
-+ * @buffers: a pointer pointing to the acquired buffer address|es.
-+ * @num_buffers: number of buffers to be acquired, must be less than 8.
-+ *
-+ * Return 0 for success, or negative error code if the acquire command
-+ * fails.
-+ */
-+int qbman_swp_acquire(struct qbman_swp *, uint32_t bpid, uint64_t *buffers,
-+ unsigned int num_buffers);
-+
-+ /*****************/
-+ /* FQ management */
-+ /*****************/
-+
-+/**
-+ * qbman_swp_fq_schedule() - Move the fq to the scheduled state.
-+ * @s: the software portal object.
-+ * @fqid: the index of frame queue to be scheduled.
-+ *
-+ * There are a couple of different ways that a FQ can end up parked state,
-+ * This schedules it.
-+ *
-+ * Return 0 for success, or negative error code for failure.
-+ */
-+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid);
-+
-+/**
-+ * qbman_swp_fq_force() - Force the FQ to fully scheduled state.
-+ * @s: the software portal object.
-+ * @fqid: the index of frame queue to be forced.
-+ *
-+ * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
-+ * and thus be available for selection by any channel-dequeuing behaviour (push
-+ * or pull). If the FQ is subsequently "dequeued" from the channel and is still
-+ * empty at the time this happens, the resulting dq_entry will have no FD.
-+ * (qbman_result_DQ_fd() will return NULL.)
-+ *
-+ * Return 0 for success, or negative error code for failure.
-+ */
-+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid);
-+
-+/**
-+ * qbman_swp_fq_xon()
-+ * qbman_swp_fq_xoff() - XON/XOFF the frame queue.
-+ * @s: the software portal object.
-+ * @fqid: the index of frame queue.
-+ *
-+ * These functions change the FQ flow-control stuff between XON/XOFF. (The
-+ * default is XON.) This setting doesn't affect enqueues to the FQ, just
-+ * dequeues. XOFF FQs will remain in the tenatively-scheduled state, even when
-+ * non-empty, meaning they won't be selected for scheduled dequeuing. If a FQ is
-+ * changed to XOFF after it had already become truly-scheduled to a channel, and
-+ * a pull dequeue of that channel occurs that selects that FQ for dequeuing,
-+ * then the resulting dq_entry will have no FD. (qbman_result_DQ_fd() will
-+ * return NULL.)
-+ *
-+ * Return 0 for success, or negative error code for failure.
-+ */
-+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid);
-+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid);
-+
-+ /**********************/
-+ /* Channel management */
-+ /**********************/
-+
-+/* If the user has been allocated a channel object that is going to generate
-+ * CDANs to another channel, then these functions will be necessary.
-+ * CDAN-enabled channels only generate a single CDAN notification, after which
-+ * it they need to be reenabled before they'll generate another. (The idea is
-+ * that pull dequeuing will occur in reaction to the CDAN, followed by a
-+ * reenable step.) Each function generates a distinct command to hardware, so a
-+ * combination function is provided if the user wishes to modify the "context"
-+ * (which shows up in each CDAN message) each time they reenable, as a single
-+ * command to hardware. */
-+/**
-+ * qbman_swp_CDAN_set_context() - Set CDAN context
-+ * @s: the software portal object.
-+ * @channelid: the channel index.
-+ * @ctx: the context to be set in CDAN.
-+ *
-+ * Return 0 for success, or negative error code for failure.
-+ */
-+int qbman_swp_CDAN_set_context(struct qbman_swp *, uint16_t channelid,
-+ uint64_t ctx);
-+
-+/**
-+ * qbman_swp_CDAN_enable() - Enable CDAN for the channel.
-+ * @s: the software portal object.
-+ * @channelid: the index of the channel to generate CDAN.
-+ *
-+ * Return 0 for success, or negative error code for failure.
-+ */
-+int qbman_swp_CDAN_enable(struct qbman_swp *, uint16_t channelid);
-+
-+/**
-+ * qbman_swp_CDAN_disable() - disable CDAN for the channel.
-+ * @s: the software portal object.
-+ * @channelid: the index of the channel to generate CDAN.
-+ *
-+ * Return 0 for success, or negative error code for failure.
-+ */
-+int qbman_swp_CDAN_disable(struct qbman_swp *, uint16_t channelid);
-+
-+/**
-+ * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
-+ * @s: the software portal object.
-+ * @channelid: the index of the channel to generate CDAN.
-+ * @ctx: the context set in CDAN.
-+ *
-+ * Return 0 for success, or negative error code for failure.
-+ */
-+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *, uint16_t channelid,
-+ uint64_t ctx);
-+
-+#endif /* !_FSL_QBMAN_PORTAL_H */
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_debug.c
-@@ -0,0 +1,846 @@
-+/* Copyright (C) 2015 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "qbman_portal.h"
-+#include "qbman_debug.h"
-+#include "fsl_qbman_portal.h"
-+
-+/* QBMan portal management command code */
-+#define QBMAN_BP_QUERY 0x32
-+#define QBMAN_FQ_QUERY 0x44
-+#define QBMAN_FQ_QUERY_NP 0x45
-+#define QBMAN_CGR_QUERY 0x51
-+#define QBMAN_WRED_QUERY 0x54
-+#define QBMAN_CGR_STAT_QUERY 0x55
-+#define QBMAN_CGR_STAT_QUERY_CLR 0x56
-+
-+enum qbman_attr_usage_e {
-+ qbman_attr_usage_fq,
-+ qbman_attr_usage_bpool,
-+ qbman_attr_usage_cgr,
-+};
-+
-+struct int_qbman_attr {
-+ uint32_t words[32];
-+ enum qbman_attr_usage_e usage;
-+};
-+
-+#define attr_type_set(a, e) \
-+{ \
-+ struct qbman_attr *__attr = a; \
-+ enum qbman_attr_usage_e __usage = e; \
-+ ((struct int_qbman_attr *)__attr)->usage = __usage; \
-+}
-+
-+#define ATTR32(d) (&(d)->dont_manipulate_directly[0])
-+#define ATTR32_1(d) (&(d)->dont_manipulate_directly[16])
-+
-+static struct qb_attr_code code_bp_bpid = QB_CODE(0, 16, 16);
-+static struct qb_attr_code code_bp_bdi = QB_CODE(1, 16, 1);
-+static struct qb_attr_code code_bp_va = QB_CODE(1, 17, 1);
-+static struct qb_attr_code code_bp_wae = QB_CODE(1, 18, 1);
-+static struct qb_attr_code code_bp_swdet = QB_CODE(4, 0, 16);
-+static struct qb_attr_code code_bp_swdxt = QB_CODE(4, 16, 16);
-+static struct qb_attr_code code_bp_hwdet = QB_CODE(5, 0, 16);
-+static struct qb_attr_code code_bp_hwdxt = QB_CODE(5, 16, 16);
-+static struct qb_attr_code code_bp_swset = QB_CODE(6, 0, 16);
-+static struct qb_attr_code code_bp_swsxt = QB_CODE(6, 16, 16);
-+static struct qb_attr_code code_bp_vbpid = QB_CODE(7, 0, 14);
-+static struct qb_attr_code code_bp_icid = QB_CODE(7, 16, 15);
-+static struct qb_attr_code code_bp_pl = QB_CODE(7, 31, 1);
-+static struct qb_attr_code code_bp_bpscn_addr_lo = QB_CODE(8, 0, 32);
-+static struct qb_attr_code code_bp_bpscn_addr_hi = QB_CODE(9, 0, 32);
-+static struct qb_attr_code code_bp_bpscn_ctx_lo = QB_CODE(10, 0, 32);
-+static struct qb_attr_code code_bp_bpscn_ctx_hi = QB_CODE(11, 0, 32);
-+static struct qb_attr_code code_bp_hw_targ = QB_CODE(12, 0, 16);
-+static struct qb_attr_code code_bp_state = QB_CODE(1, 24, 3);
-+static struct qb_attr_code code_bp_fill = QB_CODE(2, 0, 32);
-+static struct qb_attr_code code_bp_hdptr = QB_CODE(3, 0, 32);
-+static struct qb_attr_code code_bp_sdcnt = QB_CODE(13, 0, 8);
-+static struct qb_attr_code code_bp_hdcnt = QB_CODE(13, 1, 8);
-+static struct qb_attr_code code_bp_sscnt = QB_CODE(13, 2, 8);
-+
-+void qbman_bp_attr_clear(struct qbman_attr *a)
-+{
-+ memset(a, 0, sizeof(*a));
-+ attr_type_set(a, qbman_attr_usage_bpool);
-+}
-+
-+int qbman_bp_query(struct qbman_swp *s, uint32_t bpid,
-+ struct qbman_attr *a)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt;
-+ uint32_t *attr = ATTR32(a);
-+
-+ qbman_bp_attr_clear(a);
-+
-+ /* Start the management command */
-+ p = qbman_swp_mc_start(s);
-+ if (!p)
-+ return -EBUSY;
-+
-+ /* Encode the caller-provided attributes */
-+ qb_attr_code_encode(&code_bp_bpid, p, bpid);
-+
-+ /* Complete the management command */
-+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_BP_QUERY);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ BUG_ON(verb != QBMAN_BP_QUERY);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("Query of BPID 0x%x failed, code=0x%02x\n", bpid, rslt);
-+ return -EIO;
-+ }
-+
-+ /* For the query, word[0] of the result contains only the
-+ * verb/rslt fields, so skip word[0].
-+ */
-+ word_copy(&attr[1], &p[1], 15);
-+ return 0;
-+}
-+
-+void qbman_bp_attr_get_bdi(struct qbman_attr *a, int *bdi, int *va, int *wae)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *bdi = !!qb_attr_code_decode(&code_bp_bdi, p);
-+ *va = !!qb_attr_code_decode(&code_bp_va, p);
-+ *wae = !!qb_attr_code_decode(&code_bp_wae, p);
-+}
-+
-+static uint32_t qbman_bp_thresh_to_value(uint32_t val)
-+{
-+ return (val & 0xff) << ((val & 0xf00) >> 8);
-+}
-+
-+void qbman_bp_attr_get_swdet(struct qbman_attr *a, uint32_t *swdet)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *swdet = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swdet,
-+ p));
-+}
-+void qbman_bp_attr_get_swdxt(struct qbman_attr *a, uint32_t *swdxt)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *swdxt = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swdxt,
-+ p));
-+}
-+void qbman_bp_attr_get_hwdet(struct qbman_attr *a, uint32_t *hwdet)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *hwdet = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_hwdet,
-+ p));
-+}
-+void qbman_bp_attr_get_hwdxt(struct qbman_attr *a, uint32_t *hwdxt)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *hwdxt = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_hwdxt,
-+ p));
-+}
-+
-+void qbman_bp_attr_get_swset(struct qbman_attr *a, uint32_t *swset)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *swset = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swset,
-+ p));
-+}
-+
-+void qbman_bp_attr_get_swsxt(struct qbman_attr *a, uint32_t *swsxt)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *swsxt = qbman_bp_thresh_to_value(qb_attr_code_decode(&code_bp_swsxt,
-+ p));
-+}
-+
-+void qbman_bp_attr_get_vbpid(struct qbman_attr *a, uint32_t *vbpid)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *vbpid = qb_attr_code_decode(&code_bp_vbpid, p);
-+}
-+
-+void qbman_bp_attr_get_icid(struct qbman_attr *a, uint32_t *icid, int *pl)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *icid = qb_attr_code_decode(&code_bp_icid, p);
-+ *pl = !!qb_attr_code_decode(&code_bp_pl, p);
-+}
-+
-+void qbman_bp_attr_get_bpscn_addr(struct qbman_attr *a, uint64_t *bpscn_addr)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *bpscn_addr = ((uint64_t)qb_attr_code_decode(&code_bp_bpscn_addr_hi,
-+ p) << 32) |
-+ (uint64_t)qb_attr_code_decode(&code_bp_bpscn_addr_lo,
-+ p);
-+}
-+
-+void qbman_bp_attr_get_bpscn_ctx(struct qbman_attr *a, uint64_t *bpscn_ctx)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *bpscn_ctx = ((uint64_t)qb_attr_code_decode(&code_bp_bpscn_ctx_hi, p)
-+ << 32) |
-+ (uint64_t)qb_attr_code_decode(&code_bp_bpscn_ctx_lo,
-+ p);
-+}
-+
-+void qbman_bp_attr_get_hw_targ(struct qbman_attr *a, uint32_t *hw_targ)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ *hw_targ = qb_attr_code_decode(&code_bp_hw_targ, p);
-+}
-+
-+int qbman_bp_info_has_free_bufs(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return !(int)(qb_attr_code_decode(&code_bp_state, p) & 0x1);
-+}
-+
-+int qbman_bp_info_is_depleted(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return (int)(qb_attr_code_decode(&code_bp_state, p) & 0x2);
-+}
-+
-+int qbman_bp_info_is_surplus(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return (int)(qb_attr_code_decode(&code_bp_state, p) & 0x4);
-+}
-+
-+uint32_t qbman_bp_info_num_free_bufs(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return qb_attr_code_decode(&code_bp_fill, p);
-+}
-+
-+uint32_t qbman_bp_info_hdptr(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return qb_attr_code_decode(&code_bp_hdptr, p);
-+}
-+
-+uint32_t qbman_bp_info_sdcnt(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return qb_attr_code_decode(&code_bp_sdcnt, p);
-+}
-+
-+uint32_t qbman_bp_info_hdcnt(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return qb_attr_code_decode(&code_bp_hdcnt, p);
-+}
-+
-+uint32_t qbman_bp_info_sscnt(struct qbman_attr *a)
-+{
-+ uint32_t *p = ATTR32(a);
-+
-+ return qb_attr_code_decode(&code_bp_sscnt, p);
-+}
-+
-+static struct qb_attr_code code_fq_fqid = QB_CODE(1, 0, 24);
-+static struct qb_attr_code code_fq_cgrid = QB_CODE(2, 16, 16);
-+static struct qb_attr_code code_fq_destwq = QB_CODE(3, 0, 15);
-+static struct qb_attr_code code_fq_fqctrl = QB_CODE(3, 24, 8);
-+static struct qb_attr_code code_fq_icscred = QB_CODE(4, 0, 15);
-+static struct qb_attr_code code_fq_tdthresh = QB_CODE(4, 16, 13);
-+static struct qb_attr_code code_fq_oa_len = QB_CODE(5, 0, 12);
-+static struct qb_attr_code code_fq_oa_ics = QB_CODE(5, 14, 1);
-+static struct qb_attr_code code_fq_oa_cgr = QB_CODE(5, 15, 1);
-+static struct qb_attr_code code_fq_mctl_bdi = QB_CODE(5, 24, 1);
-+static struct qb_attr_code code_fq_mctl_ff = QB_CODE(5, 25, 1);
-+static struct qb_attr_code code_fq_mctl_va = QB_CODE(5, 26, 1);
-+static struct qb_attr_code code_fq_mctl_ps = QB_CODE(5, 27, 1);
-+static struct qb_attr_code code_fq_ctx_lower32 = QB_CODE(6, 0, 32);
-+static struct qb_attr_code code_fq_ctx_upper32 = QB_CODE(7, 0, 32);
-+static struct qb_attr_code code_fq_icid = QB_CODE(8, 0, 15);
-+static struct qb_attr_code code_fq_pl = QB_CODE(8, 15, 1);
-+static struct qb_attr_code code_fq_vfqid = QB_CODE(9, 0, 24);
-+static struct qb_attr_code code_fq_erfqid = QB_CODE(10, 0, 24);
-+
-+void qbman_fq_attr_clear(struct qbman_attr *a)
-+{
-+ memset(a, 0, sizeof(*a));
-+ attr_type_set(a, qbman_attr_usage_fq);
-+}
-+
-+/* FQ query function for programmable fields */
-+int qbman_fq_query(struct qbman_swp *s, uint32_t fqid, struct qbman_attr *desc)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt;
-+ uint32_t *d = ATTR32(desc);
-+
-+ qbman_fq_attr_clear(desc);
-+
-+ p = qbman_swp_mc_start(s);
-+ if (!p)
-+ return -EBUSY;
-+ qb_attr_code_encode(&code_fq_fqid, p, fqid);
-+ p = qbman_swp_mc_complete(s, p, QBMAN_FQ_QUERY);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ BUG_ON(verb != QBMAN_FQ_QUERY);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("Query of FQID 0x%x failed, code=0x%02x\n",
-+ fqid, rslt);
-+ return -EIO;
-+ }
-+ /* For the configure, word[0] of the command contains only the WE-mask.
-+ * For the query, word[0] of the result contains only the verb/rslt
-+ * fields. Skip word[0] in the latter case. */
-+ word_copy(&d[1], &p[1], 15);
-+ return 0;
-+}
-+
-+void qbman_fq_attr_get_fqctrl(struct qbman_attr *d, uint32_t *fqctrl)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *fqctrl = qb_attr_code_decode(&code_fq_fqctrl, p);
-+}
-+
-+void qbman_fq_attr_get_cgrid(struct qbman_attr *d, uint32_t *cgrid)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *cgrid = qb_attr_code_decode(&code_fq_cgrid, p);
-+}
-+
-+void qbman_fq_attr_get_destwq(struct qbman_attr *d, uint32_t *destwq)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *destwq = qb_attr_code_decode(&code_fq_destwq, p);
-+}
-+
-+void qbman_fq_attr_get_icscred(struct qbman_attr *d, uint32_t *icscred)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *icscred = qb_attr_code_decode(&code_fq_icscred, p);
-+}
-+
-+static struct qb_attr_code code_tdthresh_exp = QB_CODE(0, 0, 5);
-+static struct qb_attr_code code_tdthresh_mant = QB_CODE(0, 5, 8);
-+static uint32_t qbman_thresh_to_value(uint32_t val)
-+{
-+ uint32_t m, e;
-+
-+ m = qb_attr_code_decode(&code_tdthresh_mant, &val);
-+ e = qb_attr_code_decode(&code_tdthresh_exp, &val);
-+ return m << e;
-+}
-+
-+void qbman_fq_attr_get_tdthresh(struct qbman_attr *d, uint32_t *tdthresh)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *tdthresh = qbman_thresh_to_value(qb_attr_code_decode(&code_fq_tdthresh,
-+ p));
-+}
-+
-+void qbman_fq_attr_get_oa(struct qbman_attr *d,
-+ int *oa_ics, int *oa_cgr, int32_t *oa_len)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *oa_ics = !!qb_attr_code_decode(&code_fq_oa_ics, p);
-+ *oa_cgr = !!qb_attr_code_decode(&code_fq_oa_cgr, p);
-+ *oa_len = qb_attr_code_makesigned(&code_fq_oa_len,
-+ qb_attr_code_decode(&code_fq_oa_len, p));
-+}
-+
-+void qbman_fq_attr_get_mctl(struct qbman_attr *d,
-+ int *bdi, int *ff, int *va, int *ps)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *bdi = !!qb_attr_code_decode(&code_fq_mctl_bdi, p);
-+ *ff = !!qb_attr_code_decode(&code_fq_mctl_ff, p);
-+ *va = !!qb_attr_code_decode(&code_fq_mctl_va, p);
-+ *ps = !!qb_attr_code_decode(&code_fq_mctl_ps, p);
-+}
-+
-+void qbman_fq_attr_get_ctx(struct qbman_attr *d, uint32_t *hi, uint32_t *lo)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *hi = qb_attr_code_decode(&code_fq_ctx_upper32, p);
-+ *lo = qb_attr_code_decode(&code_fq_ctx_lower32, p);
-+}
-+
-+void qbman_fq_attr_get_icid(struct qbman_attr *d, uint32_t *icid, int *pl)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *icid = qb_attr_code_decode(&code_fq_icid, p);
-+ *pl = !!qb_attr_code_decode(&code_fq_pl, p);
-+}
-+
-+void qbman_fq_attr_get_vfqid(struct qbman_attr *d, uint32_t *vfqid)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *vfqid = qb_attr_code_decode(&code_fq_vfqid, p);
-+}
-+
-+void qbman_fq_attr_get_erfqid(struct qbman_attr *d, uint32_t *erfqid)
-+{
-+ uint32_t *p = ATTR32(d);
-+
-+ *erfqid = qb_attr_code_decode(&code_fq_erfqid, p);
-+}
-+
-+/* Query FQ Non-Programmalbe Fields */
-+static struct qb_attr_code code_fq_np_state = QB_CODE(0, 16, 3);
-+static struct qb_attr_code code_fq_np_fe = QB_CODE(0, 19, 1);
-+static struct qb_attr_code code_fq_np_x = QB_CODE(0, 20, 1);
-+static struct qb_attr_code code_fq_np_r = QB_CODE(0, 21, 1);
-+static struct qb_attr_code code_fq_np_oe = QB_CODE(0, 22, 1);
-+static struct qb_attr_code code_fq_np_frm_cnt = QB_CODE(6, 0, 24);
-+static struct qb_attr_code code_fq_np_byte_cnt = QB_CODE(7, 0, 32);
-+
-+int qbman_fq_query_state(struct qbman_swp *s, uint32_t fqid,
-+ struct qbman_attr *state)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt;
-+ uint32_t *d = ATTR32(state);
-+
-+ qbman_fq_attr_clear(state);
-+
-+ p = qbman_swp_mc_start(s);
-+ if (!p)
-+ return -EBUSY;
-+ qb_attr_code_encode(&code_fq_fqid, p, fqid);
-+ p = qbman_swp_mc_complete(s, p, QBMAN_FQ_QUERY_NP);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ BUG_ON(verb != QBMAN_FQ_QUERY_NP);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("Query NP fields of FQID 0x%x failed, code=0x%02x\n",
-+ fqid, rslt);
-+ return -EIO;
-+ }
-+ word_copy(&d[0], &p[0], 16);
-+ return 0;
-+}
-+
-+uint32_t qbman_fq_state_schedstate(const struct qbman_attr *state)
-+{
-+ const uint32_t *p = ATTR32(state);
-+
-+ return qb_attr_code_decode(&code_fq_np_state, p);
-+}
-+
-+int qbman_fq_state_force_eligible(const struct qbman_attr *state)
-+{
-+ const uint32_t *p = ATTR32(state);
-+
-+ return !!qb_attr_code_decode(&code_fq_np_fe, p);
-+}
-+
-+int qbman_fq_state_xoff(const struct qbman_attr *state)
-+{
-+ const uint32_t *p = ATTR32(state);
-+
-+ return !!qb_attr_code_decode(&code_fq_np_x, p);
-+}
-+
-+int qbman_fq_state_retirement_pending(const struct qbman_attr *state)
-+{
-+ const uint32_t *p = ATTR32(state);
-+
-+ return !!qb_attr_code_decode(&code_fq_np_r, p);
-+}
-+
-+int qbman_fq_state_overflow_error(const struct qbman_attr *state)
-+{
-+ const uint32_t *p = ATTR32(state);
-+
-+ return !!qb_attr_code_decode(&code_fq_np_oe, p);
-+}
-+
-+uint32_t qbman_fq_state_frame_count(const struct qbman_attr *state)
-+{
-+ const uint32_t *p = ATTR32(state);
-+
-+ return qb_attr_code_decode(&code_fq_np_frm_cnt, p);
-+}
-+
-+uint32_t qbman_fq_state_byte_count(const struct qbman_attr *state)
-+{
-+ const uint32_t *p = ATTR32(state);
-+
-+ return qb_attr_code_decode(&code_fq_np_byte_cnt, p);
-+}
-+
-+/* Query CGR */
-+static struct qb_attr_code code_cgr_cgid = QB_CODE(0, 16, 16);
-+static struct qb_attr_code code_cgr_cscn_wq_en_enter = QB_CODE(2, 0, 1);
-+static struct qb_attr_code code_cgr_cscn_wq_en_exit = QB_CODE(2, 1, 1);
-+static struct qb_attr_code code_cgr_cscn_wq_icd = QB_CODE(2, 2, 1);
-+static struct qb_attr_code code_cgr_mode = QB_CODE(3, 16, 2);
-+static struct qb_attr_code code_cgr_rej_cnt_mode = QB_CODE(3, 18, 1);
-+static struct qb_attr_code code_cgr_cscn_bdi = QB_CODE(3, 19, 1);
-+static struct qb_attr_code code_cgr_cscn_wr_en_enter = QB_CODE(3, 24, 1);
-+static struct qb_attr_code code_cgr_cscn_wr_en_exit = QB_CODE(3, 25, 1);
-+static struct qb_attr_code code_cgr_cg_wr_ae = QB_CODE(3, 26, 1);
-+static struct qb_attr_code code_cgr_cscn_dcp_en = QB_CODE(3, 27, 1);
-+static struct qb_attr_code code_cgr_cg_wr_va = QB_CODE(3, 28, 1);
-+static struct qb_attr_code code_cgr_i_cnt_wr_en = QB_CODE(4, 0, 1);
-+static struct qb_attr_code code_cgr_i_cnt_wr_bnd = QB_CODE(4, 1, 5);
-+static struct qb_attr_code code_cgr_td_en = QB_CODE(4, 8, 1);
-+static struct qb_attr_code code_cgr_cs_thres = QB_CODE(4, 16, 13);
-+static struct qb_attr_code code_cgr_cs_thres_x = QB_CODE(5, 0, 13);
-+static struct qb_attr_code code_cgr_td_thres = QB_CODE(5, 16, 13);
-+static struct qb_attr_code code_cgr_cscn_tdcp = QB_CODE(6, 0, 16);
-+static struct qb_attr_code code_cgr_cscn_wqid = QB_CODE(6, 16, 16);
-+static struct qb_attr_code code_cgr_cscn_vcgid = QB_CODE(7, 0, 16);
-+static struct qb_attr_code code_cgr_cg_icid = QB_CODE(7, 16, 15);
-+static struct qb_attr_code code_cgr_cg_pl = QB_CODE(7, 31, 1);
-+static struct qb_attr_code code_cgr_cg_wr_addr_lo = QB_CODE(8, 0, 32);
-+static struct qb_attr_code code_cgr_cg_wr_addr_hi = QB_CODE(9, 0, 32);
-+static struct qb_attr_code code_cgr_cscn_ctx_lo = QB_CODE(10, 0, 32);
-+static struct qb_attr_code code_cgr_cscn_ctx_hi = QB_CODE(11, 0, 32);
-+
-+void qbman_cgr_attr_clear(struct qbman_attr *a)
-+{
-+ memset(a, 0, sizeof(*a));
-+ attr_type_set(a, qbman_attr_usage_cgr);
-+}
-+
-+int qbman_cgr_query(struct qbman_swp *s, uint32_t cgid, struct qbman_attr *attr)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt;
-+ uint32_t *d[2];
-+ int i;
-+ uint32_t query_verb;
-+
-+ d[0] = ATTR32(attr);
-+ d[1] = ATTR32_1(attr);
-+
-+ qbman_cgr_attr_clear(attr);
-+
-+ for (i = 0; i < 2; i++) {
-+ p = qbman_swp_mc_start(s);
-+ if (!p)
-+ return -EBUSY;
-+ query_verb = i ? QBMAN_WRED_QUERY : QBMAN_CGR_QUERY;
-+
-+ qb_attr_code_encode(&code_cgr_cgid, p, cgid);
-+ p = qbman_swp_mc_complete(s, p, p[0] | query_verb);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ BUG_ON(verb != query_verb);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("Query CGID 0x%x failed,", cgid);
-+ pr_err(" verb=0x%02x, code=0x%02x\n", verb, rslt);
-+ return -EIO;
-+ }
-+ /* For the configure, word[0] of the command contains only the
-+ * verb/cgid. For the query, word[0] of the result contains
-+ * only the verb/rslt fields. Skip word[0] in the latter case.
-+ */
-+ word_copy(&d[i][1], &p[1], 15);
-+ }
-+ return 0;
-+}
-+
-+void qbman_cgr_attr_get_ctl1(struct qbman_attr *d, int *cscn_wq_en_enter,
-+ int *cscn_wq_en_exit, int *cscn_wq_icd)
-+ {
-+ uint32_t *p = ATTR32(d);
-+ *cscn_wq_en_enter = !!qb_attr_code_decode(&code_cgr_cscn_wq_en_enter,
-+ p);
-+ *cscn_wq_en_exit = !!qb_attr_code_decode(&code_cgr_cscn_wq_en_exit, p);
-+ *cscn_wq_icd = !!qb_attr_code_decode(&code_cgr_cscn_wq_icd, p);
-+}
-+
-+void qbman_cgr_attr_get_mode(struct qbman_attr *d, uint32_t *mode,
-+ int *rej_cnt_mode, int *cscn_bdi)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *mode = qb_attr_code_decode(&code_cgr_mode, p);
-+ *rej_cnt_mode = !!qb_attr_code_decode(&code_cgr_rej_cnt_mode, p);
-+ *cscn_bdi = !!qb_attr_code_decode(&code_cgr_cscn_bdi, p);
-+}
-+
-+void qbman_cgr_attr_get_ctl2(struct qbman_attr *d, int *cscn_wr_en_enter,
-+ int *cscn_wr_en_exit, int *cg_wr_ae,
-+ int *cscn_dcp_en, int *cg_wr_va)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cscn_wr_en_enter = !!qb_attr_code_decode(&code_cgr_cscn_wr_en_enter,
-+ p);
-+ *cscn_wr_en_exit = !!qb_attr_code_decode(&code_cgr_cscn_wr_en_exit, p);
-+ *cg_wr_ae = !!qb_attr_code_decode(&code_cgr_cg_wr_ae, p);
-+ *cscn_dcp_en = !!qb_attr_code_decode(&code_cgr_cscn_dcp_en, p);
-+ *cg_wr_va = !!qb_attr_code_decode(&code_cgr_cg_wr_va, p);
-+}
-+
-+void qbman_cgr_attr_get_iwc(struct qbman_attr *d, int *i_cnt_wr_en,
-+ uint32_t *i_cnt_wr_bnd)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *i_cnt_wr_en = !!qb_attr_code_decode(&code_cgr_i_cnt_wr_en, p);
-+ *i_cnt_wr_bnd = qb_attr_code_decode(&code_cgr_i_cnt_wr_bnd, p);
-+}
-+
-+void qbman_cgr_attr_get_tdc(struct qbman_attr *d, int *td_en)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *td_en = !!qb_attr_code_decode(&code_cgr_td_en, p);
-+}
-+
-+void qbman_cgr_attr_get_cs_thres(struct qbman_attr *d, uint32_t *cs_thres)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cs_thres = qbman_thresh_to_value(qb_attr_code_decode(
-+ &code_cgr_cs_thres, p));
-+}
-+
-+void qbman_cgr_attr_get_cs_thres_x(struct qbman_attr *d,
-+ uint32_t *cs_thres_x)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cs_thres_x = qbman_thresh_to_value(qb_attr_code_decode(
-+ &code_cgr_cs_thres_x, p));
-+}
-+
-+void qbman_cgr_attr_get_td_thres(struct qbman_attr *d, uint32_t *td_thres)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *td_thres = qbman_thresh_to_value(qb_attr_code_decode(
-+ &code_cgr_td_thres, p));
-+}
-+
-+void qbman_cgr_attr_get_cscn_tdcp(struct qbman_attr *d, uint32_t *cscn_tdcp)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cscn_tdcp = qb_attr_code_decode(&code_cgr_cscn_tdcp, p);
-+}
-+
-+void qbman_cgr_attr_get_cscn_wqid(struct qbman_attr *d, uint32_t *cscn_wqid)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cscn_wqid = qb_attr_code_decode(&code_cgr_cscn_wqid, p);
-+}
-+
-+void qbman_cgr_attr_get_cscn_vcgid(struct qbman_attr *d,
-+ uint32_t *cscn_vcgid)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cscn_vcgid = qb_attr_code_decode(&code_cgr_cscn_vcgid, p);
-+}
-+
-+void qbman_cgr_attr_get_cg_icid(struct qbman_attr *d, uint32_t *icid,
-+ int *pl)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *icid = qb_attr_code_decode(&code_cgr_cg_icid, p);
-+ *pl = !!qb_attr_code_decode(&code_cgr_cg_pl, p);
-+}
-+
-+void qbman_cgr_attr_get_cg_wr_addr(struct qbman_attr *d,
-+ uint64_t *cg_wr_addr)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cg_wr_addr = ((uint64_t)qb_attr_code_decode(&code_cgr_cg_wr_addr_hi,
-+ p) << 32) |
-+ (uint64_t)qb_attr_code_decode(&code_cgr_cg_wr_addr_lo,
-+ p);
-+}
-+
-+void qbman_cgr_attr_get_cscn_ctx(struct qbman_attr *d, uint64_t *cscn_ctx)
-+{
-+ uint32_t *p = ATTR32(d);
-+ *cscn_ctx = ((uint64_t)qb_attr_code_decode(&code_cgr_cscn_ctx_hi, p)
-+ << 32) |
-+ (uint64_t)qb_attr_code_decode(&code_cgr_cscn_ctx_lo, p);
-+}
-+
-+#define WRED_EDP_WORD(n) (18 + n/4)
-+#define WRED_EDP_OFFSET(n) (8 * (n % 4))
-+#define WRED_PARM_DP_WORD(n) (n + 20)
-+#define WRED_WE_EDP(n) (16 + n * 2)
-+#define WRED_WE_PARM_DP(n) (17 + n * 2)
-+void qbman_cgr_attr_wred_get_edp(struct qbman_attr *d, uint32_t idx,
-+ int *edp)
-+{
-+ uint32_t *p = ATTR32(d);
-+ struct qb_attr_code code_wred_edp = QB_CODE(WRED_EDP_WORD(idx),
-+ WRED_EDP_OFFSET(idx), 8);
-+ *edp = (int)qb_attr_code_decode(&code_wred_edp, p);
-+}
-+
-+void qbman_cgr_attr_wred_dp_decompose(uint32_t dp, uint64_t *minth,
-+ uint64_t *maxth, uint8_t *maxp)
-+{
-+ uint8_t ma, mn, step_i, step_s, pn;
-+
-+ ma = (uint8_t)(dp >> 24);
-+ mn = (uint8_t)(dp >> 19) & 0x1f;
-+ step_i = (uint8_t)(dp >> 11);
-+ step_s = (uint8_t)(dp >> 6) & 0x1f;
-+ pn = (uint8_t)dp & 0x3f;
-+
-+ *maxp = ((pn<<2) * 100)/256;
-+
-+ if (mn == 0)
-+ *maxth = ma;
-+ else
-+ *maxth = ((ma+256) * (1<<(mn-1)));
-+
-+ if (step_s == 0)
-+ *minth = *maxth - step_i;
-+ else
-+ *minth = *maxth - (256 + step_i) * (1<<(step_s - 1));
-+}
-+
-+void qbman_cgr_attr_wred_get_parm_dp(struct qbman_attr *d, uint32_t idx,
-+ uint32_t *dp)
-+{
-+ uint32_t *p = ATTR32(d);
-+ struct qb_attr_code code_wred_parm_dp = QB_CODE(WRED_PARM_DP_WORD(idx),
-+ 0, 8);
-+ *dp = qb_attr_code_decode(&code_wred_parm_dp, p);
-+}
-+
-+/* Query CGR/CCGR/CQ statistics */
-+static struct qb_attr_code code_cgr_stat_ct = QB_CODE(4, 0, 32);
-+static struct qb_attr_code code_cgr_stat_frame_cnt_lo = QB_CODE(4, 0, 32);
-+static struct qb_attr_code code_cgr_stat_frame_cnt_hi = QB_CODE(5, 0, 8);
-+static struct qb_attr_code code_cgr_stat_byte_cnt_lo = QB_CODE(6, 0, 32);
-+static struct qb_attr_code code_cgr_stat_byte_cnt_hi = QB_CODE(7, 0, 16);
-+static int qbman_cgr_statistics_query(struct qbman_swp *s, uint32_t cgid,
-+ int clear, uint32_t command_type,
-+ uint64_t *frame_cnt, uint64_t *byte_cnt)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt;
-+ uint32_t query_verb;
-+ uint32_t hi, lo;
-+
-+ p = qbman_swp_mc_start(s);
-+ if (!p)
-+ return -EBUSY;
-+
-+ qb_attr_code_encode(&code_cgr_cgid, p, cgid);
-+ if (command_type < 2)
-+ qb_attr_code_encode(&code_cgr_stat_ct, p, command_type);
-+ query_verb = clear ?
-+ QBMAN_CGR_STAT_QUERY_CLR : QBMAN_CGR_STAT_QUERY;
-+ p = qbman_swp_mc_complete(s, p, p[0] | query_verb);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ BUG_ON(verb != query_verb);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("Query statistics of CGID 0x%x failed,", cgid);
-+ pr_err(" verb=0x%02x code=0x%02x\n", verb, rslt);
-+ return -EIO;
-+ }
-+
-+ if (*frame_cnt) {
-+ hi = qb_attr_code_decode(&code_cgr_stat_frame_cnt_hi, p);
-+ lo = qb_attr_code_decode(&code_cgr_stat_frame_cnt_lo, p);
-+ *frame_cnt = ((uint64_t)hi << 32) | (uint64_t)lo;
-+ }
-+ if (*byte_cnt) {
-+ hi = qb_attr_code_decode(&code_cgr_stat_byte_cnt_hi, p);
-+ lo = qb_attr_code_decode(&code_cgr_stat_byte_cnt_lo, p);
-+ *byte_cnt = ((uint64_t)hi << 32) | (uint64_t)lo;
-+ }
-+
-+ return 0;
-+}
-+
-+int qbman_cgr_reject_statistics(struct qbman_swp *s, uint32_t cgid, int clear,
-+ uint64_t *frame_cnt, uint64_t *byte_cnt)
-+{
-+ return qbman_cgr_statistics_query(s, cgid, clear, 0xff,
-+ frame_cnt, byte_cnt);
-+}
-+
-+int qbman_ccgr_reject_statistics(struct qbman_swp *s, uint32_t cgid, int clear,
-+ uint64_t *frame_cnt, uint64_t *byte_cnt)
-+{
-+ return qbman_cgr_statistics_query(s, cgid, clear, 1,
-+ frame_cnt, byte_cnt);
-+}
-+
-+int qbman_cq_dequeue_statistics(struct qbman_swp *s, uint32_t cgid, int clear,
-+ uint64_t *frame_cnt, uint64_t *byte_cnt)
-+{
-+ return qbman_cgr_statistics_query(s, cgid, clear, 0,
-+ frame_cnt, byte_cnt);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_debug.h
-@@ -0,0 +1,136 @@
-+/* Copyright (C) 2015 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+struct qbman_attr {
-+ uint32_t dont_manipulate_directly[40];
-+};
-+
-+/* Buffer pool query commands */
-+int qbman_bp_query(struct qbman_swp *s, uint32_t bpid,
-+ struct qbman_attr *a);
-+void qbman_bp_attr_get_bdi(struct qbman_attr *a, int *bdi, int *va, int *wae);
-+void qbman_bp_attr_get_swdet(struct qbman_attr *a, uint32_t *swdet);
-+void qbman_bp_attr_get_swdxt(struct qbman_attr *a, uint32_t *swdxt);
-+void qbman_bp_attr_get_hwdet(struct qbman_attr *a, uint32_t *hwdet);
-+void qbman_bp_attr_get_hwdxt(struct qbman_attr *a, uint32_t *hwdxt);
-+void qbman_bp_attr_get_swset(struct qbman_attr *a, uint32_t *swset);
-+void qbman_bp_attr_get_swsxt(struct qbman_attr *a, uint32_t *swsxt);
-+void qbman_bp_attr_get_vbpid(struct qbman_attr *a, uint32_t *vbpid);
-+void qbman_bp_attr_get_icid(struct qbman_attr *a, uint32_t *icid, int *pl);
-+void qbman_bp_attr_get_bpscn_addr(struct qbman_attr *a, uint64_t *bpscn_addr);
-+void qbman_bp_attr_get_bpscn_ctx(struct qbman_attr *a, uint64_t *bpscn_ctx);
-+void qbman_bp_attr_get_hw_targ(struct qbman_attr *a, uint32_t *hw_targ);
-+int qbman_bp_info_has_free_bufs(struct qbman_attr *a);
-+int qbman_bp_info_is_depleted(struct qbman_attr *a);
-+int qbman_bp_info_is_surplus(struct qbman_attr *a);
-+uint32_t qbman_bp_info_num_free_bufs(struct qbman_attr *a);
-+uint32_t qbman_bp_info_hdptr(struct qbman_attr *a);
-+uint32_t qbman_bp_info_sdcnt(struct qbman_attr *a);
-+uint32_t qbman_bp_info_hdcnt(struct qbman_attr *a);
-+uint32_t qbman_bp_info_sscnt(struct qbman_attr *a);
-+
-+/* FQ query function for programmable fields */
-+int qbman_fq_query(struct qbman_swp *s, uint32_t fqid,
-+ struct qbman_attr *desc);
-+void qbman_fq_attr_get_fqctrl(struct qbman_attr *d, uint32_t *fqctrl);
-+void qbman_fq_attr_get_cgrid(struct qbman_attr *d, uint32_t *cgrid);
-+void qbman_fq_attr_get_destwq(struct qbman_attr *d, uint32_t *destwq);
-+void qbman_fq_attr_get_icscred(struct qbman_attr *d, uint32_t *icscred);
-+void qbman_fq_attr_get_tdthresh(struct qbman_attr *d, uint32_t *tdthresh);
-+void qbman_fq_attr_get_oa(struct qbman_attr *d,
-+ int *oa_ics, int *oa_cgr, int32_t *oa_len);
-+void qbman_fq_attr_get_mctl(struct qbman_attr *d,
-+ int *bdi, int *ff, int *va, int *ps);
-+void qbman_fq_attr_get_ctx(struct qbman_attr *d, uint32_t *hi, uint32_t *lo);
-+void qbman_fq_attr_get_icid(struct qbman_attr *d, uint32_t *icid, int *pl);
-+void qbman_fq_attr_get_vfqid(struct qbman_attr *d, uint32_t *vfqid);
-+void qbman_fq_attr_get_erfqid(struct qbman_attr *d, uint32_t *erfqid);
-+
-+/* FQ query command for non-programmable fields*/
-+enum qbman_fq_schedstate_e {
-+ qbman_fq_schedstate_oos = 0,
-+ qbman_fq_schedstate_retired,
-+ qbman_fq_schedstate_tentatively_scheduled,
-+ qbman_fq_schedstate_truly_scheduled,
-+ qbman_fq_schedstate_parked,
-+ qbman_fq_schedstate_held_active,
-+};
-+
-+int qbman_fq_query_state(struct qbman_swp *s, uint32_t fqid,
-+ struct qbman_attr *state);
-+uint32_t qbman_fq_state_schedstate(const struct qbman_attr *state);
-+int qbman_fq_state_force_eligible(const struct qbman_attr *state);
-+int qbman_fq_state_xoff(const struct qbman_attr *state);
-+int qbman_fq_state_retirement_pending(const struct qbman_attr *state);
-+int qbman_fq_state_overflow_error(const struct qbman_attr *state);
-+uint32_t qbman_fq_state_frame_count(const struct qbman_attr *state);
-+uint32_t qbman_fq_state_byte_count(const struct qbman_attr *state);
-+
-+/* CGR query */
-+int qbman_cgr_query(struct qbman_swp *s, uint32_t cgid,
-+ struct qbman_attr *attr);
-+void qbman_cgr_attr_get_ctl1(struct qbman_attr *d, int *cscn_wq_en_enter,
-+ int *cscn_wq_en_exit, int *cscn_wq_icd);
-+void qbman_cgr_attr_get_mode(struct qbman_attr *d, uint32_t *mode,
-+ int *rej_cnt_mode, int *cscn_bdi);
-+void qbman_cgr_attr_get_ctl2(struct qbman_attr *d, int *cscn_wr_en_enter,
-+ int *cscn_wr_en_exit, int *cg_wr_ae,
-+ int *cscn_dcp_en, int *cg_wr_va);
-+void qbman_cgr_attr_get_iwc(struct qbman_attr *d, int *i_cnt_wr_en,
-+ uint32_t *i_cnt_wr_bnd);
-+void qbman_cgr_attr_get_tdc(struct qbman_attr *d, int *td_en);
-+void qbman_cgr_attr_get_cs_thres(struct qbman_attr *d, uint32_t *cs_thres);
-+void qbman_cgr_attr_get_cs_thres_x(struct qbman_attr *d,
-+ uint32_t *cs_thres_x);
-+void qbman_cgr_attr_get_td_thres(struct qbman_attr *d, uint32_t *td_thres);
-+void qbman_cgr_attr_get_cscn_tdcp(struct qbman_attr *d, uint32_t *cscn_tdcp);
-+void qbman_cgr_attr_get_cscn_wqid(struct qbman_attr *d, uint32_t *cscn_wqid);
-+void qbman_cgr_attr_get_cscn_vcgid(struct qbman_attr *d,
-+ uint32_t *cscn_vcgid);
-+void qbman_cgr_attr_get_cg_icid(struct qbman_attr *d, uint32_t *icid,
-+ int *pl);
-+void qbman_cgr_attr_get_cg_wr_addr(struct qbman_attr *d,
-+ uint64_t *cg_wr_addr);
-+void qbman_cgr_attr_get_cscn_ctx(struct qbman_attr *d, uint64_t *cscn_ctx);
-+void qbman_cgr_attr_wred_get_edp(struct qbman_attr *d, uint32_t idx,
-+ int *edp);
-+void qbman_cgr_attr_wred_dp_decompose(uint32_t dp, uint64_t *minth,
-+ uint64_t *maxth, uint8_t *maxp);
-+void qbman_cgr_attr_wred_get_parm_dp(struct qbman_attr *d, uint32_t idx,
-+ uint32_t *dp);
-+
-+/* CGR/CCGR/CQ statistics query */
-+int qbman_cgr_reject_statistics(struct qbman_swp *s, uint32_t cgid, int clear,
-+ uint64_t *frame_cnt, uint64_t *byte_cnt);
-+int qbman_ccgr_reject_statistics(struct qbman_swp *s, uint32_t cgid, int clear,
-+ uint64_t *frame_cnt, uint64_t *byte_cnt);
-+int qbman_cq_dequeue_statistics(struct qbman_swp *s, uint32_t cgid, int clear,
-+ uint64_t *frame_cnt, uint64_t *byte_cnt);
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_portal.c
-@@ -0,0 +1,1212 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "qbman_portal.h"
-+
-+/* QBMan portal management command codes */
-+#define QBMAN_MC_ACQUIRE 0x30
-+#define QBMAN_WQCHAN_CONFIGURE 0x46
-+
-+/* CINH register offsets */
-+#define QBMAN_CINH_SWP_EQAR 0x8c0
-+#define QBMAN_CINH_SWP_DQPI 0xa00
-+#define QBMAN_CINH_SWP_DCAP 0xac0
-+#define QBMAN_CINH_SWP_SDQCR 0xb00
-+#define QBMAN_CINH_SWP_RAR 0xcc0
-+#define QBMAN_CINH_SWP_ISR 0xe00
-+#define QBMAN_CINH_SWP_IER 0xe40
-+#define QBMAN_CINH_SWP_ISDR 0xe80
-+#define QBMAN_CINH_SWP_IIR 0xec0
-+
-+/* CENA register offsets */
-+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))
-+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))
-+#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6))
-+#define QBMAN_CENA_SWP_CR 0x600
-+#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1))
-+#define QBMAN_CENA_SWP_VDQCR 0x780
-+
-+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
-+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
-+
-+/* QBMan FQ management command codes */
-+#define QBMAN_FQ_SCHEDULE 0x48
-+#define QBMAN_FQ_FORCE 0x49
-+#define QBMAN_FQ_XON 0x4d
-+#define QBMAN_FQ_XOFF 0x4e
-+
-+/*******************************/
-+/* Pre-defined attribute codes */
-+/*******************************/
-+
-+struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
-+struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
-+
-+/*************************/
-+/* SDQCR attribute codes */
-+/*************************/
-+
-+/* we put these here because at least some of them are required by
-+ * qbman_swp_init() */
-+struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2);
-+struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1);
-+struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8);
-+#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1)
-+enum qbman_sdqcr_dct {
-+ qbman_sdqcr_dct_null = 0,
-+ qbman_sdqcr_dct_prio_ics,
-+ qbman_sdqcr_dct_active_ics,
-+ qbman_sdqcr_dct_active
-+};
-+enum qbman_sdqcr_fc {
-+ qbman_sdqcr_fc_one = 0,
-+ qbman_sdqcr_fc_up_to_3 = 1
-+};
-+struct qb_attr_code code_sdqcr_dqsrc = QB_CODE(0, 0, 16);
-+
-+/*********************************/
-+/* Portal constructor/destructor */
-+/*********************************/
-+
-+/* Software portals should always be in the power-on state when we initialise,
-+ * due to the CCSR-based portal reset functionality that MC has.
-+ *
-+ * Erk! Turns out that QMan versions prior to 4.1 do not correctly reset DQRR
-+ * valid-bits, so we need to support a workaround where we don't trust
-+ * valid-bits when detecting new entries until any stale ring entries have been
-+ * overwritten at least once. The idea is that we read PI for the first few
-+ * entries, then switch to valid-bit after that. The trick is to clear the
-+ * bug-work-around boolean once the PI wraps around the ring for the first time.
-+ *
-+ * Note: this still carries a slight additional cost once the decrementer hits
-+ * zero, so ideally the workaround should only be compiled in if the compiled
-+ * image needs to support affected chips. We use WORKAROUND_DQRR_RESET_BUG for
-+ * this.
-+ */
-+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
-+{
-+ int ret;
-+ struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
-+
-+ if (!p)
-+ return NULL;
-+ p->desc = d;
-+#ifdef QBMAN_CHECKING
-+ p->mc.check = swp_mc_can_start;
-+#endif
-+ p->mc.valid_bit = QB_VALID_BIT;
-+ p->sdq = 0;
-+ qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
-+ qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
-+ qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
-+ atomic_set(&p->vdq.busy, 1);
-+ p->vdq.valid_bit = QB_VALID_BIT;
-+ p->dqrr.next_idx = 0;
-+ p->dqrr.valid_bit = QB_VALID_BIT;
-+ /* TODO: should also read PI/CI type registers and check that they're on
-+ * PoR values. If we're asked to initialise portals that aren't in reset
-+ * state, bad things will follow. */
-+#ifdef WORKAROUND_DQRR_RESET_BUG
-+ p->dqrr.reset_bug = 1;
-+#endif
-+ if ((p->desc->qman_version & 0xFFFF0000) < QMAN_REV_4100)
-+ p->dqrr.dqrr_size = 4;
-+ else
-+ p->dqrr.dqrr_size = 8;
-+ ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
-+ if (ret) {
-+ kfree(p);
-+ pr_err("qbman_swp_sys_init() failed %d\n", ret);
-+ return NULL;
-+ }
-+ /* SDQCR needs to be initialized to 0 when no channels are
-+ being dequeued from or else the QMan HW will indicate an
-+ error. The values that were calculated above will be
-+ applied when dequeues from a specific channel are enabled */
-+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);
-+ return p;
-+}
-+
-+void qbman_swp_finish(struct qbman_swp *p)
-+{
-+#ifdef QBMAN_CHECKING
-+ BUG_ON(p->mc.check != swp_mc_can_start);
-+#endif
-+ qbman_swp_sys_finish(&p->sys);
-+ kfree(p);
-+}
-+
-+const struct qbman_swp_desc *qbman_swp_get_desc(struct qbman_swp *p)
-+{
-+ return p->desc;
-+}
-+
-+/**************/
-+/* Interrupts */
-+/**************/
-+
-+uint32_t qbman_swp_interrupt_get_vanish(struct qbman_swp *p)
-+{
-+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISDR);
-+}
-+
-+void qbman_swp_interrupt_set_vanish(struct qbman_swp *p, uint32_t mask)
-+{
-+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISDR, mask);
-+}
-+
-+uint32_t qbman_swp_interrupt_read_status(struct qbman_swp *p)
-+{
-+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_ISR);
-+}
-+
-+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, uint32_t mask)
-+{
-+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_ISR, mask);
-+}
-+
-+uint32_t qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
-+{
-+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IER);
-+}
-+
-+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, uint32_t mask)
-+{
-+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IER, mask);
-+}
-+
-+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
-+{
-+ return qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_IIR);
-+}
-+
-+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
-+{
-+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
-+}
-+
-+/***********************/
-+/* Management commands */
-+/***********************/
-+
-+/*
-+ * Internal code common to all types of management commands.
-+ */
-+
-+void *qbman_swp_mc_start(struct qbman_swp *p)
-+{
-+ void *ret;
-+#ifdef QBMAN_CHECKING
-+ BUG_ON(p->mc.check != swp_mc_can_start);
-+#endif
-+ ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
-+#ifdef QBMAN_CHECKING
-+ if (!ret)
-+ p->mc.check = swp_mc_can_submit;
-+#endif
-+ return ret;
-+}
-+
-+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
-+{
-+ uint32_t *v = cmd;
-+#ifdef QBMAN_CHECKING
-+ BUG_ON(!p->mc.check != swp_mc_can_submit);
-+#endif
-+ /* TBD: "|=" is going to hurt performance. Need to move as many fields
-+ * out of word zero, and for those that remain, the "OR" needs to occur
-+ * at the caller side. This debug check helps to catch cases where the
-+ * caller wants to OR but has forgotten to do so. */
-+ BUG_ON((*v & cmd_verb) != *v);
-+ *v = cmd_verb | p->mc.valid_bit;
-+ qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
-+#ifdef QBMAN_CHECKING
-+ p->mc.check = swp_mc_can_poll;
-+#endif
-+}
-+
-+void *qbman_swp_mc_result(struct qbman_swp *p)
-+{
-+ uint32_t *ret, verb;
-+#ifdef QBMAN_CHECKING
-+ BUG_ON(p->mc.check != swp_mc_can_poll);
-+#endif
-+ qbman_cena_invalidate_prefetch(&p->sys,
-+ QBMAN_CENA_SWP_RR(p->mc.valid_bit));
-+ ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
-+ /* Remove the valid-bit - command completed iff the rest is non-zero */
-+ verb = ret[0] & ~QB_VALID_BIT;
-+ if (!verb)
-+ return NULL;
-+#ifdef QBMAN_CHECKING
-+ p->mc.check = swp_mc_can_start;
-+#endif
-+ p->mc.valid_bit ^= QB_VALID_BIT;
-+ return ret;
-+}
-+
-+/***********/
-+/* Enqueue */
-+/***********/
-+
-+/* These should be const, eventually */
-+static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2);
-+static struct qb_attr_code code_eq_eqdi = QB_CODE(0, 3, 1);
-+static struct qb_attr_code code_eq_dca_en = QB_CODE(0, 15, 1);
-+static struct qb_attr_code code_eq_dca_pk = QB_CODE(0, 14, 1);
-+static struct qb_attr_code code_eq_dca_idx = QB_CODE(0, 8, 2);
-+static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1);
-+static struct qb_attr_code code_eq_orp_is_nesn = QB_CODE(0, 31, 1);
-+static struct qb_attr_code code_eq_orp_nlis = QB_CODE(0, 30, 1);
-+static struct qb_attr_code code_eq_orp_seqnum = QB_CODE(0, 16, 14);
-+static struct qb_attr_code code_eq_opr_id = QB_CODE(1, 0, 16);
-+static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24);
-+/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */
-+static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1);
-+static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
-+static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
-+static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
-+static struct qb_attr_code code_eq_rsp_id = QB_CODE(5, 24, 8);
-+static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
-+
-+enum qbman_eq_cmd_e {
-+ /* No enqueue, primarily for plugging ORP gaps for dropped frames */
-+ qbman_eq_cmd_empty,
-+ /* DMA an enqueue response once complete */
-+ qbman_eq_cmd_respond,
-+ /* DMA an enqueue response only if the enqueue fails */
-+ qbman_eq_cmd_respond_reject
-+};
-+
-+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
-+{
-+ memset(d, 0, sizeof(*d));
-+}
-+
-+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_orp_en, cl, 0);
-+ qb_attr_code_encode(&code_eq_cmd, cl,
-+ respond_success ? qbman_eq_cmd_respond :
-+ qbman_eq_cmd_respond_reject);
-+}
-+
-+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
-+ uint32_t opr_id, uint32_t seqnum, int incomplete)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
-+ qb_attr_code_encode(&code_eq_cmd, cl,
-+ respond_success ? qbman_eq_cmd_respond :
-+ qbman_eq_cmd_respond_reject);
-+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
-+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
-+ qb_attr_code_encode(&code_eq_orp_nlis, cl, !!incomplete);
-+}
-+
-+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, uint32_t opr_id,
-+ uint32_t seqnum)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
-+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
-+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
-+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
-+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
-+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 0);
-+}
-+
-+void qbman_eq_desc_set_orp_nesn(struct qbman_eq_desc *d, uint32_t opr_id,
-+ uint32_t seqnum)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_orp_en, cl, 1);
-+ qb_attr_code_encode(&code_eq_cmd, cl, qbman_eq_cmd_empty);
-+ qb_attr_code_encode(&code_eq_opr_id, cl, opr_id);
-+ qb_attr_code_encode(&code_eq_orp_seqnum, cl, seqnum);
-+ qb_attr_code_encode(&code_eq_orp_nlis, cl, 0);
-+ qb_attr_code_encode(&code_eq_orp_is_nesn, cl, 1);
-+}
-+
-+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
-+ dma_addr_t storage_phys,
-+ int stash)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
-+ qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
-+}
-+
-+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, uint8_t token)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_rsp_id, cl, (uint32_t)token);
-+}
-+
-+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, uint32_t fqid)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_qd_en, cl, 0);
-+ qb_attr_code_encode(&code_eq_tgt_id, cl, fqid);
-+}
-+
-+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
-+ uint32_t qd_bin, uint32_t qd_prio)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_qd_en, cl, 1);
-+ qb_attr_code_encode(&code_eq_tgt_id, cl, qdid);
-+ qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin);
-+ qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio);
-+}
-+
-+void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_eqdi, cl, !!enable);
-+}
-+
-+void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,
-+ uint32_t dqrr_idx, int park)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_eq_dca_en, cl, !!enable);
-+ if (enable) {
-+ qb_attr_code_encode(&code_eq_dca_pk, cl, !!park);
-+ qb_attr_code_encode(&code_eq_dca_idx, cl, dqrr_idx);
-+ }
-+}
-+
-+#define EQAR_IDX(eqar) ((eqar) & 0x7)
-+#define EQAR_VB(eqar) ((eqar) & 0x80)
-+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
-+
-+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
-+ const struct qbman_fd *fd)
-+{
-+ uint32_t *p;
-+ const uint32_t *cl = qb_cl(d);
-+ uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
-+
-+ pr_debug("EQAR=%08x\n", eqar);
-+ if (!EQAR_SUCCESS(eqar))
-+ return -EBUSY;
-+ p = qbman_cena_write_start(&s->sys,
-+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
-+ word_copy(&p[1], &cl[1], 7);
-+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
-+ /* Set the verb byte, have to substitute in the valid-bit */
-+ p[0] = cl[0] | EQAR_VB(eqar);
-+ qbman_cena_write_complete(&s->sys,
-+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)),
-+ p);
-+ return 0;
-+}
-+
-+/*************************/
-+/* Static (push) dequeue */
-+/*************************/
-+
-+void qbman_swp_push_get(struct qbman_swp *s, uint8_t channel_idx, int *enabled)
-+{
-+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
-+
-+ BUG_ON(channel_idx > 15);
-+ *enabled = (int)qb_attr_code_decode(&code, &s->sdq);
-+}
-+
-+void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)
-+{
-+ uint16_t dqsrc;
-+ struct qb_attr_code code = CODE_SDQCR_DQSRC(channel_idx);
-+
-+ BUG_ON(channel_idx > 15);
-+ qb_attr_code_encode(&code, &s->sdq, !!enable);
-+ /* Read make the complete src map. If no channels are enabled
-+ the SDQCR must be 0 or else QMan will assert errors */
-+ dqsrc = (uint16_t)qb_attr_code_decode(&code_sdqcr_dqsrc, &s->sdq);
-+ if (dqsrc != 0)
-+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, s->sdq);
-+ else
-+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_SDQCR, 0);
-+}
-+
-+/***************************/
-+/* Volatile (pull) dequeue */
-+/***************************/
-+
-+/* These should be const, eventually */
-+static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2);
-+static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2);
-+static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1);
-+static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1);
-+static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
-+static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
-+static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
-+static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
-+
-+enum qb_pull_dt_e {
-+ qb_pull_dt_channel,
-+ qb_pull_dt_workqueue,
-+ qb_pull_dt_framequeue
-+};
-+
-+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
-+{
-+ memset(d, 0, sizeof(*d));
-+}
-+
-+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
-+ struct dpaa2_dq *storage,
-+ dma_addr_t storage_phys,
-+ int stash)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ /* Squiggle the pointer 'storage' into the extra 2 words of the
-+ * descriptor (which aren't copied to the hw command) */
-+ *(void **)&cl[4] = storage;
-+ if (!storage) {
-+ qb_attr_code_encode(&code_pull_rls, cl, 0);
-+ return;
-+ }
-+ qb_attr_code_encode(&code_pull_rls, cl, 1);
-+ qb_attr_code_encode(&code_pull_stash, cl, !!stash);
-+ qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
-+}
-+
-+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ BUG_ON(!numframes || (numframes > 16));
-+ qb_attr_code_encode(&code_pull_numframes, cl,
-+ (uint32_t)(numframes - 1));
-+}
-+
-+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_pull_token, cl, token);
-+}
-+
-+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_pull_dct, cl, 1);
-+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue);
-+ qb_attr_code_encode(&code_pull_dqsource, cl, fqid);
-+}
-+
-+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,
-+ enum qbman_pull_type_e dct)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_pull_dct, cl, dct);
-+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_workqueue);
-+ qb_attr_code_encode(&code_pull_dqsource, cl, wqid);
-+}
-+
-+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,
-+ enum qbman_pull_type_e dct)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_pull_dct, cl, dct);
-+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_channel);
-+ qb_attr_code_encode(&code_pull_dqsource, cl, chid);
-+}
-+
-+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
-+{
-+ uint32_t *p;
-+ uint32_t *cl = qb_cl(d);
-+
-+ if (!atomic_dec_and_test(&s->vdq.busy)) {
-+ atomic_inc(&s->vdq.busy);
-+ return -EBUSY;
-+ }
-+ s->vdq.storage = *(void **)&cl[4];
-+ qb_attr_code_encode(&code_pull_token, cl, 1);
-+ p = qbman_cena_write_start(&s->sys, QBMAN_CENA_SWP_VDQCR);
-+ word_copy(&p[1], &cl[1], 3);
-+ /* Set the verb byte, have to substitute in the valid-bit */
-+ p[0] = cl[0] | s->vdq.valid_bit;
-+ s->vdq.valid_bit ^= QB_VALID_BIT;
-+ qbman_cena_write_complete(&s->sys, QBMAN_CENA_SWP_VDQCR, p);
-+ return 0;
-+}
-+
-+/****************/
-+/* Polling DQRR */
-+/****************/
-+
-+static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8);
-+static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7);
-+static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8);
-+static struct qb_attr_code code_dqrr_seqnum = QB_CODE(0, 16, 14);
-+static struct qb_attr_code code_dqrr_odpid = QB_CODE(1, 0, 16);
-+/* static struct qb_attr_code code_dqrr_tok = QB_CODE(1, 24, 8); */
-+static struct qb_attr_code code_dqrr_fqid = QB_CODE(2, 0, 24);
-+static struct qb_attr_code code_dqrr_byte_count = QB_CODE(4, 0, 32);
-+static struct qb_attr_code code_dqrr_frame_count = QB_CODE(5, 0, 24);
-+static struct qb_attr_code code_dqrr_ctx_lo = QB_CODE(6, 0, 32);
-+
-+#define QBMAN_RESULT_DQ 0x60
-+#define QBMAN_RESULT_FQRN 0x21
-+#define QBMAN_RESULT_FQRNI 0x22
-+#define QBMAN_RESULT_FQPN 0x24
-+#define QBMAN_RESULT_FQDAN 0x25
-+#define QBMAN_RESULT_CDAN 0x26
-+#define QBMAN_RESULT_CSCN_MEM 0x27
-+#define QBMAN_RESULT_CGCU 0x28
-+#define QBMAN_RESULT_BPSCN 0x29
-+#define QBMAN_RESULT_CSCN_WQ 0x2a
-+
-+static struct qb_attr_code code_dqpi_pi = QB_CODE(0, 0, 4);
-+
-+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
-+ * only once, so repeated calls can return a sequence of DQRR entries, without
-+ * requiring they be consumed immediately or in any particular order. */
-+const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
-+{
-+ uint32_t verb;
-+ uint32_t response_verb;
-+ uint32_t flags;
-+ const struct dpaa2_dq *dq;
-+ const uint32_t *p;
-+
-+ /* Before using valid-bit to detect if something is there, we have to
-+ * handle the case of the DQRR reset bug... */
-+#ifdef WORKAROUND_DQRR_RESET_BUG
-+ if (unlikely(s->dqrr.reset_bug)) {
-+ /* We pick up new entries by cache-inhibited producer index,
-+ * which means that a non-coherent mapping would require us to
-+ * invalidate and read *only* once that PI has indicated that
-+ * there's an entry here. The first trip around the DQRR ring
-+ * will be much less efficient than all subsequent trips around
-+ * it...
-+ */
-+ uint32_t dqpi = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_DQPI);
-+ uint32_t pi = qb_attr_code_decode(&code_dqpi_pi, &dqpi);
-+ /* there are new entries iff pi != next_idx */
-+ if (pi == s->dqrr.next_idx)
-+ return NULL;
-+ /* if next_idx is/was the last ring index, and 'pi' is
-+ * different, we can disable the workaround as all the ring
-+ * entries have now been DMA'd to so valid-bit checking is
-+ * repaired. Note: this logic needs to be based on next_idx
-+ * (which increments one at a time), rather than on pi (which
-+ * can burst and wrap-around between our snapshots of it).
-+ */
-+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) {
-+ pr_debug("DEBUG: next_idx=%d, pi=%d, clear reset bug\n",
-+ s->dqrr.next_idx, pi);
-+ s->dqrr.reset_bug = 0;
-+ }
-+ qbman_cena_invalidate_prefetch(&s->sys,
-+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
-+ }
-+#endif
-+
-+ dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
-+ p = qb_cl(dq);
-+ verb = qb_attr_code_decode(&code_dqrr_verb, p);
-+
-+ /* If the valid-bit isn't of the expected polarity, nothing there. Note,
-+ * in the DQRR reset bug workaround, we shouldn't need to skip these
-+ * check, because we've already determined that a new entry is available
-+ * and we've invalidated the cacheline before reading it, so the
-+ * valid-bit behaviour is repaired and should tell us what we already
-+ * knew from reading PI.
-+ */
-+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
-+ qbman_cena_invalidate_prefetch(&s->sys,
-+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
-+ return NULL;
-+ }
-+ /* There's something there. Move "next_idx" attention to the next ring
-+ * entry (and prefetch it) before returning what we found. */
-+ s->dqrr.next_idx++;
-+ s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */
-+ /* TODO: it's possible to do all this without conditionals, optimise it
-+ * later. */
-+ if (!s->dqrr.next_idx)
-+ s->dqrr.valid_bit ^= QB_VALID_BIT;
-+
-+ /* If this is the final response to a volatile dequeue command
-+ indicate that the vdq is no longer busy */
-+ flags = dpaa2_dq_flags(dq);
-+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
-+ if ((response_verb == QBMAN_RESULT_DQ) &&
-+ (flags & DPAA2_DQ_STAT_VOLATILE) &&
-+ (flags & DPAA2_DQ_STAT_EXPIRED))
-+ atomic_inc(&s->vdq.busy);
-+
-+ qbman_cena_invalidate_prefetch(&s->sys,
-+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
-+ return dq;
-+}
-+
-+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
-+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq)
-+{
-+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
-+}
-+
-+/*********************************/
-+/* Polling user-provided storage */
-+/*********************************/
-+
-+int qbman_result_has_new_result(struct qbman_swp *s,
-+ const struct dpaa2_dq *dq)
-+{
-+ /* To avoid converting the little-endian DQ entry to host-endian prior
-+ * to us knowing whether there is a valid entry or not (and run the
-+ * risk of corrupting the incoming hardware LE write), we detect in
-+ * hardware endianness rather than host. This means we need a different
-+ * "code" depending on whether we are BE or LE in software, which is
-+ * where DQRR_TOK_OFFSET comes in... */
-+ static struct qb_attr_code code_dqrr_tok_detect =
-+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
-+ /* The user trying to poll for a result treats "dq" as const. It is
-+ * however the same address that was provided to us non-const in the
-+ * first place, for directing hardware DMA to. So we can cast away the
-+ * const because it is mutable from our perspective. */
-+ uint32_t *p = qb_cl((struct dpaa2_dq *)dq);
-+ uint32_t token;
-+
-+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
-+ if (token != 1)
-+ return 0;
-+ qb_attr_code_encode(&code_dqrr_tok_detect, &p[1], 0);
-+
-+ /* Only now do we convert from hardware to host endianness. Also, as we
-+ * are returning success, the user has promised not to call us again, so
-+ * there's no risk of us converting the endianness twice... */
-+ make_le32_n(p, 16);
-+
-+ /* VDQCR "no longer busy" hook - not quite the same as DQRR, because the
-+ * fact "VDQCR" shows busy doesn't mean that the result we're looking at
-+ * is from the same command. Eg. we may be looking at our 10th dequeue
-+ * result from our first VDQCR command, yet the second dequeue command
-+ * could have been kicked off already, after seeing the 1st result. Ie.
-+ * the result we're looking at is not necessarily proof that we can
-+ * reset "busy". We instead base the decision on whether the current
-+ * result is sitting at the first 'storage' location of the busy
-+ * command. */
-+ if (s->vdq.storage == dq) {
-+ s->vdq.storage = NULL;
-+ atomic_inc(&s->vdq.busy);
-+ }
-+ return 1;
-+}
-+
-+/********************************/
-+/* Categorising qbman_result */
-+/********************************/
-+
-+static struct qb_attr_code code_result_in_mem =
-+ QB_CODE(0, QBMAN_RESULT_VERB_OFFSET_IN_MEM, 7);
-+
-+static inline int __qbman_result_is_x(const struct dpaa2_dq *dq, uint32_t x)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+ uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p);
-+
-+ return response_verb == x;
-+}
-+
-+static inline int __qbman_result_is_x_in_mem(const struct dpaa2_dq *dq,
-+ uint32_t x)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+ uint32_t response_verb = qb_attr_code_decode(&code_result_in_mem, p);
-+
-+ return (response_verb == x);
-+}
-+
-+int qbman_result_is_DQ(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x(dq, QBMAN_RESULT_DQ);
-+}
-+
-+int qbman_result_is_FQDAN(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQDAN);
-+}
-+
-+int qbman_result_is_CDAN(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x(dq, QBMAN_RESULT_CDAN);
-+}
-+
-+int qbman_result_is_CSCN(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CSCN_MEM) ||
-+ __qbman_result_is_x(dq, QBMAN_RESULT_CSCN_WQ);
-+}
-+
-+int qbman_result_is_BPSCN(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_BPSCN);
-+}
-+
-+int qbman_result_is_CGCU(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_CGCU);
-+}
-+
-+int qbman_result_is_FQRN(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRN);
-+}
-+
-+int qbman_result_is_FQRNI(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x_in_mem(dq, QBMAN_RESULT_FQRNI);
-+}
-+
-+int qbman_result_is_FQPN(const struct dpaa2_dq *dq)
-+{
-+ return __qbman_result_is_x(dq, QBMAN_RESULT_FQPN);
-+}
-+
-+/*********************************/
-+/* Parsing frame dequeue results */
-+/*********************************/
-+
-+/* These APIs assume qbman_result_is_DQ() is TRUE */
-+
-+uint32_t dpaa2_dq_flags(const struct dpaa2_dq *dq)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+
-+ return qb_attr_code_decode(&code_dqrr_stat, p);
-+}
-+
-+uint16_t dpaa2_dq_seqnum(const struct dpaa2_dq *dq)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+
-+ return (uint16_t)qb_attr_code_decode(&code_dqrr_seqnum, p);
-+}
-+
-+uint16_t dpaa2_dq_odpid(const struct dpaa2_dq *dq)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+
-+ return (uint16_t)qb_attr_code_decode(&code_dqrr_odpid, p);
-+}
-+
-+uint32_t dpaa2_dq_fqid(const struct dpaa2_dq *dq)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+
-+ return qb_attr_code_decode(&code_dqrr_fqid, p);
-+}
-+
-+uint32_t dpaa2_dq_byte_count(const struct dpaa2_dq *dq)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+
-+ return qb_attr_code_decode(&code_dqrr_byte_count, p);
-+}
-+
-+uint32_t dpaa2_dq_frame_count(const struct dpaa2_dq *dq)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+
-+ return qb_attr_code_decode(&code_dqrr_frame_count, p);
-+}
-+
-+uint64_t dpaa2_dq_fqd_ctx(const struct dpaa2_dq *dq)
-+{
-+ const uint64_t *p = (uint64_t *)qb_cl(dq);
-+
-+ return qb_attr_code_decode_64(&code_dqrr_ctx_lo, p);
-+}
-+EXPORT_SYMBOL(dpaa2_dq_fqd_ctx);
-+
-+const struct dpaa2_fd *dpaa2_dq_fd(const struct dpaa2_dq *dq)
-+{
-+ const uint32_t *p = qb_cl(dq);
-+
-+ return (const struct dpaa2_fd *)&p[8];
-+}
-+EXPORT_SYMBOL(dpaa2_dq_fd);
-+
-+/**************************************/
-+/* Parsing state-change notifications */
-+/**************************************/
-+
-+static struct qb_attr_code code_scn_state = QB_CODE(0, 16, 8);
-+static struct qb_attr_code code_scn_rid = QB_CODE(1, 0, 24);
-+static struct qb_attr_code code_scn_state_in_mem =
-+ QB_CODE(0, SCN_STATE_OFFSET_IN_MEM, 8);
-+static struct qb_attr_code code_scn_rid_in_mem =
-+ QB_CODE(1, SCN_RID_OFFSET_IN_MEM, 24);
-+static struct qb_attr_code code_scn_ctx_lo = QB_CODE(2, 0, 32);
-+
-+uint8_t qbman_result_SCN_state(const struct dpaa2_dq *scn)
-+{
-+ const uint32_t *p = qb_cl(scn);
-+
-+ return (uint8_t)qb_attr_code_decode(&code_scn_state, p);
-+}
-+
-+uint32_t qbman_result_SCN_rid(const struct dpaa2_dq *scn)
-+{
-+ const uint32_t *p = qb_cl(scn);
-+
-+ return qb_attr_code_decode(&code_scn_rid, p);
-+}
-+
-+uint64_t qbman_result_SCN_ctx(const struct dpaa2_dq *scn)
-+{
-+ const uint64_t *p = (uint64_t *)qb_cl(scn);
-+
-+ return qb_attr_code_decode_64(&code_scn_ctx_lo, p);
-+}
-+
-+uint8_t qbman_result_SCN_state_in_mem(const struct dpaa2_dq *scn)
-+{
-+ const uint32_t *p = qb_cl(scn);
-+
-+ return (uint8_t)qb_attr_code_decode(&code_scn_state_in_mem, p);
-+}
-+
-+uint32_t qbman_result_SCN_rid_in_mem(const struct dpaa2_dq *scn)
-+{
-+ const uint32_t *p = qb_cl(scn);
-+ uint32_t result_rid;
-+
-+ result_rid = qb_attr_code_decode(&code_scn_rid_in_mem, p);
-+ return make_le24(result_rid);
-+}
-+
-+/*****************/
-+/* Parsing BPSCN */
-+/*****************/
-+uint16_t qbman_result_bpscn_bpid(const struct dpaa2_dq *scn)
-+{
-+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0x3FFF;
-+}
-+
-+int qbman_result_bpscn_has_free_bufs(const struct dpaa2_dq *scn)
-+{
-+ return !(int)(qbman_result_SCN_state_in_mem(scn) & 0x1);
-+}
-+
-+int qbman_result_bpscn_is_depleted(const struct dpaa2_dq *scn)
-+{
-+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x2);
-+}
-+
-+int qbman_result_bpscn_is_surplus(const struct dpaa2_dq *scn)
-+{
-+ return (int)(qbman_result_SCN_state_in_mem(scn) & 0x4);
-+}
-+
-+uint64_t qbman_result_bpscn_ctx(const struct dpaa2_dq *scn)
-+{
-+ return qbman_result_SCN_ctx(scn);
-+}
-+
-+/*****************/
-+/* Parsing CGCU */
-+/*****************/
-+uint16_t qbman_result_cgcu_cgid(const struct dpaa2_dq *scn)
-+{
-+ return (uint16_t)qbman_result_SCN_rid_in_mem(scn) & 0xFFFF;
-+}
-+
-+uint64_t qbman_result_cgcu_icnt(const struct dpaa2_dq *scn)
-+{
-+ return qbman_result_SCN_ctx(scn) & 0xFFFFFFFFFF;
-+}
-+
-+/******************/
-+/* Buffer release */
-+/******************/
-+
-+/* These should be const, eventually */
-+/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */
-+static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1);
-+static struct qb_attr_code code_release_rcdi = QB_CODE(0, 6, 1);
-+static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16);
-+
-+void qbman_release_desc_clear(struct qbman_release_desc *d)
-+{
-+ uint32_t *cl;
-+
-+ memset(d, 0, sizeof(*d));
-+ cl = qb_cl(d);
-+ qb_attr_code_encode(&code_release_set_me, cl, 1);
-+}
-+
-+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_release_bpid, cl, bpid);
-+}
-+
-+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
-+{
-+ uint32_t *cl = qb_cl(d);
-+
-+ qb_attr_code_encode(&code_release_rcdi, cl, !!enable);
-+}
-+
-+#define RAR_IDX(rar) ((rar) & 0x7)
-+#define RAR_VB(rar) ((rar) & 0x80)
-+#define RAR_SUCCESS(rar) ((rar) & 0x100)
-+
-+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
-+ const uint64_t *buffers, unsigned int num_buffers)
-+{
-+ uint32_t *p;
-+ const uint32_t *cl = qb_cl(d);
-+ uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
-+
-+ pr_debug("RAR=%08x\n", rar);
-+ if (!RAR_SUCCESS(rar))
-+ return -EBUSY;
-+ BUG_ON(!num_buffers || (num_buffers > 7));
-+ /* Start the release command */
-+ p = qbman_cena_write_start(&s->sys,
-+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
-+ /* Copy the caller's buffer pointers to the command */
-+ u64_to_le32_copy(&p[2], buffers, num_buffers);
-+ /* Set the verb byte, have to substitute in the valid-bit and the number
-+ * of buffers. */
-+ p[0] = cl[0] | RAR_VB(rar) | num_buffers;
-+ qbman_cena_write_complete(&s->sys,
-+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)),
-+ p);
-+ return 0;
-+}
-+
-+/*******************/
-+/* Buffer acquires */
-+/*******************/
-+
-+/* These should be const, eventually */
-+static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16);
-+static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3);
-+static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3);
-+
-+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
-+ unsigned int num_buffers)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt, num;
-+
-+ BUG_ON(!num_buffers || (num_buffers > 7));
-+
-+ /* Start the management command */
-+ p = qbman_swp_mc_start(s);
-+
-+ if (!p)
-+ return -EBUSY;
-+
-+ /* Encode the caller-provided attributes */
-+ qb_attr_code_encode(&code_acquire_bpid, p, bpid);
-+ qb_attr_code_encode(&code_acquire_num, p, num_buffers);
-+
-+ /* Complete the management command */
-+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ num = qb_attr_code_decode(&code_acquire_r_num, p);
-+ BUG_ON(verb != QBMAN_MC_ACQUIRE);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
-+ bpid, rslt);
-+ return -EIO;
-+ }
-+ BUG_ON(num > num_buffers);
-+ /* Copy the acquired buffers to the caller's array */
-+ u64_from_le32_copy(buffers, &p[2], num);
-+ return (int)num;
-+}
-+
-+/*****************/
-+/* FQ management */
-+/*****************/
-+
-+static struct qb_attr_code code_fqalt_fqid = QB_CODE(1, 0, 32);
-+
-+static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,
-+ uint8_t alt_fq_verb)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt;
-+
-+ /* Start the management command */
-+ p = qbman_swp_mc_start(s);
-+ if (!p)
-+ return -EBUSY;
-+
-+ qb_attr_code_encode(&code_fqalt_fqid, p, fqid);
-+ /* Complete the management command */
-+ p = qbman_swp_mc_complete(s, p, p[0] | alt_fq_verb);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ BUG_ON(verb != alt_fq_verb);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\n",
-+ fqid, alt_fq_verb, rslt);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+int qbman_swp_fq_schedule(struct qbman_swp *s, uint32_t fqid)
-+{
-+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
-+}
-+
-+int qbman_swp_fq_force(struct qbman_swp *s, uint32_t fqid)
-+{
-+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
-+}
-+
-+int qbman_swp_fq_xon(struct qbman_swp *s, uint32_t fqid)
-+{
-+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
-+}
-+
-+int qbman_swp_fq_xoff(struct qbman_swp *s, uint32_t fqid)
-+{
-+ return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
-+}
-+
-+/**********************/
-+/* Channel management */
-+/**********************/
-+
-+static struct qb_attr_code code_cdan_cid = QB_CODE(0, 16, 12);
-+static struct qb_attr_code code_cdan_we = QB_CODE(1, 0, 8);
-+static struct qb_attr_code code_cdan_en = QB_CODE(1, 8, 1);
-+static struct qb_attr_code code_cdan_ctx_lo = QB_CODE(2, 0, 32);
-+
-+/* Hide "ICD" for now as we don't use it, don't set it, and don't test it, so it
-+ * would be irresponsible to expose it. */
-+#define CODE_CDAN_WE_EN 0x1
-+#define CODE_CDAN_WE_CTX 0x4
-+
-+static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,
-+ uint8_t we_mask, uint8_t cdan_en,
-+ uint64_t ctx)
-+{
-+ uint32_t *p;
-+ uint32_t verb, rslt;
-+
-+ /* Start the management command */
-+ p = qbman_swp_mc_start(s);
-+ if (!p)
-+ return -EBUSY;
-+
-+ /* Encode the caller-provided attributes */
-+ qb_attr_code_encode(&code_cdan_cid, p, channelid);
-+ qb_attr_code_encode(&code_cdan_we, p, we_mask);
-+ qb_attr_code_encode(&code_cdan_en, p, cdan_en);
-+ qb_attr_code_encode_64(&code_cdan_ctx_lo, (uint64_t *)p, ctx);
-+ /* Complete the management command */
-+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_WQCHAN_CONFIGURE);
-+
-+ /* Decode the outcome */
-+ verb = qb_attr_code_decode(&code_generic_verb, p);
-+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
-+ BUG_ON(verb != QBMAN_WQCHAN_CONFIGURE);
-+
-+ /* Determine success or failure */
-+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
-+ pr_err("CDAN cQID %d failed: code = 0x%02x\n",
-+ channelid, rslt);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+int qbman_swp_CDAN_set_context(struct qbman_swp *s, uint16_t channelid,
-+ uint64_t ctx)
-+{
-+ return qbman_swp_CDAN_set(s, channelid,
-+ CODE_CDAN_WE_CTX,
-+ 0, ctx);
-+}
-+
-+int qbman_swp_CDAN_enable(struct qbman_swp *s, uint16_t channelid)
-+{
-+ return qbman_swp_CDAN_set(s, channelid,
-+ CODE_CDAN_WE_EN,
-+ 1, 0);
-+}
-+int qbman_swp_CDAN_disable(struct qbman_swp *s, uint16_t channelid)
-+{
-+ return qbman_swp_CDAN_set(s, channelid,
-+ CODE_CDAN_WE_EN,
-+ 0, 0);
-+}
-+int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, uint16_t channelid,
-+ uint64_t ctx)
-+{
-+ return qbman_swp_CDAN_set(s, channelid,
-+ CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
-+ 1, ctx);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_portal.h
-@@ -0,0 +1,261 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "qbman_private.h"
-+#include "fsl_qbman_portal.h"
-+#include "../../include/fsl_dpaa2_fd.h"
-+
-+/* All QBMan command and result structures use this "valid bit" encoding */
-+#define QB_VALID_BIT ((uint32_t)0x80)
-+
-+/* Management command result codes */
-+#define QBMAN_MC_RSLT_OK 0xf0
-+
-+/* TBD: as of QBMan 4.1, DQRR will be 8 rather than 4! */
-+#define QBMAN_DQRR_SIZE 4
-+
-+/* DQRR valid-bit reset bug. See qbman_portal.c::qbman_swp_init(). */
-+#define WORKAROUND_DQRR_RESET_BUG
-+
-+/* --------------------- */
-+/* portal data structure */
-+/* --------------------- */
-+
-+struct qbman_swp {
-+ const struct qbman_swp_desc *desc;
-+ /* The qbman_sys (ie. arch/OS-specific) support code can put anything it
-+ * needs in here. */
-+ struct qbman_swp_sys sys;
-+ /* Management commands */
-+ struct {
-+#ifdef QBMAN_CHECKING
-+ enum swp_mc_check {
-+ swp_mc_can_start, /* call __qbman_swp_mc_start() */
-+ swp_mc_can_submit, /* call __qbman_swp_mc_submit() */
-+ swp_mc_can_poll, /* call __qbman_swp_mc_result() */
-+ } check;
-+#endif
-+ uint32_t valid_bit; /* 0x00 or 0x80 */
-+ } mc;
-+ /* Push dequeues */
-+ uint32_t sdq;
-+ /* Volatile dequeues */
-+ struct {
-+ /* VDQCR supports a "1 deep pipeline", meaning that if you know
-+ * the last-submitted command is already executing in the
-+ * hardware (as evidenced by at least 1 valid dequeue result),
-+ * you can write another dequeue command to the register, the
-+ * hardware will start executing it as soon as the
-+ * already-executing command terminates. (This minimises latency
-+ * and stalls.) With that in mind, this "busy" variable refers
-+ * to whether or not a command can be submitted, not whether or
-+ * not a previously-submitted command is still executing. In
-+ * other words, once proof is seen that the previously-submitted
-+ * command is executing, "vdq" is no longer "busy".
-+ */
-+ atomic_t busy;
-+ uint32_t valid_bit; /* 0x00 or 0x80 */
-+ /* We need to determine when vdq is no longer busy. This depends
-+ * on whether the "busy" (last-submitted) dequeue command is
-+ * targeting DQRR or main-memory, and detected is based on the
-+ * presence of the dequeue command's "token" showing up in
-+ * dequeue entries in DQRR or main-memory (respectively). */
-+ struct dpaa2_dq *storage; /* NULL if DQRR */
-+ } vdq;
-+ /* DQRR */
-+ struct {
-+ uint32_t next_idx;
-+ uint32_t valid_bit;
-+ uint8_t dqrr_size;
-+#ifdef WORKAROUND_DQRR_RESET_BUG
-+ int reset_bug;
-+#endif
-+ } dqrr;
-+};
-+
-+/* -------------------------- */
-+/* portal management commands */
-+/* -------------------------- */
-+
-+/* Different management commands all use this common base layer of code to issue
-+ * commands and poll for results. The first function returns a pointer to where
-+ * the caller should fill in their MC command (though they should ignore the
-+ * verb byte), the second function commits merges in the caller-supplied command
-+ * verb (which should not include the valid-bit) and submits the command to
-+ * hardware, and the third function checks for a completed response (returns
-+ * non-NULL if only if the response is complete). */
-+void *qbman_swp_mc_start(struct qbman_swp *p);
-+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb);
-+void *qbman_swp_mc_result(struct qbman_swp *p);
-+
-+/* Wraps up submit + poll-for-result */
-+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
-+ uint32_t cmd_verb)
-+{
-+ int loopvar;
-+
-+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
-+ DBG_POLL_START(loopvar);
-+ do {
-+ DBG_POLL_CHECK(loopvar);
-+ cmd = qbman_swp_mc_result(swp);
-+ } while (!cmd);
-+ return cmd;
-+}
-+
-+/* ------------ */
-+/* qb_attr_code */
-+/* ------------ */
-+
-+/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
-+ * is either serving as a configuration command or a query result. The
-+ * representation is inherently little-endian, as the indexing of the words is
-+ * itself little-endian in nature and layerscape is little endian for anything
-+ * that crosses a word boundary too (64-bit fields are the obvious examples).
-+ */
-+struct qb_attr_code {
-+ unsigned int word; /* which uint32_t[] array member encodes the field */
-+ unsigned int lsoffset; /* encoding offset from ls-bit */
-+ unsigned int width; /* encoding width. (bool must be 1.) */
-+};
-+
-+/* Some pre-defined codes */
-+extern struct qb_attr_code code_generic_verb;
-+extern struct qb_attr_code code_generic_rslt;
-+
-+/* Macros to define codes */
-+#define QB_CODE(a, b, c) { a, b, c}
-+#define QB_CODE_NULL \
-+ QB_CODE((unsigned int)-1, (unsigned int)-1, (unsigned int)-1)
-+
-+/* Rotate a code "ms", meaning that it moves from less-significant bytes to
-+ * more-significant, from less-significant words to more-significant, etc. The
-+ * "ls" version does the inverse, from more-significant towards
-+ * less-significant.
-+ */
-+static inline void qb_attr_code_rotate_ms(struct qb_attr_code *code,
-+ unsigned int bits)
-+{
-+ code->lsoffset += bits;
-+ while (code->lsoffset > 31) {
-+ code->word++;
-+ code->lsoffset -= 32;
-+ }
-+}
-+static inline void qb_attr_code_rotate_ls(struct qb_attr_code *code,
-+ unsigned int bits)
-+{
-+ /* Don't be fooled, this trick should work because the types are
-+ * unsigned. So the case that interests the while loop (the rotate has
-+ * gone too far and the word count needs to compensate for it), is
-+ * manifested when lsoffset is negative. But that equates to a really
-+ * large unsigned value, starting with lots of "F"s. As such, we can
-+ * continue adding 32 back to it until it wraps back round above zero,
-+ * to a value of 31 or less...
-+ */
-+ code->lsoffset -= bits;
-+ while (code->lsoffset > 31) {
-+ code->word--;
-+ code->lsoffset += 32;
-+ }
-+}
-+/* Implement a loop of code rotations until 'expr' evaluates to FALSE (0). */
-+#define qb_attr_code_for_ms(code, bits, expr) \
-+ for (; expr; qb_attr_code_rotate_ms(code, bits))
-+#define qb_attr_code_for_ls(code, bits, expr) \
-+ for (; expr; qb_attr_code_rotate_ls(code, bits))
-+
-+/* decode a field from a cacheline */
-+static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
-+ const uint32_t *cacheline)
-+{
-+ return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
-+}
-+static inline uint64_t qb_attr_code_decode_64(const struct qb_attr_code *code,
-+ const uint64_t *cacheline)
-+{
-+ uint64_t res;
-+ u64_from_le32_copy(&res, &cacheline[code->word/2], 1);
-+ return res;
-+}
-+
-+/* encode a field to a cacheline */
-+static inline void qb_attr_code_encode(const struct qb_attr_code *code,
-+ uint32_t *cacheline, uint32_t val)
-+{
-+ cacheline[code->word] =
-+ r32_uint32_t(code->lsoffset, code->width, cacheline[code->word])
-+ | e32_uint32_t(code->lsoffset, code->width, val);
-+}
-+static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
-+ uint64_t *cacheline, uint64_t val)
-+{
-+ u64_to_le32_copy(&cacheline[code->word/2], &val, 1);
-+}
-+
-+/* Small-width signed values (two's-complement) will decode into medium-width
-+ * positives. (Eg. for an 8-bit signed field, which stores values from -128 to
-+ * +127, a setting of -7 would appear to decode to the 32-bit unsigned value
-+ * 249. Likewise -120 would decode as 136.) This function allows the caller to
-+ * "re-sign" such fields to 32-bit signed. (Eg. -7, which was 249 with an 8-bit
-+ * encoding, will become 0xfffffff9 if you cast the return value to uint32_t).
-+ */
-+static inline int32_t qb_attr_code_makesigned(const struct qb_attr_code *code,
-+ uint32_t val)
-+{
-+ BUG_ON(val >= (1 << code->width));
-+ /* If the high bit was set, it was encoding a negative */
-+ if (val >= (1 << (code->width - 1)))
-+ return (int32_t)0 - (int32_t)(((uint32_t)1 << code->width) -
-+ val);
-+ /* Otherwise, it was encoding a positive */
-+ return (int32_t)val;
-+}
-+
-+/* ---------------------- */
-+/* Descriptors/cachelines */
-+/* ---------------------- */
-+
-+/* To avoid needless dynamic allocation, the driver API often gives the caller
-+ * a "descriptor" type that the caller can instantiate however they like.
-+ * Ultimately though, it is just a cacheline of binary storage (or something
-+ * smaller when it is known that the descriptor doesn't need all 64 bytes) for
-+ * holding pre-formatted pieces of hardware commands. The performance-critical
-+ * code can then copy these descriptors directly into hardware command
-+ * registers more efficiently than trying to construct/format commands
-+ * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
-+ * order for the compiler to know its size, but the internal details are not
-+ * exposed. The following macro is used within the driver for converting *any*
-+ * descriptor pointer to a usable array pointer. The use of a macro (instead of
-+ * an inline) is necessary to work with different descriptor types and to work
-+ * correctly with const and non-const inputs (and similarly-qualified outputs).
-+ */
-+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_private.h
-@@ -0,0 +1,173 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+*/
-+
-+/* Perform extra checking */
-+#define QBMAN_CHECKING
-+
-+/* To maximise the amount of logic that is common between the Linux driver and
-+ * other targets (such as the embedded MC firmware), we pivot here between the
-+ * inclusion of two platform-specific headers.
-+ *
-+ * The first, qbman_sys_decl.h, includes any and all required system headers as
-+ * well as providing any definitions for the purposes of compatibility. The
-+ * second, qbman_sys.h, is where platform-specific routines go.
-+ *
-+ * The point of the split is that the platform-independent code (including this
-+ * header) may depend on platform-specific declarations, yet other
-+ * platform-specific routines may depend on platform-independent definitions.
-+ */
-+
-+#include "qbman_sys_decl.h"
-+
-+#define QMAN_REV_4000 0x04000000
-+#define QMAN_REV_4100 0x04010000
-+#define QMAN_REV_4101 0x04010001
-+
-+/* When things go wrong, it is a convenient trick to insert a few FOO()
-+ * statements in the code to trace progress. TODO: remove this once we are
-+ * hacking the code less actively.
-+ */
-+#define FOO() fsl_os_print("FOO: %s:%d\n", __FILE__, __LINE__)
-+
-+/* Any time there is a register interface which we poll on, this provides a
-+ * "break after x iterations" scheme for it. It's handy for debugging, eg.
-+ * where you don't want millions of lines of log output from a polling loop
-+ * that won't, because such things tend to drown out the earlier log output
-+ * that might explain what caused the problem. (NB: put ";" after each macro!)
-+ * TODO: we should probably remove this once we're done sanitising the
-+ * simulator...
-+ */
-+#define DBG_POLL_START(loopvar) (loopvar = 10)
-+#define DBG_POLL_CHECK(loopvar) \
-+ do {if (!(loopvar--)) BUG_ON(1); } while (0)
-+
-+/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
-+ * and widths, these macro-generated encode/decode/isolate/remove inlines can
-+ * be used.
-+ *
-+ * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
-+ * where the field is located 3 bits "up" from the least-significant bit of the
-+ * register (ie. the field location within the 32-bit register corresponds to a
-+ * mask of 0x0001fff8), you would do;
-+ * uint16_t field = d32_uint16_t(3, 14, reg_value);
-+ *
-+ * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
-+ * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
-+ * operator) into a register at bit location 0x00080000 (19 bits "in" from the
-+ * LS bit), do;
-+ * reg_value |= e32_int(19, 1, !!field);
-+ *
-+ * If you wish to read-modify-write a register, such that you leave the 14-bit
-+ * field as-is but have all other fields set to zero, then "i"solate the 14-bit
-+ * value using;
-+ * reg_value = i32_uint16_t(3, 14, reg_value);
-+ *
-+ * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
-+ * zero) but leaving all other fields as-is;
-+ * reg_val = r32_int(19, 1, reg_value);
-+ *
-+ */
-+#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
-+ (uint32_t)((1 << width) - 1))
-+#define DECLARE_CODEC32(t) \
-+static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
-+{ \
-+ BUG_ON(width > (sizeof(t) * 8)); \
-+ return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
-+} \
-+static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
-+{ \
-+ BUG_ON(width > (sizeof(t) * 8)); \
-+ return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
-+} \
-+static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
-+ uint32_t val) \
-+{ \
-+ BUG_ON(width > (sizeof(t) * 8)); \
-+ return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
-+} \
-+static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
-+ uint32_t val) \
-+{ \
-+ BUG_ON(width > (sizeof(t) * 8)); \
-+ return ~(MAKE_MASK32(width) << lsoffset) & val; \
-+}
-+DECLARE_CODEC32(uint32_t)
-+DECLARE_CODEC32(uint16_t)
-+DECLARE_CODEC32(uint8_t)
-+DECLARE_CODEC32(int)
-+
-+ /*********************/
-+ /* Debugging assists */
-+ /*********************/
-+
-+static inline void __hexdump(unsigned long start, unsigned long end,
-+ unsigned long p, size_t sz, const unsigned char *c)
-+{
-+ while (start < end) {
-+ unsigned int pos = 0;
-+ char buf[64];
-+ int nl = 0;
-+
-+ pos += sprintf(buf + pos, "%08lx: ", start);
-+ do {
-+ if ((start < p) || (start >= (p + sz)))
-+ pos += sprintf(buf + pos, "..");
-+ else
-+ pos += sprintf(buf + pos, "%02x", *(c++));
-+ if (!(++start & 15)) {
-+ buf[pos++] = '\n';
-+ nl = 1;
-+ } else {
-+ nl = 0;
-+ if (!(start & 1))
-+ buf[pos++] = ' ';
-+ if (!(start & 3))
-+ buf[pos++] = ' ';
-+ }
-+ } while (start & 15);
-+ if (!nl)
-+ buf[pos++] = '\n';
-+ buf[pos] = '\0';
-+ pr_info("%s", buf);
-+ }
-+}
-+static inline void hexdump(const void *ptr, size_t sz)
-+{
-+ unsigned long p = (unsigned long)ptr;
-+ unsigned long start = p & ~(unsigned long)15;
-+ unsigned long end = (p + sz + 15) & ~(unsigned long)15;
-+ const unsigned char *c = ptr;
-+
-+ __hexdump(start, end, p, sz, c);
-+}
-+
-+#include "qbman_sys.h"
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_sys.h
-@@ -0,0 +1,307 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the
-+ * driver. They are only included via qbman_private.h, which is itself a
-+ * platform-independent file and is included by all the other driver source.
-+ *
-+ * qbman_sys_decl.h is included prior to all other declarations and logic, and
-+ * it exists to provide compatibility with any linux interfaces our
-+ * single-source driver code is dependent on (eg. kmalloc). Ie. this file
-+ * provides linux compatibility.
-+ *
-+ * This qbman_sys.h header, on the other hand, is included *after* any common
-+ * and platform-neutral declarations and logic in qbman_private.h, and exists to
-+ * implement any platform-specific logic of the qbman driver itself. Ie. it is
-+ * *not* to provide linux compatibility.
-+ */
-+
-+/* Trace the 3 different classes of read/write access to QBMan. #undef as
-+ * required. */
-+#undef QBMAN_CCSR_TRACE
-+#undef QBMAN_CINH_TRACE
-+#undef QBMAN_CENA_TRACE
-+
-+static inline void word_copy(void *d, const void *s, unsigned int cnt)
-+{
-+ uint32_t *dd = d;
-+ const uint32_t *ss = s;
-+
-+ while (cnt--)
-+ *(dd++) = *(ss++);
-+}
-+
-+/* Currently, the CENA support code expects each 32-bit word to be written in
-+ * host order, and these are converted to hardware (little-endian) order on
-+ * command submission. However, 64-bit quantities are must be written (and read)
-+ * as two 32-bit words with the least-significant word first, irrespective of
-+ * host endianness. */
-+static inline void u64_to_le32_copy(void *d, const uint64_t *s,
-+ unsigned int cnt)
-+{
-+ uint32_t *dd = d;
-+ const uint32_t *ss = (const uint32_t *)s;
-+
-+ while (cnt--) {
-+ /* TBD: the toolchain was choking on the use of 64-bit types up
-+ * until recently so this works entirely with 32-bit variables.
-+ * When 64-bit types become usable again, investigate better
-+ * ways of doing this. */
-+#if defined(__BIG_ENDIAN)
-+ *(dd++) = ss[1];
-+ *(dd++) = ss[0];
-+ ss += 2;
-+#else
-+ *(dd++) = *(ss++);
-+ *(dd++) = *(ss++);
-+#endif
-+ }
-+}
-+static inline void u64_from_le32_copy(uint64_t *d, const void *s,
-+ unsigned int cnt)
-+{
-+ const uint32_t *ss = s;
-+ uint32_t *dd = (uint32_t *)d;
-+
-+ while (cnt--) {
-+#if defined(__BIG_ENDIAN)
-+ dd[1] = *(ss++);
-+ dd[0] = *(ss++);
-+ dd += 2;
-+#else
-+ *(dd++) = *(ss++);
-+ *(dd++) = *(ss++);
-+#endif
-+ }
-+}
-+
-+/* Convert a host-native 32bit value into little endian */
-+#if defined(__BIG_ENDIAN)
-+static inline uint32_t make_le32(uint32_t val)
-+{
-+ return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
-+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
-+}
-+static inline uint32_t make_le24(uint32_t val)
-+{
-+ return (((val & 0xff) << 16) | (val & 0xff00) |
-+ ((val & 0xff0000) >> 16));
-+}
-+#else
-+#define make_le32(val) (val)
-+#define make_le24(val) (val)
-+#endif
-+static inline void make_le32_n(uint32_t *val, unsigned int num)
-+{
-+ while (num--) {
-+ *val = make_le32(*val);
-+ val++;
-+ }
-+}
-+
-+ /******************/
-+ /* Portal access */
-+ /******************/
-+struct qbman_swp_sys {
-+ /* On GPP, the sys support for qbman_swp is here. The CENA region isi
-+ * not an mmap() of the real portal registers, but an allocated
-+ * place-holder, because the actual writes/reads to/from the portal are
-+ * marshalled from these allocated areas using QBMan's "MC access
-+ * registers". CINH accesses are atomic so there's no need for a
-+ * place-holder. */
-+ void *cena;
-+ void __iomem *addr_cena;
-+ void __iomem *addr_cinh;
-+};
-+
-+/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal
-+ * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH)
-+ * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index
-+ * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal)
-+ * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE)
-+ * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete)
-+ */
-+
-+static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset,
-+ uint32_t val)
-+{
-+
-+ writel_relaxed(val, s->addr_cinh + offset);
-+#ifdef QBMAN_CINH_TRACE
-+ pr_info("qbman_cinh_write(%p:0x%03x) 0x%08x\n",
-+ s->addr_cinh, offset, val);
-+#endif
-+}
-+
-+static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset)
-+{
-+ uint32_t reg = readl_relaxed(s->addr_cinh + offset);
-+
-+#ifdef QBMAN_CINH_TRACE
-+ pr_info("qbman_cinh_read(%p:0x%03x) 0x%08x\n",
-+ s->addr_cinh, offset, reg);
-+#endif
-+ return reg;
-+}
-+
-+static inline void *qbman_cena_write_start(struct qbman_swp_sys *s,
-+ uint32_t offset)
-+{
-+ void *shadow = s->cena + offset;
-+
-+#ifdef QBMAN_CENA_TRACE
-+ pr_info("qbman_cena_write_start(%p:0x%03x) %p\n",
-+ s->addr_cena, offset, shadow);
-+#endif
-+ BUG_ON(offset & 63);
-+ dcbz(shadow);
-+ return shadow;
-+}
-+
-+static inline void qbman_cena_write_complete(struct qbman_swp_sys *s,
-+ uint32_t offset, void *cmd)
-+{
-+ const uint32_t *shadow = cmd;
-+ int loop;
-+
-+#ifdef QBMAN_CENA_TRACE
-+ pr_info("qbman_cena_write_complete(%p:0x%03x) %p\n",
-+ s->addr_cena, offset, shadow);
-+ hexdump(cmd, 64);
-+#endif
-+ for (loop = 15; loop >= 1; loop--)
-+ writel_relaxed(shadow[loop], s->addr_cena +
-+ offset + loop * 4);
-+ lwsync();
-+ writel_relaxed(shadow[0], s->addr_cena + offset);
-+ dcbf(s->addr_cena + offset);
-+}
-+
-+static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset)
-+{
-+ uint32_t *shadow = s->cena + offset;
-+ unsigned int loop;
-+
-+#ifdef QBMAN_CENA_TRACE
-+ pr_info("qbman_cena_read(%p:0x%03x) %p\n",
-+ s->addr_cena, offset, shadow);
-+#endif
-+
-+ for (loop = 0; loop < 16; loop++)
-+ shadow[loop] = readl_relaxed(s->addr_cena + offset
-+ + loop * 4);
-+#ifdef QBMAN_CENA_TRACE
-+ hexdump(shadow, 64);
-+#endif
-+ return shadow;
-+}
-+
-+static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s,
-+ uint32_t offset)
-+{
-+ dcivac(s->addr_cena + offset);
-+ prefetch_for_load(s->addr_cena + offset);
-+}
-+
-+ /******************/
-+ /* Portal support */
-+ /******************/
-+
-+/* The SWP_CFG portal register is special, in that it is used by the
-+ * platform-specific code rather than the platform-independent code in
-+ * qbman_portal.c. So use of it is declared locally here. */
-+#define QBMAN_CINH_SWP_CFG 0xd00
-+
-+/* For MC portal use, we always configure with
-+ * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4)
-+ * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x0)
-+ * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3)
-+ * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2)
-+ * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x3)
-+ * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- FALSE)
-+ * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE)
-+ * SE is (SWP_CFG,3,1) - memory stashing enable (<- 0x0)
-+ * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE)
-+ * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- 0x0)
-+ * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- FALSE)
-+ */
-+static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,
-+ uint8_t est, uint8_t rpm, uint8_t dcm,
-+ uint8_t epm, int sd, int sp, int se,
-+ int dp, int de, int ep)
-+{
-+ uint32_t reg;
-+
-+ reg = e32_uint8_t(20, (uint32_t)(3 + (max_fill >> 3)), max_fill) |
-+ e32_uint8_t(16, 3, est) | e32_uint8_t(12, 2, rpm) |
-+ e32_uint8_t(10, 2, dcm) | e32_uint8_t(8, 2, epm) |
-+ e32_int(5, 1, sd) | e32_int(4, 1, sp) | e32_int(3, 1, se) |
-+ e32_int(2, 1, dp) | e32_int(1, 1, de) | e32_int(0, 1, ep) |
-+ e32_uint8_t(14, 1, wn);
-+ return reg;
-+}
-+
-+static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,
-+ const struct qbman_swp_desc *d,
-+ uint8_t dqrr_size)
-+{
-+ uint32_t reg;
-+
-+ s->addr_cena = d->cena_bar;
-+ s->addr_cinh = d->cinh_bar;
-+ s->cena = (void *)get_zeroed_page(GFP_KERNEL);
-+ if (!s->cena) {
-+ pr_err("Could not allocate page for cena shadow\n");
-+ return -1;
-+ }
-+
-+#ifdef QBMAN_CHECKING
-+ /* We should never be asked to initialise for a portal that isn't in
-+ * the power-on state. (Ie. don't forget to reset portals when they are
-+ * decommissioned!)
-+ */
-+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
-+ BUG_ON(reg);
-+#endif
-+ reg = qbman_set_swp_cfg(dqrr_size, 0, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0);
-+ qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);
-+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
-+ if (!reg) {
-+ pr_err("The portal is not enabled!\n");
-+ kfree(s->cena);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)
-+{
-+ free_page((unsigned long)s->cena);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_sys_decl.h
-@@ -0,0 +1,86 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/io.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/bootmem.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/memblock.h>
-+#include <linux/completion.h>
-+#include <linux/log2.h>
-+#include <linux/types.h>
-+#include <linux/ioctl.h>
-+#include <linux/device.h>
-+#include <linux/smp.h>
-+#include <linux/vmalloc.h>
-+#include "fsl_qbman_base.h"
-+
-+/* The platform-independent code shouldn't need endianness, except for
-+ * weird/fast-path cases like qbman_result_has_token(), which needs to
-+ * perform a passive and endianness-specific test on a read-only data structure
-+ * very quickly. It's an exception, and this symbol is used for that case. */
-+#if defined(__BIG_ENDIAN)
-+#define DQRR_TOK_OFFSET 0
-+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 24
-+#define SCN_STATE_OFFSET_IN_MEM 8
-+#define SCN_RID_OFFSET_IN_MEM 8
-+#else
-+#define DQRR_TOK_OFFSET 24
-+#define QBMAN_RESULT_VERB_OFFSET_IN_MEM 0
-+#define SCN_STATE_OFFSET_IN_MEM 16
-+#define SCN_RID_OFFSET_IN_MEM 0
-+#endif
-+
-+/* Similarly-named functions */
-+#define upper32(a) upper_32_bits(a)
-+#define lower32(a) lower_32_bits(a)
-+
-+ /****************/
-+ /* arch assists */
-+ /****************/
-+
-+#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
-+#define lwsync() { asm volatile("dmb st" : : : "memory"); }
-+#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
-+#define dcivac(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
-+static inline void prefetch_for_load(void *p)
-+{
-+ asm volatile("prfm pldl1keep, [%0, #64]" : : "r" (p));
-+}
-+static inline void prefetch_for_store(void *p)
-+{
-+ asm volatile("prfm pstl1keep, [%0, #64]" : : "r" (p));
-+}
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_test.c
-@@ -0,0 +1,664 @@
-+/* Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+
-+#include "qbman_private.h"
-+#include "fsl_qbman_portal.h"
-+#include "qbman_debug.h"
-+#include "../../include/fsl_dpaa2_fd.h"
-+
-+#define QBMAN_SWP_CENA_BASE 0x818000000
-+#define QBMAN_SWP_CINH_BASE 0x81c000000
-+
-+#define QBMAN_PORTAL_IDX 2
-+#define QBMAN_TEST_FQID 19
-+#define QBMAN_TEST_BPID 23
-+#define QBMAN_USE_QD
-+#ifdef QBMAN_USE_QD
-+#define QBMAN_TEST_QDID 1
-+#endif
-+#define QBMAN_TEST_LFQID 0xf00010
-+
-+#define NUM_EQ_FRAME 10
-+#define NUM_DQ_FRAME 10
-+#define NUM_DQ_IN_DQRR 5
-+#define NUM_DQ_IN_MEM (NUM_DQ_FRAME - NUM_DQ_IN_DQRR)
-+
-+static struct qbman_swp *swp;
-+static struct qbman_eq_desc eqdesc;
-+static struct qbman_pull_desc pulldesc;
-+static struct qbman_release_desc releasedesc;
-+static struct qbman_eq_response eq_storage[1];
-+static struct dpaa2_dq dq_storage[NUM_DQ_IN_MEM] __aligned(64);
-+static dma_addr_t eq_storage_phys;
-+static dma_addr_t dq_storage_phys;
-+
-+/* FQ ctx attribute values for the test code. */
-+#define FQCTX_HI 0xabbaf00d
-+#define FQCTX_LO 0x98765432
-+#define FQ_VFQID 0x123456
-+
-+/* Sample frame descriptor */
-+static struct qbman_fd_simple fd = {
-+ .addr_lo = 0xbabaf33d,
-+ .addr_hi = 0x01234567,
-+ .len = 0x7777,
-+ .frc = 0xdeadbeef,
-+ .flc_lo = 0xcafecafe,
-+ .flc_hi = 0xbeadabba
-+};
-+
-+static void fd_inc(struct qbman_fd_simple *_fd)
-+{
-+ _fd->addr_lo += _fd->len;
-+ _fd->flc_lo += 0x100;
-+ _fd->frc += 0x10;
-+}
-+
-+static int fd_cmp(struct qbman_fd *fda, struct qbman_fd *fdb)
-+{
-+ int i;
-+
-+ for (i = 0; i < 8; i++)
-+ if (fda->words[i] - fdb->words[i])
-+ return 1;
-+ return 0;
-+}
-+
-+struct qbman_fd fd_eq[NUM_EQ_FRAME];
-+struct qbman_fd fd_dq[NUM_DQ_FRAME];
-+
-+/* "Buffers" to be released (and storage for buffers to be acquired) */
-+static uint64_t rbufs[320];
-+static uint64_t abufs[320];
-+
-+static void do_enqueue(struct qbman_swp *swp)
-+{
-+ int i, j, ret;
-+
-+#ifdef QBMAN_USE_QD
-+ pr_info("*****QBMan_test: Enqueue %d frames to QD %d\n",
-+ NUM_EQ_FRAME, QBMAN_TEST_QDID);
-+#else
-+ pr_info("*****QBMan_test: Enqueue %d frames to FQ %d\n",
-+ NUM_EQ_FRAME, QBMAN_TEST_FQID);
-+#endif
-+ for (i = 0; i < NUM_EQ_FRAME; i++) {
-+ /*********************************/
-+ /* Prepare a enqueue descriptor */
-+ /*********************************/
-+ memset(eq_storage, 0, sizeof(eq_storage));
-+ eq_storage_phys = virt_to_phys(eq_storage);
-+ qbman_eq_desc_clear(&eqdesc);
-+ qbman_eq_desc_set_no_orp(&eqdesc, 0);
-+ qbman_eq_desc_set_response(&eqdesc, eq_storage_phys, 0);
-+ qbman_eq_desc_set_token(&eqdesc, 0x99);
-+#ifdef QBMAN_USE_QD
-+ /**********************************/
-+ /* Prepare a Queueing Destination */
-+ /**********************************/
-+ qbman_eq_desc_set_qd(&eqdesc, QBMAN_TEST_QDID, 0, 3);
-+#else
-+ qbman_eq_desc_set_fq(&eqdesc, QBMAN_TEST_FQID);
-+#endif
-+
-+ /******************/
-+ /* Try an enqueue */
-+ /******************/
-+ ret = qbman_swp_enqueue(swp, &eqdesc,
-+ (const struct qbman_fd *)&fd);
-+ BUG_ON(ret);
-+ for (j = 0; j < 8; j++)
-+ fd_eq[i].words[j] = *((uint32_t *)&fd + j);
-+ fd_inc(&fd);
-+ }
-+}
-+
-+static void do_push_dequeue(struct qbman_swp *swp)
-+{
-+ int i, j;
-+ const struct dpaa2_dq *dq_storage1;
-+ const struct qbman_fd *__fd;
-+ int loopvar;
-+
-+ pr_info("*****QBMan_test: Start push dequeue\n");
-+ for (i = 0; i < NUM_DQ_FRAME; i++) {
-+ DBG_POLL_START(loopvar);
-+ do {
-+ DBG_POLL_CHECK(loopvar);
-+ dq_storage1 = qbman_swp_dqrr_next(swp);
-+ } while (!dq_storage1);
-+ if (dq_storage1) {
-+ __fd = (const struct qbman_fd *)
-+ dpaa2_dq_fd(dq_storage1);
-+ for (j = 0; j < 8; j++)
-+ fd_dq[i].words[j] = __fd->words[j];
-+ if (fd_cmp(&fd_eq[i], &fd_dq[i])) {
-+ pr_info("enqueue FD is\n");
-+ hexdump(&fd_eq[i], 32);
-+ pr_info("dequeue FD is\n");
-+ hexdump(&fd_dq[i], 32);
-+ }
-+ qbman_swp_dqrr_consume(swp, dq_storage1);
-+ } else {
-+ pr_info("The push dequeue fails\n");
-+ }
-+ }
-+}
-+
-+static void do_pull_dequeue(struct qbman_swp *swp)
-+{
-+ int i, j, ret;
-+ const struct dpaa2_dq *dq_storage1;
-+ const struct qbman_fd *__fd;
-+ int loopvar;
-+
-+ pr_info("*****QBMan_test: Dequeue %d frames with dq entry in DQRR\n",
-+ NUM_DQ_IN_DQRR);
-+ for (i = 0; i < NUM_DQ_IN_DQRR; i++) {
-+ qbman_pull_desc_clear(&pulldesc);
-+ qbman_pull_desc_set_storage(&pulldesc, NULL, 0, 0);
-+ qbman_pull_desc_set_numframes(&pulldesc, 1);
-+ qbman_pull_desc_set_fq(&pulldesc, QBMAN_TEST_FQID);
-+
-+ ret = qbman_swp_pull(swp, &pulldesc);
-+ BUG_ON(ret);
-+ DBG_POLL_START(loopvar);
-+ do {
-+ DBG_POLL_CHECK(loopvar);
-+ dq_storage1 = qbman_swp_dqrr_next(swp);
-+ } while (!dq_storage1);
-+
-+ if (dq_storage1) {
-+ __fd = (const struct qbman_fd *)
-+ dpaa2_dq_fd(dq_storage1);
-+ for (j = 0; j < 8; j++)
-+ fd_dq[i].words[j] = __fd->words[j];
-+ if (fd_cmp(&fd_eq[i], &fd_dq[i])) {
-+ pr_info("enqueue FD is\n");
-+ hexdump(&fd_eq[i], 32);
-+ pr_info("dequeue FD is\n");
-+ hexdump(&fd_dq[i], 32);
-+ }
-+ qbman_swp_dqrr_consume(swp, dq_storage1);
-+ } else {
-+ pr_info("Dequeue with dq entry in DQRR fails\n");
-+ }
-+ }
-+
-+ pr_info("*****QBMan_test: Dequeue %d frames with dq entry in memory\n",
-+ NUM_DQ_IN_MEM);
-+ for (i = 0; i < NUM_DQ_IN_MEM; i++) {
-+ dq_storage_phys = virt_to_phys(&dq_storage[i]);
-+ qbman_pull_desc_clear(&pulldesc);
-+ qbman_pull_desc_set_storage(&pulldesc, &dq_storage[i],
-+ dq_storage_phys, 1);
-+ qbman_pull_desc_set_numframes(&pulldesc, 1);
-+ qbman_pull_desc_set_fq(&pulldesc, QBMAN_TEST_FQID);
-+ ret = qbman_swp_pull(swp, &pulldesc);
-+ BUG_ON(ret);
-+
-+ DBG_POLL_START(loopvar);
-+ do {
-+ DBG_POLL_CHECK(loopvar);
-+ ret = qbman_result_has_new_result(swp,
-+ &dq_storage[i]);
-+ } while (!ret);
-+
-+ if (ret) {
-+ for (j = 0; j < 8; j++)
-+ fd_dq[i + NUM_DQ_IN_DQRR].words[j] =
-+ dq_storage[i].dont_manipulate_directly[j + 8];
-+ j = i + NUM_DQ_IN_DQRR;
-+ if (fd_cmp(&fd_eq[j], &fd_dq[j])) {
-+ pr_info("enqueue FD is\n");
-+ hexdump(&fd_eq[i + NUM_DQ_IN_DQRR], 32);
-+ pr_info("dequeue FD is\n");
-+ hexdump(&fd_dq[i + NUM_DQ_IN_DQRR], 32);
-+ hexdump(&dq_storage[i], 64);
-+ }
-+ } else {
-+ pr_info("Dequeue with dq entry in memory fails\n");
-+ }
-+ }
-+}
-+
-+static void release_buffer(struct qbman_swp *swp, unsigned int num)
-+{
-+ int ret;
-+ unsigned int i, j;
-+
-+ qbman_release_desc_clear(&releasedesc);
-+ qbman_release_desc_set_bpid(&releasedesc, QBMAN_TEST_BPID);
-+ pr_info("*****QBMan_test: Release %d buffers to BP %d\n",
-+ num, QBMAN_TEST_BPID);
-+ for (i = 0; i < (num / 7 + 1); i++) {
-+ j = ((num - i * 7) > 7) ? 7 : (num - i * 7);
-+ ret = qbman_swp_release(swp, &releasedesc, &rbufs[i * 7], j);
-+ BUG_ON(ret);
-+ }
-+}
-+
-+static void acquire_buffer(struct qbman_swp *swp, unsigned int num)
-+{
-+ int ret;
-+ unsigned int i, j;
-+
-+ pr_info("*****QBMan_test: Acquire %d buffers from BP %d\n",
-+ num, QBMAN_TEST_BPID);
-+
-+ for (i = 0; i < (num / 7 + 1); i++) {
-+ j = ((num - i * 7) > 7) ? 7 : (num - i * 7);
-+ ret = qbman_swp_acquire(swp, QBMAN_TEST_BPID, &abufs[i * 7], j);
-+ BUG_ON(ret != j);
-+ }
-+}
-+
-+static void buffer_pool_test(struct qbman_swp *swp)
-+{
-+ struct qbman_attr info;
-+ struct dpaa2_dq *bpscn_message;
-+ dma_addr_t bpscn_phys;
-+ uint64_t bpscn_ctx;
-+ uint64_t ctx = 0xbbccddaadeadbeefull;
-+ int i, ret;
-+ uint32_t hw_targ;
-+
-+ pr_info("*****QBMan_test: test buffer pool management\n");
-+ ret = qbman_bp_query(swp, QBMAN_TEST_BPID, &info);
-+ qbman_bp_attr_get_bpscn_addr(&info, &bpscn_phys);
-+ pr_info("The bpscn is %llx, info_phys is %llx\n", bpscn_phys,
-+ virt_to_phys(&info));
-+ bpscn_message = phys_to_virt(bpscn_phys);
-+
-+ for (i = 0; i < 320; i++)
-+ rbufs[i] = 0xf00dabba01234567ull + i * 0x40;
-+
-+ release_buffer(swp, 320);
-+
-+ pr_info("QBMan_test: query the buffer pool\n");
-+ qbman_bp_query(swp, QBMAN_TEST_BPID, &info);
-+ hexdump(&info, 64);
-+ qbman_bp_attr_get_hw_targ(&info, &hw_targ);
-+ pr_info("hw_targ is %d\n", hw_targ);
-+
-+ /* Acquire buffers to trigger BPSCN */
-+ acquire_buffer(swp, 300);
-+ /* BPSCN should be written to the memory */
-+ qbman_bp_query(swp, QBMAN_TEST_BPID, &info);
-+ hexdump(&info, 64);
-+ hexdump(bpscn_message, 64);
-+ BUG_ON(!qbman_result_is_BPSCN(bpscn_message));
-+ /* There should be free buffers in the pool */
-+ BUG_ON(!(qbman_result_bpscn_has_free_bufs(bpscn_message)));
-+ /* Buffer pool is depleted */
-+ BUG_ON(!qbman_result_bpscn_is_depleted(bpscn_message));
-+ /* The ctx should match */
-+ bpscn_ctx = qbman_result_bpscn_ctx(bpscn_message);
-+ pr_info("BPSCN test: ctx %llx, bpscn_ctx %llx\n", ctx, bpscn_ctx);
-+ BUG_ON(ctx != bpscn_ctx);
-+ memset(bpscn_message, 0, sizeof(struct dpaa2_dq));
-+
-+ /* Re-seed the buffer pool to trigger BPSCN */
-+ release_buffer(swp, 240);
-+ /* BPSCN should be written to the memory */
-+ BUG_ON(!qbman_result_is_BPSCN(bpscn_message));
-+ /* There should be free buffers in the pool */
-+ BUG_ON(!(qbman_result_bpscn_has_free_bufs(bpscn_message)));
-+ /* Buffer pool is not depleted */
-+ BUG_ON(qbman_result_bpscn_is_depleted(bpscn_message));
-+ memset(bpscn_message, 0, sizeof(struct dpaa2_dq));
-+
-+ acquire_buffer(swp, 260);
-+ /* BPSCN should be written to the memory */
-+ BUG_ON(!qbman_result_is_BPSCN(bpscn_message));
-+ /* There should be free buffers in the pool while BPSCN generated */
-+ BUG_ON(!(qbman_result_bpscn_has_free_bufs(bpscn_message)));
-+ /* Buffer pool is depletion */
-+ BUG_ON(!qbman_result_bpscn_is_depleted(bpscn_message));
-+}
-+
-+static void ceetm_test(struct qbman_swp *swp)
-+{
-+ int i, j, ret;
-+
-+ qbman_eq_desc_clear(&eqdesc);
-+ qbman_eq_desc_set_no_orp(&eqdesc, 0);
-+ qbman_eq_desc_set_fq(&eqdesc, QBMAN_TEST_LFQID);
-+ pr_info("*****QBMan_test: Enqueue to LFQID %x\n",
-+ QBMAN_TEST_LFQID);
-+ for (i = 0; i < NUM_EQ_FRAME; i++) {
-+ ret = qbman_swp_enqueue(swp, &eqdesc,
-+ (const struct qbman_fd *)&fd);
-+ BUG_ON(ret);
-+ for (j = 0; j < 8; j++)
-+ fd_eq[i].words[j] = *((uint32_t *)&fd + j);
-+ fd_inc(&fd);
-+ }
-+}
-+
-+int qbman_test(void)
-+{
-+ struct qbman_swp_desc pd;
-+ uint32_t reg;
-+
-+ pd.cena_bar = ioremap_cache_ns(QBMAN_SWP_CENA_BASE +
-+ QBMAN_PORTAL_IDX * 0x10000, 0x10000);
-+ pd.cinh_bar = ioremap(QBMAN_SWP_CINH_BASE +
-+ QBMAN_PORTAL_IDX * 0x10000, 0x10000);
-+
-+ /* Detect whether the mc image is the test image with GPP setup */
-+ reg = readl_relaxed(pd.cena_bar + 0x4);
-+ if (reg != 0xdeadbeef) {
-+ pr_err("The MC image doesn't have GPP test setup, stop!\n");
-+ iounmap(pd.cena_bar);
-+ iounmap(pd.cinh_bar);
-+ return -1;
-+ }
-+
-+ pr_info("*****QBMan_test: Init QBMan SWP %d\n", QBMAN_PORTAL_IDX);
-+ swp = qbman_swp_init(&pd);
-+ if (!swp) {
-+ iounmap(pd.cena_bar);
-+ iounmap(pd.cinh_bar);
-+ return -1;
-+ }
-+
-+ /*******************/
-+ /* Enqueue frames */
-+ /*******************/
-+ do_enqueue(swp);
-+
-+ /*******************/
-+ /* Do pull dequeue */
-+ /*******************/
-+ do_pull_dequeue(swp);
-+
-+ /*******************/
-+ /* Enqueue frames */
-+ /*******************/
-+ qbman_swp_push_set(swp, 0, 1);
-+ qbman_swp_fq_schedule(swp, QBMAN_TEST_FQID);
-+ do_enqueue(swp);
-+
-+ /*******************/
-+ /* Do push dequeue */
-+ /*******************/
-+ do_push_dequeue(swp);
-+
-+ /**************************/
-+ /* Test buffer pool funcs */
-+ /**************************/
-+ buffer_pool_test(swp);
-+
-+ /******************/
-+ /* CEETM test */
-+ /******************/
-+ ceetm_test(swp);
-+
-+ qbman_swp_finish(swp);
-+ pr_info("*****QBMan_test: Kernel test Passed\n");
-+ return 0;
-+}
-+
-+/* user-space test-case, definitions:
-+ *
-+ * 1 portal only, using portal index 3.
-+ */
-+
-+#include <linux/uaccess.h>
-+#include <linux/ioctl.h>
-+#include <linux/miscdevice.h>
-+#include <linux/fs.h>
-+#include <linux/cdev.h>
-+#include <linux/mm.h>
-+#include <linux/mman.h>
-+
-+#define QBMAN_TEST_US_SWP 3 /* portal index for user space */
-+
-+#define QBMAN_TEST_MAGIC 'q'
-+struct qbman_test_swp_ioctl {
-+ unsigned long portal1_cinh;
-+ unsigned long portal1_cena;
-+};
-+struct qbman_test_dma_ioctl {
-+ unsigned long ptr;
-+ uint64_t phys_addr;
-+};
-+
-+struct qbman_test_priv {
-+ int has_swp_map;
-+ int has_dma_map;
-+ unsigned long pgoff;
-+};
-+
-+#define QBMAN_TEST_SWP_MAP \
-+ _IOR(QBMAN_TEST_MAGIC, 0x01, struct qbman_test_swp_ioctl)
-+#define QBMAN_TEST_SWP_UNMAP \
-+ _IOR(QBMAN_TEST_MAGIC, 0x02, struct qbman_test_swp_ioctl)
-+#define QBMAN_TEST_DMA_MAP \
-+ _IOR(QBMAN_TEST_MAGIC, 0x03, struct qbman_test_dma_ioctl)
-+#define QBMAN_TEST_DMA_UNMAP \
-+ _IOR(QBMAN_TEST_MAGIC, 0x04, struct qbman_test_dma_ioctl)
-+
-+#define TEST_PORTAL1_CENA_PGOFF ((QBMAN_SWP_CENA_BASE + QBMAN_TEST_US_SWP * \
-+ 0x10000) >> PAGE_SHIFT)
-+#define TEST_PORTAL1_CINH_PGOFF ((QBMAN_SWP_CINH_BASE + QBMAN_TEST_US_SWP * \
-+ 0x10000) >> PAGE_SHIFT)
-+
-+static int qbman_test_open(struct inode *inode, struct file *filp)
-+{
-+ struct qbman_test_priv *priv;
-+
-+ priv = kmalloc(sizeof(struct qbman_test_priv), GFP_KERNEL);
-+ if (!priv)
-+ return -EIO;
-+ filp->private_data = priv;
-+ priv->has_swp_map = 0;
-+ priv->has_dma_map = 0;
-+ priv->pgoff = 0;
-+ return 0;
-+}
-+
-+static int qbman_test_mmap(struct file *filp, struct vm_area_struct *vma)
-+{
-+ int ret;
-+ struct qbman_test_priv *priv = filp->private_data;
-+
-+ BUG_ON(!priv);
-+
-+ if (vma->vm_pgoff == TEST_PORTAL1_CINH_PGOFF)
-+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+ else if (vma->vm_pgoff == TEST_PORTAL1_CENA_PGOFF)
-+ vma->vm_page_prot = pgprot_cached_ns(vma->vm_page_prot);
-+ else if (vma->vm_pgoff == priv->pgoff)
-+ vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
-+ else {
-+ pr_err("Damn, unrecognised pg_off!!\n");
-+ return -EINVAL;
-+ }
-+ ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-+ vma->vm_end - vma->vm_start,
-+ vma->vm_page_prot);
-+ return ret;
-+}
-+
-+static long qbman_test_ioctl(struct file *fp, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ void __user *a = (void __user *)arg;
-+ unsigned long longret, populate;
-+ int ret = 0;
-+ struct qbman_test_priv *priv = fp->private_data;
-+
-+ BUG_ON(!priv);
-+
-+ switch (cmd) {
-+ case QBMAN_TEST_SWP_MAP:
-+ {
-+ struct qbman_test_swp_ioctl params;
-+
-+ if (priv->has_swp_map)
-+ return -EINVAL;
-+ down_write(&current->mm->mmap_sem);
-+ /* Map portal1 CINH */
-+ longret = do_mmap_pgoff(fp, PAGE_SIZE, 0x10000,
-+ PROT_READ | PROT_WRITE, MAP_SHARED,
-+ TEST_PORTAL1_CINH_PGOFF, &populate);
-+ if (longret & ~PAGE_MASK) {
-+ ret = (int)longret;
-+ goto out;
-+ }
-+ params.portal1_cinh = longret;
-+ /* Map portal1 CENA */
-+ longret = do_mmap_pgoff(fp, PAGE_SIZE, 0x10000,
-+ PROT_READ | PROT_WRITE, MAP_SHARED,
-+ TEST_PORTAL1_CENA_PGOFF, &populate);
-+ if (longret & ~PAGE_MASK) {
-+ ret = (int)longret;
-+ goto out;
-+ }
-+ params.portal1_cena = longret;
-+ priv->has_swp_map = 1;
-+out:
-+ up_write(&current->mm->mmap_sem);
-+ if (!ret && copy_to_user(a, &params, sizeof(params)))
-+ return -EFAULT;
-+ return ret;
-+ }
-+ case QBMAN_TEST_SWP_UNMAP:
-+ {
-+ struct qbman_test_swp_ioctl params;
-+
-+ if (!priv->has_swp_map)
-+ return -EINVAL;
-+
-+ if (copy_from_user(&params, a, sizeof(params)))
-+ return -EFAULT;
-+ down_write(&current->mm->mmap_sem);
-+ do_munmap(current->mm, params.portal1_cena, 0x10000);
-+ do_munmap(current->mm, params.portal1_cinh, 0x10000);
-+ up_write(&current->mm->mmap_sem);
-+ priv->has_swp_map = 0;
-+ return 0;
-+ }
-+ case QBMAN_TEST_DMA_MAP:
-+ {
-+ struct qbman_test_dma_ioctl params;
-+ void *vaddr;
-+
-+ if (priv->has_dma_map)
-+ return -EINVAL;
-+ vaddr = (void *)get_zeroed_page(GFP_KERNEL);
-+ params.phys_addr = virt_to_phys(vaddr);
-+ priv->pgoff = (unsigned long)params.phys_addr >> PAGE_SHIFT;
-+ down_write(&current->mm->mmap_sem);
-+ longret = do_mmap_pgoff(fp, PAGE_SIZE, PAGE_SIZE,
-+ PROT_READ | PROT_WRITE, MAP_SHARED,
-+ priv->pgoff, &populate);
-+ if (longret & ~PAGE_MASK) {
-+ ret = (int)longret;
-+ return ret;
-+ }
-+ params.ptr = longret;
-+ priv->has_dma_map = 1;
-+ up_write(&current->mm->mmap_sem);
-+ if (copy_to_user(a, &params, sizeof(params)))
-+ return -EFAULT;
-+ return 0;
-+ }
-+ case QBMAN_TEST_DMA_UNMAP:
-+ {
-+ struct qbman_test_dma_ioctl params;
-+
-+ if (!priv->has_dma_map)
-+ return -EINVAL;
-+ if (copy_from_user(&params, a, sizeof(params)))
-+ return -EFAULT;
-+ down_write(&current->mm->mmap_sem);
-+ do_munmap(current->mm, params.ptr, PAGE_SIZE);
-+ up_write(&current->mm->mmap_sem);
-+ free_page((unsigned long)phys_to_virt(params.phys_addr));
-+ priv->has_dma_map = 0;
-+ return 0;
-+ }
-+ default:
-+ pr_err("Bad ioctl cmd!\n");
-+ }
-+ return -EINVAL;
-+}
-+
-+static const struct file_operations qbman_fops = {
-+ .open = qbman_test_open,
-+ .mmap = qbman_test_mmap,
-+ .unlocked_ioctl = qbman_test_ioctl
-+};
-+
-+static struct miscdevice qbman_miscdev = {
-+ .name = "qbman-test",
-+ .fops = &qbman_fops,
-+ .minor = MISC_DYNAMIC_MINOR,
-+};
-+
-+static int qbman_miscdev_init;
-+
-+static int test_init(void)
-+{
-+ int ret = qbman_test();
-+
-+ if (!ret) {
-+ /* MC image supports the test cases, so instantiate the
-+ * character devic that the user-space test case will use to do
-+ * its memory mappings. */
-+ ret = misc_register(&qbman_miscdev);
-+ if (ret) {
-+ pr_err("qbman-test: failed to register misc device\n");
-+ return ret;
-+ }
-+ pr_info("qbman-test: misc device registered!\n");
-+ qbman_miscdev_init = 1;
-+ }
-+ return 0;
-+}
-+
-+static void test_exit(void)
-+{
-+ if (qbman_miscdev_init) {
-+ misc_deregister(&qbman_miscdev);
-+ qbman_miscdev_init = 0;
-+ }
-+}
-+
-+module_init(test_init);
-+module_exit(test_exit);
---- /dev/null
-+++ b/drivers/staging/fsl-mc/include/fsl_dpaa2_fd.h
-@@ -0,0 +1,774 @@
-+/* Copyright 2014 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#ifndef __FSL_DPAA2_FD_H
-+#define __FSL_DPAA2_FD_H
-+
-+/**
-+ * DOC: DPAA2 FD - Frame Descriptor APIs for DPAA2
-+ *
-+ * Frame Descriptors (FDs) are used to describe frame data in the DPAA2.
-+ * Frames can be enqueued and dequeued to Frame Queues which are consumed
-+ * by the various DPAA accelerators (WRIOP, SEC, PME, DCE)
-+ *
-+ * There are three types of frames: Single, Scatter Gather and Frame Lists.
-+ *
-+ * The set of APIs in this file must be used to create, manipulate and
-+ * query Frame Descriptor.
-+ *
-+ */
-+
-+/**
-+ * struct dpaa2_fd - Place-holder for FDs.
-+ * @words: for easier/faster copying the whole FD structure.
-+ * @addr_lo: the lower 32 bits of the address in FD.
-+ * @addr_hi: the upper 32 bits of the address in FD.
-+ * @len: the length field in FD.
-+ * @bpid_offset: represent the bpid and offset fields in FD
-+ * @frc: frame context
-+ * @ctrl: the 32bit control bits including dd, sc,... va, err.
-+ * @flc_lo: the lower 32bit of flow context.
-+ * @flc_hi: the upper 32bits of flow context.
-+ *
-+ * This structure represents the basic Frame Descriptor used in the system.
-+ * We represent it via the simplest form that we need for now. Different
-+ * overlays may be needed to support different options, etc. (It is impractical
-+ * to define One True Struct, because the resulting encoding routines (lots of
-+ * read-modify-writes) would be worst-case performance whether or not
-+ * circumstances required them.)
-+ */
-+struct dpaa2_fd {
-+ union {
-+ u32 words[8];
-+ struct dpaa2_fd_simple {
-+ u32 addr_lo;
-+ u32 addr_hi;
-+ u32 len;
-+ /* offset in the MS 16 bits, BPID in the LS 16 bits */
-+ u32 bpid_offset;
-+ u32 frc; /* frame context */
-+ /* "err", "va", "cbmt", "asal", [...] */
-+ u32 ctrl;
-+ /* flow context */
-+ u32 flc_lo;
-+ u32 flc_hi;
-+ } simple;
-+ };
-+};
-+
-+enum dpaa2_fd_format {
-+ dpaa2_fd_single = 0,
-+ dpaa2_fd_list,
-+ dpaa2_fd_sg
-+};
-+
-+/* Accessors for SG entry fields
-+ *
-+ * These setters and getters assume little endian format. For converting
-+ * between LE and cpu endianness, the specific conversion functions must be
-+ * called before the SGE contents are accessed by the core (on Rx),
-+ * respectively before the SG table is sent to hardware (on Tx)
-+ */
-+
-+/**
-+ * dpaa2_fd_get_addr() - get the addr field of frame descriptor
-+ * @fd: the given frame descriptor.
-+ *
-+ * Return the address in the frame descriptor.
-+ */
-+static inline dma_addr_t dpaa2_fd_get_addr(const struct dpaa2_fd *fd)
-+{
-+ return (dma_addr_t)((((uint64_t)fd->simple.addr_hi) << 32)
-+ + fd->simple.addr_lo);
-+}
-+
-+/**
-+ * dpaa2_fd_set_addr() - Set the addr field of frame descriptor
-+ * @fd: the given frame descriptor.
-+ * @addr: the address needs to be set in frame descriptor.
-+ */
-+static inline void dpaa2_fd_set_addr(struct dpaa2_fd *fd, dma_addr_t addr)
-+{
-+ fd->simple.addr_hi = upper_32_bits(addr);
-+ fd->simple.addr_lo = lower_32_bits(addr);
-+}
-+
-+/**
-+ * dpaa2_fd_get_frc() - Get the frame context in the frame descriptor
-+ * @fd: the given frame descriptor.
-+ *
-+ * Return the frame context field in the frame descriptor.
-+ */
-+static inline u32 dpaa2_fd_get_frc(const struct dpaa2_fd *fd)
-+{
-+ return fd->simple.frc;
-+}
-+
-+/**
-+ * dpaa2_fd_set_frc() - Set the frame context in the frame descriptor
-+ * @fd: the given frame descriptor.
-+ * @frc: the frame context needs to be set in frame descriptor.
-+ */
-+static inline void dpaa2_fd_set_frc(struct dpaa2_fd *fd, u32 frc)
-+{
-+ fd->simple.frc = frc;
-+}
-+
-+/**
-+ * dpaa2_fd_get_flc() - Get the flow context in the frame descriptor
-+ * @fd: the given frame descriptor.
-+ *
-+ * Return the flow context in the frame descriptor.
-+ */
-+static inline dma_addr_t dpaa2_fd_get_flc(const struct dpaa2_fd *fd)
-+{
-+ return (dma_addr_t)((((uint64_t)fd->simple.flc_hi) << 32) +
-+ fd->simple.flc_lo);
-+}
-+
-+/**
-+ * dpaa2_fd_set_flc() - Set the flow context field of frame descriptor
-+ * @fd: the given frame descriptor.
-+ * @flc_addr: the flow context needs to be set in frame descriptor.
-+ */
-+static inline void dpaa2_fd_set_flc(struct dpaa2_fd *fd, dma_addr_t flc_addr)
-+{
-+ fd->simple.flc_hi = upper_32_bits(flc_addr);
-+ fd->simple.flc_lo = lower_32_bits(flc_addr);
-+}
-+
-+/**
-+ * dpaa2_fd_get_len() - Get the length in the frame descriptor
-+ * @fd: the given frame descriptor.
-+ *
-+ * Return the length field in the frame descriptor.
-+ */
-+static inline u32 dpaa2_fd_get_len(const struct dpaa2_fd *fd)
-+{
-+ return fd->simple.len;
-+}
-+
-+/**
-+ * dpaa2_fd_set_len() - Set the length field of frame descriptor
-+ * @fd: the given frame descriptor.
-+ * @len: the length needs to be set in frame descriptor.
-+ */
-+static inline void dpaa2_fd_set_len(struct dpaa2_fd *fd, u32 len)
-+{
-+ fd->simple.len = len;
-+}
-+
-+/**
-+ * dpaa2_fd_get_offset() - Get the offset field in the frame descriptor
-+ * @fd: the given frame descriptor.
-+ *
-+ * Return the offset.
-+ */
-+static inline uint16_t dpaa2_fd_get_offset(const struct dpaa2_fd *fd)
-+{
-+ return (uint16_t)(fd->simple.bpid_offset >> 16) & 0x0FFF;
-+}
-+
-+/**
-+ * dpaa2_fd_set_offset() - Set the offset field of frame descriptor
-+ *
-+ * @fd: the given frame descriptor.
-+ * @offset: the offset needs to be set in frame descriptor.
-+ */
-+static inline void dpaa2_fd_set_offset(struct dpaa2_fd *fd, uint16_t offset)
-+{
-+ fd->simple.bpid_offset &= 0xF000FFFF;
-+ fd->simple.bpid_offset |= (u32)offset << 16;
-+}
-+
-+/**
-+ * dpaa2_fd_get_format() - Get the format field in the frame descriptor
-+ * @fd: the given frame descriptor.
-+ *
-+ * Return the format.
-+ */
-+static inline enum dpaa2_fd_format dpaa2_fd_get_format(
-+ const struct dpaa2_fd *fd)
-+{
-+ return (enum dpaa2_fd_format)((fd->simple.bpid_offset >> 28) & 0x3);
-+}
-+
-+/**
-+ * dpaa2_fd_set_format() - Set the format field of frame descriptor
-+ *
-+ * @fd: the given frame descriptor.
-+ * @format: the format needs to be set in frame descriptor.
-+ */
-+static inline void dpaa2_fd_set_format(struct dpaa2_fd *fd,
-+ enum dpaa2_fd_format format)
-+{
-+ fd->simple.bpid_offset &= 0xCFFFFFFF;
-+ fd->simple.bpid_offset |= (u32)format << 28;
-+}
-+
-+/**
-+ * dpaa2_fd_get_bpid() - Get the bpid field in the frame descriptor
-+ * @fd: the given frame descriptor.
-+ *
-+ * Return the bpid.
-+ */
-+static inline uint16_t dpaa2_fd_get_bpid(const struct dpaa2_fd *fd)
-+{
-+ return (uint16_t)(fd->simple.bpid_offset & 0xFFFF);
-+}
-+
-+/**
-+ * dpaa2_fd_set_bpid() - Set the bpid field of frame descriptor
-+ *
-+ * @fd: the given frame descriptor.
-+ * @bpid: the bpid needs to be set in frame descriptor.
-+ */
-+static inline void dpaa2_fd_set_bpid(struct dpaa2_fd *fd, uint16_t bpid)
-+{
-+ fd->simple.bpid_offset &= 0xFFFF0000;
-+ fd->simple.bpid_offset |= (u32)bpid;
-+}
-+
-+/**
-+ * struct dpaa2_sg_entry - the scatter-gathering structure
-+ * @addr_lo: the lower 32bit of address
-+ * @addr_hi: the upper 32bit of address
-+ * @len: the length in this sg entry.
-+ * @bpid_offset: offset in the MS 16 bits, BPID in the LS 16 bits.
-+ */
-+struct dpaa2_sg_entry {
-+ u32 addr_lo;
-+ u32 addr_hi;
-+ u32 len;
-+ u32 bpid_offset;
-+};
-+
-+enum dpaa2_sg_format {
-+ dpaa2_sg_single = 0,
-+ dpaa2_sg_frame_data,
-+ dpaa2_sg_sgt_ext
-+};
-+
-+/**
-+ * dpaa2_sg_get_addr() - Get the address from SG entry
-+ * @sg: the given scatter-gathering object.
-+ *
-+ * Return the address.
-+ */
-+static inline dma_addr_t dpaa2_sg_get_addr(const struct dpaa2_sg_entry *sg)
-+{
-+ return (dma_addr_t)((((u64)sg->addr_hi) << 32) + sg->addr_lo);
-+}
-+
-+/**
-+ * dpaa2_sg_set_addr() - Set the address in SG entry
-+ * @sg: the given scatter-gathering object.
-+ * @addr: the address to be set.
-+ */
-+static inline void dpaa2_sg_set_addr(struct dpaa2_sg_entry *sg, dma_addr_t addr)
-+{
-+ sg->addr_hi = upper_32_bits(addr);
-+ sg->addr_lo = lower_32_bits(addr);
-+}
-+
-+
-+static inline bool dpaa2_sg_short_len(const struct dpaa2_sg_entry *sg)
-+{
-+ return (sg->bpid_offset >> 30) & 0x1;
-+}
-+
-+/**
-+ * dpaa2_sg_get_len() - Get the length in SG entry
-+ * @sg: the given scatter-gathering object.
-+ *
-+ * Return the length.
-+ */
-+static inline u32 dpaa2_sg_get_len(const struct dpaa2_sg_entry *sg)
-+{
-+ if (dpaa2_sg_short_len(sg))
-+ return sg->len & 0x1FFFF;
-+ return sg->len;
-+}
-+
-+/**
-+ * dpaa2_sg_set_len() - Set the length in SG entry
-+ * @sg: the given scatter-gathering object.
-+ * @len: the length to be set.
-+ */
-+static inline void dpaa2_sg_set_len(struct dpaa2_sg_entry *sg, u32 len)
-+{
-+ sg->len = len;
-+}
-+
-+/**
-+ * dpaa2_sg_get_offset() - Get the offset in SG entry
-+ * @sg: the given scatter-gathering object.
-+ *
-+ * Return the offset.
-+ */
-+static inline u16 dpaa2_sg_get_offset(const struct dpaa2_sg_entry *sg)
-+{
-+ return (u16)(sg->bpid_offset >> 16) & 0x0FFF;
-+}
-+
-+/**
-+ * dpaa2_sg_set_offset() - Set the offset in SG entry
-+ * @sg: the given scatter-gathering object.
-+ * @offset: the offset to be set.
-+ */
-+static inline void dpaa2_sg_set_offset(struct dpaa2_sg_entry *sg,
-+ u16 offset)
-+{
-+ sg->bpid_offset &= 0xF000FFFF;
-+ sg->bpid_offset |= (u32)offset << 16;
-+}
-+
-+/**
-+ * dpaa2_sg_get_format() - Get the SG format in SG entry
-+ * @sg: the given scatter-gathering object.
-+ *
-+ * Return the format.
-+ */
-+static inline enum dpaa2_sg_format
-+ dpaa2_sg_get_format(const struct dpaa2_sg_entry *sg)
-+{
-+ return (enum dpaa2_sg_format)((sg->bpid_offset >> 28) & 0x3);
-+}
-+
-+/**
-+ * dpaa2_sg_set_format() - Set the SG format in SG entry
-+ * @sg: the given scatter-gathering object.
-+ * @format: the format to be set.
-+ */
-+static inline void dpaa2_sg_set_format(struct dpaa2_sg_entry *sg,
-+ enum dpaa2_sg_format format)
-+{
-+ sg->bpid_offset &= 0xCFFFFFFF;
-+ sg->bpid_offset |= (u32)format << 28;
-+}
-+
-+/**
-+ * dpaa2_sg_get_bpid() - Get the buffer pool id in SG entry
-+ * @sg: the given scatter-gathering object.
-+ *
-+ * Return the bpid.
-+ */
-+static inline u16 dpaa2_sg_get_bpid(const struct dpaa2_sg_entry *sg)
-+{
-+ return (u16)(sg->bpid_offset & 0x3FFF);
-+}
-+
-+/**
-+ * dpaa2_sg_set_bpid() - Set the buffer pool id in SG entry
-+ * @sg: the given scatter-gathering object.
-+ * @bpid: the bpid to be set.
-+ */
-+static inline void dpaa2_sg_set_bpid(struct dpaa2_sg_entry *sg, u16 bpid)
-+{
-+ sg->bpid_offset &= 0xFFFFC000;
-+ sg->bpid_offset |= (u32)bpid;
-+}
-+
-+/**
-+ * dpaa2_sg_is_final() - Check final bit in SG entry
-+ * @sg: the given scatter-gathering object.
-+ *
-+ * Return bool.
-+ */
-+static inline bool dpaa2_sg_is_final(const struct dpaa2_sg_entry *sg)
-+{
-+ return !!(sg->bpid_offset >> 31);
-+}
-+
-+/**
-+ * dpaa2_sg_set_final() - Set the final bit in SG entry
-+ * @sg: the given scatter-gathering object.
-+ * @final: the final boolean to be set.
-+ */
-+static inline void dpaa2_sg_set_final(struct dpaa2_sg_entry *sg, bool final)
-+{
-+ sg->bpid_offset &= 0x7FFFFFFF;
-+ sg->bpid_offset |= (u32)final << 31;
-+}
-+
-+/* Endianness conversion helper functions
-+ * The accelerator drivers which construct / read scatter gather entries
-+ * need to call these in order to account for endianness mismatches between
-+ * hardware and cpu
-+ */
-+#ifdef __BIG_ENDIAN
-+/**
-+ * dpaa2_sg_cpu_to_le() - convert scatter gather entry from native cpu
-+ * format little endian format.
-+ * @sg: the given scatter gather entry.
-+ */
-+static inline void dpaa2_sg_cpu_to_le(struct dpaa2_sg_entry *sg)
-+{
-+ uint32_t *p = (uint32_t *)sg;
-+ int i;
-+
-+ for (i = 0; i < sizeof(*sg) / sizeof(u32); i++)
-+ cpu_to_le32s(p++);
-+}
-+
-+/**
-+ * dpaa2_sg_le_to_cpu() - convert scatter gather entry from little endian
-+ * format to native cpu format.
-+ * @sg: the given scatter gather entry.
-+ */
-+static inline void dpaa2_sg_le_to_cpu(struct dpaa2_sg_entry *sg)
-+{
-+ uint32_t *p = (uint32_t *)sg;
-+ int i;
-+
-+ for (i = 0; i < sizeof(*sg) / sizeof(u32); i++)
-+ le32_to_cpus(p++);
-+}
-+#else
-+#define dpaa2_sg_cpu_to_le(sg)
-+#define dpaa2_sg_le_to_cpu(sg)
-+#endif /* __BIG_ENDIAN */
-+
-+
-+/**
-+ * struct dpaa2_fl_entry - structure for frame list entry.
-+ * @addr_lo: the lower 32bit of address
-+ * @addr_hi: the upper 32bit of address
-+ * @len: the length in this sg entry.
-+ * @bpid_offset: offset in the MS 16 bits, BPID in the LS 16 bits.
-+ * @frc: frame context
-+ * @ctrl: the 32bit control bits including dd, sc,... va, err.
-+ * @flc_lo: the lower 32bit of flow context.
-+ * @flc_hi: the upper 32bits of flow context.
-+ *
-+ * Frame List Entry (FLE)
-+ * Identical to dpaa2_fd.simple layout, but some bits are different
-+ */
-+struct dpaa2_fl_entry {
-+ u32 addr_lo;
-+ u32 addr_hi;
-+ u32 len;
-+ u32 bpid_offset;
-+ u32 frc;
-+ u32 ctrl;
-+ u32 flc_lo;
-+ u32 flc_hi;
-+};
-+
-+enum dpaa2_fl_format {
-+ dpaa2_fl_single = 0,
-+ dpaa2_fl_res,
-+ dpaa2_fl_sg
-+};
-+
-+/**
-+ * dpaa2_fl_get_addr() - Get address in the frame list entry
-+ * @fle: the given frame list entry.
-+ *
-+ * Return address for the get function.
-+ */
-+static inline dma_addr_t dpaa2_fl_get_addr(const struct dpaa2_fl_entry *fle)
-+{
-+ return (dma_addr_t)((((uint64_t)fle->addr_hi) << 32) + fle->addr_lo);
-+}
-+
-+/**
-+ * dpaa2_fl_set_addr() - Set the address in the frame list entry
-+ * @fle: the given frame list entry.
-+ * @addr: the address needs to be set.
-+ *
-+ */
-+static inline void dpaa2_fl_set_addr(struct dpaa2_fl_entry *fle,
-+ dma_addr_t addr)
-+{
-+ fle->addr_hi = upper_32_bits(addr);
-+ fle->addr_lo = lower_32_bits(addr);
-+}
-+
-+/**
-+ * dpaa2_fl_get_flc() - Get the flow context in the frame list entry
-+ * @fle: the given frame list entry.
-+ *
-+ * Return flow context for the get function.
-+ */
-+static inline dma_addr_t dpaa2_fl_get_flc(const struct dpaa2_fl_entry *fle)
-+{
-+ return (dma_addr_t)((((uint64_t)fle->flc_hi) << 32) + fle->flc_lo);
-+}
-+
-+/**
-+ * dpaa2_fl_set_flc() - Set the flow context in the frame list entry
-+ * @fle: the given frame list entry.
-+ * @flc_addr: the flow context address needs to be set.
-+ *
-+ */
-+static inline void dpaa2_fl_set_flc(struct dpaa2_fl_entry *fle,
-+ dma_addr_t flc_addr)
-+{
-+ fle->flc_hi = upper_32_bits(flc_addr);
-+ fle->flc_lo = lower_32_bits(flc_addr);
-+}
-+
-+/**
-+ * dpaa2_fl_get_len() - Get the length in the frame list entry
-+ * @fle: the given frame list entry.
-+ *
-+ * Return length for the get function.
-+ */
-+static inline u32 dpaa2_fl_get_len(const struct dpaa2_fl_entry *fle)
-+{
-+ return fle->len;
-+}
-+
-+/**
-+ * dpaa2_fl_set_len() - Set the length in the frame list entry
-+ * @fle: the given frame list entry.
-+ * @len: the length needs to be set.
-+ *
-+ */
-+static inline void dpaa2_fl_set_len(struct dpaa2_fl_entry *fle, u32 len)
-+{
-+ fle->len = len;
-+}
-+
-+/**
-+ * dpaa2_fl_get_offset() - Get/Set the offset in the frame list entry
-+ * @fle: the given frame list entry.
-+ *
-+ * Return offset for the get function.
-+ */
-+static inline uint16_t dpaa2_fl_get_offset(const struct dpaa2_fl_entry *fle)
-+{
-+ return (uint16_t)(fle->bpid_offset >> 16) & 0x0FFF;
-+}
-+
-+/**
-+ * dpaa2_fl_set_offset() - Set the offset in the frame list entry
-+ * @fle: the given frame list entry.
-+ * @offset: the offset needs to be set.
-+ *
-+ */
-+static inline void dpaa2_fl_set_offset(struct dpaa2_fl_entry *fle,
-+ uint16_t offset)
-+{
-+ fle->bpid_offset &= 0xF000FFFF;
-+ fle->bpid_offset |= (u32)(offset & 0x0FFF) << 16;
-+}
-+
-+/**
-+ * dpaa2_fl_get_format() - Get the format in the frame list entry
-+ * @fle: the given frame list entry.
-+ *
-+ * Return frame list format for the get function.
-+ */
-+static inline enum dpaa2_fl_format dpaa2_fl_get_format(
-+ const struct dpaa2_fl_entry *fle)
-+{
-+ return (enum dpaa2_fl_format)((fle->bpid_offset >> 28) & 0x3);
-+}
-+
-+/**
-+ * dpaa2_fl_set_format() - Set the format in the frame list entry
-+ * @fle: the given frame list entry.
-+ * @format: the frame list format needs to be set.
-+ *
-+ */
-+static inline void dpaa2_fl_set_format(struct dpaa2_fl_entry *fle,
-+ enum dpaa2_fl_format format)
-+{
-+ fle->bpid_offset &= 0xCFFFFFFF;
-+ fle->bpid_offset |= (u32)(format & 0x3) << 28;
-+}
-+
-+/**
-+ * dpaa2_fl_get_bpid() - Get the buffer pool id in the frame list entry
-+ * @fle: the given frame list entry.
-+ *
-+ * Return bpid for the get function.
-+ */
-+static inline uint16_t dpaa2_fl_get_bpid(const struct dpaa2_fl_entry *fle)
-+{
-+ return (uint16_t)(fle->bpid_offset & 0x3FFF);
-+}
-+
-+/**
-+ * dpaa2_fl_set_bpid() - Set the buffer pool id in the frame list entry
-+ * @fle: the given frame list entry.
-+ * @bpid: the buffer pool id needs to be set.
-+ *
-+ */
-+static inline void dpaa2_fl_set_bpid(struct dpaa2_fl_entry *fle, uint16_t bpid)
-+{
-+ fle->bpid_offset &= 0xFFFFC000;
-+ fle->bpid_offset |= (u32)bpid;
-+}
-+
-+/** dpaa2_fl_is_final() - check the final bit is set or not in the frame list.
-+ * @fle: the given frame list entry.
-+ *
-+ * Return final bit settting.
-+ */
-+static inline bool dpaa2_fl_is_final(const struct dpaa2_fl_entry *fle)
-+{
-+ return !!(fle->bpid_offset >> 31);
-+}
-+
-+/**
-+ * dpaa2_fl_set_final() - Set the final bit in the frame list entry
-+ * @fle: the given frame list entry.
-+ * @final: the final bit needs to be set.
-+ *
-+ */
-+static inline void dpaa2_fl_set_final(struct dpaa2_fl_entry *fle, bool final)
-+{
-+ fle->bpid_offset &= 0x7FFFFFFF;
-+ fle->bpid_offset |= (u32)final << 31;
-+}
-+
-+/**
-+ * struct dpaa2_dq - the qman result structure
-+ * @dont_manipulate_directly: the 16 32bit data to represent the whole
-+ * possible qman dequeue result.
-+ *
-+ * When frames are dequeued, the FDs show up inside "dequeue" result structures
-+ * (if at all, not all dequeue results contain valid FDs). This structure type
-+ * is intentionally defined without internal detail, and the only reason it
-+ * isn't declared opaquely (without size) is to allow the user to provide
-+ * suitably-sized (and aligned) memory for these entries.
-+ */
-+struct dpaa2_dq {
-+ uint32_t dont_manipulate_directly[16];
-+};
-+
-+/* Parsing frame dequeue results */
-+/* FQ empty */
-+#define DPAA2_DQ_STAT_FQEMPTY 0x80
-+/* FQ held active */
-+#define DPAA2_DQ_STAT_HELDACTIVE 0x40
-+/* FQ force eligible */
-+#define DPAA2_DQ_STAT_FORCEELIGIBLE 0x20
-+/* Valid frame */
-+#define DPAA2_DQ_STAT_VALIDFRAME 0x10
-+/* FQ ODP enable */
-+#define DPAA2_DQ_STAT_ODPVALID 0x04
-+/* Volatile dequeue */
-+#define DPAA2_DQ_STAT_VOLATILE 0x02
-+/* volatile dequeue command is expired */
-+#define DPAA2_DQ_STAT_EXPIRED 0x01
-+
-+/**
-+ * dpaa2_dq_flags() - Get the stat field of dequeue response
-+ * @dq: the dequeue result.
-+ */
-+uint32_t dpaa2_dq_flags(const struct dpaa2_dq *dq);
-+
-+/**
-+ * dpaa2_dq_is_pull() - Check whether the dq response is from a pull
-+ * command.
-+ * @dq: the dequeue result.
-+ *
-+ * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
-+ */
-+static inline int dpaa2_dq_is_pull(const struct dpaa2_dq *dq)
-+{
-+ return (int)(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_VOLATILE);
-+}
-+
-+/**
-+ * dpaa2_dq_is_pull_complete() - Check whether the pull command is completed.
-+ * @dq: the dequeue result.
-+ *
-+ * Return boolean.
-+ */
-+static inline int dpaa2_dq_is_pull_complete(
-+ const struct dpaa2_dq *dq)
-+{
-+ return (int)(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_EXPIRED);
-+}
-+
-+/**
-+ * dpaa2_dq_seqnum() - Get the seqnum field in dequeue response
-+ * seqnum is valid only if VALIDFRAME flag is TRUE
-+ * @dq: the dequeue result.
-+ *
-+ * Return seqnum.
-+ */
-+uint16_t dpaa2_dq_seqnum(const struct dpaa2_dq *dq);
-+
-+/**
-+ * dpaa2_dq_odpid() - Get the seqnum field in dequeue response
-+ * odpid is valid only if ODPVAILD flag is TRUE.
-+ * @dq: the dequeue result.
-+ *
-+ * Return odpid.
-+ */
-+uint16_t dpaa2_dq_odpid(const struct dpaa2_dq *dq);
-+
-+/**
-+ * dpaa2_dq_fqid() - Get the fqid in dequeue response
-+ * @dq: the dequeue result.
-+ *
-+ * Return fqid.
-+ */
-+uint32_t dpaa2_dq_fqid(const struct dpaa2_dq *dq);
-+
-+/**
-+ * dpaa2_dq_byte_count() - Get the byte count in dequeue response
-+ * @dq: the dequeue result.
-+ *
-+ * Return the byte count remaining in the FQ.
-+ */
-+uint32_t dpaa2_dq_byte_count(const struct dpaa2_dq *dq);
-+
-+/**
-+ * dpaa2_dq_frame_count() - Get the frame count in dequeue response
-+ * @dq: the dequeue result.
-+ *
-+ * Return the frame count remaining in the FQ.
-+ */
-+uint32_t dpaa2_dq_frame_count(const struct dpaa2_dq *dq);
-+
-+/**
-+ * dpaa2_dq_fd_ctx() - Get the frame queue context in dequeue response
-+ * @dq: the dequeue result.
-+ *
-+ * Return the frame queue context.
-+ */
-+uint64_t dpaa2_dq_fqd_ctx(const struct dpaa2_dq *dq);
-+
-+/**
-+ * dpaa2_dq_fd() - Get the frame descriptor in dequeue response
-+ * @dq: the dequeue result.
-+ *
-+ * Return the frame descriptor.
-+ */
-+const struct dpaa2_fd *dpaa2_dq_fd(const struct dpaa2_dq *dq);
-+
-+#endif /* __FSL_DPAA2_FD_H */
---- /dev/null
-+++ b/drivers/staging/fsl-mc/include/fsl_dpaa2_io.h
-@@ -0,0 +1,619 @@
-+/* Copyright 2014 Freescale Semiconductor Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Freescale Semiconductor nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#ifndef __FSL_DPAA2_IO_H
-+#define __FSL_DPAA2_IO_H
-+
-+#include "fsl_dpaa2_fd.h"
-+
-+struct dpaa2_io;
-+struct dpaa2_io_store;
-+
-+/**
-+ * DOC: DPIO Service Management
-+ *
-+ * The DPIO service provides APIs for users to interact with the datapath
-+ * by enqueueing and dequeing frame descriptors.
-+ *
-+ * The following set of APIs can be used to enqueue and dequeue frames
-+ * as well as producing notification callbacks when data is available
-+ * for dequeue.
-+ */
-+
-+/**
-+ * struct dpaa2_io_desc - The DPIO descriptor.
-+ * @receives_notifications: Use notificaton mode.
-+ * @has_irq: use irq-based proessing.
-+ * @will_poll: use poll processing.
-+ * @has_8prio: set for channel with 8 priority WQs.
-+ * @cpu: the cpu index that at least interrupt handlers will execute on.
-+ * @stash_affinity: the stash affinity for this portal favour 'cpu'
-+ * @regs_cena: the cache enabled regs.
-+ * @regs_cinh: the cache inhibited regs.
-+ * @dpio_id: The dpio index.
-+ * @qman_version: the qman version
-+ *
-+ * Describe the attributes and features of the DPIO object.
-+ */
-+struct dpaa2_io_desc {
-+ /* non-zero iff the DPIO has a channel */
-+ int receives_notifications;
-+ /* non-zero if the DPIO portal interrupt is handled. If so, the
-+ * caller/OS handles the interrupt and calls dpaa2_io_service_irq(). */
-+ int has_irq;
-+ /* non-zero if the caller/OS is prepared to called the
-+ * dpaa2_io_service_poll() routine as part of its run-to-completion (or
-+ * scheduling) loop. If so, the DPIO service may dynamically switch some
-+ * of its processing between polling-based and irq-based. It is illegal
-+ * combination to have (!has_irq && !will_poll). */
-+ int will_poll;
-+ /* ignored unless 'receives_notifications'. Non-zero iff the channel has
-+ * 8 priority WQs, otherwise the channel has 2. */
-+ int has_8prio;
-+ /* the cpu index that at least interrupt handlers will execute on. And
-+ * if 'stash_affinity' is non-zero, the cache targeted by stash
-+ * transactions is affine to this cpu. */
-+ int cpu;
-+ /* non-zero if stash transactions for this portal favour 'cpu' over
-+ * other CPUs. (Eg. zero if there's no stashing, or stashing is to
-+ * shared cache.) */
-+ int stash_affinity;
-+ /* Caller-provided flags, determined by bus-scanning and/or creation of
-+ * DPIO objects via MC commands. */
-+ void *regs_cena;
-+ void *regs_cinh;
-+ int dpio_id;
-+ uint32_t qman_version;
-+};
-+
-+/**
-+ * dpaa2_io_create() - create a dpaa2_io object.
-+ * @desc: the dpaa2_io descriptor
-+ *
-+ * Activates a "struct dpaa2_io" corresponding to the given config of an actual
-+ * DPIO object. This handle can be used on it's own (like a one-portal "DPIO
-+ * service") or later be added to a service-type "struct dpaa2_io" object. Note,
-+ * the information required on 'cfg' is copied so the caller is free to do as
-+ * they wish with the input parameter upon return.
-+ *
-+ * Return a valid dpaa2_io object for success, or NULL for failure.
-+ */
-+struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc);
-+
-+/**
-+ * dpaa2_io_create_service() - Create an (initially empty) DPIO service.
-+ *
-+ * Return a valid dpaa2_io object for success, or NULL for failure.
-+ */
-+struct dpaa2_io *dpaa2_io_create_service(void);
-+
-+/**
-+ * dpaa2_io_default_service() - Use the driver's own global (and initially
-+ * empty) DPIO service.
-+ *
-+ * This increments the reference count, so don't forget to use dpaa2_io_down()
-+ * for each time this function is called.
-+ *
-+ * Return a valid dpaa2_io object for success, or NULL for failure.
-+ */
-+struct dpaa2_io *dpaa2_io_default_service(void);
-+
-+/**
-+ * dpaa2_io_down() - release the dpaa2_io object.
-+ * @d: the dpaa2_io object to be released.
-+ *
-+ * The "struct dpaa2_io" type can represent an individual DPIO object (as
-+ * described by "struct dpaa2_io_desc") or an instance of a "DPIO service",
-+ * which can be used to group/encapsulate multiple DPIO objects. In all cases,
-+ * each handle obtained should be released using this function.
-+ */
-+void dpaa2_io_down(struct dpaa2_io *d);
-+
-+/**
-+ * dpaa2_io_service_add() - Add the given DPIO object to the given DPIO service.
-+ * @service: the given DPIO service.
-+ * @obj: the given DPIO object.
-+ *
-+ * 'service' must have been created by dpaa2_io_create_service() and 'obj'
-+ * must have been created by dpaa2_io_create(). This increments the reference
-+ * count on the object that 'obj' refers to, so the user could call
-+ * dpaa2_io_down(obj) after this and the object will persist within the service
-+ * (and will be destroyed when the service is destroyed).
-+ *
-+ * Return 0 for success, or -EINVAL for failure.
-+ */
-+int dpaa2_io_service_add(struct dpaa2_io *service, struct dpaa2_io *obj);
-+
-+/**
-+ * dpaa2_io_get_descriptor() - Get the DPIO descriptor of the given DPIO object.
-+ * @obj: the given DPIO object.
-+ * @desc: the returned DPIO descriptor.
-+ *
-+ * This function will return failure if the given dpaa2_io struct represents a
-+ * service rather than an individual DPIO object, otherwise it returns zero and
-+ * the given 'cfg' structure is filled in.
-+ *
-+ * Return 0 for success, or -EINVAL for failure.
-+ */
-+int dpaa2_io_get_descriptor(struct dpaa2_io *obj, struct dpaa2_io_desc *desc);
-+
-+/**
-+ * dpaa2_io_poll() - Process any notifications and h/w-initiated events that
-+ * are polling-driven.
-+ * @obj: the given DPIO object.
-+ *
-+ * Obligatory for DPIO objects that have dpaa2_io_desc::will_poll non-zero.
-+ *
-+ * Return 0 for success, or -EINVAL for failure.
-+ */
-+int dpaa2_io_poll(struct dpaa2_io *obj);
-+
-+/**
-+ * dpaa2_io_irq() - Process any notifications and h/w-initiated events that are
-+ * irq-driven.
-+ * @obj: the given DPIO object.
-+ *
-+ * Obligatory for DPIO objects that have dpaa2_io_desc::has_irq non-zero.
-+ *
-+ * Return IRQ_HANDLED for success, or -EINVAL for failure.
-+ */
-+int dpaa2_io_irq(struct dpaa2_io *obj);
-+
-+/**
-+ * dpaa2_io_pause_poll() - Used to stop polling.
-+ * @obj: the given DPIO object.
-+ *
-+ * If a polling application is going to stop polling for a period of time and
-+ * supports interrupt processing, it can call this function to convert all
-+ * processing to IRQ. (Eg. when sleeping.)
-+ *
-+ * Return -EINVAL.
-+ */
-+int dpaa2_io_pause_poll(struct dpaa2_io *obj);
-+
-+/**
-+ * dpaa2_io_resume_poll() - Resume polling
-+ * @obj: the given DPIO object.
-+ *
-+ * Return -EINVAL.
-+ */
-+int dpaa2_io_resume_poll(struct dpaa2_io *obj);
-+
-+/**
-+ * dpaa2_io_service_notifications() - Get a mask of cpus that the DPIO service
-+ * can receive notifications on.
-+ * @s: the given DPIO object.
-+ * @mask: the mask of cpus.
-+ *
-+ * Note that this is a run-time snapshot. If things like cpu-hotplug are
-+ * supported in the target system, then an attempt to register notifications
-+ * for a cpu that appears present in the given mask might fail if that cpu has
-+ * gone offline in the mean time.
-+ */
-+void dpaa2_io_service_notifications(struct dpaa2_io *s, cpumask_t *mask);
-+
-+/**
-+ * dpaa2_io_service_stashing - Get a mask of cpus that the DPIO service has stash
-+ * affinity to.
-+ * @s: the given DPIO object.
-+ * @mask: the mask of cpus.
-+ */
-+void dpaa2_io_service_stashing(struct dpaa2_io *s, cpumask_t *mask);
-+
-+/**
-+ * dpaa2_io_service_nonaffine() - Check the DPIO service's cpu affinity
-+ * for stashing.
-+ * @s: the given DPIO object.
-+ *
-+ * Return a boolean, whether or not the DPIO service has resources that have no
-+ * particular cpu affinity for stashing. (Useful to know if you wish to operate
-+ * on CPUs that the service has no affinity to, you would choose to use
-+ * resources that are neutral, rather than affine to a different CPU.) Unlike
-+ * other service-specific APIs, this one doesn't return an error if it is passed
-+ * a non-service object. So don't do it.
-+ */
-+int dpaa2_io_service_has_nonaffine(struct dpaa2_io *s);
-+
-+/*************************/
-+/* Notification handling */
-+/*************************/
-+
-+/**
-+ * struct dpaa2_io_notification_ctx - The DPIO notification context structure.
-+ * @cb: the callback to be invoked when the notification arrives.
-+ * @is_cdan: Zero/FALSE for FQDAN, non-zero/TRUE for CDAN.
-+ * @id: FQID or channel ID, needed for rearm.
-+ * @desired_cpu: the cpu on which the notifications will show up.
-+ * @actual_cpu: the cpu the notification actually shows up.
-+ * @migration_cb: callback function used for migration.
-+ * @dpio_id: the dpio index.
-+ * @qman64: the 64-bit context value shows up in the FQDAN/CDAN.
-+ * @node: the list node.
-+ * @dpio_private: the dpio object internal to dpio_service.
-+ *
-+ * When a FQDAN/CDAN registration is made (eg. by DPNI/DPCON/DPAI code), a
-+ * context of the following type is used. The caller can embed it within a
-+ * larger structure in order to add state that is tracked along with the
-+ * notification (this may be useful when callbacks are invoked that pass this
-+ * notification context as a parameter).
-+ */
-+struct dpaa2_io_notification_ctx {
-+ void (*cb)(struct dpaa2_io_notification_ctx *);
-+ int is_cdan;
-+ uint32_t id;
-+ /* This specifies which cpu the user wants notifications to show up on
-+ * (ie. to execute 'cb'). If notification-handling on that cpu is not
-+ * available at the time of notification registration, the registration
-+ * will fail. */
-+ int desired_cpu;
-+ /* If the target platform supports cpu-hotplug or other features
-+ * (related to power-management, one would expect) that can migrate IRQ
-+ * handling of a given DPIO object, then this value will potentially be
-+ * different to 'desired_cpu' at run-time. */
-+ int actual_cpu;
-+ /* And if migration does occur and this callback is non-NULL, it will
-+ * be invoked prior to any futher notification callbacks executing on
-+ * 'newcpu'. Note that 'oldcpu' is what 'actual_cpu' was prior to the
-+ * migration, and 'newcpu' is what it is now. Both could conceivably be
-+ * different to 'desired_cpu'. */
-+ void (*migration_cb)(struct dpaa2_io_notification_ctx *,
-+ int oldcpu, int newcpu);
-+ /* These are returned from dpaa2_io_service_register().
-+ * 'dpio_id' is the dpaa2_io_desc::dpio_id value of the DPIO object that
-+ * has been selected by the service for receiving the notifications. The
-+ * caller can use this value in the MC command that attaches the FQ (or
-+ * channel) of their DPNI (or DPCON, respectively) to this DPIO for
-+ * notification-generation.
-+ * 'qman64' is the 64-bit context value that needs to be sent in the
-+ * same MC command in order to be programmed into the FQ or channel -
-+ * this is the 64-bit value that shows up in the FQDAN/CDAN messages to
-+ * the DPIO object, and the DPIO service specifies this value back to
-+ * the caller so that the notifications that show up will be
-+ * comprensible/demux-able to the DPIO service. */
-+ int dpio_id;
-+ uint64_t qman64;
-+ /* These fields are internal to the DPIO service once the context is
-+ * registered. TBD: may require more internal state fields. */
-+ struct list_head node;
-+ void *dpio_private;
-+};
-+
-+/**
-+ * dpaa2_io_service_register() - Prepare for servicing of FQDAN or CDAN
-+ * notifications on the given DPIO service.
-+ * @service: the given DPIO service.
-+ * @ctx: the notification context.
-+ *
-+ * The MC command to attach the caller's DPNI/DPCON/DPAI device to a
-+ * DPIO object is performed after this function is called. In that way, (a) the
-+ * DPIO service is "ready" to handle a notification arrival (which might happen
-+ * before the "attach" command to MC has returned control of execution back to
-+ * the caller), and (b) the DPIO service can provide back to the caller the
-+ * 'dpio_id' and 'qman64' parameters that it should pass along in the MC command
-+ * in order for the DPNI/DPCON/DPAI resources to be configured to produce the
-+ * right notification fields to the DPIO service.
-+ *
-+ * Return 0 for success, or -ENODEV for failure.
-+ */
-+int dpaa2_io_service_register(struct dpaa2_io *service,
-+ struct dpaa2_io_notification_ctx *ctx);
-+
-+/**
-+ * dpaa2_io_service_deregister - The opposite of 'register'.
-+ * @service: the given DPIO service.
-+ * @ctx: the notification context.
-+ *
-+ * Note that 'register' should be called *before*
-+ * making the MC call to attach the notification-producing device to the
-+ * notification-handling DPIO service, the 'unregister' function should be
-+ * called *after* making the MC call to detach the notification-producing
-+ * device.
-+ *
-+ * Return 0 for success.
-+ */
-+int dpaa2_io_service_deregister(struct dpaa2_io *service,
-+ struct dpaa2_io_notification_ctx *ctx);
-+
-+/**
-+ * dpaa2_io_service_rearm() - Rearm the notification for the given DPIO service.
-+ * @service: the given DPIO service.
-+ * @ctx: the notification context.
-+ *
-+ * Once a FQDAN/CDAN has been produced, the corresponding FQ/channel is
-+ * considered "disarmed". Ie. the user can issue pull dequeue operations on that
-+ * traffic source for as long as it likes. Eventually it may wish to "rearm"
-+ * that source to allow it to produce another FQDAN/CDAN, that's what this
-+ * function achieves.
-+ *
-+ * Return 0 for success, or -ENODEV if no service available, -EBUSY/-EIO for not
-+ * being able to implement the rearm the notifiaton due to setting CDAN or
-+ * scheduling fq.
-+ */
-+int dpaa2_io_service_rearm(struct dpaa2_io *service,
-+ struct dpaa2_io_notification_ctx *ctx);
-+
-+/**
-+ * dpaa2_io_from_registration() - Get the DPIO object from the given notification
-+ * context.
-+ * @ctx: the given notifiation context.
-+ * @ret: the returned DPIO object.
-+ *
-+ * Like 'dpaa2_io_service_get_persistent()' (see below), except that the
-+ * returned handle is not selected based on a 'cpu' argument, but is the same
-+ * DPIO object that the given notification context is registered against. The
-+ * returned handle carries a reference count, so a corresponding dpaa2_io_down()
-+ * would be required when the reference is no longer needed.
-+ *
-+ * Return 0 for success, or -EINVAL for failure.
-+ */
-+int dpaa2_io_from_registration(struct dpaa2_io_notification_ctx *ctx,
-+ struct dpaa2_io **ret);
-+
-+/**********************************/
-+/* General usage of DPIO services */
-+/**********************************/
-+
-+/**
-+ * dpaa2_io_service_get_persistent() - Get the DPIO resource from the given
-+ * notification context and cpu.
-+ * @service: the DPIO service.
-+ * @cpu: the cpu that the DPIO resource has stashing affinity to.
-+ * @ret: the returned DPIO resource.
-+ *
-+ * The various DPIO interfaces can accept a "struct dpaa2_io" handle that refers
-+ * to an individual DPIO object or to a whole service. In the latter case, an
-+ * internal choice is made for each operation. This function supports the former
-+ * case, by selecting an individual DPIO object *from* the service in order for
-+ * it to be used multiple times to provide "persistence". The returned handle
-+ * also carries a reference count, so a corresponding dpaa2_io_down() would be
-+ * required when the reference is no longer needed. Note, a parameter of -1 for
-+ * 'cpu' will select a DPIO resource that has no particular stashing affinity to
-+ * any cpu (eg. one that stashes to platform cache).
-+ *
-+ * Return 0 for success, or -ENODEV for failure.
-+ */
-+int dpaa2_io_service_get_persistent(struct dpaa2_io *service, int cpu,
-+ struct dpaa2_io **ret);
-+
-+/*****************/
-+/* Pull dequeues */
-+/*****************/
-+
-+/**
-+ * dpaa2_io_service_pull_fq() - pull dequeue functions from a fq.
-+ * @d: the given DPIO service.
-+ * @fqid: the given frame queue id.
-+ * @s: the dpaa2_io_store object for the result.
-+ *
-+ * To support DCA/order-preservation, it will be necessary to support an
-+ * alternative form, because they must ultimately dequeue to DQRR rather than a
-+ * user-supplied dpaa2_io_store. Furthermore, those dequeue results will
-+ * "complete" using a caller-provided callback (from DQRR processing) rather
-+ * than the caller explicitly looking at their dpaa2_io_store for results. Eg.
-+ * the alternative form will likely take a callback parameter rather than a
-+ * store parameter. Ignoring it for now to keep the picture clearer.
-+ *
-+ * Return 0 for success, or error code for failure.
-+ */
-+int dpaa2_io_service_pull_fq(struct dpaa2_io *d, uint32_t fqid,
-+ struct dpaa2_io_store *s);
-+
-+/**
-+ * dpaa2_io_service_pull_channel() - pull dequeue functions from a channel.
-+ * @d: the given DPIO service.
-+ * @channelid: the given channel id.
-+ * @s: the dpaa2_io_store object for the result.
-+ *
-+ * To support DCA/order-preservation, it will be necessary to support an
-+ * alternative form, because they must ultimately dequeue to DQRR rather than a
-+ * user-supplied dpaa2_io_store. Furthermore, those dequeue results will
-+ * "complete" using a caller-provided callback (from DQRR processing) rather
-+ * than the caller explicitly looking at their dpaa2_io_store for results. Eg.
-+ * the alternative form will likely take a callback parameter rather than a
-+ * store parameter. Ignoring it for now to keep the picture clearer.
-+ *
-+ * Return 0 for success, or error code for failure.
-+ */
-+int dpaa2_io_service_pull_channel(struct dpaa2_io *d, uint32_t channelid,
-+ struct dpaa2_io_store *s);
-+
-+/************/
-+/* Enqueues */
-+/************/
-+
-+/**
-+ * dpaa2_io_service_enqueue_fq() - Enqueue a frame to a frame queue.
-+ * @d: the given DPIO service.
-+ * @fqid: the given frame queue id.
-+ * @fd: the frame descriptor which is enqueued.
-+ *
-+ * This definition bypasses some features that are not expected to be priority-1
-+ * features, and may not be needed at all via current assumptions (QBMan's
-+ * feature set is wider than the MC object model is intendeding to support,
-+ * initially at least). Plus, keeping them out (for now) keeps the API view
-+ * simpler. Missing features are;
-+ * - enqueue confirmation (results DMA'd back to the user)
-+ * - ORP
-+ * - DCA/order-preservation (see note in "pull dequeues")
-+ * - enqueue consumption interrupts
-+ *
-+ * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
-+ * or -ENODEV if there is no dpio service.
-+ */
-+int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d,
-+ uint32_t fqid,
-+ const struct dpaa2_fd *fd);
-+
-+/**
-+ * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
-+ * @d: the given DPIO service.
-+ * @qdid: the given queuing destination id.
-+ * @prio: the given queuing priority.
-+ * @qdbin: the given queuing destination bin.
-+ * @fd: the frame descriptor which is enqueued.
-+ *
-+ * This definition bypasses some features that are not expected to be priority-1
-+ * features, and may not be needed at all via current assumptions (QBMan's
-+ * feature set is wider than the MC object model is intendeding to support,
-+ * initially at least). Plus, keeping them out (for now) keeps the API view
-+ * simpler. Missing features are;
-+ * - enqueue confirmation (results DMA'd back to the user)
-+ * - ORP
-+ * - DCA/order-preservation (see note in "pull dequeues")
-+ * - enqueue consumption interrupts
-+ *
-+ * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
-+ * or -ENODEV if there is no dpio service.
-+ */
-+int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d,
-+ uint32_t qdid, uint8_t prio, uint16_t qdbin,
-+ const struct dpaa2_fd *fd);
-+
-+/*******************/
-+/* Buffer handling */
-+/*******************/
-+
-+/**
-+ * dpaa2_io_service_release() - Release buffers to a buffer pool.
-+ * @d: the given DPIO object.
-+ * @bpid: the buffer pool id.
-+ * @buffers: the buffers to be released.
-+ * @num_buffers: the number of the buffers to be released.
-+ *
-+ * Return 0 for success, and negative error code for failure.
-+ */
-+int dpaa2_io_service_release(struct dpaa2_io *d,
-+ uint32_t bpid,
-+ const uint64_t *buffers,
-+ unsigned int num_buffers);
-+
-+/**
-+ * dpaa2_io_service_acquire() - Acquire buffers from a buffer pool.
-+ * @d: the given DPIO object.
-+ * @bpid: the buffer pool id.
-+ * @buffers: the buffer addresses for acquired buffers.
-+ * @num_buffers: the expected number of the buffers to acquire.
-+ *
-+ * Return a negative error code if the command failed, otherwise it returns
-+ * the number of buffers acquired, which may be less than the number requested.
-+ * Eg. if the buffer pool is empty, this will return zero.
-+ */
-+int dpaa2_io_service_acquire(struct dpaa2_io *d,
-+ uint32_t bpid,
-+ uint64_t *buffers,
-+ unsigned int num_buffers);
-+
-+/***************/
-+/* DPIO stores */
-+/***************/
-+
-+/* These are reusable memory blocks for retrieving dequeue results into, and to
-+ * assist with parsing those results once they show up. They also hide the
-+ * details of how to use "tokens" to make detection of DMA results possible (ie.
-+ * comparing memory before the DMA and after it) while minimising the needless
-+ * clearing/rewriting of those memory locations between uses.
-+ */
-+
-+/**
-+ * dpaa2_io_store_create() - Create the dma memory storage for dequeue
-+ * result.
-+ * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
-+ * @dev: the device to allow mapping/unmapping the DMAable region.
-+ *
-+ * Constructor - max_frames must be <= 16. The user provides the
-+ * device struct to allow mapping/unmapping of the DMAable region. Area for
-+ * storage will be allocated during create. The size of this storage is
-+ * "max_frames*sizeof(struct dpaa2_dq)". The 'dpaa2_io_store' returned is a
-+ * wrapper structure allocated within the DPIO code, which owns and manages
-+ * allocated store.
-+ *
-+ * Return dpaa2_io_store struct for successfuly created storage memory, or NULL
-+ * if not getting the stroage for dequeue result in create API.
-+ */
-+struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
-+ struct device *dev);
-+
-+/**
-+ * dpaa2_io_store_destroy() - Destroy the dma memory storage for dequeue
-+ * result.
-+ * @s: the storage memory to be destroyed.
-+ *
-+ * Frees to specified storage memory.
-+ */
-+void dpaa2_io_store_destroy(struct dpaa2_io_store *s);
-+
-+/**
-+ * dpaa2_io_store_next() - Determine when the next dequeue result is available.
-+ * @s: the dpaa2_io_store object.
-+ * @is_last: indicate whether this is the last frame in the pull command.
-+ *
-+ * Once dpaa2_io_store has been passed to a function that performs dequeues to
-+ * it, like dpaa2_ni_rx(), this function can be used to determine when the next
-+ * frame result is available. Once this function returns non-NULL, a subsequent
-+ * call to it will try to find the *next* dequeue result.
-+ *
-+ * Note that if a pull-dequeue has a null result because the target FQ/channel
-+ * was empty, then this function will return NULL rather than expect the caller
-+ * to always check for this on his own side. As such, "is_last" can be used to
-+ * differentiate between "end-of-empty-dequeue" and "still-waiting".
-+ *
-+ * Return dequeue result for a valid dequeue result, or NULL for empty dequeue.
-+ */
-+struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last);
-+
-+#ifdef CONFIG_FSL_QBMAN_DEBUG
-+/**
-+ * dpaa2_io_query_fq_count() - Get the frame and byte count for a given fq.
-+ * @d: the given DPIO object.
-+ * @fqid: the id of frame queue to be queried.
-+ * @fcnt: the queried frame count.
-+ * @bcnt: the queried byte count.
-+ *
-+ * Knowing the FQ count at run-time can be useful in debugging situations.
-+ * The instantaneous frame- and byte-count are hereby returned.
-+ *
-+ * Return 0 for a successful query, and negative error code if query fails.
-+ */
-+int dpaa2_io_query_fq_count(struct dpaa2_io *d, uint32_t fqid,
-+ uint32_t *fcnt, uint32_t *bcnt);
-+
-+/**
-+ * dpaa2_io_query_bp_count() - Query the number of buffers currenty in a
-+ * buffer pool.
-+ * @d: the given DPIO object.
-+ * @bpid: the index of buffer pool to be queried.
-+ * @num: the queried number of buffers in the buffer pool.
-+ *
-+ * Return 0 for a sucessful query, and negative error code if query fails.
-+ */
-+int dpaa2_io_query_bp_count(struct dpaa2_io *d, uint32_t bpid,
-+ uint32_t *num);
-+#endif
-+#endif /* __FSL_DPAA2_IO_H */