Commit 85b51fa3 authored by Marc Kleine-Budde's avatar Marc Kleine-Budde
Browse files

Merge patch series "can: flexcan: add transceiver capabilities"

Dimitri Fedrau <dimitri.fedrau@liebherr.com> says:

Currently the flexcan driver does only support adding PHYs by using
the "old" regulator bindings. Add support for CAN transceivers as a
PHY. Add the capability to ensure that the PHY is in operational state
when the link is set to an "up" state.

Changes in v4:
- Dropped "if: required: phys" in bindings
- Link to v3: https://lore.kernel.org/r/20250221-flexcan-add-transceiver-caps-v3-0-a947bde55a62@liebherr.com

Changes in v3:
- Have xceiver-supply or phys properties in bindings
- Switch do dev_err_probe in flexcan_probe when checking error of call
  devm_phy_optional_get
- Link to v2: https://lore.kernel.org/r/20250220-flexcan-add-transceiver-caps-v2-0-a81970f11846@liebherr.com

Changes in v2:
- Rename variable xceiver to transceiver in struct flexcan_priv and in
  flexcan_probe
- Set priv->can.bitrate_max if transceiver is found
- Fix commit messages which claim that transceivers are not supported
- Do not print error on EPROBE_DEFER after calling devm_phy_optional_get in
  flexcan_probe
- Link to v1: https://lore.kernel.org/r/20250211-flexcan-add-transceiver-caps-v1-0-c6abb7817b0f@liebherr.com

Link: https://patch.msgid.link/20250312-flexcan-add-transceiver-caps-v4-0-29e89ae0225a@liebherr.com


Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parents 941defce d80bfde3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -77,6 +77,9 @@ properties:
  xceiver-supply:
    description: Regulator that powers the CAN transceiver.

  phys:
    maxItems: 1

  big-endian:
    $ref: /schemas/types.yaml#/definitions/flag
    description: |
@@ -171,6 +174,12 @@ allOf:
        interrupts:
          maxItems: 1
        interrupt-names: false
  - if:
      required:
        - xceiver-supply
    then:
      properties:
        phys: false

additionalProperties: false

+21 −6
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/can/platform/flexcan.h>
#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/regmap.h>
@@ -644,18 +645,22 @@ static void flexcan_clks_disable(const struct flexcan_priv *priv)

static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
{
	if (!priv->reg_xceiver)
		return 0;

	if (priv->reg_xceiver)
		return regulator_enable(priv->reg_xceiver);
	else if (priv->transceiver)
		return phy_power_on(priv->transceiver);

	return 0;
}

static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
{
	if (!priv->reg_xceiver)
		return 0;

	if (priv->reg_xceiver)
		return regulator_disable(priv->reg_xceiver);
	else if (priv->transceiver)
		return phy_power_off(priv->transceiver);

	return 0;
}

static int flexcan_chip_enable(struct flexcan_priv *priv)
@@ -2086,6 +2091,7 @@ static int flexcan_probe(struct platform_device *pdev)
	struct net_device *dev;
	struct flexcan_priv *priv;
	struct regulator *reg_xceiver;
	struct phy *transceiver;
	struct clk *clk_ipg = NULL, *clk_per = NULL;
	struct flexcan_regs __iomem *regs;
	struct flexcan_platform_data *pdata;
@@ -2101,6 +2107,11 @@ static int flexcan_probe(struct platform_device *pdev)
	else if (IS_ERR(reg_xceiver))
		return PTR_ERR(reg_xceiver);

	transceiver = devm_phy_optional_get(&pdev->dev, NULL);
	if (IS_ERR(transceiver))
		return dev_err_probe(&pdev->dev, PTR_ERR(transceiver),
				     "failed to get phy\n");

	if (pdev->dev.of_node) {
		of_property_read_u32(pdev->dev.of_node,
				     "clock-frequency", &clock_freq);
@@ -2198,6 +2209,10 @@ static int flexcan_probe(struct platform_device *pdev)
	priv->clk_per = clk_per;
	priv->clk_src = clk_src;
	priv->reg_xceiver = reg_xceiver;
	priv->transceiver = transceiver;

	if (transceiver)
		priv->can.bitrate_max = transceiver->attrs.max_link_rate;

	if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
		priv->irq_boff = platform_get_irq(pdev, 1);
+1 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ struct flexcan_priv {
	struct clk *clk_per;
	struct flexcan_devtype_data devtype_data;
	struct regulator *reg_xceiver;
	struct phy *transceiver;
	struct flexcan_stop_mode stm;

	int irq_boff;