Lines Matching +full:versatile +full:- +full:pci

1 // SPDX-License-Identifier: GPL-2.0
5 * The VIA (versatile interface adapter) interfaces to the PMU,
9 * to the keyboard and mouse, as well as the non-volatile RAM
13 * Copyright (C) 2001-2002 Benjamin Herrenschmidt
14 * Copyright (C) 2006-2007 Johannes Berg
17 * - Cleanup atomically disabling reply to PMU events after
30 #include <linux/pci.h>
72 #include "via-pmu-event.h"
82 /* VIA registers - spaced 0x200 bytes apart */
84 #define B 0 /* B-side data */
85 #define A RS /* A-side data */
86 #define DIRB (2*RS) /* B-side direction (1=output) */
87 #define DIRA (3*RS) /* A-side direction (1=output) */
99 #define ANH (15*RS) /* A-side data, no handshake */
161 static int gpio_irq_enabled = -1;
237 * - the number of data bytes to be sent with the command, or -1
239 * - the number of response bytes which the PMU will return, or
240 * -1 if it will send a length byte.
244 /*00*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
245 /*08*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
246 /*10*/ { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
247 /*18*/ { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0, 0},
248 /*20*/ {-1, 0},{ 0, 0},{ 2, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},
249 /*28*/ { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0,-1},
250 /*30*/ { 4, 0},{20, 0},{-1, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
251 /*38*/ { 0, 4},{ 0,20},{ 2,-1},{ 2, 1},{ 3,-1},{-1,-1},{-1,-1},{ 4, 0},
252 /*40*/ { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
253 /*48*/ { 0, 1},{ 0, 1},{-1,-1},{ 1, 0},{ 1, 0},{-1,-1},{-1,-1},{-1,-1},
254 /*50*/ { 1, 0},{ 0, 0},{ 2, 0},{ 2, 0},{-1, 0},{ 1, 0},{ 3, 0},{ 1, 0},
255 /*58*/ { 0, 1},{ 1, 0},{ 0, 2},{ 0, 2},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},
256 /*60*/ { 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
257 /*68*/ { 0, 3},{ 0, 3},{ 0, 2},{ 0, 8},{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},
258 /*70*/ { 1, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
259 /*78*/ { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{ 5, 1},{ 4, 1},{ 4, 1},
260 /*80*/ { 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
261 /*88*/ { 0, 5},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
262 /*90*/ { 1, 0},{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
263 /*98*/ { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
264 /*a0*/ { 2, 0},{ 2, 0},{ 2, 0},{ 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},
265 /*a8*/ { 1, 1},{ 1, 0},{ 3, 0},{ 2, 0},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
266 /*b0*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
267 /*b8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
268 /*c0*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
269 /*c8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
270 /*d0*/ { 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
271 /*d8*/ { 1, 1},{ 1, 1},{-1,-1},{-1,-1},{ 0, 1},{ 0,-1},{-1,-1},{-1,-1},
272 /*e0*/ {-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{ 4, 0},{-1, 0},{-1, 0},
273 /*e8*/ { 3,-1},{-1,-1},{ 0, 1},{-1,-1},{ 0,-1},{-1,-1},{-1,-1},{ 0, 0},
274 /*f0*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
275 /*f8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
295 vias = of_find_node_by_name(NULL, "via-pmu"); in find_via_pmu()
301 printk(KERN_ERR "via-pmu: Error getting \"reg\" property !\n"); in find_via_pmu()
313 if (of_node_name_eq(vias->parent, "ohare") || in find_via_pmu()
314 of_device_is_compatible(vias->parent, "ohare")) in find_via_pmu()
316 else if (of_device_is_compatible(vias->parent, "paddington")) in find_via_pmu()
318 else if (of_device_is_compatible(vias->parent, "heathrow")) in find_via_pmu()
320 else if (of_device_is_compatible(vias->parent, "Keylargo") in find_via_pmu()
321 || of_device_is_compatible(vias->parent, "K2-Keylargo")) { in find_via_pmu()
342 printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n"); in find_via_pmu()
350 printk(KERN_ERR "via-pmu: Can't map address !\n"); in find_via_pmu()
378 if (macintosh_config->adb_type != MAC_ADB_PB2) in find_via_pmu()
404 return pmu_state == uninitialized ? -ENODEV : 0; in pmu_probe()
409 return pmu_state == uninitialized ? -ENODEV : 0; in pmu_init()
425 return -ENODEV; in via_pmu_start()
432 printk(KERN_ERR "via-pmu: can't map interrupt\n"); in via_pmu_start()
433 return -ENODEV; in via_pmu_start()
440 "VIA-PMU", (void *)0)) { in via_pmu_start()
441 printk(KERN_ERR "via-pmu: can't request irq %d\n", irq); in via_pmu_start()
442 return -ENODEV; in via_pmu_start()
446 gpio_node = of_find_node_by_name(NULL, "extint-gpio1"); in via_pmu_start()
449 "pmu-interrupt"); in via_pmu_start()
468 "VIA-PMU-SR", NULL)) { in via_pmu_start()
470 return -ENODEV; in via_pmu_start()
473 "VIA-PMU-CL", NULL)) { in via_pmu_start()
476 return -ENODEV; in via_pmu_start()
505 return -ENODEV; in via_pmu_dev_init()
529 of_find_node_by_name(NULL, "power-mgt"); in via_pmu_dev_init()
532 prim_info = of_get_property(prim, "prim-info", NULL); in via_pmu_dev_init()
582 if (--timeout < 0) { in init_pmu()
594 if (--timeout < 0) { in init_pmu()
625 printk(KERN_INFO "via-pmu: Server Mode is %s\n", in init_pmu()
666 * is inspired from the implementation in gkrellm-pmu
688 * --tkoba in done_battery_state_ohare()
697 if (req->reply[0] & 0x01) in done_battery_state_ohare()
714 if (req->reply[0] & 0x04) { in done_battery_state_ohare()
716 if (req->reply[0] & 0x02) in done_battery_state_ohare()
718 vb = (req->reply[1] << 8) | req->reply[2]; in done_battery_state_ohare()
720 amperage = req->reply[5]; in done_battery_state_ohare()
721 if ((req->reply[0] & 0x01) == 0) { in done_battery_state_ohare()
723 vb += ((amperage - 200) * 15)/100; in done_battery_state_ohare()
724 } else if (req->reply[0] & 0x02) { in done_battery_state_ohare()
729 if (req->reply[0] & 0x40) { in done_battery_state_ohare()
730 pcharge = (req->reply[6] << 8) + req->reply[7]; in done_battery_state_ohare()
734 pcharge = 100 - pcharge / lmax; in done_battery_state_ohare()
743 amperage = -amperage; in done_battery_state_ohare()
784 if (req->reply[1] & 0x01) in done_battery_state_smart()
792 if (req->reply[1] & 0x04) { in done_battery_state_smart()
794 switch(req->reply[0]) { in done_battery_state_smart()
796 case 4: capa = req->reply[2]; in done_battery_state_smart()
797 max = req->reply[3]; in done_battery_state_smart()
798 amperage = *((signed char *)&req->reply[4]); in done_battery_state_smart()
799 voltage = req->reply[5]; in done_battery_state_smart()
801 case 5: capa = (req->reply[2] << 8) | req->reply[3]; in done_battery_state_smart()
802 max = (req->reply[4] << 8) | req->reply[5]; in done_battery_state_smart()
803 amperage = *((signed short *)&req->reply[6]); in done_battery_state_smart()
804 voltage = (req->reply[8] << 8) | req->reply[9]; in done_battery_state_smart()
808 "len: %d, %4ph\n", req->reply_len, in done_battery_state_smart()
809 req->reply); in done_battery_state_smart()
814 if ((req->reply[1] & 0x01) && (amperage > 0)) in done_battery_state_smart()
823 if ((req->reply[1] & 0x01) && (amperage > 0)) in done_battery_state_smart()
825 = ((max-capa) * 3600) / amperage; in done_battery_state_smart()
828 = (capa * 3600) / (-amperage); in done_battery_state_smart()
868 "PC-Card eject button", in pmu_irqstats_proc_show()
890 long batnum = (long)m->private; in pmu_battery_proc_show()
906 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) in pmu_options_proc_show()
928 return -EINVAL; in pmu_options_proc_write()
932 return -EFAULT; in pmu_options_proc_write()
945 return -EINVAL; in pmu_options_proc_write()
951 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) in pmu_options_proc_write()
980 req->complete = 1; in pmu_send_request()
981 return -ENXIO; in pmu_send_request()
984 ret = -EINVAL; in pmu_send_request()
986 switch (req->data[0]) { in pmu_send_request()
988 for (i = 0; i < req->nbytes - 1; ++i) in pmu_send_request()
989 req->data[i] = req->data[i+1]; in pmu_send_request()
990 --req->nbytes; in pmu_send_request()
991 if (pmu_data_len[req->data[0]][1] != 0) { in pmu_send_request()
992 req->reply[0] = ADB_RET_OK; in pmu_send_request()
993 req->reply_len = 1; in pmu_send_request()
995 req->reply_len = 0; in pmu_send_request()
999 switch (req->data[1]) { in pmu_send_request()
1001 if (req->nbytes != 2) in pmu_send_request()
1003 req->data[0] = PMU_READ_RTC; in pmu_send_request()
1004 req->nbytes = 1; in pmu_send_request()
1005 req->reply_len = 3; in pmu_send_request()
1006 req->reply[0] = CUDA_PACKET; in pmu_send_request()
1007 req->reply[1] = 0; in pmu_send_request()
1008 req->reply[2] = CUDA_GET_TIME; in pmu_send_request()
1012 if (req->nbytes != 6) in pmu_send_request()
1014 req->data[0] = PMU_SET_RTC; in pmu_send_request()
1015 req->nbytes = 5; in pmu_send_request()
1017 req->data[i] = req->data[i+1]; in pmu_send_request()
1018 req->reply_len = 3; in pmu_send_request()
1019 req->reply[0] = CUDA_PACKET; in pmu_send_request()
1020 req->reply[1] = 0; in pmu_send_request()
1021 req->reply[2] = CUDA_SET_TIME; in pmu_send_request()
1028 return -ENXIO; in pmu_send_request()
1029 for (i = req->nbytes - 1; i > 1; --i) in pmu_send_request()
1030 req->data[i+2] = req->data[i]; in pmu_send_request()
1031 req->data[3] = req->nbytes - 2; in pmu_send_request()
1032 req->data[2] = pmu_adb_flags; in pmu_send_request()
1033 /*req->data[1] = req->data[1];*/ in pmu_send_request()
1034 req->data[0] = PMU_ADB_CMD; in pmu_send_request()
1035 req->nbytes += 2; in pmu_send_request()
1036 req->reply_expected = 1; in pmu_send_request()
1037 req->reply_len = 0; in pmu_send_request()
1042 req->complete = 1; in pmu_send_request()
1047 while (!req->complete) in pmu_send_request()
1074 return -ENXIO; in pmu_adb_autopoll()
1087 return -ENXIO; in pmu_adb_reset_bus()
1103 return -EIO; in pmu_adb_reset_bus()
1123 return -ENXIO; in pmu_request()
1127 req->complete = 1; in pmu_request()
1128 return -EINVAL; in pmu_request()
1130 req->nbytes = nbytes; in pmu_request()
1131 req->done = done; in pmu_request()
1134 req->data[i] = va_arg(list, int); in pmu_request()
1136 req->reply_len = 0; in pmu_request()
1137 req->reply_expected = 0; in pmu_request()
1148 req->complete = 1; in pmu_queue_request()
1149 return -ENXIO; in pmu_queue_request()
1151 if (req->nbytes <= 0) { in pmu_queue_request()
1152 req->complete = 1; in pmu_queue_request()
1155 nsend = pmu_data_len[req->data[0]][0]; in pmu_queue_request()
1156 if (nsend >= 0 && req->nbytes != nsend + 1) { in pmu_queue_request()
1157 req->complete = 1; in pmu_queue_request()
1158 return -EINVAL; in pmu_queue_request()
1161 req->next = NULL; in pmu_queue_request()
1162 req->sent = 0; in pmu_queue_request()
1163 req->complete = 0; in pmu_queue_request()
1167 last_req->next = req; in pmu_queue_request()
1188 if (--timeout < 0) { in wait_for_ack()
1197 * PCI is flushed immediately */
1219 void (*done)(struct adb_request *) = req->done; in pmu_done()
1221 req->complete = 1; in pmu_done()
1223 * struct request will survive to setting req->complete to 1 in pmu_done()
1238 || (/*req->reply_expected && */req_awaiting_reply)) in pmu_start()
1243 data_len = pmu_data_len[req->data[0]][0]; in pmu_start()
1250 send_byte(req->data[0]); in pmu_start()
1283 while((pmu_state != idle && pmu_state != locked) || !req->complete) in pmu_wait_complete()
1332 pmu_suspended--; in pmu_resume()
1379 idx = ffs(ints) - 1; in pmu_handle_data()
1386 * on the Pismo. Still investigating... --BenH in pmu_handle_data()
1398 req->reply_len = 0; in pmu_handle_data()
1400 memcpy(req->reply, data + 1, len - 1); in pmu_handle_data()
1401 req->reply_len = len - 1; in pmu_handle_data()
1424 adb_input(data+1, len-1, 1); in pmu_handle_data()
1441 if ((--query_batt_timer) == 0) { in pmu_handle_data()
1492 data_len = req->nbytes - 1; in pmu_sr_intr()
1497 send_byte(req->data[data_index++]); in pmu_sr_intr()
1500 req->sent = 1; in pmu_sr_intr()
1501 data_len = pmu_data_len[req->data[0]][1]; in pmu_sr_intr()
1504 current_req = req->next; in pmu_sr_intr()
1505 if (req->reply_expected) in pmu_sr_intr()
1512 reply_ptr = req->reply + req->reply_len; in pmu_sr_intr()
1519 data_len = -1; in pmu_sr_intr()
1531 if (data_len == -1) { in pmu_sr_intr()
1554 current_req = req->next; in pmu_sr_intr()
1555 req->reply_len += data_index; in pmu_sr_intr()
1556 if (req->data[0] == PMU_SLEEP || req->data[0] == PMU_CPU_SPEED) in pmu_sr_intr()
1577 int int_data = -1; in via_pmu_interrupt()
1657 --disable_poll; in via_pmu_interrupt()
1672 int_data = -1; in via_pmu_interrupt()
1727 /* Offset between Unix time (1970-based) and Mac time (1904-based) */
1742 return (time64_t)now - RTC_OFFSET; in pmu_get_time()
1753 return -ENXIO; in pmu_set_rtc_time()
1871 return -ENODEV; in powerbook_sleep_grackle()
1881 save_l2cr = _get_L2CR(); /* (returns -1 if not available) */ in powerbook_sleep_grackle()
1900 /* Call low-level ASM sleep handler */ in powerbook_sleep_grackle()
1922 switch_mmu_context(NULL, current->active_mm, NULL); in powerbook_sleep_grackle()
1945 if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) { in powerbook_sleep_Core99()
1947 return -ENOSYS; in powerbook_sleep_Core99()
1951 return -EAGAIN; in powerbook_sleep_Core99()
1967 save_l3cr = _get_L3CR(); /* (returns -1 if not available) */ in powerbook_sleep_Core99()
1968 save_l2cr = _get_L2CR(); /* (returns -1 if not available) */ in powerbook_sleep_Core99()
1985 /* Call low-level ASM sleep handler */ in powerbook_sleep_Core99()
2011 switch_mmu_context(NULL, current->active_mm, NULL); in powerbook_sleep_Core99()
2048 return -ENOMEM; in powerbook_sleep_3400()
2053 for (i = 0x403f; i >= 0x4000; --i) { in powerbook_sleep_3400()
2123 if (len > sizeof(pp->rb_buf[0].data)) in pmu_pass_intr()
2124 len = sizeof(pp->rb_buf[0].data); in pmu_pass_intr()
2126 for (list = &all_pmu_pvt; (list = list->next) != &all_pmu_pvt; ) { in pmu_pass_intr()
2128 spin_lock(&pp->lock); in pmu_pass_intr()
2129 i = pp->rb_put + 1; in pmu_pass_intr()
2132 if (i != pp->rb_get) { in pmu_pass_intr()
2133 struct rb_entry *rp = &pp->rb_buf[pp->rb_put]; in pmu_pass_intr()
2134 rp->len = len; in pmu_pass_intr()
2135 memcpy(rp->data, data, len); in pmu_pass_intr()
2136 pp->rb_put = i; in pmu_pass_intr()
2137 wake_up_interruptible(&pp->wait); in pmu_pass_intr()
2139 spin_unlock(&pp->lock); in pmu_pass_intr()
2152 return -ENOMEM; in pmu_open()
2153 pp->rb_get = pp->rb_put = 0; in pmu_open()
2154 spin_lock_init(&pp->lock); in pmu_open()
2155 init_waitqueue_head(&pp->wait); in pmu_open()
2159 pp->backlight_locker = 0; in pmu_open()
2161 list_add(&pp->list, &all_pmu_pvt); in pmu_open()
2163 file->private_data = pp; in pmu_open()
2172 struct pmu_private *pp = file->private_data; in pmu_read()
2178 return -EINVAL; in pmu_read()
2180 spin_lock_irqsave(&pp->lock, flags); in pmu_read()
2181 add_wait_queue(&pp->wait, &wait); in pmu_read()
2185 ret = -EAGAIN; in pmu_read()
2186 if (pp->rb_get != pp->rb_put) { in pmu_read()
2187 int i = pp->rb_get; in pmu_read()
2188 struct rb_entry *rp = &pp->rb_buf[i]; in pmu_read()
2189 ret = rp->len; in pmu_read()
2190 spin_unlock_irqrestore(&pp->lock, flags); in pmu_read()
2193 if (ret > 0 && copy_to_user(buf, rp->data, ret)) in pmu_read()
2194 ret = -EFAULT; in pmu_read()
2197 spin_lock_irqsave(&pp->lock, flags); in pmu_read()
2198 pp->rb_get = i; in pmu_read()
2202 if (file->f_flags & O_NONBLOCK) in pmu_read()
2204 ret = -ERESTARTSYS; in pmu_read()
2207 spin_unlock_irqrestore(&pp->lock, flags); in pmu_read()
2209 spin_lock_irqsave(&pp->lock, flags); in pmu_read()
2212 remove_wait_queue(&pp->wait, &wait); in pmu_read()
2213 spin_unlock_irqrestore(&pp->lock, flags); in pmu_read()
2228 struct pmu_private *pp = filp->private_data; in pmu_fpoll()
2234 poll_wait(filp, &pp->wait, wait); in pmu_fpoll()
2235 spin_lock_irqsave(&pp->lock, flags); in pmu_fpoll()
2236 if (pp->rb_get != pp->rb_put) in pmu_fpoll()
2238 spin_unlock_irqrestore(&pp->lock, flags); in pmu_fpoll()
2245 struct pmu_private *pp = file->private_data; in pmu_release()
2249 file->private_data = NULL; in pmu_release()
2251 list_del(&pp->list); in pmu_release()
2255 if (pp->backlight_locker) in pmu_release()
2302 return -ENOSYS; in powerbook_sleep()
2329 && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0); in pmu_sleep_valid()
2355 int error = -EINVAL; in pmu_ioctl()
2361 return -EACCES; in pmu_ioctl()
2364 if (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) < 0) in pmu_ioctl()
2395 struct pmu_private *pp = filp->private_data; in pmu_ioctl()
2397 if (pp->backlight_locker) in pmu_ioctl()
2400 pp->backlight_locker = 1; in pmu_ioctl()
2460 return -ENOIOCTLCMD; in compat_pmu_ioctl()
2488 printk(KERN_ERR "via-pmu: cannot register misc device.\n"); in pmu_device_init()
2532 req->complete = 1; in pmu_polled_request()
2533 c = req->data[0]; in pmu_polled_request()
2535 if (l >= 0 && req->nbytes != l + 1) in pmu_polled_request()
2536 return -EINVAL; in pmu_polled_request()
2546 l = req->nbytes - 1; in pmu_polled_request()
2550 polled_send_byte(req->data[i]); in pmu_polled_request()
2556 req->reply[i + req->reply_len] = polled_recv_byte(); in pmu_polled_request()
2558 if (req->done) in pmu_polled_request()
2559 (*req->done)(req); in pmu_polled_request()
2572 for (; n > 0; --n) { in pmu_blink()