* RE: [patch v9 1/4] drivers: jtag: Add JTAG core driver
From: Oleksandr Shamray @ 2017-10-20 14:34 UTC (permalink / raw)
To: Greg KH
Cc: arnd@arndb.de, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
openbmc@lists.ozlabs.org, joel@jms.id.au, jiri@resnulli.us,
tklauser@distanz.ch, linux-serial@vger.kernel.org, mec@shout.net,
Vadim Pasternak, system-sw-low-level, robh+dt@kernel.org,
openocd-devel-owner@lists.sourceforge.net
In-Reply-To: <20171020115512.GA2073@kroah.com>
Hi Greg.
> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Friday, October 20, 2017 2:55 PM
> To: Oleksandr Shamray <oleksandrs@mellanox.com>
> Cc: arnd@arndb.de; linux-kernel@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; devicetree@vger.kernel.org;
> openbmc@lists.ozlabs.org; joel@jms.id.au; jiri@resnulli.us;
> tklauser@distanz.ch; linux-serial@vger.kernel.org; mec@shout.net; Vadim
> Pasternak <vadimp@mellanox.com>; system-sw-low-level <system-sw-low-
> level@mellanox.com>; robh+dt@kernel.org; openocd-devel-
> owner@lists.sourceforge.net; linux-api@vger.kernel.org;
> davem@davemloft.net; mchehab@kernel.org; Jiri Pirko <jiri@mellanox.com>
> Subject: Re: [patch v9 1/4] drivers: jtag: Add JTAG core driver
>
> On Thu, Sep 21, 2017 at 12:25:29PM +0300, Oleksandr Shamray wrote:
> > +struct jtag {
> > + struct device *dev;
> > + struct cdev cdev;
>
> Why are you using a cdev here and not just a normal misc device?
What the benefits to use misc instead of cdev?
> I forgot if this is what you were doing before, sorry...
>
> > + int id;
> > + atomic_t open;
>
> Why do you need this?
This counter used to avoid open at the same time by 2 or more users.
>
> > + const struct jtag_ops *ops;
> > + unsigned long priv[0] __aligned(ARCH_DMA_MINALIGN);
>
> Huh? Why is this needed to be dma aligned? Why not just use the private
> pointer in struct device?
>
It is critical?
> > +};
> > +
> > +static dev_t jtag_devt;
> > +static DEFINE_IDA(jtag_ida);
> > +
> > +void *jtag_priv(struct jtag *jtag)
> > +{
> > + return jtag->priv;
> > +}
> > +EXPORT_SYMBOL_GPL(jtag_priv);
> > +
> > +static u8 *jtag_copy_from_user(__u64 udata, unsigned long bit_size) {
> > + unsigned long size;
> > + void *kdata;
> > +
> > + size = DIV_ROUND_UP(bit_size, BITS_PER_BYTE);
> > + kdata = memdup_user(u64_to_user_ptr(udata), size);
>
> You only use this once, why not just open-code it?
I think it makes code more understandable.
>
> > +
> > + return kdata;
> > +}
> > +
> > +static unsigned long jtag_copy_to_user(__u64 udata, u8 *kdata,
> > + unsigned long bit_size)
> > +{
> > + unsigned long size;
> > +
> > + size = DIV_ROUND_UP(bit_size, BITS_PER_BYTE);
> > +
> > + return copy_to_user(u64_to_user_ptr(udata), (void *)(kdata), size);
>
> Same here, making this a separate function seems odd.
Same, I think it makes code more understandable.
>
> > +}
> > +
> > +static struct class jtag_class = {
> > + .name = "jtag",
> > + .owner = THIS_MODULE,
> > +};
> > +
> > +static int jtag_run_test_idle_op(struct jtag *jtag,
> > + struct jtag_run_test_idle *idle) {
> > + if (jtag->ops->idle)
> > + return jtag->ops->idle(jtag, idle);
> > + else
> > + return -EOPNOTSUPP;
>
> Why is this a function? Why not just do this work in the ioctl?
Agree. I will move it just to ioctl function body.
>
> > +}
> > +
> > +static int jtag_xfer_op(struct jtag *jtag, struct jtag_xfer *xfer, u8
> > +*data) {
> > + if (jtag->ops->xfer)
> > + return jtag->ops->xfer(jtag, xfer, data);
> > + else
> > + return -EOPNOTSUPP;
>
> Same here, doesn't need to be a function.
Agree.
>
> > +}
> > +
> > +static long jtag_ioctl(struct file *file, unsigned int cmd, unsigned
> > +long arg) {
> > + struct jtag *jtag = file->private_data;
> > + struct jtag_run_test_idle idle;
> > + struct jtag_xfer xfer;
> > + u8 *xfer_data;
> > + u32 value;
> > + int err;
> > +
> > + switch (cmd) {
> > + case JTAG_GIOCFREQ:
> > + if (jtag->ops->freq_get)
> > + err = jtag->ops->freq_get(jtag, &value);
> > + else
> > + err = -EOPNOTSUPP;
> > + if (err)
> > + break;
> > +
> > + err = put_user(value, (__u32 *)arg);
> > + break;
>
> Are you sure the return value of put_user is correct here? Shouldn't you return
> -EFAULT if err is not 0?
Yes, thanks for point of this.
>
> > +
> > + case JTAG_SIOCFREQ:
> > + err = get_user(value, (__u32 *)arg);
> > +
>
> why a blank line?
Will remove
>
> > + if (value == 0)
> > + err = -EINVAL;
>
> Check err first.
Ok.
>
> > + if (err)
> > + break;
>
> And set it properly, again err should be -EFAULT, right?
Right 😊0
>
> > +
> > + if (jtag->ops->freq_set)
> > + err = jtag->ops->freq_set(jtag, value);
> > + else
> > + err = -EOPNOTSUPP;
> > + break;
> > +
> > + case JTAG_IOCRUNTEST:
> > + if (copy_from_user(&idle, (void *)arg,
> > + sizeof(struct jtag_run_test_idle)))
> > + return -ENOMEM;
> > + err = jtag_run_test_idle_op(jtag, &idle);
>
> Who validates the structure fields? Is that up to the individual jtag driver? Why
> not do it in the core correctly so that it only has to be done in one place and you
> do not have to audit every individual driver?
Input parameters validated by jtag platform driver. I think it not critical.
>
> > + break;
> > +
> > + case JTAG_IOCXFER:
> > + if (copy_from_user(&xfer, (void *)arg,
> > + sizeof(struct jtag_xfer)))
> > + return -EFAULT;
> > +
> > + if (xfer.length >= JTAG_MAX_XFER_DATA_LEN)
> > + return -EFAULT;
> > +
> > + xfer_data = jtag_copy_from_user(xfer.tdio, xfer.length);
> > + if (!xfer_data)
> > + return -ENOMEM;
>
> Are you sure that's the correct error value?
I think yes, but what you suggest?
>
> > +
> > + err = jtag_xfer_op(jtag, &xfer, xfer_data);
> > + if (jtag_copy_to_user(xfer.tdio, xfer_data, xfer.length)) {
> > + kfree(xfer_data);
> > + return -EFAULT;
> > + }
> > +
> > + kfree(xfer_data);
> > + if (copy_to_user((void *)arg, &xfer, sizeof(struct jtag_xfer)))
> > + return -EFAULT;
> > + break;
> > +
> > + case JTAG_GIOCSTATUS:
> > + if (jtag->ops->status_get)
> > + err = jtag->ops->status_get(jtag, &value);
> > + else
> > + err = -EOPNOTSUPP;
> > + if (err)
> > + break;
> > +
> > + err = put_user(value, (__u32 *)arg);
>
> Same put_user err issue here.
Yes.
>
> > + break;
> > +
> > + default:
> > + return -EINVAL;
> > + }
> > + return err;
> > +}
> > +
> > +#ifdef CONFIG_COMPAT
> > +static long jtag_ioctl_compat(struct file *file, unsigned int cmd,
> > + unsigned long arg)
> > +{
> > + return jtag_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); }
> > +#endif
>
> Why do you need a compat callback for a new ioctl? Create your structures
> properly and this should not be needed, right?
I does this because Arnd (arndbergmann@gmail.com) writed in review (On Wed, Aug 2, 2017 at 3:18 PM)
[..]
> + .unlocked_ioctl = jtag_ioctl,
> + .open = jtag_open,
> + .release = jtag_release,
> +};
add a compat_ioctl pointer here, after ensuring that all ioctl commands are compatible between 32-bit and 64-bit user space.
[..]
>
> > +
> > +static int jtag_open(struct inode *inode, struct file *file) {
> > + struct jtag *jtag = container_of(inode->i_cdev, struct jtag, cdev);
> > +
> > + if (atomic_read(&jtag->open)) {
> > + dev_info(NULL, "jtag already opened\n");
> > + return -EBUSY;
>
> Why do you care if multiple opens can happen?
Jtag HW not support to using with multiple requests from different users. So we prohibit this.
>
> > + }
> > +
> > + atomic_inc(&jtag->open);
>
> Oh look, you just raced with two different people opening at the same time :(
>
> An atomic value is never a replacement for a lock, sorry.
>
> > + file->private_data = jtag;
> > + return 0;
> > +}
> > +
> > +static int jtag_release(struct inode *inode, struct file *file) {
> > + struct jtag *jtag = file->private_data;
> > +
> > + atomic_dec(&jtag->open);
>
> Again, not needed.
>
> > + return 0;
> > +}
> > +
> > +static const struct file_operations jtag_fops = {
> > + .owner = THIS_MODULE,
> > + .open = jtag_open,
> > + .release = jtag_release,
> > + .llseek = noop_llseek,
> > + .unlocked_ioctl = jtag_ioctl,
> > +#ifdef CONFIG_COMPAT
> > + .compat_ioctl = jtag_ioctl_compat,
> > +#endif
> > +};
> > +
> > +struct jtag *jtag_alloc(size_t priv_size, const struct jtag_ops *ops)
> > +{
> > + struct jtag *jtag;
> > +
> > + jtag = kzalloc(sizeof(*jtag) + round_up(priv_size,
> ARCH_DMA_MINALIGN),
> > + GFP_KERNEL);
> > + if (!jtag)
> > + return NULL;
> > +
> > + jtag->ops = ops;
> > + return jtag;
> > +}
> > +EXPORT_SYMBOL_GPL(jtag_alloc);
>
> register should allocate and register the device, why pass a structure back that
> the caller then has to do something else with to use it?
>
Before registration we need to initialize JTAG device HW registers and fill private data with HW specific parameters.
And is I see in other Linux drivers it is a common way to separate allocation device and register it
> > +
> > +void jtag_free(struct jtag *jtag)
> > +{
> > + kfree(jtag);
> > +}
> > +EXPORT_SYMBOL_GPL(jtag_free);
> > +
> > +int jtag_register(struct jtag *jtag)
> > +{
> > + int id;
> > + int err;
> > +
> > + id = ida_simple_get(&jtag_ida, 0, 0, GFP_KERNEL);
> > + if (id < 0)
> > + return id;
> > +
> > + jtag->id = id;
> > + cdev_init(&jtag->cdev, &jtag_fops);
> > + jtag->cdev.owner = THIS_MODULE;
> > + err = cdev_add(&jtag->cdev, MKDEV(MAJOR(jtag_devt), jtag->id), 1);
> > + if (err)
> > + goto err_cdev;
>
> misc device would be so much simpler and easier here :(
>
>
> > +
> > + /* Register this jtag device with the driver core */
> > + jtag->dev = device_create(&jtag_class, NULL,
> MKDEV(MAJOR(jtag_devt),
> > + jtag->id),
> > + NULL, "jtag%d", jtag->id);
> > + if (!jtag->dev)
> > + goto err_device_create;
> > +
> > + atomic_set(&jtag->open, 0);
> > + dev_set_drvdata(jtag->dev, jtag);
> > + return err;
> > +
> > +err_device_create:
> > + cdev_del(&jtag->cdev);
> > +err_cdev:
> > + ida_simple_remove(&jtag_ida, id);
> > + return err;
> > +}
> > +EXPORT_SYMBOL_GPL(jtag_register);
> > +
> > +void jtag_unregister(struct jtag *jtag) {
> > + struct device *dev = jtag->dev;
> > +
> > + cdev_del(&jtag->cdev);
> > + device_unregister(dev);
> > + ida_simple_remove(&jtag_ida, jtag->id); }
> > +EXPORT_SYMBOL_GPL(jtag_unregister);
> > +
> > +static int __init jtag_init(void)
> > +{
> > + int err;
> > +
> > + err = alloc_chrdev_region(&jtag_devt, JTAG_FIRST_MINOR,
> > + JTAG_MAX_DEVICES, "jtag");
> > + if (err)
> > + return err;
> > +
> > + err = class_register(&jtag_class);
> > + if (err)
> > + unregister_chrdev_region(jtag_devt, JTAG_MAX_DEVICES);
> > +
> > + return err;
> > +}
> > +
> > +static void __exit jtag_exit(void)
> > +{
> > + class_unregister(&jtag_class);
> > + unregister_chrdev_region(jtag_devt, JTAG_MAX_DEVICES);
>
> Your idr leaked memory :(
>
Yes I will add ida_destroy() here.
>
>
> > +}
> > +
> > +module_init(jtag_init);
> > +module_exit(jtag_exit);
> > +
> > +MODULE_AUTHOR("Oleksandr Shamray <oleksandrs@mellanox.com>");
> > +MODULE_DESCRIPTION("Generic jtag support"); MODULE_LICENSE("GPL
> v2");
> > diff --git a/include/linux/jtag.h b/include/linux/jtag.h new file mode
> > 100644 index 0000000..c016fed
> > --- /dev/null
> > +++ b/include/linux/jtag.h
> > @@ -0,0 +1,48 @@
> > +/*
> > + * drivers/jtag/jtag.c
> > + *
> > + * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
> > + * Copyright (c) 2017 Oleksandr Shamray <oleksandrs@mellanox.com>
> > + *
> > + * Released under the GPLv2 only.
> > + * SPDX-License-Identifier: GPL-2.0
> > + */
> > +
> > +#ifndef __JTAG_H
> > +#define __JTAG_H
> > +
> > +#include <uapi/linux/jtag.h>
> > +
> > +#ifndef ARCH_DMA_MINALIGN
> > +#define ARCH_DMA_MINALIGN 1
> > +#endif
> > +
> > +#define jtag_u64_to_ptr(arg) ((void *)(uintptr_t)arg)
> > +
> > +#define JTAG_MAX_XFER_DATA_LEN 65535
> > +
> > +struct jtag;
> > +/**
> > + * struct jtag_ops - callbacks for jtag control functions:
> > + *
> > + * @freq_get: get frequency function. Filled by device driver
> > + * @freq_set: set frequency function. Filled by device driver
> > + * @status_get: set status function. Filled by device driver
> > + * @idle: set JTAG to idle state function. Filled by device driver
> > + * @xfer: send JTAG xfer function. Filled by device driver */ struct
> > +jtag_ops {
> > + int (*freq_get)(struct jtag *jtag, u32 *freq);
> > + int (*freq_set)(struct jtag *jtag, u32 freq);
> > + int (*status_get)(struct jtag *jtag, u32 *state);
> > + int (*idle)(struct jtag *jtag, struct jtag_run_test_idle *idle);
> > + int (*xfer)(struct jtag *jtag, struct jtag_xfer *xfer); };
> > +
> > +void *jtag_priv(struct jtag *jtag);
> > +int jtag_register(struct jtag *jtag); void jtag_unregister(struct
> > +jtag *jtag); struct jtag *jtag_alloc(size_t priv_size, const struct
> > +jtag_ops *ops); void jtag_free(struct jtag *jtag);
> > +
> > +#endif /* __JTAG_H */
> > diff --git a/include/uapi/linux/jtag.h b/include/uapi/linux/jtag.h new
> > file mode 100644 index 0000000..180bf22
> > --- /dev/null
> > +++ b/include/uapi/linux/jtag.h
> > @@ -0,0 +1,115 @@
> > +/*
> > + * JTAG class driver
> > + *
> > + * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
> > + * Copyright (c) 2017 Oleksandr Shamray <oleksandrs@mellanox.com>
> > + *
> > + * Released under the GPLv2/BSD.
> > + * SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> > +
> > +#ifndef __UAPI_LINUX_JTAG_H
> > +#define __UAPI_LINUX_JTAG_H
> > +
> > +/**
> > + * enum jtag_xfer_mode:
> > + *
> > + * @JTAG_XFER_HW_MODE: hardware mode transfer
> > + * @JTAG_XFER_SW_MODE: software mode transfer */ enum
> jtag_xfer_mode
> > +{
> > + JTAG_XFER_HW_MODE,
> > + JTAG_XFER_SW_MODE,
> > +};
> > +
> > +/**
> > + * enum jtag_endstate:
> > + *
> > + * @JTAG_STATE_IDLE: JTAG state machine IDLE state
> > + * @JTAG_STATE_PAUSEIR: JTAG state machine PAUSE_IR state
> > + * @JTAG_STATE_PAUSEDR: JTAG state machine PAUSE_DR state */ enum
> > +jtag_endstate {
> > + JTAG_STATE_IDLE,
> > + JTAG_STATE_PAUSEIR,
> > + JTAG_STATE_PAUSEDR,
> > +};
> > +
> > +/**
> > + * enum jtag_xfer_type:
> > + *
> > + * @JTAG_SIR_XFER: SIR transfer
> > + * @JTAG_SDR_XFER: SDR transfer
> > + */
> > +enum jtag_xfer_type {
> > + JTAG_SIR_XFER,
> > + JTAG_SDR_XFER,
> > +};
> > +
> > +/**
> > + * enum jtag_xfer_direction:
> > + *
> > + * @JTAG_READ_XFER: read transfer
> > + * @JTAG_WRITE_XFER: write transfer
> > + */
> > +enum jtag_xfer_direction {
> > + JTAG_READ_XFER,
> > + JTAG_WRITE_XFER,
> > +};
> > +
> > +/**
> > + * struct jtag_run_test_idle - forces JTAG state machine to
> > + * RUN_TEST/IDLE state
> > + *
> > + * @mode: access mode
> > + * @reset: 0 - run IDLE/PAUSE from current state
> > + * 1 - go through TEST_LOGIC/RESET state before IDLE/PAUSE
> > + * @end: completion flag
> > + * @tck: clock counter
> > + *
> > + * Structure represents interface to JTAG device for jtag idle
> > + * execution.
> > + */
> > +struct jtag_run_test_idle {
> > + __u8 mode;
> > + __u8 reset;
> > + __u8 endstate;
> > + __u8 tck;
> > +};
> > +
> > +/**
> > + * struct jtag_xfer - jtag xfer:
> > + *
> > + * @mode: access mode
> > + * @type: transfer type
> > + * @direction: xfer direction
> > + * @length: xfer bits len
> > + * @tdio : xfer data array
> > + * @endir: xfer end state
> > + *
> > + * Structure represents interface to Aspeed JTAG device for jtag sdr
> > +xfer
> > + * execution.
> > + */
> > +struct jtag_xfer {
> > + __u8 mode;
> > + __u8 type;
> > + __u8 direction;
> > + __u8 endstate;
> > + __u32 length;
> > + __u64 tdio;
>
> I don't see anything odd here that requires a compat ioctl callback, do you?
>
> thanks,
>
> greg k-h
Thanks for your review.
Oleksandr S.
^ permalink raw reply
* Re: [PATCH 1/2] serdev: ttyport: enforce tty-driver open() requirement
From: Greg Kroah-Hartman @ 2017-10-20 12:21 UTC (permalink / raw)
To: Rob Herring
Cc: Johan Hovold, Jiri Slaby, linux-serial@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <CAL_JsqKhCue-vMzM2ip3NoGTKb9T_EexG3G2-SekfVZOTKdHOA@mail.gmail.com>
On Tue, Oct 17, 2017 at 11:07:20AM -0500, Rob Herring wrote:
> On Mon, Oct 16, 2017 at 8:06 AM, Johan Hovold <johan@kernel.org> wrote:
> > The tty-driver open routine is mandatory, but the serdev
> > tty-port-controller implementation did not treat it as such and would
> > instead fall back to calling tty_port_open() directly.
>
> The idea was to eventually get rid of the tty_struct dependency and
> only depend on tty_port. That's very invasive though and needs various
> pieces of tty_struct to move into tty_port.
>
> Of course, tty_port_open itself would have to change as well, so this
> change doesn't really matter.
So are you acking these patches?
confused,
greg k-h
^ permalink raw reply
* Re: [PATCH 1/1] tty: serial: imx: disable ageing timer interrupt if dma in use
From: gregkh @ 2017-10-20 11:56 UTC (permalink / raw)
To: Han, Nandor (GE Healthcare)
Cc: Troy Kisky, linux-serial@vger.kernel.org,
u.kleine-koenig@pengutronix.de, fabio.estevam@nxp.com,
linux-arm-kernel@lists.infradead.org, l.stach@pengutronix.de
In-Reply-To: <AM3P101MB01800FAA2029393C5A859629E64A0@AM3P101MB0180.NAMP101.PROD.OUTLOOK.COM>
On Wed, Oct 11, 2017 at 06:22:53AM +0000, Han, Nandor (GE Healthcare) wrote:
>
>
> > -----Original Message-----
> > From: linux-serial-owner@vger.kernel.org [mailto:linux-serial-
> > owner@vger.kernel.org] On Behalf Of Troy Kisky
> > Sent: 07 October 2017 04:47
> > To: gregkh@linuxfoundation.org
> > Cc: fabio.estevam@nxp.com; l.stach@pengutronix.de; u.kleine-
> > koenig@pengutronix.de; linux-serial@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; Troy Kisky <troy.kisky@boundarydevices.com>
> > Subject: EXT: [PATCH 1/1] tty: serial: imx: disable ageing timer interrupt if
> > dma in use
> >
> > Since commit 4dec2f119e86 ("imx-serial: RX DMA startup latency")
> >
> > the interrupt routine no longer will start rx dma.
>
> I think you have 2 commits here:
> - one that disables ageing timer when DMA is in use
> - one that cleans the leftovers after 4dec2f119e86.
I agree, Troy, please make a patch series here.
thanks,
greg k-h
^ permalink raw reply
* Re: [patch v9 1/4] drivers: jtag: Add JTAG core driver
From: Greg KH @ 2017-10-20 11:55 UTC (permalink / raw)
To: Oleksandr Shamray
Cc: arnd-r2nGTMty4D4, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, openbmc-uLR06cmDAlY/bJ5BZ2RsiQ,
joel-U3u1mxZcP9KHXe+LvDLADg, jiri-rHqAuBHg3fBzbRFIqnYvSA,
tklauser-93Khv+1bN0NyDzI6CaY1VQ,
linux-serial-u79uwXL29TY76Z2rM5mHXA, mec-WqBc5aa1uDFeoWH0uzbU5w,
vadimp-VPRAkNaXOzVWk0Htik3J/w,
system-sw-low-level-VPRAkNaXOzVWk0Htik3J/w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
openocd-devel-owner-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-api-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
mchehab-DgEjT+Ai2ygdnm+yROfE0A, Jiri Pirko
In-Reply-To: <1505985932-27568-2-git-send-email-oleksandrs-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
On Thu, Sep 21, 2017 at 12:25:29PM +0300, Oleksandr Shamray wrote:
> +struct jtag {
> + struct device *dev;
> + struct cdev cdev;
Why are you using a cdev here and not just a normal misc device? I
forgot if this is what you were doing before, sorry...
> + int id;
> + atomic_t open;
Why do you need this?
> + const struct jtag_ops *ops;
> + unsigned long priv[0] __aligned(ARCH_DMA_MINALIGN);
Huh? Why is this needed to be dma aligned? Why not just use the
private pointer in struct device?
> +};
> +
> +static dev_t jtag_devt;
> +static DEFINE_IDA(jtag_ida);
> +
> +void *jtag_priv(struct jtag *jtag)
> +{
> + return jtag->priv;
> +}
> +EXPORT_SYMBOL_GPL(jtag_priv);
> +
> +static u8 *jtag_copy_from_user(__u64 udata, unsigned long bit_size)
> +{
> + unsigned long size;
> + void *kdata;
> +
> + size = DIV_ROUND_UP(bit_size, BITS_PER_BYTE);
> + kdata = memdup_user(u64_to_user_ptr(udata), size);
You only use this once, why not just open-code it?
> +
> + return kdata;
> +}
> +
> +static unsigned long jtag_copy_to_user(__u64 udata, u8 *kdata,
> + unsigned long bit_size)
> +{
> + unsigned long size;
> +
> + size = DIV_ROUND_UP(bit_size, BITS_PER_BYTE);
> +
> + return copy_to_user(u64_to_user_ptr(udata), (void *)(kdata), size);
Same here, making this a separate function seems odd.
> +}
> +
> +static struct class jtag_class = {
> + .name = "jtag",
> + .owner = THIS_MODULE,
> +};
> +
> +static int jtag_run_test_idle_op(struct jtag *jtag,
> + struct jtag_run_test_idle *idle)
> +{
> + if (jtag->ops->idle)
> + return jtag->ops->idle(jtag, idle);
> + else
> + return -EOPNOTSUPP;
Why is this a function? Why not just do this work in the ioctl?
> +}
> +
> +static int jtag_xfer_op(struct jtag *jtag, struct jtag_xfer *xfer, u8 *data)
> +{
> + if (jtag->ops->xfer)
> + return jtag->ops->xfer(jtag, xfer, data);
> + else
> + return -EOPNOTSUPP;
Same here, doesn't need to be a function.
> +}
> +
> +static long jtag_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> + struct jtag *jtag = file->private_data;
> + struct jtag_run_test_idle idle;
> + struct jtag_xfer xfer;
> + u8 *xfer_data;
> + u32 value;
> + int err;
> +
> + switch (cmd) {
> + case JTAG_GIOCFREQ:
> + if (jtag->ops->freq_get)
> + err = jtag->ops->freq_get(jtag, &value);
> + else
> + err = -EOPNOTSUPP;
> + if (err)
> + break;
> +
> + err = put_user(value, (__u32 *)arg);
> + break;
Are you sure the return value of put_user is correct here? Shouldn't
you return -EFAULT if err is not 0?
> +
> + case JTAG_SIOCFREQ:
> + err = get_user(value, (__u32 *)arg);
> +
why a blank line?
> + if (value == 0)
> + err = -EINVAL;
Check err first.
> + if (err)
> + break;
And set it properly, again err should be -EFAULT, right?
> +
> + if (jtag->ops->freq_set)
> + err = jtag->ops->freq_set(jtag, value);
> + else
> + err = -EOPNOTSUPP;
> + break;
> +
> + case JTAG_IOCRUNTEST:
> + if (copy_from_user(&idle, (void *)arg,
> + sizeof(struct jtag_run_test_idle)))
> + return -ENOMEM;
> + err = jtag_run_test_idle_op(jtag, &idle);
Who validates the structure fields? Is that up to the individual jtag
driver? Why not do it in the core correctly so that it only has to be
done in one place and you do not have to audit every individual driver?
> + break;
> +
> + case JTAG_IOCXFER:
> + if (copy_from_user(&xfer, (void *)arg,
> + sizeof(struct jtag_xfer)))
> + return -EFAULT;
> +
> + if (xfer.length >= JTAG_MAX_XFER_DATA_LEN)
> + return -EFAULT;
> +
> + xfer_data = jtag_copy_from_user(xfer.tdio, xfer.length);
> + if (!xfer_data)
> + return -ENOMEM;
Are you sure that's the correct error value?
> +
> + err = jtag_xfer_op(jtag, &xfer, xfer_data);
> + if (jtag_copy_to_user(xfer.tdio, xfer_data, xfer.length)) {
> + kfree(xfer_data);
> + return -EFAULT;
> + }
> +
> + kfree(xfer_data);
> + if (copy_to_user((void *)arg, &xfer, sizeof(struct jtag_xfer)))
> + return -EFAULT;
> + break;
> +
> + case JTAG_GIOCSTATUS:
> + if (jtag->ops->status_get)
> + err = jtag->ops->status_get(jtag, &value);
> + else
> + err = -EOPNOTSUPP;
> + if (err)
> + break;
> +
> + err = put_user(value, (__u32 *)arg);
Same put_user err issue here.
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> + return err;
> +}
> +
> +#ifdef CONFIG_COMPAT
> +static long jtag_ioctl_compat(struct file *file, unsigned int cmd,
> + unsigned long arg)
> +{
> + return jtag_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
> +}
> +#endif
Why do you need a compat callback for a new ioctl? Create your
structures properly and this should not be needed, right?
> +
> +static int jtag_open(struct inode *inode, struct file *file)
> +{
> + struct jtag *jtag = container_of(inode->i_cdev, struct jtag, cdev);
> +
> + if (atomic_read(&jtag->open)) {
> + dev_info(NULL, "jtag already opened\n");
> + return -EBUSY;
Why do you care if multiple opens can happen?
> + }
> +
> + atomic_inc(&jtag->open);
Oh look, you just raced with two different people opening at the same
time :(
An atomic value is never a replacement for a lock, sorry.
> + file->private_data = jtag;
> + return 0;
> +}
> +
> +static int jtag_release(struct inode *inode, struct file *file)
> +{
> + struct jtag *jtag = file->private_data;
> +
> + atomic_dec(&jtag->open);
Again, not needed.
> + return 0;
> +}
> +
> +static const struct file_operations jtag_fops = {
> + .owner = THIS_MODULE,
> + .open = jtag_open,
> + .release = jtag_release,
> + .llseek = noop_llseek,
> + .unlocked_ioctl = jtag_ioctl,
> +#ifdef CONFIG_COMPAT
> + .compat_ioctl = jtag_ioctl_compat,
> +#endif
> +};
> +
> +struct jtag *jtag_alloc(size_t priv_size, const struct jtag_ops *ops)
> +{
> + struct jtag *jtag;
> +
> + jtag = kzalloc(sizeof(*jtag) + round_up(priv_size, ARCH_DMA_MINALIGN),
> + GFP_KERNEL);
> + if (!jtag)
> + return NULL;
> +
> + jtag->ops = ops;
> + return jtag;
> +}
> +EXPORT_SYMBOL_GPL(jtag_alloc);
register should allocate and register the device, why pass a structure
back that the caller then has to do something else with to use it?
> +
> +void jtag_free(struct jtag *jtag)
> +{
> + kfree(jtag);
> +}
> +EXPORT_SYMBOL_GPL(jtag_free);
> +
> +int jtag_register(struct jtag *jtag)
> +{
> + int id;
> + int err;
> +
> + id = ida_simple_get(&jtag_ida, 0, 0, GFP_KERNEL);
> + if (id < 0)
> + return id;
> +
> + jtag->id = id;
> + cdev_init(&jtag->cdev, &jtag_fops);
> + jtag->cdev.owner = THIS_MODULE;
> + err = cdev_add(&jtag->cdev, MKDEV(MAJOR(jtag_devt), jtag->id), 1);
> + if (err)
> + goto err_cdev;
misc device would be so much simpler and easier here :(
> +
> + /* Register this jtag device with the driver core */
> + jtag->dev = device_create(&jtag_class, NULL, MKDEV(MAJOR(jtag_devt),
> + jtag->id),
> + NULL, "jtag%d", jtag->id);
> + if (!jtag->dev)
> + goto err_device_create;
> +
> + atomic_set(&jtag->open, 0);
> + dev_set_drvdata(jtag->dev, jtag);
> + return err;
> +
> +err_device_create:
> + cdev_del(&jtag->cdev);
> +err_cdev:
> + ida_simple_remove(&jtag_ida, id);
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(jtag_register);
> +
> +void jtag_unregister(struct jtag *jtag)
> +{
> + struct device *dev = jtag->dev;
> +
> + cdev_del(&jtag->cdev);
> + device_unregister(dev);
> + ida_simple_remove(&jtag_ida, jtag->id);
> +}
> +EXPORT_SYMBOL_GPL(jtag_unregister);
> +
> +static int __init jtag_init(void)
> +{
> + int err;
> +
> + err = alloc_chrdev_region(&jtag_devt, JTAG_FIRST_MINOR,
> + JTAG_MAX_DEVICES, "jtag");
> + if (err)
> + return err;
> +
> + err = class_register(&jtag_class);
> + if (err)
> + unregister_chrdev_region(jtag_devt, JTAG_MAX_DEVICES);
> +
> + return err;
> +}
> +
> +static void __exit jtag_exit(void)
> +{
> + class_unregister(&jtag_class);
> + unregister_chrdev_region(jtag_devt, JTAG_MAX_DEVICES);
Your idr leaked memory :(
> +}
> +
> +module_init(jtag_init);
> +module_exit(jtag_exit);
> +
> +MODULE_AUTHOR("Oleksandr Shamray <oleksandrs-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>");
> +MODULE_DESCRIPTION("Generic jtag support");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/jtag.h b/include/linux/jtag.h
> new file mode 100644
> index 0000000..c016fed
> --- /dev/null
> +++ b/include/linux/jtag.h
> @@ -0,0 +1,48 @@
> +/*
> + * drivers/jtag/jtag.c
> + *
> + * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
> + * Copyright (c) 2017 Oleksandr Shamray <oleksandrs-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> + *
> + * Released under the GPLv2 only.
> + * SPDX-License-Identifier: GPL-2.0
> + */
> +
> +#ifndef __JTAG_H
> +#define __JTAG_H
> +
> +#include <uapi/linux/jtag.h>
> +
> +#ifndef ARCH_DMA_MINALIGN
> +#define ARCH_DMA_MINALIGN 1
> +#endif
> +
> +#define jtag_u64_to_ptr(arg) ((void *)(uintptr_t)arg)
> +
> +#define JTAG_MAX_XFER_DATA_LEN 65535
> +
> +struct jtag;
> +/**
> + * struct jtag_ops - callbacks for jtag control functions:
> + *
> + * @freq_get: get frequency function. Filled by device driver
> + * @freq_set: set frequency function. Filled by device driver
> + * @status_get: set status function. Filled by device driver
> + * @idle: set JTAG to idle state function. Filled by device driver
> + * @xfer: send JTAG xfer function. Filled by device driver
> + */
> +struct jtag_ops {
> + int (*freq_get)(struct jtag *jtag, u32 *freq);
> + int (*freq_set)(struct jtag *jtag, u32 freq);
> + int (*status_get)(struct jtag *jtag, u32 *state);
> + int (*idle)(struct jtag *jtag, struct jtag_run_test_idle *idle);
> + int (*xfer)(struct jtag *jtag, struct jtag_xfer *xfer);
> +};
> +
> +void *jtag_priv(struct jtag *jtag);
> +int jtag_register(struct jtag *jtag);
> +void jtag_unregister(struct jtag *jtag);
> +struct jtag *jtag_alloc(size_t priv_size, const struct jtag_ops *ops);
> +void jtag_free(struct jtag *jtag);
> +
> +#endif /* __JTAG_H */
> diff --git a/include/uapi/linux/jtag.h b/include/uapi/linux/jtag.h
> new file mode 100644
> index 0000000..180bf22
> --- /dev/null
> +++ b/include/uapi/linux/jtag.h
> @@ -0,0 +1,115 @@
> +/*
> + * JTAG class driver
> + *
> + * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
> + * Copyright (c) 2017 Oleksandr Shamray <oleksandrs-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> + *
> + * Released under the GPLv2/BSD.
> + * SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> + */
> +
> +#ifndef __UAPI_LINUX_JTAG_H
> +#define __UAPI_LINUX_JTAG_H
> +
> +/**
> + * enum jtag_xfer_mode:
> + *
> + * @JTAG_XFER_HW_MODE: hardware mode transfer
> + * @JTAG_XFER_SW_MODE: software mode transfer
> + */
> +enum jtag_xfer_mode {
> + JTAG_XFER_HW_MODE,
> + JTAG_XFER_SW_MODE,
> +};
> +
> +/**
> + * enum jtag_endstate:
> + *
> + * @JTAG_STATE_IDLE: JTAG state machine IDLE state
> + * @JTAG_STATE_PAUSEIR: JTAG state machine PAUSE_IR state
> + * @JTAG_STATE_PAUSEDR: JTAG state machine PAUSE_DR state
> + */
> +enum jtag_endstate {
> + JTAG_STATE_IDLE,
> + JTAG_STATE_PAUSEIR,
> + JTAG_STATE_PAUSEDR,
> +};
> +
> +/**
> + * enum jtag_xfer_type:
> + *
> + * @JTAG_SIR_XFER: SIR transfer
> + * @JTAG_SDR_XFER: SDR transfer
> + */
> +enum jtag_xfer_type {
> + JTAG_SIR_XFER,
> + JTAG_SDR_XFER,
> +};
> +
> +/**
> + * enum jtag_xfer_direction:
> + *
> + * @JTAG_READ_XFER: read transfer
> + * @JTAG_WRITE_XFER: write transfer
> + */
> +enum jtag_xfer_direction {
> + JTAG_READ_XFER,
> + JTAG_WRITE_XFER,
> +};
> +
> +/**
> + * struct jtag_run_test_idle - forces JTAG state machine to
> + * RUN_TEST/IDLE state
> + *
> + * @mode: access mode
> + * @reset: 0 - run IDLE/PAUSE from current state
> + * 1 - go through TEST_LOGIC/RESET state before IDLE/PAUSE
> + * @end: completion flag
> + * @tck: clock counter
> + *
> + * Structure represents interface to JTAG device for jtag idle
> + * execution.
> + */
> +struct jtag_run_test_idle {
> + __u8 mode;
> + __u8 reset;
> + __u8 endstate;
> + __u8 tck;
> +};
> +
> +/**
> + * struct jtag_xfer - jtag xfer:
> + *
> + * @mode: access mode
> + * @type: transfer type
> + * @direction: xfer direction
> + * @length: xfer bits len
> + * @tdio : xfer data array
> + * @endir: xfer end state
> + *
> + * Structure represents interface to Aspeed JTAG device for jtag sdr xfer
> + * execution.
> + */
> +struct jtag_xfer {
> + __u8 mode;
> + __u8 type;
> + __u8 direction;
> + __u8 endstate;
> + __u32 length;
> + __u64 tdio;
I don't see anything odd here that requires a compat ioctl callback, do
you?
thanks,
greg k-h
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] serial: meson: add Magic SysRq support
From: Neil Armstrong @ 2017-10-20 8:48 UTC (permalink / raw)
To: Yixun Lan
Cc: Kevin Hilman, Greg Kroah-Hartman, linux-arm-kernel, linux-amlogic,
Ben Dooks, linux-kernel, linux-serial
In-Reply-To: <20171020083227.GA20623@ofmlt>
I Yixun,
On 20/10/2017 10:32, Yixun Lan wrote:
> Hi Greg-KH
>
> I think you've already accepted this patch (and merged into your git repo)
>
> so, is it possible for you to amend the commit message? or do you want me
> to send a PATCH v3 then?
I was not aware greg applied it, no need to amen anything, ignore my tag.
Neil
>
> On 10:10 Fri 20 Oct , Neil Armstrong wrote:
>> Hi Yixun,
>>
>> On 06/09/2017 15:52, Yixun Lan wrote:
>>> This dirver try to implement the Magic SysRq support[1] for
>>> Amlogic Inc's meson platfo
>>
>> Please fix these typos.
>>
> oops, not sure why this line is broken..
>
> s/platfo/platform./
> and should squash next line .
>
>>> From the hardware perspective, the UART IP can't detect the 'BREAK' command
>>> clearly via the status register. Instead, we rely on the combination of
>>> 'FRAME_ERR bit && ch == 0', and it works fine.
>>>
>>> [1] Documentation/admin-guide/sysrq.rst
>>>
>>> Signed-off-by: Yixun Lan <dlan@gentoo.org>
>>>
>>> ---
>>> Changes since v1 at [0]:
>>> - add changelog & a few more comments
>>>
>>> [0] https://patchwork.kernel.org/patch/9728475/
>>> ---
>>> drivers/tty/serial/meson_uart.c | 18 ++++++++++++++++--
>>> 1 file changed, 16 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>> index 42e4a4c7597f..3fea24bafd80 100644
>>> --- a/drivers/tty/serial/meson_uart.c
>>> +++ b/drivers/tty/serial/meson_uart.c
>>> @@ -14,6 +14,10 @@
>>> *
>>> */
>>>
>>> +#if defined(CONFIG_SERIAL_MESON_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
>>> +#define SUPPORT_SYSRQ
>>> +#endif
>>> +
>>> #include <linux/clk.h>
>>> #include <linux/console.h>
>>> #include <linux/delay.h>
>>> @@ -183,12 +187,12 @@ static void meson_receive_chars(struct uart_port *port)
>>> {
>>> struct tty_port *tport = &port->state->port;
>>> char flag;
>>> - u32 status, ch, mode;
>>> + u32 ostatus, status, ch, mode;
>>>
>>> do {
>>> flag = TTY_NORMAL;
>>> port->icount.rx++;
>>> - status = readl(port->membase + AML_UART_STATUS);
>>> + ostatus = status = readl(port->membase + AML_UART_STATUS);
>>>
>>> if (status & AML_UART_ERR) {
>>> if (status & AML_UART_TX_FIFO_WERR)
>>> @@ -216,6 +220,16 @@ static void meson_receive_chars(struct uart_port *port)
>>> ch = readl(port->membase + AML_UART_RFIFO);
>>> ch &= 0xff;
>>>
>>> + if ((ostatus & AML_UART_FRAME_ERR) && (ch == 0)) {
>>> + port->icount.brk++;
>>> + flag = TTY_BREAK;
>>> + if (uart_handle_break(port))
>>> + continue;
>>> + }
>>> +
>>> + if (uart_handle_sysrq_char(port, ch))
>>> + continue;
>>> +
>>> if ((status & port->ignore_status_mask) == 0)
>>> tty_insert_flip_char(tport, ch, flag);
>>>
>>>
>>
>> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
>>
>> _______________________________________________
>> linux-amlogic mailing list
>> linux-amlogic@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-amlogic
>
^ permalink raw reply
* Re: [PATCH v2] serial: meson: add Magic SysRq support
From: Yixun Lan @ 2017-10-20 8:32 UTC (permalink / raw)
To: Neil Armstrong
Cc: Kevin Hilman, Greg Kroah-Hartman, linux-arm-kernel, linux-amlogic,
Ben Dooks, linux-kernel, linux-serial
In-Reply-To: <d727b350-7936-2671-45c2-cf32dfda1a2a@baylibre.com>
Hi Greg-KH
I think you've already accepted this patch (and merged into your git repo)
so, is it possible for you to amend the commit message? or do you want me
to send a PATCH v3 then?
On 10:10 Fri 20 Oct , Neil Armstrong wrote:
> Hi Yixun,
>
> On 06/09/2017 15:52, Yixun Lan wrote:
> > This dirver try to implement the Magic SysRq support[1] for
> > Amlogic Inc's meson platfo
>
> Please fix these typos.
>
oops, not sure why this line is broken..
s/platfo/platform./
and should squash next line .
> > From the hardware perspective, the UART IP can't detect the 'BREAK' command
> > clearly via the status register. Instead, we rely on the combination of
> > 'FRAME_ERR bit && ch == 0', and it works fine.
> >
> > [1] Documentation/admin-guide/sysrq.rst
> >
> > Signed-off-by: Yixun Lan <dlan@gentoo.org>
> >
> > ---
> > Changes since v1 at [0]:
> > - add changelog & a few more comments
> >
> > [0] https://patchwork.kernel.org/patch/9728475/
> > ---
> > drivers/tty/serial/meson_uart.c | 18 ++++++++++++++++--
> > 1 file changed, 16 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> > index 42e4a4c7597f..3fea24bafd80 100644
> > --- a/drivers/tty/serial/meson_uart.c
> > +++ b/drivers/tty/serial/meson_uart.c
> > @@ -14,6 +14,10 @@
> > *
> > */
> >
> > +#if defined(CONFIG_SERIAL_MESON_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
> > +#define SUPPORT_SYSRQ
> > +#endif
> > +
> > #include <linux/clk.h>
> > #include <linux/console.h>
> > #include <linux/delay.h>
> > @@ -183,12 +187,12 @@ static void meson_receive_chars(struct uart_port *port)
> > {
> > struct tty_port *tport = &port->state->port;
> > char flag;
> > - u32 status, ch, mode;
> > + u32 ostatus, status, ch, mode;
> >
> > do {
> > flag = TTY_NORMAL;
> > port->icount.rx++;
> > - status = readl(port->membase + AML_UART_STATUS);
> > + ostatus = status = readl(port->membase + AML_UART_STATUS);
> >
> > if (status & AML_UART_ERR) {
> > if (status & AML_UART_TX_FIFO_WERR)
> > @@ -216,6 +220,16 @@ static void meson_receive_chars(struct uart_port *port)
> > ch = readl(port->membase + AML_UART_RFIFO);
> > ch &= 0xff;
> >
> > + if ((ostatus & AML_UART_FRAME_ERR) && (ch == 0)) {
> > + port->icount.brk++;
> > + flag = TTY_BREAK;
> > + if (uart_handle_break(port))
> > + continue;
> > + }
> > +
> > + if (uart_handle_sysrq_char(port, ch))
> > + continue;
> > +
> > if ((status & port->ignore_status_mask) == 0)
> > tty_insert_flip_char(tport, ch, flag);
> >
> >
>
> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
>
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic
--
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55
^ permalink raw reply
* Re: [PATCH v2] serial: meson: add Magic SysRq support
From: Neil Armstrong @ 2017-10-20 8:10 UTC (permalink / raw)
To: Yixun Lan, Kevin Hilman, Greg Kroah-Hartman
Cc: linux-kernel, Ben Dooks, linux-serial, linux-amlogic,
linux-arm-kernel
In-Reply-To: <20170906135239.29531-1-dlan@gentoo.org>
Hi Yixun,
On 06/09/2017 15:52, Yixun Lan wrote:
> This dirver try to implement the Magic SysRq support[1] for
> Amlogic Inc's meson platfo
Please fix these typos.
> From the hardware perspective, the UART IP can't detect the 'BREAK' command
> clearly via the status register. Instead, we rely on the combination of
> 'FRAME_ERR bit && ch == 0', and it works fine.
>
> [1] Documentation/admin-guide/sysrq.rst
>
> Signed-off-by: Yixun Lan <dlan@gentoo.org>
>
> ---
> Changes since v1 at [0]:
> - add changelog & a few more comments
>
> [0] https://patchwork.kernel.org/patch/9728475/
> ---
> drivers/tty/serial/meson_uart.c | 18 ++++++++++++++++--
> 1 file changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 42e4a4c7597f..3fea24bafd80 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -14,6 +14,10 @@
> *
> */
>
> +#if defined(CONFIG_SERIAL_MESON_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
> +#define SUPPORT_SYSRQ
> +#endif
> +
> #include <linux/clk.h>
> #include <linux/console.h>
> #include <linux/delay.h>
> @@ -183,12 +187,12 @@ static void meson_receive_chars(struct uart_port *port)
> {
> struct tty_port *tport = &port->state->port;
> char flag;
> - u32 status, ch, mode;
> + u32 ostatus, status, ch, mode;
>
> do {
> flag = TTY_NORMAL;
> port->icount.rx++;
> - status = readl(port->membase + AML_UART_STATUS);
> + ostatus = status = readl(port->membase + AML_UART_STATUS);
>
> if (status & AML_UART_ERR) {
> if (status & AML_UART_TX_FIFO_WERR)
> @@ -216,6 +220,16 @@ static void meson_receive_chars(struct uart_port *port)
> ch = readl(port->membase + AML_UART_RFIFO);
> ch &= 0xff;
>
> + if ((ostatus & AML_UART_FRAME_ERR) && (ch == 0)) {
> + port->icount.brk++;
> + flag = TTY_BREAK;
> + if (uart_handle_break(port))
> + continue;
> + }
> +
> + if (uart_handle_sysrq_char(port, ch))
> + continue;
> +
> if ((status & port->ignore_status_mask) == 0)
> tty_insert_flip_char(tport, ch, flag);
>
>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Hans de Goede @ 2017-10-19 19:05 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Loic Poulain, Johan Hovold, Greg Kroah-Hartman,
Frédéric Danis, Rafael J. Wysocki, Rob Herring,
Sebastian Reichel, Loic Poulain, Lukas Wunner,
open list:BLUETOOTH DRIVERS,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ACPI Devel Maling List
In-Reply-To: <FFD85CA6-6BD9-45AA-B3C2-898212711C0C-kz+m5ild9QBg9hUCZPvPmw@public.gmane.org>
Hi,
On 19-10-17 21:00, Marcel Holtmann wrote:
> Hi Hans,
>
>>> Hmm, I've never actually seen any hardware use an intel BT HCI connected
>>> to a serdev, but I guess people did not write that code for fun, so those
>>> do exist ?
>>> they are all ACPI based and could now start using serdev. Previously they were all driven by btattach.
>>> I understand, I was just wondering if anyone is aware of any hardware
>>> actually using Intel BT devices in this manner, because it is going
>>> to be tricky to do a similar series if we cannot test it.
>>> Yeah this driver supports Lightning-Peak iBT 3.0 UART controller.
>>> I remember this controller comes (at least) with Atom x3-c3440 / x3-c3445 SoCs.
>>> However I don't have the hardware anymore.
>>
>> Ah, those are the Rockchip manufactured Atom based SoCs which
>> come with Mali graphics, I don't think anyone is trying to run
>> mainline on those and not a whole lot of those have shipped to
>> begin with (the line has been canceled).
>>
>> I've an Apollo Lake based laptop with Intel Bluetooth, I just
>> checked and that is simply using USB.
>>
>> So I don't think we are actually going to break anything by
>> just moving forward as planned. This reminds me of the axp288
>> driver where Intel's "embedded" engineering team upstreamed
>> parts of the axp288 PMIC code, but in a way where the driver
>> could not work as it would not load with platform_data which
>> was never provided by the mainline kernel.
>>
>> As such it might actually be good to break this and if no-one
>> complains we can just remove the hci_intel.c code altogether.
>
> I think we can go forward with what we have. I am not going to remove hci_intel.c since the firmware loading code etc. is pretty generic to all Intel UART based chips. However we just take the PM pieces out or maybe someone is going to fix them.
Ok.
>> The alternative would be to revert 2 if the 3 patches of
>> my last series for making the BT on the GPD win / pocket
>> (and likely other devices) work in uart mode. Then someone
>> (me?) would need to do a completely untested series for
>> hci_intel.c, and get that + reverts of the reverts into 4.16,
>> which is not the best way forward IMHO.
>
> I am not doing that. We have to make progress towards serdev. So if things really turn out badly, then we have to deal with it, but that should not hold up getting things in the direction this needs to go.
Sounds good to me.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Marcel Holtmann @ 2017-10-19 19:00 UTC (permalink / raw)
To: Hans de Goede
Cc: Loic Poulain, Johan Hovold, Greg Kroah-Hartman,
Frédéric Danis, Rafael J. Wysocki, Rob Herring,
Sebastian Reichel, Loic Poulain, Lukas Wunner,
open list:BLUETOOTH DRIVERS, linux-serial@vger.kernel.org,
ACPI Devel Maling List
In-Reply-To: <28b99df9-de22-4542-055e-d9fa585aba8f@redhat.com>
Hi Hans,
>> Hmm, I've never actually seen any hardware use an intel BT HCI connected
>> to a serdev, but I guess people did not write that code for fun, so those
>> do exist ?
>> they are all ACPI based and could now start using serdev. Previously they were all driven by btattach.
>> I understand, I was just wondering if anyone is aware of any hardware
>> actually using Intel BT devices in this manner, because it is going
>> to be tricky to do a similar series if we cannot test it.
>> Yeah this driver supports Lightning-Peak iBT 3.0 UART controller.
>> I remember this controller comes (at least) with Atom x3-c3440 / x3-c3445 SoCs.
>> However I don't have the hardware anymore.
>
> Ah, those are the Rockchip manufactured Atom based SoCs which
> come with Mali graphics, I don't think anyone is trying to run
> mainline on those and not a whole lot of those have shipped to
> begin with (the line has been canceled).
>
> I've an Apollo Lake based laptop with Intel Bluetooth, I just
> checked and that is simply using USB.
>
> So I don't think we are actually going to break anything by
> just moving forward as planned. This reminds me of the axp288
> driver where Intel's "embedded" engineering team upstreamed
> parts of the axp288 PMIC code, but in a way where the driver
> could not work as it would not load with platform_data which
> was never provided by the mainline kernel.
>
> As such it might actually be good to break this and if no-one
> complains we can just remove the hci_intel.c code altogether.
I think we can go forward with what we have. I am not going to remove hci_intel.c since the firmware loading code etc. is pretty generic to all Intel UART based chips. However we just take the PM pieces out or maybe someone is going to fix them.
> The alternative would be to revert 2 if the 3 patches of
> my last series for making the BT on the GPD win / pocket
> (and likely other devices) work in uart mode. Then someone
> (me?) would need to do a completely untested series for
> hci_intel.c, and get that + reverts of the reverts into 4.16,
> which is not the best way forward IMHO.
I am not doing that. We have to make progress towards serdev. So if things really turn out badly, then we have to deal with it, but that should not hold up getting things in the direction this needs to go.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Hans de Goede @ 2017-10-19 18:50 UTC (permalink / raw)
To: Loic Poulain
Cc: Marcel Holtmann, Johan Hovold, Greg Kroah-Hartman,
Frédéric Danis, Rafael J. Wysocki, Rob Herring,
Sebastian Reichel, Loic Poulain, Lukas Wunner,
open list:BLUETOOTH DRIVERS,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ACPI Devel Maling List
In-Reply-To: <CAMZdPi_ZpNrdjJPnS_rQ9t3oYe6+en9oHQMjmMjx_xHL-WWZKQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi,
On 19-10-17 18:15, Loic Poulain wrote:
> Hi
>
>
> Hmm, I've never actually seen any hardware use an intel BT HCI connected
> to a serdev, but I guess people did not write that code for fun, so those
> do exist ?
>
>
> they are all ACPI based and could now start using serdev. Previously they were all driven by btattach.
>
>
> I understand, I was just wondering if anyone is aware of any hardware
> actually using Intel BT devices in this manner, because it is going
> to be tricky to do a similar series if we cannot test it.
>
>
> Yeah this driver supports Lightning-Peak iBT 3.0 UART controller.
> I remember this controller comes (at least) with Atom x3-c3440 / x3-c3445 SoCs.
> However I don't have the hardware anymore.
Ah, those are the Rockchip manufactured Atom based SoCs which
come with Mali graphics, I don't think anyone is trying to run
mainline on those and not a whole lot of those have shipped to
begin with (the line has been canceled).
I've an Apollo Lake based laptop with Intel Bluetooth, I just
checked and that is simply using USB.
So I don't think we are actually going to break anything by
just moving forward as planned. This reminds me of the axp288
driver where Intel's "embedded" engineering team upstreamed
parts of the axp288 PMIC code, but in a way where the driver
could not work as it would not load with platform_data which
was never provided by the mainline kernel.
As such it might actually be good to break this and if no-one
complains we can just remove the hci_intel.c code altogether.
The alternative would be to revert 2 if the 3 patches of
my last series for making the BT on the GPD win / pocket
(and likely other devices) work in uart mode. Then someone
(me?) would need to do a completely untested series for
hci_intel.c, and get that + reverts of the reverts into 4.16,
which is not the best way forward IMHO.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Hans de Goede @ 2017-10-19 14:56 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Johan Hovold, Greg Kroah-Hartman, Frédéric Danis,
Rafael J. Wysocki, Rob Herring, Sebastian Reichel, Loic Poulain,
Lukas Wunner, open list:BLUETOOTH DRIVERS,
linux-serial@vger.kernel.org, ACPI Devel Maling List
In-Reply-To: <115502FA-19DE-439C-A171-3CD5E6D92338@holtmann.org>
Hi,
On 19-10-17 16:32, Marcel Holtmann wrote:
> Hi Hans,
>
>>>>>>>>> Add ACPI support for serial attached devices.
>>>>>>>>>
>>>>>>>>> Currently, serial devices are not set as enumerated during
>>>>>>>>> ACPI scan for SPI or i2c buses (but not for UART). This
>>>>>>>>> should also be done for UART serial devices. I renamed
>>>>>>>>> *spi_i2c_slave* to *serial_bus_slave* to reflect this.
>>>>>>>>>
>>>>>>>>> This needs Johan Hovold's "serdev: fix registration of
>>>>>>>>> second slave" patch.
>>>>>>>> In theory this series could go in through the acpi-tree
>>>>>>>> without my fix. It would only affect an error case where an
>>>>>>>> unlikely failure to register an ACPI serdev device, would
>>>>>>>> prevent the tty-class device from being registered instead of
>>>>>>>> the controller. That is, something we can live with until this
>>>>>>>> all converges in 4.15-rc1 if needed.
>>>>>>>>
>>>>>>>> That said, I think we should consider taking all serdev
>>>>>>>> changes, and therefore also the ACPI patch, through the tty
>>>>>>>> tree instead in order to avoid merge conflicts. Rafael?
>>>>>>> OK
>>>>>>>
>>>>>>> Please feel free to add
>>>>>>>
>>>>>>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>>>>>>
>>>>>>> to the ACPI core change.
>>>>>>>
>>>>>>> And I will assume that this series will go in via the tty tree.
>>>>>> you have to take these two patches now via the TTY tree now. In
>>>>>> case you already marked them as someone else problem ;)
>>>>> Is there any problem I missed with those patches?
>>>>> Do I have to re-send them?
>>>>
>>>> No, they are in my queue, still catching up...
>>> I just realised that we cannot merge this series (the second acpi patch)
>>> until the hci_intel driver gains serdev support or otherwise PM will
>>> break for those devices.
>>> Specifically, the hci_intel driver uses similar hacks as the hci_bcm
>>> driver does for PM, so we need something like Hans's hci_bcm series also
>>> for hci_intel before we can do the switch.
>>
>> Hmm, I've never actually seen any hardware use an intel BT HCI connected
>> to a serdev, but I guess people did not write that code for fun, so those
>> do exist ?
>
> they are all ACPI based and could now start using serdev. Previously they were all driven by btattach.
I understand, I was just wondering if anyone is aware of any hardware
actually using Intel BT devices in this manner, because it is going
to be tricky to do a similar series if we cannot test it.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Johan Hovold @ 2017-10-19 14:32 UTC (permalink / raw)
To: Hans de Goede
Cc: Johan Hovold, Greg Kroah-Hartman, Frédéric Danis,
Marcel Holtmann, Rafael J. Wysocki, Rob Herring,
Sebastian Reichel, Loic Poulain, Lukas Wunner,
open list:BLUETOOTH DRIVERS,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ACPI Devel Maling List
In-Reply-To: <877ea825-eec5-d982-f962-d67067749009-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Thu, Oct 19, 2017 at 04:26:25PM +0200, Hans de Goede wrote:
> Hi,
>
> On 19-10-17 16:23, Johan Hovold wrote:
> > On Wed, Oct 18, 2017 at 04:56:08PM +0200, Greg Kroah-Hartman wrote:
> >> On Wed, Oct 18, 2017 at 04:46:05PM +0200, Frédéric Danis wrote:
> >
> >>> Le 11/10/2017 à 20:32, Marcel Holtmann a écrit :
> >
> >>>>>>> Add ACPI support for serial attached devices.
> >>>>>>>
> >>>>>>> Currently, serial devices are not set as enumerated during
> >>>>>>> ACPI scan for SPI or i2c buses (but not for UART). This
> >>>>>>> should also be done for UART serial devices. I renamed
> >>>>>>> *spi_i2c_slave* to *serial_bus_slave* to reflect this.
> > I just realised that we cannot merge this series (the second acpi patch)
> > until the hci_intel driver gains serdev support or otherwise PM will
> > break for those devices.
> >
> > Specifically, the hci_intel driver uses similar hacks as the hci_bcm
> > driver does for PM, so we need something like Hans's hci_bcm series also
> > for hci_intel before we can do the switch.
>
> Hmm, I've never actually seen any hardware use an intel BT HCI connected
> to a serdev, but I guess people did not write that code for fun, so those
> do exist ?
At least that's what it looks like.
It was added by Loic Poulain in commit 1ab1f239bf17 ("Bluetooth:
hci_intel: Add support for platform driver") two years ago and the
ACPI-match table has an entry for "INT33E1".
Johan
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Marcel Holtmann @ 2017-10-19 14:32 UTC (permalink / raw)
To: Hans de Goede
Cc: Johan Hovold, Greg Kroah-Hartman, Frédéric Danis,
Rafael J. Wysocki, Rob Herring, Sebastian Reichel, Loic Poulain,
Lukas Wunner, open list:BLUETOOTH DRIVERS,
linux-serial@vger.kernel.org, ACPI Devel Maling List
In-Reply-To: <877ea825-eec5-d982-f962-d67067749009@redhat.com>
Hi Hans,
>>>>>>>> Add ACPI support for serial attached devices.
>>>>>>>>
>>>>>>>> Currently, serial devices are not set as enumerated during
>>>>>>>> ACPI scan for SPI or i2c buses (but not for UART). This
>>>>>>>> should also be done for UART serial devices. I renamed
>>>>>>>> *spi_i2c_slave* to *serial_bus_slave* to reflect this.
>>>>>>>>
>>>>>>>> This needs Johan Hovold's "serdev: fix registration of
>>>>>>>> second slave" patch.
>>>>>>> In theory this series could go in through the acpi-tree
>>>>>>> without my fix. It would only affect an error case where an
>>>>>>> unlikely failure to register an ACPI serdev device, would
>>>>>>> prevent the tty-class device from being registered instead of
>>>>>>> the controller. That is, something we can live with until this
>>>>>>> all converges in 4.15-rc1 if needed.
>>>>>>>
>>>>>>> That said, I think we should consider taking all serdev
>>>>>>> changes, and therefore also the ACPI patch, through the tty
>>>>>>> tree instead in order to avoid merge conflicts. Rafael?
>>>>>> OK
>>>>>>
>>>>>> Please feel free to add
>>>>>>
>>>>>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>>>>>
>>>>>> to the ACPI core change.
>>>>>>
>>>>>> And I will assume that this series will go in via the tty tree.
>>>>> you have to take these two patches now via the TTY tree now. In
>>>>> case you already marked them as someone else problem ;)
>>>> Is there any problem I missed with those patches?
>>>> Do I have to re-send them?
>>>
>>> No, they are in my queue, still catching up...
>> I just realised that we cannot merge this series (the second acpi patch)
>> until the hci_intel driver gains serdev support or otherwise PM will
>> break for those devices.
>> Specifically, the hci_intel driver uses similar hacks as the hci_bcm
>> driver does for PM, so we need something like Hans's hci_bcm series also
>> for hci_intel before we can do the switch.
>
> Hmm, I've never actually seen any hardware use an intel BT HCI connected
> to a serdev, but I guess people did not write that code for fun, so those
> do exist ?
they are all ACPI based and could now start using serdev. Previously they were all driven by btattach.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Hans de Goede @ 2017-10-19 14:26 UTC (permalink / raw)
To: Johan Hovold, Greg Kroah-Hartman
Cc: Frédéric Danis, Marcel Holtmann, Rafael J. Wysocki,
Rob Herring, Sebastian Reichel, Loic Poulain, Lukas Wunner,
open list:BLUETOOTH DRIVERS, linux-serial@vger.kernel.org,
ACPI Devel Maling List
In-Reply-To: <20171019142354.GE5638@localhost>
Hi,
On 19-10-17 16:23, Johan Hovold wrote:
> On Wed, Oct 18, 2017 at 04:56:08PM +0200, Greg Kroah-Hartman wrote:
>> On Wed, Oct 18, 2017 at 04:46:05PM +0200, Frédéric Danis wrote:
>
>>> Le 11/10/2017 à 20:32, Marcel Holtmann a écrit :
>
>>>>>>> Add ACPI support for serial attached devices.
>>>>>>>
>>>>>>> Currently, serial devices are not set as enumerated during
>>>>>>> ACPI scan for SPI or i2c buses (but not for UART). This
>>>>>>> should also be done for UART serial devices. I renamed
>>>>>>> *spi_i2c_slave* to *serial_bus_slave* to reflect this.
>>>>>>>
>>>>>>> This needs Johan Hovold's "serdev: fix registration of
>>>>>>> second slave" patch.
>>>>>> In theory this series could go in through the acpi-tree
>>>>>> without my fix. It would only affect an error case where an
>>>>>> unlikely failure to register an ACPI serdev device, would
>>>>>> prevent the tty-class device from being registered instead of
>>>>>> the controller. That is, something we can live with until this
>>>>>> all converges in 4.15-rc1 if needed.
>>>>>>
>>>>>> That said, I think we should consider taking all serdev
>>>>>> changes, and therefore also the ACPI patch, through the tty
>>>>>> tree instead in order to avoid merge conflicts. Rafael?
>>>>> OK
>>>>>
>>>>> Please feel free to add
>>>>>
>>>>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>>>>
>>>>> to the ACPI core change.
>>>>>
>>>>> And I will assume that this series will go in via the tty tree.
>>>> you have to take these two patches now via the TTY tree now. In
>>>> case you already marked them as someone else problem ;)
>
>>> Is there any problem I missed with those patches?
>>> Do I have to re-send them?
>>
>> No, they are in my queue, still catching up...
>
> I just realised that we cannot merge this series (the second acpi patch)
> until the hci_intel driver gains serdev support or otherwise PM will
> break for those devices.
>
> Specifically, the hci_intel driver uses similar hacks as the hci_bcm
> driver does for PM, so we need something like Hans's hci_bcm series also
> for hci_intel before we can do the switch.
Hmm, I've never actually seen any hardware use an intel BT HCI connected
to a serdev, but I guess people did not write that code for fun, so those
do exist ?
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Johan Hovold @ 2017-10-19 14:23 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Frédéric Danis, Marcel Holtmann, Rafael J. Wysocki,
Johan Hovold, Rob Herring, Sebastian Reichel, Loic Poulain,
Lukas Wunner, Hans de Goede, open list:BLUETOOTH DRIVERS,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ACPI Devel Maling List
In-Reply-To: <20171018145608.GB27138-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
On Wed, Oct 18, 2017 at 04:56:08PM +0200, Greg Kroah-Hartman wrote:
> On Wed, Oct 18, 2017 at 04:46:05PM +0200, Frédéric Danis wrote:
> > Le 11/10/2017 à 20:32, Marcel Holtmann a écrit :
> > > > > > Add ACPI support for serial attached devices.
> > > > > >
> > > > > > Currently, serial devices are not set as enumerated during
> > > > > > ACPI scan for SPI or i2c buses (but not for UART). This
> > > > > > should also be done for UART serial devices. I renamed
> > > > > > *spi_i2c_slave* to *serial_bus_slave* to reflect this.
> > > > > >
> > > > > > This needs Johan Hovold's "serdev: fix registration of
> > > > > > second slave" patch.
> > > > > In theory this series could go in through the acpi-tree
> > > > > without my fix. It would only affect an error case where an
> > > > > unlikely failure to register an ACPI serdev device, would
> > > > > prevent the tty-class device from being registered instead of
> > > > > the controller. That is, something we can live with until this
> > > > > all converges in 4.15-rc1 if needed.
> > > > >
> > > > > That said, I think we should consider taking all serdev
> > > > > changes, and therefore also the ACPI patch, through the tty
> > > > > tree instead in order to avoid merge conflicts. Rafael?
> > > > OK
> > > >
> > > > Please feel free to add
> > > >
> > > > Acked-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> > > >
> > > > to the ACPI core change.
> > > >
> > > > And I will assume that this series will go in via the tty tree.
> > > you have to take these two patches now via the TTY tree now. In
> > > case you already marked them as someone else problem ;)
> > Is there any problem I missed with those patches?
> > Do I have to re-send them?
>
> No, they are in my queue, still catching up...
I just realised that we cannot merge this series (the second acpi patch)
until the hci_intel driver gains serdev support or otherwise PM will
break for those devices.
Specifically, the hci_intel driver uses similar hacks as the hci_bcm
driver does for PM, so we need something like Hans's hci_bcm series also
for hci_intel before we can do the switch.
Hopefully there are no more of these...
Johan
^ permalink raw reply
* Re: [PATCH v2 01/16] dt-bindings: mvebu-uart: update documentation with extended UART
From: Miquel RAYNAL @ 2017-10-19 7:36 UTC (permalink / raw)
To: Rob Herring
Cc: Greg Kroah-Hartman, Linus Walleij, Jason Cooper, Andrew Lunn,
Gregory Clement, Sebastian Hesselbarth, Jiri Slaby,
Catalin Marinas, Will Deacon,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Thomas Petazzoni, Antoine Tenart, Nadav Haklai
In-Reply-To: <CAL_JsqJ3VkXHnh1H2NcBhgiFE+++WvXGA9Phdgj77X-4VGX3+w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi Rob,
On Wed, 18 Oct 2017 08:29:07 -0500
Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Wed, Oct 18, 2017 at 1:25 AM, Miquel RAYNAL
> <miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> > Hi Rob,
> >
> > On Tue, 17 Oct 2017 17:00:22 -0500
> > Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> >
> >> On Fri, Oct 13, 2017 at 11:01:45AM +0200, Miquel Raynal wrote:
> >> > Update the Device Tree binding documentation for the Marvell EBU
> >> > UART, in order to allow describing the extended UART IP block, in
> >> > addition to the already supported standard UART IP. This requires
> >> > adding a new compatible string, the introduction of a clocks
> >> > property, and extensions to the interrupts property.
> >> >
> >> > Signed-off-by: Miquel Raynal <miquel.raynal-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> >> > Reviewed-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> >> > ---
> >> > .../devicetree/bindings/serial/mvebu-uart.txt | 49
> >> > +++++++++++++++++++--- 1 file changed, 44 insertions(+), 5
> >> > deletions(-)
> >> >
> >> > diff --git
> >> > a/Documentation/devicetree/bindings/serial/mvebu-uart.txt
> >> > b/Documentation/devicetree/bindings/serial/mvebu-uart.txt index
> >> > d37fabe17bd1..3df3a3fab4bb 100644 ---
> >> > a/Documentation/devicetree/bindings/serial/mvebu-uart.txt +++
> >> > b/Documentation/devicetree/bindings/serial/mvebu-uart.txt @@
> >> > -1,13 +1,52 @@ -* Marvell UART : Non standard UART used in some
> >> > of Marvell EBU SoCs (e.g., Armada-3700) +* Marvell UART : Non
> >> > standard UART used in some of Marvell EBU SoCs
> >> > + e.g., Armada-3700.
> >> >
> >> > Required properties:
> >> > -- compatible: "marvell,armada-3700-uart"
> >> > +- compatible:
> >> > + - "marvell,armada-3700-uart" for the standard variant of the
> >> > UART
> >> > + (32 bytes FIFO, no DMA, level interrupts, 8-bit access to
> >> > the
> >> > + FIFO, baudrate limited to 230400).
> >> > + - "marvell,armada-3700-uart-ext" for the extended variant of
> >> > the
> >> > + UART (128 bytes FIFO, DMA, front interrupts, 8-bit or
> >> > 32-bit
> >> > + accesses to the FIFO, baudrate unlimited by the
> >> > dividers).
> >>
> >> What do you call the next extended version?
> >> marvell,armada-3700-uart-ext-ext?
> >
> > I don't know what you mean by "next extended version"?
>
> IP evolves on new chips with new features. Just trying to understand
> how you are
I think I misunderstood your initial question.
Indeed you are right, I did not think about the naming of a potential
next extended version of the extended IP, but I don't know how to
rename it otherwise than "-ext" to best fit what the "new" IP
does.
>
> >> This is different versions of UART on the same chip?
> >
> > Today in mainline there is support for the A3700 UART IP.
> > This series add support for another IP, based on the A3700, but with
> > extended features (explaining the -ext suffix).
> >
> > Can you precise what is bothering you?
>
> Is this different versions of UART IP on 1 chip or a new version of
> the UART IP on a new SoC? The latter should be a new compatible with
> the new SoC. The former case does happen some, but is not common. I'm
> just trying to understand which applies here.
Actually, both IP are available since the first version of the
Armada 3700 SoCs. There is no other implementation of these IPs yet. I
think we fall in the former case.
>
>
> >> > - reg: offset and length of the register set for the device.
> >> > -- interrupts: device interrupt
> >> > +- clocks: UART reference clock used to derive the baudrate (only
> >> > + mandatory with "marvell,armada-3700-uart-ext"
> >> > compatible).
> >>
> >> How is this optional? The freq is fixed if not present? If so, what
> >> frequency?
> >
> > The "clocks" property should not be optional at all but that is how
> > the bindings were handled before this series, so I can't tell now
> > that this property is mandatory as it would break compatibility
> > with older versions of the driver.
>
> Okay. I think it should be mandatory with a note how missing property
> is handled.
Sure.
>
> > When no clock is provided, the frequency is fixed by the bootloader
> > and cannot be changed. There is no standard frequency for it but the
> > one chosen by the bootloader often is 115200 as the UART is usually
> > used as the serial console.
> >
> > Because the bootloader does only initialize the UART in use for the
> > serial console, the clock is mandatory when using another port or it
> > will not work at all.
Thank you,
Miquèl
--
Miquel Raynal, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V1 1/1] serial: 8250_fintek: Fix finding base_port with activated SuperIO
From: Alan Cox @ 2017-10-18 20:04 UTC (permalink / raw)
To: Ji-Ze Hong (Peter Hong)
Cc: gregkh, jslaby, rel+kernel, stable, linux-serial, linux-kernel,
hpeter+linux_kernel, peter_hong
In-Reply-To: <1508221388-25001-1-git-send-email-hpeter+linux_kernel@gmail.com>
On Tue, 17 Oct 2017 14:23:08 +0800
"Ji-Ze Hong (Peter Hong)" <hpeter@gmail.com> wrote:
> The SuperIO will be configured at boot time by BIOS, but some BIOS
> will not deactivate the SuperIO when the end of configuration. It'll
> lead to mismatch for pdata->base_port in probe_setup_port(). So we'll
> deactivate all SuperIO before activate special base_port in
> fintek_8250_enter_key().
>
> Tested on iBASE MI802.
Good point.
Reviewd-by: Alan Cox <alan@linux.intel.com>
Alan
^ permalink raw reply
* [PATCH v8 2/5] serdev: Introduce devm_serdev_device_open()
From: Andrey Smirnov @ 2017-10-18 17:01 UTC (permalink / raw)
To: linux-kernel
Cc: Andrey Smirnov, linux-serial, Rob Herring, cphealy, Guenter Roeck,
Lucas Stach, Nikita Yushchenko, Lee Jones, Greg Kroah-Hartman,
Pavel Machek, Andy Shevchenko, Johan Hovold
In-Reply-To: <20171018170136.12347-1-andrew.smirnov@gmail.com>
Add code implementing managed version of serdev_device_open() for
serdev device drivers that "open" the device during driver's lifecycle
only once (e.g. opened in .probe() and closed in .remove()).
Cc: linux-kernel@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: Rob Herring <robh@kernel.org>
Cc: cphealy@gmail.com
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Johan Hovold <johan@kernel.org>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
Documentation/driver-model/devres.txt | 3 +++
drivers/tty/serdev/core.c | 27 +++++++++++++++++++++++++++
include/linux/serdev.h | 1 +
3 files changed, 31 insertions(+)
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 69f08c0f23a8..e9c6b5cfeec1 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -383,6 +383,9 @@ RESET
devm_reset_control_get()
devm_reset_controller_register()
+SERDEV
+ devm_serdev_device_open()
+
SLAVE DMA ENGINE
devm_acpi_dma_controller_register()
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index f500f6a2ca88..b3a785665c6f 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -116,6 +116,33 @@ void serdev_device_close(struct serdev_device *serdev)
}
EXPORT_SYMBOL_GPL(serdev_device_close);
+static void devm_serdev_device_release(struct device *dev, void *dr)
+{
+ serdev_device_close(*(struct serdev_device **)dr);
+}
+
+int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev)
+{
+ struct serdev_device **dr;
+ int ret;
+
+ dr = devres_alloc(devm_serdev_device_release, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ ret = serdev_device_open(serdev);
+ if (ret) {
+ devres_free(dr);
+ return ret;
+ }
+
+ *dr = serdev;
+ devres_add(dev, dr);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_serdev_device_open);
+
void serdev_device_write_wakeup(struct serdev_device *serdev)
{
complete(&serdev->write_comp);
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index e69402d4a8ae..9929063bd45d 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -193,6 +193,7 @@ static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl,
int serdev_device_open(struct serdev_device *);
void serdev_device_close(struct serdev_device *);
+int devm_serdev_device_open(struct device *, struct serdev_device *);
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
void serdev_device_set_flow_control(struct serdev_device *, bool);
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
--
2.13.5
^ permalink raw reply related
* [PATCH v8 1/5] serdev: Make .remove in struct serdev_device_driver optional
From: Andrey Smirnov @ 2017-10-18 17:01 UTC (permalink / raw)
To: linux-kernel
Cc: Andrey Smirnov, linux-serial, Rob Herring, cphealy, Guenter Roeck,
Lucas Stach, Nikita Yushchenko, Lee Jones, Greg Kroah-Hartman,
Pavel Machek, Andy Shevchenko, Johan Hovold
In-Reply-To: <20171018170136.12347-1-andrew.smirnov@gmail.com>
Using devres infrastructure it is possible to wirte a serdev driver
that doesn't have any code that needs to be called as a part of
.remove. Add code to make .remove optional.
Cc: linux-kernel@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: Rob Herring <robh@kernel.org>
Cc: cphealy@gmail.com
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Johan Hovold <johan@kernel.org>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/tty/serdev/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index c68fb3a8ea1c..f500f6a2ca88 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -252,8 +252,8 @@ static int serdev_drv_probe(struct device *dev)
static int serdev_drv_remove(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
-
- sdrv->remove(to_serdev_device(dev));
+ if (sdrv->remove)
+ sdrv->remove(to_serdev_device(dev));
return 0;
}
--
2.13.5
^ permalink raw reply related
* Re: [PATCH v3 0/2] ACPI serdev support
From: Greg Kroah-Hartman @ 2017-10-18 14:56 UTC (permalink / raw)
To: Frédéric Danis
Cc: Marcel Holtmann, Rafael J. Wysocki, Johan Hovold, Rob Herring,
Sebastian Reichel, Loic Poulain, Lukas Wunner, Hans de Goede,
open list:BLUETOOTH DRIVERS, linux-serial@vger.kernel.org,
ACPI Devel Maling List
In-Reply-To: <ac53458d-c910-2d0a-a2ad-e7d21f8a5be7@gmail.com>
On Wed, Oct 18, 2017 at 04:46:05PM +0200, Frédéric Danis wrote:
> Hi Greg, Rafael, Marcel,
>
> Le 11/10/2017 à 20:32, Marcel Holtmann a écrit :
> > Hi Greg,
> >
> > > > > Add ACPI support for serial attached devices.
> > > > >
> > > > > Currently, serial devices are not set as enumerated during ACPI scan for SPI
> > > > > or i2c buses (but not for UART). This should also be done for UART serial
> > > > > devices.
> > > > > I renamed *spi_i2c_slave* to *serial_bus_slave* to reflect this.
> > > > >
> > > > > This needs Johan Hovold's "serdev: fix registration of second slave" patch.
> > > > In theory this series could go in through the acpi-tree without my
> > > > fix. It would only affect an error case where an unlikely failure to
> > > > register an ACPI serdev device, would prevent the tty-class device from
> > > > being registered instead of the controller. That is, something we can
> > > > live with until this all converges in 4.15-rc1 if needed.
> > > >
> > > > That said, I think we should consider taking all serdev changes, and
> > > > therefore also the ACPI patch, through the tty tree instead in order to
> > > > avoid merge conflicts. Rafael?
> > > OK
> > >
> > > Please feel free to add
> > >
> > > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > >
> > > to the ACPI core change.
> > >
> > > And I will assume that this series will go in via the tty tree.
> > you have to take these two patches now via the TTY tree now. In case you already marked them as someone else problem ;)
> >
> > Regards
> >
> > Marcel
>
> Is there any problem I missed with those patches?
> Do I have to re-send them?
No, they are in my queue, still catching up...
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v3 0/2] ACPI serdev support
From: Frédéric Danis @ 2017-10-18 14:46 UTC (permalink / raw)
To: Marcel Holtmann, Rafael J. Wysocki, Greg Kroah-Hartman
Cc: Johan Hovold, Rob Herring, Sebastian Reichel, Loic Poulain,
Lukas Wunner, Hans de Goede, open list:BLUETOOTH DRIVERS,
linux-serial@vger.kernel.org, ACPI Devel Maling List
In-Reply-To: <AA38D4FD-5A35-460D-85CF-380BAB933448@holtmann.org>
Hi Greg, Rafael, Marcel,
Le 11/10/2017 à 20:32, Marcel Holtmann a écrit :
> Hi Greg,
>
>>>> Add ACPI support for serial attached devices.
>>>>
>>>> Currently, serial devices are not set as enumerated during ACPI scan for SPI
>>>> or i2c buses (but not for UART). This should also be done for UART serial
>>>> devices.
>>>> I renamed *spi_i2c_slave* to *serial_bus_slave* to reflect this.
>>>>
>>>> This needs Johan Hovold's "serdev: fix registration of second slave" patch.
>>> In theory this series could go in through the acpi-tree without my
>>> fix. It would only affect an error case where an unlikely failure to
>>> register an ACPI serdev device, would prevent the tty-class device from
>>> being registered instead of the controller. That is, something we can
>>> live with until this all converges in 4.15-rc1 if needed.
>>>
>>> That said, I think we should consider taking all serdev changes, and
>>> therefore also the ACPI patch, through the tty tree instead in order to
>>> avoid merge conflicts. Rafael?
>> OK
>>
>> Please feel free to add
>>
>> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>
>> to the ACPI core change.
>>
>> And I will assume that this series will go in via the tty tree.
> you have to take these two patches now via the TTY tree now. In case you already marked them as someone else problem ;)
>
> Regards
>
> Marcel
Is there any problem I missed with those patches?
Do I have to re-send them?
Regards,
Fred
^ permalink raw reply
* [RFC PATCH 3/3] tty: amba-pl011: earlycon: Don't drain the transmitter after each char
From: Dave Martin @ 2017-10-18 14:14 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Andre Przywara, Stephen Boyd, Russell King, Andy Gross,
linux-serial, Greg Kroah-Hartman, Bhupinder Thakur
In-Reply-To: <1508336088-3948-1-git-send-email-Dave.Martin@arm.com>
Currently, the pl011 earlycon implementation waits for the UART
transmitter to drain completely and become idle after each
character is written.
This can result in (mostly harmless) delays and stuttering output
on the wire, and can also lead to poor performance in virtualised
UART implementations: thrashing between VMs can occur as each
character gets forcibly drained to the remove sink (dom0 in the Xen
case) before the source guest writes another character.
However, the semantics of earlycon don't allow callers to write one
character at a time with the expectation of completion: the only
interface to exposed to earlycon writes a whole string before
returning.
So, this patch eliminates the draining of the transmitted from
pl011_putc() and moves if to the the and of pl011_early_write()
instead. From the earlycon caller's point of view, the effect
should be faster but otherwise identical: either way, all the
characters have gone out onto the wire before the write method
returns.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
For background on the virtualisation issue, see [1]. Although
virtual UART implementations should be working around this issue
somehow for compatibility with current and older kernels, this patch
should promote better interoperation, and earlycon throughput should
improve a bit on real hardware too.
[1] Re: [Xen-devel] [PATCH 26/27 v12] arm/xen: vpl011: Fix the slow
early console SBSA UART output
https://lists.xenproject.org/archives/html/xen-devel/2017-10/msg01949.html
---
drivers/tty/serial/amba-pl011.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 084ed3f..e27059a 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2444,16 +2444,18 @@ static void pl011_putc(struct uart_port *port, int c)
while (__pl011_read(port, reg_offset, REG_FR) & UART01x_FR_TXFF)
cpu_relax();
__pl011_write(c, port, reg_offset, REG_DR);
- while (!__pl011_tx_empty(port, reg_offset, vendor))
- cpu_relax();
}
static void pl011_early_write(struct console *con, const char *s, unsigned n)
{
struct earlycon_device *dev = con->data;
+ const struct vendor_data *vendor = dev->port.private_data;
+ const u16 *reg_offset = vendor->reg_offset;
wmb();
uart_console_write(&dev->port, s, n, pl011_putc);
+ while (!__pl011_tx_empty(&dev->port, reg_offset, vendor))
+ cpu_relax();
}
static int __init
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 2/3] tty: amba-pl011: earlycon: Unify earlycon backends
From: Dave Martin @ 2017-10-18 14:14 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Andre Przywara, Stephen Boyd, Russell King, Andy Gross,
linux-serial, Greg Kroah-Hartman, Bhupinder Thakur
In-Reply-To: <1508336088-3948-1-git-send-email-Dave.Martin@arm.com>
Now that the generic pl011 and qdf2400_e44 earlycon backends differ
only in the choice of vendor_data and minor initialisation detatils
that are detectable based on vendor_data, there's no strong need
for them to be separate.
This patch factors common earlyon setup into a new function
pl011_early_console_setup_common(), which does generic setup and
stashes a pointer to the relevant vendor_data struct in
port->private_data (which appears otherwise unused by the
amba-pl011 driver).
The qdf2400_e44-specific earlycon write/putc functions would now be
identical to the pl011 versions, so they are deleted.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
drivers/tty/serial/amba-pl011.c | 53 ++++++++++++++++-------------------------
1 file changed, 20 insertions(+), 33 deletions(-)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index fd9e08c..084ed3f 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2436,29 +2436,9 @@ static struct console amba_console = {
#define AMBA_CONSOLE (&amba_console)
-static void qdf2400_e44_putc(struct uart_port *port, int c)
-{
- const struct vendor_data *vendor = &vendor_qdt_qdf2400_e44;
- const u16 *reg_offset = vendor->reg_offset;
-
- while (__pl011_read(port, reg_offset, REG_FR) & UART01x_FR_TXFF)
- cpu_relax();
- __pl011_write(c, port, reg_offset, REG_DR);
- while (!__pl011_tx_empty(port, reg_offset, vendor))
- cpu_relax();
-}
-
-static void qdf2400_e44_early_write(struct console *con, const char *s, unsigned n)
-{
- struct earlycon_device *dev = con->data;
-
- wmb();
- uart_console_write(&dev->port, s, n, qdf2400_e44_putc);
-}
-
static void pl011_putc(struct uart_port *port, int c)
{
- const struct vendor_data *vendor = &vendor_arm;
+ const struct vendor_data *vendor = port->private_data;
const u16 *reg_offset = vendor->reg_offset;
while (__pl011_read(port, reg_offset, REG_FR) & UART01x_FR_TXFF)
@@ -2476,6 +2456,22 @@ static void pl011_early_write(struct console *con, const char *s, unsigned n)
uart_console_write(&dev->port, s, n, pl011_putc);
}
+static int __init
+pl011_early_console_setup_common(struct earlycon_device *device,
+ const struct vendor_data *vendor)
+{
+ if (!device->port.membase)
+ return -ENODEV;
+
+ device->port.private_data = (void *)vendor;
+ if (vendor->access_32b)
+ device->port.iotype = UPIO_MEM32;
+
+ device->con->write = pl011_early_write;
+
+ return 0;
+}
+
/*
* On non-ACPI systems, earlycon is enabled by specifying
* "earlycon=pl011,<address>" on the kernel command line.
@@ -2491,12 +2487,7 @@ static void pl011_early_write(struct console *con, const char *s, unsigned n)
static int __init pl011_early_console_setup(struct earlycon_device *device,
const char *opt)
{
- if (!device->port.membase)
- return -ENODEV;
-
- device->con->write = pl011_early_write;
-
- return 0;
+ return pl011_early_console_setup_common(device, &vendor_arm);
}
OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup);
OF_EARLYCON_DECLARE(pl011, "arm,sbsa-uart", pl011_early_console_setup);
@@ -2515,12 +2506,8 @@ static int __init
qdf2400_e44_early_console_setup(struct earlycon_device *device,
const char *opt)
{
- if (!device->port.membase)
- return -ENODEV;
-
- device->port.iotype = UPIO_MEM32;
- device->con->write = qdf2400_e44_early_write;
- return 0;
+ return pl011_early_console_setup_common(device,
+ &vendor_qdt_qdf2400_e44);
}
EARLYCON_DECLARE(qdf2400_e44, qdf2400_e44_early_console_setup);
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 1/3] tty: amba-pl011: earlycon: Switch to relaxed I/O
From: Dave Martin @ 2017-10-18 14:14 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Andre Przywara, Stephen Boyd, Russell King, Andy Gross,
linux-serial, Greg Kroah-Hartman, Bhupinder Thakur
In-Reply-To: <1508336088-3948-1-git-send-email-Dave.Martin@arm.com>
The current pl011 earlycon implementation uses the regular I/O
accessors, but this is unnecessary because the architecture
enforces ordering of accesses to the same device anyway.
Using relaxed I/O brings the added bonus that the generic pl011
helpers can be used instead of having to open-code: this allows
some duplicate logic to be unified.
This patch does some refactoring so that pl011_{read,write,
tx_empty}() are split into a frontend that does the same thing as
before, and a backend __* that can be used with a uart_port that
has no corresponding uart_amba_port structure yet (i.e., the
earlycon scenario).
__pl011_tx_empty() can now be used in place of an open-coded poll
that differs between the generic and qdf2400_e44 earlycon
implementations, because __pl011_tx_empty() handles the necessary
quirkage transparently.
Moving to relaxed I/O loses wmb() semantics at the start of an
earlycon write, and this may be important for some debugging
scenarios, so an explicit wmb() is inserted at the start of each
earlycon write implementation.
Because qdf2400_e44 only supports 32-bit I/O, this patch also
explicitly sets port->iotype == UPIO_MEM32 so that __pl011_{write,
read}() use the correct I/O size.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
drivers/tty/serial/amba-pl011.c | 69 ++++++++++++++++++++++++++++-------------
1 file changed, 47 insertions(+), 22 deletions(-)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 111e6a9..fd9e08c 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -300,26 +300,38 @@ static unsigned int pl011_reg_to_offset(const struct uart_amba_port *uap,
return uap->reg_offset[reg];
}
-static unsigned int pl011_read(const struct uart_amba_port *uap,
- unsigned int reg)
+static unsigned int __pl011_read(const struct uart_port *port,
+ const u16 *reg_offset, unsigned int reg)
{
- void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg);
+ void __iomem *addr = port->membase + reg_offset[reg];
- return (uap->port.iotype == UPIO_MEM32) ?
+ return (port->iotype == UPIO_MEM32) ?
readl_relaxed(addr) : readw_relaxed(addr);
}
-static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
+static unsigned int pl011_read(const struct uart_amba_port *uap,
unsigned int reg)
{
- void __iomem *addr = uap->port.membase + pl011_reg_to_offset(uap, reg);
+ return __pl011_read(&uap->port, uap->reg_offset, reg);
+}
- if (uap->port.iotype == UPIO_MEM32)
+static void __pl011_write(unsigned int val, const struct uart_port *port,
+ const u16 *reg_offset, unsigned int reg)
+{
+ void __iomem *addr = port->membase + reg_offset[reg];
+
+ if (port->iotype == UPIO_MEM32)
writel_relaxed(val, addr);
else
writew_relaxed(val, addr);
}
+static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
+ unsigned int reg)
+{
+ __pl011_write(val, &uap->port, uap->reg_offset, reg);
+}
+
/*
* Reads up to 256 characters from the FIFO or until it's empty and
* inserts them into the TTY layer. Returns the number of characters
@@ -1537,16 +1549,23 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
return IRQ_RETVAL(handled);
}
-static unsigned int pl011_tx_empty(struct uart_port *port)
+static unsigned int __pl011_tx_empty(struct uart_port *port,
+ const u16 *reg_offset, const struct vendor_data *vendor)
{
- struct uart_amba_port *uap =
- container_of(port, struct uart_amba_port, port);
+ unsigned int status = __pl011_read(port, reg_offset, REG_FR);
/* Allow feature register bits to be inverted to work around errata */
- unsigned int status = pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr;
+ status ^= vendor->inv_fr;
+ status &= vendor->fr_busy | UART01x_FR_TXFF;
+ return status ? 0 : TIOCSER_TEMT;
+}
- return status & (uap->vendor->fr_busy | UART01x_FR_TXFF) ?
- 0 : TIOCSER_TEMT;
+static unsigned int pl011_tx_empty(struct uart_port *port)
+{
+ struct uart_amba_port *uap =
+ container_of(port, struct uart_amba_port, port);
+
+ return __pl011_tx_empty(port, uap->reg_offset, uap->vendor);
}
static unsigned int pl011_get_mctrl(struct uart_port *port)
@@ -2419,10 +2438,13 @@ static struct console amba_console = {
static void qdf2400_e44_putc(struct uart_port *port, int c)
{
- while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
+ const struct vendor_data *vendor = &vendor_qdt_qdf2400_e44;
+ const u16 *reg_offset = vendor->reg_offset;
+
+ while (__pl011_read(port, reg_offset, REG_FR) & UART01x_FR_TXFF)
cpu_relax();
- writel(c, port->membase + UART01x_DR);
- while (!(readl(port->membase + UART01x_FR) & UART011_FR_TXFE))
+ __pl011_write(c, port, reg_offset, REG_DR);
+ while (!__pl011_tx_empty(port, reg_offset, vendor))
cpu_relax();
}
@@ -2430,18 +2452,19 @@ static void qdf2400_e44_early_write(struct console *con, const char *s, unsigned
{
struct earlycon_device *dev = con->data;
+ wmb();
uart_console_write(&dev->port, s, n, qdf2400_e44_putc);
}
static void pl011_putc(struct uart_port *port, int c)
{
- while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
+ const struct vendor_data *vendor = &vendor_arm;
+ const u16 *reg_offset = vendor->reg_offset;
+
+ while (__pl011_read(port, reg_offset, REG_FR) & UART01x_FR_TXFF)
cpu_relax();
- if (port->iotype == UPIO_MEM32)
- writel(c, port->membase + UART01x_DR);
- else
- writeb(c, port->membase + UART01x_DR);
- while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
+ __pl011_write(c, port, reg_offset, REG_DR);
+ while (!__pl011_tx_empty(port, reg_offset, vendor))
cpu_relax();
}
@@ -2449,6 +2472,7 @@ static void pl011_early_write(struct console *con, const char *s, unsigned n)
{
struct earlycon_device *dev = con->data;
+ wmb();
uart_console_write(&dev->port, s, n, pl011_putc);
}
@@ -2494,6 +2518,7 @@ qdf2400_e44_early_console_setup(struct earlycon_device *device,
if (!device->port.membase)
return -ENODEV;
+ device->port.iotype = UPIO_MEM32;
device->con->write = qdf2400_e44_early_write;
return 0;
}
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 0/3] tty: amba-pl011: Decruft and streamline earlycon output
From: Dave Martin @ 2017-10-18 14:14 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Andre Przywara, Stephen Boyd, Russell King, Andy Gross,
linux-serial, Greg Kroah-Hartman, Bhupinder Thakur
This series avoids waiting for the UART transmitter to go idle in
between every earlycon char written, and does some refactoring so that
this change doesn't have to be implemented multiple times.
The initial motiviation for this is a performance issue encountered
during Xen virtual UART development (see [1] and patch 3).
It's debatable whether this is Linux's responsibility or the
responsibility of the virtual UART: this is a situation where the
virtualised behaviour is inevitably so different from hardware that
it's hard to make a ruling on exactly what behaviour is reasonable.
The best course is probably to work around it on _both_ ends, in the
interest of best interoperation.
Currently amba-pl011 has two distinct earlycon implementations: a
generic pl011 implementation and a quirked implementation that works
around the lack of a usable BUSY status bit in QDF2400 SoCs.
I don't like applying the same obscure fix in multiple places if I can
avoid it, so I've had a go at unifying the earlycons here (patches 1-2).
I'd appreciate people's views, particularly on:
* (pl011) Whether to refactor harder: the caching of vendor->reg_offset
vendor->access_32b in uart_amba_port is convenient and avoids chasing
an extra pointer in the common case, but this the refactoring for the
earlycon case a bit ugly. Maybe we can do better.
* (pl011, serial_core) Whether the new use of port->private_data will
conflict with existing code (no, AFAICT).
* (earlycon) Whether overriding port->iotype for 32-bit-only
implementations is the right thing to do.
* (earlycon) Whether there is some reason to drain the transmitter
after every char that I've overlooked.
Currently I don't consider this to be a candidate for stable, but it
could be backported. Due to the steady quirkage churn in amba-pl011,
it would be better to drop the refactoring stuff for backporting
purposes.
Testing:
* tested rather casually no ARM Juno r0 (real PL011) and the ARM VFP
Base Model (emulated PL011)
* *Not tested* on QDF2400, since I don't have access to one.
Someone probably ought to test that.
[1] Re: [Xen-devel] [PATCH 26/27 v12] arm/xen: vpl011: Fix the slow
early console SBSA UART output
https://lists.xenproject.org/archives/html/xen-devel/2017-10/msg01949.html
Dave Martin (3):
tty: amba-pl011: earlycon: Switch to relaxed I/O
tty: amba-pl011: earlycon: Unify earlycon backends
tty: amba-pl011: earlycon: Don't drain the transmitter after each char
drivers/tty/serial/amba-pl011.c | 108 +++++++++++++++++++++++-----------------
1 file changed, 61 insertions(+), 47 deletions(-)
--
2.1.4
^ permalink raw reply
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