Skip to content

Commit c16a85a

Browse files
Finn Thainmpe
authored andcommitted
macintosh/via-pmu: Add support for m68k PowerBooks
Put #ifdefs around the Open Firmware, xmon, interrupt dispatch, battery and suspend code. Add the necessary interrupt handling to support m68k PowerBooks. The pmu_kind value is available to userspace using the PMU_IOC_GET_MODEL ioctl. It is not clear yet what hardware classes are be needed to describe m68k PowerBook models, so pmu_kind is given the provisional value PMU_UNKNOWN. To find out about the hardware, user programs can use /proc/bootinfo or /proc/hardware, or send the PMU_GET_VERSION command using /dev/adb. Tested-by: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent c70c35d commit c16a85a

File tree

2 files changed

+91
-12
lines changed

2 files changed

+91
-12
lines changed

drivers/macintosh/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ config ADB_CUDA
6565
If unsure say Y.
6666

6767
config ADB_PMU
68-
bool "Support for PMU based PowerMacs"
68+
bool "Support for PMU based PowerMacs and PowerBooks"
6969
depends on PPC_PMAC
7070
help
7171
On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the

drivers/macintosh/via-pmu.c

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/*
3-
* Device driver for the via-pmu on Apple Powermacs.
3+
* Device driver for the PMU in Apple PowerBooks and PowerMacs.
44
*
55
* The VIA (versatile interface adapter) interfaces to the PMU,
66
* a 6805 microprocessor core whose primary function is to control
@@ -49,20 +49,26 @@
4949
#include <linux/compat.h>
5050
#include <linux/of_address.h>
5151
#include <linux/of_irq.h>
52-
#include <asm/prom.h>
52+
#include <linux/uaccess.h>
5353
#include <asm/machdep.h>
5454
#include <asm/io.h>
5555
#include <asm/pgtable.h>
5656
#include <asm/sections.h>
5757
#include <asm/irq.h>
58+
#ifdef CONFIG_PPC_PMAC
5859
#include <asm/pmac_feature.h>
5960
#include <asm/pmac_pfunc.h>
6061
#include <asm/pmac_low_i2c.h>
61-
#include <linux/uaccess.h>
62+
#include <asm/prom.h>
6263
#include <asm/mmu_context.h>
6364
#include <asm/cputable.h>
6465
#include <asm/time.h>
6566
#include <asm/backlight.h>
67+
#else
68+
#include <asm/macintosh.h>
69+
#include <asm/macints.h>
70+
#include <asm/mac_via.h>
71+
#endif
6672

6773
#include "via-pmu-event.h"
6874

@@ -97,8 +103,13 @@ static DEFINE_MUTEX(pmu_info_proc_mutex);
97103
#define ANH (15*RS) /* A-side data, no handshake */
98104

99105
/* Bits in B data register: both active low */
106+
#ifdef CONFIG_PPC_PMAC
100107
#define TACK 0x08 /* Transfer acknowledge (input) */
101108
#define TREQ 0x10 /* Transfer request (output) */
109+
#else
110+
#define TACK 0x02
111+
#define TREQ 0x04
112+
#endif
102113

103114
/* Bits in ACR */
104115
#define SR_CTRL 0x1c /* Shift register control bits */
@@ -140,13 +151,15 @@ static int data_index;
140151
static int data_len;
141152
static volatile int adb_int_pending;
142153
static volatile int disable_poll;
143-
static struct device_node *vias;
144154
static int pmu_kind = PMU_UNKNOWN;
145155
static int pmu_fully_inited;
146156
static int pmu_has_adb;
157+
#ifdef CONFIG_PPC_PMAC
147158
static volatile unsigned char __iomem *via1;
148159
static volatile unsigned char __iomem *via2;
160+
static struct device_node *vias;
149161
static struct device_node *gpio_node;
162+
#endif
150163
static unsigned char __iomem *gpio_reg;
151164
static int gpio_irq = 0;
152165
static int gpio_irq_enabled = -1;
@@ -273,6 +286,7 @@ static char *pbook_type[] = {
273286

274287
int __init find_via_pmu(void)
275288
{
289+
#ifdef CONFIG_PPC_PMAC
276290
u64 taddr;
277291
const u32 *reg;
278292

@@ -355,9 +369,6 @@ int __init find_via_pmu(void)
355369
if (!init_pmu())
356370
goto fail_init;
357371

358-
printk(KERN_INFO "PMU driver v%d initialized for %s, firmware: %02x\n",
359-
PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
360-
361372
sys_ctrler = SYS_CTRLER_PMU;
362373

363374
return 1;
@@ -373,6 +384,30 @@ int __init find_via_pmu(void)
373384
vias = NULL;
374385
pmu_state = uninitialized;
375386
return 0;
387+
#else
388+
if (macintosh_config->adb_type != MAC_ADB_PB2)
389+
return 0;
390+
391+
pmu_kind = PMU_UNKNOWN;
392+
393+
spin_lock_init(&pmu_lock);
394+
395+
pmu_has_adb = 1;
396+
397+
pmu_intr_mask = PMU_INT_PCEJECT |
398+
PMU_INT_SNDBRT |
399+
PMU_INT_ADB |
400+
PMU_INT_TICK;
401+
402+
pmu_state = idle;
403+
404+
if (!init_pmu()) {
405+
pmu_state = uninitialized;
406+
return 0;
407+
}
408+
409+
return 1;
410+
#endif /* !CONFIG_PPC_PMAC */
376411
}
377412

378413
#ifdef CONFIG_ADB
@@ -396,13 +431,14 @@ static int pmu_init(void)
396431
*/
397432
static int __init via_pmu_start(void)
398433
{
399-
unsigned int irq;
434+
unsigned int __maybe_unused irq;
400435

401436
if (pmu_state == uninitialized)
402437
return -ENODEV;
403438

404439
batt_req.complete = 1;
405440

441+
#ifdef CONFIG_PPC_PMAC
406442
irq = irq_of_parse_and_map(vias, 0);
407443
if (!irq) {
408444
printk(KERN_ERR "via-pmu: can't map interrupt\n");
@@ -439,6 +475,19 @@ static int __init via_pmu_start(void)
439475

440476
/* Enable interrupts */
441477
out_8(&via1[IER], IER_SET | SR_INT | CB1_INT);
478+
#else
479+
if (request_irq(IRQ_MAC_ADB_SR, via_pmu_interrupt, IRQF_NO_SUSPEND,
480+
"VIA-PMU-SR", NULL)) {
481+
pr_err("%s: couldn't get SR irq\n", __func__);
482+
return -ENODEV;
483+
}
484+
if (request_irq(IRQ_MAC_ADB_CL, via_pmu_interrupt, IRQF_NO_SUSPEND,
485+
"VIA-PMU-CL", NULL)) {
486+
pr_err("%s: couldn't get CL irq\n", __func__);
487+
free_irq(IRQ_MAC_ADB_SR, NULL);
488+
return -ENODEV;
489+
}
490+
#endif /* !CONFIG_PPC_PMAC */
442491

443492
pmu_fully_inited = 1;
444493

@@ -589,6 +638,10 @@ init_pmu(void)
589638
option_server_mode ? "enabled" : "disabled");
590639
}
591640
}
641+
642+
printk(KERN_INFO "PMU driver v%d initialized for %s, firmware: %02x\n",
643+
PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
644+
592645
return 1;
593646
}
594647

@@ -627,6 +680,7 @@ static void pmu_set_server_mode(int server_mode)
627680
static void
628681
done_battery_state_ohare(struct adb_request* req)
629682
{
683+
#ifdef CONFIG_PPC_PMAC
630684
/* format:
631685
* [0] : flags
632686
* 0x01 : AC indicator
@@ -708,6 +762,7 @@ done_battery_state_ohare(struct adb_request* req)
708762
pmu_batteries[pmu_cur_battery].amperage = amperage;
709763
pmu_batteries[pmu_cur_battery].voltage = voltage;
710764
pmu_batteries[pmu_cur_battery].time_remaining = time;
765+
#endif /* CONFIG_PPC_PMAC */
711766

712767
clear_bit(0, &async_req_locks);
713768
}
@@ -1356,13 +1411,15 @@ pmu_handle_data(unsigned char *data, int len)
13561411
}
13571412
pmu_done(req);
13581413
} else {
1414+
#ifdef CONFIG_XMON
13591415
if (len == 4 && data[1] == 0x2c) {
13601416
extern int xmon_wants_key, xmon_adb_keycode;
13611417
if (xmon_wants_key) {
13621418
xmon_adb_keycode = data[2];
13631419
return;
13641420
}
13651421
}
1422+
#endif /* CONFIG_XMON */
13661423
#ifdef CONFIG_ADB
13671424
/*
13681425
* XXX On the [23]400 the PMU gives us an up
@@ -1530,7 +1587,25 @@ via_pmu_interrupt(int irq, void *arg)
15301587
++disable_poll;
15311588

15321589
for (;;) {
1533-
intr = in_8(&via1[IFR]) & (SR_INT | CB1_INT);
1590+
/* On 68k Macs, VIA interrupts are dispatched individually.
1591+
* Unless we are polling, the relevant IRQ flag has already
1592+
* been cleared.
1593+
*/
1594+
intr = 0;
1595+
if (IS_ENABLED(CONFIG_PPC_PMAC) || !irq) {
1596+
intr = in_8(&via1[IFR]) & (SR_INT | CB1_INT);
1597+
out_8(&via1[IFR], intr);
1598+
}
1599+
#ifndef CONFIG_PPC_PMAC
1600+
switch (irq) {
1601+
case IRQ_MAC_ADB_CL:
1602+
intr = CB1_INT;
1603+
break;
1604+
case IRQ_MAC_ADB_SR:
1605+
intr = SR_INT;
1606+
break;
1607+
}
1608+
#endif
15341609
if (intr == 0)
15351610
break;
15361611
handled = 1;
@@ -1540,7 +1615,6 @@ via_pmu_interrupt(int irq, void *arg)
15401615
intr, in_8(&via1[IER]), pmu_state);
15411616
break;
15421617
}
1543-
out_8(&via1[IFR], intr);
15441618
if (intr & CB1_INT) {
15451619
adb_int_pending = 1;
15461620
pmu_irq_stats[0]++;
@@ -1550,6 +1624,9 @@ via_pmu_interrupt(int irq, void *arg)
15501624
if (req)
15511625
break;
15521626
}
1627+
#ifndef CONFIG_PPC_PMAC
1628+
break;
1629+
#endif
15531630
}
15541631

15551632
recheck:
@@ -1616,7 +1693,7 @@ pmu_unlock(void)
16161693
}
16171694

16181695

1619-
static irqreturn_t
1696+
static __maybe_unused irqreturn_t
16201697
gpio1_interrupt(int irq, void *arg)
16211698
{
16221699
unsigned long flags;
@@ -2250,6 +2327,7 @@ static int pmu_ioctl(struct file *filp,
22502327
int error = -EINVAL;
22512328

22522329
switch (cmd) {
2330+
#ifdef CONFIG_PPC_PMAC
22532331
case PMU_IOC_SLEEP:
22542332
if (!capable(CAP_SYS_ADMIN))
22552333
return -EACCES;
@@ -2259,6 +2337,7 @@ static int pmu_ioctl(struct file *filp,
22592337
return put_user(0, argp);
22602338
else
22612339
return put_user(1, argp);
2340+
#endif
22622341

22632342
#ifdef CONFIG_PMAC_BACKLIGHT_LEGACY
22642343
/* Compatibility ioctl's for backlight */

0 commit comments

Comments
 (0)