This source file includes following definitions.
- dbg_dumpregs
- prepare_dbgmsg
- dbg_dumpcmd
- dbg_dumpcmd
- prepare_dbgmsg
- dbg_dumpregs
- s3cmci_host_usedma
- enable_imask
- disable_imask
- clear_imask
- s3cmci_check_sdio_irq
- get_data_buffer
- fifo_count
- fifo_free
- s3cmci_enable_irq
- s3cmci_disable_irq
- do_pio_read
- do_pio_write
- pio_tasklet
- s3cmci_irq
- s3cmci_dma_done_callback
- finalize_request
- s3cmci_send_command
- s3cmci_setup_data
- s3cmci_prepare_pio
- s3cmci_prepare_dma
- s3cmci_send_request
- s3cmci_request
- s3cmci_set_clk
- s3cmci_set_ios
- s3cmci_reset
- s3cmci_enable_sdio_irq
- s3cmci_cpufreq_transition
- s3cmci_cpufreq_register
- s3cmci_cpufreq_deregister
- s3cmci_cpufreq_register
- s3cmci_cpufreq_deregister
- s3cmci_state_show
- s3cmci_regs_show
- s3cmci_debugfs_attach
- s3cmci_debugfs_remove
- s3cmci_debugfs_attach
- s3cmci_debugfs_remove
- s3cmci_probe_pdata
- s3cmci_probe_dt
- s3cmci_probe
- s3cmci_shutdown
- s3cmci_remove
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 #include <linux/module.h>
  12 #include <linux/dmaengine.h>
  13 #include <linux/dma-mapping.h>
  14 #include <linux/clk.h>
  15 #include <linux/mmc/host.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/cpufreq.h>
  18 #include <linux/debugfs.h>
  19 #include <linux/seq_file.h>
  20 #include <linux/gpio.h>
  21 #include <linux/interrupt.h>
  22 #include <linux/irq.h>
  23 #include <linux/io.h>
  24 #include <linux/of.h>
  25 #include <linux/of_device.h>
  26 #include <linux/mmc/slot-gpio.h>
  27 
  28 #include <plat/gpio-cfg.h>
  29 #include <mach/dma.h>
  30 #include <mach/gpio-samsung.h>
  31 
  32 #include <linux/platform_data/mmc-s3cmci.h>
  33 
  34 #include "s3cmci.h"
  35 
  36 #define DRIVER_NAME "s3c-mci"
  37 
  38 #define S3C2410_SDICON                  (0x00)
  39 #define S3C2410_SDIPRE                  (0x04)
  40 #define S3C2410_SDICMDARG               (0x08)
  41 #define S3C2410_SDICMDCON               (0x0C)
  42 #define S3C2410_SDICMDSTAT              (0x10)
  43 #define S3C2410_SDIRSP0                 (0x14)
  44 #define S3C2410_SDIRSP1                 (0x18)
  45 #define S3C2410_SDIRSP2                 (0x1C)
  46 #define S3C2410_SDIRSP3                 (0x20)
  47 #define S3C2410_SDITIMER                (0x24)
  48 #define S3C2410_SDIBSIZE                (0x28)
  49 #define S3C2410_SDIDCON                 (0x2C)
  50 #define S3C2410_SDIDCNT                 (0x30)
  51 #define S3C2410_SDIDSTA                 (0x34)
  52 #define S3C2410_SDIFSTA                 (0x38)
  53 
  54 #define S3C2410_SDIDATA                 (0x3C)
  55 #define S3C2410_SDIIMSK                 (0x40)
  56 
  57 #define S3C2440_SDIDATA                 (0x40)
  58 #define S3C2440_SDIIMSK                 (0x3C)
  59 
  60 #define S3C2440_SDICON_SDRESET          (1 << 8)
  61 #define S3C2410_SDICON_SDIOIRQ          (1 << 3)
  62 #define S3C2410_SDICON_FIFORESET        (1 << 1)
  63 #define S3C2410_SDICON_CLOCKTYPE        (1 << 0)
  64 
  65 #define S3C2410_SDICMDCON_LONGRSP       (1 << 10)
  66 #define S3C2410_SDICMDCON_WAITRSP       (1 << 9)
  67 #define S3C2410_SDICMDCON_CMDSTART      (1 << 8)
  68 #define S3C2410_SDICMDCON_SENDERHOST    (1 << 6)
  69 #define S3C2410_SDICMDCON_INDEX         (0x3f)
  70 
  71 #define S3C2410_SDICMDSTAT_CRCFAIL      (1 << 12)
  72 #define S3C2410_SDICMDSTAT_CMDSENT      (1 << 11)
  73 #define S3C2410_SDICMDSTAT_CMDTIMEOUT   (1 << 10)
  74 #define S3C2410_SDICMDSTAT_RSPFIN       (1 << 9)
  75 
  76 #define S3C2440_SDIDCON_DS_WORD         (2 << 22)
  77 #define S3C2410_SDIDCON_TXAFTERRESP     (1 << 20)
  78 #define S3C2410_SDIDCON_RXAFTERCMD      (1 << 19)
  79 #define S3C2410_SDIDCON_BLOCKMODE       (1 << 17)
  80 #define S3C2410_SDIDCON_WIDEBUS         (1 << 16)
  81 #define S3C2410_SDIDCON_DMAEN           (1 << 15)
  82 #define S3C2410_SDIDCON_STOP            (1 << 14)
  83 #define S3C2440_SDIDCON_DATSTART        (1 << 14)
  84 
  85 #define S3C2410_SDIDCON_XFER_RXSTART    (2 << 12)
  86 #define S3C2410_SDIDCON_XFER_TXSTART    (3 << 12)
  87 
  88 #define S3C2410_SDIDCON_BLKNUM_MASK     (0xFFF)
  89 
  90 #define S3C2410_SDIDSTA_SDIOIRQDETECT   (1 << 9)
  91 #define S3C2410_SDIDSTA_FIFOFAIL        (1 << 8)
  92 #define S3C2410_SDIDSTA_CRCFAIL         (1 << 7)
  93 #define S3C2410_SDIDSTA_RXCRCFAIL       (1 << 6)
  94 #define S3C2410_SDIDSTA_DATATIMEOUT     (1 << 5)
  95 #define S3C2410_SDIDSTA_XFERFINISH      (1 << 4)
  96 #define S3C2410_SDIDSTA_TXDATAON        (1 << 1)
  97 #define S3C2410_SDIDSTA_RXDATAON        (1 << 0)
  98 
  99 #define S3C2440_SDIFSTA_FIFORESET       (1 << 16)
 100 #define S3C2440_SDIFSTA_FIFOFAIL        (3 << 14)
 101 #define S3C2410_SDIFSTA_TFDET           (1 << 13)
 102 #define S3C2410_SDIFSTA_RFDET           (1 << 12)
 103 #define S3C2410_SDIFSTA_COUNTMASK       (0x7f)
 104 
 105 #define S3C2410_SDIIMSK_RESPONSECRC     (1 << 17)
 106 #define S3C2410_SDIIMSK_CMDSENT         (1 << 16)
 107 #define S3C2410_SDIIMSK_CMDTIMEOUT      (1 << 15)
 108 #define S3C2410_SDIIMSK_RESPONSEND      (1 << 14)
 109 #define S3C2410_SDIIMSK_SDIOIRQ         (1 << 12)
 110 #define S3C2410_SDIIMSK_FIFOFAIL        (1 << 11)
 111 #define S3C2410_SDIIMSK_CRCSTATUS       (1 << 10)
 112 #define S3C2410_SDIIMSK_DATACRC         (1 << 9)
 113 #define S3C2410_SDIIMSK_DATATIMEOUT     (1 << 8)
 114 #define S3C2410_SDIIMSK_DATAFINISH      (1 << 7)
 115 #define S3C2410_SDIIMSK_TXFIFOHALF      (1 << 4)
 116 #define S3C2410_SDIIMSK_RXFIFOLAST      (1 << 2)
 117 #define S3C2410_SDIIMSK_RXFIFOHALF      (1 << 0)
 118 
 119 enum dbg_channels {
 120         dbg_err   = (1 << 0),
 121         dbg_debug = (1 << 1),
 122         dbg_info  = (1 << 2),
 123         dbg_irq   = (1 << 3),
 124         dbg_sg    = (1 << 4),
 125         dbg_dma   = (1 << 5),
 126         dbg_pio   = (1 << 6),
 127         dbg_fail  = (1 << 7),
 128         dbg_conf  = (1 << 8),
 129 };
 130 
 131 static const int dbgmap_err   = dbg_fail;
 132 static const int dbgmap_info  = dbg_info | dbg_conf;
 133 static const int dbgmap_debug = dbg_err | dbg_debug;
 134 
 135 #define dbg(host, channels, args...)              \
 136         do {                                      \
 137         if (dbgmap_err & channels)                \
 138                 dev_err(&host->pdev->dev, args);  \
 139         else if (dbgmap_info & channels)          \
 140                 dev_info(&host->pdev->dev, args); \
 141         else if (dbgmap_debug & channels)         \
 142                 dev_dbg(&host->pdev->dev, args);  \
 143         } while (0)
 144 
 145 static void finalize_request(struct s3cmci_host *host);
 146 static void s3cmci_send_request(struct mmc_host *mmc);
 147 static void s3cmci_reset(struct s3cmci_host *host);
 148 
 149 #ifdef CONFIG_MMC_DEBUG
 150 
 151 static void dbg_dumpregs(struct s3cmci_host *host, char *prefix)
 152 {
 153         u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;
 154         u32 datcon, datcnt, datsta, fsta, imask;
 155 
 156         con     = readl(host->base + S3C2410_SDICON);
 157         pre     = readl(host->base + S3C2410_SDIPRE);
 158         cmdarg  = readl(host->base + S3C2410_SDICMDARG);
 159         cmdcon  = readl(host->base + S3C2410_SDICMDCON);
 160         cmdsta  = readl(host->base + S3C2410_SDICMDSTAT);
 161         r0      = readl(host->base + S3C2410_SDIRSP0);
 162         r1      = readl(host->base + S3C2410_SDIRSP1);
 163         r2      = readl(host->base + S3C2410_SDIRSP2);
 164         r3      = readl(host->base + S3C2410_SDIRSP3);
 165         timer   = readl(host->base + S3C2410_SDITIMER);
 166         bsize   = readl(host->base + S3C2410_SDIBSIZE);
 167         datcon  = readl(host->base + S3C2410_SDIDCON);
 168         datcnt  = readl(host->base + S3C2410_SDIDCNT);
 169         datsta  = readl(host->base + S3C2410_SDIDSTA);
 170         fsta    = readl(host->base + S3C2410_SDIFSTA);
 171         imask   = readl(host->base + host->sdiimsk);
 172 
 173         dbg(host, dbg_debug, "%s  CON:[%08x]  PRE:[%08x]  TMR:[%08x]\n",
 174                                 prefix, con, pre, timer);
 175 
 176         dbg(host, dbg_debug, "%s CCON:[%08x] CARG:[%08x] CSTA:[%08x]\n",
 177                                 prefix, cmdcon, cmdarg, cmdsta);
 178 
 179         dbg(host, dbg_debug, "%s DCON:[%08x] FSTA:[%08x]"
 180                                " DSTA:[%08x] DCNT:[%08x]\n",
 181                                 prefix, datcon, fsta, datsta, datcnt);
 182 
 183         dbg(host, dbg_debug, "%s   R0:[%08x]   R1:[%08x]"
 184                                "   R2:[%08x]   R3:[%08x]\n",
 185                                 prefix, r0, r1, r2, r3);
 186 }
 187 
 188 static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd,
 189                            int stop)
 190 {
 191         snprintf(host->dbgmsg_cmd, 300,
 192                  "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u",
 193                  host->ccnt, (stop ? " (STOP)" : ""),
 194                  cmd->opcode, cmd->arg, cmd->flags, cmd->retries);
 195 
 196         if (cmd->data) {
 197                 snprintf(host->dbgmsg_dat, 300,
 198                          "#%u bsize:%u blocks:%u bytes:%u",
 199                          host->dcnt, cmd->data->blksz,
 200                          cmd->data->blocks,
 201                          cmd->data->blocks * cmd->data->blksz);
 202         } else {
 203                 host->dbgmsg_dat[0] = '\0';
 204         }
 205 }
 206 
 207 static void dbg_dumpcmd(struct s3cmci_host *host, struct mmc_command *cmd,
 208                         int fail)
 209 {
 210         unsigned int dbglvl = fail ? dbg_fail : dbg_debug;
 211 
 212         if (!cmd)
 213                 return;
 214 
 215         if (cmd->error == 0) {
 216                 dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n",
 217                         host->dbgmsg_cmd, cmd->resp[0]);
 218         } else {
 219                 dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n",
 220                         cmd->error, host->dbgmsg_cmd, host->status);
 221         }
 222 
 223         if (!cmd->data)
 224                 return;
 225 
 226         if (cmd->data->error == 0) {
 227                 dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat);
 228         } else {
 229                 dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n",
 230                         cmd->data->error, host->dbgmsg_dat,
 231                         readl(host->base + S3C2410_SDIDCNT));
 232         }
 233 }
 234 #else
 235 static void dbg_dumpcmd(struct s3cmci_host *host,
 236                         struct mmc_command *cmd, int fail) { }
 237 
 238 static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd,
 239                            int stop) { }
 240 
 241 static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { }
 242 
 243 #endif 
 244 
 245 
 246 
 247 
 248 
 249 
 250 
 251 
 252 
 253 static inline bool s3cmci_host_usedma(struct s3cmci_host *host)
 254 {
 255 #ifdef CONFIG_MMC_S3C_PIO
 256         return false;
 257 #else 
 258         return true;
 259 #endif
 260 }
 261 
 262 static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
 263 {
 264         u32 newmask;
 265 
 266         newmask = readl(host->base + host->sdiimsk);
 267         newmask |= imask;
 268 
 269         writel(newmask, host->base + host->sdiimsk);
 270 
 271         return newmask;
 272 }
 273 
 274 static inline u32 disable_imask(struct s3cmci_host *host, u32 imask)
 275 {
 276         u32 newmask;
 277 
 278         newmask = readl(host->base + host->sdiimsk);
 279         newmask &= ~imask;
 280 
 281         writel(newmask, host->base + host->sdiimsk);
 282 
 283         return newmask;
 284 }
 285 
 286 static inline void clear_imask(struct s3cmci_host *host)
 287 {
 288         u32 mask = readl(host->base + host->sdiimsk);
 289 
 290         
 291         mask &= S3C2410_SDIIMSK_SDIOIRQ;
 292         writel(mask, host->base + host->sdiimsk);
 293 }
 294 
 295 
 296 
 297 
 298 
 299 
 300 
 301 
 302 
 303 
 304 
 305 
 306 
 307 static void s3cmci_check_sdio_irq(struct s3cmci_host *host)
 308 {
 309         if (host->sdio_irqen) {
 310                 if (gpio_get_value(S3C2410_GPE(8)) == 0) {
 311                         pr_debug("%s: signalling irq\n", __func__);
 312                         mmc_signal_sdio_irq(host->mmc);
 313                 }
 314         }
 315 }
 316 
 317 static inline int get_data_buffer(struct s3cmci_host *host,
 318                                   u32 *bytes, u32 **pointer)
 319 {
 320         struct scatterlist *sg;
 321 
 322         if (host->pio_active == XFER_NONE)
 323                 return -EINVAL;
 324 
 325         if ((!host->mrq) || (!host->mrq->data))
 326                 return -EINVAL;
 327 
 328         if (host->pio_sgptr >= host->mrq->data->sg_len) {
 329                 dbg(host, dbg_debug, "no more buffers (%i/%i)\n",
 330                       host->pio_sgptr, host->mrq->data->sg_len);
 331                 return -EBUSY;
 332         }
 333         sg = &host->mrq->data->sg[host->pio_sgptr];
 334 
 335         *bytes = sg->length;
 336         *pointer = sg_virt(sg);
 337 
 338         host->pio_sgptr++;
 339 
 340         dbg(host, dbg_sg, "new buffer (%i/%i)\n",
 341             host->pio_sgptr, host->mrq->data->sg_len);
 342 
 343         return 0;
 344 }
 345 
 346 static inline u32 fifo_count(struct s3cmci_host *host)
 347 {
 348         u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
 349 
 350         fifostat &= S3C2410_SDIFSTA_COUNTMASK;
 351         return fifostat;
 352 }
 353 
 354 static inline u32 fifo_free(struct s3cmci_host *host)
 355 {
 356         u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
 357 
 358         fifostat &= S3C2410_SDIFSTA_COUNTMASK;
 359         return 63 - fifostat;
 360 }
 361 
 362 
 363 
 364 
 365 
 366 
 367 
 368 
 369 
 370 
 371 
 372 
 373 
 374 
 375 static void s3cmci_enable_irq(struct s3cmci_host *host, bool more)
 376 {
 377         unsigned long flags;
 378         bool enable = false;
 379 
 380         local_irq_save(flags);
 381 
 382         host->irq_enabled = more;
 383         host->irq_disabled = false;
 384 
 385         enable = more | host->sdio_irqen;
 386 
 387         if (host->irq_state != enable) {
 388                 host->irq_state = enable;
 389 
 390                 if (enable)
 391                         enable_irq(host->irq);
 392                 else
 393                         disable_irq(host->irq);
 394         }
 395 
 396         local_irq_restore(flags);
 397 }
 398 
 399 
 400 
 401 
 402 static void s3cmci_disable_irq(struct s3cmci_host *host, bool transfer)
 403 {
 404         unsigned long flags;
 405 
 406         local_irq_save(flags);
 407 
 408         
 409 
 410         host->irq_disabled = transfer;
 411 
 412         if (transfer && host->irq_state) {
 413                 host->irq_state = false;
 414                 disable_irq(host->irq);
 415         }
 416 
 417         local_irq_restore(flags);
 418 }
 419 
 420 static void do_pio_read(struct s3cmci_host *host)
 421 {
 422         int res;
 423         u32 fifo;
 424         u32 *ptr;
 425         u32 fifo_words;
 426         void __iomem *from_ptr;
 427 
 428         
 429         writel(host->prescaler, host->base + S3C2410_SDIPRE);
 430 
 431         from_ptr = host->base + host->sdidata;
 432 
 433         while ((fifo = fifo_count(host))) {
 434                 if (!host->pio_bytes) {
 435                         res = get_data_buffer(host, &host->pio_bytes,
 436                                               &host->pio_ptr);
 437                         if (res) {
 438                                 host->pio_active = XFER_NONE;
 439                                 host->complete_what = COMPLETION_FINALIZE;
 440 
 441                                 dbg(host, dbg_pio, "pio_read(): "
 442                                     "complete (no more data).\n");
 443                                 return;
 444                         }
 445 
 446                         dbg(host, dbg_pio,
 447                             "pio_read(): new target: [%i]@[%p]\n",
 448                             host->pio_bytes, host->pio_ptr);
 449                 }
 450 
 451                 dbg(host, dbg_pio,
 452                     "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n",
 453                     fifo, host->pio_bytes,
 454                     readl(host->base + S3C2410_SDIDCNT));
 455 
 456                 
 457 
 458 
 459 
 460 
 461                 if (fifo >= host->pio_bytes)
 462                         fifo = host->pio_bytes;
 463                 else
 464                         fifo -= fifo & 3;
 465 
 466                 host->pio_bytes -= fifo;
 467                 host->pio_count += fifo;
 468 
 469                 fifo_words = fifo >> 2;
 470                 ptr = host->pio_ptr;
 471                 while (fifo_words--)
 472                         *ptr++ = readl(from_ptr);
 473                 host->pio_ptr = ptr;
 474 
 475                 if (fifo & 3) {
 476                         u32 n = fifo & 3;
 477                         u32 data = readl(from_ptr);
 478                         u8 *p = (u8 *)host->pio_ptr;
 479 
 480                         while (n--) {
 481                                 *p++ = data;
 482                                 data >>= 8;
 483                         }
 484                 }
 485         }
 486 
 487         if (!host->pio_bytes) {
 488                 res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr);
 489                 if (res) {
 490                         dbg(host, dbg_pio,
 491                             "pio_read(): complete (no more buffers).\n");
 492                         host->pio_active = XFER_NONE;
 493                         host->complete_what = COMPLETION_FINALIZE;
 494 
 495                         return;
 496                 }
 497         }
 498 
 499         enable_imask(host,
 500                      S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
 501 }
 502 
 503 static void do_pio_write(struct s3cmci_host *host)
 504 {
 505         void __iomem *to_ptr;
 506         int res;
 507         u32 fifo;
 508         u32 *ptr;
 509 
 510         to_ptr = host->base + host->sdidata;
 511 
 512         while ((fifo = fifo_free(host)) > 3) {
 513                 if (!host->pio_bytes) {
 514                         res = get_data_buffer(host, &host->pio_bytes,
 515                                                         &host->pio_ptr);
 516                         if (res) {
 517                                 dbg(host, dbg_pio,
 518                                     "pio_write(): complete (no more data).\n");
 519                                 host->pio_active = XFER_NONE;
 520 
 521                                 return;
 522                         }
 523 
 524                         dbg(host, dbg_pio,
 525                             "pio_write(): new source: [%i]@[%p]\n",
 526                             host->pio_bytes, host->pio_ptr);
 527 
 528                 }
 529 
 530                 
 531 
 532 
 533 
 534                 if (fifo >= host->pio_bytes)
 535                         fifo = host->pio_bytes;
 536                 else
 537                         fifo -= fifo & 3;
 538 
 539                 host->pio_bytes -= fifo;
 540                 host->pio_count += fifo;
 541 
 542                 fifo = (fifo + 3) >> 2;
 543                 ptr = host->pio_ptr;
 544                 while (fifo--)
 545                         writel(*ptr++, to_ptr);
 546                 host->pio_ptr = ptr;
 547         }
 548 
 549         enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
 550 }
 551 
 552 static void pio_tasklet(unsigned long data)
 553 {
 554         struct s3cmci_host *host = (struct s3cmci_host *) data;
 555 
 556         s3cmci_disable_irq(host, true);
 557 
 558         if (host->pio_active == XFER_WRITE)
 559                 do_pio_write(host);
 560 
 561         if (host->pio_active == XFER_READ)
 562                 do_pio_read(host);
 563 
 564         if (host->complete_what == COMPLETION_FINALIZE) {
 565                 clear_imask(host);
 566                 if (host->pio_active != XFER_NONE) {
 567                         dbg(host, dbg_err, "unfinished %s "
 568                             "- pio_count:[%u] pio_bytes:[%u]\n",
 569                             (host->pio_active == XFER_READ) ? "read" : "write",
 570                             host->pio_count, host->pio_bytes);
 571 
 572                         if (host->mrq->data)
 573                                 host->mrq->data->error = -EINVAL;
 574                 }
 575 
 576                 s3cmci_enable_irq(host, false);
 577                 finalize_request(host);
 578         } else
 579                 s3cmci_enable_irq(host, true);
 580 }
 581 
 582 
 583 
 584 
 585 
 586 
 587 
 588 
 589 
 590 
 591 
 592 
 593 
 594 
 595 
 596 
 597 
 598 
 599 
 600 
 601 
 602 
 603 
 604 
 605 
 606 
 607 
 608 
 609 static irqreturn_t s3cmci_irq(int irq, void *dev_id)
 610 {
 611         struct s3cmci_host *host = dev_id;
 612         struct mmc_command *cmd;
 613         u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
 614         u32 mci_cclear = 0, mci_dclear;
 615         unsigned long iflags;
 616 
 617         mci_dsta = readl(host->base + S3C2410_SDIDSTA);
 618         mci_imsk = readl(host->base + host->sdiimsk);
 619 
 620         if (mci_dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
 621                 if (mci_imsk & S3C2410_SDIIMSK_SDIOIRQ) {
 622                         mci_dclear = S3C2410_SDIDSTA_SDIOIRQDETECT;
 623                         writel(mci_dclear, host->base + S3C2410_SDIDSTA);
 624 
 625                         mmc_signal_sdio_irq(host->mmc);
 626                         return IRQ_HANDLED;
 627                 }
 628         }
 629 
 630         spin_lock_irqsave(&host->complete_lock, iflags);
 631 
 632         mci_csta = readl(host->base + S3C2410_SDICMDSTAT);
 633         mci_dcnt = readl(host->base + S3C2410_SDIDCNT);
 634         mci_fsta = readl(host->base + S3C2410_SDIFSTA);
 635         mci_dclear = 0;
 636 
 637         if ((host->complete_what == COMPLETION_NONE) ||
 638             (host->complete_what == COMPLETION_FINALIZE)) {
 639                 host->status = "nothing to complete";
 640                 clear_imask(host);
 641                 goto irq_out;
 642         }
 643 
 644         if (!host->mrq) {
 645                 host->status = "no active mrq";
 646                 clear_imask(host);
 647                 goto irq_out;
 648         }
 649 
 650         cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd;
 651 
 652         if (!cmd) {
 653                 host->status = "no active cmd";
 654                 clear_imask(host);
 655                 goto irq_out;
 656         }
 657 
 658         if (!s3cmci_host_usedma(host)) {
 659                 if ((host->pio_active == XFER_WRITE) &&
 660                     (mci_fsta & S3C2410_SDIFSTA_TFDET)) {
 661 
 662                         disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
 663                         tasklet_schedule(&host->pio_tasklet);
 664                         host->status = "pio tx";
 665                 }
 666 
 667                 if ((host->pio_active == XFER_READ) &&
 668                     (mci_fsta & S3C2410_SDIFSTA_RFDET)) {
 669 
 670                         disable_imask(host,
 671                                       S3C2410_SDIIMSK_RXFIFOHALF |
 672                                       S3C2410_SDIIMSK_RXFIFOLAST);
 673 
 674                         tasklet_schedule(&host->pio_tasklet);
 675                         host->status = "pio rx";
 676                 }
 677         }
 678 
 679         if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
 680                 dbg(host, dbg_err, "CMDSTAT: error CMDTIMEOUT\n");
 681                 cmd->error = -ETIMEDOUT;
 682                 host->status = "error: command timeout";
 683                 goto fail_transfer;
 684         }
 685 
 686         if (mci_csta & S3C2410_SDICMDSTAT_CMDSENT) {
 687                 if (host->complete_what == COMPLETION_CMDSENT) {
 688                         host->status = "ok: command sent";
 689                         goto close_transfer;
 690                 }
 691 
 692                 mci_cclear |= S3C2410_SDICMDSTAT_CMDSENT;
 693         }
 694 
 695         if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) {
 696                 if (cmd->flags & MMC_RSP_CRC) {
 697                         if (host->mrq->cmd->flags & MMC_RSP_136) {
 698                                 dbg(host, dbg_irq,
 699                                     "fixup: ignore CRC fail with long rsp\n");
 700                         } else {
 701                                 
 702 
 703 
 704 
 705 
 706 
 707 
 708 
 709                         }
 710                 }
 711 
 712                 mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL;
 713         }
 714 
 715         if (mci_csta & S3C2410_SDICMDSTAT_RSPFIN) {
 716                 if (host->complete_what == COMPLETION_RSPFIN) {
 717                         host->status = "ok: command response received";
 718                         goto close_transfer;
 719                 }
 720 
 721                 if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)
 722                         host->complete_what = COMPLETION_XFERFINISH;
 723 
 724                 mci_cclear |= S3C2410_SDICMDSTAT_RSPFIN;
 725         }
 726 
 727         
 728 
 729 
 730         if (!cmd->data)
 731                 goto clear_status_bits;
 732 
 733         
 734         if (host->is2440) {
 735                 if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
 736                         dbg(host, dbg_err, "FIFO failure\n");
 737                         host->mrq->data->error = -EILSEQ;
 738                         host->status = "error: 2440 fifo failure";
 739                         goto fail_transfer;
 740                 }
 741         } else {
 742                 if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) {
 743                         dbg(host, dbg_err, "FIFO failure\n");
 744                         cmd->data->error = -EILSEQ;
 745                         host->status = "error:  fifo failure";
 746                         goto fail_transfer;
 747                 }
 748         }
 749 
 750         if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
 751                 dbg(host, dbg_err, "bad data crc (outgoing)\n");
 752                 cmd->data->error = -EILSEQ;
 753                 host->status = "error: bad data crc (outgoing)";
 754                 goto fail_transfer;
 755         }
 756 
 757         if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) {
 758                 dbg(host, dbg_err, "bad data crc (incoming)\n");
 759                 cmd->data->error = -EILSEQ;
 760                 host->status = "error: bad data crc (incoming)";
 761                 goto fail_transfer;
 762         }
 763 
 764         if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
 765                 dbg(host, dbg_err, "data timeout\n");
 766                 cmd->data->error = -ETIMEDOUT;
 767                 host->status = "error: data timeout";
 768                 goto fail_transfer;
 769         }
 770 
 771         if (mci_dsta & S3C2410_SDIDSTA_XFERFINISH) {
 772                 if (host->complete_what == COMPLETION_XFERFINISH) {
 773                         host->status = "ok: data transfer completed";
 774                         goto close_transfer;
 775                 }
 776 
 777                 if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)
 778                         host->complete_what = COMPLETION_RSPFIN;
 779 
 780                 mci_dclear |= S3C2410_SDIDSTA_XFERFINISH;
 781         }
 782 
 783 clear_status_bits:
 784         writel(mci_cclear, host->base + S3C2410_SDICMDSTAT);
 785         writel(mci_dclear, host->base + S3C2410_SDIDSTA);
 786 
 787         goto irq_out;
 788 
 789 fail_transfer:
 790         host->pio_active = XFER_NONE;
 791 
 792 close_transfer:
 793         host->complete_what = COMPLETION_FINALIZE;
 794 
 795         clear_imask(host);
 796         tasklet_schedule(&host->pio_tasklet);
 797 
 798         goto irq_out;
 799 
 800 irq_out:
 801         dbg(host, dbg_irq,
 802             "csta:0x%08x dsta:0x%08x fsta:0x%08x dcnt:0x%08x status:%s.\n",
 803             mci_csta, mci_dsta, mci_fsta, mci_dcnt, host->status);
 804 
 805         spin_unlock_irqrestore(&host->complete_lock, iflags);
 806         return IRQ_HANDLED;
 807 
 808 }
 809 
 810 static void s3cmci_dma_done_callback(void *arg)
 811 {
 812         struct s3cmci_host *host = arg;
 813         unsigned long iflags;
 814 
 815         BUG_ON(!host->mrq);
 816         BUG_ON(!host->mrq->data);
 817 
 818         spin_lock_irqsave(&host->complete_lock, iflags);
 819 
 820         dbg(host, dbg_dma, "DMA FINISHED\n");
 821 
 822         host->dma_complete = 1;
 823         host->complete_what = COMPLETION_FINALIZE;
 824 
 825         tasklet_schedule(&host->pio_tasklet);
 826         spin_unlock_irqrestore(&host->complete_lock, iflags);
 827 
 828 }
 829 
 830 static void finalize_request(struct s3cmci_host *host)
 831 {
 832         struct mmc_request *mrq = host->mrq;
 833         struct mmc_command *cmd;
 834         int debug_as_failure = 0;
 835 
 836         if (host->complete_what != COMPLETION_FINALIZE)
 837                 return;
 838 
 839         if (!mrq)
 840                 return;
 841         cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
 842 
 843         if (cmd->data && (cmd->error == 0) &&
 844             (cmd->data->error == 0)) {
 845                 if (s3cmci_host_usedma(host) && (!host->dma_complete)) {
 846                         dbg(host, dbg_dma, "DMA Missing (%d)!\n",
 847                             host->dma_complete);
 848                         return;
 849                 }
 850         }
 851 
 852         
 853         cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0);
 854         cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1);
 855         cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2);
 856         cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);
 857 
 858         writel(host->prescaler, host->base + S3C2410_SDIPRE);
 859 
 860         if (cmd->error)
 861                 debug_as_failure = 1;
 862 
 863         if (cmd->data && cmd->data->error)
 864                 debug_as_failure = 1;
 865 
 866         dbg_dumpcmd(host, cmd, debug_as_failure);
 867 
 868         
 869         writel(0, host->base + S3C2410_SDICMDARG);
 870         writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
 871         writel(0, host->base + S3C2410_SDICMDCON);
 872         clear_imask(host);
 873 
 874         if (cmd->data && cmd->error)
 875                 cmd->data->error = cmd->error;
 876 
 877         if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) {
 878                 host->cmd_is_stop = 1;
 879                 s3cmci_send_request(host->mmc);
 880                 return;
 881         }
 882 
 883         
 884         if (!mrq->data)
 885                 goto request_done;
 886 
 887         
 888         if (mrq->data->error == 0) {
 889                 mrq->data->bytes_xfered =
 890                         (mrq->data->blocks * mrq->data->blksz);
 891         } else {
 892                 mrq->data->bytes_xfered = 0;
 893         }
 894 
 895         
 896 
 897         if (mrq->data->error != 0) {
 898                 if (s3cmci_host_usedma(host))
 899                         dmaengine_terminate_all(host->dma);
 900 
 901                 if (host->is2440) {
 902                         
 903                         writel(S3C2440_SDIFSTA_FIFORESET |
 904                                S3C2440_SDIFSTA_FIFOFAIL,
 905                                host->base + S3C2410_SDIFSTA);
 906                 } else {
 907                         u32 mci_con;
 908 
 909                         
 910                         mci_con = readl(host->base + S3C2410_SDICON);
 911                         mci_con |= S3C2410_SDICON_FIFORESET;
 912 
 913                         writel(mci_con, host->base + S3C2410_SDICON);
 914                 }
 915         }
 916 
 917 request_done:
 918         host->complete_what = COMPLETION_NONE;
 919         host->mrq = NULL;
 920 
 921         s3cmci_check_sdio_irq(host);
 922         mmc_request_done(host->mmc, mrq);
 923 }
 924 
 925 static void s3cmci_send_command(struct s3cmci_host *host,
 926                                         struct mmc_command *cmd)
 927 {
 928         u32 ccon, imsk;
 929 
 930         imsk  = S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_CMDTIMEOUT |
 931                 S3C2410_SDIIMSK_RESPONSEND | S3C2410_SDIIMSK_CMDSENT |
 932                 S3C2410_SDIIMSK_RESPONSECRC;
 933 
 934         enable_imask(host, imsk);
 935 
 936         if (cmd->data)
 937                 host->complete_what = COMPLETION_XFERFINISH_RSPFIN;
 938         else if (cmd->flags & MMC_RSP_PRESENT)
 939                 host->complete_what = COMPLETION_RSPFIN;
 940         else
 941                 host->complete_what = COMPLETION_CMDSENT;
 942 
 943         writel(cmd->arg, host->base + S3C2410_SDICMDARG);
 944 
 945         ccon  = cmd->opcode & S3C2410_SDICMDCON_INDEX;
 946         ccon |= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;
 947 
 948         if (cmd->flags & MMC_RSP_PRESENT)
 949                 ccon |= S3C2410_SDICMDCON_WAITRSP;
 950 
 951         if (cmd->flags & MMC_RSP_136)
 952                 ccon |= S3C2410_SDICMDCON_LONGRSP;
 953 
 954         writel(ccon, host->base + S3C2410_SDICMDCON);
 955 }
 956 
 957 static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
 958 {
 959         u32 dcon, imsk, stoptries = 3;
 960 
 961         
 962 
 963         if (!data) {
 964                 writel(0, host->base + S3C2410_SDIDCON);
 965                 return 0;
 966         }
 967 
 968         if ((data->blksz & 3) != 0) {
 969                 
 970 
 971 
 972                 if (data->blocks > 1) {
 973                         pr_warn("%s: can't do non-word sized block transfers (blksz %d)\n",
 974                                 __func__, data->blksz);
 975                         return -EINVAL;
 976                 }
 977         }
 978 
 979         while (readl(host->base + S3C2410_SDIDSTA) &
 980                (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {
 981 
 982                 dbg(host, dbg_err,
 983                     "mci_setup_data() transfer stillin progress.\n");
 984 
 985                 writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
 986                 s3cmci_reset(host);
 987 
 988                 if ((stoptries--) == 0) {
 989                         dbg_dumpregs(host, "DRF");
 990                         return -EINVAL;
 991                 }
 992         }
 993 
 994         dcon  = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
 995 
 996         if (s3cmci_host_usedma(host))
 997                 dcon |= S3C2410_SDIDCON_DMAEN;
 998 
 999         if (host->bus_width == MMC_BUS_WIDTH_4)
1000                 dcon |= S3C2410_SDIDCON_WIDEBUS;
1001 
1002         dcon |= S3C2410_SDIDCON_BLOCKMODE;
1003 
1004         if (data->flags & MMC_DATA_WRITE) {
1005                 dcon |= S3C2410_SDIDCON_TXAFTERRESP;
1006                 dcon |= S3C2410_SDIDCON_XFER_TXSTART;
1007         }
1008 
1009         if (data->flags & MMC_DATA_READ) {
1010                 dcon |= S3C2410_SDIDCON_RXAFTERCMD;
1011                 dcon |= S3C2410_SDIDCON_XFER_RXSTART;
1012         }
1013 
1014         if (host->is2440) {
1015                 dcon |= S3C2440_SDIDCON_DS_WORD;
1016                 dcon |= S3C2440_SDIDCON_DATSTART;
1017         }
1018 
1019         writel(dcon, host->base + S3C2410_SDIDCON);
1020 
1021         
1022 
1023         writel(data->blksz, host->base + S3C2410_SDIBSIZE);
1024 
1025         
1026         imsk = S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |
1027                S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;
1028 
1029         enable_imask(host, imsk);
1030 
1031         
1032 
1033         if (host->is2440) {
1034                 writel(0x007FFFFF, host->base + S3C2410_SDITIMER);
1035         } else {
1036                 writel(0x0000FFFF, host->base + S3C2410_SDITIMER);
1037 
1038                 
1039                 if (data->flags & MMC_DATA_READ)
1040                         writel(0xFF, host->base + S3C2410_SDIPRE);
1041         }
1042 
1043         return 0;
1044 }
1045 
1046 #define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ)
1047 
1048 static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
1049 {
1050         int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
1051 
1052         BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
1053 
1054         host->pio_sgptr = 0;
1055         host->pio_bytes = 0;
1056         host->pio_count = 0;
1057         host->pio_active = rw ? XFER_WRITE : XFER_READ;
1058 
1059         if (rw) {
1060                 do_pio_write(host);
1061                 enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
1062         } else {
1063                 enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF
1064                              | S3C2410_SDIIMSK_RXFIFOLAST);
1065         }
1066 
1067         return 0;
1068 }
1069 
1070 static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
1071 {
1072         int rw = data->flags & MMC_DATA_WRITE;
1073         struct dma_async_tx_descriptor *desc;
1074         struct dma_slave_config conf = {
1075                 .src_addr = host->mem->start + host->sdidata,
1076                 .dst_addr = host->mem->start + host->sdidata,
1077                 .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
1078                 .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
1079         };
1080 
1081         BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
1082 
1083         
1084         writel(host->prescaler, host->base + S3C2410_SDIPRE);
1085 
1086         if (!rw)
1087                 conf.direction = DMA_DEV_TO_MEM;
1088         else
1089                 conf.direction = DMA_MEM_TO_DEV;
1090 
1091         dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
1092                    mmc_get_dma_dir(data));
1093 
1094         dmaengine_slave_config(host->dma, &conf);
1095         desc = dmaengine_prep_slave_sg(host->dma, data->sg, data->sg_len,
1096                 conf.direction,
1097                 DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
1098         if (!desc)
1099                 goto unmap_exit;
1100         desc->callback = s3cmci_dma_done_callback;
1101         desc->callback_param = host;
1102         dmaengine_submit(desc);
1103         dma_async_issue_pending(host->dma);
1104 
1105         return 0;
1106 
1107 unmap_exit:
1108         dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
1109                      mmc_get_dma_dir(data));
1110         return -ENOMEM;
1111 }
1112 
1113 static void s3cmci_send_request(struct mmc_host *mmc)
1114 {
1115         struct s3cmci_host *host = mmc_priv(mmc);
1116         struct mmc_request *mrq = host->mrq;
1117         struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
1118 
1119         host->ccnt++;
1120         prepare_dbgmsg(host, cmd, host->cmd_is_stop);
1121 
1122         
1123 
1124 
1125         writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);
1126         writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);
1127         writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA);
1128 
1129         if (cmd->data) {
1130                 int res = s3cmci_setup_data(host, cmd->data);
1131 
1132                 host->dcnt++;
1133 
1134                 if (res) {
1135                         dbg(host, dbg_err, "setup data error %d\n", res);
1136                         cmd->error = res;
1137                         cmd->data->error = res;
1138 
1139                         mmc_request_done(mmc, mrq);
1140                         return;
1141                 }
1142 
1143                 if (s3cmci_host_usedma(host))
1144                         res = s3cmci_prepare_dma(host, cmd->data);
1145                 else
1146                         res = s3cmci_prepare_pio(host, cmd->data);
1147 
1148                 if (res) {
1149                         dbg(host, dbg_err, "data prepare error %d\n", res);
1150                         cmd->error = res;
1151                         cmd->data->error = res;
1152 
1153                         mmc_request_done(mmc, mrq);
1154                         return;
1155                 }
1156         }
1157 
1158         
1159         s3cmci_send_command(host, cmd);
1160 
1161         
1162         s3cmci_enable_irq(host, true);
1163 }
1164 
1165 static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
1166 {
1167         struct s3cmci_host *host = mmc_priv(mmc);
1168 
1169         host->status = "mmc request";
1170         host->cmd_is_stop = 0;
1171         host->mrq = mrq;
1172 
1173         if (mmc_gpio_get_cd(mmc) == 0) {
1174                 dbg(host, dbg_err, "%s: no medium present\n", __func__);
1175                 host->mrq->cmd->error = -ENOMEDIUM;
1176                 mmc_request_done(mmc, mrq);
1177         } else
1178                 s3cmci_send_request(mmc);
1179 }
1180 
1181 static void s3cmci_set_clk(struct s3cmci_host *host, struct mmc_ios *ios)
1182 {
1183         u32 mci_psc;
1184 
1185         
1186         for (mci_psc = 0; mci_psc < 255; mci_psc++) {
1187                 host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1));
1188 
1189                 if (host->real_rate <= ios->clock)
1190                         break;
1191         }
1192 
1193         if (mci_psc > 255)
1194                 mci_psc = 255;
1195 
1196         host->prescaler = mci_psc;
1197         writel(host->prescaler, host->base + S3C2410_SDIPRE);
1198 
1199         
1200         if (ios->clock == 0)
1201                 host->real_rate = 0;
1202 }
1203 
1204 static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1205 {
1206         struct s3cmci_host *host = mmc_priv(mmc);
1207         u32 mci_con;
1208 
1209         
1210 
1211         mci_con = readl(host->base + S3C2410_SDICON);
1212 
1213         switch (ios->power_mode) {
1214         case MMC_POWER_ON:
1215         case MMC_POWER_UP:
1216                 
1217                 if (!host->pdev->dev.of_node)
1218                         s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
1219                                               S3C_GPIO_PULL_NONE);
1220 
1221                 if (host->pdata->set_power)
1222                         host->pdata->set_power(ios->power_mode, ios->vdd);
1223 
1224                 if (!host->is2440)
1225                         mci_con |= S3C2410_SDICON_FIFORESET;
1226 
1227                 break;
1228 
1229         case MMC_POWER_OFF:
1230         default:
1231                 if (!host->pdev->dev.of_node)
1232                         gpio_direction_output(S3C2410_GPE(5), 0);
1233 
1234                 if (host->is2440)
1235                         mci_con |= S3C2440_SDICON_SDRESET;
1236 
1237                 if (host->pdata->set_power)
1238                         host->pdata->set_power(ios->power_mode, ios->vdd);
1239 
1240                 break;
1241         }
1242 
1243         s3cmci_set_clk(host, ios);
1244 
1245         
1246         if (ios->clock)
1247                 mci_con |= S3C2410_SDICON_CLOCKTYPE;
1248         else
1249                 mci_con &= ~S3C2410_SDICON_CLOCKTYPE;
1250 
1251         writel(mci_con, host->base + S3C2410_SDICON);
1252 
1253         if ((ios->power_mode == MMC_POWER_ON) ||
1254             (ios->power_mode == MMC_POWER_UP)) {
1255                 dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",
1256                         host->real_rate/1000, ios->clock/1000);
1257         } else {
1258                 dbg(host, dbg_conf, "powered down.\n");
1259         }
1260 
1261         host->bus_width = ios->bus_width;
1262 }
1263 
1264 static void s3cmci_reset(struct s3cmci_host *host)
1265 {
1266         u32 con = readl(host->base + S3C2410_SDICON);
1267 
1268         con |= S3C2440_SDICON_SDRESET;
1269         writel(con, host->base + S3C2410_SDICON);
1270 }
1271 
1272 static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1273 {
1274         struct s3cmci_host *host = mmc_priv(mmc);
1275         unsigned long flags;
1276         u32 con;
1277 
1278         local_irq_save(flags);
1279 
1280         con = readl(host->base + S3C2410_SDICON);
1281         host->sdio_irqen = enable;
1282 
1283         if (enable == host->sdio_irqen)
1284                 goto same_state;
1285 
1286         if (enable) {
1287                 con |= S3C2410_SDICON_SDIOIRQ;
1288                 enable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
1289 
1290                 if (!host->irq_state && !host->irq_disabled) {
1291                         host->irq_state = true;
1292                         enable_irq(host->irq);
1293                 }
1294         } else {
1295                 disable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
1296                 con &= ~S3C2410_SDICON_SDIOIRQ;
1297 
1298                 if (!host->irq_enabled && host->irq_state) {
1299                         disable_irq_nosync(host->irq);
1300                         host->irq_state = false;
1301                 }
1302         }
1303 
1304         writel(con, host->base + S3C2410_SDICON);
1305 
1306  same_state:
1307         local_irq_restore(flags);
1308 
1309         s3cmci_check_sdio_irq(host);
1310 }
1311 
1312 static const struct mmc_host_ops s3cmci_ops = {
1313         .request        = s3cmci_request,
1314         .set_ios        = s3cmci_set_ios,
1315         .get_ro         = mmc_gpio_get_ro,
1316         .get_cd         = mmc_gpio_get_cd,
1317         .enable_sdio_irq = s3cmci_enable_sdio_irq,
1318 };
1319 
1320 static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
1321         
1322 
1323          .no_wprotect = 1,
1324          .no_detect = 1,
1325 };
1326 
1327 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
1328 
1329 static int s3cmci_cpufreq_transition(struct notifier_block *nb,
1330                                      unsigned long val, void *data)
1331 {
1332         struct s3cmci_host *host;
1333         struct mmc_host *mmc;
1334         unsigned long newclk;
1335         unsigned long flags;
1336 
1337         host = container_of(nb, struct s3cmci_host, freq_transition);
1338         newclk = clk_get_rate(host->clk);
1339         mmc = host->mmc;
1340 
1341         if ((val == CPUFREQ_PRECHANGE && newclk > host->clk_rate) ||
1342             (val == CPUFREQ_POSTCHANGE && newclk < host->clk_rate)) {
1343                 spin_lock_irqsave(&mmc->lock, flags);
1344 
1345                 host->clk_rate = newclk;
1346 
1347                 if (mmc->ios.power_mode != MMC_POWER_OFF &&
1348                     mmc->ios.clock != 0)
1349                         s3cmci_set_clk(host, &mmc->ios);
1350 
1351                 spin_unlock_irqrestore(&mmc->lock, flags);
1352         }
1353 
1354         return 0;
1355 }
1356 
1357 static inline int s3cmci_cpufreq_register(struct s3cmci_host *host)
1358 {
1359         host->freq_transition.notifier_call = s3cmci_cpufreq_transition;
1360 
1361         return cpufreq_register_notifier(&host->freq_transition,
1362                                          CPUFREQ_TRANSITION_NOTIFIER);
1363 }
1364 
1365 static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
1366 {
1367         cpufreq_unregister_notifier(&host->freq_transition,
1368                                     CPUFREQ_TRANSITION_NOTIFIER);
1369 }
1370 
1371 #else
1372 static inline int s3cmci_cpufreq_register(struct s3cmci_host *host)
1373 {
1374         return 0;
1375 }
1376 
1377 static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
1378 {
1379 }
1380 #endif
1381 
1382 
1383 #ifdef CONFIG_DEBUG_FS
1384 
1385 static int s3cmci_state_show(struct seq_file *seq, void *v)
1386 {
1387         struct s3cmci_host *host = seq->private;
1388 
1389         seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
1390         seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
1391         seq_printf(seq, "Prescale = %d\n", host->prescaler);
1392         seq_printf(seq, "is2440 = %d\n", host->is2440);
1393         seq_printf(seq, "IRQ = %d\n", host->irq);
1394         seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
1395         seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
1396         seq_printf(seq, "IRQ state = %d\n", host->irq_state);
1397         seq_printf(seq, "CD IRQ = %d\n", host->irq_cd);
1398         seq_printf(seq, "Do DMA = %d\n", s3cmci_host_usedma(host));
1399         seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk);
1400         seq_printf(seq, "SDIDATA at %d\n", host->sdidata);
1401 
1402         return 0;
1403 }
1404 
1405 DEFINE_SHOW_ATTRIBUTE(s3cmci_state);
1406 
1407 #define DBG_REG(_r) { .addr = S3C2410_SDI##_r, .name = #_r }
1408 
1409 struct s3cmci_reg {
1410         unsigned short  addr;
1411         unsigned char   *name;
1412 };
1413 
1414 static const struct s3cmci_reg debug_regs[] = {
1415         DBG_REG(CON),
1416         DBG_REG(PRE),
1417         DBG_REG(CMDARG),
1418         DBG_REG(CMDCON),
1419         DBG_REG(CMDSTAT),
1420         DBG_REG(RSP0),
1421         DBG_REG(RSP1),
1422         DBG_REG(RSP2),
1423         DBG_REG(RSP3),
1424         DBG_REG(TIMER),
1425         DBG_REG(BSIZE),
1426         DBG_REG(DCON),
1427         DBG_REG(DCNT),
1428         DBG_REG(DSTA),
1429         DBG_REG(FSTA),
1430         {}
1431 };
1432 
1433 static int s3cmci_regs_show(struct seq_file *seq, void *v)
1434 {
1435         struct s3cmci_host *host = seq->private;
1436         const struct s3cmci_reg *rptr = debug_regs;
1437 
1438         for (; rptr->name; rptr++)
1439                 seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name,
1440                            readl(host->base + rptr->addr));
1441 
1442         seq_printf(seq, "SDIIMSK\t=0x%08x\n", readl(host->base + host->sdiimsk));
1443 
1444         return 0;
1445 }
1446 
1447 DEFINE_SHOW_ATTRIBUTE(s3cmci_regs);
1448 
1449 static void s3cmci_debugfs_attach(struct s3cmci_host *host)
1450 {
1451         struct device *dev = &host->pdev->dev;
1452         struct dentry *root;
1453 
1454         root = debugfs_create_dir(dev_name(dev), NULL);
1455         host->debug_root = root;
1456 
1457         debugfs_create_file("state", 0444, root, host, &s3cmci_state_fops);
1458         debugfs_create_file("regs", 0444, root, host, &s3cmci_regs_fops);
1459 }
1460 
1461 static void s3cmci_debugfs_remove(struct s3cmci_host *host)
1462 {
1463         debugfs_remove_recursive(host->debug_root);
1464 }
1465 
1466 #else
1467 static inline void s3cmci_debugfs_attach(struct s3cmci_host *host) { }
1468 static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
1469 
1470 #endif 
1471 
1472 static int s3cmci_probe_pdata(struct s3cmci_host *host)
1473 {
1474         struct platform_device *pdev = host->pdev;
1475         struct mmc_host *mmc = host->mmc;
1476         struct s3c24xx_mci_pdata *pdata;
1477         int i, ret;
1478 
1479         host->is2440 = platform_get_device_id(pdev)->driver_data;
1480 
1481         for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
1482                 ret = gpio_request(i, dev_name(&pdev->dev));
1483                 if (ret) {
1484                         dev_err(&pdev->dev, "failed to get gpio %d\n", i);
1485 
1486                         for (i--; i >= S3C2410_GPE(5); i--)
1487                                 gpio_free(i);
1488 
1489                         return ret;
1490                 }
1491         }
1492 
1493         if (!pdev->dev.platform_data)
1494                 pdev->dev.platform_data = &s3cmci_def_pdata;
1495 
1496         pdata = pdev->dev.platform_data;
1497 
1498         if (pdata->no_wprotect)
1499                 mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
1500 
1501         if (pdata->no_detect)
1502                 mmc->caps |= MMC_CAP_NEEDS_POLL;
1503 
1504         if (pdata->wprotect_invert)
1505                 mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
1506 
1507         
1508         ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
1509         if (ret != -ENOENT) {
1510                 dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
1511                         ret);
1512                 return ret;
1513         }
1514 
1515         ret = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL);
1516         if (ret != -ENOENT) {
1517                 dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
1518                         ret);
1519                 return ret;
1520         }
1521 
1522         return 0;
1523 }
1524 
1525 static int s3cmci_probe_dt(struct s3cmci_host *host)
1526 {
1527         struct platform_device *pdev = host->pdev;
1528         struct s3c24xx_mci_pdata *pdata;
1529         struct mmc_host *mmc = host->mmc;
1530         int ret;
1531 
1532         host->is2440 = (int) of_device_get_match_data(&pdev->dev);
1533 
1534         ret = mmc_of_parse(mmc);
1535         if (ret)
1536                 return ret;
1537 
1538         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
1539         if (!pdata)
1540                 return -ENOMEM;
1541 
1542         pdev->dev.platform_data = pdata;
1543 
1544         return 0;
1545 }
1546 
1547 static int s3cmci_probe(struct platform_device *pdev)
1548 {
1549         struct s3cmci_host *host;
1550         struct mmc_host *mmc;
1551         int ret;
1552         int i;
1553 
1554         mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
1555         if (!mmc) {
1556                 ret = -ENOMEM;
1557                 goto probe_out;
1558         }
1559 
1560         host = mmc_priv(mmc);
1561         host->mmc       = mmc;
1562         host->pdev      = pdev;
1563 
1564         if (pdev->dev.of_node)
1565                 ret = s3cmci_probe_dt(host);
1566         else
1567                 ret = s3cmci_probe_pdata(host);
1568 
1569         if (ret)
1570                 goto probe_free_host;
1571 
1572         host->pdata = pdev->dev.platform_data;
1573 
1574         spin_lock_init(&host->complete_lock);
1575         tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
1576 
1577         if (host->is2440) {
1578                 host->sdiimsk   = S3C2440_SDIIMSK;
1579                 host->sdidata   = S3C2440_SDIDATA;
1580                 host->clk_div   = 1;
1581         } else {
1582                 host->sdiimsk   = S3C2410_SDIIMSK;
1583                 host->sdidata   = S3C2410_SDIDATA;
1584                 host->clk_div   = 2;
1585         }
1586 
1587         host->complete_what     = COMPLETION_NONE;
1588         host->pio_active        = XFER_NONE;
1589 
1590         host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1591         if (!host->mem) {
1592                 dev_err(&pdev->dev,
1593                         "failed to get io memory region resource.\n");
1594 
1595                 ret = -ENOENT;
1596                 goto probe_free_gpio;
1597         }
1598 
1599         host->mem = request_mem_region(host->mem->start,
1600                                        resource_size(host->mem), pdev->name);
1601 
1602         if (!host->mem) {
1603                 dev_err(&pdev->dev, "failed to request io memory region.\n");
1604                 ret = -ENOENT;
1605                 goto probe_free_gpio;
1606         }
1607 
1608         host->base = ioremap(host->mem->start, resource_size(host->mem));
1609         if (!host->base) {
1610                 dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
1611                 ret = -EINVAL;
1612                 goto probe_free_mem_region;
1613         }
1614 
1615         host->irq = platform_get_irq(pdev, 0);
1616         if (host->irq <= 0) {
1617                 ret = -EINVAL;
1618                 goto probe_iounmap;
1619         }
1620 
1621         if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) {
1622                 dev_err(&pdev->dev, "failed to request mci interrupt.\n");
1623                 ret = -ENOENT;
1624                 goto probe_iounmap;
1625         }
1626 
1627         
1628 
1629 
1630 
1631         disable_irq(host->irq);
1632         host->irq_state = false;
1633 
1634         
1635 
1636         if (s3cmci_host_usedma(host)) {
1637                 host->dma = dma_request_chan(&pdev->dev, "rx-tx");
1638                 ret = PTR_ERR_OR_ZERO(host->dma);
1639                 if (ret) {
1640                         dev_err(&pdev->dev, "cannot get DMA channel.\n");
1641                         goto probe_free_irq;
1642                 }
1643         }
1644 
1645         host->clk = clk_get(&pdev->dev, "sdi");
1646         if (IS_ERR(host->clk)) {
1647                 dev_err(&pdev->dev, "failed to find clock source.\n");
1648                 ret = PTR_ERR(host->clk);
1649                 host->clk = NULL;
1650                 goto probe_free_dma;
1651         }
1652 
1653         ret = clk_prepare_enable(host->clk);
1654         if (ret) {
1655                 dev_err(&pdev->dev, "failed to enable clock source.\n");
1656                 goto clk_free;
1657         }
1658 
1659         host->clk_rate = clk_get_rate(host->clk);
1660 
1661         mmc->ops        = &s3cmci_ops;
1662         mmc->ocr_avail  = MMC_VDD_32_33 | MMC_VDD_33_34;
1663 #ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ
1664         mmc->caps       = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
1665 #else
1666         mmc->caps       = MMC_CAP_4_BIT_DATA;
1667 #endif
1668         mmc->f_min      = host->clk_rate / (host->clk_div * 256);
1669         mmc->f_max      = host->clk_rate / host->clk_div;
1670 
1671         if (host->pdata->ocr_avail)
1672                 mmc->ocr_avail = host->pdata->ocr_avail;
1673 
1674         mmc->max_blk_count      = 4095;
1675         mmc->max_blk_size       = 4095;
1676         mmc->max_req_size       = 4095 * 512;
1677         mmc->max_seg_size       = mmc->max_req_size;
1678 
1679         mmc->max_segs           = 128;
1680 
1681         dbg(host, dbg_debug,
1682             "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%p.\n",
1683             (host->is2440?"2440":""),
1684             host->base, host->irq, host->irq_cd, host->dma);
1685 
1686         ret = s3cmci_cpufreq_register(host);
1687         if (ret) {
1688                 dev_err(&pdev->dev, "failed to register cpufreq\n");
1689                 goto free_dmabuf;
1690         }
1691 
1692         ret = mmc_add_host(mmc);
1693         if (ret) {
1694                 dev_err(&pdev->dev, "failed to add mmc host.\n");
1695                 goto free_cpufreq;
1696         }
1697 
1698         s3cmci_debugfs_attach(host);
1699 
1700         platform_set_drvdata(pdev, mmc);
1701         dev_info(&pdev->dev, "%s - using %s, %s SDIO IRQ\n", mmc_hostname(mmc),
1702                  s3cmci_host_usedma(host) ? "dma" : "pio",
1703                  mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");
1704 
1705         return 0;
1706 
1707  free_cpufreq:
1708         s3cmci_cpufreq_deregister(host);
1709 
1710  free_dmabuf:
1711         clk_disable_unprepare(host->clk);
1712 
1713  clk_free:
1714         clk_put(host->clk);
1715 
1716  probe_free_dma:
1717         if (s3cmci_host_usedma(host))
1718                 dma_release_channel(host->dma);
1719 
1720  probe_free_irq:
1721         free_irq(host->irq, host);
1722 
1723  probe_iounmap:
1724         iounmap(host->base);
1725 
1726  probe_free_mem_region:
1727         release_mem_region(host->mem->start, resource_size(host->mem));
1728 
1729  probe_free_gpio:
1730         if (!pdev->dev.of_node)
1731                 for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
1732                         gpio_free(i);
1733 
1734  probe_free_host:
1735         mmc_free_host(mmc);
1736 
1737  probe_out:
1738         return ret;
1739 }
1740 
1741 static void s3cmci_shutdown(struct platform_device *pdev)
1742 {
1743         struct mmc_host *mmc = platform_get_drvdata(pdev);
1744         struct s3cmci_host *host = mmc_priv(mmc);
1745 
1746         if (host->irq_cd >= 0)
1747                 free_irq(host->irq_cd, host);
1748 
1749         s3cmci_debugfs_remove(host);
1750         s3cmci_cpufreq_deregister(host);
1751         mmc_remove_host(mmc);
1752         clk_disable_unprepare(host->clk);
1753 }
1754 
1755 static int s3cmci_remove(struct platform_device *pdev)
1756 {
1757         struct mmc_host         *mmc  = platform_get_drvdata(pdev);
1758         struct s3cmci_host      *host = mmc_priv(mmc);
1759         int i;
1760 
1761         s3cmci_shutdown(pdev);
1762 
1763         clk_put(host->clk);
1764 
1765         tasklet_disable(&host->pio_tasklet);
1766 
1767         if (s3cmci_host_usedma(host))
1768                 dma_release_channel(host->dma);
1769 
1770         free_irq(host->irq, host);
1771 
1772         if (!pdev->dev.of_node)
1773                 for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
1774                         gpio_free(i);
1775 
1776         iounmap(host->base);
1777         release_mem_region(host->mem->start, resource_size(host->mem));
1778 
1779         mmc_free_host(mmc);
1780         return 0;
1781 }
1782 
1783 static const struct of_device_id s3cmci_dt_match[] = {
1784         {
1785                 .compatible = "samsung,s3c2410-sdi",
1786                 .data = (void *)0,
1787         },
1788         {
1789                 .compatible = "samsung,s3c2412-sdi",
1790                 .data = (void *)1,
1791         },
1792         {
1793                 .compatible = "samsung,s3c2440-sdi",
1794                 .data = (void *)1,
1795         },
1796         {  },
1797 };
1798 MODULE_DEVICE_TABLE(of, s3cmci_dt_match);
1799 
1800 static const struct platform_device_id s3cmci_driver_ids[] = {
1801         {
1802                 .name   = "s3c2410-sdi",
1803                 .driver_data    = 0,
1804         }, {
1805                 .name   = "s3c2412-sdi",
1806                 .driver_data    = 1,
1807         }, {
1808                 .name   = "s3c2440-sdi",
1809                 .driver_data    = 1,
1810         },
1811         { }
1812 };
1813 
1814 MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids);
1815 
1816 static struct platform_driver s3cmci_driver = {
1817         .driver = {
1818                 .name   = "s3c-sdi",
1819                 .of_match_table = s3cmci_dt_match,
1820         },
1821         .id_table       = s3cmci_driver_ids,
1822         .probe          = s3cmci_probe,
1823         .remove         = s3cmci_remove,
1824         .shutdown       = s3cmci_shutdown,
1825 };
1826 
1827 module_platform_driver(s3cmci_driver);
1828 
1829 MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
1830 MODULE_LICENSE("GPL v2");
1831 MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");