diff options
author | David S. Miller <davem@davemloft.net> | 2014-02-13 18:16:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-13 18:16:00 -0500 |
commit | 886ab57c848892ebdddabca9990415176cf90679 (patch) | |
tree | b2db893ef0aecacd26ffd9d1d69a4099a1b8885b /drivers/net/can | |
parent | 3410f22ea9693ed66e15a0764f20388bf39dd93d (diff) | |
parent | 17a50ee4bd47bdba94546e0526fc9ce93dc77d5e (diff) |
Merge tag 'linux-can-next-for-3.15-20140212' of git://gitorious.org/linux-can/linux-can-next
linux-can-next-for-3.15-20140212
Marc Kleine-Budde says:
====================
this is a pull request of eight patches for net-next/master.
Florian Vaussard contributed a series that merged the sja1000 of_platform
into the platform driver. The of_platform driver is finally removed.
Stephane Grosjean supplied a patch to allocate CANFD skbs. In a patch
by Uwe Kleine-König another missing copyright information was added to
a userspace header. And a patch by Yoann DI RUZZA that adds listen only
mode to the at91_can driver.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/at91_can.c | 9 | ||||
-rw-r--r-- | drivers/net/can/dev.c | 24 | ||||
-rw-r--r-- | drivers/net/can/sja1000/Kconfig | 13 | ||||
-rw-r--r-- | drivers/net/can/sja1000/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 3 | ||||
-rw-r--r-- | drivers/net/can/sja1000/sja1000_of_platform.c | 220 | ||||
-rw-r--r-- | drivers/net/can/sja1000/sja1000_platform.c | 194 |
7 files changed, 168 insertions, 296 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 6efe27458116..1d00b95f8983 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
@@ -420,7 +420,11 @@ static void at91_chip_start(struct net_device *dev) | |||
420 | at91_transceiver_switch(priv, 1); | 420 | at91_transceiver_switch(priv, 1); |
421 | 421 | ||
422 | /* enable chip */ | 422 | /* enable chip */ |
423 | at91_write(priv, AT91_MR, AT91_MR_CANEN); | 423 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) |
424 | reg_mr = AT91_MR_CANEN | AT91_MR_ABM; | ||
425 | else | ||
426 | reg_mr = AT91_MR_CANEN; | ||
427 | at91_write(priv, AT91_MR, reg_mr); | ||
424 | 428 | ||
425 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 429 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
426 | 430 | ||
@@ -1341,7 +1345,8 @@ static int at91_can_probe(struct platform_device *pdev) | |||
1341 | priv->can.bittiming_const = &at91_bittiming_const; | 1345 | priv->can.bittiming_const = &at91_bittiming_const; |
1342 | priv->can.do_set_mode = at91_set_mode; | 1346 | priv->can.do_set_mode = at91_set_mode; |
1343 | priv->can.do_get_berr_counter = at91_get_berr_counter; | 1347 | priv->can.do_get_berr_counter = at91_get_berr_counter; |
1344 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | 1348 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | |
1349 | CAN_CTRLMODE_LISTENONLY; | ||
1345 | priv->dev = dev; | 1350 | priv->dev = dev; |
1346 | priv->reg_base = addr; | 1351 | priv->reg_base = addr; |
1347 | priv->devtype_data = *devtype_data; | 1352 | priv->devtype_data = *devtype_data; |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index fc59bc6f040b..c0563f183721 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -512,6 +512,30 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) | |||
512 | } | 512 | } |
513 | EXPORT_SYMBOL_GPL(alloc_can_skb); | 513 | EXPORT_SYMBOL_GPL(alloc_can_skb); |
514 | 514 | ||
515 | struct sk_buff *alloc_canfd_skb(struct net_device *dev, | ||
516 | struct canfd_frame **cfd) | ||
517 | { | ||
518 | struct sk_buff *skb; | ||
519 | |||
520 | skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + | ||
521 | sizeof(struct canfd_frame)); | ||
522 | if (unlikely(!skb)) | ||
523 | return NULL; | ||
524 | |||
525 | skb->protocol = htons(ETH_P_CANFD); | ||
526 | skb->pkt_type = PACKET_BROADCAST; | ||
527 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
528 | |||
529 | can_skb_reserve(skb); | ||
530 | can_skb_prv(skb)->ifindex = dev->ifindex; | ||
531 | |||
532 | *cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame)); | ||
533 | memset(*cfd, 0, sizeof(struct canfd_frame)); | ||
534 | |||
535 | return skb; | ||
536 | } | ||
537 | EXPORT_SYMBOL_GPL(alloc_canfd_skb); | ||
538 | |||
515 | struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) | 539 | struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) |
516 | { | 540 | { |
517 | struct sk_buff *skb; | 541 | struct sk_buff *skb; |
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig index ff2ba86cd4a4..4b18b8765523 100644 --- a/drivers/net/can/sja1000/Kconfig +++ b/drivers/net/can/sja1000/Kconfig | |||
@@ -17,16 +17,9 @@ config CAN_SJA1000_PLATFORM | |||
17 | the "platform bus" (Linux abstraction for directly to the | 17 | the "platform bus" (Linux abstraction for directly to the |
18 | processor attached devices). Which can be found on various | 18 | processor attached devices). Which can be found on various |
19 | boards from Phytec (http://www.phytec.de) like the PCM027, | 19 | boards from Phytec (http://www.phytec.de) like the PCM027, |
20 | PCM038. | 20 | PCM038. It also provides the OpenFirmware "platform bus" found |
21 | 21 | on embedded systems with OpenFirmware bindings, e.g. if you | |
22 | config CAN_SJA1000_OF_PLATFORM | 22 | have a PowerPC based system you may want to enable this option. |
23 | tristate "Generic OF Platform Bus based SJA1000 driver" | ||
24 | depends on OF | ||
25 | ---help--- | ||
26 | This driver adds support for the SJA1000 chips connected to | ||
27 | the OpenFirmware "platform bus" found on embedded systems with | ||
28 | OpenFirmware bindings, e.g. if you have a PowerPC based system | ||
29 | you may want to enable this option. | ||
30 | 23 | ||
31 | config CAN_EMS_PCMCIA | 24 | config CAN_EMS_PCMCIA |
32 | tristate "EMS CPC-CARD Card" | 25 | tristate "EMS CPC-CARD Card" |
diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile index b3d05cbfec36..531d5fcc97e5 100644 --- a/drivers/net/can/sja1000/Makefile +++ b/drivers/net/can/sja1000/Makefile | |||
@@ -5,7 +5,6 @@ | |||
5 | obj-$(CONFIG_CAN_SJA1000) += sja1000.o | 5 | obj-$(CONFIG_CAN_SJA1000) += sja1000.o |
6 | obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o | 6 | obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o |
7 | obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o | 7 | obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o |
8 | obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o | ||
9 | obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o | 8 | obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o |
10 | obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o | 9 | obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o |
11 | obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o | 10 | obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index f17c3018b7c7..55cce4737518 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -106,8 +106,7 @@ static int sja1000_probe_chip(struct net_device *dev) | |||
106 | struct sja1000_priv *priv = netdev_priv(dev); | 106 | struct sja1000_priv *priv = netdev_priv(dev); |
107 | 107 | ||
108 | if (priv->reg_base && sja1000_is_absent(priv)) { | 108 | if (priv->reg_base && sja1000_is_absent(priv)) { |
109 | printk(KERN_INFO "%s: probing @0x%lX failed\n", | 109 | netdev_err(dev, "probing failed\n"); |
110 | DRV_NAME, dev->base_addr); | ||
111 | return 0; | 110 | return 0; |
112 | } | 111 | } |
113 | return -1; | 112 | return -1; |
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c deleted file mode 100644 index 2f6e24534231..000000000000 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ /dev/null | |||
@@ -1,220 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the version 2 of the GNU General Public License | ||
8 | * as published by the Free Software Foundation | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /* This is a generic driver for SJA1000 chips on the OpenFirmware platform | ||
20 | * bus found on embedded PowerPC systems. You need a SJA1000 CAN node | ||
21 | * definition in your flattened device tree source (DTS) file similar to: | ||
22 | * | ||
23 | * can@3,100 { | ||
24 | * compatible = "nxp,sja1000"; | ||
25 | * reg = <3 0x100 0x80>; | ||
26 | * interrupts = <2 0>; | ||
27 | * interrupt-parent = <&mpic>; | ||
28 | * nxp,external-clock-frequency = <16000000>; | ||
29 | * }; | ||
30 | * | ||
31 | * See "Documentation/devicetree/bindings/net/can/sja1000.txt" for further | ||
32 | * information. | ||
33 | */ | ||
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/interrupt.h> | ||
38 | #include <linux/netdevice.h> | ||
39 | #include <linux/delay.h> | ||
40 | #include <linux/io.h> | ||
41 | #include <linux/can/dev.h> | ||
42 | |||
43 | #include <linux/of_platform.h> | ||
44 | #include <linux/of_address.h> | ||
45 | #include <linux/of_irq.h> | ||
46 | |||
47 | #include "sja1000.h" | ||
48 | |||
49 | #define DRV_NAME "sja1000_of_platform" | ||
50 | |||
51 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | ||
52 | MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus"); | ||
53 | MODULE_LICENSE("GPL v2"); | ||
54 | |||
55 | #define SJA1000_OFP_CAN_CLOCK (16000000 / 2) | ||
56 | |||
57 | #define SJA1000_OFP_OCR OCR_TX0_PULLDOWN | ||
58 | #define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF) | ||
59 | |||
60 | static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg) | ||
61 | { | ||
62 | return ioread8(priv->reg_base + reg); | ||
63 | } | ||
64 | |||
65 | static void sja1000_ofp_write_reg(const struct sja1000_priv *priv, | ||
66 | int reg, u8 val) | ||
67 | { | ||
68 | iowrite8(val, priv->reg_base + reg); | ||
69 | } | ||
70 | |||
71 | static int sja1000_ofp_remove(struct platform_device *ofdev) | ||
72 | { | ||
73 | struct net_device *dev = platform_get_drvdata(ofdev); | ||
74 | struct sja1000_priv *priv = netdev_priv(dev); | ||
75 | struct device_node *np = ofdev->dev.of_node; | ||
76 | struct resource res; | ||
77 | |||
78 | unregister_sja1000dev(dev); | ||
79 | free_sja1000dev(dev); | ||
80 | iounmap(priv->reg_base); | ||
81 | irq_dispose_mapping(dev->irq); | ||
82 | |||
83 | of_address_to_resource(np, 0, &res); | ||
84 | release_mem_region(res.start, resource_size(&res)); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int sja1000_ofp_probe(struct platform_device *ofdev) | ||
90 | { | ||
91 | struct device_node *np = ofdev->dev.of_node; | ||
92 | struct net_device *dev; | ||
93 | struct sja1000_priv *priv; | ||
94 | struct resource res; | ||
95 | u32 prop; | ||
96 | int err, irq, res_size; | ||
97 | void __iomem *base; | ||
98 | |||
99 | err = of_address_to_resource(np, 0, &res); | ||
100 | if (err) { | ||
101 | dev_err(&ofdev->dev, "invalid address\n"); | ||
102 | return err; | ||
103 | } | ||
104 | |||
105 | res_size = resource_size(&res); | ||
106 | |||
107 | if (!request_mem_region(res.start, res_size, DRV_NAME)) { | ||
108 | dev_err(&ofdev->dev, "couldn't request %pR\n", &res); | ||
109 | return -EBUSY; | ||
110 | } | ||
111 | |||
112 | base = ioremap_nocache(res.start, res_size); | ||
113 | if (!base) { | ||
114 | dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res); | ||
115 | err = -ENOMEM; | ||
116 | goto exit_release_mem; | ||
117 | } | ||
118 | |||
119 | irq = irq_of_parse_and_map(np, 0); | ||
120 | if (irq == 0) { | ||
121 | dev_err(&ofdev->dev, "no irq found\n"); | ||
122 | err = -ENODEV; | ||
123 | goto exit_unmap_mem; | ||
124 | } | ||
125 | |||
126 | dev = alloc_sja1000dev(0); | ||
127 | if (!dev) { | ||
128 | err = -ENOMEM; | ||
129 | goto exit_dispose_irq; | ||
130 | } | ||
131 | |||
132 | priv = netdev_priv(dev); | ||
133 | |||
134 | priv->read_reg = sja1000_ofp_read_reg; | ||
135 | priv->write_reg = sja1000_ofp_write_reg; | ||
136 | |||
137 | err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); | ||
138 | if (!err) | ||
139 | priv->can.clock.freq = prop / 2; | ||
140 | else | ||
141 | priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ | ||
142 | |||
143 | err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); | ||
144 | if (!err) | ||
145 | priv->ocr |= prop & OCR_MODE_MASK; | ||
146 | else | ||
147 | priv->ocr |= OCR_MODE_NORMAL; /* default */ | ||
148 | |||
149 | err = of_property_read_u32(np, "nxp,tx-output-config", &prop); | ||
150 | if (!err) | ||
151 | priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; | ||
152 | else | ||
153 | priv->ocr |= OCR_TX0_PULLDOWN; /* default */ | ||
154 | |||
155 | err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); | ||
156 | if (!err && prop) { | ||
157 | u32 divider = priv->can.clock.freq * 2 / prop; | ||
158 | |||
159 | if (divider > 1) | ||
160 | priv->cdr |= divider / 2 - 1; | ||
161 | else | ||
162 | priv->cdr |= CDR_CLKOUT_MASK; | ||
163 | } else { | ||
164 | priv->cdr |= CDR_CLK_OFF; /* default */ | ||
165 | } | ||
166 | |||
167 | if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) | ||
168 | priv->cdr |= CDR_CBP; /* default */ | ||
169 | |||
170 | priv->irq_flags = IRQF_SHARED; | ||
171 | priv->reg_base = base; | ||
172 | |||
173 | dev->irq = irq; | ||
174 | |||
175 | dev_info(&ofdev->dev, | ||
176 | "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n", | ||
177 | priv->reg_base, dev->irq, priv->can.clock.freq, | ||
178 | priv->ocr, priv->cdr); | ||
179 | |||
180 | platform_set_drvdata(ofdev, dev); | ||
181 | SET_NETDEV_DEV(dev, &ofdev->dev); | ||
182 | |||
183 | err = register_sja1000dev(dev); | ||
184 | if (err) { | ||
185 | dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", | ||
186 | DRV_NAME, err); | ||
187 | goto exit_free_sja1000; | ||
188 | } | ||
189 | |||
190 | return 0; | ||
191 | |||
192 | exit_free_sja1000: | ||
193 | free_sja1000dev(dev); | ||
194 | exit_dispose_irq: | ||
195 | irq_dispose_mapping(irq); | ||
196 | exit_unmap_mem: | ||
197 | iounmap(base); | ||
198 | exit_release_mem: | ||
199 | release_mem_region(res.start, res_size); | ||
200 | |||
201 | return err; | ||
202 | } | ||
203 | |||
204 | static struct of_device_id sja1000_ofp_table[] = { | ||
205 | {.compatible = "nxp,sja1000"}, | ||
206 | {}, | ||
207 | }; | ||
208 | MODULE_DEVICE_TABLE(of, sja1000_ofp_table); | ||
209 | |||
210 | static struct platform_driver sja1000_ofp_driver = { | ||
211 | .driver = { | ||
212 | .owner = THIS_MODULE, | ||
213 | .name = DRV_NAME, | ||
214 | .of_match_table = sja1000_ofp_table, | ||
215 | }, | ||
216 | .probe = sja1000_ofp_probe, | ||
217 | .remove = sja1000_ofp_remove, | ||
218 | }; | ||
219 | |||
220 | module_platform_driver(sja1000_ofp_driver); | ||
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 943df645b459..95a844a7ee7b 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c | |||
@@ -26,12 +26,16 @@ | |||
26 | #include <linux/can/dev.h> | 26 | #include <linux/can/dev.h> |
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> | ||
30 | #include <linux/of_irq.h> | ||
29 | 31 | ||
30 | #include "sja1000.h" | 32 | #include "sja1000.h" |
31 | 33 | ||
32 | #define DRV_NAME "sja1000_platform" | 34 | #define DRV_NAME "sja1000_platform" |
35 | #define SP_CAN_CLOCK (16000000 / 2) | ||
33 | 36 | ||
34 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | 37 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); |
38 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | ||
35 | MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus"); | 39 | MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus"); |
36 | MODULE_ALIAS("platform:" DRV_NAME); | 40 | MODULE_ALIAS("platform:" DRV_NAME); |
37 | MODULE_LICENSE("GPL v2"); | 41 | MODULE_LICENSE("GPL v2"); |
@@ -66,59 +70,16 @@ static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val) | |||
66 | iowrite8(val, priv->reg_base + reg * 4); | 70 | iowrite8(val, priv->reg_base + reg * 4); |
67 | } | 71 | } |
68 | 72 | ||
69 | static int sp_probe(struct platform_device *pdev) | 73 | static void sp_populate(struct sja1000_priv *priv, |
74 | struct sja1000_platform_data *pdata, | ||
75 | unsigned long resource_mem_flags) | ||
70 | { | 76 | { |
71 | int err; | ||
72 | void __iomem *addr; | ||
73 | struct net_device *dev; | ||
74 | struct sja1000_priv *priv; | ||
75 | struct resource *res_mem, *res_irq; | ||
76 | struct sja1000_platform_data *pdata; | ||
77 | |||
78 | pdata = dev_get_platdata(&pdev->dev); | ||
79 | if (!pdata) { | ||
80 | dev_err(&pdev->dev, "No platform data provided!\n"); | ||
81 | err = -ENODEV; | ||
82 | goto exit; | ||
83 | } | ||
84 | |||
85 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
86 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
87 | if (!res_mem || !res_irq) { | ||
88 | err = -ENODEV; | ||
89 | goto exit; | ||
90 | } | ||
91 | |||
92 | if (!request_mem_region(res_mem->start, resource_size(res_mem), | ||
93 | DRV_NAME)) { | ||
94 | err = -EBUSY; | ||
95 | goto exit; | ||
96 | } | ||
97 | |||
98 | addr = ioremap_nocache(res_mem->start, resource_size(res_mem)); | ||
99 | if (!addr) { | ||
100 | err = -ENOMEM; | ||
101 | goto exit_release; | ||
102 | } | ||
103 | |||
104 | dev = alloc_sja1000dev(0); | ||
105 | if (!dev) { | ||
106 | err = -ENOMEM; | ||
107 | goto exit_iounmap; | ||
108 | } | ||
109 | priv = netdev_priv(dev); | ||
110 | |||
111 | dev->irq = res_irq->start; | ||
112 | priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; | ||
113 | if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) | ||
114 | priv->irq_flags |= IRQF_SHARED; | ||
115 | priv->reg_base = addr; | ||
116 | /* The CAN clock frequency is half the oscillator clock frequency */ | 77 | /* The CAN clock frequency is half the oscillator clock frequency */ |
117 | priv->can.clock.freq = pdata->osc_freq / 2; | 78 | priv->can.clock.freq = pdata->osc_freq / 2; |
118 | priv->ocr = pdata->ocr; | 79 | priv->ocr = pdata->ocr; |
119 | priv->cdr = pdata->cdr; | 80 | priv->cdr = pdata->cdr; |
120 | 81 | ||
121 | switch (res_mem->flags & IORESOURCE_MEM_TYPE_MASK) { | 82 | switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) { |
122 | case IORESOURCE_MEM_32BIT: | 83 | case IORESOURCE_MEM_32BIT: |
123 | priv->read_reg = sp_read_reg32; | 84 | priv->read_reg = sp_read_reg32; |
124 | priv->write_reg = sp_write_reg32; | 85 | priv->write_reg = sp_write_reg32; |
@@ -133,6 +94,124 @@ static int sp_probe(struct platform_device *pdev) | |||
133 | priv->write_reg = sp_write_reg8; | 94 | priv->write_reg = sp_write_reg8; |
134 | break; | 95 | break; |
135 | } | 96 | } |
97 | } | ||
98 | |||
99 | static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of) | ||
100 | { | ||
101 | int err; | ||
102 | u32 prop; | ||
103 | |||
104 | err = of_property_read_u32(of, "reg-io-width", &prop); | ||
105 | if (err) | ||
106 | prop = 1; /* 8 bit is default */ | ||
107 | |||
108 | switch (prop) { | ||
109 | case 4: | ||
110 | priv->read_reg = sp_read_reg32; | ||
111 | priv->write_reg = sp_write_reg32; | ||
112 | break; | ||
113 | case 2: | ||
114 | priv->read_reg = sp_read_reg16; | ||
115 | priv->write_reg = sp_write_reg16; | ||
116 | break; | ||
117 | case 1: /* fallthrough */ | ||
118 | default: | ||
119 | priv->read_reg = sp_read_reg8; | ||
120 | priv->write_reg = sp_write_reg8; | ||
121 | } | ||
122 | |||
123 | err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop); | ||
124 | if (!err) | ||
125 | priv->can.clock.freq = prop / 2; | ||
126 | else | ||
127 | priv->can.clock.freq = SP_CAN_CLOCK; /* default */ | ||
128 | |||
129 | err = of_property_read_u32(of, "nxp,tx-output-mode", &prop); | ||
130 | if (!err) | ||
131 | priv->ocr |= prop & OCR_MODE_MASK; | ||
132 | else | ||
133 | priv->ocr |= OCR_MODE_NORMAL; /* default */ | ||
134 | |||
135 | err = of_property_read_u32(of, "nxp,tx-output-config", &prop); | ||
136 | if (!err) | ||
137 | priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; | ||
138 | else | ||
139 | priv->ocr |= OCR_TX0_PULLDOWN; /* default */ | ||
140 | |||
141 | err = of_property_read_u32(of, "nxp,clock-out-frequency", &prop); | ||
142 | if (!err && prop) { | ||
143 | u32 divider = priv->can.clock.freq * 2 / prop; | ||
144 | |||
145 | if (divider > 1) | ||
146 | priv->cdr |= divider / 2 - 1; | ||
147 | else | ||
148 | priv->cdr |= CDR_CLKOUT_MASK; | ||
149 | } else { | ||
150 | priv->cdr |= CDR_CLK_OFF; /* default */ | ||
151 | } | ||
152 | |||
153 | if (!of_property_read_bool(of, "nxp,no-comparator-bypass")) | ||
154 | priv->cdr |= CDR_CBP; /* default */ | ||
155 | } | ||
156 | |||
157 | static int sp_probe(struct platform_device *pdev) | ||
158 | { | ||
159 | int err, irq = 0; | ||
160 | void __iomem *addr; | ||
161 | struct net_device *dev; | ||
162 | struct sja1000_priv *priv; | ||
163 | struct resource *res_mem, *res_irq = NULL; | ||
164 | struct sja1000_platform_data *pdata; | ||
165 | struct device_node *of = pdev->dev.of_node; | ||
166 | |||
167 | pdata = dev_get_platdata(&pdev->dev); | ||
168 | if (!pdata && !of) { | ||
169 | dev_err(&pdev->dev, "No platform data provided!\n"); | ||
170 | return -ENODEV; | ||
171 | } | ||
172 | |||
173 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
174 | if (!res_mem) | ||
175 | return -ENODEV; | ||
176 | |||
177 | if (!devm_request_mem_region(&pdev->dev, res_mem->start, | ||
178 | resource_size(res_mem), DRV_NAME)) | ||
179 | return -EBUSY; | ||
180 | |||
181 | addr = devm_ioremap_nocache(&pdev->dev, res_mem->start, | ||
182 | resource_size(res_mem)); | ||
183 | if (!addr) | ||
184 | return -ENOMEM; | ||
185 | |||
186 | if (of) | ||
187 | irq = irq_of_parse_and_map(of, 0); | ||
188 | else | ||
189 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
190 | |||
191 | if (!irq && !res_irq) | ||
192 | return -ENODEV; | ||
193 | |||
194 | dev = alloc_sja1000dev(0); | ||
195 | if (!dev) | ||
196 | return -ENOMEM; | ||
197 | priv = netdev_priv(dev); | ||
198 | |||
199 | if (res_irq) { | ||
200 | irq = res_irq->start; | ||
201 | priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; | ||
202 | if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) | ||
203 | priv->irq_flags |= IRQF_SHARED; | ||
204 | } else { | ||
205 | priv->irq_flags = IRQF_SHARED; | ||
206 | } | ||
207 | |||
208 | dev->irq = irq; | ||
209 | priv->reg_base = addr; | ||
210 | |||
211 | if (of) | ||
212 | sp_populate_of(priv, of); | ||
213 | else | ||
214 | sp_populate(priv, pdata, res_mem->flags); | ||
136 | 215 | ||
137 | platform_set_drvdata(pdev, dev); | 216 | platform_set_drvdata(pdev, dev); |
138 | SET_NETDEV_DEV(dev, &pdev->dev); | 217 | SET_NETDEV_DEV(dev, &pdev->dev); |
@@ -150,39 +229,32 @@ static int sp_probe(struct platform_device *pdev) | |||
150 | 229 | ||
151 | exit_free: | 230 | exit_free: |
152 | free_sja1000dev(dev); | 231 | free_sja1000dev(dev); |
153 | exit_iounmap: | ||
154 | iounmap(addr); | ||
155 | exit_release: | ||
156 | release_mem_region(res_mem->start, resource_size(res_mem)); | ||
157 | exit: | ||
158 | return err; | 232 | return err; |
159 | } | 233 | } |
160 | 234 | ||
161 | static int sp_remove(struct platform_device *pdev) | 235 | static int sp_remove(struct platform_device *pdev) |
162 | { | 236 | { |
163 | struct net_device *dev = platform_get_drvdata(pdev); | 237 | struct net_device *dev = platform_get_drvdata(pdev); |
164 | struct sja1000_priv *priv = netdev_priv(dev); | ||
165 | struct resource *res; | ||
166 | 238 | ||
167 | unregister_sja1000dev(dev); | 239 | unregister_sja1000dev(dev); |
168 | |||
169 | if (priv->reg_base) | ||
170 | iounmap(priv->reg_base); | ||
171 | |||
172 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
173 | release_mem_region(res->start, resource_size(res)); | ||
174 | |||
175 | free_sja1000dev(dev); | 240 | free_sja1000dev(dev); |
176 | 241 | ||
177 | return 0; | 242 | return 0; |
178 | } | 243 | } |
179 | 244 | ||
245 | static struct of_device_id sp_of_table[] = { | ||
246 | {.compatible = "nxp,sja1000"}, | ||
247 | {}, | ||
248 | }; | ||
249 | MODULE_DEVICE_TABLE(of, sp_of_table); | ||
250 | |||
180 | static struct platform_driver sp_driver = { | 251 | static struct platform_driver sp_driver = { |
181 | .probe = sp_probe, | 252 | .probe = sp_probe, |
182 | .remove = sp_remove, | 253 | .remove = sp_remove, |
183 | .driver = { | 254 | .driver = { |
184 | .name = DRV_NAME, | 255 | .name = DRV_NAME, |
185 | .owner = THIS_MODULE, | 256 | .owner = THIS_MODULE, |
257 | .of_match_table = sp_of_table, | ||
186 | }, | 258 | }, |
187 | }; | 259 | }; |
188 | 260 | ||