LCOV - code coverage report
Current view: top level - lkbce/drivers/mmc/core - host.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 7 59 11.9 %
Date: 2017-01-25 Functions: 2 7 28.6 %

          Line data    Source code
       1             : /*
       2             :  *  linux/drivers/mmc/core/host.c
       3             :  *
       4             :  *  Copyright (C) 2003 Russell King, All Rights Reserved.
       5             :  *  Copyright (C) 2007-2008 Pierre Ossman
       6             :  *
       7             :  * This program is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License version 2 as
       9             :  * published by the Free Software Foundation.
      10             :  *
      11             :  *  MMC host class device management
      12             :  */
      13             : 
      14             : #include <linux/device.h>
      15             : #include <linux/err.h>
      16             : #include <linux/idr.h>
      17             : #include <linux/pagemap.h>
      18             : #include <linux/leds.h>
      19             : 
      20             : #include <linux/mmc/host.h>
      21             : 
      22             : #include "core.h"
      23             : #include "host.h"
      24             : 
      25             : #define cls_dev_to_mmc_host(d)  container_of(d, struct mmc_host, class_dev)
      26             : 
      27             : static void mmc_host_classdev_release(struct device *dev)
      28             : {
      29           0 :         struct mmc_host *host = cls_dev_to_mmc_host(dev);
      30           0 :         kfree(host);
      31           0 : }
      32             : 
      33           1 : static struct class mmc_host_class = {
      34             :         .name           = "mmc_host",
      35             :         .dev_release    = mmc_host_classdev_release,
      36             : };
      37             : 
      38             : int mmc_register_host_class(void)
      39             : {
      40           3 :         return class_register(&mmc_host_class);
      41           1 : }
      42             : 
      43             : void mmc_unregister_host_class(void)
      44             : {
      45           3 :         class_unregister(&mmc_host_class);
      46           3 : }
      47             : 
      48           1 : static DEFINE_IDR(mmc_host_idr);
      49           1 : static DEFINE_SPINLOCK(mmc_host_lock);
      50             : 
      51             : /**
      52             :  *      mmc_alloc_host - initialise the per-host structure.
      53             :  *      @extra: sizeof private data structure
      54             :  *      @dev: pointer to host device model structure
      55             :  *
      56             :  *      Initialise the per-host structure.
      57             :  */
      58             : struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
      59             : {
      60           0 :         int err;
      61           0 :         struct mmc_host *host;
      62           0 : 
      63           0 :         if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
      64           0 :                 return NULL;
      65           0 : 
      66           0 :         host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
      67           0 :         if (!host)
      68           0 :                 return NULL;
      69             : 
      70           0 :         spin_lock(&mmc_host_lock);
      71           0 :         err = idr_get_new(&mmc_host_idr, host, &host->index);
      72           0 :         spin_unlock(&mmc_host_lock);
      73           0 :         if (err)
      74           0 :                 goto free;
      75             : 
      76           0 :         dev_set_name(&host->class_dev, "mmc%d", host->index);
      77             : 
      78           0 :         host->parent = dev;
      79           0 :         host->class_dev.parent = dev;
      80           0 :         host->class_dev.class = &mmc_host_class;
      81           0 :         device_initialize(&host->class_dev);
      82             : 
      83           0 :         spin_lock_init(&host->lock);
      84           0 :         init_waitqueue_head(&host->wq);
      85           0 :         INIT_DELAYED_WORK(&host->detect, mmc_rescan);
      86           0 :         INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable);
      87             : 
      88             :         /*
      89             :          * By default, hosts do not support SGIO or large requests.
      90             :          * They have to set these according to their abilities.
      91             :          */
      92           0 :         host->max_hw_segs = 1;
      93           0 :         host->max_phys_segs = 1;
      94           0 :         host->max_seg_size = PAGE_CACHE_SIZE;
      95             : 
      96           0 :         host->max_req_size = PAGE_CACHE_SIZE;
      97           0 :         host->max_blk_size = 512;
      98           0 :         host->max_blk_count = PAGE_CACHE_SIZE / 512;
      99             : 
     100           0 :         return host;
     101           0 : 
     102             : free:
     103           0 :         kfree(host);
     104           0 :         return NULL;
     105             : }
     106             : 
     107             : EXPORT_SYMBOL(mmc_alloc_host);
     108             : 
     109             : /**
     110             :  *      mmc_add_host - initialise host hardware
     111             :  *      @host: mmc host
     112             :  *
     113             :  *      Register the host with the driver model. The host must be
     114             :  *      prepared to start servicing requests before this function
     115             :  *      completes.
     116             :  */
     117             : int mmc_add_host(struct mmc_host *host)
     118             : {
     119           0 :         int err;
     120           0 : 
     121           0 :         WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
     122             :                 !host->ops->enable_sdio_irq);
     123             : 
     124             :         led_trigger_register_simple(dev_name(&host->class_dev), &host->led);
     125             : 
     126           0 :         err = device_add(&host->class_dev);
     127           0 :         if (err)
     128           0 :                 return err;
     129             : 
     130             : #ifdef CONFIG_DEBUG_FS
     131             :         mmc_add_host_debugfs(host);
     132             : #endif
     133             : 
     134           0 :         mmc_start_host(host);
     135             : 
     136           0 :         return 0;
     137             : }
     138             : 
     139             : EXPORT_SYMBOL(mmc_add_host);
     140             : 
     141             : /**
     142             :  *      mmc_remove_host - remove host hardware
     143             :  *      @host: mmc host
     144             :  *
     145             :  *      Unregister and remove all cards associated with this host,
     146             :  *      and power down the MMC bus. No new requests will be issued
     147             :  *      after this function has returned.
     148             :  */
     149             : void mmc_remove_host(struct mmc_host *host)
     150             : {
     151           0 :         mmc_stop_host(host);
     152             : 
     153             : #ifdef CONFIG_DEBUG_FS
     154             :         mmc_remove_host_debugfs(host);
     155             : #endif
     156             : 
     157           0 :         device_del(&host->class_dev);
     158           0 : 
     159             :         led_trigger_unregister_simple(host->led);
     160             : }
     161             : 
     162             : EXPORT_SYMBOL(mmc_remove_host);
     163             : 
     164             : /**
     165             :  *      mmc_free_host - free the host structure
     166             :  *      @host: mmc host
     167             :  *
     168             :  *      Free the host once all references to it have been dropped.
     169             :  */
     170             : void mmc_free_host(struct mmc_host *host)
     171             : {
     172           0 :         spin_lock(&mmc_host_lock);
     173           0 :         idr_remove(&mmc_host_idr, host->index);
     174           0 :         spin_unlock(&mmc_host_lock);
     175             : 
     176           0 :         put_device(&host->class_dev);
     177           0 : }
     178             : 
     179             : EXPORT_SYMBOL(mmc_free_host);
     180             : 

Generated by: LCOV version 1.10