Commit 50599817 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 7c4e441b 7516ebee
...@@ -45,7 +45,7 @@ MAILING LISTS REGARDING THE INTEL SDK. ...@@ -45,7 +45,7 @@ MAILING LISTS REGARDING THE INTEL SDK.
4. Usage Notes 4. Usage Notes
- The IXP2000 platforms ususally have rather complex PCI bus topologies - The IXP2000 platforms usually have rather complex PCI bus topologies
with large memory space requirements. In addition, b/c of the way the with large memory space requirements. In addition, b/c of the way the
Intel SDK is designed, devices are enumerated in a very specific Intel SDK is designed, devices are enumerated in a very specific
way. B/c of this this, we use "pci=firmware" option in the kernel way. B/c of this this, we use "pci=firmware" option in the kernel
......
...@@ -48,12 +48,15 @@ Machines ...@@ -48,12 +48,15 @@ Machines
Handheld (IPAQ), available in several varieties Handheld (IPAQ), available in several varieties
HP iPAQ rx3715 HP iPAQ rx3715
S3C2440 based IPAQ, with a number of variations depending on S3C2440 based IPAQ, with a number of variations depending on
features shipped. features shipped.
Acer N30
A S3C2410 based PDA from Acer. There is a Wiki page at
http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
NAND NAND
---- ----
...@@ -103,7 +106,7 @@ Port Contributors ...@@ -103,7 +106,7 @@ Port Contributors
Dimitry Andric Dimitry Andric
Shannon Holland Shannon Holland
Guillaume Gourat (NexVision) Guillaume Gourat (NexVision)
Christer Weinigel (wingel) (Acer N30)
Document Changes Document Changes
---------------- ----------------
...@@ -115,6 +118,7 @@ Document Changes ...@@ -115,6 +118,7 @@ Document Changes
21 Jan 2005 - BJD - Added rx3715, added Shannon to contributors 21 Jan 2005 - BJD - Added rx3715, added Shannon to contributors
10 Feb 2005 - BJD - Added Guillaume Gourat to contributors 10 Feb 2005 - BJD - Added Guillaume Gourat to contributors
02 Mar 2005 - BJD - Added SMDK2440 to list of machines 02 Mar 2005 - BJD - Added SMDK2440 to list of machines
06 Mar 2005 - BJD - Added Christer Weinigel
Document Author Document Author
--------------- ---------------
......
...@@ -101,7 +101,7 @@ int rtc_valid_tm(struct rtc_time *tm) ...@@ -101,7 +101,7 @@ int rtc_valid_tm(struct rtc_time *tm)
if (tm->tm_year < 70 || if (tm->tm_year < 70 ||
tm->tm_mon >= 12 || tm->tm_mon >= 12 ||
tm->tm_mday < 1 || tm->tm_mday < 1 ||
tm->tm_mday > month_days(tm->tm_mon, yrs) || tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) ||
tm->tm_hour >= 24 || tm->tm_hour >= 24 ||
tm->tm_min >= 60 || tm->tm_min >= 60 ||
tm->tm_sec >= 60) tm->tm_sec >= 60)
......
...@@ -15,47 +15,52 @@ ...@@ -15,47 +15,52 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/hardware/scoop.h> #include <asm/hardware/scoop.h>
static void __iomem *scoop_io_base; #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
#define SCOOP_REG(adr) (*(volatile unsigned short*)(scoop_io_base+(adr))) struct scoop_dev {
void *base;
spinlock_t scoop_lock;
u32 scoop_gpwr;
};
void reset_scoop(void) void reset_scoop(struct device *dev)
{ {
SCOOP_REG(SCOOP_MCR) = 0x0100; // 00 struct scoop_dev *sdev = dev_get_drvdata(dev);
SCOOP_REG(SCOOP_CDR) = 0x0000; // 04
SCOOP_REG(SCOOP_CPR) = 0x0000; // 0C SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00
SCOOP_REG(SCOOP_CCR) = 0x0000; // 10 SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04
SCOOP_REG(SCOOP_IMR) = 0x0000; // 18 SCOOP_REG(sdev->base,SCOOP_CPR) = 0x0000; // 0C
SCOOP_REG(SCOOP_IRM) = 0x00FF; // 14 SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10
SCOOP_REG(SCOOP_ISR) = 0x0000; // 1C SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18
SCOOP_REG(SCOOP_IRM) = 0x0000; SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14
SCOOP_REG(sdev->base,SCOOP_ISR) = 0x0000; // 1C
SCOOP_REG(sdev->base,SCOOP_IRM) = 0x0000;
} }
static DEFINE_SPINLOCK(scoop_lock); unsigned short set_scoop_gpio(struct device *dev, unsigned short bit)
static u32 scoop_gpwr;
unsigned short set_scoop_gpio(unsigned short bit)
{ {
unsigned short gpio_bit; unsigned short gpio_bit;
unsigned long flag; unsigned long flag;
struct scoop_dev *sdev = dev_get_drvdata(dev);
spin_lock_irqsave(&scoop_lock, flag); spin_lock_irqsave(&sdev->scoop_lock, flag);
gpio_bit = SCOOP_REG(SCOOP_GPWR) | bit; gpio_bit = SCOOP_REG(sdev->base, SCOOP_GPWR) | bit;
SCOOP_REG(SCOOP_GPWR) = gpio_bit; SCOOP_REG(sdev->base, SCOOP_GPWR) = gpio_bit;
spin_unlock_irqrestore(&scoop_lock, flag); spin_unlock_irqrestore(&sdev->scoop_lock, flag);
return gpio_bit; return gpio_bit;
} }
unsigned short reset_scoop_gpio(unsigned short bit) unsigned short reset_scoop_gpio(struct device *dev, unsigned short bit)
{ {
unsigned short gpio_bit; unsigned short gpio_bit;
unsigned long flag; unsigned long flag;
struct scoop_dev *sdev = dev_get_drvdata(dev);
spin_lock_irqsave(&scoop_lock, flag); spin_lock_irqsave(&sdev->scoop_lock, flag);
gpio_bit = SCOOP_REG(SCOOP_GPWR) & ~bit; gpio_bit = SCOOP_REG(sdev->base, SCOOP_GPWR) & ~bit;
SCOOP_REG(SCOOP_GPWR) = gpio_bit; SCOOP_REG(sdev->base,SCOOP_GPWR) = gpio_bit;
spin_unlock_irqrestore(&scoop_lock, flag); spin_unlock_irqrestore(&sdev->scoop_lock, flag);
return gpio_bit; return gpio_bit;
} }
...@@ -63,25 +68,30 @@ unsigned short reset_scoop_gpio(unsigned short bit) ...@@ -63,25 +68,30 @@ unsigned short reset_scoop_gpio(unsigned short bit)
EXPORT_SYMBOL(set_scoop_gpio); EXPORT_SYMBOL(set_scoop_gpio);
EXPORT_SYMBOL(reset_scoop_gpio); EXPORT_SYMBOL(reset_scoop_gpio);
unsigned short read_scoop_reg(unsigned short reg) unsigned short read_scoop_reg(struct device *dev, unsigned short reg)
{ {
return SCOOP_REG(reg); struct scoop_dev *sdev = dev_get_drvdata(dev);
return SCOOP_REG(sdev->base,reg);
} }
void write_scoop_reg(unsigned short reg, unsigned short data) void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data)
{ {
SCOOP_REG(reg)=data; struct scoop_dev *sdev = dev_get_drvdata(dev);
SCOOP_REG(sdev->base,reg)=data;
} }
EXPORT_SYMBOL(reset_scoop); EXPORT_SYMBOL(reset_scoop);
EXPORT_SYMBOL(read_scoop_reg); EXPORT_SYMBOL(read_scoop_reg);
EXPORT_SYMBOL(write_scoop_reg); EXPORT_SYMBOL(write_scoop_reg);
#ifdef CONFIG_PM
static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level) static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level)
{ {
if (level == SUSPEND_POWER_DOWN) { if (level == SUSPEND_POWER_DOWN) {
scoop_gpwr = SCOOP_REG(SCOOP_GPWR); struct scoop_dev *sdev = dev_get_drvdata(dev);
SCOOP_REG(SCOOP_GPWR) = 0;
sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR);
SCOOP_REG(sdev->base,SCOOP_GPWR) = 0;
} }
return 0; return 0;
} }
...@@ -89,13 +99,20 @@ static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level) ...@@ -89,13 +99,20 @@ static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level)
static int scoop_resume(struct device *dev, uint32_t level) static int scoop_resume(struct device *dev, uint32_t level)
{ {
if (level == RESUME_POWER_ON) { if (level == RESUME_POWER_ON) {
SCOOP_REG(SCOOP_GPWR) = scoop_gpwr; struct scoop_dev *sdev = dev_get_drvdata(dev);
SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
} }
return 0; return 0;
} }
#else
#define scoop_suspend NULL
#define scoop_resume NULL
#endif
int __init scoop_probe(struct device *dev) int __init scoop_probe(struct device *dev)
{ {
struct scoop_dev *devptr;
struct scoop_config *inf; struct scoop_config *inf;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -103,25 +120,50 @@ int __init scoop_probe(struct device *dev) ...@@ -103,25 +120,50 @@ int __init scoop_probe(struct device *dev)
if (!mem) if (!mem)
return -EINVAL; return -EINVAL;
devptr = kmalloc(sizeof(struct scoop_dev), GFP_KERNEL);
if (!devptr)
return -ENOMEM;
memset(devptr, 0, sizeof(struct scoop_dev));
spin_lock_init(&devptr->scoop_lock);
inf = dev->platform_data; inf = dev->platform_data;
scoop_io_base = ioremap(mem->start, 0x1000); devptr->base = ioremap(mem->start, mem->end - mem->start + 1);
if (!scoop_io_base)
if (!devptr->base) {
kfree(devptr);
return -ENOMEM; return -ENOMEM;
}
SCOOP_REG(SCOOP_MCR) = 0x0140; dev_set_drvdata(dev, devptr);
reset_scoop(); printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);
SCOOP_REG(SCOOP_GPCR) = inf->io_dir & 0xffff; SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
SCOOP_REG(SCOOP_GPWR) = inf->io_out & 0xffff; reset_scoop(dev);
SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
return 0; return 0;
} }
static int scoop_remove(struct device *dev)
{
struct scoop_dev *sdev = dev_get_drvdata(dev);
if (sdev) {
iounmap(sdev->base);
kfree(sdev);
dev_set_drvdata(dev, NULL);
}
return 0;
}
static struct device_driver scoop_driver = { static struct device_driver scoop_driver = {
.name = "sharp-scoop", .name = "sharp-scoop",
.bus = &platform_bus_type, .bus = &platform_bus_type,
.probe = scoop_probe, .probe = scoop_probe,
.remove = scoop_remove,
.suspend = scoop_suspend, .suspend = scoop_suspend,
.resume = scoop_resume, .resume = scoop_resume,
}; };
......
...@@ -86,6 +86,7 @@ CONFIG_ARCH_S3C2410=y ...@@ -86,6 +86,7 @@ CONFIG_ARCH_S3C2410=y
# #
CONFIG_ARCH_BAST=y CONFIG_ARCH_BAST=y
CONFIG_ARCH_H1940=y CONFIG_ARCH_H1940=y
CONFIG_MACH_N30=y
CONFIG_ARCH_SMDK2410=y CONFIG_ARCH_SMDK2410=y
CONFIG_ARCH_S3C2440=y CONFIG_ARCH_S3C2440=y
CONFIG_MACH_VR1000=y CONFIG_MACH_VR1000=y
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The * Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The
* original version carries the following notices: * original version carries the following notices:
* *
* Original Author: Andrzej Mialwoski <andrzej.mialwoski@intel.com> * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net> * Maintainer: Deepak Saxena <dsaxena@plexity.net>
* *
* Copyright (C) 2002-2003 Intel Corp. * Copyright (C) 2002-2003 Intel Corp.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Code common to Intel IXDP2401 and IXDP2801 platforms * Code common to Intel IXDP2401 and IXDP2801 platforms
* *
* Original Author: Andrzej Mialwoski <andrzej.mialwoski@intel.com> * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net> * Maintainer: Deepak Saxena <dsaxena@plexity.net>
* *
* Copyright (C) 2002-2003 Intel Corp. * Copyright (C) 2002-2003 Intel Corp.
......
...@@ -112,6 +112,38 @@ config OMAP_MUX_WARNINGS ...@@ -112,6 +112,38 @@ config OMAP_MUX_WARNINGS
to change the pin multiplexing setup. When there are no warnings to change the pin multiplexing setup. When there are no warnings
printed, it's safe to deselect OMAP_MUX for your product. printed, it's safe to deselect OMAP_MUX for your product.
choice
prompt "System timer"
default OMAP_MPU_TIMER
config OMAP_MPU_TIMER
bool "Use mpu timer"
help
Select this option if you want to use the OMAP mpu timer. This
timer provides more intra-tick resolution than the 32KHz timer,
but consumes more power.
config OMAP_32K_TIMER
bool "Use 32KHz timer"
depends on ARCH_OMAP16XX
help
Select this option if you want to enable the OMAP 32KHz timer.
This timer saves power compared to the OMAP_MPU_TIMER, and has
support for no tick during idle. The 32KHz timer provides less
intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
currently only available for OMAP-16xx.
endchoice
config OMAP_32K_TIMER_HZ
int "Kernel internal timer frequency for 32KHz timer"
range 32 1024
depends on OMAP_32K_TIMER
default "128"
help
Kernel internal timer frequency should be a divisor of 32768,
such as 64 or 128.
choice choice
prompt "Low-level debug console UART" prompt "Low-level debug console UART"
depends on ARCH_OMAP depends on ARCH_OMAP
......
...@@ -51,6 +51,8 @@ ...@@ -51,6 +51,8 @@
struct sys_timer omap_timer; struct sys_timer omap_timer;
#ifdef CONFIG_OMAP_MPU_TIMER
/* /*
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
* MPU timer * MPU timer
...@@ -67,6 +69,36 @@ struct sys_timer omap_timer; ...@@ -67,6 +69,36 @@ struct sys_timer omap_timer;
#define MPU_TIMER_AR (1 << 1) #define MPU_TIMER_AR (1 << 1)
#define MPU_TIMER_ST (1 << 0) #define MPU_TIMER_ST (1 << 0)
/* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c,
* converted to use kHz by Kevin Hilman */
/* convert from cycles(64bits) => nanoseconds (64bits)
* basic equation:
* ns = cycles / (freq / ns_per_sec)
* ns = cycles * (ns_per_sec / freq)
* ns = cycles * (10^9 / (cpu_khz * 10^3))
* ns = cycles * (10^6 / cpu_khz)
*
* Then we use scaling math (suggested by george at mvista.com) to get:
* ns = cycles * (10^6 * SC / cpu_khz / SC
* ns = cycles * cyc2ns_scale / SC
*
* And since SC is a constant power of two, we can convert the div
* into a shift.
* -johnstul at us.ibm.com "math is hard, lets go shopping!"
*/
static unsigned long cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
{
return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
}
/* /*
* MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs
* will break. On P2, the timer count rate is 6.5 MHz after programming PTV * will break. On P2, the timer count rate is 6.5 MHz after programming PTV
...@@ -112,8 +144,10 @@ static inline void omap_mpu_timer_start(int nr, unsigned long load_val) ...@@ -112,8 +144,10 @@ static inline void omap_mpu_timer_start(int nr, unsigned long load_val)
unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks) unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks)
{ {
/* Round up to nearest usec */ unsigned long long nsec;
return ((nr_ticks * 1000) / (MPU_TICKS_PER_SEC / 2 / 1000) + 1) >> 1;
nsec = cycles_2_ns((unsigned long long)nr_ticks);
return (unsigned long)nsec / 1000;
} }
/* /*
...@@ -158,14 +192,176 @@ static struct irqaction omap_mpu_timer_irq = { ...@@ -158,14 +192,176 @@ static struct irqaction omap_mpu_timer_irq = {
.handler = omap_mpu_timer_interrupt .handler = omap_mpu_timer_interrupt
}; };
static unsigned long omap_mpu_timer1_overflows;
static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
omap_mpu_timer1_overflows++;
return IRQ_HANDLED;
}
static struct irqaction omap_mpu_timer1_irq = {
.name = "mpu timer1 overflow",
.flags = SA_INTERRUPT,
.handler = omap_mpu_timer1_interrupt
};
static __init void omap_init_mpu_timer(void) static __init void omap_init_mpu_timer(void)
{ {
set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000);
omap_timer.offset = omap_mpu_timer_gettimeoffset; omap_timer.offset = omap_mpu_timer_gettimeoffset;
setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
setup_irq(INT_TIMER2, &omap_mpu_timer_irq); setup_irq(INT_TIMER2, &omap_mpu_timer_irq);
omap_mpu_timer_start(0, 0xffffffff); omap_mpu_timer_start(0, 0xffffffff);
omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD); omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD);
} }
/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
{
unsigned long ticks = 0 - omap_mpu_timer_read(0);
unsigned long long ticks64;
ticks64 = omap_mpu_timer1_overflows;
ticks64 <<= 32;
ticks64 |= ticks;
return cycles_2_ns(ticks64);
}
#endif /* CONFIG_OMAP_MPU_TIMER */
#ifdef CONFIG_OMAP_32K_TIMER
#ifdef CONFIG_ARCH_OMAP1510
#error OMAP 32KHz timer does not currently work on 1510!
#endif
/*
* ---------------------------------------------------------------------------
* 32KHz OS timer
*
* This currently works only on 16xx, as 1510 does not have the continuous
* 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
* of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
* on 1510 would be possible, but the timer would not be as accurate as
* with the 32KHz synchronized timer.
* ---------------------------------------------------------------------------
*/
#define OMAP_32K_TIMER_BASE 0xfffb9000
#define OMAP_32K_TIMER_CR 0x08
#define OMAP_32K_TIMER_TVR 0x00
#define OMAP_32K_TIMER_TCR 0x04
#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
/*
* TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
* so with HZ = 100, TVR = 327.68.
*/
#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
#define MAX_SKIP_JIFFIES 25
#define TIMER_32K_SYNCHRONIZED 0xfffbc410
#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
(((nr_jiffies) * (clock_rate)) / HZ)
static inline void omap_32k_timer_write(int val, int reg)
{
omap_writew(val, reg + OMAP_32K_TIMER_BASE);
}
static inline unsigned long omap_32k_timer_read(int reg)
{
return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
}
/*
* The 32KHz synchronized timer is an additional timer on 16xx.
* It is always running.
*/
static inline unsigned long omap_32k_sync_timer_read(void)
{
return omap_readl(TIMER_32K_SYNCHRONIZED);
}
static inline void omap_32k_timer_start(unsigned long load_val)
{
omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
}
static inline void omap_32k_timer_stop(void)
{
omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
}
/*
* Rounds down to nearest usec
*/
static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
{
return (ticks_32k * 5*5*5*5*5*5) >> 9;
}
static unsigned long omap_32k_last_tick = 0;
/*
* Returns elapsed usecs since last 32k timer interrupt
*/
static unsigned long omap_32k_timer_gettimeoffset(void)
{
unsigned long now = omap_32k_sync_timer_read();
return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
}
/*
* Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
* function is also called from other interrupts to remove latency
* issues with dynamic tick. In the dynamic tick case, we need to lock
* with irqsave.
*/
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
unsigned long flags;
unsigned long now;
write_seqlock_irqsave(&xtime_lock, flags);
now = omap_32k_sync_timer_read();
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
timer_tick(regs);
}
/* Restart timer so we don't drift off due to modulo or dynamic tick.
* By default we program the next timer to be continuous to avoid
* latencies during high system load. During dynamic tick operation the
* continuous timer can be overridden from pm_idle to be longer.
*/
omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
write_sequnlock_irqrestore(&xtime_lock, flags);
return IRQ_HANDLED;
}
static struct irqaction omap_32k_timer_irq = {
.name = "32KHz timer",
.flags = SA_INTERRUPT,
.handler = omap_32k_timer_interrupt
};
static __init void omap_init_32k_timer(void)
{
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
omap_timer.offset = omap_32k_timer_gettimeoffset;
omap_32k_last_tick = omap_32k_sync_timer_read();
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
}
#endif /* CONFIG_OMAP_32K_TIMER */
/* /*
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
* Timer initialization * Timer initialization
...@@ -173,7 +369,13 @@ static __init void omap_init_mpu_timer(void) ...@@ -173,7 +369,13 @@ static __init void omap_init_mpu_timer(void)
*/ */
void __init omap_timer_init(void) void __init omap_timer_init(void)
{ {
#if defined(CONFIG_OMAP_MPU_TIMER)
omap_init_mpu_timer(); omap_init_mpu_timer();
#elif defined(CONFIG_OMAP_32K_TIMER)
omap_init_32k_timer();
#else
#error No system timer selected in Kconfig!
#endif
} }
struct sys_timer omap_timer = { struct sys_timer omap_timer = {
......
...@@ -59,7 +59,7 @@ static struct scoop_config corgi_scoop_setup = { ...@@ -59,7 +59,7 @@ static struct scoop_config corgi_scoop_setup = {
.io_out = CORGI_SCOOP_IO_OUT, .io_out = CORGI_SCOOP_IO_OUT,
}; };
static struct platform_device corgiscoop_device = { struct platform_device corgiscoop_device = {
.name = "sharp-scoop", .name = "sharp-scoop",
.id = -1, .id = -1,
.dev = { .dev = {
......
...@@ -51,7 +51,7 @@ static struct scoop_config poodle_scoop_setup = { ...@@ -51,7 +51,7 @@ static struct scoop_config poodle_scoop_setup = {
.io_out = POODLE_SCOOP_IO_OUT, .io_out = POODLE_SCOOP_IO_OUT,
}; };
static struct platform_device poodle_scoop_device = { struct platform_device poodle_scoop_device = {
.name = "sharp-scoop", .name = "sharp-scoop",
.id = -1, .id = -1,
.dev = { .dev = {
......
...@@ -19,6 +19,14 @@ config ARCH_H1940 ...@@ -19,6 +19,14 @@ config ARCH_H1940
<http://www.handhelds.org/projects/h1940.html>. <http://www.handhelds.org/projects/h1940.html>.
config MACH_N30
bool "Acer N30"
select CPU_S3C2410
help
Say Y here if you are using the Acer N30
<http://zoo.weinigel.se/n30>.
config ARCH_SMDK2410 config ARCH_SMDK2410
bool "SMDK2410/A9M2410" bool "SMDK2410/A9M2410"
select CPU_S3C2410 select CPU_S3C2410
......
...@@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o ...@@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
obj-$(CONFIG_ARCH_H1940) += mach-h1940.o obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
obj-$(CONFIG_MACH_N30) += mach-n30.o
obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
......
/* linux/arch/arm/mach-s3c2410/mach-n30.c
*
* Copyright (c) 2003-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Copyright (c) 2005 Christer Weinigel <christer@weinigel.se>
*
* There is a wiki with more information about the n30 port at
* http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
*
* 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/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/kthread.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/hardware/iomd.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/iic.h>
#include <linux/serial_core.h>
#include "s3c2410.h"
#include "clock.h"
#include "devs.h"
#include "cpu.h"
static struct map_desc n30_iodesc[] __initdata = {
/* nothing here yet */
};
static struct s3c2410_uartcfg n30_uartcfgs[] = {
/* Normal serial port */
[0] = {
.hwport = 0,
.flags = 0,
.ucon = 0x2c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
/* IR port */
[1] = {
.hwport = 1,
.flags = 0,
.uart_flags = UPF_CONS_FLOW,
.ucon = 0x2c5,
.ulcon = 0x43,
.ufcon = 0x51,
},
/* The BlueTooth controller is connected to port 2 */
[2] = {
.hwport = 2,
.flags = 0,
.ucon = 0x2c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
};
static struct platform_device *n30_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_usbgadget,
};
static struct s3c2410_platform_i2c n30_i2ccfg = {
.flags = 0,
.slave_addr = 0x10,
.bus_freq = 10*1000,
.max_freq = 10*1000,
};
static struct s3c24xx_board n30_board __initdata = {
.devices = n30_devices,
.devices_count = ARRAY_SIZE(n30_devices)
};
void __init n30_map_io(void)
{
s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
s3c24xx_set_board(&n30_board);
}
void __init n30_init_irq(void)
{
s3c24xx_init_irq();
}
static int n30_usbstart_thread(void *unused)
{
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
writel(readl(S3C2410_MISCCR) & ~0x00003008, S3C2410_MISCCR);
/* Turn off the D+ pull up for 3 seconds so that the USB host
* at the other end will do a rescan of the USB bus. */
s3c2410_gpio_setpin(S3C2410_GPB3, 0);
msleep_interruptible(3*HZ);
s3c2410_gpio_setpin(S3C2410_GPB3, 1);
return 0;
}
void __init n30_init(void)
{
s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
kthread_run(n30_usbstart_thread, NULL, "n30_usbstart");
}
MACHINE_START(N30, "Acer-N30")
MAINTAINER("Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
.timer = &s3c24xx_timer,
.init_machine = n30_init,
.init_irq = n30_init_irq,
.map_io = n30_map_io,
MACHINE_END
/*
Local variables:
compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.."
c-basic-offset: 8
End:
*/
...@@ -55,7 +55,7 @@ static struct scoop_config collie_scoop_setup = { ...@@ -55,7 +55,7 @@ static struct scoop_config collie_scoop_setup = {
.io_out = COLLIE_SCOOP_IO_OUT, .io_out = COLLIE_SCOOP_IO_OUT,
}; };
static struct platform_device colliescoop_device = { struct platform_device colliescoop_device = {
.name = "sharp-scoop", .name = "sharp-scoop",
.id = -1, .id = -1,
.dev = { .dev = {
......
...@@ -38,7 +38,7 @@ static struct pcmcia_irqs irqs[] = { ...@@ -38,7 +38,7 @@ static struct pcmcia_irqs irqs[] = {
static void sharpsl_pcmcia_init_reset(void) static void sharpsl_pcmcia_init_reset(void)
{ {
reset_scoop(); reset_scoop(&corgiscoop_device.dev);
keep_vs = NO_KEEP_VS; keep_vs = NO_KEEP_VS;
keep_rd = 0; keep_rd = 0;
} }
...@@ -79,8 +79,8 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -79,8 +79,8 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
} }
/* Enable interrupt */ /* Enable interrupt */
write_scoop_reg(SCOOP_IMR, 0x00C0); write_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR, 0x00C0);
write_scoop_reg(SCOOP_MCR, 0x0101); write_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR, 0x0101);
keep_vs = NO_KEEP_VS; keep_vs = NO_KEEP_VS;
skt->irq = CORGI_IRQ_GPIO_CF_IRQ; skt->irq = CORGI_IRQ_GPIO_CF_IRQ;
...@@ -102,30 +102,30 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, ...@@ -102,30 +102,30 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
{ {
unsigned short cpr, csr; unsigned short cpr, csr;
cpr = read_scoop_reg(SCOOP_CPR); cpr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR);
write_scoop_reg(SCOOP_IRM, 0x00FF); write_scoop_reg(&corgiscoop_device.dev, SCOOP_IRM, 0x00FF);
write_scoop_reg(SCOOP_ISR, 0x0000); write_scoop_reg(&corgiscoop_device.dev, SCOOP_ISR, 0x0000);
write_scoop_reg(SCOOP_IRM, 0x0000); write_scoop_reg(&corgiscoop_device.dev, SCOOP_IRM, 0x0000);
csr = read_scoop_reg(SCOOP_CSR); csr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CSR);
if (csr & 0x0004) { if (csr & 0x0004) {
/* card eject */ /* card eject */
write_scoop_reg(SCOOP_CDR, 0x0000); write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000);
keep_vs = NO_KEEP_VS; keep_vs = NO_KEEP_VS;
} }
else if (!(keep_vs & NO_KEEP_VS)) { else if (!(keep_vs & NO_KEEP_VS)) {
/* keep vs1,vs2 */ /* keep vs1,vs2 */
write_scoop_reg(SCOOP_CDR, 0x0000); write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000);
csr |= keep_vs; csr |= keep_vs;
} }
else if (cpr & 0x0003) { else if (cpr & 0x0003) {
/* power on */ /* power on */
write_scoop_reg(SCOOP_CDR, 0x0000); write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000);
keep_vs = (csr & 0x00C0); keep_vs = (csr & 0x00C0);
} }
else { else {
/* card detect */ /* card detect */
write_scoop_reg(SCOOP_CDR, 0x0002); write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0002);
} }
state->detect = (csr & 0x0004) ? 0 : 1; state->detect = (csr & 0x0004) ? 0 : 1;
...@@ -166,10 +166,10 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -166,10 +166,10 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
local_irq_save(flags); local_irq_save(flags);
nmcr = (mcr = read_scoop_reg(SCOOP_MCR)) & ~0x0010; nmcr = (mcr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR)) & ~0x0010;
ncpr = (cpr = read_scoop_reg(SCOOP_CPR)) & ~0x0083; ncpr = (cpr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR)) & ~0x0083;
nccr = (ccr = read_scoop_reg(SCOOP_CCR)) & ~0x0080; nccr = (ccr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CCR)) & ~0x0080;
nimr = (imr = read_scoop_reg(SCOOP_IMR)) & ~0x003E; nimr = (imr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR)) & ~0x003E;
ncpr |= (state->Vcc == 33) ? 0x0001 : ncpr |= (state->Vcc == 33) ? 0x0001 :
(state->Vcc == 50) ? 0x0002 : 0; (state->Vcc == 50) ? 0x0002 : 0;
...@@ -193,13 +193,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ...@@ -193,13 +193,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
} }
if (mcr != nmcr) if (mcr != nmcr)
write_scoop_reg(SCOOP_MCR, nmcr); write_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR, nmcr);
if (cpr != ncpr) if (cpr != ncpr)
write_scoop_reg(SCOOP_CPR, ncpr); write_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR, ncpr);
if (ccr != nccr) if (ccr != nccr)
write_scoop_reg(SCOOP_CCR, nccr); write_scoop_reg(&corgiscoop_device.dev, SCOOP_CCR, nccr);
if (imr != nimr) if (imr != nimr)
write_scoop_reg(SCOOP_IMR, nimr); write_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR, nimr);
local_irq_restore(flags); local_irq_restore(flags);
......
...@@ -729,6 +729,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) ...@@ -729,6 +729,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
status2 = serial_in(up, UART_IIR) >> 5; status2 = serial_in(up, UART_IIR) >> 5;
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
serial_outp(up, UART_LCR, 0);
DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
......
...@@ -1759,7 +1759,7 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev) ...@@ -1759,7 +1759,7 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
} }
} }
static int pciserial_suspend_one(struct pci_dev *dev, u32 state) static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
{ {
struct serial_private *priv = pci_get_drvdata(dev); struct serial_private *priv = pci_get_drvdata(dev);
...@@ -1769,6 +1769,8 @@ static int pciserial_suspend_one(struct pci_dev *dev, u32 state) ...@@ -1769,6 +1769,8 @@ static int pciserial_suspend_one(struct pci_dev *dev, u32 state)
for (i = 0; i < priv->nr; i++) for (i = 0; i < priv->nr; i++)
serial8250_suspend_port(priv->line[i]); serial8250_suspend_port(priv->line[i]);
} }
pci_save_state(dev);
pci_set_power_state(dev, pci_choose_state(dev, state));
return 0; return 0;
} }
...@@ -1776,9 +1778,17 @@ static int pciserial_resume_one(struct pci_dev *dev) ...@@ -1776,9 +1778,17 @@ static int pciserial_resume_one(struct pci_dev *dev)
{ {
struct serial_private *priv = pci_get_drvdata(dev); struct serial_private *priv = pci_get_drvdata(dev);
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
if (priv) { if (priv) {
int i; int i;
/*
* The device may have been disabled. Re-enable it.
*/
pci_enable_device(dev);
/* /*
* Ensure that the board is correctly configured. * Ensure that the board is correctly configured.
*/ */
......
...@@ -52,9 +52,9 @@ static void corgibl_send_intensity(int intensity) ...@@ -52,9 +52,9 @@ static void corgibl_send_intensity(int intensity)
corgi_ssp_blduty_set(intensity & 0x1f); corgi_ssp_blduty_set(intensity & 0x1f);
/* Bit 5 is via SCOOP */ /* Bit 5 is via SCOOP */
if (intensity & 0x0020) if (intensity & 0x0020)
set_scoop_gpio(CORGI_SCP_BACKLIGHT_CONT); set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
else else
reset_scoop_gpio(CORGI_SCP_BACKLIGHT_CONT); reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
spin_unlock_irqrestore(&bl_lock, flags); spin_unlock_irqrestore(&bl_lock, flags);
} }
......
/* /*
* linux/include/asm-arm/arch-ixdp2000/io.h * linux/include/asm-arm/arch-ixp2000/io.h
* *
* Original Author: Naeem M Afzal <naeem.m.afzal@intel.com> * Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net> * Maintainer: Deepak Saxena <dsaxena@plexity.net>
......
/* /*
* include/asm/arch/ixdp2x01.h * include/asm-arm/arch-ixp2000/ixdp2x01.h
* *
* Platform definitions for IXDP2X01 && IXDP2801 systems * Platform definitions for IXDP2X01 && IXDP2801 systems
* *
......
/* /*
* include/asm-arh/arch-ixp2000/platform.h * include/asm-arm/arch-ixp2000/platform.h
* *
* Various bits of code used by platform-level code. * Various bits of code used by platform-level code.
* *
...@@ -50,7 +50,7 @@ static inline void ixp2000_reg_write(volatile unsigned long *reg, unsigned long ...@@ -50,7 +50,7 @@ static inline void ixp2000_reg_write(volatile unsigned long *reg, unsigned long
* Boards may multiplex different devices on the 2nd channel of * Boards may multiplex different devices on the 2nd channel of
* the slowport interface that each need different configuration * the slowport interface that each need different configuration
* settings. For example, the IXDP2400 uses channel 2 on the interface * settings. For example, the IXDP2400 uses channel 2 on the interface
* to access the CPLD, the switch fabric card, and te media card. Each * to access the CPLD, the switch fabric card, and the media card. Each
* one needs a different mode so drivers must save/restore the mode * one needs a different mode so drivers must save/restore the mode
* before and after each operation. * before and after each operation.
* *
......
...@@ -133,6 +133,10 @@ struct sharpsl_flash_param_info { ...@@ -133,6 +133,10 @@ struct sharpsl_flash_param_info {
unsigned int phadadj; unsigned int phadadj;
}; };
/*
* Shared data structures
*/
extern struct platform_device corgiscoop_device;
/* /*
* External Functions * External Functions
......
...@@ -40,8 +40,8 @@ struct scoop_config { ...@@ -40,8 +40,8 @@ struct scoop_config {
unsigned short io_dir; unsigned short io_dir;
}; };
void reset_scoop(void); void reset_scoop(struct device *dev);
unsigned short set_scoop_gpio(unsigned short bit); unsigned short set_scoop_gpio(struct device *dev, unsigned short bit);
unsigned short reset_scoop_gpio(unsigned short bit); unsigned short reset_scoop_gpio(struct device *dev, unsigned short bit);
unsigned short read_scoop_reg(unsigned short reg); unsigned short read_scoop_reg(struct device *dev, unsigned short reg);
void write_scoop_reg(unsigned short reg, unsigned short data); void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data);
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