summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ata_piix.c2
-rw-r--r--drivers/ata/sata_inic162x.c3
-rw-r--r--drivers/ide/ide-cd.c2
-rw-r--r--drivers/ide/pci/hpt366.c31
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/memstick/core/memstick.c10
-rw-r--r--drivers/memstick/core/mspro_block.c33
-rw-r--r--drivers/memstick/host/jmb38x_ms.c39
-rw-r--r--drivers/misc/sgi-gru/grufile.c3
-rw-r--r--drivers/net/niu.c56
-rw-r--r--drivers/net/wireless/ath9k/beacon.c13
-rw-r--r--drivers/net/wireless/ath9k/core.h1
-rw-r--r--drivers/net/wireless/ath9k/main.c14
-rw-r--r--drivers/pci/hotplug/fakephp.c6
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c2
-rw-r--r--drivers/pci/intel-iommu.c23
-rw-r--r--drivers/pci/probe.c18
-rw-r--r--drivers/pci/setup-bus.c6
-rw-r--r--drivers/pcmcia/soc_common.c6
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c6
-rw-r--r--drivers/s390/scsi/zfcp_fc.c33
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c88
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c4
-rw-r--r--drivers/scsi/Kconfig2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c12
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c4
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c4
-rw-r--r--drivers/scsi/scsi_error.c2
-rw-r--r--drivers/scsi/scsi_scan.c3
-rw-r--r--drivers/scsi/sd.c2
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--drivers/serial/imx.c27
-rw-r--r--drivers/spi/pxa2xx_spi.c116
-rw-r--r--drivers/spi/spi_mpc83xx.c26
-rw-r--r--drivers/spi/spi_s3c24xx.c6
-rw-r--r--drivers/video/atmel_lcdfb.c84
36 files changed, 469 insertions, 222 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index b1d08a8f500..e6b4606e36b 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1499,7 +1499,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
* off.
*/
if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2652) {
- int rc = piix_disable_ahci(pdev);
+ rc = piix_disable_ahci(pdev);
if (rc)
return rc;
}
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 3ead02fe379..5032c32fa50 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -96,6 +96,7 @@ enum {
PORT_SCR = 0x20,
/* HOST_CTL bits */
+ HCTL_LEDEN = (1 << 3), /* enable LED operation */
HCTL_IRQOFF = (1 << 8), /* global IRQ off */
HCTL_FTHD0 = (1 << 10), /* fifo threshold 0 */
HCTL_FTHD1 = (1 << 11), /* fifo threshold 1*/
@@ -540,7 +541,7 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
void __iomem *port_base = inic_port_base(ap);
/* fire up the ADMA engine */
- writew(HCTL_FTHD0, port_base + HOST_CTL);
+ writew(HCTL_FTHD0 | HCTL_LEDEN, port_base + HOST_CTL);
writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL);
writeb(0, port_base + PORT_CPB_PTQFIFO);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index f1489999cf9..49a8c589e34 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1933,7 +1933,6 @@ static void ide_cd_remove(ide_drive_t *drive)
ide_proc_unregister_driver(drive, info->driver);
- blk_unregister_filter(info->disk);
del_gendisk(info->disk);
ide_cd_put(info);
@@ -2159,7 +2158,6 @@ static int ide_cd_probe(ide_drive_t *drive)
g->fops = &idecd_ops;
g->flags |= GENHD_FL_REMOVABLE;
add_disk(g);
- blk_register_filter(g);
return 0;
out_free_cd:
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index eb107eef0db..c37ab174381 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -613,6 +613,14 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
return 0;
}
+static struct hpt_info *hpt3xx_get_info(struct device *dev)
+{
+ struct ide_host *host = dev_get_drvdata(dev);
+ struct hpt_info *info = (struct hpt_info *)host->host_priv;
+
+ return dev == host->dev[1] ? info + 1 : info;
+}
+
/*
* The Marvell bridge chips used on the HighPoint SATA cards do not seem
* to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes...
@@ -621,9 +629,7 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
static u8 hpt3xx_udma_filter(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_host *host = pci_get_drvdata(dev);
- struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]);
+ struct hpt_info *info = hpt3xx_get_info(hwif->dev);
u8 mask = hwif->ultra_mask;
switch (info->chip_type) {
@@ -662,9 +668,7 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive)
static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_host *host = pci_get_drvdata(dev);
- struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]);
+ struct hpt_info *info = hpt3xx_get_info(hwif->dev);
switch (info->chip_type) {
case HPT372 :
@@ -700,8 +704,7 @@ static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_host *host = pci_get_drvdata(dev);
- struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]);
+ struct hpt_info *info = hpt3xx_get_info(hwif->dev);
struct hpt_timings *t = info->timings;
u8 itr_addr = 0x40 + (drive->dn * 4);
u32 old_itr = 0;
@@ -744,8 +747,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_host *host = pci_get_drvdata(dev);
- struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]);
+ struct hpt_info *info = hpt3xx_get_info(hwif->dev);
if (drive->quirk_list) {
if (info->chip_type >= HPT370) {
@@ -973,8 +975,7 @@ static int __devinit hpt37x_calibrate_dpll(struct pci_dev *dev, u16 f_low, u16 f
static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev)
{
unsigned long io_base = pci_resource_start(dev, 4);
- struct ide_host *host = pci_get_drvdata(dev);
- struct hpt_info *info = host->host_priv + (&dev->dev == host->dev[1]);
+ struct hpt_info *info = hpt3xx_get_info(&dev->dev);
const char *name = DRV_NAME;
u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */
u8 chip_type;
@@ -1217,8 +1218,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev)
static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_host *host = pci_get_drvdata(dev);
- struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]);
+ struct hpt_info *info = hpt3xx_get_info(hwif->dev);
u8 chip_type = info->chip_type;
u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02;
@@ -1262,8 +1262,7 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_host *host = pci_get_drvdata(dev);
- struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]);
+ struct hpt_info *info = hpt3xx_get_info(hwif->dev);
int serialize = HPT_SERIALIZE_IO;
u8 chip_type = info->chip_type;
u8 new_mcr, old_mcr = 0;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ecbfa1b39b7..3e9e0dcd217 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -968,7 +968,7 @@ config VIDEO_PXA27x
config VIDEO_SH_MOBILE_CEU
tristate "SuperH Mobile CEU Interface driver"
- depends on VIDEO_DEV
+ depends on VIDEO_DEV && HAS_DMA
select SOC_CAMERA
select VIDEOBUF_DMA_CONTIG
---help---
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index a38005008a2..cea46906408 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -185,7 +185,7 @@ static void memstick_free(struct device *dev)
}
static struct class memstick_host_class = {
- .name = "memstick_host",
+ .name = "memstick_host",
.dev_release = memstick_free
};
@@ -264,7 +264,7 @@ EXPORT_SYMBOL(memstick_new_req);
* @sg - TPC argument
*/
void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
- struct scatterlist *sg)
+ const struct scatterlist *sg)
{
mrq->tpc = tpc;
if (tpc & 8)
@@ -294,7 +294,7 @@ EXPORT_SYMBOL(memstick_init_req_sg);
* user supplied buffer.
*/
void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
- void *buf, size_t length)
+ const void *buf, size_t length)
{
mrq->tpc = tpc;
if (tpc & 8)
@@ -439,7 +439,7 @@ static void memstick_check(struct work_struct *work)
if (!host->card) {
if (memstick_power_on(host))
goto out_power_off;
- } else
+ } else if (host->card->stop)
host->card->stop(host->card);
card = memstick_alloc_card(host);
@@ -458,7 +458,7 @@ static void memstick_check(struct work_struct *work)
|| !(host->card->check(host->card))) {
device_unregister(&host->card->dev);
host->card = NULL;
- } else
+ } else if (host->card->start)
host->card->start(host->card);
}
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 44b1817f2f2..d2d2318dafa 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -30,6 +30,8 @@ module_param(major, int, 0644);
#define MSPRO_BLOCK_SIGNATURE 0xa5c3
#define MSPRO_BLOCK_MAX_ATTRIBUTES 41
+#define MSPRO_BLOCK_PART_SHIFT 3
+
enum {
MSPRO_BLOCK_ID_SYSINFO = 0x10,
MSPRO_BLOCK_ID_MODELNAME = 0x15,
@@ -195,7 +197,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp)
static int mspro_block_disk_release(struct gendisk *disk)
{
struct mspro_block_data *msb = disk->private_data;
- int disk_id = disk->first_minor >> MEMSTICK_PART_SHIFT;
+ int disk_id = disk->first_minor >> MSPRO_BLOCK_PART_SHIFT;
mutex_lock(&mspro_block_disk_lock);
@@ -877,6 +879,7 @@ static int mspro_block_switch_interface(struct memstick_dev *card)
struct mspro_block_data *msb = memstick_get_drvdata(card);
int rc = 0;
+try_again:
if (msb->caps & MEMSTICK_CAP_PAR4)
rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR4);
else
@@ -930,6 +933,18 @@ static int mspro_block_switch_interface(struct memstick_dev *card)
rc = memstick_set_rw_addr(card);
if (!rc)
rc = mspro_block_set_interface(card, msb->system);
+
+ if (!rc) {
+ msleep(150);
+ rc = mspro_block_wait_for_ced(card);
+ if (rc)
+ return rc;
+
+ if (msb->caps & MEMSTICK_CAP_PAR8) {
+ msb->caps &= ~MEMSTICK_CAP_PAR8;
+ goto try_again;
+ }
+ }
}
return rc;
}
@@ -1117,14 +1132,16 @@ static int mspro_block_init_card(struct memstick_dev *card)
return -EIO;
msb->caps = host->caps;
- rc = mspro_block_switch_interface(card);
+
+ msleep(150);
+ rc = mspro_block_wait_for_ced(card);
if (rc)
return rc;
- msleep(200);
- rc = mspro_block_wait_for_ced(card);
+ rc = mspro_block_switch_interface(card);
if (rc)
return rc;
+
dev_dbg(&card->dev, "card activated\n");
if (msb->system != MEMSTICK_SYS_SERIAL)
msb->caps |= MEMSTICK_CAP_AUTO_GET_INT;
@@ -1192,12 +1209,12 @@ static int mspro_block_init_disk(struct memstick_dev *card)
if (rc)
return rc;
- if ((disk_id << MEMSTICK_PART_SHIFT) > 255) {
+ if ((disk_id << MSPRO_BLOCK_PART_SHIFT) > 255) {
rc = -ENOSPC;
goto out_release_id;
}
- msb->disk = alloc_disk(1 << MEMSTICK_PART_SHIFT);
+ msb->disk = alloc_disk(1 << MSPRO_BLOCK_PART_SHIFT);
if (!msb->disk) {
rc = -ENOMEM;
goto out_release_id;
@@ -1220,7 +1237,7 @@ static int mspro_block_init_disk(struct memstick_dev *card)
MSPRO_BLOCK_MAX_PAGES * msb->page_size);
msb->disk->major = major;
- msb->disk->first_minor = disk_id << MEMSTICK_PART_SHIFT;
+ msb->disk->first_minor = disk_id << MSPRO_BLOCK_PART_SHIFT;
msb->disk->fops = &ms_block_bdops;
msb->usage_count = 1;
msb->disk->private_data = msb;
@@ -1416,7 +1433,7 @@ out_unlock:
static struct memstick_device_id mspro_block_id_tbl[] = {
{MEMSTICK_MATCH_ALL, MEMSTICK_TYPE_PRO, MEMSTICK_CATEGORY_STORAGE_DUO,
- MEMSTICK_CLASS_GENERIC_DUO},
+ MEMSTICK_CLASS_DUO},
{}
};
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 3485c63d20b..2fb95a5b72e 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -81,6 +81,8 @@ struct jmb38x_ms {
#define TPC_CODE_SZ_MASK 0x00000700
#define TPC_DATA_SZ_MASK 0x00000007
+#define HOST_CONTROL_TDELAY_EN 0x00040000
+#define HOST_CONTROL_HW_OC_P 0x00010000
#define HOST_CONTROL_RESET_REQ 0x00008000
#define HOST_CONTROL_REI 0x00004000
#define HOST_CONTROL_LED 0x00000400
@@ -88,6 +90,7 @@ struct jmb38x_ms {
#define HOST_CONTROL_RESET 0x00000100
#define HOST_CONTROL_POWER_EN 0x00000080
#define HOST_CONTROL_CLOCK_EN 0x00000040
+#define HOST_CONTROL_REO 0x00000008
#define HOST_CONTROL_IF_SHIFT 4
#define HOST_CONTROL_IF_SERIAL 0x0
@@ -133,11 +136,15 @@ struct jmb38x_ms {
#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
#define CLOCK_CONTROL_40MHZ 0x00000001
-#define CLOCK_CONTROL_50MHZ 0x00000002
+#define CLOCK_CONTROL_50MHZ 0x0000000a
#define CLOCK_CONTROL_60MHZ 0x00000008
#define CLOCK_CONTROL_62_5MHZ 0x0000000c
#define CLOCK_CONTROL_OFF 0x00000000
+#define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0
+#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00
+#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000
+
enum {
CMD_READY = 0x01,
FIFO_READY = 0x02,
@@ -367,8 +374,7 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
return host->req->error;
}
- dev_dbg(&msh->dev, "control %08x\n",
- readl(host->addr + HOST_CONTROL));
+ dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL));
dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS));
dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS));
@@ -637,7 +643,7 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
ndelay(20);
}
dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
- return -EIO;
+ /* return -EIO; */
reset_next:
writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
@@ -680,7 +686,9 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
host_ctl = 7;
host_ctl |= HOST_CONTROL_POWER_EN
- | HOST_CONTROL_CLOCK_EN;
+ | HOST_CONTROL_CLOCK_EN
+ | HOST_CONTROL_HW_OC_P
+ | HOST_CONTROL_TDELAY_EN;
writel(host_ctl, host->addr + HOST_CONTROL);
writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
@@ -704,33 +712,40 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
break;
case MEMSTICK_INTERFACE:
host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
+ pci_read_config_dword(host->chip->pdev,
+ PCI_CTL_CLOCK_DLY_ADDR,
+ &clock_delay);
+ clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B
+ : ~PCI_CTL_CLOCK_DLY_MASK_A;
if (value == MEMSTICK_SERIAL) {
host_ctl &= ~HOST_CONTROL_FAST_CLK;
+ host_ctl &= ~HOST_CONTROL_REO;
host_ctl |= HOST_CONTROL_IF_SERIAL
<< HOST_CONTROL_IF_SHIFT;
host_ctl |= HOST_CONTROL_REI;
clock_ctl = CLOCK_CONTROL_40MHZ;
- clock_delay = 0;
} else if (value == MEMSTICK_PAR4) {
- host_ctl |= HOST_CONTROL_FAST_CLK;
+ host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO;
host_ctl |= HOST_CONTROL_IF_PAR4
<< HOST_CONTROL_IF_SHIFT;
host_ctl &= ~HOST_CONTROL_REI;
clock_ctl = CLOCK_CONTROL_40MHZ;
- clock_delay = 4;
+ clock_delay |= host->id ? (4 << 12) : (4 << 8);
} else if (value == MEMSTICK_PAR8) {
host_ctl |= HOST_CONTROL_FAST_CLK;
host_ctl |= HOST_CONTROL_IF_PAR8
<< HOST_CONTROL_IF_SHIFT;
- host_ctl &= ~HOST_CONTROL_REI;
- clock_ctl = CLOCK_CONTROL_60MHZ;
- clock_delay = 0;
+ host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO);
+ clock_ctl = CLOCK_CONTROL_50MHZ;
} else
return -EINVAL;
+
writel(host_ctl, host->addr + HOST_CONTROL);
writel(clock_ctl, host->addr + CLOCK_CONTROL);
- writel(clock_delay, host->addr + CLOCK_DELAY);
+ pci_write_config_dword(host->chip->pdev,
+ PCI_CTL_CLOCK_DLY_ADDR,
+ clock_delay);
break;
};
return 0;
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 23c91f5f6b6..d61cee796ef 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -445,6 +445,9 @@ static void __exit gru_exit(void)
int order = get_order(sizeof(struct gru_state) *
GRU_CHIPLETS_PER_BLADE);
+ if (!IS_UV())
+ return;
+
for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
free_irq(IRQ_GRU + i, NULL);
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index e4765b713ab..e3be81eba8a 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -5984,6 +5984,56 @@ static void niu_netif_start(struct niu *np)
niu_enable_interrupts(np, 1);
}
+static void niu_reset_buffers(struct niu *np)
+{
+ int i, j, k, err;
+
+ if (np->rx_rings) {
+ for (i = 0; i < np->num_rx_rings; i++) {
+ struct rx_ring_info *rp = &np->rx_rings[i];
+
+ for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
+ struct page *page;
+
+ page = rp->rxhash[j];
+ while (page) {
+ struct page *next =
+ (struct page *) page->mapping;
+ u64 base = page->index;
+ base = base >> RBR_DESCR_ADDR_SHIFT;
+ rp->rbr[k++] = cpu_to_le32(base);
+ page = next;
+ }
+ }
+ for (; k < MAX_RBR_RING_SIZE; k++) {
+ err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
+ if (unlikely(err))
+ break;
+ }
+
+ rp->rbr_index = rp->rbr_table_size - 1;
+ rp->rcr_index = 0;
+ rp->rbr_pending = 0;
+ rp->rbr_refill_pending = 0;
+ }
+ }
+ if (np->tx_rings) {
+ for (i = 0; i < np->num_tx_rings; i++) {
+ struct tx_ring_info *rp = &np->tx_rings[i];
+
+ for (j = 0; j < MAX_TX_RING_SIZE; j++) {
+ if (rp->tx_buffs[j].skb)
+ (void) release_tx_packet(np, rp, j);
+ }
+
+ rp->pending = MAX_TX_RING_SIZE;
+ rp->prod = 0;
+ rp->cons = 0;
+ rp->wrap_bit = 0;
+ }
+ }
+}
+
static void niu_reset_task(struct work_struct *work)
{
struct niu *np = container_of(work, struct niu, reset_task);
@@ -6006,6 +6056,12 @@ static void niu_reset_task(struct work_struct *work)
niu_stop_hw(np);
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ niu_reset_buffers(np);
+
+ spin_lock_irqsave(&np->lock, flags);
+
err = niu_init_hw(np);
if (!err) {
np->timer.expires = jiffies + HZ;
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index caf569401a3..00a0eaa0886 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -209,6 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
unsigned int curlen;
struct ath_txq *cabq;
struct ath_txq *mcastq;
+ struct ieee80211_tx_info *info;
avp = sc->sc_vaps[if_id];
mcastq = &avp->av_mcastq;
@@ -232,6 +233,18 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
*/
curlen = skb->len;
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ /*
+ * TODO: make sure the seq# gets assigned properly (vs. other
+ * TX frames)
+ */
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ sc->seq_no += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+ }
+
/* XXX: spin_lock_bh should not be used here, but sparse bitches
* otherwise. We should fix sparse :) */
spin_lock_bh(&mcastq->axq_lock);
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 673b3d81133..4ee695b76b8 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -992,6 +992,7 @@ struct ath_softc {
u32 sc_txintrperiod; /* tx interrupt batching */
int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
u32 sc_ant_tx[8]; /* recent tx frames/antenna */
+ u16 seq_no; /* TX sequence number */
/* Beacon */
struct ath9k_tx_queue_info sc_beacon_qi;
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index c5107f269f2..99badf1404c 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -369,6 +369,20 @@ static int ath9k_tx(struct ieee80211_hw *hw,
{
struct ath_softc *sc = hw->priv;
int hdrlen, padsize;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ /*
+ * As a temporary workaround, assign seq# here; this will likely need
+ * to be cleaned up to work better with Beacon transmission and virtual
+ * BSSes.
+ */
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+ sc->seq_no += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+ }
/* Add the padding after the header if this is not already done */
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index 40337a06c18..146ca9cd156 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -320,15 +320,15 @@ static int disable_slot(struct hotplug_slot *slot)
return -ENODEV;
}
+ /* remove the device from the pci core */
+ pci_remove_bus_device(dev);
+
/* queue work item to blow away this sysfs entry and other
* parts.
*/
INIT_WORK(&dslot->remove_work, remove_slot_worker);
queue_work(dummyphp_wq, &dslot->remove_work);
- /* blow away this sysfs entry and other parts. */
- remove_slot(dslot);
-
pci_dev_put(dev);
}
return 0;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index ab31f5ba665..9d934ddee95 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -258,7 +258,7 @@ static int pcie_poll_cmd(struct controller *ctrl)
return 1;
}
}
- while (timeout > 1000) {
+ while (timeout > 0) {
msleep(10);
timeout -= 10;
if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) {
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index eaba6ecc2ad..6c4c1c3c50e 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -2348,11 +2348,34 @@ static void __init iommu_exit_mempool(void)
}
+static int blacklist_iommu(const struct dmi_system_id *id)
+{
+ printk(KERN_INFO "%s detected; disabling IOMMU\n",
+ id->ident);
+ dmar_disabled = 1;
+ return 0;
+}
+
+static struct dmi_system_id __initdata intel_iommu_dmi_table[] = {
+ { /* Some DG33BU BIOS revisions advertised non-existent VT-d */
+ .callback = blacklist_iommu,
+ .ident = "Intel DG33BU",
+ { DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+ DMI_MATCH(DMI_BOARD_NAME, "DG33BU"),
+ }
+ },
+ { }
+};
+
+
void __init detect_intel_iommu(void)
{
if (swiotlb || no_iommu || iommu_detected || dmar_disabled)
return;
if (early_dmar_detect()) {
+ dmi_check_system(intel_iommu_dmi_table);
+ if (dmar_disabled)
+ return;
iommu_detected = 1;
}
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cce2f4cb1fb..36698e57b97 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -304,6 +304,9 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
} else {
res->start = l64;
res->end = l64 + sz64;
+ printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: [%llx, %llx]\n",
+ pci_name(dev), pos, (unsigned long long)res->start,
+ (unsigned long long)res->end);
}
} else {
sz = pci_size(l, sz, mask);
@@ -313,6 +316,9 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
res->start = l;
res->end = l + sz;
+ printk(KERN_DEBUG "PCI: %s reg %x %s: [%llx, %llx]\n", pci_name(dev),
+ pos, (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio",
+ (unsigned long long)res->start, (unsigned long long)res->end);
}
out:
@@ -383,7 +389,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->start = base;
if (!res->end)
res->end = limit + 0xfff;
- printk(KERN_INFO "PCI: bridge %s io port: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
+ printk(KERN_DEBUG "PCI: bridge %s io port: [%llx, %llx]\n",
+ pci_name(dev), (unsigned long long) res->start,
+ (unsigned long long) res->end);
}
res = child->resource[1];
@@ -395,7 +403,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
res->start = base;
res->end = limit + 0xfffff;
- printk(KERN_INFO "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
+ printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: [%llx, %llx]\n",
+ pci_name(dev), (unsigned long long) res->start,
+ (unsigned long long) res->end);
}
res = child->resource[2];
@@ -431,7 +441,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
res->start = base;
res->end = limit + 0xfffff;
- printk(KERN_INFO "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64)?"64":"32",res->start, res->end);
+ printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n",
+ pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
+ (unsigned long long) res->start, (unsigned long long) res->end);
}
}
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 1aad599816f..3abbfad9dda 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -540,7 +540,11 @@ static void pci_bus_dump_res(struct pci_bus *bus)
if (!res)
continue;
- printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", bus->number, i, (res->flags & IORESOURCE_IO)? "io port":"mmio", res->start, res->end);
+ printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n",
+ bus->number, i,
+ (res->flags & IORESOURCE_IO) ? "io port" : "mmio",
+ (unsigned long long) res->start,
+ (unsigned long long) res->end);
}
}
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index c48f3f69bda..da397215322 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -748,7 +748,9 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
add_timer(&skt->poll_timer);
- device_create_file(&skt->socket.dev, &dev_attr_status);
+ ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+ if (ret)
+ goto out_err_8;
}
dev_set_drvdata(dev, sinfo);
@@ -758,6 +760,8 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
do {
skt = &sinfo->skt[i];
+ device_remove_file(&skt->socket.dev, &dev_attr_status);
+ out_err_8:
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 391dd29749f..51b6a05f4d1 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -152,10 +152,8 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
*/
static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
{
- struct zfcp_adapter *adapter;
+ struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev);
- down(&zfcp_data.config_sema);
- adapter = dev_get_drvdata(&ccw_device->dev);
switch (event) {
case CIO_GONE:
dev_warn(&adapter->ccw_device->dev, "device gone\n");
@@ -174,8 +172,6 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
89, NULL);
break;
}
- zfcp_erp_wait(adapter);
- up(&zfcp_data.config_sema);
return 1;
}
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index e984469bb98..56196c98c07 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -39,18 +39,6 @@ struct zfcp_gpn_ft {
struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
};
-static struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter,
- u32 d_id)
-{
- struct zfcp_port *port;
-
- list_for_each_entry(port, &adapter->port_list_head, list)
- if ((port->d_id == d_id) &&
- !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status))
- return port;
- return NULL;
-}
-
static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
struct fcp_rscn_element *elem)
{
@@ -341,12 +329,13 @@ void zfcp_test_link(struct zfcp_port *port)
zfcp_port_get(port);
retval = zfcp_fc_adisc(port);
- if (retval == 0 || retval == -EBUSY)
+ if (retval == 0)
return;
/* send of ADISC was not possible */
zfcp_port_put(port);
- zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
+ if (retval != -EBUSY)
+ zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
}
static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
@@ -363,7 +352,6 @@ static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
if (ret)
return ret;
zfcp_erp_wait(adapter);
- zfcp_port_put(adapter->nameserver_port);
}
return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
&adapter->nameserver_port->status);
@@ -475,7 +463,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
struct zfcp_adapter *adapter = ct->port->adapter;
struct zfcp_port *port, *tmp;
u32 d_id;
- int ret = 0, x;
+ int ret = 0, x, last = 0;
if (ct->status)
return -EIO;
@@ -492,19 +480,24 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
down(&zfcp_data.config_sema);
/* first entry is the header */
- for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) {
+ for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) {
if (x % (ZFCP_GPN_FT_ENTRIES + 1))
acc++;
else
acc = sg_virt(++sg);
+ last = acc->control & 0x80;
d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
acc->port_id[2];
/* skip the adapter's port and known remote ports */
- if (acc->wwpn == fc_host_port_name(adapter->scsi_host) ||
- zfcp_get_port_by_did(adapter, d_id))
+ if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
+ continue;
+ port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
+ if (port) {
+ zfcp_port_get(port);
continue;
+ }
port = zfcp_port_enqueue(adapter, acc->wwpn,
ZFCP_STATUS_PORT_DID_DID |
@@ -513,8 +506,6 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
ret = PTR_ERR(port);
else
zfcp_erp_port_reopen(port, 0, 149, NULL);
- if (acc->control & 0x80) /* last entry */
- break;
}
zfcp_erp_wait(adapter);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 19c1ca91387..49dbeb754e5 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -710,10 +710,10 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue)
{
- spin_lock(&queue->lock);
+ spin_lock_bh(&queue->lock);
if (atomic_read(&queue->count))
return 1;
- spin_unlock(&queue->lock);
+ spin_unlock_bh(&queue->lock);
return 0;
}
@@ -722,13 +722,13 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
long ret;
struct zfcp_qdio_queue *req_q = &adapter->req_q;
- spin_unlock(&req_q->lock);
+ spin_unlock_bh(&req_q->lock);
ret = wait_event_interruptible_timeout(adapter->request_wq,
zfcp_fsf_sbal_check(req_q), 5 * HZ);
if (ret > 0)
return 0;
- spin_lock(&req_q->lock);
+ spin_lock_bh(&req_q->lock);
return -EIO;
}
@@ -870,14 +870,14 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
volatile struct qdio_buffer_element *sbale;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS,
ZFCP_REQ_NO_QTCB,
adapter->pool.fsf_req_status_read);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -910,7 +910,7 @@ failed_buf:
zfcp_fsf_req_free(req);
zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -988,7 +988,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
req_flags, adapter->pool.fsf_req_abort);
- if (unlikely(IS_ERR(req)))
+ if (IS_ERR(req))
goto out;
if (unlikely(!(atomic_read(&unit->status) &
@@ -1106,13 +1106,13 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
struct zfcp_fsf_req *req;
int ret = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC,
ZFCP_REQ_AUTO_CLEANUP, pool);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
ret = PTR_ERR(req);
goto out;
}
@@ -1148,7 +1148,7 @@ failed_send:
if (erp_action)
erp_action->fsf_req = NULL;
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return ret;
}
@@ -1223,7 +1223,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,
ZFCP_REQ_AUTO_CLEANUP, NULL);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
ret = PTR_ERR(req);
goto out;
}
@@ -1263,14 +1263,14 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
struct zfcp_adapter *adapter = erp_action->adapter;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (!atomic_read(&adapter->req_q.count))
goto out;
req = zfcp_fsf_req_create(adapter,
FSF_QTCB_EXCHANGE_CONFIG_DATA,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_erp);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1295,7 +1295,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL;
}
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -1306,13 +1306,13 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
struct zfcp_fsf_req *req = NULL;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
0, NULL);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1334,7 +1334,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(req);
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
if (!retval)
wait_event(req->completion_wq,
req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1359,13 +1359,13 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
return -EOPNOTSUPP;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (!atomic_read(&adapter->req_q.count))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_erp);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1385,7 +1385,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL;
}
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -1405,13 +1405,13 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
return -EOPNOTSUPP;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (!atomic_read(&adapter->req_q.count))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0,
NULL);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1427,7 +1427,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(req);
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
if (!retval)
wait_event(req->completion_wq,
req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1531,7 +1531,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
@@ -1539,7 +1539,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
FSF_QTCB_OPEN_PORT_WITH_DID,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_erp);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1562,7 +1562,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL;
}
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -1603,14 +1603,14 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_erp);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1633,7 +1633,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL;
}
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -1700,14 +1700,14 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_erp);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1731,7 +1731,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL;
}
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -1875,14 +1875,14 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_erp);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1910,7 +1910,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL;
}
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -1965,13 +1965,13 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req;
int retval = -EIO;
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_erp);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -1995,7 +1995,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL;
}
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
return retval;
}
@@ -2228,7 +2228,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
adapter->pool.fsf_req_scsi);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = PTR_ERR(req);
goto out;
}
@@ -2351,7 +2351,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
adapter->pool.fsf_req_scsi);
- if (unlikely(IS_ERR(req)))
+ if (IS_ERR(req))
goto out;
req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT;
@@ -2417,12 +2417,12 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
return ERR_PTR(-EINVAL);
}
- spin_lock(&adapter->req_q.lock);
+ spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, fsf_cfdc->command, 0, NULL);
- if (unlikely(IS_ERR(req))) {
+ if (IS_ERR(req)) {
retval = -EPERM;
goto out;
}
@@ -2447,7 +2447,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(req);
out:
- spin_unlock(&adapter->req_q.lock);
+ spin_unlock_bh(&adapter->req_q.lock);
if (!retval) {
wait_event(req->completion_wq,
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index d6dbd653fde..69d632d851d 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
req_q = &adapter->req_q;
- spin_lock(&req_q->lock);
+ spin_lock_bh(&req_q->lock);
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
- spin_unlock(&req_q->lock);
+ spin_unlock_bh(&req_q->lock);
qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index c7f06298bd3..4e0322b1c1e 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -63,7 +63,7 @@ comment "SCSI support type (disk, tape, CD-ROM)"
config BLK_DEV_SD
tristate "SCSI disk support"
depends on SCSI
- select CRC_T10DIF
+ select CRC_T10DIF if BLK_DEV_INTEGRITY
---help---
If you want to use SCSI hard disks, Fibre Channel disks,
Serial ATA (SATA) or Parallel ATA (PATA) hard disks,
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 994da56fffe..708e475896b 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -425,7 +425,7 @@ static int alua_check_sense(struct scsi_device *sdev,
/*
* LUN Not Accessible - ALUA state transition
*/
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b)
/*
* LUN Not Accessible -- Target port in standby state
@@ -447,18 +447,18 @@ static int alua_check_sense(struct scsi_device *sdev,
/*
* Power On, Reset, or Bus Device Reset, just retry.
*/
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
/*
* ALUA state changed
*/
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
}
if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
/*
* Implicit ALUA state transition failed
*/
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
}
break;
}
@@ -490,7 +490,7 @@ static int alua_stpg(struct scsi_device *sdev, int state,
if (!err)
return SCSI_DH_IO;
err = alua_check_sense(sdev, &sense_hdr);
- if (retry > 0 && err == NEEDS_RETRY) {
+ if (retry > 0 && err == ADD_TO_MLQUEUE) {
retry--;
goto retry;
}
@@ -535,7 +535,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
return SCSI_DH_IO;
err = alua_check_sense(sdev, &sense_hdr);
- if (err == NEEDS_RETRY)
+ if (err == ADD_TO_MLQUEUE)
goto retry;
sdev_printk(KERN_INFO, sdev,
"%s: rtpg sense code %02x/%02x/%02x\n",
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index b9d23e9e9a4..ef693e8412e 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -439,7 +439,7 @@ static int clariion_check_sense(struct scsi_device *sdev,
* Unit Attention Code. This is the first IO
* to the new path, so just retry.
*/
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
break;
}
@@ -514,7 +514,7 @@ retry:
return SCSI_DH_IO;
err = clariion_check_sense(sdev, &sshdr);
- if (retry > 0 && err == NEEDS_RETRY) {
+ if (retry > 0 && err == ADD_TO_MLQUEUE) {
retry--;
goto retry;
}
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 2dee69da35c..6e2f130d56d 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -551,7 +551,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
*
* Just retry and wait.
*/
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
break;
case ILLEGAL_REQUEST:
if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) {
@@ -568,7 +568,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
/*
* Power On, Reset, or Bus Device Reset, just retry.
*/
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
break;
}
/* success just means we do not care what scsi-ml does */
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 880051c89bd..39ce3aba1da 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -391,7 +391,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
case HARDWARE_ERROR:
if (scmd->device->retry_hwerror)
- return NEEDS_RETRY;
+ return ADD_TO_MLQUEUE;
else
return SUCCESS;
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 84b4879cff1..34d0de6cd51 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1080,7 +1080,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
* PDT=1Fh none (no FDD connected to the requested logical unit)
*/
if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
- (result[0] & 0x1f) == 0x1f) {
+ (result[0] & 0x1f) == 0x1f &&
+ !scsi_is_wlun(lun)) {
SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
"scsi scan: peripheral device type"
" of 31, no device added\n"));
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2a2bc89aba8..e5e7d785645 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1875,7 +1875,6 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
add_disk(gd);
- blk_register_filter(gd);
sd_dif_config_host(sdkp);
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
@@ -1909,7 +1908,6 @@ static int sd_remove(struct device *dev)
struct scsi_disk *sdkp = dev_get_drvdata(dev);
device_del(&sdkp->dev);
- blk_unregister_filter(sdkp->disk);
del_gendisk(sdkp->disk);
sd_shutdown(dev);
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 3292965bfd8..27f5bfd1def 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -656,7 +656,6 @@ static int sr_probe(struct device *dev)
dev_set_drvdata(dev, cd);
disk->flags |= GENHD_FL_REMOVABLE;
add_disk(disk);
- blk_register_filter(disk);
sdev_printk(KERN_DEBUG, sdev,
"Attached scsi CD-ROM %s\n", cd->cdi.name);
@@ -895,7 +894,6 @@ static int sr_remove(struct device *dev)
{
struct scsi_cd *cd = dev_get_drvdata(dev);
- blk_unregister_filter(cd->disk);
del_gendisk(cd->disk);
mutex_lock(&sr_ref_mutex);
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 6a29f9330a7..3f90f1bbbbc 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -127,8 +127,13 @@
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
-#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
-#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
+#ifdef CONFIG_ARCH_IMX
+#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */
+#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */
+#endif
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+#define UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */
+#endif
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
#define UCR3_BPEN (1<<0) /* Preset registers enable */
#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
@@ -445,7 +450,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
imx_txint(irq, dev_id);
- if (sts & USR1_RTSS)
+ if (sts & USR1_RTSD)
imx_rtsint(irq, dev_id);
return IRQ_HANDLED;
@@ -598,6 +603,12 @@ static int imx_startup(struct uart_port *port)
temp |= (UCR2_RXEN | UCR2_TXEN);
writel(temp, sport->port.membase + UCR2);
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+ temp = readl(sport->port.membase + UCR3);
+ temp |= UCR3_RXDMUXSEL;
+ writel(temp, sport->port.membase + UCR3);
+#endif
+
/*
* Enable modem status interrupts
*/
@@ -1133,13 +1144,19 @@ static int serial_imx_probe(struct platform_device *pdev)
if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
sport->have_rtscts = 1;
- if (pdata->init)
- pdata->init(pdev);
+ if (pdata->init) {
+ ret = pdata->init(pdev);
+ if (ret)
+ goto clkput;
+ }
uart_add_one_port(&imx_reg, &sport->port);
platform_set_drvdata(pdev, &sport->port);
return 0;
+clkput:
+ clk_put(sport->clk);
+ clk_disable(sport->clk);
unmap:
iounmap(sport->port.membase);
free:
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 34c7c987568..0e53354c1cf 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -47,9 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
#define MAX_BUSES 3
-#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
-#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
-#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
+#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
+#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
+#define IS_DMA_ALIGNED(x) (((x) & 0x07) == 0)
+#define MAX_DMA_LEN 8191
/*
* for testing SSCR1 changes that require SSP restart, basically
@@ -144,7 +145,6 @@ struct driver_data {
size_t tx_map_len;
u8 n_bytes;
u32 dma_width;
- int cs_change;
int (*write)(struct driver_data *drv_data);
int (*read)(struct driver_data *drv_data);
irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
@@ -406,8 +406,45 @@ static void giveback(struct driver_data *drv_data)
struct spi_transfer,
transfer_list);
+ /* Delay if requested before any change in chip select */
+ if (last_transfer->delay_usecs)
+ udelay(last_transfer->delay_usecs);
+
+ /* Drop chip select UNLESS cs_change is true or we are returning
+ * a message with an error, or next message is for another chip
+ */
if (!last_transfer->cs_change)
drv_data->cs_control(PXA2XX_CS_DEASSERT);
+ else {
+ struct spi_message *next_msg;
+
+ /* Holding of cs was hinted, but we need to make sure
+ * the next message is for the same chip. Don't waste
+ * time with the following tests unless this was hinted.
+ *
+ * We cannot postpone this until pump_messages, because
+ * after calling msg->complete (below) the driver that
+ * sent the current message could be unloaded, which
+ * could invalidate the cs_control() callback...
+ */
+
+ /* get a pointer to the next message, if any */
+ spin_lock_irqsave(&drv_data->lock, flags);
+ if (list_empty(&drv_data->queue))
+ next_msg = NULL;
+ else
+ next_msg = list_entry(drv_data->queue.next,
+ struct spi_message, queue);
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ /* see if the next and current messages point
+ * to the same chip
+ */
+ if (next_msg && next_msg->spi != msg->spi)
+ next_msg = NULL;
+ if (!next_msg || msg->state == ERROR_STATE)
+ drv_data->cs_control(PXA2XX_CS_DEASSERT);
+ }
msg->state = NULL;
if (msg->complete)
@@ -490,10 +527,9 @@ static void dma_transfer_complete(struct driver_data *drv_data)
msg->actual_length += drv_data->len -
(drv_data->rx_end - drv_data->rx);
- /* Release chip select if requested, transfer delays are
- * handled in pump_transfers */
- if (drv_data->cs_change)
- drv_data->cs_control(PXA2XX_CS_DEASSERT);
+ /* Transfer delays and chip select release are
+ * handled in pump_transfers or giveback
+ */
/* Move to next transfer */
msg->state = next_transfer(drv_data);
@@ -602,10 +638,9 @@ static void int_transfer_complete(struct driver_data *drv_data)
drv_data->cur_msg->actual_length += drv_data->len -
(drv_data->rx_end - drv_data->rx);
- /* Release chip select if requested, transfer delays are
- * handled in pump_transfers */
- if (drv_data->cs_change)
- drv_data->cs_control(PXA2XX_CS_DEASSERT);
+ /* Transfer delays and chip select release are
+ * handled in pump_transfers or giveback
+ */
/* Move to next transfer */
drv_data->cur_msg->state = next_transfer(drv_data);
@@ -840,23 +875,40 @@ static void pump_transfers(unsigned long data)
return;
}
- /* Delay if requested at end of transfer*/
+ /* Delay if requested at end of transfer before CS change */
if (message->state == RUNNING_STATE) {
previous = list_entry(transfer->transfer_list.prev,
struct spi_transfer,
transfer_list);
if (previous->delay_usecs)
udelay(previous->delay_usecs);
+
+ /* Drop chip select only if cs_change is requested */
+ if (previous->cs_change)
+ drv_data->cs_control(PXA2XX_CS_DEASSERT);
}
- /* Check transfer length */
- if (transfer->len > 8191)
- {
- dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer "
- "length greater than 8191\n");
- message->status = -EINVAL;
- giveback(drv_data);
- return;
+ /* Check for transfers that need multiple DMA segments */
+ if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
+
+ /* reject already-mapped transfers; PIO won't always work */
+ if (message->is_dma_mapped
+ || transfer->rx_dma || transfer->tx_dma) {
+ dev_err(&drv_data->pdev->dev,
+ "pump_transfers: mapped transfer length "
+ "of %lu is greater than %d\n",
+ transfer->len, MAX_DMA_LEN);
+ message->status = -EINVAL;
+ giveback(drv_data);
+ return;
+ }
+
+ /* warn ... we force this to PIO mode */
+ if (printk_ratelimit())
+ dev_warn(&message->spi->dev, "pump_transfers: "
+ "DMA disabled for transfer length %ld "
+ "greater than %d\n",
+ (long)drv_data->len, MAX_DMA_LEN);
}
/* Setup the transfer state based on the type of transfer */
@@ -878,7 +930,6 @@ static void pump_transfers(unsigned long data)
drv_data->len = transfer->len & DCMD_LENGTH;
drv_data->write = drv_data->tx ? chip->write : null_writer;
drv_data->read = drv_data->rx ? chip->read : null_reader;
- drv_data->cs_change = transfer->cs_change;
/* Change speed and bit per word on a per transfer */
cr0 = chip->cr0;
@@ -925,7 +976,7 @@ static void pump_transfers(unsigned long data)
&dma_thresh))
if (printk_ratelimit())
dev_warn(&message->spi->dev,
- "pump_transfer: "
+ "pump_transfers: "
"DMA burst size reduced to "
"match bits_per_word\n");
}
@@ -939,8 +990,23 @@ static void pump_transfers(unsigned long data)
message->state = RUNNING_STATE;
- /* Try to map dma buffer and do a dma transfer if successful */
- if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
+ /* Try to map dma buffer and do a dma transfer if successful, but
+ * only if the length is non-zero and less than MAX_DMA_LEN.
+ *
+ * Zero-length non-descriptor DMA is illegal on PXA2xx; force use
+ * of PIO instead. Care is needed above because the transfer may
+ * have have been passed with buffers that are already dma mapped.
+ * A zero-length transfer in PIO mode will not try to write/read
+ * to/from the buffers
+ *
+ * REVISIT large transfers are exactly where we most want to be
+ * using DMA. If this happens much, split those transfers into
+ * multiple DMA segments rather than forcing PIO.
+ */
+ drv_data->dma_mapped = 0;
+ if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN)
+ drv_data->dma_mapped = map_dma_buffers(drv_data);
+ if (drv_data->dma_mapped) {
/* Ensure we have the correct interrupt handler */
drv_data->transfer_handler = dma_transfer;
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 070c6219e2d..ac0e3e4b3c5 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -267,16 +267,13 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
cs->hw_mode |= SPMODE_LEN(bits_per_word);
if ((mpc83xx_spi->spibrg / hz) > 64) {
+ cs->hw_mode |= SPMODE_DIV16;
pm = mpc83xx_spi->spibrg / (hz * 64);
if (pm > 16) {
- cs->hw_mode |= SPMODE_DIV16;
- pm /= 16;
- if (pm > 16) {
- dev_err(&spi->dev, "Requested speed is too "
- "low: %d Hz. Will use %d Hz instead.\n",
- hz, mpc83xx_spi->spibrg / 1024);
- pm = 16;
- }
+ dev_err(&spi->dev, "Requested speed is too "
+ "low: %d Hz. Will use %d Hz instead.\n",
+ hz, mpc83xx_spi->spibrg / 1024);
+ pm = 16;
}
} else
pm = mpc83xx_spi->spibrg / (hz * 4);
@@ -315,11 +312,20 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
if (t->bits_per_word)
bits_per_word = t->bits_per_word;
len = t->len;
- if (bits_per_word > 8)
+ if (bits_per_word > 8) {
+ /* invalid length? */
+ if (len & 1)
+ return -EINVAL;
len /= 2;
- if (bits_per_word > 16)
+ }
+ if (bits_per_word > 16) {
+ /* invalid length? */
+ if (len & 1)
+ return -EINVAL;
len /= 2;
+ }
mpc83xx_spi->count = len;
+
INIT_COMPLETION(mpc83xx_spi->done);
/* enable rx ints */
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 98abc73c1a1..3eb414b84a9 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -430,7 +430,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev)
#endif
MODULE_ALIAS("platform:s3c2410-spi");
-static struct platform_driver s3c24xx_spidrv = {
+static struct platform_driver s3c24xx_spi_driver = {
.remove = __exit_p(s3c24xx_spi_remove),
.suspend = s3c24xx_spi_suspend,
.resume = s3c24xx_spi_resume,
@@ -442,12 +442,12 @@ static struct platform_driver s3c24xx_spidrv = {
static int __init s3c24xx_spi_init(void)
{
- return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe);
+ return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe);
}
static void __exit s3c24xx_spi_exit(void)
{
- platform_driver_unregister(&s3c24xx_spidrv);
+ platform_driver_unregister(&s3c24xx_spi_driver);
}
module_init(s3c24xx_spi_init);
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 5a24c6411d3..75dac578104 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -208,6 +208,36 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
return value;
}
+static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
+{
+ /* Turn off the LCD controller and the DMA controller */
+ lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+ sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
+
+ /* Wait for the LCDC core to become idle */
+ while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
+ msleep(10);
+
+ lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+}
+
+static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)
+{
+ atmel_lcdfb_stop_nowait(sinfo);
+
+ /* Wait for DMA engine to become idle... */
+ while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
+ msleep(10);
+}
+
+static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
+{
+ lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+ lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+ (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
+ | ATMEL_LCDC_PWR);
+}
+
static void atmel_lcdfb_update_dma(struct fb_info *info,
struct fb_var_screeninfo *var)
{
@@ -420,26 +450,8 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo)
{
might_sleep();
- /* LCD power off */
- lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-
- /* wait for the LCDC core to become idle */
- while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
- msleep(10);
-
- /* DMA disable */
- lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
-
- /* wait for DMA engine to become idle */
- while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
- msleep(10);
-
- /* LCD power on */
- lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
- (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
-
- /* DMA enable */
- lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+ atmel_lcdfb_stop(sinfo);
+ atmel_lcdfb_start(sinfo);
}
/**
@@ -471,14 +483,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
info->var.xres, info->var.yres,
info->var.xres_virtual, info->var.yres_virtual);
- /* Turn off the LCD controller and the DMA controller */
- lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-
- /* Wait for the LCDC core to become idle */
- while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
- msleep(10);
-
- lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+ atmel_lcdfb_stop_nowait(sinfo);
if (info->var.bits_per_pixel == 1)
info->fix.visual = FB_VISUAL_MONO01;
@@ -583,13 +588,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
msleep(10);
- dev_dbg(info->device, " * re-enable DMA engine\n");
- /* ...and enable it with updated configuration */
- lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
-
- dev_dbg(info->device, " * re-enable LCDC core\n");
- lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
- (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
+ atmel_lcdfb_start(sinfo);
dev_dbg(info->device, " * DONE\n");
@@ -1032,11 +1031,20 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
struct fb_info *info = platform_get_drvdata(pdev);
struct atmel_lcdfb_info *sinfo = info->par;
+ /*
+ * We don't want to handle interrupts while the clock is
+ * stopped. It may take forever.
+ */
+ lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
+
sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
if (sinfo->atmel_lcdfb_power_control)
sinfo->atmel_lcdfb_power_control(0);
+
+ atmel_lcdfb_stop(sinfo);
atmel_lcdfb_stop_clock(sinfo);
+
return 0;
}
@@ -1046,9 +1054,15 @@ static int atmel_lcdfb_resume(struct platform_device *pdev)
struct atmel_lcdfb_info *sinfo = info->par;
atmel_lcdfb_start_clock(sinfo);
+ atmel_lcdfb_start(sinfo);
if (sinfo->atmel_lcdfb_power_control)
sinfo->atmel_lcdfb_power_control(1);
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
+
+ /* Enable FIFO & DMA errors */
+ lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI
+ | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
+
return 0;
}