Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright (c) 2006 Simtec Electronics
0004 //  Ben Dooks <ben@simtec.co.uk>
0005 //
0006 // http://armlinux.simtec.co.uk/.
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/types.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/list.h>
0012 #include <linux/timer.h>
0013 #include <linux/init.h>
0014 #include <linux/clk.h>
0015 #include <linux/delay.h>
0016 #include <linux/device.h>
0017 #include <linux/syscore_ops.h>
0018 #include <linux/serial_core.h>
0019 #include <linux/serial_s3c.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/io.h>
0022 #include <linux/reboot.h>
0023 
0024 #include <asm/mach/arch.h>
0025 #include <asm/mach/map.h>
0026 #include <asm/mach/irq.h>
0027 
0028 #include <asm/proc-fns.h>
0029 #include <asm/irq.h>
0030 #include <asm/system_misc.h>
0031 
0032 #include "map.h"
0033 #include "regs-clock.h"
0034 #include "regs-gpio.h"
0035 
0036 #include "cpu.h"
0037 #include "devs.h"
0038 #include "pm.h"
0039 
0040 #include "s3c24xx.h"
0041 #include "nand-core-s3c24xx.h"
0042 #include "regs-dsc-s3c24xx.h"
0043 #include "s3c2412-power.h"
0044 
0045 #ifndef CONFIG_CPU_S3C2412_ONLY
0046 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
0047 
0048 static inline void s3c2412_init_gpio2(void)
0049 {
0050     s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
0051 }
0052 #else
0053 #define s3c2412_init_gpio2() do { } while(0)
0054 #endif
0055 
0056 /* Initial IO mappings */
0057 
0058 static struct map_desc s3c2412_iodesc[] __initdata __maybe_unused = {
0059     IODESC_ENT(CLKPWR),
0060     IODESC_ENT(TIMER),
0061     IODESC_ENT(WATCHDOG),
0062     {
0063         .virtual = (unsigned long)S3C2412_VA_SSMC,
0064         .pfn     = __phys_to_pfn(S3C2412_PA_SSMC),
0065         .length  = SZ_1M,
0066         .type    = MT_DEVICE,
0067     },
0068     {
0069         .virtual = (unsigned long)S3C2412_VA_EBI,
0070         .pfn     = __phys_to_pfn(S3C2412_PA_EBI),
0071         .length  = SZ_1M,
0072         .type    = MT_DEVICE,
0073     },
0074 };
0075 
0076 /* uart registration process */
0077 
0078 void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
0079 {
0080     s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
0081 
0082     /* rename devices that are s3c2412/s3c2413 specific */
0083     s3c_device_sdi.name  = "s3c2412-sdi";
0084     s3c_device_lcd.name  = "s3c2412-lcd";
0085     s3c_nand_setname("s3c2412-nand");
0086 
0087     /* alter IRQ of SDI controller */
0088 
0089     s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
0090     s3c_device_sdi.resource[1].end   = IRQ_S3C2412_SDI;
0091 
0092     /* spi channel related changes, s3c2412/13 specific */
0093     s3c_device_spi0.name = "s3c2412-spi";
0094     s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
0095     s3c_device_spi1.name = "s3c2412-spi";
0096     s3c_device_spi1.resource[0].start = S3C24XX_PA_SPI + S3C2412_SPI1;
0097     s3c_device_spi1.resource[0].end = S3C24XX_PA_SPI + S3C2412_SPI1 + 0x24;
0098 
0099 }
0100 
0101 /* s3c2412_idle
0102  *
0103  * use the standard idle call by ensuring the idle mode
0104  * in power config, then issuing the idle co-processor
0105  * instruction
0106 */
0107 
0108 static void s3c2412_idle(void)
0109 {
0110     unsigned long tmp;
0111 
0112     /* ensure our idle mode is to go to idle */
0113 
0114     tmp = __raw_readl(S3C2412_PWRCFG);
0115     tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
0116     tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
0117     __raw_writel(tmp, S3C2412_PWRCFG);
0118 
0119     cpu_do_idle();
0120 }
0121 
0122 /* s3c2412_map_io
0123  *
0124  * register the standard cpu IO areas, and any passed in from the
0125  * machine specific initialisation.
0126 */
0127 
0128 void __init s3c2412_map_io(void)
0129 {
0130     /* move base of IO */
0131 
0132     s3c2412_init_gpio2();
0133 
0134     /* set our idle function */
0135 
0136     arm_pm_idle = s3c2412_idle;
0137 
0138     /* register our io-tables */
0139 
0140     iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
0141 }
0142 
0143 /* need to register the subsystem before we actually register the device, and
0144  * we also need to ensure that it has been initialised before any of the
0145  * drivers even try to use it (even if not on an s3c2412 based system)
0146  * as a driver which may support both 2410 and 2440 may try and use it.
0147 */
0148 
0149 struct bus_type s3c2412_subsys = {
0150     .name = "s3c2412-core",
0151     .dev_name = "s3c2412-core",
0152 };
0153 
0154 static int __init s3c2412_core_init(void)
0155 {
0156     return subsys_system_register(&s3c2412_subsys, NULL);
0157 }
0158 
0159 core_initcall(s3c2412_core_init);
0160 
0161 static struct device s3c2412_dev = {
0162     .bus        = &s3c2412_subsys,
0163 };
0164 
0165 int __init s3c2412_init(void)
0166 {
0167     printk("S3C2412: Initialising architecture\n");
0168 
0169 #ifdef CONFIG_PM_SLEEP
0170     register_syscore_ops(&s3c2412_pm_syscore_ops);
0171     register_syscore_ops(&s3c24xx_irq_syscore_ops);
0172 #endif
0173 
0174     return device_register(&s3c2412_dev);
0175 }