aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2014-02-20 03:48:05 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:57:44 -0400
commit93a1ab5533c0fb9047d7ab91e516c450219a97a3 (patch)
tree30fb31ef8b3cfd1e337666d922d7588daa4976cc
parent80a72be45341c352bb178c83715ac4f3473893d7 (diff)
ENGR00300439-3 imx6sx: use auxdata for can transceiver setting
We still do not have a framework for can tranceiver settings. Use audxdata as workaround as before. Signed-off-by: Dong Aisheng <b29396@freescale.com>
-rw-r--r--arch/arm/mach-imx/mach-imx6sx.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index 3aca0e0359a1..a0059960dd8b 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -7,11 +7,14 @@
7 * 7 *
8 */ 8 */
9 9
10#include <linux/can/platform/flexcan.h>
10#include <linux/clk-provider.h> 11#include <linux/clk-provider.h>
11#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/gpio.h>
12#include <linux/irqchip.h> 14#include <linux/irqchip.h>
13#include <linux/of.h> 15#include <linux/of.h>
14#include <linux/of_address.h> 16#include <linux/of_address.h>
17#include <linux/of_gpio.h>
15#include <linux/of_platform.h> 18#include <linux/of_platform.h>
16#include <linux/opp.h> 19#include <linux/opp.h>
17#include <linux/phy.h> 20#include <linux/phy.h>
@@ -26,6 +29,62 @@
26#include "cpuidle.h" 29#include "cpuidle.h"
27#include "hardware.h" 30#include "hardware.h"
28 31
32static struct flexcan_platform_data flexcan_pdata[2];
33static int flexcan_en_gpio;
34static int flexcan_stby_gpio;
35static int flexcan0_en;
36static int flexcan1_en;
37static void mx6sx_flexcan_switch(void)
38{
39 if (flexcan0_en || flexcan1_en) {
40 gpio_set_value_cansleep(flexcan_en_gpio, 0);
41 gpio_set_value_cansleep(flexcan_stby_gpio, 0);
42 gpio_set_value_cansleep(flexcan_en_gpio, 1);
43 gpio_set_value_cansleep(flexcan_stby_gpio, 1);
44 } else {
45 /*
46 * avoid to disable CAN xcvr if any of the CAN interfaces
47 * are down. XCRV will be disabled only if both CAN2
48 * interfaces are DOWN.
49 */
50 gpio_set_value_cansleep(flexcan_en_gpio, 0);
51 gpio_set_value_cansleep(flexcan_stby_gpio, 0);
52 }
53}
54
55static void imx6sx_arm2_flexcan0_switch(int enable)
56{
57 flexcan0_en = enable;
58 mx6sx_flexcan_switch();
59}
60
61static void imx6sx_arm2_flexcan1_switch(int enable)
62{
63 flexcan1_en = enable;
64 mx6sx_flexcan_switch();
65}
66
67static int __init imx6sx_arm2_flexcan_fixup(void)
68{
69 struct device_node *np;
70
71 np = of_find_node_by_path("/soc/aips-bus@02000000/can@02090000");
72 if (!np)
73 return -ENODEV;
74
75 flexcan_en_gpio = of_get_named_gpio(np, "trx-en-gpio", 0);
76 flexcan_stby_gpio = of_get_named_gpio(np, "trx-stby-gpio", 0);
77 if (gpio_is_valid(flexcan_en_gpio) && gpio_is_valid(flexcan_stby_gpio) &&
78 !gpio_request_one(flexcan_en_gpio, GPIOF_DIR_OUT, "flexcan-trx-en") &&
79 !gpio_request_one(flexcan_stby_gpio, GPIOF_DIR_OUT, "flexcan-trx-stby")) {
80 /* flexcan 0 & 1 are using the same GPIOs for transceiver */
81 flexcan_pdata[0].transceiver_switch = imx6sx_arm2_flexcan0_switch;
82 flexcan_pdata[1].transceiver_switch = imx6sx_arm2_flexcan1_switch;
83 }
84
85 return 0;
86}
87
29static void __init imx6sx_enet_clk_sel(void) 88static void __init imx6sx_enet_clk_sel(void)
30{ 89{
31 struct regmap *gpr; 90 struct regmap *gpr;
@@ -87,6 +146,13 @@ static inline void imx6sx_enet_init(void)
87 imx6sx_enet_clk_sel(); 146 imx6sx_enet_clk_sel();
88} 147}
89 148
149/* Add auxdata to pass platform data */
150static const struct of_dev_auxdata imx6sx_auxdata_lookup[] __initconst = {
151 OF_DEV_AUXDATA("fsl,imx6q-flexcan", 0x02090000, NULL, &flexcan_pdata[0]),
152 OF_DEV_AUXDATA("fsl,imx6q-flexcan", 0x02094000, NULL, &flexcan_pdata[1]),
153 { /* sentinel */ }
154};
155
90static void __init imx6sx_init_machine(void) 156static void __init imx6sx_init_machine(void)
91{ 157{
92 struct device *parent; 158 struct device *parent;
@@ -97,7 +163,8 @@ static void __init imx6sx_init_machine(void)
97 if (parent == NULL) 163 if (parent == NULL)
98 pr_warn("failed to initialize soc device\n"); 164 pr_warn("failed to initialize soc device\n");
99 165
100 of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); 166 of_platform_populate(NULL, of_default_bus_match_table,
167 imx6sx_auxdata_lookup, parent);
101 168
102 imx6sx_enet_init(); 169 imx6sx_enet_init();
103 imx_anatop_init(); 170 imx_anatop_init();
@@ -119,6 +186,9 @@ static void __init imx6sx_init_late(void)
119 IMX6Q_GPR1_GINT_ASSERT); 186 IMX6Q_GPR1_GINT_ASSERT);
120 187
121 imx6q_cpuidle_init(); 188 imx6q_cpuidle_init();
189
190 if (of_machine_is_compatible("fsl,imx6sx-17x17-arm2"))
191 imx6sx_arm2_flexcan_fixup();
122} 192}
123 193
124static void __init imx6sx_map_io(void) 194static void __init imx6sx_map_io(void)