Commit ae0a0dc5 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents d96524e4 9ceea8ed
......@@ -2093,6 +2093,13 @@ L: sparclinux@vger.kernel.org
L: ultralinux@vger.kernel.org
S: Maintained
SHARP LH SUPPORT (LH7952X & LH7A40X)
P: Marc Singer
M: elf@buici.com
W: http://projects.buici.com/arm
L: linux-arm-kernel@lists.arm.linux.org.uk
S: Maintained
SPARC (sparc32):
P: William L. Irwin
M: wli@holomorphy.com
......
......@@ -60,7 +60,7 @@ static DECLARE_MUTEX(clocks_sem);
/* old functions */
void inline s3c2410_clk_enable(unsigned int clocks, unsigned int enable)
void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
{
unsigned long clkcon;
unsigned long flags;
......@@ -88,9 +88,9 @@ static int clk_null_enable(struct clk *clk, int enable)
return 0;
}
int s3c2410_clkcon_enable(struct clk *clk, int enable)
int s3c24xx_clkcon_enable(struct clk *clk, int enable)
{
s3c2410_clk_enable(clk->ctrlbit, enable);
s3c24xx_clk_enable(clk->ctrlbit, enable);
return 0;
}
......@@ -264,90 +264,90 @@ static struct clk init_clocks[] = {
{ .name = "nand",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_NAND
},
{ .name = "lcd",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_LCDC
},
{ .name = "usb-host",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBH
},
{ .name = "usb-device",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBD
},
{ .name = "timers",
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_PWMT
},
{ .name = "sdi",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SDI
},
{ .name = "uart",
.id = 0,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART0
},
{ .name = "uart",
.id = 1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART1
},
{ .name = "uart",
.id = 2,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART2
},
{ .name = "gpio",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_GPIO
},
{ .name = "rtc",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_RTC
},
{ .name = "adc",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_ADC
},
{ .name = "i2c",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIC
},
{ .name = "iis",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIS
},
{ .name = "spi",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SPI
},
{ .name = "watchdog",
......@@ -359,7 +359,7 @@ static struct clk init_clocks[] = {
/* initialise the clock system */
int s3c2410_register_clock(struct clk *clk)
int s3c24xx_register_clock(struct clk *clk)
{
clk->owner = THIS_MODULE;
atomic_set(&clk->used, 0);
......@@ -378,7 +378,7 @@ int s3c2410_register_clock(struct clk *clk)
/* initalise all the clocks */
int __init s3c2410_init_clocks(void)
int __init s3c24xx_setup_clocks(void)
{
struct clk *clkp = init_clocks;
int ptr;
......@@ -403,28 +403,28 @@ int __init s3c2410_init_clocks(void)
* and of course, this looks neater
*/
s3c2410_clk_enable(S3C2410_CLKCON_NAND, 0);
s3c2410_clk_enable(S3C2410_CLKCON_USBH, 0);
s3c2410_clk_enable(S3C2410_CLKCON_USBD, 0);
s3c2410_clk_enable(S3C2410_CLKCON_ADC, 0);
s3c2410_clk_enable(S3C2410_CLKCON_IIC, 0);
s3c2410_clk_enable(S3C2410_CLKCON_SPI, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
/* assume uart clocks are correctly setup */
/* register our clocks */
if (s3c2410_register_clock(&clk_f) < 0)
if (s3c24xx_register_clock(&clk_f) < 0)
printk(KERN_ERR "failed to register cpu fclk\n");
if (s3c2410_register_clock(&clk_h) < 0)
if (s3c24xx_register_clock(&clk_h) < 0)
printk(KERN_ERR "failed to register cpu hclk\n");
if (s3c2410_register_clock(&clk_p) < 0)
if (s3c24xx_register_clock(&clk_p) < 0)
printk(KERN_ERR "failed to register cpu pclk\n");
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
ret = s3c2410_register_clock(clkp);
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
......
......@@ -41,7 +41,7 @@ extern unsigned long s3c24xx_fclk;
* Please DO NOT use these outside of arch/arm/mach-s3c2410
*/
extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
extern int s3c2410_register_clock(struct clk *clk);
extern int s3c2410_init_clocks(void);
extern int s3c24xx_clkcon_enable(struct clk *clk, int enable);
extern int s3c24xx_register_clock(struct clk *clk);
extern int s3c24xx_setup_clocks(void);
......@@ -47,6 +47,7 @@ struct cpu_table {
unsigned long idmask;
void (*map_io)(struct map_desc *mach_desc, int size);
void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
void (*init_clocks)(int xtal);
int (*init)(void);
const char *name;
};
......@@ -63,6 +64,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = 0x32410000,
.idmask = 0xffffffff,
.map_io = s3c2410_map_io,
.init_clocks = s3c2410_init_clocks,
.init_uarts = s3c2410_init_uarts,
.init = s3c2410_init,
.name = name_s3c2410
......@@ -71,6 +73,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = 0x32410002,
.idmask = 0xffffffff,
.map_io = s3c2410_map_io,
.init_clocks = s3c2410_init_clocks,
.init_uarts = s3c2410_init_uarts,
.init = s3c2410_init,
.name = name_s3c2410a
......@@ -79,6 +82,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = 0x32440000,
.idmask = 0xffffffff,
.map_io = s3c2440_map_io,
.init_clocks = s3c2440_init_clocks,
.init_uarts = s3c2440_init_uarts,
.init = s3c2440_init,
.name = name_s3c2440
......@@ -87,6 +91,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = 0x32440001,
.idmask = 0xffffffff,
.map_io = s3c2440_map_io,
.init_clocks = s3c2440_init_clocks,
.init_uarts = s3c2440_init_uarts,
.init = s3c2440_init,
.name = name_s3c2440a
......@@ -132,7 +137,7 @@ void s3c24xx_set_board(struct s3c24xx_board *b)
struct clk **ptr = b->clocks;;
for (i = b->clocks_count; i > 0; i--, ptr++)
s3c2410_register_clock(*ptr);
s3c24xx_register_clock(*ptr);
}
}
......@@ -165,6 +170,29 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
(cpu->map_io)(mach_desc, size);
}
/* s3c24xx_init_clocks
*
* Initialise the clock subsystem and associated information from the
* given master crystal value.
*
* xtal = 0 -> use default PLL crystal value (normally 12MHz)
* != 0 -> PLL crystal value in Hz
*/
void __init s3c24xx_init_clocks(int xtal)
{
if (xtal != 0)
s3c24xx_xtal = xtal;
if (cpu == NULL)
panic("s3c24xx_init_clocks: no cpu setup?\n");
if (cpu->init_clocks == NULL)
panic("s3c24xx_init_clocks: cpu has no clock init\n");
else
(cpu->init_clocks)(xtal);
}
void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
if (cpu == NULL)
......@@ -175,6 +203,7 @@ void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
} else
(cpu->init_uarts)(cfg, no);
}
static int __init s3c_arch_init(void)
{
int ret;
......
......@@ -14,6 +14,7 @@
* 18-Oct-2004 BJD Moved board struct into this file
* 04-Jan-2005 BJD New uart initialisation
* 10-Jan-2005 BJD Moved generic init here, specific to cpu headers
* 14-Jan-2005 BJD Added s3c24xx_init_clocks() call
*/
#define IODESC_ENT(x) { S3C2410_VA_##x, S3C2410_PA_##x, S3C2410_SZ_##x, MT_DEVICE }
......@@ -35,6 +36,8 @@ extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c24xx_init_clocks(int xtal);
/* the board structure is used at first initialsation time
* to get info such as the devices to register for this
* board. This is done because platfrom_add_devices() cannot
......
......@@ -263,6 +263,7 @@ void __init bast_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
s3c24xx_set_board(&bast_board);
usb_simtec_init();
......
......@@ -22,6 +22,7 @@
* 04-Nov-2004 BJD Change for new serial clock
* 04-Jan-2005 BJD Updated uart init call
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Added clock init
*/
#include <linux/kernel.h>
......@@ -103,6 +104,7 @@ static struct s3c24xx_board h1940_board __initdata = {
void __init h1940_map_io(void)
{
s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
s3c24xx_set_board(&h1940_board);
}
......
......@@ -13,6 +13,7 @@
* 16-Sep-2004 BJD Copied from mach-h1940.c
* 25-Oct-2004 BJD Updates for 2.6.10-rc1
* 10-Jan-2005 BJD Removed include of s3c2410.h s3c2440.h
* 14-Jan-2005 BJD Added new clock init
*/
#include <linux/kernel.h>
......@@ -91,9 +92,8 @@ static struct s3c24xx_board rx3715_board __initdata = {
void __init rx3715_map_io(void)
{
s3c24xx_xtal = 16934000;
s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
s3c24xx_init_clocks(16934000);
s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
s3c24xx_set_board(&rx3715_board);
}
......
......@@ -97,6 +97,7 @@ static struct s3c24xx_board smdk2410_board __initdata = {
void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
s3c24xx_set_board(&smdk2410_board);
}
......
......@@ -20,6 +20,7 @@
* 04-Nov-2004 BJD Clock and serial configuration update
* 04-Jan-2005 BJD Updated uart init call
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Added clock init
*/
#include <linux/kernel.h>
......@@ -205,6 +206,7 @@ void __init vr1000_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
s3c24xx_set_board(&vr1000_board);
usb_simtec_init();
......
......@@ -151,19 +151,19 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
*
* register the standard cpu IO areas, and any passed in from the
* machine specific initialisation.
*
* this function also sets the initial clock frequencies from the
* settings passed in
*/
void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size)
{
unsigned long tmp;
/* register our io-tables */
iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
iotable_init(mach_desc, mach_size);
}
void __init s3c2410_init_clocks(int xtal)
{
unsigned long tmp;
/* now we've got our machine bits initialised, work out what
* clocks we've got */
......@@ -188,7 +188,7 @@ void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size)
* console to use them
*/
s3c2410_init_clocks();
s3c24xx_setup_clocks();
}
int __init s3c2410_init(void)
......
......@@ -16,6 +16,7 @@
* 17-Oct-2004 BJD Moved board out to cpu
* 04-Jan-2005 BJD Changed uart init
* 10-Jan-2005 BJD Removed timer to cpu.h, moved 2410 specific bits here
* 14-Jan-2005 BJD Added s3c2410_init_clocks call
*/
#ifdef CONFIG_CPU_S3C2410
......@@ -26,7 +27,10 @@ extern void s3c2410_map_io(struct map_desc *mach_desc, int size);
extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c2410_init_clocks(int xtal);
#else
#define s3c2410_init_clocks NULL
#define s3c2410_init_uarts NULL
#define s3c2410_map_io NULL
#define s3c2410_init NULL
......
/* linux/arch/arm/mach-s3c2410/s3c2440.c
*
* Copyright (c) 2004 Simtec Electronics
* Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Samsung S3C2440 Mobile CPU support
......@@ -16,6 +16,8 @@
* 09-Nov-2004 BJD Added sysdev for power management
* 04-Nov-2004 BJD New serial registration
* 15-Nov-2004 BJD Rename the i2c device for the s3c2440
* 14-Jan-2005 BJD Moved clock init code into seperate function
* 14-Jan-2005 BJD Removed un-used clock bits
*/
#include <linux/kernel.h>
......@@ -48,10 +50,6 @@
#include "cpu.h"
#include "pm.h"
int s3c2440_clock_tick_rate = 12*1000*1000; /* current timers at 12MHz */
/* clock info */
unsigned long s3c2440_hdiv;
static struct map_desc s3c2440_iodesc[] __initdata = {
IODESC_ENT(USBHOST),
......@@ -155,13 +153,13 @@ void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
static struct clk s3c2440_clk_cam = {
.name = "camera",
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2440_CLKCON_CAMERA
};
static struct clk s3c2440_clk_ac97 = {
.name = "ac97",
.enable = s3c2410_clkcon_enable,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2440_CLKCON_CAMERA
};
......@@ -204,13 +202,20 @@ static struct sys_device s3c2440_sysdev = {
void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
{
unsigned long clkdiv;
unsigned long camdiv;
/* register our io-tables */
iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
iotable_init(mach_desc, size);
/* rename any peripherals used differing from the s3c2410 */
s3c_device_i2c.name = "s3c2440-i2c";
}
void __init s3c2440_init_clocks(int xtal)
{
unsigned long clkdiv;
unsigned long camdiv;
int s3c2440_hdiv = 1;
/* now we've got our machine bits initialised, work out what
* clocks we've got */
......@@ -254,22 +259,18 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
* console to use them, and to add new ones after the initialisation
*/
s3c2410_init_clocks();
s3c24xx_setup_clocks();
/* add s3c2440 specific clocks */
s3c2440_clk_cam.parent = clk_get(NULL, "hclk");
s3c2440_clk_ac97.parent = clk_get(NULL, "pclk");
s3c2410_register_clock(&s3c2440_clk_ac97);
s3c2410_register_clock(&s3c2440_clk_cam);
s3c24xx_register_clock(&s3c2440_clk_ac97);
s3c24xx_register_clock(&s3c2440_clk_cam);
clk_disable(&s3c2440_clk_ac97);
clk_disable(&s3c2440_clk_cam);
/* rename any peripherals used differing from the s3c2410 */
s3c_device_i2c.name = "s3c2440-i2c";
}
int __init s3c2440_init(void)
......
......@@ -14,6 +14,7 @@
* 04-Nov-2004 BJD Added s3c2440_init_uarts()
* 04-Jan-2005 BJD Moved uart init to cpu code
* 10-Jan-2005 BJD Moved 2440 specific init here
* 14-Jan-2005 BJD Split the clock initialisation code
*/
#ifdef CONFIG_CPU_S3C2440
......@@ -24,7 +25,10 @@ extern void s3c2440_map_io(struct map_desc *mach_desc, int size);
extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c2440_init_clocks(int xtal);
#else
#define s3c2440_init_clocks NULL
#define s3c2440_init_uarts NULL
#define s3c2440_map_io NULL
#define s3c2440_init NULL
......
......@@ -148,7 +148,7 @@ __ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
*/
offset = phys_addr & ~PAGE_MASK;
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr) - phys_addr;
size = PAGE_ALIGN(last_addr + 1) - phys_addr;
/*
* Ok, go for it..
......
......@@ -105,6 +105,7 @@ ENTRY(cpu_v6_dcache_clean_area)
ENTRY(cpu_v6_switch_mm)
mov r2, #0
ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
mcr p15, 0, r1, c13, c0, 1 @ set context ID
......
......@@ -17,7 +17,7 @@
*/
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/thread_info.h>
#include <asm/constants.h>
#include <asm/vfpmacros.h>
.globl do_vfp
......
......@@ -48,4 +48,5 @@ sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o
pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
/*
* Sharp SL-C7xx Series PCMCIA routines
*
* Copyright (c) 2004-2005 Richard Purdie
*
* Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c
*
* 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/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/hardware/scoop.h>
#include <asm/arch/corgi.h>
#include <asm/arch/pxa-regs.h>
#include "soc_common.h"
#define NO_KEEP_VS 0x0001
static unsigned char keep_vs;
static unsigned char keep_rd;
static struct pcmcia_irqs irqs[] = {
{ 0, CORGI_IRQ_GPIO_CF_CD, "PCMCIA0 CD"},
};
static void sharpsl_pcmcia_init_reset(void)
{
reset_scoop();
keep_vs = NO_KEEP_VS;
keep_rd = 0;
}
static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
/*
* 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);
/* Register interrupts */
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
if (ret) {
printk(KERN_ERR "Request for Compact Flash IRQ failed\n");
return ret;
}
/* Enable interrupt */
write_scoop_reg(SCOOP_IMR, 0x00C0);
write_scoop_reg(SCOOP_MCR, 0x0101);
keep_vs = NO_KEEP_VS;
skt->irq = CORGI_IRQ_GPIO_CF_IRQ;
return 0;
}
static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* CF_BUS_OFF */
sharpsl_pcmcia_init_reset();
}
static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
unsigned short cpr, csr;
cpr = read_scoop_reg(SCOOP_CPR);
write_scoop_reg(SCOOP_IRM, 0x00FF);
write_scoop_reg(SCOOP_ISR, 0x0000);
write_scoop_reg(SCOOP_IRM, 0x0000);
csr = read_scoop_reg(SCOOP_CSR);
if (csr & 0x0004) {
/* card eject */
write_scoop_reg(SCOOP_CDR, 0x0000);
keep_vs = NO_KEEP_VS;
}
else if (!(keep_vs & NO_KEEP_VS)) {
/* keep vs1,vs2 */
write_scoop_reg(SCOOP_CDR, 0x0000);
csr |= keep_vs;
}
else if (cpr & 0x0003) {
/* power on */
write_scoop_reg(SCOOP_CDR, 0x0000);
keep_vs = (csr & 0x00C0);
}
else {
/* card detect */
write_scoop_reg(SCOOP_CDR, 0x0002);
}
state->detect = (csr & 0x0004) ? 0 : 1;
state->ready = (csr & 0x0002) ? 1 : 0;
state->bvd1 = (csr & 0x0010) ? 1 : 0;
state->bvd2 = (csr & 0x0020) ? 1 : 0;
state->wrprot = (csr & 0x0008) ? 1 : 0;
state->vs_3v = (csr & 0x0040) ? 0 : 1;
state->vs_Xv = (csr & 0x0080) ? 0 : 1;
if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
}
}
static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long flags;
unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
switch (state->Vcc) {
case 0: break;
case 33: break;
case 50: break;
default:
printk(KERN_ERR "sharpsl_pcmcia_configure_socket(): bad Vcc %u\n", state->Vcc);
return -1;
}
if ((state->Vpp!=state->Vcc) && (state->Vpp!=0)) {
printk(KERN_ERR "CF slot cannot support Vpp %u\n", state->Vpp);
return -1;
}
local_irq_save(flags);
nmcr = (mcr = read_scoop_reg(SCOOP_MCR)) & ~0x0010;
ncpr = (cpr = read_scoop_reg(SCOOP_CPR)) & ~0x0083;
nccr = (ccr = read_scoop_reg(SCOOP_CCR)) & ~0x0080;
nimr = (imr = read_scoop_reg(SCOOP_IMR)) & ~0x003E;
ncpr |= (state->Vcc == 33) ? 0x0001 :
(state->Vcc == 50) ? 0x0002 : 0;
nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
nccr |= (state->flags&SS_RESET)? 0x0080: 0;
nimr |= ((skt->status&SS_DETECT) ? 0x0004 : 0)|
((skt->status&SS_READY) ? 0x0002 : 0)|
((skt->status&SS_BATDEAD)? 0x0010 : 0)|
((skt->status&SS_BATWARN)? 0x0020 : 0)|
((skt->status&SS_STSCHG) ? 0x0010 : 0)|
((skt->status&SS_WRPROT) ? 0x0008 : 0);
if (!(ncpr & 0x0003)) {
keep_rd = 0;
} else if (!keep_rd) {
if (nccr & 0x0080)
keep_rd = 1;
else
nccr |= 0x0080;
}
if (mcr != nmcr)
write_scoop_reg(SCOOP_MCR, nmcr);
if (cpr != ncpr)
write_scoop_reg(SCOOP_CPR, ncpr);
if (ccr != nccr)
write_scoop_reg(SCOOP_CCR, nccr);
if (imr != nimr)
write_scoop_reg(SCOOP_IMR, nimr);
local_irq_restore(flags);
return 0;
}
static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
}
static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
}
static struct pcmcia_low_level sharpsl_pcmcia_ops = {
.owner = THIS_MODULE,
.hw_init = sharpsl_pcmcia_hw_init,
.hw_shutdown = sharpsl_pcmcia_hw_shutdown,
.socket_state = sharpsl_pcmcia_socket_state,
.configure_socket = sharpsl_pcmcia_configure_socket,
.socket_init = sharpsl_pcmcia_socket_init,
.socket_suspend = sharpsl_pcmcia_socket_suspend,
.first = 0,
.nr = 1,
};
static struct platform_device *sharpsl_pcmcia_device;
static int __init sharpsl_pcmcia_init(void)
{
int ret;
sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
if (!sharpsl_pcmcia_device)
return -ENOMEM;
memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
ret = platform_device_register(sharpsl_pcmcia_device);
if (ret)
kfree(sharpsl_pcmcia_device);
return ret;
}
static void __exit sharpsl_pcmcia_exit(void)
{
/*
* This call is supposed to free our sharpsl_pcmcia_device.
* Unfortunately platform_device don't have a free method, and
* we can't assume it's free of any reference at this point so we
* can't free it either.
*/
platform_device_unregister(sharpsl_pcmcia_device);
}
module_init(sharpsl_pcmcia_init);
module_exit(sharpsl_pcmcia_exit);
MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
MODULE_LICENSE("GPL");
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