diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-13 02:04:28 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-13 02:04:28 -0400 |
| commit | 338c09a94b14c449dd53227e9bea44816668c6a5 (patch) | |
| tree | d07da3a009a93c5a6eb4e1d9216f2ce3b0b67b00 | |
| parent | ed9ea4ed3a44e8f8e8c7e8a12a05fd73f9ae1fb4 (diff) | |
| parent | 21d8582d480443574d6a8811e25ccb65dff974d5 (diff) | |
Merge branch 'topic/omap3isp' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull OMAP3 updates from Mauro Carvalho Chehab:
"Some driver improvements on OMAP3. This series depend on some iommu
patches already merged"
* 'topic/omap3isp' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (26 commits)
[media] omap3isp: Rename isp_buffer isp_addr field to dma
[media] omap3isp: Move to videobuf2
[media] v4l: vb2: Add a function to discard all DONE buffers
[media] omap3isp: Cancel all queued buffers when stopping the video stream
[media] omap3isp: Move buffer irqlist to isp_buffer structure
[media] omap3isp: Move queue irqlock to isp_video structure
[media] omap3isp: Move queue mutex to isp_video structure
[media] omap3isp: queue: Don't build scatterlist for kernel buffer
[media] omap3isp: Use the ARM DMA IOMMU-aware operations
[media] omap3isp: queue: Use sg_alloc_table_from_pages()
[media] omap3isp: queue: Map PFNMAP buffers to device
[media] omap3isp: queue: Fix the dma_map_sg() return value check
[media] omap3isp: queue: Allocate kernel buffers with dma_alloc_coherent
[media] omap3isp: queue: Inline the ispmmu_v(un)map functions
[media] omap3isp: queue: Merge the prepare and sglist functions
[media] omap3isp: queue: Use sg_table structure
[media] omap3isp: queue: Move IOMMU handling code to the queue
[media] omap3isp: video: Set the buffer bytesused field at completion time
[media] omap3isp: ccdc: Use the DMA API for FPC
[media] omap3isp: ccdc: Use the DMA API for LSC
...
21 files changed, 458 insertions, 1745 deletions
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 20f1655e6d75..8108c698b548 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig | |||
| @@ -93,7 +93,9 @@ config VIDEO_M32R_AR_M64278 | |||
| 93 | 93 | ||
| 94 | config VIDEO_OMAP3 | 94 | config VIDEO_OMAP3 |
| 95 | tristate "OMAP 3 Camera support" | 95 | tristate "OMAP 3 Camera support" |
| 96 | depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 | 96 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 |
| 97 | select ARM_DMA_USE_IOMMU | ||
| 98 | select OMAP_IOMMU | ||
| 97 | ---help--- | 99 | ---help--- |
| 98 | Driver for an OMAP 3 camera controller. | 100 | Driver for an OMAP 3 camera controller. |
| 99 | 101 | ||
diff --git a/drivers/media/platform/omap3isp/Makefile b/drivers/media/platform/omap3isp/Makefile index e8847e79e31a..254975a9174e 100644 --- a/drivers/media/platform/omap3isp/Makefile +++ b/drivers/media/platform/omap3isp/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | ccflags-$(CONFIG_VIDEO_OMAP3_DEBUG) += -DDEBUG | 3 | ccflags-$(CONFIG_VIDEO_OMAP3_DEBUG) += -DDEBUG |
| 4 | 4 | ||
| 5 | omap3-isp-objs += \ | 5 | omap3-isp-objs += \ |
| 6 | isp.o ispqueue.o ispvideo.o \ | 6 | isp.o ispvideo.o \ |
| 7 | ispcsiphy.o ispccp2.o ispcsi2.o \ | 7 | ispcsiphy.o ispccp2.o ispcsi2.o \ |
| 8 | ispccdc.o isppreview.o ispresizer.o \ | 8 | ispccdc.o isppreview.o ispresizer.o \ |
| 9 | ispstat.o isph3a_aewb.o isph3a_af.o isphist.o | 9 | ispstat.o isph3a_aewb.o isph3a_af.o isphist.o |
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 06a0df434249..2c7aa6720569 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c | |||
| @@ -69,6 +69,8 @@ | |||
| 69 | #include <linux/sched.h> | 69 | #include <linux/sched.h> |
| 70 | #include <linux/vmalloc.h> | 70 | #include <linux/vmalloc.h> |
| 71 | 71 | ||
| 72 | #include <asm/dma-iommu.h> | ||
| 73 | |||
| 72 | #include <media/v4l2-common.h> | 74 | #include <media/v4l2-common.h> |
| 73 | #include <media/v4l2-device.h> | 75 | #include <media/v4l2-device.h> |
| 74 | 76 | ||
| @@ -1397,14 +1399,14 @@ int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait, | |||
| 1397 | if (isp_pipeline_is_last(me)) { | 1399 | if (isp_pipeline_is_last(me)) { |
| 1398 | struct isp_video *video = pipe->output; | 1400 | struct isp_video *video = pipe->output; |
| 1399 | unsigned long flags; | 1401 | unsigned long flags; |
| 1400 | spin_lock_irqsave(&video->queue->irqlock, flags); | 1402 | spin_lock_irqsave(&video->irqlock, flags); |
| 1401 | if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) { | 1403 | if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) { |
| 1402 | spin_unlock_irqrestore(&video->queue->irqlock, flags); | 1404 | spin_unlock_irqrestore(&video->irqlock, flags); |
| 1403 | atomic_set(stopping, 0); | 1405 | atomic_set(stopping, 0); |
| 1404 | smp_mb(); | 1406 | smp_mb(); |
| 1405 | return 0; | 1407 | return 0; |
| 1406 | } | 1408 | } |
| 1407 | spin_unlock_irqrestore(&video->queue->irqlock, flags); | 1409 | spin_unlock_irqrestore(&video->irqlock, flags); |
| 1408 | if (!wait_event_timeout(*wait, !atomic_read(stopping), | 1410 | if (!wait_event_timeout(*wait, !atomic_read(stopping), |
| 1409 | msecs_to_jiffies(1000))) { | 1411 | msecs_to_jiffies(1000))) { |
| 1410 | atomic_set(stopping, 0); | 1412 | atomic_set(stopping, 0); |
| @@ -1625,7 +1627,7 @@ struct isp_device *omap3isp_get(struct isp_device *isp) | |||
| 1625 | * Decrement the reference count on the ISP. If the last reference is released, | 1627 | * Decrement the reference count on the ISP. If the last reference is released, |
| 1626 | * power-down all submodules, disable clocks and free temporary buffers. | 1628 | * power-down all submodules, disable clocks and free temporary buffers. |
| 1627 | */ | 1629 | */ |
| 1628 | void omap3isp_put(struct isp_device *isp) | 1630 | static void __omap3isp_put(struct isp_device *isp, bool save_ctx) |
| 1629 | { | 1631 | { |
| 1630 | if (isp == NULL) | 1632 | if (isp == NULL) |
| 1631 | return; | 1633 | return; |
| @@ -1634,7 +1636,7 @@ void omap3isp_put(struct isp_device *isp) | |||
| 1634 | BUG_ON(isp->ref_count == 0); | 1636 | BUG_ON(isp->ref_count == 0); |
| 1635 | if (--isp->ref_count == 0) { | 1637 | if (--isp->ref_count == 0) { |
| 1636 | isp_disable_interrupts(isp); | 1638 | isp_disable_interrupts(isp); |
| 1637 | if (isp->domain) { | 1639 | if (save_ctx) { |
| 1638 | isp_save_ctx(isp); | 1640 | isp_save_ctx(isp); |
| 1639 | isp->has_context = 1; | 1641 | isp->has_context = 1; |
| 1640 | } | 1642 | } |
| @@ -1648,6 +1650,11 @@ void omap3isp_put(struct isp_device *isp) | |||
| 1648 | mutex_unlock(&isp->isp_mutex); | 1650 | mutex_unlock(&isp->isp_mutex); |
| 1649 | } | 1651 | } |
| 1650 | 1652 | ||
| 1653 | void omap3isp_put(struct isp_device *isp) | ||
| 1654 | { | ||
| 1655 | __omap3isp_put(isp, true); | ||
| 1656 | } | ||
| 1657 | |||
| 1651 | /* -------------------------------------------------------------------------- | 1658 | /* -------------------------------------------------------------------------- |
| 1652 | * Platform device driver | 1659 | * Platform device driver |
| 1653 | */ | 1660 | */ |
| @@ -2120,6 +2127,61 @@ error_csiphy: | |||
| 2120 | return ret; | 2127 | return ret; |
| 2121 | } | 2128 | } |
| 2122 | 2129 | ||
| 2130 | static void isp_detach_iommu(struct isp_device *isp) | ||
| 2131 | { | ||
| 2132 | arm_iommu_release_mapping(isp->mapping); | ||
| 2133 | isp->mapping = NULL; | ||
| 2134 | iommu_group_remove_device(isp->dev); | ||
| 2135 | } | ||
| 2136 | |||
| 2137 | static int isp_attach_iommu(struct isp_device *isp) | ||
| 2138 | { | ||
| 2139 | struct dma_iommu_mapping *mapping; | ||
| 2140 | struct iommu_group *group; | ||
| 2141 | int ret; | ||
| 2142 | |||
| 2143 | /* Create a device group and add the device to it. */ | ||
| 2144 | group = iommu_group_alloc(); | ||
| 2145 | if (IS_ERR(group)) { | ||
| 2146 | dev_err(isp->dev, "failed to allocate IOMMU group\n"); | ||
| 2147 | return PTR_ERR(group); | ||
| 2148 | } | ||
| 2149 | |||
| 2150 | ret = iommu_group_add_device(group, isp->dev); | ||
| 2151 | iommu_group_put(group); | ||
| 2152 | |||
| 2153 | if (ret < 0) { | ||
| 2154 | dev_err(isp->dev, "failed to add device to IPMMU group\n"); | ||
| 2155 | return ret; | ||
| 2156 | } | ||
| 2157 | |||
| 2158 | /* | ||
| 2159 | * Create the ARM mapping, used by the ARM DMA mapping core to allocate | ||
| 2160 | * VAs. This will allocate a corresponding IOMMU domain. | ||
| 2161 | */ | ||
| 2162 | mapping = arm_iommu_create_mapping(&platform_bus_type, SZ_1G, SZ_2G); | ||
| 2163 | if (IS_ERR(mapping)) { | ||
| 2164 | dev_err(isp->dev, "failed to create ARM IOMMU mapping\n"); | ||
| 2165 | ret = PTR_ERR(mapping); | ||
| 2166 | goto error; | ||
| 2167 | } | ||
| 2168 | |||
| 2169 | isp->mapping = mapping; | ||
| 2170 | |||
| 2171 | /* Attach the ARM VA mapping to the device. */ | ||
| 2172 | ret = arm_iommu_attach_device(isp->dev, mapping); | ||
| 2173 | if (ret < 0) { | ||
| 2174 | dev_err(isp->dev, "failed to attach device to VA mapping\n"); | ||
| 2175 | goto error; | ||
| 2176 | } | ||
| 2177 | |||
| 2178 | return 0; | ||
| 2179 | |||
| 2180 | error: | ||
| 2181 | isp_detach_iommu(isp); | ||
| 2182 | return ret; | ||
| 2183 | } | ||
