* Re: swusp acpi [not found] <BF1FE1855350A0479097B3A0D2A80EE0023E83B3@hdsmsx402.hd.intel.com> @ 2004-02-07 7:25 ` Len Brown 2004-02-07 11:50 ` Michael Frank 0 siblings, 1 reply; 12+ messages in thread From: Len Brown @ 2004-02-07 7:25 UTC (permalink / raw) To: Pavel Machek; +Cc: Nigel Cunningham, Linux Kernel Mailing List, Michael Frank Michael, my serial console is toast on 2.6 after resume. Can you point me to said patch? thanks, -Len On Thu, 2004-01-22 at 15:43, Pavel Machek wrote: > Hi! > > > Michael Frank has done a patch giving 2.4 PM support for serial > ports > > (my serial console now works flawlessly). Perhaps it could be ported > to > > 2.6 and the driver model... > > That would certainly be good thing (tm). > > > > > Nigel > > > > On Thu, 2004-01-22 at 23:26, Pavel Machek wrote: > > > Hi! > > > > > > > > Not only serial console... Noone wrote serial port support. > > > > > > > > Incorrect. I never merged the changes because it's rather too > hacky. > > > > > > Who wrote them? Do you have that patch somewhere? > > > Pavel > > -- > > My work on Software Suspend is graciously brought to you by > > LinuxFund.org. > > > > -- > 64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 > ms > > - > To unsubscribe from this list: send the line "unsubscribe > linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-02-07 7:25 ` swusp acpi Len Brown @ 2004-02-07 11:50 ` Michael Frank 0 siblings, 0 replies; 12+ messages in thread From: Michael Frank @ 2004-02-07 11:50 UTC (permalink / raw) To: Len Brown; +Cc: Linux Kernel Mailing List [-- Attachment #1: Type: text/plain, Size: 564 bytes --] Len, On Saturday 07 February 2004 15:25, Len Brown wrote: > Michael, > my serial console is toast on 2.6 after resume. Can you point me to > said patch? > Patch for 2.4.[345] enclosed. Apply alpha than alpha2. software-suspend-linux-2.4.24-rev7-whole.bz2 on swsusp.sf.net has some minor updates wrt tidyness and not resuming (PCMCIA) serial ports after being removed. Please note that the 2.6 driver is very different. Russel King may have some patches he called "too ugly" to be merged, perhaps these could be used even if not merged. Regards Michael [-- Attachment #2: serial-2.4.23-pm-alpha2-incremental.diff --] [-- Type: text/x-diff, Size: 1200 bytes --] --- linux-2.4.23-mhf145/drivers/char/serial.c 2004-01-02 13:09:24.000000000 +0800 +++ linux-2.4.23-mhf146/drivers/char/serial.c 2004-01-03 03:38:49.000000000 +0800 @@ -1359,21 +1430,8 @@ unsigned short ICP; #endif - serial_outp(info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ + serial_outp(info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ - info->MCR = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; -#ifdef CONFIG_SERIAL_MANY_PORTS - if (info->flags & ASYNC_FOURPORT) { - if (state->irq == 0) - info->MCR |= UART_MCR_OUT1; - } else -#endif - { - if (state->irq != 0) - info->MCR |= UART_MCR_OUT2; - } info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ serial_outp(info, UART_MCR, info->MCR); @@ -1466,6 +1524,20 @@ printk("starting up ttys%d (irq %d)...", info->line, state->irq); #endif + info->MCR = 0; + if (info->tty->termios->c_cflag & CBAUD) + info->MCR = UART_MCR_DTR | UART_MCR_RTS; +#ifdef CONFIG_SERIAL_MANY_PORTS + if (info->flags & ASYNC_FOURPORT) { + if (state->irq == 0) + info->MCR |= UART_MCR_OUT1; + } else +#endif + { + if (state->irq != 0) + info->MCR |= UART_MCR_OUT2; + } + start_uart(info); /* [-- Attachment #3: serial-2.4.23-pm-alpha.diff --] [-- Type: text/x-diff, Size: 11226 bytes --] diff -uN linux-2.4.23-mhf145/drivers/char/serial.c.mhf.orig linux-2.4.23-mhf145/drivers/char/serial.c --- linux-2.4.23-mhf145/drivers/char/serial.c.mhf.orig 2003-12-02 05:37:49.000000000 +0800 +++ linux-2.4.23-mhf145/drivers/char/serial.c 2004-01-02 13:04:40.000000000 +0800 @@ -62,10 +62,14 @@ * Robert Schwebel <robert@schwebel.de>, * Juergen Beisert <jbeisert@eurodsn.de>, * Theodore Ts'o <tytso@mit.edu> + * + * 01/04: Verion: 5.1 + * Add PM suspend/resume support + * Michael Frank <mhf@linuxmail.org> */ -static char *serial_version = "5.05c"; -static char *serial_revdate = "2001-07-08"; +static char *serial_version = "5.1-alpha"; +static char *serial_revdate = "2004-01-01"; /* * Serial driver configuration section. Here are the various options: @@ -203,6 +207,9 @@ #include <linux/ioport.h> #include <linux/mm.h> #include <linux/slab.h> +#ifdef CONFIG_PM +#include <linux/pm.h> +#endif #if (LINUX_VERSION_CODE >= 131343) #include <linux/init.h> #endif @@ -1208,44 +1215,16 @@ } #endif /* CONFIG_SERIAL_RSA */ -static int startup(struct async_struct * info) +/* + * Starts the uart + */ + +int start_uart(struct async_struct * info) { - unsigned long flags; int retval=0; - void (*handler)(int, void *, struct pt_regs *); struct serial_state *state= info->state; - unsigned long page; -#ifdef CONFIG_SERIAL_MANY_PORTS - unsigned short ICP; -#endif - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit.buf) - free_page(page); - else - info->xmit.buf = (unsigned char *) page; - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - if (uart_config[state->type].flags & UART_STARTECH) { + if (uart_config[state->type].flags & UART_STARTECH) { /* Wake up UART */ serial_outp(info, UART_LCR, 0xBF); serial_outp(info, UART_EFR, UART_EFR_ECB); @@ -1341,55 +1320,19 @@ retval = -ENODEV; goto errout; } - - /* - * Allocate the IRQ if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { -#ifdef CONFIG_SERIAL_SHARE_IRQ - free_irq(state->irq, &IRQ_ports[state->irq]); -#ifdef CONFIG_SERIAL_MULTIPORT - if (rs_multiport[state->irq].port1) - handler = rs_interrupt_multi; - else -#endif - handler = rs_interrupt; -#else - retval = -EBUSY; - goto errout; -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - } else - handler = rs_interrupt_single; - - retval = request_irq(state->irq, handler, SA_SHIRQ, - "serial", &IRQ_ports[state->irq]); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } +errout: + return retval; +} - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); +int init_uart(struct async_struct * info) +{ + int retval=0; + struct serial_state *state= info->state; +#ifdef CONFIG_SERIAL_MANY_PORTS + unsigned short ICP; +#endif - /* - * Now, initialize the UART - */ - serial_outp(info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ + serial_outp(info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ info->MCR = 0; if (info->tty->termios->c_cflag & CBAUD) @@ -1459,6 +1402,94 @@ * and set the speed of the serial port */ change_speed(info, 0); + return retval; +} + +static int startup(struct async_struct * info) +{ + unsigned long flags; + int retval=0; + void (*handler)(int, void *, struct pt_regs *); + struct serial_state *state= info->state; + unsigned long page; + + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + save_flags(flags); cli(); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + + if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + free_page(page); + goto errout; + } + if (info->xmit.buf) + free_page(page); + else + info->xmit.buf = (unsigned char *) page; + +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttys%d (irq %d)...", info->line, state->irq); +#endif + + start_uart(info); + + /* + * Allocate the IRQ if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { +#ifdef CONFIG_SERIAL_SHARE_IRQ + free_irq(state->irq, &IRQ_ports[state->irq]); +#ifdef CONFIG_SERIAL_MULTIPORT + if (rs_multiport[state->irq].port1) + handler = rs_interrupt_multi; + else +#endif + handler = rs_interrupt; +#else + retval = -EBUSY; + goto errout; +#endif /* CONFIG_SERIAL_SHARE_IRQ */ + } else + handler = rs_interrupt_single; + + retval = request_irq(state->irq, handler, SA_SHIRQ, + "serial", &IRQ_ports[state->irq]); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + } + + /* + * Insert serial port into IRQ chain. + */ + info->prev_port = 0; + info->next_port = IRQ_ports[state->irq]; + if (info->next_port) + info->next_port->prev_port = info; + IRQ_ports[state->irq] = info; + figure_IRQ_timeout(state->irq); + + /* + * Now, initialize the UART + */ + + init_uart(info); info->flags |= ASYNC_INITIALIZED; restore_flags(flags); @@ -1470,6 +1501,33 @@ } /* + * Sleep capable UART + */ + +static void sleep_uart(struct async_struct * info) +{ + (void)serial_in(info, UART_RX); /* read data port to reset things */ + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + if (uart_config[info->state->type].flags & UART_STARTECH) { + /* Arrange to enter sleep mode */ + serial_outp(info, UART_LCR, 0xBF); + serial_outp(info, UART_EFR, UART_EFR_ECB); + serial_outp(info, UART_LCR, 0); + serial_outp(info, UART_IER, UART_IERX_SLEEP); + serial_outp(info, UART_LCR, 0xBF); + serial_outp(info, UART_EFR, 0); + serial_outp(info, UART_LCR, 0); + } + if (info->state->type == PORT_16750) { + /* Arrange to enter sleep mode */ + serial_outp(info, UART_IER, UART_IERX_SLEEP); + } +} + +/* * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on. */ @@ -1566,27 +1624,9 @@ disable_rsa(info))) state->baud_base = SERIAL_RSA_BAUD_BASE_LO; #endif - - (void)serial_in(info, UART_RX); /* read data port to reset things */ - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); + sleep_uart(info); - if (uart_config[info->state->type].flags & UART_STARTECH) { - /* Arrange to enter sleep mode */ - serial_outp(info, UART_LCR, 0xBF); - serial_outp(info, UART_EFR, UART_EFR_ECB); - serial_outp(info, UART_LCR, 0); - serial_outp(info, UART_IER, UART_IERX_SLEEP); - serial_outp(info, UART_LCR, 0xBF); - serial_outp(info, UART_EFR, 0); - serial_outp(info, UART_LCR, 0); - } - if (info->state->type == PORT_16750) { - /* Arrange to enter sleep mode */ - serial_outp(info, UART_IER, UART_IERX_SLEEP); - } info->flags &= ~ASYNC_INITIALIZED; restore_flags(flags); } @@ -3250,6 +3290,110 @@ return 0; } +#ifdef CONFIG_PM + +/* + * Suspend an UART + */ + +static int rs_suspend_uart(struct async_struct *info) +{ + int retval = 0; + printk("serio: Suspending %lx\n", info->port); + + /* disable all intrs */ + serial_outp(info, UART_IER, 0x00); + + /* disable break condition */ + serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); + + /* Disable line */ + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + serial_outp(info, UART_MCR,(info->MCR & ~(UART_MCR_DTR|UART_MCR_RTS))); + + /* put UART to sleep */ + sleep_uart(info); + + if (retval) + info->flags &= ~ASYNC_INITIALIZED; + return retval; +} +static int rs_suspend(struct tty_struct *tty) +{ + int retval = 0; + unsigned long flags; + save_flags(flags); cli(); + + retval = rs_suspend_uart((struct async_struct *)tty->driver_data); + + restore_flags(flags); + return retval; +} + +/* + * Resume an UART + */ + +/* Todo: eval multiport interrupt resume */ + +static int rs_resume_uart(struct async_struct *info) +{ + int retval = 0; + + printk("serio: Resuming %lx\n", info->port); + + if ((retval = start_uart(info))) + goto out; + retval = init_uart(info); +out: + if (retval) + info->flags &= ~ASYNC_INITIALIZED; + return retval; +} + +static int rs_resume(struct tty_struct *tty) +{ + int retval = 0; + unsigned long flags; + save_flags(flags); cli(); + + retval = rs_resume_uart((struct async_struct *)tty->driver_data); + + restore_flags(flags); + return retval; +} + +/* + * Suspend or Resume all UARTs + */ + +static int rs_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + struct serial_state *state = rs_table; + int i; + unsigned long flags; /* Interrupts will be reenabled once per iteration */ + + printk("serio: pm event 0x%x received\n", rqst); + + for (i =0; i < NR_PORTS; i++, state++) { + if (!state->info) /* info is NULL unless port opened */ + continue; + + save_flags(flags); cli(); + + switch (rqst) { + case PM_SUSPEND: + rs_suspend_uart(state->info); + break; + case PM_RESUME: + rs_resume_uart(state->info); + } + restore_flags(flags); + } + return 0; +} +#endif + /* * /proc fs routines.... */ @@ -5475,6 +5619,10 @@ serial_driver.wait_until_sent = rs_wait_until_sent; serial_driver.read_proc = rs_read_proc; #endif +#ifdef CONFIG_PM + serial_driver.suspend = rs_suspend; + serial_driver.resume = rs_resume; +#endif /* * The callout device is just like normal device except for @@ -5554,8 +5702,13 @@ probe_serial_pci(); #endif #ifdef ENABLE_SERIAL_PNP - probe_serial_pnp(); + probe_serial_pnp(); #endif +#ifdef CONFIG_PM + if (!pm_register(PM_UNKNOWN_DEV, 0, rs_pm_callback)) + panic("Couldn't register with PM subsystem\n"); +#endif + return 0; } @@ -5726,6 +5879,7 @@ struct async_struct *info; /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ + pm_unregister_all(rs_pm_callback); del_timer_sync(&serial_timer); save_flags(flags); cli(); remove_bh(SERIAL_BH); diff -uN linux-2.4.23-mhf145/include/linux/tty_driver.h.mhf.orig linux-2.4.23-mhf145/include/linux/tty_driver.h --- linux-2.4.23-mhf145/include/linux/tty_driver.h.mhf.orig 2004-01-02 13:06:39.000000000 +0800 +++ linux-2.4.23-mhf145/include/linux/tty_driver.h 2004-01-02 13:04:40.000000000 +0800 @@ -170,7 +170,10 @@ int count, int *eof, void *data); int (*write_proc)(struct file *file, const char *buffer, unsigned long count, void *data); - +#ifdef CONFIG_PM + int (*suspend) (struct tty_struct *tty); + int (*resume) (struct tty_struct *tty); +#endif /* * linked list pointers */ ^ permalink raw reply [flat|nested] 12+ messages in thread
* swusp acpi @ 2004-01-21 9:43 tuija t. 2004-01-22 0:32 ` Pavel Machek 0 siblings, 1 reply; 12+ messages in thread From: tuija t. @ 2004-01-21 9:43 UTC (permalink / raw) To: linux-kernel Hi, Sorry about the newbie question but I haven't managed to get answer elsewhere :-) I have a laptop (Fujitsu Lifebook C1020) Debian system with linux-2.6.1 vanilla. An I have wondered how I should but it in sleep? # echo 4 > /proc/acpi/sleep writes the ram in the swap: Stopping tasks: ===================================================| Freeing memory: ........................| hdc: start_power_step(step: 0) hdc: completing PM request, suspend hda: start_power_step(step: 0) hda: completing PM request, suspend /critical section: Counting pages to copy[nosave c03cf000] (pages needed: 4727+512=5239 free: 118136) Alloc pagedir [nosave c03cf000]<4>Freeing prev allocated pagedir eth0: link up, 100Mbps, full-duplex, lpa 0x45E1 hda: Wakeup request inited, waiting for !BSY... hda: start_power_step(step: 1000) hda: completing PM request, resume hdc: Wakeup request inited, waiting for !BSY... hdc: start_power_step(step: 1000) hdc: completing PM request, resume Fixing swap signatures... ok Restarting tasks... done And after reboot comes back to same than it was before This behaviour is kind of "big sleep" and have to boot from grub. When I do # echo 3 > /proc/acpi/sleep it beebs from bios and do: PM: Preparing system for suspend Stopping tasks: ===================================================| hdc: start_power_step(step: 0) hdc: completing PM request, suspend hda: start_power_step(step: 0) hda: start_power_step(step: 1) hda: complete_power_step(step: 1, stat: 50, err: 0) hda: completing PM request, suspend PM: Entering state. Back to C! PM: Finishing up. eth0: link up, 100Mbps, full-duplex, lpa 0x45E1 hda: Wakeup request inited, waiting for !BSY... hda: start_power_step(step: 1000) hda: completing PM request, resume hdc: Wakeup request inited, waiting for !BSY... hdc: start_power_step(step: 1000) hdc: completing PM request, resume Restarting tasks...<6>usb 1-1: USB disconnect, address 2 drivers/usb/host/uhci-hcd.c: 1200: host system error, PCI problems? drivers/usb/host/uhci-hcd.c: 1200: host controller halted. very bad drivers/usb/host/uhci-hcd.c: 1300: host system error, PCI problems? drivers/usb/host/uhci-hcd.c: 1300: host controller halted. very bad drivers/usb/host/uhci-hcd.c: 1700: host system error, PCI problems? drivers/usb/host/uhci-hcd.c: 1700: host controller halted. very bad psmouse: reconnect request, but serio is disconnected, ignoring... done hub 1-0:1.0: new USB device on port 1, assigned address 3 usb 1-1: control timeout on ep0out And with pressing power button everything else comes back exept usb. This behaviour is kind of "little light nap" and system comes back fast. And I have also noticed that I cannot use bios passwd with # echo 3 > /proc/acpi/sleep cause even it doesn't reboot it goes somehow to bios and bios passwd prompted but it doesn't accept it? But after disabled bios passwd it works exept usb. Can somebody give me any wise what I'm doing wrong or point me to some documentation about this matter? Thank you for your patience and possible answers advance :-) -- best rgds ~tt ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-21 9:43 tuija t. @ 2004-01-22 0:32 ` Pavel Machek 2004-01-22 1:45 ` Nigel Cunningham 0 siblings, 1 reply; 12+ messages in thread From: Pavel Machek @ 2004-01-22 0:32 UTC (permalink / raw) To: tuija t.; +Cc: linux-kernel Hi! > And with pressing power button everything else comes back exept > usb. > This behaviour is kind of "little light nap" and system comes back fast. > And I have also noticed that I cannot use bios passwd with > # echo 3 > /proc/acpi/sleep cause even it doesn't reboot it goes > somehow to bios and bios passwd prompted but it doesn't accept it? > But after disabled bios passwd it works exept usb. > > Can somebody give me any wise what I'm doing wrong or point > me to some documentation about this matter? Seems like USB suspend/resume support is not yet working... Talk to usb maintainers and offer them some testing... Pavel -- When do you have a heart between your knees? [Johanka's followup: and *two* hearts?] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 0:32 ` Pavel Machek @ 2004-01-22 1:45 ` Nigel Cunningham 2004-01-22 10:15 ` Pavel Machek 0 siblings, 1 reply; 12+ messages in thread From: Nigel Cunningham @ 2004-01-22 1:45 UTC (permalink / raw) To: Pavel Machek; +Cc: Linux Kernel Mailing List [-- Attachment #1: Type: text/plain, Size: 964 bytes --] Howdy. It looks like PM support for serial ports is also broken; a serial console is unusable after resuming. Regards, Nigel On Thu, 2004-01-22 at 13:32, Pavel Machek wrote: > Hi! > > > And with pressing power button everything else comes back exept > > usb. > > This behaviour is kind of "little light nap" and system comes back fast. > > And I have also noticed that I cannot use bios passwd with > > # echo 3 > /proc/acpi/sleep cause even it doesn't reboot it goes > > somehow to bios and bios passwd prompted but it doesn't accept it? > > But after disabled bios passwd it works exept usb. > > > > Can somebody give me any wise what I'm doing wrong or point > > me to some documentation about this matter? > > Seems like USB suspend/resume support is not yet working... Talk to > usb maintainers and offer them some testing... > Pavel -- My work on Software Suspend is graciously brought to you by LinuxFund.org. [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 1:45 ` Nigel Cunningham @ 2004-01-22 10:15 ` Pavel Machek 2004-01-22 10:22 ` Russell King 0 siblings, 1 reply; 12+ messages in thread From: Pavel Machek @ 2004-01-22 10:15 UTC (permalink / raw) To: Nigel Cunningham; +Cc: Linux Kernel Mailing List Hi! > It looks like PM support for serial ports is also broken; a serial > console is unusable after resuming. Not only serial console... Noone wrote serial port support. Pavel -- When do you have a heart between your knees? [Johanka's followup: and *two* hearts?] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 10:15 ` Pavel Machek @ 2004-01-22 10:22 ` Russell King 2004-01-22 10:26 ` Pavel Machek 0 siblings, 1 reply; 12+ messages in thread From: Russell King @ 2004-01-22 10:22 UTC (permalink / raw) To: Pavel Machek; +Cc: Nigel Cunningham, Linux Kernel Mailing List On Thu, Jan 22, 2004 at 11:15:55AM +0100, Pavel Machek wrote: > Not only serial console... Noone wrote serial port support. Incorrect. I never merged the changes because it's rather too hacky. -- Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 10:22 ` Russell King @ 2004-01-22 10:26 ` Pavel Machek 2004-01-22 10:32 ` Russell King 2004-01-22 18:08 ` Nigel Cunningham 0 siblings, 2 replies; 12+ messages in thread From: Pavel Machek @ 2004-01-22 10:26 UTC (permalink / raw) To: Nigel Cunningham, Linux Kernel Mailing List Hi! > > Not only serial console... Noone wrote serial port support. > > Incorrect. I never merged the changes because it's rather too hacky. Who wrote them? Do you have that patch somewhere? Pavel -- When do you have a heart between your knees? [Johanka's followup: and *two* hearts?] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 10:26 ` Pavel Machek @ 2004-01-22 10:32 ` Russell King 2004-01-22 18:08 ` Nigel Cunningham 1 sibling, 0 replies; 12+ messages in thread From: Russell King @ 2004-01-22 10:32 UTC (permalink / raw) To: Pavel Machek; +Cc: Nigel Cunningham, Linux Kernel Mailing List On Thu, Jan 22, 2004 at 11:26:55AM +0100, Pavel Machek wrote: > > > Not only serial console... Noone wrote serial port support. > > > > Incorrect. I never merged the changes because it's rather too hacky. > > Who wrote them? Do you have that patch somewhere? Me and not separated out from the ARM changes. -- Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 10:26 ` Pavel Machek 2004-01-22 10:32 ` Russell King @ 2004-01-22 18:08 ` Nigel Cunningham 2004-01-22 20:43 ` Pavel Machek 2004-01-23 5:51 ` Michael Frank 1 sibling, 2 replies; 12+ messages in thread From: Nigel Cunningham @ 2004-01-22 18:08 UTC (permalink / raw) To: Pavel Machek; +Cc: Linux Kernel Mailing List, Michael Frank [-- Attachment #1: Type: text/plain, Size: 556 bytes --] Hi. Michael Frank has done a patch giving 2.4 PM support for serial ports (my serial console now works flawlessly). Perhaps it could be ported to 2.6 and the driver model... Nigel On Thu, 2004-01-22 at 23:26, Pavel Machek wrote: > Hi! > > > > Not only serial console... Noone wrote serial port support. > > > > Incorrect. I never merged the changes because it's rather too hacky. > > Who wrote them? Do you have that patch somewhere? > Pavel -- My work on Software Suspend is graciously brought to you by LinuxFund.org. [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 18:08 ` Nigel Cunningham @ 2004-01-22 20:43 ` Pavel Machek 2004-01-23 5:51 ` Michael Frank 1 sibling, 0 replies; 12+ messages in thread From: Pavel Machek @ 2004-01-22 20:43 UTC (permalink / raw) To: Nigel Cunningham; +Cc: Pavel Machek, Linux Kernel Mailing List, Michael Frank Hi! > Michael Frank has done a patch giving 2.4 PM support for serial ports > (my serial console now works flawlessly). Perhaps it could be ported to > 2.6 and the driver model... That would certainly be good thing (tm). > > Nigel > > On Thu, 2004-01-22 at 23:26, Pavel Machek wrote: > > Hi! > > > > > > Not only serial console... Noone wrote serial port support. > > > > > > Incorrect. I never merged the changes because it's rather too hacky. > > > > Who wrote them? Do you have that patch somewhere? > > Pavel > -- > My work on Software Suspend is graciously brought to you by > LinuxFund.org. -- 64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: swusp acpi 2004-01-22 18:08 ` Nigel Cunningham 2004-01-22 20:43 ` Pavel Machek @ 2004-01-23 5:51 ` Michael Frank 1 sibling, 0 replies; 12+ messages in thread From: Michael Frank @ 2004-01-23 5:51 UTC (permalink / raw) To: ncunningham, Pavel Machek; +Cc: Linux Kernel Mailing List On Friday 23 January 2004 02:08, Nigel Cunningham wrote: > Hi. > > Michael Frank has done a patch giving 2.4 PM support for serial ports > (my serial console now works flawlessly). Perhaps it could be ported to > 2.6 and the driver model... > > Nigel > > On Thu, 2004-01-22 at 23:26, Pavel Machek wrote: > > Hi! > > > > > > Not only serial console... Noone wrote serial port support. > > > > > > Incorrect. I never merged the changes because it's rather too hacky. > > > > Who wrote them? Do you have that patch somewhere? > > Pavel > -- > My work on Software Suspend is graciously brought to you by > LinuxFund.org. > This patch works fine for standerd serial ports with serial.c compiled in. We use it mainly to suspend/resume serial consoles. The patch was implemented with the objective to just move code around in testable blocks to prevent breaking devices unavailable for testing. However this patch is not suitable for 2.6 as the 2.6 drivers are a rewrite and the old driver and this patch have a number of issues. - The patch does not touch interupts and relies on the resuming kernel to init them for standard serial ports with serial.c compiled in. - Terefor, device resume would not work with serial.c as a module or some non-standard serial ports because of the foregoing. - The old driver initializes serial ports in a non-standard way. Notably MCR lines and interrupts are enabled prior to setting baud rate. This is unsuitable for suspending while hardware handshaked transfers are ongoing. - No suspend support for software handshaked transmissions. I think the driver should send the current XOFF character in this case. - The patch does not attempt to fix the above problem to minimize disruption and the likelyhood of break device that can't be test. Another fundamental limitation is that only open ports are resumed, this will not resume DOSEMU/Win4Lin ports for example. I got a utility for this which reads back the ports from userspace and writes them back on resume. This is a bad fix as some registers can't be read back (FIFO control) and must be set with generic settings. Regards Michael --- linux-2.4.23-Vanilla/drivers/char/serial.c 2003-12-02 05:37:49.000000000 +0800 +++ linux-2.4.23-mhf156/drivers/char/serial.c 2004-01-17 18:05:43.000000000 +0800 @@ -62,10 +62,14 @@ * Robert Schwebel <robert@schwebel.de>, * Juergen Beisert <jbeisert@eurodsn.de>, * Theodore Ts'o <tytso@mit.edu> + * + * 01/04: Verion: 5.1 + * Add PM suspend/resume support + * Michael Frank <mhf@linuxmail.org> */ -static char *serial_version = "5.05c"; -static char *serial_revdate = "2001-07-08"; +static char *serial_version = "5.1-alpha"; +static char *serial_revdate = "2004-01-01"; /* * Serial driver configuration section. Here are the various options: @@ -99,6 +103,13 @@ #include <linux/config.h> #include <linux/version.h> +#include <linux/completion.h> +#include <linux/suspend.h> +#include <linux/suspend-debug.h> + +#ifdef CONFIG_PM +extern struct completion swsusp_wait_for_shift; +#endif #undef SERIAL_PARANOIA_CHECK #define CONFIG_SERIAL_NOPAUSE_IO @@ -203,6 +214,9 @@ #include <linux/ioport.h> #include <linux/mm.h> #include <linux/slab.h> +#ifdef CONFIG_PM +#include <linux/pm.h> +#endif #if (LINUX_VERSION_CODE >= 131343) #include <linux/init.h> #endif @@ -223,6 +237,21 @@ #include <linux/sysrq.h> #endif +#ifdef CONFIG_KDB +#include <linux/kdb.h> +#ifdef CONFIG_SERIAL_CONSOLE +/* + * kdb_serial_line records the serial line number of the first serial console. + * NOTE: The kernel ignores characters on the serial line unless a user space + * program has opened the line first. To enter kdb before user space has opened + * the serial line, you can use the 'kdb=early' flag to lilo and set the + * appropriate breakpoints. + */ + +static int kdb_serial_line = -1; +static const char *kdb_serial_ptr = kdb_serial_str; +#endif /* CONFIG_SERIAL_CONSOLE */ +#endif /* CONFIG_KDB */ /* * All of the compatibilty code so we can compile serial.c against * older kernels is hidden in serial_compat.h @@ -577,6 +606,18 @@ return; // if TTY_DONT_FLIP is set } ch = serial_inp(info, UART_RX); +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_KDB) + if ((info->line == kdb_serial_line) && kdb_on) { + if (ch == *kdb_serial_ptr) { + if (!(*++kdb_serial_ptr)) { + kdb(KDB_REASON_KEYBOARD, 0, regs); + kdb_serial_ptr = kdb_serial_str; + break; + } + } else + kdb_serial_ptr = kdb_serial_str; + } +#endif /* CONFIG_SERIAL_CONSOLE && CONFIG_KDB */ *tty->flip.char_buf_ptr = ch; icount->rx++; @@ -638,7 +679,8 @@ else if (*status & UART_LSR_FE) *tty->flip.flag_buf_ptr = TTY_FRAME; } -#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#if defined(CONFIG_SERIAL_CONSOLE) +#if defined(CONFIG_MAGIC_SYSRQ) if (break_pressed && info->line == sercons.index) { if (ch != 0 && time_before(jiffies, break_pressed + HZ*5)) { @@ -648,7 +690,71 @@ } break_pressed = 0; } +#endif /* CONFIG_MAGIC_SYSRQ */ + +#ifdef CONFIG_PM + if ((software_suspend_state & SOFTWARE_SUSPEND_RUNNING) || + waitqueue_active(&swsusp_wait_for_shift.wait)) { +#ifdef CONFIG_SOFTWARE_SUSPEND2 + extern void prepare_status(int printalways, int clearbar, const char *fmt, ...); + extern unsigned long swsusp_action; + extern void request_abort_suspend(void); + + switch (ch) { + case 27: + /* Abort suspend */ + if (TEST_ACTION_STATE(SUSPEND_CAN_CANCEL)) + request_abort_suspend(); + break; + case 49: + console_loglevel = 1; + break; + case 48: + console_loglevel = 0; + break; +#ifdef CONFIG_SOFTWARE_SUSPEND_DEBUG + case 80: + case 112: + /* During suspend, toggle pausing with Pause or Break if kdb active */ + swsusp_action ^= (1 << SUSPEND_PAUSE); + prepare_status(1, 0, "Pausing %s.\n", + TEST_ACTION_STATE(SUSPEND_PAUSE) ? "enabled" : "disabled"); + if (!TEST_ACTION_STATE(SUSPEND_PAUSE)) + complete(&swsusp_wait_for_shift); + break; + case 82: + case 114: + /* Otherwise, if R pressed, toggle rebooting */ + swsusp_action ^= (1 << SUSPEND_REBOOT); + prepare_status(1, 0, "Rebooting %s.\n", + TEST_ACTION_STATE(SUSPEND_REBOOT) ? "enabled" : "disabled"); + break; + case 76: + case 108: + /* Otherwise, if L pressed, toggle logging everything */ + swsusp_action ^= (1 << SUSPEND_LOGALL); + prepare_status(1, 0, "Logging all output %s.\n", + TEST_ACTION_STATE(SUSPEND_LOGALL) ? "enabled" : "disabled"); + break; + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + console_loglevel = ((ch - 48)); + break; +#endif + } #endif + if (ch == 32) + complete(&swsusp_wait_for_shift); + + goto ignore_char; + } +#endif /* CONFIG_PM */ +#endif /* CONFIG_SERIAL_CONSOLE */ + if ((*status & info->ignore_status_mask) == 0) { tty->flip.flag_buf_ptr++; tty->flip.char_buf_ptr++; @@ -666,7 +772,7 @@ tty->flip.flag_buf_ptr++; tty->flip.char_buf_ptr++; } -#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#if defined(CONFIG_SERIAL_CONSOLE) && ( defined(CONFIG_MAGIC_SYSRQ) || defined(CONFIG_PM)) ignore_char: #endif *status = serial_inp(info, UART_LSR); @@ -1208,44 +1314,16 @@ } #endif /* CONFIG_SERIAL_RSA */ -static int startup(struct async_struct * info) +/* + * Starts the uart + */ + +int start_uart(struct async_struct * info) { - unsigned long flags; int retval=0; - void (*handler)(int, void *, struct pt_regs *); struct serial_state *state= info->state; - unsigned long page; -#ifdef CONFIG_SERIAL_MANY_PORTS - unsigned short ICP; -#endif - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit.buf) - free_page(page); - else - info->xmit.buf = (unsigned char *) page; - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - if (uart_config[state->type].flags & UART_STARTECH) { + if (uart_config[state->type].flags & UART_STARTECH) { /* Wake up UART */ serial_outp(info, UART_LCR, 0xBF); serial_outp(info, UART_EFR, UART_EFR_ECB); @@ -1341,69 +1419,20 @@ retval = -ENODEV; goto errout; } - - /* - * Allocate the IRQ if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { -#ifdef CONFIG_SERIAL_SHARE_IRQ - free_irq(state->irq, &IRQ_ports[state->irq]); -#ifdef CONFIG_SERIAL_MULTIPORT - if (rs_multiport[state->irq].port1) - handler = rs_interrupt_multi; - else -#endif - handler = rs_interrupt; -#else - retval = -EBUSY; - goto errout; -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - } else - handler = rs_interrupt_single; - - retval = request_irq(state->irq, handler, SA_SHIRQ, - "serial", &IRQ_ports[state->irq]); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } +errout: + return retval; +} - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); +int init_uart(struct async_struct * info) +{ + int retval=0; + struct serial_state *state= info->state; +#ifdef CONFIG_SERIAL_MANY_PORTS + unsigned short ICP; +#endif - /* - * Now, initialize the UART - */ serial_outp(info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ - info->MCR = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; -#ifdef CONFIG_SERIAL_MANY_PORTS - if (info->flags & ASYNC_FOURPORT) { - if (state->irq == 0) - info->MCR |= UART_MCR_OUT1; - } else -#endif - { - if (state->irq != 0) - info->MCR |= UART_MCR_OUT2; - } info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ serial_outp(info, UART_MCR, info->MCR); @@ -1459,6 +1488,108 @@ * and set the speed of the serial port */ change_speed(info, 0); + return retval; +} + +static int startup(struct async_struct * info) +{ + unsigned long flags; + int retval=0; + void (*handler)(int, void *, struct pt_regs *); + struct serial_state *state= info->state; + unsigned long page; + + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + save_flags(flags); cli(); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + + if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + free_page(page); + goto errout; + } + if (info->xmit.buf) + free_page(page); + else + info->xmit.buf = (unsigned char *) page; + +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttys%d (irq %d)...", info->line, state->irq); +#endif + + info->MCR = 0; + if (info->tty->termios->c_cflag & CBAUD) + info->MCR = UART_MCR_DTR | UART_MCR_RTS; +#ifdef CONFIG_SERIAL_MANY_PORTS + if (info->flags & ASYNC_FOURPORT) { + if (state->irq == 0) + info->MCR |= UART_MCR_OUT1; + } else +#endif + { + if (state->irq != 0) + info->MCR |= UART_MCR_OUT2; + } + + start_uart(info); + + /* + * Allocate the IRQ if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { +#ifdef CONFIG_SERIAL_SHARE_IRQ + free_irq(state->irq, &IRQ_ports[state->irq]); +#ifdef CONFIG_SERIAL_MULTIPORT + if (rs_multiport[state->irq].port1) + handler = rs_interrupt_multi; + else +#endif + handler = rs_interrupt; +#else + retval = -EBUSY; + goto errout; +#endif /* CONFIG_SERIAL_SHARE_IRQ */ + } else + handler = rs_interrupt_single; + + retval = request_irq(state->irq, handler, SA_SHIRQ, + "serial", &IRQ_ports[state->irq]); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + } + + /* + * Insert serial port into IRQ chain. + */ + info->prev_port = 0; + info->next_port = IRQ_ports[state->irq]; + if (info->next_port) + info->next_port->prev_port = info; + IRQ_ports[state->irq] = info; + figure_IRQ_timeout(state->irq); + + /* + * Now, initialize the UART + */ + + init_uart(info); info->flags |= ASYNC_INITIALIZED; restore_flags(flags); @@ -1470,6 +1601,33 @@ } /* + * Sleep capable UART + */ + +static void sleep_uart(struct async_struct * info) +{ + (void)serial_in(info, UART_RX); /* read data port to reset things */ + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + if (uart_config[info->state->type].flags & UART_STARTECH) { + /* Arrange to enter sleep mode */ + serial_outp(info, UART_LCR, 0xBF); + serial_outp(info, UART_EFR, UART_EFR_ECB); + serial_outp(info, UART_LCR, 0); + serial_outp(info, UART_IER, UART_IERX_SLEEP); + serial_outp(info, UART_LCR, 0xBF); + serial_outp(info, UART_EFR, 0); + serial_outp(info, UART_LCR, 0); + } + if (info->state->type == PORT_16750) { + /* Arrange to enter sleep mode */ + serial_outp(info, UART_IER, UART_IERX_SLEEP); + } +} + +/* * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on. */ @@ -1566,27 +1724,9 @@ disable_rsa(info))) state->baud_base = SERIAL_RSA_BAUD_BASE_LO; #endif - - (void)serial_in(info, UART_RX); /* read data port to reset things */ - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); + sleep_uart(info); - if (uart_config[info->state->type].flags & UART_STARTECH) { - /* Arrange to enter sleep mode */ - serial_outp(info, UART_LCR, 0xBF); - serial_outp(info, UART_EFR, UART_EFR_ECB); - serial_outp(info, UART_LCR, 0); - serial_outp(info, UART_IER, UART_IERX_SLEEP); - serial_outp(info, UART_LCR, 0xBF); - serial_outp(info, UART_EFR, 0); - serial_outp(info, UART_LCR, 0); - } - if (info->state->type == PORT_16750) { - /* Arrange to enter sleep mode */ - serial_outp(info, UART_IER, UART_IERX_SLEEP); - } info->flags &= ~ASYNC_INITIALIZED; restore_flags(flags); } @@ -3250,6 +3390,108 @@ return 0; } +#ifdef CONFIG_PM + +/* + * Suspend an UART + */ + +static int rs_suspend_uart(struct async_struct *info) +{ + int retval = 0; + printk("serio: Suspending %lx\n", info->port); + + /* disable all intrs */ + serial_outp(info, UART_IER, 0x00); + + /* disable break condition */ + serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); + + /* Disable line */ + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + serial_outp(info, UART_MCR,(info->MCR & ~(UART_MCR_DTR|UART_MCR_RTS))); + + /* put UART to sleep */ + sleep_uart(info); + + if (retval) + info->flags &= ~ASYNC_INITIALIZED; + return retval; +} +static int rs_suspend(struct tty_struct *tty) +{ + int retval = 0; + unsigned long flags; + save_flags(flags); cli(); + + retval = rs_suspend_uart((struct async_struct *)tty->driver_data); + + restore_flags(flags); + return retval; +} + +/* + * Resume an UART + */ + +/* Todo: eval multiport interrupt resume */ + +static int rs_resume_uart(struct async_struct *info) +{ + int retval = 0; + + printk("serio: Resuming %lx\n", info->port); + + if ((retval = start_uart(info))) + goto out; + retval = init_uart(info); +out: + if (retval) + info->flags &= ~ASYNC_INITIALIZED; + return retval; +} + +static int rs_resume(struct tty_struct *tty) +{ + int retval = 0; + unsigned long flags; + save_flags(flags); cli(); + + retval = rs_resume_uart((struct async_struct *)tty->driver_data); + + restore_flags(flags); + return retval; +} + +/* + * Suspend or Resume all UARTs + */ + +static int rs_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + struct serial_state *state = rs_table; + int i; + unsigned long flags; /* Interrupts will be reenabled once per iteration */ + + for (i =0; i < NR_PORTS; i++, state++) { + if (!state->info) /* info is NULL unless port opened */ + continue; + + save_flags(flags); cli(); + + switch (rqst) { + case PM_SUSPEND: + rs_suspend_uart(state->info); + break; + case PM_RESUME: + rs_resume_uart(state->info); + } + restore_flags(flags); + } + return 0; +} +#endif + /* * /proc fs routines.... */ @@ -5475,6 +5717,10 @@ serial_driver.wait_until_sent = rs_wait_until_sent; serial_driver.read_proc = rs_read_proc; #endif +#ifdef CONFIG_PM + serial_driver.suspend = rs_suspend; + serial_driver.resume = rs_resume; +#endif /* * The callout device is just like normal device except for @@ -5554,8 +5800,13 @@ probe_serial_pci(); #endif #ifdef ENABLE_SERIAL_PNP - probe_serial_pnp(); + probe_serial_pnp(); +#endif +#ifdef CONFIG_PM + if (!pm_register(PM_UNKNOWN_DEV, 0, rs_pm_callback)) + panic("Couldn't register with PM subsystem\n"); #endif + return 0; } @@ -5726,6 +5977,7 @@ struct async_struct *info; /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ + pm_unregister_all(rs_pm_callback); del_timer_sync(&serial_timer); save_flags(flags); cli(); remove_bh(SERIAL_BH); @@ -6001,6 +6253,30 @@ if (serial_in(info, UART_LSR) == 0xff) return -1; +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_KDB) + /* + * Remember the line number of the first serial + * console. We'll make this the kdb serial console too. + */ + if (kdb_serial_line == -1) { + kdb_serial_line = co->index; + kdb_serial.io_type = info->io_type; + switch (info->io_type) { + case SERIAL_IO_MEM: +#ifdef SERIAL_IO_MEM32 + case SERIAL_IO_MEM32: +#endif + kdb_serial.iobase = (unsigned long)(info->iomem_base); + kdb_serial.ioreg_shift = info->iomem_reg_shift; + break; + default: + kdb_serial.iobase = state->port; + kdb_serial.ioreg_shift = 0; + break; + } + } +#endif /* CONFIG_SERIAL_CONSOLE && CONFIG_KDB */ + return 0; } ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2004-02-07 11:53 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <BF1FE1855350A0479097B3A0D2A80EE0023E83B3@hdsmsx402.hd.intel.com>
2004-02-07 7:25 ` swusp acpi Len Brown
2004-02-07 11:50 ` Michael Frank
2004-01-21 9:43 tuija t.
2004-01-22 0:32 ` Pavel Machek
2004-01-22 1:45 ` Nigel Cunningham
2004-01-22 10:15 ` Pavel Machek
2004-01-22 10:22 ` Russell King
2004-01-22 10:26 ` Pavel Machek
2004-01-22 10:32 ` Russell King
2004-01-22 18:08 ` Nigel Cunningham
2004-01-22 20:43 ` Pavel Machek
2004-01-23 5:51 ` Michael Frank
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox