summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-06 01:03:25 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-06 01:03:25 -0800
commitbfa166fa144c919a7cc5c2836343d4091dfd54ff (patch)
tree5dc730222fa1c9912e04cd405d57291fca4c7a27
parentfe2839b325194b12448f5a4c2d6ae9d41b175ebb (diff)
parent4595e94727d41a70e13447de5b77c2f07f789db2 (diff)
Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk
into ppc970.osdl.org:/home/torvalds/v2.6/linux
-rw-r--r--arch/arm/common/rtctime.c38
-rw-r--r--arch/arm/mach-ebsa110/io.c87
-rw-r--r--arch/arm/mach-sa1100/assabet.c8
-rw-r--r--arch/arm/mm/mm-armv.c8
-rw-r--r--arch/arm/tools/mach-types47
-rw-r--r--drivers/serial/s3c2410.c141
-rw-r--r--include/asm-arm/arch-s3c2410/regs-serial.h5
-rw-r--r--include/asm-arm/io.h12
-rw-r--r--include/asm-arm/pgtable.h6
-rw-r--r--include/asm-arm/rtc.h1
10 files changed, 235 insertions, 118 deletions
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index 812dac1fa886..edfc00af56b1 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -94,15 +94,11 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
EXPORT_SYMBOL(rtc_time_to_tm);
/*
- * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
+ * Does the rtc_time represent a valid date/time?
*/
-int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
+int rtc_valid_tm(struct rtc_time *tm)
{
- unsigned int yrs = tm->tm_year + 1900;
-
- *time = 0;
-
- if (yrs < 1970 ||
+ if (tm->tm_year < 70 ||
tm->tm_mon >= 12 ||
tm->tm_mday < 1 ||
tm->tm_mday > month_days(tm->tm_mon, yrs) ||
@@ -111,7 +107,16 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
tm->tm_sec >= 60)
return -EINVAL;
- *time = mktime(yrs, tm->tm_mon + 1, tm->tm_mday,
+ return 0;
+}
+EXPORT_SYMBOL(rtc_valid_tm);
+
+/*
+ * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
+ */
+int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
+{
+ *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0;
@@ -144,7 +149,13 @@ static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
{
- return ops->set_time(tm);
+ int ret;
+
+ ret = rtc_valid_tm(tm);
+ if (ret == 0)
+ ret = ops->set_time(tm);
+
+ return ret;
}
static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
@@ -412,7 +423,6 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
struct rtc_wkalrm alrm;
struct rtc_time tm;
char *p = page;
- int len;
rtc_read_time(ops, &tm);
@@ -461,13 +471,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
if (ops->proc)
p += ops->proc(p);
- len = (p - page) - off;
- if (len < 0)
- len = 0;
- *eof = len <= count;
- *start = page + off;
-
- return len;
+ return p - page;
}
int register_rtc(struct rtc_ops *ops)
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
index f5181ed485ed..ef7eb5dc91bd 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -153,9 +153,9 @@ u8 __inb8(unsigned int port)
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- ret = __raw_readb(ISAIO_BASE + (port << 2));
+ ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2));
else {
- void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
+ void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
/*
* Shame nothing else does
@@ -174,45 +174,33 @@ u8 __inb8(unsigned int port)
*/
u8 __inb16(unsigned int port)
{
- u32 ret;
+ unsigned int offset;
/*
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- ret = __raw_readb(ISAIO_BASE + (port << 2));
- else {
- void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
+ offset = port << 2;
+ else
+ offset = (port & ~1) << 1 | (port & 1);
- /*
- * Shame nothing else does
- */
- ret = __raw_readb(a + (port & 1));
- }
- return ret;
+ return __raw_readb((void __iomem *)ISAIO_BASE + offset);
}
u16 __inw(unsigned int port)
{
- u32 ret;
+ unsigned int offset;
/*
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- ret = __raw_readw(ISAIO_BASE + (port << 2));
+ offset = port << 2;
else {
- void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
-
- /*
- * Shame nothing else does
- */
- if (port & 1)
- BUG();
-
- ret = __raw_readw(a);
+ offset = port << 1;
+ BUG_ON(port & 1);
}
- return ret;
+ return __raw_readw((void __iomem *)ISAIO_BASE + offset);
}
/*
@@ -225,7 +213,7 @@ u32 __inl(unsigned int port)
if (SUPERIO_PORT(port) || port & 3)
BUG();
- a = ISAIO_BASE + (port << 1);
+ a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
return __raw_readw(a) | __raw_readw(a + 4) << 16;
}
@@ -241,9 +229,9 @@ void __outb8(u8 val, unsigned int port)
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- __raw_writeb(val, ISAIO_BASE + (port << 2));
+ __raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2));
else {
- void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
+ void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
/*
* Shame nothing else does
@@ -257,37 +245,33 @@ void __outb8(u8 val, unsigned int port)
void __outb16(u8 val, unsigned int port)
{
+ unsigned int offset;
+
/*
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- __raw_writeb(val, ISAIO_BASE + (port << 2));
- else {
- void __iomem *a = ISAIO_BASE + ((port & ~1) << 1);
+ offset = port << 2;
+ else
+ offset = (port & ~1) << 1 | (port & 1);
- /*
- * Shame nothing else does
- */
- __raw_writeb(val, a + (port & 1));
- }
+ __raw_writeb(val, (void __iomem *)ISAIO_BASE + offset);
}
void __outw(u16 val, unsigned int port)
{
- u32 off;
+ unsigned int offset;
/*
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- off = port << 2;
+ offset = port << 2;
else {
- off = port << 1;
- if (port & 1)
- BUG();
-
+ offset = port << 1;
+ BUG_ON(port & 1);
}
- __raw_writew(val, ISAIO_BASE + off);
+ __raw_writew(val, (void __iomem *)ISAIO_BASE + offset);
}
void __outl(u32 val, unsigned int port)
@@ -300,13 +284,6 @@ EXPORT_SYMBOL(__outb16);
EXPORT_SYMBOL(__outw);
EXPORT_SYMBOL(__outl);
-extern void __arch_writesb(unsigned long virt, const void *from, int len);
-extern void __arch_writesw(unsigned long virt, const void *from, int len);
-extern void __arch_writesl(unsigned long virt, const void *from, int len);
-extern void __arch_readsb(unsigned long virt, void *from, int len);
-extern void __arch_readsw(unsigned long virt, void *from, int len);
-extern void __arch_readsl(unsigned long virt, void *from, int len);
-
void outsb(unsigned int port, const void *from, int len)
{
u32 off;
@@ -319,7 +296,7 @@ void outsb(unsigned int port, const void *from, int len)
BUG();
}
- __raw_writesb(ISAIO_BASE + off, from, len);
+ __raw_writesb((void __iomem *)ISAIO_BASE + off, from, len);
}
void insb(unsigned int port, void *from, int len)
@@ -334,7 +311,7 @@ void insb(unsigned int port, void *from, int len)
BUG();
}
- __raw_readsb(ISAIO_BASE + off, from, len);
+ __raw_readsb((void __iomem *)ISAIO_BASE + off, from, len);
}
EXPORT_SYMBOL(outsb);
@@ -352,7 +329,7 @@ void outsw(unsigned int port, const void *from, int len)
BUG();
}
- __raw_writesw(ISAIO_BASE + off, from, len);
+ __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len);
}
void insw(unsigned int port, void *from, int len)
@@ -367,7 +344,7 @@ void insw(unsigned int port, void *from, int len)
BUG();
}
- __raw_readsw(ISAIO_BASE + off, from, len);
+ __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len);
}
EXPORT_SYMBOL(outsw);
@@ -384,7 +361,7 @@ void outsl(unsigned int port, const void *from, int len)
if (SUPERIO_PORT(port) || port & 3)
BUG();
- __raw_writesw(ISAIO_BASE + off, from, len << 1);
+ __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1);
}
void insl(unsigned int port, void *from, int len)
@@ -394,7 +371,7 @@ void insl(unsigned int port, void *from, int len)
if (SUPERIO_PORT(port) || port & 3)
BUG();
- __raw_readsw(ISAIO_BASE + off, from, len << 1);
+ __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1);
}
EXPORT_SYMBOL(outsl);
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index a3003b867555..bedf88fafe08 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -259,9 +259,11 @@ static void __init map_sa1100_gpio_regs( void )
unsigned long phys = __PREG(GPLR) & PMD_MASK;
unsigned long virt = io_p2v(phys);
int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO);
- pmd_t pmd;
- pmd_val(pmd) = phys | prot;
- set_pmd(pmd_offset(pgd_offset_k(virt), virt), pmd);
+ pmd_t *pmd;
+
+ pmd = pmd_offset(pgd_offset_k(virt), virt);
+ *pmd = __pmd(phys | prot);
+ flush_pmd_entry(pmd);
}
/*
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 0bcdbd73e1f1..48a11d03e3bd 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -252,7 +252,8 @@ alloc_init_section(unsigned long virt, unsigned long phys, int prot)
if (virt & (1 << 20))
pmdp++;
- set_pmd(pmdp, __pmd(phys | prot));
+ *pmdp = __pmd(phys | prot);
+ flush_pmd_entry(pmdp);
}
/*
@@ -568,8 +569,9 @@ void setup_mm_for_reboot(char mode)
if (cpu_arch <= CPU_ARCH_ARMv5)
pmdval |= PMD_BIT4;
pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
- set_pmd(pmd, __pmd(pmdval));
- set_pmd(pmd + 1, __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))));
+ pmd[0] = __pmd(pmdval);
+ pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
+ flush_pmd_entry(pmd);
}
}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 0678f4fcba39..a1c044cbfff9 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
-# Last update: Thu Jan 6 00:10:23 2005
+# Last update: Wed Mar 2 11:32:53 2005
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -226,7 +226,7 @@ dnp1110 SA1100_DNP1110 DNP1110 214
pnp1110 SA1100_PNP1110 PNP1110 215
csb226 ARCH_CSB226 CSB226 216
arnold SA1100_ARNOLD ARNOLD 217
-voiceblue SA1100_PSIBOARD PSIBOARD 218
+voiceblue MACH_VOICEBLUE VOICEBLUE 218
jz8028 ARCH_JZ8028 JZ8028 219
h5400 ARCH_H5400 H5400 220
forte SA1100_FORTE FORTE 221
@@ -381,7 +381,7 @@ s5c7375 ARCH_S5C7375 S5C7375 369
spearhead ARCH_SPEARHEAD SPEARHEAD 370
pantera ARCH_PANTERA PANTERA 371
prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372
-gumstik ARCH_GUMSTIK GUMSTIK 373
+gumstix ARCH_GUMSTIK GUMSTIK 373
rcube ARCH_RCUBE RCUBE 374
rea_olv ARCH_REA_OLV REA_OLV 375
pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376
@@ -667,3 +667,44 @@ n30 MACH_N30 N30 656
manga_ks8695 MACH_MANGA_KS8695 MANGA_KS8695 657
ajax MACH_AJAX AJAX 658
nec_mp900 MACH_NEC_MP900 NEC_MP900 659
+vvtk1000 MACH_VVTK1000 VVTK1000 661
+kafa MACH_KAFA KAFA 662
+vvtk3000 MACH_VVTK3000 VVTK3000 663
+pimx1 MACH_PIMX1 PIMX1 664
+ollie MACH_OLLIE OLLIE 665
+skymax MACH_SKYMAX SKYMAX 666
+jazz MACH_JAZZ JAZZ 667
+tel_t3 MACH_TEL_T3 TEL_T3 668
+aisino_fcr255 MACH_AISINO_FCR255 AISINO_FCR255 669
+btweb MACH_BTWEB BTWEB 670
+dbg_lh79520 MACH_DBG_LH79520 DBG_LH79520 671
+cm41xx MACH_CM41XX CM41XX 672
+ts72xx MACH_TS72XX TS72XX 673
+nggpxa MACH_NGGPXA NGGPXA 674
+csb535 MACH_CSB535 CSB535 675
+csb536 MACH_CSB536 CSB536 676
+pxa_trakpod MACH_PXA_TRAKPOD PXA_TRAKPOD 677
+praxis MACH_PRAXIS PRAXIS 678
+lh75411 MACH_LH75411 LH75411 679
+otom MACH_OTOM OTOM 680
+nexcoder_2440 MACH_NEXCODER_2440 NEXCODER_2440 681
+loox410 MACH_LOOX410 LOOX410 682
+westlake MACH_WESTLAKE WESTLAKE 683
+nsb MACH_NSB NSB 684
+esl_sarva_stn MACH_ESL_SARVA_STN ESL_SARVA_STN 685
+esl_sarva_tft MACH_ESL_SARVA_TFT ESL_SARVA_TFT 686
+esl_sarva_iad MACH_ESL_SARVA_IAD ESL_SARVA_IAD 687
+esl_sarva_acc MACH_ESL_SARVA_ACC ESL_SARVA_ACC 688
+typhoon MACH_TYPHOON TYPHOON 689
+cnav MACH_CNAV CNAV 690
+a730 MACH_A730 A730 691
+netstar MACH_NETSTAR NETSTAR 692
+supercon MACH_PHASEFALE_SUPERCON PHASEFALE_SUPERCON 693
+shiva1100 MACH_SHIVA1100 SHIVA1100 694
+etexsc MACH_ETEXSC ETEXSC 695
+ixdpg465 MACH_IXDPG465 IXDPG465 696
+a9m2410 MACH_A9M2410 A9M2410 697
+a9m2440 MACH_A9M2440 A9M2440 698
+a9m9750 MACH_A9M9750 A9M9750 699
+a9m9360 MACH_A9M9360 A9M9360 700
+unc90 MACH_UNC90 UNC90 701
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index e38ee543ec81..a991a30d6488 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -5,7 +5,8 @@
*
* Based on drivers/char/serial.c and drivers/char/21285.c
*
- * Ben Dooks, (c) 2003 Simtec Electronics
+ * Ben Dooks, (c) 2003-2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/SWLINUX/
*
* Changelog:
*
@@ -24,6 +25,15 @@
* - spin-lock initialisation (Dimitry Andric)
* - added clock control
* - updated init code to use platform_device info
+ *
+ * 06-Mar-2005 BJD Add s3c2440 fclk clock source
+*/
+
+/* Note on 2440 fclk clock source handling
+ *
+ * Whilst it is possible to use the fclk as clock source, the method
+ * of properly switching too/from this is currently un-implemented, so
+ * whichever way is configured at startup is the one that will be used.
*/
/* Hote on 2410 error handling
@@ -87,6 +97,9 @@ struct s3c24xx_uart_info {
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
+
+ /* uart controls */
+ int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
};
struct s3c24xx_uart_port {
@@ -606,11 +619,6 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
* baud clocks (and the resultant actual baud rates) and then tries to
* pick the closest one and select that.
*
- * NOTES:
- * 1) there is no current code to properly select/deselect FCLK on
- * the s3c2440, so only specify FCLK or non-FCLK in the clock
- * sources for the UART
- *
*/
@@ -658,6 +666,7 @@ static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
return 0;
rate = clk_get_rate(calc->src);
+ rate /= clksrc->divisor;
calc->clksrc = clksrc;
calc->quot = (rate + (8 * baud)) / (16 * baud);
@@ -685,6 +694,27 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
if (cfg->clocks_size == 0)
clkp = &tmp_clksrc;
+ /* check to see if we're sourcing fclk, and if so we're
+ * going to have to update the clock source
+ */
+
+ if (strcmp(clkp->name, "fclk") == 0) {
+ struct s3c24xx_uart_clksrc src;
+
+ s3c24xx_serial_getsource(port, &src);
+
+ /* check that the port already using fclk, and if
+ * not, then re-select fclk
+ */
+
+ if (strcmp(src.name, clkp->name) == 0) {
+ s3c24xx_serial_setsource(port, clkp);
+ s3c24xx_serial_getsource(port, &src);
+ }
+
+ clkp->divisor = src.divisor;
+ }
+
s3c24xx_serial_calcbaud(res, port, clkp, baud);
best = res;
resptr = best + 1;
@@ -993,24 +1023,18 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
#endif
};
+/* s3c24xx_serial_resetport
+ *
+ * wrapper to call the specific reset for this port (reset the fifos
+ * and the settings)
+*/
-static int s3c24xx_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
+static inline int s3c24xx_serial_resetport(struct uart_port * port,
+ struct s3c2410_uartcfg *cfg)
{
- /* ensure registers are setup */
-
- dbg("s3c24xx_serial_resetport: port=%p (%08lx), cfg=%p\n",
- port, port->mapbase, cfg);
-
- wr_regl(port, S3C2410_UCON, cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- return 0;
+ return (info->reset_port)(port, cfg);
}
/* s3c24xx_serial_init_port
@@ -1201,6 +1225,23 @@ static int s3c2410_serial_getsource(struct uart_port *port,
return 0;
}
+static int s3c2410_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
+{
+ dbg("s3c2410_serial_resetport: port=%p (%08lx), cfg=%p\n",
+ port, port->mapbase, cfg);
+
+ wr_regl(port, S3C2410_UCON, cfg->ucon);
+ wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+
+ /* reset both fifos */
+
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+ return 0;
+}
+
static struct s3c24xx_uart_info s3c2410_uart_inf = {
.name = "Samsung S3C2410 UART",
.type = PORT_S3C2410,
@@ -1213,6 +1254,7 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = {
.tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
.get_clksrc = s3c2410_serial_getsource,
.set_clksrc = s3c2410_serial_setsource,
+ .reset_port = s3c2410_serial_resetport,
};
/* device management */
@@ -1288,6 +1330,7 @@ static int s3c2440_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
+ unsigned long ucon0, ucon1, ucon2;
switch (ucon & S3C2440_UCON_CLKMASK) {
case S3C2440_UCON_UCLK:
@@ -1302,7 +1345,33 @@ static int s3c2440_serial_getsource(struct uart_port *port,
break;
case S3C2440_UCON_FCLK:
- clk->divisor = 7; /* todo - work out divisor */
+ /* the fun of calculating the uart divisors on
+ * the s3c2440 */
+
+ ucon0 = __raw_readl(S3C2410_VA_UART0 + S3C2410_UCON);
+ ucon1 = __raw_readl(S3C2410_VA_UART1 + S3C2410_UCON);
+ ucon2 = __raw_readl(S3C2410_VA_UART2 + S3C2410_UCON);
+
+ printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
+
+ ucon0 &= S3C2440_UCON0_DIVMASK;
+ ucon1 &= S3C2440_UCON1_DIVMASK;
+ ucon2 &= S3C2440_UCON2_DIVMASK;
+
+ if (ucon0 != 0) {
+ clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
+ clk->divisor += 6;
+ } else if (ucon1 != 0) {
+ clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
+ clk->divisor += 21;
+ } else if (ucon2 != 0) {
+ clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
+ clk->divisor += 36;
+ } else {
+ /* manual calims 44, seems to be 9 */
+ clk->divisor = 9;
+ }
+
clk->name = "fclk";
break;
}
@@ -1310,6 +1379,28 @@ static int s3c2440_serial_getsource(struct uart_port *port,
return 0;
}
+static int s3c2440_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n",
+ port, port->mapbase, cfg);
+
+ /* ensure we don't change the clock settings... */
+
+ ucon &= (S3C2440_UCON0_DIVMASK | (3<<10));
+
+ wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
+ wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+
+ /* reset both fifos */
+
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+ return 0;
+}
static struct s3c24xx_uart_info s3c2440_uart_inf = {
.name = "Samsung S3C2440 UART",
@@ -1322,7 +1413,8 @@ static struct s3c24xx_uart_info s3c2440_uart_inf = {
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.get_clksrc = s3c2440_serial_getsource,
- .set_clksrc = s3c2440_serial_setsource
+ .set_clksrc = s3c2440_serial_setsource,
+ .reset_port = s3c2440_serial_resetport,
};
/* device management */
@@ -1503,7 +1595,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
clk = clk_get(port->dev, clksrc.name);
if (!IS_ERR(clk) && clk != NULL)
- rate = clk_get_rate(clk);
+ rate = clk_get_rate(clk) / clksrc.divisor;
else
rate = 1;
@@ -1597,7 +1689,6 @@ static struct console s3c24xx_serial_console =
.setup = s3c24xx_serial_console_setup
};
-
static int s3c24xx_serial_initconsole(void)
{
struct s3c24xx_uart_info *info;
diff --git a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/arch-s3c2410/regs-serial.h
index 33a4842f64cf..782ce5f5d24d 100644
--- a/include/asm-arm/arch-s3c2410/regs-serial.h
+++ b/include/asm-arm/arch-s3c2410/regs-serial.h
@@ -73,6 +73,11 @@
#define S3C2440_UCON_UCLK (1<<10)
#define S3C2440_UCON_PCLK2 (2<<10)
#define S3C2440_UCON_FCLK (3<<10)
+#define S3C2440_UCON2_FCLK_EN (1<<15)
+#define S3C2440_UCON0_DIVMASK (15 << 12)
+#define S3C2440_UCON1_DIVMASK (15 << 12)
+#define S3C2440_UCON2_DIVMASK (7 << 12)
+#define S3C2440_UCON_DIVSHIFT (12)
#define S3C2410_UCON_UCLK (1<<10)
#define S3C2410_UCON_SBREAK (1<<4)
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 60513375e728..4fdff0484a32 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -47,13 +47,13 @@ extern void __raw_readsb(void __iomem *addr, void *data, int bytelen);
extern void __raw_readsw(void __iomem *addr, void *data, int wordlen);
extern void __raw_readsl(void __iomem *addr, void *data, int longlen);
-#define __raw_writeb(v,a) (*(volatile unsigned char __force *)(a) = (v))
-#define __raw_writew(v,a) (*(volatile unsigned short __force *)(a) = (v))
-#define __raw_writel(v,a) (*(volatile unsigned int __force *)(a) = (v))
+#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
+#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
+#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
-#define __raw_readb(a) (*(volatile unsigned char __force *)(a))
-#define __raw_readw(a) (*(volatile unsigned short __force *)(a))
-#define __raw_readl(a) (*(volatile unsigned int __force *)(a))
+#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
+#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
/*
* Bad read/write accesses...
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 9a8b8cb63dea..c2455a7a3287 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -317,12 +317,6 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
#define pmd_present(pmd) (pmd_val(pmd))
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
-#define set_pmd(pmdp,pmd) \
- do { \
- *(pmdp) = pmd; \
- flush_pmd_entry(pmdp); \
- } while (0)
-
#define copy_pmd(pmdpd,pmdps) \
do { \
pmdpd[0] = pmdps[0]; \
diff --git a/include/asm-arm/rtc.h b/include/asm-arm/rtc.h
index c3e330ded860..aa7e16b2e225 100644
--- a/include/asm-arm/rtc.h
+++ b/include/asm-arm/rtc.h
@@ -27,6 +27,7 @@ struct rtc_ops {
void rtc_time_to_tm(unsigned long, struct rtc_time *);
int rtc_tm_to_time(struct rtc_time *, unsigned long *);
+int rtc_valid_tm(struct rtc_time *);
void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *);
void rtc_update(unsigned long, unsigned long);
int register_rtc(struct rtc_ops *);