diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/pata_mpc52xx.c | 1 | ||||
-rw-r--r-- | drivers/base/memory.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_bus.c | 15 | ||||
-rw-r--r-- | drivers/mtd/mtdconcat.c | 1 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 29 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 28 | ||||
-rw-r--r-- | drivers/mtd/ubi/debug.c | 37 | ||||
-rw-r--r-- | drivers/mtd/ubi/debug.h | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 131 | ||||
-rw-r--r-- | drivers/mtd/ubi/io.c | 75 | ||||
-rw-r--r-- | drivers/mtd/ubi/kapi.c | 9 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.c | 45 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.h | 8 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 42 | ||||
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 70 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 8 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 136 | ||||
-rw-r--r-- | drivers/net/ibm_newemac/rgmii.c | 2 | ||||
-rw-r--r-- | drivers/serial/mpc52xx_uart.c | 8 | ||||
-rw-r--r-- | drivers/ssb/main.c | 10 | ||||
-rw-r--r-- | drivers/ssb/pcmcia.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-ssb.c | 2 | ||||
-rw-r--r-- | drivers/video/cg6.c | 294 | ||||
-rw-r--r-- | drivers/video/ffb.c | 161 | ||||
-rw-r--r-- | drivers/video/xilinxfb.c | 2 |
25 files changed, 555 insertions, 564 deletions
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 412140f0285..50c56e2814c 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -308,7 +308,6 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv, struct ata_host *host; struct ata_port *ap; struct ata_ioports *aio; - int rc; host = ata_host_alloc(dev, 1); if (!host) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index cb99daeae93..7a1390cd6aa 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -34,7 +34,7 @@ static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj) return MEMORY_CLASS_NAME; } -static int memory_uevent(struct kset *kset, struct kobj_uevent_env *env) +static int memory_uevent(struct kset *kset, struct kobject *obj, struct kobj_uevent_env *env) { int retval = 0; diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 0713a8c71e5..233d0f9b3c4 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -96,30 +96,23 @@ static int sdio_bus_match(struct device *dev, struct device_driver *drv) } static int -sdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, - int buf_size) +sdio_bus_uevent(struct device *dev, struct kobj_uevent_env *env) { struct sdio_func *func = dev_to_sdio_func(dev); - int i = 0, length = 0; - if (add_uevent_var(envp, num_envp, &i, - buf, buf_size, &length, + if (add_uevent_var(env, "SDIO_CLASS=%02X", func->class)) return -ENOMEM; - if (add_uevent_var(envp, num_envp, &i, - buf, buf_size, &length, + if (add_uevent_var(env, "SDIO_ID=%04X:%04X", func->vendor, func->device)) return -ENOMEM; - if (add_uevent_var(envp, num_envp, &i, - buf, buf_size, &length, + if (add_uevent_var(env, "MODALIAS=sdio:c%02Xv%04Xd%04X", func->class, func->vendor, func->device)) return -ENOMEM; - envp[i] = NULL; - return 0; } diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 96be7ef62f3..d563dcd4b26 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -726,6 +726,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.size = subdev[0]->size; concat->mtd.erasesize = subdev[0]->erasesize; concat->mtd.writesize = subdev[0]->writesize; + concat->mtd.subpage_sft = subdev[0]->subpage_sft; concat->mtd.oobsize = subdev[0]->oobsize; concat->mtd.oobavail = subdev[0]->oobavail; if (subdev[0]->writev) diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index b2c40f67db8..dd283556909 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -327,7 +327,7 @@ static int onenand_wait(struct mtd_info *mtd, int state) printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl); if (ctrl & ONENAND_CTRL_LOCK) printk(KERN_ERR "onenand_wait: it's locked error.\n"); - return ctrl; + return -EIO; } if (interrupt & ONENAND_INT_READ) { @@ -336,7 +336,7 @@ static int onenand_wait(struct mtd_info *mtd, int state) if (ecc & ONENAND_ECC_2BIT_ALL) { printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc); mtd->ecc_stats.failed++; - return ecc; + return -EBADMSG; } else if (ecc & ONENAND_ECC_1BIT_ALL) { printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc); mtd->ecc_stats.corrected++; @@ -1711,13 +1711,14 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) erase_exit: ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; - /* Do call back function */ - if (!ret) - mtd_erase_callback(instr); /* Deselect and wake up anyone waiting on the device */ onenand_release_device(mtd); + /* Do call back function */ + if (!ret) + mtd_erase_callback(instr); + return ret; } @@ -1904,7 +1905,12 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int */ static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len) { - return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK); + int ret; + + onenand_get_device(mtd, FL_LOCKING); + ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK); + onenand_release_device(mtd); + return ret; } /** @@ -1917,7 +1923,12 @@ static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len) */ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) { - return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); + int ret; + + onenand_get_device(mtd, FL_LOCKING); + ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); + onenand_release_device(mtd); + return ret; } /** @@ -1979,7 +1990,7 @@ static int onenand_unlock_all(struct mtd_info *mtd) loff_t ofs = this->chipsize >> 1; size_t len = mtd->erasesize; - onenand_unlock(mtd, ofs, len); + onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); } onenand_check_lock_status(this); @@ -1987,7 +1998,7 @@ static int onenand_unlock_all(struct mtd_info *mtd) return 0; } - onenand_unlock(mtd, 0x0, this->chipsize); + onenand_do_lock_cmd(mtd, 0x0, this->chipsize, ONENAND_CMD_UNLOCK); return 0; } diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 1cb22bfae75..023653977a1 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -565,7 +565,7 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, } ubi = ubi_devices[ubi_devices_cnt] = kzalloc(sizeof(struct ubi_device), - GFP_KERNEL); + GFP_KERNEL); if (!ubi) { err = -ENOMEM; goto out_mtd; @@ -583,6 +583,22 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, if (err) goto out_free; + mutex_init(&ubi->buf_mutex); + ubi->peb_buf1 = vmalloc(ubi->peb_size); + if (!ubi->peb_buf1) + goto out_free; + + ubi->peb_buf2 = vmalloc(ubi->peb_size); + if (!ubi->peb_buf2) + goto out_free; + +#ifdef CONFIG_MTD_UBI_DEBUG + mutex_init(&ubi->dbg_buf_mutex); + ubi->dbg_peb_buf = vmalloc(ubi->peb_size); + if (!ubi->dbg_peb_buf) + goto out_free; +#endif + err = attach_by_scanning(ubi); if (err) { dbg_err("failed to attach by scanning, error %d", err); @@ -630,6 +646,11 @@ out_detach: ubi_wl_close(ubi); vfree(ubi->vtbl); out_free: + vfree(ubi->peb_buf1); + vfree(ubi->peb_buf2); +#ifdef CONFIG_MTD_UBI_DEBUG + vfree(ubi->dbg_peb_buf); +#endif kfree(ubi); out_mtd: put_mtd_device(mtd); @@ -651,6 +672,11 @@ static void detach_mtd_dev(struct ubi_device *ubi) ubi_wl_close(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); + vfree(ubi->peb_buf1); + vfree(ubi->peb_buf2); +#ifdef CONFIG_MTD_UBI_DEBUG + vfree(ubi->dbg_peb_buf); +#endif kfree(ubi_devices[ubi_num]); ubi_devices[ubi_num] = NULL; ubi_devices_cnt -= 1; diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 310341e5cd4..56956ec2845 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -42,7 +42,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset)); dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc)); dbg_msg("erase counter header hexdump:"); - ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + ec_hdr, UBI_EC_HDR_SIZE, 1); } /** @@ -187,38 +188,4 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) dbg_msg("the 1st 16 characters of the name: %s", nm); } -#define BYTES_PER_LINE 32 - -/** - * ubi_dbg_hexdump - dump a buffer. - * @ptr: the buffer to dump - * @size: buffer size which must be multiple of 4 bytes - */ -void ubi_dbg_hexdump(const void *ptr, int size) -{ - int i, k = 0, rows, columns; - const uint8_t *p = ptr; - - size = ALIGN(size, 4); - rows = size/BYTES_PER_LINE + size % BYTES_PER_LINE; - for (i = 0; i < rows; i++) { - int j; - - cond_resched(); - columns = min(size - k, BYTES_PER_LINE) / 4; - if (columns == 0) - break; - printk(KERN_DEBUG "%5d: ", i * BYTES_PER_LINE); - for (j = 0; j < columns; j++) { - int n, N; - - N = size - k > 4 ? 4 : size - k; - for (n = 0; n < N; n++) - printk("%02x", p[k++]); - printk(" "); - } - printk("\n"); - } -} - #endif /* CONFIG_MTD_UBI_DEBUG_MSG */ diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index ff8f39548cd..467722eb618 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -59,7 +59,6 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); -void ubi_dbg_hexdump(const void *buf, int size); #else @@ -72,7 +71,6 @@ void ubi_dbg_hexdump(const void *buf, int size); #define ubi_dbg_dump_sv(sv) ({}) #define ubi_dbg_dump_seb(seb, type) ({}) #define ubi_dbg_dump_mkvol_req(req) ({}) -#define ubi_dbg_hexdump(buf, size) ({}) #endif /* CONFIG_MTD_UBI_DEBUG_MSG */ diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 7c5e29eaf11..1297732f4db 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -46,6 +46,9 @@ #include <linux/err.h> #include "ubi.h" +/* Number of physical eraseblocks reserved for atomic LEB change operation */ +#define EBA_RESERVED_PEBS 1 + /** * struct ltree_entry - an entry in the lock tree. * @rb: links RB-tree nodes @@ -157,7 +160,7 @@ static struct ltree_entry *ltree_add_entry(struct ubi_device *ubi, int vol_id, { struct ltree_entry *le, *le1, *le_free; - le = kmem_cache_alloc(ltree_slab, GFP_KERNEL); + le = kmem_cache_alloc(ltree_slab, GFP_NOFS); if (!le) return ERR_PTR(-ENOMEM); @@ -397,7 +400,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf, retry: if (check) { - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { err = -ENOMEM; goto out_unlock; @@ -495,16 +498,18 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; struct ubi_volume *vol = ubi->volumes[idx]; struct ubi_vid_hdr *vid_hdr; - unsigned char *new_buf; - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { return -ENOMEM; } + mutex_lock(&ubi->buf_mutex); + retry: new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); if (new_pnum < 0) { + mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return new_pnum; } @@ -524,31 +529,22 @@ retry: goto write_error; data_size = offset + len; - new_buf = vmalloc(data_size); - if (!new_buf) { - err = -ENOMEM; - goto out_put; - } - memset(new_buf + offset, 0xFF, len); + memset(ubi->peb_buf1 + offset, 0xFF, len); /* Read everything before the area where the write failure happened */ if (offset > 0) { - err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset); - if (err && err != UBI_IO_BITFLIPS) { - vfree(new_buf); + err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); + if (err && err != UBI_IO_BITFLIPS) goto out_put; - } } - memcpy(new_buf + offset, buf, len); + memcpy(ubi->peb_buf1 + offset, buf, len); - err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size); - if (err) { - vfree(new_buf); + err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); + if (err) goto write_error; - } - vfree(new_buf); + mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); vol->eba_tbl[lnum] = new_pnum; @@ -558,6 +554,7 @@ retry: return 0; out_put: + mutex_unlock(&ubi->buf_mutex); ubi_wl_put_peb(ubi, new_pnum, 1); ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -570,6 +567,7 @@ write_error: ubi_warn("failed to write to PEB %d", new_pnum); ubi_wl_put_peb(ubi, new_pnum, 1); if (++tries > UBI_IO_RETRIES) { + mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return err; } @@ -627,7 +625,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum, * The logical eraseblock is not mapped. We have to get a free physical * eraseblock and write the volume identifier header there first. */ - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { leb_write_unlock(ubi, vol_id, lnum); return -ENOMEM; @@ -738,7 +736,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, else ubi_assert(len % ubi->min_io_size == 0); - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; @@ -832,6 +830,9 @@ write_error: * data, which has to be aligned. This function guarantees that in case of an * unclean reboot the old contents is preserved. Returns zero in case of * success and a negative error code in case of failure. + * + * UBI reserves one LEB for the "atomic LEB change" operation, so only one + * LEB change may be done at a time. This is ensured by @ubi->alc_mutex. */ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, const void *buf, int len, int dtype) @@ -844,15 +845,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, if (ubi->ro_mode) return -EROFS; - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; + mutex_lock(&ubi->alc_mutex); err = leb_write_lock(ubi, vol_id, lnum); - if (err) { - ubi_free_vid_hdr(ubi, vid_hdr); - return err; - } + if (err) + goto out_mutex; vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); vid_hdr->vol_id = cpu_to_be32(vol_id); @@ -869,9 +869,8 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, retry: pnum = ubi_wl_get_peb(ubi, dtype); if (pnum < 0) { - ubi_free_vid_hdr(ubi, vid_hdr); - leb_write_unlock(ubi, vol_id, lnum); - return pnum; + err = pnum; + goto out_leb_unlock; } dbg_eba("change LEB %d:%d, PEB %d, write VID hdr to PEB %d", @@ -893,17 +892,18 @@ retry: if (vol->eba_tbl[lnum] >= 0) { err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1); - if (err) { - ubi_free_vid_hdr(ubi, vid_hdr); - leb_write_unlock(ubi, vol_id, lnum); - return err; - } + if (err) + goto out_leb_unlock; } vol->eba_tbl[lnum] = pnum; + +out_leb_unlock: leb_write_unlock(ubi, vol_id, lnum); +out_mutex: + mutex_unlock(&ubi->alc_mutex); ubi_free_vid_hdr(ubi, vid_hdr); - return 0; + return err; write_error: if (err != -EIO || !ubi->bad_allowed) { @@ -913,17 +913,13 @@ write_error: * mode just in case. */ ubi_ro_mode(ubi); - leb_write_unlock(ubi, vol_id, lnum); - ubi_free_vid_hdr(ubi, vid_hdr); - return err; + goto out_leb_unlock; } err = ubi_wl_put_peb(ubi, pnum, 1); if (err || ++tries > UBI_IO_RETRIES) { ubi_ro_mode(ubi); - leb_write_unlock(ubi, vol_id, lnum); - ubi_free_vid_hdr(ubi, vid_hdr); - return err; + goto out_leb_unlock; } vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); @@ -965,7 +961,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, int err, vol_id, lnum, data_size, aldata_size, pnum, idx; struct ubi_volume *vol; uint32_t crc; - void *buf, *buf1 = NULL; vol_id = be32_to_cpu(vid_hdr->vol_id); lnum = be32_to_cpu(vid_hdr->lnum); @@ -979,19 +974,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, data_size = aldata_size = ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); - buf = vmalloc(aldata_size); - if (!buf) - return -ENOMEM; - /* * We do not want anybody to write to this logical eraseblock while we * are moving it, so we lock it. */ err = leb_write_lock(ubi, vol_id, lnum); - if (err) { - vfree(buf); + if (err) return err; - } + + mutex_lock(&ubi->buf_mutex); /* * But the logical eraseblock might have been put by this time. @@ -1023,7 +1014,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, /* OK, now the LEB is locked and we can safely start moving it */ dbg_eba("read %d bytes of data", aldata_size); - err = ubi_io_read_data(ubi, buf, from, 0, aldata_size); + err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size); if (err && err != UBI_IO_BITFLIPS) { ubi_warn("error %d while reading data from PEB %d", err, from); @@ -1042,10 +1033,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, */ if (vid_hdr->vol_type == UBI_VID_DYNAMIC) aldata_size = data_size = - ubi_calc_data_len(ubi, buf, data_size); + ubi_calc_data_len(ubi, ubi->peb_buf1, data_size); cond_resched(); - crc = crc32(UBI_CRC32_INIT, buf, data_size); + crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size); cond_resched(); /* @@ -1076,23 +1067,18 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } if (data_size > 0) { - err = ubi_io_write_data(ubi, buf, to, 0, aldata_size); + err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); if (err) goto out_unlock; + cond_resched(); + /* * We've written the data and are going to read it back to make * sure it was written correctly. */ - buf1 = vmalloc(aldata_size); - if (!buf1) { - err = -ENOMEM; - goto out_unlock; - } - - cond_resched(); - err = ubi_io_read_data(ubi, buf1, to, 0, aldata_size); + err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) ubi_warn("cannot read data back from PEB %d", @@ -1102,7 +1088,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); - if (memcmp(buf, buf1, aldata_size)) { + if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { ubi_warn("read data back from PEB %d - it is different", to); goto out_unlock; @@ -1112,16 +1098,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ubi_assert(vol->eba_tbl[lnum] == from); vol->eba_tbl[lnum] = to; - leb_write_unlock(ubi, vol_id, lnum); - vfree(buf); - vfree(buf1); - - return 0; - out_unlock: + mutex_unlock(&ubi->buf_mutex); leb_write_unlock(ubi, vol_id, lnum); - vfree(buf); - vfree(buf1); return err; } @@ -1144,6 +1123,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) dbg_eba("initialize EBA unit"); spin_lock_init(&ubi->ltree_lock); + mutex_init(&ubi->alc_mutex); ubi->ltree = RB_ROOT; if (ubi_devices_cnt == 0) { @@ -1205,6 +1185,15 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) ubi->rsvd_pebs += ubi->beb_rsvd_pebs; } + if (ubi->avail_pebs < EBA_RESERVED_PEBS) { + ubi_err("no enough physical eraseblocks (%d, need %d)", + ubi->avail_pebs, EBA_RESERVED_PEBS); + err = -ENOSPC; + goto out_free; + } + ubi->avail_pebs -= EBA_RESERVED_PEBS; + ubi->rsvd_pebs += EBA_RESERVED_PEBS; + dbg_eba("EBA unit is initialized"); return 0; diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index b0d8f4cede9..7c304eec78b 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -98,8 +98,8 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, const struct ubi_vid_hdr *vid_hdr); -static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, - int offset, int len); +static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, + int len); #else #define paranoid_check_not_bad(ubi, pnum) 0 #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 @@ -202,8 +202,8 @@ retry: * Note, in case of an error, it is possible that something was still written * to the flash media, but may be some garbage. */ -int ubi_io_write(const struct ubi_device *ubi, const void *buf, int pnum, - int offset, int len) +int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, + int len) { int err; size_t written; @@ -285,7 +285,7 @@ static void erase_callback(struct erase_info *ei) * zero in case of success and a negative error code in case of failure. If * %-EIO is returned, the physical eraseblock most probably went bad. */ -static int do_sync_erase(const struct ubi_device *ubi, int pnum) +static int do_sync_erase(struct ubi_device *ubi, int pnum) { int err, retries = 0; struct erase_info ei; @@ -377,29 +377,25 @@ static uint8_t patterns[] = {0xa5, 0x5a, 0x0}; * test, a positive number of erase operations done if the test was * successfully passed, and other negative error codes in case of other errors. */ -static int torture_peb(const struct ubi_device *ubi, int pnum) +static int torture_peb(struct ubi_device *ubi, int pnum) { - void *buf; int err, i, patt_count; - buf = vmalloc(ubi->peb_size); - if (!buf) - return -ENOMEM; - patt_count = ARRAY_SIZE(patterns); ubi_assert(patt_count > 0); + mutex_lock(&ubi->buf_mutex); for (i = 0; i < patt_count; i++) { err = do_sync_erase(ubi, pnum); if (err) goto out; /* Make sure the PEB contains only 0xFF bytes */ - err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); + err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; - err = check_pattern(buf, 0xFF, ubi->peb_size); + err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); if (err == 0) { ubi_err("erased PEB %d, but a non-0xFF byte found", pnum); @@ -408,17 +404,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) } /* Write a pattern and check it */ - memset(buf, patterns[i], ubi->peb_size); - err = ubi_io_write(ubi, buf, pnum, 0, ubi->peb_size); + memset(ubi->peb_buf1, patterns[i], ubi->peb_size); + err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; - memset(buf, ~patterns[i], ubi->peb_size); - err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); + memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); + err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; - err = check_pattern(buf, patterns[i], ubi->peb_size); + err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size); if (err == 0) { ubi_err("pattern %x checking failed for PEB %d", patterns[i], pnum); @@ -430,14 +426,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) err = patt_count; out: - if (err == UBI_IO_BITFLIPS || err == -EBADMSG) + mutex_unlock(&ubi->buf_mutex); + if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { /* * If a bit-flip or data integrity error was detected, the test * has not passed because it happened on a freshly erased * physical eraseblock which means something is wrong with it. */ + ubi_err("read problems on freshly erased PEB %d, must be bad", + pnum); err = -EIO; - vfree(buf); + } return err; } @@ -457,7 +456,7 @@ out: * codes in case of other errors. Note, %-EIO means that the physical * eraseblock is bad. */ -int ubi_io_sync_erase(const struct ubi_device *ubi, int pnum, int torture) +int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) { int err, ret = 0; @@ -614,7 +613,7 @@ bad: * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty; * o a negative error code in case of failure. */ -int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr, int verbose) { int err, read_err = 0; @@ -720,7 +719,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, * case of failure. If %-EIO is returned, the physical eraseblock most probably * went bad. */ -int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr) { int err; @@ -886,7 +885,7 @@ bad: * header there); * o a negative error code in case of failure. */ -int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr, int verbose) { int err, read_err = 0; @@ -993,7 +992,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, * case of failure. If %-EIO is returned, the physical eraseblock probably went * bad. */ -int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr) { int err; @@ -1096,7 +1095,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) uint32_t crc, hdr_crc; struct ubi_ec_hdr *ec_hdr; - ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); if (!ec_hdr) return -ENOMEM; @@ -1176,7 +1175,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) struct ubi_vid_hdr *vid_hdr; void *p; - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; @@ -1216,44 +1215,40 @@ exit: * @offset of the physical eraseblock @pnum, %1 if not, and a negative error * code if an error occurred. */ -static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, - int offset, int len) +static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, + int len) { size_t read; int err; - void *buf; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; - buf = vmalloc(len); - if (!buf) - return -ENOMEM; - memset(buf, 0, len); - - err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); + mutex_lock(&ubi->dbg_buf_mutex); + err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); if (err && err != -EUCLEAN) { ubi_err("error %d while reading %d bytes from PEB %d:%d, " "read %zd bytes", err, len, pnum, offset, read); goto error; } - err = check_pattern(buf, 0xFF, len); + err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); if (err == 0) { ubi_err("flash region at PEB %d:%d, length %d does not " "contain all 0xFF bytes", pnum, offset, len); goto fail; } + mutex_unlock(&ubi->dbg_buf_mutex); - vfree(buf); return 0; fail: ubi_err("paranoid check failed for PEB %d", pnum); dbg_msg("hex dump of the %d-%d region", offset, offset + len); - ubi_dbg_hexdump(buf, len); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + ubi->dbg_peb_buf, len, 1); err = 1; error: ubi_dbg_dump_stack(); - vfree(buf); + mutex_unlock(&ubi->dbg_buf_mutex); return err; } diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 4a458e83e4e..03c774f4154 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -99,16 +99,21 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) { int err; struct ubi_volume_desc *desc; - struct ubi_device *ubi = ubi_devices[ubi_num]; + struct ubi_device *ubi; struct ubi_volume *vol; dbg_msg("open device %d volume %d, mode %d", ubi_num, vol_id, mode); err = -ENODEV; + if (ubi_num < 0) + return ERR_PTR(err); + + ubi = ubi_devices[ubi_num]; + if (!try_module_get(THIS_MODULE)) return ERR_PTR(err); - if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES || !ubi) + if (ubi_num >= UBI_MAX_DEVICES || !ubi) goto out_put; err = -EINVAL; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 29c41eeb09f..c7b0afc9d28 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -45,8 +45,7 @@ #include "ubi.h" #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID -static int paranoid_check_si(const struct ubi_device *ubi, - struct ubi_scan_info *si); +static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); #else #define paranoid_check_si(ubi, si) 0 #endif @@ -259,14 +258,13 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, * o bit 2 is cleared: the older LEB is not corrupted; * o bit 2 is set: the older LEB is corrupted. */ -static int compare_lebs(const struct ubi_device *ubi, - const struct ubi_scan_leb *seb, int pnum, - const struct ubi_vid_hdr *vid_hdr) +static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, + int pnum, const struct ubi_vid_hdr *vid_hdr) { void *buf; int len, err, second_is_newer, bitflips = 0, corrupted = 0; uint32_t data_crc, crc; - struct ubi_vid_hdr *vidh = NULL; + struct ubi_vid_hdr *vh = NULL; unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); if (seb->sqnum == 0 && sqnum2 == 0) { @@ -323,11 +321,11 @@ static int compare_lebs(const struct ubi_device *ubi, } else { pnum = seb->pnum; - vidh = ubi_zalloc_vid_hdr(ubi); - if (!vidh) + vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vh) return -ENOMEM; - err = ubi_io_read_vid_hdr(ubi, pnum, vidh, 0); + err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (err) { if (err == UBI_IO_BITFLIPS) bitflips = 1; @@ -341,7 +339,7 @@ static int compare_lebs(const struct ubi_device *ubi, } } - if (!vidh->copy_flag) { + if (!vh->copy_flag) { /* It is not a copy, so it is newer */ dbg_bld("first PEB %d is newer, copy_flag is unset", pnum); @@ -349,7 +347,7 @@ static int compare_lebs(const struct ubi_device *ubi, goto out_free_vidh; } - vid_hdr = vidh; + vid_hdr = vh; } /* Read the data of the copy and check the CRC */ @@ -379,7 +377,7 @@ static int compare_lebs(const struct ubi_device *ubi, } vfree(buf); - ubi_free_vid_hdr(ubi, vidh); + ubi_free_vid_hdr(ubi, vh); if (second_is_newer) dbg_bld("second PEB %d is newer, copy_flag is set", pnum); @@ -391,7 +389,7 @@ static int compare_lebs(const struct ubi_device *ubi, out_free_buf: vfree(buf); out_free_vidh: - ubi_free_vid_hdr(ubi, vidh); + ubi_free_vid_hdr(ubi, vh); ubi_assert(err < 0); return err; } @@ -413,7 +411,7 @@ out_free_vidh: * to be picked, while the older one has to be dropped. This function returns * zero in case of success and a negative error code in case of failure. */ -int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) { @@ -667,16 +665,12 @@ void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv) * function returns zero in case of success and a negative error code in case * of failure. */ -int ubi_scan_erase_peb(const struct ubi_device *ubi, - const struct ubi_scan_info *si, int pnum, int ec) +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, + int pnum, int ec) { int err; struct ubi_ec_hdr *ec_hdr; - ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); - if (!ec_hdr) - return -ENOMEM; - if ((long long)ec >= UBI_MAX_ERASECOUNTER) { /* * Erase counter overflow. Upgrade UBI and use 64-bit @@ -686,6 +680,10 @@ int ubi_scan_erase_peb(const struct ubi_device *ubi, return -EINVAL; } + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ec_hdr) + return -ENOMEM; + ec_hdr->ec = cpu_to_be64(ec); err = ubi_io_sync_erase(ubi, pnum, 0); @@ -712,7 +710,7 @@ out_free: * This function returns scanning physical eraseblock information in case of * success and an error code in case of failure. */ -struct ubi_scan_leb *ubi_scan_get_free_peb(const struct ubi_device *ubi, +struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_scan_info *si) { int err = 0, i; @@ -948,7 +946,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) if (!ech) goto out_si; - vidh = ubi_zalloc_vid_hdr(ubi); + vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vidh) goto out_ech; @@ -1110,8 +1108,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) * This function returns zero if the scanning information is all right, %1 if * not and a negative error code if an error occurred. */ -static int paranoid_check_si(const struct ubi_device *ubi, - struct ubi_scan_info *si) +static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) { int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 140e82e2653..46d444af471 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -147,7 +147,7 @@ static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv, list_add_tail(&seb->u.list, list); } -int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, @@ -155,10 +155,10 @@ struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, int lnum); void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv); -struct ubi_scan_leb *ubi_scan_get_free_peb(const struct ubi_device *ubi, +struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_scan_info *si); -int ubi_scan_erase_peb(const struct ubi_device *ubi, - const struct ubi_scan_info *si, int pnum, int ec); +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, + int pnum, int ec); struct ubi_scan_info *ubi_scan(struct ubi_device *ubi); void ubi_scan_destroy_si(struct ubi_scan_info *si); diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 5959f91be24..5e941a63303 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -221,14 +221,15 @@ struct ubi_wl_entry; * @vtbl_slots: how many slots are available in the volume table * @vtbl_size: size of the volume table in bytes * @vtbl: in-RAM volume table copy + * @vtbl_mutex: protects on-flash volume table * * @max_ec: current highest erase counter value * @mean_ec: current mean erase counter value * - * global_sqnum: global sequence number + * @global_sqnum: global sequence number * @ltree_lock: protects the lock tree and @global_sqnum * @ltree: the lock tree - * @vtbl_mutex: protects on-flash volume table + * @alc_mutex: serializes "atomic LEB change" operations * * @used: RB-tree of used physical eraseblocks * @free: RB-tree of free physical eraseblocks @@ -274,6 +275,12 @@ struct ubi_wl_entry; * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or * not * @mtd: MTD device descriptor + * + * @peb_buf1: a buffer of PEB size used for different purposes + * @peb_buf2: another buffer of PEB size used for different purposes + * @buf_mutex: proptects @peb_buf1 and @peb_buf2 + * @dbg_peb_buf: buffer of PEB size used for debugging + * @dbg_buf_mutex: proptects @dbg_peb_buf */ struct ubi_device { struct cdev cdev; @@ -302,6 +309,7 @@ struct ubi_device { unsigned long long global_sqnum; spinlock_t ltree_lock; struct rb_root ltree; + struct mutex alc_mutex; /* Wear-leveling unit's stuff */ struct rb_root used; @@ -343,6 +351,14 @@ struct ubi_device { int vid_hdr_shift; int bad_allowed; struct mtd_info *mtd; + + void *peb_buf1; + void *peb_buf2; + struct mutex buf_mutex; +#ifdef CONFIG_MTD_UBI_DEBUG + void *dbg_peb_buf; + struct mutex dbg_buf_mutex; +#endif }; extern struct file_operations ubi_cdev_operations; @@ -409,18 +425,18 @@ void ubi_wl_close(struct ubi_device *ubi); /* io.c */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, int len); -int ubi_io_write(const struct ubi_device *ubi, const void *buf, int pnum, - int offset, int len); -int ubi_io_sync_erase(const struct ubi_device *ubi, int pnum, int torture); +int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, + int len); +int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture); int ubi_io_is_bad(const struct ubi_device *ubi, int pnum); int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum); -int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr, int verbose); -int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr); -int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr, int verbose); -int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, +int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr); /* @@ -439,16 +455,18 @@ int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, /** * ubi_zalloc_vid_hdr - allocate a volume identifier header object. * @ubi: UBI device description object + * @gfp_flags: GFP flags to allocate with * * This function returns a pointer to the newly allocated and zero-filled * volume identifier header object in case of success and %NULL in case of * failure. */ -static inline struct ubi_vid_hdr *ubi_zalloc_vid_hdr(const struct ubi_device *ubi) +static inline struct ubi_vid_hdr * +ubi_zalloc_vid_hdr(const struct ubi_device *ubi, gfp_t gfp_flags) { void *vid_hdr; - vid_hdr = kzalloc(ubi->vid_hdr_alsize, GFP_KERNEL); + vid_hdr = kzalloc(ubi->vid_hdr_alsize, gfp_flags); if (!vid_hdr) return NULL; @@ -492,7 +510,7 @@ static inline int ubi_io_read_data(const struct ubi_device *ubi, void *buf, * the beginning of the logical eraseblock, not to the beginning of the * physical eraseblock. */ -static inline int ubi_io_write_data(const struct ubi_device *ubi, const void *buf, +static inline int ubi_io_write_data(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { ubi_assert(offset >= 0); diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index ea0d5c825ab..88629a320c2 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -37,21 +37,21 @@ static ssize_t vol_attribute_show(struct device *dev, struct device_attribute *attr, char *buf); /* Device attributes corresponding to files in '/<sysfs>/class/ubi/ubiX_Y' */ -static struct device_attribute vol_reserved_ebs = +static struct device_attribute attr_vol_reserved_ebs = __ATTR(reserved_ebs, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_type = +static struct device_attribute attr_vol_type = __ATTR(type, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_name = +static struct device_attribute attr_vol_name = __ATTR(name, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_corrupted = +static struct device_attribute attr_vol_corrupted = __ATTR(corrupted, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_alignment = +static struct device_attribute attr_vol_alignment = __ATTR(alignment, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_usable_eb_size = +static struct device_attribute attr_vol_usable_eb_size = __ATTR(usable_eb_size, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_data_bytes = +static struct device_attribute attr_vol_data_bytes = __ATTR(data_bytes, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_upd_marker = +static struct device_attribute attr_vol_upd_marker = __ATTR(upd_marker, S_IRUGO, vol_attribute_show, NULL); /* @@ -78,23 +78,27 @@ static ssize_t vol_attribute_show(struct device *dev, spin_unlock(&vol->ubi->volumes_lock); return -ENODEV; } - if (attr == &vol_reserved_ebs) + if (attr == &attr_vol_reserved_ebs) ret = sprintf(buf, "%d\n", vol->reserved_pebs); - else if (attr == &vol_type) { + else if (attr == &attr_vol_type) { const char *tp; - tp = vol->vol_type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static"; + + if (vol->vol_type == UBI_DYNAMIC_VOLUME) + tp = "dynamic"; + else + tp = "static"; ret = sprintf(buf, "%s\n", tp); - } else if (attr == &vol_name) + } else if (attr == &attr_vol_name) ret = sprintf(buf, "%s\n", vol->name); - else if (attr == &vol_corrupted) + else if (attr == &attr_vol_corrupted) ret = sprintf(buf, "%d\n", vol->corrupted); - else if (attr == &vol_alignment) + else if (attr == &attr_vol_alignment) ret = sprintf(buf, "%d\n", vol->alignment); - else if (attr == &vol_usable_eb_size) { + else if (attr == &attr_vol_usable_eb_size) { ret = sprintf(buf, "%d\n", vol->usable_leb_size); - } else if (attr == &vol_data_bytes) + } else if (attr == &attr_vol_data_bytes) ret = sprintf(buf, "%lld\n", vol->used_bytes); - else if (attr == &vol_upd_marker) + else if (attr == &attr_vol_upd_marker) ret = sprintf(buf, "%d\n", vol->upd_marker); else BUG(); @@ -126,28 +130,28 @@ static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol) { int err; - err = device_create_file(&vol->dev, &vol_reserved_ebs); + err = device_create_file(&vol->dev, &attr_vol_reserved_ebs); if (err) return err; - err = device_create_file(&vol->dev, &vol_type); + err = device_create_file(&vol->dev, &attr_vol_type); if (err) return err; - err = device_create_file(&vol->dev, &vol_name); + err = device_create_file(&vol->dev, &attr_vol_name); if (err) return err; - err = device_create_file(&vol->dev, &vol_corrupted); + err = device_create_file(&vol->dev, &attr_vol_corrupted); if (err) return err; - err = device_create_file(&vol->dev, &vol_alignment); + err = device_create_file(&vol->dev, &attr_vol_alignment); if (err) return err; - err = device_create_file(&vol->dev, &vol_usable_eb_size); + err = device_create_file(&vol->dev, &attr_vol_usable_eb_size); if (err) return err; - err = device_create_file(&vol->dev, &vol_data_bytes); + err = device_create_file(&vol->dev, &attr_vol_data_bytes); if (err) return err; - err = device_create_file(&vol->dev, &vol_upd_marker); + err = device_create_file(&vol->dev, &attr_vol_upd_marker); if (err) return err; return 0; @@ -159,14 +163,14 @@ static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol) */ static void volume_sysfs_close(struct ubi_volume *vol) { - device_remove_file(&vol->dev, &vol_upd_marker); - device_remove_file(&vol->dev, &vol_data_bytes); - device_remove_file(&vol->dev, &vol_usable_eb_size); - device_remove_file(&vol->dev, &vol_alignment); - device_remove_file(&vol->dev, &vol_corrupted); - device_remove_file(&vol->dev, &vol_name); - device_remove_file(&vol->dev, &vol_type); - device_remove_file(&vol->dev, &vol_reserved_ebs); + device_remove_file(&vol->dev, &attr_vol_upd_marker); + device_remove_file(&vol->dev, &attr_vol_data_bytes); + device_remove_file(&vol->dev, &attr_vol_usable_eb_size); + device_remove_file(&vol->dev, &attr_vol_alignment); + device_remove_file(&vol->dev, &attr_vol_corrupted); + device_remove_file(&vol->dev, &attr_vol_name); + device_remove_file(&vol->dev, &attr_vol_type); + device_remove_file(&vol->dev, &attr_vol_reserved_ebs); device_unregister(&vol->dev); } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index bc5df50813d..25b3bd61c7e 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -254,7 +254,7 @@ bad: * This function returns zero in case of success and a negative error code in * case of failure. */ -static int create_vtbl(const struct ubi_device *ubi, struct ubi_scan_info *si, +static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, int copy, void *vtbl) { int err, tries = 0; @@ -264,7 +264,7 @@ static int create_vtbl(const struct ubi_device *ubi, struct ubi_scan_info *si, ubi_msg("create volume table (copy #%d)", copy + 1); - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vid_hdr) return -ENOMEM; @@ -339,7 +339,7 @@ out_free: * not corrupted, and recovering from corruptions if needed. Returns volume * table in case of success and a negative error code in case of failure. */ -static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi, +static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, struct ubi_scan_info *si, struct ubi_scan_volume *sv) { @@ -453,7 +453,7 @@ out_free: * This function returns volume table contents in case of success and a * negative error code in case of failure. */ -static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi, +static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, struct ubi_scan_info *si) { int i; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index a5a9b8d8730..a4f1bf33164 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -208,7 +208,7 @@ struct ubi_work { }; #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID -static int paranoid_check_ec(const struct ubi_device *ubi, int pnum, int ec); +static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root); #else @@ -220,17 +220,6 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, static struct kmem_cache *wl_entries_slab; /** - * tree_empty - a helper function to check if an RB-tree is empty. - * @root: the root of the tree - * - * This function returns non-zero if the RB-tree is empty and zero if not. - */ -static inline int tree_empty(struct rb_root *root) -{ - return root->rb_node == NULL; -} - -/** * wl_tree_add - add a wear-leveling entry to a WL RB-tree. * @e: the wear-leveling entry to add * @root: the root of the tree @@ -266,45 +255,6 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root) rb_insert_color(&e->rb, root); } - -/* - * Helper functions to add and delete wear-leveling entries from different - * trees. - */ - -static void free_tree_add(struct ubi_device *ubi, struct ubi_wl_entry *e) -{ - wl_tree_add(e, &ubi->free); -} -static inline void used_tree_add(struct ubi_device *ubi, - struct ubi_wl_entry *e) -{ - wl_tree_add(e, &ubi->used); -} -static inline void scrub_tree_add(struct ubi_device *ubi, - struct ubi_wl_entry *e) -{ - wl_tree_add(e, &ubi->scrub); -} -static inline void free_tree_del(struct ubi_device *ubi, - struct ubi_wl_entry *e) -{ - paranoid_check_in_wl_tree(e, &ubi->free); - rb_erase(&e->rb, &ubi->free); -} -static inline void used_tree_del(struct ubi_device *ubi, - struct ubi_wl_entry *e) -{ - paranoid_check_in_wl_tree(e, &ubi->used); - rb_erase(&e->rb, &ubi->used); -} -static inline void scrub_tree_del(struct ubi_device *ubi, - struct ubi_wl_entry *e) -{ - paranoid_check_in_wl_tree(e, &ubi->scrub); - rb_erase(&e->rb, &ubi->scrub); -} - /** * do_work - do one pending work. * @ubi: UBI device description object @@ -358,7 +308,7 @@ static int produce_free_peb(struct ubi_device *ubi) int err; spin_lock(&ubi->wl_lock); - while (tree_empty(&ubi->free)) { + while (!ubi->free.rb_node) { spin_unlock(&ubi->wl_lock); dbg_wl("do one work synchronously"); @@ -508,13 +458,13 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || dtype == UBI_UNKNOWN); - pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_KERNEL); + pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); if (!pe) return -ENOMEM; retry: spin_lock(&ubi->wl_lock); - if (tree_empty(&ubi->free)) { + if (!ubi->free.rb_node) { if (ubi->works_count == 0) { ubi_assert(list_empty(&ubi->works)); ubi_err("no free eraseblocks"); @@ -585,7 +535,8 @@ retry: * Move the physical eraseblock to the protection trees where it will * be protected from being moved for some time. */ - free_tree_del(ubi, e); + paranoid_check_in_wl_tree(e, &ubi->free); + rb_erase(&e->rb, &ubi->free); prot_tree_add(ubi, e, pe, protect); dbg_wl("PEB %d EC %d, protection %d", e->pnum, e->ec, protect); @@ -645,7 +596,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, int tortur if (err > 0) return -EINVAL; - ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); if (!ec_hdr) return -ENOMEM; @@ -704,7 +655,7 @@ static void check_protection_over(struct ubi_device *ubi) */ while (1) { spin_lock(&ubi->wl_lock); - if (tree_empty(&ubi->prot.aec)) { + if (!ubi->prot.aec.rb_node) { spin_unlock(&ubi->wl_lock); break; } @@ -721,7 +672,7 @@ static void check_protection_over(struct ubi_device *ubi) pe->e->pnum, ubi->abs_ec, pe->abs_ec); rb_erase(&pe->rb_aec, &ubi->prot.aec); rb_erase(&pe->rb_pnum, &ubi->prot.pnum); - used_tree_add(ubi, pe->e); + wl_tree_add(pe->e, &ubi->used); spin_unlock(&ubi->wl_lock); kfree(pe); @@ -768,7 +719,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", e->pnum, e->ec, torture); - wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_KERNEL); + wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); if (!wl_wrk) return -ENOMEM; @@ -802,7 +753,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, if (cancel) return 0; - vid_hdr = ubi_zalloc_vid_hdr(ubi); + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; @@ -812,8 +763,8 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, * Only one WL worker at a time is supported at this implementation, so * make sure a PEB is not being moved already. */ - if (ubi->move_to || tree_empty(&ubi->free) || - (tree_empty(&ubi->used) && tree_empty(&ubi->scrub))) { + if (ubi->move_to || !ubi->free.rb_node || + (!ubi->used.rb_node && !ubi->scrub.rb_node)) { /* * Only one WL worker at a time is supported at this * implementation, so if a LEB is already being moved, cancel. @@ -828,14 +779,14 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, * triggered again. */ dbg_wl("cancel WL, a list is empty: free %d, used %d", - tree_empty(&ubi->free), tree_empty(&ubi->used)); + !ubi->free.rb_node, !ubi->used.rb_node); ubi->wl_scheduled = 0; spin_unlock(&ubi->wl_lock); ubi_free_vid_hdr(ubi, vid_hdr); return 0; } - if (tree_empty(&ubi->scrub)) { + if (!ubi->scrub.rb_node) { /* * Now pick the least worn-out used physical eraseblock and a * highly worn-out free physical eraseblock. If the erase @@ -852,17 +803,20 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, ubi_free_vid_hdr(ubi, vid_hdr); return 0; } - used_tree_del(ubi, e1); + paranoid_check_in_wl_tree(e1, &ubi->used); + rb_erase(&e1->rb, &ubi->used); dbg_wl("move PEB %d EC %d to PEB %d EC %d", e1->pnum, e1->ec, e2->pnum, e2->ec); } else { e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, rb); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); - scrub_tree_del(ubi, e1); + paranoid_check_in_wl_tree(e1, &ubi->scrub); + rb_erase(&e1->rb, &ubi->scrub); dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); } - free_tree_del(ubi, e2); + paranoid_check_in_wl_tree(e2, &ubi->free); + rb_erase(&e2->rb, &ubi->free); ubi_assert(!ubi->move_from && !ubi->move_to); ubi_assert(!ubi->move_to_put && !ubi->move_from_put); ubi->move_from = e1; @@ -908,7 +862,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, ubi_free_vid_hdr(ubi, vid_hdr); spin_lock(&ubi->wl_lock); if (!ubi->move_to_put) - used_tree_add(ubi, e2); + wl_tree_add(e2, &ubi->used); else put = 1; ubi->move_from = ubi->move_to = NULL; @@ -953,7 +907,7 @@ error: if (ubi->move_from_put) put = 1; else - used_tree_add(ubi, e1); + wl_tree_add(e1, &ubi->used); ubi->move_from = ubi->move_to = NULL; ubi->move_from_put = ubi->move_to_put = 0; spin_unlock(&ubi->wl_lock); @@ -1005,8 +959,8 @@ static int ensure_wear_leveling(struct ubi_device *ubi) * If the ubi->scrub tree is not empty, scrubbing is needed, and the * the WL worker has to be scheduled anyway. */ - if (tree_empty(&ubi->scrub)) { - if (tree_empty(&ubi->used) || tree_empty(&ubi->free)) + if (!ubi->scrub.rb_node) { + if (!ubi->used.rb_node || !ubi->free.rb_node) /* No physical eraseblocks - no deal */ goto out_unlock; @@ -1028,7 +982,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi) ubi->wl_scheduled = 1; spin_unlock(&ubi->wl_lock); - wrk = kmalloc(sizeof(struct ubi_work), GFP_KERNEL); + wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); if (!wrk) { err = -ENOMEM; goto out_cancel; @@ -1079,7 +1033,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, spin_lock(&ubi->wl_lock); ubi->abs_ec += 1; - free_tree_add(ubi, e); + wl_tree_add(e, &ubi->free); spin_unlock(&ubi->wl_lock); /* @@ -1093,6 +1047,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, return err; } + ubi_err("failed to erase PEB %d, error %d", pnum, err); kfree(wl_wrk); kmem_cache_free(wl_entries_slab, e); @@ -1211,11 +1166,13 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture) spin_unlock(&ubi->wl_lock); return 0; } else { - if (in_wl_tree(e, &ubi->used)) - used_tree_del(ubi, e); - else if (in_wl_tree(e, &ubi->scrub)) - scrub_tree_del(ubi, e); - else + if (in_wl_tree(e, &ubi->used)) { + paranoid_check_in_wl_tree(e, &ubi->used); + rb_erase(&e->rb, &ubi->used); + } else if (in_wl_tree(e, &ubi->scrub)) { + paranoid_check_in_wl_tree(e, &ubi->scrub); + rb_erase(&e->rb, &ubi->scrub); + } else prot_tree_del(ubi, e->pnum); } spin_unlock(&ubi->wl_lock); @@ -1223,7 +1180,7 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture) err = schedule_erase(ubi, e, torture); if (err) { spin_lock(&ubi->wl_lock); - used_tree_add(ubi, e); + wl_tree_add(e, &ubi->used); spin_unlock(&ubi->wl_lock); } @@ -1267,12 +1224,13 @@ retry: goto retry; } - if (in_wl_tree(e, &ubi->used)) - used_tree_del(ubi, e); - else + if (in_wl_tree(e, &ubi->used)) { + paranoid_check_in_wl_tree(e, &ubi->used); + rb_erase(&e->rb, &ubi->used); + } else prot_tree_del(ubi, pnum); - scrub_tree_add(ubi, e); + wl_tree_add(e, &ubi->scrub); spin_unlock(&ubi->wl_lock); /* @@ -1488,7 +1446,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) e->pnum = seb->pnum; e->ec = seb->ec; ubi_assert(e->ec >= 0); - free_tree_add(ubi, e); + wl_tree_add(e, &ubi->free); ubi->lookuptbl[e->pnum] = e; } @@ -1522,16 +1480,16 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) if (!seb->scrub) { dbg_wl("add PEB %d EC %d to the used tree", e->pnum, e->ec); - used_tree_add(ubi, e); + wl_tree_add(e, &ubi->used); } else { dbg_wl("add PEB %d EC %d to the scrub tree", e->pnum, e->ec); - scrub_tree_add(ubi, e); + wl_tree_add(e, &ubi->scrub); } } } - if (WL_RESERVED_PEBS > ubi->avail_pebs) { + if (ubi->avail_pebs < WL_RESERVED_PEBS) { ubi_err("no enough physical eraseblocks (%d, need %d)", ubi->avail_pebs, WL_RESERVED_PEBS); goto out_free; @@ -1624,13 +1582,13 @@ void ubi_wl_close(struct ubi_device *ubi) * is equivalent to @ec, %1 if not, and a negative error code if an error * occurred. */ -static int paranoid_check_ec(const struct ubi_device *ubi, int pnum, int ec) +static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) { int err; long long read_ec; struct ubi_ec_hdr *ec_hdr; - ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); if (!ec_hdr) return -ENOMEM; diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index bcd7fc639c4..3f57d6cd26e 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -251,7 +251,7 @@ static int __devinit rgmii_probe(struct of_device *ofdev, } /* Check for RGMII type */ - if (device_is_compatible(ofdev->node, "ibm,rgmii-axon")) + if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon")) dev->type = RGMII_AXON; else dev->type = RGMII_STANDARD; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 035cca02819..ec36ad78d2f 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -756,8 +756,8 @@ mpc52xx_console_setup(struct console *co, char *options) if (port->membase == NULL) return -EINVAL; - pr_debug("mpc52xx-psc uart at %lx, mapped to %p, irq=%x, freq=%i\n", - port->mapbase, port->membase, port->irq, port->uartclk); + pr_debug("mpc52xx-psc uart at %p, mapped to %p, irq=%x, freq=%i\n", + (void*)port->mapbase, port->membase, port->irq, port->uartclk); /* Setup the port parameters accoding to options */ if (options) @@ -974,8 +974,8 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) port->mapbase = res.start; port->irq = irq_of_parse_and_map(op->node, 0); - dev_dbg(&op->dev, "mpc52xx-psc uart at %lx, irq=%x, freq=%i\n", - port->mapbase, port->irq, port->uartclk); + dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n", + (void*)port->mapbase, port->irq, port->uartclk); if ((port->irq==NO_IRQ) || !port->mapbase) { printk(KERN_ERR "Could not allocate resources for PSC\n"); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index cfd13eb866b..c12a741b557 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -321,23 +321,17 @@ static int ssb_bus_match(struct device *dev, struct device_driver *drv) return 0; } -static int ssb_device_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) +static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env) { struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); - int ret, i = 0, length = 0; if (!dev) return -ENODEV; - ret = add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, + return add_uevent_var(env, "MODALIAS=ssb:v%04Xid%04Xrev%02X", ssb_dev->id.vendor, ssb_dev->id.coreid, ssb_dev->id.revision); - envp[i] = NULL; - - return ret; } static struct bus_type ssb_bustype = { diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index 7c773603b40..b6abee846f0 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c @@ -10,6 +10,7 @@ #include <linux/ssb/ssb.h> #include <linux/delay.h> +#include <linux/io.h> #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c index bc3e785d8c0..fe70e72340d 100644 --- a/drivers/usb/host/ohci-ssb.c +++ b/drivers/usb/host/ohci-ssb.c @@ -117,8 +117,10 @@ static const struct hc_driver ssb_ohci_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, .hub_irq_enable = ohci_rhsc_enable, +#ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, +#endif .start_port_reset = ohci_start_port_reset, }; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index ee9046db9c7..549891d76ef 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -19,7 +19,6 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/prom.h> #include <asm/of_device.h> #include <asm/fbio.h> @@ -38,6 +37,7 @@ static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *); static int cg6_sync(struct fb_info *); static int cg6_mmap(struct fb_info *, struct vm_area_struct *); static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long); +static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area); /* * Frame buffer operations @@ -48,7 +48,7 @@ static struct fb_ops cg6_ops = { .fb_setcolreg = cg6_setcolreg, .fb_blank = cg6_blank, .fb_fillrect = cg6_fillrect, - .fb_copyarea = cfb_copyarea, + .fb_copyarea = cg6_copyarea, .fb_imageblit = cg6_imageblit, .fb_sync = cg6_sync, .fb_mmap = cg6_mmap, @@ -65,41 +65,41 @@ static struct fb_ops cg6_ops = { * The FBC could be the frame buffer control * The FHC could is the frame buffer hardware control. */ -#define CG6_ROM_OFFSET 0x0UL -#define CG6_BROOKTREE_OFFSET 0x200000UL -#define CG6_DHC_OFFSET 0x240000UL -#define CG6_ALT_OFFSET 0x280000UL -#define CG6_FHC_OFFSET 0x300000UL -#define CG6_THC_OFFSET 0x301000UL -#define CG6_FBC_OFFSET 0x700000UL -#define CG6_TEC_OFFSET 0x701000UL -#define CG6_RAM_OFFSET 0x800000UL +#define CG6_ROM_OFFSET 0x0UL +#define CG6_BROOKTREE_OFFSET 0x200000UL +#define CG6_DHC_OFFSET 0x240000UL +#define CG6_ALT_OFFSET 0x280000UL +#define CG6_FHC_OFFSET 0x300000UL +#define CG6_THC_OFFSET 0x301000UL +#define CG6_FBC_OFFSET 0x700000UL +#define CG6_TEC_OFFSET 0x701000UL +#define CG6_RAM_OFFSET 0x800000UL /* FHC definitions */ -#define CG6_FHC_FBID_SHIFT 24 -#define CG6_FHC_FBID_MASK 255 -#define CG6_FHC_REV_SHIFT 20 -#define CG6_FHC_REV_MASK 15 -#define CG6_FHC_FROP_DISABLE (1 << 19) -#define CG6_FHC_ROW_DISABLE (1 << 18) -#define CG6_FHC_SRC_DISABLE (1 << 17) -#define CG6_FHC_DST_DISABLE (1 << 16) -#define CG6_FHC_RESET (1 << 15) -#define CG6_FHC_LITTLE_ENDIAN (1 << 13) -#define CG6_FHC_RES_MASK (3 << 11) -#define CG6_FHC_1024 (0 << 11) -#define CG6_FHC_1152 (1 << 11) -#define CG6_FHC_1280 (2 << 11) -#define CG6_FHC_1600 (3 << 11) -#define CG6_FHC_CPU_MASK (3 << 9) -#define CG6_FHC_CPU_SPARC (0 << 9) -#define CG6_FHC_CPU_68020 (1 << 9) -#define CG6_FHC_CPU_386 (2 << 9) -#define CG6_FHC_TEST (1 << 8) -#define CG6_FHC_TEST_X_SHIFT 4 -#define CG6_FHC_TEST_X_MASK 15 -#define CG6_FHC_TEST_Y_SHIFT 0 -#define CG6_FHC_TEST_Y_MASK 15 +#define CG6_FHC_FBID_SHIFT 24 +#define CG6_FHC_FBID_MASK 255 +#define CG6_FHC_REV_SHIFT 20 +#define CG6_FHC_REV_MASK 15 +#define CG6_FHC_FROP_DISABLE (1 << 19) +#define CG6_FHC_ROW_DISABLE (1 << 18) +#define CG6_FHC_SRC_DISABLE (1 << 17) +#define CG6_FHC_DST_DISABLE (1 << 16) +#define CG6_FHC_RESET (1 << 15) +#define CG6_FHC_LITTLE_ENDIAN (1 << 13) +#define CG6_FHC_RES_MASK (3 << 11) +#define CG6_FHC_1024 (0 << 11) +#define CG6_FHC_1152 (1 << 11) +#define CG6_FHC_1280 (2 << 11) +#define CG6_FHC_1600 (3 << 11) +#define CG6_FHC_CPU_MASK (3 << 9) +#define CG6_FHC_CPU_SPARC (0 << 9) +#define CG6_FHC_CPU_68020 (1 << 9) +#define CG6_FHC_CPU_386 (2 << 9) +#define CG6_FHC_TEST (1 << 8) +#define CG6_FHC_TEST_X_SHIFT 4 +#define CG6_FHC_TEST_X_MASK 15 +#define CG6_FHC_TEST_Y_SHIFT 0 +#define CG6_FHC_TEST_Y_MASK 15 /* FBC mode definitions */ #define CG6_FBC_BLIT_IGNORE 0x00000000 @@ -150,17 +150,17 @@ static struct fb_ops cg6_ops = { #define CG6_FBC_INDEX_MASK 0x00000030 /* THC definitions */ -#define CG6_THC_MISC_REV_SHIFT 16 -#define CG6_THC_MISC_REV_MASK 15 -#define CG6_THC_MISC_RESET (1 << 12) -#define CG6_THC_MISC_VIDEO (1 << 10) -#define CG6_THC_MISC_SYNC (1 << 9) -#define CG6_THC_MISC_VSYNC (1 << 8) -#define CG6_THC_MISC_SYNC_ENAB (1 << 7) -#define CG6_THC_MISC_CURS_RES (1 << 6) -#define CG6_THC_MISC_INT_ENAB (1 << 5) -#define CG6_THC_MISC_INT (1 << 4) -#define CG6_THC_MISC_INIT 0x9f +#define CG6_THC_MISC_REV_SHIFT 16 +#define CG6_THC_MISC_REV_MASK 15 +#define CG6_THC_MISC_RESET (1 << 12) +#define CG6_THC_MISC_VIDEO (1 << 10) +#define CG6_THC_MISC_SYNC (1 << 9) +#define CG6_THC_MISC_VSYNC (1 << 8) +#define CG6_THC_MISC_SYNC_ENAB (1 << 7) +#define CG6_THC_MISC_CURS_RES (1 << 6) +#define CG6_THC_MISC_INT_ENAB (1 << 5) +#define CG6_THC_MISC_INT (1 << 4) +#define CG6_THC_MISC_INIT 0x9f /* The contents are unknown */ struct cg6_tec { @@ -170,25 +170,25 @@ struct cg6_tec { }; struct cg6_thc { - u32 thc_pad0[512]; - u32 thc_hs; /* hsync timing */ - u32 thc_hsdvs; - u32 thc_hd; - u32 thc_vs; /* vsync timing */ - u32 thc_vd; - u32 thc_refresh; - u32 thc_misc; - u32 thc_pad1[56]; - u32 thc_cursxy; /* cursor x,y position (16 bits each) */ - u32 thc_cursmask[32]; /* cursor mask bits */ - u32 thc_cursbits[32]; /* what to show where mask enabled */ + u32 thc_pad0[512]; + u32 thc_hs; /* hsync timing */ + u32 thc_hsdvs; + u32 thc_hd; + u32 thc_vs; /* vsync timing */ + u32 thc_vd; + u32 thc_refresh; + u32 thc_misc; + u32 thc_pad1[56]; + u32 thc_cursxy; /* cursor x,y position (16 bits each) */ + u32 thc_cursmask[32]; /* cursor mask bits */ + u32 thc_cursbits[32]; /* what to show where mask enabled */ }; struct cg6_fbc { u32 xxx0[1]; u32 mode; u32 clip; - u32 xxx1[1]; + u32 xxx1[1]; u32 s; u32 draw; u32 blit; @@ -243,10 +243,10 @@ struct cg6_fbc { }; struct bt_regs { - u32 addr; - u32 color_map; - u32 control; - u32 cursor; + u32 addr; + u32 color_map; + u32 control; + u32 cursor; }; struct cg6_par { @@ -267,7 +267,7 @@ struct cg6_par { static int cg6_sync(struct fb_info *info) { - struct cg6_par *par = (struct cg6_par *) info->par; + struct cg6_par *par = (struct cg6_par *)info->par; struct cg6_fbc __iomem *fbc = par->fbc; int limit = 10000; @@ -281,24 +281,24 @@ static int cg6_sync(struct fb_info *info) } /** - * cg6_fillrect - REQUIRED function. Can use generic routines if - * non acclerated hardware and packed pixel based. - * Draws a rectangle on the screen. + * cg6_fillrect - Draws a rectangle on the screen. * - * @info: frame buffer structure that represents a single frame buffer - * @rect: structure defining the rectagle and operation. + * @info: frame buffer structure that represents a single frame buffer + * @rect: structure defining the rectagle and operation. */ static void cg6_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct cg6_par *par = (struct cg6_par *) info->par; + struct cg6_par *par = (struct cg6_par *)info->par; struct cg6_fbc __iomem *fbc = par->fbc; unsigned long flags; s32 val; - /* XXX doesn't handle ROP_XOR */ + /* CG6 doesn't handle ROP_XOR */ spin_lock_irqsave(&par->lock, flags); + cg6_sync(info); + sbus_writel(rect->color, &fbc->fg); sbus_writel(~(u32)0, &fbc->pixelm); sbus_writel(0xea80ff00, &fbc->alu); @@ -316,16 +316,56 @@ static void cg6_fillrect(struct fb_info *info, const struct fb_fillrect *rect) } /** - * cg6_imageblit - REQUIRED function. Can use generic routines if - * non acclerated hardware and packed pixel based. - * Copies a image from system memory to the screen. + * cg6_copyarea - Copies one area of the screen to another area. + * + * @info: frame buffer structure that represents a single frame buffer + * @area: Structure providing the data to copy the framebuffer contents + * from one region to another. + * + * This drawing operation copies a rectangular area from one area of the + * screen to another area. + */ +static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area) +{ + struct cg6_par *par = (struct cg6_par *)info->par; + struct cg6_fbc __iomem *fbc = par->fbc; + unsigned long flags; + int i; + + spin_lock_irqsave(&par->lock, flags); + + cg6_sync(info); + + sbus_writel(0xff, &fbc->fg); + sbus_writel(0x00, &fbc->bg); + sbus_writel(~0, &fbc->pixelm); + sbus_writel(0xe880cccc, &fbc->alu); + sbus_writel(0, &fbc->s); + sbus_writel(0, &fbc->clip); + + sbus_writel(area->sy, &fbc->y0); + sbus_writel(area->sx, &fbc->x0); + sbus_writel(area->sy + area->height - 1, &fbc->y1); + sbus_writel(area->sx + area->width - 1, &fbc->x1); + sbus_writel(area->dy, &fbc->y2); + sbus_writel(area->dx, &fbc->x2); + sbus_writel(area->dy + area->height - 1, &fbc->y3); + sbus_writel(area->dx + area->width - 1, &fbc->x3); + do { + i = sbus_readl(&fbc->blit); + } while (i < 0 && (i & 0x20000000)); + spin_unlock_irqrestore(&par->lock, flags); +} + +/** + * cg6_imageblit - Copies a image from system memory to the screen. * - * @info: frame buffer structure that represents a single frame buffer - * @image: structure defining the image. + * @info: frame buffer structure that represents a single frame buffer + * @image: structure defining the image. */ static void cg6_imageblit(struct fb_info *info, const struct fb_image *image) { - struct cg6_par *par = (struct cg6_par *) info->par; + struct cg6_par *par = (struct cg6_par *)info->par; struct cg6_fbc __iomem *fbc = par->fbc; const u8 *data = image->data; unsigned long flags; @@ -363,7 +403,7 @@ static void cg6_imageblit(struct fb_info *info, const struct fb_image *image) sbus_writel(y, &fbc->y0); sbus_writel(x, &fbc->x0); sbus_writel(x + 32 - 1, &fbc->x1); - + val = ((u32)data[0] << 24) | ((u32)data[1] << 16) | ((u32)data[2] << 8) | @@ -404,19 +444,20 @@ static void cg6_imageblit(struct fb_info *info, const struct fb_image *image) } /** - * cg6_setcolreg - Optional function. Sets a color register. - * @regno: boolean, 0 copy local, 1 get_user() function - * @red: frame buffer colormap structure - * @green: The green value which can be up to 16 bits wide - * @blue: The blue value which can be up to 16 bits wide. - * @transp: If supported the alpha value which can be up to 16 bits wide. - * @info: frame buffer info structure + * cg6_setcolreg - Sets a color register. + * + * @regno: boolean, 0 copy local, 1 get_user() function + * @red: frame buffer colormap structure + * @green: The green value which can be up to 16 bits wide + * @blue: The blue value which can be up to 16 bits wide. + * @transp: If supported the alpha value which can be up to 16 bits wide. + * @info: frame buffer info structure */ static int cg6_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct cg6_par *par = (struct cg6_par *) info->par; + struct cg6_par *par = (struct cg6_par *)info->par; struct bt_regs __iomem *bt = par->bt; unsigned long flags; @@ -440,25 +481,24 @@ static int cg6_setcolreg(unsigned regno, } /** - * cg6_blank - Optional function. Blanks the display. - * @blank_mode: the blank mode we want. - * @info: frame buffer structure that represents a single frame buffer + * cg6_blank - Blanks the display. + * + * @blank_mode: the blank mode we want. + * @info: frame buffer structure that represents a single frame buffer */ -static int -cg6_blank(int blank, struct fb_info *info) +static int cg6_blank(int blank, struct fb_info *info) { - struct cg6_par *par = (struct cg6_par *) info->par; + struct cg6_par *par = (struct cg6_par *)info->par; struct cg6_thc __iomem *thc = par->thc; unsigned long flags; u32 val; spin_lock_irqsave(&par->lock, flags); + val = sbus_readl(&thc->thc_misc); switch (blank) { case FB_BLANK_UNBLANK: /* Unblanking */ - val = sbus_readl(&thc->thc_misc); val |= CG6_THC_MISC_VIDEO; - sbus_writel(val, &thc->thc_misc); par->flags &= ~CG6_FLAG_BLANKED; break; @@ -466,13 +506,12 @@ cg6_blank(int blank, struct fb_info *info) case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */ case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */ case FB_BLANK_POWERDOWN: /* Poweroff */ - val = sbus_readl(&thc->thc_misc); val &= ~CG6_THC_MISC_VIDEO; - sbus_writel(val, &thc->thc_misc); par->flags |= CG6_FLAG_BLANKED; break; } + sbus_writel(val, &thc->thc_misc); spin_unlock_irqrestore(&par->lock, flags); return 0; @@ -533,7 +572,7 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma) static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { - struct cg6_par *par = (struct cg6_par *) info->par; + struct cg6_par *par = (struct cg6_par *)info->par; return sbusfb_ioctl_helper(cmd, arg, info, FBTYPE_SUNFAST_COLOR, 8, par->fbsize); @@ -543,15 +582,14 @@ static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) * Initialisation */ -static void -cg6_init_fix(struct fb_info *info, int linebytes) +static void __devinit cg6_init_fix(struct fb_info *info, int linebytes) { struct cg6_par *par = (struct cg6_par *)info->par; const char *cg6_cpu_name, *cg6_card_name; u32 conf; conf = sbus_readl(par->fhc); - switch(conf & CG6_FHC_CPU_MASK) { + switch (conf & CG6_FHC_CPU_MASK) { case CG6_FHC_CPU_SPARC: cg6_cpu_name = "sparc"; break; @@ -563,21 +601,19 @@ cg6_init_fix(struct fb_info *info, int linebytes) break; }; if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) { - if (par->fbsize <= 0x100000) { + if (par->fbsize <= 0x100000) cg6_card_name = "TGX"; - } else { + else cg6_card_name = "TGX+"; - } } else { - if (par->fbsize <= 0x100000) { + if (par->fbsize <= 0x100000) cg6_card_name = "GX"; - } else { + else cg6_card_name = "GX+"; - } } sprintf(info->fix.id, "%s %s", cg6_card_name, cg6_cpu_name); - info->fix.id[sizeof(info->fix.id)-1] = 0; + info->fix.id[sizeof(info->fix.id) - 1] = 0; info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -588,28 +624,28 @@ cg6_init_fix(struct fb_info *info, int linebytes) } /* Initialize Brooktree DAC */ -static void cg6_bt_init(struct cg6_par *par) +static void __devinit cg6_bt_init(struct cg6_par *par) { struct bt_regs __iomem *bt = par->bt; - sbus_writel(0x04 << 24, &bt->addr); /* color planes */ + sbus_writel(0x04 << 24, &bt->addr); /* color planes */ sbus_writel(0xff << 24, &bt->control); sbus_writel(0x05 << 24, &bt->addr); sbus_writel(0x00 << 24, &bt->control); - sbus_writel(0x06 << 24, &bt->addr); /* overlay plane */ + sbus_writel(0x06 << 24, &bt->addr); /* overlay plane */ sbus_writel(0x73 << 24, &bt->control); sbus_writel(0x07 << 24, &bt->addr); sbus_writel(0x00 << 24, &bt->control); } -static void cg6_chip_init(struct fb_info *info) +static void __devinit cg6_chip_init(struct fb_info *info) { - struct cg6_par *par = (struct cg6_par *) info->par; + struct cg6_par *par = (struct cg6_par *)info->par; struct cg6_tec __iomem *tec = par->tec; struct cg6_fbc __iomem *fbc = par->fbc; u32 rev, conf, mode; int i; - + /* Turn off stuff in the Transform Engine. */ sbus_writel(0, &tec->tec_matrix); sbus_writel(0, &tec->tec_clip); @@ -635,13 +671,13 @@ static void cg6_chip_init(struct fb_info *info) i = sbus_readl(&fbc->s); } while (i & 0x10000000); mode &= ~(CG6_FBC_BLIT_MASK | CG6_FBC_MODE_MASK | - CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK | - CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK | - CG6_FBC_BDISP_MASK); + CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK | + CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK | + CG6_FBC_BDISP_MASK); mode |= (CG6_FBC_BLIT_SRC | CG6_FBC_MODE_COLOR8 | - CG6_FBC_DRAW_RENDER | CG6_FBC_BWRITE0_ENABLE | - CG6_FBC_BWRITE1_DISABLE | CG6_FBC_BREAD_0 | - CG6_FBC_BDISP_0); + CG6_FBC_DRAW_RENDER | CG6_FBC_BWRITE0_ENABLE | + CG6_FBC_BWRITE1_DISABLE | CG6_FBC_BREAD_0 | + CG6_FBC_BDISP_0); sbus_writel(mode, &fbc->mode); sbus_writel(0, &fbc->clip); @@ -671,7 +707,8 @@ static void cg6_unmap_regs(struct of_device *op, struct fb_info *info, of_iounmap(&op->resource[0], info->screen_base, par->fbsize); } -static int __devinit cg6_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit cg6_probe(struct of_device *op, + const struct of_device_id *match) { struct device_node *dp = op->node; struct fb_info *info; @@ -705,22 +742,23 @@ static int __devinit cg6_probe(struct of_device *op, const struct of_device_id * par->fbsize *= 4; par->fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET, - 4096, "cgsix fbc"); + 4096, "cgsix fbc"); par->tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET, - sizeof(struct cg6_tec), "cgsix tec"); + sizeof(struct cg6_tec), "cgsix tec"); par->thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET, - sizeof(struct cg6_thc), "cgsix thc"); + sizeof(struct cg6_thc), "cgsix thc"); par->bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET, - sizeof(struct bt_regs), "cgsix dac"); + sizeof(struct bt_regs), "cgsix dac"); par->fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET, - sizeof(u32), "cgsix fhc"); + sizeof(u32), "cgsix fhc"); info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | - FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; + FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | + FBINFO_READS_FAST; info->fbops = &cg6_ops; - info->screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET, - par->fbsize, "cgsix ram"); + info->screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET, + par->fbsize, "cgsix ram"); if (!par->fbc || !par->tec || !par->thc || !par->bt || !par->fhc || !info->screen_base) goto out_unmap_regs; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 4b520b57391..d7e24889650 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -171,17 +171,17 @@ static struct fb_ops ffb_ops = { #define FFB_PPC_CS_VAR 0x000002 #define FFB_PPC_CS_CONST 0x000003 -#define FFB_ROP_NEW 0x83 -#define FFB_ROP_OLD 0x85 -#define FFB_ROP_NEW_XOR_OLD 0x86 - -#define FFB_UCSR_FIFO_MASK 0x00000fff -#define FFB_UCSR_FB_BUSY 0x01000000 -#define FFB_UCSR_RP_BUSY 0x02000000 -#define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY) -#define FFB_UCSR_READ_ERR 0x40000000 -#define FFB_UCSR_FIFO_OVFL 0x80000000 -#define FFB_UCSR_ALL_ERRORS (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL) +#define FFB_ROP_NEW 0x83 +#define FFB_ROP_OLD 0x85 +#define FFB_ROP_NEW_XOR_OLD 0x86 + +#define FFB_UCSR_FIFO_MASK 0x00000fff +#define FFB_UCSR_FB_BUSY 0x01000000 +#define FFB_UCSR_RP_BUSY 0x02000000 +#define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY) +#define FFB_UCSR_READ_ERR 0x40000000 +#define FFB_UCSR_FIFO_OVFL 0x80000000 +#define FFB_UCSR_ALL_ERRORS (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL) struct ffb_fbc { /* Next vertex registers */ @@ -197,7 +197,7 @@ struct ffb_fbc { u32 ryf; u32 rxf; u32 xxx3[2]; - + u32 dmyf; u32 dmxf; u32 xxx4[2]; @@ -211,13 +211,13 @@ struct ffb_fbc { u32 bh; u32 bw; u32 xxx6[2]; - + u32 xxx7[32]; - + /* Setup unit vertex state register */ u32 suvtx; u32 xxx8[63]; - + /* Control registers */ u32 ppc; u32 wid; @@ -235,7 +235,7 @@ struct ffb_fbc { u32 dcsb; u32 dczf; u32 dczb; - + u32 xxx9; u32 blendc; u32 blendc1; @@ -252,7 +252,7 @@ struct ffb_fbc { u32 fbcfg1; u32 fbcfg2; u32 fbcfg3; - + u32 ppcfg; u32 pick; u32 fillmode; @@ -269,7 +269,7 @@ struct ffb_fbc { u32 clip2max; u32 clip3min; u32 clip3max; - + /* New 3dRAM III support regs */ u32 rawblend2; u32 rawpreblend; @@ -287,7 +287,7 @@ struct ffb_fbc { u32 rawcmp; u32 rawwac; u32 fbramid; - + u32 drawop; u32 xxx10[2]; u32 fontlpat; @@ -302,7 +302,7 @@ struct ffb_fbc { u32 stencil; u32 stencilctl; - u32 xxx13[4]; + u32 xxx13[4]; u32 dcss1; u32 dcss2; u32 dcss3; @@ -315,17 +315,17 @@ struct ffb_fbc { u32 dcd3; u32 dcd4; u32 xxx15; - + u32 pattern[32]; - + u32 xxx16[256]; - + u32 devid; u32 xxx17[63]; - + u32 ucsr; u32 xxx18[31]; - + u32 mer; }; @@ -336,20 +336,20 @@ struct ffb_dac { u32 value2; }; -#define FFB_DAC_UCTRL 0x1001 /* User Control */ -#define FFB_DAC_UCTRL_MANREV 0x00000f00 /* 4-bit Manufacturing Revision */ -#define FFB_DAC_UCTRL_MANREV_SHIFT 8 -#define FFB_DAC_TGEN 0x6000 /* Timing Generator */ -#define FFB_DAC_TGEN_VIDE 0x00000001 /* Video Enable */ -#define FFB_DAC_DID 0x8000 /* Device Identification */ -#define FFB_DAC_DID_PNUM 0x0ffff000 /* Device Part Number */ -#define FFB_DAC_DID_PNUM_SHIFT 12 -#define FFB_DAC_DID_REV 0xf0000000 /* Device Revision */ -#define FFB_DAC_DID_REV_SHIFT 28 +#define FFB_DAC_UCTRL 0x1001 /* User Control */ +#define FFB_DAC_UCTRL_MANREV 0x00000f00 /* 4-bit Manufacturing Revision */ +#define FFB_DAC_UCTRL_MANREV_SHIFT 8 +#define FFB_DAC_TGEN 0x6000 /* Timing Generator */ +#define FFB_DAC_TGEN_VIDE 0x00000001 /* Video Enable */ +#define FFB_DAC_DID 0x8000 /* Device Identification */ +#define FFB_DAC_DID_PNUM 0x0ffff000 /* Device Part Number */ +#define FFB_DAC_DID_PNUM_SHIFT 12 +#define FFB_DAC_DID_REV 0xf0000000 /* Device Revision */ +#define FFB_DAC_DID_REV_SHIFT 28 #define FFB_DAC_CUR_CTRL 0x100 -#define FFB_DAC_CUR_CTRL_P0 0x00000001 -#define FFB_DAC_CUR_CTRL_P1 0x00000002 +#define FFB_DAC_CUR_CTRL_P0 0x00000001 +#define FFB_DAC_CUR_CTRL_P1 0x00000002 struct ffb_par { spinlock_t lock; @@ -382,7 +382,9 @@ static void FFBFifo(struct ffb_par *par, int n) if (cache - n < 0) { fbc = par->fbc; - do { cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK) - 8; + do { + cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK); + cache -= 8; } while (cache - n < 0); } par->fifo_cache = cache - n; @@ -401,12 +403,12 @@ static void FFBWait(struct ffb_par *par) upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); } udelay(10); - } while(--limit > 0); + } while (--limit > 0); } static int ffb_sync(struct fb_info *p) { - struct ffb_par *par = (struct ffb_par *) p->par; + struct ffb_par *par = (struct ffb_par *)p->par; FFBWait(par); return 0; @@ -431,8 +433,8 @@ static void ffb_switch_from_graph(struct ffb_par *par) FFBWait(par); par->fifo_cache = 0; FFBFifo(par, 7); - upa_writel(FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE| - FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST, + upa_writel(FFB_PPC_VCE_DISABLE | FFB_PPC_TBE_OPAQUE | + FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST, &fbc->ppc); upa_writel(0x2000707f, &fbc->fbc); upa_writel(par->rop_cache, &fbc->rop); @@ -455,7 +457,7 @@ static void ffb_switch_from_graph(struct ffb_par *par) static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct ffb_par *par = (struct ffb_par *) info->par; + struct ffb_par *par = (struct ffb_par *)info->par; /* We just use this to catch switches out of * graphics mode. @@ -468,16 +470,14 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) } /** - * ffb_fillrect - REQUIRED function. Can use generic routines if - * non acclerated hardware and packed pixel based. - * Draws a rectangle on the screen. + * ffb_fillrect - Draws a rectangle on the screen. * - * @info: frame buffer structure that represents a single frame buffer - * @rect: structure defining the rectagle and operation. + * @info: frame buffer structure that represents a single frame buffer + * @rect: structure defining the rectagle and operation. */ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct ffb_par *par = (struct ffb_par *) info->par; + struct ffb_par *par = (struct ffb_par *)info->par; struct ffb_fbc __iomem *fbc = par->fbc; unsigned long flags; u32 fg; @@ -494,9 +494,9 @@ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) par->fg_cache = fg; } - ffb_rop(par, (rect->rop == ROP_COPY ? - FFB_ROP_NEW : - FFB_ROP_NEW_XOR_OLD)); + ffb_rop(par, rect->rop == ROP_COPY ? + FFB_ROP_NEW : + FFB_ROP_NEW_XOR_OLD); FFBFifo(par, 5); upa_writel(FFB_DRAWOP_RECTANGLE, &fbc->drawop); @@ -509,18 +509,15 @@ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) } /** - * ffb_copyarea - REQUIRED function. Can use generic routines if - * non acclerated hardware and packed pixel based. - * Copies on area of the screen to another area. + * ffb_copyarea - Copies on area of the screen to another area. * - * @info: frame buffer structure that represents a single frame buffer - * @area: structure defining the source and destination. + * @info: frame buffer structure that represents a single frame buffer + * @area: structure defining the source and destination. */ -static void -ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +static void ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { - struct ffb_par *par = (struct ffb_par *) info->par; + struct ffb_par *par = (struct ffb_par *)info->par; struct ffb_fbc __iomem *fbc = par->fbc; unsigned long flags; @@ -547,16 +544,14 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) } /** - * ffb_imageblit - REQUIRED function. Can use generic routines if - * non acclerated hardware and packed pixel based. - * Copies a image from system memory to the screen. + * ffb_imageblit - Copies a image from system memory to the screen. * - * @info: frame buffer structure that represents a single frame buffer - * @image: structure defining the image. + * @info: frame buffer structure that represents a single frame buffer + * @image: structure defining the image. */ static void ffb_imageblit(struct fb_info *info, const struct fb_image *image) { - struct ffb_par *par = (struct ffb_par *) info->par; + struct ffb_par *par = (struct ffb_par *)info->par; struct ffb_fbc __iomem *fbc = par->fbc; const u8 *data = image->data; unsigned long flags; @@ -644,13 +639,14 @@ static void ffb_fixup_var_rgb(struct fb_var_screeninfo *var) } /** - * ffb_setcolreg - Optional function. Sets a color register. - * @regno: boolean, 0 copy local, 1 get_user() function - * @red: frame buffer colormap structure - * @green: The green value which can be up to 16 bits wide - * @blue: The blue value which can be up to 16 bits wide. - * @transp: If supported the alpha value which can be up to 16 bits wide. - * @info: frame buffer info structure + * ffb_setcolreg - Sets a color register. + * + * @regno: boolean, 0 copy local, 1 get_user() function + * @red: frame buffer colormap structure + * @green: The green value which can be up to 16 bits wide + * @blue: The blue value which can be up to 16 bits wide. + * @transp: If supported the alpha value which can be up to 16 bits wide. + * @info: frame buffer info structure */ static int ffb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, @@ -672,14 +668,13 @@ static int ffb_setcolreg(unsigned regno, } /** - * ffb_blank - Optional function. Blanks the display. - * @blank_mode: the blank mode we want. - * @info: frame buffer structure that represents a single frame buffer + * ffb_blank - Optional function. Blanks the display. + * @blank_mode: the blank mode we want. + * @info: frame buffer structure that represents a single frame buffer */ -static int -ffb_blank(int blank, struct fb_info *info) +static int ffb_blank(int blank, struct fb_info *info) { - struct ffb_par *par = (struct ffb_par *) info->par; + struct ffb_par *par = (struct ffb_par *)info->par; struct ffb_dac __iomem *dac = par->dac; unsigned long flags; u32 val; @@ -867,7 +862,7 @@ static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma) static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { - struct ffb_par *par = (struct ffb_par *) info->par; + struct ffb_par *par = (struct ffb_par *)info->par; return sbusfb_ioctl_helper(cmd, arg, info, FBTYPE_CREATOR, 24, par->fbsize); @@ -877,8 +872,7 @@ static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) * Initialisation */ -static void -ffb_init_fix(struct fb_info *info) +static void ffb_init_fix(struct fb_info *info) { struct ffb_par *par = (struct ffb_par *)info->par; const char *ffb_type_name; @@ -902,7 +896,8 @@ ffb_init_fix(struct fb_info *info) info->fix.accel = FB_ACCEL_SUN_CREATOR; } -static int __devinit ffb_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit ffb_probe(struct of_device *op, + const struct of_device_id *match) { struct device_node *dp = op->node; struct ffb_fbc __iomem *fbc; diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 6ef99b2d13c..e38d3b7c3ad 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -84,7 +84,7 @@ static struct xilinxfb_platform_data xilinx_fb_default_pdata = { .xres = 640, .yres = 480, .xvirt = 1024, - .yvirt = 480; + .yvirt = 480, }; /* |