Merge branch 'master'
This commit is contained in:
commit
ebc62fb36c
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
|||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 15
|
SUBLEVEL = 15
|
||||||
EXTRAVERSION =-rc5
|
EXTRAVERSION =-rc6
|
||||||
NAME=Affluent Albatross
|
NAME=Sliding Snow Leopard
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
# To see a list of typical targets execute "make help"
|
# To see a list of typical targets execute "make help"
|
||||||
|
@ -1311,7 +1311,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
|
|||||||
|
|
||||||
static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
{
|
{
|
||||||
drm_radeon_private_t *dev_priv = dev->dev_private;;
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
unsigned int mem_size;
|
unsigned int mem_size;
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
@ -41,6 +41,7 @@ struct hpsb_host {
|
|||||||
/* this nodes state */
|
/* this nodes state */
|
||||||
unsigned in_bus_reset:1;
|
unsigned in_bus_reset:1;
|
||||||
unsigned is_shutdown:1;
|
unsigned is_shutdown:1;
|
||||||
|
unsigned resume_packet_sent:1;
|
||||||
|
|
||||||
/* this nodes' duties on the bus */
|
/* this nodes' duties on the bus */
|
||||||
unsigned is_root:1;
|
unsigned is_root:1;
|
||||||
|
@ -1349,6 +1349,33 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This
|
||||||
|
* seems like an optional service but in the end it is practically mandatory
|
||||||
|
* as a consequence of these clauses.
|
||||||
|
*
|
||||||
|
* Note that we cannot do a broadcast write to all nodes at once because some
|
||||||
|
* pre-1394a devices would hang. */
|
||||||
|
static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
|
||||||
|
{
|
||||||
|
const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
|
||||||
|
quadlet_t bc_remote, bc_local;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!ne->host->is_irm || ne->generation != generation ||
|
||||||
|
ne->nodeid == ne->host->node_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
|
||||||
|
|
||||||
|
/* Check if the register is implemented and 1394a compliant. */
|
||||||
|
ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
|
||||||
|
sizeof(bc_remote));
|
||||||
|
if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
|
||||||
|
bc_remote != bc_local)
|
||||||
|
hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
|
static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
|
||||||
{
|
{
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
@ -1360,6 +1387,8 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
|
|||||||
if (!dev)
|
if (!dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
nodemgr_irm_write_bc(ne, generation);
|
||||||
|
|
||||||
/* If "needs_probe", then this is either a new or changed node we
|
/* If "needs_probe", then this is either a new or changed node we
|
||||||
* rescan totally. If the generation matches for an existing node
|
* rescan totally. If the generation matches for an existing node
|
||||||
* (one that existed prior to the bus reset) we send update calls
|
* (one that existed prior to the bus reset) we send update calls
|
||||||
@ -1413,9 +1442,25 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other
|
static int nodemgr_send_resume_packet(struct hpsb_host *host)
|
||||||
* nodes of the broadcast channel. (Really we're only setting the validity
|
{
|
||||||
* bit). Other IRM responsibilities go in here as well. */
|
struct hpsb_packet *packet;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
packet = hpsb_make_phypacket(host,
|
||||||
|
0x003c0000 | NODEID_TO_NODE(host->node_id) << 24);
|
||||||
|
if (packet) {
|
||||||
|
packet->no_waiter = 1;
|
||||||
|
packet->generation = get_hpsb_generation(host);
|
||||||
|
ret = hpsb_send_packet(packet);
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
|
||||||
|
host->id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform a few high-level IRM responsibilities. */
|
||||||
static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
|
static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
|
||||||
{
|
{
|
||||||
quadlet_t bc;
|
quadlet_t bc;
|
||||||
@ -1424,13 +1469,8 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
|
|||||||
if (!host->is_irm || host->irm_id == (nodeid_t)-1)
|
if (!host->is_irm || host->irm_id == (nodeid_t)-1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
host->csr.broadcast_channel |= 0x40000000; /* set validity bit */
|
/* We are a 1394a-2000 compliant IRM. Set the validity bit. */
|
||||||
|
host->csr.broadcast_channel |= 0x40000000;
|
||||||
bc = cpu_to_be32(host->csr.broadcast_channel);
|
|
||||||
|
|
||||||
hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host),
|
|
||||||
(CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
|
|
||||||
&bc, sizeof(quadlet_t));
|
|
||||||
|
|
||||||
/* If there is no bus manager then we should set the root node's
|
/* If there is no bus manager then we should set the root node's
|
||||||
* force_root bit to promote bus stability per the 1394
|
* force_root bit to promote bus stability per the 1394
|
||||||
@ -1463,6 +1503,13 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some devices suspend their ports while being connected to an inactive
|
||||||
|
* host adapter, i.e. if connected before the low-level driver is
|
||||||
|
* loaded. They become visible either when physically unplugged and
|
||||||
|
* replugged, or when receiving a resume packet. Send one once. */
|
||||||
|
if (!host->resume_packet_sent && !nodemgr_send_resume_packet(host))
|
||||||
|
host->resume_packet_sent = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
* This is a device driver for the OneNAND flash for generic boards.
|
* This is a device driver for the OneNAND flash for generic boards.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/onenand.h>
|
#include <linux/mtd/onenand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
@ -39,7 +39,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct onenand_info *info;
|
struct onenand_info *info;
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
struct onenand_platform_data *pdata = pdev->dev.platform_data;
|
struct flash_platform_data *pdata = pdev->dev.platform_data;
|
||||||
struct resource *res = pdev->resource;
|
struct resource *res = pdev->resource;
|
||||||
unsigned long size = res->end - res->start + 1;
|
unsigned long size = res->end - res->start + 1;
|
||||||
int err;
|
int err;
|
||||||
|
@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
|||||||
u_char *eccbuf, struct nand_oobinfo *oobsel)
|
u_char *eccbuf, struct nand_oobinfo *oobsel)
|
||||||
{
|
{
|
||||||
struct onenand_chip *this = mtd->priv;
|
struct onenand_chip *this = mtd->priv;
|
||||||
unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
|
unsigned char *pbuf;
|
||||||
size_t total_len, len;
|
size_t total_len, len;
|
||||||
int i, written = 0;
|
int i, written = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -975,7 +975,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
|||||||
/* Loop until all keve's data has been written */
|
/* Loop until all keve's data has been written */
|
||||||
len = 0;
|
len = 0;
|
||||||
while (count) {
|
while (count) {
|
||||||
pbuf = buffer;
|
pbuf = this->page_buf;
|
||||||
/*
|
/*
|
||||||
* If the given tuple is >= pagesize then
|
* If the given tuple is >= pagesize then
|
||||||
* write it out from the iov
|
* write it out from the iov
|
||||||
@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
|||||||
int cnt = 0, thislen;
|
int cnt = 0, thislen;
|
||||||
while (cnt < mtd->oobblock) {
|
while (cnt < mtd->oobblock) {
|
||||||
thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
|
thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
|
||||||
memcpy(buffer + cnt, vecs->iov_base + len, thislen);
|
memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
|
||||||
cnt += thislen;
|
cnt += thislen;
|
||||||
len += thislen;
|
len += thislen;
|
||||||
|
|
||||||
@ -1296,6 +1296,12 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||||||
|
|
||||||
/* Block lock scheme */
|
/* Block lock scheme */
|
||||||
for (block = start; block < end; block++) {
|
for (block = start; block < end; block++) {
|
||||||
|
/* Set block address */
|
||||||
|
value = onenand_block_address(this, block);
|
||||||
|
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
|
||||||
|
/* Select DataRAM for DDP */
|
||||||
|
value = onenand_bufferram_address(this, block);
|
||||||
|
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
|
||||||
/* Set start block address */
|
/* Set start block address */
|
||||||
this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
|
this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
|
||||||
/* Write unlock command */
|
/* Write unlock command */
|
||||||
@ -1309,10 +1315,6 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||||||
& ONENAND_CTRL_ONGO)
|
& ONENAND_CTRL_ONGO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Set block address for read block status */
|
|
||||||
value = onenand_block_address(this, block);
|
|
||||||
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
|
|
||||||
|
|
||||||
/* Check lock status */
|
/* Check lock status */
|
||||||
status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
|
status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
|
||||||
if (!(status & ONENAND_WP_US))
|
if (!(status & ONENAND_WP_US))
|
||||||
@ -1346,7 +1348,6 @@ static void onenand_print_device_info(int device)
|
|||||||
|
|
||||||
static const struct onenand_manufacturers onenand_manuf_ids[] = {
|
static const struct onenand_manufacturers onenand_manuf_ids[] = {
|
||||||
{ONENAND_MFR_SAMSUNG, "Samsung"},
|
{ONENAND_MFR_SAMSUNG, "Samsung"},
|
||||||
{ONENAND_MFR_UNKNOWN, "Unknown"}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1357,17 +1358,22 @@ static const struct onenand_manufacturers onenand_manuf_ids[] = {
|
|||||||
*/
|
*/
|
||||||
static int onenand_check_maf(int manuf)
|
static int onenand_check_maf(int manuf)
|
||||||
{
|
{
|
||||||
|
int size = ARRAY_SIZE(onenand_manuf_ids);
|
||||||
|
char *name;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; onenand_manuf_ids[i].id; i++) {
|
for (i = 0; i < size; i++)
|
||||||
if (manuf == onenand_manuf_ids[i].id)
|
if (manuf == onenand_manuf_ids[i].id)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
|
if (i < size)
|
||||||
onenand_manuf_ids[i].name, manuf);
|
name = onenand_manuf_ids[i].name;
|
||||||
|
else
|
||||||
|
name = "Unknown";
|
||||||
|
|
||||||
return (i != ONENAND_MFR_UNKNOWN);
|
printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
|
||||||
|
|
||||||
|
return (i == size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1513,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
|
|||||||
this->read_bufferram = onenand_sync_read_bufferram;
|
this->read_bufferram = onenand_sync_read_bufferram;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate buffers, if necessary */
|
||||||
|
if (!this->page_buf) {
|
||||||
|
size_t len;
|
||||||
|
len = mtd->oobblock + mtd->oobsize;
|
||||||
|
this->page_buf = kmalloc(len, GFP_KERNEL);
|
||||||
|
if (!this->page_buf) {
|
||||||
|
printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
this->options |= ONENAND_PAGEBUF_ALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
this->state = FL_READY;
|
this->state = FL_READY;
|
||||||
init_waitqueue_head(&this->wq);
|
init_waitqueue_head(&this->wq);
|
||||||
spin_lock_init(&this->chip_lock);
|
spin_lock_init(&this->chip_lock);
|
||||||
@ -1574,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
|
|||||||
*/
|
*/
|
||||||
void onenand_release(struct mtd_info *mtd)
|
void onenand_release(struct mtd_info *mtd)
|
||||||
{
|
{
|
||||||
|
struct onenand_chip *this = mtd->priv;
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
#ifdef CONFIG_MTD_PARTITIONS
|
||||||
/* Deregister partitions */
|
/* Deregister partitions */
|
||||||
del_mtd_partitions (mtd);
|
del_mtd_partitions (mtd);
|
||||||
#endif
|
#endif
|
||||||
/* Deregister the device */
|
/* Deregister the device */
|
||||||
del_mtd_device (mtd);
|
del_mtd_device (mtd);
|
||||||
|
|
||||||
|
/* Free bad block table memory, if allocated */
|
||||||
|
if (this->bbm)
|
||||||
|
kfree(this->bbm);
|
||||||
|
/* Buffer allocated by onenand_scan */
|
||||||
|
if (this->options & ONENAND_PAGEBUF_ALLOC)
|
||||||
|
kfree(this->page_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(onenand_scan);
|
EXPORT_SYMBOL_GPL(onenand_scan);
|
||||||
|
@ -118,10 +118,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
|
|||||||
*/
|
*/
|
||||||
static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
|
static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
|
||||||
{
|
{
|
||||||
unsigned char data_buf[MAX_ONENAND_PAGESIZE];
|
struct onenand_chip *this = mtd->priv;
|
||||||
|
|
||||||
bd->options &= ~NAND_BBT_SCANEMPTY;
|
bd->options &= ~NAND_BBT_SCANEMPTY;
|
||||||
return create_bbt(mtd, data_buf, bd, -1);
|
return create_bbt(mtd, this->page_buf, bd, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include <linux/mtd/bbm.h>
|
#include <linux/mtd/bbm.h>
|
||||||
|
|
||||||
#define MAX_BUFFERRAM 2
|
#define MAX_BUFFERRAM 2
|
||||||
#define MAX_ONENAND_PAGESIZE (2048 + 64)
|
|
||||||
|
|
||||||
/* Scan and identify a OneNAND device */
|
/* Scan and identify a OneNAND device */
|
||||||
extern int onenand_scan(struct mtd_info *mtd, int max_chips);
|
extern int onenand_scan(struct mtd_info *mtd, int max_chips);
|
||||||
@ -110,6 +109,7 @@ struct onenand_chip {
|
|||||||
spinlock_t chip_lock;
|
spinlock_t chip_lock;
|
||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
onenand_state_t state;
|
onenand_state_t state;
|
||||||
|
unsigned char *page_buf;
|
||||||
|
|
||||||
struct nand_oobinfo *autooob;
|
struct nand_oobinfo *autooob;
|
||||||
|
|
||||||
@ -134,13 +134,12 @@ struct onenand_chip {
|
|||||||
* Options bits
|
* Options bits
|
||||||
*/
|
*/
|
||||||
#define ONENAND_CONT_LOCK (0x0001)
|
#define ONENAND_CONT_LOCK (0x0001)
|
||||||
|
#define ONENAND_PAGEBUF_ALLOC (0x1000)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OneNAND Flash Manufacturer ID Codes
|
* OneNAND Flash Manufacturer ID Codes
|
||||||
*/
|
*/
|
||||||
#define ONENAND_MFR_SAMSUNG 0xec
|
#define ONENAND_MFR_SAMSUNG 0xec
|
||||||
#define ONENAND_MFR_UNKNOWN 0x00
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct nand_manufacturers - NAND Flash Manufacturer ID Structure
|
* struct nand_manufacturers - NAND Flash Manufacturer ID Structure
|
||||||
|
Loading…
x
Reference in New Issue
Block a user