aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-08 17:06:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-08 17:06:53 -0400
commit212fe84a6f215c39795a76517c1c02114d428681 (patch)
tree4692680312616d6a5c562f2d494c12d21b697237 /drivers/misc
parent4a4743e840d06a5772be7c21110807165c5b3c9f (diff)
parent05301fe7de11dac87638f1728f8ee8b31bc1cf31 (diff)
Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups from Arnd Bergmann: "This time around, the cleanup branch contains mostly code removal. A number of board files for at91, imx and msm have become obsolete because of the DT conversion and are now ready to be removed. The OMAP platform has traditionally had its own DMA engine abstraction and as this is being phased out, a lot of the original code is now unused and can be removed as well. S3C24xx can be simplified now that the restart code is a proper device driver. Finally, a number of cleanups in shmobile are done to prepare for the addition of new code in other branches" * tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (43 commits) ARM: at91: Remove the support for the RSI EWS board arm: mach-omap2: Convert pr_warning to pr_warn ARM: OMAP: Remove unused pieces of legacy DMA API ARM: at91: remove board file for Acme Systems Fox G20 ARM: orion5x: Convert pr_warning to pr_warn ARM: S3C24XX: remove separate restart code ARM: EXYNOS: Do not calculate boot address twice ARM: sunxi: Remove sun4i reboot code from mach directory ARM: imx: Remove mach-mxt_td60 board file ARM: shmobile: armadillo800eva legacy: Use rmobile_add_devices_to_domains() ARM: shmobile: r8a7740: Clean up pm domain table ARM: shmobile: r8a7740: Use rmobile_add_devices_to_domains() ARM: shmobile: sh7372: Make domain_devices[] static __initdata ARM: shmobile: mackerel: Make domain_devices[] static __initdata clocksource: tcb_clksrc: sanitize IRQ request ARM: at91/tclib: mask interruptions at shutdown and probe ARM: at91/tclib: move initialization from alloc to probe ARM: at91/tclib: prefer using of devm_* functions ARM: clps711x: Switch CLPS711X subarch to use clk and clocksource driver ARM: shmobile: r8a7791 is now called "R-Car M2-W" ...
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/atmel_tclib.c101
1 files changed, 44 insertions, 57 deletions
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
index c8d8e38d0d8a..0ca05c3ec8d6 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,25 +108,27 @@ 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)) 112 unsigned int i;
147 return -EINVAL;
148 113
149 irq = platform_get_irq(pdev, 0); 114 irq = platform_get_irq(pdev, 0);
150 if (irq < 0) 115 if (irq < 0)
151 return -EINVAL; 116 return -EINVAL;
152 117
153 tc = kzalloc(sizeof(struct atmel_tc), GFP_KERNEL); 118 tc = devm_kzalloc(&pdev->dev, sizeof(struct atmel_tc), GFP_KERNEL);
154 if (!tc) 119 if (!tc)
155 return -ENOMEM; 120 return -ENOMEM;
156 121
157 tc->pdev = pdev; 122 tc->pdev = pdev;
158 123
159 clk = clk_get(&pdev->dev, "t0_clk"); 124 clk = devm_clk_get(&pdev->dev, "t0_clk");
160 if (IS_ERR(clk)) { 125 if (IS_ERR(clk))
161 kfree(tc); 126 return PTR_ERR(clk);
162 return -EINVAL; 127
163 } 128 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
129 tc->regs = devm_ioremap_resource(&pdev->dev, r);
130 if (IS_ERR(tc->regs))
131 return PTR_ERR(tc->regs);
164 132
165 /* Now take SoC information if available */ 133 /* Now take SoC information if available */
166 if (pdev->dev.of_node) { 134 if (pdev->dev.of_node) {
@@ -168,13 +136,17 @@ static int __init tc_probe(struct platform_device *pdev)
168 match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node); 136 match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node);
169 if (match) 137 if (match)
170 tc->tcb_config = match->data; 138 tc->tcb_config = match->data;
139
140 tc->id = of_alias_get_id(tc->pdev->dev.of_node, "tcb");
141 } else {
142 tc->id = pdev->id;
171 } 143 }
172 144
173 tc->clk[0] = clk; 145 tc->clk[0] = clk;
174 tc->clk[1] = clk_get(&pdev->dev, "t1_clk"); 146 tc->clk[1] = devm_clk_get(&pdev->dev, "t1_clk");
175 if (IS_ERR(tc->clk[1])) 147 if (IS_ERR(tc->clk[1]))
176 tc->clk[1] = clk; 148 tc->clk[1] = clk;
177 tc->clk[2] = clk_get(&pdev->dev, "t2_clk"); 149 tc->clk[2] = devm_clk_get(&pdev->dev, "t2_clk");
178 if (IS_ERR(tc->clk[2])) 150 if (IS_ERR(tc->clk[2]))
179 tc->clk[2] = clk; 151 tc->clk[2] = clk;
180 152
@@ -186,18 +158,33 @@ static int __init tc_probe(struct platform_device *pdev)
186 if (tc->irq[2] < 0) 158 if (tc->irq[2] < 0)
187 tc->irq[2] = irq; 159 tc->irq[2] = irq;
188 160
161 for (i = 0; i < 3; i++)
162 writel(ATMEL_TC_ALL_IRQ, tc->regs + ATMEL_TC_REG(i, IDR));
163
189 spin_lock(&tc_list_lock); 164 spin_lock(&tc_list_lock);
190 list_add_tail(&tc->node, &tc_list); 165 list_add_tail(&tc->node, &tc_list);
191 spin_unlock(&tc_list_lock); 166 spin_unlock(&tc_list_lock);
192 167
168 platform_set_drvdata(pdev, tc);
169
193 return 0; 170 return 0;
194} 171}
195 172
173static void tc_shutdown(struct platform_device *pdev)
174{
175 int i;
176 struct atmel_tc *tc = platform_get_drvdata(pdev);
177
178 for (i = 0; i < 3; i++)
179 writel(ATMEL_TC_ALL_IRQ, tc->regs + ATMEL_TC_REG(i, IDR));
180}
181
196static struct platform_driver tc_driver = { 182static struct platform_driver tc_driver = {
197 .driver = { 183 .driver = {
198 .name = "atmel_tcb", 184 .name = "atmel_tcb",
199 .of_match_table = of_match_ptr(atmel_tcb_dt_ids), 185 .of_match_table = of_match_ptr(atmel_tcb_dt_ids),
200 }, 186 },
187 .shutdown = tc_shutdown,
201}; 188};
202 189
203static int __init tc_init(void) 190static int __init tc_init(void)