diff options
author | Bo Shen <voice.shen@atmel.com> | 2012-11-06 22:41:41 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-11-07 03:23:49 -0500 |
commit | 099343c64e1615ae83b0994197027be363ca4899 (patch) | |
tree | bd828471a305ec5c30398dd30876f369d70649ec /drivers/misc/atmel-ssc.c | |
parent | 636036d29a20154b897571e1d5949faac98bfb7c (diff) |
ARM: at91: atmel-ssc: add device tree support
Add atmel-ssc for device tree support
Match "atmel,at91rm9200-ssc" for using pdc for data transfer
Match "atmel,at91sam9g45-ssc" for using dma for data transfer
Signed-off-by: Bo Shen <voice.shen@atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/misc/atmel-ssc.c')
-rw-r--r-- | drivers/misc/atmel-ssc.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index f40abd8a6695..a769719e36bf 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | 20 | ||
21 | #include <linux/of.h> | ||
22 | |||
21 | /* Serialize access to ssc_list and user count */ | 23 | /* Serialize access to ssc_list and user count */ |
22 | static DEFINE_SPINLOCK(user_lock); | 24 | static DEFINE_SPINLOCK(user_lock); |
23 | static LIST_HEAD(ssc_list); | 25 | static LIST_HEAD(ssc_list); |
@@ -29,7 +31,13 @@ struct ssc_device *ssc_request(unsigned int ssc_num) | |||
29 | 31 | ||
30 | spin_lock(&user_lock); | 32 | spin_lock(&user_lock); |
31 | list_for_each_entry(ssc, &ssc_list, list) { | 33 | list_for_each_entry(ssc, &ssc_list, list) { |
32 | if (ssc->pdev->id == ssc_num) { | 34 | if (ssc->pdev->dev.of_node) { |
35 | if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc") | ||
36 | == ssc_num) { | ||
37 | ssc_valid = 1; | ||
38 | break; | ||
39 | } | ||
40 | } else if (ssc->pdev->id == ssc_num) { | ||
33 | ssc_valid = 1; | 41 | ssc_valid = 1; |
34 | break; | 42 | break; |
35 | } | 43 | } |
@@ -88,10 +96,41 @@ static const struct platform_device_id atmel_ssc_devtypes[] = { | |||
88 | } | 96 | } |
89 | }; | 97 | }; |
90 | 98 | ||
99 | #ifdef CONFIG_OF | ||
100 | static const struct of_device_id atmel_ssc_dt_ids[] = { | ||
101 | { | ||
102 | .compatible = "atmel,at91rm9200-ssc", | ||
103 | .data = &at91rm9200_config, | ||
104 | }, { | ||
105 | .compatible = "atmel,at91sam9g45-ssc", | ||
106 | .data = &at91sam9g45_config, | ||
107 | }, { | ||
108 | /* sentinel */ | ||
109 | } | ||
110 | }; | ||
111 | MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids); | ||
112 | #endif | ||
113 | |||
114 | static inline const struct atmel_ssc_platform_data * __init | ||
115 | atmel_ssc_get_driver_data(struct platform_device *pdev) | ||
116 | { | ||
117 | if (pdev->dev.of_node) { | ||
118 | const struct of_device_id *match; | ||
119 | match = of_match_node(atmel_ssc_dt_ids, pdev->dev.of_node); | ||
120 | if (match == NULL) | ||
121 | return NULL; | ||
122 | return match->data; | ||
123 | } | ||
124 | |||
125 | return (struct atmel_ssc_platform_data *) | ||
126 | platform_get_device_id(pdev)->driver_data; | ||
127 | } | ||
128 | |||
91 | static int ssc_probe(struct platform_device *pdev) | 129 | static int ssc_probe(struct platform_device *pdev) |
92 | { | 130 | { |
93 | struct resource *regs; | 131 | struct resource *regs; |
94 | struct ssc_device *ssc; | 132 | struct ssc_device *ssc; |
133 | const struct atmel_ssc_platform_data *plat_dat; | ||
95 | 134 | ||
96 | ssc = devm_kzalloc(&pdev->dev, sizeof(struct ssc_device), GFP_KERNEL); | 135 | ssc = devm_kzalloc(&pdev->dev, sizeof(struct ssc_device), GFP_KERNEL); |
97 | if (!ssc) { | 136 | if (!ssc) { |
@@ -100,8 +139,11 @@ static int ssc_probe(struct platform_device *pdev) | |||
100 | } | 139 | } |
101 | 140 | ||
102 | ssc->pdev = pdev; | 141 | ssc->pdev = pdev; |
103 | ssc->pdata = (struct atmel_ssc_platform_data *) | 142 | |
104 | platform_get_device_id(pdev)->driver_data; | 143 | plat_dat = atmel_ssc_get_driver_data(pdev); |
144 | if (!plat_dat) | ||
145 | return -ENODEV; | ||
146 | ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat; | ||
105 | 147 | ||
106 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 148 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
107 | if (!regs) { | 149 | if (!regs) { |
@@ -160,6 +202,7 @@ static struct platform_driver ssc_driver = { | |||
160 | .driver = { | 202 | .driver = { |
161 | .name = "ssc", | 203 | .name = "ssc", |
162 | .owner = THIS_MODULE, | 204 | .owner = THIS_MODULE, |
205 | .of_match_table = of_match_ptr(atmel_ssc_dt_ids), | ||
163 | }, | 206 | }, |
164 | .id_table = atmel_ssc_devtypes, | 207 | .id_table = atmel_ssc_devtypes, |
165 | .probe = ssc_probe, | 208 | .probe = ssc_probe, |