Commit 73b5d164 authored by Linus Torvalds's avatar Linus Torvalds

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

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents ba1abdbf 3bfc2601
This diff is collapsed.
......@@ -120,6 +120,13 @@ config PCMCIA_SA1111
This driver is also available as a module called sa1111_cs.
config PCMCIA_PXA2XX
tristate "PXA2xx support"
depends on ARM && ARCH_PXA && PCMCIA
help
Say Y here to include support for the PXA2xx PCMCIA controller
config PCMCIA_PROBE
bool
default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X
......
......@@ -15,10 +15,14 @@ obj-$(CONFIG_TCIC) += tcic.o
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o
pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
sa11xx_core-y += soc_common.o sa11xx_base.o
pxa2xx_core-y += soc_common.o pxa2xx_base.o
sa1111_cs-y += sa1111_generic.o
sa1111_cs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o
sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
......@@ -42,3 +46,6 @@ sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
sa1100_cs-$(CONFIG_SA1100_STORK) += sa1100_stork.o
sa1100_cs-$(CONFIG_SA1100_TRIZEPS) += sa1100_trizeps.o
sa1100_cs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o
pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o
/*======================================================================
Device driver for the PCMCIA control functionality of PXA2xx
microprocessors.
The contents of this file may be used under the
terms of the GNU Public License version 2 (the "GPL")
(c) Ian Molton (spyro@f2s.com) 2003
(c) Stefan Eletzhofer (stefan.eletzhofer@inquant.de) 2003,4
derived from sa11xx_base.c
Portions created by John G. Dorsey are
Copyright (C) 1999 John G. Dorsey.
======================================================================*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/config.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
#include "soc_common.h"
#include "pxa2xx_base.h"
#define MCXX_SETUP_MASK (0x7f)
#define MCXX_ASST_MASK (0x1f)
#define MCXX_HOLD_MASK (0x3f)
#define MCXX_SETUP_SHIFT (0)
#define MCXX_ASST_SHIFT (7)
#define MCXX_HOLD_SHIFT (14)
static inline u_int pxa2xx_mcxx_hold(u_int pcmcia_cycle_ns,
u_int mem_clk_10khz)
{
u_int code = pcmcia_cycle_ns * mem_clk_10khz;
return (code / 300000) + ((code % 300000) ? 1 : 0) - 1;
}
static inline u_int pxa2xx_mcxx_asst(u_int pcmcia_cycle_ns,
u_int mem_clk_10khz)
{
u_int code = pcmcia_cycle_ns * mem_clk_10khz;
return (code / 300000) + ((code % 300000) ? 1 : 0) - 1;
}
static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns,
u_int mem_clk_10khz)
{
u_int code = pcmcia_cycle_ns * mem_clk_10khz;
return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
}
/* This function returns the (approximate) command assertion period, in
* nanoseconds, for a given CPU clock frequency and MCXX_ASST value:
*/
static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz,
u_int pcmcia_mcxx_asst)
{
return (300000 * (pcmcia_mcxx_asst + 1) / mem_clk_10khz);
}
static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock )
{
MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock)
& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
| ((pxa2xx_mcxx_asst(speed, clock)
& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
| ((pxa2xx_mcxx_hold(speed, clock)
& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
return 0;
}
static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock )
{
MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock)
& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
| ((pxa2xx_mcxx_asst(speed, clock)
& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
| ((pxa2xx_mcxx_hold(speed, clock)
& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
return 0;
}
static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock )
{
MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock)
& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
| ((pxa2xx_mcxx_asst(speed, clock)
& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
| ((pxa2xx_mcxx_hold(speed, clock)
& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
return 0;
}
static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int lclk)
{
int sock = skt->nr;
pxa2xx_pcmcia_set_mcmem( sock, SOC_PCMCIA_5V_MEM_ACCESS, lclk );
pxa2xx_pcmcia_set_mcatt( sock, SOC_PCMCIA_ATTR_MEM_ACCESS, lclk );
pxa2xx_pcmcia_set_mcio( sock, SOC_PCMCIA_IO_ACCESS, lclk );
return 0;
}
static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
{
unsigned int lclk = get_lclk_frequency_10khz();
return pxa2xx_pcmcia_set_mcxx(skt, lclk);
}
int pxa2xx_drv_pcmcia_probe(struct device *dev)
{
int ret;
struct pcmcia_low_level *ops;
int first, nr;
if (!dev || !dev->platform_data)
return -ENODEV;
ops = (struct pcmcia_low_level *)dev->platform_data;
first = ops->first;
nr = ops->nr;
/* Setup GPIOs for PCMCIA/CF alternate function mode.
*
* It would be nice if set_GPIO_mode included support
* for driving GPIO outputs to default high/low state
* before programming GPIOs as outputs. Setting GPIO
* outputs to default high/low state via GPSR/GPCR
* before defining them as outputs should reduce
* the possibility of glitching outputs during GPIO
* setup. This of course assumes external terminators
* are present to hold GPIOs in a defined state.
*
* In the meantime, 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); /* REVISIT: s/b dependent on num sockets */
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
/* Provide our PXA2xx specific timing routines. */
ops->set_timing = pxa2xx_pcmcia_set_timing;
ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr);
if (ret == 0) {
/*
* We have at least one socket, so set MECR:CIT
* (Card Is There)
*/
MECR |= MECR_CIT;
/* Set MECR:NOS (Number Of Sockets) */
if (nr > 1)
MECR |= MECR_NOS;
else
MECR &= ~MECR_NOS;
}
return ret;
}
EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe);
static int pxa2xx_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
{
int ret = 0;
if (level == SUSPEND_SAVE_STATE)
ret = pcmcia_socket_dev_suspend(dev, state);
return ret;
}
static int pxa2xx_drv_pcmcia_resume(struct device *dev, u32 level)
{
int ret = 0;
if (level == RESUME_RESTORE_STATE)
ret = pcmcia_socket_dev_resume(dev);
return ret;
}
static struct device_driver pxa2xx_pcmcia_driver = {
.probe = pxa2xx_drv_pcmcia_probe,
.remove = soc_common_drv_pcmcia_remove,
.suspend = pxa2xx_drv_pcmcia_suspend,
.resume = pxa2xx_drv_pcmcia_resume,
.name = "pxa2xx-pcmcia",
.bus = &platform_bus_type,
};
#ifdef CONFIG_CPU_FREQ
/*
* When pxa2xx_pcmcia_notifier() decides that a MC{IO,MEM,ATT} adjustment (due
* to a core clock frequency change) is needed, this routine establishes
* new values consistent with the clock speed `clock'.
*/
static void pxa2xx_pcmcia_update_mcxx(unsigned int clock)
{
struct soc_pcmcia_socket *skt;
down(&soc_sockets_lock);
list_for_each_entry(skt, &soc_sockets, node) {
pxa2xx_pcmcia_set_mcio(skt->nr, calc_speed(skt->spd_io,
MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS), clock);
pxa2xx_pcmcia_set_mcmem(skt->nr, calc_speed(skt->spd_io,
MAX_IO_WIN, SOC_PCMCIA_3V_MEM_ACCESS), clock );
pxa2xx_pcmcia_set_mcatt(skt->nr, calc_speed(skt->spd_io,
MAX_IO_WIN, SOC_PCMCIA_3V_MEM_ACCESS), clock );
}
up(&soc_sockets_lock);
}
/*
* When changing the processor L clock frequency, it is necessary
* to adjust the MCXX timings accordingly. We've recorded the timings
* requested by Card Services, so this is just a matter of finding
* out what our current speed is, and then recomputing the new MCXX
* values.
*
* Returns: 0 on success, -1 on error
*/
static int
pxa2xx_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
{
struct cpufreq_freqs *freqs = data;
#warning "it's not clear if this is right since the core CPU (N) clock has no effect on the memory (L) clock"
switch (val) {
case CPUFREQ_PRECHANGE:
if (freqs->new > freqs->old) {
debug( 2, "new frequency %u.%uMHz > %u.%uMHz, "
"pre-updating\n",
freqs->new / 1000, (freqs->new / 100) % 10,
freqs->old / 1000, (freqs->old / 100) % 10);
pxa2xx_pcmcia_update_mcxx(freqs->new);
}
break;
case CPUFREQ_POSTCHANGE:
if (freqs->new < freqs->old) {
debug( 2, "new frequency %u.%uMHz < %u.%uMHz, "
"post-updating\n",
freqs->new / 1000, (freqs->new / 100) % 10,
freqs->old / 1000, (freqs->old / 100) % 10);
pxa2xx_pcmcia_update_mcxx(freqs->new);
}
break;
}
return 0;
}
static struct notifier_block pxa2xx_pcmcia_notifier_block = {
.notifier_call = pxa2xx_pcmcia_notifier
};
static int __init pxa2xx_pcmcia_cpufreq_init(void)
{
int ret;
ret = cpufreq_register_notifier(&pxa2xx_pcmcia_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
if (ret < 0)
printk(KERN_ERR "Unable to register CPU frequency change "
"notifier for PCMCIA (%d)\n", ret);
return ret;
}
static void __exit pxa2xx_pcmcia_cpufreq_exit(void)
{
cpufreq_unregister_notifier(&pxa2xx_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
}
#else
#define pxa2xx_pcmcia_cpufreq_init()
#define pxa2xx_pcmcia_cpufreq_exit()
#endif
static int __init pxa2xx_pcmcia_init(void)
{
int ret = driver_register(&pxa2xx_pcmcia_driver);
if (ret == 0)
pxa2xx_pcmcia_cpufreq_init();
return ret;
}
static void __exit pxa2xx_pcmcia_exit(void)
{
pxa2xx_pcmcia_cpufreq_exit();
driver_unregister(&pxa2xx_pcmcia_driver);
}
module_init(pxa2xx_pcmcia_init);
module_exit(pxa2xx_pcmcia_exit);
MODULE_AUTHOR("Stefan Eletzhofer <stefan.eletzhofer@inquant.de> and Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("Linux PCMCIA Card Services: PXA2xx core socket driver");
MODULE_LICENSE("GPL");
/* temporary measure */
extern int pxa2xx_drv_pcmcia_probe(struct device *);
/*
* linux/drivers/pcmcia/pxa2xx_lubbock.c
*
* Author: George Davis
* Created: Jan 10, 2002
* Copyright: MontaVista Software Inc.
*
* 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.
*
* Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
*
* Lubbock PCMCIA specific routines.
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
#include "sa1111_generic.h"
static int
lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long flags, gpio, misc_wr;
int ret = 1;
struct pcmcia_state new_state;
local_irq_save(flags);
gpio = PA_DWR;
misc_wr = LUB_MISC_WR;
/* Lubbock uses the Maxim MAX1602, with the following connections:
*
* Socket 0 (PCMCIA):
* MAX1602 Lubbock Register
* Pin Signal
* ----- ------- ----------------------
* A0VPP S0_PWR0 SA-1111 GPIO A<0>
* A1VPP S0_PWR1 SA-1111 GPIO A<1>
* A0VCC S0_PWR2 SA-1111 GPIO A<2>
* A1VCC S0_PWR3 SA-1111 GPIO A<3>
* VX VCC
* VY +3.3V
* 12IN +12V
* CODE +3.3V Cirrus Code, CODE = High (VY)
*
* Socket 1 (CF):
* MAX1602 Lubbock Register
* Pin Signal
* ----- ------- ----------------------
* A0VPP GND VPP is not connected
* A1VPP GND VPP is not connected
* A0VCC S1_PWR0 MISC_WR<14>
* A1VCC S1_PWR0 MISC_WR<15>
* VX VCC
* VY +3.3V
* 12IN GND VPP is not connected
* CODE +3.3V Cirrus Code, CODE = High (VY)
*
*/
again:
switch(skt->nr){
case 0:
switch(state->Vcc){
case 0:
gpio &= ~(GPIO_bit(2) | GPIO_bit(3));
break;
case 33:
gpio = (gpio & ~(GPIO_bit(2) | GPIO_bit(3))) | GPIO_bit(3);
break;
case 50:
gpio = (gpio & ~(GPIO_bit(2) | GPIO_bit(3))) | GPIO_bit(2);
break;
default:
printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, state->Vcc);
ret = -1;
}
switch(state->Vpp){
case 0:
gpio &= ~(GPIO_bit(0) | GPIO_bit(1));
break;
case 120:
gpio = (gpio & ~(GPIO_bit(0) | GPIO_bit(1))) | GPIO_bit(1);
break;
default:
/* REVISIT: I'm not sure about this? Is this correct?
Is it always safe or do we have potential problems
with bogus combinations of Vcc and Vpp settings? */
if(state->Vpp == state->Vcc)
gpio = (gpio & ~(GPIO_bit(0) | GPIO_bit(1))) | GPIO_bit(0);
else {
printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__, state->Vpp);
ret = -1;
break;
}
}
break;
case 1:
switch(state->Vcc){
case 0:
misc_wr &= ~((1 << 15) | (1 << 14));
break;
case 33:
misc_wr = (misc_wr & ~(1 << 15)) | (1 << 14);
gpio = (gpio & ~(GPIO_bit(2) | GPIO_bit(3))) | GPIO_bit(2);
break;
case 50:
misc_wr = (misc_wr & ~(1 << 15)) | (1 << 14);
break;
default:
printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, state->Vcc);
ret = -1;
break;
}
if(state->Vpp!=state->Vcc && state->Vpp!=0){
printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__, state->Vpp);
ret = -1;
break;
}
break;
default:
ret = -1;
}
if (ret >= 0) {
sa1111_pcmcia_configure_socket(skt, state);
LUB_MISC_WR = misc_wr;
PA_DWR = gpio;
}
if (ret > 0) {
ret = 0;
#if 1
/*
* HACK ALERT:
* We can't sense the voltage properly on Lubbock before actually
* applying some power to the socket (catch 22).
* Resense the socket Voltage Sense pins after applying socket power.
*/
sa1111_pcmcia_socket_state(skt, &new_state);
if (state->Vcc == 33 && !new_state.vs_3v && !new_state.vs_Xv) {
/* Switch to 5V, Configure socket with 5V voltage */
PA_DWR &= ~(GPIO_bit(0) | GPIO_bit(1) | GPIO_bit(2) | GPIO_bit(3));
PA_DDR &= ~(GPIO_bit(0) | GPIO_bit(1) | GPIO_bit(2) | GPIO_bit(3));
/* We need to hack around the const qualifier as well to keep this
ugly workaround localized and not force it to the rest of the code.
Barf bags avaliable in the seat pocket in front of you! */
((socket_state_t *)state)->Vcc = 50;
((socket_state_t *)state)->Vpp = 50;
goto again;
}
#endif
}
local_irq_restore(flags);
return ret;
}
static struct pcmcia_low_level lubbock_pcmcia_ops = {
.owner = THIS_MODULE,
.hw_init = sa1111_pcmcia_hw_init,
.hw_shutdown = sa1111_pcmcia_hw_shutdown,
.socket_state = sa1111_pcmcia_socket_state,
.configure_socket = lubbock_pcmcia_configure_socket,
.socket_init = sa1111_pcmcia_socket_init,
.socket_suspend = sa1111_pcmcia_socket_suspend,
.first = 0,
.nr = 2,
};
#include "pxa2xx_base.h"
int __init pcmcia_lubbock_init(struct device *dev)
{
int ret = -ENODEV;
if (machine_is_lubbock()) {
/*
* Set GPIO_A<3:0> to be outputs for the MAX1600,
* and switch to standby mode.
*/
PA_DWR = 0;
PA_DDR = 0;
PA_SDR = 0;
PA_SSR = 0;
/* Set CF Socket 1 power to standby mode. */
LUB_MISC_WR &= ~(GPIO_bit(15) | GPIO_bit(14));
dev->platform_data = &lubbock_pcmcia_ops;
ret = pxa2xx_drv_pcmcia_probe(dev);
}
return ret;
}
......@@ -20,7 +20,7 @@
#include "sa1111_generic.h"
static int adsbitsy_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int adsbitsy_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
......@@ -35,7 +35,7 @@ static int adsbitsy_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
}
static int
adsbitsy_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
adsbitsy_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
unsigned int pa_dwr_mask, pa_dwr_set;
int ret;
......
......@@ -25,23 +25,23 @@ static struct pcmcia_irqs irqs[] = {
{ 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" },
};
static int assabet_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->irq = ASSABET_IRQ_GPIO_CF_IRQ;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
/*
* Release all resources.
*/
static void assabet_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void
assabet_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *state)
assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
unsigned long levels = GPLR;
......@@ -55,7 +55,7 @@ assabet_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_stat
}
static int
assabet_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
unsigned int mask;
......@@ -93,22 +93,22 @@ assabet_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_s
* be called at initialisation, power management event, or
* pcmcia event.
*/
static void assabet_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
/*
* Enable CF bus
*/
ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
/*
* Disable card status IRQs on suspend.
*/
static void assabet_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
/*
* Tristate the CF bus signals. Also assert CF
......
......@@ -75,7 +75,7 @@ static void complain_about_jumpering(const char *whom,
}
static int
badge4_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
int ret;
......
......@@ -27,20 +27,20 @@ static struct pcmcia_irqs irqs[] = {
{ CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" }
};
static int cerf_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->irq = CERF_IRQ_GPIO_CF_IRQ;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void cerf_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void
cerf_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *state)
cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
unsigned long levels = GPLR;
......@@ -54,7 +54,7 @@ cerf_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *
}
static int
cerf_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
switch (state->Vcc) {
......@@ -78,14 +78,14 @@ cerf_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void cerf_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void cerf_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level cerf_pcmcia_ops = {
......
......@@ -28,20 +28,20 @@ static struct pcmcia_irqs irqs[] = {
*
* Called by sa1100_pcmcia_driver_init on startup.
*/
static int flexanet_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int flexanet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->irq = skt->nr ? IRQ_GPIO_CF2_IRQ : IRQ_GPIO_CF1_IRQ;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
/*
* Socket shutdown
*/
static void flexanet_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void flexanet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
......@@ -52,7 +52,7 @@ static void flexanet_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
*
*/
static void
flexanet_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
flexanet_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
unsigned long levels = GPLR; /* Sense the GPIOs, asynchronously */
......@@ -85,7 +85,7 @@ flexanet_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
*
*/
static int
flexanet_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
flexanet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long value, flags, mask;
......@@ -133,14 +133,14 @@ flexanet_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void flexanet_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void flexanet_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void flexanet_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void flexanet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
/*
......
......@@ -20,7 +20,7 @@ static struct pcmcia_irqs irqs[] = {
{ 0, IRQ_GPIO_FREEBIRD_CF_BVD, "CF_BVD1" },
};
static int freebird_pcmcia_init(struct sa1100_pcmcia_socket *skt)
static int freebird_pcmcia_init(struct soc_pcmcia_socket *skt)
{
/* Enable Linkup CF card */
LINKUP_PRC = 0xc0;
......@@ -35,12 +35,12 @@ static int freebird_pcmcia_init(struct sa1100_pcmcia_socket *skt)
skt->irq = IRQ_GPIO_FREEBIRD_CF_IRQ;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void freebird_pcmcia_shutdown(struct sa1100_pcmcia_socket *skt)
static void freebird_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs);
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs);
/* Disable CF card */
LINKUP_PRC = 0x40; /* SSP=1 SOE=0 */
......@@ -48,7 +48,7 @@ static void freebird_pcmcia_shutdown(struct sa1100_pcmcia_socket *skt)
}
static void
freebird_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *state)
freebird_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
unsigned long levels = LINKUP_PRS;
// printk("LINKUP_PRS=%x\n",levels);
......@@ -63,7 +63,7 @@ freebird_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_sta
}
static int
freebird_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
freebird_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
socket_state_t *state)
{
unsigned long value, flags;
......@@ -103,14 +103,14 @@ freebird_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void freebird_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void freebird_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void freebird_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void freebird_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level freebird_pcmcia_ops = {
......
......@@ -43,7 +43,7 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include "sa1100.h"
#include "sa1100_generic.h"
static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_ASSABET
......@@ -118,7 +118,7 @@ static int sa11x0_drv_pcmcia_resume(struct device *dev, u32 level)
static struct device_driver sa11x0_pcmcia_driver = {
.probe = sa11x0_drv_pcmcia_probe,
.remove = sa11xx_drv_pcmcia_remove,
.remove = soc_common_drv_pcmcia_remove,
.name = "sa11x0-pcmcia",
.bus = &platform_bus_type,
.suspend = sa11x0_drv_pcmcia_suspend,
......
#include "sa11xx_core.h"
#include "soc_common.h"
#include "sa11xx_base.h"
/*
* Declaration for all machine specific init/exit functions.
......
......@@ -38,7 +38,7 @@ static struct pcmcia_irqs irqs[] = {
{ 0, S0_CD_IRQ, "PCMCIA 0 CD" },
};
static int gcplus_pcmcia_init(struct sa1100_pcmcia_socket *skt)
static int gcplus_pcmcia_init(struct soc_pcmcia_socket *skt)
{
// Reset PCMCIA
// Reset Timing for CPLD(U2) version 8001E or later
......@@ -54,10 +54,10 @@ static int gcplus_pcmcia_init(struct sa1100_pcmcia_socket *skt)
skt->irq = S0_STS_IRQ;
/* Register interrupts */
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void gcplus_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void gcplus_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
/* disable IRQs */
free_irq(S0_CD_IRQ, skt);
......@@ -68,7 +68,7 @@ static void gcplus_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
}
static void
gcplus_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *state)
gcplus_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
unsigned long levels = *PCMCIA_Status;
......@@ -82,7 +82,7 @@ gcplus_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state
}
static int
gcplus_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
gcplus_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long flags;
......@@ -125,11 +125,11 @@ gcplus_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void gcplus_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void gcplus_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
}
static void gcplus_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void gcplus_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
}
......
......@@ -19,7 +19,7 @@
#include "sa1111_generic.h"
static int graphicsmaster_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int graphicsmaster_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int return_val=0;
......@@ -36,7 +36,7 @@ static int graphicsmaster_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
}
static int
graphicsmaster_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
graphicsmaster_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned int pa_dwr_mask, pa_dwr_set;
......
......@@ -23,18 +23,18 @@ static struct pcmcia_irqs irqs[] = {
{ 1, IRQ_GPIO_H3600_PCMCIA_CD1, "PCMCIA CD1" }
};
static int h3600_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
: IRQ_GPIO_H3600_PCMCIA_IRQ0;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void h3600_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF bus: */
clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
......@@ -43,7 +43,7 @@ static void h3600_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
}
static void
h3600_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *state)
h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
unsigned long levels = GPLR;
......@@ -71,7 +71,7 @@ h3600_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state
}
static int
h3600_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
if (state->Vcc != 0 && state->Vcc != 33 && state->Vcc != 50) {
printk(KERN_ERR "h3600_pcmcia: unrecognized Vcc %u.%uV\n",
......@@ -89,7 +89,7 @@ h3600_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_sta
return 0;
}
static void h3600_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
/* Enable CF bus: */
set_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
......@@ -99,12 +99,12 @@ static void h3600_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(10*HZ / 1000);
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void h3600_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
/*
* FIXME: This doesn't fit well. We don't have the mechanism in
......
......@@ -23,7 +23,7 @@
#warning *** Does SOCKET1_3V actually do anything?
#define SOCKET1_3V GPIO_GPIO3
static int jornada720_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
/*
* What is all this crap for?
......@@ -49,7 +49,7 @@ static int jornada720_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
}
static int
jornada720_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
unsigned int pa_dwr_mask, pa_dwr_set;
int ret;
......
......@@ -42,7 +42,7 @@
*/
static int
neponset_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
int ret;
......@@ -106,7 +106,7 @@ neponset_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_
return 0;
}
static void neponset_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
if (skt->nr == 0)
NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
......
......@@ -26,7 +26,7 @@ static struct pcmcia_irqs irqs[] = {
{ PANGOLIN_SOCK, IRQ_PCMCIA_CD, "PCMCIA CD" },
};
static int pangolin_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int pangolin_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int res;
......@@ -37,12 +37,12 @@ static int pangolin_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
skt->irq = IRQ_PCMCIA_IRQ;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void pangolin_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void pangolin_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
/* Disable PCMCIA bus: */
......@@ -51,7 +51,7 @@ static void pangolin_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
}
static void
pangolin_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
pangolin_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
unsigned long levels = GPLR;
......@@ -66,7 +66,7 @@ pangolin_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
}
static int
pangolin_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
pangolin_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long value, flags;
......@@ -115,14 +115,14 @@ pangolin_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void pangolin_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void pangolin_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void pangolin_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void pangolin_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level pangolin_pcmcia_ops = {
......
......@@ -18,7 +18,7 @@
#include "sa1111_generic.h"
static int pfs168_pcmcia_init(struct sa1100_pcmcia_socket *skt)
static int pfs168_pcmcia_init(struct soc_pcmcia_socket *skt)
{
/* TPS2211 to standby mode: */
PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
......@@ -30,7 +30,7 @@ static int pfs168_pcmcia_init(struct sa1100_pcmcia_socket *skt)
}
static int
pfs168_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
pfs168_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned int pa_dwr_mask = 0, pa_dwr_set = 0;
......
......@@ -21,7 +21,7 @@ static struct pcmcia_irqs irqs[] = {
{ 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" },
};
static int shannon_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
/* All those are inputs */
GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 |
......@@ -31,16 +31,16 @@ static int shannon_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
skt->irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void shannon_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void
shannon_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
unsigned long levels = GPLR;
......@@ -69,7 +69,7 @@ shannon_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
}
static int
shannon_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
switch (state->Vcc) {
......@@ -93,14 +93,14 @@ shannon_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void shannon_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void shannon_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level shannon_pcmcia_ops = {
......
......@@ -24,19 +24,19 @@ static struct pcmcia_irqs irqs[] = {
{ 1, IRQ_GPIO_CF_CD, "CF_CD" },
};
static int simpad_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
skt->irq = IRQ_GPIO_CF_IRQ;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void simpad_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF bus: */
//set_cs3_bit(PCMCIA_BUFF_DIS);
......@@ -44,7 +44,7 @@ static void simpad_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
}
static void
simpad_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
unsigned long levels = GPLR;
......@@ -66,7 +66,7 @@ simpad_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
}
static int
simpad_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long flags;
......@@ -103,14 +103,14 @@ simpad_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void simpad_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void simpad_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
set_cs3_bit(PCMCIA_RESET);
}
......
......@@ -36,24 +36,24 @@ static struct pcmcia_irqs irqs[] = {
{ 1, IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, "PCMCIA_CD1" },
};
static int stork_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int stork_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
printk("in stork_pcmcia_init\n");
skt->irq = skt->nr ? IRQ_GPIO_STORK_PCMCIA_B_RDY
: IRQ_GPIO_STORK_PCMCIA_A_RDY;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void stork_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void stork_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
int i;
printk("%s\n", __FUNCTION__);
/* disable IRQs */
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF bus: */
storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
......@@ -62,7 +62,7 @@ static void stork_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
}
static void
stork_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
stork_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
unsigned long levels = GPLR;
......@@ -95,7 +95,7 @@ stork_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
}
static int
stork_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
stork_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long flags;
......@@ -156,16 +156,16 @@ stork_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void stork_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void stork_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void stork_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void stork_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
/*
* Hack!
......
......@@ -47,7 +47,7 @@
# define DPRINTK( x, args... ) /* nix */
#endif
static int system3_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int system3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
......@@ -55,12 +55,12 @@ static int system3_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
return 0;
}
void system3_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
void system3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
}
static void
system3_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *state)
system3_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
unsigned long status = PCSR;
......
......@@ -32,7 +32,7 @@ static struct pcmcia_irqs irqs[] = {
*
*
******************************************************/
static int trizeps_pcmcia_init(struct sa1100_pcmcia_socket *skt)
static int trizeps_pcmcia_init(struct soc_pcmcia_socket *skt)
{
skt->irq = TRIZEPS_IRQ_PCMCIA_IRQ0;
......@@ -43,18 +43,18 @@ static int trizeps_pcmcia_init(struct sa1100_pcmcia_socket *skt)
GPDR &= ~((GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0))
| (GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)));
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
/**
*
*
******************************************************/
static void trizeps_pcmcia_shutdown(struct sa1100_pcmcia_socket *skt)
static void trizeps_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
{
printk(">>>>>PCMCIA TRIZEPS shutdown\n");
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF bus: */
TRIZEPS_BCR_set(TRIZEPS_BCR1, TRIZEPS_nPCM_ENA_REG);
......@@ -64,7 +64,7 @@ static void trizeps_pcmcia_shutdown(struct sa1100_pcmcia_socket *skt)
*
******************************************************/
static void
trizeps_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state_array)
{
unsigned long levels = GPLR;
......@@ -83,7 +83,7 @@ trizeps_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
*
******************************************************/
static int
trizeps_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
trizeps_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long flags;
......@@ -129,14 +129,14 @@ trizeps_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void trizeps_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void trizeps_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void trizeps_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
/**
......
......@@ -19,7 +19,7 @@
#define NCR_A0VPP (1<<16)
#define NCR_A1VPP (1<<17)
static int xp860_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int xp860_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
......@@ -42,7 +42,7 @@ static int xp860_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
}
static int
xp860_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
xp860_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
unsigned int gpio_mask, pa_dwr_mask;
unsigned int gpio_set, pa_dwr_set;
......
......@@ -33,19 +33,19 @@ static struct pcmcia_irqs irqs[] = {
{ 0, IRQ_CF_BVD1, "CF_BVD1" },
};
static int yopy_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
static int yopy_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->irq = IRQ_CF_IREQ;
pcmcia_power(0);
pcmcia_reset(1);
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void yopy_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
static void yopy_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF */
pcmcia_reset(1);
......@@ -53,7 +53,7 @@ static void yopy_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
}
static void
yopy_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
yopy_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state_array *state)
{
unsigned long levels = GPLR;
......@@ -68,7 +68,7 @@ yopy_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
}
static int
yopy_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
yopy_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
switch (state->Vcc) {
......@@ -93,14 +93,14 @@ yopy_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
return 0;
}
static void yopy_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
static void yopy_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void yopy_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
static void yopy_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level yopy_pcmcia_ops = {
......
......@@ -29,20 +29,20 @@ static struct pcmcia_irqs irqs[] = {
{ 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" },
};
int sa1111_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
if (skt->irq == NO_IRQ)
skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
void sa1111_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
void sa1111_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_state *state)
void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
{
struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR);
......@@ -70,7 +70,7 @@ void sa1111_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt, struct pcmcia_
}
}
int sa1111_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socket_state_t *state)
int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
{
struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
unsigned int pccr_skt_mask, pccr_set_mask, val;
......@@ -110,14 +110,14 @@ int sa1111_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt, const socke
return 0;
}
void sa1111_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
void sa1111_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static int pcmcia_probe(struct sa1111_dev *dev)
......@@ -148,6 +148,9 @@ static int pcmcia_probe(struct sa1111_dev *dev)
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_init(&dev->dev);
#endif
#ifdef CONFIG_ARCH_LUBBOCK
pcmcia_lubbock_init(&dev->dev);
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_init(dev);
#endif
......@@ -165,7 +168,7 @@ static int pcmcia_probe(struct sa1111_dev *dev)
static int __devexit pcmcia_remove(struct sa1111_dev *dev)
{
sa11xx_drv_pcmcia_remove(&dev->dev);
soc_common_drv_pcmcia_remove(&dev->dev);
release_mem_region(dev->res.start, 512);
return 0;
}
......
#include "sa11xx_core.h"
#include "soc_common.h"
#include "sa11xx_base.h"
extern int sa1111_pcmcia_hw_init(struct sa1100_pcmcia_socket *);
extern void sa1111_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *);
extern void sa1111_pcmcia_socket_state(struct sa1100_pcmcia_socket *, struct pcmcia_state *);
extern int sa1111_pcmcia_configure_socket(struct sa1100_pcmcia_socket *, const socket_state_t *);
extern void sa1111_pcmcia_socket_init(struct sa1100_pcmcia_socket *);
extern void sa1111_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *);
extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *);
extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *);
extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
extern void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *);
extern int pcmcia_badge4_init(struct device *);
extern int pcmcia_jornada720_init(struct device *);
extern int pcmcia_lubbock_init(struct device *);
extern int pcmcia_neponset_init(struct sa1111_dev *);
/*======================================================================
Device driver for the PCMCIA control functionality of StrongARM
SA-1100 microprocessors.
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The initial developer of the original code is John G. Dorsey
<john+@cs.cmu.edu>. Portions created by John G. Dorsey are
Copyright (C) 1999 John G. Dorsey. All Rights Reserved.
Alternatively, the contents of this file may be used under the
terms of the GNU Public License version 2 (the "GPL"), in which
case the provisions of the GPL are applicable instead of the
above. If you wish to allow the use of your version of this file
only under the terms of the GPL and not to allow others to use
your version of this file under the MPL, indicate your decision
by deleting the provisions above and replace them with the notice
and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this
file under either the MPL or the GPL.
======================================================================*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/config.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include "soc_common.h"
#include "sa11xx_base.h"
/*
* sa1100_pcmcia_default_mecr_timing
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
* Calculate MECR clock wait states for given CPU clock
* speed and command wait state. This function can be over-
* written by a board specific version.
*
* The default is to simply calculate the BS values as specified in
* the INTEL SA1100 development manual
* "Expansion Memory (PCMCIA) Configuration Register (MECR)"
* that's section 10.2.5 in _my_ version of the manual ;)
*/
static unsigned int
sa1100_pcmcia_default_mecr_timing(struct soc_pcmcia_socket *skt,
unsigned int cpu_speed,
unsigned int cmd_time)
{
return sa1100_pcmcia_mecr_bs(cmd_time, cpu_speed);
}
static unsigned short
calc_speed(unsigned short *spds, int num, unsigned short dflt)
{
unsigned short speed = 0;
int i;
for (i = 0; i < num; i++)
if (speed < spds[i])
speed = spds[i];
if (speed == 0)
speed = dflt;
return speed;
}
/* sa1100_pcmcia_set_mecr()
* ^^^^^^^^^^^^^^^^^^^^^^^^
*
* set MECR value for socket <sock> based on this sockets
* io, mem and attribute space access speed.
* Call board specific BS value calculation to allow boards
* to tweak the BS values.
*/
static int
sa1100_pcmcia_set_mecr(struct soc_pcmcia_socket *skt, unsigned int cpu_clock)
{
u32 mecr, old_mecr;
unsigned long flags;
unsigned short speed;
unsigned int bs_io, bs_mem, bs_attr;
speed = calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
bs_io = skt->ops->get_timing(skt, cpu_clock, speed);
speed = calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
bs_mem = skt->ops->get_timing(skt, cpu_clock, speed);
speed = calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
bs_attr = skt->ops->get_timing(skt, cpu_clock, speed);
local_irq_save(flags);
old_mecr = mecr = MECR;
MECR_FAST_SET(mecr, skt->nr, 0);
MECR_BSIO_SET(mecr, skt->nr, bs_io);
MECR_BSA_SET(mecr, skt->nr, bs_attr);
MECR_BSM_SET(mecr, skt->nr, bs_mem);
if (old_mecr != mecr)
MECR = mecr;
local_irq_restore(flags);
debug(skt, 2, "FAST %X BSM %X BSA %X BSIO %X\n",
MECR_FAST_GET(mecr, skt->nr),
MECR_BSM_GET(mecr, skt->nr), MECR_BSA_GET(mecr, skt->nr),
MECR_BSIO_GET(mecr, skt->nr));
return 0;
}
static int
sa1100_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
{
return sa1100_pcmcia_set_mecr(skt, cpufreq_get(0));
}
static int
sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
{
unsigned int clock = cpufreq_get(0);
unsigned long mecr = MECR;
char *p = buf;
p+=sprintf(p, "I/O : %u (%u)\n",
calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS),
sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr)));
p+=sprintf(p, "attribute: %u (%u)\n",
calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS),
sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr)));
p+=sprintf(p, "common : %u (%u)\n",
calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS),
sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr)));
return p - buf;
}
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
int first, int nr)
{
/*
* set default MECR calculation if the board specific
* code did not specify one...
*/
if (!ops->get_timing)
ops->get_timing = sa1100_pcmcia_default_mecr_timing;
/* Provide our SA11x0 specific timing routines. */
ops->set_timing = sa1100_pcmcia_set_timing;
ops->show_timing = sa1100_pcmcia_show_timing;
return soc_common_drv_pcmcia_probe(dev, ops, first, nr);
}
EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
#ifdef CONFIG_CPU_FREQ
/* sa1100_pcmcia_update_mecr()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^
* When sa1100_pcmcia_notifier() decides that a MECR adjustment (due
* to a core clock frequency change) is needed, this routine establishes
* new BS_xx values consistent with the clock speed `clock'.
*/
static void sa1100_pcmcia_update_mecr(unsigned int clock)
{
struct soc_pcmcia_socket *skt;
down(&soc_pcmcia_sockets_lock);
list_for_each_entry(skt, &soc_pcmcia_sockets, node)
sa1100_pcmcia_set_mecr(skt, clock);
up(&soc_pcmcia_sockets_lock);
}
/* sa1100_pcmcia_notifier()
* ^^^^^^^^^^^^^^^^^^^^^^^^
* When changing the processor core clock frequency, it is necessary
* to adjust the MECR timings accordingly. We've recorded the timings
* requested by Card Services, so this is just a matter of finding
* out what our current speed is, and then recomputing the new MECR
* values.
*
* Returns: 0 on success, -1 on error
*/
static int
sa1100_pcmcia_notifier(struct notifier_block *nb, unsigned long val,
void *data)
{
struct cpufreq_freqs *freqs = data;
switch (val) {
case CPUFREQ_PRECHANGE:
if (freqs->new > freqs->old)
sa1100_pcmcia_update_mecr(freqs->new);
break;
case CPUFREQ_POSTCHANGE:
if (freqs->new < freqs->old)
sa1100_pcmcia_update_mecr(freqs->new);
break;
}
return 0;
}
static struct notifier_block sa1100_pcmcia_notifier_block = {
.notifier_call = sa1100_pcmcia_notifier
};
static int __init sa11xx_pcmcia_init(void)
{
int ret;
printk(KERN_INFO "SA11xx PCMCIA\n");
ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
if (ret < 0)
printk(KERN_ERR "Unable to register CPU frequency change "
"notifier (%d)\n", ret);
return ret;
}
module_init(sa11xx_pcmcia_init);
static void __exit sa11xx_pcmcia_exit(void)
{
cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
}
module_exit(sa11xx_pcmcia_exit);
#endif
MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11xx core socket driver");
MODULE_LICENSE("Dual MPL/GPL");
......@@ -27,23 +27,27 @@
and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this
file under either the MPL or the GPL.
======================================================================*/
#if !defined(_PCMCIA_SA1100_H)
# define _PCMCIA_SA1100_H
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
#include "sa1100_generic.h"
/* SA-1100 PCMCIA Memory and I/O timing
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* The SA-1110 Developer's Manual, section 10.2.5, says the following:
*
* "To calculate the recommended BS_xx value for each address space:
* divide the command width time (the greater of twIOWR and twIORD,
* or the greater of twWE and twOE) by processor cycle time; divide
* by 2; divide again by 3 (number of BCLK's per command assertion);
* round up to the next whole number; and subtract 1."
*/
/* MECR: Expansion Memory Configuration Register
* (SA-1100 Developers Manual, p.10-13; SA-1110 Developers Manual, p.10-24)
*
* MECR layout is:
* MECR layout is:
*
* FAST1 BSM1<4:0> BSA1<4:0> BSIO1<4:0> FAST0 BSM0<4:0> BSA0<4:0> BSIO0<4:0>
*
......@@ -105,7 +109,7 @@ static inline unsigned int sa1100_pcmcia_mecr_bs(unsigned int pcmcia_cycle_ns,
return (t / 1000000) + (((t % 1000000) == 0) ? 0 : 1);
}
/* This function returns the (approxmiate) command assertion period, in
/* This function returns the (approximate) command assertion period, in
* nanoseconds, for a given CPU clock frequency and MECR BS value:
*/
static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
......@@ -114,51 +118,6 @@ static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
}
/* SA-1100 PCMCIA Memory and I/O timing
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* The SA-1110 Developer's Manual, section 10.2.5, says the following:
*
* "To calculate the recommended BS_xx value for each address space:
* divide the command width time (the greater of twIOWR and twIORD,
* or the greater of twWE and twOE) by processor cycle time; divide
* by 2; divide again by 3 (number of BCLK's per command assertion);
* round up to the next whole number; and subtract 1."
*
* The PC Card Standard, Release 7, section 4.13.4, says that twIORD
* has a minimum value of 165ns. Section 4.13.5 says that twIOWR has
* a minimum value of 165ns, as well. Section 4.7.2 (describing
* common and attribute memory write timing) says that twWE has a
* minimum value of 150ns for a 250ns cycle time (for 5V operation;
* see section 4.7.4), or 300ns for a 600ns cycle time (for 3.3V
* operation, also section 4.7.4). Section 4.7.3 says that taOE
* has a maximum value of 150ns for a 300ns cycle time (for 5V
* operation), or 300ns for a 600ns cycle time (for 3.3V operation).
*
* When configuring memory maps, Card Services appears to adopt the policy
* that a memory access time of "0" means "use the default." The default
* PCMCIA I/O command width time is 165ns. The default PCMCIA 5V attribute
* and memory command width time is 150ns; the PCMCIA 3.3V attribute and
* memory command width time is 300ns.
*/
#define SA1100_PCMCIA_IO_ACCESS (165)
#define SA1100_PCMCIA_5V_MEM_ACCESS (150)
#define SA1100_PCMCIA_3V_MEM_ACCESS (300)
/* The socket driver actually works nicely in interrupt-driven form,
* so the (relatively infrequent) polling is "just to be sure."
*/
#define SA1100_PCMCIA_POLL_PERIOD (2*HZ)
struct pcmcia_low_level;
/* I/O pins replacing memory pins
* (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
*
* These signals change meaning when going from memory-only to
* memory-or-I/O interface:
*/
#define iostschg bvd1
#define iospkr bvd2
extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
#endif /* !defined(_PCMCIA_SA1100_H) */
/*
* linux/include/asm/arch/pcmcia.h
* linux/drivers/pcmcia/soc_common.h
*
* Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
*
* This file contains definitions for the low-level SA-1100 kernel PCMCIA
* interface. Please see linux/Documentation/arm/SA1100/PCMCIA for details.
* This file contains definitions for the PCMCIA support code common to
* integrated SOCs like the SA-11x0 and PXA2xx microprocessors.
*/
#ifndef _ASM_ARCH_PCMCIA
#define _ASM_ARCH_PCMCIA
......@@ -18,31 +18,15 @@
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
struct device;
/* Ideally, we'd support up to MAX_SOCK sockets, but the SA-1100 only
* has support for two. This shows up in lots of hardwired ways, such
* as the fact that MECR only has enough bits to configure two sockets.
* Since it's so entrenched in the hardware, limiting the software
* in this way doesn't seem too terrible.
*/
#define SA1100_PCMCIA_MAX_SOCK (2)
struct pcmcia_state {
unsigned detect: 1,
ready: 1,
bvd1: 1,
bvd2: 1,
wrprot: 1,
vs_3v: 1,
vs_Xv: 1;
};
struct device;
struct pcmcia_low_level;
/*
* This structure encapsulates per-socket state which we might need to
* use when responding to a Card Services query of some kind.
*/
struct sa1100_pcmcia_socket {
struct soc_pcmcia_socket {
struct pcmcia_socket socket;
/*
......@@ -76,46 +60,120 @@ struct sa1100_pcmcia_socket {
struct list_head node;
};
struct pcmcia_state {
unsigned detect: 1,
ready: 1,
bvd1: 1,
bvd2: 1,
wrprot: 1,
vs_3v: 1,
vs_Xv: 1;
};
struct pcmcia_low_level {
struct module *owner;
int (*hw_init)(struct sa1100_pcmcia_socket *);
void (*hw_shutdown)(struct sa1100_pcmcia_socket *);
/* first socket in system */
int first;
/* nr of sockets */
int nr;
void (*socket_state)(struct sa1100_pcmcia_socket *, struct pcmcia_state *);
int (*configure_socket)(struct sa1100_pcmcia_socket *, const socket_state_t *);
int (*hw_init)(struct soc_pcmcia_socket *);
void (*hw_shutdown)(struct soc_pcmcia_socket *);
void (*socket_state)(struct soc_pcmcia_socket *, struct pcmcia_state *);
int (*configure_socket)(struct soc_pcmcia_socket *, const socket_state_t *);
/*
* Enable card status IRQs on (re-)initialisation. This can
* be called at initialisation, power management event, or
* pcmcia event.
*/
void (*socket_init)(struct sa1100_pcmcia_socket *);
void (*socket_init)(struct soc_pcmcia_socket *);
/*
* Disable card status IRQs and PCMCIA bus on suspend.
*/
void (*socket_suspend)(struct sa1100_pcmcia_socket *);
void (*socket_suspend)(struct soc_pcmcia_socket *);
/*
* Calculate MECR timing clock wait states
* Hardware specific timing routines.
* If provided, the get_timing routine overrides the SOC default.
*/
unsigned int (*socket_get_timing)(struct sa1100_pcmcia_socket *,
unsigned int cpu_speed, unsigned int cmd_time);
unsigned int (*get_timing)(struct soc_pcmcia_socket *, unsigned int, unsigned int);
int (*set_timing)(struct soc_pcmcia_socket *);
int (*show_timing)(struct soc_pcmcia_socket *, char *);
};
struct pcmcia_irqs {
int sock;
int irq;
const char *str;
};
int sa11xx_request_irqs(struct sa1100_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
void sa11xx_free_irqs(struct sa1100_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
void sa11xx_disable_irqs(struct sa1100_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
void sa11xx_enable_irqs(struct sa1100_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
extern struct list_head soc_pcmcia_sockets;
extern struct semaphore soc_pcmcia_sockets_lock;
extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
extern int soc_common_drv_pcmcia_remove(struct device *dev);
#ifdef DEBUG
extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
int lvl, const char *fmt, ...);
#define debug(skt, lvl, fmt, arg...) \
soc_pcmcia_debug(skt, __func__, lvl, fmt , ## arg)
#else
#define debug(skt, lvl, fmt, arg...) do { } while (0)
#endif
/*
* The PC Card Standard, Release 7, section 4.13.4, says that twIORD
* has a minimum value of 165ns. Section 4.13.5 says that twIOWR has
* a minimum value of 165ns, as well. Section 4.7.2 (describing
* common and attribute memory write timing) says that twWE has a
* minimum value of 150ns for a 250ns cycle time (for 5V operation;
* see section 4.7.4), or 300ns for a 600ns cycle time (for 3.3V
* operation, also section 4.7.4). Section 4.7.3 says that taOE
* has a maximum value of 150ns for a 300ns cycle time (for 5V
* operation), or 300ns for a 600ns cycle time (for 3.3V operation).
*
* When configuring memory maps, Card Services appears to adopt the policy
* that a memory access time of "0" means "use the default." The default
* PCMCIA I/O command width time is 165ns. The default PCMCIA 5V attribute
* and memory command width time is 150ns; the PCMCIA 3.3V attribute and
* memory command width time is 300ns.
*/
#define SOC_PCMCIA_IO_ACCESS (165)
#define SOC_PCMCIA_5V_MEM_ACCESS (150)
#define SOC_PCMCIA_3V_MEM_ACCESS (300)
#define SOC_PCMCIA_ATTR_MEM_ACCESS (300)
extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
extern int sa11xx_drv_pcmcia_remove(struct device *dev);
/*
* The socket driver actually works nicely in interrupt-driven form,
* so the (relatively infrequent) polling is "just to be sure."
*/
#define SOC_PCMCIA_POLL_PERIOD (2*HZ)
/* I/O pins replacing memory pins
* (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
*
* These signals change meaning when going from memory-only to
* memory-or-I/O interface:
*/
#define iostschg bvd1
#define iospkr bvd2
#endif
......@@ -1336,6 +1336,19 @@ typedef void (*ExcpHndlr) (void) ;
#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
/*
* More handy macros for PCMCIA
*
* Arg is socket number
*/
#define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */
#define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */
#define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */
/* MECR register defines */
#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */
#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
......
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