linux/arch/arm/mach-s3c24xx/s3c2412.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2006 Simtec Electronics
   3 *      Ben Dooks <ben@simtec.co.uk>
   4 *
   5 * http://armlinux.simtec.co.uk/.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10*/
  11
  12#include <linux/kernel.h>
  13#include <linux/types.h>
  14#include <linux/interrupt.h>
  15#include <linux/list.h>
  16#include <linux/timer.h>
  17#include <linux/init.h>
  18#include <linux/clk.h>
  19#include <linux/delay.h>
  20#include <linux/device.h>
  21#include <linux/syscore_ops.h>
  22#include <linux/serial_core.h>
  23#include <linux/serial_s3c.h>
  24#include <linux/platform_device.h>
  25#include <linux/io.h>
  26#include <linux/reboot.h>
  27
  28#include <asm/mach/arch.h>
  29#include <asm/mach/map.h>
  30#include <asm/mach/irq.h>
  31
  32#include <asm/proc-fns.h>
  33#include <asm/irq.h>
  34#include <asm/system_misc.h>
  35
  36#include <mach/hardware.h>
  37#include <mach/regs-clock.h>
  38#include <mach/regs-gpio.h>
  39
  40#include <plat/cpu.h>
  41#include <plat/cpu-freq.h>
  42#include <plat/devs.h>
  43#include <plat/pm.h>
  44#include <plat/regs-spi.h>
  45
  46#include "common.h"
  47#include "nand-core.h"
  48#include "regs-dsc.h"
  49#include "s3c2412-power.h"
  50
  51#ifndef CONFIG_CPU_S3C2412_ONLY
  52void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
  53
  54static inline void s3c2412_init_gpio2(void)
  55{
  56        s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
  57}
  58#else
  59#define s3c2412_init_gpio2() do { } while(0)
  60#endif
  61
  62/* Initial IO mappings */
  63
  64static struct map_desc s3c2412_iodesc[] __initdata = {
  65        IODESC_ENT(CLKPWR),
  66        IODESC_ENT(TIMER),
  67        IODESC_ENT(WATCHDOG),
  68        {
  69                .virtual = (unsigned long)S3C2412_VA_SSMC,
  70                .pfn     = __phys_to_pfn(S3C2412_PA_SSMC),
  71                .length  = SZ_1M,
  72                .type    = MT_DEVICE,
  73        },
  74        {
  75                .virtual = (unsigned long)S3C2412_VA_EBI,
  76                .pfn     = __phys_to_pfn(S3C2412_PA_EBI),
  77                .length  = SZ_1M,
  78                .type    = MT_DEVICE,
  79        },
  80};
  81
  82/* uart registration process */
  83
  84void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
  85{
  86        s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
  87
  88        /* rename devices that are s3c2412/s3c2413 specific */
  89        s3c_device_sdi.name  = "s3c2412-sdi";
  90        s3c_device_lcd.name  = "s3c2412-lcd";
  91        s3c_nand_setname("s3c2412-nand");
  92
  93        /* alter IRQ of SDI controller */
  94
  95        s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
  96        s3c_device_sdi.resource[1].end   = IRQ_S3C2412_SDI;
  97
  98        /* spi channel related changes, s3c2412/13 specific */
  99        s3c_device_spi0.name = "s3c2412-spi";
 100        s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
 101        s3c_device_spi1.name = "s3c2412-spi";
 102        s3c_device_spi1.resource[0].start = S3C24XX_PA_SPI + S3C2412_SPI1;
 103        s3c_device_spi1.resource[0].end = S3C24XX_PA_SPI + S3C2412_SPI1 + 0x24;
 104
 105}
 106
 107/* s3c2412_idle
 108 *
 109 * use the standard idle call by ensuring the idle mode
 110 * in power config, then issuing the idle co-processor
 111 * instruction
 112*/
 113
 114static void s3c2412_idle(void)
 115{
 116        unsigned long tmp;
 117
 118        /* ensure our idle mode is to go to idle */
 119
 120        tmp = __raw_readl(S3C2412_PWRCFG);
 121        tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
 122        tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
 123        __raw_writel(tmp, S3C2412_PWRCFG);
 124
 125        cpu_do_idle();
 126}
 127
 128/* s3c2412_map_io
 129 *
 130 * register the standard cpu IO areas, and any passed in from the
 131 * machine specific initialisation.
 132*/
 133
 134void __init s3c2412_map_io(void)
 135{
 136        /* move base of IO */
 137
 138        s3c2412_init_gpio2();
 139
 140        /* set our idle function */
 141
 142        arm_pm_idle = s3c2412_idle;
 143
 144        /* register our io-tables */
 145
 146        iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
 147}
 148
 149/* need to register the subsystem before we actually register the device, and
 150 * we also need to ensure that it has been initialised before any of the
 151 * drivers even try to use it (even if not on an s3c2412 based system)
 152 * as a driver which may support both 2410 and 2440 may try and use it.
 153*/
 154
 155struct bus_type s3c2412_subsys = {
 156        .name = "s3c2412-core",
 157        .dev_name = "s3c2412-core",
 158};
 159
 160static int __init s3c2412_core_init(void)
 161{
 162        return subsys_system_register(&s3c2412_subsys, NULL);
 163}
 164
 165core_initcall(s3c2412_core_init);
 166
 167static struct device s3c2412_dev = {
 168        .bus            = &s3c2412_subsys,
 169};
 170
 171int __init s3c2412_init(void)
 172{
 173        printk("S3C2412: Initialising architecture\n");
 174
 175#ifdef CONFIG_PM_SLEEP
 176        register_syscore_ops(&s3c2412_pm_syscore_ops);
 177        register_syscore_ops(&s3c24xx_irq_syscore_ops);
 178#endif
 179
 180        return device_register(&s3c2412_dev);
 181}
 182