Merge tag 'for-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power...
[linux-2.6-block.git] / arch / arm / mach-imx / devices / platform-ipu-core.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2011 Pengutronix
4  * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
5  */
6 #include <linux/dma-mapping.h>
7
8 #include "../hardware.h"
9 #include "devices-common.h"
10
11 #define imx_ipu_core_entry_single(soc)                                  \
12 {                                                                       \
13         .iobase = soc ## _IPU_CTRL_BASE_ADDR,                           \
14         .synirq = soc ## _INT_IPU_SYN,                                  \
15         .errirq = soc ## _INT_IPU_ERR,                                  \
16 }
17
18 #ifdef CONFIG_SOC_IMX31
19 const struct imx_ipu_core_data imx31_ipu_core_data __initconst =
20         imx_ipu_core_entry_single(MX31);
21 #endif
22
23 #ifdef CONFIG_SOC_IMX35
24 const struct imx_ipu_core_data imx35_ipu_core_data __initconst =
25         imx_ipu_core_entry_single(MX35);
26 #endif
27
28 static struct platform_device *imx_ipu_coredev __initdata;
29
30 struct platform_device *__init imx_add_ipu_core(
31                 const struct imx_ipu_core_data *data)
32 {
33         /* The resource order is important! */
34         struct resource res[] = {
35                 {
36                         .start = data->iobase,
37                         .end = data->iobase + 0x5f,
38                         .flags = IORESOURCE_MEM,
39                 }, {
40                         .start = data->iobase + 0x88,
41                         .end = data->iobase + 0xb3,
42                         .flags = IORESOURCE_MEM,
43                 }, {
44                         .start = data->synirq,
45                         .end = data->synirq,
46                         .flags = IORESOURCE_IRQ,
47                 }, {
48                         .start = data->errirq,
49                         .end = data->errirq,
50                         .flags = IORESOURCE_IRQ,
51                 },
52         };
53
54         return imx_ipu_coredev = imx_add_platform_device("ipu-core", -1,
55                         res, ARRAY_SIZE(res), NULL, 0);
56 }
57
58 struct platform_device *__init imx_alloc_mx3_camera(
59                 const struct imx_ipu_core_data *data,
60                 const struct mx3_camera_pdata *pdata)
61 {
62         struct resource res[] = {
63                 {
64                         .start = data->iobase + 0x60,
65                         .end = data->iobase + 0x87,
66                         .flags = IORESOURCE_MEM,
67                 },
68         };
69         int ret = -ENOMEM;
70         struct platform_device *pdev;
71
72         if (IS_ERR_OR_NULL(imx_ipu_coredev))
73                 return ERR_PTR(-ENODEV);
74
75         pdev = platform_device_alloc("mx3-camera", 0);
76         if (!pdev)
77                 return ERR_PTR(-ENOMEM);
78
79         pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
80         if (!pdev->dev.dma_mask)
81                 goto err;
82
83         *pdev->dev.dma_mask = DMA_BIT_MASK(32);
84         pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
85
86         ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
87         if (ret)
88                 goto err;
89
90         if (pdata) {
91                 struct mx3_camera_pdata *copied_pdata;
92
93                 ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
94                 if (ret) {
95 err:
96                         kfree(pdev->dev.dma_mask);
97                         platform_device_put(pdev);
98                         return ERR_PTR(-ENODEV);
99                 }
100                 copied_pdata = dev_get_platdata(&pdev->dev);
101                 copied_pdata->dma_dev = &imx_ipu_coredev->dev;
102         }
103
104         return pdev;
105 }
106
107 struct platform_device *__init imx_add_mx3_sdc_fb(
108                 const struct imx_ipu_core_data *data,
109                 struct mx3fb_platform_data *pdata)
110 {
111         struct resource res[] = {
112                 {
113                         .start = data->iobase + 0xb4,
114                         .end = data->iobase + 0x1bf,
115                         .flags = IORESOURCE_MEM,
116                 },
117         };
118
119         if (IS_ERR_OR_NULL(imx_ipu_coredev))
120                 return ERR_PTR(-ENODEV);
121
122         pdata->dma_dev = &imx_ipu_coredev->dev;
123
124         return imx_add_platform_device_dmamask("mx3_sdc_fb", -1,
125                         res, ARRAY_SIZE(res), pdata, sizeof(*pdata),
126                         DMA_BIT_MASK(32));
127 }