From patchwork Tue Jul 21 16:45:19 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: some more i945 patches Date: Tue, 21 Jul 2009 16:45:19 -0000 From: Stefan Reinauer X-Patchwork-Id: 58 Message-Id: <4A65F09F.4000308@coresystems.de> To: Coreboot I'm pushing out a number of i945 patches in order to get more public input and testing on the i945 chipset port and in order to keep some structural changes (XSDT support et al) from bit-rotting. See patches Stefan Acked-by: Peter Stuge Acked-by: Carl-Daniel Hailfinger Rewrite keyboard driver to actually wait time in ms as specified in the specs, rather than doing inexact and slow idle loops. Also improve error reporting in case of problems Signed-off-by: Stefan Reinauer --- src/pc80/keyboard.c (.../branches/upstream/coreboot-v2) +++ src/pc80/keyboard.c (.../trunk/coreboot-v2) @@ -1,8 +1,9 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2009 coresystems GmbH * Copyright (C) 2008 Advanced Micro Devices, Inc. - * Copyright (C) ???? Ollie Lo + * Copyright (C) 2003 Ollie Lo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,16 +24,20 @@ #include #include #include +#include +/* Wait 200ms for keyboard controller answers */ +#define KBC_TIMEOUT_IN_MS 200 + static int kbc_input_buffer_empty(void) { u32 timeout; - for(timeout = 1000000; timeout && (inb(0x64) & 0x02); timeout--) { - inb(0x80); + for(timeout = KBC_TIMEOUT_IN_MS; timeout && (inb(0x64) & 0x02); timeout--) { + mdelay(1); } if (!timeout) { - printk_err("Unexpected Keyboard controller input buffer full\n"); + printk_warning("Unexpected Keyboard controller input buffer full\n"); } return !!timeout; } @@ -41,12 +46,12 @@ static int kbc_output_buffer_full(void) { u32 timeout; - for(timeout = 1000000; timeout && ((inb(0x64) & 0x01) == 0); timeout--) { - inb(0x80); + for(timeout = KBC_TIMEOUT_IN_MS; timeout && ((inb(0x64) & 0x01) == 0); timeout--) { + mdelay(1); } if (!timeout) { - printk_err("Keyboard controller output buffer result timeout\n"); + printk_warning("Keyboard controller output buffer result timeout\n"); } return !!timeout; } @@ -55,7 +60,8 @@ static int kbc_cleanup_buffers(void) { u32 timeout; - for(timeout = 1000000; timeout && (inb(0x64) & 0x03); timeout--) { + for(timeout = KBC_TIMEOUT_IN_MS; timeout && (inb(0x64) & 0x03); timeout--) { + mdelay(1); inb(0x60); } @@ -75,7 +81,11 @@ do { if (!kbc_input_buffer_empty()) return 0; outb(command, 0x60); - if (!kbc_output_buffer_full()) return 0; + if (!kbc_output_buffer_full()) { + printk_err("Could not send keyboard command %02x\n", + command); + return 0; + } regval = inb(0x60); --resend; } while (regval == 0xFE && resend > 0); @@ -93,18 +103,21 @@ /* clean up any junk that might have been in the kbc */ if (!kbc_cleanup_buffers()) return; - /* reset/self test 8042 - send cmd 0xAA, */ + /* reset/self test 8042 - send cmd 0xAA */ if (!kbc_input_buffer_empty()) return; outb(0xAA, 0x64); - if (!kbc_output_buffer_full()) return; + if (!kbc_output_buffer_full()) { + printk_err("Could not reset keyboard controller.\n"); + return; + } /* read self-test result, 0x55 is returned in the output buffer (0x60) */ if ((regval = inb(0x60) != 0x55)) { - printk_err("Keyboard Controller selftest failed: 0x%x\n", regval); + printk_err("Keyboard Controller self-test failed: 0x%x\n", regval); return; } - /* Enable keyboard interface - No IRQ*/ + /* Enable keyboard interface - No IRQ */ resend = 10; regval = 0; do { @@ -112,8 +125,11 @@ outb(0x60, 0x64); if (!kbc_input_buffer_empty()) return; outb(0x20, 0x60); /* send cmd: enable keyboard */ - if ((inb(0x64) & 0x01)) { + if (kbc_output_buffer_full()) { regval = inb(0x60); + } else { + printk_info("Timeout while enabling keyboard. (No keyboard present?)\n"); + regval = inb(0x60); /* Better than 0 ? */ } --resend; } while (regval == 0xFE && resend > 0); @@ -127,7 +143,11 @@ printk_err("Keyboard selftest failed ACK: 0x%x\n", regval); return; } - if (!kbc_output_buffer_full()) return; + if (!kbc_output_buffer_full()) { + printk_err("Timeout waiting for keyboard after reset.\n"); + return; + } + regval = inb(0x60); if (regval != 0xAA) { printk_err("Keyboard selftest failed: 0x%x\n", regval); @@ -174,7 +194,7 @@ outb(0x60, 0x64); if (!kbc_input_buffer_empty()) return; outb(0x61, 0x60); /* send cmd: enable keyboard and IRQ 1 */ - if ((inb(0x64) & 0x01)) { + if (kbc_output_buffer_full()) { regval = inb(0x60); } --resend;