コード例 #1
0
ファイル: cfi_probe.c プロジェクト: hugh712/Jollen
static int cfi_chip_setup(struct map_info *map, 
		   struct cfi_private *cfi)
{
	int ofs_factor = cfi->interleave*cfi->device_type;
	__u32 base = 0;
	int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
	int i;

#ifdef DEBUG_CFI
	printk("Number of erase regions: %d\n", num_erase_regions);
#endif
	if (!num_erase_regions)
		return 0;

	cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
	if (!cfi->cfiq) {
		printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
		return 0;
	}
	
	memset(cfi->cfiq,0,sizeof(struct cfi_ident));	
	
	cfi->cfi_mode = CFI_MODE_CFI;
	cfi->fast_prog=1;		/* CFI supports fast programming */
	
	/* Read the CFI info structure */
	for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
		((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
	}
	
	/* Do any necessary byteswapping */
	cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
	
	cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR);
	cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID);
	cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR);
	cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc);
	cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize);

#ifdef DEBUG_CFI
	/* Dump the information therein */
	print_cfi_ident(cfi->cfiq);
#endif

	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
		cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
		
#ifdef DEBUG_CFI		
		printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
		       i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, 
		       (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
#endif
	}
	/* Put it back into Read Mode */
	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);

	return 1;
}
コード例 #2
0
static int cfi_chip_setup(struct map_info *map,
                          struct cfi_private *cfi)
{
    int ofs_factor = cfi->interleave*cfi->device_type;
    __u32 base = 0;
    int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
    int i;

#ifdef DEBUG_CFI
    printk("Number of erase regions: %d\n", num_erase_regions);
#endif
    if (!num_erase_regions)
        return 0;

    cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
    if (!cfi->cfiq) {
        printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
        return 0;
    }

    memset(cfi->cfiq,0,sizeof(struct cfi_ident));

    cfi->cfi_mode = CFI_MODE_CFI;
    cfi->fast_prog=1;		/* CFI supports fast programming */

    /* Read the CFI info structure */
    for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
        ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
    }

    /* Do any necessary byteswapping */
    cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);

    cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR);
    cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID);
    cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR);
    cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc);
    cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize);

    /*
     * ST screwed up the CFI interface for buffer writes on their parts,
     * so this needs to be fixed up by hand here.
         *
         * A possible enhancment is that instead of just reverting back
         * to word write (as this does), we could use the ST specific double
         * word write instead.
     */

    if (cfi_read_query(map,base) == 0x20) {
        cfi->cfiq->BufWriteTimeoutTyp = 0;
        cfi->cfiq->BufWriteTimeoutMax = 0;
    }

#ifdef DEBUG_CFI
    /* Dump the information therein */
    print_cfi_ident(cfi->cfiq);
#endif

    for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
        cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);

#ifdef DEBUG_CFI
        printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
               i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
               (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
#endif
    }
    /* Put it back into Read Mode */
    cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);

    /* some devices don't respond to 0xF0, so send 0xFF to be sure */
    cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);

    return 1;
}