Message ID | 20230327073354.1003134-2-mkl@pengutronix.de (mailing list archive) |
---|---|
State | Accepted |
Commit | a0340df7eca4f28e18afd3ecd6e464db5f2994c0 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next,01/11] can: rcar_canfd: Add transceiver support | expand |
Hello: This series was applied to netdev/net-next.git (main) by Marc Kleine-Budde <mkl@pengutronix.de>: On Mon, 27 Mar 2023 09:33:44 +0200 you wrote: > From: Geert Uytterhoeven <geert+renesas@glider.be> > > Add support for CAN transceivers described as PHYs. > > While simple CAN transceivers can do without, this is needed for CAN > transceivers like NXP TJR1443 that need a configuration step (like > pulling standby or enable lines), and/or impose a bitrate limit. > > [...] Here is the summary with links: - [net-next,01/11] can: rcar_canfd: Add transceiver support https://git.kernel.org/netdev/net-next/c/a0340df7eca4 - [net-next,02/11] can: rcar_canfd: Improve error messages https://git.kernel.org/netdev/net-next/c/33eced402b18 - [net-next,03/11] can: c_can: Remove redundant pci_clear_master https://git.kernel.org/netdev/net-next/c/594503341de7 - [net-next,04/11] can: ctucanfd: Remove redundant pci_clear_master https://git.kernel.org/netdev/net-next/c/c9d23f9657ca - [net-next,05/11] can: kvaser_pciefd: Remove redundant pci_clear_master https://git.kernel.org/netdev/net-next/c/8db931835fad - [net-next,06/11] can: esd_usb: Improve code readability by means of replacing struct esd_usb_msg with a union https://git.kernel.org/netdev/net-next/c/a57915aee315 - [net-next,07/11] can: m_can: Remove repeated check for is_peripheral https://git.kernel.org/netdev/net-next/c/73042934e4a3 - [net-next,08/11] can: m_can: Always acknowledge all interrupts https://git.kernel.org/netdev/net-next/c/4ab639480900 - [net-next,09/11] can: m_can: Remove double interrupt enable https://git.kernel.org/netdev/net-next/c/71725bfdbbf2 - [net-next,10/11] can: m_can: Disable unused interrupts https://git.kernel.org/netdev/net-next/c/897e663218e2 - [net-next,11/11] can: m_can: Keep interrupts enabled during peripheral read https://git.kernel.org/netdev/net-next/c/9083e0b09df3 You are awesome, thank you!
On Mon, 27 Mar 2023 09:33:44 +0200 Marc Kleine-Budde wrote: > @@ -1836,6 +1849,7 @@ static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch) > > static int rcar_canfd_probe(struct platform_device *pdev) > { > + struct phy *transceivers[RCANFD_NUM_CHANNELS] = { 0, }; > const struct rcar_canfd_hw_info *info; > struct device *dev = &pdev->dev; > void __iomem *addr; [somehow this got stuck in my outgoing mail] drivers/net/can/rcar/rcar_canfd.c:1852:59: warning: Using plain integer as NULL pointer Could you follow up with a fix fix?
Hi Jakub, On Tue, Mar 28, 2023 at 11:57 PM Jakub Kicinski <kuba@kernel.org> wrote: > On Mon, 27 Mar 2023 09:33:44 +0200 Marc Kleine-Budde wrote: > > @@ -1836,6 +1849,7 @@ static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch) > > > > static int rcar_canfd_probe(struct platform_device *pdev) > > { > > + struct phy *transceivers[RCANFD_NUM_CHANNELS] = { 0, }; > > const struct rcar_canfd_hw_info *info; > > struct device *dev = &pdev->dev; > > void __iomem *addr; > > [somehow this got stuck in my outgoing mail] > > drivers/net/can/rcar/rcar_canfd.c:1852:59: warning: Using plain integer as NULL pointer > > Could you follow up with a fix fix? Sure (that one was well hidden in the sparse output) https://lore.kernel.org/r/7f7b0dde0caa2d2977b4fb5b65b63036e75f5022.1680071972.git.geert+renesas@glider.be Thanks! Gr{oetje,eeting}s, Geert
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index ef4e1b9a9e1e..d8fbc3fca475 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -35,6 +35,7 @@ #include <linux/netdevice.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/reset.h> #include <linux/types.h> @@ -530,6 +531,7 @@ struct rcar_canfd_channel { struct net_device *ndev; struct rcar_canfd_global *gpriv; /* Controller reference */ void __iomem *base; /* Register base address */ + struct phy *transceiver; /* Optional transceiver */ struct napi_struct napi; u32 tx_head; /* Incremented on xmit */ u32 tx_tail; /* Incremented on xmit done */ @@ -1413,11 +1415,17 @@ static int rcar_canfd_open(struct net_device *ndev) struct rcar_canfd_global *gpriv = priv->gpriv; int err; + err = phy_power_on(priv->transceiver); + if (err) { + netdev_err(ndev, "failed to power on PHY: %pe\n", ERR_PTR(err)); + return err; + } + /* Peripheral clock is already enabled in probe */ err = clk_prepare_enable(gpriv->can_clk); if (err) { netdev_err(ndev, "failed to enable CAN clock, error %d\n", err); - goto out_clock; + goto out_phy; } err = open_candev(ndev); @@ -1437,7 +1445,8 @@ static int rcar_canfd_open(struct net_device *ndev) close_candev(ndev); out_can_clock: clk_disable_unprepare(gpriv->can_clk); -out_clock: +out_phy: + phy_power_off(priv->transceiver); return err; } @@ -1480,6 +1489,7 @@ static int rcar_canfd_close(struct net_device *ndev) napi_disable(&priv->napi); clk_disable_unprepare(gpriv->can_clk); close_candev(ndev); + phy_power_off(priv->transceiver); return 0; } @@ -1711,7 +1721,7 @@ static const struct ethtool_ops rcar_canfd_ethtool_ops = { }; static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, - u32 fcan_freq) + u32 fcan_freq, struct phy *transceiver) { const struct rcar_canfd_hw_info *info = gpriv->info; struct platform_device *pdev = gpriv->pdev; @@ -1732,8 +1742,11 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ndev->flags |= IFF_ECHO; priv->ndev = ndev; priv->base = gpriv->base; + priv->transceiver = transceiver; priv->channel = ch; priv->gpriv = gpriv; + if (transceiver) + priv->can.bitrate_max = transceiver->attrs.max_link_rate; priv->can.clock.freq = fcan_freq; dev_info(dev, "can_clk rate is %u\n", priv->can.clock.freq); @@ -1836,6 +1849,7 @@ static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch) static int rcar_canfd_probe(struct platform_device *pdev) { + struct phy *transceivers[RCANFD_NUM_CHANNELS] = { 0, }; const struct rcar_canfd_hw_info *info; struct device *dev = &pdev->dev; void __iomem *addr; @@ -1857,9 +1871,14 @@ static int rcar_canfd_probe(struct platform_device *pdev) for (i = 0; i < info->max_channels; ++i) { name[7] = '0' + i; of_child = of_get_child_by_name(dev->of_node, name); - if (of_child && of_device_is_available(of_child)) + if (of_child && of_device_is_available(of_child)) { channels_mask |= BIT(i); + transceivers[i] = devm_of_phy_optional_get(dev, + of_child, NULL); + } of_node_put(of_child); + if (IS_ERR(transceivers[i])) + return PTR_ERR(transceivers[i]); } if (info->shared_global_irqs) { @@ -2035,7 +2054,8 @@ static int rcar_canfd_probe(struct platform_device *pdev) } for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) { - err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq); + err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq, + transceivers[ch]); if (err) goto fail_channel; }