* Re: [PATCH 1/2] irq/irq_sim: make the irq_sim structure opaque
From: Jonathan Cameron @ 2019-08-18 19:41 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Linus Walleij, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler, Thomas Gleixner, Marc Zyngier, linux-gpio,
linux-kernel, linux-iio, Bartosz Golaszewski
In-Reply-To: <20190818203836.6cceb4d3@archlinux>
On Sun, 18 Aug 2019 20:38:36 +0100
Jonathan Cameron <jic23@kernel.org> wrote:
> On Mon, 12 Aug 2019 14:52:55 +0200
> Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> > From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> >
> > There's no good reason to export the interrupt simulator structure to
> > users and have them provide memory for it. Let's make all the related
> > data structures opaque and convert both users. This way we have a lot
> > less APIs exposed in the header.
> >
> > Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> I agree in principle, but there is the disadvantage that all drivers
> that use it now need to bother with another allocation. I guess
> it is still worthwhile though.
>
> One comment inline.
Ignore that one as it's in code you get rid of in patch 2 ;)
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>
> Jonathan
>
> > ---
> > drivers/gpio/gpio-mockup.c | 12 ++---
> > drivers/iio/dummy/iio_dummy_evgen.c | 18 +++----
> > include/linux/irq_sim.h | 24 ++-------
> > kernel/irq/irq_sim.c | 83 ++++++++++++++++++-----------
> > 4 files changed, 70 insertions(+), 67 deletions(-)
> >
> > diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c
> > index f1a9c0544e3f..9b28ffec5826 100644
> > --- a/drivers/gpio/gpio-mockup.c
> > +++ b/drivers/gpio/gpio-mockup.c
> > @@ -53,7 +53,7 @@ struct gpio_mockup_line_status {
> > struct gpio_mockup_chip {
> > struct gpio_chip gc;
> > struct gpio_mockup_line_status *lines;
> > - struct irq_sim irqsim;
> > + struct irq_sim *irqsim;
> > struct dentry *dbg_dir;
> > struct mutex lock;
> > };
> > @@ -186,7 +186,7 @@ static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
> > {
> > struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
> >
> > - return irq_sim_irqnum(&chip->irqsim, offset);
> > + return irq_sim_irqnum(chip->irqsim, offset);
> > }
> >
> > static void gpio_mockup_free(struct gpio_chip *gc, unsigned int offset)
> > @@ -247,7 +247,7 @@ static ssize_t gpio_mockup_debugfs_write(struct file *file,
> > chip = priv->chip;
> > gc = &chip->gc;
> > desc = &gc->gpiodev->descs[priv->offset];
> > - sim = &chip->irqsim;
> > + sim = chip->irqsim;
> >
> > mutex_lock(&chip->lock);
> >
> > @@ -431,9 +431,9 @@ static int gpio_mockup_probe(struct platform_device *pdev)
> > return rv;
> > }
> >
> > - rv = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
> > - if (rv < 0)
> > - return rv;
> > + chip->irqsim = devm_irq_sim_new(dev, gc->ngpio);
> > + if (IS_ERR(chip->irqsim))
> > + return PTR_ERR(chip->irqsim);
> >
> > rv = devm_gpiochip_add_data(dev, &chip->gc, chip);
> > if (rv)
> > diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c
> > index a6edf30567aa..efbcd4a5609e 100644
> > --- a/drivers/iio/dummy/iio_dummy_evgen.c
> > +++ b/drivers/iio/dummy/iio_dummy_evgen.c
> > @@ -37,7 +37,7 @@ struct iio_dummy_eventgen {
> > struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
> > struct mutex lock;
> > bool inuse[IIO_EVENTGEN_NO];
> > - struct irq_sim irq_sim;
> > + struct irq_sim *irq_sim;
> > int base;
> > };
> >
> > @@ -46,19 +46,17 @@ static struct iio_dummy_eventgen *iio_evgen;
> >
> > static int iio_dummy_evgen_create(void)
> > {
> > - int ret;
> > -
> > iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL);
> > if (!iio_evgen)
> > return -ENOMEM;
> >
> > - ret = irq_sim_init(&iio_evgen->irq_sim, IIO_EVENTGEN_NO);
> > - if (ret < 0) {
> > + iio_evgen->irq_sim = irq_sim_new(IIO_EVENTGEN_NO);
> > + if (IS_ERR(iio_evgen->irq_sim)) {
> > kfree(iio_evgen);
> > - return ret;
> > + return PTR_ERR(iio_evgen->irq_sim);
> > }
> >
> > - iio_evgen->base = irq_sim_irqnum(&iio_evgen->irq_sim, 0);
> > + iio_evgen->base = irq_sim_irqnum(iio_evgen->irq_sim, 0);
> > mutex_init(&iio_evgen->lock);
> >
> > return 0;
> > @@ -80,7 +78,7 @@ int iio_dummy_evgen_get_irq(void)
> > mutex_lock(&iio_evgen->lock);
> > for (i = 0; i < IIO_EVENTGEN_NO; i++) {
> > if (!iio_evgen->inuse[i]) {
> > - ret = irq_sim_irqnum(&iio_evgen->irq_sim, i);
> > + ret = irq_sim_irqnum(iio_evgen->irq_sim, i);
> > iio_evgen->inuse[i] = true;
> > break;
> > }
> > @@ -115,7 +113,7 @@ EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
> >
> > static void iio_dummy_evgen_free(void)
> > {
> > - irq_sim_fini(&iio_evgen->irq_sim);
> > + irq_sim_free(iio_evgen->irq_sim);
> > kfree(iio_evgen);
> > }
> >
> > @@ -140,7 +138,7 @@ static ssize_t iio_evgen_poke(struct device *dev,
> > iio_evgen->regs[this_attr->address].reg_id = this_attr->address;
> > iio_evgen->regs[this_attr->address].reg_data = event;
> >
> > - irq_sim_fire(&iio_evgen->irq_sim, this_attr->address);
> > + irq_sim_fire(iio_evgen->irq_sim, this_attr->address);
> >
> > return len;
> > }
> > diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h
> > index 4500d453a63e..4bbf036145e2 100644
> > --- a/include/linux/irq_sim.h
> > +++ b/include/linux/irq_sim.h
> > @@ -14,27 +14,11 @@
> > * requested like normal irqs and enqueued from process context.
> > */
> >
> > -struct irq_sim_work_ctx {
> > - struct irq_work work;
> > - unsigned long *pending;
> > -};
> > +struct irq_sim;
> >
> > -struct irq_sim_irq_ctx {
> > - int irqnum;
> > - bool enabled;
> > -};
> > -
> > -struct irq_sim {
> > - struct irq_sim_work_ctx work_ctx;
> > - int irq_base;
> > - unsigned int irq_count;
> > - struct irq_sim_irq_ctx *irqs;
> > -};
> > -
> > -int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs);
> > -int devm_irq_sim_init(struct device *dev, struct irq_sim *sim,
> > - unsigned int num_irqs);
> > -void irq_sim_fini(struct irq_sim *sim);
> > +struct irq_sim *irq_sim_new(unsigned int num_irqs);
> > +struct irq_sim *devm_irq_sim_new(struct device *dev, unsigned int num_irqs);
> > +void irq_sim_free(struct irq_sim *sim);
> > void irq_sim_fire(struct irq_sim *sim, unsigned int offset);
> > int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset);
> >
> > diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c
> > index b992f88c5613..79f0a6494b6c 100644
> > --- a/kernel/irq/irq_sim.c
> > +++ b/kernel/irq/irq_sim.c
> > @@ -7,6 +7,23 @@
> > #include <linux/irq_sim.h>
> > #include <linux/irq.h>
> >
> > +struct irq_sim_work_ctx {
> > + struct irq_work work;
> > + unsigned long *pending;
> > +};
> > +
> > +struct irq_sim_irq_ctx {
> > + int irqnum;
> > + bool enabled;
> > +};
> > +
> > +struct irq_sim {
> > + struct irq_sim_work_ctx work_ctx;
> > + int irq_base;
> > + unsigned int irq_count;
> > + struct irq_sim_irq_ctx *irqs;
> > +};
> > +
> > struct irq_sim_devres {
> > struct irq_sim *sim;
> > };
> > @@ -63,34 +80,42 @@ static void irq_sim_handle_irq(struct irq_work *work)
> > }
> >
> > /**
> > - * irq_sim_init - Initialize the interrupt simulator: allocate a range of
> > - * dummy interrupts.
> > + * irq_sim_new - Create a new interrupt simulator: allocate a range of
> > + * dummy interrupts.
> > *
> > - * @sim: The interrupt simulator object to initialize.
> > * @num_irqs: Number of interrupts to allocate
> > *
> > - * On success: return the base of the allocated interrupt range.
> > - * On failure: a negative errno.
> > + * On success: return the new irq_sim object.
> > + * On failure: a negative errno wrapped with ERR_PTR().
> > */
> > -int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs)
> > +struct irq_sim *irq_sim_new(unsigned int num_irqs)
> > {
> > + struct irq_sim *sim;
> > int i;
> >
> > + sim = kmalloc(sizeof(*sim), GFP_KERNEL);
> > + if (!sim)
> > + return ERR_PTR(-ENOMEM);
> > +
> > sim->irqs = kmalloc_array(num_irqs, sizeof(*sim->irqs), GFP_KERNEL);
> > - if (!sim->irqs)
> > - return -ENOMEM;
> > + if (!sim->irqs) {
> > + kfree(sim);
> > + return ERR_PTR(-ENOMEM);
> > + }
> >
> > sim->irq_base = irq_alloc_descs(-1, 0, num_irqs, 0);
> > if (sim->irq_base < 0) {
> > kfree(sim->irqs);
> > - return sim->irq_base;
> > + kfree(sim);
> > + return ERR_PTR(sim->irq_base);
> > }
> >
> > sim->work_ctx.pending = bitmap_zalloc(num_irqs, GFP_KERNEL);
> > if (!sim->work_ctx.pending) {
> > kfree(sim->irqs);
> > + kfree(sim);
>
> This rather looks like a function that could benefit from some
> unified error paths. That was true already, but adding another step
> makes it an even better idea. Goto fun :)
>
> > irq_free_descs(sim->irq_base, num_irqs);
> > - return -ENOMEM;
> > + return ERR_PTR(-ENOMEM);
> > }
> >
> > for (i = 0; i < num_irqs; i++) {
> > @@ -106,64 +131,60 @@ int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs)
> > init_irq_work(&sim->work_ctx.work, irq_sim_handle_irq);
> > sim->irq_count = num_irqs;
> >
> > - return sim->irq_base;
> > + return sim;
> > }
> > -EXPORT_SYMBOL_GPL(irq_sim_init);
> > +EXPORT_SYMBOL_GPL(irq_sim_new);
> >
> > /**
> > - * irq_sim_fini - Deinitialize the interrupt simulator: free the interrupt
> > + * irq_sim_free - Deinitialize the interrupt simulator: free the interrupt
> > * descriptors and allocated memory.
> > *
> > * @sim: The interrupt simulator to tear down.
> > */
> > -void irq_sim_fini(struct irq_sim *sim)
> > +void irq_sim_free(struct irq_sim *sim)
> > {
> > irq_work_sync(&sim->work_ctx.work);
> > bitmap_free(sim->work_ctx.pending);
> > irq_free_descs(sim->irq_base, sim->irq_count);
> > kfree(sim->irqs);
> > + kfree(sim);
> > }
> > -EXPORT_SYMBOL_GPL(irq_sim_fini);
> > +EXPORT_SYMBOL_GPL(irq_sim_free);
> >
> > static void devm_irq_sim_release(struct device *dev, void *res)
> > {
> > struct irq_sim_devres *this = res;
> >
> > - irq_sim_fini(this->sim);
> > + irq_sim_free(this->sim);
> > }
> >
> > /**
> > - * irq_sim_init - Initialize the interrupt simulator for a managed device.
> > + * devm_irq_sim_new - Create a new interrupt simulator for a managed device.
> > *
> > * @dev: Device to initialize the simulator object for.
> > - * @sim: The interrupt simulator object to initialize.
> > * @num_irqs: Number of interrupts to allocate
> > *
> > - * On success: return the base of the allocated interrupt range.
> > - * On failure: a negative errno.
> > + * On success: return a new irq_sim object.
> > + * On failure: a negative errno wrapped with ERR_PTR().
> > */
> > -int devm_irq_sim_init(struct device *dev, struct irq_sim *sim,
> > - unsigned int num_irqs)
> > +struct irq_sim *devm_irq_sim_new(struct device *dev, unsigned int num_irqs)
> > {
> > struct irq_sim_devres *dr;
> > - int rv;
> >
> > dr = devres_alloc(devm_irq_sim_release, sizeof(*dr), GFP_KERNEL);
> > if (!dr)
> > - return -ENOMEM;
> > + return ERR_PTR(-ENOMEM);
> >
> > - rv = irq_sim_init(sim, num_irqs);
> > - if (rv < 0) {
> > + dr->sim = irq_sim_new(num_irqs);
> > + if (IS_ERR(dr->sim)) {
> > devres_free(dr);
> > - return rv;
> > + return dr->sim;
> > }
> >
> > - dr->sim = sim;
> > devres_add(dev, dr);
> > -
> > - return rv;
> > + return dr->sim;
> > }
> > -EXPORT_SYMBOL_GPL(devm_irq_sim_init);
> > +EXPORT_SYMBOL_GPL(devm_irq_sim_new);
> >
> > /**
> > * irq_sim_fire - Enqueue an interrupt.
>
^ permalink raw reply
* Re: [PATCH 1/2] irq/irq_sim: make the irq_sim structure opaque
From: Jonathan Cameron @ 2019-08-18 19:38 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Linus Walleij, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler, Thomas Gleixner, Marc Zyngier, linux-gpio,
linux-kernel, linux-iio, Bartosz Golaszewski
In-Reply-To: <20190812125256.9690-2-brgl@bgdev.pl>
On Mon, 12 Aug 2019 14:52:55 +0200
Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> There's no good reason to export the interrupt simulator structure to
> users and have them provide memory for it. Let's make all the related
> data structures opaque and convert both users. This way we have a lot
> less APIs exposed in the header.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
I agree in principle, but there is the disadvantage that all drivers
that use it now need to bother with another allocation. I guess
it is still worthwhile though.
One comment inline.
Jonathan
> ---
> drivers/gpio/gpio-mockup.c | 12 ++---
> drivers/iio/dummy/iio_dummy_evgen.c | 18 +++----
> include/linux/irq_sim.h | 24 ++-------
> kernel/irq/irq_sim.c | 83 ++++++++++++++++++-----------
> 4 files changed, 70 insertions(+), 67 deletions(-)
>
> diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c
> index f1a9c0544e3f..9b28ffec5826 100644
> --- a/drivers/gpio/gpio-mockup.c
> +++ b/drivers/gpio/gpio-mockup.c
> @@ -53,7 +53,7 @@ struct gpio_mockup_line_status {
> struct gpio_mockup_chip {
> struct gpio_chip gc;
> struct gpio_mockup_line_status *lines;
> - struct irq_sim irqsim;
> + struct irq_sim *irqsim;
> struct dentry *dbg_dir;
> struct mutex lock;
> };
> @@ -186,7 +186,7 @@ static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
> {
> struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
>
> - return irq_sim_irqnum(&chip->irqsim, offset);
> + return irq_sim_irqnum(chip->irqsim, offset);
> }
>
> static void gpio_mockup_free(struct gpio_chip *gc, unsigned int offset)
> @@ -247,7 +247,7 @@ static ssize_t gpio_mockup_debugfs_write(struct file *file,
> chip = priv->chip;
> gc = &chip->gc;
> desc = &gc->gpiodev->descs[priv->offset];
> - sim = &chip->irqsim;
> + sim = chip->irqsim;
>
> mutex_lock(&chip->lock);
>
> @@ -431,9 +431,9 @@ static int gpio_mockup_probe(struct platform_device *pdev)
> return rv;
> }
>
> - rv = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
> - if (rv < 0)
> - return rv;
> + chip->irqsim = devm_irq_sim_new(dev, gc->ngpio);
> + if (IS_ERR(chip->irqsim))
> + return PTR_ERR(chip->irqsim);
>
> rv = devm_gpiochip_add_data(dev, &chip->gc, chip);
> if (rv)
> diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c
> index a6edf30567aa..efbcd4a5609e 100644
> --- a/drivers/iio/dummy/iio_dummy_evgen.c
> +++ b/drivers/iio/dummy/iio_dummy_evgen.c
> @@ -37,7 +37,7 @@ struct iio_dummy_eventgen {
> struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
> struct mutex lock;
> bool inuse[IIO_EVENTGEN_NO];
> - struct irq_sim irq_sim;
> + struct irq_sim *irq_sim;
> int base;
> };
>
> @@ -46,19 +46,17 @@ static struct iio_dummy_eventgen *iio_evgen;
>
> static int iio_dummy_evgen_create(void)
> {
> - int ret;
> -
> iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL);
> if (!iio_evgen)
> return -ENOMEM;
>
> - ret = irq_sim_init(&iio_evgen->irq_sim, IIO_EVENTGEN_NO);
> - if (ret < 0) {
> + iio_evgen->irq_sim = irq_sim_new(IIO_EVENTGEN_NO);
> + if (IS_ERR(iio_evgen->irq_sim)) {
> kfree(iio_evgen);
> - return ret;
> + return PTR_ERR(iio_evgen->irq_sim);
> }
>
> - iio_evgen->base = irq_sim_irqnum(&iio_evgen->irq_sim, 0);
> + iio_evgen->base = irq_sim_irqnum(iio_evgen->irq_sim, 0);
> mutex_init(&iio_evgen->lock);
>
> return 0;
> @@ -80,7 +78,7 @@ int iio_dummy_evgen_get_irq(void)
> mutex_lock(&iio_evgen->lock);
> for (i = 0; i < IIO_EVENTGEN_NO; i++) {
> if (!iio_evgen->inuse[i]) {
> - ret = irq_sim_irqnum(&iio_evgen->irq_sim, i);
> + ret = irq_sim_irqnum(iio_evgen->irq_sim, i);
> iio_evgen->inuse[i] = true;
> break;
> }
> @@ -115,7 +113,7 @@ EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
>
> static void iio_dummy_evgen_free(void)
> {
> - irq_sim_fini(&iio_evgen->irq_sim);
> + irq_sim_free(iio_evgen->irq_sim);
> kfree(iio_evgen);
> }
>
> @@ -140,7 +138,7 @@ static ssize_t iio_evgen_poke(struct device *dev,
> iio_evgen->regs[this_attr->address].reg_id = this_attr->address;
> iio_evgen->regs[this_attr->address].reg_data = event;
>
> - irq_sim_fire(&iio_evgen->irq_sim, this_attr->address);
> + irq_sim_fire(iio_evgen->irq_sim, this_attr->address);
>
> return len;
> }
> diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h
> index 4500d453a63e..4bbf036145e2 100644
> --- a/include/linux/irq_sim.h
> +++ b/include/linux/irq_sim.h
> @@ -14,27 +14,11 @@
> * requested like normal irqs and enqueued from process context.
> */
>
> -struct irq_sim_work_ctx {
> - struct irq_work work;
> - unsigned long *pending;
> -};
> +struct irq_sim;
>
> -struct irq_sim_irq_ctx {
> - int irqnum;
> - bool enabled;
> -};
> -
> -struct irq_sim {
> - struct irq_sim_work_ctx work_ctx;
> - int irq_base;
> - unsigned int irq_count;
> - struct irq_sim_irq_ctx *irqs;
> -};
> -
> -int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs);
> -int devm_irq_sim_init(struct device *dev, struct irq_sim *sim,
> - unsigned int num_irqs);
> -void irq_sim_fini(struct irq_sim *sim);
> +struct irq_sim *irq_sim_new(unsigned int num_irqs);
> +struct irq_sim *devm_irq_sim_new(struct device *dev, unsigned int num_irqs);
> +void irq_sim_free(struct irq_sim *sim);
> void irq_sim_fire(struct irq_sim *sim, unsigned int offset);
> int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset);
>
> diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c
> index b992f88c5613..79f0a6494b6c 100644
> --- a/kernel/irq/irq_sim.c
> +++ b/kernel/irq/irq_sim.c
> @@ -7,6 +7,23 @@
> #include <linux/irq_sim.h>
> #include <linux/irq.h>
>
> +struct irq_sim_work_ctx {
> + struct irq_work work;
> + unsigned long *pending;
> +};
> +
> +struct irq_sim_irq_ctx {
> + int irqnum;
> + bool enabled;
> +};
> +
> +struct irq_sim {
> + struct irq_sim_work_ctx work_ctx;
> + int irq_base;
> + unsigned int irq_count;
> + struct irq_sim_irq_ctx *irqs;
> +};
> +
> struct irq_sim_devres {
> struct irq_sim *sim;
> };
> @@ -63,34 +80,42 @@ static void irq_sim_handle_irq(struct irq_work *work)
> }
>
> /**
> - * irq_sim_init - Initialize the interrupt simulator: allocate a range of
> - * dummy interrupts.
> + * irq_sim_new - Create a new interrupt simulator: allocate a range of
> + * dummy interrupts.
> *
> - * @sim: The interrupt simulator object to initialize.
> * @num_irqs: Number of interrupts to allocate
> *
> - * On success: return the base of the allocated interrupt range.
> - * On failure: a negative errno.
> + * On success: return the new irq_sim object.
> + * On failure: a negative errno wrapped with ERR_PTR().
> */
> -int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs)
> +struct irq_sim *irq_sim_new(unsigned int num_irqs)
> {
> + struct irq_sim *sim;
> int i;
>
> + sim = kmalloc(sizeof(*sim), GFP_KERNEL);
> + if (!sim)
> + return ERR_PTR(-ENOMEM);
> +
> sim->irqs = kmalloc_array(num_irqs, sizeof(*sim->irqs), GFP_KERNEL);
> - if (!sim->irqs)
> - return -ENOMEM;
> + if (!sim->irqs) {
> + kfree(sim);
> + return ERR_PTR(-ENOMEM);
> + }
>
> sim->irq_base = irq_alloc_descs(-1, 0, num_irqs, 0);
> if (sim->irq_base < 0) {
> kfree(sim->irqs);
> - return sim->irq_base;
> + kfree(sim);
> + return ERR_PTR(sim->irq_base);
> }
>
> sim->work_ctx.pending = bitmap_zalloc(num_irqs, GFP_KERNEL);
> if (!sim->work_ctx.pending) {
> kfree(sim->irqs);
> + kfree(sim);
This rather looks like a function that could benefit from some
unified error paths. That was true already, but adding another step
makes it an even better idea. Goto fun :)
> irq_free_descs(sim->irq_base, num_irqs);
> - return -ENOMEM;
> + return ERR_PTR(-ENOMEM);
> }
>
> for (i = 0; i < num_irqs; i++) {
> @@ -106,64 +131,60 @@ int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs)
> init_irq_work(&sim->work_ctx.work, irq_sim_handle_irq);
> sim->irq_count = num_irqs;
>
> - return sim->irq_base;
> + return sim;
> }
> -EXPORT_SYMBOL_GPL(irq_sim_init);
> +EXPORT_SYMBOL_GPL(irq_sim_new);
>
> /**
> - * irq_sim_fini - Deinitialize the interrupt simulator: free the interrupt
> + * irq_sim_free - Deinitialize the interrupt simulator: free the interrupt
> * descriptors and allocated memory.
> *
> * @sim: The interrupt simulator to tear down.
> */
> -void irq_sim_fini(struct irq_sim *sim)
> +void irq_sim_free(struct irq_sim *sim)
> {
> irq_work_sync(&sim->work_ctx.work);
> bitmap_free(sim->work_ctx.pending);
> irq_free_descs(sim->irq_base, sim->irq_count);
> kfree(sim->irqs);
> + kfree(sim);
> }
> -EXPORT_SYMBOL_GPL(irq_sim_fini);
> +EXPORT_SYMBOL_GPL(irq_sim_free);
>
> static void devm_irq_sim_release(struct device *dev, void *res)
> {
> struct irq_sim_devres *this = res;
>
> - irq_sim_fini(this->sim);
> + irq_sim_free(this->sim);
> }
>
> /**
> - * irq_sim_init - Initialize the interrupt simulator for a managed device.
> + * devm_irq_sim_new - Create a new interrupt simulator for a managed device.
> *
> * @dev: Device to initialize the simulator object for.
> - * @sim: The interrupt simulator object to initialize.
> * @num_irqs: Number of interrupts to allocate
> *
> - * On success: return the base of the allocated interrupt range.
> - * On failure: a negative errno.
> + * On success: return a new irq_sim object.
> + * On failure: a negative errno wrapped with ERR_PTR().
> */
> -int devm_irq_sim_init(struct device *dev, struct irq_sim *sim,
> - unsigned int num_irqs)
> +struct irq_sim *devm_irq_sim_new(struct device *dev, unsigned int num_irqs)
> {
> struct irq_sim_devres *dr;
> - int rv;
>
> dr = devres_alloc(devm_irq_sim_release, sizeof(*dr), GFP_KERNEL);
> if (!dr)
> - return -ENOMEM;
> + return ERR_PTR(-ENOMEM);
>
> - rv = irq_sim_init(sim, num_irqs);
> - if (rv < 0) {
> + dr->sim = irq_sim_new(num_irqs);
> + if (IS_ERR(dr->sim)) {
> devres_free(dr);
> - return rv;
> + return dr->sim;
> }
>
> - dr->sim = sim;
> devres_add(dev, dr);
> -
> - return rv;
> + return dr->sim;
> }
> -EXPORT_SYMBOL_GPL(devm_irq_sim_init);
> +EXPORT_SYMBOL_GPL(devm_irq_sim_new);
>
> /**
> * irq_sim_fire - Enqueue an interrupt.
^ permalink raw reply
* Re: [PATCH] Skip deferred request irqs for devices known to fail
From: Hans de Goede @ 2019-08-18 18:59 UTC (permalink / raw)
To: Ian W MORRISON
Cc: benjamin.tissoires, mika.westerberg, Andy Shevchenko,
linus.walleij, bgolaszewski, linux-gpio, linux-acpi, linux-kernel,
stable
In-Reply-To: <CAFXWsS9UYYz0HaYPgLAUZ0OaUE9gb25bT0+PSuexY9Nn05rY8Q@mail.gmail.com>
Hi Ian, et. al.,
On 23-03-19 04:39, Ian W MORRISON wrote:
> Hi Hans,
>
>> IMHO we need to root-cause this problem a bit more before applying this
>> kludge.
>>
>> Can you provide an ACPI dump of one of the affected machines ?
>>
>
> Attached is an ACPI dump.
First of all sorry for taking way too long to get back to you on this.
So I've taken a look at all the _AEI code in the DSDT, a whole bunch of
it seems copy and pasted from various tablets, but nothing really
stands out as being a likely cause of this.
As such I guess we may need to go with the blacklist patch you suggested
which sucks, but having these devices not boot sucks even harder.
I guess this problem did not magically fix it self in the mean time
(with newer kernels) ?
Can you resubmit your patch with Andy's review remarks addressed?
In case you've lost Andy's reply I will reproduce the review remarks
below.
Regards,
Hans
p.s.
Andy's review remarks as promised:
> #include <linux/interrupt.h>
> #include <linux/mutex.h>
> #include <linux/pinctrl/pinctrl.h>
> +#include <linux/dmi.h>
This should be in order.
> /* Run deferred acpi_gpiochip_request_irqs() */
> +/* but exclude devices known to fail */
/*
* This should be done in the similar style
* as for multi-line comments. Like this one.
*/
> + dmi_id = dmi_first_match(skip_deferred_request_irqs_table);
> +
Redundant blank line.
> + if (! dmi_id) {
No space here, however, better to write positive conditional.
^ permalink raw reply
* Re: [PATCH v2] gpio: pl061: Fix the issue failed to register the ACPI interrtupion
From: kbuild test robot @ 2019-08-18 12:58 UTC (permalink / raw)
To: Wei Xu
Cc: kbuild-all, xuwei5, linux-gpio, linux-kernel, linux-arm-kernel,
linus.walleij, rjw, lenb, mika.westerberg, andy.shevchenko,
linuxarm, shameerali.kolothum.thodi, jonathan.cameron, john.garry,
salil.mehta, shiju.jose, jinying, zhangyi.ac, liguozhu,
tangkunshan, huangdaode
In-Reply-To: <1565946336-20080-1-git-send-email-xuwei5@hisilicon.com>
[-- Attachment #1: Type: text/plain, Size: 1306 bytes --]
Hi Wei,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[cannot apply to v5.3-rc4 next-20190816]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Wei-Xu/gpio-pl061-Fix-the-issue-failed-to-register-the-ACPI-interrtupion/20190818-183921
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=arm
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> drivers/gpio/gpio-pl061.c:29:10: fatal error: gpiolib-acpi.h: No such file or directory
#include "gpiolib-acpi.h"
^~~~~~~~~~~~~~~~
compilation terminated.
vim +29 drivers/gpio/gpio-pl061.c
27
28 #include "gpiolib.h"
> 29 #include "gpiolib-acpi.h"
30
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 71381 bytes --]
^ permalink raw reply
* Re: [PATCH] pinctrl/qcom: Fix -Wimplicit-fallthrough
From: Bjorn Andersson @ 2019-08-18 0:12 UTC (permalink / raw)
To: Alex Dewar; +Cc: agross, linus.walleij, linux-arm-msm, linux-gpio, linux-kernel
In-Reply-To: <20190817082520.7751-1-alex.dewar@gmx.co.uk>
On Sat 17 Aug 01:25 PDT 2019, Alex Dewar wrote:
> In pinctrl-spmi-gpio.c there is a switch case which is obviously
> intended to fall through to the next label. Add a comment to suppress
> -Wimplicit-fallthrough warning.
>
Thanks for your patch Alex, this was fixed in 6161dc03587b ("pinctrl:
qcom: spmi-gpio: Mark expected switch fall-through")
Regards,
Bjorn
> Signed-off-by: Alex Dewar <alex.dewar@gmx.co.uk>
> ---
> drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
> index f39da87ea185..b035dd5e25b8 100644
> --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
> +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
> @@ -813,6 +813,7 @@ static int pmic_gpio_populate(struct pmic_gpio_state *state,
> switch (subtype) {
> case PMIC_GPIO_SUBTYPE_GPIO_4CH:
> pad->have_buffer = true;
> + /* FALLS THROUGH */
> case PMIC_GPIO_SUBTYPE_GPIOC_4CH:
> pad->num_sources = 4;
> break;
> --
> 2.22.1
>
^ permalink raw reply
* [PATCH] pinctrl/qcom: Fix -Wimplicit-fallthrough
From: Alex Dewar @ 2019-08-17 8:25 UTC (permalink / raw)
To: agross, linus.walleij, bjorn.andersson
Cc: linux-arm-msm, linux-gpio, linux-kernel, Alex Dewar
In pinctrl-spmi-gpio.c there is a switch case which is obviously
intended to fall through to the next label. Add a comment to suppress
-Wimplicit-fallthrough warning.
Signed-off-by: Alex Dewar <alex.dewar@gmx.co.uk>
---
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
index f39da87ea185..b035dd5e25b8 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
@@ -813,6 +813,7 @@ static int pmic_gpio_populate(struct pmic_gpio_state *state,
switch (subtype) {
case PMIC_GPIO_SUBTYPE_GPIO_4CH:
pad->have_buffer = true;
+ /* FALLS THROUGH */
case PMIC_GPIO_SUBTYPE_GPIOC_4CH:
pad->num_sources = 4;
break;
--
2.22.1
^ permalink raw reply related
* linusw/fixes boot: 54 boots: 2 failed, 52 passed (v5.3-rc4-3-gdf451f83e1fc)
From: kernelci.org bot @ 2019-08-17 0:42 UTC (permalink / raw)
To: linux-gpio, fellows
linusw/fixes boot: 54 boots: 2 failed, 52 passed (v5.3-rc4-3-gdf451f83e1fc)
Full Boot Summary: https://kernelci.org/boot/all/job/linusw/branch/fixes/kernel/v5.3-rc4-3-gdf451f83e1fc/
Full Build Summary: https://kernelci.org/build/linusw/branch/fixes/kernel/v5.3-rc4-3-gdf451f83e1fc/
Tree: linusw
Branch: fixes
Git Describe: v5.3-rc4-3-gdf451f83e1fc
Git Commit: df451f83e1fc0fa3764a2724b0faaaf9d07ab1b6
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/
Tested: 38 unique boards, 15 SoC families, 3 builds out of 6
Boot Regressions Detected:
arm:
multi_v7_defconfig:
gcc-8:
sun8i-h3-libretech-all-h3-cc:
lab-baylibre: new failure (last pass: v5.3-rc4-2-g68e03b85474a)
arm64:
defconfig:
gcc-8:
meson-gxbb-nanopi-k2:
lab-baylibre: new failure (last pass: v5.3-rc4-2-g68e03b85474a)
Boot Failures Detected:
arm64:
defconfig:
gcc-8:
meson-gxbb-nanopi-k2: 1 failed lab
arm:
multi_v7_defconfig:
gcc-8:
sun8i-h3-libretech-all-h3-cc: 1 failed lab
---
For more info write to <info@kernelci.org>
^ permalink raw reply
* linusw/devel boot: 55 boots: 3 failed, 52 passed (v5.3-rc1-31-g379ce1ff51aa)
From: kernelci.org bot @ 2019-08-17 0:35 UTC (permalink / raw)
To: linux-gpio, fellows
linusw/devel boot: 55 boots: 3 failed, 52 passed (v5.3-rc1-31-g379ce1ff51aa)
Full Boot Summary: https://kernelci.org/boot/all/job/linusw/branch/devel/kernel/v5.3-rc1-31-g379ce1ff51aa/
Full Build Summary: https://kernelci.org/build/linusw/branch/devel/kernel/v5.3-rc1-31-g379ce1ff51aa/
Tree: linusw
Branch: devel
Git Describe: v5.3-rc1-31-g379ce1ff51aa
Git Commit: 379ce1ff51aac14405604a45fa6c9bfc77a854e8
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/
Tested: 39 unique boards, 15 SoC families, 3 builds out of 6
Boot Regressions Detected:
arm64:
defconfig:
gcc-8:
apq8016-sbc:
lab-mhart: failing since 17 days (last pass: v5.2-10808-g9637d517347e - first fail: v5.3-rc1-5-ga299726da44f)
meson-gxbb-nanopi-k2:
lab-baylibre: failing since 1 day (last pass: v5.3-rc1-25-g470219c619e9 - first fail: v5.3-rc1-30-ge00fae7d82ec)
Boot Failures Detected:
arm64:
defconfig:
gcc-8:
apq8016-sbc: 1 failed lab
meson-gxbb-nanopi-k2: 1 failed lab
meson-gxm-khadas-vim2: 1 failed lab
---
For more info write to <info@kernelci.org>
^ permalink raw reply
* linusw/for-next boot: 55 boots: 2 failed, 53 passed (v5.3-rc4-35-g984078b26420)
From: kernelci.org bot @ 2019-08-17 0:17 UTC (permalink / raw)
To: linux-gpio, fellows
linusw/for-next boot: 55 boots: 2 failed, 53 passed (v5.3-rc4-35-g984078b26420)
Full Boot Summary: https://kernelci.org/boot/all/job/linusw/branch/for-next/kernel/v5.3-rc4-35-g984078b26420/
Full Build Summary: https://kernelci.org/build/linusw/branch/for-next/kernel/v5.3-rc4-35-g984078b26420/
Tree: linusw
Branch: for-next
Git Describe: v5.3-rc4-35-g984078b26420
Git Commit: 984078b264207fc748c1b1d3aede99b0271b3b55
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/
Tested: 39 unique boards, 15 SoC families, 3 builds out of 6
Boot Regressions Detected:
arm64:
defconfig:
gcc-8:
meson-gxbb-nanopi-k2:
lab-baylibre: new failure (last pass: v5.3-rc4-33-g02c05fd1775c)
meson-gxbb-p200:
lab-baylibre: new failure (last pass: v5.2-rc6-74-g08fc54c5c8ec)
Boot Failures Detected:
arm64:
defconfig:
gcc-8:
meson-gxbb-nanopi-k2: 1 failed lab
meson-gxbb-p200: 1 failed lab
---
For more info write to <info@kernelci.org>
^ permalink raw reply
* linusw/fixes build: 6 builds: 0 failed, 6 passed, 34 warnings (v5.3-rc4-3-gdf451f83e1fc)
From: kernelci.org bot @ 2019-08-16 23:58 UTC (permalink / raw)
To: linux-gpio, fellows
linusw/fixes build: 6 builds: 0 failed, 6 passed, 34 warnings (v5.3-rc4-3-gdf451f83e1fc)
Full Build Summary: https://kernelci.org/build/linusw/branch/fixes/kernel/v5.3-rc4-3-gdf451f83e1fc/
Tree: linusw
Branch: fixes
Git Describe: v5.3-rc4-3-gdf451f83e1fc
Git Commit: df451f83e1fc0fa3764a2724b0faaaf9d07ab1b6
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/
Built: 6 unique architectures
Warnings Detected:
arc:
nsim_hs_defconfig (gcc-8): 5 warnings
arm64:
defconfig (gcc-8): 5 warnings
arm:
multi_v7_defconfig (gcc-8): 21 warnings
mips:
32r2el_defconfig (gcc-8): 3 warnings
riscv:
x86_64:
Warnings summary:
5 <stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
2 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:820:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
2 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:815:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
2 drivers/pinctrl/pinctrl-rockchip.c:2783:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
2 drivers/gpu/drm/sun4i/sun4i_tcon.c:316:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 include/linux/compiler.h:328:5: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/video/fbdev/sh_mobile_lcdcfb.c:2086:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/video/fbdev/sh_mobile_lcdcfb.c:1596:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:459:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:440:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:424:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:370:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:352:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:332:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/sdhci-s3c.c:613:19: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/atmel-mci.c:2426:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/atmel-mci.c:2422:28: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/atmel-mci.c:2415:30: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/iommu/arm-smmu-v3.c:1189:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:992:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sti/sti_hdmi.c:855:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sti/sti_hdmi.c:853:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sti/sti_hdmi.c:851:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/dma/imx-dma.c:542:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 arch/arc/kernel/unwind.c:836:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 arch/arc/kernel/unwind.c:827:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
================================================================================
Detailed per-defconfig build reports:
--------------------------------------------------------------------------------
32r2el_defconfig (mips, gcc-8) — PASS, 0 errors, 3 warnings, 0 section mismatches
Warnings:
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
--------------------------------------------------------------------------------
defconfig (riscv, gcc-8) — PASS, 0 errors, 0 warnings, 0 section mismatches
--------------------------------------------------------------------------------
defconfig (arm64, gcc-8) — PASS, 0 errors, 5 warnings, 0 section mismatches
Warnings:
drivers/iommu/arm-smmu-v3.c:1189:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:815:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:820:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/pinctrl-rockchip.c:2783:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sun4i/sun4i_tcon.c:316:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
--------------------------------------------------------------------------------
multi_v7_defconfig (arm, gcc-8) — PASS, 0 errors, 21 warnings, 0 section mismatches
Warnings:
drivers/dma/imx-dma.c:542:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/sdhci-s3c.c:613:19: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/atmel-mci.c:2415:30: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/atmel-mci.c:2422:28: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/atmel-mci.c:2426:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:815:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:820:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/pinctrl-rockchip.c:2783:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/video/fbdev/sh_mobile_lcdcfb.c:2086:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/video/fbdev/sh_mobile_lcdcfb.c:1596:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:424:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:440:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:459:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:332:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:352:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:370:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sti/sti_hdmi.c:851:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sti/sti_hdmi.c:853:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sti/sti_hdmi.c:855:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sun4i/sun4i_tcon.c:316:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:992:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
--------------------------------------------------------------------------------
nsim_hs_defconfig (arc, gcc-8) — PASS, 0 errors, 5 warnings, 0 section mismatches
Warnings:
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
include/linux/compiler.h:328:5: warning: this statement may fall through [-Wimplicit-fallthrough=]
arch/arc/kernel/unwind.c:827:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
arch/arc/kernel/unwind.c:836:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
--------------------------------------------------------------------------------
x86_64_defconfig (x86_64, gcc-8) — PASS, 0 errors, 0 warnings, 0 section mismatches
---
For more info write to <info@kernelci.org>
^ permalink raw reply
* linusw/devel build: 6 builds: 0 failed, 6 passed, 13 warnings (v5.3-rc1-31-g379ce1ff51aa)
From: kernelci.org bot @ 2019-08-16 23:50 UTC (permalink / raw)
To: linux-gpio, fellows
linusw/devel build: 6 builds: 0 failed, 6 passed, 13 warnings (v5.3-rc1-31-g379ce1ff51aa)
Full Build Summary: https://kernelci.org/build/linusw/branch/devel/kernel/v5.3-rc1-31-g379ce1ff51aa/
Tree: linusw
Branch: devel
Git Describe: v5.3-rc1-31-g379ce1ff51aa
Git Commit: 379ce1ff51aac14405604a45fa6c9bfc77a854e8
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/
Built: 6 unique architectures
Warnings Detected:
arc:
nsim_hs_defconfig (gcc-8): 2 warnings
arm64:
arm:
multi_v7_defconfig (gcc-8): 6 warnings
mips:
32r2el_defconfig (gcc-8): 3 warnings
riscv:
defconfig (gcc-8): 2 warnings
x86_64:
Warnings summary:
7 <stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
1 arch/arm/boot/dts/bcm47094-linksys-panamera.dts:129.4-18: Warning (reg_format): /mdio-bus-mux/mdio@200:reg: property has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
1 arch/arm/boot/dts/bcm47094-linksys-panamera.dts:128.22-132.5: Warning (avoid_default_addr_size): /mdio-bus-mux/mdio@200: Relying on default #size-cells value
1 arch/arm/boot/dts/bcm47094-linksys-panamera.dts:128.22-132.5: Warning (avoid_default_addr_size): /mdio-bus-mux/mdio@200: Relying on default #address-cells value
1 arch/arm/boot/dts/bcm47094-linksys-panamera.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
1 arch/arm/boot/dts/bcm47094-linksys-panamera.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
1 arch/arm/boot/dts/bcm47094-linksys-panamera.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
================================================================================
Detailed per-defconfig build reports:
--------------------------------------------------------------------------------
32r2el_defconfig (mips, gcc-8) — PASS, 0 errors, 3 warnings, 0 section mismatches
Warnings:
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
--------------------------------------------------------------------------------
defconfig (riscv, gcc-8) — PASS, 0 errors, 2 warnings, 0 section mismatches
Warnings:
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
--------------------------------------------------------------------------------
defconfig (arm64, gcc-8) — PASS, 0 errors, 0 warnings, 0 section mismatches
--------------------------------------------------------------------------------
multi_v7_defconfig (arm, gcc-8) — PASS, 0 errors, 6 warnings, 0 section mismatches
Warnings:
arch/arm/boot/dts/bcm47094-linksys-panamera.dts:129.4-18: Warning (reg_format): /mdio-bus-mux/mdio@200:reg: property has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
arch/arm/boot/dts/bcm47094-linksys-panamera.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
arch/arm/boot/dts/bcm47094-linksys-panamera.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
arch/arm/boot/dts/bcm47094-linksys-panamera.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
arch/arm/boot/dts/bcm47094-linksys-panamera.dts:128.22-132.5: Warning (avoid_default_addr_size): /mdio-bus-mux/mdio@200: Relying on default #address-cells value
arch/arm/boot/dts/bcm47094-linksys-panamera.dts:128.22-132.5: Warning (avoid_default_addr_size): /mdio-bus-mux/mdio@200: Relying on default #size-cells value
--------------------------------------------------------------------------------
nsim_hs_defconfig (arc, gcc-8) — PASS, 0 errors, 2 warnings, 0 section mismatches
Warnings:
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
--------------------------------------------------------------------------------
x86_64_defconfig (x86_64, gcc-8) — PASS, 0 errors, 0 warnings, 0 section mismatches
---
For more info write to <info@kernelci.org>
^ permalink raw reply
* linusw/for-next build: 6 builds: 0 failed, 6 passed, 34 warnings (v5.3-rc4-35-g984078b26420)
From: kernelci.org bot @ 2019-08-16 23:32 UTC (permalink / raw)
To: linux-gpio, fellows
linusw/for-next build: 6 builds: 0 failed, 6 passed, 34 warnings (v5.3-rc4-35-g984078b26420)
Full Build Summary: https://kernelci.org/build/linusw/branch/for-next/kernel/v5.3-rc4-35-g984078b26420/
Tree: linusw
Branch: for-next
Git Describe: v5.3-rc4-35-g984078b26420
Git Commit: 984078b264207fc748c1b1d3aede99b0271b3b55
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/
Built: 6 unique architectures
Warnings Detected:
arc:
nsim_hs_defconfig (gcc-8): 5 warnings
arm64:
defconfig (gcc-8): 5 warnings
arm:
multi_v7_defconfig (gcc-8): 21 warnings
mips:
32r2el_defconfig (gcc-8): 3 warnings
riscv:
x86_64:
Warnings summary:
5 <stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
2 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:800:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
2 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:795:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
2 drivers/pinctrl/pinctrl-rockchip.c:2783:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
2 drivers/gpu/drm/sun4i/sun4i_tcon.c:316:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 include/linux/compiler.h:328:5: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/video/fbdev/sh_mobile_lcdcfb.c:2086:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/video/fbdev/sh_mobile_lcdcfb.c:1596:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:459:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:440:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:424:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:370:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:352:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/usb/phy/phy-ab8500-usb.c:332:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/sdhci-s3c.c:613:19: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/atmel-mci.c:2426:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/atmel-mci.c:2422:28: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/mmc/host/atmel-mci.c:2415:30: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/iommu/arm-smmu-v3.c:1189:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:992:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sti/sti_hdmi.c:855:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sti/sti_hdmi.c:853:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/gpu/drm/sti/sti_hdmi.c:851:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 drivers/dma/imx-dma.c:542:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 arch/arc/kernel/unwind.c:836:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
1 arch/arc/kernel/unwind.c:827:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
================================================================================
Detailed per-defconfig build reports:
--------------------------------------------------------------------------------
32r2el_defconfig (mips, gcc-8) — PASS, 0 errors, 3 warnings, 0 section mismatches
Warnings:
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
--------------------------------------------------------------------------------
defconfig (riscv, gcc-8) — PASS, 0 errors, 0 warnings, 0 section mismatches
--------------------------------------------------------------------------------
defconfig (arm64, gcc-8) — PASS, 0 errors, 5 warnings, 0 section mismatches
Warnings:
drivers/iommu/arm-smmu-v3.c:1189:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:795:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:800:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/pinctrl-rockchip.c:2783:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sun4i/sun4i_tcon.c:316:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
--------------------------------------------------------------------------------
multi_v7_defconfig (arm, gcc-8) — PASS, 0 errors, 21 warnings, 0 section mismatches
Warnings:
drivers/dma/imx-dma.c:542:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/sdhci-s3c.c:613:19: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/atmel-mci.c:2415:30: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/atmel-mci.c:2422:28: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/mmc/host/atmel-mci.c:2426:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:795:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c:800:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/pinctrl/pinctrl-rockchip.c:2783:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/video/fbdev/sh_mobile_lcdcfb.c:2086:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/video/fbdev/sh_mobile_lcdcfb.c:1596:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:424:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:440:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:459:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:332:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:352:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/usb/phy/phy-ab8500-usb.c:370:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sti/sti_hdmi.c:851:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sti/sti_hdmi.c:853:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sti/sti_hdmi.c:855:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sun4i/sun4i_tcon.c:316:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:992:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
--------------------------------------------------------------------------------
nsim_hs_defconfig (arc, gcc-8) — PASS, 0 errors, 5 warnings, 0 section mismatches
Warnings:
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
include/linux/compiler.h:328:5: warning: this statement may fall through [-Wimplicit-fallthrough=]
arch/arc/kernel/unwind.c:827:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
arch/arc/kernel/unwind.c:836:20: warning: this statement may fall through [-Wimplicit-fallthrough=]
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
--------------------------------------------------------------------------------
x86_64_defconfig (x86_64, gcc-8) — PASS, 0 errors, 0 warnings, 0 section mismatches
---
For more info write to <info@kernelci.org>
^ permalink raw reply
* Re: [PATCH] gpio: of: fix Freescale SPI CS quirk handling
From: Linus Walleij @ 2019-08-16 22:29 UTC (permalink / raw)
To: Andreas Kemnade
Cc: Bartosz Golaszewski, open list:GPIO SUBSYSTEM,
linux-kernel@vger.kernel.org, Discussions about the Letux Kernel,
linux-spi, H . Nikolaus Schaller
In-Reply-To: <20190816165000.32334-1-andreas@kemnade.info>
On Fri, Aug 16, 2019 at 6:50 PM Andreas Kemnade <andreas@kemnade.info> wrote:
> On the gta04 we see:
> spi_gpio: probe of spi_lcd failed with error -2
>
> The quirk introduced in
> commit e3023bf80639 ("gpio: of: Handle the Freescale SPI CS")
> can also be triggered by a temporary -EPROBE_DEFER and
> so "convert" it to a hard -ENOENT.
>
> Disable that conversion by checking for -EPROBE_DEFER.
>
> Fixes: e3023bf80639 ("gpio: of: Handle the Freescale SPI CS")
> Suggested-by: H. Nikolaus Schaller <hns@goldelico.com>
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Good catch! Patch applied for fixes.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 1/3] include: linux: i2c: more helpers for declaring i2c drivers
From: Wolfram Sang @ 2019-08-16 19:56 UTC (permalink / raw)
To: Enrico Weigelt, metux IT consult
Cc: Enrico Weigelt, metux IT consult, linux-kernel, linus.walleij,
bgolaszewski, linux-gpio, linux-i2c
In-Reply-To: <205d0ef7-d487-006b-d104-88958f40e197@metux.net>
[-- Attachment #1: Type: text/plain, Size: 581 bytes --]
(Found this mail in the offline draft folder of another laptop)
> So, then the current approach of using subsys_initcall() can't be
> changed easily, right now. But planned for the future (or at least
> not introducing new caes).
Yes.
> But: how does that conflict w/ just moving the existing redundant
> pieces into a helper macro ? The logic stays the same - just using
> a shorter notation. (assuming my patch isn't buggy ;-)).
It is not conflicting. My thinking is that such helpers, in general,
scale better and are less error prone. But there is nothing to scale
here.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH v9 01/22] pinctrl: tegra: Fix write barrier placement in pmx_writel
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
pmx_writel uses writel which inserts write barrier before the
register write.
This patch has fix to replace writel with writel_relaxed followed
by a readback and memory barrier to ensure write operation is
completed for successful pinctrl change.
Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/pinctrl/tegra/pinctrl-tegra.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
index e3a237534281..5e3c00137d71 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
@@ -32,7 +32,9 @@ static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
{
- writel(val, pmx->regs[bank] + reg);
+ writel_relaxed(val, pmx->regs[bank] + reg);
+ /* make sure pinmux register write completed */
+ pmx_readl(pmx, bank, reg);
}
static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
--
2.7.4
^ permalink raw reply related
* [PATCH v9 04/22] clk: tegra: pllout: Save and restore pllout context
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch implements save and restore of pllout context.
During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.
So during suspend entry the state of pllout is saved and on resume
it is restored back to have pllout in same state as before suspend.
pllout rate is saved and restore in clock divider so it will be at
same rate as before suspend when pllout state is restored.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-pll-out.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c
index 35f2bf00e1e6..d8bf89a81e6d 100644
--- a/drivers/clk/tegra/clk-pll-out.c
+++ b/drivers/clk/tegra/clk-pll-out.c
@@ -69,10 +69,19 @@ static void clk_pll_out_disable(struct clk_hw *hw)
spin_unlock_irqrestore(pll_out->lock, flags);
}
+static void tegra_clk_pll_out_restore_context(struct clk_hw *hw)
+{
+ if (!__clk_get_enable_count(hw->clk))
+ clk_pll_out_disable(hw);
+ else
+ clk_pll_out_enable(hw);
+}
+
const struct clk_ops tegra_clk_pll_out_ops = {
.is_enabled = clk_pll_out_is_enabled,
.enable = clk_pll_out_enable,
.disable = clk_pll_out_disable,
+ .restore_context = tegra_clk_pll_out_restore_context,
};
struct clk *tegra_clk_register_pll_out(const char *name,
--
2.7.4
^ permalink raw reply related
* [PATCH v9 00/22] SC7 entry and exit support for Tegra210
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
This patch series includes Tegra210 deepsleep (SC7) support with RTC alarm
wake event.
This series also includes save and restore of PLLs, clocks, OSC contexts
for deepsleep exit to normal operation.
This patch series doesn't support 100% suspend/resume to allow fully
functional state upon resume and we are working on some more drivers suspend
and resume implementations.
[V9]: Changed betweenv8 & v9 are
- v8 feedback fixes
Note:
Below patch is also needed for SC7 support as GPIO restore need
to happen prior to pinctrl.
https://patchwork.kernel.org/patch/11012077/
[v8]: Changes between v7 & v8 are
- v7 feedback fixes
- moved clock enable/disable state and reset enable/disable state
restore from clk_save/restore_context back to clk-tegra210 driver
to do complete register value store/restore.
- Removed manual store/restore of peripheral parent context and added
API in clk core to retrieve clock parent index to use during
restoring parent on resume.
- Implemented Tegra recommended clock source programming sequence
during restore (CLK ENB ON followed by divider/source programming
followed by restoring CLK ENB ON/OFF state followed by restoring
RST state).
- Removed pinctrl suspend/resume patch from this series as pinctrl
suspend/resume patch from v7 got acked and merged.
- Added pinctrl patch-0001 to update pmx_writel for proper placement
of write barrier.
- Added pinctrl patch-0002 to insert write barrier after all pinctrl
register writes during pinctrl resume.
Note:
Below patch is also needed for SC7 support as GPIO restore need
to happen prior to pinctrl.
https://patchwork.kernel.org/patch/11012077/
[v7]: Changes between V6 & v7 are
- V6 feedback fixes
- Removed patch-0001 from V6 which keeps COP IRQ enabled. Looking
more into ATF FW, it loads SC7 entry FW into IRAM and sets the
COP reset vector to SC7 FW load address and resets COP. So, COP
IRQ can be cleared during suspend.
Note:
Below patch is also needed for SC7 support as GPIO restore need
to happen prior to pinctrl.
https://patchwork.kernel.org/patch/11012077/
[V6]: Changes between V5 & V6 are
- V5 feedback fixes
- DFLL suspend and resume moved to DFLL clock driver
- Add suspend and resume support for CPUFreq driver to explicitly
switch source to safe source of PLLP and disable DFLL clock.
- Fix to super clock driver to enable PLLP branch to CPU before
source switch to PLLP.
- Added save and restore support for super clock driver.
[V5]: Changes between V4 & V5 are
- V4 feedback fixes
[V4]: Changes between V3 & V4 are
- V3 feedback fixes
- Removed park bits clear for EMMC pads in pinctrl-tegra driver
function tegra_pinctrl_clear_parked_bits as based on V3 feedback
parked_bit is updated to parked_bitmask to use with DRV_PINGROUP
as well and thierry posted patch series for this.
- Implemented all peripheral clocks save and restore through their
corresponding clk_ops save_context and restore_context and removed
all direct registers store and restore in clk-tegra210 driver.
- Created separate patch for fence_delay update during PLLU init based
on V3 feedback.
- Added more comments in tegra210_clk_resume regarding dfll restore
sequence and its dependency on peripheral clocks restore.
[V3]: Changes between V2 & V3 are
- V2 feedback fixes
- GPIO restore should happen prior to Pinctrl restore to prevent
glitch on GPIO lines. So using resume_noirq for gpio tegra to allow
gpio resume prior to pinctrl resume.
- Implemented save_context and restore_context callbacks for clock
plls, pll outs and dividers in corresponding drivers.
Note: Peripheral clocks and clock enable and reset need to be in
Tegra210 clock suspend/resume as they need to be in proper sequence
w.r.t DFLL resume for restoring CPU clock.
- Removed gpio-tegra changes for hierarchical support to have PMC as
parent to GPIOs for GPIO wake event support. Thierry is working on
gpiolib for some cleanup before adding hierarchical support. So
holding on to GPIO wake support for now.
[V2] : V1 feedback fixes
Patch 0002: This version still using syscore. Thierry suggest not to
use syscore and waiting on suggestion from Linux Walleij for any better
way of storing current state of pins before suspend entry and restoring
them on resume at very early stage. So left this the same way as V1 and
will address once I get more feedback on this.
Also need to findout and implement proper way of forcing resume order
between pinctrl and gpio driver.
[V1]: Tegra210 SC7 entry and exit thru RTC wake and Power button GPIO wake
using hierarchical IRQ with PMC as parent to GPIO.
Sowjanya Komatineni (22):
pinctrl: tegra: Fix write barrier placement in pmx_writel
pinctrl: tegra: Flush pinctrl writes during resume
clk: tegra: divider: Save and restore divider rate
clk: tegra: pllout: Save and restore pllout context
clk: tegra: pll: Save and restore pll context
clk: tegra: Support for OSC context save and restore
clk: Add API to get index of the clock parent
clk: tegra: periph: Add restore_context support
clk: tegra: clk-super: Fix to enable PLLP branches to CPU
clk: tegra: clk-super: Add restore-context support
clk: tegra: clk-dfll: Add suspend and resume support
cpufreq: tegra124: Add suspend and resume support
clk: tegra210: Use fence_udelay during PLLU init
clk: tegra: Share clk and rst register defines with Tegra clock driver
clk: tegra210: Add suspend and resume support
soc/tegra: pmc: Allow to support more tegras wake
soc/tegra: pmc: Add pmc wake support for tegra210
arm64: tegra: Enable wake from deep sleep on RTC alarm
soc/tegra: pmc: Configure core power request polarity
soc/tegra: pmc: Configure deep sleep control settings
arm64: dts: tegra210-p2180: Jetson TX1 SC7 timings
arm64: dts: tegra210-p3450: Jetson Nano SC7 timings
arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 7 ++
arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts | 7 ++
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 5 +-
drivers/clk/clk.c | 17 +++
drivers/clk/tegra/clk-dfll.c | 56 +++++++++
drivers/clk/tegra/clk-dfll.h | 2 +
drivers/clk/tegra/clk-divider.c | 11 ++
drivers/clk/tegra/clk-periph.c | 18 +++
drivers/clk/tegra/clk-pll-out.c | 9 ++
drivers/clk/tegra/clk-pll.c | 86 +++++++++-----
drivers/clk/tegra/clk-sdmmc-mux.c | 12 ++
drivers/clk/tegra/clk-super.c | 35 ++++++
drivers/clk/tegra/clk-tegra-fixed.c | 15 +++
drivers/clk/tegra/clk-tegra-super-gen4.c | 7 +-
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 1 +
drivers/clk/tegra/clk-tegra210.c | 104 +++++++++++++++--
drivers/clk/tegra/clk.c | 112 +++++++++++-------
drivers/clk/tegra/clk.h | 67 +++++++++++
drivers/cpufreq/tegra124-cpufreq.c | 59 ++++++++++
drivers/pinctrl/tegra/pinctrl-tegra.c | 8 +-
drivers/soc/tegra/pmc.c | 130 ++++++++++++++++++++-
include/linux/clk-provider.h | 1 +
22 files changed, 677 insertions(+), 92 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v9 06/22] clk: tegra: Support for OSC context save and restore
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch adds support for saving OSC clock frequency and the
drive-strength during OSC clock init and creates an API to restore
OSC control register value from the saved context.
This API is invoked by Tegra210 clock driver during system resume
to restore the OSC clock settings.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-tegra-fixed.c | 15 +++++++++++++++
drivers/clk/tegra/clk.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c
index 8d91b2b191cf..7c6c8abfcde6 100644
--- a/drivers/clk/tegra/clk-tegra-fixed.c
+++ b/drivers/clk/tegra/clk-tegra-fixed.c
@@ -17,6 +17,10 @@
#define OSC_CTRL 0x50
#define OSC_CTRL_OSC_FREQ_SHIFT 28
#define OSC_CTRL_PLL_REF_DIV_SHIFT 26
+#define OSC_CTRL_MASK (0x3f2 | \
+ (0xf << OSC_CTRL_OSC_FREQ_SHIFT))
+
+static u32 osc_ctrl_ctx;
int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
unsigned long *input_freqs, unsigned int num,
@@ -29,6 +33,7 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
unsigned osc_idx;
val = readl_relaxed(clk_base + OSC_CTRL);
+ osc_ctrl_ctx = val & OSC_CTRL_MASK;
osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT;
if (osc_idx < num)
@@ -96,3 +101,13 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks)
*dt_clk = clk;
}
}
+
+void tegra_clk_osc_resume(void __iomem *clk_base)
+{
+ u32 val;
+
+ val = readl_relaxed(clk_base + OSC_CTRL) & ~OSC_CTRL_MASK;
+ val |= osc_ctrl_ctx;
+ writel_relaxed(val, clk_base + OSC_CTRL);
+ fence_udelay(2, clk_base);
+}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 905bf1096558..cbbca28bf7e4 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -829,6 +829,7 @@ u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
u8 frac_width, u8 flags);
+void tegra_clk_osc_resume(void __iomem *clk_base);
/* Combined read fence with delay */
--
2.7.4
^ permalink raw reply related
* [PATCH v9 05/22] clk: tegra: pll: Save and restore pll context
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch implements save and restore of PLL context.
During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.
So during resume, pll context is restored based on cached rate
and state.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-pll.c | 86 ++++++++++++++++++++++++++++-----------------
1 file changed, 54 insertions(+), 32 deletions(-)
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 1583f5fc992f..531c2b3d814e 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -1008,6 +1008,27 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
return rate;
}
+static void tegra_clk_pll_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ unsigned long parent_rate = clk_hw_get_rate(parent);
+ unsigned long rate = clk_hw_get_rate(hw);
+
+ if (clk_pll_is_enabled(hw))
+ return;
+
+ if (pll->params->set_defaults)
+ pll->params->set_defaults(pll);
+
+ clk_pll_set_rate(hw, rate, parent_rate);
+
+ if (!__clk_get_enable_count(hw->clk))
+ clk_pll_disable(hw);
+ else
+ clk_pll_enable(hw);
+}
+
const struct clk_ops tegra_clk_pll_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_pll_enable,
@@ -1015,6 +1036,7 @@ const struct clk_ops tegra_clk_pll_ops = {
.recalc_rate = clk_pll_recalc_rate,
.round_rate = clk_pll_round_rate,
.set_rate = clk_pll_set_rate,
+ .restore_context = tegra_clk_pll_restore_context,
};
const struct clk_ops tegra_clk_plle_ops = {
@@ -1802,6 +1824,27 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw)
return ret;
}
+
+static void _clk_plle_tegra_init_parent(struct tegra_clk_pll *pll)
+{
+ u32 val, val_aux;
+
+ /* ensure parent is set to pll_ref */
+ val = pll_readl_base(pll);
+ val_aux = pll_readl(pll->params->aux_reg, pll);
+
+ if (val & PLL_BASE_ENABLE) {
+ if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
+ (val_aux & PLLE_AUX_PLLP_SEL))
+ WARN(1, "pll_e enabled with unsupported parent %s\n",
+ (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
+ "pll_re_vco");
+ } else {
+ val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
+ pll_writel(val_aux, pll->params->aux_reg, pll);
+ fence_udelay(1, pll->clk_base);
+ }
+}
#endif
static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
@@ -2214,27 +2257,12 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
{
struct tegra_clk_pll *pll;
struct clk *clk;
- u32 val, val_aux;
pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
- /* ensure parent is set to pll_re_vco */
-
- val = pll_readl_base(pll);
- val_aux = pll_readl(pll_params->aux_reg, pll);
-
- if (val & PLL_BASE_ENABLE) {
- if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
- (val_aux & PLLE_AUX_PLLP_SEL))
- WARN(1, "pll_e enabled with unsupported parent %s\n",
- (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
- "pll_re_vco");
- } else {
- val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
- pll_writel(val_aux, pll_params->aux_reg, pll);
- }
+ _clk_plle_tegra_init_parent(pll);
clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
&tegra_clk_plle_tegra114_ops);
@@ -2276,6 +2304,7 @@ static const struct clk_ops tegra_clk_pllss_ops = {
.recalc_rate = clk_pll_recalc_rate,
.round_rate = clk_pll_ramp_round_rate,
.set_rate = clk_pllxc_set_rate,
+ .restore_context = tegra_clk_pll_restore_context,
};
struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
@@ -2520,11 +2549,19 @@ static void clk_plle_tegra210_disable(struct clk_hw *hw)
spin_unlock_irqrestore(pll->lock, flags);
}
+static void tegra_clk_plle_t210_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+
+ _clk_plle_tegra_init_parent(pll);
+}
+
static const struct clk_ops tegra_clk_plle_tegra210_ops = {
.is_enabled = clk_plle_tegra210_is_enabled,
.enable = clk_plle_tegra210_enable,
.disable = clk_plle_tegra210_disable,
.recalc_rate = clk_pll_recalc_rate,
+ .restore_context = tegra_clk_plle_t210_restore_context,
};
struct clk *tegra_clk_register_plle_tegra210(const char *name,
@@ -2535,27 +2572,12 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
{
struct tegra_clk_pll *pll;
struct clk *clk;
- u32 val, val_aux;
pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
- /* ensure parent is set to pll_re_vco */
-
- val = pll_readl_base(pll);
- val_aux = pll_readl(pll_params->aux_reg, pll);
-
- if (val & PLLE_BASE_ENABLE) {
- if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
- (val_aux & PLLE_AUX_PLLP_SEL))
- WARN(1, "pll_e enabled with unsupported parent %s\n",
- (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
- "pll_re_vco");
- } else {
- val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
- pll_writel(val_aux, pll_params->aux_reg, pll);
- }
+ _clk_plle_tegra_init_parent(pll);
clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
&tegra_clk_plle_tegra210_ops);
--
2.7.4
^ permalink raw reply related
* [PATCH v9 03/22] clk: tegra: divider: Save and restore divider rate
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch implements context restore for clock divider.
During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.
So on resume, clock dividers are restored back for normal operation.
Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-divider.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index e76731fb7d69..ca0de5f11f84 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -109,10 +109,21 @@ static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
+static void clk_divider_restore_context(struct clk_hw *hw)
+{
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ unsigned long parent_rate = clk_hw_get_rate(parent);
+ unsigned long rate = clk_hw_get_rate(hw);
+
+ if (clk_frac_div_set_rate(hw, rate, parent_rate) < 0)
+ WARN_ON(1);
+}
+
const struct clk_ops tegra_clk_frac_div_ops = {
.recalc_rate = clk_frac_div_recalc_rate,
.set_rate = clk_frac_div_set_rate,
.round_rate = clk_frac_div_round_rate,
+ .restore_context = clk_divider_restore_context,
};
struct clk *tegra_clk_register_divider(const char *name,
--
2.7.4
^ permalink raw reply related
* [PATCH v9 08/22] clk: tegra: periph: Add restore_context support
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch implements restore_context support for clk-periph and
clk-sdmmc-mux clock operations to restore clock parent and rates
on system resume.
During system suspend, core power goes off and looses the context
of the Tegra clock controller registers.
So on system resume, clocks parent and rate are restored back to
the context before suspend based on cached data.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-periph.c | 18 ++++++++++++++++++
drivers/clk/tegra/clk-sdmmc-mux.c | 12 ++++++++++++
2 files changed, 30 insertions(+)
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 58437da25156..c9d28cbadccc 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -3,6 +3,7 @@
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
*/
+#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/export.h>
#include <linux/slab.h>
@@ -99,6 +100,20 @@ static void clk_periph_disable(struct clk_hw *hw)
gate_ops->disable(gate_hw);
}
+static void clk_periph_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_periph *periph = to_clk_periph(hw);
+ const struct clk_ops *div_ops = periph->div_ops;
+ struct clk_hw *div_hw = &periph->divider.hw;
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ int parent_id = clk_hw_get_parent_index(hw, parent);
+
+ if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV))
+ div_ops->restore_context(div_hw);
+
+ clk_periph_set_parent(hw, parent_id);
+}
+
const struct clk_ops tegra_clk_periph_ops = {
.get_parent = clk_periph_get_parent,
.set_parent = clk_periph_set_parent,
@@ -108,6 +123,7 @@ const struct clk_ops tegra_clk_periph_ops = {
.is_enabled = clk_periph_is_enabled,
.enable = clk_periph_enable,
.disable = clk_periph_disable,
+ .restore_context = clk_periph_restore_context,
};
static const struct clk_ops tegra_clk_periph_nodiv_ops = {
@@ -116,6 +132,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
.is_enabled = clk_periph_is_enabled,
.enable = clk_periph_enable,
.disable = clk_periph_disable,
+ .restore_context = clk_periph_restore_context,
};
static const struct clk_ops tegra_clk_periph_no_gate_ops = {
@@ -124,6 +141,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = {
.recalc_rate = clk_periph_recalc_rate,
.round_rate = clk_periph_round_rate,
.set_rate = clk_periph_set_rate,
+ .restore_context = clk_periph_restore_context,
};
static struct clk *_tegra_clk_register_periph(const char *name,
diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c
index a5cd3e31dbae..8db48966b100 100644
--- a/drivers/clk/tegra/clk-sdmmc-mux.c
+++ b/drivers/clk/tegra/clk-sdmmc-mux.c
@@ -194,6 +194,17 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw)
gate_ops->disable(gate_hw);
}
+static void clk_sdmmc_mux_restore_context(struct clk_hw *hw)
+{
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ unsigned long parent_rate = clk_hw_get_rate(parent);
+ unsigned long rate = clk_hw_get_rate(hw);
+ int parent_id = clk_hw_get_parent_index(hw, parent);
+
+ clk_sdmmc_mux_set_parent(hw, parent_id);
+ clk_sdmmc_mux_set_rate(hw, rate, parent_rate);
+}
+
static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
.get_parent = clk_sdmmc_mux_get_parent,
.set_parent = clk_sdmmc_mux_set_parent,
@@ -203,6 +214,7 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
.is_enabled = clk_sdmmc_mux_is_enabled,
.enable = clk_sdmmc_mux_enable,
.disable = clk_sdmmc_mux_disable,
+ .restore_context = clk_sdmmc_mux_restore_context,
};
struct clk *tegra_clk_register_sdmmc_mux_div(const char *name,
--
2.7.4
^ permalink raw reply related
* [PATCH v9 10/22] clk: tegra: clk-super: Add restore-context support
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch implements restore_context for clk_super_mux and clk_super.
During system supend, core power goes off the and context of Tegra
CAR registers is lost.
So on system resume, context of super clock registers are restored
to have them in same state as before suspend.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-super.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index e2a1e95a8db7..74c9e913e41c 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -124,9 +124,18 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index)
return err;
}
+static void clk_super_mux_restore_context(struct clk_hw *hw)
+{
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ int parent_id = clk_hw_get_parent_index(hw, parent);
+
+ clk_super_set_parent(hw, parent_id);
+}
+
static const struct clk_ops tegra_clk_super_mux_ops = {
.get_parent = clk_super_get_parent,
.set_parent = clk_super_set_parent,
+ .restore_context = clk_super_mux_restore_context,
};
static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -162,12 +171,24 @@ static int clk_super_set_rate(struct clk_hw *hw, unsigned long rate,
return super->div_ops->set_rate(div_hw, rate, parent_rate);
}
+static void clk_super_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
+ struct clk_hw *div_hw = &super->frac_div.hw;
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ int parent_id = clk_hw_get_parent_index(hw, parent);
+
+ super->div_ops->restore_context(div_hw);
+ clk_super_set_parent(hw, parent_id);
+}
+
const struct clk_ops tegra_clk_super_ops = {
.get_parent = clk_super_get_parent,
.set_parent = clk_super_set_parent,
.set_rate = clk_super_set_rate,
.round_rate = clk_super_round_rate,
.recalc_rate = clk_super_recalc_rate,
+ .restore_context = clk_super_restore_context,
};
struct clk *tegra_clk_register_super_mux(const char *name,
--
2.7.4
^ permalink raw reply related
* [PATCH v9 09/22] clk: tegra: clk-super: Fix to enable PLLP branches to CPU
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch has a fix to enable PLLP branches to CPU before changing
the CPU cluster clock source to PLLP for Gen5 Super clock and
disables PLLP branches to CPU when not in use.
During system suspend entry and exit, CPU source will be switched
to PLLP and this needs PLLP branches to be enabled to CPU prior to
the switch.
On system resume, warmboot code enables PLLP branches to CPU and
powers up the CPU with PLLP clock source.
Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-super.c | 14 ++++++++++++++
drivers/clk/tegra/clk-tegra-super-gen4.c | 7 ++++++-
drivers/clk/tegra/clk.c | 14 ++++++++++++++
drivers/clk/tegra/clk.h | 5 +++++
4 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index 39ef31b46df5..e2a1e95a8db7 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -28,6 +28,9 @@
#define super_state_to_src_shift(m, s) ((m->width * s))
#define super_state_to_src_mask(m) (((1 << m->width) - 1))
+#define CCLK_SRC_PLLP_OUT0 4
+#define CCLK_SRC_PLLP_OUT4 5
+
static u8 clk_super_get_parent(struct clk_hw *hw)
{
struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
@@ -97,12 +100,23 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index)
if (index == mux->div2_index)
index = mux->pllx_index;
}
+
+ /* enable PLLP branches to CPU before selecting PLLP source */
+ if ((mux->flags & TEGRA210_CPU_CLK) &&
+ (index == CCLK_SRC_PLLP_OUT0 || index == CCLK_SRC_PLLP_OUT4))
+ tegra_clk_set_pllp_out_cpu(true);
+
val &= ~((super_state_to_src_mask(mux)) << shift);
val |= (index & (super_state_to_src_mask(mux))) << shift;
writel_relaxed(val, mux->reg);
udelay(2);
+ /* disable PLLP branches to CPU if not used */
+ if ((mux->flags & TEGRA210_CPU_CLK) &&
+ index != CCLK_SRC_PLLP_OUT0 && index != CCLK_SRC_PLLP_OUT4)
+ tegra_clk_set_pllp_out_cpu(false);
+
out:
if (mux->lock)
spin_unlock_irqrestore(mux->lock, flags);
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index cdfe7c9697e1..5760c978bef7 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -180,7 +180,7 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
gen_info->num_cclk_g_parents,
CLK_SET_RATE_PARENT,
clk_base + CCLKG_BURST_POLICY,
- 0, 4, 8, 0, NULL);
+ TEGRA210_CPU_CLK, 4, 8, 0, NULL);
} else {
clk = tegra_clk_register_super_mux("cclk_g",
gen_info->cclk_g_parents,
@@ -196,6 +196,11 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks);
if (dt_clk) {
if (gen_info->gen == gen5) {
+ /*
+ * TEGRA210_CPU_CLK flag is not needed for cclk_lp as
+ * cluster switching is not currently supported on
+ * Tegra210 and also cpu_lp is not used.
+ */
clk = tegra_clk_register_super_mux("cclk_lp",
gen_info->cclk_lp_parents,
gen_info->num_cclk_lp_parents,
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index 573e3c967ae1..eb08047fd02f 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -23,6 +23,7 @@
#define CLK_OUT_ENB_W 0x364
#define CLK_OUT_ENB_X 0x280
#define CLK_OUT_ENB_Y 0x298
+#define CLK_ENB_PLLP_OUT_CPU BIT(31)
#define CLK_OUT_ENB_SET_L 0x320
#define CLK_OUT_ENB_CLR_L 0x324
#define CLK_OUT_ENB_SET_H 0x328
@@ -199,6 +200,19 @@ const struct tegra_clk_periph_regs *get_reg_bank(int clkid)
}
}
+void tegra_clk_set_pllp_out_cpu(bool enable)
+{
+ u32 val;
+
+ val = readl_relaxed(clk_base + CLK_OUT_ENB_Y);
+ if (enable)
+ val |= CLK_ENB_PLLP_OUT_CPU;
+ else
+ val &= ~CLK_ENB_PLLP_OUT_CPU;
+
+ writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
+}
+
struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
{
clk_base = regs;
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index cbbca28bf7e4..55c4b78280be 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -669,6 +669,9 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
* Flags:
* TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
* that this is LP cluster clock.
+ * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5
+ * super mux parent using PLLP branches. To use PLLP branches to CPU, need
+ * to configure additional bit PLLP_OUT_CPU in the clock registers.
*/
struct tegra_clk_super_mux {
struct clk_hw hw;
@@ -685,6 +688,7 @@ struct tegra_clk_super_mux {
#define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
#define TEGRA_DIVIDER_2 BIT(0)
+#define TEGRA210_CPU_CLK BIT(1)
extern const struct clk_ops tegra_clk_super_ops;
struct clk *tegra_clk_register_super_mux(const char *name,
@@ -830,6 +834,7 @@ int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
u8 frac_width, u8 flags);
void tegra_clk_osc_resume(void __iomem *clk_base);
+void tegra_clk_set_pllp_out_cpu(bool enable);
/* Combined read fence with delay */
--
2.7.4
^ permalink raw reply related
* [PATCH v9 11/22] clk: tegra: clk-dfll: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch implements DFLL suspend and resume operation.
During system suspend entry, CPU clock will switch CPU to safe
clock source of PLLP and disables DFLL clock output.
DFLL driver suspend confirms DFLL disable state and errors out on
being active.
DFLL is re-initialized during the DFLL driver resume as it goes
through complete reset during suspend entry.
Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-dfll.c | 56 ++++++++++++++++++++++++++++++
drivers/clk/tegra/clk-dfll.h | 2 ++
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 1 +
3 files changed, 59 insertions(+)
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
index f8688c2ddf1a..c051d92c2bbf 100644
--- a/drivers/clk/tegra/clk-dfll.c
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -1487,6 +1487,7 @@ static int dfll_init(struct tegra_dfll *td)
td->last_unrounded_rate = 0;
pm_runtime_enable(td->dev);
+ pm_runtime_irq_safe(td->dev);
pm_runtime_get_sync(td->dev);
dfll_set_mode(td, DFLL_DISABLED);
@@ -1513,6 +1514,61 @@ static int dfll_init(struct tegra_dfll *td)
return ret;
}
+/**
+ * tegra_dfll_suspend - check DFLL is disabled
+ * @dev: DFLL device *
+ *
+ * DFLL clock should be disabled by the CPUFreq driver. So, make
+ * sure it is disabled and disable all clocks needed by the DFLL.
+ */
+int tegra_dfll_suspend(struct device *dev)
+{
+ struct tegra_dfll *td = dev_get_drvdata(dev);
+
+ if (dfll_is_running(td)) {
+ dev_err(td->dev, "DFLL still enabled while suspending\n");
+ return -EBUSY;
+ }
+
+ reset_control_assert(td->dvco_rst);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dfll_suspend);
+
+/**
+ * tegra_dfll_resume - reinitialize DFLL on resume
+ * @dev: DFLL instance
+ *
+ * DFLL is disabled and reset during suspend and resume.
+ * So, reinitialize the DFLL IP block back for use.
+ * DFLL clock is enabled later in closed loop mode by CPUFreq
+ * driver before switching its clock source to DFLL output.
+ */
+int tegra_dfll_resume(struct device *dev)
+{
+ struct tegra_dfll *td = dev_get_drvdata(dev);
+
+ reset_control_deassert(td->dvco_rst);
+
+ pm_runtime_get_sync(td->dev);
+
+ dfll_set_mode(td, DFLL_DISABLED);
+ dfll_set_default_params(td);
+
+ if (td->soc->init_clock_trimmers)
+ td->soc->init_clock_trimmers();
+
+ dfll_set_open_loop_config(td);
+
+ dfll_init_out_if(td);
+
+ pm_runtime_put_sync(td->dev);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dfll_resume);
+
/*
* DT data fetch
*/
diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h
index 1b14ebe7268b..fb209eb5f365 100644
--- a/drivers/clk/tegra/clk-dfll.h
+++ b/drivers/clk/tegra/clk-dfll.h
@@ -42,5 +42,7 @@ int tegra_dfll_register(struct platform_device *pdev,
struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev);
int tegra_dfll_runtime_suspend(struct device *dev);
int tegra_dfll_runtime_resume(struct device *dev);
+int tegra_dfll_suspend(struct device *dev);
+int tegra_dfll_resume(struct device *dev);
#endif /* __DRIVERS_CLK_TEGRA_CLK_DFLL_H */
diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
index e84b6d52cbbd..2ac2679d696d 100644
--- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
+++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
@@ -631,6 +631,7 @@ static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra124_dfll_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend,
tegra_dfll_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(tegra_dfll_suspend, tegra_dfll_resume)
};
static struct platform_driver tegra124_dfll_fcpu_driver = {
--
2.7.4
^ permalink raw reply related
* [PATCH v9 12/22] cpufreq: tegra124: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>
This patch adds suspend and resume pm ops for cpufreq driver.
PLLP is the safe clock source for CPU during system suspend and
resume as PLLP rate is below the CPU Fmax at Vmin.
CPUFreq driver suspend switches the CPU clock source to PLLP and
disables the DFLL clock.
During system resume, warmboot code powers up the CPU with PLLP
clock source. So CPUFreq driver resume enabled DFLL clock and
switches CPU back to DFLL clock source.
Acked-by: Thierry Reding <treding@nvidia.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/cpufreq/tegra124-cpufreq.c | 59 ++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/drivers/cpufreq/tegra124-cpufreq.c b/drivers/cpufreq/tegra124-cpufreq.c
index 4f0c637b3b49..7a1ea6fdcab6 100644
--- a/drivers/cpufreq/tegra124-cpufreq.c
+++ b/drivers/cpufreq/tegra124-cpufreq.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/clk.h>
+#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -128,8 +129,66 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
return ret;
}
+static int __maybe_unused tegra124_cpufreq_suspend(struct device *dev)
+{
+ struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+ int err;
+
+ /*
+ * PLLP rate 408Mhz is below the CPU Fmax at Vmin and is safe to
+ * use during suspend and resume. So, switch the CPU clock source
+ * to PLLP and disable DFLL.
+ */
+ err = clk_set_parent(priv->cpu_clk, priv->pllp_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to reparent to PLLP: %d\n", err);
+ return err;
+ }
+
+ clk_disable_unprepare(priv->dfll_clk);
+
+ return 0;
+}
+
+static int __maybe_unused tegra124_cpufreq_resume(struct device *dev)
+{
+ struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+ int err;
+
+ /*
+ * Warmboot code powers up the CPU with PLLP clock source.
+ * Enable DFLL clock and switch CPU clock source back to DFLL.
+ */
+ err = clk_prepare_enable(priv->dfll_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to enable DFLL clock for CPU: %d\n", err);
+ goto disable_cpufreq;
+ }
+
+ err = clk_set_parent(priv->cpu_clk, priv->dfll_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to reparent to DFLL clock: %d\n", err);
+ goto disable_dfll;
+ }
+
+ return 0;
+
+disable_dfll:
+ clk_disable_unprepare(priv->dfll_clk);
+disable_cpufreq:
+ disable_cpufreq();
+
+ return err;
+}
+
+static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
+ tegra124_cpufreq_resume)
+};
+
static struct platform_driver tegra124_cpufreq_platdrv = {
.driver.name = "cpufreq-tegra124",
+ .driver.pm = &tegra124_cpufreq_pm_ops,
.probe = tegra124_cpufreq_probe,
};
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox