Commit 9f04012c authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-arm

parents 329f7dba 72274c9e
...@@ -356,6 +356,16 @@ config HOTPLUG_CPU ...@@ -356,6 +356,16 @@ config HOTPLUG_CPU
Say Y here to experiment with turning CPUs off and on. CPUs Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu. can be controlled through /sys/devices/system/cpu.
config LOCAL_TIMERS
bool "Use local timer interrupts"
depends on SMP && n
default y
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
accounting to be spread across the timer interval, preventing a
"thundering herd" at every timer tick.
config PREEMPT config PREEMPT
bool "Preemptible Kernel (EXPERIMENTAL)" bool "Preemptible Kernel (EXPERIMENTAL)"
depends on EXPERIMENTAL depends on EXPERIMENTAL
......
...@@ -283,8 +283,14 @@ void flush_window(void) ...@@ -283,8 +283,14 @@ void flush_window(void)
putstr("."); putstr(".");
} }
#ifndef arch_error
#define arch_error(x)
#endif
static void error(char *x) static void error(char *x)
{ {
arch_error(x);
putstr("\n\n"); putstr("\n\n");
putstr(x); putstr(x);
putstr("\n\n -- System halted"); putstr("\n\n -- System halted");
......
...@@ -19,12 +19,6 @@ ...@@ -19,12 +19,6 @@
#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
There is no easy way to link multiple scoop devices into one
single entity for the pxa2xx_pcmcia device */
int scoop_num;
struct scoop_pcmcia_dev *scoop_devs;
struct scoop_dev { struct scoop_dev {
void *base; void *base;
spinlock_t scoop_lock; spinlock_t scoop_lock;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/cryptohash.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
...@@ -126,6 +127,9 @@ EXPORT_SYMBOL(__put_user_2); ...@@ -126,6 +127,9 @@ EXPORT_SYMBOL(__put_user_2);
EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_4);
EXPORT_SYMBOL(__put_user_8); EXPORT_SYMBOL(__put_user_8);
/* crypto hash */
EXPORT_SYMBOL(sha_transform);
/* gcc lib functions */ /* gcc lib functions */
EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__ashrdi3);
......
...@@ -47,6 +47,13 @@ ...@@ -47,6 +47,13 @@
movne r0, sp movne r0, sp
adrne lr, 1b adrne lr, 1b
bne do_IPI bne do_IPI
#ifdef CONFIG_LOCAL_TIMERS
test_for_ltirq r0, r6, r5, lr
movne r0, sp
adrne lr, 1b
bne do_local_timer
#endif
#endif #endif
.endm .endm
......
...@@ -264,6 +264,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -264,6 +264,7 @@ int show_interrupts(struct seq_file *p, void *v)
#endif #endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
show_ipi_list(p); show_ipi_list(p);
show_local_irqs(p);
#endif #endif
seq_printf(p, "Err: %10lu\n", irq_err_count); seq_printf(p, "Err: %10lu\n", irq_err_count);
} }
...@@ -995,7 +996,7 @@ void __init init_irq_proc(void) ...@@ -995,7 +996,7 @@ void __init init_irq_proc(void)
struct proc_dir_entry *dir; struct proc_dir_entry *dir;
int irq; int irq;
dir = proc_mkdir("irq", 0); dir = proc_mkdir("irq", NULL);
if (!dir) if (!dir)
return; return;
......
...@@ -142,7 +142,7 @@ int __cpuinit __cpu_up(unsigned int cpu) ...@@ -142,7 +142,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
ret = -EIO; ret = -EIO;
} }
secondary_data.stack = 0; secondary_data.stack = NULL;
secondary_data.pgdir = 0; secondary_data.pgdir = 0;
*pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
...@@ -184,6 +184,11 @@ int __cpuexit __cpu_disable(void) ...@@ -184,6 +184,11 @@ int __cpuexit __cpu_disable(void)
*/ */
migrate_irqs(); migrate_irqs();
/*
* Stop the local timer for this CPU.
*/
local_timer_stop(cpu);
/* /*
* Flush user cache and TLB mappings, and then remove this CPU * Flush user cache and TLB mappings, and then remove this CPU
* from the vm mask set of all processes. * from the vm mask set of all processes.
...@@ -289,6 +294,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void) ...@@ -289,6 +294,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
*/ */
cpu_set(cpu, cpu_online_map); cpu_set(cpu, cpu_online_map);
/*
* Setup local timer for this CPU.
*/
local_timer_setup(cpu);
/* /*
* OK, it's off to the idle thread for us * OK, it's off to the idle thread for us
*/ */
...@@ -359,8 +369,8 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) ...@@ -359,8 +369,8 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
* You must not call this function with disabled interrupts, from a * You must not call this function with disabled interrupts, from a
* hardware interrupt handler, nor from a bottom half handler. * hardware interrupt handler, nor from a bottom half handler.
*/ */
int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry, static int smp_call_function_on_cpu(void (*func)(void *info), void *info,
int wait, cpumask_t callmap) int retry, int wait, cpumask_t callmap)
{ {
struct smp_call_struct data; struct smp_call_struct data;
unsigned long timeout; unsigned long timeout;
...@@ -454,6 +464,18 @@ void show_ipi_list(struct seq_file *p) ...@@ -454,6 +464,18 @@ void show_ipi_list(struct seq_file *p)
seq_putc(p, '\n'); seq_putc(p, '\n');
} }
void show_local_irqs(struct seq_file *p)
{
unsigned int cpu;
seq_printf(p, "LOC: ");
for_each_present_cpu(cpu)
seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs);
seq_putc(p, '\n');
}
static void ipi_timer(struct pt_regs *regs) static void ipi_timer(struct pt_regs *regs)
{ {
int user = user_mode(regs); int user = user_mode(regs);
...@@ -464,6 +486,18 @@ static void ipi_timer(struct pt_regs *regs) ...@@ -464,6 +486,18 @@ static void ipi_timer(struct pt_regs *regs)
irq_exit(); irq_exit();
} }
#ifdef CONFIG_LOCAL_TIMERS
asmlinkage void do_local_timer(struct pt_regs *regs)
{
int cpu = smp_processor_id();
if (local_timer_ack()) {
irq_stat[cpu].local_timer_irqs++;
ipi_timer(regs);
}
}
#endif
/* /*
* ipi_call_function - handle IPI from smp_call_function() * ipi_call_function - handle IPI from smp_call_function()
* *
...@@ -515,7 +549,7 @@ static void ipi_cpu_stop(unsigned int cpu) ...@@ -515,7 +549,7 @@ static void ipi_cpu_stop(unsigned int cpu)
* *
* Bit 0 - Inter-processor function call * Bit 0 - Inter-processor function call
*/ */
void do_IPI(struct pt_regs *regs) asmlinkage void do_IPI(struct pt_regs *regs)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
struct ipi_data *ipi = &per_cpu(ipi_data, cpu); struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
......
...@@ -62,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = { ...@@ -62,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = {
.io_out = CORGI_SCOOP_IO_OUT, .io_out = CORGI_SCOOP_IO_OUT,
}; };
struct platform_device corgiscoop_device = {
.name = "sharp-scoop",
.id = -1,
.dev = {
.platform_data = &corgi_scoop_setup,
},
.num_resources = ARRAY_SIZE(corgi_scoop_resources),
.resource = corgi_scoop_resources,
};
static void corgi_pcmcia_init(void)
{
/* Setup default state of GPIO outputs
before we enable them as outputs. */
GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
GPIO_bit(GPIO53_nPCE_2);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
pxa_gpio_mode(GPIO52_nPCE_1_MD);
pxa_gpio_mode(GPIO53_nPCE_2_MD);
pxa_gpio_mode(GPIO54_pSKTSEL_MD);
}
static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
{ {
.dev = &corgiscoop_device.dev, .dev = &corgiscoop_device.dev,
...@@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { ...@@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
}, },
}; };
struct platform_device corgiscoop_device = { static struct scoop_pcmcia_config corgi_pcmcia_config = {
.name = "sharp-scoop", .devs = &corgi_pcmcia_scoop[0],
.id = -1, .num_devs = 1,
.dev = { .pcmcia_init = corgi_pcmcia_init,
.platform_data = &corgi_scoop_setup,
},
.num_resources = ARRAY_SIZE(corgi_scoop_resources),
.resource = corgi_scoop_resources,
}; };
EXPORT_SYMBOL(corgiscoop_device);
/* /*
* Corgi SSP Device * Corgi SSP Device
...@@ -294,8 +323,7 @@ static void __init corgi_init(void) ...@@ -294,8 +323,7 @@ static void __init corgi_init(void)
pxa_set_mci_info(&corgi_mci_platform_data); pxa_set_mci_info(&corgi_mci_platform_data);
pxa_set_ficp_info(&corgi_ficp_platform_data); pxa_set_ficp_info(&corgi_ficp_platform_data);
scoop_num = 1; platform_scoop_config = &corgi_pcmcia_config;
scoop_devs = &corgi_pcmcia_scoop[0];
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
} }
......
...@@ -65,6 +65,27 @@ struct platform_device poodle_scoop_device = { ...@@ -65,6 +65,27 @@ struct platform_device poodle_scoop_device = {
.resource = poodle_scoop_resources, .resource = poodle_scoop_resources,
}; };
static void poodle_pcmcia_init(void)
{
/* Setup default state of GPIO outputs
before we enable them as outputs. */
GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
GPIO_bit(GPIO53_nPCE_2);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
pxa_gpio_mode(GPIO52_nPCE_1_MD);
pxa_gpio_mode(GPIO53_nPCE_2_MD);
pxa_gpio_mode(GPIO54_pSKTSEL_MD);
}
static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
{ {
.dev = &poodle_scoop_device.dev, .dev = &poodle_scoop_device.dev,
...@@ -74,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { ...@@ -74,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
}, },
}; };
static struct scoop_pcmcia_config poodle_pcmcia_config = {
.devs = &poodle_pcmcia_scoop[0],
.num_devs = 1,
.pcmcia_init = poodle_pcmcia_init,
};
EXPORT_SYMBOL(poodle_scoop_device);
/* LoCoMo device */ /* LoCoMo device */
static struct resource locomo_resources[] = { static struct resource locomo_resources[] = {
...@@ -268,8 +297,7 @@ static void __init poodle_init(void) ...@@ -268,8 +297,7 @@ static void __init poodle_init(void)
pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_mci_info(&poodle_mci_platform_data);
pxa_set_ficp_info(&poodle_ficp_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data);
scoop_num = 1; platform_scoop_config = &poodle_pcmcia_config;
scoop_devs = &poodle_pcmcia_scoop[0];
ret = platform_add_devices(devices, ARRAY_SIZE(devices)); ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret) { if (ret) {
......
...@@ -104,6 +104,66 @@ struct platform_device spitzscoop2_device = { ...@@ -104,6 +104,66 @@ struct platform_device spitzscoop2_device = {
.resource = spitz_scoop2_resources, .resource = spitz_scoop2_resources,
}; };
#define SPITZ_PWR_SD 0x01
#define SPITZ_PWR_CF 0x02
/* Power control is shared with between one of the CF slots and SD */
static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr)
{
unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
if (new_cpr & 0x0007) {
set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
if (!(cpr & 0x0002) && !(cpr & 0x0004))
mdelay(5);
if (device == SPITZ_PWR_CF)
cpr |= 0x0002;
if (device == SPITZ_PWR_SD)
cpr |= 0x0004;
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
} else {
if (device == SPITZ_PWR_CF)
cpr &= ~0x0002;
if (device == SPITZ_PWR_SD)
cpr &= ~0x0004;
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
mdelay(1);
reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
}
}
}
static void spitz_pcmcia_init(void)
{
/* Setup default state of GPIO outputs
before we enable them as outputs. */
GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2);
GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
pxa_gpio_mode(GPIO85_nPCE_1_MD);
pxa_gpio_mode(GPIO54_nPCE_2_MD);
pxa_gpio_mode(GPIO104_pSKTSEL_MD);
}
static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr)
{
/* Only need to override behaviour for slot 0 */
if (nr == 0)
spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr);
else
write_scoop_reg(scoop, SCOOP_CPR, cpr);
}
static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
{ {
.dev = &spitzscoop_device.dev, .dev = &spitzscoop_device.dev,
...@@ -117,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { ...@@ -117,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
}, },
}; };
static struct scoop_pcmcia_config spitz_pcmcia_config = {
.devs = &spitz_pcmcia_scoop[0],
.num_devs = 2,
.pcmcia_init = spitz_pcmcia_init,
.power_ctrl = spitz_pcmcia_pwr,
};
EXPORT_SYMBOL(spitzscoop_device);
EXPORT_SYMBOL(spitzscoop2_device);
/* /*
* Spitz SSP Device * Spitz SSP Device
...@@ -235,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in ...@@ -235,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in
return 0; return 0;
} }
/* Power control is shared with one of the CF slots so we have a mess */
static void spitz_mci_setpower(struct device *dev, unsigned int vdd) static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
{ {
struct pxamci_platform_data* p_d = dev->platform_data; struct pxamci_platform_data* p_d = dev->platform_data;
unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); if (( 1 << vdd) & p_d->ocr_mask)
spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004);
if (( 1 << vdd) & p_d->ocr_mask) { else
/* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000);
set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
mdelay(2);
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04);
} else {
/* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */
write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04);
if (!(cpr | 0x02)) {
mdelay(1);
reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
}
}
} }
static int spitz_mci_get_ro(struct device *dev) static int spitz_mci_get_ro(struct device *dev)
...@@ -351,8 +408,8 @@ static void __init common_init(void) ...@@ -351,8 +408,8 @@ static void __init common_init(void)
static void __init spitz_init(void) static void __init spitz_init(void)
{ {
scoop_num = 2; platform_scoop_config = &spitz_pcmcia_config;
scoop_devs = &spitz_pcmcia_scoop[0];
spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
common_init(); common_init();
......
...@@ -132,11 +132,13 @@ static void __init pxa_timer_init(void) ...@@ -132,11 +132,13 @@ static void __init pxa_timer_init(void)
tv.tv_sec = pxa_get_rtc_time(); tv.tv_sec = pxa_get_rtc_time();
do_settimeofday(&tv); do_settimeofday(&tv);
OSMR0 = 0; /* set initial match at 0 */ OIER = 0; /* disable any timer interrupts */
OSCR = LATCH*2; /* push OSCR out of the way */
OSMR0 = LATCH; /* set initial match */
OSSR = 0xf; /* clear status on all timers */ OSSR = 0xf; /* clear status on all timers */
setup_irq(IRQ_OST0, &pxa_timer_irq); setup_irq(IRQ_OST0, &pxa_timer_irq);
OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
OSCR = 0; /* initialize free-running timer, force first match */ OSCR = 0; /* initialize free-running timer */
} }
#ifdef CONFIG_NO_IDLE_HZ #ifdef CONFIG_NO_IDLE_HZ
......
...@@ -98,6 +98,9 @@ struct platform_device tosascoop_jc_device = { ...@@ -98,6 +98,9 @@ struct platform_device tosascoop_jc_device = {
.resource = tosa_scoop_jc_resources, .resource = tosa_scoop_jc_resources,
}; };
/*
* PCMCIA
*/
static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
{ {
.dev = &tosascoop_device.dev, .dev = &tosascoop_device.dev,
...@@ -111,16 +114,155 @@ static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { ...@@ -111,16 +114,155 @@ static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
}, },
}; };
static void tosa_pcmcia_init(void)
{
/* Setup default state of GPIO outputs
before we enable them as outputs. */
GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
GPIO_bit(GPIO53_nPCE_2);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
pxa_gpio_mode(GPIO52_nPCE_1_MD);
pxa_gpio_mode(GPIO53_nPCE_2_MD);
pxa_gpio_mode(GPIO54_pSKTSEL_MD);
}
static struct scoop_pcmcia_config tosa_pcmcia_config = {
.devs = &tosa_pcmcia_scoop[0],
.num_devs = 2,
.pcmcia_init = tosa_pcmcia_init,
};
/*
* USB Device Controller
*/
static void tosa_udc_command(int cmd)
{
switch(cmd) {
case PXA2XX_UDC_CMD_CONNECT:
set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
break;
case PXA2XX_UDC_CMD_DISCONNECT:
reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
break;
}
}
static int tosa_udc_is_connected(void)
{
return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0);
}
static struct pxa2xx_udc_mach_info udc_info __initdata = {
.udc_command = tosa_udc_command,
.udc_is_connected = tosa_udc_is_connected,
};
/*
* MMC/SD Device
*/
static struct pxamci_platform_data tosa_mci_platform_data;
static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int, void *, struct pt_regs *), void *data)
{
int err;
/* setup GPIO for PXA25x MMC controller */
pxa_gpio_mode(GPIO6_MMCCLK_MD);
pxa_gpio_mode(GPIO8_MMCCS0_MD);
pxa_gpio_mode(TOSA_GPIO_nSD_DETECT | GPIO_IN);
tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, SA_INTERRUPT,
"MMC/SD card detect", data);
if (err) {
printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
return -1;
}
set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
return 0;
}
static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
{
struct pxamci_platform_data* p_d = dev->platform_data;
if (( 1 << vdd) & p_d->ocr_mask) {
set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
} else {
reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
}
}
static int tosa_mci_get_ro(struct device *dev)
{
return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP);
}
static void tosa_mci_exit(struct device *dev, void *data)
{
free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
}
static struct pxamci_platform_data tosa_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
.init = tosa_mci_init,
.get_ro = tosa_mci_get_ro,
.setpower = tosa_mci_setpower,
.exit = tosa_mci_exit,
};
/*
* Irda
*/
static void tosa_irda_transceiver_mode(struct device *dev, int mode)
{
if (mode & IR_OFF) {
reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
pxa_gpio_mode(GPIO47_STTXD|GPIO_DFLT_LOW);
pxa_gpio_mode(GPIO47_STTXD|GPIO_OUT);
} else {
pxa_gpio_mode(GPIO47_STTXD_MD);
set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
}
}
static struct pxaficp_platform_data tosa_ficp_platform_data = {
.transceiver_cap = IR_SIRMODE | IR_OFF,
.transceiver_mode = tosa_irda_transceiver_mode,
};
/*
* Tosa Keyboard
*/
static struct platform_device tosakbd_device = {
.name = "tosa-keyboard",
.id = -1,
};
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&tosascoop_device, &tosascoop_device,
&tosascoop_jc_device, &tosascoop_jc_device,
&tosakbd_device,
}; };
static void __init tosa_init(void) static void __init tosa_init(void)
{ {
pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN);
pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);
/* setup sleep mode values */ /* setup sleep mode values */
PWER = 0x00000002; PWER = 0x00000002;
...@@ -131,13 +273,15 @@ static void __init tosa_init(void) ...@@ -131,13 +273,15 @@ static void __init tosa_init(void)
PGSR2 = 0x00014000; PGSR2 = 0x00014000;
PCFR |= PCFR_OPDE; PCFR |= PCFR_OPDE;
// enable batt_fault /* enable batt_fault */
PMCR = 0x01; PMCR = 0x01;
platform_add_devices(devices, ARRAY_SIZE(devices)); pxa_set_mci_info(&tosa_mci_platform_data);
pxa_set_udc_info(&udc_info);
pxa_set_ficp_info(&tosa_ficp_platform_data);
platform_scoop_config = &tosa_pcmcia_config;
scoop_num = 2; platform_add_devices(devices, ARRAY_SIZE(devices));
scoop_devs = &tosa_pcmcia_scoop[0];
} }
static void __init fixup_tosa(struct machine_desc *desc, static void __init fixup_tosa(struct machine_desc *desc,
......
...@@ -550,6 +550,11 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg ...@@ -550,6 +550,11 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg
timer_tick(regs); timer_tick(regs);
#ifdef CONFIG_SMP
smp_send_timer();
update_process_times(user_mode(regs));
#endif
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -32,7 +32,7 @@ static unsigned int __init get_core_count(void) ...@@ -32,7 +32,7 @@ static unsigned int __init get_core_count(void)
{ {
unsigned int ncores; unsigned int ncores;
ncores = __raw_readl(IO_ADDRESS(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG); ncores = __raw_readl(__io_address(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
return (ncores & 0x03) + 1; return (ncores & 0x03) + 1;
} }
...@@ -133,12 +133,12 @@ static void __init poke_milo(void) ...@@ -133,12 +133,12 @@ static void __init poke_milo(void)
#if 1 #if 1
#define REALVIEW_SYS_FLAGSS_OFFSET 0x30 #define REALVIEW_SYS_FLAGSS_OFFSET 0x30
__raw_writel(virt_to_phys(realview_secondary_startup), __raw_writel(virt_to_phys(realview_secondary_startup),
(IO_ADDRESS(REALVIEW_SYS_BASE) + __io_address(REALVIEW_SYS_BASE) +
REALVIEW_SYS_FLAGSS_OFFSET)); REALVIEW_SYS_FLAGSS_OFFSET);
#define REALVIEW_SYS_FLAGSC_OFFSET 0x34 #define REALVIEW_SYS_FLAGSC_OFFSET 0x34
__raw_writel(3, __raw_writel(3,
(IO_ADDRESS(REALVIEW_SYS_BASE) + __io_address(REALVIEW_SYS_BASE) +
REALVIEW_SYS_FLAGSC_OFFSET)); REALVIEW_SYS_FLAGSC_OFFSET);
#endif #endif
mb(); mb();
......
...@@ -121,6 +121,14 @@ config S3C2410_BOOT_WATCHDOG ...@@ -121,6 +121,14 @@ config S3C2410_BOOT_WATCHDOG
system resets depends on the value of PCLK. The timeout on an system resets depends on the value of PCLK. The timeout on an
200MHz s3c2410 should be about 30 seconds. 200MHz s3c2410 should be about 30 seconds.
config S3C2410_BOOT_ERROR_RESET
bool "S3C2410 Reboot on decompression error"
depends on ARCH_S3C2410
help
Say y here to use the watchdog to reset the system if the
kernel decompressor detects an error during decompression.
comment "S3C2410 Setup" comment "S3C2410 Setup"
config S3C2410_DMA config S3C2410_DMA
......
...@@ -89,32 +89,63 @@ ...@@ -89,32 +89,63 @@
/* macros to modify the physical addresses for io space */ /* macros to modify the physical addresses for io space */
#define PA_CS2(item) ((item) + S3C2410_CS2) #define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
#define PA_CS3(item) ((item) + S3C2410_CS3) #define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
#define PA_CS4(item) ((item) + S3C2410_CS4) #define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
#define PA_CS5(item) ((item) + S3C2410_CS5) #define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
static struct map_desc bast_iodesc[] __initdata = { static struct map_desc bast_iodesc[] __initdata = {
/* ISA IO areas */ /* ISA IO areas */
{
{ (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, .virtual = (u32)S3C24XX_VA_ISA_BYTE,
{ (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, .pfn = PA_CS2(BAST_PA_ISAIO),
.length = SZ_16M,
/* we could possibly compress the next set down into a set of smaller tables .type = MT_DEVICE,
* pagetables, but that would mean using an L2 section, and it still means }, {
* we cannot actually feed the same register to an LDR due to 16K spacing .virtual = (u32)S3C24XX_VA_ISA_WORD,
*/ .pfn = PA_CS3(BAST_PA_ISAIO),
.length = SZ_16M,
.type = MT_DEVICE,
},
/* bast CPLD control registers, and external interrupt controls */ /* bast CPLD control registers, and external interrupt controls */
{ (u32)BAST_VA_CTRL1, BAST_PA_CTRL1, SZ_1M, MT_DEVICE }, {
{ (u32)BAST_VA_CTRL2, BAST_PA_CTRL2, SZ_1M, MT_DEVICE }, .virtual = (u32)BAST_VA_CTRL1,
{ (u32)BAST_VA_CTRL3, BAST_PA_CTRL3, SZ_1M, MT_DEVICE }, .pfn = __phys_to_pfn(BAST_PA_CTRL1),
{ (u32)BAST_VA_CTRL4, BAST_PA_CTRL4, SZ_1M, MT_DEVICE }, .length = SZ_1M,
.type = MT_DEVICE,
}, {
.virtual = (u32)BAST_VA_CTRL2,
.pfn = __phys_to_pfn(BAST_PA_CTRL2),
.length = SZ_1M,
.type = MT_DEVICE,
}, {
.virtual = (u32)BAST_VA_CTRL3,
.pfn = __phys_to_pfn(BAST_PA_CTRL3),
.length = SZ_1M,
.type = MT_DEVICE,
}, {
.virtual = (u32)BAST_VA_CTRL4,
.pfn = __phys_to_pfn(BAST_PA_CTRL4),
.length = SZ_1M,
.type = MT_DEVICE,
},
/* PC104 IRQ mux */ /* PC104 IRQ mux */
{ (u32)BAST_VA_PC104_IRQREQ, BAST_PA_PC104_IRQREQ, SZ_1M, MT_DEVICE }, {
{ (u32)BAST_VA_PC104_IRQRAW, BAST_PA_PC104_IRQRAW, SZ_1M, MT_DEVICE }, .virtual = (u32)BAST_VA_PC104_IRQREQ,
{ (u32)BAST_VA_PC104_IRQMASK, BAST_PA_PC104_IRQMASK, SZ_1M, MT_DEVICE }, .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ),
.length = SZ_1M,
.type = MT_DEVICE,
}, {
.virtual = (u32)BAST_VA_PC104_IRQRAW,
.pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW),
.length = SZ_1M,
.type = MT_DEVICE,
}, {
.virtual = (u32)BAST_VA_PC104_IRQMASK,
.pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK),
.length = SZ_1M,
.type = MT_DEVICE,
},
/* peripheral space... one for each of fast/slow/byte/16bit */ /* peripheral space... one for each of fast/slow/byte/16bit */
/* note, ide is only decoded in word space, even though some registers /* note, ide is only decoded in word space, even though some registers
......
...@@ -74,27 +74,47 @@ ...@@ -74,27 +74,47 @@
/* macros to modify the physical addresses for io space */ /* macros to modify the physical addresses for io space */
#define PA_CS2(item) ((item) + S3C2410_CS2) #define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
#define PA_CS3(item) ((item) + S3C2410_CS3) #define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
#define PA_CS4(item) ((item) + S3C2410_CS4) #define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
#define PA_CS5(item) ((item) + S3C2410_CS5) #define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
static struct map_desc vr1000_iodesc[] __initdata = { static struct map_desc vr1000_iodesc[] __initdata = {
/* ISA IO areas */ /* ISA IO areas */
{
.virtual = (u32)S3C24XX_VA_ISA_BYTE,
.pfn = PA_CS2(BAST_PA_ISAIO),
.length = SZ_16M,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_WORD,
.pfn = PA_CS3(BAST_PA_ISAIO),
.length = SZ_16M,
.type = MT_DEVICE,
},
{ (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, /* CPLD control registers, and external interrupt controls */
{ (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, {
.virtual = (u32)VR1000_VA_CTRL1,
/* we could possibly compress the next set down into a set of smaller tables .pfn = __phys_to_pfn(VR1000_PA_CTRL1),
* pagetables, but that would mean using an L2 section, and it still means .length = SZ_1M,
* we cannot actually feed the same register to an LDR due to 16K spacing .type = MT_DEVICE,
*/ }, {
.virtual = (u32)VR1000_VA_CTRL2,
/* bast CPLD control registers, and external interrupt controls */ .pfn = __phys_to_pfn(VR1000_PA_CTRL2),
{ (u32)VR1000_VA_CTRL1, VR1000_PA_CTRL1, SZ_1M, MT_DEVICE }, .length = SZ_1M,
{ (u32)VR1000_VA_CTRL2, VR1000_PA_CTRL2, SZ_1M, MT_DEVICE }, .type = MT_DEVICE,
{ (u32)VR1000_VA_CTRL3, VR1000_PA_CTRL3, SZ_1M, MT_DEVICE }, }, {
{ (u32)VR1000_VA_CTRL4, VR1000_PA_CTRL4, SZ_1M, MT_DEVICE }, .virtual = (u32)VR1000_VA_CTRL3,
.pfn = __phys_to_pfn(VR1000_PA_CTRL3),
.length = SZ_1M,
.type = MT_DEVICE,
}, {
.virtual = (u32)VR1000_VA_CTRL4,
.pfn = __phys_to_pfn(VR1000_PA_CTRL4),
.length = SZ_1M,
.type = MT_DEVICE,
},
/* peripheral space... one for each of fast/slow/byte/16bit */ /* peripheral space... one for each of fast/slow/byte/16bit */
/* note, ide is only decoded in word space, even though some registers /* note, ide is only decoded in word space, even though some registers
......
...@@ -124,11 +124,13 @@ static void __init sa1100_timer_init(void) ...@@ -124,11 +124,13 @@ static void __init sa1100_timer_init(void)
tv.tv_sec = sa1100_get_rtc_time(); tv.tv_sec = sa1100_get_rtc_time();
do_settimeofday(&tv); do_settimeofday(&tv);
OSMR0 = 0; /* set initial match at 0 */ OIER = 0; /* disable any timer interrupts */
OSCR = LATCH*2; /* push OSCR out of the way */
OSMR0 = LATCH; /* set initial match */
OSSR = 0xf; /* clear status on all timers */ OSSR = 0xf; /* clear status on all timers */
setup_irq(IRQ_OST0, &sa1100_timer_irq); setup_irq(IRQ_OST0, &sa1100_timer_irq);
OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
OSCR = 0; /* initialize free-running timer, force first match */ OSCR = 0; /* initialize free-running timer */
} }
#ifdef CONFIG_NO_IDLE_HZ #ifdef CONFIG_NO_IDLE_HZ
......
...@@ -22,16 +22,20 @@ ...@@ -22,16 +22,20 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hardware/scoop.h> #include <asm/hardware/scoop.h>
#ifdef CONFIG_SA1100_COLLIE
#include <asm/arch-sa1100/collie.h>
#else
#include <asm/arch-pxa/pxa-regs.h>
#endif
#include "soc_common.h" #include "soc_common.h"
#define NO_KEEP_VS 0x0001 #define NO_KEEP_VS 0x0001
/* PCMCIA to Scoop linkage
There is no easy way to link multiple scoop devices into one
single entity for the pxa2xx_pcmcia device so this structure
is used which is setup by the platform code
*/
struct scoop_pcmcia_config *platform_scoop_config;
#define SCOOP_DEV platform_scoop_config->devs
static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
{ {
reset_scoop(scoopdev->dev); reset_scoop(scoopdev->dev);
...@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; int ret;
#ifndef CONFIG_SA1100_COLLIE if (platform_scoop_config->pcmcia_init)
/* platform_scoop_config->pcmcia_init();
* Setup default state of GPIO outputs
* before we enable them as outputs.
*/
GPSR(GPIO48_nPOE) =
GPIO_bit(GPIO48_nPOE) |
GPIO_bit(GPIO49_nPWE) |
GPIO_bit(GPIO50_nPIOR) |
GPIO_bit(GPIO51_nPIOW) |
GPIO_bit(GPIO52_nPCE_1) |
GPIO_bit(GPIO53_nPCE_2);
pxa_gpio_mode(GPIO48_nPOE_MD);
pxa_gpio_mode(GPIO49_nPWE_MD);
pxa_gpio_mode(GPIO50_nPIOR_MD);
pxa_gpio_mode(GPIO51_nPIOW_MD);
pxa_gpio_mode(GPIO52_nPCE_1_MD);
pxa_gpio_mode(GPIO53_nPCE_2_MD);
pxa_gpio_mode(GPIO54_pSKTSEL_MD);
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
#endif
/* Register interrupts */ /* Register interrupts */
if (scoop_devs[skt->nr].cd_irq >= 0) { if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq; struct pcmcia_irqs cd_irq;
cd_irq.sock = skt->nr; cd_irq.sock = skt->nr;
cd_irq.irq = scoop_devs[skt->nr].cd_irq; cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
cd_irq.str = scoop_devs[skt->nr].cd_irq_str; cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
if (ret) { if (ret) {
...@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
} }
} }
skt->irq = scoop_devs[skt->nr].irq; skt->irq = SCOOP_DEV[skt->nr].irq;
return 0; return 0;
} }
static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
if (scoop_devs[skt->nr].cd_irq >= 0) { if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq; struct pcmcia_irqs cd_irq;
cd_irq.sock = skt->nr; cd_irq.sock = skt->nr;
cd_irq.irq = scoop_devs[skt->nr].cd_irq; cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
cd_irq.str = scoop_devs[skt->nr].cd_irq_str; cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
soc_pcmcia_free_irqs(skt, &cd_irq, 1); soc_pcmcia_free_irqs(skt, &cd_irq, 1);
} }
} }
...@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
unsigned short cpr, csr; unsigned short cpr, csr;
struct device *scoop = scoop_devs[skt->nr].dev; struct device *scoop = SCOOP_DEV[skt->nr].dev;
cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
write_scoop_reg(scoop, SCOOP_ISR, 0x0000); write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
...@@ -116,22 +98,26 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -116,22 +98,26 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
if (csr & 0x0004) { if (csr & 0x0004) {
/* card eject */ /* card eject */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000); write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
} }
else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
/* keep vs1,vs2 */ /* keep vs1,vs2 */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000); write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
csr |= scoop_devs[skt->nr].keep_vs; csr |= SCOOP_DEV[skt->nr].keep_vs;
} }
else if (cpr & 0x0003) { else if (cpr & 0x0003) {
/* power on */ /* power on */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000); write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
} }
else { else {
/* card detect */ /* card detect */
if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) {
write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
} else {
write_scoop_reg(scoop, SCOOP_CDR, 0x0002); write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
} }
}
state->detect = (csr & 0x0004) ? 0 : 1; state->detect = (csr & 0x0004) ? 0 : 1;
state->ready = (csr & 0x0002) ? 1 : 0; state->ready = (csr & 0x0002) ? 1 : 0;
...@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
} }
} }
...@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state) const socket_state_t *state)
{ {
unsigned long flags; unsigned long flags;
struct device *scoop = scoop_devs[skt->nr].dev; struct device *scoop = SCOOP_DEV[skt->nr].dev;
unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
...@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080;
nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E;
if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) {
ncpr |= (state->Vcc == 33) ? 0x0002 :
(state->Vcc == 50) ? 0x0002 : 0;
} else {
ncpr |= (state->Vcc == 33) ? 0x0001 : ncpr |= (state->Vcc == 33) ? 0x0001 :
(state->Vcc == 50) ? 0x0002 : 0; (state->Vcc == 50) ? 0x0002 : 0;
}
nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
nccr |= (state->flags&SS_RESET)? 0x0080: 0; nccr |= (state->flags&SS_RESET)? 0x0080: 0;
...@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
((skt->status&SS_WRPROT) ? 0x0008 : 0); ((skt->status&SS_WRPROT) ? 0x0008 : 0);
if (!(ncpr & 0x0003)) { if (!(ncpr & 0x0003)) {
scoop_devs[skt->nr].keep_rd = 0; SCOOP_DEV[skt->nr].keep_rd = 0;
} else if (!scoop_devs[skt->nr].keep_rd) { } else if (!SCOOP_DEV[skt->nr].keep_rd) {
if (nccr & 0x0080) if (nccr & 0x0080)
scoop_devs[skt->nr].keep_rd = 1; SCOOP_DEV[skt->nr].keep_rd = 1;
else else
nccr |= 0x0080; nccr |= 0x0080;
} }
if (mcr != nmcr) if (mcr != nmcr)
write_scoop_reg(scoop, SCOOP_MCR, nmcr); write_scoop_reg(scoop, SCOOP_MCR, nmcr);
if (cpr != ncpr) if (cpr != ncpr) {
if (platform_scoop_config->power_ctrl)
platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr);
else
write_scoop_reg(scoop, SCOOP_CPR, ncpr); write_scoop_reg(scoop, SCOOP_CPR, ncpr);
}
if (ccr != nccr) if (ccr != nccr)
write_scoop_reg(scoop, SCOOP_CCR, nccr); write_scoop_reg(scoop, SCOOP_CCR, nccr);
if (imr != nimr) if (imr != nimr)
...@@ -214,26 +208,26 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -214,26 +208,26 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{ {
sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
/* Enable interrupt */ /* Enable interrupt */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
if (machine_is_collie()) if (machine_is_collie())
/* We need to disable SS_OUTPUT_ENA here. */ /* We need to disable SS_OUTPUT_ENA here. */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
} }
static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{ {
/* CF_BUS_OFF */ /* CF_BUS_OFF */
sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
if (machine_is_collie()) if (machine_is_collie())
/* We need to disable SS_OUTPUT_ENA here. */ /* We need to disable SS_OUTPUT_ENA here. */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
} }
static struct pcmcia_low_level sharpsl_pcmcia_ops = { static struct pcmcia_low_level sharpsl_pcmcia_ops = {
...@@ -248,9 +242,9 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops = { ...@@ -248,9 +242,9 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops = {
.nr = 0, .nr = 0,
}; };
static struct platform_device *sharpsl_pcmcia_device;
#ifdef CONFIG_SA1100_COLLIE #ifdef CONFIG_SA1100_COLLIE
#include "sa11xx_base.h"
int __init pcmcia_collie_init(struct device *dev) int __init pcmcia_collie_init(struct device *dev)
{ {
int ret = -ENODEV; int ret = -ENODEV;
...@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev) ...@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev)
#else #else
static struct platform_device *sharpsl_pcmcia_device;
static int __init sharpsl_pcmcia_init(void) static int __init sharpsl_pcmcia_init(void)
{ {
int ret; int ret;
sharpsl_pcmcia_ops.nr=scoop_num; sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
if (!sharpsl_pcmcia_device) if (!sharpsl_pcmcia_device)
return -ENOMEM; return -ENOMEM;
...@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void) ...@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void)
memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
ret = platform_device_register(sharpsl_pcmcia_device); ret = platform_device_register(sharpsl_pcmcia_device);
if (ret) if (ret)
......
...@@ -518,7 +518,7 @@ static struct amba_driver clcd_driver = { ...@@ -518,7 +518,7 @@ static struct amba_driver clcd_driver = {
.id_table = clcdfb_id_table, .id_table = clcdfb_id_table,
}; };
int __init amba_clcdfb_init(void) static int __init amba_clcdfb_init(void)
{ {
if (fb_get_options("ambafb", NULL)) if (fb_get_options("ambafb", NULL))
return -ENODEV; return -ENODEV;
......
...@@ -116,6 +116,8 @@ putstr(const char *ptr) ...@@ -116,6 +116,8 @@ putstr(const char *ptr)
} }
} }
#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
/* CONFIG_S3C2410_BOOT_WATCHDOG /* CONFIG_S3C2410_BOOT_WATCHDOG
* *
* Simple boot-time watchdog setup, to reboot the system if there is * Simple boot-time watchdog setup, to reboot the system if there is
...@@ -126,8 +128,6 @@ putstr(const char *ptr) ...@@ -126,8 +128,6 @@ putstr(const char *ptr)
#define WDOG_COUNT (0xff00) #define WDOG_COUNT (0xff00)
#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
static inline void arch_decomp_wdog(void) static inline void arch_decomp_wdog(void)
{ {
__raw_writel(WDOG_COUNT, S3C2410_WTCNT); __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
...@@ -145,6 +145,24 @@ static void arch_decomp_wdog_start(void) ...@@ -145,6 +145,24 @@ static void arch_decomp_wdog_start(void)
#define arch_decomp_wdog() #define arch_decomp_wdog()
#endif #endif
#ifdef CONFIG_S3C2410_BOOT_ERROR_RESET
static void arch_decomp_error(const char *x)
{
putstr("\n\n");
putstr(x);
putstr("\n\n -- System resetting\n");
__raw_writel(0x4000, S3C2410_WTDAT);
__raw_writel(0x4000, S3C2410_WTCNT);
__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
while(1);
}
#define arch_error arch_decomp_error
#endif
static void error(char *err); static void error(char *err);
static void static void
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
typedef struct { typedef struct {
unsigned int __softirq_pending; unsigned int __softirq_pending;
unsigned int local_timer_irqs;
} ____cacheline_aligned irq_cpustat_t; } ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
......
...@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev { ...@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev {
unsigned char keep_rd; unsigned char keep_rd;
}; };
extern int scoop_num; struct scoop_pcmcia_config {
extern struct scoop_pcmcia_dev *scoop_devs; struct scoop_pcmcia_dev *devs;
int num_devs;
void (*pcmcia_init)(void);
void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
};
extern struct scoop_pcmcia_config *platform_scoop_config;
void reset_scoop(struct device *dev); void reset_scoop(struct device *dev);
unsigned short set_scoop_gpio(struct device *dev, unsigned short bit); unsigned short set_scoop_gpio(struct device *dev, unsigned short bit);
......
...@@ -36,6 +36,11 @@ struct seq_file; ...@@ -36,6 +36,11 @@ struct seq_file;
*/ */
extern void show_ipi_list(struct seq_file *p); extern void show_ipi_list(struct seq_file *p);
/*
* Called from assembly code, this handles an IPI.
*/
asmlinkage void do_IPI(struct pt_regs *regs);
/* /*
* Move global data into per-processor storage. * Move global data into per-processor storage.
*/ */
...@@ -46,12 +51,23 @@ extern void smp_store_cpu_info(unsigned int cpuid); ...@@ -46,12 +51,23 @@ extern void smp_store_cpu_info(unsigned int cpuid);
*/ */
extern void smp_cross_call(cpumask_t callmap); extern void smp_cross_call(cpumask_t callmap);
/*
* Broadcast a timer interrupt to the other CPUs.
*/
extern void smp_send_timer(void);
/* /*
* Boot a secondary CPU, and assign it the specified idle task. * Boot a secondary CPU, and assign it the specified idle task.
* This also gives us the initial stack to use for this CPU. * This also gives us the initial stack to use for this CPU.
*/ */
extern int boot_secondary(unsigned int cpu, struct task_struct *); extern int boot_secondary(unsigned int cpu, struct task_struct *);
/*
* Called from platform specific assembly code, this is the
* secondary CPU entry point.
*/
asmlinkage void secondary_start_kernel(void);
/* /*
* Perform platform specific initialisation of the specified CPU. * Perform platform specific initialisation of the specified CPU.
*/ */
...@@ -76,4 +92,42 @@ extern void platform_cpu_die(unsigned int cpu); ...@@ -76,4 +92,42 @@ extern void platform_cpu_die(unsigned int cpu);
extern int platform_cpu_kill(unsigned int cpu); extern int platform_cpu_kill(unsigned int cpu);
extern void platform_cpu_enable(unsigned int cpu); extern void platform_cpu_enable(unsigned int cpu);
#ifdef CONFIG_LOCAL_TIMERS
/*
* Setup a local timer interrupt for a CPU.
*/
extern void local_timer_setup(unsigned int cpu);
/*
* Stop a local timer interrupt.
*/
extern void local_timer_stop(unsigned int cpu);
/*
* Platform provides this to acknowledge a local timer IRQ
*/
extern int local_timer_ack(void);
#else
static inline void local_timer_setup(unsigned int cpu)
{
}
static inline void local_timer_stop(unsigned int cpu)
{
}
#endif
/*
* show local interrupt info
*/
extern void show_local_irqs(struct seq_file *);
/*
* Called from assembly, this is the local timer IRQ handler
*/
asmlinkage void do_local_timer(struct pt_regs *);
#endif /* ifndef __ASM_ARM_SMP_H */ #endif /* ifndef __ASM_ARM_SMP_H */
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