aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-05 14:15:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-05 14:15:54 -0400
commit45e36c1666aa6c8b0c538abcf984b336184d8c3f (patch)
treec1f1771d6b02ec210238081450b4a063847b3383 /drivers
parent87fc94d54b639d8c39fc4a11db0e142f84096e13 (diff)
parent68b42d1b548be1840aff7122fdebeb804daf0fa3 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (23 commits) sh: sh7785lcr: Map whole PCI address space. sh: Fix up DSP context save/restore. sh: Fix up number of on-chip DMA channels on SH7091. sh: update defconfigs. sh: Kill off broken direct-mapped cache mode. sh: Wire up ARCH_HAS_DEFAULT_IDLE for cpuidle. sh: Add a command line option for disabling I/O trapping. sh: Select ARCH_HIBERNATION_POSSIBLE. sh: migor: Fix up CEU use flags. input: migor_ts: add wakeup support rtc: rtc-sh: use set_irq_wake() input: sh_keysc: use enable/disable_irq_wake() sh: intc: set_irq_wake() support sh: intc: install enable, disable and shutdown callbacks clocksource: sh_cmt: use remove_irq() and remove clockevent workaround sh: ap325 and Migo-R use new sh_mobile_ceu_info flags sh: Fix up -Wformat-security whining. sh: ap325rxa: Add ov772x support, again. sh: Sanitize asm/mmu.h for assembly use. sh: Tidy up sh7786 pinmux table. ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clocksource/sh_cmt.c3
-rw-r--r--drivers/input/keyboard/sh_keysc.c17
-rw-r--r--drivers/input/touchscreen/migor_ts.c23
-rw-r--r--drivers/rtc/rtc-sh.c36
-rw-r--r--drivers/sh/intc.c68
5 files changed, 144 insertions, 3 deletions
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 7783b42f6914..1c92c39a53aa 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -465,7 +465,6 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
465 ced->set_mode = sh_cmt_clock_event_mode; 465 ced->set_mode = sh_cmt_clock_event_mode;
466 466
467 pr_info("sh_cmt: %s used for clock events\n", ced->name); 467 pr_info("sh_cmt: %s used for clock events\n", ced->name);
468 ced->mult = 1; /* work around misplaced WARN_ON() in clockevents.c */
469 clockevents_register_device(ced); 468 clockevents_register_device(ced);
470} 469}
471 470
@@ -557,7 +556,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
557 cfg->clockevent_rating, 556 cfg->clockevent_rating,
558 cfg->clocksource_rating); 557 cfg->clocksource_rating);
559 err2: 558 err2:
560 free_irq(irq, p); 559 remove_irq(irq, &p->irqaction);
561 err1: 560 err1:
562 iounmap(p->mapbase); 561 iounmap(p->mapbase);
563 err0: 562 err0:
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index e1480fb11de3..cea70e6a1031 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -259,12 +259,15 @@ static int sh_keysc_suspend(struct device *dev)
259{ 259{
260 struct platform_device *pdev = to_platform_device(dev); 260 struct platform_device *pdev = to_platform_device(dev);
261 struct sh_keysc_priv *priv = platform_get_drvdata(pdev); 261 struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
262 int irq = platform_get_irq(pdev, 0);
262 unsigned short value; 263 unsigned short value;
263 264
264 value = ioread16(priv->iomem_base + KYCR1_OFFS); 265 value = ioread16(priv->iomem_base + KYCR1_OFFS);
265 266
266 if (device_may_wakeup(dev)) 267 if (device_may_wakeup(dev)) {
267 value |= 0x80; 268 value |= 0x80;
269 enable_irq_wake(irq);
270 }
268 else 271 else
269 value &= ~0x80; 272 value &= ~0x80;
270 273
@@ -272,8 +275,20 @@ static int sh_keysc_suspend(struct device *dev)
272 return 0; 275 return 0;
273} 276}
274 277
278static int sh_keysc_resume(struct device *dev)
279{
280 struct platform_device *pdev = to_platform_device(dev);
281 int irq = platform_get_irq(pdev, 0);
282
283 if (device_may_wakeup(dev))
284 disable_irq_wake(irq);
285
286 return 0;
287}
288
275static struct dev_pm_ops sh_keysc_dev_pm_ops = { 289static struct dev_pm_ops sh_keysc_dev_pm_ops = {
276 .suspend = sh_keysc_suspend, 290 .suspend = sh_keysc_suspend,
291 .resume = sh_keysc_resume,
277}; 292};
278 293
279struct platform_driver sh_keysc_device_driver = { 294struct platform_driver sh_keysc_device_driver = {
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 504ca11749a1..141dd584330e 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -198,6 +198,7 @@ static int migor_ts_probe(struct i2c_client *client,
198 goto err2; 198 goto err2;
199 } 199 }
200 200
201 device_init_wakeup(&client->dev, 1);
201 return 0; 202 return 0;
202 203
203 err2: 204 err2:
@@ -224,6 +225,26 @@ static int migor_ts_remove(struct i2c_client *client)
224 return 0; 225 return 0;
225} 226}
226 227
228static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
229{
230 struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
231
232 if (device_may_wakeup(&client->dev))
233 enable_irq_wake(priv->irq);
234
235 return 0;
236}
237
238static int migor_ts_resume(struct i2c_client *client)
239{
240 struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
241
242 if (device_may_wakeup(&client->dev))
243 disable_irq_wake(priv->irq);
244
245 return 0;
246}
247
227static const struct i2c_device_id migor_ts_id[] = { 248static const struct i2c_device_id migor_ts_id[] = {
228 { "migor_ts", 0 }, 249 { "migor_ts", 0 },
229 { } 250 { }
@@ -236,6 +257,8 @@ static struct i2c_driver migor_ts_driver = {
236 }, 257 },
237 .probe = migor_ts_probe, 258 .probe = migor_ts_probe,
238 .remove = migor_ts_remove, 259 .remove = migor_ts_remove,
260 .suspend = migor_ts_suspend,
261 .resume = migor_ts_resume,
239 .id_table = migor_ts_id, 262 .id_table = migor_ts_id,
240}; 263};
241 264
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 4898f7fe8518..9b1ff12bf947 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -795,10 +795,46 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
795 795
796 return 0; 796 return 0;
797} 797}
798
799static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
800{
801 struct platform_device *pdev = to_platform_device(dev);
802 struct sh_rtc *rtc = platform_get_drvdata(pdev);
803
804 set_irq_wake(rtc->periodic_irq, enabled);
805 if (rtc->carry_irq > 0) {
806 set_irq_wake(rtc->carry_irq, enabled);
807 set_irq_wake(rtc->alarm_irq, enabled);
808 }
809
810}
811
812static int sh_rtc_suspend(struct device *dev)
813{
814 if (device_may_wakeup(dev))
815 sh_rtc_set_irq_wake(dev, 1);
816
817 return 0;
818}
819
820static int sh_rtc_resume(struct device *dev)
821{
822 if (device_may_wakeup(dev))
823 sh_rtc_set_irq_wake(dev, 0);
824
825 return 0;
826}
827
828static struct dev_pm_ops sh_rtc_dev_pm_ops = {
829 .suspend = sh_rtc_suspend,
830 .resume = sh_rtc_resume,
831};
832
798static struct platform_driver sh_rtc_platform_driver = { 833static struct platform_driver sh_rtc_platform_driver = {
799 .driver = { 834 .driver = {
800 .name = DRV_NAME, 835 .name = DRV_NAME,
801 .owner = THIS_MODULE, 836 .owner = THIS_MODULE,
837 .pm = &sh_rtc_dev_pm_ops,
802 }, 838 },
803 .probe = sh_rtc_probe, 839 .probe = sh_rtc_probe,
804 .remove = __devexit_p(sh_rtc_remove), 840 .remove = __devexit_p(sh_rtc_remove),
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 2269fbcaa182..7fb9b5c4669a 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -22,6 +22,8 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/sh_intc.h> 24#include <linux/sh_intc.h>
25#include <linux/sysdev.h>
26#include <linux/list.h>
25 27
26#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ 28#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
27 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ 29 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -40,6 +42,8 @@ struct intc_handle_int {
40}; 42};
41 43
42struct intc_desc_int { 44struct intc_desc_int {
45 struct list_head list;
46 struct sys_device sysdev;
43 unsigned long *reg; 47 unsigned long *reg;
44#ifdef CONFIG_SMP 48#ifdef CONFIG_SMP
45 unsigned long *smp; 49 unsigned long *smp;
@@ -52,6 +56,8 @@ struct intc_desc_int {
52 struct irq_chip chip; 56 struct irq_chip chip;
53}; 57};
54 58
59static LIST_HEAD(intc_list);
60
55#ifdef CONFIG_SMP 61#ifdef CONFIG_SMP
56#define IS_SMP(x) x.smp 62#define IS_SMP(x) x.smp
57#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) 63#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
@@ -232,6 +238,11 @@ static void intc_disable(unsigned int irq)
232 } 238 }
233} 239}
234 240
241static int intc_set_wake(unsigned int irq, unsigned int on)
242{
243 return 0; /* allow wakeup, but setup hardware in intc_suspend() */
244}
245
235#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 246#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
236static void intc_mask_ack(unsigned int irq) 247static void intc_mask_ack(unsigned int irq)
237{ 248{
@@ -664,6 +675,9 @@ void __init register_intc_controller(struct intc_desc *desc)
664 675
665 d = alloc_bootmem(sizeof(*d)); 676 d = alloc_bootmem(sizeof(*d));
666 677
678 INIT_LIST_HEAD(&d->list);
679 list_add(&d->list, &intc_list);
680
667 d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; 681 d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
668 d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; 682 d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
669 d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; 683 d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
@@ -707,7 +721,11 @@ void __init register_intc_controller(struct intc_desc *desc)
707 d->chip.mask = intc_disable; 721 d->chip.mask = intc_disable;
708 d->chip.unmask = intc_enable; 722 d->chip.unmask = intc_enable;
709 d->chip.mask_ack = intc_disable; 723 d->chip.mask_ack = intc_disable;
724 d->chip.enable = intc_enable;
725 d->chip.disable = intc_disable;
726 d->chip.shutdown = intc_disable;
710 d->chip.set_type = intc_set_sense; 727 d->chip.set_type = intc_set_sense;
728 d->chip.set_wake = intc_set_wake;
711 729
712#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) 730#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
713 if (desc->ack_regs) { 731 if (desc->ack_regs) {
@@ -758,3 +776,53 @@ void __init register_intc_controller(struct intc_desc *desc)
758 intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); 776 intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
759 } 777 }
760} 778}
779
780static int intc_suspend(struct sys_device *dev, pm_message_t state)
781{
782 struct intc_desc_int *d;
783 struct irq_desc *desc;
784 int irq;
785
786 /* get intc controller associated with this sysdev */
787 d = container_of(dev, struct intc_desc_int, sysdev);
788
789 /* enable wakeup irqs belonging to this intc controller */
790 for_each_irq_desc(irq, desc) {
791 if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
792 intc_enable(irq);
793 }
794
795 return 0;
796}
797
798static struct sysdev_class intc_sysdev_class = {
799 .name = "intc",
800 .suspend = intc_suspend,
801};
802
803/* register this intc as sysdev to allow suspend/resume */
804static int __init register_intc_sysdevs(void)
805{
806 struct intc_desc_int *d;
807 int error;
808 int id = 0;
809
810 error = sysdev_class_register(&intc_sysdev_class);
811 if (!error) {
812 list_for_each_entry(d, &intc_list, list) {
813 d->sysdev.id = id;
814 d->sysdev.cls = &intc_sysdev_class;
815 error = sysdev_register(&d->sysdev);
816 if (error)
817 break;
818 id++;
819 }
820 }
821
822 if (error)
823 pr_warning("intc: sysdev registration error\n");
824
825 return error;
826}
827
828device_initcall(register_intc_sysdevs);