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