4 * Copyright (C) 2007 Atmel Corporation
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/platform_device.h>
12 #include <linux/list.h>
13 #include <linux/clk.h>
14 #include <linux/err.h>
16 #include <linux/spinlock.h>
17 #include <linux/atmel-ssc.h>
18 #include <linux/slab.h>
19 #include <linux/module.h>
21 /* Serialize access to ssc_list and user count */
22 static DEFINE_SPINLOCK(user_lock);
23 static LIST_HEAD(ssc_list);
25 struct ssc_device *ssc_request(unsigned int ssc_num)
28 struct ssc_device *ssc;
30 spin_lock(&user_lock);
31 list_for_each_entry(ssc, &ssc_list, list) {
32 if (ssc->pdev->id == ssc_num) {
39 spin_unlock(&user_lock);
40 pr_err("ssc: ssc%d platform device is missing\n", ssc_num);
41 return ERR_PTR(-ENODEV);
45 spin_unlock(&user_lock);
46 dev_dbg(&ssc->pdev->dev, "module busy\n");
47 return ERR_PTR(-EBUSY);
50 spin_unlock(&user_lock);
56 EXPORT_SYMBOL(ssc_request);
58 void ssc_free(struct ssc_device *ssc)
60 spin_lock(&user_lock);
63 clk_disable(ssc->clk);
65 dev_dbg(&ssc->pdev->dev, "device already free\n");
67 spin_unlock(&user_lock);
69 EXPORT_SYMBOL(ssc_free);
71 static int ssc_probe(struct platform_device *pdev)
73 struct resource *regs;
74 struct ssc_device *ssc;
76 ssc = devm_kzalloc(&pdev->dev, sizeof(struct ssc_device), GFP_KERNEL);
78 dev_dbg(&pdev->dev, "out of memory\n");
84 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
86 dev_dbg(&pdev->dev, "no mmio resource defined\n");
90 ssc->regs = devm_request_and_ioremap(&pdev->dev, regs);
92 dev_dbg(&pdev->dev, "ioremap failed\n");
96 ssc->clk = devm_clk_get(&pdev->dev, "pclk");
97 if (IS_ERR(ssc->clk)) {
98 dev_dbg(&pdev->dev, "no pclk clock defined\n");
102 /* disable all interrupts */
103 clk_enable(ssc->clk);
104 ssc_writel(ssc->regs, IDR, ~0UL);
105 ssc_readl(ssc->regs, SR);
106 clk_disable(ssc->clk);
108 ssc->irq = platform_get_irq(pdev, 0);
110 dev_dbg(&pdev->dev, "could not get irq\n");
114 spin_lock(&user_lock);
115 list_add_tail(&ssc->list, &ssc_list);
116 spin_unlock(&user_lock);
118 platform_set_drvdata(pdev, ssc);
120 dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n",
121 ssc->regs, ssc->irq);
126 static int __devexit ssc_remove(struct platform_device *pdev)
128 struct ssc_device *ssc = platform_get_drvdata(pdev);
130 spin_lock(&user_lock);
131 list_del(&ssc->list);
132 spin_unlock(&user_lock);
137 static struct platform_driver ssc_driver = {
140 .owner = THIS_MODULE,
143 .remove = __devexit_p(ssc_remove),
145 module_platform_driver(ssc_driver);
147 MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
148 MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91");
149 MODULE_LICENSE("GPL");
150 MODULE_ALIAS("platform:ssc");