root/drivers/scsi/ufs/ufshcd-pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ufs_intel_disable_lcc
  2. ufs_intel_link_startup_notify
  3. ufshcd_pci_suspend
  4. ufshcd_pci_resume
  5. ufshcd_pci_runtime_suspend
  6. ufshcd_pci_runtime_resume
  7. ufshcd_pci_runtime_idle
  8. ufshcd_pci_shutdown
  9. ufshcd_pci_remove
  10. ufshcd_pci_probe

   1 /*
   2  * Universal Flash Storage Host controller PCI glue driver
   3  *
   4  * This code is based on drivers/scsi/ufs/ufshcd-pci.c
   5  * Copyright (C) 2011-2013 Samsung India Software Operations
   6  *
   7  * Authors:
   8  *      Santosh Yaraganavi <santosh.sy@samsung.com>
   9  *      Vinayak Holikatti <h.vinayak@samsung.com>
  10  *
  11  * This program is free software; you can redistribute it and/or
  12  * modify it under the terms of the GNU General Public License
  13  * as published by the Free Software Foundation; either version 2
  14  * of the License, or (at your option) any later version.
  15  * See the COPYING file in the top-level directory or visit
  16  * <http://www.gnu.org/licenses/gpl-2.0.html>
  17  *
  18  * This program is distributed in the hope that it will be useful,
  19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21  * GNU General Public License for more details.
  22  *
  23  * This program is provided "AS IS" and "WITH ALL FAULTS" and
  24  * without warranty of any kind. You are solely responsible for
  25  * determining the appropriateness of using and distributing
  26  * the program and assume all risks associated with your exercise
  27  * of rights with respect to the program, including but not limited
  28  * to infringement of third party rights, the risks and costs of
  29  * program errors, damage to or loss of data, programs or equipment,
  30  * and unavailability or interruption of operations. Under no
  31  * circumstances will the contributor of this Program be liable for
  32  * any damages of any kind arising from your use or distribution of
  33  * this program.
  34  */
  35 
  36 #include "ufshcd.h"
  37 #include <linux/pci.h>
  38 #include <linux/pm_runtime.h>
  39 
  40 static int ufs_intel_disable_lcc(struct ufs_hba *hba)
  41 {
  42         u32 attr = UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE);
  43         u32 lcc_enable = 0;
  44 
  45         ufshcd_dme_get(hba, attr, &lcc_enable);
  46         if (lcc_enable)
  47                 ufshcd_dme_set(hba, attr, 0);
  48 
  49         return 0;
  50 }
  51 
  52 static int ufs_intel_link_startup_notify(struct ufs_hba *hba,
  53                                          enum ufs_notify_change_status status)
  54 {
  55         int err = 0;
  56 
  57         switch (status) {
  58         case PRE_CHANGE:
  59                 err = ufs_intel_disable_lcc(hba);
  60                 break;
  61         case POST_CHANGE:
  62                 break;
  63         default:
  64                 break;
  65         }
  66 
  67         return err;
  68 }
  69 
  70 static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = {
  71         .name                   = "intel-pci",
  72         .link_startup_notify    = ufs_intel_link_startup_notify,
  73 };
  74 
  75 #ifdef CONFIG_PM_SLEEP
  76 /**
  77  * ufshcd_pci_suspend - suspend power management function
  78  * @dev: pointer to PCI device handle
  79  *
  80  * Returns 0 if successful
  81  * Returns non-zero otherwise
  82  */
  83 static int ufshcd_pci_suspend(struct device *dev)
  84 {
  85         return ufshcd_system_suspend(dev_get_drvdata(dev));
  86 }
  87 
  88 /**
  89  * ufshcd_pci_resume - resume power management function
  90  * @dev: pointer to PCI device handle
  91  *
  92  * Returns 0 if successful
  93  * Returns non-zero otherwise
  94  */
  95 static int ufshcd_pci_resume(struct device *dev)
  96 {
  97         return ufshcd_system_resume(dev_get_drvdata(dev));
  98 }
  99 #endif /* !CONFIG_PM_SLEEP */
 100 
 101 #ifdef CONFIG_PM
 102 static int ufshcd_pci_runtime_suspend(struct device *dev)
 103 {
 104         return ufshcd_runtime_suspend(dev_get_drvdata(dev));
 105 }
 106 static int ufshcd_pci_runtime_resume(struct device *dev)
 107 {
 108         return ufshcd_runtime_resume(dev_get_drvdata(dev));
 109 }
 110 static int ufshcd_pci_runtime_idle(struct device *dev)
 111 {
 112         return ufshcd_runtime_idle(dev_get_drvdata(dev));
 113 }
 114 #endif /* !CONFIG_PM */
 115 
 116 /**
 117  * ufshcd_pci_shutdown - main function to put the controller in reset state
 118  * @pdev: pointer to PCI device handle
 119  */
 120 static void ufshcd_pci_shutdown(struct pci_dev *pdev)
 121 {
 122         ufshcd_shutdown((struct ufs_hba *)pci_get_drvdata(pdev));
 123 }
 124 
 125 /**
 126  * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space
 127  *              data structure memory
 128  * @pdev: pointer to PCI handle
 129  */
 130 static void ufshcd_pci_remove(struct pci_dev *pdev)
 131 {
 132         struct ufs_hba *hba = pci_get_drvdata(pdev);
 133 
 134         pm_runtime_forbid(&pdev->dev);
 135         pm_runtime_get_noresume(&pdev->dev);
 136         ufshcd_remove(hba);
 137         ufshcd_dealloc_host(hba);
 138 }
 139 
 140 /**
 141  * ufshcd_pci_probe - probe routine of the driver
 142  * @pdev: pointer to PCI device handle
 143  * @id: PCI device id
 144  *
 145  * Returns 0 on success, non-zero value on failure
 146  */
 147 static int
 148 ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 149 {
 150         struct ufs_hba *hba;
 151         void __iomem *mmio_base;
 152         int err;
 153 
 154         err = pcim_enable_device(pdev);
 155         if (err) {
 156                 dev_err(&pdev->dev, "pcim_enable_device failed\n");
 157                 return err;
 158         }
 159 
 160         pci_set_master(pdev);
 161 
 162         err = pcim_iomap_regions(pdev, 1 << 0, UFSHCD);
 163         if (err < 0) {
 164                 dev_err(&pdev->dev, "request and iomap failed\n");
 165                 return err;
 166         }
 167 
 168         mmio_base = pcim_iomap_table(pdev)[0];
 169 
 170         err = ufshcd_alloc_host(&pdev->dev, &hba);
 171         if (err) {
 172                 dev_err(&pdev->dev, "Allocation failed\n");
 173                 return err;
 174         }
 175 
 176         hba->vops = (struct ufs_hba_variant_ops *)id->driver_data;
 177 
 178         err = ufshcd_init(hba, mmio_base, pdev->irq);
 179         if (err) {
 180                 dev_err(&pdev->dev, "Initialization failed\n");
 181                 ufshcd_dealloc_host(hba);
 182                 return err;
 183         }
 184 
 185         pci_set_drvdata(pdev, hba);
 186         pm_runtime_put_noidle(&pdev->dev);
 187         pm_runtime_allow(&pdev->dev);
 188 
 189         return 0;
 190 }
 191 
 192 static const struct dev_pm_ops ufshcd_pci_pm_ops = {
 193         SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend,
 194                                 ufshcd_pci_resume)
 195         SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend,
 196                            ufshcd_pci_runtime_resume,
 197                            ufshcd_pci_runtime_idle)
 198 };
 199 
 200 static const struct pci_device_id ufshcd_pci_tbl[] = {
 201         { PCI_VENDOR_ID_SAMSUNG, 0xC00C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 202         { PCI_VDEVICE(INTEL, 0x9DFA), (kernel_ulong_t)&ufs_intel_cnl_hba_vops },
 203         { PCI_VDEVICE(INTEL, 0x4B41), (kernel_ulong_t)&ufs_intel_cnl_hba_vops },
 204         { PCI_VDEVICE(INTEL, 0x4B43), (kernel_ulong_t)&ufs_intel_cnl_hba_vops },
 205         { }     /* terminate list */
 206 };
 207 
 208 MODULE_DEVICE_TABLE(pci, ufshcd_pci_tbl);
 209 
 210 static struct pci_driver ufshcd_pci_driver = {
 211         .name = UFSHCD,
 212         .id_table = ufshcd_pci_tbl,
 213         .probe = ufshcd_pci_probe,
 214         .remove = ufshcd_pci_remove,
 215         .shutdown = ufshcd_pci_shutdown,
 216         .driver = {
 217                 .pm = &ufshcd_pci_pm_ops
 218         },
 219 };
 220 
 221 module_pci_driver(ufshcd_pci_driver);
 222 
 223 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
 224 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
 225 MODULE_DESCRIPTION("UFS host controller PCI glue driver");
 226 MODULE_LICENSE("GPL");
 227 MODULE_VERSION(UFSHCD_DRIVER_VERSION);

/* [<][>][^][v][top][bottom][index][help] */