aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorDamien Riegel <damien.riegel@savoirfairelinux.com>2016-01-12 17:31:18 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2016-02-20 08:56:00 -0500
commitf49cbe6b7988b51aa2b72c45d4332fabea62fba6 (patch)
treea1cfd97d66ceff39821f8f686f4f3609d3a55252 /drivers/net/can
parent80c804bfc487c6df783c258b9034b9d81c34f7a0 (diff)
can: sja1000: of: add per-compatible init hook
This commit adds the capability to allocate and init private data embedded in the sja1000_priv structure on a per-compatible basis. The device node is passed as a parameter of the init callback to allow parsing of custom device tree properties. Signed-off-by: Damien Riegel <damien.riegel@savoirfairelinux.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/sja1000/sja1000_platform.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
index 0552ed46a206..777d312f1779 100644
--- a/drivers/net/can/sja1000/sja1000_platform.c
+++ b/drivers/net/can/sja1000/sja1000_platform.c
@@ -27,6 +27,7 @@
27#include <linux/can/platform/sja1000.h> 27#include <linux/can/platform/sja1000.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/of.h> 29#include <linux/of.h>
30#include <linux/of_device.h>
30#include <linux/of_irq.h> 31#include <linux/of_irq.h>
31 32
32#include "sja1000.h" 33#include "sja1000.h"
@@ -40,6 +41,11 @@ MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
40MODULE_ALIAS("platform:" DRV_NAME); 41MODULE_ALIAS("platform:" DRV_NAME);
41MODULE_LICENSE("GPL v2"); 42MODULE_LICENSE("GPL v2");
42 43
44struct sja1000_of_data {
45 size_t priv_sz;
46 int (*init)(struct sja1000_priv *priv, struct device_node *of);
47};
48
43static u8 sp_read_reg8(const struct sja1000_priv *priv, int reg) 49static u8 sp_read_reg8(const struct sja1000_priv *priv, int reg)
44{ 50{
45 return ioread8(priv->reg_base + reg); 51 return ioread8(priv->reg_base + reg);
@@ -154,6 +160,12 @@ static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of)
154 priv->cdr |= CDR_CBP; /* default */ 160 priv->cdr |= CDR_CBP; /* default */
155} 161}
156 162
163static const struct of_device_id sp_of_table[] = {
164 { .compatible = "nxp,sja1000", .data = NULL, },
165 { /* sentinel */ },
166};
167MODULE_DEVICE_TABLE(of, sp_of_table);
168
157static int sp_probe(struct platform_device *pdev) 169static int sp_probe(struct platform_device *pdev)
158{ 170{
159 int err, irq = 0; 171 int err, irq = 0;
@@ -163,6 +175,9 @@ static int sp_probe(struct platform_device *pdev)
163 struct resource *res_mem, *res_irq = NULL; 175 struct resource *res_mem, *res_irq = NULL;
164 struct sja1000_platform_data *pdata; 176 struct sja1000_platform_data *pdata;
165 struct device_node *of = pdev->dev.of_node; 177 struct device_node *of = pdev->dev.of_node;
178 const struct of_device_id *of_id;
179 const struct sja1000_of_data *of_data = NULL;
180 size_t priv_sz = 0;
166 181
167 pdata = dev_get_platdata(&pdev->dev); 182 pdata = dev_get_platdata(&pdev->dev);
168 if (!pdata && !of) { 183 if (!pdata && !of) {
@@ -191,7 +206,13 @@ static int sp_probe(struct platform_device *pdev)
191 if (!irq && !res_irq) 206 if (!irq && !res_irq)
192 return -ENODEV; 207 return -ENODEV;
193 208
194 dev = alloc_sja1000dev(0); 209 of_id = of_match_device(sp_of_table, &pdev->dev);
210 if (of_id && of_id->data) {
211 of_data = of_id->data;
212 priv_sz = of_data->priv_sz;
213 }
214
215 dev = alloc_sja1000dev(priv_sz);
195 if (!dev) 216 if (!dev)
196 return -ENOMEM; 217 return -ENOMEM;
197 priv = netdev_priv(dev); 218 priv = netdev_priv(dev);
@@ -208,10 +229,17 @@ static int sp_probe(struct platform_device *pdev)
208 dev->irq = irq; 229 dev->irq = irq;
209 priv->reg_base = addr; 230 priv->reg_base = addr;
210 231
211 if (of) 232 if (of) {
212 sp_populate_of(priv, of); 233 sp_populate_of(priv, of);
213 else 234
235 if (of_data && of_data->init) {
236 err = of_data->init(priv, of);
237 if (err)
238 goto exit_free;
239 }
240 } else {
214 sp_populate(priv, pdata, res_mem->flags); 241 sp_populate(priv, pdata, res_mem->flags);
242 }
215 243
216 platform_set_drvdata(pdev, dev); 244 platform_set_drvdata(pdev, dev);
217 SET_NETDEV_DEV(dev, &pdev->dev); 245 SET_NETDEV_DEV(dev, &pdev->dev);
@@ -242,12 +270,6 @@ static int sp_remove(struct platform_device *pdev)
242 return 0; 270 return 0;
243} 271}
244 272
245static const struct of_device_id sp_of_table[] = {
246 {.compatible = "nxp,sja1000"},
247 {},
248};
249MODULE_DEVICE_TABLE(of, sp_of_table);
250
251static struct platform_driver sp_driver = { 273static struct platform_driver sp_driver = {
252 .probe = sp_probe, 274 .probe = sp_probe,
253 .remove = sp_remove, 275 .remove = sp_remove,