[PARISC] fix user-triggerable panic on parisc
[sfrench/cifs-2.6.git] / arch / arm / mach-omap2 / devices.c
1 /*
2  * linux/arch/arm/mach-omap2/devices.c
3  *
4  * OMAP2 platform device setup/initialization
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11 #include <linux/gpio.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/platform_device.h>
15 #include <linux/io.h>
16 #include <linux/clk.h>
17 #include <linux/err.h>
18 #include <linux/slab.h>
19 #include <linux/of.h>
20 #include <linux/pinctrl/machine.h>
21 #include <linux/platform_data/omap4-keypad.h>
22
23 #include <asm/mach-types.h>
24 #include <asm/mach/map.h>
25
26 #include "iomap.h"
27 #include <plat/dma.h>
28 #include <plat/omap_hwmod.h>
29 #include <plat/omap_device.h>
30 #include "omap4-keypad.h"
31
32 #include "soc.h"
33 #include "common.h"
34 #include "mux.h"
35 #include "control.h"
36 #include "devices.h"
37
38 #define L3_MODULES_MAX_LEN 12
39 #define L3_MODULES 3
40
41 static int __init omap3_l3_init(void)
42 {
43         struct omap_hwmod *oh;
44         struct platform_device *pdev;
45         char oh_name[L3_MODULES_MAX_LEN];
46
47         /*
48          * To avoid code running on other OMAPs in
49          * multi-omap builds
50          */
51         if (!(cpu_is_omap34xx()))
52                 return -ENODEV;
53
54         snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main");
55
56         oh = omap_hwmod_lookup(oh_name);
57
58         if (!oh)
59                 pr_err("could not look up %s\n", oh_name);
60
61         pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0,
62                                                            NULL, 0, 0);
63
64         WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
65
66         return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
67 }
68 postcore_initcall(omap3_l3_init);
69
70 static int __init omap4_l3_init(void)
71 {
72         int i;
73         struct omap_hwmod *oh[3];
74         struct platform_device *pdev;
75         char oh_name[L3_MODULES_MAX_LEN];
76
77         /* If dtb is there, the devices will be created dynamically */
78         if (of_have_populated_dt())
79                 return -ENODEV;
80
81         /*
82          * To avoid code running on other OMAPs in
83          * multi-omap builds
84          */
85         if (!cpu_is_omap44xx() && !soc_is_omap54xx())
86                 return -ENODEV;
87
88         for (i = 0; i < L3_MODULES; i++) {
89                 snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main_%d", i+1);
90
91                 oh[i] = omap_hwmod_lookup(oh_name);
92                 if (!(oh[i]))
93                         pr_err("could not look up %s\n", oh_name);
94         }
95
96         pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL,
97                                                      0, NULL, 0, 0);
98
99         WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
100
101         return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
102 }
103 postcore_initcall(omap4_l3_init);
104
105 #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
106
107 static struct resource omap2cam_resources[] = {
108         {
109                 .start          = OMAP24XX_CAMERA_BASE,
110                 .end            = OMAP24XX_CAMERA_BASE + 0xfff,
111                 .flags          = IORESOURCE_MEM,
112         },
113         {
114                 .start          = 24 + OMAP_INTC_START,
115                 .flags          = IORESOURCE_IRQ,
116         }
117 };
118
119 static struct platform_device omap2cam_device = {
120         .name           = "omap24xxcam",
121         .id             = -1,
122         .num_resources  = ARRAY_SIZE(omap2cam_resources),
123         .resource       = omap2cam_resources,
124 };
125 #endif
126
127 #if defined(CONFIG_IOMMU_API)
128
129 #include <plat/iommu.h>
130
131 static struct resource omap3isp_resources[] = {
132         {
133                 .start          = OMAP3430_ISP_BASE,
134                 .end            = OMAP3430_ISP_END,
135                 .flags          = IORESOURCE_MEM,
136         },
137         {
138                 .start          = OMAP3430_ISP_CCP2_BASE,
139                 .end            = OMAP3430_ISP_CCP2_END,
140                 .flags          = IORESOURCE_MEM,
141         },
142         {
143                 .start          = OMAP3430_ISP_CCDC_BASE,
144                 .end            = OMAP3430_ISP_CCDC_END,
145                 .flags          = IORESOURCE_MEM,
146         },
147         {
148                 .start          = OMAP3430_ISP_HIST_BASE,
149                 .end            = OMAP3430_ISP_HIST_END,
150                 .flags          = IORESOURCE_MEM,
151         },
152         {
153                 .start          = OMAP3430_ISP_H3A_BASE,
154                 .end            = OMAP3430_ISP_H3A_END,
155                 .flags          = IORESOURCE_MEM,
156         },
157         {
158                 .start          = OMAP3430_ISP_PREV_BASE,
159                 .end            = OMAP3430_ISP_PREV_END,
160                 .flags          = IORESOURCE_MEM,
161         },
162         {
163                 .start          = OMAP3430_ISP_RESZ_BASE,
164                 .end            = OMAP3430_ISP_RESZ_END,
165                 .flags          = IORESOURCE_MEM,
166         },
167         {
168                 .start          = OMAP3430_ISP_SBL_BASE,
169                 .end            = OMAP3430_ISP_SBL_END,
170                 .flags          = IORESOURCE_MEM,
171         },
172         {
173                 .start          = OMAP3430_ISP_CSI2A_REGS1_BASE,
174                 .end            = OMAP3430_ISP_CSI2A_REGS1_END,
175                 .flags          = IORESOURCE_MEM,
176         },
177         {
178                 .start          = OMAP3430_ISP_CSIPHY2_BASE,
179                 .end            = OMAP3430_ISP_CSIPHY2_END,
180                 .flags          = IORESOURCE_MEM,
181         },
182         {
183                 .start          = OMAP3630_ISP_CSI2A_REGS2_BASE,
184                 .end            = OMAP3630_ISP_CSI2A_REGS2_END,
185                 .flags          = IORESOURCE_MEM,
186         },
187         {
188                 .start          = OMAP3630_ISP_CSI2C_REGS1_BASE,
189                 .end            = OMAP3630_ISP_CSI2C_REGS1_END,
190                 .flags          = IORESOURCE_MEM,
191         },
192         {
193                 .start          = OMAP3630_ISP_CSIPHY1_BASE,
194                 .end            = OMAP3630_ISP_CSIPHY1_END,
195                 .flags          = IORESOURCE_MEM,
196         },
197         {
198                 .start          = OMAP3630_ISP_CSI2C_REGS2_BASE,
199                 .end            = OMAP3630_ISP_CSI2C_REGS2_END,
200                 .flags          = IORESOURCE_MEM,
201         },
202         {
203                 .start          = 24 + OMAP_INTC_START,
204                 .flags          = IORESOURCE_IRQ,
205         }
206 };
207
208 static struct platform_device omap3isp_device = {
209         .name           = "omap3isp",
210         .id             = -1,
211         .num_resources  = ARRAY_SIZE(omap3isp_resources),
212         .resource       = omap3isp_resources,
213 };
214
215 static struct omap_iommu_arch_data omap3_isp_iommu = {
216         .name = "isp",
217 };
218
219 int omap3_init_camera(struct isp_platform_data *pdata)
220 {
221         omap3isp_device.dev.platform_data = pdata;
222         omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;
223
224         return platform_device_register(&omap3isp_device);
225 }
226
227 #else /* !CONFIG_IOMMU_API */
228
229 int omap3_init_camera(struct isp_platform_data *pdata)
230 {
231         return 0;
232 }
233
234 #endif
235
236 static inline void omap_init_camera(void)
237 {
238 #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
239         if (cpu_is_omap24xx())
240                 platform_device_register(&omap2cam_device);
241 #endif
242 }
243
244 int __init omap4_keyboard_init(struct omap4_keypad_platform_data
245                         *sdp4430_keypad_data, struct omap_board_data *bdata)
246 {
247         struct platform_device *pdev;
248         struct omap_hwmod *oh;
249         struct omap4_keypad_platform_data *keypad_data;
250         unsigned int id = -1;
251         char *oh_name = "kbd";
252         char *name = "omap4-keypad";
253
254         oh = omap_hwmod_lookup(oh_name);
255         if (!oh) {
256                 pr_err("Could not look up %s\n", oh_name);
257                 return -ENODEV;
258         }
259
260         keypad_data = sdp4430_keypad_data;
261
262         pdev = omap_device_build(name, id, oh, keypad_data,
263                         sizeof(struct omap4_keypad_platform_data), NULL, 0, 0);
264
265         if (IS_ERR(pdev)) {
266                 WARN(1, "Can't build omap_device for %s:%s.\n",
267                                                 name, oh->name);
268                 return PTR_ERR(pdev);
269         }
270         oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
271
272         return 0;
273 }
274
275 #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
276 static inline void __init omap_init_mbox(void)
277 {
278         struct omap_hwmod *oh;
279         struct platform_device *pdev;
280
281         oh = omap_hwmod_lookup("mailbox");
282         if (!oh) {
283                 pr_err("%s: unable to find hwmod\n", __func__);
284                 return;
285         }
286
287         pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0);
288         WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
289                                                 __func__, PTR_ERR(pdev));
290 }
291 #else
292 static inline void omap_init_mbox(void) { }
293 #endif /* CONFIG_OMAP_MBOX_FWK */
294
295 static inline void omap_init_sti(void) {}
296
297 #if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
298
299 static struct platform_device omap_pcm = {
300         .name   = "omap-pcm-audio",
301         .id     = -1,
302 };
303
304 static void omap_init_audio(void)
305 {
306         platform_device_register(&omap_pcm);
307 }
308
309 #else
310 static inline void omap_init_audio(void) {}
311 #endif
312
313 #if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
314                 defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
315
316 static void __init omap_init_mcpdm(void)
317 {
318         struct omap_hwmod *oh;
319         struct platform_device *pdev;
320
321         oh = omap_hwmod_lookup("mcpdm");
322         if (!oh) {
323                 printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
324                 return;
325         }
326
327         pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0, NULL, 0, 0);
328         WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n");
329 }
330 #else
331 static inline void omap_init_mcpdm(void) {}
332 #endif
333
334 #if defined(CONFIG_SND_OMAP_SOC_DMIC) || \
335                 defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE)
336
337 static void __init omap_init_dmic(void)
338 {
339         struct omap_hwmod *oh;
340         struct platform_device *pdev;
341
342         oh = omap_hwmod_lookup("dmic");
343         if (!oh) {
344                 pr_err("Could not look up dmic hw_mod\n");
345                 return;
346         }
347
348         pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0);
349         WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n");
350 }
351 #else
352 static inline void omap_init_dmic(void) {}
353 #endif
354
355 #if defined(CONFIG_SND_OMAP_SOC_OMAP_HDMI) || \
356                 defined(CONFIG_SND_OMAP_SOC_OMAP_HDMI_MODULE)
357
358 static struct platform_device omap_hdmi_audio = {
359         .name   = "omap-hdmi-audio",
360         .id     = -1,
361 };
362
363 static void __init omap_init_hdmi_audio(void)
364 {
365         struct omap_hwmod *oh;
366         struct platform_device *pdev;
367
368         oh = omap_hwmod_lookup("dss_hdmi");
369         if (!oh) {
370                 printk(KERN_ERR "Could not look up dss_hdmi hw_mod\n");
371                 return;
372         }
373
374         pdev = omap_device_build("omap-hdmi-audio-dai",
375                 -1, oh, NULL, 0, NULL, 0, 0);
376         WARN(IS_ERR(pdev),
377              "Can't build omap_device for omap-hdmi-audio-dai.\n");
378
379         platform_device_register(&omap_hdmi_audio);
380 }
381 #else
382 static inline void omap_init_hdmi_audio(void) {}
383 #endif
384
385 #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
386
387 #include <linux/platform_data/spi-omap2-mcspi.h>
388
389 static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)
390 {
391         struct platform_device *pdev;
392         char *name = "omap2_mcspi";
393         struct omap2_mcspi_platform_config *pdata;
394         static int spi_num;
395         struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr;
396
397         pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
398         if (!pdata) {
399                 pr_err("Memory allocation for McSPI device failed\n");
400                 return -ENOMEM;
401         }
402
403         pdata->num_cs = mcspi_attrib->num_chipselect;
404         switch (oh->class->rev) {
405         case OMAP2_MCSPI_REV:
406         case OMAP3_MCSPI_REV:
407                         pdata->regs_offset = 0;
408                         break;
409         case OMAP4_MCSPI_REV:
410                         pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET;
411                         break;
412         default:
413                         pr_err("Invalid McSPI Revision value\n");
414                         kfree(pdata);
415                         return -EINVAL;
416         }
417
418         spi_num++;
419         pdev = omap_device_build(name, spi_num, oh, pdata,
420                                 sizeof(*pdata), NULL, 0, 0);
421         WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",
422                                 name, oh->name);
423         kfree(pdata);
424         return 0;
425 }
426
427 static void omap_init_mcspi(void)
428 {
429         omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL);
430 }
431
432 #else
433 static inline void omap_init_mcspi(void) {}
434 #endif
435
436 /**
437  * omap_init_rng - bind the RNG hwmod to the RNG omap_device
438  *
439  * Bind the RNG hwmod to the RNG omap_device.  No return value.
440  */
441 static void omap_init_rng(void)
442 {
443         struct omap_hwmod *oh;
444         struct platform_device *pdev;
445
446         oh = omap_hwmod_lookup("rng");
447         if (!oh)
448                 return;
449
450         pdev = omap_device_build("omap_rng", -1, oh, NULL, 0, NULL, 0, 0);
451         WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
452 }
453
454 #if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
455
456 #ifdef CONFIG_ARCH_OMAP2
457 static struct resource omap2_sham_resources[] = {
458         {
459                 .start  = OMAP24XX_SEC_SHA1MD5_BASE,
460                 .end    = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
461                 .flags  = IORESOURCE_MEM,
462         },
463         {
464                 .start  = 51 + OMAP_INTC_START,
465                 .flags  = IORESOURCE_IRQ,
466         }
467 };
468 static int omap2_sham_resources_sz = ARRAY_SIZE(omap2_sham_resources);
469 #else
470 #define omap2_sham_resources            NULL
471 #define omap2_sham_resources_sz         0
472 #endif
473
474 #ifdef CONFIG_ARCH_OMAP3
475 static struct resource omap3_sham_resources[] = {
476         {
477                 .start  = OMAP34XX_SEC_SHA1MD5_BASE,
478                 .end    = OMAP34XX_SEC_SHA1MD5_BASE + 0x64,
479                 .flags  = IORESOURCE_MEM,
480         },
481         {
482                 .start  = 49 + OMAP_INTC_START,
483                 .flags  = IORESOURCE_IRQ,
484         },
485         {
486                 .start  = OMAP34XX_DMA_SHA1MD5_RX,
487                 .flags  = IORESOURCE_DMA,
488         }
489 };
490 static int omap3_sham_resources_sz = ARRAY_SIZE(omap3_sham_resources);
491 #else
492 #define omap3_sham_resources            NULL
493 #define omap3_sham_resources_sz         0
494 #endif
495
496 static struct platform_device sham_device = {
497         .name           = "omap-sham",
498         .id             = -1,
499 };
500
501 static void omap_init_sham(void)
502 {
503         if (cpu_is_omap24xx()) {
504                 sham_device.resource = omap2_sham_resources;
505                 sham_device.num_resources = omap2_sham_resources_sz;
506         } else if (cpu_is_omap34xx()) {
507                 sham_device.resource = omap3_sham_resources;
508                 sham_device.num_resources = omap3_sham_resources_sz;
509         } else {
510                 pr_err("%s: platform not supported\n", __func__);
511                 return;
512         }
513         platform_device_register(&sham_device);
514 }
515 #else
516 static inline void omap_init_sham(void) { }
517 #endif
518
519 #if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
520
521 #ifdef CONFIG_ARCH_OMAP2
522 static struct resource omap2_aes_resources[] = {
523         {
524                 .start  = OMAP24XX_SEC_AES_BASE,
525                 .end    = OMAP24XX_SEC_AES_BASE + 0x4C,
526                 .flags  = IORESOURCE_MEM,
527         },
528         {
529                 .start  = OMAP24XX_DMA_AES_TX,
530                 .flags  = IORESOURCE_DMA,
531         },
532         {
533                 .start  = OMAP24XX_DMA_AES_RX,
534                 .flags  = IORESOURCE_DMA,
535         }
536 };
537 static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources);
538 #else
539 #define omap2_aes_resources             NULL
540 #define omap2_aes_resources_sz          0
541 #endif
542
543 #ifdef CONFIG_ARCH_OMAP3
544 static struct resource omap3_aes_resources[] = {
545         {
546                 .start  = OMAP34XX_SEC_AES_BASE,
547                 .end    = OMAP34XX_SEC_AES_BASE + 0x4C,
548                 .flags  = IORESOURCE_MEM,
549         },
550         {
551                 .start  = OMAP34XX_DMA_AES2_TX,
552                 .flags  = IORESOURCE_DMA,
553         },
554         {
555                 .start  = OMAP34XX_DMA_AES2_RX,
556                 .flags  = IORESOURCE_DMA,
557         }
558 };
559 static int omap3_aes_resources_sz = ARRAY_SIZE(omap3_aes_resources);
560 #else
561 #define omap3_aes_resources             NULL
562 #define omap3_aes_resources_sz          0
563 #endif
564
565 static struct platform_device aes_device = {
566         .name           = "omap-aes",
567         .id             = -1,
568 };
569
570 static void omap_init_aes(void)
571 {
572         if (cpu_is_omap24xx()) {
573                 aes_device.resource = omap2_aes_resources;
574                 aes_device.num_resources = omap2_aes_resources_sz;
575         } else if (cpu_is_omap34xx()) {
576                 aes_device.resource = omap3_aes_resources;
577                 aes_device.num_resources = omap3_aes_resources_sz;
578         } else {
579                 pr_err("%s: platform not supported\n", __func__);
580                 return;
581         }
582         platform_device_register(&aes_device);
583 }
584
585 #else
586 static inline void omap_init_aes(void) { }
587 #endif
588
589 /*-------------------------------------------------------------------------*/
590
591 #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
592         defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
593 #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
594 static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = {
595 };
596 #else
597 static struct resource omap_vout_resource[2] = {
598 };
599 #endif
600
601 static struct platform_device omap_vout_device = {
602         .name           = "omap_vout",
603         .num_resources  = ARRAY_SIZE(omap_vout_resource),
604         .resource       = &omap_vout_resource[0],
605         .id             = -1,
606 };
607 static void omap_init_vout(void)
608 {
609         if (platform_device_register(&omap_vout_device) < 0)
610                 printk(KERN_ERR "Unable to register OMAP-VOUT device\n");
611 }
612 #else
613 static inline void omap_init_vout(void) {}
614 #endif
615
616 /*-------------------------------------------------------------------------*/
617
618 static int __init omap2_init_devices(void)
619 {
620         /* Enable dummy states for those platforms without pinctrl support */
621         if (!of_have_populated_dt())
622                 pinctrl_provide_dummies();
623
624         /*
625          * please keep these calls, and their implementations above,
626          * in alphabetical order so they're easier to sort through.
627          */
628         omap_init_audio();
629         omap_init_camera();
630         omap_init_hdmi_audio();
631         omap_init_mbox();
632         /* If dtb is there, the devices will be created dynamically */
633         if (!of_have_populated_dt()) {
634                 omap_init_dmic();
635                 omap_init_mcpdm();
636                 omap_init_mcspi();
637         }
638         omap_init_sti();
639         omap_init_rng();
640         omap_init_sham();
641         omap_init_aes();
642         omap_init_vout();
643
644         return 0;
645 }
646 arch_initcall(omap2_init_devices);
647
648 #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
649 static int __init omap_init_wdt(void)
650 {
651         int id = -1;
652         struct platform_device *pdev;
653         struct omap_hwmod *oh;
654         char *oh_name = "wd_timer2";
655         char *dev_name = "omap_wdt";
656
657         if (!cpu_class_is_omap2() || of_have_populated_dt())
658                 return 0;
659
660         oh = omap_hwmod_lookup(oh_name);
661         if (!oh) {
662                 pr_err("Could not look up wd_timer%d hwmod\n", id);
663                 return -EINVAL;
664         }
665
666         pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
667         WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
668                                 dev_name, oh->name);
669         return 0;
670 }
671 subsys_initcall(omap_init_wdt);
672 #endif