aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 18:07:46 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 18:07:46 -0800
commit0d7e0daa8a8fb7f9e2796f7b96374fcb07b152fd (patch)
tree31e8147e2a8f4e4ef5ad6146205e656b7745c867 /drivers
parenta93e105a334c551338fa52386c52a1afc4018c44 (diff)
parent5ed500c58d9a11baeb62321963298a3235ac5ee0 (diff)
downloadhistory-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.c31
-rw-r--r--drivers/ide/cris/ide-v10.c19
-rw-r--r--drivers/ide/ide-cd.c15
-rw-r--r--drivers/ide/ide-default.c1
-rw-r--r--drivers/ide/ide-dma.c2
-rw-r--r--drivers/ide/ide-io.c11
-rw-r--r--drivers/ide/ide-lib.c14
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/ide/ide.c36
-rw-r--r--drivers/ide/pci/atiixp.c5
-rw-r--r--drivers/ide/pci/piix.c3
-rw-r--r--drivers/ide/pci/piix.h1
-rw-r--r--drivers/mmc/mmc_block.c12
-rw-r--r--drivers/pci/pci.ids1
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c264
-rw-r--r--drivers/serial/serial_core.c16
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);
}