All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@siemens.com>
To: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Linus Walleij <linus.walleij@linaro.org>,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-gpio@vger.kernel.org, linux-acpi@vger.kernel.org,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Subject: Re: [PATCH 2/2] gpio: sch: Add interrupt support
Date: Wed, 24 Apr 2019 10:12:42 +0200	[thread overview]
Message-ID: <8999d3f8-d169-eb85-bd2f-08c99d184ea2@siemens.com> (raw)
In-Reply-To: <20190424075816.GU2654@lahna.fi.intel.com>

On 24.04.19 09:58, Mika Westerberg wrote:
> +Rafael and linux-acpi.
> 
> On Thu, Apr 18, 2019 at 11:23:49AM +0200, Jan Kiszka wrote:
>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>
>> Validated on the Quark platform, this adds interrupt support on rising
>> and/or falling edges.
> 
> The irqchip parts look good to me but but the ACPI SCI handling seems
> weird. This is typically handled by ACPI core based on the values read
> from FADT ACPI table. What does it contain on this Quark platform?

There is no FADT on the original Quark firmware, nor did we add one. As we are 
talking about existing devices, possibly not only Quarks, I was going down the 
ACPI-independent way to hook into the interrupt. But I'm open to learn about 
better alternatives.

Jan

> 
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>   drivers/gpio/gpio-sch.c | 142 +++++++++++++++++++++++++++++++++++++++++++++---
>>   1 file changed, 135 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
>> index fb143f28c386..9459f1920996 100644
>> --- a/drivers/gpio/gpio-sch.c
>> +++ b/drivers/gpio/gpio-sch.c
>> @@ -18,12 +18,17 @@
>>   #define GEN	0x00
>>   #define GIO	0x04
>>   #define GLV	0x08
>> +#define GTPE	0x0c
>> +#define GTNE	0x10
>> +#define GGPE	0x14
>> +#define GTS	0x1c
>>   
>>   struct sch_gpio {
>>   	struct gpio_chip chip;
>>   	spinlock_t lock;
>>   	unsigned short iobase;
>>   	unsigned short resume_base;
>> +	int irq_base;
>>   };
>>   
>>   static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
>> @@ -79,10 +84,11 @@ static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg,
>>   static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
>>   {
>>   	struct sch_gpio *sch = gpiochip_get_data(gc);
>> +	unsigned long flags;
>>   
>> -	spin_lock(&sch->lock);
>> +	spin_lock_irqsave(&sch->lock, flags);
>>   	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
>> -	spin_unlock(&sch->lock);
>> +	spin_unlock_irqrestore(&sch->lock, flags);
>>   	return 0;
>>   }
>>   
>> @@ -95,20 +101,22 @@ static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
>>   static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
>>   {
>>   	struct sch_gpio *sch = gpiochip_get_data(gc);
>> +	unsigned long flags;
>>   
>> -	spin_lock(&sch->lock);
>> +	spin_lock_irqsave(&sch->lock, flags);
>>   	sch_gpio_reg_set(sch, gpio_num, GLV, val);
>> -	spin_unlock(&sch->lock);
>> +	spin_unlock_irqrestore(&sch->lock, flags);
>>   }
>>   
>>   static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
>>   				  int val)
>>   {
>>   	struct sch_gpio *sch = gpiochip_get_data(gc);
>> +	unsigned long flags;
>>   
>> -	spin_lock(&sch->lock);
>> +	spin_lock_irqsave(&sch->lock, flags);
>>   	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
>> -	spin_unlock(&sch->lock);
>> +	spin_unlock_irqrestore(&sch->lock, flags);
>>   
>>   	/*
>>   	 * according to the datasheet, writing to the level register has no
>> @@ -130,6 +138,12 @@ static int sch_gpio_get_direction(struct gpio_chip *gc, unsigned gpio_num)
>>   	return sch_gpio_reg_get(sch, gpio_num, GIO);
>>   }
>>   
>> +static int sch_gpio_to_irq(struct gpio_chip *gpio, unsigned int offset)
>> +{
>> +	struct sch_gpio *sch = gpiochip_get_data(gpio);
>> +	return sch->irq_base + offset;
>> +}
>> +
>>   static const struct gpio_chip sch_gpio_chip = {
>>   	.label			= "sch_gpio",
>>   	.owner			= THIS_MODULE,
>> @@ -138,12 +152,94 @@ static const struct gpio_chip sch_gpio_chip = {
>>   	.direction_output	= sch_gpio_direction_out,
>>   	.set			= sch_gpio_set,
>>   	.get_direction		= sch_gpio_get_direction,
>> +	.to_irq			= sch_gpio_to_irq,
>>   };
>>   
>> +static u32 sch_sci_handler(void *context)
>> +{
>> +	struct sch_gpio *sch = context;
>> +	unsigned long core_status, resume_status;
>> +	unsigned int resume_gpios, offset;
>> +
>> +	core_status = inl(sch->iobase + GTS);
>> +	resume_status = inl(sch->iobase + GTS + 0x20);
>> +
>> +	if (core_status == 0 && resume_status == 0)
>> +		return ACPI_INTERRUPT_NOT_HANDLED;
>> +
>> +	for_each_set_bit(offset, &core_status, sch->resume_base)
>> +		generic_handle_irq(sch->irq_base + offset);
>> +
>> +	resume_gpios = sch->chip.ngpio - sch->resume_base;
>> +	for_each_set_bit(offset, &resume_status, resume_gpios)
>> +		generic_handle_irq(sch->irq_base + sch->resume_base + offset);
>> +
>> +	outl(core_status, sch->iobase + GTS);
>> +	outl(resume_status, sch->iobase + GTS + 0x20);
>> +
>> +	return ACPI_INTERRUPT_HANDLED;
>> +}
>> +
>> +static int sch_irq_type(struct irq_data *d, unsigned int type)
>> +{
>> +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
>> +	struct sch_gpio *sch = gc->private;
>> +	unsigned int gpio_num = d->irq - sch->irq_base;
>> +	int rising = 0;
>> +	int falling = 0;
>> +
>> +	switch (type & IRQ_TYPE_SENSE_MASK) {
>> +	case IRQ_TYPE_EDGE_RISING:
>> +		rising = 1;
>> +		break;
>> +	case IRQ_TYPE_EDGE_FALLING:
>> +		falling = 1;
>> +		break;
>> +	case IRQ_TYPE_EDGE_BOTH:
>> +		rising = 1;
>> +		falling = 1;
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	spin_lock(&sch->lock);
>> +	sch_gpio_reg_set(sch, gpio_num, GTPE, rising);
>> +	sch_gpio_reg_set(sch, gpio_num, GTNE, falling);
>> +	spin_unlock(&sch->lock);
>> +
>> +	return 0;
>> +}
>> +
>> +static void sch_irq_set_enable(struct irq_data *d, int val)
>> +{
>> +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
>> +	struct sch_gpio *sch = gc->private;
>> +	unsigned int gpio_num = d->irq - sch->irq_base;
>> +
>> +	spin_lock(&sch->lock);
>> +	sch_gpio_reg_set(sch, gpio_num, GGPE, val);
>> +	spin_unlock(&sch->lock);
>> +}
>> +
>> +static void sch_irq_mask(struct irq_data *d)
>> +{
>> +	sch_irq_set_enable(d, 0);
>> +}
>> +
>> +static void sch_irq_unmask(struct irq_data *d)
>> +{
>> +	sch_irq_set_enable(d, 1);
>> +}
>> +
>>   static int sch_gpio_probe(struct platform_device *pdev)
>>   {
>> +	struct irq_chip_generic *gc;
>> +	struct irq_chip_type *ct;
>>   	struct sch_gpio *sch;
>>   	struct resource *res;
>> +	acpi_status status;
>> +	int irq_base, ret;
>>   
>>   	sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
>>   	if (!sch)
>> @@ -203,7 +299,39 @@ static int sch_gpio_probe(struct platform_device *pdev)
>>   
>>   	platform_set_drvdata(pdev, sch);
>>   
>> -	return devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
>> +	ret = devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
>> +	if (ret)
>> +		return ret;
>> +
>> +	irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, sch->chip.ngpio,
>> +					NUMA_NO_NODE);
>> +	if (irq_base < 0)
>> +		return irq_base;
>> +	sch->irq_base = irq_base;
>> +
>> +	gc = devm_irq_alloc_generic_chip(&pdev->dev, "sch_gpio", 1, irq_base,
>> +					 NULL, handle_simple_irq);
>> +	if (!gc)
>> +		return -ENOMEM;
>> +
>> +	gc->private = sch;
>> +	ct = gc->chip_types;
>> +
>> +	ct->chip.irq_mask = sch_irq_mask;
>> +	ct->chip.irq_unmask = sch_irq_unmask;
>> +	ct->chip.irq_set_type = sch_irq_type;
>> +
>> +	ret = devm_irq_setup_generic_chip(&pdev->dev, gc,
>> +					  IRQ_MSK(sch->chip.ngpio),
>> +					  0, IRQ_NOREQUEST | IRQ_NOPROBE, 0);
>> +	if (ret)
>> +		return ret;
>> +
>> +	status = acpi_install_sci_handler(sch_sci_handler, sch);
>> +	if (ACPI_FAILURE(status))
>> +		return -EINVAL;
>> +
>> +	return 0;
>>   }
>>   
>>   static struct platform_driver sch_gpio_driver = {
>> -- 
>> 2.16.4


-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux

  reply	other threads:[~2019-04-24  8:12 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-18  9:23 [PATCH 0/2] gpio: sch: Interrupt support Jan Kiszka
2019-04-18  9:23 ` [PATCH 1/2] gpio: sch: Remove write-only core_base Jan Kiszka
2019-04-23 11:09   ` Linus Walleij
2019-04-18  9:23 ` [PATCH 2/2] gpio: sch: Add interrupt support Jan Kiszka
2019-04-23 11:10   ` Linus Walleij
2019-04-24  7:58   ` Mika Westerberg
2019-04-24  8:12     ` Jan Kiszka [this message]
2019-04-24  8:18       ` Mika Westerberg
2019-04-24  8:25         ` Jan Kiszka
2019-04-24  8:42           ` Mika Westerberg
2019-04-24  9:36             ` Jan Kiszka
2019-04-24  9:45               ` Mika Westerberg
2019-04-24  9:48                 ` Jan Kiszka
2019-04-24 10:01                   ` Mika Westerberg
2019-04-24 10:19                     ` Jan Kiszka
2019-04-24 10:33                       ` Mika Westerberg
2019-04-24 10:39                         ` Jan Kiszka
2019-04-24 10:46                           ` Mika Westerberg
2019-04-24 12:41                             ` Jan Kiszka
2019-04-24 13:13                               ` Mika Westerberg
2019-04-24 14:24                                 ` Jan Kiszka
2019-04-24 15:33                                   ` Mika Westerberg
2019-04-26 13:06                           ` Andy Shevchenko
2019-04-26 13:36                             ` Jan Kiszka
2019-04-26 14:42                               ` Enrico Weigelt, metux IT consult
2019-04-26 15:31                                 ` Manivannan Sadhasivam
2019-04-26 16:03                                 ` Jan Kiszka
2019-04-26 17:20                                   ` Andy Shevchenko
2019-04-26 17:33                                     ` Manivannan Sadhasivam
2019-04-26 17:39                                       ` Jan Kiszka
2019-04-26 17:46                                         ` Manivannan Sadhasivam
2019-04-26 17:52                                           ` Jan Kiszka
2019-04-26 17:56                                             ` Manivannan Sadhasivam
2019-04-26 17:44                                       ` Andy Shevchenko
2019-04-26 17:52                                         ` Manivannan Sadhasivam
2019-04-26 18:26                                           ` Andy Shevchenko
2019-04-26 17:37                                     ` Jan Kiszka
2019-04-29 11:09                                   ` Enrico Weigelt, metux IT consult
2019-05-16 12:20                                     ` Linus Walleij
2019-04-26 14:41                             ` Linus Walleij
2019-04-26 15:44                               ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8999d3f8-d169-eb85-bd2f-08c99d184ea2@siemens.com \
    --to=jan.kiszka@siemens.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=bgolaszewski@baylibre.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=rafael.j.wysocki@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.