aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/Kconfig9
-rw-r--r--drivers/ide/ppc/pmac.c125
-rw-r--r--drivers/macintosh/Kconfig11
-rw-r--r--drivers/macintosh/Makefile1
-rw-r--r--drivers/macintosh/via-pmu-led.c144
5 files changed, 164 insertions, 126 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index d633081fa4c5..d1266fe2d1ab 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -774,11 +774,18 @@ config BLK_DEV_IDEDMA_PMAC
774 performance. 774 performance.
775 775
776config BLK_DEV_IDE_PMAC_BLINK 776config BLK_DEV_IDE_PMAC_BLINK
777 bool "Blink laptop LED on drive activity" 777 bool "Blink laptop LED on drive activity (DEPRECATED)"
778 depends on BLK_DEV_IDE_PMAC && ADB_PMU 778 depends on BLK_DEV_IDE_PMAC && ADB_PMU
779 select ADB_PMU_LED
780 select LEDS_TRIGGERS
781 select LEDS_TRIGGER_IDE_DISK
779 help 782 help
780 This option enables the use of the sleep LED as a hard drive 783 This option enables the use of the sleep LED as a hard drive
781 activity LED. 784 activity LED.
785 This option is deprecated, it only selects ADB_PMU_LED and
786 LEDS_TRIGGER_IDE_DISK and changes the code in the new led class
787 device to default to the ide-disk trigger (which should be set
788 from userspace via sysfs).
782 789
783config BLK_DEV_IDE_SWARM 790config BLK_DEV_IDE_SWARM
784 tristate "IDE for Sibyte evaluation boards" 791 tristate "IDE for Sibyte evaluation boards"
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index ffca8b63ee79..e8ef3455ec35 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -421,107 +421,6 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
421#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ 421#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
422 422
423/* 423/*
424 * Below is the code for blinking the laptop LED along with hard
425 * disk activity.
426 */
427
428#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
429
430/* Set to 50ms minimum led-on time (also used to limit frequency
431 * of requests sent to the PMU
432 */
433#define PMU_HD_BLINK_TIME (HZ/50)
434
435static struct adb_request pmu_blink_on, pmu_blink_off;
436static spinlock_t pmu_blink_lock;
437static unsigned long pmu_blink_stoptime;
438static int pmu_blink_ledstate;
439static struct timer_list pmu_blink_timer;
440static int pmu_ide_blink_enabled;
441
442
443static void
444pmu_hd_blink_timeout(unsigned long data)
445{
446 unsigned long flags;
447
448 spin_lock_irqsave(&pmu_blink_lock, flags);
449
450 /* We may have been triggered again in a racy way, check
451 * that we really want to switch it off
452 */
453 if (time_after(pmu_blink_stoptime, jiffies))
454 goto done;
455
456 /* Previous req. not complete, try 100ms more */
457 if (pmu_blink_off.complete == 0)
458 mod_timer(&pmu_blink_timer, jiffies + PMU_HD_BLINK_TIME);
459 else if (pmu_blink_ledstate) {
460 pmu_request(&pmu_blink_off, NULL, 4, 0xee, 4, 0, 0);
461 pmu_blink_ledstate = 0;
462 }
463done:
464 spin_unlock_irqrestore(&pmu_blink_lock, flags);
465}
466
467static void
468pmu_hd_kick_blink(void *data, int rw)
469{
470 unsigned long flags;
471
472 pmu_blink_stoptime = jiffies + PMU_HD_BLINK_TIME;
473 wmb();
474 mod_timer(&pmu_blink_timer, pmu_blink_stoptime);
475 /* Fast path when LED is already ON */
476 if (pmu_blink_ledstate == 1)
477 return;
478 spin_lock_irqsave(&pmu_blink_lock, flags);
479 if (pmu_blink_on.complete && !pmu_blink_ledstate) {
480 pmu_request(&pmu_blink_on, NULL, 4, 0xee, 4, 0, 1);
481 pmu_blink_ledstate = 1;
482 }
483 spin_unlock_irqrestore(&pmu_blink_lock, flags);
484}
485
486static int
487pmu_hd_blink_init(void)
488{
489 struct device_node *dt;
490 const char *model;
491
492 /* Currently, I only enable this feature on KeyLargo based laptops,
493 * older laptops may support it (at least heathrow/paddington) but
494 * I don't feel like loading those venerable old machines with so
495 * much additional interrupt & PMU activity...
496 */
497 if (pmu_get_model() != PMU_KEYLARGO_BASED)
498 return 0;
499
500 dt = of_find_node_by_path("/");
501 if (dt == NULL)
502 return 0;
503 model = (const char *)get_property(dt, "model", NULL);
504 if (model == NULL)
505 return 0;
506 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
507 strncmp(model, "iBook", strlen("iBook")) != 0) {
508 of_node_put(dt);
509 return 0;
510 }
511 of_node_put(dt);
512
513 pmu_blink_on.complete = 1;
514 pmu_blink_off.complete = 1;
515 spin_lock_init(&pmu_blink_lock);
516 init_timer(&pmu_blink_timer);
517 pmu_blink_timer.function = pmu_hd_blink_timeout;
518
519 return 1;
520}
521
522#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
523
524/*
525 * N.B. this can't be an initfunc, because the media-bay task can 424 * N.B. this can't be an initfunc, because the media-bay task can
526 * call ide_[un]register at any time. 425 * call ide_[un]register at any time.
527 */ 426 */
@@ -1192,23 +1091,6 @@ pmac_ide_do_suspend(ide_hwif_t *hwif)
1192 pmif->timings[0] = 0; 1091 pmif->timings[0] = 0;
1193 pmif->timings[1] = 0; 1092 pmif->timings[1] = 0;
1194 1093
1195#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
1196 /* Note: This code will be called for every hwif, thus we'll
1197 * try several time to stop the LED blinker timer, but that
1198 * should be harmless
1199 */
1200 if (pmu_ide_blink_enabled) {
1201 unsigned long flags;
1202
1203 /* Make sure we don't hit the PMU blink */
1204 spin_lock_irqsave(&pmu_blink_lock, flags);
1205 if (pmu_blink_ledstate)
1206 del_timer(&pmu_blink_timer);
1207 pmu_blink_ledstate = 0;
1208 spin_unlock_irqrestore(&pmu_blink_lock, flags);
1209 }
1210#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
1211
1212 disable_irq(pmif->irq); 1094 disable_irq(pmif->irq);
1213 1095
1214 /* The media bay will handle itself just fine */ 1096 /* The media bay will handle itself just fine */
@@ -1376,13 +1258,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
1376 hwif->selectproc = pmac_ide_selectproc; 1258 hwif->selectproc = pmac_ide_selectproc;
1377 hwif->speedproc = pmac_ide_tune_chipset; 1259 hwif->speedproc = pmac_ide_tune_chipset;
1378 1260
1379#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
1380 pmu_ide_blink_enabled = pmu_hd_blink_init();
1381
1382 if (pmu_ide_blink_enabled)
1383 hwif->led_act = pmu_hd_kick_blink;
1384#endif
1385
1386 printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", 1261 printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",
1387 hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, 1262 hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
1388 pmif->mediabay ? " (mediabay)" : "", hwif->irq); 1263 pmif->mediabay ? " (mediabay)" : "", hwif->irq);
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 37cd6ee4586b..062dac26f2ae 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -78,6 +78,17 @@ config ADB_PMU
78 this device; you should do so if your machine is one of those 78 this device; you should do so if your machine is one of those
79 mentioned above. 79 mentioned above.
80 80
81config ADB_PMU_LED
82 bool "Support for the Power/iBook front LED"
83 depends on ADB_PMU
84 select LEDS_CLASS
85 help
86 Support the front LED on Power/iBooks as a generic LED that can
87 be triggered by any of the supported triggers. To get the
88 behaviour of the old CONFIG_BLK_DEV_IDE_PMAC_BLINK, select this
89 and the ide-disk LED trigger and configure appropriately through
90 sysfs.
91
81config PMAC_SMU 92config PMAC_SMU
82 bool "Support for SMU based PowerMacs" 93 bool "Support for SMU based PowerMacs"
83 depends on PPC_PMAC64 94 depends on PPC_PMAC64
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index 45a268f8047e..b53d45f87b0b 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_INPUT_ADBHID) += adbhid.o
12obj-$(CONFIG_ANSLCD) += ans-lcd.o 12obj-$(CONFIG_ANSLCD) += ans-lcd.o
13 13
14obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o 14obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o
15obj-$(CONFIG_ADB_PMU_LED) += via-pmu-led.o
15obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o 16obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o
16obj-$(CONFIG_ADB_CUDA) += via-cuda.o 17obj-$(CONFIG_ADB_CUDA) += via-cuda.o
17obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o 18obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
new file mode 100644
index 000000000000..af8375ed0f5e
--- /dev/null
+++ b/drivers/macintosh/via-pmu-led.c
@@ -0,0 +1,144 @@
1/*
2 * via-pmu LED class device
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22#include <linux/types.h>
23#include <linux/kernel.h>
24#include <linux/device.h>
25#include <linux/leds.h>
26#include <linux/adb.h>
27#include <linux/pmu.h>
28#include <asm/prom.h>
29
30static spinlock_t pmu_blink_lock;
31static struct adb_request pmu_blink_req;
32/* -1: no change, 0: request off, 1: request on */
33static int requested_change;
34static int sleeping;
35
36static void pmu_req_done(struct adb_request * req)
37{
38 unsigned long flags;
39
40 spin_lock_irqsave(&pmu_blink_lock, flags);
41 /* if someone requested a change in the meantime
42 * (we only see the last one which is fine)
43 * then apply it now */
44 if (requested_change != -1 && !sleeping)
45 pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
46 /* reset requested change */
47 requested_change = -1;
48 spin_unlock_irqrestore(&pmu_blink_lock, flags);
49}
50
51static void pmu_led_set(struct led_classdev *led_cdev,
52 enum led_brightness brightness)
53{
54 unsigned long flags;
55
56 spin_lock_irqsave(&pmu_blink_lock, flags);
57 switch (brightness) {
58 case LED_OFF:
59 requested_change = 0;
60 break;
61 case LED_FULL:
62 requested_change = 1;
63 break;
64 default:
65 goto out;
66 break;
67 }
68 /* if request isn't done, then don't do anything */
69 if (pmu_blink_req.complete && !sleeping)
70 pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
71 out:
72 spin_unlock_irqrestore(&pmu_blink_lock, flags);
73}
74
75static struct led_classdev pmu_led = {
76 .name = "pmu-front-led",
77#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
78 .default_trigger = "ide-disk",
79#endif
80 .brightness_set = pmu_led_set,
81};
82
83#ifdef CONFIG_PM
84static int pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when)
85{
86 unsigned long flags;
87
88 spin_lock_irqsave(&pmu_blink_lock, flags);
89
90 switch (when) {
91 case PBOOK_SLEEP_REQUEST:
92 sleeping = 1;
93 break;
94 case PBOOK_WAKE:
95 sleeping = 0;
96 break;
97 default:
98 /* do nothing */
99 break;
100 }
101 spin_unlock_irqrestore(&pmu_blink_lock, flags);
102
103 return PBOOK_SLEEP_OK;
104}
105
106static struct pmu_sleep_notifier via_pmu_led_sleep_notif = {
107 .notifier_call = pmu_led_sleep_call,
108};
109#endif
110
111static int __init via_pmu_led_init(void)
112{
113 struct device_node *dt;
114 const char *model;
115
116 /* only do this on keylargo based models */
117 if (pmu_get_model() != PMU_KEYLARGO_BASED)
118 return -ENODEV;
119
120 dt = of_find_node_by_path("/");
121 if (dt == NULL)
122 return -ENODEV;
123 model = (const char *)get_property(dt, "model", NULL);
124 if (model == NULL)
125 return -ENODEV;
126 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
127 strncmp(model, "iBook", strlen("iBook")) != 0) {
128 of_node_put(dt);
129 /* ignore */
130 return -ENODEV;
131 }
132 of_node_put(dt);
133
134 spin_lock_init(&pmu_blink_lock);
135 /* no outstanding req */
136 pmu_blink_req.complete = 1;
137 pmu_blink_req.done = pmu_req_done;
138#ifdef CONFIG_PM
139 pmu_register_sleep_notifier(&via_pmu_led_sleep_notif);
140#endif
141 return led_classdev_register(NULL, &pmu_led);
142}
143
144late_initcall(via_pmu_led_init);