diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-14 18:07:46 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-14 18:07:46 -0800 |
commit | 0d7e0daa8a8fb7f9e2796f7b96374fcb07b152fd (patch) | |
tree | 31e8147e2a8f4e4ef5ad6146205e656b7745c867 /drivers | |
parent | a93e105a334c551338fa52386c52a1afc4018c44 (diff) | |
parent | 5ed500c58d9a11baeb62321963298a3235ac5ee0 (diff) | |
download | history-0d7e0daa8a8fb7f9e2796f7b96374fcb07b152fd.tar.gz |
Merge bk://linux-dj.bkbits.net/cpufreq
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/arm/icside.c | 31 | ||||
-rw-r--r-- | drivers/ide/cris/ide-v10.c | 19 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 15 | ||||
-rw-r--r-- | drivers/ide/ide-default.c | 1 | ||||
-rw-r--r-- | drivers/ide/ide-dma.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 11 | ||||
-rw-r--r-- | drivers/ide/ide-lib.c | 14 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide.c | 36 | ||||
-rw-r--r-- | drivers/ide/pci/atiixp.c | 5 | ||||
-rw-r--r-- | drivers/ide/pci/piix.c | 3 | ||||
-rw-r--r-- | drivers/ide/pci/piix.h | 1 | ||||
-rw-r--r-- | drivers/mmc/mmc_block.c | 12 | ||||
-rw-r--r-- | drivers/pci/pci.ids | 1 | ||||
-rw-r--r-- | drivers/pcmcia/Makefile | 1 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_sharpsl.c | 264 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 16 |
17 files changed, 316 insertions, 118 deletions
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 82817bc7ff61fe..e63ff1db270dd4 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -397,35 +397,6 @@ static void icside_dma_start(ide_drive_t *drive) enable_dma(hwif->hw.dma); } -/* - * dma_intr() is the handler for disk read/write DMA interrupts - */ -static ide_startstop_t icside_dmaintr(ide_drive_t *drive) -{ - unsigned int stat; - int dma_stat; - - dma_stat = icside_dma_end(drive); - stat = HWIF(drive)->INB(IDE_STATUS_REG); - if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) { - if (!dma_stat) { - struct request *rq = HWGROUP(drive)->rq; - int i; - - for (i = rq->nr_sectors; i > 0; ) { - i -= rq->current_nr_sectors; - DRIVER(drive)->end_request(drive, 1, rq->nr_sectors); - } - - return ide_stopped; - } - printk(KERN_ERR "%s: bad DMA status (dma_stat=%x)\n", - drive->name, dma_stat); - } - - return ide_error(drive, __FUNCTION__, stat); -} - static int icside_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); @@ -474,7 +445,7 @@ static int icside_dma_setup(ide_drive_t *drive) static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd) { /* issue cmd to drive */ - ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL); + ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL); } static int icside_dma_test_irq(ide_drive_t *drive) diff --git a/drivers/ide/cris/ide-v10.c b/drivers/ide/cris/ide-v10.c index 6a782931c33353..5b40220d3ddcee 100644 --- a/drivers/ide/cris/ide-v10.c +++ b/drivers/ide/cris/ide-v10.c @@ -753,27 +753,10 @@ static int config_drive_for_dma (ide_drive_t *drive) */ static ide_startstop_t etrax_dma_intr (ide_drive_t *drive) { - int i, dma_stat; - byte stat; - LED_DISK_READ(0); LED_DISK_WRITE(0); - dma_stat = HWIF(drive)->ide_dma_end(drive); - stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */ - if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { - if (!dma_stat) { - struct request *rq; - rq = HWGROUP(drive)->rq; - for (i = rq->nr_sectors; i > 0;) { - i -= rq->current_nr_sectors; - DRIVER(drive)->end_request(drive, 1, rq->nr_sectors); - } - return ide_stopped; - } - printk("%s: bad DMA status\n", drive->name); - } - return ide_error(drive, "dma_intr", stat); + return ide_dma_intr(drive); } /* diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 8778702739cdd8..a4ad198c4e25dd 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1464,19 +1464,6 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive) } -/* Sleep for TIME jiffies. - Not to be called from an interrupt handler. */ -static -void cdrom_sleep (int time) -{ - int sleep = time; - - do { - set_current_state(TASK_INTERRUPTIBLE); - sleep = schedule_timeout(sleep); - } while (sleep); -} - static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) { @@ -1511,7 +1498,7 @@ int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) /* The drive is in the process of loading a disk. Retry, but wait a little to give the drive time to complete the load. */ - cdrom_sleep(2 * HZ); + ssleep(2); } else { /* Otherwise, don't retry. */ retries = 0; diff --git a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c index a6bea5d0de036f..99fc59db018832 100644 --- a/drivers/ide/ide-default.c +++ b/drivers/ide/ide-default.c @@ -46,6 +46,7 @@ ide_driver_t idedefault_driver = { .name = "ide-default", .version = IDEDEFAULT_VERSION, .attach = idedefault_attach, + .cleanup = ide_unregister_subdriver, .drives = LIST_HEAD_INIT(idedefault_driver.drives) }; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 560e483eb63d4a..d40a08f41d43b4 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -158,7 +158,6 @@ static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *d return 0; } -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI /** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for @@ -188,6 +187,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) EXPORT_SYMBOL_GPL(ide_dma_intr); +#ifdef CONFIG_BLK_DEV_IDEDMA_PCI /** * ide_build_sglist - map IDE scatter gather for DMA I/O * @drive: the drive to build the DMA table for diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index e0ab726b1e4369..b839d34e7deea0 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -437,7 +437,7 @@ EXPORT_SYMBOL(ide_end_drive_cmd); * by read a sector's worth of data from the drive. Of course, * this may not help if the drive is *waiting* for data from *us*. */ -void try_to_flush_leftover_data (ide_drive_t *drive) +static void try_to_flush_leftover_data (ide_drive_t *drive) { int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS; @@ -452,8 +452,6 @@ void try_to_flush_leftover_data (ide_drive_t *drive) } } -EXPORT_SYMBOL(try_to_flush_leftover_data); - static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) { ide_hwif_t *hwif = drive->hwif; @@ -854,13 +852,6 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) goto kill_rq; } - /* - * bail early if we've sent a device to sleep, however how to wake - * this needs to be a masked flag. FIXME for proper operations. - */ - if (drive->suspend_reset) - goto kill_rq; - block = rq->sector; if (blk_fs_request(rq) && (drive->media == ide_disk || drive->media == ide_floppy)) { diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 26ceda6134d6e2..181b0b5b4f63e7 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -571,8 +571,7 @@ static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) status.all = stat; local_irq_set(flags); - printk("%s: %s: status=0x%02x", drive->name, msg, stat); - printk(" { "); + printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); if (status.b.bsy) printk("Busy "); else { @@ -584,18 +583,17 @@ static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) if (status.b.idx) printk("Index "); if (status.b.check) printk("Error "); } - printk("}"); - printk("\n"); + printk("}\n"); if ((status.all & (status.b.bsy|status.b.check)) == status.b.check) { error.all = HWIF(drive)->INB(IDE_ERROR_REG); - printk("%s: %s: error=0x%02x", drive->name, msg, error.all); + printk("%s: %s: error=0x%02x { ", drive->name, msg, error.all); if (error.b.ili) printk("IllegalLengthIndication "); if (error.b.eom) printk("EndOfMedia "); - if (error.b.abrt) printk("Aborted Command "); + if (error.b.abrt) printk("AbortedCommand "); if (error.b.mcr) printk("MediaChangeRequested "); - if (error.b.sense_key) printk("LastFailedSense 0x%02x ", + if (error.b.sense_key) printk("LastFailedSense=0x%02x ", error.b.sense_key); - printk("\n"); + printk("}\n"); } ide_dump_opcode(drive); local_irq_restore(flags); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index d0ffc54b662525..048548322264c7 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -749,7 +749,7 @@ static void probe_hwif(ide_hwif_t *hwif) * * BenH. */ - if (wait_hwif_ready(hwif)) + if (wait_hwif_ready(hwif) == -EBUSY) printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name); /* diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 7f867df01a5603..e96ae74bcb97ea 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1554,18 +1554,7 @@ int generic_ide_ioctl(struct file *file, struct block_device *bdev, HWGROUP(drive)->busy = 1; spin_unlock_irqrestore(&ide_lock, flags); (void) ide_do_reset(drive); - if (drive->suspend_reset) { -/* - * APM WAKE UP todo !! - * int nogoodpower = 1; - * while(nogoodpower) { - * check_power1() or check_power2() - * nogoodpower = 0; - * } - * HWIF(drive)->multiproc(drive); - */ - return ioctl_by_bdev(bdev, BLKRRPART, 0); - } + return 0; } @@ -2029,16 +2018,6 @@ static void __init probe_for_hwifs (void) #endif } -/* - * Actually unregister the subdriver. Called with the - * request lock dropped. - */ - -static int default_cleanup (ide_drive_t *drive) -{ - return ide_unregister_subdriver(drive); -} - static ide_startstop_t default_do_request (ide_drive_t *drive, struct request *rq, sector_t block) { ide_end_request(drive, 0, 0); @@ -2074,14 +2053,6 @@ static ide_startstop_t default_special (ide_drive_t *drive) return ide_stopped; } -static int default_attach (ide_drive_t *drive) -{ - printk(KERN_ERR "%s: does not support hotswap of device class !\n", - drive->name); - - return 0; -} - static ide_startstop_t default_abort(ide_drive_t *drive, struct request *rq) { return __ide_abort(drive, rq); @@ -2096,7 +2067,8 @@ static ide_startstop_t default_start_power_step(ide_drive_t *drive, static void setup_driver_defaults (ide_driver_t *d) { - if (d->cleanup == NULL) d->cleanup = default_cleanup; + BUG_ON(d->attach == NULL || d->cleanup == NULL); + if (d->do_request == NULL) d->do_request = default_do_request; if (d->end_request == NULL) d->end_request = default_end_request; if (d->error == NULL) d->error = default_error; @@ -2104,7 +2076,6 @@ static void setup_driver_defaults (ide_driver_t *d) if (d->pre_reset == NULL) d->pre_reset = default_pre_reset; if (d->capacity == NULL) d->capacity = default_capacity; if (d->special == NULL) d->special = default_special; - if (d->attach == NULL) d->attach = default_attach; if (d->start_power_step == NULL) d->start_power_step = default_start_power_step; } @@ -2133,7 +2104,6 @@ int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); drive->nice1 = 1; } - drive->suspend_reset = 0; #ifdef CONFIG_PROC_FS if (drive->driver != &idedefault_driver) { ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 10e438c964eac5..df9ee9a784350c 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -345,8 +345,9 @@ static int __devinit atiixp_init_one(struct pci_dev *dev, const struct pci_devic } static struct pci_device_id atiixp_pci_tbl[] = { - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 7be71917ed4287..bde44877bb971d 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -129,6 +129,7 @@ static u8 piix_ratemask (ide_drive_t *drive) case PCI_DEVICE_ID_INTEL_82801CA_10: case PCI_DEVICE_ID_INTEL_82801CA_11: case PCI_DEVICE_ID_INTEL_82801E_11: + case PCI_DEVICE_ID_INTEL_82801DB_1: case PCI_DEVICE_ID_INTEL_82801DB_10: case PCI_DEVICE_ID_INTEL_82801DB_11: case PCI_DEVICE_ID_INTEL_82801EB_11: @@ -440,6 +441,7 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char case PCI_DEVICE_ID_INTEL_82801BA_9: case PCI_DEVICE_ID_INTEL_82801CA_10: case PCI_DEVICE_ID_INTEL_82801CA_11: + case PCI_DEVICE_ID_INTEL_82801DB_1: case PCI_DEVICE_ID_INTEL_82801DB_10: case PCI_DEVICE_ID_INTEL_82801DB_11: case PCI_DEVICE_ID_INTEL_82801EB_11: @@ -614,6 +616,7 @@ static struct pci_device_id piix_pci_tbl[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22}, { 0, }, }; MODULE_DEVICE_TABLE(pci, piix_pci_tbl); diff --git a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h index d3f24732f1d002..fc207f5486b62b 100644 --- a/drivers/ide/pci/piix.h +++ b/drivers/ide/pci/piix.h @@ -59,6 +59,7 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { /* 19 */ DECLARE_PIIX_DEV("ICH5"), /* 20 */ DECLARE_PIIX_DEV("ICH6"), /* 21 */ DECLARE_PIIX_DEV("ICH7"), + /* 22 */ DECLARE_PIIX_DEV("ICH4"), }; #endif /* PIIX_H */ diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 49a1f1a40d9d2b..ea2927ee4085ba 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -332,6 +332,18 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) md->disk->queue = md->queue.queue; md->disk->driverfs_dev = &card->dev; + /* + * As discussed on lkml, GENHD_FL_REMOVABLE should: + * + * - be set for removable media with permanent block devices + * - be unset for removable block devices with permanent media + * + * Since MMC block devices clearly fall under the second + * case, we do not set GENHD_FL_REMOVABLE. Userspace + * should use the block device creation/destruction hotplug + * messages to tell when the card is present. + */ + sprintf(md->disk->disk_name, "mmcblk%d", devidx); sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index 7427c23113df28..7c1cbd0707d8f4 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids @@ -8088,6 +8088,7 @@ 24c0 82801DB/DBL (ICH4/ICH4-L) LPC Bridge 1014 0267 NetVista A30p 1462 5800 845PE Max (MS-6580) + 24c1 82801DBL (ICH4-L) IDE Controller 24c2 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 1014 0267 NetVista A30p 1071 8160 MIM2000 diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 3d5eb4984a7fbb..7c5a82898905a0 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -48,4 +48,5 @@ sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o +pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c new file mode 100644 index 00000000000000..cabb91fff0d91f --- /dev/null +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -0,0 +1,264 @@ +/* + * Sharp SL-C7xx Series PCMCIA routines + * + * Copyright (c) 2004-2005 Richard Purdie + * + * Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/device.h> + +#include <asm/hardware.h> +#include <asm/irq.h> + +#include <asm/hardware/scoop.h> +#include <asm/arch/corgi.h> +#include <asm/arch/pxa-regs.h> + +#include "soc_common.h" + +#define NO_KEEP_VS 0x0001 + +static unsigned char keep_vs; +static unsigned char keep_rd; + +static struct pcmcia_irqs irqs[] = { + { 0, CORGI_IRQ_GPIO_CF_CD, "PCMCIA0 CD"}, +}; + +static void sharpsl_pcmcia_init_reset(void) +{ + reset_scoop(); + keep_vs = NO_KEEP_VS; + keep_rd = 0; +} + +static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int ret; + + /* + * Setup default state of GPIO outputs + * before we enable them as outputs. + */ + GPSR(GPIO48_nPOE) = + GPIO_bit(GPIO48_nPOE) | + GPIO_bit(GPIO49_nPWE) | + GPIO_bit(GPIO50_nPIOR) | + GPIO_bit(GPIO51_nPIOW) | + GPIO_bit(GPIO52_nPCE_1) | + GPIO_bit(GPIO53_nPCE_2); + + pxa_gpio_mode(GPIO48_nPOE_MD); + pxa_gpio_mode(GPIO49_nPWE_MD); + pxa_gpio_mode(GPIO50_nPIOR_MD); + pxa_gpio_mode(GPIO51_nPIOW_MD); + pxa_gpio_mode(GPIO52_nPCE_1_MD); + pxa_gpio_mode(GPIO53_nPCE_2_MD); + pxa_gpio_mode(GPIO54_pSKTSEL_MD); + pxa_gpio_mode(GPIO55_nPREG_MD); + pxa_gpio_mode(GPIO56_nPWAIT_MD); + pxa_gpio_mode(GPIO57_nIOIS16_MD); + + /* Register interrupts */ + ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); + + if (ret) { + printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); + return ret; + } + + /* Enable interrupt */ + write_scoop_reg(SCOOP_IMR, 0x00C0); + write_scoop_reg(SCOOP_MCR, 0x0101); + keep_vs = NO_KEEP_VS; + + skt->irq = CORGI_IRQ_GPIO_CF_IRQ; + + return 0; +} + +static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + + /* CF_BUS_OFF */ + sharpsl_pcmcia_init_reset(); +} + + +static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + unsigned short cpr, csr; + + cpr = read_scoop_reg(SCOOP_CPR); + + write_scoop_reg(SCOOP_IRM, 0x00FF); + write_scoop_reg(SCOOP_ISR, 0x0000); + write_scoop_reg(SCOOP_IRM, 0x0000); + csr = read_scoop_reg(SCOOP_CSR); + if (csr & 0x0004) { + /* card eject */ + write_scoop_reg(SCOOP_CDR, 0x0000); + keep_vs = NO_KEEP_VS; + } + else if (!(keep_vs & NO_KEEP_VS)) { + /* keep vs1,vs2 */ + write_scoop_reg(SCOOP_CDR, 0x0000); + csr |= keep_vs; + } + else if (cpr & 0x0003) { + /* power on */ + write_scoop_reg(SCOOP_CDR, 0x0000); + keep_vs = (csr & 0x00C0); + } + else { + /* card detect */ + write_scoop_reg(SCOOP_CDR, 0x0002); + } + + state->detect = (csr & 0x0004) ? 0 : 1; + state->ready = (csr & 0x0002) ? 1 : 0; + state->bvd1 = (csr & 0x0010) ? 1 : 0; + state->bvd2 = (csr & 0x0020) ? 1 : 0; + state->wrprot = (csr & 0x0008) ? 1 : 0; + state->vs_3v = (csr & 0x0040) ? 0 : 1; + state->vs_Xv = (csr & 0x0080) ? 0 : 1; + + if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { + printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); + } + +} + + +static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + unsigned long flags; + + unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; + + switch (state->Vcc) { + case 0: break; + case 33: break; + case 50: break; + default: + printk(KERN_ERR "sharpsl_pcmcia_configure_socket(): bad Vcc %u\n", state->Vcc); + return -1; + } + + if ((state->Vpp!=state->Vcc) && (state->Vpp!=0)) { + printk(KERN_ERR "CF slot cannot support Vpp %u\n", state->Vpp); + return -1; + } + + local_irq_save(flags); + + nmcr = (mcr = read_scoop_reg(SCOOP_MCR)) & ~0x0010; + ncpr = (cpr = read_scoop_reg(SCOOP_CPR)) & ~0x0083; + nccr = (ccr = read_scoop_reg(SCOOP_CCR)) & ~0x0080; + nimr = (imr = read_scoop_reg(SCOOP_IMR)) & ~0x003E; + + ncpr |= (state->Vcc == 33) ? 0x0001 : + (state->Vcc == 50) ? 0x0002 : 0; + nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; + ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; + nccr |= (state->flags&SS_RESET)? 0x0080: 0; + nimr |= ((skt->status&SS_DETECT) ? 0x0004 : 0)| + ((skt->status&SS_READY) ? 0x0002 : 0)| + ((skt->status&SS_BATDEAD)? 0x0010 : 0)| + ((skt->status&SS_BATWARN)? 0x0020 : 0)| + ((skt->status&SS_STSCHG) ? 0x0010 : 0)| + ((skt->status&SS_WRPROT) ? 0x0008 : 0); + + if (!(ncpr & 0x0003)) { + keep_rd = 0; + } else if (!keep_rd) { + if (nccr & 0x0080) + keep_rd = 1; + else + nccr |= 0x0080; + } + + if (mcr != nmcr) + write_scoop_reg(SCOOP_MCR, nmcr); + if (cpr != ncpr) + write_scoop_reg(SCOOP_CPR, ncpr); + if (ccr != nccr) + write_scoop_reg(SCOOP_CCR, nccr); + if (imr != nimr) + write_scoop_reg(SCOOP_IMR, nimr); + + local_irq_restore(flags); + + return 0; +} + +static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +static struct pcmcia_low_level sharpsl_pcmcia_ops = { + .owner = THIS_MODULE, + .hw_init = sharpsl_pcmcia_hw_init, + .hw_shutdown = sharpsl_pcmcia_hw_shutdown, + .socket_state = sharpsl_pcmcia_socket_state, + .configure_socket = sharpsl_pcmcia_configure_socket, + .socket_init = sharpsl_pcmcia_socket_init, + .socket_suspend = sharpsl_pcmcia_socket_suspend, + .first = 0, + .nr = 1, +}; + +static struct platform_device *sharpsl_pcmcia_device; + +static int __init sharpsl_pcmcia_init(void) +{ + int ret; + + sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); + if (!sharpsl_pcmcia_device) + return -ENOMEM; + memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); + sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; + sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; + + ret = platform_device_register(sharpsl_pcmcia_device); + if (ret) + kfree(sharpsl_pcmcia_device); + + return ret; +} + +static void __exit sharpsl_pcmcia_exit(void) +{ + /* + * This call is supposed to free our sharpsl_pcmcia_device. + * Unfortunately platform_device don't have a free method, and + * we can't assume it's free of any reference at this point so we + * can't free it either. + */ + platform_device_unregister(sharpsl_pcmcia_device); +} + +module_init(sharpsl_pcmcia_init); +module_exit(sharpsl_pcmcia_exit); + +MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 5ed45a7cbddad7..16c227d30016b7 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1877,7 +1877,21 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) * Re-enable the console device after suspending. */ if (uart_console(port)) { - uart_change_speed(state, NULL); + struct termios termios; + + /* + * First try to use the console cflag setting. + */ + memset(&termios, 0, sizeof(struct termios)); + termios.c_cflag = port->cons->cflag; + + /* + * If that's unset, use the tty termios setting. + */ + if (state->info && state->info->tty && termios.c_cflag == 0) + termios = *state->info->tty->termios; + + port->ops->set_termios(port, &termios, NULL); console_start(port->cons); } |