diff options
author | Arun Kumar K <arun.kk@samsung.com> | 2012-10-25 04:24:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-01-06 06:50:38 -0500 |
commit | b27a23be0d1de44ab2cc01495b4f9149f4f762d5 (patch) | |
tree | 88513af9f446a028e9e76702c759770cd1cb89e7 /drivers/media/platform/s5p-mfc | |
parent | 371a664eea4e2c0d2acc1df082f7e08693506f89 (diff) |
[media] s5p-mfc: Add device tree support
This patch will add the device tree support for MFC driver.
Signed-off-by: Arun Kumar K <arun.kk@samsung.com>
Acked-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform/s5p-mfc')
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc.c | 100 |
1 files changed, 84 insertions, 16 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 3afe879d54d7..e2fe64efb756 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/videodev2.h> | 21 | #include <linux/videodev2.h> |
22 | #include <media/v4l2-event.h> | 22 | #include <media/v4l2-event.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <linux/of.h> | ||
24 | #include <media/videobuf2-core.h> | 25 | #include <media/videobuf2-core.h> |
25 | #include "s5p_mfc_common.h" | 26 | #include "s5p_mfc_common.h" |
26 | #include "s5p_mfc_ctrl.h" | 27 | #include "s5p_mfc_ctrl.h" |
@@ -1027,6 +1028,8 @@ static int match_child(struct device *dev, void *data) | |||
1027 | return !strcmp(dev_name(dev), (char *)data); | 1028 | return !strcmp(dev_name(dev), (char *)data); |
1028 | } | 1029 | } |
1029 | 1030 | ||
1031 | static void *mfc_get_drv_data(struct platform_device *pdev); | ||
1032 | |||
1030 | /* MFC probe function */ | 1033 | /* MFC probe function */ |
1031 | static int s5p_mfc_probe(struct platform_device *pdev) | 1034 | static int s5p_mfc_probe(struct platform_device *pdev) |
1032 | { | 1035 | { |
@@ -1034,6 +1037,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) | |||
1034 | struct video_device *vfd; | 1037 | struct video_device *vfd; |
1035 | struct resource *res; | 1038 | struct resource *res; |
1036 | int ret; | 1039 | int ret; |
1040 | unsigned int mem_info[2]; | ||
1037 | 1041 | ||
1038 | pr_debug("%s++\n", __func__); | 1042 | pr_debug("%s++\n", __func__); |
1039 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); | 1043 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
@@ -1050,8 +1054,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) | |||
1050 | return -ENODEV; | 1054 | return -ENODEV; |
1051 | } | 1055 | } |
1052 | 1056 | ||
1053 | dev->variant = (struct s5p_mfc_variant *) | 1057 | dev->variant = mfc_get_drv_data(pdev); |
1054 | platform_get_device_id(pdev)->driver_data; | ||
1055 | 1058 | ||
1056 | ret = s5p_mfc_init_pm(dev); | 1059 | ret = s5p_mfc_init_pm(dev); |
1057 | if (ret < 0) { | 1060 | if (ret < 0) { |
@@ -1081,20 +1084,55 @@ static int s5p_mfc_probe(struct platform_device *pdev) | |||
1081 | goto err_res; | 1084 | goto err_res; |
1082 | } | 1085 | } |
1083 | 1086 | ||
1084 | dev->mem_dev_l = device_find_child(&dev->plat_dev->dev, "s5p-mfc-l", | 1087 | if (pdev->dev.of_node) { |
1085 | match_child); | 1088 | dev->mem_dev_l = kzalloc(sizeof(struct device), GFP_KERNEL); |
1086 | if (!dev->mem_dev_l) { | 1089 | if (!dev->mem_dev_l) { |
1087 | mfc_err("Mem child (L) device get failed\n"); | 1090 | mfc_err("Not enough memory\n"); |
1088 | ret = -ENODEV; | 1091 | ret = -ENOMEM; |
1089 | goto err_res; | 1092 | goto err_res; |
1090 | } | 1093 | } |
1094 | of_property_read_u32_array(pdev->dev.of_node, "samsung,mfc-l", | ||
1095 | mem_info, 2); | ||
1096 | if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0], | ||
1097 | mem_info[0], mem_info[1], | ||
1098 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) { | ||
1099 | mfc_err("Failed to declare coherent memory for\n" | ||
1100 | "MFC device\n"); | ||
1101 | ret = -ENOMEM; | ||
1102 | goto err_res; | ||
1103 | } | ||
1091 | 1104 | ||
1092 | dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r", | 1105 | dev->mem_dev_r = kzalloc(sizeof(struct device), GFP_KERNEL); |
1093 | match_child); | 1106 | if (!dev->mem_dev_r) { |
1094 | if (!dev->mem_dev_r) { | 1107 | mfc_err("Not enough memory\n"); |
1095 | mfc_err("Mem child (R) device get failed\n"); | 1108 | ret = -ENOMEM; |
1096 | ret = -ENODEV; | 1109 | goto err_res; |
1097 | goto err_res; | 1110 | } |
1111 | of_property_read_u32_array(pdev->dev.of_node, "samsung,mfc-r", | ||
1112 | mem_info, 2); | ||
1113 | if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0], | ||
1114 | mem_info[0], mem_info[1], | ||
1115 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) { | ||
1116 | pr_err("Failed to declare coherent memory for\n" | ||
1117 | "MFC device\n"); | ||
1118 | ret = -ENOMEM; | ||
1119 | goto err_res; | ||
1120 | } | ||
1121 | } else { | ||
1122 | dev->mem_dev_l = device_find_child(&dev->plat_dev->dev, | ||
1123 | "s5p-mfc-l", match_child); | ||
1124 | if (!dev->mem_dev_l) { | ||
1125 | mfc_err("Mem child (L) device get failed\n"); | ||
1126 | ret = -ENODEV; | ||
1127 | goto err_res; | ||
1128 | } | ||
1129 | dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, | ||
1130 | "s5p-mfc-r", match_child); | ||
1131 | if (!dev->mem_dev_r) { | ||
1132 | mfc_err("Mem child (R) device get failed\n"); | ||
1133 | ret = -ENODEV; | ||
1134 | goto err_res; | ||
1135 | } | ||
1098 | } | 1136 | } |
1099 | 1137 | ||
1100 | dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l); | 1138 | dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l); |
@@ -1366,6 +1404,35 @@ static struct platform_device_id mfc_driver_ids[] = { | |||
1366 | }; | 1404 | }; |
1367 | MODULE_DEVICE_TABLE(platform, mfc_driver_ids); | 1405 | MODULE_DEVICE_TABLE(platform, mfc_driver_ids); |
1368 | 1406 | ||
1407 | static const struct of_device_id exynos_mfc_match[] = { | ||
1408 | { | ||
1409 | .compatible = "samsung,mfc-v5", | ||
1410 | .data = &mfc_drvdata_v5, | ||
1411 | }, { | ||
1412 | .compatible = "samsung,mfc-v6", | ||
1413 | .data = &mfc_drvdata_v6, | ||
1414 | }, | ||
1415 | {}, | ||
1416 | }; | ||
1417 | MODULE_DEVICE_TABLE(of, exynos_mfc_match); | ||
1418 | |||
1419 | static void *mfc_get_drv_data(struct platform_device *pdev) | ||
1420 | { | ||
1421 | struct s5p_mfc_variant *driver_data = NULL; | ||
1422 | |||
1423 | if (pdev->dev.of_node) { | ||
1424 | const struct of_device_id *match; | ||
1425 | match = of_match_node(of_match_ptr(exynos_mfc_match), | ||
1426 | pdev->dev.of_node); | ||
1427 | if (match) | ||
1428 | driver_data = (struct s5p_mfc_variant *)match->data; | ||
1429 | } else { | ||
1430 | driver_data = (struct s5p_mfc_variant *) | ||
1431 | platform_get_device_id(pdev)->driver_data; | ||
1432 | } | ||
1433 | return driver_data; | ||
1434 | } | ||
1435 | |||
1369 | static struct platform_driver s5p_mfc_driver = { | 1436 | static struct platform_driver s5p_mfc_driver = { |
1370 | .probe = s5p_mfc_probe, | 1437 | .probe = s5p_mfc_probe, |
1371 | .remove = __devexit_p(s5p_mfc_remove), | 1438 | .remove = __devexit_p(s5p_mfc_remove), |
@@ -1373,7 +1440,8 @@ static struct platform_driver s5p_mfc_driver = { | |||
1373 | .driver = { | 1440 | .driver = { |
1374 | .name = S5P_MFC_NAME, | 1441 | .name = S5P_MFC_NAME, |
1375 | .owner = THIS_MODULE, | 1442 | .owner = THIS_MODULE, |
1376 | .pm = &s5p_mfc_pm_ops | 1443 | .pm = &s5p_mfc_pm_ops, |
1444 | .of_match_table = exynos_mfc_match, | ||
1377 | }, | 1445 | }, |
1378 | }; | 1446 | }; |
1379 | 1447 | ||