ravb: Add support for r8a7795 SoC
This patch supports the r8a7795 SoC by: - Using two interrupts + One for E-MAC + One for everything else + Both can be handled by the existing common interrupt handler, which affords a simpler update to support the new SoC. In future some consideration may be given to implementing multiple interrupt handlers - Limiting the phy speed to 100Mbit/s for the new SoC; at this time it is not clear how this restriction may be lifted but I hope it will be possible as more information comes to light Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com> [horms: reworked] Signed-off-by: Simon Horman <horms+renesas@verge.net.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
619f3bd2e1
Коммит
22d4df8ff3
|
@ -766,6 +766,11 @@ struct ravb_ptp {
|
||||||
struct ravb_ptp_perout perout[N_PER_OUT];
|
struct ravb_ptp_perout perout[N_PER_OUT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ravb_chip_id {
|
||||||
|
RCAR_GEN2,
|
||||||
|
RCAR_GEN3,
|
||||||
|
};
|
||||||
|
|
||||||
struct ravb_private {
|
struct ravb_private {
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
|
@ -806,6 +811,8 @@ struct ravb_private {
|
||||||
int msg_enable;
|
int msg_enable;
|
||||||
int speed;
|
int speed;
|
||||||
int duplex;
|
int duplex;
|
||||||
|
int emac_irq;
|
||||||
|
enum ravb_chip_id chip_id;
|
||||||
|
|
||||||
unsigned no_avb_link:1;
|
unsigned no_avb_link:1;
|
||||||
unsigned avb_link_active_low:1;
|
unsigned avb_link_active_low:1;
|
||||||
|
|
|
@ -889,6 +889,22 @@ static int ravb_phy_init(struct net_device *ndev)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This driver only support 10/100Mbit speeds on Gen3
|
||||||
|
* at this time.
|
||||||
|
*/
|
||||||
|
if (priv->chip_id == RCAR_GEN3) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = phy_set_max_speed(phydev, SPEED_100);
|
||||||
|
if (err) {
|
||||||
|
netdev_err(ndev, "failed to limit PHY to 100Mbit/s\n");
|
||||||
|
phy_disconnect(phydev);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev_info(ndev, "limited PHY to 100Mbit/s\n");
|
||||||
|
}
|
||||||
|
|
||||||
netdev_info(ndev, "attached PHY %d (IRQ %d) to driver %s\n",
|
netdev_info(ndev, "attached PHY %d (IRQ %d) to driver %s\n",
|
||||||
phydev->addr, phydev->irq, phydev->drv->name);
|
phydev->addr, phydev->irq, phydev->drv->name);
|
||||||
|
|
||||||
|
@ -1197,6 +1213,15 @@ static int ravb_open(struct net_device *ndev)
|
||||||
goto out_napi_off;
|
goto out_napi_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->chip_id == RCAR_GEN3) {
|
||||||
|
error = request_irq(priv->emac_irq, ravb_interrupt,
|
||||||
|
IRQF_SHARED, ndev->name, ndev);
|
||||||
|
if (error) {
|
||||||
|
netdev_err(ndev, "cannot request IRQ\n");
|
||||||
|
goto out_free_irq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Device init */
|
/* Device init */
|
||||||
error = ravb_dmac_init(ndev);
|
error = ravb_dmac_init(ndev);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -1220,6 +1245,7 @@ out_ptp_stop:
|
||||||
ravb_ptp_stop(ndev);
|
ravb_ptp_stop(ndev);
|
||||||
out_free_irq:
|
out_free_irq:
|
||||||
free_irq(ndev->irq, ndev);
|
free_irq(ndev->irq, ndev);
|
||||||
|
free_irq(priv->emac_irq, ndev);
|
||||||
out_napi_off:
|
out_napi_off:
|
||||||
napi_disable(&priv->napi[RAVB_NC]);
|
napi_disable(&priv->napi[RAVB_NC]);
|
||||||
napi_disable(&priv->napi[RAVB_BE]);
|
napi_disable(&priv->napi[RAVB_BE]);
|
||||||
|
@ -1625,10 +1651,20 @@ static int ravb_mdio_release(struct ravb_private *priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id ravb_match_table[] = {
|
||||||
|
{ .compatible = "renesas,etheravb-r8a7790", .data = (void *)RCAR_GEN2 },
|
||||||
|
{ .compatible = "renesas,etheravb-r8a7794", .data = (void *)RCAR_GEN2 },
|
||||||
|
{ .compatible = "renesas,etheravb-r8a7795", .data = (void *)RCAR_GEN3 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, ravb_match_table);
|
||||||
|
|
||||||
static int ravb_probe(struct platform_device *pdev)
|
static int ravb_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
const struct of_device_id *match;
|
||||||
struct ravb_private *priv;
|
struct ravb_private *priv;
|
||||||
|
enum ravb_chip_id chip_id;
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
int error, irq, q;
|
int error, irq, q;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
@ -1657,6 +1693,13 @@ static int ravb_probe(struct platform_device *pdev)
|
||||||
/* The Ether-specific entries in the device structure. */
|
/* The Ether-specific entries in the device structure. */
|
||||||
ndev->base_addr = res->start;
|
ndev->base_addr = res->start;
|
||||||
ndev->dma = -1;
|
ndev->dma = -1;
|
||||||
|
|
||||||
|
match = of_match_device(of_match_ptr(ravb_match_table), &pdev->dev);
|
||||||
|
chip_id = (enum ravb_chip_id)match->data;
|
||||||
|
|
||||||
|
if (chip_id == RCAR_GEN3)
|
||||||
|
irq = platform_get_irq_byname(pdev, "ch22");
|
||||||
|
else
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if (irq < 0) {
|
if (irq < 0) {
|
||||||
error = irq;
|
error = irq;
|
||||||
|
@ -1688,6 +1731,17 @@ static int ravb_probe(struct platform_device *pdev)
|
||||||
priv->avb_link_active_low =
|
priv->avb_link_active_low =
|
||||||
of_property_read_bool(np, "renesas,ether-link-active-low");
|
of_property_read_bool(np, "renesas,ether-link-active-low");
|
||||||
|
|
||||||
|
if (chip_id == RCAR_GEN3) {
|
||||||
|
irq = platform_get_irq_byname(pdev, "ch24");
|
||||||
|
if (irq < 0) {
|
||||||
|
error = irq;
|
||||||
|
goto out_release;
|
||||||
|
}
|
||||||
|
priv->emac_irq = irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->chip_id = chip_id;
|
||||||
|
|
||||||
/* Set function */
|
/* Set function */
|
||||||
ndev->netdev_ops = &ravb_netdev_ops;
|
ndev->netdev_ops = &ravb_netdev_ops;
|
||||||
ndev->ethtool_ops = &ravb_ethtool_ops;
|
ndev->ethtool_ops = &ravb_ethtool_ops;
|
||||||
|
@ -1818,13 +1872,6 @@ static const struct dev_pm_ops ravb_dev_pm_ops = {
|
||||||
#define RAVB_PM_OPS NULL
|
#define RAVB_PM_OPS NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const struct of_device_id ravb_match_table[] = {
|
|
||||||
{ .compatible = "renesas,etheravb-r8a7790" },
|
|
||||||
{ .compatible = "renesas,etheravb-r8a7794" },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(of, ravb_match_table);
|
|
||||||
|
|
||||||
static struct platform_driver ravb_driver = {
|
static struct platform_driver ravb_driver = {
|
||||||
.probe = ravb_probe,
|
.probe = ravb_probe,
|
||||||
.remove = ravb_remove,
|
.remove = ravb_remove,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче