Files
android_kernel_xiaomi_sm8450/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
Yangbo Lu d346c9e86d dpaa2-ptp: reuse ptp_qoriq driver
Although dpaa2-ptp.c driver is a fsl_mc_driver which
is using MC APIs for register accessing, it's same IP
block with eTSEC/DPAA/ENETC 1588 timer.
This patch is to convert to reuse ptp_qoriq driver by
using register ioremap and dropping related MC APIs.
However the interrupts could only be handled by MC which
fires MSIs to ARM cores. So the interrupt enabling and
handling still rely on MC APIs.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-06-15 13:43:06 -07:00

132 lines
2.6 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2013-2016 Freescale Semiconductor Inc.
* Copyright 2016-2018 NXP
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/fsl/mc.h>
#include <linux/fsl/ptp_qoriq.h>
#include "dpaa2-ptp.h"
static const struct ptp_clock_info dpaa2_ptp_caps = {
.owner = THIS_MODULE,
.name = "DPAA2 PTP Clock",
.max_adj = 512000,
.n_alarm = 2,
.n_ext_ts = 2,
.n_per_out = 3,
.n_pins = 0,
.pps = 1,
.adjfine = ptp_qoriq_adjfine,
.adjtime = ptp_qoriq_adjtime,
.gettime64 = ptp_qoriq_gettime,
.settime64 = ptp_qoriq_settime,
};
static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
{
struct device *dev = &mc_dev->dev;
struct ptp_qoriq *ptp_qoriq;
struct device_node *node;
void __iomem *base;
int err;
ptp_qoriq = devm_kzalloc(dev, sizeof(*ptp_qoriq), GFP_KERNEL);
if (!ptp_qoriq)
return -ENOMEM;
err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io);
if (err) {
if (err == -ENXIO)
err = -EPROBE_DEFER;
else
dev_err(dev, "fsl_mc_portal_allocate err %d\n", err);
goto err_exit;
}
err = dprtc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
&mc_dev->mc_handle);
if (err) {
dev_err(dev, "dprtc_open err %d\n", err);
goto err_free_mcp;
}
ptp_qoriq->dev = dev;
node = of_find_compatible_node(NULL, NULL, "fsl,dpaa2-ptp");
if (!node) {
err = -ENODEV;
goto err_close;
}
dev->of_node = node;
base = of_iomap(node, 0);
if (!base) {
err = -ENOMEM;
goto err_close;
}
err = ptp_qoriq_init(ptp_qoriq, base, &dpaa2_ptp_caps);
if (err)
goto err_unmap;
dpaa2_phc_index = ptp_qoriq->phc_index;
dev_set_drvdata(dev, ptp_qoriq);
return 0;
err_unmap:
iounmap(base);
err_close:
dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
err_free_mcp:
fsl_mc_portal_free(mc_dev->mc_io);
err_exit:
return err;
}
static int dpaa2_ptp_remove(struct fsl_mc_device *mc_dev)
{
struct device *dev = &mc_dev->dev;
struct ptp_qoriq *ptp_qoriq;
ptp_qoriq = dev_get_drvdata(dev);
dpaa2_phc_index = -1;
ptp_qoriq_free(ptp_qoriq);
dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
fsl_mc_portal_free(mc_dev->mc_io);
return 0;
}
static const struct fsl_mc_device_id dpaa2_ptp_match_id_table[] = {
{
.vendor = FSL_MC_VENDOR_FREESCALE,
.obj_type = "dprtc",
},
{}
};
MODULE_DEVICE_TABLE(fslmc, dpaa2_ptp_match_id_table);
static struct fsl_mc_driver dpaa2_ptp_drv = {
.driver = {
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = dpaa2_ptp_probe,
.remove = dpaa2_ptp_remove,
.match_id_table = dpaa2_ptp_match_id_table,
};
module_fsl_mc_driver(dpaa2_ptp_drv);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("DPAA2 PTP Clock Driver");