aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorGaël PORTAY <gael.portay@gmail.com>2014-09-06 13:52:35 -0400
committerNicolas Ferre <nicolas.ferre@atmel.com>2014-09-08 04:54:03 -0400
commit4930d247af29f849cd1bddd65be2400684dc886e (patch)
tree8afec844dc080e009e2e1d52e59e1e72339fe2be /drivers/misc
parent8495497f921e73d5192d4896d55414f0304d8561 (diff)
ARM: at91/tclib: move initialization from alloc to probe
Move resource retrieval from atmel_tc_alloc to tc_probe to avoid lately reporting resource related issues when a TC block user request a TC block. Moreover, resources retrieval are usually done in the probe function, thus moving them add some consistency with other drivers. Initialization is done once, ie not every time a tc block is requested. If it fails, the device is not appended to the list of tc blocks. Furhermore, the device id is retrieved at probe as well, avoiding parsing DT every time the user requests of tc block. Signed-off-by: Gaël PORTAY <gael.portay@gmail.com> Acked-by: Thierry Reding <thierry.reding@gmail.com> Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/atmel_tclib.c71
1 files changed, 22 insertions, 49 deletions
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
index b514a2d4485b..d505d1e0857b 100644
--- a/drivers/misc/atmel_tclib.c
+++ b/drivers/misc/atmel_tclib.c
@@ -35,60 +35,31 @@ static LIST_HEAD(tc_list);
35/** 35/**
36 * atmel_tc_alloc - allocate a specified TC block 36 * atmel_tc_alloc - allocate a specified TC block
37 * @block: which block to allocate 37 * @block: which block to allocate
38 * @name: name to be associated with the iomem resource
39 * 38 *
40 * Caller allocates a block. If it is available, a pointer to a 39 * Caller allocates a block. If it is available, a pointer to a
41 * pre-initialized struct atmel_tc is returned. The caller can access 40 * pre-initialized struct atmel_tc is returned. The caller can access
42 * the registers directly through the "regs" field. 41 * the registers directly through the "regs" field.
43 */ 42 */
44struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name) 43struct atmel_tc *atmel_tc_alloc(unsigned block)
45{ 44{
46 struct atmel_tc *tc; 45 struct atmel_tc *tc;
47 struct platform_device *pdev = NULL; 46 struct platform_device *pdev = NULL;
48 struct resource *r;
49 size_t size;
50 47
51 spin_lock(&tc_list_lock); 48 spin_lock(&tc_list_lock);
52 list_for_each_entry(tc, &tc_list, node) { 49 list_for_each_entry(tc, &tc_list, node) {
53 if (tc->pdev->dev.of_node) { 50 if (tc->allocated)
54 if (of_alias_get_id(tc->pdev->dev.of_node, "tcb") 51 continue;
55 == block) { 52
56 pdev = tc->pdev; 53 if ((tc->pdev->dev.of_node && tc->id == block) ||
57 break; 54 (tc->pdev->id == block)) {
58 }
59 } else if (tc->pdev->id == block) {
60 pdev = tc->pdev; 55 pdev = tc->pdev;
56 tc->allocated = true;
61 break; 57 break;
62 } 58 }
63 } 59 }
64
65 if (!pdev || tc->iomem)
66 goto fail;
67
68 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
69 if (!r)
70 goto fail;
71
72 size = resource_size(r);
73 r = request_mem_region(r->start, size, name);
74 if (!r)
75 goto fail;
76
77 tc->regs = ioremap(r->start, size);
78 if (!tc->regs)
79 goto fail_ioremap;
80
81 tc->iomem = r;
82
83out:
84 spin_unlock(&tc_list_lock); 60 spin_unlock(&tc_list_lock);
85 return tc;
86 61
87fail_ioremap: 62 return pdev ? tc : NULL;
88 release_mem_region(r->start, size);
89fail:
90 tc = NULL;
91 goto out;
92} 63}
93EXPORT_SYMBOL_GPL(atmel_tc_alloc); 64EXPORT_SYMBOL_GPL(atmel_tc_alloc);
94 65
@@ -96,19 +67,14 @@ EXPORT_SYMBOL_GPL(atmel_tc_alloc);
96 * atmel_tc_free - release a specified TC block 67 * atmel_tc_free - release a specified TC block
97 * @tc: Timer/counter block that was returned by atmel_tc_alloc() 68 * @tc: Timer/counter block that was returned by atmel_tc_alloc()
98 * 69 *
99 * This reverses the effect of atmel_tc_alloc(), unmapping the I/O 70 * This reverses the effect of atmel_tc_alloc(), invalidating the resource
100 * registers, invalidating the resource returned by that routine and 71 * returned by that routine and making the TC available to other drivers.
101 * making the TC available to other drivers.
102 */ 72 */
103void atmel_tc_free(struct atmel_tc *tc) 73void atmel_tc_free(struct atmel_tc *tc)
104{ 74{
105 spin_lock(&tc_list_lock); 75 spin_lock(&tc_list_lock);
106 if (tc->regs) { 76 if (tc->allocated)
107 iounmap(tc->regs); 77 tc->allocated = false;
108 release_mem_region(tc->iomem->start, resource_size(tc->iomem));
109 tc->regs = NULL;
110 tc->iomem = NULL;
111 }
112 spin_unlock(&tc_list_lock); 78 spin_unlock(&tc_list_lock);
113} 79}
114EXPORT_SYMBOL_GPL(atmel_tc_free); 80EXPORT_SYMBOL_GPL(atmel_tc_free);
@@ -142,9 +108,7 @@ static int __init tc_probe(struct platform_device *pdev)
142 struct atmel_tc *tc; 108 struct atmel_tc *tc;
143 struct clk *clk; 109 struct clk *clk;
144 int irq; 110 int irq;
145 111 struct resource *r;
146 if (!platform_get_resource(pdev, IORESOURCE_MEM, 0))
147 return -EINVAL;
148 112
149 irq = platform_get_irq(pdev, 0); 113 irq = platform_get_irq(pdev, 0);
150 if (irq < 0) 114 if (irq < 0)
@@ -160,12 +124,21 @@ static int __init tc_probe(struct platform_device *pdev)
160 if (IS_ERR(clk)) 124 if (IS_ERR(clk))
161 return PTR_ERR(clk); 125 return PTR_ERR(clk);
162 126
127 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
128 tc->regs = devm_ioremap_resource(&pdev->dev, r);
129 if (IS_ERR(tc->regs))
130 return PTR_ERR(tc->regs);
131
163 /* Now take SoC information if available */ 132 /* Now take SoC information if available */
164 if (pdev->dev.of_node) { 133 if (pdev->dev.of_node) {
165 const struct of_device_id *match; 134 const struct of_device_id *match;
166 match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node); 135 match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node);
167 if (match) 136 if (match)
168 tc->tcb_config = match->data; 137 tc->tcb_config = match->data;
138
139 tc->id = of_alias_get_id(tc->pdev->dev.of_node, "tcb");
140 } else {
141 tc->id = pdev->id;
169 } 142 }
170 143
171 tc->clk[0] = clk; 144 tc->clk[0] = clk;