patch-2.2.8 linux/drivers/macintosh/via-pmu.c
Next file: linux/drivers/misc/Makefile
Previous file: linux/drivers/macintosh/via-cuda.c
Back to the patch index
Back to the overall index
- Lines: 386
- Date:
Thu Apr 29 12:53:48 1999
- Orig file:
v2.2.7/linux/drivers/macintosh/via-pmu.c
- Orig date:
Tue Mar 23 14:35:47 1999
diff -u --recursive --new-file v2.2.7/linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
@@ -93,6 +93,7 @@
static struct adb_request bright_req_1, bright_req_2, bright_req_3;
static struct device_node *vias;
static int pmu_kind = PMU_UNKNOWN;
+static int pmu_fully_inited = 0;
int asleep;
struct notifier_block *sleep_notifier_list;
@@ -103,7 +104,7 @@
static void via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
static int pmu_adb_send_request(struct adb_request *req, int sync);
static int pmu_adb_autopoll(int devs);
-static int pmu_reset_bus(void);
+static int pmu_adb_reset_bus(void);
static void send_byte(int x);
static void recv_byte(void);
static void pmu_sr_intr(struct pt_regs *regs);
@@ -112,6 +113,14 @@
struct pt_regs *regs);
static void set_volume(int level);
+static struct adb_controller pmu_controller = {
+ ADB_VIAPMU,
+ pmu_adb_send_request,
+ pmu_adb_autopoll,
+ pmu_adb_reset_bus,
+ pmu_poll
+};
+
/*
* This table indicates for each PMU opcode:
* - the number of data bytes to be sent with the command, or -1
@@ -126,17 +135,17 @@
/*10*/ { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*18*/ { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0, 0},
/*20*/ {-1, 0},{ 0, 0},{ 2, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},
-/*28*/ { 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
-/*30*/ { 4, 0},{20, 0},{ 2, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
-/*38*/ { 0, 4},{ 0,20},{ 1, 1},{ 2, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
+/*28*/ { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0,-1},
+/*30*/ { 4, 0},{20, 0},{-1, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
+/*38*/ { 0, 4},{ 0,20},{ 2,-1},{ 2, 1},{ 3,-1},{-1,-1},{-1,-1},{ 4, 0},
/*40*/ { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
-/*48*/ { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{ 1, 0},{-1,-1},{-1,-1},{-1,-1},
+/*48*/ { 0, 1},{ 0, 1},{-1,-1},{ 1, 0},{ 1, 0},{-1,-1},{-1,-1},{-1,-1},
/*50*/ { 1, 0},{ 0, 0},{ 2, 0},{ 2, 0},{-1, 0},{ 1, 0},{ 3, 0},{ 1, 0},
/*58*/ { 0, 1},{ 1, 0},{ 0, 2},{ 0, 2},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},
-/*60*/ { 2, 0},{-1, 0},{ 2, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
+/*60*/ { 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*68*/ { 0, 3},{ 0, 3},{ 0, 2},{ 0, 8},{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},
/*70*/ { 1, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
-/*78*/ { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 4, 1},{ 4, 1},
+/*78*/ { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{ 5, 1},{ 4, 1},{ 4, 1},
/*80*/ { 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*88*/ { 0, 5},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
/*90*/ { 1, 0},{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
@@ -149,7 +158,7 @@
/*c8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
/*d0*/ { 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*d8*/ { 1, 1},{ 1, 1},{-1,-1},{-1,-1},{ 0, 1},{ 0,-1},{-1,-1},{-1,-1},
-/*e0*/ {-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
+/*e0*/ {-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{ 4, 0},{-1, 0},{-1, 0},
/*e8*/ { 3,-1},{-1,-1},{ 0, 1},{-1,-1},{ 0,-1},{-1,-1},{-1,-1},{ 0, 0},
/*f0*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*f8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
@@ -186,8 +195,8 @@
return;
}
- if (vias->parent->name && strcmp(vias->parent->name, "ohare") == 0
- || device_is_compatible(vias->parent, "ohare"))
+ if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
+ || device_is_compatible(vias->parent, "ohare")))
pmu_kind = PMU_OHARE_BASED;
else if (device_is_compatible(vias->parent, "heathrow"))
pmu_kind = PMU_HEATHROW_BASED;
@@ -203,13 +212,13 @@
if (!init_pmu())
via = NULL;
- adb_hardware = ADB_VIAPMU;
-
+ adb_controller = &pmu_controller;
+
if (via)
printk(KERN_INFO "PMU driver initialized for %s\n",
- (pmu_kind == PMU_OHARE_BASED) ? "PowerBook 2400/3400/3500(G3)" :
- ((pmu_kind == PMU_HEATHROW_BASED) ? "PowerBook G3 Series" :
- "Unknown PowerBook"));
+ (pmu_kind == PMU_OHARE_BASED) ? "PowerBook 2400/3400/3500(G3)" :
+ ((pmu_kind == PMU_HEATHROW_BASED) ? "PowerBook G3 Series" :
+ "Unknown PowerBook"));
}
void __openfirmware
@@ -232,11 +241,8 @@
/* Enable interrupts */
out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
- /* Set function pointers */
- adb_send_request = pmu_adb_send_request;
- adb_autopoll = pmu_adb_autopoll;
- adb_reset_bus = pmu_reset_bus;
-
+ pmu_fully_inited = 1;
+
/* Enable backlight */
pmu_enable_backlight(1);
}
@@ -288,25 +294,81 @@
static int __openfirmware
pmu_adb_send_request(struct adb_request *req, int sync)
{
- int i;
+ int i, ret;
- for (i = req->nbytes - 1; i > 0; --i)
- req->data[i+3] = req->data[i];
- req->data[3] = req->nbytes - 1;
- req->data[2] = pmu_adb_flags;
- req->data[1] = req->data[0];
- req->data[0] = PMU_ADB_CMD;
- req->nbytes += 3;
- req->reply_expected = 1;
- req->reply_len = 0;
- i = pmu_queue_request(req);
- if (i)
- return i;
- if (sync) {
- while (!req->complete)
- pmu_poll();
- }
- return 0;
+ if ((vias == NULL) || (!pmu_fully_inited))
+ {
+ req->complete = 1;
+ return -ENXIO;
+ }
+
+ ret = -EINVAL;
+
+ switch (req->data[0]) {
+ case PMU_PACKET:
+ for (i = 0; i < req->nbytes - 1; ++i)
+ req->data[i] = req->data[i+1];
+ --req->nbytes;
+ if (pmu_data_len[req->data[0]][1] != 0) {
+ req->reply[0] = ADB_RET_OK;
+ req->reply_len = 1;
+ } else
+ req->reply_len = 0;
+ ret = pmu_queue_request(req);
+ break;
+ case CUDA_PACKET:
+ switch (req->data[1]) {
+ case CUDA_GET_TIME:
+ if (req->nbytes != 2)
+ break;
+ req->data[0] = PMU_READ_RTC;
+ req->nbytes = 1;
+ req->reply_len = 3;
+ req->reply[0] = CUDA_PACKET;
+ req->reply[1] = 0;
+ req->reply[2] = CUDA_GET_TIME;
+ ret = pmu_queue_request(req);
+ break;
+ case CUDA_SET_TIME:
+ if (req->nbytes != 6)
+ break;
+ req->data[0] = PMU_SET_RTC;
+ req->nbytes = 5;
+ for (i = 1; i <= 4; ++i)
+ req->data[i] = req->data[i+1];
+ req->reply_len = 3;
+ req->reply[0] = CUDA_PACKET;
+ req->reply[1] = 0;
+ req->reply[2] = CUDA_SET_TIME;
+ ret = pmu_queue_request(req);
+ break;
+ }
+ break;
+ case ADB_PACKET:
+ for (i = req->nbytes - 1; i > 1; --i)
+ req->data[i+2] = req->data[i];
+ req->data[3] = req->nbytes - 2;
+ req->data[2] = pmu_adb_flags;
+ /*req->data[1] = req->data[1];*/
+ req->data[0] = PMU_ADB_CMD;
+ req->nbytes += 2;
+ req->reply_expected = 1;
+ req->reply_len = 0;
+ ret = pmu_queue_request(req);
+ break;
+ }
+ if (ret)
+ {
+ req->complete = 1;
+ return ret;
+ }
+
+ if (sync) {
+ while (!req->complete)
+ pmu_poll();
+ }
+
+ return 0;
}
/* Enable/disable autopolling */
@@ -315,6 +377,9 @@
{
struct adb_request req;
+ if ((vias == NULL) || (!pmu_fully_inited))
+ return -ENXIO;
+
if (devs) {
adb_dev_map = devs;
pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86,
@@ -331,12 +396,15 @@
/* Reset the ADB bus */
static int __openfirmware
-pmu_reset_bus(void)
+pmu_adb_reset_bus(void)
{
struct adb_request req;
long timeout;
int save_autopoll = adb_dev_map;
+ if ((vias == NULL) || (!pmu_fully_inited))
+ return -ENXIO;
+
/* anyone got a better idea?? */
pmu_adb_autopoll(0);
@@ -344,23 +412,23 @@
req.done = NULL;
req.data[0] = PMU_ADB_CMD;
req.data[1] = 0;
- req.data[2] = 3;
+ req.data[2] = 3; /* ADB_BUSRESET ??? */
req.data[3] = 0;
req.data[4] = 0;
req.reply_len = 0;
req.reply_expected = 1;
if (pmu_queue_request(&req) != 0)
{
- printk(KERN_ERR "pmu_reset_bus: pmu_queue_request failed\n");
- return 0;
+ printk(KERN_ERR "pmu_adb_reset_bus: pmu_queue_request failed\n");
+ return -EIO;
}
while (!req.complete)
pmu_poll();
timeout = 100000;
while (!req.complete) {
if (--timeout < 0) {
- printk(KERN_ERR "pmu_reset_bus (reset): no response from PMU\n");
- return 0;
+ printk(KERN_ERR "pmu_adb_reset_bus (reset): no response from PMU\n");
+ return -EIO;
}
udelay(10);
pmu_poll();
@@ -369,7 +437,7 @@
if (save_autopoll != 0)
pmu_adb_autopoll(save_autopoll);
- return 1;
+ return 0;
}
/* Construct and send a pmu request */
@@ -380,6 +448,9 @@
va_list list;
int i;
+ if (vias == NULL)
+ return -ENXIO;
+
if (nbytes < 0 || nbytes > 32) {
printk(KERN_ERR "pmu_request: bad nbytes (%d)\n", nbytes);
req->complete = 1;
@@ -400,57 +471,6 @@
return pmu_queue_request(req);
}
-/*
- * This procedure handles requests written to /dev/adb where the
- * first byte is CUDA_PACKET or PMU_PACKET. For CUDA_PACKET, we
- * emulate a few CUDA requests.
- */
-int __openfirmware
-pmu_send_request(struct adb_request *req)
-{
- int i;
-
- switch (req->data[0]) {
- case PMU_PACKET:
- for (i = 0; i < req->nbytes - 1; ++i)
- req->data[i] = req->data[i+1];
- --req->nbytes;
- if (pmu_data_len[req->data[0]][1] != 0) {
- req->reply[0] = ADB_RET_OK;
- req->reply_len = 1;
- } else
- req->reply_len = 0;
- return pmu_queue_request(req);
- case CUDA_PACKET:
- switch (req->data[1]) {
- case CUDA_GET_TIME:
- if (req->nbytes != 2)
- break;
- req->data[0] = PMU_READ_RTC;
- req->nbytes = 1;
- req->reply_len = 3;
- req->reply[0] = CUDA_PACKET;
- req->reply[1] = 0;
- req->reply[2] = CUDA_GET_TIME;
- return pmu_queue_request(req);
- case CUDA_SET_TIME:
- if (req->nbytes != 6)
- break;
- req->data[0] = PMU_SET_RTC;
- req->nbytes = 5;
- for (i = 1; i <= 4; ++i)
- req->data[i] = req->data[i+1];
- req->reply_len = 3;
- req->reply[0] = CUDA_PACKET;
- req->reply[1] = 0;
- req->reply[2] = CUDA_SET_TIME;
- return pmu_queue_request(req);
- }
- break;
- }
- return -EINVAL;
-}
-
int __openfirmware
pmu_queue_request(struct adb_request *req)
{
@@ -737,7 +757,7 @@
{
struct adb_request req;
- if (adb_hardware != ADB_VIAPMU)
+ if (vias == NULL)
return ;
if (on) {
@@ -780,7 +800,7 @@
{
int bright;
- if (adb_hardware != ADB_VIAPMU)
+ if (vias == NULL)
return ;
backlight_level = level;
@@ -807,7 +827,7 @@
{
struct adb_request req;
- if (adb_hardware != ADB_VIAPMU)
+ if (vias == NULL)
return ;
pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |
@@ -860,6 +880,11 @@
;
}
+int
+pmu_present(void)
+{
+ return (adb_controller && (adb_controller->kind == ADB_VIAPMU) && vias);
+}
#ifdef CONFIG_PMAC_PBOOK
@@ -1104,3 +1129,4 @@
misc_register(&pmu_device);
}
#endif /* CONFIG_PMAC_PBOOK */
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)