|
@@ -24,7 +24,6 @@
|
|
|
#include <linux/can/dev.h>
|
|
|
#include <linux/can/error.h>
|
|
|
#include <linux/can/led.h>
|
|
|
-#include <linux/can/platform/flexcan.h>
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/if_arp.h>
|
|
@@ -37,6 +36,7 @@
|
|
|
#include <linux/of.h>
|
|
|
#include <linux/of_device.h>
|
|
|
#include <linux/platform_device.h>
|
|
|
+#include <linux/regulator/consumer.h>
|
|
|
|
|
|
#define DRV_NAME "flexcan"
|
|
|
|
|
@@ -211,6 +211,7 @@ struct flexcan_priv {
|
|
|
struct clk *clk_per;
|
|
|
struct flexcan_platform_data *pdata;
|
|
|
const struct flexcan_devtype_data *devtype_data;
|
|
|
+ struct regulator *reg_xceiver;
|
|
|
};
|
|
|
|
|
|
static struct flexcan_devtype_data fsl_p1010_devtype_data = {
|
|
@@ -258,15 +259,6 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-/*
|
|
|
- * Swtich transceiver on or off
|
|
|
- */
|
|
|
-static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on)
|
|
|
-{
|
|
|
- if (priv->pdata && priv->pdata->transceiver_switch)
|
|
|
- priv->pdata->transceiver_switch(on);
|
|
|
-}
|
|
|
-
|
|
|
static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
|
|
|
u32 reg_esr)
|
|
|
{
|
|
@@ -799,7 +791,11 @@ static int flexcan_chip_start(struct net_device *dev)
|
|
|
if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
|
|
|
flexcan_write(0x0, ®s->rxfgmask);
|
|
|
|
|
|
- flexcan_transceiver_switch(priv, 1);
|
|
|
+ if (priv->reg_xceiver) {
|
|
|
+ err = regulator_enable(priv->reg_xceiver);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
/* synchronize with the can bus */
|
|
|
reg_mcr = flexcan_read(®s->mcr);
|
|
@@ -842,7 +838,8 @@ static void flexcan_chip_stop(struct net_device *dev)
|
|
|
reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
|
|
|
flexcan_write(reg, ®s->mcr);
|
|
|
|
|
|
- flexcan_transceiver_switch(priv, 0);
|
|
|
+ if (priv->reg_xceiver)
|
|
|
+ regulator_disable(priv->reg_xceiver);
|
|
|
priv->can.state = CAN_STATE_STOPPED;
|
|
|
|
|
|
return;
|
|
@@ -1084,6 +1081,10 @@ static int flexcan_probe(struct platform_device *pdev)
|
|
|
priv->pdata = pdev->dev.platform_data;
|
|
|
priv->devtype_data = devtype_data;
|
|
|
|
|
|
+ priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver");
|
|
|
+ if (IS_ERR(priv->reg_xceiver))
|
|
|
+ priv->reg_xceiver = NULL;
|
|
|
+
|
|
|
netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
|
|
|
|
|
|
dev_set_drvdata(&pdev->dev, dev);
|