17
17
*
18
18
*/
19
19
20
- /*
21
- * Your platform definitions should specify module ram offsets and interrupt
22
- * number to use as follows:
23
- *
24
- * static struct ti_hecc_platform_data am3517_evm_hecc_pdata = {
25
- * .scc_hecc_offset = 0,
26
- * .scc_ram_offset = 0x3000,
27
- * .hecc_ram_offset = 0x3000,
28
- * .mbx_offset = 0x2000,
29
- * .int_line = 0,
30
- * .revision = 1,
31
- * .transceiver_switch = hecc_phy_control,
32
- * };
33
- *
34
- * Please see include/linux/can/platform/ti_hecc.h for description of
35
- * above fields.
36
- *
37
- */
38
-
39
20
#include <linux/module.h>
40
21
#include <linux/kernel.h>
41
22
#include <linux/types.h>
46
27
#include <linux/platform_device.h>
47
28
#include <linux/clk.h>
48
29
#include <linux/io.h>
30
+ #include <linux/of.h>
31
+ #include <linux/of_device.h>
32
+ #include <linux/regulator/consumer.h>
49
33
50
34
#include <linux/can/dev.h>
51
35
#include <linux/can/error.h>
52
36
#include <linux/can/led.h>
53
- #include <linux/can/platform/ti_hecc.h>
54
37
55
38
#define DRV_NAME "ti_hecc"
56
39
#define HECC_MODULE_VERSION "0.7"
@@ -214,15 +197,14 @@ struct ti_hecc_priv {
214
197
struct net_device * ndev ;
215
198
struct clk * clk ;
216
199
void __iomem * base ;
217
- u32 scc_ram_offset ;
218
- u32 hecc_ram_offset ;
219
- u32 mbx_offset ;
220
- u32 int_line ;
200
+ void __iomem * hecc_ram ;
201
+ void __iomem * mbx ;
202
+ bool use_hecc1int ;
221
203
spinlock_t mbx_lock ; /* CANME register needs protection */
222
204
u32 tx_head ;
223
205
u32 tx_tail ;
224
206
u32 rx_next ;
225
- void ( * transceiver_switch )( int ) ;
207
+ struct regulator * reg_xceiver ;
226
208
};
227
209
228
210
static inline int get_tx_head_mb (struct ti_hecc_priv * priv )
@@ -242,20 +224,18 @@ static inline int get_tx_head_prio(struct ti_hecc_priv *priv)
242
224
243
225
static inline void hecc_write_lam (struct ti_hecc_priv * priv , u32 mbxno , u32 val )
244
226
{
245
- __raw_writel (val , priv -> base + priv -> hecc_ram_offset + mbxno * 4 );
227
+ __raw_writel (val , priv -> hecc_ram + mbxno * 4 );
246
228
}
247
229
248
230
static inline void hecc_write_mbx (struct ti_hecc_priv * priv , u32 mbxno ,
249
231
u32 reg , u32 val )
250
232
{
251
- __raw_writel (val , priv -> base + priv -> mbx_offset + mbxno * 0x10 +
252
- reg );
233
+ __raw_writel (val , priv -> mbx + mbxno * 0x10 + reg );
253
234
}
254
235
255
236
static inline u32 hecc_read_mbx (struct ti_hecc_priv * priv , u32 mbxno , u32 reg )
256
237
{
257
- return __raw_readl (priv -> base + priv -> mbx_offset + mbxno * 0x10 +
258
- reg );
238
+ return __raw_readl (priv -> mbx + mbxno * 0x10 + reg );
259
239
}
260
240
261
241
static inline void hecc_write (struct ti_hecc_priv * priv , u32 reg , u32 val )
@@ -311,11 +291,16 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv)
311
291
return 0 ;
312
292
}
313
293
314
- static void ti_hecc_transceiver_switch (const struct ti_hecc_priv * priv ,
315
- int on )
294
+ static int ti_hecc_transceiver_switch (const struct ti_hecc_priv * priv ,
295
+ int on )
316
296
{
317
- if (priv -> transceiver_switch )
318
- priv -> transceiver_switch (on );
297
+ if (!priv -> reg_xceiver )
298
+ return 0 ;
299
+
300
+ if (on )
301
+ return regulator_enable (priv -> reg_xceiver );
302
+ else
303
+ return regulator_disable (priv -> reg_xceiver );
319
304
}
320
305
321
306
static void ti_hecc_reset (struct net_device * ndev )
@@ -409,7 +394,7 @@ static void ti_hecc_start(struct net_device *ndev)
409
394
410
395
/* Prevent message over-write & Enable interrupts */
411
396
hecc_write (priv , HECC_CANOPC , HECC_SET_REG );
412
- if (priv -> int_line ) {
397
+ if (priv -> use_hecc1int ) {
413
398
hecc_write (priv , HECC_CANMIL , HECC_SET_REG );
414
399
hecc_write (priv , HECC_CANGIM , HECC_CANGIM_DEF_MASK |
415
400
HECC_CANGIM_I1EN | HECC_CANGIM_SIL );
@@ -760,7 +745,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
760
745
unsigned long ack , flags ;
761
746
762
747
int_status = hecc_read (priv ,
763
- (priv -> int_line ) ? HECC_CANGIF1 : HECC_CANGIF0 );
748
+ (priv -> use_hecc1int ) ? HECC_CANGIF1 : HECC_CANGIF0 );
764
749
765
750
if (!int_status )
766
751
return IRQ_NONE ;
@@ -806,7 +791,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
806
791
}
807
792
808
793
/* clear all interrupt conditions - read back to avoid spurious ints */
809
- if (priv -> int_line ) {
794
+ if (priv -> use_hecc1int ) {
810
795
hecc_write (priv , HECC_CANGIF1 , HECC_SET_REG );
811
796
int_status = hecc_read (priv , HECC_CANGIF1 );
812
797
} else {
@@ -872,58 +857,87 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
872
857
.ndo_change_mtu = can_change_mtu ,
873
858
};
874
859
860
+ static const struct of_device_id ti_hecc_dt_ids [] = {
861
+ {
862
+ .compatible = "ti,am3517-hecc" ,
863
+ },
864
+ { }
865
+ };
866
+ MODULE_DEVICE_TABLE (of , ti_hecc_dt_ids );
867
+
875
868
static int ti_hecc_probe (struct platform_device * pdev )
876
869
{
877
870
struct net_device * ndev = (struct net_device * )0 ;
878
871
struct ti_hecc_priv * priv ;
879
- struct ti_hecc_platform_data * pdata ;
880
- struct resource * mem , * irq ;
881
- void __iomem * addr ;
872
+ struct device_node * np = pdev -> dev . of_node ;
873
+ struct resource * res , * irq ;
874
+ struct regulator * reg_xceiver ;
882
875
int err = - ENODEV ;
883
876
884
- pdata = dev_get_platdata (& pdev -> dev );
885
- if (!pdata ) {
886
- dev_err (& pdev -> dev , "No platform data\n" );
887
- goto probe_exit ;
877
+ if (!IS_ENABLED (CONFIG_OF ) || !np )
878
+ return - EINVAL ;
879
+
880
+ reg_xceiver = devm_regulator_get (& pdev -> dev , "xceiver" );
881
+ if (PTR_ERR (reg_xceiver ) == - EPROBE_DEFER )
882
+ return - EPROBE_DEFER ;
883
+ else if (IS_ERR (reg_xceiver ))
884
+ reg_xceiver = NULL ;
885
+
886
+ ndev = alloc_candev (sizeof (struct ti_hecc_priv ), HECC_MAX_TX_MBOX );
887
+ if (!ndev ) {
888
+ dev_err (& pdev -> dev , "alloc_candev failed\n" );
889
+ return - ENOMEM ;
888
890
}
891
+ priv = netdev_priv (ndev );
889
892
890
- mem = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
891
- if (!mem ) {
892
- dev_err (& pdev -> dev , "No mem resources\n" );
893
- goto probe_exit ;
893
+ /* handle hecc memory */
894
+ res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "hecc" );
895
+ if (!res ) {
896
+ dev_err (& pdev -> dev , "can't get IORESOURCE_MEM hecc\n" );
897
+ return - EINVAL ;
894
898
}
895
- irq = platform_get_resource (pdev , IORESOURCE_IRQ , 0 );
896
- if (!irq ) {
897
- dev_err (& pdev -> dev , "No irq resource\n" );
898
- goto probe_exit ;
899
+
900
+ priv -> base = devm_ioremap_resource (& pdev -> dev , res );
901
+ if (!priv -> base ) {
902
+ dev_err (& pdev -> dev , "hecc ioremap failed\n" );
903
+ return - ENOMEM ;
899
904
}
900
- if (!request_mem_region (mem -> start , resource_size (mem ), pdev -> name )) {
901
- dev_err (& pdev -> dev , "HECC region already claimed\n" );
902
- err = - EBUSY ;
903
- goto probe_exit ;
905
+
906
+ /* handle hecc-ram memory */
907
+ res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "hecc-ram" );
908
+ if (!res ) {
909
+ dev_err (& pdev -> dev , "can't get IORESOURCE_MEM hecc-ram\n" );
910
+ return - EINVAL ;
904
911
}
905
- addr = ioremap ( mem -> start , resource_size ( mem ));
906
- if (! addr ) {
907
- dev_err ( & pdev -> dev , "ioremap failed\n" );
908
- err = - ENOMEM ;
909
- goto probe_exit_free_region ;
912
+
913
+ priv -> hecc_ram = devm_ioremap_resource ( & pdev -> dev , res );
914
+ if (! priv -> hecc_ram ) {
915
+ dev_err ( & pdev -> dev , "hecc-ram ioremap failed\n" ) ;
916
+ return - ENOMEM ;
910
917
}
911
918
912
- ndev = alloc_candev (sizeof (struct ti_hecc_priv ), HECC_MAX_TX_MBOX );
913
- if (!ndev ) {
914
- dev_err (& pdev -> dev , "alloc_candev failed\n" );
915
- err = - ENOMEM ;
916
- goto probe_exit_iounmap ;
919
+ /* handle mbx memory */
920
+ res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "mbx" );
921
+ if (!res ) {
922
+ dev_err (& pdev -> dev , "can't get IORESOURCE_MEM mbx\n" );
923
+ return - EINVAL ;
924
+ }
925
+
926
+ priv -> mbx = devm_ioremap_resource (& pdev -> dev , res );
927
+ if (!priv -> mbx ) {
928
+ dev_err (& pdev -> dev , "mbx ioremap failed\n" );
929
+ return - ENOMEM ;
930
+ }
931
+
932
+ irq = platform_get_resource (pdev , IORESOURCE_IRQ , 0 );
933
+ if (!irq ) {
934
+ dev_err (& pdev -> dev , "No irq resource\n" );
935
+ goto probe_exit ;
917
936
}
918
937
919
- priv = netdev_priv (ndev );
920
938
priv -> ndev = ndev ;
921
- priv -> base = addr ;
922
- priv -> scc_ram_offset = pdata -> scc_ram_offset ;
923
- priv -> hecc_ram_offset = pdata -> hecc_ram_offset ;
924
- priv -> mbx_offset = pdata -> mbx_offset ;
925
- priv -> int_line = pdata -> int_line ;
926
- priv -> transceiver_switch = pdata -> transceiver_switch ;
939
+ priv -> reg_xceiver = reg_xceiver ;
940
+ priv -> use_hecc1int = of_property_read_bool (np , "ti,use-hecc1int" );
927
941
928
942
priv -> can .bittiming_const = & ti_hecc_bittiming_const ;
929
943
priv -> can .do_set_mode = ti_hecc_do_set_mode ;
@@ -971,32 +985,23 @@ static int ti_hecc_probe(struct platform_device *pdev)
971
985
clk_put (priv -> clk );
972
986
probe_exit_candev :
973
987
free_candev (ndev );
974
- probe_exit_iounmap :
975
- iounmap (addr );
976
- probe_exit_free_region :
977
- release_mem_region (mem -> start , resource_size (mem ));
978
988
probe_exit :
979
989
return err ;
980
990
}
981
991
982
992
static int ti_hecc_remove (struct platform_device * pdev )
983
993
{
984
- struct resource * res ;
985
994
struct net_device * ndev = platform_get_drvdata (pdev );
986
995
struct ti_hecc_priv * priv = netdev_priv (ndev );
987
996
988
997
unregister_candev (ndev );
989
998
clk_disable_unprepare (priv -> clk );
990
999
clk_put (priv -> clk );
991
- res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
992
- iounmap (priv -> base );
993
- release_mem_region (res -> start , resource_size (res ));
994
1000
free_candev (ndev );
995
1001
996
1002
return 0 ;
997
1003
}
998
1004
999
-
1000
1005
#ifdef CONFIG_PM
1001
1006
static int ti_hecc_suspend (struct platform_device * pdev , pm_message_t state )
1002
1007
{
@@ -1045,6 +1050,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
1045
1050
static struct platform_driver ti_hecc_driver = {
1046
1051
.driver = {
1047
1052
.name = DRV_NAME ,
1053
+ .of_match_table = ti_hecc_dt_ids ,
1048
1054
},
1049
1055
.probe = ti_hecc_probe ,
1050
1056
.remove = ti_hecc_remove ,
0 commit comments