diff options
author | Ludovic Desroches <ludovic.desroches@atmel.com> | 2013-03-11 13:26:03 -0400 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2013-03-27 08:07:08 -0400 |
commit | 3078cde792340280b761a0f46f99799a78f4395d (patch) | |
tree | eeb21240aa769eecba6f0a3aa84d18b5036fce28 /drivers/net/can | |
parent | 6bdeaba47d87f48a3943b6899d6c6e6f17d52f1d (diff) |
can: at91_can: add dt support
Add device tree support.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/at91_can.c | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 44f363792b59..db52f4414def 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
30 | #include <linux/of.h> | ||
30 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
31 | #include <linux/rtnetlink.h> | 32 | #include <linux/rtnetlink.h> |
32 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
@@ -155,19 +156,20 @@ struct at91_priv { | |||
155 | canid_t mb0_id; | 156 | canid_t mb0_id; |
156 | }; | 157 | }; |
157 | 158 | ||
158 | static const struct at91_devtype_data at91_devtype_data[] = { | 159 | static const struct at91_devtype_data at91_at91sam9263_data = { |
159 | [AT91_DEVTYPE_SAM9263] = { | 160 | .rx_first = 1, |
160 | .rx_first = 1, | 161 | .rx_split = 8, |
161 | .rx_split = 8, | 162 | .rx_last = 11, |
162 | .rx_last = 11, | 163 | .tx_shift = 2, |
163 | .tx_shift = 2, | 164 | .type = AT91_DEVTYPE_SAM9263, |
164 | }, | 165 | }; |
165 | [AT91_DEVTYPE_SAM9X5] = { | 166 | |
166 | .rx_first = 0, | 167 | static const struct at91_devtype_data at91_at91sam9x5_data = { |
167 | .rx_split = 4, | 168 | .rx_first = 0, |
168 | .rx_last = 5, | 169 | .rx_split = 4, |
169 | .tx_shift = 1, | 170 | .rx_last = 5, |
170 | }, | 171 | .tx_shift = 1, |
172 | .type = AT91_DEVTYPE_SAM9X5, | ||
171 | }; | 173 | }; |
172 | 174 | ||
173 | static const struct can_bittiming_const at91_bittiming_const = { | 175 | static const struct can_bittiming_const at91_bittiming_const = { |
@@ -1249,10 +1251,42 @@ static struct attribute_group at91_sysfs_attr_group = { | |||
1249 | .attrs = at91_sysfs_attrs, | 1251 | .attrs = at91_sysfs_attrs, |
1250 | }; | 1252 | }; |
1251 | 1253 | ||
1254 | #if defined(CONFIG_OF) | ||
1255 | static const struct of_device_id at91_can_dt_ids[] = { | ||
1256 | { | ||
1257 | .compatible = "atmel,at91sam9x5-can", | ||
1258 | .data = &at91_at91sam9x5_data, | ||
1259 | }, { | ||
1260 | .compatible = "atmel,at91sam9263-can", | ||
1261 | .data = &at91_at91sam9263_data, | ||
1262 | }, { | ||
1263 | /* sentinel */ | ||
1264 | } | ||
1265 | }; | ||
1266 | MODULE_DEVICE_TABLE(of, at91_can_dt_ids); | ||
1267 | #else | ||
1268 | #define at91_can_dt_ids NULL | ||
1269 | #endif | ||
1270 | |||
1271 | static const struct at91_devtype_data *at91_can_get_driver_data(struct platform_device *pdev) | ||
1272 | { | ||
1273 | if (pdev->dev.of_node) { | ||
1274 | const struct of_device_id *match; | ||
1275 | |||
1276 | match = of_match_node(at91_can_dt_ids, pdev->dev.of_node); | ||
1277 | if (!match) { | ||
1278 | dev_err(&pdev->dev, "no matching node found in dtb\n"); | ||
1279 | return NULL; | ||
1280 | } | ||
1281 | return (const struct at91_devtype_data *)match->data; | ||
1282 | } | ||
1283 | return (const struct at91_devtype_data *) | ||
1284 | platform_get_device_id(pdev)->driver_data; | ||
1285 | } | ||
1286 | |||
1252 | static int at91_can_probe(struct platform_device *pdev) | 1287 | static int at91_can_probe(struct platform_device *pdev) |
1253 | { | 1288 | { |
1254 | const struct at91_devtype_data *devtype_data; | 1289 | const struct at91_devtype_data *devtype_data; |
1255 | enum at91_devtype devtype; | ||
1256 | struct net_device *dev; | 1290 | struct net_device *dev; |
1257 | struct at91_priv *priv; | 1291 | struct at91_priv *priv; |
1258 | struct resource *res; | 1292 | struct resource *res; |
@@ -1260,8 +1294,12 @@ static int at91_can_probe(struct platform_device *pdev) | |||
1260 | void __iomem *addr; | 1294 | void __iomem *addr; |
1261 | int err, irq; | 1295 | int err, irq; |
1262 | 1296 | ||
1263 | devtype = pdev->id_entry->driver_data; | 1297 | devtype_data = at91_can_get_driver_data(pdev); |
1264 | devtype_data = &at91_devtype_data[devtype]; | 1298 | if (!devtype_data) { |
1299 | dev_err(&pdev->dev, "no driver data\n"); | ||
1300 | err = -ENODEV; | ||
1301 | goto exit; | ||
1302 | } | ||
1265 | 1303 | ||
1266 | clk = clk_get(&pdev->dev, "can_clk"); | 1304 | clk = clk_get(&pdev->dev, "can_clk"); |
1267 | if (IS_ERR(clk)) { | 1305 | if (IS_ERR(clk)) { |
@@ -1310,7 +1348,6 @@ static int at91_can_probe(struct platform_device *pdev) | |||
1310 | priv->dev = dev; | 1348 | priv->dev = dev; |
1311 | priv->reg_base = addr; | 1349 | priv->reg_base = addr; |
1312 | priv->devtype_data = *devtype_data; | 1350 | priv->devtype_data = *devtype_data; |
1313 | priv->devtype_data.type = devtype; | ||
1314 | priv->clk = clk; | 1351 | priv->clk = clk; |
1315 | priv->pdata = pdev->dev.platform_data; | 1352 | priv->pdata = pdev->dev.platform_data; |
1316 | priv->mb0_id = 0x7ff; | 1353 | priv->mb0_id = 0x7ff; |
@@ -1373,10 +1410,10 @@ static int at91_can_remove(struct platform_device *pdev) | |||
1373 | static const struct platform_device_id at91_can_id_table[] = { | 1410 | static const struct platform_device_id at91_can_id_table[] = { |
1374 | { | 1411 | { |
1375 | .name = "at91_can", | 1412 | .name = "at91_can", |
1376 | .driver_data = AT91_DEVTYPE_SAM9263, | 1413 | .driver_data = (kernel_ulong_t)&at91_at91sam9x5_data, |
1377 | }, { | 1414 | }, { |
1378 | .name = "at91sam9x5_can", | 1415 | .name = "at91sam9x5_can", |
1379 | .driver_data = AT91_DEVTYPE_SAM9X5, | 1416 | .driver_data = (kernel_ulong_t)&at91_at91sam9263_data, |
1380 | }, { | 1417 | }, { |
1381 | /* sentinel */ | 1418 | /* sentinel */ |
1382 | } | 1419 | } |
@@ -1389,6 +1426,7 @@ static struct platform_driver at91_can_driver = { | |||
1389 | .driver = { | 1426 | .driver = { |
1390 | .name = KBUILD_MODNAME, | 1427 | .name = KBUILD_MODNAME, |
1391 | .owner = THIS_MODULE, | 1428 | .owner = THIS_MODULE, |
1429 | .of_match_table = at91_can_dt_ids, | ||
1392 | }, | 1430 | }, |
1393 | .id_table = at91_can_id_table, | 1431 | .id_table = at91_can_id_table, |
1394 | }; | 1432 | }; |