1717 *
1818 */
1919
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-
3920#include <linux/module.h>
4021#include <linux/kernel.h>
4122#include <linux/types.h>
4627#include <linux/platform_device.h>
4728#include <linux/clk.h>
4829#include <linux/io.h>
30+ #include <linux/of.h>
31+ #include <linux/of_device.h>
32+ #include <linux/regulator/consumer.h>
4933
5034#include <linux/can/dev.h>
5135#include <linux/can/error.h>
5236#include <linux/can/led.h>
53- #include <linux/can/platform/ti_hecc.h>
5437
5538#define DRV_NAME "ti_hecc"
5639#define HECC_MODULE_VERSION "0.7"
@@ -214,15 +197,14 @@ struct ti_hecc_priv {
214197 struct net_device * ndev ;
215198 struct clk * clk ;
216199 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 ;
221203 spinlock_t mbx_lock ; /* CANME register needs protection */
222204 u32 tx_head ;
223205 u32 tx_tail ;
224206 u32 rx_next ;
225- void ( * transceiver_switch )( int ) ;
207+ struct regulator * reg_xceiver ;
226208};
227209
228210static 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)
242224
243225static inline void hecc_write_lam (struct ti_hecc_priv * priv , u32 mbxno , u32 val )
244226{
245- __raw_writel (val , priv -> base + priv -> hecc_ram_offset + mbxno * 4 );
227+ __raw_writel (val , priv -> hecc_ram + mbxno * 4 );
246228}
247229
248230static inline void hecc_write_mbx (struct ti_hecc_priv * priv , u32 mbxno ,
249231 u32 reg , u32 val )
250232{
251- __raw_writel (val , priv -> base + priv -> mbx_offset + mbxno * 0x10 +
252- reg );
233+ __raw_writel (val , priv -> mbx + mbxno * 0x10 + reg );
253234}
254235
255236static inline u32 hecc_read_mbx (struct ti_hecc_priv * priv , u32 mbxno , u32 reg )
256237{
257- return __raw_readl (priv -> base + priv -> mbx_offset + mbxno * 0x10 +
258- reg );
238+ return __raw_readl (priv -> mbx + mbxno * 0x10 + reg );
259239}
260240
261241static 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)
311291 return 0 ;
312292}
313293
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 )
316296{
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 );
319304}
320305
321306static void ti_hecc_reset (struct net_device * ndev )
@@ -409,7 +394,7 @@ static void ti_hecc_start(struct net_device *ndev)
409394
410395 /* Prevent message over-write & Enable interrupts */
411396 hecc_write (priv , HECC_CANOPC , HECC_SET_REG );
412- if (priv -> int_line ) {
397+ if (priv -> use_hecc1int ) {
413398 hecc_write (priv , HECC_CANMIL , HECC_SET_REG );
414399 hecc_write (priv , HECC_CANGIM , HECC_CANGIM_DEF_MASK |
415400 HECC_CANGIM_I1EN | HECC_CANGIM_SIL );
@@ -760,7 +745,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
760745 unsigned long ack , flags ;
761746
762747 int_status = hecc_read (priv ,
763- (priv -> int_line ) ? HECC_CANGIF1 : HECC_CANGIF0 );
748+ (priv -> use_hecc1int ) ? HECC_CANGIF1 : HECC_CANGIF0 );
764749
765750 if (!int_status )
766751 return IRQ_NONE ;
@@ -806,7 +791,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
806791 }
807792
808793 /* clear all interrupt conditions - read back to avoid spurious ints */
809- if (priv -> int_line ) {
794+ if (priv -> use_hecc1int ) {
810795 hecc_write (priv , HECC_CANGIF1 , HECC_SET_REG );
811796 int_status = hecc_read (priv , HECC_CANGIF1 );
812797 } else {
@@ -872,58 +857,87 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
872857 .ndo_change_mtu = can_change_mtu ,
873858};
874859
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+
875868static int ti_hecc_probe (struct platform_device * pdev )
876869{
877870 struct net_device * ndev = (struct net_device * )0 ;
878871 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 ;
882875 int err = - ENODEV ;
883876
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 ;
888890 }
891+ priv = netdev_priv (ndev );
889892
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 ;
894898 }
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 ;
899904 }
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 ;
904911 }
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 ;
910917 }
911918
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 ;
917936 }
918937
919- priv = netdev_priv (ndev );
920938 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" );
927941
928942 priv -> can .bittiming_const = & ti_hecc_bittiming_const ;
929943 priv -> can .do_set_mode = ti_hecc_do_set_mode ;
@@ -971,32 +985,23 @@ static int ti_hecc_probe(struct platform_device *pdev)
971985 clk_put (priv -> clk );
972986probe_exit_candev :
973987 free_candev (ndev );
974- probe_exit_iounmap :
975- iounmap (addr );
976- probe_exit_free_region :
977- release_mem_region (mem -> start , resource_size (mem ));
978988probe_exit :
979989 return err ;
980990}
981991
982992static int ti_hecc_remove (struct platform_device * pdev )
983993{
984- struct resource * res ;
985994 struct net_device * ndev = platform_get_drvdata (pdev );
986995 struct ti_hecc_priv * priv = netdev_priv (ndev );
987996
988997 unregister_candev (ndev );
989998 clk_disable_unprepare (priv -> clk );
990999 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 ));
9941000 free_candev (ndev );
9951001
9961002 return 0 ;
9971003}
9981004
999-
10001005#ifdef CONFIG_PM
10011006static int ti_hecc_suspend (struct platform_device * pdev , pm_message_t state )
10021007{
@@ -1045,6 +1050,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
10451050static struct platform_driver ti_hecc_driver = {
10461051 .driver = {
10471052 .name = DRV_NAME ,
1053+ .of_match_table = ti_hecc_dt_ids ,
10481054 },
10491055 .probe = ti_hecc_probe ,
10501056 .remove = ti_hecc_remove ,
0 commit comments