1. 09 7月, 2014 4 次提交
    • M
      dma-buf: use reservation objects · 3aac4502
      Maarten Lankhorst 提交于
      This allows reservation objects to be used in dma-buf. it's required
      for implementing polling support on the fences that belong to a dma-buf.
      Signed-off-by: NMaarten Lankhorst <maarten.lankhorst@canonical.com>
      Acked-by: Mauro Carvalho Chehab <m.chehab@samsung.com> #drivers/media/v4l2-core/
      Acked-by: Thomas Hellstrom <thellstrom@vmware.com> #drivers/gpu/drm/ttm
      Acked-by: NSumit Semwal <sumit.semwal@linaro.org>
      Acked-by: NDaniel Vetter <daniel@ffwll.ch>
      Signed-off-by: Vincent Stehlé <vincent.stehle@laposte.net> #drivers/gpu/drm/armada/
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3aac4502
    • M
      seqno-fence: Hardware dma-buf implementation of fencing (v6) · 606b23ad
      Maarten Lankhorst 提交于
      This type of fence can be used with hardware synchronization for simple
      hardware that can block execution until the condition
      (dma_buf[offset] - value) >= 0 has been met when WAIT_GEQUAL is used,
      or (dma_buf[offset] != 0) has been met when WAIT_NONZERO is set.
      
      A software fallback still has to be provided in case the fence is used
      with a device that doesn't support this mechanism. It is useful to expose
      this for graphics cards that have an op to support this.
      
      Some cards like i915 can export those, but don't have an option to wait,
      so they need the software fallback.
      
      I extended the original patch by Rob Clark.
      
      v1: Original
      v2: Renamed from bikeshed to seqno, moved into dma-fence.c since
          not much was left of the file. Lots of documentation added.
      v3: Use fence_ops instead of custom callbacks. Moved to own file
          to avoid circular dependency between dma-buf.h and fence.h
      v4: Add spinlock pointer to seqno_fence_init
      v5: Add condition member to allow wait for != 0.
          Fix small style errors pointed out by checkpatch.
      v6: Move to a separate file. Fix up api changes in fences.
      Signed-off-by: NMaarten Lankhorst <maarten.lankhorst@canonical.com>
      Acked-by: NSumit Semwal <sumit.semwal@linaro.org>
      Acked-by: NDaniel Vetter <daniel@ffwll.ch>
      Reviewed-by: Rob Clark <robdclark@gmail.com> #v4
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      606b23ad
    • M
      fence: dma-buf cross-device synchronization (v18) · e941759c
      Maarten Lankhorst 提交于
      A fence can be attached to a buffer which is being filled or consumed
      by hw, to allow userspace to pass the buffer without waiting to another
      device.  For example, userspace can call page_flip ioctl to display the
      next frame of graphics after kicking the GPU but while the GPU is still
      rendering.  The display device sharing the buffer with the GPU would
      attach a callback to get notified when the GPU's rendering-complete IRQ
      fires, to update the scan-out address of the display, without having to
      wake up userspace.
      
      A driver must allocate a fence context for each execution ring that can
      run in parallel. The function for this takes an argument with how many
      contexts to allocate:
        + fence_context_alloc()
      
      A fence is transient, one-shot deal.  It is allocated and attached
      to one or more dma-buf's.  When the one that attached it is done, with
      the pending operation, it can signal the fence:
        + fence_signal()
      
      To have a rough approximation whether a fence is fired, call:
        + fence_is_signaled()
      
      The dma-buf-mgr handles tracking, and waiting on, the fences associated
      with a dma-buf.
      
      The one pending on the fence can add an async callback:
        + fence_add_callback()
      
      The callback can optionally be cancelled with:
        + fence_remove_callback()
      
      To wait synchronously, optionally with a timeout:
        + fence_wait()
        + fence_wait_timeout()
      
      When emitting a fence, call:
        + trace_fence_emit()
      
      To annotate that a fence is blocking on another fence, call:
        + trace_fence_annotate_wait_on(fence, on_fence)
      
      A default software-only implementation is provided, which can be used
      by drivers attaching a fence to a buffer when they have no other means
      for hw sync.  But a memory backed fence is also envisioned, because it
      is common that GPU's can write to, or poll on some memory location for
      synchronization.  For example:
      
        fence = custom_get_fence(...);
        if ((seqno_fence = to_seqno_fence(fence)) != NULL) {
          dma_buf *fence_buf = seqno_fence->sync_buf;
          get_dma_buf(fence_buf);
      
          ... tell the hw the memory location to wait ...
          custom_wait_on(fence_buf, seqno_fence->seqno_ofs, fence->seqno);
        } else {
          /* fall-back to sw sync * /
          fence_add_callback(fence, my_cb);
        }
      
      On SoC platforms, if some other hw mechanism is provided for synchronizing
      between IP blocks, it could be supported as an alternate implementation
      with it's own fence ops in a similar way.
      
      enable_signaling callback is used to provide sw signaling in case a cpu
      waiter is requested or no compatible hardware signaling could be used.
      
      The intention is to provide a userspace interface (presumably via eventfd)
      later, to be used in conjunction with dma-buf's mmap support for sw access
      to buffers (or for userspace apps that would prefer to do their own
      synchronization).
      
      v1: Original
      v2: After discussion w/ danvet and mlankhorst on #dri-devel, we decided
          that dma-fence didn't need to care about the sw->hw signaling path
          (it can be handled same as sw->sw case), and therefore the fence->ops
          can be simplified and more handled in the core.  So remove the signal,
          add_callback, cancel_callback, and wait ops, and replace with a simple
          enable_signaling() op which can be used to inform a fence supporting
          hw->hw signaling that one or more devices which do not support hw
          signaling are waiting (and therefore it should enable an irq or do
          whatever is necessary in order that the CPU is notified when the
          fence is passed).
      v3: Fix locking fail in attach_fence() and get_fence()
      v4: Remove tie-in w/ dma-buf..  after discussion w/ danvet and mlankorst
          we decided that we need to be able to attach one fence to N dma-buf's,
          so using the list_head in dma-fence struct would be problematic.
      v5: [ Maarten Lankhorst ] Updated for dma-bikeshed-fence and dma-buf-manager.
      v6: [ Maarten Lankhorst ] I removed dma_fence_cancel_callback and some comments
          about checking if fence fired or not. This is broken by design.
          waitqueue_active during destruction is now fatal, since the signaller
          should be holding a reference in enable_signalling until it signalled
          the fence. Pass the original dma_fence_cb along, and call __remove_wait
          in the dma_fence_callback handler, so that no cleanup needs to be
          performed.
      v7: [ Maarten Lankhorst ] Set cb->func and only enable sw signaling if
          fence wasn't signaled yet, for example for hardware fences that may
          choose to signal blindly.
      v8: [ Maarten Lankhorst ] Tons of tiny fixes, moved __dma_fence_init to
          header and fixed include mess. dma-fence.h now includes dma-buf.h
          All members are now initialized, so kmalloc can be used for
          allocating a dma-fence. More documentation added.
      v9: Change compiler bitfields to flags, change return type of
          enable_signaling to bool. Rework dma_fence_wait. Added
          dma_fence_is_signaled and dma_fence_wait_timeout.
          s/dma// and change exports to non GPL. Added fence_is_signaled and
          fence_enable_sw_signaling calls, add ability to override default
          wait operation.
      v10: remove event_queue, use a custom list, export try_to_wake_up from
          scheduler. Remove fence lock and use a global spinlock instead,
          this should hopefully remove all the locking headaches I was having
          on trying to implement this. enable_signaling is called with this
          lock held.
      v11:
          Use atomic ops for flags, lifting the need for some spin_lock_irqsaves.
          However I kept the guarantee that after fence_signal returns, it is
          guaranteed that enable_signaling has either been called to completion,
          or will not be called any more.
      
          Add contexts and seqno to base fence implementation. This allows you
          to wait for less fences, by testing for seqno + signaled, and then only
          wait on the later fence.
      
          Add FENCE_TRACE, FENCE_WARN, and FENCE_ERR. This makes debugging easier.
          An CONFIG_DEBUG_FENCE will be added to turn off the FENCE_TRACE
          spam, and another runtime option can turn it off at runtime.
      v12:
          Add CONFIG_FENCE_TRACE. Add missing documentation for the fence->context
          and fence->seqno members.
      v13:
          Fixup CONFIG_FENCE_TRACE kconfig description.
          Move fence_context_alloc to fence.
          Simplify fence_later.
          Kill priv member to fence_cb.
      v14:
          Remove priv argument from fence_add_callback, oops!
      v15:
          Remove priv from documentation.
          Explicitly include linux/atomic.h.
      v16:
          Add trace events.
          Import changes required by android syncpoints.
      v17:
          Use wake_up_state instead of try_to_wake_up. (Colin Cross)
          Fix up commit description for seqno_fence. (Rob Clark)
      v18:
          Rename release_fence to fence_release.
          Move to drivers/dma-buf/.
          Rename __fence_is_signaled and __fence_signal to *_locked.
          Rename __fence_init to fence_init.
          Make fence_default_wait return a signed long, and fix wait ops too.
      Signed-off-by: NMaarten Lankhorst <maarten.lankhorst@canonical.com>
      Signed-off-by: Thierry Reding <thierry.reding@gmail.com> #use smp_mb__before_atomic()
      Acked-by: NSumit Semwal <sumit.semwal@linaro.org>
      Acked-by: NDaniel Vetter <daniel@ffwll.ch>
      Reviewed-by: NRob Clark <robdclark@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e941759c
    • M
  2. 05 7月, 2014 1 次提交
  3. 04 7月, 2014 2 次提交
  4. 03 7月, 2014 9 次提交
  5. 02 7月, 2014 4 次提交
  6. 01 7月, 2014 13 次提交
  7. 30 6月, 2014 1 次提交
  8. 28 6月, 2014 2 次提交
    • M
      iscsi-target: fix iscsit_del_np deadlock on unload · 81a9c5e7
      Mikulas Patocka 提交于
      On uniprocessor preemptible kernel, target core deadlocks on unload. The
      following events happen:
      * iscsit_del_np is called
      * it calls send_sig(SIGINT, np->np_thread, 1);
      * the scheduler switches to the np_thread
      * the np_thread is woken up, it sees that kthread_should_stop() returns
        false, so it doesn't terminate
      * the np_thread clears signals with flush_signals(current); and goes back
        to sleep in iscsit_accept_np
      * the scheduler switches back to iscsit_del_np
      * iscsit_del_np calls kthread_stop(np->np_thread);
      * the np_thread is waiting in iscsit_accept_np and it doesn't respond to
        kthread_stop
      
      The deadlock could be resolved if the administrator sends SIGINT signal to
      the np_thread with killall -INT iscsi_np
      
      The reproducible deadlock was introduced in commit
      db6077fd, but the thread-stopping code was
      racy even before.
      
      This patch fixes the problem. Using kthread_should_stop to stop the
      np_thread is unreliable, so we test np_thread_state instead. If
      np_thread_state equals ISCSI_NP_THREAD_SHUTDOWN, the thread exits.
      Signed-off-by: NMikulas Patocka <mpatocka@redhat.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NNicholas Bellinger <nab@linux-iscsi.org>
      81a9c5e7
    • N
      iscsi-target: Avoid rejecting incorrect ITT for Data-Out · 97c99b47
      Nicholas Bellinger 提交于
      This patch changes iscsit_check_dataout_hdr() to dump the incoming
      Data-Out payload when the received ITT is not associated with a
      WRITE, instead of calling iscsit_reject_cmd() for the non WRITE
      ITT descriptor.
      
      This addresses a bug where an initiator sending an Data-Out for
      an ITT associated with a READ would end up generating a reject
      for the READ, eventually resulting in list corruption.
      Reported-by: NSantosh Kulkarni <santosh.kulkarni@calsoftinc.com>
      Reported-by: NArshad Hussain <arshad.hussain@calsoftinc.com>
      Cc: stable@vger.kernel.org # 3.10+
      Signed-off-by: NNicholas Bellinger <nab@linux-iscsi.org>
      97c99b47
  9. 27 6月, 2014 4 次提交
    • T
      usb: musb: Ensure that cppi41 timer gets armed on premature DMA TX irq · c58d80f5
      Thomas Gleixner 提交于
      Some TI chips raise the DMA complete interrupt before the actual
      transfer has been completed. The code tries to busy wait for a few
      microseconds and if that fails it arms an hrtimer to recheck. So far
      so good, but that has the following issue:
      
      CPU 0					CPU1
      
      start_next_transfer(RQ1);
      
      DMA interrupt
        if (premature_irq(RQ1))
          if (!hrtimer_active(timer))
             hrtimer_start(timer);
      
      hrtimer expires
        timer->state = CALLBACK_RUNNING;
        timer->fn()
          cppi41_recheck_tx_req()
            complete_request(RQ1);
            if (requests_pending())
              start_next_transfer(RQ2);
      
      					DMA interrupt
      					  if (premature_irq(RQ2))
      					    if (!hrtimer_active(timer))
      					       hrtimer_start(timer);
        timer->state = INACTIVE;
      
      The premature interrupt of request2 on CPU1 does not arm the timer and
      therefor the request completion never happens because it checks for
      !hrtimer_active(). hrtimer_active() evaluates:
      
        timer->state != HRTIMER_STATE_INACTIVE
      
      which of course evaluates to true in the above case as timer->state is
      CALLBACK_RUNNING.
      
      That's clearly documented:
      
       * A timer is active, when it is enqueued into the rbtree or the
       * callback function is running or it's in the state of being migrated
       * to another cpu.
      
      But that's not what the code wants to check. The code wants to check
      whether the timer is queued, i.e. whether its armed and waiting for
      expiry.
      
      We have a helper function for this: hrtimer_is_queued(). This
      evaluates:
      
        timer->state & HRTIMER_STATE_QUEUED
      
      So in the above case this evaluates to false and therefor forces the
      DMA interrupt on CPU1 to call hrtimer_start().
      
      Use hrtimer_is_queued() instead of hrtimer_active() and evrything is
      good.
      Reported-by: NTorben Hohn <torbenh@linutronix.de>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: stable@vger.kernel.org
      Signed-off-by: NFelipe Balbi <balbi@ti.com>
      c58d80f5
    • A
      usb: gadget: gr_udc: Fix check for invalid number of microframes · 6ee96cc0
      Andreas Larsson 提交于
      The value 0x3 (not 0x11) in the field for additional transaction/microframe
      is reserved and should not be let through. Be clear in the error message about
      what value caused the error return.
      Reported-by: NDavid Binderman <dcb314@hotmail.com>
      Signed-off-by: NAndreas Larsson <andreas@gaisler.com>
      Signed-off-by: NFelipe Balbi <balbi@ti.com>
      6ee96cc0
    • E
      usb: musb: Fix panic upon musb_am335x module removal · 7adb5c87
      Ezequiel Garcia 提交于
      At probe time, the musb_am335x driver register its childs by
      calling of_platform_populate(), which registers all childs in
      the devicetree hierarchy recursively.
      
      On the other side, the driver's remove() function uses of_device_unregister()
      to remove each child of musb_am335x's.
      
      However, when musb_dsps is loaded, its devices are attached to the musb_am335x
      device as musb_am335x childs. Hence, musb_am335x remove() will attempt to
      unregister the devices registered by musb_dsps, which produces a kernel panic.
      
      In other words, the childs in the "struct device" hierarchy are not the same
      as the childs in the "devicetree" hierarchy.
      
      Ideally, we should enforce the removal of the devices registered by
      musb_am335x *only*, instead of all its child devices. However, because of the
      recursive nature of of_platform_populate, this doesn't seem possible.
      
      Therefore, as the only solution at hand, this commit disables musb_am335x
      driver removal capability, preventing it from being ever removed. This was
      originally suggested by Sebastian Siewior:
      
      https://www.mail-archive.com/linux-omap@vger.kernel.org/msg104946.html
      
      And for reference, here's the panic upon module removal:
      
      musb-hdrc musb-hdrc.0.auto: remove, state 4
      usb usb1: USB disconnect, device number 1
      musb-hdrc musb-hdrc.0.auto: USB bus 1 deregistered
      Unable to handle kernel NULL pointer dereference at virtual address 0000008c
      pgd = de11c000
      [0000008c] *pgd=9e174831, *pte=00000000, *ppte=00000000
      Internal error: Oops: 17 [#1] ARM
      Modules linked in: musb_am335x(-) musb_dsps musb_hdrc usbcore usb_common
      CPU: 0 PID: 623 Comm: modprobe Not tainted 3.15.0-rc4-00001-g24efd13 #69
      task: de1b7500 ti: de122000 task.ti: de122000
      PC is at am335x_shutdown+0x10/0x28
      LR is at am335x_shutdown+0xc/0x28
      pc : [<c0327798>]    lr : [<c0327794>]    psr: a0000013
      sp : de123df8  ip : 00000004  fp : 00028f00
      r10: 00000000  r9 : de122000  r8 : c000e6c4
      r7 : de0e3c10  r6 : de0e3800  r5 : de624010  r4 : de1ec750
      r3 : de0e3810  r2 : 00000000  r1 : 00000001  r0 : 00000000
      Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
      Control: 10c5387d  Table: 9e11c019  DAC: 00000015
      Process modprobe (pid: 623, stack limit = 0xde122240)
      Stack: (0xde123df8 to 0xde124000)
      3de0:                                                       de0e3810 bf054488
      3e00: bf05444c de624010 60000013 bf043650 000012fc de624010 de0e3810 bf043a20
      3e20: de0e3810 bf04b240 c0635b88 c02ca37c c02ca364 c02c8db0 de1b7500 de0e3844
      3e40: de0e3810 c02c8e28 c0635b88 de02824c de0e3810 c02c884c de0e3800 de0e3810
      3e60: de0e3818 c02c5b20 bf05417c de0e3800 de0e3800 c0635b88 de0f2410 c02ca838
      3e80: bf05417c de0e3800 bf055438 c02ca8cc de0e3c10 bf054194 de0e3c10 c02ca37c
      3ea0: c02ca364 c02c8db0 de1b7500 de0e3c44 de0e3c10 c02c8e28 c0635b88 de02824c
      3ec0: de0e3c10 c02c884c de0e3c10 de0e3c10 de0e3c18 c02c5b20 de0e3c10 de0e3c10
      3ee0: 00000000 bf059000 a0000013 c02c5bc0 00000000 bf05900c de0e3c10 c02c5c48
      3f00: de0dd0c0 de1ec970 de0f2410 bf05929c de0f2444 bf05902c de0f2410 c02ca37c
      3f20: c02ca364 c02c8db0 bf05929c de0f2410 bf05929c c02c94c8 bf05929c 00000000
      3f40: 00000800 c02c8ab4 bf0592e0 c007fc40 c00dd820 6273756d 336d615f 00783533
      3f60: c064a0ac de1b7500 de122000 de1b7500 c000e590 00000001 c000e6c4 c0060160
      3f80: 00028e70 00028e70 00028ea4 00000081 60000010 00028e70 00028e70 00028ea4
      3fa0: 00000081 c000e500 00028e70 00028e70 00028ea4 00000800 becb59f8 00027608
      3fc0: 00028e70 00028e70 00028ea4 00000081 00000001 00000001 00000000 00028f00
      3fe0: b6e6b6f0 becb59d4 000160e8 b6e6b6fc 60000010 00028ea4 00000000 00000000
      [<c0327798>] (am335x_shutdown) from [<bf054488>] (dsps_musb_exit+0x3c/0x4c [musb_dsps])
      [<bf054488>] (dsps_musb_exit [musb_dsps]) from [<bf043650>] (musb_shutdown+0x80/0x90 [musb_hdrc])
      [<bf043650>] (musb_shutdown [musb_hdrc]) from [<bf043a20>] (musb_remove+0x24/0x68 [musb_hdrc])
      [<bf043a20>] (musb_remove [musb_hdrc]) from [<c02ca37c>] (platform_drv_remove+0x18/0x1c)
      [<c02ca37c>] (platform_drv_remove) from [<c02c8db0>] (__device_release_driver+0x70/0xc8)
      [<c02c8db0>] (__device_release_driver) from [<c02c8e28>] (device_release_driver+0x20/0x2c)
      [<c02c8e28>] (device_release_driver) from [<c02c884c>] (bus_remove_device+0xdc/0x10c)
      [<c02c884c>] (bus_remove_device) from [<c02c5b20>] (device_del+0x104/0x198)
      [<c02c5b20>] (device_del) from [<c02ca838>] (platform_device_del+0x14/0x9c)
      [<c02ca838>] (platform_device_del) from [<c02ca8cc>] (platform_device_unregister+0xc/0x20)
      [<c02ca8cc>] (platform_device_unregister) from [<bf054194>] (dsps_remove+0x18/0x38 [musb_dsps])
      [<bf054194>] (dsps_remove [musb_dsps]) from [<c02ca37c>] (platform_drv_remove+0x18/0x1c)
      [<c02ca37c>] (platform_drv_remove) from [<c02c8db0>] (__device_release_driver+0x70/0xc8)
      [<c02c8db0>] (__device_release_driver) from [<c02c8e28>] (device_release_driver+0x20/0x2c)
      [<c02c8e28>] (device_release_driver) from [<c02c884c>] (bus_remove_device+0xdc/0x10c)
      [<c02c884c>] (bus_remove_device) from [<c02c5b20>] (device_del+0x104/0x198)
      [<c02c5b20>] (device_del) from [<c02c5bc0>] (device_unregister+0xc/0x20)
      [<c02c5bc0>] (device_unregister) from [<bf05900c>] (of_remove_populated_child+0xc/0x14 [musb_am335x])
      [<bf05900c>] (of_remove_populated_child [musb_am335x]) from [<c02c5c48>] (device_for_each_child+0x44/0x70)
      [<c02c5c48>] (device_for_each_child) from [<bf05902c>] (am335x_child_remove+0x18/0x30 [musb_am335x])
      [<bf05902c>] (am335x_child_remove [musb_am335x]) from [<c02ca37c>] (platform_drv_remove+0x18/0x1c)
      [<c02ca37c>] (platform_drv_remove) from [<c02c8db0>] (__device_release_driver+0x70/0xc8)
      [<c02c8db0>] (__device_release_driver) from [<c02c94c8>] (driver_detach+0xb4/0xb8)
      [<c02c94c8>] (driver_detach) from [<c02c8ab4>] (bus_remove_driver+0x4c/0xa0)
      [<c02c8ab4>] (bus_remove_driver) from [<c007fc40>] (SyS_delete_module+0x128/0x1cc)
      [<c007fc40>] (SyS_delete_module) from [<c000e500>] (ret_fast_syscall+0x0/0x48)
      
      Fixes: 97238b35 ("usb: musb: dsps: use proper child nodes")
      Cc: <stable@vger.kernel.org> # v3.12+
      Acked-by: NGeorge Cherian <george.cherian@ti.com>
      Signed-off-by: NEzequiel Garcia <ezequiel@vanguardiasur.com.ar>
      Signed-off-by: NFelipe Balbi <balbi@ti.com>
      7adb5c87
    • V
      drm/i915: Wait for vblank after enabling the primary plane on BDW · 33c3b0d1
      Ville Syrjälä 提交于
      BDW signals the flip done interrupt immediately after the DSPSURF write
      when the plane is disabled. This is true even if we've already armed
      DSPCNTR to enable the plane at the next vblank. This causes major
      problems for our page flip code which relies on the flip done interrupts
      happening at vblank time.
      
      So what happens is that we enable the plane, and immediately allow
      userspace to submit a page flip. If the plane is still in the process
      of being enabled when the page flip is issued, the flip done gets
      signalled immediately. Our DSPSURFLIVE check catches this to prevent
      premature flip completion, but it also means that we don't get a flip
      done interrupt when the plane actually gets enabled, and so the page
      flip is never completed.
      
      Work around this by re-introducing blocking vblank waits on BDW
      whenever we enable the primary plane.
      
      I removed some of the vblank waits here:
       commit 6304cd91
       Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
       Date:   Fri Apr 25 13:30:12 2014 +0300
      
          drm/i915: Drop the excessive vblank waits from modeset codepaths
      
      To avoid these blocking vblank waits we should start using the vblank
      interrupt instead of the flip done interrupt to complete page flips.
      But that's material for another patch.
      
      Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79354Tested-by: NGuo Jinxian <jinxianx.guo@intel.com>
      Signed-off-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
      Reviewed-by: NRodrigo Vivi <rodrigo.vivi@intel.com>
      Signed-off-by: NJani Nikula <jani.nikula@intel.com>
      33c3b0d1