diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-05 14:15:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-05 14:15:54 -0400 |
commit | 45e36c1666aa6c8b0c538abcf984b336184d8c3f (patch) | |
tree | c1f1771d6b02ec210238081450b4a063847b3383 /drivers | |
parent | 87fc94d54b639d8c39fc4a11db0e142f84096e13 (diff) | |
parent | 68b42d1b548be1840aff7122fdebeb804daf0fa3 (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.c | 3 | ||||
-rw-r--r-- | drivers/input/keyboard/sh_keysc.c | 17 | ||||
-rw-r--r-- | drivers/input/touchscreen/migor_ts.c | 23 | ||||
-rw-r--r-- | drivers/rtc/rtc-sh.c | 36 | ||||
-rw-r--r-- | drivers/sh/intc.c | 68 |
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 | ||
278 | static 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 | |||
275 | static struct dev_pm_ops sh_keysc_dev_pm_ops = { | 289 | static 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 | ||
279 | struct platform_driver sh_keysc_device_driver = { | 294 | struct 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 | ||
228 | static 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 | |||
238 | static 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 | |||
227 | static const struct i2c_device_id migor_ts_id[] = { | 248 | static 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 | |||
799 | static 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 | |||
812 | static 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 | |||
820 | static 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 | |||
828 | static struct dev_pm_ops sh_rtc_dev_pm_ops = { | ||
829 | .suspend = sh_rtc_suspend, | ||
830 | .resume = sh_rtc_resume, | ||
831 | }; | ||
832 | |||
798 | static struct platform_driver sh_rtc_platform_driver = { | 833 | static 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 | ||
42 | struct intc_desc_int { | 44 | struct 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 | ||
59 | static 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 | ||
241 | static 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) |
236 | static void intc_mask_ack(unsigned int irq) | 247 | static 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 | |||
780 | static 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 | |||
798 | static 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 */ | ||
804 | static 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 | |||
828 | device_initcall(register_intc_sysdevs); | ||