diff options
Diffstat (limited to 'drivers/pcmcia/sa11xx_base.c')
| -rw-r--r-- | drivers/pcmcia/sa11xx_base.c | 103 |
1 files changed, 62 insertions, 41 deletions
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index e15d59f2d8a..54d3089d157 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -37,10 +37,10 @@ #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/io.h> +#include <linux/slab.h> #include <mach/hardware.h> #include <asm/irq.h> -#include <asm/system.h> #include "soc_common.h" #include "sa11xx_base.h" @@ -125,9 +125,6 @@ sa1100_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, if (freqs->new < freqs->old) sa1100_pcmcia_set_mecr(skt, freqs->new); break; - case CPUFREQ_RESUMECHANGE: - sa1100_pcmcia_set_mecr(skt, freqs->new); - break; } return 0; @@ -171,12 +168,58 @@ static const char *skt_names[] = { #define SKT_DEV_INFO_SIZE(n) \ (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) +int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt) +{ + skt->res_skt.start = _PCMCIA(skt->nr); + skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; + skt->res_skt.name = skt_names[skt->nr]; + skt->res_skt.flags = IORESOURCE_MEM; + + skt->res_io.start = _PCMCIAIO(skt->nr); + skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1; + skt->res_io.name = "io"; + skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + skt->res_mem.start = _PCMCIAMem(skt->nr); + skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; + skt->res_mem.name = "memory"; + skt->res_mem.flags = IORESOURCE_MEM; + + skt->res_attr.start = _PCMCIAAttr(skt->nr); + skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1; + skt->res_attr.name = "attribute"; + skt->res_attr.flags = IORESOURCE_MEM; + + return soc_pcmcia_add_one(skt); +} +EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one); + +void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops) +{ + /* + * 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; +#ifdef CONFIG_CPU_FREQ + ops->frequency_change = sa1100_pcmcia_frequency_change; +#endif +} +EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops); + int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) { struct skt_dev_info *sinfo; struct soc_pcmcia_socket *skt; - int i; + int i, ret = 0; + + sa11xx_drv_pcmcia_ops(ops); sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); if (!sinfo) @@ -184,49 +227,27 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, sinfo->nskt = nr; - /* Initiliaze processor specific parameters */ + /* Initialize processor specific parameters */ for (i = 0; i < nr; i++) { skt = &sinfo->skt[i]; - skt->nr = first + i; - skt->irq = NO_IRQ; - - skt->res_skt.start = _PCMCIA(skt->nr); - skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; - skt->res_skt.name = skt_names[skt->nr]; - skt->res_skt.flags = IORESOURCE_MEM; - - skt->res_io.start = _PCMCIAIO(skt->nr); - skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1; - skt->res_io.name = "io"; - skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; - - skt->res_mem.start = _PCMCIAMem(skt->nr); - skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; - skt->res_mem.name = "memory"; - skt->res_mem.flags = IORESOURCE_MEM; + skt->nr = first + i; + soc_pcmcia_init_one(skt, ops, dev); - skt->res_attr.start = _PCMCIAAttr(skt->nr); - skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1; - skt->res_attr.name = "attribute"; - skt->res_attr.flags = IORESOURCE_MEM; + ret = sa11xx_drv_pcmcia_add_one(skt); + if (ret) + break; } - /* - * 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; -#ifdef CONFIG_CPU_FREQ - ops->frequency_change = sa1100_pcmcia_frequency_change; -#endif + if (ret) { + while (--i >= 0) + soc_pcmcia_remove_one(&sinfo->skt[i]); + kfree(sinfo); + } else { + dev_set_drvdata(dev, sinfo); + } - return soc_common_drv_pcmcia_probe(dev, ops, sinfo); + return ret; } EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe); |
