1 /* 2 * Synopsys DesignWare Multimedia Card Interface driver 3 * 4 * Copyright (C) 2009 NXP Semiconductors 5 * Copyright (C) 2009, 2010 Imagination Technologies Ltd. 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 as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 13 #include <linux/interrupt.h> 14 #include <linux/module.h> 15 #include <linux/io.h> 16 #include <linux/irq.h> 17 #include <linux/platform_device.h> 18 #include <linux/slab.h> 19 #include <linux/mmc/host.h> 20 #include <linux/mmc/mmc.h> 21 #include <linux/mmc/dw_mmc.h> 22 #include "dw_mmc.h" 23 24 static int __devinit dw_mci_pltfm_probe(struct platform_device *pdev) 25 { 26 struct dw_mci *host; 27 struct resource *regs; 28 int ret; 29 30 host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL); 31 if (!host) 32 return -ENOMEM; 33 34 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 35 if (!regs) 36 return -ENXIO; 37 38 host->irq = platform_get_irq(pdev, 0); 39 if (host->irq < 0) 40 return host->irq; 41 42 host->dev = &pdev->dev; 43 host->irq_flags = 0; 44 host->pdata = pdev->dev.platform_data; 45 host->regs = devm_request_and_ioremap(&pdev->dev, regs); 46 if (!host->regs) 47 return -ENOMEM; 48 49 platform_set_drvdata(pdev, host); 50 ret = dw_mci_probe(host); 51 return ret; 52 } 53 54 static int __devexit dw_mci_pltfm_remove(struct platform_device *pdev) 55 { 56 struct dw_mci *host = platform_get_drvdata(pdev); 57 58 platform_set_drvdata(pdev, NULL); 59 dw_mci_remove(host); 60 return 0; 61 } 62 63 #ifdef CONFIG_PM_SLEEP 64 /* 65 * TODO: we should probably disable the clock to the card in the suspend path. 66 */ 67 static int dw_mci_pltfm_suspend(struct device *dev) 68 { 69 int ret; 70 struct dw_mci *host = dev_get_drvdata(dev); 71 72 ret = dw_mci_suspend(host); 73 if (ret) 74 return ret; 75 76 return 0; 77 } 78 79 static int dw_mci_pltfm_resume(struct device *dev) 80 { 81 int ret; 82 struct dw_mci *host = dev_get_drvdata(dev); 83 84 ret = dw_mci_resume(host); 85 if (ret) 86 return ret; 87 88 return 0; 89 } 90 #else 91 #define dw_mci_pltfm_suspend NULL 92 #define dw_mci_pltfm_resume NULL 93 #endif /* CONFIG_PM_SLEEP */ 94 95 static SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume); 96 97 static struct platform_driver dw_mci_pltfm_driver = { 98 .remove = __exit_p(dw_mci_pltfm_remove), 99 .driver = { 100 .name = "dw_mmc", 101 .pm = &dw_mci_pltfm_pmops, 102 }, 103 }; 104 105 static int __init dw_mci_init(void) 106 { 107 return platform_driver_probe(&dw_mci_pltfm_driver, dw_mci_pltfm_probe); 108 } 109 110 static void __exit dw_mci_exit(void) 111 { 112 platform_driver_unregister(&dw_mci_pltfm_driver); 113 } 114 115 module_init(dw_mci_init); 116 module_exit(dw_mci_exit); 117 118 MODULE_DESCRIPTION("DW Multimedia Card Interface driver"); 119 MODULE_AUTHOR("NXP Semiconductor VietNam"); 120 MODULE_AUTHOR("Imagination Technologies Ltd"); 121 MODULE_LICENSE("GPL v2"); 122