From fb2ce3c005ede30b65b891c58ff56398df6089f8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:50:10 -0500 Subject: Sonypi: make sure that input_work is not running when unloading the module; submit/retrieve key release data into/from input_fifo in one shot. Signed-off-by: Dmitry Torokhov --- drivers/char/sonypi.c | 122 ++++++++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 59 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index fd042060809..983915bf87f 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -439,6 +439,11 @@ static struct { { 0, 0 }, }; +struct sonypi_keypress { + struct input_dev *dev; + int key; +}; + static struct sonypi_device { struct pci_dev *dev; struct platform_device *pdev; @@ -710,22 +715,61 @@ static void sonypi_setbluetoothpower(u8 state) static void input_keyrelease(void *data) { - struct input_dev *input_dev; - int key; - - while (1) { - if (kfifo_get(sonypi_device.input_fifo, - (unsigned char *)&input_dev, - sizeof(input_dev)) != sizeof(input_dev)) - return; - if (kfifo_get(sonypi_device.input_fifo, - (unsigned char *)&key, - sizeof(key)) != sizeof(key)) - return; + struct sonypi_keypress kp; + while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, + sizeof(kp)) == sizeof(kp)) { msleep(10); - input_report_key(input_dev, key, 0); - input_sync(input_dev); + input_report_key(kp.dev, kp.key, 0); + input_sync(kp.dev); + } +} + +static void sonypi_report_input_event(u8 event) +{ + struct input_dev *jog_dev = &sonypi_device.input_jog_dev; + struct input_dev *key_dev = &sonypi_device.input_key_dev; + struct sonypi_keypress kp = { NULL }; + int i; + + switch (event) { + case SONYPI_EVENT_JOGDIAL_UP: + case SONYPI_EVENT_JOGDIAL_UP_PRESSED: + input_report_rel(jog_dev, REL_WHEEL, 1); + input_sync(jog_dev); + break; + + case SONYPI_EVENT_JOGDIAL_DOWN: + case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: + input_report_rel(jog_dev, REL_WHEEL, -1); + input_sync(jog_dev); + break; + + case SONYPI_EVENT_JOGDIAL_PRESSED: + kp.key = BTN_MIDDLE; + kp.dev = jog_dev; + break; + + case SONYPI_EVENT_FNKEY_RELEASED: + /* Nothing, not all VAIOs generate this event */ + break; + + default: + for (i = 0; sonypi_inputkeys[i].sonypiev; i++) + if (event == sonypi_inputkeys[i].sonypiev) { + kp.dev = key_dev; + kp.key = sonypi_inputkeys[i].inputev; + break; + } + break; + } + + if (kp.dev) { + input_report_key(kp.dev, kp.key, 1); + input_sync(kp.dev); + kfifo_put(sonypi_device.input_fifo, + (unsigned char *)&kp, sizeof(kp)); + schedule_work(&sonypi_device.input_work); } } @@ -768,51 +812,8 @@ found: printk(KERN_INFO "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); - if (useinput) { - struct input_dev *input_jog_dev = &sonypi_device.input_jog_dev; - struct input_dev *input_key_dev = &sonypi_device.input_key_dev; - switch (event) { - case SONYPI_EVENT_JOGDIAL_UP: - case SONYPI_EVENT_JOGDIAL_UP_PRESSED: - input_report_rel(input_jog_dev, REL_WHEEL, 1); - break; - case SONYPI_EVENT_JOGDIAL_DOWN: - case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: - input_report_rel(input_jog_dev, REL_WHEEL, -1); - break; - case SONYPI_EVENT_JOGDIAL_PRESSED: { - int key = BTN_MIDDLE; - input_report_key(input_jog_dev, key, 1); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&input_jog_dev, - sizeof(input_jog_dev)); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&key, sizeof(key)); - break; - } - case SONYPI_EVENT_FNKEY_RELEASED: - /* Nothing, not all VAIOs generate this event */ - break; - } - input_sync(input_jog_dev); - - for (i = 0; sonypi_inputkeys[i].sonypiev; i++) { - int key; - - if (event != sonypi_inputkeys[i].sonypiev) - continue; - - key = sonypi_inputkeys[i].inputev; - input_report_key(input_key_dev, key, 1); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&input_key_dev, - sizeof(input_key_dev)); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&key, sizeof(key)); - } - input_sync(input_key_dev); - schedule_work(&sonypi_device.input_work); - } + if (useinput) + sonypi_report_input_event(event); kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); @@ -1337,6 +1338,9 @@ static void __devexit sonypi_remove(void) { sonypi_disable(); + synchronize_sched(); /* Allow sonypi interrupt to complete. */ + flush_scheduled_work(); + platform_device_unregister(sonypi_device.pdev); if (useinput) { -- cgit v1.2.3 From 5b6271bda42be8edb77fbd588621cc09199fa7fb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 Jun 2005 00:50:38 -0500 Subject: Input: make name, phys and uniq be 'const char *' because once set noone should attempt to change them. Signed-off-by: Dmitry Torokhov --- drivers/char/sonypi.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 983915bf87f..cefbe985e55 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1228,14 +1228,7 @@ static int __devinit sonypi_probe(void) sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE); sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL); - sonypi_device.input_jog_dev.name = - kmalloc(sizeof(SONYPI_JOG_INPUTNAME), GFP_KERNEL); - if (!sonypi_device.input_jog_dev.name) { - printk(KERN_ERR "sonypi: kmalloc failed\n"); - ret = -ENOMEM; - goto out_inkmallocinput1; - } - sprintf(sonypi_device.input_jog_dev.name, SONYPI_JOG_INPUTNAME); + sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME; sonypi_device.input_jog_dev.id.bustype = BUS_ISA; sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY; @@ -1249,14 +1242,7 @@ static int __devinit sonypi_probe(void) if (sonypi_inputkeys[i].inputev) set_bit(sonypi_inputkeys[i].inputev, sonypi_device.input_key_dev.keybit); - sonypi_device.input_key_dev.name = - kmalloc(sizeof(SONYPI_KEY_INPUTNAME), GFP_KERNEL); - if (!sonypi_device.input_key_dev.name) { - printk(KERN_ERR "sonypi: kmalloc failed\n"); - ret = -ENOMEM; - goto out_inkmallocinput2; - } - sprintf(sonypi_device.input_key_dev.name, SONYPI_KEY_INPUTNAME); + sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME; sonypi_device.input_key_dev.id.bustype = BUS_ISA; sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY; @@ -1314,11 +1300,7 @@ out_platformdev: kfifo_free(sonypi_device.input_fifo); out_infifo: input_unregister_device(&sonypi_device.input_key_dev); - kfree(sonypi_device.input_key_dev.name); -out_inkmallocinput2: input_unregister_device(&sonypi_device.input_jog_dev); - kfree(sonypi_device.input_jog_dev.name); -out_inkmallocinput1: free_irq(sonypi_device.irq, sonypi_irq); out_reqirq: release_region(sonypi_device.ioport1, sonypi_device.region_size); @@ -1345,9 +1327,7 @@ static void __devexit sonypi_remove(void) if (useinput) { input_unregister_device(&sonypi_device.input_key_dev); - kfree(sonypi_device.input_key_dev.name); input_unregister_device(&sonypi_device.input_jog_dev); - kfree(sonypi_device.input_jog_dev.name); kfifo_free(sonypi_device.input_fifo); } -- cgit v1.2.3 From 6e498c1080ae794a8dc788152002fb39994ae78b Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 12 Jul 2005 13:58:32 -0700 Subject: [PATCH] TB0219: add PCI IRQ initialization This patch adds PCI IRQ initialization to TB0219 driver. Signed-off-by: Yoichi Yuasa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tb0219.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/char') diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index 5413f290885..eb7058cbf01 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -24,6 +24,8 @@ #include #include +#include +#include MODULE_AUTHOR("Yoichi Yuasa "); MODULE_DESCRIPTION("TANBAC TB0219 base board driver"); @@ -266,6 +268,21 @@ static void tb0219_restart(char *command) tb0219_write(TB0219_RESET, 0); } +static void tb0219_pci_irq_init(void) +{ + /* PCI Slot 1 */ + vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, IRQ_LEVEL_LOW); + + /* PCI Slot 2 */ + vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, IRQ_LEVEL_LOW); + + /* PCI Slot 3 */ + vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW); +} + static int tb0219_probe(struct device *dev) { int retval; @@ -292,6 +309,8 @@ static int tb0219_probe(struct device *dev) old_machine_restart = _machine_restart; _machine_restart = tb0219_restart; + tb0219_pci_irq_init(); + if (major == 0) { major = retval; printk(KERN_INFO "TB0219: major number %d\n", major); -- cgit v1.2.3 From 030babac6ae54df64ae3bba4685ecb1d8d8dd8c3 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Fri, 15 Jul 2005 03:56:25 -0700 Subject: [PATCH] vt.c build fix Signed-off-by: Nishanth Aravamudan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/vt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/vt.c b/drivers/char/vt.c index d7aa7a29f67..30d96739fb2 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2796,7 +2796,7 @@ void do_blank_screen(int entering_gfx) return; if (vesa_off_interval) { - blank_state = blank_vesa_wait, + blank_state = blank_vesa_wait; mod_timer(&console_timer, jiffies + vesa_off_interval); } -- cgit v1.2.3 From a1287ba1ba810aae1f8b81e32560d5d3bf3ff9f0 Mon Sep 17 00:00:00 2001 From: Michal Ostrowski Date: Fri, 15 Jul 2005 03:56:33 -0700 Subject: [PATCH] rocket.c: Fix ldisc ref count handling If bailing out because there is nothing to receive in rp_do_receive(), tty_ldisc_deref is not called. Failure to do so increases the ref count and causes release_dev() to hang since it can't get the ref count to 0. Signed-off-by: Michal Ostrowski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/rocket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index f463d6baa68..5b1d3680c8a 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -355,7 +355,7 @@ static void rp_do_receive(struct r_port *info, ToRecv = space; if (ToRecv <= 0) - return; + goto done; /* * if status indicates there are errored characters in the @@ -437,6 +437,7 @@ static void rp_do_receive(struct r_port *info, } /* Push the data up to the tty layer */ ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); +done: tty_ldisc_deref(ld); } -- cgit v1.2.3 From 5ac7ba3ff599d66ffde182676f2e4fbcac61a2fe Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sun, 24 Jul 2005 00:50:03 -0500 Subject: Input: check keycodesize when adjusting keymaps When changing key mappings we need to make sure that the new keycode value can be stored in dev->keycodesize bytes. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7b19e02f112..523fd3c8bba 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -198,10 +198,10 @@ int setkeycode(unsigned int scancode, unsigned int keycode) if (scancode >= dev->keycodemax) return -EINVAL; - if (keycode > KEY_MAX) - return -EINVAL; if (keycode < 0 || keycode > KEY_MAX) return -EINVAL; + if (keycode >> (dev->keycodesize * 8)) + return -EINVAL; oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); -- cgit v1.2.3 From 4de8b9b76017365572f778332d74fe050d9c8c2a Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 11:51:06 -0600 Subject: [PATCH] Update sysrq-B to use emergency_restart() sysrq calls into the reboot path from an interrupt handler we can either push the code do into process context and call kernel_restart and get a clean reboot or we can simply reboot the machine, and increase our chances of actually rebooting. emergency_reboot() seems like the closest match to what we have previously done, and what we want. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- drivers/char/sysrq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 12d563c648f..feb25158c8e 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -115,7 +115,7 @@ static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, struct tty_struct *tty) { local_irq_enable(); - machine_restart(NULL); + emergency_restart(); } static struct sysrq_key_op sysrq_reboot_op = { -- cgit v1.2.3 From f82567e55fcd25bb7addf2cfd8b79f36f409dc2e Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 11:53:19 -0600 Subject: [PATCH] Fix watchdog drivers to call emergency_reboot() If a watchdog driver has decided it is time to reboot the system we know something is wrong and we are in interrupt context so emergency_reboot() is what we want. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- drivers/char/watchdog/eurotechwdt.c | 2 +- drivers/char/watchdog/softdog.c | 2 +- drivers/char/watchdog/wdt.c | 2 +- drivers/char/watchdog/wdt_pci.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index d10e554a14d..f1016e3ba11 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c @@ -167,7 +167,7 @@ static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) printk(KERN_CRIT "Would Reboot.\n"); #else printk(KERN_CRIT "Initiating system reboot.\n"); - machine_restart(NULL); + emergency_restart(NULL); #endif return IRQ_HANDLED; } diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c index 117903498a0..0d93097f06b 100644 --- a/drivers/char/watchdog/softdog.c +++ b/drivers/char/watchdog/softdog.c @@ -97,7 +97,7 @@ static void watchdog_fire(unsigned long data) else { printk(KERN_CRIT PFX "Initiating system reboot.\n"); - machine_restart(NULL); + emergency_restart(NULL); printk(KERN_CRIT PFX "Reboot didn't ?????\n"); } } diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c index 5684aa37988..1210ca0c425 100644 --- a/drivers/char/watchdog/wdt.c +++ b/drivers/char/watchdog/wdt.c @@ -266,7 +266,7 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) printk(KERN_CRIT "Would Reboot.\n"); #else printk(KERN_CRIT "Initiating system reboot.\n"); - machine_restart(NULL); + emergency_restart(); #endif #else printk(KERN_CRIT "Reset in 5ms.\n"); diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c index 7651deda928..c80cb77b92f 100644 --- a/drivers/char/watchdog/wdt_pci.c +++ b/drivers/char/watchdog/wdt_pci.c @@ -311,7 +311,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs) printk(KERN_CRIT PFX "Would Reboot.\n"); #else printk(KERN_CRIT PFX "Initiating system reboot.\n"); - machine_restart(NULL); + emergency_restart(NULL); #endif #else printk(KERN_CRIT PFX "Reset in 5ms.\n"); -- cgit v1.2.3 From 970d32443e3d0be57a5cdc3de3752f528424b73d Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 11:55:59 -0600 Subject: [PATCH] In hangcheck-timer.c call emergency_restart() If we've hung a clean reboot does not sound like a real option. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- drivers/char/hangcheck-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index 78e650fc5b4..81d811edf3c 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c @@ -173,7 +173,7 @@ static void hangcheck_fire(unsigned long data) } if (hangcheck_reboot) { printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); - machine_restart(NULL); + emergency_restart(); } else { printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n"); } -- cgit v1.2.3 From 68acc05d0120e19c850e1f347ee96055f5aa032f Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 26 Jul 2005 12:03:08 -0600 Subject: [PATCH] pcwd.c: Call kernel_power_off not machine_power_off The call appears to come from process context so kernel_power_off should be safe. And acpi_power_off won't necessarily work if you just call machine_power_off. Signed-off-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- drivers/char/watchdog/pcwd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 592dca10886..6ebce3f2ef9 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c @@ -344,7 +344,7 @@ static int pcwd_get_status(int *status) *status |= WDIOF_OVERHEAT; if (temp_panic) { printk (KERN_INFO PFX "Temperature overheat trip!\n"); - machine_power_off(); + kernel_power_off(); } } } else { @@ -355,7 +355,7 @@ static int pcwd_get_status(int *status) *status |= WDIOF_OVERHEAT; if (temp_panic) { printk (KERN_INFO PFX "Temperature overheat trip!\n"); - machine_power_off(); + kernel_power_off(); } } } -- cgit v1.2.3 From cc1d3a9a78f0f602fa1e7993dba4d16ad9781bc1 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 26 Jul 2005 21:41:37 -0700 Subject: [PATCH] eurotechwdt build fix drivers/char/watchdog/eurotechwdt.c:165: too many arguments to function `emergency_restart' Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/watchdog/eurotechwdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index f1016e3ba11..2a29a511df7 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c @@ -167,7 +167,7 @@ static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) printk(KERN_CRIT "Would Reboot.\n"); #else printk(KERN_CRIT "Initiating system reboot.\n"); - emergency_restart(NULL); + emergency_restart(); #endif return IRQ_HANDLED; } -- cgit v1.2.3 From 479d0f41e50646a618c43f69af7af31a8f748433 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 26 Jul 2005 21:41:38 -0700 Subject: [PATCH] softdog build fix drivers/char/watchdog/softdog.c:94: too many arguments to function `emergency_restart' Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/watchdog/softdog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c index 0d93097f06b..98c7578740e 100644 --- a/drivers/char/watchdog/softdog.c +++ b/drivers/char/watchdog/softdog.c @@ -97,7 +97,7 @@ static void watchdog_fire(unsigned long data) else { printk(KERN_CRIT PFX "Initiating system reboot.\n"); - emergency_restart(NULL); + emergency_restart(); printk(KERN_CRIT PFX "Reboot didn't ?????\n"); } } -- cgit v1.2.3 From b7343f01e326374e69666ca6001bdb6a7c67e9f7 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 27 Jul 2005 11:43:42 -0700 Subject: [PATCH] watchdog: add missing 0x in alim1535_wdt.c Usually the device IDs are given in hex. This one is a bit strange: it is without 0x in the first place and used with it some lines later. I suspect the first one to be the wrong. Signed-off-by: Rolf Eike Beer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/watchdog/alim1535_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index 35dcbf8be7d..0715fcf0aed 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c @@ -317,7 +317,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void */ static struct pci_device_id ali_pci_tbl[] = { - { PCI_VENDOR_ID_AL, 1535, PCI_ANY_ID, PCI_ANY_ID,}, + { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, { 0, }, }; MODULE_DEVICE_TABLE(pci, ali_pci_tbl); -- cgit v1.2.3 From bbaf364103cee15c895e2086723d0ad9ef47ae99 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 27 Jul 2005 11:43:56 -0700 Subject: [PATCH] drm: via: fix sparse warnings Signed-off-by: Alexey Dobriyan Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/drm/via_dma.c | 10 +++++----- drivers/char/drm/via_drm.h | 2 +- drivers/char/drm/via_ds.c | 4 ++-- drivers/char/drm/via_ds.h | 4 ++-- drivers/char/drm/via_map.c | 3 ++- drivers/char/drm/via_mm.c | 15 +++++++++------ drivers/char/drm/via_video.c | 3 ++- 7 files changed, 23 insertions(+), 18 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c index 82f83945162..4f60f7f4193 100644 --- a/drivers/char/drm/via_dma.c +++ b/drivers/char/drm/via_dma.c @@ -231,7 +231,7 @@ int via_dma_init(DRM_IOCTL_ARGS) drm_via_dma_init_t init; int retcode = 0; - DRM_COPY_FROM_USER_IOCTL(init, (drm_via_dma_init_t *) data, + DRM_COPY_FROM_USER_IOCTL(init, (drm_via_dma_init_t __user *) data, sizeof(init)); switch (init.func) { @@ -343,7 +343,7 @@ int via_cmdbuffer(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN( dev, filp ); - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t *) data, + DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data, sizeof(cmdbuf)); DRM_DEBUG("via cmdbuffer, buf %p size %lu\n", cmdbuf.buf, cmdbuf.size); @@ -386,7 +386,7 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN( dev, filp ); - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t *) data, + DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data, sizeof(cmdbuf)); DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf.buf, @@ -701,7 +701,7 @@ via_cmdbuf_size(DRM_IOCTL_ARGS) return DRM_ERR(EFAULT); } - DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t *) data, + DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t __user *) data, sizeof(d_siz)); @@ -735,7 +735,7 @@ via_cmdbuf_size(DRM_IOCTL_ARGS) } d_siz.size = tmp_size; - DRM_COPY_TO_USER_IOCTL((drm_via_cmdbuf_size_t *) data, d_siz, + DRM_COPY_TO_USER_IOCTL((drm_via_cmdbuf_size_t __user *) data, d_siz, sizeof(d_siz)); return ret; } diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h index 4588c9bd181..be346bb0a26 100644 --- a/drivers/char/drm/via_drm.h +++ b/drivers/char/drm/via_drm.h @@ -158,7 +158,7 @@ typedef struct _drm_via_dma_init { } drm_via_dma_init_t; typedef struct _drm_via_cmdbuffer { - char *buf; + char __user *buf; unsigned long size; } drm_via_cmdbuffer_t; diff --git a/drivers/char/drm/via_ds.c b/drivers/char/drm/via_ds.c index daf3df75a20..5c71e089246 100644 --- a/drivers/char/drm/via_ds.c +++ b/drivers/char/drm/via_ds.c @@ -133,7 +133,7 @@ memHeap_t *via_mmInit(int ofs, int size) PMemBlock blocks; if (size <= 0) - return 0; + return NULL; blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER); @@ -143,7 +143,7 @@ memHeap_t *via_mmInit(int ofs, int size) blocks->free = 1; return (memHeap_t *) blocks; } else - return 0; + return NULL; } static TMemBlock *SliceBlock(TMemBlock * p, diff --git a/drivers/char/drm/via_ds.h b/drivers/char/drm/via_ds.h index be9c7f9f1ae..d2bb9f37ca3 100644 --- a/drivers/char/drm/via_ds.h +++ b/drivers/char/drm/via_ds.h @@ -61,8 +61,8 @@ struct mem_block_t { struct mem_block_t *heap; int ofs, size; int align; - int free:1; - int reserved:1; + unsigned int free:1; + unsigned int reserved:1; }; typedef struct mem_block_t TMemBlock; typedef struct mem_block_t *PMemBlock; diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c index 0be829b6ec6..bb171139e73 100644 --- a/drivers/char/drm/via_map.c +++ b/drivers/char/drm/via_map.c @@ -95,7 +95,8 @@ int via_map_init(DRM_IOCTL_ARGS) DRM_DEBUG("%s\n", __FUNCTION__); - DRM_COPY_FROM_USER_IOCTL(init, (drm_via_init_t *) data, sizeof(init)); + DRM_COPY_FROM_USER_IOCTL(init, (drm_via_init_t __user *) data, + sizeof(init)); switch (init.func) { case VIA_INIT_MAP: diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c index c22712f44d4..13921f3c0ec 100644 --- a/drivers/char/drm/via_mm.c +++ b/drivers/char/drm/via_mm.c @@ -76,7 +76,8 @@ int via_agp_init(DRM_IOCTL_ARGS) { drm_via_agp_t agp; - DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t *) data, sizeof(agp)); + DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t __user *) data, + sizeof(agp)); AgpHeap = via_mmInit(agp.offset, agp.size); @@ -92,7 +93,7 @@ int via_fb_init(DRM_IOCTL_ARGS) { drm_via_fb_t fb; - DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t *) data, sizeof(fb)); + DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t __user *) data, sizeof(fb)); FBHeap = via_mmInit(fb.offset, fb.size); @@ -193,19 +194,20 @@ int via_mem_alloc(DRM_IOCTL_ARGS) { drm_via_mem_t mem; - DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t *) data, sizeof(mem)); + DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data, + sizeof(mem)); switch (mem.type) { case VIDEO: if (via_fb_alloc(&mem) < 0) return -EFAULT; - DRM_COPY_TO_USER_IOCTL((drm_via_mem_t *) data, mem, + DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, sizeof(mem)); return 0; case AGP: if (via_agp_alloc(&mem) < 0) return -EFAULT; - DRM_COPY_TO_USER_IOCTL((drm_via_mem_t *) data, mem, + DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, sizeof(mem)); return 0; } @@ -289,7 +291,8 @@ int via_mem_free(DRM_IOCTL_ARGS) { drm_via_mem_t mem; - DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t *) data, sizeof(mem)); + DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data, + sizeof(mem)); switch (mem.type) { diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c index 37a61c67b29..1e2d444587b 100644 --- a/drivers/char/drm/via_video.c +++ b/drivers/char/drm/via_video.c @@ -76,7 +76,8 @@ via_decoder_futex(DRM_IOCTL_ARGS) DRM_DEBUG("%s\n", __FUNCTION__); - DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t *) data, sizeof(fx)); + DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t __user *) data, + sizeof(fx)); if (fx.lock > VIA_NR_XVMC_LOCKS) return -EFAULT; -- cgit v1.2.3 From 4bfdf37830111321e2cd1fe0102dd776ce93194d Mon Sep 17 00:00:00 2001 From: Andrey Panin Date: Wed, 27 Jul 2005 11:43:58 -0700 Subject: [PATCH] consolidate CONFIG_WATCHDOG_NOWAYOUT handling Attached patch removes #ifdef CONFIG_WATCHDOG_NOWAYOUT mess duplicated in almost every watchdog driver and replaces it with common define in linux/watchdog.h. Signed-off-by: Andrey Panin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_watchdog.c | 6 +----- drivers/char/watchdog/acquirewdt.c | 7 +------ drivers/char/watchdog/advantechwdt.c | 7 +------ drivers/char/watchdog/alim1535_wdt.c | 7 +------ drivers/char/watchdog/alim7101_wdt.c | 7 +------ drivers/char/watchdog/eurotechwdt.c | 7 +------ drivers/char/watchdog/i8xx_tco.c | 7 +------ drivers/char/watchdog/ib700wdt.c | 7 +------ drivers/char/watchdog/indydog.c | 7 +------ drivers/char/watchdog/ixp2000_wdt.c | 6 +----- drivers/char/watchdog/ixp4xx_wdt.c | 6 +----- drivers/char/watchdog/machzwd.c | 7 +------ drivers/char/watchdog/mixcomwd.c | 7 +------ drivers/char/watchdog/pcwd.c | 7 +------ drivers/char/watchdog/pcwd_pci.c | 7 +------ drivers/char/watchdog/pcwd_usb.c | 7 +------ drivers/char/watchdog/s3c2410_wdt.c | 7 +------ drivers/char/watchdog/sa1100_wdt.c | 6 +----- drivers/char/watchdog/sbc60xxwdt.c | 7 +------ drivers/char/watchdog/sc1200wdt.c | 7 +------ drivers/char/watchdog/sc520_wdt.c | 7 +------ drivers/char/watchdog/scx200_wdt.c | 6 +----- drivers/char/watchdog/shwdt.c | 6 +----- drivers/char/watchdog/softdog.c | 7 +------ drivers/char/watchdog/w83627hf_wdt.c | 7 +------ drivers/char/watchdog/w83877f_wdt.c | 7 +------ drivers/char/watchdog/wafer5823wdt.c | 7 +------ drivers/char/watchdog/wdt.c | 7 +------ drivers/char/watchdog/wdt977.c | 7 +------ drivers/char/watchdog/wdt_pci.c | 7 +------ 30 files changed, 30 insertions(+), 174 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index fcd1c02a32c..d35a953961c 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -131,11 +131,7 @@ #define WDIOC_GET_PRETIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 22, int) #endif -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout; -#endif +static int nowayout = WATCHDOG_NOWAYOUT; static ipmi_user_t watchdog_user = NULL; diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c index 8f302121741..7289f4af93d 100644 --- a/drivers/char/watchdog/acquirewdt.c +++ b/drivers/char/watchdog/acquirewdt.c @@ -82,12 +82,7 @@ static int wdt_start = 0x443; module_param(wdt_start, int, 0); MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif - +static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c index ea73c8379bd..194a3fd36b9 100644 --- a/drivers/char/watchdog/advantechwdt.c +++ b/drivers/char/watchdog/advantechwdt.c @@ -73,12 +73,7 @@ static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif - +static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index 0715fcf0aed..8338ca300e2 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c @@ -38,12 +38,7 @@ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0 #include -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif +static int nowayout = WATCHDOG_NOWAYOUT; static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ static unsigned long wdt_status; diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c index 83df369113a..8d916afbf4f 100644 --- a/drivers/char/watchdog/ixp4xx_wdt.c +++ b/drivers/char/watchdog/ixp4xx_wdt.c @@ -27,11 +27,7 @@ #include #include -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif +static int nowayout = WATCHDOG_NOWAYOUT; static int heartbeat = 60; /* (secs) Default is 1 minute */ static unsigned long wdt_status; static unsigned long boot_status; diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c index 9da395fa779..a9a20aad61e 100644 --- a/drivers/char/watchdog/machzwd.c +++ b/drivers/char/watchdog/machzwd.c @@ -94,12 +94,7 @@ MODULE_DESCRIPTION("MachZ ZF-Logic Watchdog driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif - +static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c index 3143e4a0753..c9b301dccec 100644 --- a/drivers/char/watchdog/mixcomwd.c +++ b/drivers/char/watchdog/mixcomwd.c @@ -62,12 +62,7 @@ static int mixcomwd_timer_alive; static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0); static char expect_close; -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif - +static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 6ebce3f2ef9..427ad51b7a3 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c @@ -146,12 +146,7 @@ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif - +static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c index 8ce06662732..2b13afb09c5 100644 --- a/drivers/char/watchdog/pcwd_pci.c +++ b/drivers/char/watchdog/pcwd_pci.c @@ -103,12 +103,7 @@ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0 Date: Wed, 27 Jul 2005 11:44:17 -0700 Subject: [PATCH] ppc64: genrtc build fix genrtc.c won't compile on ppc64. Seems that ppc32 does support it though? We do this wrong btw - we should be selecting GEN_RTC in each arch/xxx/Kconfig. Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 43d0cb19ef6..4f27e551929 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -735,7 +735,7 @@ config SGI_IP27_RTC config GEN_RTC tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM + depends on RTC!=y && !IA64 && !ARM && !PPC64 ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you -- cgit v1.2.3 From ebb81fdb3dd0be7514b84197c4f8388a17130f04 Mon Sep 17 00:00:00 2001 From: Marcel Selhorst Date: Wed, 27 Jul 2005 11:45:12 -0700 Subject: [PATCH] tpm: Support for Infineon TPM This patch provides a new device driver for the Infineon SLD 9630 TT Trusted Platform Module (TPM 1.1b) [1] which is embedded on Intel- mainboards or in HP/ Fujitsu-Siemens / Toshiba-Notebooks. A nearly complete list where this module is integrated in can be found in [2]. This kernel module acts as a communication gateway between the linux kernel and the hardware chip and fits the TPM-specific interfaces created by IBM in drivers/char/tpm/tpm.h Further information about this module and a list of succesfully tested and therefore supported hardware can be found at our project page [3]. [1] http://www.infineon.com/cgi/ecrm.dll/ecrm/scripts/public_download.jsp?oid=114135&parent_oid=29049 [2] http://www.tonymcfadden.net/tpmvendors.htm [3] http://www.prosec.rub.de/tpm Signed-off-by: Marcel Selhorst Acked-by: Kylene Jo Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/Kconfig | 11 + drivers/char/tpm/Makefile | 2 +- drivers/char/tpm/tpm_infineon.c | 467 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 drivers/char/tpm/tpm_infineon.c (limited to 'drivers/char') diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 7a969778915..94a3b3e20bf 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -35,5 +35,16 @@ config TCG_ATMEL will be accessible from within Linux. To compile this driver as a module, choose M here; the module will be called tpm_atmel. +config TCG_INFINEON + tristate "Infineon Technologies SLD 9630 TPM Interface" + depends on TCG_TPM + ---help--- + If you have a TPM security chip from Infineon Technologies + say Yes and it will be accessible from within Linux. To + compile this driver as a module, choose M here; the module + will be called tpm_infineon. + Further information on this driver and the supported hardware + can be found at http://www.prosec.rub.de/tpm + endmenu diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 736d3df266f..2392e404e8d 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_TCG_TPM) += tpm.o obj-$(CONFIG_TCG_NSC) += tpm_nsc.o obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o - +obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c new file mode 100644 index 00000000000..07542f9e764 --- /dev/null +++ b/drivers/char/tpm/tpm_infineon.c @@ -0,0 +1,467 @@ +/* + * Description: + * Device Driver for the Infineon Technologies + * SLD 9630 TT Trusted Platform Module + * Specifications at www.trustedcomputinggroup.org + * + * Copyright (C) 2005, Marcel Selhorst + * Applied Data Security Group, Ruhr-University Bochum, Germany + * Project-Homepage: http://www.prosec.rub.de/tpm + * + * 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 the Free Software Foundation, version 2 of the + * License. + * + */ + +#include "tpm.h" + +/* Infineon specific definitions */ +/* maximum number of WTX-packages */ +#define TPM_MAX_WTX_PACKAGES 50 +/* msleep-Time for WTX-packages */ +#define TPM_WTX_MSLEEP_TIME 20 +/* msleep-Time --> Interval to check status register */ +#define TPM_MSLEEP_TIME 3 +/* gives number of max. msleep()-calls before throwing timeout */ +#define TPM_MAX_TRIES 5000 +#define TCPA_INFINEON_DEV_VEN_VALUE 0x15D1 +#define TPM_DATA (TPM_ADDR + 1) & 0xff + +/* TPM header definitions */ +enum infineon_tpm_header { + TPM_VL_VER = 0x01, + TPM_VL_CHANNEL_CONTROL = 0x07, + TPM_VL_CHANNEL_PERSONALISATION = 0x0A, + TPM_VL_CHANNEL_TPM = 0x0B, + TPM_VL_CONTROL = 0x00, + TPM_INF_NAK = 0x15, + TPM_CTRL_WTX = 0x10, + TPM_CTRL_WTX_ABORT = 0x18, + TPM_CTRL_WTX_ABORT_ACK = 0x18, + TPM_CTRL_ERROR = 0x20, + TPM_CTRL_CHAININGACK = 0x40, + TPM_CTRL_CHAINING = 0x80, + TPM_CTRL_DATA = 0x04, + TPM_CTRL_DATA_CHA = 0x84, + TPM_CTRL_DATA_CHA_ACK = 0xC4 +}; + +enum infineon_tpm_register { + WRFIFO = 0x00, + RDFIFO = 0x01, + STAT = 0x02, + CMD = 0x03 +}; + +enum infineon_tpm_command_bits { + CMD_DIS = 0x00, + CMD_LP = 0x01, + CMD_RES = 0x02, + CMD_IRQC = 0x06 +}; + +enum infineon_tpm_status_bits { + STAT_XFE = 0x00, + STAT_LPA = 0x01, + STAT_FOK = 0x02, + STAT_TOK = 0x03, + STAT_IRQA = 0x06, + STAT_RDA = 0x07 +}; + +/* some outgoing values */ +enum infineon_tpm_values { + CHIP_ID1 = 0x20, + CHIP_ID2 = 0x21, + DAR = 0x30, + RESET_LP_IRQC_DISABLE = 0x41, + ENABLE_REGISTER_PAIR = 0x55, + IOLIMH = 0x60, + IOLIML = 0x61, + DISABLE_REGISTER_PAIR = 0xAA, + IDVENL = 0xF1, + IDVENH = 0xF2, + IDPDL = 0xF3, + IDPDH = 0xF4 +}; + +static int number_of_wtx; + +static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) +{ + int status; + int check = 0; + int i; + + if (clear_wrfifo) { + for (i = 0; i < 4096; i++) { + status = inb(chip->vendor->base + WRFIFO); + if (status == 0xff) { + if (check == 5) + break; + else + check++; + } + } + } + /* Note: The values which are currently in the FIFO of the TPM + are thrown away since there is no usage for them. Usually, + this has nothing to say, since the TPM will give its answer + immediately or will be aborted anyway, so the data here is + usually garbage and useless. + We have to clean this, because the next communication with + the TPM would be rubbish, if there is still some old data + in the Read FIFO. + */ + i = 0; + do { + status = inb(chip->vendor->base + RDFIFO); + status = inb(chip->vendor->base + STAT); + i++; + if (i == TPM_MAX_TRIES) + return -EIO; + } while ((status & (1 << STAT_RDA)) != 0); + return 0; +} + +static int wait(struct tpm_chip *chip, int wait_for_bit) +{ + int status; + int i; + for (i = 0; i < TPM_MAX_TRIES; i++) { + status = inb(chip->vendor->base + STAT); + /* check the status-register if wait_for_bit is set */ + if (status & 1 << wait_for_bit) + break; + msleep(TPM_MSLEEP_TIME); + } + if (i == TPM_MAX_TRIES) { /* timeout occurs */ + if (wait_for_bit == STAT_XFE) + dev_err(&chip->pci_dev->dev, + "Timeout in wait(STAT_XFE)\n"); + if (wait_for_bit == STAT_RDA) + dev_err(&chip->pci_dev->dev, + "Timeout in wait(STAT_RDA)\n"); + return -EIO; + } + return 0; +}; + +static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) +{ + wait(chip, STAT_XFE); + outb(sendbyte, chip->vendor->base + WRFIFO); +} + + /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more + calculation time, it sends a WTX-package, which has to be acknowledged + or aborted. This usually occurs if you are hammering the TPM with key + creation. Set the maximum number of WTX-packages in the definitions + above, if the number is reached, the waiting-time will be denied + and the TPM command has to be resend. + */ + +static void tpm_wtx(struct tpm_chip *chip) +{ + number_of_wtx++; + dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n", + number_of_wtx, TPM_MAX_WTX_PACKAGES); + wait_and_send(chip, TPM_VL_VER); + wait_and_send(chip, TPM_CTRL_WTX); + wait_and_send(chip, 0x00); + wait_and_send(chip, 0x00); + msleep(TPM_WTX_MSLEEP_TIME); +} + +static void tpm_wtx_abort(struct tpm_chip *chip) +{ + dev_info(&chip->pci_dev->dev, "Aborting WTX\n"); + wait_and_send(chip, TPM_VL_VER); + wait_and_send(chip, TPM_CTRL_WTX_ABORT); + wait_and_send(chip, 0x00); + wait_and_send(chip, 0x00); + number_of_wtx = 0; + msleep(TPM_WTX_MSLEEP_TIME); +} + +static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) +{ + int i; + int ret; + u32 size = 0; + +recv_begin: + /* start receiving header */ + for (i = 0; i < 4; i++) { + ret = wait(chip, STAT_RDA); + if (ret) + return -EIO; + buf[i] = inb(chip->vendor->base + RDFIFO); + } + + if (buf[0] != TPM_VL_VER) { + dev_err(&chip->pci_dev->dev, + "Wrong transport protocol implementation!\n"); + return -EIO; + } + + if (buf[1] == TPM_CTRL_DATA) { + /* size of the data received */ + size = ((buf[2] << 8) | buf[3]); + + for (i = 0; i < size; i++) { + wait(chip, STAT_RDA); + buf[i] = inb(chip->vendor->base + RDFIFO); + } + + if ((size == 0x6D00) && (buf[1] == 0x80)) { + dev_err(&chip->pci_dev->dev, + "Error handling on vendor layer!\n"); + return -EIO; + } + + for (i = 0; i < size; i++) + buf[i] = buf[i + 6]; + + size = size - 6; + return size; + } + + if (buf[1] == TPM_CTRL_WTX) { + dev_info(&chip->pci_dev->dev, "WTX-package received\n"); + if (number_of_wtx < TPM_MAX_WTX_PACKAGES) { + tpm_wtx(chip); + goto recv_begin; + } else { + tpm_wtx_abort(chip); + goto recv_begin; + } + } + + if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) { + dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n"); + return size; + } + + if (buf[1] == TPM_CTRL_ERROR) { + dev_err(&chip->pci_dev->dev, "ERROR-package received:\n"); + if (buf[4] == TPM_INF_NAK) + dev_err(&chip->pci_dev->dev, + "-> Negative acknowledgement" + " - retransmit command!\n"); + return -EIO; + } + return -EIO; +} + +static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) +{ + int i; + int ret; + u8 count_high, count_low, count_4, count_3, count_2, count_1; + + /* Disabling Reset, LP and IRQC */ + outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD); + + ret = empty_fifo(chip, 1); + if (ret) { + dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n"); + return -EIO; + } + + ret = wait(chip, STAT_XFE); + if (ret) + return -EIO; + + count_4 = (count & 0xff000000) >> 24; + count_3 = (count & 0x00ff0000) >> 16; + count_2 = (count & 0x0000ff00) >> 8; + count_1 = (count & 0x000000ff); + count_high = ((count + 6) & 0xffffff00) >> 8; + count_low = ((count + 6) & 0x000000ff); + + /* Sending Header */ + wait_and_send(chip, TPM_VL_VER); + wait_and_send(chip, TPM_CTRL_DATA); + wait_and_send(chip, count_high); + wait_and_send(chip, count_low); + + /* Sending Data Header */ + wait_and_send(chip, TPM_VL_VER); + wait_and_send(chip, TPM_VL_CHANNEL_TPM); + wait_and_send(chip, count_4); + wait_and_send(chip, count_3); + wait_and_send(chip, count_2); + wait_and_send(chip, count_1); + + /* Sending Data */ + for (i = 0; i < count; i++) { + wait_and_send(chip, buf[i]); + } + return count; +} + +static void tpm_inf_cancel(struct tpm_chip *chip) +{ + /* Nothing yet! + This has something to do with the internal functions + of the TPM. Abort isn't really necessary... + */ +} + +static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); +static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); +static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); + +static struct attribute *inf_attrs[] = { + &dev_attr_pubek.attr, + &dev_attr_pcrs.attr, + &dev_attr_caps.attr, + &dev_attr_cancel.attr, + NULL, +}; + +static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; + +static struct file_operations inf_ops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = tpm_open, + .read = tpm_read, + .write = tpm_write, + .release = tpm_release, +}; + +static struct tpm_vendor_specific tpm_inf = { + .recv = tpm_inf_recv, + .send = tpm_inf_send, + .cancel = tpm_inf_cancel, + .req_complete_mask = 0, + .req_complete_val = 0, + .attr_group = &inf_attr_grp, + .miscdev = {.fops = &inf_ops,}, +}; + +static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, + const struct pci_device_id *pci_id) +{ + int rc = 0; + u8 iol, ioh; + int vendorid[2]; + int version[2]; + int productid[2]; + + if (pci_enable_device(pci_dev)) + return -EIO; + + dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); + + /* query chip for its vendor, its version number a.s.o. */ + outb(ENABLE_REGISTER_PAIR, TPM_ADDR); + outb(IDVENL, TPM_ADDR); + vendorid[1] = inb(TPM_DATA); + outb(IDVENH, TPM_ADDR); + vendorid[0] = inb(TPM_DATA); + outb(IDPDL, TPM_ADDR); + productid[1] = inb(TPM_DATA); + outb(IDPDH, TPM_ADDR); + productid[0] = inb(TPM_DATA); + outb(CHIP_ID1, TPM_ADDR); + version[1] = inb(TPM_DATA); + outb(CHIP_ID2, TPM_ADDR); + version[0] = inb(TPM_DATA); + + if ((vendorid[0] << 8 | vendorid[1]) == (TCPA_INFINEON_DEV_VEN_VALUE)) { + + /* read IO-ports from TPM */ + outb(IOLIMH, TPM_ADDR); + ioh = inb(TPM_DATA); + outb(IOLIML, TPM_ADDR); + iol = inb(TPM_DATA); + tpm_inf.base = (ioh << 8) | iol; + + if (tpm_inf.base == 0) { + dev_err(&pci_dev->dev, "No IO-ports set!\n"); + pci_disable_device(pci_dev); + return -ENODEV; + } + + /* activate register */ + outb(DAR, TPM_ADDR); + outb(0x01, TPM_DATA); + outb(DISABLE_REGISTER_PAIR, TPM_ADDR); + + /* disable RESET, LP and IRQC */ + outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); + + /* Finally, we're done, print some infos */ + dev_info(&pci_dev->dev, "TPM found: " + "io base 0x%x, " + "chip version %02x%02x, " + "vendor id %x%x (Infineon), " + "product id %02x%02x" + "%s\n", + tpm_inf.base, + version[0], version[1], + vendorid[0], vendorid[1], + productid[0], productid[1], ((productid[0] == 0) + && (productid[1] == + 6)) ? + " (SLD 9630 TT 1.1)" : ""); + + rc = tpm_register_hardware(pci_dev, &tpm_inf); + if (rc < 0) { + pci_disable_device(pci_dev); + return -ENODEV; + } + return 0; + } else { + dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); + pci_disable_device(pci_dev); + return -ENODEV; + } +} + +static struct pci_device_id tpm_pci_tbl[] __devinitdata = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)}, + {0,} +}; + +MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); + +static struct pci_driver inf_pci_driver = { + .name = "tpm_inf", + .id_table = tpm_pci_tbl, + .probe = tpm_inf_probe, + .remove = __devexit_p(tpm_remove), + .suspend = tpm_pm_suspend, + .resume = tpm_pm_resume, +}; + +static int __init init_inf(void) +{ + return pci_register_driver(&inf_pci_driver); +} + +static void __exit cleanup_inf(void) +{ + pci_unregister_driver(&inf_pci_driver); +} + +module_init(init_inf); +module_exit(cleanup_inf); + +MODULE_AUTHOR("Marcel Selhorst "); +MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT"); +MODULE_VERSION("1.4"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 3dcce8e22bf9956ac2c5233539cac07c978e58c7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 27 Jul 2005 11:45:14 -0700 Subject: [PATCH] ppc64: tpm_infineon build fix ppc64 uses symbol `DAR', as does the TPM driver, causing a build failure. Change the TPM name. Cc: Marcel Selhorst Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_infineon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 07542f9e764..0e3241645c1 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -75,7 +75,7 @@ enum infineon_tpm_status_bits { enum infineon_tpm_values { CHIP_ID1 = 0x20, CHIP_ID2 = 0x21, - DAR = 0x30, + TPM_DAR = 0x30, RESET_LP_IRQC_DISABLE = 0x41, ENABLE_REGISTER_PAIR = 0x55, IOLIMH = 0x60, @@ -390,7 +390,7 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, } /* activate register */ - outb(DAR, TPM_ADDR); + outb(TPM_DAR, TPM_ADDR); outb(0x01, TPM_DATA); outb(DISABLE_REGISTER_PAIR, TPM_ADDR); -- cgit v1.2.3 From 44456d37b59d8e541936ed26d8b6e08d27e88ac1 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 27 Jul 2005 11:45:17 -0700 Subject: [PATCH] turn many #if $undefined_string into #ifdef $undefined_string turn many #if $undefined_string into #ifdef $undefined_string to fix some warnings after -Wno-def was added to global CFLAGS Signed-off-by: Olaf Hering Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/rio/rioboot.c | 12 ++++++------ drivers/char/rio/rioroute.c | 2 +- drivers/char/rio/riotable.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c index a8be11dfcba..34cbb13aad4 100644 --- a/drivers/char/rio/rioboot.c +++ b/drivers/char/rio/rioboot.c @@ -902,7 +902,7 @@ static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, st (HostP->Mapping[entry].RtaUniqueNum==RtaUniq)) { HostP->Mapping[entry].Flags |= RTA_BOOTED|RTA_NEWBOOT; -#if NEED_TO_FIX +#ifdef NEED_TO_FIX RIO_SV_BROADCAST(HostP->svFlags[entry]); #endif if ( (sysport=HostP->Mapping[entry].SysPort) != NO_PORT ) @@ -918,7 +918,7 @@ static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, st { entry2 = HostP->Mapping[entry].ID2 - 1; HostP->Mapping[entry2].Flags |= RTA_BOOTED|RTA_NEWBOOT; -#if NEED_TO_FIX +#ifdef NEED_TO_FIX RIO_SV_BROADCAST(HostP->svFlags[entry2]); #endif sysport = HostP->Mapping[entry2].SysPort; @@ -1143,7 +1143,7 @@ static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, st CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN ); HostP->Mapping[entry].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; -#if NEED_TO_FIX +#ifdef NEED_TO_FIX RIO_SV_BROADCAST(HostP->svFlags[entry]); #endif RIOReMapPorts( p, HostP, &HostP->Mapping[entry] ); @@ -1159,7 +1159,7 @@ static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, st "This RTA has a tentative entry on another host - delete that entry (1)\n"); HostP->Mapping[entry].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; -#if NEED_TO_FIX +#ifdef NEED_TO_FIX RIO_SV_BROADCAST(HostP->svFlags[entry]); #endif } @@ -1169,7 +1169,7 @@ static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, st { HostP->Mapping[entry2].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; -#if NEED_TO_FIX +#ifdef NEED_TO_FIX RIO_SV_BROADCAST(HostP->svFlags[entry2]); #endif HostP->Mapping[entry2].SysPort = MapP2->SysPort; @@ -1188,7 +1188,7 @@ static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, st else HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; -#if NEED_TO_FIX +#ifdef NEED_TO_FIX RIO_SV_BROADCAST(HostP->svFlags[entry2]); #endif bzero( (caddr_t)MapP2, sizeof(struct Map) ); diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c index 106b31f48a2..e9564c9fb37 100644 --- a/drivers/char/rio/rioroute.c +++ b/drivers/char/rio/rioroute.c @@ -1023,7 +1023,7 @@ RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit) if (link < LINKS_PER_UNIT) return 1; -#if NEED_TO_FIX_THIS +#ifdef NEED_TO_FIX_THIS /* Ok so all the links are disconnected. But we may have only just ** made this slot tentative and not yet received a topology update. ** Lets check how long ago we made it tentative. diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c index 8fb26ad2aa1..e45bc275907 100644 --- a/drivers/char/rio/riotable.c +++ b/drivers/char/rio/riotable.c @@ -771,7 +771,7 @@ int RIOAssignRta( struct rio_info *p, struct Map *MapP ) if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) CCOPY( MapP->Name, HostMapP->Name, MAX_NAME_LEN ); HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED; -#if NEED_TO_FIX +#ifdef NEED_TO_FIX RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID-1]); #endif if (MapP->Flags & RTA16_SECOND_SLOT) -- cgit v1.2.3 From 77933d7276ee8fa0e2947641941a6f7a100a327b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 27 Jul 2005 11:46:09 -0700 Subject: [PATCH] clean up inline static vs static inline `gcc -W' likes to complain if the static keyword is not at the beginning of the declaration. This patch fixes all remaining occurrences of "inline static" up with "static inline" in the entire kernel tree (140 occurrences in 47 files). While making this change I came across a few lines with trailing whitespace that I also fixed up, I have also added or removed a blank line or two here and there, but there are no functional changes in the patch. Signed-off-by: Jesper Juhl Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 298574e1606..a44b97304e9 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1726,7 +1726,7 @@ static int dmi_table(u32 base, int len, int num) return status; } -inline static int dmi_checksum(u8 *buf) +static inline int dmi_checksum(u8 *buf) { u8 sum=0; int a; -- cgit v1.2.3 From b0825488a642cadcf39709961dde61440cb0731c Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Fri, 29 Jul 2005 14:03:39 -0700 Subject: [PATCH] agp: restore APBASE after setting APSIZE When leaving S3 state, the AGP bridge may not have all PCI configuration registers set in the same way as they were at boot. This should be fixed by pci_restore_state - however, the APBASE register cannot be set to conflict with the APSIZE register. If APSIZE is larger than it was before suspend, pci_restore_state will not restore APBASE correctly. The attached patch adds an extra item to the agp_bridge_data structure and uses it to store the value of APBASE. On resume, this is then written after APSIZE has been set. This patch only touches the path used for Intel chipsets without integrated graphics, and may need to be extended to work with the others. Without this patch, I get the symptoms described in bug 4921 - APBASE ends up overlapping various PCI devices, and as a result they fail to work after resume. Signed-off-by: Matthew Garrett Acked-by: Dave Jones Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/agp/agp.h | 1 + drivers/char/agp/intel-agp.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index c1fe013c64f..b4af87c6f9c 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -143,6 +143,7 @@ struct agp_bridge_data { char major_version; char minor_version; struct list_head list; + u32 apbase_config; }; #define KB(x) ((x) * 1024) diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 51266d6b4d7..1f7d415f432 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1047,9 +1047,15 @@ static int intel_845_configure(void) /* aperture size */ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); - /* address to map to */ - pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); - agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + if (agp_bridge->apbase_config != 0) { + pci_write_config_dword(agp_bridge->dev, AGP_APBASE, + agp_bridge->apbase_config); + } else { + /* address to map to */ + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge->apbase_config = temp; + } /* attbase - aperture base */ pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); -- cgit v1.2.3