* [PATCH V6] arm64: alternative:flush cache with unpatched code
From: Will Deacon @ 2018-06-07 10:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528327743-29263-1-git-send-email-rokhanna@nvidia.com>
On Wed, Jun 06, 2018 at 04:29:03PM -0700, Rohit Khanna wrote:
> In the current implementation, __apply_alternatives patches
> flush_icache_range and then executes it without invalidating the icache.
> Thus, icache can contain some of the old instructions for
> flush_icache_range. This can cause unpredictable behavior as during
> execution we can get a mix of old and new instructions for
> flush_icache_range.
>
> This patch modifies __apply_alternatives so that it uses non hot-patched
> __flush_icache_all after applying all the alternatives.
Please can you try the diff I posted the other day? [1]
Will
--->8
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-June/582861.html
^ permalink raw reply
* [PATCH v4 05/14] coresight: get/put module in coresight_build/release_path
From: Greg Kroah-Hartman @ 2018-06-07 9:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2f8d233e-8847-ce3d-3a5b-06b175e3944b@arm.com>
On Thu, Jun 07, 2018 at 10:32:21AM +0100, Suzuki K Poulose wrote:
> On 06/07/2018 10:13 AM, Greg Kroah-Hartman wrote:
> > On Thu, Jun 07, 2018 at 10:04:33AM +0100, Suzuki K Poulose wrote:
> > > Hi Greg,
> > >
> > > On 06/07/2018 09:34 AM, Greg Kroah-Hartman wrote:
> > > > On Wed, Jun 06, 2018 at 03:55:01PM -0500, Kim Phillips wrote:
> > > > > On Wed, 6 Jun 2018 10:46:36 +0100
> > > > > Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
> > > > >
> > > > > > On 06/06/2018 09:24 AM, Greg Kroah-Hartman wrote:
> > > > > > > On Tue, Jun 05, 2018 at 04:07:01PM -0500, Kim Phillips wrote:
> > > > > > > > Increment the refcnt for driver modules in current use by calling
> > > > > > > > module_get in coresight_build_path and module_put in release_path.
> > > > > > > >
> > > > > > > > This prevents driver modules from being unloaded when they are in use,
> > > > > > > > either in sysfs or perf mode.
> > > > > > >
> > > > > > > Why does it matter? Shouldn't you be allowed to remove any module at
> > > > > > > any point in time, much like a networking driver?
> > >
> > > The user doesn't have an explicit refcount on the individual components
> > > in a trace session. So, when a trace session is in progress, it is as
> > > good as having a "file" open on each component that is part of the
> > > active trace session. So, we don't want the driver to be removed when
> > > the component is being used in the trace collection.
> >
> > Why not? What's wrong with that happening and then the trace collection
> > starts failing with -ENODEV or something?
>
> May be I am missing something here. Can we allow the driver to be removed
> when one of its device is "turned ON" and we need the same
> driver to "turn it OFF" when the session ends ? To make a better
> comparison :
>
> Can we unload a usb_mass_storage module when a USB disk(which uses the
> module driver) is mounted and is being used ? I believe, the module
> will eventually get unloaded when we unmount the disk, if someone did
> a unload.
No, mount causes the module count to be incrememted. Mount and
"open/close" are the old-school way of doing module reference counting.
Look at how network drivers work today, you can unload any network
driver even if there is a valid network connection "up and running"
attached to it. It just gets torn down when that request happens.
> We have a similar situation here. The only difference is the driver is
> referenced only when one of its device is in a trace session.
I understand, I'm saying that you have to be very careful when messing
around with module reference counts to get it correct and perhaps you
should just change your design to not care about module reference counts
at all, like networking did 15+ years ago.
Let's learn from the good examples in our past (like networking), and
not like the older bad examples (like mount/files).
> > Remember, removing a kernel module is something that only happens very
> > rarely, and is an explicit choice by someone with root permissions. If
> > you want to remove that module, it should be able to go, as you know
> > what you are doing at that point in time.
>
> Right, but when a device is "in use" can we do that ? I thought the user
> will get a module is in use or busy, error.
Try it on networking today :)
> > Don't try to "protect the user from themselves" here, they want to shoot
> > their foot, make it hurt if they are aiming it there :)
> >
>
> The module_get/put added here are only triggered when we start a trace
> session, where we build a path for the current session from the configured
> "source" to the configured "sink" and the path is destroyed
> at the end of the trace session. i.e, the path is not a permanent thing.
> It is constructed per session. So it is perfectly possible to remove a
> device in between trace sessions.
That's fine, but again, just be careful to get this correct. The patch
I reviewed did not seem to do that.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v4 05/14] coresight: get/put module in coresight_build/release_path
From: Suzuki K Poulose @ 2018-06-07 9:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180606155501.704583e1412996a1a2c6fa61@arm.com>
On 06/06/2018 09:55 PM, Kim Phillips wrote:
> On Wed, 6 Jun 2018 10:46:36 +0100
> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>
>> And while we are at this, I also realised that we hold references to the
>> parent devices for each connection (via bus_find_device() from
>> of_coresight_get_endpoint_device()), while parsing the platform data,
>> which is never released.
>
> Would this fix that?:
Not completely. We store the dev_name() as a reference, which itself can
be free'd, when the device is gone. I have a fix for this in my next
version of the DT clean up series [0], where I clean up most of the
platform parsing code.
[0]
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-June/582904.html
Cheers
Suzuki
>
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index a33a92ebe74b..a43ab078c85e 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -181,6 +181,8 @@ of_get_coresight_platform_data(struct device *dev,
> pdata->child_names[i] = dev_name(rdev);
> pdata->child_ports[i] = rendpoint.id;
>
> + put_device(rdev);
> +
> i++;
> } while (ep);
> }
^ permalink raw reply
* [PATCH v4 05/14] coresight: get/put module in coresight_build/release_path
From: Suzuki K Poulose @ 2018-06-07 9:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2f8d233e-8847-ce3d-3a5b-06b175e3944b@arm.com>
On 06/07/2018 10:32 AM, Suzuki K Poulose wrote:
> On 06/07/2018 10:13 AM, Greg Kroah-Hartman wrote:
>> On Thu, Jun 07, 2018 at 10:04:33AM +0100, Suzuki K Poulose wrote:
>>> Hi Greg,
>>>
>>> On 06/07/2018 09:34 AM, Greg Kroah-Hartman wrote:
>>>> On Wed, Jun 06, 2018 at 03:55:01PM -0500, Kim Phillips wrote:
>>>>> On Wed, 6 Jun 2018 10:46:36 +0100
>>>>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>>>>
>>>>>> On 06/06/2018 09:24 AM, Greg Kroah-Hartman wrote:
>>>>>>> On Tue, Jun 05, 2018 at 04:07:01PM -0500, Kim Phillips wrote:
>>>>>>>> Increment the refcnt for driver modules in current use by calling
>>>>>>>> module_get in coresight_build_path and module_put in release_path.
>>>>>>>>
>>>>>>>> This prevents driver modules from being unloaded when they are
>>>>>>>> in use,
>>>>>>>> either in sysfs or perf mode.
>>>>>>>
>>>>>>> Why does it matter?? Shouldn't you be allowed to remove any
>>>>>>> module at
>>>>>>> any point in time, much like a networking driver?
>>>
>>> The user doesn't have an explicit refcount on the individual components
>>> in a trace session. So, when a trace session is in progress, it is as
>>> good as having a "file" open on each component that is part of the
>>> active trace session. So, we don't want the driver to be removed when
>>> the component is being used in the trace collection.
>>
>> Why not?? What's wrong with that happening and then the trace collection
>> starts failing with -ENODEV or something?
Forgot to add, this will indeed hit -ENODEV, if the device driver was
removed, as we fail to build the trace path before the session.
>
> May be I am missing something here. Can we allow the driver to be
> removed when one of its device is "turned ON" and we need the same
> driver to "turn it OFF" when the session ends ? To make a better
> comparison :
>
> Can we unload a usb_mass_storage module when a USB disk(which uses the
> module driver) is mounted and is being used ? I believe, the module
> will eventually get unloaded when we unmount the disk, if someone did
> a unload.
>
> We have a similar situation here. The only difference is the driver is
> referenced only when one of its device is in a trace session.
>
>>
>> Remember, removing a kernel module is something that only happens very
>> rarely, and is an explicit choice by someone with root permissions.? If
>> you want to remove that module, it should be able to go, as you know
>> what you are doing at that point in time.
>
> Right, but when a device is "in use" can we do that ? I thought the user
> will get a module is in use or busy, error.
>
>
>>
>> Don't try to "protect the user from themselves" here, they want to shoot
>> their foot, make it hurt if they are aiming it there :)
>>
>
> The module_get/put added here are only triggered when we start a trace
> session, where we build a path for the current session from the
> configured "source" to the configured "sink" and the path is destroyed
> at the end of the trace session. i.e, the path is not a permanent thing.
> It is constructed per session. So it is perfectly possible to remove a
> device in between trace sessions.
>
>>> This will be
>>> released as soon as the session is ended. It is just like a PMU driver
>>> where the module refcount is held to ensure the module stays until the
>>> session is over. In this case, we have multiple components, each with
>>> its own driver invisible to the PMU driver. Hence the coresight driver
>>> must hold the reference.
>>
>> Again, please think this through and don't add extra complexity to the
>> normal path, and get it right if you do it (the existing patch is not
>> right as I pointed out.)? Personally, I feel the code should just be
>> able to be unloaded whenever they want, user beware...
>
> Sure, will explore more to refine the code. Thanks for the trigger.
>
> Cheers
> Suzuki
Suzuki
^ permalink raw reply
* [PATCH v4 05/14] coresight: get/put module in coresight_build/release_path
From: Suzuki K Poulose @ 2018-06-07 9:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607091353.GA20438@kroah.com>
On 06/07/2018 10:13 AM, Greg Kroah-Hartman wrote:
> On Thu, Jun 07, 2018 at 10:04:33AM +0100, Suzuki K Poulose wrote:
>> Hi Greg,
>>
>> On 06/07/2018 09:34 AM, Greg Kroah-Hartman wrote:
>>> On Wed, Jun 06, 2018 at 03:55:01PM -0500, Kim Phillips wrote:
>>>> On Wed, 6 Jun 2018 10:46:36 +0100
>>>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>>>
>>>>> On 06/06/2018 09:24 AM, Greg Kroah-Hartman wrote:
>>>>>> On Tue, Jun 05, 2018 at 04:07:01PM -0500, Kim Phillips wrote:
>>>>>>> Increment the refcnt for driver modules in current use by calling
>>>>>>> module_get in coresight_build_path and module_put in release_path.
>>>>>>>
>>>>>>> This prevents driver modules from being unloaded when they are in use,
>>>>>>> either in sysfs or perf mode.
>>>>>>
>>>>>> Why does it matter? Shouldn't you be allowed to remove any module at
>>>>>> any point in time, much like a networking driver?
>>
>> The user doesn't have an explicit refcount on the individual components
>> in a trace session. So, when a trace session is in progress, it is as
>> good as having a "file" open on each component that is part of the
>> active trace session. So, we don't want the driver to be removed when
>> the component is being used in the trace collection.
>
> Why not? What's wrong with that happening and then the trace collection
> starts failing with -ENODEV or something?
May be I am missing something here. Can we allow the driver to be
removed when one of its device is "turned ON" and we need the same
driver to "turn it OFF" when the session ends ? To make a better
comparison :
Can we unload a usb_mass_storage module when a USB disk(which uses the
module driver) is mounted and is being used ? I believe, the module
will eventually get unloaded when we unmount the disk, if someone did
a unload.
We have a similar situation here. The only difference is the driver is
referenced only when one of its device is in a trace session.
>
> Remember, removing a kernel module is something that only happens very
> rarely, and is an explicit choice by someone with root permissions. If
> you want to remove that module, it should be able to go, as you know
> what you are doing at that point in time.
Right, but when a device is "in use" can we do that ? I thought the user
will get a module is in use or busy, error.
>
> Don't try to "protect the user from themselves" here, they want to shoot
> their foot, make it hurt if they are aiming it there :)
>
The module_get/put added here are only triggered when we start a trace
session, where we build a path for the current session from the
configured "source" to the configured "sink" and the path is destroyed
at the end of the trace session. i.e, the path is not a permanent thing.
It is constructed per session. So it is perfectly possible to remove a
device in between trace sessions.
>> This will be
>> released as soon as the session is ended. It is just like a PMU driver
>> where the module refcount is held to ensure the module stays until the
>> session is over. In this case, we have multiple components, each with
>> its own driver invisible to the PMU driver. Hence the coresight driver
>> must hold the reference.
>
> Again, please think this through and don't add extra complexity to the
> normal path, and get it right if you do it (the existing patch is not
> right as I pointed out.) Personally, I feel the code should just be
> able to be unloaded whenever they want, user beware...
Sure, will explore more to refine the code. Thanks for the trigger.
Cheers
Suzuki
^ permalink raw reply
* [v2, 09/10] dpaa_eth: add support for hardware timestamping
From: Y.b. Lu @ 2018-06-07 9:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AM6PR04MB40080865F823C7C57716818FEC640@AM6PR04MB4008.eurprd04.prod.outlook.com>
Hi Madalin,
> -----Original Message-----
> From: Madalin-cristian Bucur
> Sent: Thursday, June 7, 2018 4:24 PM
> To: Y.b. Lu <yangbo.lu@nxp.com>; netdev at vger.kernel.org; Richard Cochran
> <richardcochran@gmail.com>; Rob Herring <robh+dt@kernel.org>; Shawn
> Guo <shawnguo@kernel.org>; David S . Miller <davem@davemloft.net>
> Cc: devicetree at vger.kernel.org; linuxppc-dev at lists.ozlabs.org;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Y.b. Lu
> <yangbo.lu@nxp.com>
> Subject: RE: [v2, 09/10] dpaa_eth: add support for hardware timestamping
>
> > -----Original Message-----
> > From: Yangbo Lu [mailto:yangbo.lu at nxp.com]
> > Sent: Thursday, June 7, 2018 6:23 AM
> > Subject: [v2, 09/10] dpaa_eth: add support for hardware timestamping
> >
> > This patch is to add hardware timestamping support for dpaa_eth. On
> > Rx, timestamping is enabled for all frames. On Tx, we only instruct
> > the hardware to timestamp the frames marked accordingly by the stack.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> > ---
> > Changes for v2:
> > - Removed ifdef for timestamp code.
> > - Minor fixes for code style.
> > ---
> > drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 101
> > ++++++++++++++++++++++-
> > drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 3 +
> > 2 files changed, 99 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> > b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> > index fd43f98..bd589ac 100644
> > --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> > +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> > @@ -1168,7 +1168,7 @@ static int dpaa_eth_init_tx_port(struct
> > fman_port *port, struct dpaa_fq *errq,
> > buf_prefix_content.priv_data_size = buf_layout->priv_data_size;
> > buf_prefix_content.pass_prs_result = true;
> > buf_prefix_content.pass_hash_result = true;
> > - buf_prefix_content.pass_time_stamp = false;
> > + buf_prefix_content.pass_time_stamp = true;
> > buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT;
> >
> > params.specific_params.non_rx_params.err_fqid = errq->fqid; @@
> > -1210,7 +1210,7 @@ static int dpaa_eth_init_rx_port(struct fman_port
> > *port, struct dpaa_bp **bps,
> > buf_prefix_content.priv_data_size = buf_layout->priv_data_size;
> > buf_prefix_content.pass_prs_result = true;
> > buf_prefix_content.pass_hash_result = true;
> > - buf_prefix_content.pass_time_stamp = false;
> > + buf_prefix_content.pass_time_stamp = true;
> > buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT;
> >
> > rx_p = ¶ms.specific_params.rx_params;
> > @@ -1592,6 +1592,16 @@ static int dpaa_eth_refill_bpools(struct
> > dpaa_priv
> > *priv)
> > return 0;
> > }
> >
> > +static int dpaa_get_tstamp_ns(struct net_device *net_dev, u64 *ns,
> > + struct fman_port *port, const void *data) {
> > + if (!fman_port_get_tstamp_field(port, data, ns)) {
> > + be64_to_cpus(ns);
>
> Please move this endianness conversion in the fman API.
[Y.b. Lu] Ok. Will move to fman API in next version.
>
> > + return 0;
> > + }
> > + return -EINVAL;
> > +}
> > +
> > /* Cleanup function for outgoing frame descriptors that were built on
> > Tx path,
> > * either contiguous frames or scatter/gather ones.
> > * Skb freeing is not handled here.
> > @@ -1607,14 +1617,29 @@ static int dpaa_eth_refill_bpools(struct
> > dpaa_priv
> > *priv)
> > {
> > const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
> > struct device *dev = priv->net_dev->dev.parent;
> > + struct skb_shared_hwtstamps shhwtstamps;
> > dma_addr_t addr = qm_fd_addr(fd);
> > const struct qm_sg_entry *sgt;
> > struct sk_buff **skbh, *skb;
> > int nr_frags, i;
> > + u64 ns;
> >
> > skbh = (struct sk_buff **)phys_to_virt(addr);
> > skb = *skbh;
> >
> > + if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags &
> > SKBTX_HW_TSTAMP) {
> > + memset(&shhwtstamps, 0, sizeof(shhwtstamps));
> > +
> > + if (!dpaa_get_tstamp_ns(priv->net_dev, &ns,
> > + priv->mac_dev->port[TX],
> > + (void *)skbh)) {
> > + shhwtstamps.hwtstamp = ns_to_ktime(ns);
> > + skb_tstamp_tx(skb, &shhwtstamps);
> > + } else {
> > + dev_warn(dev, "dpaa_get_tstamp_ns failed!\n");
> > + }
> > + }
> > +
> > if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) {
> > nr_frags = skb_shinfo(skb)->nr_frags;
> > dma_unmap_single(dev, addr, qm_fd_get_offset(fd) + @@ -2086,6
> > +2111,11 @@ static int dpaa_start_xmit(struct sk_buff *skb, struct
> > net_device *net_dev)
> > if (unlikely(err < 0))
> > goto skb_to_fd_failed;
> >
> > + if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags &
> > SKBTX_HW_TSTAMP) {
> > + fd.cmd |= FM_FD_CMD_UPD;
>
> The fd.cmd field is big endian, please use this:
>
> + fd.cmd |= cpu_to_be32(FM_FD_CMD_UPD);
>
[Y.b. Lu] Thanks a lot for pointing out this issue. This fixes TX timestamp issue on ARM platform.
By now, I have verified both PowerPC platform and ARM platform. The PTP clock driver and timestamping worked fine.
I will send out v3 patch-set for reviewing.
> > + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
> > + }
> > +
> > if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0))
> > return NETDEV_TX_OK;
> >
> > @@ -2227,6 +2257,7 @@ static enum qman_cb_dqrr_result
> > rx_default_dqrr(struct qman_portal *portal,
> > struct qman_fq *fq,
> > const struct qm_dqrr_entry
> > *dq)
> > {
> > + struct skb_shared_hwtstamps *shhwtstamps;
> > struct rtnl_link_stats64 *percpu_stats;
> > struct dpaa_percpu_priv *percpu_priv;
> > const struct qm_fd *fd = &dq->fd;
> > @@ -2240,6 +2271,7 @@ static enum qman_cb_dqrr_result
> > rx_default_dqrr(struct qman_portal *portal,
> > struct sk_buff *skb;
> > int *count_ptr;
> > void *vaddr;
> > + u64 ns;
> >
> > fd_status = be32_to_cpu(fd->status);
> > fd_format = qm_fd_get_format(fd);
> > @@ -2304,6 +2336,18 @@ static enum qman_cb_dqrr_result
> > rx_default_dqrr(struct qman_portal *portal,
> > if (!skb)
> > return qman_cb_dqrr_consume;
> >
> > + if (priv->rx_tstamp) {
> > + shhwtstamps = skb_hwtstamps(skb);
> > + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
> > +
> > + if (!dpaa_get_tstamp_ns(priv->net_dev, &ns,
> > + priv->mac_dev->port[RX],
> > + vaddr))
> > + shhwtstamps->hwtstamp = ns_to_ktime(ns);
> > + else
> > + dev_warn(net_dev->dev.parent,
> > "dpaa_get_tstamp_ns failed!\n");
> > + }
> > +
> > skb->protocol = eth_type_trans(skb, net_dev);
> >
> > if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
> @@
> > -2523,11 +2567,58 @@ static int dpaa_eth_stop(struct net_device
> > *net_dev)
> > return err;
> > }
> >
> > +static int dpaa_ts_ioctl(struct net_device *dev, struct ifreq *rq,
> > +int cmd) {
> > + struct dpaa_priv *priv = netdev_priv(dev);
> > + struct hwtstamp_config config;
> > +
> > + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
> > + return -EFAULT;
> > +
> > + switch (config.tx_type) {
> > + case HWTSTAMP_TX_OFF:
> > + /* Couldn't disable rx/tx timestamping separately.
> > + * Do nothing here.
> > + */
> > + priv->tx_tstamp = false;
> > + break;
> > + case HWTSTAMP_TX_ON:
> > + priv->mac_dev->set_tstamp(priv->mac_dev->fman_mac,
> > true);
> > + priv->tx_tstamp = true;
> > + break;
> > + default:
> > + return -ERANGE;
> > + }
> > +
> > + if (config.rx_filter == HWTSTAMP_FILTER_NONE) {
> > + /* Couldn't disable rx/tx timestamping separately.
> > + * Do nothing here.
> > + */
> > + priv->rx_tstamp = false;
> > + } else {
> > + priv->mac_dev->set_tstamp(priv->mac_dev->fman_mac,
> > true);
> > + priv->rx_tstamp = true;
> > + /* TS is set for all frame types, not only those requested */
> > + config.rx_filter = HWTSTAMP_FILTER_ALL;
> > + }
> > +
> > + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
> > + -EFAULT : 0;
> > +}
> > +
> > static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq,
> > int cmd) {
> > - if (!net_dev->phydev)
> > - return -EINVAL;
> > - return phy_mii_ioctl(net_dev->phydev, rq, cmd);
> > + int ret = -EINVAL;
> > +
> > + if (cmd == SIOCGMIIREG) {
> > + if (net_dev->phydev)
> > + return phy_mii_ioctl(net_dev->phydev, rq, cmd);
> > + }
> > +
> > + if (cmd == SIOCSHWTSTAMP)
> > + return dpaa_ts_ioctl(net_dev, rq, cmd);
> > +
> > + return ret;
> > }
> >
> > static const struct net_device_ops dpaa_ops = { diff --git
> > a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
> > b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
> > index bd94220..af320f8 100644
> > --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
> > +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
> > @@ -182,6 +182,9 @@ struct dpaa_priv {
> >
> > struct dpaa_buffer_layout buf_layout[2];
> > u16 rx_headroom;
> > +
> > + bool tx_tstamp; /* Tx timestamping enabled */
> > + bool rx_tstamp; /* Rx timestamping enabled */
> > };
> >
> > /* from dpaa_ethtool.c */
> > --
> > 1.7.1
^ permalink raw reply
* [v3, 10/10] dpaa_eth: add the get_ts_info interface for ethtool
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
Added the get_ts_info interface for ethtool to check
the timestamping capability.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- Removed ifdef for hw timestamp.
Changes for v3:
- None.
---
drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 39 ++++++++++++++++++++
1 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 2f933b6..3184c8f 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -32,6 +32,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/string.h>
+#include <linux/of_platform.h>
+#include <linux/net_tstamp.h>
+#include <linux/fsl/ptp_qoriq.h>
#include "dpaa_eth.h"
#include "mac.h"
@@ -515,6 +518,41 @@ static int dpaa_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
return ret;
}
+static int dpaa_get_ts_info(struct net_device *net_dev,
+ struct ethtool_ts_info *info)
+{
+ struct device *dev = net_dev->dev.parent;
+ struct device_node *mac_node = dev->of_node;
+ struct device_node *fman_node = NULL, *ptp_node = NULL;
+ struct platform_device *ptp_dev = NULL;
+ struct qoriq_ptp *ptp = NULL;
+
+ info->phc_index = -1;
+
+ fman_node = of_get_parent(mac_node);
+ if (fman_node)
+ ptp_node = of_parse_phandle(fman_node, "ptimer-handle", 0);
+
+ if (ptp_node)
+ ptp_dev = of_find_device_by_node(ptp_node);
+
+ if (ptp_dev)
+ ptp = platform_get_drvdata(ptp_dev);
+
+ if (ptp)
+ info->phc_index = ptp->phc_index;
+
+ info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->tx_types = (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+ info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_ALL);
+
+ return 0;
+}
+
const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
@@ -530,4 +568,5 @@ static int dpaa_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
.set_link_ksettings = dpaa_set_link_ksettings,
.get_rxnfc = dpaa_get_rxnfc,
.set_rxnfc = dpaa_set_rxnfc,
+ .get_ts_info = dpaa_get_ts_info,
};
--
1.7.1
^ permalink raw reply related
* [v3, 09/10] dpaa_eth: add support for hardware timestamping
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to add hardware timestamping support
for dpaa_eth. On Rx, timestamping is enabled for
all frames. On Tx, we only instruct the hardware
to timestamp the frames marked accordingly by the
stack.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- Removed ifdef for timestamp code.
- Minor fixes for code style.
Changes for v3:
- Moved tstamp endianness conversion to fman API.
- Fixed fm.cmd endianness.
---
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 88 ++++++++++++++++++++++--
drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 3 +
2 files changed, 86 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index fd43f98..6a1c58a 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -1168,7 +1168,7 @@ static int dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq,
buf_prefix_content.priv_data_size = buf_layout->priv_data_size;
buf_prefix_content.pass_prs_result = true;
buf_prefix_content.pass_hash_result = true;
- buf_prefix_content.pass_time_stamp = false;
+ buf_prefix_content.pass_time_stamp = true;
buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT;
params.specific_params.non_rx_params.err_fqid = errq->fqid;
@@ -1210,7 +1210,7 @@ static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps,
buf_prefix_content.priv_data_size = buf_layout->priv_data_size;
buf_prefix_content.pass_prs_result = true;
buf_prefix_content.pass_hash_result = true;
- buf_prefix_content.pass_time_stamp = false;
+ buf_prefix_content.pass_time_stamp = true;
buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT;
rx_p = ¶ms.specific_params.rx_params;
@@ -1607,14 +1607,28 @@ static int dpaa_eth_refill_bpools(struct dpaa_priv *priv)
{
const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
struct device *dev = priv->net_dev->dev.parent;
+ struct skb_shared_hwtstamps shhwtstamps;
dma_addr_t addr = qm_fd_addr(fd);
const struct qm_sg_entry *sgt;
struct sk_buff **skbh, *skb;
int nr_frags, i;
+ u64 ns;
skbh = (struct sk_buff **)phys_to_virt(addr);
skb = *skbh;
+ if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+
+ if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh,
+ &ns)) {
+ shhwtstamps.hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, &shhwtstamps);
+ } else {
+ dev_warn(dev, "fman_port_get_tstamp failed!\n");
+ }
+ }
+
if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) {
nr_frags = skb_shinfo(skb)->nr_frags;
dma_unmap_single(dev, addr, qm_fd_get_offset(fd) +
@@ -2086,6 +2100,11 @@ static int dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
if (unlikely(err < 0))
goto skb_to_fd_failed;
+ if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+ fd.cmd |= cpu_to_be32(FM_FD_CMD_UPD);
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ }
+
if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0))
return NETDEV_TX_OK;
@@ -2227,6 +2246,7 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
struct qman_fq *fq,
const struct qm_dqrr_entry *dq)
{
+ struct skb_shared_hwtstamps *shhwtstamps;
struct rtnl_link_stats64 *percpu_stats;
struct dpaa_percpu_priv *percpu_priv;
const struct qm_fd *fd = &dq->fd;
@@ -2240,6 +2260,7 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
struct sk_buff *skb;
int *count_ptr;
void *vaddr;
+ u64 ns;
fd_status = be32_to_cpu(fd->status);
fd_format = qm_fd_get_format(fd);
@@ -2304,6 +2325,16 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
if (!skb)
return qman_cb_dqrr_consume;
+ if (priv->rx_tstamp) {
+ shhwtstamps = skb_hwtstamps(skb);
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+
+ if (!fman_port_get_tstamp(priv->mac_dev->port[RX], vaddr, &ns))
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ else
+ dev_warn(net_dev->dev.parent, "fman_port_get_tstamp failed!\n");
+ }
+
skb->protocol = eth_type_trans(skb, net_dev);
if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
@@ -2523,11 +2554,58 @@ static int dpaa_eth_stop(struct net_device *net_dev)
return err;
}
+static int dpaa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct dpaa_priv *priv = netdev_priv(dev);
+ struct hwtstamp_config config;
+
+ if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ /* Couldn't disable rx/tx timestamping separately.
+ * Do nothing here.
+ */
+ priv->tx_tstamp = false;
+ break;
+ case HWTSTAMP_TX_ON:
+ priv->mac_dev->set_tstamp(priv->mac_dev->fman_mac, true);
+ priv->tx_tstamp = true;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ if (config.rx_filter == HWTSTAMP_FILTER_NONE) {
+ /* Couldn't disable rx/tx timestamping separately.
+ * Do nothing here.
+ */
+ priv->rx_tstamp = false;
+ } else {
+ priv->mac_dev->set_tstamp(priv->mac_dev->fman_mac, true);
+ priv->rx_tstamp = true;
+ /* TS is set for all frame types, not only those requested */
+ config.rx_filter = HWTSTAMP_FILTER_ALL;
+ }
+
+ return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
{
- if (!net_dev->phydev)
- return -EINVAL;
- return phy_mii_ioctl(net_dev->phydev, rq, cmd);
+ int ret = -EINVAL;
+
+ if (cmd == SIOCGMIIREG) {
+ if (net_dev->phydev)
+ return phy_mii_ioctl(net_dev->phydev, rq, cmd);
+ }
+
+ if (cmd == SIOCSHWTSTAMP)
+ return dpaa_ts_ioctl(net_dev, rq, cmd);
+
+ return ret;
}
static const struct net_device_ops dpaa_ops = {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index bd94220..af320f8 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -182,6 +182,9 @@ struct dpaa_priv {
struct dpaa_buffer_layout buf_layout[2];
u16 rx_headroom;
+
+ bool tx_tstamp; /* Tx timestamping enabled */
+ bool rx_tstamp; /* Rx timestamping enabled */
};
/* from dpaa_ethtool.c */
--
1.7.1
^ permalink raw reply related
* [v3, 08/10] fsl/fman: define frame description command UPD
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
Defined frame description command FM_FD_CMD_UPD for
prepended data updating.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- None.
Changes for v3:
- None.
---
drivers/net/ethernet/freescale/fman/fman.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h
index bfa02e0..935c317 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -41,6 +41,7 @@
/* Frame queue Context Override */
#define FM_FD_CMD_FCO 0x80000000
#define FM_FD_CMD_RPD 0x40000000 /* Read Prepended Data */
+#define FM_FD_CMD_UPD 0x20000000 /* Update Prepended Data */
#define FM_FD_CMD_DTC 0x10000000 /* Do L4 Checksum */
/* TX-Port: Unsupported Format */
--
1.7.1
^ permalink raw reply related
* [v3, 07/10] fsl/fman_port: support getting timestamp
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to add fman_port_get_tstamp() interface
to get timestamp.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- None.
Changes for v3:
- Moved endianness conversion from dpaa to fman API.
---
drivers/net/ethernet/freescale/fman/fman_port.c | 12 ++++++++++++
drivers/net/ethernet/freescale/fman/fman_port.h | 2 ++
2 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c
index ce6e24c..dce860d 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1731,6 +1731,18 @@ int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset)
}
EXPORT_SYMBOL(fman_port_get_hash_result_offset);
+int fman_port_get_tstamp(struct fman_port *port, const void *data, u64 *tstamp)
+{
+ if (port->buffer_offsets.time_stamp_offset == ILLEGAL_BASE)
+ return -EINVAL;
+
+ *tstamp = be64_to_cpu(*(u64 *)(data +
+ port->buffer_offsets.time_stamp_offset));
+
+ return 0;
+}
+EXPORT_SYMBOL(fman_port_get_tstamp);
+
static int fman_port_probe(struct platform_device *of_dev)
{
struct fman_port *port;
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.h b/drivers/net/ethernet/freescale/fman/fman_port.h
index e86ca6a..9dbb69f 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.h
+++ b/drivers/net/ethernet/freescale/fman/fman_port.h
@@ -153,6 +153,8 @@ int fman_port_cfg_buf_prefix_content(struct fman_port *port,
int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset);
+int fman_port_get_tstamp(struct fman_port *port, const void *data, u64 *tstamp);
+
struct fman_port *fman_port_bind(struct device *dev);
#endif /* __FMAN_PORT_H */
--
1.7.1
^ permalink raw reply related
* [v3, 06/10] fsl/fman: add set_tstamp interface
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to add set_tstamp interface for memac,
dtsec, and 10GEC controllers to configure HW timestamping.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- None.
Changes for v3:
- None.
---
drivers/net/ethernet/freescale/fman/fman_dtsec.c | 27 ++++++++++++++++++++++
drivers/net/ethernet/freescale/fman/fman_dtsec.h | 1 +
drivers/net/ethernet/freescale/fman/fman_memac.c | 5 ++++
drivers/net/ethernet/freescale/fman/fman_memac.h | 1 +
drivers/net/ethernet/freescale/fman/fman_tgec.c | 21 +++++++++++++++++
drivers/net/ethernet/freescale/fman/fman_tgec.h | 1 +
drivers/net/ethernet/freescale/fman/mac.c | 3 ++
drivers/net/ethernet/freescale/fman/mac.h | 1 +
8 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
index 57b1e2b..1ca543a 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
@@ -123,11 +123,13 @@
#define DTSEC_ECNTRL_R100M 0x00000008
#define DTSEC_ECNTRL_QSGMIIM 0x00000001
+#define TCTRL_TTSE 0x00000040
#define TCTRL_GTS 0x00000020
#define RCTRL_PAL_MASK 0x001f0000
#define RCTRL_PAL_SHIFT 16
#define RCTRL_GHTX 0x00000400
+#define RCTRL_RTSE 0x00000040
#define RCTRL_GRS 0x00000020
#define RCTRL_MPROM 0x00000008
#define RCTRL_RSF 0x00000004
@@ -1136,6 +1138,31 @@ int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
return 0;
}
+int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
+{
+ struct dtsec_regs __iomem *regs = dtsec->regs;
+ u32 rctrl, tctrl;
+
+ if (!is_init_done(dtsec->dtsec_drv_param))
+ return -EINVAL;
+
+ rctrl = ioread32be(®s->rctrl);
+ tctrl = ioread32be(®s->tctrl);
+
+ if (enable) {
+ rctrl |= RCTRL_RTSE;
+ tctrl |= TCTRL_TTSE;
+ } else {
+ rctrl &= ~RCTRL_RTSE;
+ tctrl &= ~TCTRL_TTSE;
+ }
+
+ iowrite32be(rctrl, ®s->rctrl);
+ iowrite32be(tctrl, ®s->tctrl);
+
+ return 0;
+}
+
int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
{
struct dtsec_regs __iomem *regs = dtsec->regs;
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.h b/drivers/net/ethernet/freescale/fman/fman_dtsec.h
index 1a689ad..5149d96 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.h
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.h
@@ -56,5 +56,6 @@ int dtsec_set_exception(struct fman_mac *dtsec,
int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable);
+int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable);
#endif /* __DTSEC_H */
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index 446a97b..bc6eb30 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -964,6 +964,11 @@ int memac_set_allmulti(struct fman_mac *memac, bool enable)
return 0;
}
+int memac_set_tstamp(struct fman_mac *memac, bool enable)
+{
+ return 0; /* Always enabled. */
+}
+
int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
{
struct memac_regs __iomem *regs = memac->regs;
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.h b/drivers/net/ethernet/freescale/fman/fman_memac.h
index b5a5033..b2c671e 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.h
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.h
@@ -58,5 +58,6 @@ int memac_set_exception(struct fman_mac *memac,
int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
int memac_set_allmulti(struct fman_mac *memac, bool enable);
+int memac_set_tstamp(struct fman_mac *memac, bool enable);
#endif /* __MEMAC_H */
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
index 284735d..4070593 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
@@ -44,6 +44,7 @@
#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
/* Command and Configuration Register (COMMAND_CONFIG) */
+#define CMD_CFG_EN_TIMESTAMP 0x00100000
#define CMD_CFG_NO_LEN_CHK 0x00020000
#define CMD_CFG_PAUSE_IGNORE 0x00000100
#define CMF_CFG_CRC_FWD 0x00000040
@@ -588,6 +589,26 @@ int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
return 0;
}
+int tgec_set_tstamp(struct fman_mac *tgec, bool enable)
+{
+ struct tgec_regs __iomem *regs = tgec->regs;
+ u32 tmp;
+
+ if (!is_init_done(tgec->cfg))
+ return -EINVAL;
+
+ tmp = ioread32be(®s->command_config);
+
+ if (enable)
+ tmp |= CMD_CFG_EN_TIMESTAMP;
+ else
+ tmp &= ~CMD_CFG_EN_TIMESTAMP;
+
+ iowrite32be(tmp, ®s->command_config);
+
+ return 0;
+}
+
int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
{
struct tgec_regs __iomem *regs = tgec->regs;
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.h b/drivers/net/ethernet/freescale/fman/fman_tgec.h
index cbbd3b4..3bfd106 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.h
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.h
@@ -52,5 +52,6 @@ int tgec_set_exception(struct fman_mac *tgec,
int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
int tgec_get_version(struct fman_mac *tgec, u32 *mac_version);
int tgec_set_allmulti(struct fman_mac *tgec, bool enable);
+int tgec_set_tstamp(struct fman_mac *tgec, bool enable);
#endif /* __TGEC_H */
diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
index 7b5b95f..a847b9c 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -471,6 +471,7 @@ static void setup_dtsec(struct mac_device *mac_dev)
mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
mac_dev->set_exception = dtsec_set_exception;
mac_dev->set_allmulti = dtsec_set_allmulti;
+ mac_dev->set_tstamp = dtsec_set_tstamp;
mac_dev->set_multi = set_multi;
mac_dev->start = start;
mac_dev->stop = stop;
@@ -490,6 +491,7 @@ static void setup_tgec(struct mac_device *mac_dev)
mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
mac_dev->set_exception = tgec_set_exception;
mac_dev->set_allmulti = tgec_set_allmulti;
+ mac_dev->set_tstamp = tgec_set_tstamp;
mac_dev->set_multi = set_multi;
mac_dev->start = start;
mac_dev->stop = stop;
@@ -509,6 +511,7 @@ static void setup_memac(struct mac_device *mac_dev)
mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
mac_dev->set_exception = memac_set_exception;
mac_dev->set_allmulti = memac_set_allmulti;
+ mac_dev->set_tstamp = memac_set_tstamp;
mac_dev->set_multi = set_multi;
mac_dev->start = start;
mac_dev->stop = stop;
diff --git a/drivers/net/ethernet/freescale/fman/mac.h b/drivers/net/ethernet/freescale/fman/mac.h
index b520cec..824a81a 100644
--- a/drivers/net/ethernet/freescale/fman/mac.h
+++ b/drivers/net/ethernet/freescale/fman/mac.h
@@ -68,6 +68,7 @@ struct mac_device {
int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr);
int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
+ int (*set_tstamp)(struct fman_mac *mac_dev, bool enable);
int (*set_multi)(struct net_device *net_dev,
struct mac_device *mac_dev);
int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
--
1.7.1
^ permalink raw reply related
* [v3, 05/10] arm64: dts: fsl: move ptp timer out of fman
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to move ptp timer node out of fman.
Because ptp timer will be probed by ptp_qoriq driver,
it should be an independent device in case of conflict
memory mapping.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- Fixed address-cells for ptp-timer.
Changes for v3:
- None.
---
arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi b/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi
index 4dd0676..a56a408 100644
--- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi
+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi
@@ -11,13 +11,14 @@ fman0: fman at 1a00000 {
#size-cells = <1>;
cell-index = <0>;
compatible = "fsl,fman";
- ranges = <0x0 0x0 0x1a00000 0x100000>;
- reg = <0x0 0x1a00000 0x0 0x100000>;
+ ranges = <0x0 0x0 0x1a00000 0xfe000>;
+ reg = <0x0 0x1a00000 0x0 0xfe000>;
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 3 0>;
clock-names = "fmanclk";
fsl,qman-channel-range = <0x800 0x10>;
+ ptimer-handle = <&ptp_timer0>;
muram at 0 {
compatible = "fsl,fman-muram";
@@ -73,9 +74,10 @@ fman0: fman at 1a00000 {
compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
reg = <0xfd000 0x1000>;
};
+};
- ptp_timer0: ptp-timer at fe000 {
- compatible = "fsl,fman-ptp-timer";
- reg = <0xfe000 0x1000>;
- };
+ptp_timer0: ptp-timer at 1afe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0x0 0x1afe000 0x0 0x1000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
};
--
1.7.1
^ permalink raw reply related
* [v3, 04/10] powerpc/mpc85xx: move ptp timer out of fman in dts
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to move ptp timer node out of fman.
Because ptp timer will be probed by ptp_qoriq driver,
it should be an independent device in case of conflict
memory mapping.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- None.
Changes for v3:
- None.
---
arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi | 14 ++++++++------
arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi | 14 ++++++++------
arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi | 14 ++++++++------
arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi | 14 ++++++++------
arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi | 14 ++++++++------
5 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
index abd01d4..6b124f7 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
@@ -37,12 +37,13 @@ fman0: fman at 400000 {
#size-cells = <1>;
cell-index = <0>;
compatible = "fsl,fman";
- ranges = <0 0x400000 0x100000>;
- reg = <0x400000 0x100000>;
+ ranges = <0 0x400000 0xfe000>;
+ reg = <0x400000 0xfe000>;
interrupts = <96 2 0 0>, <16 2 1 1>;
clocks = <&clockgen 3 0>;
clock-names = "fmanclk";
fsl,qman-channel-range = <0x40 0xc>;
+ ptimer-handle = <&ptp_timer0>;
muram at 0 {
compatible = "fsl,fman-muram";
@@ -93,9 +94,10 @@ fman0: fman at 400000 {
reg = <0x87000 0x1000>;
status = "disabled";
};
+};
- ptp_timer0: ptp-timer at fe000 {
- compatible = "fsl,fman-ptp-timer";
- reg = <0xfe000 0x1000>;
- };
+ptp_timer0: ptp-timer at 4fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0x4fe000 0x1000>;
+ interrupts = <96 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
index debea75..b80aaf5 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
@@ -37,12 +37,13 @@ fman1: fman at 500000 {
#size-cells = <1>;
cell-index = <1>;
compatible = "fsl,fman";
- ranges = <0 0x500000 0x100000>;
- reg = <0x500000 0x100000>;
+ ranges = <0 0x500000 0xfe000>;
+ reg = <0x500000 0xfe000>;
interrupts = <97 2 0 0>, <16 2 1 0>;
clocks = <&clockgen 3 1>;
clock-names = "fmanclk";
fsl,qman-channel-range = <0x60 0xc>;
+ ptimer-handle = <&ptp_timer1>;
muram at 0 {
compatible = "fsl,fman-muram";
@@ -93,9 +94,10 @@ fman1: fman at 500000 {
reg = <0x87000 0x1000>;
status = "disabled";
};
+};
- ptp_timer1: ptp-timer at fe000 {
- compatible = "fsl,fman-ptp-timer";
- reg = <0xfe000 0x1000>;
- };
+ptp_timer1: ptp-timer at 5fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0x5fe000 0x1000>;
+ interrupts = <97 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
index 3a20e0d..d3720fd 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
@@ -37,12 +37,13 @@ fman0: fman at 400000 {
#size-cells = <1>;
cell-index = <0>;
compatible = "fsl,fman";
- ranges = <0 0x400000 0x100000>;
- reg = <0x400000 0x100000>;
+ ranges = <0 0x400000 0xfe000>;
+ reg = <0x400000 0xfe000>;
interrupts = <96 2 0 0>, <16 2 1 1>;
clocks = <&clockgen 3 0>;
clock-names = "fmanclk";
fsl,qman-channel-range = <0x800 0x10>;
+ ptimer-handle = <&ptp_timer0>;
muram at 0 {
compatible = "fsl,fman-muram";
@@ -98,9 +99,10 @@ fman0: fman at 400000 {
compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
reg = <0xfd000 0x1000>;
};
+};
- ptp_timer0: ptp-timer at fe000 {
- compatible = "fsl,fman-ptp-timer";
- reg = <0xfe000 0x1000>;
- };
+ptp_timer0: ptp-timer at 4fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0x4fe000 0x1000>;
+ interrupts = <96 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
index 82750ac..ae34c20 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
@@ -37,12 +37,13 @@ fman1: fman at 500000 {
#size-cells = <1>;
cell-index = <1>;
compatible = "fsl,fman";
- ranges = <0 0x500000 0x100000>;
- reg = <0x500000 0x100000>;
+ ranges = <0 0x500000 0xfe000>;
+ reg = <0x500000 0xfe000>;
interrupts = <97 2 0 0>, <16 2 1 0>;
clocks = <&clockgen 3 1>;
clock-names = "fmanclk";
fsl,qman-channel-range = <0x820 0x10>;
+ ptimer-handle = <&ptp_timer1>;
muram at 0 {
compatible = "fsl,fman-muram";
@@ -98,9 +99,10 @@ fman1: fman at 500000 {
compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
reg = <0xfd000 0x1000>;
};
+};
- ptp_timer1: ptp-timer at fe000 {
- compatible = "fsl,fman-ptp-timer";
- reg = <0xfe000 0x1000>;
- };
+ptp_timer1: ptp-timer at 5fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0x5fe000 0x1000>;
+ interrupts = <97 2 0 0>;
};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
index 7f60b60..02f2755 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
@@ -37,12 +37,13 @@ fman0: fman at 400000 {
#size-cells = <1>;
cell-index = <0>;
compatible = "fsl,fman";
- ranges = <0 0x400000 0x100000>;
- reg = <0x400000 0x100000>;
+ ranges = <0 0x400000 0xfe000>;
+ reg = <0x400000 0xfe000>;
interrupts = <96 2 0 0>, <16 2 1 1>;
clocks = <&clockgen 3 0>;
clock-names = "fmanclk";
fsl,qman-channel-range = <0x800 0x10>;
+ ptimer-handle = <&ptp_timer0>;
muram at 0 {
compatible = "fsl,fman-muram";
@@ -86,9 +87,10 @@ fman0: fman at 400000 {
compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
reg = <0xfd000 0x1000>;
};
+};
- ptp_timer0: ptp-timer at fe000 {
- compatible = "fsl,fman-ptp-timer";
- reg = <0xfe000 0x1000>;
- };
+ptp_timer0: ptp-timer at 4fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0x4fe000 0x1000>;
+ interrupts = <96 2 0 0>;
};
--
1.7.1
^ permalink raw reply related
* [v3, 03/10] dt-binding: ptp_qoriq: add DPAA FMan support
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to add bindings description for DPAA
FMan 1588 timer, and also remove its description in
fsl-fman dt-bindings document.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- None.
Changes for v3:
- None.
---
Documentation/devicetree/bindings/net/fsl-fman.txt | 25 +-------------------
.../devicetree/bindings/ptp/ptp-qoriq.txt | 15 +++++++++--
2 files changed, 13 insertions(+), 27 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt
index df873d1..74603dd 100644
--- a/Documentation/devicetree/bindings/net/fsl-fman.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -356,30 +356,7 @@ ethernet at e0000 {
============================================================================
FMan IEEE 1588 Node
-DESCRIPTION
-
-The FMan interface to support IEEE 1588
-
-
-PROPERTIES
-
-- compatible
- Usage: required
- Value type: <stringlist>
- Definition: A standard property.
- Must include "fsl,fman-ptp-timer".
-
-- reg
- Usage: required
- Value type: <prop-encoded-array>
- Definition: A standard property.
-
-EXAMPLE
-
-ptp-timer at fe000 {
- compatible = "fsl,fman-ptp-timer";
- reg = <0xfe000 0x1000>;
-};
+Refer to Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
=============================================================================
FMan MDIO Node
diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index 0f569d8..c5d0e79 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -2,7 +2,8 @@
General Properties:
- - compatible Should be "fsl,etsec-ptp"
+ - compatible Should be "fsl,etsec-ptp" for eTSEC
+ Should be "fsl,fman-ptp-timer" for DPAA FMan
- reg Offset and length of the register set for the device
- interrupts There should be at least two interrupts. Some devices
have as many as four PTP related interrupts.
@@ -43,14 +44,22 @@ Clock Properties:
value, which will be directly written in those bits, that is why,
according to reference manual, the next clock sources can be used:
+ For eTSEC,
<0> - external high precision timer reference clock (TSEC_TMR_CLK
input is used for this purpose);
<1> - eTSEC system clock;
<2> - eTSEC1 transmit clock;
<3> - RTC clock input.
- When this attribute is not used, eTSEC system clock will serve as
- IEEE 1588 timer reference clock.
+ For DPAA FMan,
+ <0> - external high precision timer reference clock (TMR_1588_CLK)
+ <1> - MAC system clock (1/2 FMan clock)
+ <2> - reserved
+ <3> - RTC clock oscillator
+
+ When this attribute is not used, the IEEE 1588 timer reference clock
+ will use the eTSEC system clock (for Gianfar) or the MAC system
+ clock (for DPAA).
Example:
--
1.7.1
^ permalink raw reply related
* [v3, 02/10] ptp: support DPAA FMan 1588 timer in ptp_qoriq
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to support DPAA (Data Path Acceleration Architecture)
1588 timer by adding "fsl,fman-ptp-timer" compatible, sharing
interrupt with FMan, adding FSL_DPAA_ETH dependency, and fixing
up register offset.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- None.
Changes for v3:
- None.
---
drivers/ptp/Kconfig | 2 +-
drivers/ptp/ptp_qoriq.c | 104 ++++++++++++++++++++++++++---------------
include/linux/fsl/ptp_qoriq.h | 38 ++++++++++++---
3 files changed, 98 insertions(+), 46 deletions(-)
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index 474c988..d137c48 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -43,7 +43,7 @@ config PTP_1588_CLOCK_DTE
config PTP_1588_CLOCK_QORIQ
tristate "Freescale QorIQ 1588 timer as PTP clock"
- depends on GIANFAR
+ depends on GIANFAR || FSL_DPAA_ETH
depends on PTP_1588_CLOCK
default y
help
diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 1468a16..c4e3545 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -39,11 +39,12 @@
/* Caller must hold qoriq_ptp->lock. */
static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
{
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
u64 ns;
u32 lo, hi;
- lo = qoriq_read(&qoriq_ptp->regs->tmr_cnt_l);
- hi = qoriq_read(&qoriq_ptp->regs->tmr_cnt_h);
+ lo = qoriq_read(®s->ctrl_regs->tmr_cnt_l);
+ hi = qoriq_read(®s->ctrl_regs->tmr_cnt_h);
ns = ((u64) hi) << 32;
ns |= lo;
return ns;
@@ -52,16 +53,18 @@ static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
/* Caller must hold qoriq_ptp->lock. */
static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
{
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
u32 hi = ns >> 32;
u32 lo = ns & 0xffffffff;
- qoriq_write(&qoriq_ptp->regs->tmr_cnt_l, lo);
- qoriq_write(&qoriq_ptp->regs->tmr_cnt_h, hi);
+ qoriq_write(®s->ctrl_regs->tmr_cnt_l, lo);
+ qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi);
}
/* Caller must hold qoriq_ptp->lock. */
static void set_alarm(struct qoriq_ptp *qoriq_ptp)
{
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
u64 ns;
u32 lo, hi;
@@ -70,16 +73,18 @@ static void set_alarm(struct qoriq_ptp *qoriq_ptp)
ns -= qoriq_ptp->tclk_period;
hi = ns >> 32;
lo = ns & 0xffffffff;
- qoriq_write(&qoriq_ptp->regs->tmr_alarm1_l, lo);
- qoriq_write(&qoriq_ptp->regs->tmr_alarm1_h, hi);
+ qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo);
+ qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi);
}
/* Caller must hold qoriq_ptp->lock. */
static void set_fipers(struct qoriq_ptp *qoriq_ptp)
{
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+
set_alarm(qoriq_ptp);
- qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
- qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+ qoriq_write(®s->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
+ qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
}
/*
@@ -89,16 +94,17 @@ static void set_fipers(struct qoriq_ptp *qoriq_ptp)
static irqreturn_t isr(int irq, void *priv)
{
struct qoriq_ptp *qoriq_ptp = priv;
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
struct ptp_clock_event event;
u64 ns;
u32 ack = 0, lo, hi, mask, val;
- val = qoriq_read(&qoriq_ptp->regs->tmr_tevent);
+ val = qoriq_read(®s->ctrl_regs->tmr_tevent);
if (val & ETS1) {
ack |= ETS1;
- hi = qoriq_read(&qoriq_ptp->regs->tmr_etts1_h);
- lo = qoriq_read(&qoriq_ptp->regs->tmr_etts1_l);
+ hi = qoriq_read(®s->etts_regs->tmr_etts1_h);
+ lo = qoriq_read(®s->etts_regs->tmr_etts1_l);
event.type = PTP_CLOCK_EXTTS;
event.index = 0;
event.timestamp = ((u64) hi) << 32;
@@ -108,8 +114,8 @@ static irqreturn_t isr(int irq, void *priv)
if (val & ETS2) {
ack |= ETS2;
- hi = qoriq_read(&qoriq_ptp->regs->tmr_etts2_h);
- lo = qoriq_read(&qoriq_ptp->regs->tmr_etts2_l);
+ hi = qoriq_read(®s->etts_regs->tmr_etts2_h);
+ lo = qoriq_read(®s->etts_regs->tmr_etts2_l);
event.type = PTP_CLOCK_EXTTS;
event.index = 1;
event.timestamp = ((u64) hi) << 32;
@@ -130,16 +136,16 @@ static irqreturn_t isr(int irq, void *priv)
hi = ns >> 32;
lo = ns & 0xffffffff;
spin_lock(&qoriq_ptp->lock);
- qoriq_write(&qoriq_ptp->regs->tmr_alarm2_l, lo);
- qoriq_write(&qoriq_ptp->regs->tmr_alarm2_h, hi);
+ qoriq_write(®s->alarm_regs->tmr_alarm2_l, lo);
+ qoriq_write(®s->alarm_regs->tmr_alarm2_h, hi);
spin_unlock(&qoriq_ptp->lock);
qoriq_ptp->alarm_value = ns;
} else {
- qoriq_write(&qoriq_ptp->regs->tmr_tevent, ALM2);
+ qoriq_write(®s->ctrl_regs->tmr_tevent, ALM2);
spin_lock(&qoriq_ptp->lock);
- mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+ mask = qoriq_read(®s->ctrl_regs->tmr_temask);
mask &= ~ALM2EN;
- qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+ qoriq_write(®s->ctrl_regs->tmr_temask, mask);
spin_unlock(&qoriq_ptp->lock);
qoriq_ptp->alarm_value = 0;
qoriq_ptp->alarm_interval = 0;
@@ -153,7 +159,7 @@ static irqreturn_t isr(int irq, void *priv)
}
if (ack) {
- qoriq_write(&qoriq_ptp->regs->tmr_tevent, ack);
+ qoriq_write(®s->ctrl_regs->tmr_tevent, ack);
return IRQ_HANDLED;
} else
return IRQ_NONE;
@@ -169,6 +175,7 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
u32 tmr_add;
int neg_adj = 0;
struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
if (scaled_ppm < 0) {
neg_adj = 1;
@@ -186,7 +193,7 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
- qoriq_write(&qoriq_ptp->regs->tmr_add, tmr_add);
+ qoriq_write(®s->ctrl_regs->tmr_add, tmr_add);
return 0;
}
@@ -250,6 +257,7 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
unsigned long flags;
u32 bit, mask;
@@ -266,23 +274,23 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
return -EINVAL;
}
spin_lock_irqsave(&qoriq_ptp->lock, flags);
- mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+ mask = qoriq_read(®s->ctrl_regs->tmr_temask);
if (on)
mask |= bit;
else
mask &= ~bit;
- qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+ qoriq_write(®s->ctrl_regs->tmr_temask, mask);
spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
return 0;
case PTP_CLK_REQ_PPS:
spin_lock_irqsave(&qoriq_ptp->lock, flags);
- mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+ mask = qoriq_read(®s->ctrl_regs->tmr_temask);
if (on)
mask |= PP1EN;
else
mask &= ~PP1EN;
- qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+ qoriq_write(®s->ctrl_regs->tmr_temask, mask);
spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
return 0;
@@ -313,10 +321,12 @@ static int qoriq_ptp_probe(struct platform_device *dev)
{
struct device_node *node = dev->dev.of_node;
struct qoriq_ptp *qoriq_ptp;
+ struct qoriq_ptp_registers *regs;
struct timespec64 now;
int err = -ENOMEM;
u32 tmr_ctrl;
unsigned long flags;
+ void __iomem *base;
qoriq_ptp = kzalloc(sizeof(*qoriq_ptp), GFP_KERNEL);
if (!qoriq_ptp)
@@ -351,7 +361,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
pr_err("irq not in device tree\n");
goto no_node;
}
- if (request_irq(qoriq_ptp->irq, isr, 0, DRIVER, qoriq_ptp)) {
+ if (request_irq(qoriq_ptp->irq, isr, IRQF_SHARED, DRIVER, qoriq_ptp)) {
pr_err("request_irq failed\n");
goto no_node;
}
@@ -368,12 +378,27 @@ static int qoriq_ptp_probe(struct platform_device *dev)
spin_lock_init(&qoriq_ptp->lock);
- qoriq_ptp->regs = ioremap(qoriq_ptp->rsrc->start,
- resource_size(qoriq_ptp->rsrc));
- if (!qoriq_ptp->regs) {
+ base = ioremap(qoriq_ptp->rsrc->start,
+ resource_size(qoriq_ptp->rsrc));
+ if (!base) {
pr_err("ioremap ptp registers failed\n");
goto no_ioremap;
}
+
+ qoriq_ptp->base = base;
+
+ if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
+ qoriq_ptp->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
+ qoriq_ptp->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
+ qoriq_ptp->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET;
+ qoriq_ptp->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET;
+ } else {
+ qoriq_ptp->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
+ qoriq_ptp->regs.alarm_regs = base + ALARM_REGS_OFFSET;
+ qoriq_ptp->regs.fiper_regs = base + FIPER_REGS_OFFSET;
+ qoriq_ptp->regs.etts_regs = base + ETTS_REGS_OFFSET;
+ }
+
getnstimeofday64(&now);
ptp_qoriq_settime(&qoriq_ptp->caps, &now);
@@ -383,13 +408,14 @@ static int qoriq_ptp_probe(struct platform_device *dev)
spin_lock_irqsave(&qoriq_ptp->lock, flags);
- qoriq_write(&qoriq_ptp->regs->tmr_ctrl, tmr_ctrl);
- qoriq_write(&qoriq_ptp->regs->tmr_add, qoriq_ptp->tmr_add);
- qoriq_write(&qoriq_ptp->regs->tmr_prsc, qoriq_ptp->tmr_prsc);
- qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
- qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+ regs = &qoriq_ptp->regs;
+ qoriq_write(®s->ctrl_regs->tmr_ctrl, tmr_ctrl);
+ qoriq_write(®s->ctrl_regs->tmr_add, qoriq_ptp->tmr_add);
+ qoriq_write(®s->ctrl_regs->tmr_prsc, qoriq_ptp->tmr_prsc);
+ qoriq_write(®s->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
+ qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
set_alarm(qoriq_ptp);
- qoriq_write(&qoriq_ptp->regs->tmr_ctrl, tmr_ctrl|FIPERST|RTPE|TE|FRD);
+ qoriq_write(®s->ctrl_regs->tmr_ctrl, tmr_ctrl|FIPERST|RTPE|TE|FRD);
spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
@@ -405,7 +431,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
return 0;
no_clock:
- iounmap(qoriq_ptp->regs);
+ iounmap(qoriq_ptp->base);
no_ioremap:
release_resource(qoriq_ptp->rsrc);
no_resource:
@@ -419,12 +445,13 @@ static int qoriq_ptp_probe(struct platform_device *dev)
static int qoriq_ptp_remove(struct platform_device *dev)
{
struct qoriq_ptp *qoriq_ptp = platform_get_drvdata(dev);
+ struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
- qoriq_write(&qoriq_ptp->regs->tmr_temask, 0);
- qoriq_write(&qoriq_ptp->regs->tmr_ctrl, 0);
+ qoriq_write(®s->ctrl_regs->tmr_temask, 0);
+ qoriq_write(®s->ctrl_regs->tmr_ctrl, 0);
ptp_clock_unregister(qoriq_ptp->clock);
- iounmap(qoriq_ptp->regs);
+ iounmap(qoriq_ptp->base);
release_resource(qoriq_ptp->rsrc);
free_irq(qoriq_ptp->irq, qoriq_ptp);
kfree(qoriq_ptp);
@@ -434,6 +461,7 @@ static int qoriq_ptp_remove(struct platform_device *dev)
static const struct of_device_id match_table[] = {
{ .compatible = "fsl,etsec-ptp" },
+ { .compatible = "fsl,fman-ptp-timer" },
{},
};
MODULE_DEVICE_TABLE(of, match_table);
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index b462d9e..dc3dac4 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -11,9 +11,8 @@
/*
* qoriq ptp registers
- * Generated by regen.tcl on Thu May 13 01:38:57 PM CEST 2010
*/
-struct qoriq_ptp_registers {
+struct ctrl_regs {
u32 tmr_ctrl; /* Timer control register */
u32 tmr_tevent; /* Timestamp event register */
u32 tmr_temask; /* Timer event mask register */
@@ -28,22 +27,47 @@ struct qoriq_ptp_registers {
u8 res1[4];
u32 tmroff_h; /* Timer offset high */
u32 tmroff_l; /* Timer offset low */
- u8 res2[8];
+};
+
+struct alarm_regs {
u32 tmr_alarm1_h; /* Timer alarm 1 high register */
u32 tmr_alarm1_l; /* Timer alarm 1 high register */
u32 tmr_alarm2_h; /* Timer alarm 2 high register */
u32 tmr_alarm2_l; /* Timer alarm 2 high register */
- u8 res3[48];
+};
+
+struct fiper_regs {
u32 tmr_fiper1; /* Timer fixed period interval */
u32 tmr_fiper2; /* Timer fixed period interval */
u32 tmr_fiper3; /* Timer fixed period interval */
- u8 res4[20];
+};
+
+struct etts_regs {
u32 tmr_etts1_h; /* Timestamp of general purpose external trigger */
u32 tmr_etts1_l; /* Timestamp of general purpose external trigger */
u32 tmr_etts2_h; /* Timestamp of general purpose external trigger */
u32 tmr_etts2_l; /* Timestamp of general purpose external trigger */
};
+struct qoriq_ptp_registers {
+ struct ctrl_regs __iomem *ctrl_regs;
+ struct alarm_regs __iomem *alarm_regs;
+ struct fiper_regs __iomem *fiper_regs;
+ struct etts_regs __iomem *etts_regs;
+};
+
+/* Offset definitions for the four register groups */
+#define CTRL_REGS_OFFSET 0x0
+#define ALARM_REGS_OFFSET 0x40
+#define FIPER_REGS_OFFSET 0x80
+#define ETTS_REGS_OFFSET 0xa0
+
+#define FMAN_CTRL_REGS_OFFSET 0x80
+#define FMAN_ALARM_REGS_OFFSET 0xb8
+#define FMAN_FIPER_REGS_OFFSET 0xd0
+#define FMAN_ETTS_REGS_OFFSET 0xe0
+
+
/* Bit definitions for the TMR_CTRL register */
#define ALM1P (1<<31) /* Alarm1 output polarity */
#define ALM2P (1<<30) /* Alarm2 output polarity */
@@ -105,10 +129,10 @@ struct qoriq_ptp_registers {
#define DRIVER "ptp_qoriq"
#define DEFAULT_CKSEL 1
#define N_EXT_TS 2
-#define REG_SIZE sizeof(struct qoriq_ptp_registers)
struct qoriq_ptp {
- struct qoriq_ptp_registers __iomem *regs;
+ void __iomem *base;
+ struct qoriq_ptp_registers regs;
spinlock_t lock; /* protects regs */
struct ptp_clock *clock;
struct ptp_clock_info caps;
--
1.7.1
^ permalink raw reply related
* [v3, 01/10] fsl/fman: share the event interrupt
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607092050.46128-1-yangbo.lu@nxp.com>
This patch is to share fman event interrupt because
the 1588 timer driver will also use this interrupt.
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
- None.
Changes for v3:
- None.
---
drivers/net/ethernet/freescale/fman/fman.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
index 9530405..c415ac6 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -2801,7 +2801,8 @@ static irqreturn_t fman_irq(int irq, void *handle)
of_node_put(muram_node);
of_node_put(fm_node);
- err = devm_request_irq(&of_dev->dev, irq, fman_irq, 0, "fman", fman);
+ err = devm_request_irq(&of_dev->dev, irq, fman_irq, IRQF_SHARED,
+ "fman", fman);
if (err < 0) {
dev_err(&of_dev->dev, "%s: irq %d allocation failed (error = %d)\n",
__func__, irq, err);
--
1.7.1
^ permalink raw reply related
* [v3, 00/10] Support DPAA PTP clock and timestamping
From: Yangbo Lu @ 2018-06-07 9:20 UTC (permalink / raw)
To: linux-arm-kernel
This patchset is to support DPAA FMAN PTP clock and HW timestamping.
It had been verified on both ARM platform and PPC platform.
- The patch #1 to patch #5 are to support DPAA FMAN 1588 timer in
ptp_qoriq driver.
- The patch #6 to patch #10 are to add HW timestamping support in
DPAA ethernet driver.
Yangbo Lu (10):
fsl/fman: share the event interrupt
ptp: support DPAA FMan 1588 timer in ptp_qoriq
dt-binding: ptp_qoriq: add DPAA FMan support
powerpc/mpc85xx: move ptp timer out of fman in dts
arm64: dts: fsl: move ptp timer out of fman
fsl/fman: add set_tstamp interface
fsl/fman_port: support getting timestamp
fsl/fman: define frame description command UPD
dpaa_eth: add support for hardware timestamping
dpaa_eth: add the get_ts_info interface for ethtool
Documentation/devicetree/bindings/net/fsl-fman.txt | 25 +-----
.../devicetree/bindings/ptp/ptp-qoriq.txt | 15 +++-
arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi | 14 ++-
arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi | 14 ++-
arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi | 14 ++-
arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi | 14 ++-
arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi | 14 ++-
arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi | 14 ++-
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 88 ++++++++++++++++-
drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 3 +
drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 39 ++++++++
drivers/net/ethernet/freescale/fman/fman.c | 3 +-
drivers/net/ethernet/freescale/fman/fman.h | 1 +
drivers/net/ethernet/freescale/fman/fman_dtsec.c | 27 +++++
drivers/net/ethernet/freescale/fman/fman_dtsec.h | 1 +
drivers/net/ethernet/freescale/fman/fman_memac.c | 5 +
drivers/net/ethernet/freescale/fman/fman_memac.h | 1 +
drivers/net/ethernet/freescale/fman/fman_port.c | 12 +++
drivers/net/ethernet/freescale/fman/fman_port.h | 2 +
drivers/net/ethernet/freescale/fman/fman_tgec.c | 21 ++++
drivers/net/ethernet/freescale/fman/fman_tgec.h | 1 +
drivers/net/ethernet/freescale/fman/mac.c | 3 +
drivers/net/ethernet/freescale/fman/mac.h | 1 +
drivers/ptp/Kconfig | 2 +-
drivers/ptp/ptp_qoriq.c | 104 ++++++++++++-------
include/linux/fsl/ptp_qoriq.h | 38 ++++++--
26 files changed, 361 insertions(+), 115 deletions(-)
^ permalink raw reply
* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Viresh Kumar @ 2018-06-07 9:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607091816.GT13775@localhost>
On 07-06-18, 11:18, Johan Hovold wrote:
> If you want to work around the warning and think you can do it in some
> non-contrived way, then go for it.
>
> Clearing the request buffer, checking for termination using strnlen, and
> then using memcpy might not be too bad.
>
> But after all, it is a false positive, so leaving things as they stand
> is fine too.
Leave it then :)
--
viresh
^ permalink raw reply
* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Johan Hovold @ 2018-06-07 9:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607091025.m7dfix3e2xbwx4cs@vireshk-i7>
On Thu, Jun 07, 2018 at 02:40:25PM +0530, Viresh Kumar wrote:
> On 07-06-18, 11:03, Bernd Petrovitsch wrote:
> > On Thu, 2018-06-07 at 14:08 +0530, Viresh Kumar wrote:
> > > On 07-06-18, 15:46, Du, Changbin wrote:
> > > > I think if the destination is not a null terminated string (If I understand your
> > > > description below), memcpy can be used to get rid of such warning. The warning
> > > > makes sense in general as explained in mannual. Thanks!
> > >
> > > The destination should be a null terminated string eventually, but we first need
> > > to make sure src is a null terminated string.
> >
> > Is there strnlen() or memchr() in the kernel?
> > Then check the source before copying it.
>
> It would be extra work, but memchr can be used to work around this I believe.
>
> @Johan ??
If you want to work around the warning and think you can do it in some
non-contrived way, then go for it.
Clearing the request buffer, checking for termination using strnlen, and
then using memcpy might not be too bad.
But after all, it is a false positive, so leaving things as they stand
is fine too.
Thanks,
Johan
^ permalink raw reply
* [PATCH v4 05/14] coresight: get/put module in coresight_build/release_path
From: Greg Kroah-Hartman @ 2018-06-07 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3219276b-2703-bc30-92e1-bae80cdc5901@arm.com>
On Thu, Jun 07, 2018 at 10:04:33AM +0100, Suzuki K Poulose wrote:
> Hi Greg,
>
> On 06/07/2018 09:34 AM, Greg Kroah-Hartman wrote:
> > On Wed, Jun 06, 2018 at 03:55:01PM -0500, Kim Phillips wrote:
> > > On Wed, 6 Jun 2018 10:46:36 +0100
> > > Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
> > >
> > > > On 06/06/2018 09:24 AM, Greg Kroah-Hartman wrote:
> > > > > On Tue, Jun 05, 2018 at 04:07:01PM -0500, Kim Phillips wrote:
> > > > > > Increment the refcnt for driver modules in current use by calling
> > > > > > module_get in coresight_build_path and module_put in release_path.
> > > > > >
> > > > > > This prevents driver modules from being unloaded when they are in use,
> > > > > > either in sysfs or perf mode.
> > > > >
> > > > > Why does it matter? Shouldn't you be allowed to remove any module at
> > > > > any point in time, much like a networking driver?
>
> The user doesn't have an explicit refcount on the individual components
> in a trace session. So, when a trace session is in progress, it is as
> good as having a "file" open on each component that is part of the
> active trace session. So, we don't want the driver to be removed when
> the component is being used in the trace collection.
Why not? What's wrong with that happening and then the trace collection
starts failing with -ENODEV or something?
Remember, removing a kernel module is something that only happens very
rarely, and is an explicit choice by someone with root permissions. If
you want to remove that module, it should be able to go, as you know
what you are doing at that point in time.
Don't try to "protect the user from themselves" here, they want to shoot
their foot, make it hurt if they are aiming it there :)
> This will be
> released as soon as the session is ended. It is just like a PMU driver
> where the module refcount is held to ensure the module stays until the
> session is over. In this case, we have multiple components, each with
> its own driver invisible to the PMU driver. Hence the coresight driver
> must hold the reference.
Again, please think this through and don't add extra complexity to the
normal path, and get it right if you do it (the existing patch is not
right as I pointed out.) Personally, I feel the code should just be
able to be unloaded whenever they want, user beware...
thanks,
greg k-h
^ permalink raw reply
* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Viresh Kumar @ 2018-06-07 9:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1303b1abf9f9229a8d3ccbb68a3e413266b360d7.camel@petrovitsch.priv.at>
On 07-06-18, 11:03, Bernd Petrovitsch wrote:
> On Thu, 2018-06-07 at 14:08 +0530, Viresh Kumar wrote:
> > On 07-06-18, 15:46, Du, Changbin wrote:
> > > I think if the destination is not a null terminated string (If I understand your
> > > description below), memcpy can be used to get rid of such warning. The warning
> > > makes sense in general as explained in mannual. Thanks!
> >
> > The destination should be a null terminated string eventually, but we first need
> > to make sure src is a null terminated string.
>
> Is there strnlen() or memchr() in the kernel?
> Then check the source before copying it.
It would be extra work, but memchr can be used to work around this I believe.
@Johan ??
--
viresh
^ permalink raw reply
* [PATCH v4 05/14] coresight: get/put module in coresight_build/release_path
From: Suzuki K Poulose @ 2018-06-07 9:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607083401.GE16651@kroah.com>
Hi Greg,
On 06/07/2018 09:34 AM, Greg Kroah-Hartman wrote:
> On Wed, Jun 06, 2018 at 03:55:01PM -0500, Kim Phillips wrote:
>> On Wed, 6 Jun 2018 10:46:36 +0100
>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>
>>> On 06/06/2018 09:24 AM, Greg Kroah-Hartman wrote:
>>>> On Tue, Jun 05, 2018 at 04:07:01PM -0500, Kim Phillips wrote:
>>>>> Increment the refcnt for driver modules in current use by calling
>>>>> module_get in coresight_build_path and module_put in release_path.
>>>>>
>>>>> This prevents driver modules from being unloaded when they are in use,
>>>>> either in sysfs or perf mode.
>>>>
>>>> Why does it matter? Shouldn't you be allowed to remove any module at
>>>> any point in time, much like a networking driver?
The user doesn't have an explicit refcount on the individual components
in a trace session. So, when a trace session is in progress, it is as
good as having a "file" open on each component that is part of the
active trace session. So, we don't want the driver to be removed when
the component is being used in the trace collection. This will be
released as soon as the session is ended. It is just like a PMU driver
where the module refcount is held to ensure the module stays until the
session is over. In this case, we have multiple components, each with
its own driver invisible to the PMU driver. Hence the coresight driver
must hold the reference.
>>>>
>>>>
>>>>>
>>>>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>>>>> Cc: Leo Yan <leo.yan@linaro.org>
>>>>> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>>>>> Cc: Randy Dunlap <rdunlap@infradead.org>
>>>>> Cc: Suzuki K Poulose <Suzuki.Poulose@arm.com>
>>>>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>>>> Cc: Russell King <linux@armlinux.org.uk>
>>>>> Signed-off-by: Kim Phillips <kim.phillips@arm.com>
>>>>> ---
>>>>> drivers/hwtracing/coresight/coresight.c | 9 +++++++++
>>>>> 1 file changed, 9 insertions(+)
>>>>>
>>>>> diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
>>>>> index 338f1719641c..1c941351f1d1 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight.c
>>>>> +++ b/drivers/hwtracing/coresight/coresight.c
>>>>> @@ -465,6 +465,12 @@ static int _coresight_build_path(struct coresight_device *csdev,
>>>>>
>>>>> node->csdev = csdev;
>>>>> list_add(&node->link, path);
>>>>> +
>>>>> + if (!try_module_get(csdev->dev.parent->driver->owner)) {
>>>>
>>>> What is to keep parent->driver from going away right here? What keeps
>>>> parent around? This feels very fragile to me, I don't see any locking
>>>> anywhere around this code path to try to keep things in place.
>>>
>>> You're right. We do have coresight_mutex, which is held across the build
>>> path and the csdev is removed when a device is unregistered. However, I
>>> see that we don't hold the mutex while removing the connections from
>>> coresight_unregister(). Holding the mutex should protect us from the
>>> csdev being removed, while we build the path.
>>
>> OK, I'll add this for the next version:
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
>> index f96258de1e9b..da702507a55c 100644
>> --- a/drivers/hwtracing/coresight/coresight-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-core.c
>> @@ -1040,8 +1040,12 @@ EXPORT_SYMBOL_GPL(coresight_register);
>>
>> void coresight_unregister(struct coresight_device *csdev)
>> {
>> + mutex_lock(&coresight_mutex);
>> +
>
> Locks are to protect data, not code, be careful here please.
The mutex here is to protect updates to the device links. We
keep a list of connections from each device to form a trace path.
When we unregister a device, we must remove the references to the
device from all the other connected components to ensure they don't
end up accessing a device which is gone.
>
> That's the big issue with the module reference counting, it "protects"
> code, not data. If at all possible, never grab a module reference
> count, as you should always be able to unload a module, unless you have
> a file handle open, and if you have that, the kernel core will properly
> protect you.
So in a nutshell, we have user invisible components which cannot be
refcounted explicitly by the file handles, and thus the driver must
do it.
Now, one option we could explore is getting the refcount on the
devices itself, rather than the drivers for trace sessions. And each
device could potentially hold a refcount on the driver (which I assume
is already held), which can be dropped when the device is no longer
used and thus get rid of the reference on the module everywhere.
Thoughts ? Suggestions ?
Suzuki
>
> thanks,
>
> greg k-h
>
^ permalink raw reply
* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Bernd Petrovitsch @ 2018-06-07 9:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607083856.ealw62v3wx43zeqz@vireshk-i7>
On Thu, 2018-06-07 at 14:08 +0530, Viresh Kumar wrote:
> On 07-06-18, 15:46, Du, Changbin wrote:
> > I think if the destination is not a null terminated string (If I understand your
> > description below), memcpy can be used to get rid of such warning. The warning
> > makes sense in general as explained in mannual. Thanks!
>
> The destination should be a null terminated string eventually, but we first need
> to make sure src is a null terminated string.
Is there strnlen() or memchr() in the kernel?
Then check the source before copying it.
Kind regards,
Bernd
--
Bernd Petrovitsch Email : bernd at petrovitsch.priv.at
LUGA : http://www.luga.at
^ permalink raw reply
* [PATCH v2] ARM: DTS: imx53: Add support for imx53 HSC/DDC boards from K+P
From: Lukasz Majewski @ 2018-06-07 8:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOMZO5BiKjoiyh0dxycRhPkRzS2Uk9h8fPTA+sXMZBDJpbcyWQ@mail.gmail.com>
Hi Shawn,
> On Sat, May 19, 2018 at 9:15 AM, Lukasz Majewski <lukma@denx.de>
> wrote:
> > This commit provides support for HSC and DDC boards from
> > Kieback&Peter GmbH vendor.
> >
> > Signed-off-by: Lukasz Majewski <lukma@denx.de>
>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Gentle ping on this patch.
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180607/edd7b2ad/attachment.sig>
^ permalink raw reply
* [PATCH 4/4] ARM: dts: fix PMC compatible
From: Alexandre Belloni @ 2018-06-07 8:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607084107.4461-1-alexandre.belloni@bootlin.com>
Make each SoC dtsi use its soc specific PMc compatible string. This solves
a potential issue on at91sam9261 and at91sam9263 when using suspend to RAM
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
arch/arm/boot/dts/at91sam9261.dtsi | 2 +-
arch/arm/boot/dts/at91sam9263.dtsi | 2 +-
arch/arm/boot/dts/at91sam9rl.dtsi | 2 +-
arch/arm/boot/dts/sama5d4.dtsi | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
index 53c63d0a418a..33f09d5ea020 100644
--- a/arch/arm/boot/dts/at91sam9261.dtsi
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -590,7 +590,7 @@
};
pmc: pmc at fffffc00 {
- compatible = "atmel,at91rm9200-pmc", "syscon";
+ compatible = "atmel,at91sam9261-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index 87fb0660ab5d..af68a86c9973 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -93,7 +93,7 @@
};
pmc: pmc at fffffc00 {
- compatible = "atmel,at91rm9200-pmc", "syscon";
+ compatible = "atmel,at91sam9263-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
index bd001cca25a4..8fb22030f00b 100644
--- a/arch/arm/boot/dts/at91sam9rl.dtsi
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -832,7 +832,7 @@
};
pmc: pmc at fffffc00 {
- compatible = "atmel,at91sam9g45-pmc", "syscon";
+ compatible = "atmel,at91sam9rl-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 0cf9beddd556..92a35a1942b6 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -392,7 +392,7 @@
};
pmc: pmc at f0018000 {
- compatible = "atmel,sama5d3-pmc", "syscon";
+ compatible = "atmel,sama5d4-pmc", "syscon";
reg = <0xf0018000 0x120>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox