aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2013-06-27 00:31:54 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-06-28 16:11:28 -0400
commit2953f850c3b80bdca004967c83733365d8aa0aa2 (patch)
treede80e56c2a9f42ab51bb50d05c40c31ed643a454 /drivers/scsi
parent3ca316c582ddf11944806a27e460e7bd8f61a968 (diff)
[SCSI] ufs: use devres functions for ufshcd
This patch replaces normal calls for resource allocation with devm_*() derivative functions. It makes resource freeing simpler. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Signed-off-by: Santosh Y <santoshsy@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ufs/ufshcd-pci.c1
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c72
-rw-r--r--drivers/scsi/ufs/ufshcd.c86
3 files changed, 39 insertions, 120 deletions
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c
index 5cb1d75f5868..48be39a6f6d7 100644
--- a/drivers/scsi/ufs/ufshcd-pci.c
+++ b/drivers/scsi/ufs/ufshcd-pci.c
@@ -92,7 +92,6 @@ static void ufshcd_pci_remove(struct pci_dev *pdev)
92 struct ufs_hba *hba = pci_get_drvdata(pdev); 92 struct ufs_hba *hba = pci_get_drvdata(pdev);
93 93
94 disable_irq(pdev->irq); 94 disable_irq(pdev->irq);
95 free_irq(pdev->irq, hba);
96 ufshcd_remove(hba); 95 ufshcd_remove(hba);
97 pci_release_regions(pdev); 96 pci_release_regions(pdev);
98 pci_set_drvdata(pdev, NULL); 97 pci_set_drvdata(pdev, NULL);
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index 3db2ee1a38bd..0e48827c86bd 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -33,9 +33,10 @@
33 * this program. 33 * this program.
34 */ 34 */
35 35
36#include "ufshcd.h"
37#include <linux/platform_device.h> 36#include <linux/platform_device.h>
38 37
38#include "ufshcd.h"
39
39#ifdef CONFIG_PM 40#ifdef CONFIG_PM
40/** 41/**
41 * ufshcd_pltfrm_suspend - suspend power management function 42 * ufshcd_pltfrm_suspend - suspend power management function
@@ -97,62 +98,45 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
97 struct ufs_hba *hba; 98 struct ufs_hba *hba;
98 void __iomem *mmio_base; 99 void __iomem *mmio_base;
99 struct resource *mem_res; 100 struct resource *mem_res;
100 struct resource *irq_res; 101 int irq, err;
101 resource_size_t mem_size;
102 int err;
103 struct device *dev = &pdev->dev; 102 struct device *dev = &pdev->dev;
104 103
105 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 104 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
106 if (!mem_res) { 105 if (!mem_res) {
107 dev_err(&pdev->dev, 106 dev_err(dev, "Memory resource not available\n");
108 "Memory resource not available\n");
109 err = -ENODEV; 107 err = -ENODEV;
110 goto out_error; 108 goto out;
111 } 109 }
112 110
113 mem_size = resource_size(mem_res); 111 mmio_base = devm_ioremap_resource(dev, mem_res);
114 if (!request_mem_region(mem_res->start, mem_size, "ufshcd")) { 112 if (IS_ERR(mmio_base)) {
115 dev_err(&pdev->dev, 113 dev_err(dev, "memory map failed\n");
116 "Cannot reserve the memory resource\n"); 114 err = PTR_ERR(mmio_base);
117 err = -EBUSY; 115 goto out;
118 goto out_error;
119 } 116 }
120 117
121 mmio_base = ioremap_nocache(mem_res->start, mem_size); 118 irq = platform_get_irq(pdev, 0);
122 if (!mmio_base) { 119 if (irq < 0) {
123 dev_err(&pdev->dev, "memory map failed\n"); 120 dev_err(dev, "IRQ resource not available\n");
124 err = -ENOMEM;
125 goto out_release_regions;
126 }
127
128 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
129 if (!irq_res) {
130 dev_err(&pdev->dev, "IRQ resource not available\n");
131 err = -ENODEV; 121 err = -ENODEV;
132 goto out_iounmap; 122 goto out;
133 } 123 }
134 124
135 err = dma_set_coherent_mask(dev, dev->coherent_dma_mask); 125 err = dma_set_coherent_mask(dev, dev->coherent_dma_mask);
136 if (err) { 126 if (err) {
137 dev_err(&pdev->dev, "set dma mask failed\n"); 127 dev_err(dev, "set dma mask failed\n");
138 goto out_iounmap; 128 goto out;
139 } 129 }
140 130
141 err = ufshcd_init(&pdev->dev, &hba, mmio_base, irq_res->start); 131 err = ufshcd_init(dev, &hba, mmio_base, irq);
142 if (err) { 132 if (err) {
143 dev_err(&pdev->dev, "Intialization failed\n"); 133 dev_err(dev, "Intialization failed\n");
144 goto out_iounmap; 134 goto out;
145 } 135 }
146 136
147 platform_set_drvdata(pdev, hba); 137 platform_set_drvdata(pdev, hba);
148 138
149 return 0; 139out:
150
151out_iounmap:
152 iounmap(mmio_base);
153out_release_regions:
154 release_mem_region(mem_res->start, mem_size);
155out_error:
156 return err; 140 return err;
157} 141}
158 142
@@ -164,26 +148,10 @@ out_error:
164 */ 148 */
165static int ufshcd_pltfrm_remove(struct platform_device *pdev) 149static int ufshcd_pltfrm_remove(struct platform_device *pdev)
166{ 150{
167 struct resource *mem_res;
168 resource_size_t mem_size;
169 struct ufs_hba *hba = platform_get_drvdata(pdev); 151 struct ufs_hba *hba = platform_get_drvdata(pdev);
170 152
171 disable_irq(hba->irq); 153 disable_irq(hba->irq);
172
173 /* Some buggy controllers raise interrupt after
174 * the resources are removed. So first we unregister the
175 * irq handler and then the resources used by driver
176 */
177
178 free_irq(hba->irq, hba);
179 ufshcd_remove(hba); 154 ufshcd_remove(hba);
180 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
181 if (!mem_res)
182 dev_err(&pdev->dev, "ufshcd: Memory resource not available\n");
183 else {
184 mem_size = resource_size(mem_res);
185 release_mem_region(mem_res->start, mem_size);
186 }
187 return 0; 155 return 0;
188} 156}
189 157
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2230f1412d88..aba461f0f11c 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -191,38 +191,6 @@ static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba)
191} 191}
192 192
193/** 193/**
194 * ufshcd_free_hba_memory - Free allocated memory for LRB, request
195 * and task lists
196 * @hba: Pointer to adapter instance
197 */
198static inline void ufshcd_free_hba_memory(struct ufs_hba *hba)
199{
200 size_t utmrdl_size, utrdl_size, ucdl_size;
201
202 kfree(hba->lrb);
203
204 if (hba->utmrdl_base_addr) {
205 utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs;
206 dma_free_coherent(hba->dev, utmrdl_size,
207 hba->utmrdl_base_addr, hba->utmrdl_dma_addr);
208 }
209
210 if (hba->utrdl_base_addr) {
211 utrdl_size =
212 (sizeof(struct utp_transfer_req_desc) * hba->nutrs);
213 dma_free_coherent(hba->dev, utrdl_size,
214 hba->utrdl_base_addr, hba->utrdl_dma_addr);
215 }
216
217 if (hba->ucdl_base_addr) {
218 ucdl_size =
219 (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs);
220 dma_free_coherent(hba->dev, ucdl_size,
221 hba->ucdl_base_addr, hba->ucdl_dma_addr);
222 }
223}
224
225/**
226 * ufshcd_is_valid_req_rsp - checks if controller TR response is valid 194 * ufshcd_is_valid_req_rsp - checks if controller TR response is valid
227 * @ucd_rsp_ptr: pointer to response UPIU 195 * @ucd_rsp_ptr: pointer to response UPIU
228 * 196 *
@@ -690,10 +658,10 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
690 658
691 /* Allocate memory for UTP command descriptors */ 659 /* Allocate memory for UTP command descriptors */
692 ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs); 660 ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs);
693 hba->ucdl_base_addr = dma_alloc_coherent(hba->dev, 661 hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev,
694 ucdl_size, 662 ucdl_size,
695 &hba->ucdl_dma_addr, 663 &hba->ucdl_dma_addr,
696 GFP_KERNEL); 664 GFP_KERNEL);
697 665
698 /* 666 /*
699 * UFSHCI requires UTP command descriptor to be 128 byte aligned. 667 * UFSHCI requires UTP command descriptor to be 128 byte aligned.
@@ -713,10 +681,10 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
713 * UFSHCI requires 1024 byte alignment of UTRD 681 * UFSHCI requires 1024 byte alignment of UTRD
714 */ 682 */
715 utrdl_size = (sizeof(struct utp_transfer_req_desc) * hba->nutrs); 683 utrdl_size = (sizeof(struct utp_transfer_req_desc) * hba->nutrs);
716 hba->utrdl_base_addr = dma_alloc_coherent(hba->dev, 684 hba->utrdl_base_addr = dmam_alloc_coherent(hba->dev,
717 utrdl_size, 685 utrdl_size,
718 &hba->utrdl_dma_addr, 686 &hba->utrdl_dma_addr,
719 GFP_KERNEL); 687 GFP_KERNEL);
720 if (!hba->utrdl_base_addr || 688 if (!hba->utrdl_base_addr ||
721 WARN_ON(hba->utrdl_dma_addr & (PAGE_SIZE - 1))) { 689 WARN_ON(hba->utrdl_dma_addr & (PAGE_SIZE - 1))) {
722 dev_err(hba->dev, 690 dev_err(hba->dev,
@@ -729,10 +697,10 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
729 * UFSHCI requires 1024 byte alignment of UTMRD 697 * UFSHCI requires 1024 byte alignment of UTMRD
730 */ 698 */
731 utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs; 699 utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs;
732 hba->utmrdl_base_addr = dma_alloc_coherent(hba->dev, 700 hba->utmrdl_base_addr = dmam_alloc_coherent(hba->dev,
733 utmrdl_size, 701 utmrdl_size,
734 &hba->utmrdl_dma_addr, 702 &hba->utmrdl_dma_addr,
735 GFP_KERNEL); 703 GFP_KERNEL);
736 if (!hba->utmrdl_base_addr || 704 if (!hba->utmrdl_base_addr ||
737 WARN_ON(hba->utmrdl_dma_addr & (PAGE_SIZE - 1))) { 705 WARN_ON(hba->utmrdl_dma_addr & (PAGE_SIZE - 1))) {
738 dev_err(hba->dev, 706 dev_err(hba->dev,
@@ -741,14 +709,15 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
741 } 709 }
742 710
743 /* Allocate memory for local reference block */ 711 /* Allocate memory for local reference block */
744 hba->lrb = kcalloc(hba->nutrs, sizeof(struct ufshcd_lrb), GFP_KERNEL); 712 hba->lrb = devm_kzalloc(hba->dev,
713 hba->nutrs * sizeof(struct ufshcd_lrb),
714 GFP_KERNEL);
745 if (!hba->lrb) { 715 if (!hba->lrb) {
746 dev_err(hba->dev, "LRB Memory allocation failed\n"); 716 dev_err(hba->dev, "LRB Memory allocation failed\n");
747 goto out; 717 goto out;
748 } 718 }
749 return 0; 719 return 0;
750out: 720out:
751 ufshcd_free_hba_memory(hba);
752 return -ENOMEM; 721 return -ENOMEM;
753} 722}
754 723
@@ -1682,17 +1651,6 @@ int ufshcd_resume(struct ufs_hba *hba)
1682EXPORT_SYMBOL_GPL(ufshcd_resume); 1651EXPORT_SYMBOL_GPL(ufshcd_resume);
1683 1652
1684/** 1653/**
1685 * ufshcd_hba_free - free allocated memory for
1686 * host memory space data structures
1687 * @hba: per adapter instance
1688 */
1689static void ufshcd_hba_free(struct ufs_hba *hba)
1690{
1691 iounmap(hba->mmio_base);
1692 ufshcd_free_hba_memory(hba);
1693}
1694
1695/**
1696 * ufshcd_remove - de-allocate SCSI host and host memory space 1654 * ufshcd_remove - de-allocate SCSI host and host memory space
1697 * data structure memory 1655 * data structure memory
1698 * @hba - per adapter instance 1656 * @hba - per adapter instance
@@ -1701,9 +1659,7 @@ void ufshcd_remove(struct ufs_hba *hba)
1701{ 1659{
1702 /* disable interrupts */ 1660 /* disable interrupts */
1703 ufshcd_disable_intr(hba, hba->intr_mask); 1661 ufshcd_disable_intr(hba, hba->intr_mask);
1704
1705 ufshcd_hba_stop(hba); 1662 ufshcd_hba_stop(hba);
1706 ufshcd_hba_free(hba);
1707 1663
1708 scsi_remove_host(hba->host); 1664 scsi_remove_host(hba->host);
1709 scsi_host_put(hba->host); 1665 scsi_host_put(hba->host);
@@ -1789,23 +1745,23 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
1789 mutex_init(&hba->uic_cmd_mutex); 1745 mutex_init(&hba->uic_cmd_mutex);
1790 1746
1791 /* IRQ registration */ 1747 /* IRQ registration */
1792 err = request_irq(irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); 1748 err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
1793 if (err) { 1749 if (err) {
1794 dev_err(hba->dev, "request irq failed\n"); 1750 dev_err(hba->dev, "request irq failed\n");
1795 goto out_lrb_free; 1751 goto out_disable;
1796 } 1752 }
1797 1753
1798 /* Enable SCSI tag mapping */ 1754 /* Enable SCSI tag mapping */
1799 err = scsi_init_shared_tag_map(host, host->can_queue); 1755 err = scsi_init_shared_tag_map(host, host->can_queue);
1800 if (err) { 1756 if (err) {
1801 dev_err(hba->dev, "init shared queue failed\n"); 1757 dev_err(hba->dev, "init shared queue failed\n");
1802 goto out_free_irq; 1758 goto out_disable;
1803 } 1759 }
1804 1760
1805 err = scsi_add_host(host, hba->dev); 1761 err = scsi_add_host(host, hba->dev);
1806 if (err) { 1762 if (err) {
1807 dev_err(hba->dev, "scsi_add_host failed\n"); 1763 dev_err(hba->dev, "scsi_add_host failed\n");
1808 goto out_free_irq; 1764 goto out_disable;
1809 } 1765 }
1810 1766
1811 /* Host controller enable */ 1767 /* Host controller enable */
@@ -1823,10 +1779,6 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
1823 1779
1824out_remove_scsi_host: 1780out_remove_scsi_host:
1825 scsi_remove_host(hba->host); 1781 scsi_remove_host(hba->host);
1826out_free_irq:
1827 free_irq(irq, hba);
1828out_lrb_free:
1829 ufshcd_free_hba_memory(hba);
1830out_disable: 1782out_disable:
1831 scsi_host_put(host); 1783 scsi_host_put(host);
1832out_error: 1784out_error: