1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
Uwe Kleine-König 59272ad8d9 bus: fsl-mc: Make remove function return void
The value returned by an fsl-mc driver's remove function is mostly
ignored.  (Only an error message is printed if the value is non-zero
and then device removal continues unconditionally.)

So change the prototype of the remove function to return no value. This
way driver authors are not tempted to assume that passing an error to
the upper layer is a good idea. All drivers are adapted accordingly.
There is no intended change of behaviour, all callbacks were prepared to
return 0 before.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com> # sanity checks
Reviewed-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Tested-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Signed-off-by: Li Yang <leoyang.li@nxp.com>
2023-05-30 18:58:43 -05:00

259 lines
5.4 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2013-2016 Freescale Semiconductor Inc.
* Copyright 2016-2018 NXP
* Copyright 2020 NXP
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/fsl/mc.h>
#include "dpaa2-ptp.h"
static int dpaa2_ptp_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);
struct fsl_mc_device *mc_dev;
struct device *dev;
u32 mask = 0;
u32 bit;
int err;
dev = ptp_qoriq->dev;
mc_dev = to_fsl_mc_device(dev);
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
switch (rq->extts.index) {
case 0:
bit = DPRTC_EVENT_ETS1;
break;
case 1:
bit = DPRTC_EVENT_ETS2;
break;
default:
return -EINVAL;
}
if (on)
extts_clean_up(ptp_qoriq, rq->extts.index, false);
break;
case PTP_CLK_REQ_PPS:
bit = DPRTC_EVENT_PPS;
break;
default:
return -EOPNOTSUPP;
}
err = dprtc_get_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPRTC_IRQ_INDEX, &mask);
if (err < 0) {
dev_err(dev, "dprtc_get_irq_mask(): %d\n", err);
return err;
}
if (on)
mask |= bit;
else
mask &= ~bit;
err = dprtc_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPRTC_IRQ_INDEX, mask);
if (err < 0) {
dev_err(dev, "dprtc_set_irq_mask(): %d\n", err);
return err;
}
return 0;
}
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,
.enable = dpaa2_ptp_enable,
};
static irqreturn_t dpaa2_ptp_irq_handler_thread(int irq, void *priv)
{
struct ptp_qoriq *ptp_qoriq = priv;
struct ptp_clock_event event;
struct fsl_mc_device *mc_dev;
struct device *dev;
u32 status = 0;
int err;
dev = ptp_qoriq->dev;
mc_dev = to_fsl_mc_device(dev);
err = dprtc_get_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPRTC_IRQ_INDEX, &status);
if (unlikely(err)) {
dev_err(dev, "dprtc_get_irq_status err %d\n", err);
return IRQ_NONE;
}
if (status & DPRTC_EVENT_PPS) {
event.type = PTP_CLOCK_PPS;
ptp_clock_event(ptp_qoriq->clock, &event);
}
if (status & DPRTC_EVENT_ETS1)
extts_clean_up(ptp_qoriq, 0, true);
if (status & DPRTC_EVENT_ETS2)
extts_clean_up(ptp_qoriq, 1, true);
err = dprtc_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPRTC_IRQ_INDEX, status);
if (unlikely(err)) {
dev_err(dev, "dprtc_clear_irq_status err %d\n", err);
return IRQ_NONE;
}
return IRQ_HANDLED;
}
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_put;
}
err = fsl_mc_allocate_irqs(mc_dev);
if (err) {
dev_err(dev, "MC irqs allocation failed\n");
goto err_unmap;
}
ptp_qoriq->irq = mc_dev->irqs[0]->virq;
err = request_threaded_irq(ptp_qoriq->irq, NULL,
dpaa2_ptp_irq_handler_thread,
IRQF_NO_SUSPEND | IRQF_ONESHOT,
dev_name(dev), ptp_qoriq);
if (err < 0) {
dev_err(dev, "devm_request_threaded_irq(): %d\n", err);
goto err_free_mc_irq;
}
err = dprtc_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPRTC_IRQ_INDEX, 1);
if (err < 0) {
dev_err(dev, "dprtc_set_irq_enable(): %d\n", err);
goto err_free_threaded_irq;
}
err = ptp_qoriq_init(ptp_qoriq, base, &dpaa2_ptp_caps);
if (err)
goto err_free_threaded_irq;
dpaa2_phc_index = ptp_qoriq->phc_index;
dpaa2_ptp = ptp_qoriq;
dev_set_drvdata(dev, ptp_qoriq);
return 0;
err_free_threaded_irq:
free_irq(ptp_qoriq->irq, ptp_qoriq);
err_free_mc_irq:
fsl_mc_free_irqs(mc_dev);
err_unmap:
iounmap(base);
err_put:
of_node_put(node);
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 void 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);
fsl_mc_free_irqs(mc_dev);
dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
fsl_mc_portal_free(mc_dev->mc_io);
}
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");