diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-03-26 08:33:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-31 09:44:40 -0400 |
commit | eb62d9e9d6327322a5fd3894bfecb3a3aa9391ba (patch) | |
tree | c7572cf5ae9afa7859e663711d0a6aa0b36605d3 | |
parent | e80cb1fae55ceb01b6e886e5499461c07b69c454 (diff) |
[media] s5p-fimc: Add device tree support for FIMC-LITE device driver
This patch adds the device tree support for FIMC-LITE device
driver. The bindings include compatible property for the Exynos5
SoC series, however the actual implementation for these SoCs will
be added in a separate patch.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | Documentation/devicetree/bindings/media/exynos-fimc-lite.txt | 14 | ||||
-rw-r--r-- | drivers/media/platform/s5p-fimc/fimc-lite.c | 63 |
2 files changed, 59 insertions, 18 deletions
diff --git a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt new file mode 100644 index 000000000000..3f62adfb3e0b --- /dev/null +++ b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | Exynos4x12/Exynos5 SoC series camera host interface (FIMC-LITE) | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible : should be "samsung,exynos4212-fimc" for Exynos4212 and | ||
6 | Exynos4412 SoCs; | ||
7 | - reg : physical base address and size of the device memory mapped | ||
8 | registers; | ||
9 | - interrupts : should contain FIMC-LITE interrupt; | ||
10 | - clocks : FIMC LITE gate clock should be specified in this property. | ||
11 | - clock-names : should contain "flite" entry. | ||
12 | |||
13 | Each FIMC device should have an alias in the aliases node, in the form of | ||
14 | fimc-lite<n>, where <n> is an integer specifying the IP block instance. | ||
diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.c b/drivers/media/platform/s5p-fimc/fimc-lite.c index b64297ba35d3..65082fe2578c 100644 --- a/drivers/media/platform/s5p-fimc/fimc-lite.c +++ b/drivers/media/platform/s5p-fimc/fimc-lite.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/list.h> | 18 | #include <linux/list.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/of.h> | ||
20 | #include <linux/types.h> | 21 | #include <linux/types.h> |
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
@@ -1400,18 +1401,34 @@ static int fimc_lite_clk_get(struct fimc_lite *fimc) | |||
1400 | return ret; | 1401 | return ret; |
1401 | } | 1402 | } |
1402 | 1403 | ||
1404 | static const struct of_device_id flite_of_match[]; | ||
1405 | |||
1403 | static int fimc_lite_probe(struct platform_device *pdev) | 1406 | static int fimc_lite_probe(struct platform_device *pdev) |
1404 | { | 1407 | { |
1405 | struct flite_drvdata *drv_data = fimc_lite_get_drvdata(pdev); | 1408 | struct flite_drvdata *drv_data = NULL; |
1409 | struct device *dev = &pdev->dev; | ||
1410 | const struct of_device_id *of_id; | ||
1406 | struct fimc_lite *fimc; | 1411 | struct fimc_lite *fimc; |
1407 | struct resource *res; | 1412 | struct resource *res; |
1408 | int ret; | 1413 | int ret; |
1409 | 1414 | ||
1410 | fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL); | 1415 | fimc = devm_kzalloc(dev, sizeof(*fimc), GFP_KERNEL); |
1411 | if (!fimc) | 1416 | if (!fimc) |
1412 | return -ENOMEM; | 1417 | return -ENOMEM; |
1413 | 1418 | ||
1414 | fimc->index = pdev->id; | 1419 | if (dev->of_node) { |
1420 | of_id = of_match_node(flite_of_match, dev->of_node); | ||
1421 | if (of_id) | ||
1422 | drv_data = (struct flite_drvdata *)of_id->data; | ||
1423 | fimc->index = of_alias_get_id(dev->of_node, "fimc-lite"); | ||
1424 | } else { | ||
1425 | drv_data = fimc_lite_get_drvdata(pdev); | ||
1426 | fimc->index = pdev->id; | ||
1427 | } | ||
1428 | |||
1429 | if (!drv_data || fimc->index < 0 || fimc->index >= FIMC_LITE_MAX_DEVS) | ||
1430 | return -EINVAL; | ||
1431 | |||
1415 | fimc->variant = drv_data->variant[fimc->index]; | 1432 | fimc->variant = drv_data->variant[fimc->index]; |
1416 | fimc->pdev = pdev; | 1433 | fimc->pdev = pdev; |
1417 | 1434 | ||
@@ -1420,13 +1437,13 @@ static int fimc_lite_probe(struct platform_device *pdev) | |||
1420 | mutex_init(&fimc->lock); | 1437 | mutex_init(&fimc->lock); |
1421 | 1438 | ||
1422 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1439 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1423 | fimc->regs = devm_ioremap_resource(&pdev->dev, res); | 1440 | fimc->regs = devm_ioremap_resource(dev, res); |
1424 | if (IS_ERR(fimc->regs)) | 1441 | if (IS_ERR(fimc->regs)) |
1425 | return PTR_ERR(fimc->regs); | 1442 | return PTR_ERR(fimc->regs); |
1426 | 1443 | ||
1427 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1444 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1428 | if (res == NULL) { | 1445 | if (res == NULL) { |
1429 | dev_err(&pdev->dev, "Failed to get IRQ resource\n"); | 1446 | dev_err(dev, "Failed to get IRQ resource\n"); |
1430 | return -ENXIO; | 1447 | return -ENXIO; |
1431 | } | 1448 | } |
1432 | 1449 | ||
@@ -1434,10 +1451,10 @@ static int fimc_lite_probe(struct platform_device *pdev) | |||
1434 | if (ret) | 1451 | if (ret) |
1435 | return ret; | 1452 | return ret; |
1436 | 1453 | ||
1437 | ret = devm_request_irq(&pdev->dev, res->start, flite_irq_handler, | 1454 | ret = devm_request_irq(dev, res->start, flite_irq_handler, |
1438 | 0, dev_name(&pdev->dev), fimc); | 1455 | 0, dev_name(dev), fimc); |
1439 | if (ret) { | 1456 | if (ret) { |
1440 | dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret); | 1457 | dev_err(dev, "Failed to install irq (%d)\n", ret); |
1441 | goto err_clk; | 1458 | goto err_clk; |
1442 | } | 1459 | } |
1443 | 1460 | ||
@@ -1447,23 +1464,23 @@ static int fimc_lite_probe(struct platform_device *pdev) | |||
1447 | goto err_clk; | 1464 | goto err_clk; |
1448 | 1465 | ||
1449 | platform_set_drvdata(pdev, fimc); | 1466 | platform_set_drvdata(pdev, fimc); |
1450 | pm_runtime_enable(&pdev->dev); | 1467 | pm_runtime_enable(dev); |
1451 | ret = pm_runtime_get_sync(&pdev->dev); | 1468 | ret = pm_runtime_get_sync(dev); |
1452 | if (ret < 0) | 1469 | if (ret < 0) |
1453 | goto err_sd; | 1470 | goto err_sd; |
1454 | 1471 | ||
1455 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | 1472 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); |
1456 | if (IS_ERR(fimc->alloc_ctx)) { | 1473 | if (IS_ERR(fimc->alloc_ctx)) { |
1457 | ret = PTR_ERR(fimc->alloc_ctx); | 1474 | ret = PTR_ERR(fimc->alloc_ctx); |
1458 | goto err_pm; | 1475 | goto err_pm; |
1459 | } | 1476 | } |
1460 | pm_runtime_put(&pdev->dev); | 1477 | pm_runtime_put(dev); |
1461 | 1478 | ||
1462 | dev_dbg(&pdev->dev, "FIMC-LITE.%d registered successfully\n", | 1479 | dev_dbg(dev, "FIMC-LITE.%d registered successfully\n", |
1463 | fimc->index); | 1480 | fimc->index); |
1464 | return 0; | 1481 | return 0; |
1465 | err_pm: | 1482 | err_pm: |
1466 | pm_runtime_put(&pdev->dev); | 1483 | pm_runtime_put(dev); |
1467 | err_sd: | 1484 | err_sd: |
1468 | fimc_lite_unregister_capture_subdev(fimc); | 1485 | fimc_lite_unregister_capture_subdev(fimc); |
1469 | err_clk: | 1486 | err_clk: |
@@ -1554,6 +1571,12 @@ static int fimc_lite_remove(struct platform_device *pdev) | |||
1554 | return 0; | 1571 | return 0; |
1555 | } | 1572 | } |
1556 | 1573 | ||
1574 | static const struct dev_pm_ops fimc_lite_pm_ops = { | ||
1575 | SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume) | ||
1576 | SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume, | ||
1577 | NULL) | ||
1578 | }; | ||
1579 | |||
1557 | static struct flite_variant fimc_lite0_variant_exynos4 = { | 1580 | static struct flite_variant fimc_lite0_variant_exynos4 = { |
1558 | .max_width = 8192, | 1581 | .max_width = 8192, |
1559 | .max_height = 8192, | 1582 | .max_height = 8192, |
@@ -1579,17 +1602,21 @@ static struct platform_device_id fimc_lite_driver_ids[] = { | |||
1579 | }; | 1602 | }; |
1580 | MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids); | 1603 | MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids); |
1581 | 1604 | ||
1582 | static const struct dev_pm_ops fimc_lite_pm_ops = { | 1605 | static const struct of_device_id flite_of_match[] = { |
1583 | SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume) | 1606 | { |
1584 | SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume, | 1607 | .compatible = "samsung,exynos4212-fimc-lite", |
1585 | NULL) | 1608 | .data = &fimc_lite_drvdata_exynos4, |
1609 | }, | ||
1610 | { /* sentinel */ }, | ||
1586 | }; | 1611 | }; |
1612 | MODULE_DEVICE_TABLE(of, flite_of_match); | ||
1587 | 1613 | ||
1588 | static struct platform_driver fimc_lite_driver = { | 1614 | static struct platform_driver fimc_lite_driver = { |
1589 | .probe = fimc_lite_probe, | 1615 | .probe = fimc_lite_probe, |
1590 | .remove = fimc_lite_remove, | 1616 | .remove = fimc_lite_remove, |
1591 | .id_table = fimc_lite_driver_ids, | 1617 | .id_table = fimc_lite_driver_ids, |
1592 | .driver = { | 1618 | .driver = { |
1619 | .of_match_table = flite_of_match, | ||
1593 | .name = FIMC_LITE_DRV_NAME, | 1620 | .name = FIMC_LITE_DRV_NAME, |
1594 | .owner = THIS_MODULE, | 1621 | .owner = THIS_MODULE, |
1595 | .pm = &fimc_lite_pm_ops, | 1622 | .pm = &fimc_lite_pm_ops, |