summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-core.c4
-rw-r--r--drivers/block/DAC960.c11
-rw-r--r--drivers/block/cciss.c25
-rw-r--r--drivers/block/cpqarray.c36
-rw-r--r--drivers/block/floppy.c16
-rw-r--r--drivers/block/nbd.c8
-rw-r--r--drivers/block/ps3disk.c12
-rw-r--r--drivers/block/sunvdc.c11
-rw-r--r--drivers/block/sx8.c58
-rw-r--r--drivers/block/ub.c10
-rw-r--r--drivers/block/viodasd.c15
-rw-r--r--drivers/block/xen-blkfront.c10
-rw-r--r--drivers/block/xsysace.c5
-rw-r--r--drivers/cdrom/viocd.c15
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c32
-rw-r--r--drivers/ide/ide-cd.c55
-rw-r--r--drivers/ide/ide-io.c25
-rw-r--r--drivers/input/touchscreen/corgi_ts.c8
-rw-r--r--drivers/message/i2o/i2o_block.c20
-rw-r--r--drivers/mfd/ucb1x00-assabet.c14
-rw-r--r--drivers/mmc/card/block.c24
-rw-r--r--drivers/mmc/card/queue.c4
-rw-r--r--drivers/mmc/host/pxamci.c61
-rw-r--r--drivers/mmc/host/pxamci.h2
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/dm9000.c3
-rw-r--r--drivers/net/smc91x.c19
-rw-r--r--drivers/net/smc91x.h24
-rw-r--r--drivers/pcmcia/pxa2xx_base.c1
-rw-r--r--drivers/rtc/rtc-sa1100.c31
-rw-r--r--drivers/s390/block/dasd.c17
-rw-r--r--drivers/s390/char/tape_block.c13
-rw-r--r--drivers/scsi/ide-scsi.c8
-rw-r--r--drivers/scsi/scsi_lib.c171
-rw-r--r--drivers/scsi/scsi_tgt_lib.c3
-rw-r--r--drivers/scsi/sg.c12
-rw-r--r--drivers/serial/21285.c2
-rw-r--r--drivers/spi/Kconfig1
-rw-r--r--drivers/spi/pxa2xx_spi.c139
-rw-r--r--drivers/usb/Kconfig1
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/host/ohci-hcd.c2
-rw-r--r--drivers/usb/host/ohci-pxa27x.c13
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/atmel_lcdfb.c2
46 files changed, 416 insertions, 535 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ce803d18e96a..bdbd55af7022 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4924,7 +4924,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
* @dev: device to target
* @buf: data buffer
* @buflen: buffer length
- * @write_data: read/write
+ * @rw: read/write
*
* Transfer data from/to the device data register by PIO.
*
@@ -4970,7 +4970,7 @@ unsigned int ata_data_xfer(struct ata_device *dev, unsigned char *buf,
* @dev: device to target
* @buf: data buffer
* @buflen: buffer length
- * @write_data: read/write
+ * @rw: read/write
*
* Transfer data from/to the device data register by PIO. Do the
* transfer with interrupts disabled.
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 9030c373ce67..cd03473f3547 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -3455,19 +3455,12 @@ static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
bool SuccessfulIO)
{
struct request *Request = Command->Request;
- int UpToDate;
-
- UpToDate = 0;
- if (SuccessfulIO)
- UpToDate = 1;
+ int Error = SuccessfulIO ? 0 : -EIO;
pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist,
Command->SegmentCount, Command->DmaDirection);
- if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) {
- add_disk_randomness(Request->rq_disk);
- end_that_request_last(Request, UpToDate);
-
+ if (!__blk_end_request(Request, Error, Command->BlockCount << 9)) {
if (Command->Completion) {
complete(Command->Completion);
Command->Completion = NULL;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 509b6490413b..ef50068def88 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1187,17 +1187,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
}
}
-static inline void complete_buffers(struct bio *bio, int status)
-{
- while (bio) {
- struct bio *xbh = bio->bi_next;
-
- bio->bi_next = NULL;
- bio_endio(bio, status ? 0 : -EIO);
- bio = xbh;
- }
-}
-
static void cciss_check_queues(ctlr_info_t *h)
{
int start_queue = h->next_to_run;
@@ -1263,21 +1252,14 @@ static void cciss_softirq_done(struct request *rq)
pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
}
- complete_buffers(rq->bio, (rq->errors == 0));
-
- if (blk_fs_request(rq)) {
- const int rw = rq_data_dir(rq);
-
- disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
- }
-
#ifdef CCISS_DEBUG
printk("Done with %p\n", rq);
#endif /* CCISS_DEBUG */
- add_disk_randomness(rq->rq_disk);
+ if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
+ BUG();
+
spin_lock_irqsave(&h->lock, flags);
- end_that_request_last(rq, (rq->errors == 0));
cmd_free(h, cmd, 1);
cciss_check_queues(h);
spin_unlock_irqrestore(&h->lock, flags);
@@ -2544,7 +2526,6 @@ after_error_processing:
}
cmd->rq->data_len = 0;
cmd->rq->completion_data = cmd;
- blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
blk_complete_request(cmd->rq);
}
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index c8132d958795..69199185ff4b 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -167,7 +167,6 @@ static void start_io(ctlr_info_t *h);
static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c);
static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c);
-static inline void complete_buffers(struct bio *bio, int ok);
static inline void complete_command(cmdlist_t *cmd, int timeout);
static irqreturn_t do_ida_intr(int irq, void *dev_id);
@@ -980,26 +979,13 @@ static void start_io(ctlr_info_t *h)
}
}
-static inline void complete_buffers(struct bio *bio, int ok)
-{
- struct bio *xbh;
-
- while (bio) {
- xbh = bio->bi_next;
- bio->bi_next = NULL;
-
- bio_endio(bio, ok ? 0 : -EIO);
-
- bio = xbh;
- }
-}
/*
* Mark all buffers that cmd was responsible for
*/
static inline void complete_command(cmdlist_t *cmd, int timeout)
{
struct request *rq = cmd->rq;
- int ok=1;
+ int error = 0;
int i, ddir;
if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
@@ -1011,16 +997,17 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
if (cmd->req.hdr.rcode & RCODE_FATAL) {
printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
cmd->ctlr, cmd->hdr.unit);
- ok = 0;
+ error = -EIO;
}
if (cmd->req.hdr.rcode & RCODE_INVREQ) {
printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd,
cmd->req.hdr.blk, cmd->req.hdr.blk_cnt,
cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode);
- ok = 0;
+ error = -EIO;
}
- if (timeout) ok = 0;
+ if (timeout)
+ error = -EIO;
/* unmap the DMA mapping for all the scatter gather elements */
if (cmd->req.hdr.cmd == IDA_READ)
ddir = PCI_DMA_FROMDEVICE;
@@ -1030,18 +1017,9 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
cmd->req.sg[i].size, ddir);
- complete_buffers(rq->bio, ok);
-
- if (blk_fs_request(rq)) {
- const int rw = rq_data_dir(rq);
-
- disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
- }
-
- add_disk_randomness(rq->rq_disk);
-
DBGPX(printk("Done with %p\n", rq););
- end_that_request_last(rq, ok ? 1 : -EIO);
+ if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
+ BUG();
}
/*
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 639ed14bb08d..32c79a55511b 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2287,21 +2287,19 @@ static int do_format(int drive, struct format_descr *tmp_format_req)
* =============================
*/
-static void floppy_end_request(struct request *req, int uptodate)
+static void floppy_end_request(struct request *req, int error)
{
unsigned int nr_sectors = current_count_sectors;
+ unsigned int drive = (unsigned long)req->rq_disk->private_data;
/* current_count_sectors can be zero if transfer failed */
- if (!uptodate)
+ if (error)
nr_sectors = req->current_nr_sectors;
- if (end_that_request_first(req, uptodate, nr_sectors))
+ if (__blk_end_request(req, error, nr_sectors << 9))
return;
- add_disk_randomness(req->rq_disk);
- floppy_off((long)req->rq_disk->private_data);
- blkdev_dequeue_request(req);
- end_that_request_last(req, uptodate);
/* We're done with the request */
+ floppy_off(drive);
current_req = NULL;
}
@@ -2332,7 +2330,7 @@ static void request_done(int uptodate)
/* unlock chained buffers */
spin_lock_irqsave(q->queue_lock, flags);
- floppy_end_request(req, 1);
+ floppy_end_request(req, 0);
spin_unlock_irqrestore(q->queue_lock, flags);
} else {
if (rq_data_dir(req) == WRITE) {
@@ -2346,7 +2344,7 @@ static void request_done(int uptodate)
DRWE->last_error_generation = DRS->generation;
}
spin_lock_irqsave(q->queue_lock, flags);
- floppy_end_request(req, 0);
+ floppy_end_request(req, -EIO);
spin_unlock_irqrestore(q->queue_lock, flags);
}
}
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index ba9b17e507e0..ae3106045ee5 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -100,17 +100,15 @@ static const char *nbdcmd_to_ascii(int cmd)
static void nbd_end_request(struct request *req)
{
- int uptodate = (req->errors == 0) ? 1 : 0;
+ int error = req->errors ? -EIO : 0;
struct request_queue *q = req->q;
unsigned long flags;
dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name,
- req, uptodate? "done": "failed");
+ req, error ? "failed" : "done");
spin_lock_irqsave(q->queue_lock, flags);
- if (!end_that_request_first(req, uptodate, req->nr_sectors)) {
- end_that_request_last(req, uptodate);
- }
+ __blk_end_request(req, error, req->nr_sectors << 9);
spin_unlock_irqrestore(q->queue_lock, flags);
}
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index e354bfc070e1..7483f947f0e9 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -229,7 +229,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
struct ps3_storage_device *dev = data;
struct ps3disk_private *priv;
struct request *req;
- int res, read, uptodate;
+ int res, read, error;
u64 tag, status;
unsigned long num_sectors;
const char *op;
@@ -270,21 +270,17 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
if (status) {
dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
__LINE__, op, status);
- uptodate = 0;
+ error = -EIO;
} else {
dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
__LINE__, op);
- uptodate = 1;
+ error = 0;
if (read)
ps3disk_scatter_gather(dev, req, 0);
}
spin_lock(&priv->lock);
- if (!end_that_request_first(req, uptodate, num_sectors)) {
- add_disk_randomness(req->rq_disk);
- blkdev_dequeue_request(req);
- end_that_request_last(req, uptodate);
- }
+ __blk_end_request(req, error, num_sectors << 9);
priv->req = NULL;
ps3disk_do_request(dev, priv->queue);
spin_unlock(&priv->lock);
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index fac4c6cd04f7..66e30155b0ab 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -212,12 +212,9 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc)
vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD);
}
-static void vdc_end_request(struct request *req, int uptodate, int num_sectors)
+static void vdc_end_request(struct request *req, int error, int num_sectors)
{
- if (end_that_request_first(req, uptodate, num_sectors))
- return;
- add_disk_randomness(req->rq_disk);
- end_that_request_last(req, uptodate);
+ __blk_end_request(req, error, num_sectors << 9);
}
static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
@@ -242,7 +239,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
rqe->req = NULL;
- vdc_end_request(req, !desc->status, desc->size >> 9);
+ vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9);
if (blk_queue_stopped(port->disk->queue))
blk_start_queue(port->disk->queue);
@@ -456,7 +453,7 @@ static void do_vdc_request(struct request_queue *q)
blkdev_dequeue_request(req);
if (__send_request(req) < 0)
- vdc_end_request(req, 0, req->hard_nr_sectors);
+ vdc_end_request(req, -EIO, req->hard_nr_sectors);
}
}
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 52dc5e131718..cd5674b63faf 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -744,16 +744,14 @@ static unsigned int carm_fill_get_fw_ver(struct carm_host *host,
static inline void carm_end_request_queued(struct carm_host *host,
struct carm_request *crq,
- int uptodate)
+ int error)
{
struct request *req = crq->rq;
int rc;
- rc = end_that_request_first(req, uptodate, req->hard_nr_sectors);
+ rc = __blk_end_request(req, error, blk_rq_bytes(req));
assert(rc == 0);
- end_that_request_last(req, uptodate);
-
rc = carm_put_request(host, crq);
assert(rc == 0);
}
@@ -793,9 +791,9 @@ static inline void carm_round_robin(struct carm_host *host)
}
static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
- int is_ok)
+ int error)
{
- carm_end_request_queued(host, crq, is_ok);
+ carm_end_request_queued(host, crq, error);
if (max_queue == 1)
carm_round_robin(host);
else if ((host->n_msgs <= CARM_MSG_LOW_WATER) &&
@@ -873,14 +871,14 @@ queue_one_request:
sg = &crq->sg[0];
n_elem = blk_rq_map_sg(q, rq, sg);
if (n_elem <= 0) {
- carm_end_rq(host, crq, 0);
+ carm_end_rq(host, crq, -EIO);
return; /* request with no s/g entries? */
}
/* map scatterlist to PCI bus addresses */
n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir);
if (n_elem <= 0) {
- carm_end_rq(host, crq, 0);
+ carm_end_rq(host, crq, -EIO);
return; /* request with no s/g entries? */
}
crq->n_elem = n_elem;
@@ -941,7 +939,7 @@ queue_one_request:
static void carm_handle_array_info(struct carm_host *host,
struct carm_request *crq, u8 *mem,
- int is_ok)
+ int error)
{
struct carm_port *port;
u8 *msg_data = mem + sizeof(struct carm_array_info);
@@ -952,9 +950,9 @@ static void carm_handle_array_info(struct carm_host *host,
DPRINTK("ENTER\n");
- carm_end_rq(host, crq, is_ok);
+ carm_end_rq(host, crq, error);
- if (!is_ok)
+ if (error)
goto out;
if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST)
goto out;
@@ -1001,7 +999,7 @@ out:
static void carm_handle_scan_chan(struct carm_host *host,
struct carm_request *crq, u8 *mem,
- int is_ok)
+ int error)
{
u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET;
unsigned int i, dev_count = 0;
@@ -1009,9 +1007,9 @@ static void carm_handle_scan_chan(struct carm_host *host,
DPRINTK("ENTER\n");
- carm_end_rq(host, crq, is_ok);
+ carm_end_rq(host, crq, error);
- if (!is_ok) {
+ if (error) {
new_state = HST_ERROR;
goto out;
}
@@ -1033,23 +1031,23 @@ out:
}
static void carm_handle_generic(struct carm_host *host,
- struct carm_request *crq, int is_ok,
+ struct carm_request *crq, int error,
int cur_state, int next_state)
{
DPRINTK("ENTER\n");
- carm_end_rq(host, crq, is_ok);
+ carm_end_rq(host, crq, error);
assert(host->state == cur_state);
- if (is_ok)
- host->state = next_state;
- else
+ if (error)
host->state = HST_ERROR;
+ else
+ host->state = next_state;
schedule_work(&host->fsm_task);
}
static inline void carm_handle_rw(struct carm_host *host,
- struct carm_request *crq, int is_ok)
+ struct carm_request *crq, int error)
{
int pci_dir;
@@ -1062,7 +1060,7 @@ static inline void carm_handle_rw(struct carm_host *host,
pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir);
- carm_end_rq(host, crq, is_ok);
+ carm_end_rq(host, crq, error);
}
static inline void carm_handle_resp(struct carm_host *host,
@@ -1071,7 +1069,7 @@ static inline void carm_handle_resp(struct carm_host *host,
u32 handle = le32_to_cpu(ret_handle_le);
unsigned int msg_idx;
struct carm_request *crq;
- int is_ok = (status == RMSG_OK);
+ int error = (status == RMSG_OK) ? 0 : -EIO;
u8 *mem;
VPRINTK("ENTER, handle == 0x%x\n", handle);
@@ -1090,7 +1088,7 @@ static inline void carm_handle_resp(struct carm_host *host,
/* fast path */
if (likely(crq->msg_type == CARM_MSG_READ ||
crq->msg_type == CARM_MSG_WRITE)) {
- carm_handle_rw(host, crq, is_ok);
+ carm_handle_rw(host, crq, error);
return;
}
@@ -1100,7 +1098,7 @@ static inline void carm_handle_resp(struct carm_host *host,
case CARM_MSG_IOCTL: {
switch (crq->msg_subtype) {
case CARM_IOC_SCAN_CHAN:
- carm_handle_scan_chan(host, crq, mem, is_ok);
+ carm_handle_scan_chan(host, crq, mem, error);
break;
default:
/* unknown / invalid response */
@@ -1112,21 +1110,21 @@ static inline void carm_handle_resp(struct carm_host *host,
case CARM_MSG_MISC: {
switch (crq->msg_subtype) {
case MISC_ALLOC_MEM:
- carm_handle_generic(host, crq, is_ok,
+ carm_handle_generic(host, crq, error,
HST_ALLOC_BUF, HST_SYNC_TIME);
break;
case MISC_SET_TIME:
- carm_handle_generic(host, crq, is_ok,
+ carm_handle_generic(host, crq, error,
HST_SYNC_TIME, HST_GET_FW_VER);
break;
case MISC_GET_FW_VER: {
struct carm_fw_ver *ver = (struct carm_fw_ver *)
mem + sizeof(struct carm_msg_get_fw_ver);
- if (is_ok) {
+ if (!error) {
host->fw_ver = le32_to_cpu(ver->version);
host->flags |= (ver->features & FL_FW_VER_MASK);
}
- carm_handle_generic(host, crq, is_ok,
+ carm_handle_generic(host, crq, error,
HST_GET_FW_VER, HST_PORT_SCAN);
break;
}
@@ -1140,7 +1138,7 @@ static inline void carm_handle_resp(struct carm_host *host,
case CARM_MSG_ARRAY: {
switch (crq->msg_subtype) {
case CARM_ARRAY_INFO:
- carm_handle_array_info(host, crq, mem, is_ok);
+ carm_handle_array_info(host, crq, mem, error);
break;
default:
/* unknown / invalid response */
@@ -1159,7 +1157,7 @@ static inline void carm_handle_resp(struct carm_host *host,
err_out:
printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n",
pci_name(host->pdev), crq->msg_type, crq->msg_subtype);
- carm_end_rq(host, crq, 0);
+ carm_end_rq(host, crq, -EIO);
}
static inline void carm_handle_responses(struct carm_host *host)
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 08e909dc7944..c6179d6ac6e4 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -808,16 +808,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
static void ub_end_rq(struct request *rq, unsigned int scsi_status)
{
- int uptodate;
+ int error;
if (scsi_status == 0) {
- uptodate = 1;
+ error = 0;
} else {
- uptodate = 0;
+ error = -EIO;
rq->errors = scsi_status;
}
- end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
- end_that_request_last(rq, uptodate);
+ if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
+ BUG();
}
static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index ab5d404faa11..9e61fca46117 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -229,13 +229,10 @@ static struct block_device_operations viodasd_fops = {
/*
* End a request
*/
-static void viodasd_end_request(struct request *req, int uptodate,
+static void viodasd_end_request(struct request *req, int error,
int num_sectors)
{
- if (end_that_request_first(req, uptodate, num_sectors))
- return;
- add_disk_randomness(req->rq_disk);
- end_that_request_last(req, uptodate);
+ __blk_end_request(req, error, num_sectors << 9);
}
/*
@@ -374,12 +371,12 @@ static void do_viodasd_request(struct request_queue *q)
blkdev_dequeue_request(req);
/* check that request contains a valid command */
if (!blk_fs_request(req)) {
- viodasd_end_request(req, 0, req->hard_nr_sectors);
+ viodasd_end_request(req, -EIO, req->hard_nr_sectors);
continue;
}
/* Try sending the request */
if (send_request(req) != 0)
- viodasd_end_request(req, 0, req->hard_nr_sectors);
+ viodasd_end_request(req, -EIO, req->hard_nr_sectors);
}
}
@@ -591,7 +588,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent)
num_req_outstanding--;
spin_unlock_irqrestore(&viodasd_spinlock, irq_flags);
- error = event->xRc != HvLpEvent_Rc_Good;
+ error = (event->xRc == HvLpEvent_Rc_Good) ? 0 : -EIO;
if (error) {
const struct vio_error_entry *err;
err = vio_lookup_rc(viodasd_err_table, bevent->sub_result);
@@ -601,7 +598,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent)
}
qlock = req->q->queue_lock;
spin_lock_irqsave(qlock, irq_flags);
- viodasd_end_request(req, !error, num_sect);
+ viodasd_end_request(req, error, num_sect);
spin_unlock_irqrestore(qlock, irq_flags);
/* Finally, try to get more requests off of this device's queue */
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 2bdebcb3ff16..8afce67c0aa5 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -452,7 +452,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
RING_IDX i, rp;
unsigned long flags;
struct blkfront_info *info = (struct blkfront_info *)dev_id;
- int uptodate;
+ int error;
spin_lock_irqsave(&blkif_io_lock, flags);
@@ -477,13 +477,13 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
add_id_to_freelist(info, id);
- uptodate = (bret->status == BLKIF_RSP_OKAY);
+ error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO;
switch (bret->operation) {
case BLKIF_OP_WRITE_BARRIER:
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
info->gd->disk_name);
- uptodate = -EOPNOTSUPP;
+ error = -EOPNOTSUPP;
info->feature_barrier = 0;
xlvbd_barrier(info);
}
@@ -494,10 +494,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
"request: %x\n", bret->status);
- ret = end_that_request_first(req, uptodate,
- req->hard_nr_sectors);
+ ret = __blk_end_request(req, error, blk_rq_bytes(req));
BUG_ON(ret);
- end_that_request_last(req, uptodate);
break;
default:
BUG();
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 82effce97c51..2c81465fd60c 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -703,7 +703,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
/* bio finished; is there another one? */
i = ace->req->current_nr_sectors;
- if (end_that_request_first(ace->req, 1, i)) {
+ if (__blk_end_request(ace->req, 0, i)) {
/* dev_dbg(ace->dev, "next block; h=%li c=%i\n",
* ace->req->hard_nr_sectors,
* ace->req->current_nr_sectors);
@@ -718,9 +718,6 @@ static void ace_fsm_dostate(struct ace_device *ace)
break;
case ACE_FSM_STATE_REQ_COMPLETE:
- /* Complete the block request */
- blkdev_dequeue_request(ace->req);
- end_that_request_last(ace->req, 1);
ace->req = NULL;
/* Finished request; go to idle state */
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index d8bb44b98a6a..8473b9f1da96 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -289,7 +289,7 @@ static int send_request(struct request *req)
return 0;
}
-static void viocd_end_request(struct request *req, int uptodate)
+static void viocd_end_request(struct request *req, int error)
{
int nsectors = req->hard_nr_sectors;
@@ -302,11 +302,8 @@ static void viocd_end_request(struct request *req, int uptodate)
if (!nsectors)
nsectors = 1;
- if (end_that_request_first(req, uptodate, nsectors))
+ if (__blk_end_request(req, error, nsectors << 9))
BUG();
- add_disk_randomness(req->rq_disk);
- blkdev_dequeue_request(req);
- end_that_request_last(req, uptodate);
}
static int rwreq;
@@ -317,11 +314,11 @@ static void do_viocd_request(struct request_queue *q)
while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) {
if (!blk_fs_request(req))
- viocd_end_request(req, 0);
+ viocd_end_request(req, -EIO);
else if (send_request(req) < 0) {
printk(VIOCD_KERN_WARNING
"unable to send message to OS/400!");
- viocd_end_request(req, 0);
+ viocd_end_request(req, -EIO);
} else
rwreq++;
}
@@ -532,9 +529,9 @@ return_complete:
"with rc %d:0x%04X: %s\n",
req, event->xRc,
bevent->sub_result, err->msg);
- viocd_end_request(req, 0);
+ viocd_end_request(req, -EIO);
} else
- viocd_end_request(req, 1);
+ viocd_end_request(req, 0);
/* restart handling of incoming requests */
spin_unlock_irqrestore(&viocd_reqlock, flags);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 8d12b26bb6c6..b61f56b6f311 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -643,7 +643,7 @@ config I2C_PCA_ISA
config I2C_MV64XXX
tristate "Marvell mv64xxx I2C Controller"
- depends on MV64X60 && EXPERIMENTAL
+ depends on (MV64X60 || ARCH_ORION) && EXPERIMENTAL
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Marvell 64xxx line of host bridges.
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index bb7bf68a7fb6..036e6a883e67 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -1,6 +1,6 @@
/*
- * Driver for the i2c controller on the Marvell line of host bridges for MIPS
- * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0).
+ * Driver for the i2c controller on the Marvell line of host bridges
+ * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, and Orion SoC family).
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
@@ -14,7 +14,7 @@
#include <linux/spinlock.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
-#include <linux/mv643xx.h>
+#include <linux/mv643xx_i2c.h>
#include <linux/platform_device.h>
#include <asm/io.h>
@@ -86,6 +86,7 @@ struct mv64xxx_i2c_data {
u32 cntl_bits;
void __iomem *reg_base;
u32 reg_base_p;
+ u32 reg_size;
u32 addr1;
u32 addr2;
u32 bytes_left;
@@ -463,17 +464,20 @@ static int __devinit
mv64xxx_i2c_map_regs(struct platform_device *pd,
struct mv64xxx_i2c_data *drv_data)
{
- struct resource *r;
+ int size;
+ struct resource *r = platform_get_resource(pd, IORESOURCE_MEM, 0);
- if ((r = platform_get_resource(pd, IORESOURCE_MEM, 0)) &&
- request_mem_region(r->start, MV64XXX_I2C_REG_BLOCK_SIZE,
- drv_data->adapter.name)) {
+ if (!r)
+ return -ENODEV;
- drv_data->reg_base = ioremap(r->start,
- MV64XXX_I2C_REG_BLOCK_SIZE);
- drv_data->reg_base_p = r->start;
- } else
- return -ENOMEM;
+ size = r->end - r->start + 1;
+
+ if (!request_mem_region(r->start, size, drv_data->adapter.name))
+ return -EBUSY;
+
+ drv_data->reg_base = ioremap(r->start, size);
+ drv_data->reg_base_p = r->start;
+ drv_data->reg_size = size;
return 0;
}
@@ -483,8 +487,7 @@ mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
{
if (drv_data->reg_base) {
iounmap(drv_data->reg_base);
- release_mem_region(drv_data->reg_base_p,
- MV64XXX_I2C_REG_BLOCK_SIZE);
+ release_mem_region(drv_data->reg_base_p, drv_data->reg_size);
}
drv_data->reg_base = NULL;
@@ -529,7 +532,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
drv_data->adapter.owner = THIS_MODULE;
drv_data->adapter.class = I2C_CLASS_HWMON;
drv_data->adapter.timeout = pdata->timeout;
- drv_data->adapter.retries = pdata->retries;
drv_data->adapter.nr = pd->id;
platform_set_drvdata(pd, drv_data);
i2c_set_adapdata(&drv_data->adapter, drv_data);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 44b033ec0ab0..74c6087ada38 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -655,9 +655,9 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
BUG();
} else {
spin_lock_irqsave(&ide_lock, flags);
- end_that_request_chunk(failed, 0,
- failed->data_len);
- end_that_request_last(failed, 0);
+ if (__blk_end_request(failed, -EIO,
+ failed->data_len))
+ BUG();
spin_unlock_irqrestore(&ide_lock, flags);
}
} else
@@ -1647,6 +1647,17 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
return 1;
}
+/*
+ * Called from blk_end_request_callback() after the data of the request
+ * is completed and before the request is completed.
+ * By returning value '1', blk_end_request_callback() returns immediately
+ * without completing the request.
+ */
+static int cdrom_newpc_intr_dummy_cb(struct request *rq)
+{
+ return 1;
+}
+
typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
/*
@@ -1685,9 +1696,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
return ide_error(drive, "dma error", stat);
}
- end_that_request_chunk(rq, 1, rq->data_len);
- rq->data_len = 0;
- goto end_request;
+ spin_lock_irqsave(&ide_lock, flags);
+ if (__blk_end_request(rq, 0, rq->data_len))
+ BUG();
+ HWGROUP(drive)->rq = NULL;
+ spin_unlock_irqrestore(&ide_lock, flags);
+
+ return ide_stopped;
}
/*
@@ -1705,8 +1720,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/*
* If DRQ is clear, the command has completed.
*/
- if ((stat & DRQ_STAT) == 0)
- goto end_request;
+ if ((stat & DRQ_STAT) == 0) {
+ spin_lock_irqsave(&ide_lock, flags);
+ if (__blk_end_request(rq, 0, 0))
+ BUG();
+ HWGROUP(drive)->rq = NULL;
+ spin_unlock_irqrestore(&ide_lock, flags);
+
+ return ide_stopped;
+ }
/*
* check which way to transfer data
@@ -1759,7 +1781,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
rq->data_len -= blen;
if (rq->bio)
- end_that_request_chunk(rq, 1, blen);
+ /*
+ * The request can't be completed until DRQ is cleared.
+ * So complete the data, but don't complete the request
+ * using the dummy function for the callback feature
+ * of blk_end_request_callback().
+ */
+ blk_end_request_callback(rq, 0, blen,
+ cdrom_newpc_intr_dummy_cb);
else
rq->data += blen;
}
@@ -1780,14 +1809,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
return ide_started;
-
-end_request:
- spin_lock_irqsave(&ide_lock, flags);
- blkdev_dequeue_request(rq);
- end_that_request_last(rq, 1);
- HWGROUP(drive)->rq = NULL;
- spin_unlock_irqrestore(&ide_lock, flags);
- return ide_stopped;
}
static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 6f8f544392a8..e6bb9cf24e3d 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -58,15 +58,19 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
int uptodate, unsigned int nr_bytes, int dequeue)
{
int ret = 1;
+ int error = 0;
+
+ if (uptodate <= 0)
+ error = uptodate ? uptodate : -EIO;
/*
* if failfast is set on a request, override number of sectors and
* complete the whole request right now
*/
- if (blk_noretry_request(rq) && end_io_error(uptodate))
+ if (blk_noretry_request(rq) && error)
nr_bytes = rq->hard_nr_sectors << 9;
- if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
+ if (!blk_fs_request(rq) && error && !rq->errors)
rq->errors = -EIO;
/*
@@ -78,14 +82,9 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
ide_dma_on(drive);
}
- if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
- add_disk_randomness(rq->rq_disk);
- if (dequeue) {
- if (!list_empty(&rq->queuelist))
- blkdev_dequeue_request(rq);
+ if (!__blk_end_request(rq, error, nr_bytes)) {
+ if (dequeue)
HWGROUP(drive)->rq = NULL;
- }
- end_that_request_last(rq, uptodate);
ret = 0;
}
@@ -290,9 +289,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
drive->blocked = 0;
blk_start_queue(drive->queue);
}
- blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq, 1);
+ if (__blk_end_request(rq, 0, 0))
+ BUG();
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -387,10 +386,10 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
}
spin_lock_irqsave(&ide_lock, flags);
- blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
rq->errors = err;
- end_that_request_last(rq, !rq->errors);
+ if (__blk_end_request(rq, (rq->errors ? -EIO : 0), 0))
+ BUG();
spin_unlock_irqrestore(&ide_lock, flags);
}
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index b1b2e07bf080..99d92f5c93d6 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -74,10 +74,10 @@ extern unsigned int get_clk_frequency_khz(int info);
static unsigned long calc_waittime(struct corgi_ts *corgi_ts)
{
- unsigned long hsync_len = corgi_ts->machinfo->get_hsync_len();
+ unsigned long hsync_invperiod = corgi_ts->machinfo->get_hsync_invperiod();
- if (hsync_len)
- return get_clk_frequency_khz(0)*1000/hsync_len;
+ if (hsync_invperiod)
+ return get_clk_frequency_khz(0)*1000/hsync_invperiod;
else
return 0;
}
@@ -114,7 +114,7 @@ static int sync_receive_data_send_cmd(struct corgi_ts *corgi_ts, int doRecive, i
if (timer2-timer1 > wait_time) {
/* too slow - timeout, try again */
corgi_ts->machinfo->wait_hsync();
- /* get OSCR */
+ /* get CCNT */
CCNT(timer1);
/* Wait after HSync */
CCNT(timer2);
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index e4ad7a1c4fbd..a95314897402 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -412,13 +412,13 @@ static void i2o_block_delayed_request_fn(struct work_struct *work)
/**
* i2o_block_end_request - Post-processing of completed commands
* @req: request which should be completed
- * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
+ * @error: 0 for success, < 0 for error
* @nr_bytes: number of bytes to complete
*
* Mark the request as complete. The lock must not be held when entering.
*
*/
-static void i2o_block_end_request(struct request *req, int uptodate,
+static void i2o_block_end_request(struct request *req, int error,
int nr_bytes)
{
struct i2o_block_request *ireq = req->special;
@@ -426,22 +426,18 @@ static void i2o_block_end_request(struct request *req, int uptodate,
struct request_queue *q = req->q;
unsigned long flags;
- if (end_that_request_chunk(req, uptodate, nr_bytes)) {
+ if (blk_end_request(req, error, nr_bytes)) {
int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT);
if (blk_pc_request(req))
leftover = req->data_len;
- if (end_io_error(uptodate))
- end_that_request_chunk(req, 0, leftover);
+ if (error)
+ blk_end_request(req, -EIO, leftover);
}
- add_disk_randomness(req->rq_disk);
-
spin_lock_irqsave(q->queue_lock, flags);
- end_that_request_last(req, uptodate);
-
if (likely(dev)) {
dev->open_queue_depth--;
list_del(&ireq->queue);
@@ -468,7 +464,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg)
{
struct request *req;
- int uptodate = 1;
+ int error = 0;
req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
if (unlikely(!req)) {
@@ -501,10 +497,10 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
req->errors++;
- uptodate = 0;
+ error = -EIO;
}
- i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1]));
+ i2o_block_end_request(req, error, le32_to_cpu(msg->body[1]));
return 1;
};
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c
index b7c8e7813865..61aeaf79640d 100644
--- a/drivers/mfd/ucb1x00-assabet.c
+++ b/drivers/mfd/ucb1x00-assabet.c
@@ -20,7 +20,7 @@
#include "ucb1x00.h"
#define UCB1X00_ATTR(name,input)\
-static ssize_t name##_show(struct device *dev, struct device_attribute *attr,
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
@@ -38,17 +38,17 @@ UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
static int ucb1x00_assabet_add(struct ucb1x00_dev *dev)
{
- device_create_file(&dev->ucb->dev, &device_attr_vbatt);
- device_create_file(&dev->ucb->dev, &device_attr_vcharger);
- device_create_file(&dev->ucb->dev, &device_attr_batt_temp);
+ device_create_file(&dev->ucb->dev, &dev_attr_vbatt);
+ device_create_file(&dev->ucb->dev, &dev_attr_vcharger);
+ device_create_file(&dev->ucb->dev, &dev_attr_batt_temp);
return 0;
}
static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev)
{
- device_remove_file(&dev->ucb->cdev, &device_attr_batt_temp);
- device_remove_file(&dev->ucb->cdev, &device_attr_vcharger);
- device_remove_file(&dev->ucb->cdev, &device_attr_vbatt);
+ device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp);
+ device_remove_file(&dev->ucb->dev, &dev_attr_vcharger);
+ device_remove_file(&dev->ucb->dev, &dev_attr_vbatt);
}
static struct ucb1x00_driver ucb1x00_assabet_driver = {
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index aeb32a93f6a0..91ded3e82401 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -348,15 +348,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
* A block was successfully transferred.
*/
spin_lock_irq(&md->lock);
- ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered);
- if (!ret) {
- /*
- * The whole request completed successfully.
- */
- add_disk_randomness(req->rq_disk);
- blkdev_dequeue_request(req);
- end_that_request_last(req, 1);
- }
+ ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
spin_unlock_irq(&md->lock);
} while (ret);
@@ -386,27 +378,21 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
else
bytes = blocks << 9;
spin_lock_irq(&md->lock);
- ret = end_that_request_chunk(req, 1, bytes);
+ ret = __blk_end_request(req, 0, bytes);
spin_unlock_irq(&md->lock);
}
} else if (rq_data_dir(req) != READ &&
(card->host->caps & MMC_CAP_MULTIWRITE)) {
spin_lock_irq(&md->lock);
- ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered);
+ ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
spin_unlock_irq(&md->lock);
}
mmc_release_host(card->host);
spin_lock_irq(&md->lock);
- while (ret) {
- ret = end_that_request_chunk(req, 0,
- req->current_nr_sectors << 9);
- }
-
- add_disk_randomness(req->rq_disk);
- blkdev_dequeue_request(req);
- end_that_request_last(req, 0);
+ while (ret)
+ ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
spin_unlock_irq(&md->lock);
return 0;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 30cd13b13ac3..7731ddefdc1b 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -94,8 +94,8 @@ static void mmc_request(struct request_queue *q)
printk(KERN_ERR "MMC: killing requests for dead queue\n");
while ((req = elv_next_request(q)) != NULL) {
do {
- ret = end_that_request_chunk(req, 0,
- req->current_nr_sectors << 9);
+ ret = __blk_end_request(req, -EIO,
+ blk_rq_cur_bytes(req));
} while (ret);
}
return;
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 1654a3330340..1ea8482037bb 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -65,6 +65,8 @@ struct pxamci_host {
unsigned int dma_len;
unsigned int dma_dir;
+ unsigned int dma_drcmrrx;
+ unsigned int dma_drcmrtx;
};
static void pxamci_stop_clock(struct pxamci_host *host)
@@ -131,13 +133,13 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
if (data->flags & MMC_DATA_READ) {
host->dma_dir = DMA_FROM_DEVICE;
dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG;
- DRCMRTXMMC = 0;
- DRCMRRXMMC = host->dma | DRCMR_MAPVLD;
+ DRCMR(host->dma_drcmrtx) = 0;
+ DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD;
} else {
host->dma_dir = DMA_TO_DEVICE;
dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC;
- DRCMRRXMMC = 0;
- DRCMRTXMMC = host->dma | DRCMR_MAPVLD;
+ DRCMR(host->dma_drcmrrx) = 0;
+ DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD;
}
dcmd |= DCMD_BURST32 | DCMD_WIDTH1;
@@ -375,14 +377,23 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->clkrt == CLKRT_OFF)
clk_enable(host->clk);
- /*
- * clk might result in a lower divisor than we
- * desire. check for that condition and adjust
- * as appropriate.
- */
- if (rate / clk > ios->clock)
- clk <<= 1;
- host->clkrt = fls(clk) - 1;
+ if (ios->clock == 26000000) {
+ /* to support 26MHz on pxa300/pxa310 */
+ host->clkrt = 7;
+ } else {
+ /* to handle (19.5MHz, 26MHz) */
+ if (!clk)
+ clk = 1;
+
+ /*
+ * clk might result in a lower divisor than we
+ * desire. check for that condition and adjust
+ * as appropriate.
+ */
+ if (rate / clk > ios->clock)
+ clk <<= 1;
+ host->clkrt = fls(clk) - 1;
+ }
/*
* we write clkrt on the next command
@@ -459,7 +470,7 @@ static int pxamci_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
struct pxamci_host *host = NULL;
- struct resource *r;
+ struct resource *r, *dmarx, *dmatx;
int ret, irq;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -519,7 +530,8 @@ static int pxamci_probe(struct platform_device *pdev)
* Calculate minimum clock rate, rounding up.
*/
mmc->f_min = (host->clkrate + 63) / 64;
- mmc->f_max = host->clkrate;
+ mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000
+ : host->clkrate;
mmc->ocr_avail = host->pdata ?
host->pdata->ocr_mask :
@@ -529,6 +541,9 @@ static int pxamci_probe(struct platform_device *pdev)
if (!cpu_is_pxa21x() && !cpu_is_pxa25x()) {
mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
host->cmdat |= CMDAT_SDIO_INT_EN;
+ if (cpu_is_pxa300() || cpu_is_pxa310())
+ mmc->caps |= MMC_CAP_MMC_HIGHSPEED |
+ MMC_CAP_SD_HIGHSPEED;
}
host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
@@ -570,6 +585,20 @@ static int pxamci_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mmc);
+ dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!dmarx) {
+ ret = -ENXIO;
+ goto out;
+ }
+ host->dma_drcmrrx = dmarx->start;
+
+ dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!dmatx) {
+ ret = -ENXIO;
+ goto out;
+ }
+ host->dma_drcmrtx = dmatx->start;
+
if (host->pdata && host->pdata->init)
host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc);
@@ -613,8 +642,8 @@ static int pxamci_remove(struct platform_device *pdev)
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
host->base + MMC_I_MASK);
- DRCMRRXMMC = 0;
- DRCMRTXMMC = 0;
+ DRCMR(host->dma_drcmrrx) = 0;
+ DRCMR(host->dma_drcmrtx) = 0;
free_irq(host->irq, host);
pxa_free_dma(host->dma);
diff --git a/drivers/mmc/host/pxamci.h b/drivers/mmc/host/pxamci.h
index 748c7706f237..f6c2e2fcce37 100644
--- a/drivers/mmc/host/pxamci.h
+++ b/drivers/mmc/host/pxamci.h
@@ -68,7 +68,7 @@
#define PRG_DONE (1 << 1)
#define DATA_TRAN_DONE (1 << 0)
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#define MMC_I_MASK_ALL 0x00001fff
#else
#define MMC_I_MASK_ALL 0x0000007f
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9af05a2f4af3..a6728661c416 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -212,7 +212,7 @@ config MII
config MACB
tristate "Atmel MACB support"
- depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263
+ depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91CAP9
select PHYLIB
help
The Atmel MACB ethernet interface is found on many AT32 and AT91
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 3286d2a0a870..6a20a5491a96 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -66,6 +66,7 @@
#include <linux/dm9000.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/irq.h>
#include <asm/delay.h>
#include <asm/irq.h>
@@ -113,7 +114,7 @@
#define writesl outsl
#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH)
#else
-#define DM9000_IRQ_FLAGS IRQF_SHARED
+#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQT_RISING)
#endif
/*
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 7da7589d45dd..4020e9e955b3 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1775,7 +1775,8 @@ static int __init smc_findirq(void __iomem *ioaddr)
* o actually GRAB the irq.
* o GRAB the region
*/
-static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
+static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+ unsigned long irq_flags)
{
struct smc_local *lp = netdev_priv(dev);
static int version_printed = 0;
@@ -1941,7 +1942,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
}
/* Grab the IRQ */
- retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
+ retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev);
if (retval)
goto err_out;
@@ -2123,8 +2124,9 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
static int smc_drv_probe(struct platform_device *pdev)
{
struct net_device *ndev;
- struct resource *res;
+ struct resource *res, *ires;
unsigned int __iomem *addr;
+ unsigned long irq_flags = SMC_IRQ_FLAGS;
int ret;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
@@ -2150,12 +2152,17 @@ static int smc_drv_probe(struct platform_device *pdev)
SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->dma = (unsigned char)-1;
- ndev->irq = platform_get_irq(pdev, 0);
- if (ndev->irq < 0) {
+
+ ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!ires) {
ret = -ENODEV;
goto out_free_netdev;
}
+ ndev->irq = ires->start;
+ if (SMC_IRQ_FLAGS == -1)
+ irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+
ret = smc_request_attrib(pdev);
if (ret)
goto out_free_netdev;
@@ -2181,7 +2188,7 @@ static int smc_drv_probe(struct platform_device *pdev)
#endif
platform_set_drvdata(pdev, ndev);
- ret = smc_probe(ndev, addr);
+ ret = smc_probe(ndev, addr, irq_flags);
if (ret != 0)
goto out_iounmap;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 07b7f7120e37..271c28dc9baa 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -54,6 +54,7 @@
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
+#define SMC_IRQ_FLAGS (-1) /* from resource */
#elif defined(CONFIG_BLACKFIN)
@@ -158,7 +159,7 @@
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
-#define SMC_IRQ_FLAGS (0)
+#define SMC_IRQ_FLAGS (-1)
#elif defined(CONFIG_SA1100_ASSABET)
@@ -177,6 +178,7 @@
#define SMC_outb(v, a, r) writeb(v, (a) + (r))
#define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l))
#define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l))
+#define SMC_IRQ_FLAGS (-1) /* from resource */
#elif defined(CONFIG_MACH_LOGICPD_PXA270)
@@ -194,7 +196,8 @@
#elif defined(CONFIG_ARCH_INNOKOM) || \
defined(CONFIG_MACH_MAINSTONE) || \
defined(CONFIG_ARCH_PXA_IDP) || \
- defined(CONFIG_ARCH_RAMSES)
+ defined(CONFIG_ARCH_RAMSES) || \
+ defined(CONFIG_ARCH_PCM027)
#define SMC_CAN_USE_8BIT 1
#define SMC_CAN_USE_16BIT 1
@@ -210,6 +213,7 @@
#define SMC_outl(v, a, r) writel(v, (a) + (r))
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
+#define SMC_IRQ_FLAGS (-1) /* from resource */
/* We actually can't write halfwords properly if not word aligned */
static inline void
@@ -238,6 +242,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
#define SMC_outb(v, a, r) writeb(v, (a) + (r))
#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_IRQ_FLAGS (-1) /* from resource */
#elif defined(CONFIG_ARCH_OMAP)
@@ -252,17 +257,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
-
-#include <asm/mach-types.h>
-#include <asm/arch/cpu.h>
-
-#define SMC_IRQ_FLAGS (( \
- machine_is_omap_h2() \
- || machine_is_omap_h3() \
- || machine_is_omap_h4() \
- || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
- ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
-
+#define SMC_IRQ_FLAGS (-1) /* from resource */
#elif defined(CONFIG_SH_SH4202_MICRODEV)
@@ -453,8 +448,7 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#define SMC_outl(v, a, r) writel(v, (a) + (r))
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
-
-#define SMC_IRQ_FLAGS (0)
+#define SMC_IRQ_FLAGS (-1) /* from resource */
#else
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 874923fcb2f9..e439044d88f2 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -29,6 +29,7 @@
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 6f1e9a9804bc..2eb38520f0c8 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -337,6 +337,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
if (IS_ERR(rtc))
return PTR_ERR(rtc);
+ device_init_wakeup(&pdev->dev, 1);
+
platform_set_drvdata(pdev, rtc);
return 0;
@@ -352,9 +354,38 @@ static int sa1100_rtc_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ if (pdev->dev.power.power_state.event != state.event) {
+ if (state.event == PM_EVENT_SUSPEND &&
+ device_may_wakeup(&pdev->dev))
+ enable_irq_wake(IRQ_RTCAlrm);
+
+ pdev->dev.power.power_state = state;
+ }
+ return 0;
+}
+
+static int sa1100_rtc_resume(struct platform_device *pdev)
+{
+ if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
+ if (device_may_wakeup(&pdev->dev))
+ disable_irq_wake(IRQ_RTCAlrm);
+ pdev->dev.power.power_state = PMSG_ON;
+ }
+ return 0;
+}
+#else
+#define sa1100_rtc_suspend NULL
+#define sa1100_rtc_resume NULL
+#endif
+
static struct platform_driver sa1100_rtc_driver = {
.probe = sa1100_rtc_probe,
.remove = sa1100_rtc_remove,
+ .suspend = sa1100_rtc_suspend,
+ .resume = sa1100_rtc_resume,
.driver = {
.name = "sa1100-rtc",
},
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 1db15f3e5d20..d640427c74c8 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1595,12 +1595,10 @@ void dasd_block_clear_timer(struct dasd_block *block)
/*
* posts the buffer_cache about a finalized request
*/
-static inline void dasd_end_request(struct request *req, int uptodate)
+static inline void dasd_end_request(struct request *req, int error)
{
- if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
+ if (__blk_end_request(req, error, blk_rq_bytes(req)))
BUG();
- add_disk_randomness(req->rq_disk);
- end_that_request_last(req, uptodate);
}
/*
@@ -1657,7 +1655,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
"Rejecting write request %p",
req);
blkdev_dequeue_request(req);
- dasd_end_request(req, 0);
+ dasd_end_request(req, -EIO);
continue;
}
cqr = basedev->discipline->build_cp(basedev, block, req);
@@ -1686,7 +1684,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
"on request %p",
PTR_ERR(cqr), req);
blkdev_dequeue_request(req);
- dasd_end_request(req, 0);
+ dasd_end_request(req, -EIO);
continue;
}
/*
@@ -1705,11 +1703,14 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr)
{
struct request *req;
int status;
+ int error = 0;
req = (struct request *) cqr->callback_data;
dasd_profile_end(cqr->block, cqr, req);
status = cqr->memdev->discipline->free_cp(cqr, req);
- dasd_end_request(req, status);
+ if (status <= 0)
+ error = status ? status : -EIO;
+ dasd_end_request(req, error);
}
/*
@@ -2009,7 +2010,7 @@ static void dasd_flush_request_queue(struct dasd_block *block)
spin_lock_irq(&block->request_queue_lock);
while ((req = elv_next_request(block->request_queue))) {
blkdev_dequeue_request(req);
- dasd_end_request(req, 0);
+ dasd_end_request(req, -EIO);
}
spin_unlock_irq(&block->request_queue_lock);
}
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index eeb92e2ed0cc..ddc4a114e7f4 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -74,11 +74,10 @@ tapeblock_trigger_requeue(struct tape_device *device)
* Post finished request.
*/
static void
-tapeblock_end_request(struct request *req, int uptodate)
+tapeblock_end_request(struct request *req, int error)
{
- if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
+ if (__blk_end_request(req, error, blk_rq_bytes(req)))
BUG();
- end_that_request_last(req, uptodate);
}
static void
@@ -91,7 +90,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data)
device = ccw_req->device;
req = (struct request *) data;
- tapeblock_end_request(req, ccw_req->rc == 0);
+ tapeblock_end_request(req, (ccw_req->rc == 0) ? 0 : -EIO);
if (ccw_req->rc == 0)
/* Update position. */
device->blk_data.block_position =
@@ -119,7 +118,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
ccw_req = device->discipline->bread(device, req);
if (IS_ERR(ccw_req)) {
DBF_EVENT(1, "TBLOCK: bread failed\n");
- tapeblock_end_request(req, 0);
+ tapeblock_end_request(req, -EIO);
return PTR_ERR(ccw_req);
}
ccw_req->callback = __tapeblock_end_request;
@@ -132,7 +131,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
* Start/enqueueing failed. No retries in
* this case.
*/
- tapeblock_end_request(req, 0);
+ tapeblock_end_request(req, -EIO);
device->discipline->free_bread(ccw_req);
}
@@ -177,7 +176,7 @@ tapeblock_requeue(struct work_struct *work) {
if (rq_data_dir(req) == WRITE) {
DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
blkdev_dequeue_request(req);
- tapeblock_end_request(req, 0);
+ tapeblock_end_request(req, -EIO);
continue;
}
spin_unlock_irq(&device->blk_data.request_queue_lock);
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 02e91893064d..db8bc20539e1 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -919,8 +919,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
}
/* kill current request */
- blkdev_dequeue_request(req);
- end_that_request_last(req, 0);
+ if (__blk_end_request(req, -EIO, 0))
+ BUG();
if (blk_sense_request(req))
kfree(scsi->pc->buffer);
kfree(scsi->pc);
@@ -929,8 +929,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
/* now nuke the drive queue */
while ((req = elv_next_request(drive->queue))) {
- blkdev_dequeue_request(req);
- end_that_request_last(req, 0);
+ if (__blk_end_request(req, -EIO, 0))
+ BUG();
}
HWGROUP(drive)->rq = NULL;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4cf902efbdbf..7c4c889c5221 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -634,7 +634,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
* of upper level post-processing and scsi_io_completion).
*
* Arguments: cmd - command that is complete.
- * uptodate - 1 if I/O indicates success, <= 0 for I/O error.
+ * error - 0 if I/O indicates success, < 0 for I/O error.
* bytes - number of bytes of completed I/O
* requeue - indicates whether we should requeue leftovers.
*
@@ -649,26 +649,25 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
* at some point during this call.
* Notes: If cmd was requeued, upon return it will be a stale pointer.
*/
-static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
+static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
int bytes, int requeue)
{
struct request_queue *q = cmd->device->request_queue;
struct request *req = cmd->request;
- unsigned long flags;
/*
* If there are blocks left over at the end, set up the command
* to queue the remainder of them.
*/
- if (end_that_request_chunk(req, uptodate, bytes)) {
+ if (blk_end_request(req, error, bytes)) {
int leftover = (req->hard_nr_sectors << 9);
if (blk_pc_request(req))
leftover = req->data_len;
/* kill remainder if no retrys */
- if (!uptodate && blk_noretry_request(req))
- end_that_request_chunk(req, 0, leftover);
+ if (error && blk_noretry_request(req))
+ blk_end_request(req, error, leftover);
else {
if (requeue) {
/*
@@ -683,14 +682,6 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
}
}
- add_disk_randomness(req->rq_disk);
-
- spin_lock_irqsave(q->queue_lock, flags);
- if (blk_rq_tagged(req))
- blk_queue_end_tag(q, req);
- end_that_request_last(req, uptodate);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
/*
* This will goose the queue request function at the end, so we don't
* need to worry about launching another command.
@@ -739,138 +730,43 @@ static inline unsigned int scsi_sgtable_index(unsigned short nents)
return index;
}
-struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+static void scsi_sg_free(struct scatterlist *sgl, unsigned int nents)
{
struct scsi_host_sg_pool *sgp;
- struct scatterlist *sgl, *prev, *ret;
- unsigned int index;
- int this, left;
-
- BUG_ON(!cmd->use_sg);
-
- left = cmd->use_sg;
- ret = prev = NULL;
- do {
- this = left;
- if (this > SCSI_MAX_SG_SEGMENTS) {
- this = SCSI_MAX_SG_SEGMENTS - 1;
- index = SG_MEMPOOL_NR - 1;
- } else
- index = scsi_sgtable_index(this);
-
- left -= this;
- sgp = scsi_sg_pools + index;
-
- sgl = mempool_alloc(sgp->pool, gfp_mask);
- if (unlikely(!sgl))
- goto enomem;
+ sgp = scsi_sg_pools + scsi_sgtable_index(nents);
+ mempool_free(sgl, sgp->pool);
+}
- sg_init_table(sgl, sgp->size);
+static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask)
+{
+ struct scsi_host_sg_pool *sgp;
- /*
- * first loop through, set initial index and return value
- */
- if (!ret)
- ret = sgl;
+ sgp = scsi_sg_pools + scsi_sgtable_index(nents);
+ return mempool_alloc(sgp->pool, gfp_mask);
+}
- /*
- * chain previous sglist, if any. we know the previous
- * sglist must be the biggest one, or we would not have
- * ended up doing another loop.
- */
- if (prev)
- sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
+int scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+{
+ int ret;
- /*
- * if we have nothing left, mark the last segment as
- * end-of-list
- */
- if (!left)
- sg_mark_end(&sgl[this - 1]);
+ BUG_ON(!cmd->use_sg);
- /*
- * don't allow subsequent mempool allocs to sleep, it would
- * violate the mempool principle.
- */
- gfp_mask &= ~__GFP_WAIT;
- gfp_mask |= __GFP_HIGH;
- prev = sgl;
- } while (left);
+ ret = __sg_alloc_table(&cmd->sg_table, cmd->use_sg,
+ SCSI_MAX_SG_SEGMENTS, gfp_mask, scsi_sg_alloc);
+ if (unlikely(ret))
+ __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS,
+ scsi_sg_free);
- /*
- * ->use_sg may get modified after dma mapping has potentially
- * shrunk the number of segments, so keep a copy of it for free.
- */
- cmd->__use_sg = cmd->use_sg;
+ cmd->request_buffer = cmd->sg_table.sgl;
return ret;
-enomem:
- if (ret) {
- /*
- * Free entries chained off ret. Since we were trying to
- * allocate another sglist, we know that all entries are of
- * the max size.
- */
- sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
- prev = ret;
- ret = &ret[SCSI_MAX_SG_SEGMENTS - 1];
-
- while ((sgl = sg_chain_ptr(ret)) != NULL) {
- ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1];
- mempool_free(sgl, sgp->pool);
- }
-
- mempool_free(prev, sgp->pool);
- }
- return NULL;
}
EXPORT_SYMBOL(scsi_alloc_sgtable);
void scsi_free_sgtable(struct scsi_cmnd *cmd)
{
- struct scatterlist *sgl = cmd->request_buffer;
- struct scsi_host_sg_pool *sgp;
-
- /*
- * if this is the biggest size sglist, check if we have
- * chained parts we need to free
- */
- if (cmd->__use_sg > SCSI_MAX_SG_SEGMENTS) {
- unsigned short this, left;
- struct scatterlist *next;
- unsigned int index;
-
- left = cmd->__use_sg - (SCSI_MAX_SG_SEGMENTS - 1);
- next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]);
- while (left && next) {
- sgl = next;
- this = left;
- if (this > SCSI_MAX_SG_SEGMENTS) {
- this = SCSI_MAX_SG_SEGMENTS - 1;
- index = SG_MEMPOOL_NR - 1;
- } else
- index = scsi_sgtable_index(this);
-
- left -= this;
-
- sgp = scsi_sg_pools + index;
-
- if (left)
- next = sg_chain_ptr(&sgl[sgp->size - 1]);
-
- mempool_free(sgl, sgp->pool);
- }
-
- /*
- * Restore original, will be freed below
- */
- sgl = cmd->request_buffer;
- sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
- } else
- sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg);
-
- mempool_free(sgl, sgp->pool);
+ __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free);
}
EXPORT_SYMBOL(scsi_free_sgtable);
@@ -987,7 +883,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* are leftovers and there is some kind of error
* (result != 0), retry the rest.
*/
- if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL)
+ if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL)
return;
/* good_bytes = 0, or (inclusive) there were leftovers and
@@ -1001,7 +897,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* and quietly refuse further access.
*/
cmd->device->changed = 1;
- scsi_end_request(cmd, 0, this_count, 1);
+ scsi_end_request(cmd, -EIO, this_count, 1);
return;
} else {
/* Must have been a power glitch, or a
@@ -1033,7 +929,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_requeue_command(q, cmd);
return;
} else {
- scsi_end_request(cmd, 0, this_count, 1);
+ scsi_end_request(cmd, -EIO, this_count, 1);
return;
}
break;
@@ -1061,7 +957,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
"Device not ready",
&sshdr);
- scsi_end_request(cmd, 0, this_count, 1);
+ scsi_end_request(cmd, -EIO, this_count, 1);
return;
case VOLUME_OVERFLOW:
if (!(req->cmd_flags & REQ_QUIET)) {
@@ -1071,7 +967,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_print_sense("", cmd);
}
/* See SSC3rXX or current. */
- scsi_end_request(cmd, 0, this_count, 1);
+ scsi_end_request(cmd, -EIO, this_count, 1);
return;
default:
break;
@@ -1092,7 +988,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_print_sense("", cmd);
}
}
- scsi_end_request(cmd, 0, this_count, !result);
+ scsi_end_request(cmd, -EIO, this_count, !result);
}
/*
@@ -1120,8 +1016,7 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
/*
* If sg table allocation fails, requeue request later.
*/
- cmd->request_buffer = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
- if (unlikely(!cmd->request_buffer)) {
+ if (unlikely(scsi_alloc_sgtable(cmd, GFP_ATOMIC))) {
scsi_unprep_request(req);
return BLKPREP_DEFER;
}
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 93ece8f4e5de..01e03f3f6ffa 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -359,8 +359,7 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
int count;
cmd->use_sg = rq->nr_phys_segments;
- cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask);
- if (!cmd->request_buffer)
+ if (scsi_alloc_sgtable(cmd, gfp_mask))
return -ENOMEM;
cmd->request_bufflen = rq->data_len;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 17216b76efdc..aba28f335b88 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -48,6 +48,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/scatterlist.h>
+#include <linux/blktrace_api.h>
#include "scsi.h"
#include <scsi/scsi_dbg.h>
@@ -1067,6 +1068,17 @@ sg_ioctl(struct inode *inode, struct file *filp,
case BLKSECTGET:
return put_user(sdp->device->request_queue->max_sectors * 512,
ip);
+ case BLKTRACESETUP:
+ return blk_trace_setup(sdp->device->request_queue,
+ sdp->disk->disk_name,
+ sdp->device->sdev_gendev.devt,
+ (char *)arg);
+ case BLKTRACESTART:
+ return blk_trace_startstop(sdp->device->request_queue, 1);
+ case BLKTRACESTOP:
+ return blk_trace_startstop(sdp->device->request_queue, 0);
+ case BLKTRACETEARDOWN:
+ return blk_trace_remove(sdp->device->request_queue);
default:
if (read_only)
return -EPERM; /* don't know so take safe approach */
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index facb67855619..6a48dfa1efe8 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -277,6 +277,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
if (termios->c_iflag & INPCK)
port->read_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY;
+ tty_encode_baud_rate(tty, baud, baud);
+
/*
* Which character status flags should we ignore?
*/
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index abf05048c638..aaaea81e412a 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -153,6 +153,7 @@ config SPI_OMAP24XX
config SPI_PXA2XX
tristate "PXA2xx SSP SPI master"
depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
+ select PXA_SSP
help
This enables using a PXA2xx SSP port as a SPI master controller.
The driver can be configured to use any SSP port and additional
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 1c2ab541d37d..eb817b8eb024 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -27,6 +27,7 @@
#include <linux/spi/spi.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
+#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -36,6 +37,8 @@
#include <asm/arch/hardware.h>
#include <asm/arch/pxa-regs.h>
+#include <asm/arch/regs-ssp.h>
+#include <asm/arch/ssp.h>
#include <asm/arch/pxa2xx_spi.h>
MODULE_AUTHOR("Stephen Street");
@@ -80,6 +83,9 @@ struct driver_data {
/* Driver model hookup */
struct platform_device *pdev;
+ /* SSP Info */
+ struct ssp_device *ssp;
+
/* SPI framework hookup */
enum pxa_ssp_type ssp_type;
struct spi_master *master;
@@ -778,6 +784,16 @@ int set_dma_burst_and_threshold(struct chip_data *chip, struct spi_device *spi,
return retval;
}
+static unsigned int ssp_get_clk_div(struct ssp_device *ssp, int rate)
+{
+ unsigned long ssp_clk = clk_get_rate(ssp->clk);
+
+ if (ssp->type == PXA25x_SSP)
+ return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8;
+ else
+ return ((ssp_clk / rate - 1) & 0xfff) << 8;
+}
+
static void pump_transfers(unsigned long data)
{
struct driver_data *drv_data = (struct driver_data *)data;
@@ -785,6 +801,7 @@ static void pump_transfers(unsigned long data)
struct spi_transfer *transfer = NULL;
struct spi_transfer *previous = NULL;
struct chip_data *chip = NULL;
+ struct ssp_device *ssp = drv_data->ssp;
void *reg = drv_data->ioaddr;
u32 clk_div = 0;
u8 bits = 0;
@@ -866,12 +883,7 @@ static void pump_transfers(unsigned long data)
if (transfer->bits_per_word)
bits = transfer->bits_per_word;
- if (reg == SSP1_VIRT)
- clk_div = SSP1_SerClkDiv(speed);
- else if (reg == SSP2_VIRT)
- clk_div = SSP2_SerClkDiv(speed);
- else if (reg == SSP3_VIRT)
- clk_div = SSP3_SerClkDiv(speed);
+ clk_div = ssp_get_clk_div(ssp, speed);
if (bits <= 8) {
drv_data->n_bytes = 1;
@@ -1074,6 +1086,7 @@ static int setup(struct spi_device *spi)
struct pxa2xx_spi_chip *chip_info = NULL;
struct chip_data *chip;
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+ struct ssp_device *ssp = drv_data->ssp;
unsigned int clk_div;
if (!spi->bits_per_word)
@@ -1157,18 +1170,7 @@ static int setup(struct spi_device *spi)
}
}
- if (drv_data->ioaddr == SSP1_VIRT)
- clk_div = SSP1_SerClkDiv(spi->max_speed_hz);
- else if (drv_data->ioaddr == SSP2_VIRT)
- clk_div = SSP2_SerClkDiv(spi->max_speed_hz);
- else if (drv_data->ioaddr == SSP3_VIRT)
- clk_div = SSP3_SerClkDiv(spi->max_speed_hz);
- else
- {
- dev_err(&spi->dev, "failed setup: unknown IO address=0x%p\n",
- drv_data->ioaddr);
- return -ENODEV;
- }
+ clk_div = ssp_get_clk_div(ssp, spi->max_speed_hz);
chip->speed_hz = spi->max_speed_hz;
chip->cr0 = clk_div
@@ -1183,15 +1185,15 @@ static int setup(struct spi_device *spi)
/* NOTE: PXA25x_SSP _could_ use external clocking ... */
if (drv_data->ssp_type != PXA25x_SSP)
- dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
+ dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
spi->bits_per_word,
- (CLOCK_SPEED_HZ)
+ clk_get_rate(ssp->clk)
/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
spi->mode & 0x3);
else
- dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
+ dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
spi->bits_per_word,
- (CLOCK_SPEED_HZ/2)
+ clk_get_rate(ssp->clk)
/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
spi->mode & 0x3);
@@ -1323,14 +1325,14 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
struct pxa2xx_spi_master *platform_info;
struct spi_master *master;
struct driver_data *drv_data = 0;
- struct resource *memory_resource;
- int irq;
+ struct ssp_device *ssp;
int status = 0;
platform_info = dev->platform_data;
- if (platform_info->ssp_type == SSP_UNDEFINED) {
- dev_err(&pdev->dev, "undefined SSP\n");
+ ssp = ssp_request(pdev->id, pdev->name);
+ if (ssp == NULL) {
+ dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id);
return -ENODEV;
}
@@ -1338,12 +1340,14 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
if (!master) {
dev_err(&pdev->dev, "can not alloc spi_master\n");
+ ssp_free(ssp);
return -ENOMEM;
}
drv_data = spi_master_get_devdata(master);
drv_data->master = master;
drv_data->master_info = platform_info;
drv_data->pdev = pdev;
+ drv_data->ssp = ssp;
master->bus_num = pdev->id;
master->num_chipselect = platform_info->num_chipselect;
@@ -1351,21 +1355,13 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
master->setup = setup;
master->transfer = transfer;
- drv_data->ssp_type = platform_info->ssp_type;
+ drv_data->ssp_type = ssp->type;
drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data +
sizeof(struct driver_data)), 8);
- /* Setup register addresses */
- memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!memory_resource) {
- dev_err(&pdev->dev, "memory resources not defined\n");
- status = -ENODEV;
- goto out_error_master_alloc;
- }
-
- drv_data->ioaddr = (void *)io_p2v((unsigned long)(memory_resource->start));
- drv_data->ssdr_physical = memory_resource->start + 0x00000010;
- if (platform_info->ssp_type == PXA25x_SSP) {
+ drv_data->ioaddr = ssp->mmio_base;
+ drv_data->ssdr_physical = ssp->phys_base + SSDR;
+ if (ssp->type == PXA25x_SSP) {
drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
drv_data->dma_cr1 = 0;
drv_data->clear_sr = SSSR_ROR;
@@ -1377,15 +1373,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR;
}
- /* Attach to IRQ */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "irq resource not defined\n");
- status = -ENODEV;
- goto out_error_master_alloc;
- }
-
- status = request_irq(irq, ssp_int, 0, dev->bus_id, drv_data);
+ status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
if (status < 0) {
dev_err(&pdev->dev, "can not get IRQ\n");
goto out_error_master_alloc;
@@ -1418,29 +1406,12 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
goto out_error_dma_alloc;
}
- if (drv_data->ioaddr == SSP1_VIRT) {
- DRCMRRXSSDR = DRCMR_MAPVLD
- | drv_data->rx_channel;
- DRCMRTXSSDR = DRCMR_MAPVLD
- | drv_data->tx_channel;
- } else if (drv_data->ioaddr == SSP2_VIRT) {
- DRCMRRXSS2DR = DRCMR_MAPVLD
- | drv_data->rx_channel;
- DRCMRTXSS2DR = DRCMR_MAPVLD
- | drv_data->tx_channel;
- } else if (drv_data->ioaddr == SSP3_VIRT) {
- DRCMRRXSS3DR = DRCMR_MAPVLD
- | drv_data->rx_channel;
- DRCMRTXSS3DR = DRCMR_MAPVLD
- | drv_data->tx_channel;
- } else {
- dev_err(dev, "bad SSP type\n");
- goto out_error_dma_alloc;
- }
+ DRCMR(ssp->drcmr_rx) = DRCMR_MAPVLD | drv_data->rx_channel;
+ DRCMR(ssp->drcmr_tx) = DRCMR_MAPVLD | drv_data->tx_channel;
}
/* Enable SOC clock */
- pxa_set_cken(platform_info->clock_enable, 1);
+ clk_enable(ssp->clk);
/* Load default SSP configuration */
write_SSCR0(0, drv_data->ioaddr);
@@ -1479,7 +1450,7 @@ out_error_queue_alloc:
destroy_queue(drv_data);
out_error_clock_enabled:
- pxa_set_cken(platform_info->clock_enable, 0);
+ clk_disable(ssp->clk);
out_error_dma_alloc:
if (drv_data->tx_channel != -1)
@@ -1488,17 +1459,18 @@ out_error_dma_alloc:
pxa_free_dma(drv_data->rx_channel);
out_error_irq_alloc:
- free_irq(irq, drv_data);
+ free_irq(ssp->irq, drv_data);
out_error_master_alloc:
spi_master_put(master);
+ ssp_free(ssp);
return status;
}
static int pxa2xx_spi_remove(struct platform_device *pdev)
{
struct driver_data *drv_data = platform_get_drvdata(pdev);
- int irq;
+ struct ssp_device *ssp = drv_data->ssp;
int status = 0;
if (!drv_data)
@@ -1520,28 +1492,21 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)
/* Disable the SSP at the peripheral and SOC level */
write_SSCR0(0, drv_data->ioaddr);
- pxa_set_cken(drv_data->master_info->clock_enable, 0);
+ clk_disable(ssp->clk);
/* Release DMA */
if (drv_data->master_info->enable_dma) {
- if (drv_data->ioaddr == SSP1_VIRT) {
- DRCMRRXSSDR = 0;
- DRCMRTXSSDR = 0;
- } else if (drv_data->ioaddr == SSP2_VIRT) {
- DRCMRRXSS2DR = 0;
- DRCMRTXSS2DR = 0;
- } else if (drv_data->ioaddr == SSP3_VIRT) {
- DRCMRRXSS3DR = 0;
- DRCMRTXSS3DR = 0;
- }
+ DRCMR(ssp->drcmr_rx) = 0;
+ DRCMR(ssp->drcmr_tx) = 0;
pxa_free_dma(drv_data->tx_channel);
pxa_free_dma(drv_data->rx_channel);
}
/* Release IRQ */
- irq = platform_get_irq(pdev, 0);
- if (irq >= 0)
- free_irq(irq, drv_data);
+ free_irq(ssp->irq, drv_data);
+
+ /* Release SSP */
+ ssp_free(ssp);
/* Disconnect from the SPI framework */
spi_unregister_master(drv_data->master);
@@ -1576,6 +1541,7 @@ static int suspend_devices(struct device *dev, void *pm_message)
static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
{
struct driver_data *drv_data = platform_get_drvdata(pdev);
+ struct ssp_device *ssp = drv_data->ssp;
int status = 0;
/* Check all childern for current power state */
@@ -1588,7 +1554,7 @@ static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
if (status != 0)
return status;
write_SSCR0(0, drv_data->ioaddr);
- pxa_set_cken(drv_data->master_info->clock_enable, 0);
+ clk_disable(ssp->clk);
return 0;
}
@@ -1596,10 +1562,11 @@ static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
static int pxa2xx_spi_resume(struct platform_device *pdev)
{
struct driver_data *drv_data = platform_get_drvdata(pdev);
+ struct ssp_device *ssp = drv_data->ssp;
int status = 0;
/* Enable the SSP clock */
- pxa_set_cken(drv_data->master_info->clock_enable, 1);
+ clk_disable(ssp->clk);
/* Start the queue running */
status = start_queue(drv_data);
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 7580aa5da0f8..7a6499008b89 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -33,6 +33,7 @@ config USB_ARCH_HAS_OHCI
default y if ARCH_LH7A404
default y if ARCH_S3C2410
default y if PXA27x
+ default y if PXA3xx
default y if ARCH_EP93XX
default y if ARCH_AT91
default y if ARCH_PNX4008
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index f81d08d6538b..77a3759d6fc7 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -308,7 +308,7 @@ config USB_S3C2410_DEBUG
config USB_GADGET_AT91
boolean "AT91 USB Device Port"
- depends on ARCH_AT91 && !ARCH_AT91SAM9RL
+ depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
select USB_GADGET_SELECTED
help
Many Atmel AT91 processors (such as the AT91RM2000) have a
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index ecfe800fd720..ddd4ee1f2413 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -997,7 +997,7 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_lh7a404_driver
#endif
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#include "ohci-pxa27x.c"
#define PLATFORM_DRIVER ohci_hcd_pxa27x_driver
#endif
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 23d2fe5a62f4..ff9a79843471 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/signal.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
@@ -32,6 +33,8 @@
#define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 )
+static struct clk *usb_clk;
+
/*
PMM_NPS_MODE -- PMM Non-power switching mode
Ports are powered continuously.
@@ -80,7 +83,7 @@ static int pxa27x_start_hc(struct device *dev)
inf = dev->platform_data;
- pxa_set_cken(CKEN_USBHOST, 1);
+ clk_enable(usb_clk);
UHCHR |= UHCHR_FHR;
udelay(11);
@@ -123,7 +126,7 @@ static void pxa27x_stop_hc(struct device *dev)
UHCCOMS |= 1;
udelay(10);
- pxa_set_cken(CKEN_USBHOST, 0);
+ clk_disable(usb_clk);
}
@@ -158,6 +161,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
return -ENOMEM;
}
+ usb_clk = clk_get(&pdev->dev, "USBCLK");
+ if (IS_ERR(usb_clk))
+ return PTR_ERR(usb_clk);
+
hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
if (!hcd)
return -ENOMEM;
@@ -201,6 +208,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
usb_put_hcd(hcd);
+ clk_put(usb_clk);
return retval;
}
@@ -225,6 +233,7 @@ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
+ clk_put(usb_clk);
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5b3dbcfcda48..758435f8a6f8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -889,7 +889,7 @@ config FB_S1D13XXX
config FB_ATMEL
tristate "AT91/AT32 LCD Controller support"
- depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || AVR32)
+ depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 7c30cc8df71e..f8e711147501 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -30,7 +30,7 @@
#define ATMEL_LCDC_CVAL_DEFAULT 0xc8
#define ATMEL_LCDC_DMA_BURST_LEN 8
-#if defined(CONFIG_ARCH_AT91SAM9263)
+#if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9)
#define ATMEL_LCDC_FIFO_SIZE 2048
#else
#define ATMEL_LCDC_FIFO_SIZE 512
OpenPOWER on IntegriCloud