From patchwork Wed Apr 1 14:30:59 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 15700 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n31EXkau015433 for ; Wed, 1 Apr 2009 14:33:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758985AbZDAOdq (ORCPT ); Wed, 1 Apr 2009 10:33:46 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1763660AbZDAOdq (ORCPT ); Wed, 1 Apr 2009 10:33:46 -0400 Received: from ti-out-0910.google.com ([209.85.142.187]:40435 "EHLO ti-out-0910.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758985AbZDAOdp (ORCPT ); Wed, 1 Apr 2009 10:33:45 -0400 Received: by ti-out-0910.google.com with SMTP id i7so49648tid.23 for ; Wed, 01 Apr 2009 07:33:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:date:message-id :subject; bh=0ZDT9qQx+NR49vp0dJ15GVSalznxr01jibPIe++/n38=; b=d91QwiDlW9rJmBSsZVSQLWXe81qdOFq9p3EB7kXv8E6yB8vY8530x1fJPX/K7BCfHk 3Lxdx08MeRJ2dhyG+ewIpcoKRxtYuItAShXB0mkb+xq6UoBnUwFifjCRZrYQKVwMvoqw +gaLPBDImWEAMds2sah4LTcR7dvm55cqx4joc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:date:message-id:subject; b=AvU/3n68v1eps9Za3RKu0zLOVOUJ4qET/QeHWfxuo9CFeBwEPtCBfQmvtFaG31rW+S Ee59Me0elnzgQ04fZKI3nN+rmiJIRfri+BjJD+QU8lEye0WJ+Y51595pBgGl+Cnj9jxC wM9gHOX23HIzF9aSX0+6BF5zzPP9Kk+Z5+vUM= Received: by 10.110.42.17 with SMTP id p17mr1020282tip.32.1238596422770; Wed, 01 Apr 2009 07:33:42 -0700 (PDT) Received: from rx1.opensource.se (210.5.32.202.bf.2iij.net [202.32.5.210]) by mx.google.com with ESMTPS id y5sm28197tia.17.2009.04.01.07.33.35 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 01 Apr 2009 07:33:37 -0700 (PDT) From: Magnus Damm To: linux-sh@vger.kernel.org Cc: francesco.virlinzi@st.com, Magnus Damm , lethal@linux-sh.org Date: Wed, 01 Apr 2009 23:30:59 +0900 Message-Id: <20090401143059.32645.74804.sendpatchset@rx1.opensource.se> Subject: [PATCH] sh_intc: set_irq_wake() support Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org From: Magnus Damm Add set_irq_wake() support to intc using sysdev and suspend. The intc controllers are put on a list at registration time and registered as sysdev devices later on during the boot. The sysdev class suspend callback is used to find irqs with wakeup enabled belonging to our intc controller. Such irqs are simply enabled so wakeup interrupts may reach the cpu. Signed-off-by: Magnus Damm --- drivers/sh/intc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- 0002/drivers/sh/intc.c +++ work/drivers/sh/intc.c 2009-04-01 22:54:58.000000000 +0900 @@ -22,6 +22,8 @@ #include #include #include +#include +#include #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ @@ -40,6 +42,8 @@ struct intc_handle_int { }; struct intc_desc_int { + struct list_head list; + struct sys_device sysdev; unsigned long *reg; #ifdef CONFIG_SMP unsigned long *smp; @@ -52,6 +56,8 @@ struct intc_desc_int { struct irq_chip chip; }; +static LIST_HEAD(intc_list); + #ifdef CONFIG_SMP #define IS_SMP(x) x.smp #define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) @@ -232,6 +238,11 @@ static void intc_disable(unsigned int ir } } +static int intc_set_wake(unsigned int irq, unsigned int on) +{ + return 0; /* allow wakeup, but setup hardware in intc_suspend() */ +} + #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) static void intc_mask_ack(unsigned int irq) { @@ -664,6 +675,9 @@ void __init register_intc_controller(str d = alloc_bootmem(sizeof(*d)); + INIT_LIST_HEAD(&d->list); + list_add(&d->list, &intc_list); + d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; @@ -711,6 +725,7 @@ void __init register_intc_controller(str d->chip.disable = intc_disable; d->chip.shutdown = intc_disable; d->chip.set_type = intc_set_sense; + d->chip.set_wake = intc_set_wake; #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) if (desc->ack_regs) { @@ -761,3 +776,53 @@ void __init register_intc_controller(str intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); } } + +static int intc_suspend(struct sys_device *dev, pm_message_t state) +{ + struct intc_desc_int *d; + struct irq_desc *desc; + int irq; + + /* get intc controller associated with this sysdev */ + d = container_of(dev, struct intc_desc_int, sysdev); + + /* enable wakeup irqs belonging to this intc controller */ + for_each_irq_desc(irq, desc) { + if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip)) + intc_enable(irq); + } + + return 0; +} + +static struct sysdev_class intc_sysdev_class = { + .name = "intc", + .suspend = intc_suspend, +}; + +/* register this intc as sysdev to allow suspend/resume */ +static int __init register_intc_sysdevs(void) +{ + struct intc_desc_int *d; + int error; + int id = 0; + + error = sysdev_class_register(&intc_sysdev_class); + if (!error) { + list_for_each_entry(d, &intc_list, list) { + d->sysdev.id = id; + d->sysdev.cls = &intc_sysdev_class; + error = sysdev_register(&d->sysdev); + if (error) + break; + id++; + } + } + + if (error) + pr_warning("intc: sysdev registration error\n"); + + return error; +} + +device_initcall(register_intc_sysdevs);