diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-11-09 22:04:41 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-11-09 22:04:41 -0500 |
commit | dc7c0b6a6d28b0de231728de963ed53a9cee85cf (patch) | |
tree | e7d4deeaba1ea8f905f1bb2be42cc47b4441eb97 /drivers/video/via | |
parent | d6ff7d0fe22cdf3ea41c48b50da9a9181500d1bf (diff) | |
parent | b884a94ed16d1a633e76f80fb1bd75d0e7373ce3 (diff) |
Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6
Diffstat (limited to 'drivers/video/via')
-rw-r--r-- | drivers/video/via/via-core.c | 96 | ||||
-rw-r--r-- | drivers/video/via/via-gpio.c | 29 | ||||
-rw-r--r-- | drivers/video/via/viafbdev.c | 34 | ||||
-rw-r--r-- | drivers/video/via/viafbdev.h | 2 |
4 files changed, 138 insertions, 23 deletions
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index a3aa91709503..6723d6910cde 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/list.h> | ||
19 | #include <linux/pm.h> | ||
20 | #include <asm/olpc.h> | ||
18 | 21 | ||
19 | /* | 22 | /* |
20 | * The default port config. | 23 | * The default port config. |
@@ -29,6 +32,19 @@ static struct via_port_cfg adap_configs[] = { | |||
29 | }; | 32 | }; |
30 | 33 | ||
31 | /* | 34 | /* |
35 | * The OLPC XO-1.5 puts the camera power and reset lines onto | ||
36 | * GPIO 2C. | ||
37 | */ | ||
38 | static const struct via_port_cfg olpc_adap_configs[] = { | ||
39 | [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x26 }, | ||
40 | [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 }, | ||
41 | [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 }, | ||
42 | [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x2c }, | ||
43 | [VIA_PORT_3D] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x3d }, | ||
44 | { 0, 0, 0, 0 } | ||
45 | }; | ||
46 | |||
47 | /* | ||
32 | * We currently only support one viafb device (will there ever be | 48 | * We currently only support one viafb device (will there ever be |
33 | * more than one?), so just declare it globally here. | 49 | * more than one?), so just declare it globally here. |
34 | */ | 50 | */ |
@@ -575,6 +591,78 @@ static void via_teardown_subdevs(void) | |||
575 | } | 591 | } |
576 | } | 592 | } |
577 | 593 | ||
594 | /* | ||
595 | * Power management functions | ||
596 | */ | ||
597 | #ifdef CONFIG_PM | ||
598 | static LIST_HEAD(viafb_pm_hooks); | ||
599 | static DEFINE_MUTEX(viafb_pm_hooks_lock); | ||
600 | |||
601 | void viafb_pm_register(struct viafb_pm_hooks *hooks) | ||
602 | { | ||
603 | INIT_LIST_HEAD(&hooks->list); | ||
604 | |||
605 | mutex_lock(&viafb_pm_hooks_lock); | ||
606 | list_add_tail(&hooks->list, &viafb_pm_hooks); | ||
607 | mutex_unlock(&viafb_pm_hooks_lock); | ||
608 | } | ||
609 | EXPORT_SYMBOL_GPL(viafb_pm_register); | ||
610 | |||
611 | void viafb_pm_unregister(struct viafb_pm_hooks *hooks) | ||
612 | { | ||
613 | mutex_lock(&viafb_pm_hooks_lock); | ||
614 | list_del(&hooks->list); | ||
615 | mutex_unlock(&viafb_pm_hooks_lock); | ||
616 | } | ||
617 | EXPORT_SYMBOL_GPL(viafb_pm_unregister); | ||
618 | |||
619 | static int via_suspend(struct pci_dev *pdev, pm_message_t state) | ||
620 | { | ||
621 | struct viafb_pm_hooks *hooks; | ||
622 | |||
623 | if (state.event != PM_EVENT_SUSPEND) | ||
624 | return 0; | ||
625 | /* | ||
626 | * "I've occasionally hit a few drivers that caused suspend | ||
627 | * failures, and each and every time it was a driver bug, and | ||
628 | * the right thing to do was to just ignore the error and suspend | ||
629 | * anyway - returning an error code and trying to undo the suspend | ||
630 | * is not what anybody ever really wants, even if our model | ||
631 | *_allows_ for it." | ||
632 | * -- Linus Torvalds, Dec. 7, 2009 | ||
633 | */ | ||
634 | mutex_lock(&viafb_pm_hooks_lock); | ||
635 | list_for_each_entry_reverse(hooks, &viafb_pm_hooks, list) | ||
636 | hooks->suspend(hooks->private); | ||
637 | mutex_unlock(&viafb_pm_hooks_lock); | ||
638 | |||
639 | pci_save_state(pdev); | ||
640 | pci_disable_device(pdev); | ||
641 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | static int via_resume(struct pci_dev *pdev) | ||
646 | { | ||
647 | struct viafb_pm_hooks *hooks; | ||
648 | |||
649 | /* Get the bus side powered up */ | ||
650 | pci_set_power_state(pdev, PCI_D0); | ||
651 | pci_restore_state(pdev); | ||
652 | if (pci_enable_device(pdev)) | ||
653 | return 0; | ||
654 | |||
655 | pci_set_master(pdev); | ||
656 | |||
657 | /* Now bring back any subdevs */ | ||
658 | mutex_lock(&viafb_pm_hooks_lock); | ||
659 | list_for_each_entry(hooks, &viafb_pm_hooks, list) | ||
660 | hooks->resume(hooks->private); | ||
661 | mutex_unlock(&viafb_pm_hooks_lock); | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | #endif /* CONFIG_PM */ | ||
578 | 666 | ||
579 | static int __devinit via_pci_probe(struct pci_dev *pdev, | 667 | static int __devinit via_pci_probe(struct pci_dev *pdev, |
580 | const struct pci_device_id *ent) | 668 | const struct pci_device_id *ent) |
@@ -584,6 +672,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
584 | ret = pci_enable_device(pdev); | 672 | ret = pci_enable_device(pdev); |
585 | if (ret) | 673 | if (ret) |
586 | return ret; | 674 | return ret; |
675 | |||
587 | /* | 676 | /* |
588 | * Global device initialization. | 677 | * Global device initialization. |
589 | */ | 678 | */ |
@@ -591,6 +680,9 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
591 | global_dev.pdev = pdev; | 680 | global_dev.pdev = pdev; |
592 | global_dev.chip_type = ent->driver_data; | 681 | global_dev.chip_type = ent->driver_data; |
593 | global_dev.port_cfg = adap_configs; | 682 | global_dev.port_cfg = adap_configs; |
683 | if (machine_is_olpc()) | ||
684 | global_dev.port_cfg = olpc_adap_configs; | ||
685 | |||
594 | spin_lock_init(&global_dev.reg_lock); | 686 | spin_lock_init(&global_dev.reg_lock); |
595 | ret = via_pci_setup_mmio(&global_dev); | 687 | ret = via_pci_setup_mmio(&global_dev); |
596 | if (ret) | 688 | if (ret) |
@@ -663,8 +755,8 @@ static struct pci_driver via_driver = { | |||
663 | .probe = via_pci_probe, | 755 | .probe = via_pci_probe, |
664 | .remove = __devexit_p(via_pci_remove), | 756 | .remove = __devexit_p(via_pci_remove), |
665 | #ifdef CONFIG_PM | 757 | #ifdef CONFIG_PM |
666 | .suspend = viafb_suspend, | 758 | .suspend = via_suspend, |
667 | .resume = viafb_resume, | 759 | .resume = via_resume, |
668 | #endif | 760 | #endif |
669 | }; | 761 | }; |
670 | 762 | ||
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/via/via-gpio.c index 39acb37e7a1d..c2a0a1cfd3b3 100644 --- a/drivers/video/via/via-gpio.c +++ b/drivers/video/via/via-gpio.c | |||
@@ -172,6 +172,28 @@ static void viafb_gpio_disable(struct viafb_gpio *gpio) | |||
172 | via_write_reg_mask(VIASR, gpio->vg_port_index, 0, 0x02); | 172 | via_write_reg_mask(VIASR, gpio->vg_port_index, 0, 0x02); |
173 | } | 173 | } |
174 | 174 | ||
175 | #ifdef CONFIG_PM | ||
176 | |||
177 | static int viafb_gpio_suspend(void *private) | ||
178 | { | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int viafb_gpio_resume(void *private) | ||
183 | { | ||
184 | int i; | ||
185 | |||
186 | for (i = 0; i < gpio_config.gpio_chip.ngpio; i += 2) | ||
187 | viafb_gpio_enable(gpio_config.active_gpios[i]); | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static struct viafb_pm_hooks viafb_gpio_pm_hooks = { | ||
192 | .suspend = viafb_gpio_suspend, | ||
193 | .resume = viafb_gpio_resume | ||
194 | }; | ||
195 | #endif /* CONFIG_PM */ | ||
196 | |||
175 | /* | 197 | /* |
176 | * Look up a specific gpio and return the number it was assigned. | 198 | * Look up a specific gpio and return the number it was assigned. |
177 | */ | 199 | */ |
@@ -236,6 +258,9 @@ static __devinit int viafb_gpio_probe(struct platform_device *platdev) | |||
236 | printk(KERN_ERR "viafb: failed to add gpios (%d)\n", ret); | 258 | printk(KERN_ERR "viafb: failed to add gpios (%d)\n", ret); |
237 | gpio_config.gpio_chip.ngpio = 0; | 259 | gpio_config.gpio_chip.ngpio = 0; |
238 | } | 260 | } |
261 | #ifdef CONFIG_PM | ||
262 | viafb_pm_register(&viafb_gpio_pm_hooks); | ||
263 | #endif | ||
239 | return ret; | 264 | return ret; |
240 | } | 265 | } |
241 | 266 | ||
@@ -245,6 +270,10 @@ static int viafb_gpio_remove(struct platform_device *platdev) | |||
245 | unsigned long flags; | 270 | unsigned long flags; |
246 | int ret = 0, i; | 271 | int ret = 0, i; |
247 | 272 | ||
273 | #ifdef CONFIG_PM | ||
274 | viafb_pm_unregister(&viafb_gpio_pm_hooks); | ||
275 | #endif | ||
276 | |||
248 | /* | 277 | /* |
249 | * Get unregistered. | 278 | * Get unregistered. |
250 | */ | 279 | */ |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index d298cfccd6fc..289edd519527 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -1672,31 +1672,19 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres) | |||
1672 | 1672 | ||
1673 | 1673 | ||
1674 | #ifdef CONFIG_PM | 1674 | #ifdef CONFIG_PM |
1675 | int viafb_suspend(struct pci_dev *pdev, pm_message_t state) | 1675 | static int viafb_suspend(void *unused) |
1676 | { | 1676 | { |
1677 | if (state.event == PM_EVENT_SUSPEND) { | 1677 | acquire_console_sem(); |
1678 | acquire_console_sem(); | 1678 | fb_set_suspend(viafbinfo, 1); |
1679 | fb_set_suspend(viafbinfo, 1); | 1679 | viafb_sync(viafbinfo); |
1680 | 1680 | release_console_sem(); | |
1681 | viafb_sync(viafbinfo); | ||
1682 | |||
1683 | pci_save_state(pdev); | ||
1684 | pci_disable_device(pdev); | ||
1685 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1686 | release_console_sem(); | ||
1687 | } | ||
1688 | 1681 | ||
1689 | return 0; | 1682 | return 0; |
1690 | } | 1683 | } |
1691 | 1684 | ||
1692 | int viafb_resume(struct pci_dev *pdev) | 1685 | static int viafb_resume(void *unused) |
1693 | { | 1686 | { |
1694 | acquire_console_sem(); | 1687 | acquire_console_sem(); |
1695 | pci_set_power_state(pdev, PCI_D0); | ||
1696 | pci_restore_state(pdev); | ||
1697 | if (pci_enable_device(pdev)) | ||
1698 | goto fail; | ||
1699 | pci_set_master(pdev); | ||
1700 | if (viaparinfo->shared->vdev->engine_mmio) | 1688 | if (viaparinfo->shared->vdev->engine_mmio) |
1701 | viafb_reset_engine(viaparinfo); | 1689 | viafb_reset_engine(viaparinfo); |
1702 | viafb_set_par(viafbinfo); | 1690 | viafb_set_par(viafbinfo); |
@@ -1704,11 +1692,15 @@ int viafb_resume(struct pci_dev *pdev) | |||
1704 | viafb_set_par(viafbinfo1); | 1692 | viafb_set_par(viafbinfo1); |
1705 | fb_set_suspend(viafbinfo, 0); | 1693 | fb_set_suspend(viafbinfo, 0); |
1706 | 1694 | ||
1707 | fail: | ||
1708 | release_console_sem(); | 1695 | release_console_sem(); |
1709 | return 0; | 1696 | return 0; |
1710 | } | 1697 | } |
1711 | 1698 | ||
1699 | static struct viafb_pm_hooks viafb_fb_pm_hooks = { | ||
1700 | .suspend = viafb_suspend, | ||
1701 | .resume = viafb_resume | ||
1702 | }; | ||
1703 | |||
1712 | #endif | 1704 | #endif |
1713 | 1705 | ||
1714 | 1706 | ||
@@ -1899,6 +1891,10 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) | |||
1899 | 1891 | ||
1900 | viafb_init_proc(viaparinfo->shared); | 1892 | viafb_init_proc(viaparinfo->shared); |
1901 | viafb_init_dac(IGA2); | 1893 | viafb_init_dac(IGA2); |
1894 | |||
1895 | #ifdef CONFIG_PM | ||
1896 | viafb_pm_register(&viafb_fb_pm_hooks); | ||
1897 | #endif | ||
1902 | return 0; | 1898 | return 0; |
1903 | 1899 | ||
1904 | out_fb_unreg: | 1900 | out_fb_unreg: |
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 4960e3da6645..d66f963e930e 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
@@ -108,6 +108,4 @@ void via_fb_pci_remove(struct pci_dev *pdev); | |||
108 | /* Temporary */ | 108 | /* Temporary */ |
109 | int viafb_init(void); | 109 | int viafb_init(void); |
110 | void viafb_exit(void); | 110 | void viafb_exit(void); |
111 | int viafb_suspend(struct pci_dev *pdev, pm_message_t state); | ||
112 | int viafb_resume(struct pci_dev *pdev); | ||
113 | #endif /* __VIAFBDEV_H__ */ | 111 | #endif /* __VIAFBDEV_H__ */ |