Skip to content

Commit 338c09a

Browse files
committed
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 ...
2 parents ed9ea4e + 21d8582 commit 338c09a

File tree

21 files changed

+458
-1745
lines changed

21 files changed

+458
-1745
lines changed

drivers/media/platform/Kconfig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ config VIDEO_M32R_AR_M64278
9393

9494
config VIDEO_OMAP3
9595
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
9799
---help---
98100
Driver for an OMAP 3 camera controller.
99101

drivers/media/platform/omap3isp/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
ccflags-$(CONFIG_VIDEO_OMAP3_DEBUG) += -DDEBUG
44

55
omap3-isp-objs += \
6-
isp.o ispqueue.o ispvideo.o \
6+
isp.o ispvideo.o \
77
ispcsiphy.o ispccp2.o ispcsi2.o \
88
ispccdc.o isppreview.o ispresizer.o \
99
ispstat.o isph3a_aewb.o isph3a_af.o isphist.o

drivers/media/platform/omap3isp/isp.c

Lines changed: 79 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
#include <linux/sched.h>
7070
#include <linux/vmalloc.h>
7171

72+
#include <asm/dma-iommu.h>
73+
7274
#include <media/v4l2-common.h>
7375
#include <media/v4l2-device.h>
7476

@@ -1397,14 +1399,14 @@ int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
13971399
if (isp_pipeline_is_last(me)) {
13981400
struct isp_video *video = pipe->output;
13991401
unsigned long flags;
1400-
spin_lock_irqsave(&video->queue->irqlock, flags);
1402+
spin_lock_irqsave(&video->irqlock, flags);
14011403
if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
1402-
spin_unlock_irqrestore(&video->queue->irqlock, flags);
1404+
spin_unlock_irqrestore(&video->irqlock, flags);
14031405
atomic_set(stopping, 0);
14041406
smp_mb();
14051407
return 0;
14061408
}
1407-
spin_unlock_irqrestore(&video->queue->irqlock, flags);
1409+
spin_unlock_irqrestore(&video->irqlock, flags);
14081410
if (!wait_event_timeout(*wait, !atomic_read(stopping),
14091411
msecs_to_jiffies(1000))) {
14101412
atomic_set(stopping, 0);
@@ -1625,7 +1627,7 @@ struct isp_device *omap3isp_get(struct isp_device *isp)
16251627
* Decrement the reference count on the ISP. If the last reference is released,
16261628
* power-down all submodules, disable clocks and free temporary buffers.
16271629
*/
1628-
void omap3isp_put(struct isp_device *isp)
1630+
static void __omap3isp_put(struct isp_device *isp, bool save_ctx)
16291631
{
16301632
if (isp == NULL)
16311633
return;
@@ -1634,7 +1636,7 @@ void omap3isp_put(struct isp_device *isp)
16341636
BUG_ON(isp->ref_count == 0);
16351637
if (--isp->ref_count == 0) {
16361638
isp_disable_interrupts(isp);
1637-
if (isp->domain) {
1639+
if (save_ctx) {
16381640
isp_save_ctx(isp);
16391641
isp->has_context = 1;
16401642
}
@@ -1648,6 +1650,11 @@ void omap3isp_put(struct isp_device *isp)
16481650
mutex_unlock(&isp->isp_mutex);
16491651
}
16501652

1653+
void omap3isp_put(struct isp_device *isp)
1654+
{
1655+
__omap3isp_put(isp, true);
1656+
}
1657+
16511658
/* --------------------------------------------------------------------------
16521659
* Platform device driver
16531660
*/
@@ -2120,6 +2127,61 @@ static int isp_initialize_modules(struct isp_device *isp)
21202127
return ret;
21212128
}
21222129

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+
}
2184+
21232185
/*
21242186
* isp_remove - Remove ISP platform device
21252187
* @pdev: Pointer to ISP platform device
@@ -2135,10 +2197,8 @@ static int isp_remove(struct platform_device *pdev)
21352197
isp_xclk_cleanup(isp);
21362198

21372199
__omap3isp_get(isp, false);
2138-
iommu_detach_device(isp->domain, &pdev->dev);
2139-
iommu_domain_free(isp->domain);
2140-
isp->domain = NULL;
2141-
omap3isp_put(isp);
2200+
isp_detach_iommu(isp);
2201+
__omap3isp_put(isp, false);
21422202

21432203
return 0;
21442204
}
@@ -2265,39 +2325,32 @@ static int isp_probe(struct platform_device *pdev)
22652325
}
22662326
}
22672327

2268-
isp->domain = iommu_domain_alloc(pdev->dev.bus);
2269-
if (!isp->domain) {
2270-
dev_err(isp->dev, "can't alloc iommu domain\n");
2271-
ret = -ENOMEM;
2328+
/* IOMMU */
2329+
ret = isp_attach_iommu(isp);
2330+
if (ret < 0) {
2331+
dev_err(&pdev->dev, "unable to attach to IOMMU\n");
22722332
goto error_isp;
22732333
}
22742334

2275-
ret = iommu_attach_device(isp->domain, &pdev->dev);
2276-
if (ret) {
2277-
dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);
2278-
ret = -EPROBE_DEFER;
2279-
goto free_domain;
2280-
}
2281-
22822335
/* Interrupt */
22832336
isp->irq_num = platform_get_irq(pdev, 0);
22842337
if (isp->irq_num <= 0) {
22852338
dev_err(isp->dev, "No IRQ resource\n");
22862339
ret = -ENODEV;
2287-
goto detach_dev;
2340+
goto error_iommu;
22882341
}
22892342

