Commit 74b265d4 authored by Ben Dooks's avatar Ben Dooks

[ARM] S3C24XX: Move initialisation code to arch/arm/plat-s3c

We need to add plat-s3c to the build to get the headers
that will go in here once moved from include/asm-arm so
we may as well put some useful common s3c code in here
to stop the errors generated form having nothing built.

The cpu setup is now passed the cpu idcode and the table
of supported cpus to s3c_init_cpu() to abstract the
cpu identification out of the initial io setup.

As well as moving the cpu initialisation code, we move the
map of the board specific items up to the calling code as
none of the map_io() functions actually do anything other
than pass this to iotable_init().

This patch does not rename any of the init functions that
will be common to s3c24xx and any other s3c architectures
as this can be done at a later date as it will touch all
the board support files which use functions such as
s3c24xx_init_clocks() and s3c24xx_init_uarts().

Note, the header arch/arm/plat-s3c24xx/include/plat/cpu.h
still has functions that are used by both the cpu and
board initialisation functions. This means that each board
has definitions specific to the cpu support included and
the vice-versa.
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
parent 2cd493fc
...@@ -59,12 +59,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -59,12 +59,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
* machine specific initialisation. * machine specific initialisation.
*/ */
void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size) void __init s3c2410_map_io(void)
{ {
/* register our io-tables */
iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
iotable_init(mach_desc, mach_size);
} }
void __init s3c2410_init_clocks(int xtal) void __init s3c2410_init_clocks(int xtal)
......
...@@ -136,7 +136,7 @@ static void s3c2412_hard_reset(void) ...@@ -136,7 +136,7 @@ static void s3c2412_hard_reset(void)
* machine specific initialisation. * machine specific initialisation.
*/ */
void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) void __init s3c2412_map_io(void)
{ {
/* move base of IO */ /* move base of IO */
...@@ -153,7 +153,6 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) ...@@ -153,7 +153,6 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
/* register our io-tables */ /* register our io-tables */
iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
iotable_init(mach_desc, mach_size);
} }
void __init s3c2412_init_clocks(int xtal) void __init s3c2412_init_clocks(int xtal)
......
...@@ -81,10 +81,9 @@ void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -81,10 +81,9 @@ void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
* machine specific initialisation. * machine specific initialisation.
*/ */
void __init s3c2443_map_io(struct map_desc *mach_desc, int mach_size) void __init s3c2443_map_io(void)
{ {
iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
iotable_init(mach_desc, mach_size);
} }
/* need to register class before we actually register the device, and /* need to register class before we actually register the device, and
......
# dummy makefile, currently just including asm/arm/plat-s3c/include/plat # arch/arm/plat-s3c/Makefile
#
# Copyright 2008 Simtec Electronics
#
# Licensed under GPLv2
obj-n := dummy.o obj-y :=
obj-m :=
obj-n :=
obj- :=
# Core support for all Samsung SoCs
obj-y += init.o
/* linux/arch/arm/plat-s3c/init.c
*
* Copyright (c) 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C series CPU initialisation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/clock.h>
#include <plat/regs-serial.h>
static struct cpu_table *cpu;
static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
struct cpu_table *tab,
unsigned int count)
{
for (; count != 0; count--, tab++) {
if ((idcode & tab->idmask) == tab->idcode)
return tab;
}
return NULL;
}
void __init s3c_init_cpu(unsigned long idcode,
struct cpu_table *cputab, unsigned int cputab_size)
{
cpu = s3c_lookup_cpu(idcode, cputab, cputab_size);
if (cpu == NULL) {
printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
panic("Unknown S3C24XX CPU");
}
printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
if (cpu->map_io == NULL || cpu->init == NULL) {
printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
panic("Unsupported Samsung CPU");
}
cpu->map_io();
}
/* s3c24xx_init_clocks
*
* Initialise the clock subsystem and associated information from the
* given master crystal value.
*
* xtal = 0 -> use default PLL crystal value (normally 12MHz)
* != 0 -> PLL crystal value in Hz
*/
void __init s3c24xx_init_clocks(int xtal)
{
if (xtal == 0)
xtal = 12*1000*1000;
if (cpu == NULL)
panic("s3c24xx_init_clocks: no cpu setup?\n");
if (cpu->init_clocks == NULL)
panic("s3c24xx_init_clocks: cpu has no clock init\n");
else
(cpu->init_clocks)(xtal);
}
/* uart management */
static int nr_uarts __initdata = 0;
static struct s3c2410_uartcfg uart_cfgs[3];
/* s3c24xx_init_uartdevs
*
* copy the specified platform data and configuration into our central
* set of devices, before the data is thrown away after the init process.
*
* This also fills in the array passed to the serial driver for the
* early initialisation of the console.
*/
void __init s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
struct s3c2410_uartcfg *cfgptr = uart_cfgs;
struct s3c24xx_uart_resources *resp;
int uart;
memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
platdev = s3c24xx_uart_src[cfgptr->hwport];
resp = res + cfgptr->hwport;
s3c24xx_uart_devs[uart] = platdev;
platdev->name = name;
platdev->resource = resp->resources;
platdev->num_resources = resp->nr_resources;
platdev->dev.platform_data = cfgptr;
}
nr_uarts = no;
}
void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
if (cpu == NULL)
return;
if (cpu->init_uarts == NULL) {
printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
} else
(cpu->init_uarts)(cfg, no);
}
static int __init s3c_arch_init(void)
{
int ret;
// do the correct init for cpu
if (cpu == NULL)
panic("s3c_arch_init: NULL cpu\n");
ret = (cpu->init)();
if (ret != 0)
return ret;
ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
return ret;
}
arch_initcall(s3c_arch_init);
...@@ -55,16 +55,6 @@ ...@@ -55,16 +55,6 @@
#include <plat/s3c2442.h> #include <plat/s3c2442.h>
#include <plat/s3c2443.h> #include <plat/s3c2443.h>
struct cpu_table {
unsigned long idcode;
unsigned long idmask;
void (*map_io)(struct map_desc *mach_desc, int size);
void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
void (*init_clocks)(int xtal);
int (*init)(void);
const char *name;
};
/* table of supported CPUs */ /* table of supported CPUs */
static const char name_s3c2400[] = "S3C2400"; static const char name_s3c2400[] = "S3C2400";
...@@ -169,23 +159,7 @@ static struct map_desc s3c_iodesc[] __initdata = { ...@@ -169,23 +159,7 @@ static struct map_desc s3c_iodesc[] __initdata = {
IODESC_ENT(UART) IODESC_ENT(UART)
}; };
static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode) /* read cpu identificaiton code */
{
struct cpu_table *tab;
int count;
tab = cpu_ids;
for (count = 0; count < ARRAY_SIZE(cpu_ids); count++, tab++) {
if ((idcode & tab->idmask) == tab->idcode)
return tab;
}
return NULL;
}
/* cpu information */
static struct cpu_table *cpu;
static unsigned long s3c24xx_read_idcode_v5(void) static unsigned long s3c24xx_read_idcode_v5(void)
{ {
...@@ -231,6 +205,7 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) ...@@ -231,6 +205,7 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
unsigned long idcode = 0x0; unsigned long idcode = 0x0;
/* initialise the io descriptors we need for initialisation */ /* initialise the io descriptors we need for initialisation */
iotable_init(mach_desc, size);
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
if (cpu_architecture() >= CPU_ARCH_ARMv5) { if (cpu_architecture() >= CPU_ARCH_ARMv5) {
...@@ -239,117 +214,7 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) ...@@ -239,117 +214,7 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
idcode = s3c24xx_read_idcode_v4(); idcode = s3c24xx_read_idcode_v4();
} }
cpu = s3c_lookup_cpu(idcode);
if (cpu == NULL) {
printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
panic("Unknown S3C24XX CPU");
}
printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
if (cpu->map_io == NULL || cpu->init == NULL) {
printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
panic("Unsupported S3C24XX CPU");
}
arm_pm_restart = s3c24xx_pm_restart; arm_pm_restart = s3c24xx_pm_restart;
(cpu->map_io)(mach_desc, size); s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
}
/* s3c24xx_init_clocks
*
* Initialise the clock subsystem and associated information from the
* given master crystal value.
*
* xtal = 0 -> use default PLL crystal value (normally 12MHz)
* != 0 -> PLL crystal value in Hz
*/
void __init s3c24xx_init_clocks(int xtal)
{
if (xtal == 0)
xtal = 12*1000*1000;
if (cpu == NULL)
panic("s3c24xx_init_clocks: no cpu setup?\n");
if (cpu->init_clocks == NULL)
panic("s3c24xx_init_clocks: cpu has no clock init\n");
else
(cpu->init_clocks)(xtal);
}
/* uart management */
static int nr_uarts __initdata = 0;
static struct s3c2410_uartcfg uart_cfgs[3];
/* s3c24xx_init_uartdevs
*
* copy the specified platform data and configuration into our central
* set of devices, before the data is thrown away after the init process.
*
* This also fills in the array passed to the serial driver for the
* early initialisation of the console.
*/
void __init s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
struct s3c2410_uartcfg *cfgptr = uart_cfgs;
struct s3c24xx_uart_resources *resp;
int uart;
memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
platdev = s3c24xx_uart_src[cfgptr->hwport];
resp = res + cfgptr->hwport;
s3c24xx_uart_devs[uart] = platdev;
platdev->name = name;
platdev->resource = resp->resources;
platdev->num_resources = resp->nr_resources;
platdev->dev.platform_data = cfgptr;
}
nr_uarts = no;
} }
void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
if (cpu == NULL)
return;
if (cpu->init_uarts == NULL) {
printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
} else
(cpu->init_uarts)(cfg, no);
}
static int __init s3c_arch_init(void)
{
int ret;
// do the correct init for cpu
if (cpu == NULL)
panic("s3c_arch_init: NULL cpu\n");
ret = (cpu->init)();
if (ret != 0)
return ret;
ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
return ret;
}
arch_initcall(s3c_arch_init);
...@@ -26,6 +26,21 @@ struct platform_device; ...@@ -26,6 +26,21 @@ struct platform_device;
struct s3c2410_uartcfg; struct s3c2410_uartcfg;
struct map_desc; struct map_desc;
/* per-cpu initialisation function table. */
struct cpu_table {
unsigned long idcode;
unsigned long idmask;
void (*map_io)(void);
void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
void (*init_clocks)(int xtal);
int (*init)(void);
const char *name;
};
extern void s3c_init_cpu(unsigned long idcode,
struct cpu_table *cpus, unsigned int cputab_size);
/* core initialisation functions */ /* core initialisation functions */
extern void s3c24xx_init_irq(void); extern void s3c24xx_init_irq(void);
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
extern int s3c2400_init(void); extern int s3c2400_init(void);
extern void s3c2400_map_io(struct map_desc *mach_desc, int size); extern void s3c2400_map_io(void);
extern void s3c2400_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s3c2400_init_uarts(struct s3c2410_uartcfg *cfg, int no);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
extern int s3c2410_init(void); extern int s3c2410_init(void);
extern void s3c2410_map_io(struct map_desc *mach_desc, int size); extern void s3c2410_map_io(void);
extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
extern int s3c2412_init(void); extern int s3c2412_init(void);
extern void s3c2412_map_io(struct map_desc *mach_desc, int size); extern void s3c2412_map_io(void);
extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
......
...@@ -16,7 +16,7 @@ struct s3c2410_uartcfg; ...@@ -16,7 +16,7 @@ struct s3c2410_uartcfg;
extern int s3c2443_init(void); extern int s3c2443_init(void);
extern void s3c2443_map_io(struct map_desc *mach_desc, int size); extern void s3c2443_map_io(void);
extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
......
...@@ -56,12 +56,11 @@ void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -56,12 +56,11 @@ void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
} }
void __init s3c244x_map_io(struct map_desc *mach_desc, int size) void __init s3c244x_map_io(void)
{ {
/* register our io-tables */ /* register our io-tables */
iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc)); iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
iotable_init(mach_desc, size);
/* rename any peripherals used differing from the s3c2410 */ /* rename any peripherals used differing from the s3c2410 */
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
extern void s3c244x_map_io(struct map_desc *mach_desc, int size); extern void s3c244x_map_io(void);
extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment