接下来我们来看看davinci_mmc.c文件,这个是我们真正需要修改或者移植的文件,对应的是davinci_mmc.ko模块;

davinci_mmcsd_init-> platform_driver_register-> davinci_mmc_probe

相关代码如下:

static struct platform_driver davinci_mmcsd_driver = {

       .probe           = davinci_mmc_probe,

       .remove          = davinci_mmcsd_remove,

       .suspend  = davinci_mmcsd_suspend,

       .resume          = davinci_mmcsd_resume,

       .driver            = {

              .name      = DRIVER_NAME,

       },

};

 

 

static int davinci_mmcsd_init(void)

{

       return platform_driver_register(&davinci_mmcsd_driver);

}

 

/**

 *    platform_driver_register

 *    @drv: platform driver structure

 */

int platform_driver_register(struct platform_driver *drv)

{

       drv->driver.bus = &platform_bus_type;

       if (drv->probe)

              drv->driver.probe = platform_drv_probe;

       if (drv->remove)

              drv->driver.remove = platform_drv_remove;

       if (drv->shutdown)

              drv->driver.shutdown = platform_drv_shutdown;

       if (drv->suspend)

              drv->driver.suspend = platform_drv_suspend;

       if (drv->resume)

              drv->driver.resume = platform_drv_resume;

       return driver_register(&drv->driver);

}

调用了driver_register函数,是要把驱动注册到总线上去;

 

下面我们来看下davinci_mmc_probe函数:

在这个函数总主要创建并初始化了两个结构体

       struct mmc_host *mmc;//用于DMA方式传输

       struct mmc_davinci_host *host = NULL;//irq 中断

 

函数原型:

1410  static int davinci_mmc_probe(struct platform_device *pdev)

  1411  {

  1412          struct davinci_mmc_platform_data *minfo = pdev->dev.platform_data;

  1413          struct mmc_host *mmc;//DMA

  1414          struct mmc_davinci_host *host = NULL;//irq

  1415          struct resource *res;

  1416          resource_size_t dma_rx_chan, dma_tx_chan, dma_eventq;

  1417          int ret = 0;

  1418          int irq;

  1419

  1420          if (minfo == NULL) {

  1421                  dev_err(&pdev->dev, "platform data missing\n");

  1422                  return -ENODEV;

  1423          }

  1424                  //获取内存资源

  1425          res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

                //获取中断号

  1426          irq = platform_get_irq(pdev, 0);

  1427          if (res == NULL || irq < 0)

  1428                  return -ENODEV;

  1429                  //分配从start开始,n长度的内存

  1430          res = request_mem_region(res->start, res->end - res->start + 1,

  1431                                   pdev->name);

  1432          if (res == NULL)

  1433                  return -EBUSY;

  1434                  //分配sizeof(struct mmc_host)+extra这么大的空间,并做以下初始化

  1435          mmc = mmc_alloc_host(sizeof(struct mmc_davinci_host), &pdev->dev);

  1436          if (mmc == NULL) {

  1437                  ret = -ENOMEM;

  1438                  goto err_free_mem_region;

  1439          }

  1440

  1441          host = mmc_priv(mmc);  //mmc转化为host

  1442          host->mmc = mmc;

  1443

  //*******************以下都在初始化host结构体****************************

  1444          spin_lock_init(&host->mmc_lock);

  1445

  1446          host->mem_res = res;  //MEM INFO

  1447          host->irq = irq;   //IRQ

  1448

  1449          host->phys_base = host->mem_res->start;  //MEM INFO START ADDR

  1450          host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base); //STARTADDR TO VIRTUAL ADDR

  1451

  1452          host->use_dma = 0; //不使能DMA

  1453  我们是需要使用DMA来传输的,下面是获取DMA相关的资源

  1454  #ifdef CONFIG_MMC_DAVINCI_DMA

  1455    dma_rx_chan = mmc_get_dma_resource(pdev, IORESOURCE_DMA_RX_CHAN);

  1456          if (dma_rx_chan >= 0) {

  1457                  host->dma_rx_event = dma_rx_chan;//dma recv start address

  1458                  dma_tx_chan = mmc_get_dma_resource(pdev,

  1459                                                     IORESOURCE_DMA_TX_CHAN);

  1460                  if (dma_tx_chan >= 0) {

  1461                          host->dma_tx_event = dma_tx_chan; //dma snd start address

  1462                          dma_eventq = mmc_get_dma_resource(pdev,

  1463                                                  IORESOURCE_DMA_EVENT_Q);

  1464                          if (dma_eventq >= 0) {

  1465                                  host->queue_no = dma_eventq; //dma event quene start address

  如果获取前面的DMA资源都成功,那么使能DMA传输功能

  1466                                  host->use_dma = 1; //enable dma

  1467                          } else {

  1468                                  host->dma_tx_event = 0;

  1469                                  host->dma_rx_event = 0;

  1470                          }

  1471                  } else

  1472                          host->dma_rx_event = 0;

  1473          }

  1474  #endif

  1475          //获取host所需要的时钟

  1476          host->clk = clk_get(&pdev->dev, minfo->mmc_clk);

  1477          if (IS_ERR(host->clk)) {

  1478                  ret = -ENODEV;

  1479                  goto err_free_mmc_host;

  1480          }

  1481

  1482          ret = clk_enable(host->clk);//使能时钟

  1483          if (ret)

  1484                  goto err_put_clk;

  1485

  1486          init_mmcsd_host(host);  //write clock reg

  1487

  1488          if (minfo->use_8bit_mode) {

  1489                  dev_info(mmc->dev, "Supporting 8-bit mode\n");

  1490                  mmc->caps |= MMC_CAP_8_BIT_DATA;

  1491          }

  1492

  1493          if (minfo->use_4bit_mode) {

  1494                  dev_info(mmc->dev, "Supporting 4-bit mode\n");

  1495                  mmc->caps |= MMC_CAP_4_BIT_DATA;

  1496          }

  1497

  1498          if (!minfo->use_8bit_mode && !minfo->use_4bit_mode)

  1499                  dev_info(mmc->dev, "Supporting 1-bit mode\n");

  1500

  1501          host->get_ro = minfo->get_ro;

  1502

  1503          host->pio_set_dmatrig = minfo->pio_set_dmatrig;

  1504

  1505          host->rw_threshold = minfo->rw_threshold;

  1506

  1507          mmc->ops = &mmc_davinci_ops;//对应sd卡的操作请求,设置时钟,bus modebus宽带都是这里实现的

  1508          mmc->f_min = 312500;

  1509          if (minfo->max_frq)

  1510                  mmc->f_max = minfo->max_frq;

  1511          else

  1512                  mmc->f_max = 25000000;

  1513          mmc->ocr_avail = MMC_VDD_32_33;

  1514

  1518          mmc->max_phys_segs = EDMA_MAX_LOGICAL_CHA_ALLOWED + 1;

  1519          mmc->max_hw_segs = EDMA_MAX_LOGICAL_CHA_ALLOWED + 1;

  1520

  1521          mmc->max_sectors = 256;

  1522

  1523          /* Restrict the max size of seg we can handle */

  1524          mmc->max_seg_size = mmc->max_sectors * 512;  //128kB

  1525

  1526          dev_dbg(mmc->dev, "max_phys_segs=%d\n", mmc->max_phys_segs);

  1527          dev_dbg(mmc->dev, "max_hw_segs=%d\n", mmc->max_hw_segs);

  1528          dev_dbg(mmc->dev, "max_sect=%d\n", mmc->max_sectors);

  1529          dev_dbg(mmc->dev, "max_seg_size=%d\n", mmc->max_seg_size);

  1530

  1531          if (host->use_dma) {

  1532                  dev_info(mmc->dev, "Using DMA mode\n");

  1533                  ret = davinci_acquire_dma_channels(host);

  1534                  if (ret)

  1535                  {

  1536                          printk("MMC: Acquire dma channels fail!!!!!!!!!!\n");

  1537                          goto err_release_clk;

  1538                  }

  1539          } else {

  1540                  dev_info(mmc->dev, "Not Using DMA mode\n");

  1541          }

  1542          //这里启用了中断请求函数;mmc_davinci_irq

  1543          host->sd_support = 1;

  1544          ret = request_irq(host->irq, mmc_davinci_irq, 0, DRIVER_NAME, host);

  1545          if (ret)

  1546          {

  1547                  printk("MMC: IRQ register fail!!!!!!!!!!\n");

  1548                  goto err_release_dma;

  1549          }

  1550

  1551          host->dev = &pdev->dev;

  1552          platform_set_drvdata(pdev, host);//保存私有数据

  1553          mmc_add_host(mmc);

  1554          //初始化一个定时器,1HZ调用一次davinci_mmc_check_status函数去检查sd卡的状态

  1555          init_timer(&host->timer);

  1556          host->timer.data = (unsigned long)host;

  1557          host->timer.function = davinci_mmc_check_status;

  1558          host->timer.expires = jiffies + MULTIPLIER_TO_HZ * HZ;

  1559          add_timer(&host->timer);

  1560

  1561          return 0;

  1562

  1563  err_release_dma:

  1564          davinci_release_dma_channels(host);

  1565  err_release_clk:

  1566          clk_disable(host->clk);

  1567  err_put_clk:

  1568          clk_put(host->clk);

  1569  err_free_mmc_host:

  1570          mmc_free_host(mmc);

  1571  err_free_mem_region:

  1572          release_mem_region(res->start, res->end - res->start + 1);

  1573

  1574          return ret;

  1575  }