This source file includes following definitions.
- sa1100_pcmcia_default_mecr_timing
- sa1100_pcmcia_set_mecr
- sa1100_pcmcia_frequency_change
- sa1100_pcmcia_set_timing
- sa1100_pcmcia_show_timing
- sa11xx_drv_pcmcia_ops
- sa11xx_drv_pcmcia_probe
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 #include <linux/module.h>
  34 #include <linux/init.h>
  35 #include <linux/cpufreq.h>
  36 #include <linux/ioport.h>
  37 #include <linux/kernel.h>
  38 #include <linux/spinlock.h>
  39 #include <linux/io.h>
  40 #include <linux/slab.h>
  41 
  42 #include <mach/hardware.h>
  43 #include <asm/irq.h>
  44 
  45 #include "soc_common.h"
  46 #include "sa11xx_base.h"
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 
  62 static unsigned int
  63 sa1100_pcmcia_default_mecr_timing(struct soc_pcmcia_socket *skt,
  64                                   unsigned int cpu_speed,
  65                                   unsigned int cmd_time)
  66 {
  67         return sa1100_pcmcia_mecr_bs(cmd_time, cpu_speed);
  68 }
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77 
  78 static int
  79 sa1100_pcmcia_set_mecr(struct soc_pcmcia_socket *skt, unsigned int cpu_clock)
  80 {
  81         struct soc_pcmcia_timing timing;
  82         u32 mecr, old_mecr;
  83         unsigned long flags;
  84         unsigned int bs_io, bs_mem, bs_attr;
  85 
  86         soc_common_pcmcia_get_timing(skt, &timing);
  87 
  88         bs_io = skt->ops->get_timing(skt, cpu_clock, timing.io);
  89         bs_mem = skt->ops->get_timing(skt, cpu_clock, timing.mem);
  90         bs_attr = skt->ops->get_timing(skt, cpu_clock, timing.attr);
  91 
  92         local_irq_save(flags);
  93 
  94         old_mecr = mecr = MECR;
  95         MECR_FAST_SET(mecr, skt->nr, 0);
  96         MECR_BSIO_SET(mecr, skt->nr, bs_io);
  97         MECR_BSA_SET(mecr, skt->nr, bs_attr);
  98         MECR_BSM_SET(mecr, skt->nr, bs_mem);
  99         if (old_mecr != mecr)
 100                 MECR = mecr;
 101 
 102         local_irq_restore(flags);
 103 
 104         debug(skt, 2, "FAST %X  BSM %X  BSA %X  BSIO %X\n",
 105               MECR_FAST_GET(mecr, skt->nr),
 106               MECR_BSM_GET(mecr, skt->nr), MECR_BSA_GET(mecr, skt->nr),
 107               MECR_BSIO_GET(mecr, skt->nr));
 108 
 109         return 0;
 110 }
 111 
 112 #ifdef CONFIG_CPU_FREQ
 113 static int
 114 sa1100_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
 115                                unsigned long val,
 116                                struct cpufreq_freqs *freqs)
 117 {
 118         switch (val) {
 119         case CPUFREQ_PRECHANGE:
 120                 if (freqs->new > freqs->old)
 121                         sa1100_pcmcia_set_mecr(skt, freqs->new);
 122                 break;
 123 
 124         case CPUFREQ_POSTCHANGE:
 125                 if (freqs->new < freqs->old)
 126                         sa1100_pcmcia_set_mecr(skt, freqs->new);
 127                 break;
 128         }
 129 
 130         return 0;
 131 }
 132 
 133 #endif
 134 
 135 static int
 136 sa1100_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
 137 {
 138         unsigned long clk = clk_get_rate(skt->clk);
 139 
 140         return sa1100_pcmcia_set_mecr(skt, clk / 1000);
 141 }
 142 
 143 static int
 144 sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
 145 {
 146         struct soc_pcmcia_timing timing;
 147         unsigned int clock = clk_get_rate(skt->clk) / 1000;
 148         unsigned long mecr = MECR;
 149         char *p = buf;
 150 
 151         soc_common_pcmcia_get_timing(skt, &timing);
 152 
 153         p+=sprintf(p, "I/O      : %uns (%uns)\n", timing.io,
 154                    sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr)));
 155 
 156         p+=sprintf(p, "attribute: %uns (%uns)\n", timing.attr,
 157                    sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr)));
 158 
 159         p+=sprintf(p, "common   : %uns (%uns)\n", timing.mem,
 160                    sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr)));
 161 
 162         return p - buf;
 163 }
 164 
 165 static const char *skt_names[] = {
 166         "PCMCIA socket 0",
 167         "PCMCIA socket 1",
 168 };
 169 
 170 #define SKT_DEV_INFO_SIZE(n) \
 171         (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
 172 
 173 int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 174 {
 175         skt->res_skt.start = _PCMCIA(skt->nr);
 176         skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
 177         skt->res_skt.name = skt_names[skt->nr];
 178         skt->res_skt.flags = IORESOURCE_MEM;
 179 
 180         skt->res_io.start = _PCMCIAIO(skt->nr);
 181         skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
 182         skt->res_io.name = "io";
 183         skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 184 
 185         skt->res_mem.start = _PCMCIAMem(skt->nr);
 186         skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
 187         skt->res_mem.name = "memory";
 188         skt->res_mem.flags = IORESOURCE_MEM;
 189 
 190         skt->res_attr.start = _PCMCIAAttr(skt->nr);
 191         skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
 192         skt->res_attr.name = "attribute";
 193         skt->res_attr.flags = IORESOURCE_MEM;
 194 
 195         return soc_pcmcia_add_one(skt);
 196 }
 197 EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one);
 198 
 199 void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
 200 {
 201         
 202 
 203 
 204 
 205         if (!ops->get_timing)
 206                 ops->get_timing = sa1100_pcmcia_default_mecr_timing;
 207 
 208         
 209         ops->set_timing  = sa1100_pcmcia_set_timing;
 210         ops->show_timing = sa1100_pcmcia_show_timing;
 211 #ifdef CONFIG_CPU_FREQ
 212         ops->frequency_change = sa1100_pcmcia_frequency_change;
 213 #endif
 214 }
 215 EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops);
 216 
 217 int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
 218                             int first, int nr)
 219 {
 220         struct skt_dev_info *sinfo;
 221         struct soc_pcmcia_socket *skt;
 222         int i, ret = 0;
 223         struct clk *clk;
 224 
 225         clk = devm_clk_get(dev, NULL);
 226         if (IS_ERR(clk))
 227                 return PTR_ERR(clk);
 228 
 229         sa11xx_drv_pcmcia_ops(ops);
 230 
 231         sinfo = devm_kzalloc(dev, SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
 232         if (!sinfo)
 233                 return -ENOMEM;
 234 
 235         sinfo->nskt = nr;
 236 
 237         
 238         for (i = 0; i < nr; i++) {
 239                 skt = &sinfo->skt[i];
 240 
 241                 skt->nr = first + i;
 242                 skt->clk = clk;
 243                 soc_pcmcia_init_one(skt, ops, dev);
 244 
 245                 ret = sa11xx_drv_pcmcia_add_one(skt);
 246                 if (ret)
 247                         break;
 248         }
 249 
 250         if (ret) {
 251                 while (--i >= 0)
 252                         soc_pcmcia_remove_one(&sinfo->skt[i]);
 253         } else {
 254                 dev_set_drvdata(dev, sinfo);
 255         }
 256 
 257         return ret;
 258 }
 259 EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
 260 
 261 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
 262 MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11xx core socket driver");
 263 MODULE_LICENSE("Dual MPL/GPL");