22902343
if (devm_request_irq(isp->dev, isp->irq_num, isp_isr, IRQF_SHARED,
22912344
"OMAP3 ISP", isp)) {
22922345
dev_err(isp->dev, "Unable to request IRQ\n");
22932346
ret = -EINVAL;
2294-
goto detach_dev;
2347+
goto error_iommu;
22952348
}
22962349

22972350
/* Entities */
22982351
ret = isp_initialize_modules(isp);
22992352
if (ret < 0)
2300-
goto detach_dev;
2353+
goto error_iommu;
23012354

23022355
ret = isp_register_entities(isp);
23032356
if (ret < 0)
@@ -2310,14 +2363,11 @@ static int isp_probe(struct platform_device *pdev)
23102363

23112364
error_modules:
23122365
isp_cleanup_modules(isp);
2313-
detach_dev:
2314-
iommu_detach_device(isp->domain, &pdev->dev);
2315-
free_domain:
2316-
iommu_domain_free(isp->domain);
2317-
isp->domain = NULL;
2366+
error_iommu:
2367+
isp_detach_iommu(isp);
23182368
error_isp:
23192369
isp_xclk_cleanup(isp);
2320-
omap3isp_put(isp);
2370+
__omap3isp_put(isp, false);
23212371
error:
23222372
mutex_destroy(&isp->isp_mutex);
23232373

drivers/media/platform/omap3isp/isp.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@
4545
#include "ispcsi2.h"
4646
#include "ispccp2.h"
4747

48-
#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
49-
5048
#define ISP_TOK_TERM 0xFFFFFFFF /*
5149
* terminating token for ISP
5250
* modules reg list
@@ -152,6 +150,7 @@ struct isp_xclk {
152150
* regions.
153151
* @mmio_base_phys: Array with physical L4 bus addresses for ISP register
154152
* regions.
153+
* @mapping: IOMMU mapping
155154
* @stat_lock: Spinlock for handling statistics
156155
* @isp_mutex: Mutex for serializing requests to ISP.
157156
* @stop_failure: Indicates that an entity failed to stop.
@@ -171,7 +170,6 @@ struct isp_xclk {
171170
* @isp_res: Pointer to current settings for ISP Resizer.
172171
* @isp_prev: Pointer to current settings for ISP Preview.
173172
* @isp_ccdc: Pointer to current settings for ISP CCDC.
174-
* @iommu: Pointer to requested IOMMU instance for ISP.
175173
* @platform_cb: ISP driver callback function pointers for platform code
176174
*
177175
* This structure is used to store the OMAP ISP Information.
@@ -189,6 +187,8 @@ struct isp_device {
189187
void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
190188
unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST];
191189

190+
struct dma_iommu_mapping *mapping;
191+
192192
/* ISP Obj */
193193
spinlock_t stat_lock; /* common lock for statistic drivers */
194194
struct mutex isp_mutex; /* For handling ref_count field */
@@ -219,8 +219,6 @@ struct isp_device {
219219

220220
unsigned int sbl_resources;
221221
unsigned int subclk_resources;
222-
223-
struct iommu_domain *domain;
224222
};
225223

226224
#define v4l2_dev_to_isp_device(dev) \

0 commit comments

Comments
 (0)