cgroup: superblock can't be released with active dentries
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-omap2 / board-apollon.c
1 /*
2  * linux/arch/arm/mach-omap2/board-apollon.c
3  *
4  * Copyright (C) 2005,2006 Samsung Electronics
5  * Author: Kyungmin Park <kyungmin.park@samsung.com>
6  *
7  * Modified from mach-omap/omap2/board-h4.c
8  *
9  * Code for apollon OMAP2 board. Should work on many OMAP2 systems where
10  * the bootloader passes the board-specific data to the kernel.
11  * Do not put any board specific code to this file; create a new machine
12  * type if you need custom low-level initializations.
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License version 2 as
16  * published by the Free Software Foundation.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/platform_device.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/partitions.h>
24 #include <linux/mtd/onenand.h>
25 #include <linux/delay.h>
26 #include <linux/leds.h>
27 #include <linux/err.h>
28 #include <linux/clk.h>
29 #include <linux/smc91x.h>
30 #include <linux/gpio.h>
31
32 #include <mach/hardware.h>
33 #include <asm/mach-types.h>
34 #include <asm/mach/arch.h>
35 #include <asm/mach/flash.h>
36
37 #include <plat/led.h>
38 #include <plat/usb.h>
39 #include <plat/board.h>
40 #include "common.h"
41 #include <plat/gpmc.h>
42
43 #include <video/omapdss.h>
44 #include <video/omap-panel-generic-dpi.h>
45
46 #include "mux.h"
47 #include "control.h"
48
49 /* LED & Switch macros */
50 #define LED0_GPIO13             13
51 #define LED1_GPIO14             14
52 #define LED2_GPIO15             15
53 #define SW_ENTER_GPIO16         16
54 #define SW_UP_GPIO17            17
55 #define SW_DOWN_GPIO58          58
56
57 #define APOLLON_FLASH_CS        0
58 #define APOLLON_ETH_CS          1
59 #define APOLLON_ETHR_GPIO_IRQ   74
60
61 static struct mtd_partition apollon_partitions[] = {
62         {
63                 .name           = "X-Loader + U-Boot",
64                 .offset         = 0,
65                 .size           = SZ_128K,
66                 .mask_flags     = MTD_WRITEABLE,
67         },
68         {
69                 .name           = "params",
70                 .offset         = MTDPART_OFS_APPEND,
71                 .size           = SZ_128K,
72         },
73         {
74                 .name           = "kernel",
75                 .offset         = MTDPART_OFS_APPEND,
76                 .size           = SZ_2M,
77         },
78         {
79                 .name           = "rootfs",
80                 .offset         = MTDPART_OFS_APPEND,
81                 .size           = SZ_16M,
82         },
83         {
84                 .name           = "filesystem00",
85                 .offset         = MTDPART_OFS_APPEND,
86                 .size           = SZ_32M,
87         },
88         {
89                 .name           = "filesystem01",
90                 .offset         = MTDPART_OFS_APPEND,
91                 .size           = MTDPART_SIZ_FULL,
92         },
93 };
94
95 static struct onenand_platform_data apollon_flash_data = {
96         .parts          = apollon_partitions,
97         .nr_parts       = ARRAY_SIZE(apollon_partitions),
98 };
99
100 static struct resource apollon_flash_resource[] = {
101         [0] = {
102                 .flags          = IORESOURCE_MEM,
103         },
104 };
105
106 static struct platform_device apollon_onenand_device = {
107         .name           = "onenand-flash",
108         .id             = -1,
109         .dev            = {
110                 .platform_data  = &apollon_flash_data,
111         },
112         .num_resources  = ARRAY_SIZE(apollon_flash_resource),
113         .resource       = apollon_flash_resource,
114 };
115
116 static void __init apollon_flash_init(void)
117 {
118         unsigned long base;
119
120         if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
121                 printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
122                 return;
123         }
124         apollon_flash_resource[0].start = base;
125         apollon_flash_resource[0].end   = base + SZ_128K - 1;
126 }
127
128 static struct smc91x_platdata appolon_smc91x_info = {
129         .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
130         .leda   = RPC_LED_100_10,
131         .ledb   = RPC_LED_TX_RX,
132 };
133
134 static struct resource apollon_smc91x_resources[] = {
135         [0] = {
136                 .flags  = IORESOURCE_MEM,
137         },
138         [1] = {
139                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
140         },
141 };
142
143 static struct platform_device apollon_smc91x_device = {
144         .name           = "smc91x",
145         .id             = -1,
146         .dev    = {
147                 .platform_data  = &appolon_smc91x_info,
148         },
149         .num_resources  = ARRAY_SIZE(apollon_smc91x_resources),
150         .resource       = apollon_smc91x_resources,
151 };
152
153 static struct omap_led_config apollon_led_config[] = {
154         {
155                 .cdev   = {
156                         .name   = "apollon:led0",
157                 },
158                 .gpio   = LED0_GPIO13,
159         },
160         {
161                 .cdev   = {
162                         .name   = "apollon:led1",
163                 },
164                 .gpio   = LED1_GPIO14,
165         },
166         {
167                 .cdev   = {
168                         .name   = "apollon:led2",
169                 },
170                 .gpio   = LED2_GPIO15,
171         },
172 };
173
174 static struct omap_led_platform_data apollon_led_data = {
175         .nr_leds        = ARRAY_SIZE(apollon_led_config),
176         .leds           = apollon_led_config,
177 };
178
179 static struct platform_device apollon_led_device = {
180         .name           = "omap-led",
181         .id             = -1,
182         .dev            = {
183                 .platform_data  = &apollon_led_data,
184         },
185 };
186
187 static struct platform_device *apollon_devices[] __initdata = {
188         &apollon_onenand_device,
189         &apollon_smc91x_device,
190         &apollon_led_device,
191 };
192
193 static inline void __init apollon_init_smc91x(void)
194 {
195         unsigned long base;
196
197         unsigned int rate;
198         struct clk *gpmc_fck;
199         int eth_cs;
200         int err;
201
202         gpmc_fck = clk_get(NULL, "gpmc_fck");   /* Always on ENABLE_ON_INIT */
203         if (IS_ERR(gpmc_fck)) {
204                 WARN_ON(1);
205                 return;
206         }
207
208         clk_enable(gpmc_fck);
209         rate = clk_get_rate(gpmc_fck);
210
211         eth_cs = APOLLON_ETH_CS;
212
213         /* Make sure CS1 timings are correct */
214         gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
215
216         if (rate >= 160000000) {
217                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
218                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
219                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
220                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
221                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
222         } else if (rate >= 130000000) {
223                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
224                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
225                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
226                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
227                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
228         } else {/* rate = 100000000 */
229                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
230                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
231                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
232                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
233                 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
234         }
235
236         if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
237                 printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
238                 goto out;
239         }
240         apollon_smc91x_resources[0].start = base + 0x300;
241         apollon_smc91x_resources[0].end   = base + 0x30f;
242         udelay(100);
243
244         omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0);
245         err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq");
246         if (err) {
247                 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
248                         APOLLON_ETHR_GPIO_IRQ);
249                 gpmc_cs_free(APOLLON_ETH_CS);
250         }
251 out:
252         clk_disable(gpmc_fck);
253         clk_put(gpmc_fck);
254 }
255
256 static struct omap_usb_config apollon_usb_config __initdata = {
257         .register_dev   = 1,
258         .hmc_mode       = 0x14, /* 0:dev 1:host1 2:disable */
259
260         .pins[0]        = 6,
261 };
262
263 static struct panel_generic_dpi_data apollon_panel_data = {
264         .name                   = "apollon",
265 };
266
267 static struct omap_dss_device apollon_lcd_device = {
268         .name                   = "lcd",
269         .driver_name            = "generic_dpi_panel",
270         .type                   = OMAP_DISPLAY_TYPE_DPI,
271         .phy.dpi.data_lines     = 18,
272         .data                   = &apollon_panel_data,
273 };
274
275 static struct omap_dss_device *apollon_dss_devices[] = {
276         &apollon_lcd_device,
277 };
278
279 static struct omap_dss_board_info apollon_dss_data = {
280         .num_devices    = ARRAY_SIZE(apollon_dss_devices),
281         .devices        = apollon_dss_devices,
282         .default_device = &apollon_lcd_device,
283 };
284
285 static struct gpio apollon_gpio_leds[] __initdata = {
286         { LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */
287         { LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6  */
288         { LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4  */
289 };
290
291 static void __init apollon_led_init(void)
292 {
293         omap_mux_init_signal("vlynq_clk.gpio_13", 0);
294         omap_mux_init_signal("vlynq_rx1.gpio_14", 0);
295         omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
296
297         gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));
298 }
299
300 static void __init apollon_usb_init(void)
301 {
302         /* USB device */
303         /* DEVICE_SUSPEND */
304         omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
305         gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend");
306         omap2_usbfs_init(&apollon_usb_config);
307 }
308
309 #ifdef CONFIG_OMAP_MUX
310 static struct omap_board_mux board_mux[] __initdata = {
311         { .reg_offset = OMAP_MUX_TERMINATOR },
312 };
313 #endif
314
315 static void __init omap_apollon_init(void)
316 {
317         u32 v;
318
319         omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
320
321         apollon_init_smc91x();
322         apollon_led_init();
323         apollon_flash_init();
324         apollon_usb_init();
325
326         /* REVISIT: where's the correct place */
327         omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP);
328
329         /* LCD PWR_EN */
330         omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
331
332         /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
333         v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
334         v |= (1 << 24);
335         omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
336
337         /*
338          * Make sure the serial ports are muxed on at this point.
339          * You have to mux them off in device drivers later on
340          * if not needed.
341          */
342         apollon_smc91x_resources[1].start = gpio_to_irq(APOLLON_ETHR_GPIO_IRQ);
343         apollon_smc91x_resources[1].end = gpio_to_irq(APOLLON_ETHR_GPIO_IRQ);
344         platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
345         omap_serial_init();
346         omap_sdrc_init(NULL, NULL);
347         omap_display_init(&apollon_dss_data);
348 }
349
350 MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
351         /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
352         .atag_offset    = 0x100,
353         .reserve        = omap_reserve,
354         .map_io         = omap242x_map_io,
355         .init_early     = omap2420_init_early,
356         .init_irq       = omap2_init_irq,
357         .handle_irq     = omap2_intc_handle_irq,
358         .init_machine   = omap_apollon_init,
359         .timer          = &omap2_timer,
360         .restart        = omap_prcm_restart,
361 MACHINE_END