Example #1
0
static int mmc_max_clock_set(void *data, u64 val)
{
	struct mmc_host *host = data;
	int err = -EINVAL;
	unsigned long freq = val;
	unsigned int old_freq;

	if (!host || (val < host->f_min))
		goto out;

	mmc_rpm_hold(host, &host->class_dev);
	mmc_claim_host(host);
	if (host->bus_ops && host->bus_ops->change_bus_speed) {
		old_freq = host->f_max;
		host->f_max = freq;

		err = host->bus_ops->change_bus_speed(host, &freq);

		if (err)
			host->f_max = old_freq;
	}
	mmc_release_host(host);
	mmc_rpm_release(host, &host->class_dev);
out:
	return err;
}
Example #2
0
static int mmc_clock_opt_set(void *data, u64 val)
{
	struct mmc_host *host = data;

	/* We need this check due to input value is u64 */
	if (val > host->f_max)
		return -EINVAL;

	mmc_rpm_hold(host, &host->class_dev);
	mmc_claim_host(host);
	mmc_set_clock(host, (unsigned int) val);
	mmc_release_host(host);
	mmc_rpm_release(host, &host->class_dev);

	return 0;
}
static int mmc_clock_opt_set(void *data, u64 val)
{
	struct mmc_host *host = data;

	
	if (val > host->f_max)
		return -EINVAL;

	mmc_rpm_hold(host, &host->class_dev);
	mmc_claim_host(host);
	mmc_set_clock(host, (unsigned int) val);
	mmc_release_host(host);
	mmc_rpm_release(host, &host->class_dev);

	return 0;
}
Example #4
0
static int mmc_dbg_card_status_get(void *data, u64 *val)
{
	struct mmc_card	*card = data;
	u32		status;
	int		ret;

	mmc_rpm_hold(card->host, &card->dev);
	mmc_claim_host(card->host);

	ret = mmc_send_status(data, &status);
	if (!ret)
		*val = status;

	mmc_release_host(card->host);
	mmc_rpm_release(card->host, &card->dev);

	return ret;
}
Example #5
0
static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
{
	struct mmc_card *card = inode->i_private;
	char *buf;
	ssize_t n = 0;
	u8 *ext_csd;
	int err, i;

	buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	ext_csd = kmalloc(512, GFP_KERNEL);
	if (!ext_csd) {
		err = -ENOMEM;
		goto out_free;
	}

	mmc_rpm_hold(card->host, &card->dev);
	mmc_claim_host(card->host);
	err = mmc_send_ext_csd(card, ext_csd);
	mmc_release_host(card->host);
	mmc_rpm_release(card->host, &card->dev);
	if (err)
		goto out_free;

	for (i = 511; i >= 0; i--)
		n += sprintf(buf + n, "%02x", ext_csd[i]);
	n += sprintf(buf + n, "\n");
	BUG_ON(n != EXT_CSD_STR_LEN);

	filp->private_data = buf;
	kfree(ext_csd);
	return 0;

out_free:
	kfree(buf);
	kfree(ext_csd);
	return err;
}
static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
#endif
{
#ifdef CONFIG_MACH_LGE
	struct mmc_card *card = s->private;
#else
	struct mmc_card *card = inode->i_private;
	char *buf;
	ssize_t n = 0;
#endif
	u8 *ext_csd;
#ifdef CONFIG_MACH_LGE
	u8 ext_csd_rev;
	int err;
	const char *str;
	char *buf_for_health_report;
	char *buf_for_firmwware_version;
	ssize_t output = 0;
	int cnt;
#else
	int err, i;

	buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
#endif
	ext_csd = kmalloc(512, GFP_KERNEL);
	if (!ext_csd) {
		err = -ENOMEM;
		goto out_free;
	}

	mmc_rpm_hold(card->host, &card->dev);
	mmc_claim_host(card->host);
	err = mmc_send_ext_csd(card, ext_csd);
	mmc_release_host(card->host);
	mmc_rpm_release(card->host, &card->dev);
	if (err)
		goto out_free;
#ifdef CONFIG_MACH_LGE

	ext_csd_rev = ext_csd[192];
#else
	for (i = 0; i < 512; i++)
		n += sprintf(buf + n, "%02x", ext_csd[i]);
	n += sprintf(buf + n, "\n");
	BUG_ON(n != EXT_CSD_STR_LEN);

	filp->private_data = buf;
	kfree(ext_csd);
	return 0;
#endif

#ifdef CONFIG_MACH_LGE
	switch (ext_csd_rev) {
	case 7:
	       str = "5.0";
	       break;
       case 6:
               str = "4.5";
               break;
       case 5:
               str = "4.41";
               break;
       case 3:
               str = "4.3";
               break;
       case 2:
               str = "4.2";
               break;
       case 1:
               str = "4.1";
               break;
       case 0:
               str = "4.0";
               break;
       default:
               goto out_free;
       }
       seq_printf(s, "Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, str);
       if (ext_csd_rev < 3)
               goto out_free; /* No ext_csd */
	if (ext_csd_rev >= 7) {
		seq_printf(s, "[505] Extended Security Commands Error, ext_security_err: 0x%02x\n", ext_csd[505]);
	}
       seq_printf(s, "[504] Supported Command Sets, s_cmd_set: 0x%02x\n", ext_csd[504]);
       seq_printf(s, "[503] HPI features, hpi_features: 0x%02x\n", ext_csd[503]);
       seq_printf(s, "[502] Background operations support, bkops_support: 0x%02x\n", ext_csd[502]);
       if (ext_csd_rev >= 6) {
		seq_printf(s, "[501] Max packed read commands, max_packed_reads: 0x%02x\n", ext_csd[501]);
		seq_printf(s, "[500] Max packed write commands, max_packed_writes: 0x%02x\n", ext_csd[500]);
		seq_printf(s, "[499] Data Tag Support, data_tag_support: 0x%02x\n", ext_csd[499]);
		seq_printf(s, "[498] Tag Unit Size, tag_unit_size: 0x%02x\n", ext_csd[498]);
		seq_printf(s, "[497] Tag Resources Size, tag_res_size: 0x%02x\n", ext_csd[497]);
		seq_printf(s, "[496] Context management capabilities, context_capabilities: 0x%02x\n", ext_csd[496]);
		seq_printf(s, "[495] Large Unit size, large_unit_size_m1: 0x%02x\n", ext_csd[495]);
		seq_printf(s, "[494] Extended partitions attribute support, ext_support: 0x%02x\n", ext_csd[494]);
		if (ext_csd_rev >= 7) {
			buf_for_health_report = kmalloc(66, GFP_KERNEL);
			if (!buf_for_health_report)
			return -ENOMEM;
			buf_for_firmwware_version = kmalloc(18, GFP_KERNEL);
			if (!buf_for_firmwware_version)
			return -ENOMEM;
			seq_printf(s, "[493] Supported modes, supported_modes: 0x%02x\n", ext_csd[493]);
			seq_printf(s, "[492] Ffu features, ffu_features: 0x%02x\n", ext_csd[492]);
			seq_printf(s, "[491] Operation codes timeout, operation_code_timeout: 0x%02x\n", ext_csd[491]);
			seq_printf(s, "[490:487] Ffu features, ffu_features: 0x%08x\n", (ext_csd[487] << 0) | (ext_csd[488] << 8) | (ext_csd[489] << 16) | (ext_csd[490] << 24));
			seq_printf(s, "[305:302] Number of FW sectors correctly programmed, number_of_fw_sectors_correctly_programmed: 0x%08x\n", (ext_csd[302] << 0) | (ext_csd[303] << 8) | (ext_csd[304] << 16) | (ext_csd[305] << 24));
			output = 0;
			for (cnt = 301 ; cnt >= 270 ; cnt--)
				output += sprintf(buf_for_health_report + output, "%02x", ext_csd[cnt]);
			output += sprintf(buf_for_health_report + output, "\n");
			seq_printf(s, "[301:270] Vendor proprietary health report, vendor_proprietary_health_report(raw data): %s", buf_for_health_report); //mina.park;
			kfree(buf_for_health_report);
			seq_printf(s, "[269] Device life time estimation type B, device_life_time_est_typ_b: 0x%02x\n", ext_csd[269]);
			seq_printf(s, "[268] Device life time estimation type A, device_life_time_est_typ_a: 0x%02x\n", ext_csd[268]);
			seq_printf(s, "[267] Pre EOL information, pre_eol_info: 0x%02x\n", ext_csd[267]);
			seq_printf(s, "[266] Optimal read size, optimal_read_size: 0x%02x\n", ext_csd[266]);
			seq_printf(s, "[265] Optimal write size, optimal_write_size: 0x%02x\n", ext_csd[265]);
			seq_printf(s, "[264] Optimal trim unit size, optimal_trim_unit_size: 0x%02x\n", ext_csd[264]);
			seq_printf(s, "[263:262] Device version, device_version: 0x%02x\n", (ext_csd[262] << 0) | (ext_csd[263] << 8));
			output=0;
			for (cnt = 261 ; cnt >= 254 ; cnt--)
				output += sprintf(buf_for_firmwware_version + output, "%02x", ext_csd[cnt]);
			output += sprintf(buf_for_firmwware_version + output, "\n");
			seq_printf(s, "[261:254] Firmware version, firmwware_version(raw data): %s", buf_for_firmwware_version); //mina.park;
			kfree(buf_for_firmwware_version);
			seq_printf(s, "[253] Power class for 200MHz, DDR at VCC=3.6V, pwr_cl_ddr_200_360: 0x%02x\n", ext_csd[253]);
		}
		seq_printf(s, "[252:249] Cache size, cache_size %d KiB\n", (ext_csd[249] << 0) |
                          (ext_csd[250] << 8) | (ext_csd[251] << 16) |
                          (ext_csd[252] << 24));
		seq_printf(s, "[248] Generic CMD6 timeout, generic_cmd6_time: 0x%02x\n", ext_csd[248]);
		seq_printf(s, "[247] Power off notification timeout, power_off_long_time: 0x%02x\n", ext_csd[247]);
		seq_printf(s, "[246] Background operations status, bkops_status: 0x%02x\n", ext_csd[246]);
		seq_printf(s, "[245:242] Number of correctly programmed sectors, correctly_prg_sectors_num %d KiB\n", (ext_csd[242] << 0) | (ext_csd[243] << 8) | (ext_csd[244] << 16) | (ext_csd[245] << 24));
       }
       if (ext_csd_rev >= 5) {
               seq_printf(s, "[241] 1st initialization time after partitioning, ini_timeout_ap: 0x%02x\n", ext_csd[241]);
               seq_printf(s, "[239] Power class for 52MHz, DDR at 3.6V, pwr_cl_ddr_52_360: 0x%02x\n", ext_csd[239]);
               seq_printf(s, "[238] POwer class for 52MHz, DDR at 1.95V, pwr_cl_ddr_52_195: 0x%02x\n", ext_csd[238]);
               if (ext_csd_rev >= 6) {
			seq_printf(s, "[237] Power class for 200MHz, SDR at 3.6V, pwr_cl_200_360: 0x%02x\n", ext_csd[237]);
			seq_printf(s, "[236] Power class for 200MHz, SDR at 1.95V, pwr_cl_200_195: 0x%02x\n", ext_csd[236]);
               }
               seq_printf(s, "[235] Minimun Write Performance for 8bit at 52MHz in DDR mode, min_perf_ddr_w_8_52: 0x%02x\n", ext_csd[235]);
               seq_printf(s, "[234] Minimun Read Performance for 8bit at 52MHz in DDR modemin_perf_ddr_r_8_52: 0x%02x\n", ext_csd[234]);
               seq_printf(s, "[232] TRIM Multiplier, trim_mult: 0x%02x\n", ext_csd[232]);
               seq_printf(s, "[231] Secure Feature support, sec_feature_support: 0x%02x\n", ext_csd[231]);
       }
	if (ext_csd_rev == 5 || ext_csd_rev == 7) { /* Obsolete in 4.5 */  /*---->revived in 5.0*/
               seq_printf(s, "[230] Secure Erase Multiplier, sec_erase_mult: 0x%02x\n", ext_csd[230]);
               seq_printf(s, "[229] Secure TRIM Multiplier, sec_trim_mult:  0x%02x\n", ext_csd[229]);
       }
       seq_printf(s, "[228] Boot information, boot_info: 0x%02x\n", ext_csd[228]);
       seq_printf(s, "[226] Boot partition size, boot_size_mult : 0x%02x\n", ext_csd[226]);
       seq_printf(s, "[225] Access size, acc_size: 0x%02x\n", ext_csd[225]);
       seq_printf(s, "[224] High-capacity erase unit size, hc_erase_grp_size: 0x%02x\n", ext_csd[224]);
       seq_printf(s, "[223] High-capacity erase timeout, erase_timeout_mult: 0x%02x\n", ext_csd[223]);
       seq_printf(s, "[222] Reliable write sector count, rel_wr_sec_c: 0x%02x\n", ext_csd[222]);
       seq_printf(s, "[221] High-capacity write protect group size, hc_wp_grp_size: 0x%02x\n", ext_csd[221]);
       seq_printf(s, "[220] Sleep current(VCC), s_c_vcc: 0x%02x\n", ext_csd[220]);
       seq_printf(s, "[219] Sleep current(VCCQ), s_c_vccq: 0x%02x\n", ext_csd[219]);
	if (ext_csd_rev == 7) {
		seq_printf(s, "[218] Production state awareness timeout, production_state_awareness_timeout: 0x%02x\n", ext_csd[218]);
	}
       seq_printf(s, "[217] Sleep/awake timeout, s_a_timeout: 0x%02x\n", ext_csd[217]);
		if (ext_csd_rev == 7) {
		seq_printf(s, "[216] Sleep notification timeout, sleep_notification_time: 0x%02x\n", ext_csd[216]);
	}
       seq_printf(s, "[215:212] Sector Count, sec_count: 0x%08x\n", (ext_csd[215] << 24) |(ext_csd[214] << 16) | (ext_csd[213] << 8)  | ext_csd[212]);
       seq_printf(s, "[210] Minimum Write Performance for 8bit at 52MHz, min_perf_w_8_52: 0x%02x\n", ext_csd[210]);
       seq_printf(s, "[209] Minimum Read Performance for 8bit at 52MHz, min_perf_r_8_52: 0x%02x\n", ext_csd[209]);
       seq_printf(s, "[208] Minimum Write Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_w_8_26_4_52: 0x%02x\n", ext_csd[208]);
       seq_printf(s, "[207] Minimum Read Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_r_8_26_4_52: 0x%02x\n", ext_csd[207]);
       seq_printf(s, "[206] Minimum Write Performance for 4bit at 26MHz, min_perf_w_4_26: 0x%02x\n", ext_csd[206]);
       seq_printf(s, "[205] Minimum Read Performance for 4bit at 26MHz, min_perf_r_4_26: 0x%02x\n", ext_csd[205]);
       seq_printf(s, "[203] Power class for 26MHz at 3.6V, pwr_cl_26_360: 0x%02x\n", ext_csd[203]);
       seq_printf(s, "[202] Power class for 52MHz at 3.6V, pwr_cl_52_360: 0x%02x\n", ext_csd[202]);
       seq_printf(s, "[201] Power class for 26MHz at 1.95V, pwr_cl_26_195: 0x%02x\n", ext_csd[201]);
       seq_printf(s, "[200] Power class for 52MHz at 1.95V, pwr_cl_52_195: 0x%02x\n", ext_csd[200]);
       if (ext_csd_rev >= 5) {
               seq_printf(s, "[199] Partition switching timing, partition_switch_time: 0x%02x\n", ext_csd[199]);
               seq_printf(s, "[198] Out-of-interrupt busy timing, out_of_interrupt_time: 0x%02x\n", ext_csd[198]);
       }
       if (ext_csd_rev >= 6)
		seq_printf(s, "[197] IO Driver Strength, driver_strength: 0x%02x\n", ext_csd[197]);
	seq_printf(s, "[196] Device type, device_type: 0x%02x\n", ext_csd[196]);
       seq_printf(s, "[194] CSD structure version, csd_structure: 0x%02x\n", ext_csd[194]);
       seq_printf(s, "[192] Extended CSD revision, ext_csd_rev: 0x%02x\n", ext_csd[192]);
       seq_printf(s, "[191] Command set, cmd_set: 0x%02x\n", ext_csd[191]);
       seq_printf(s, "[189] Command set revision, cmd_set_rev: 0x%02x\n", ext_csd[189]);
       seq_printf(s, "[187] Power class, power_class: 0x%02x\n", ext_csd[187]);
       seq_printf(s, "[185] High-speed interface timing, hs_timing: 0x%02x\n", ext_csd[185]);
       seq_printf(s, "[181] Erased memory content, erased_mem_cont: 0x%02x\n", ext_csd[181]);
       seq_printf(s, "[179] Partition configuration, partition_config: 0x%02x\n", ext_csd[179]);
       seq_printf(s, "[178] Boot config protection, boot_config_prot: 0x%02x\n", ext_csd[178]);
	seq_printf(s, "[177] Boot bus Conditions, boot_bus_conditions: 0x%02x\n", ext_csd[177]);
       seq_printf(s, "[175] High-density erase group definition, erase_group_def: 0x%02x\n", ext_csd[175]);
       if (ext_csd_rev >= 5) {
		seq_printf(s, "[174] Boot write protection status registers, boot_wp_status: 0x%02x\n", ext_csd[174]);
               seq_printf(s, "[173] Boot area write protection register, boot_wp: 0x%02x\n", ext_csd[173]);
               seq_printf(s, "[171] User area write protection register, user_wp: 0x%02x\n", ext_csd[171]);
               seq_printf(s, "[169] FW configuration, fw_config: 0x%02x\n", ext_csd[169]);
               seq_printf(s, "[168] RPMB Size, rpmb_size_mult: 0x%02x\n", ext_csd[168]);
               seq_printf(s, "[167] Write reliability setting register, wr_rel_set: 0x%02x\n", ext_csd[167]);
               seq_printf(s, "[166] Write reliability parameter register, wr_rel_param: 0x%02x\n", ext_csd[166]);
               seq_printf(s, "[163] Enable background operations handshake, bkops_en: 0x%02x\n", ext_csd[163]);
               seq_printf(s, "[162] H/W reset function, rst_n_function: 0x%02x\n", ext_csd[162]);
		seq_printf(s, "[161] HPI management, hpi_mgmt: 0x%02x\n", ext_csd[161]);
		seq_printf(s, "[160] Partitioning Support, partitioning_support: 0x%02x\n", ext_csd[160]);
               seq_printf(s, "[159:157] Max Enhanced Area Size, max_enh_size_mult: 0x%06x\n", (ext_csd[159] << 16) | (ext_csd[158] << 8) |ext_csd[157]);
               seq_printf(s, "[156] Partitions attribute, partitions_attribute: 0x%02x\n", ext_csd[156]);
               seq_printf(s, "[155] Partitioning Setting, partition_setting_completed: 0x%02x\n", ext_csd[155]);
               seq_printf(s, "[154:152] General Purpose Partition Size, gp_size_mult_4: 0x%06x\n", (ext_csd[154] << 16) |(ext_csd[153] << 8) | ext_csd[152]);
               seq_printf(s, "[151:149] General Purpose Partition Size, gp_size_mult_3: 0x%06x\n", (ext_csd[151] << 16) |(ext_csd[150] << 8) | ext_csd[149]);
               seq_printf(s, "[148:146] General Purpose Partition Size, gp_size_mult_2: 0x%06x\n", (ext_csd[148] << 16) |(ext_csd[147] << 8) | ext_csd[146]);
               seq_printf(s, "[145:143] General Purpose Partition Size, gp_size_mult_1: 0x%06x\n", (ext_csd[145] << 16) |(ext_csd[144] << 8) | ext_csd[143]);
               seq_printf(s, "[142:140] Enhanced User Data Area Size, enh_size_mult: 0x%06x\n", (ext_csd[142] << 16) |(ext_csd[141] << 8) | ext_csd[140]);
		seq_printf(s, "[139:136] Enhanced User Data Start Address, enh_start_addr: 0x%06x\n", (ext_csd[139] << 24) | (ext_csd[138] << 16) | (ext_csd[137] << 8) | ext_csd[136]);
               seq_printf(s, "[134] Bad Block Management mode, sec_bad_blk_mgmnt: 0x%02x\n", ext_csd[134]);
       }
       if (ext_csd_rev >= 6) {
               int j;
		seq_printf(s, "[131] Periodic Wake-up, periodic_wakeup: 0x%02x\n", ext_csd[131]);
		seq_printf(s, "[130] Program CID CSD in DDR mode support, program_cid_csd_ddr_support: 0x%02x\n",
                          ext_csd[130]);
               for (j = 127; j >= 64; j--)
			seq_printf(s, "[127:64] Vendor Specific Fields, vendor_specific_field[%d]: 0x%02x\n",
                                  j, ext_csd[j]);
		seq_printf(s, "[63] Native sector size, native_sector_size: 0x%02x\n", ext_csd[63]);
		seq_printf(s, "[62] Sector size emulation, use_native_sector: 0x%02x\n", ext_csd[62]);
		seq_printf(s, "[61] Sector size, data_sector_size: 0x%02x\n", ext_csd[61]);
		seq_printf(s, "[60] 1st initialization after disabling sector size emulation, ini_timeout_emu: 0x%02x\n", ext_csd[60]);
		seq_printf(s, "[59] Class 6 commands control, class_6_ctrl: 0x%02x\n", ext_csd[59]);
		seq_printf(s, "[58] Number of addressed group to be Released, dyncap_needed: 0x%02x\n", ext_csd[58]);
		seq_printf(s, "[57:56] Exception events control, exception_events_ctrl: 0x%04x\n",
                          (ext_csd[57] << 8) | ext_csd[56]);
		seq_printf(s, "[55:54] Exception events status, exception_events_status: 0x%04x\n",
                          (ext_csd[55] << 8) | ext_csd[54]);
		seq_printf(s, "[53:52] Extended Partitions Attribute, ext_partitions_attribute: 0x%04x\n",
                          (ext_csd[53] << 8) | ext_csd[52]);
               for (j = 51; j >= 37; j--)
			seq_printf(s, "[51:37]Context configuration, context_conf[%d]: 0x%02x\n", j,
                                  ext_csd[j]);
		seq_printf(s, "[36] Packed command status, packed_command_status: 0x%02x\n", ext_csd[36]);
		seq_printf(s, "[35] Packed command failure index, packed_failure_index: 0x%02x\n", ext_csd[35]);
		seq_printf(s, "[34] Power Off Notification, power_off_notification: 0x%02x\n", ext_csd[34]);
		seq_printf(s, "[33] Control to turn the Cache On Off, cache_ctrl: 0x%02x\n", ext_csd[33]);
       }
#endif
out_free:
#ifndef CONFIG_MACH_LGE
	kfree(buf);
#endif
	kfree(ext_csd);
	return err;
}
static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
#endif
{
#ifdef CONFIG_MACH_LGE
	/* LGE_CHANGE
	* http://www.mail-archive.com/[email protected]/msg10669.html
	* 2013-06-28, [email protected]
	*/
	struct mmc_card *card = s->private;
#else
	struct mmc_card *card = inode->i_private;
	char *buf;
	ssize_t n = 0;
#endif
	u8 *ext_csd;
#ifdef CONFIG_MACH_LGE
	/* LGE_CHANGE
	* http://www.mail-archive.com/[email protected]/msg10669.html
	* 2013-06-28, [email protected]
	*/
	u8 ext_csd_rev;
	int err;
	const char *str;
#else
	int err, i;

	buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
#endif
	ext_csd = kmalloc(512, GFP_KERNEL);
	if (!ext_csd) {
		err = -ENOMEM;
		goto out_free;
	}

	mmc_rpm_hold(card->host, &card->dev);
	mmc_claim_host(card->host);
	err = mmc_send_ext_csd(card, ext_csd);
	mmc_release_host(card->host);
	mmc_rpm_release(card->host, &card->dev);
	if (err)
		goto out_free;
#ifdef CONFIG_MACH_LGE
	/* LGE_CHANGE
	* http://www.mail-archive.com/[email protected]/msg10669.html
	* 2013-06-28, [email protected]
	*/
	ext_csd_rev = ext_csd[192];
#else
	for (i = 511; i >= 0; i--)
		n += sprintf(buf + n, "%02x", ext_csd[i]);
	n += sprintf(buf + n, "\n");
	BUG_ON(n != EXT_CSD_STR_LEN);

	filp->private_data = buf;
	kfree(ext_csd);
	return 0;
#endif

#ifdef CONFIG_MACH_LGE
	/* LGE_CHANGE
	 * http://www.mail-archive.com/[email protected]/msg10669.html
	 2013-06-28, [email protected]
	 */

	switch (ext_csd_rev) {
	case 6:
		str = "4.5";
		break;
	case 5:
		str = "4.41";
		break;
	case 3:
		str = "4.3";
		break;
	case 2:
		str = "4.2";
		break;
	case 1:
		str = "4.1";
		break;
	case 0:
		str = "4.0";
		break;
	default:
		goto out_free;
	}
	seq_printf(s, "Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, str);

	if (ext_csd_rev < 3)
		goto out_free; /* No ext_csd */

	/* Parse the Extended CSD registers.
	 * Reserved bit should be read as "0" in case of spec older
	 * than A441.
	 */
	/* B45: reserved [511:505] */
	seq_printf(s, "[504] Supported Command Sets, s_cmd_set: 0x%02x\n", ext_csd[504]);
	seq_printf(s, "[503] HPI features, hpi_features: 0x%02x\n", ext_csd[503]);
	seq_printf(s, "[502] Background operations support, bkops_support: 0x%02x\n", ext_csd[502]);

	if (ext_csd_rev >= 6) {
		seq_printf(s, "[501] Max packed read commands, max_packed_reads: 0x%02x\n", ext_csd[501]);
		seq_printf(s, "[500] Max packed write commands, max_packed_writes: 0x%02x\n", ext_csd[500]);
		seq_printf(s, "[499] Data Tag Support, data_tag_support: 0x%02x\n", ext_csd[499]);
		seq_printf(s, "[498] Tag Unit Size, tag_unit_size: 0x%02x\n", ext_csd[498]);
		seq_printf(s, "[497] Tag Resources Size, tag_res_size: 0x%02x\n", ext_csd[497]);
		seq_printf(s, "[496] Context management capabilities, context_capabilities: 0x%02x\n", ext_csd[496]);
		seq_printf(s, "[495] Large Unit size, large_unit_size_m1: 0x%02x\n", ext_csd[495]);
		seq_printf(s, "[494] Extended partitions attribute support, ext_support: 0x%02x\n", ext_csd[494]);
		/* B45: reserved [493:253] */
		seq_printf(s, "[252:249] Cache size, cache_size %d KiB\n", ext_csd[249] << 0 |
				(ext_csd[250] << 8) | (ext_csd[251] << 16) |
				(ext_csd[252] << 24));
		seq_printf(s, "[248] Generic CMD6 timeout, generic_cmd6_time: 0x%02x\n", ext_csd[248]);
		seq_printf(s, "[247] Power off notification timeout, power_off_long_time: 0x%02x\n", ext_csd[247]);
		seq_printf(s, "[246] Background operations status, bkops_status: 0x%02x\n", ext_csd[246]);
		seq_printf(s, "[245:242] Number of correctly programmed sectors, correctly_prg_sectors_num %d KiB\n", ext_csd[242] << 0 |
				(ext_csd[243] << 8) | (ext_csd[244] << 16) |
				(ext_csd[245] << 24));

	}
	/* B45: Reserved [493:253]
	 * A441: Reserved [501:247]
	 * A43: reserved [246:229] */
	if (ext_csd_rev >= 5) {
		seq_printf(s, "[241] 1st initialization time after partitioning, ini_timeout_ap: 0x%02x\n", ext_csd[241]);
		/* B45: reserved [240] */
		/* A441: reserved [240] */
		seq_printf(s, "[239] Power class for 52MHz, DDR at 3.6V, pwr_cl_ddr_52_360: 0x%02x\n", ext_csd[239]);
		seq_printf(s, "[238] POwer class for 52MHz, DDR at 1.95V, pwr_cl_ddr_52_195: 0x%02x\n", ext_csd[238]);

		/* A441: reserved [237-236] */

		if (ext_csd_rev >= 6) {
			seq_printf(s, "[237] Power class for 200MHz, SDR at 3.6V, pwr_cl_200_360: 0x%02x\n", ext_csd[237]);
			seq_printf(s, "[236] Power class for 200MHz, SDR at 1.95V, pwr_cl_200_195: 0x%02x\n", ext_csd[236]);
		}

		seq_printf(s, "[235] Minimun Write Performance for 8bit at 52MHz in DDR mode, min_perf_ddr_w_8_52: 0x%02x\n", ext_csd[235]);
		seq_printf(s, "[234] Minimun Read Performance for 8bit at 52MHz in DDR modemin_perf_ddr_r_8_52: 0x%02x\n", ext_csd[234]);
		/* B45: reserved [233] */
		/* A441: reserved [233] */
		seq_printf(s, "[232] TRIM Multiplier, trim_mult: 0x%02x\n", ext_csd[232]);
		seq_printf(s, "[231] Secure Feature support, sec_feature_support: 0x%02x\n", ext_csd[231]);
	}
	if (ext_csd_rev == 5) { /* Obsolete in 4.5 */
		seq_printf(s, "[230] Secure Erase Multiplier, sec_erase_mult: 0x%02x\n", ext_csd[230]);
		seq_printf(s, "[229] Secure TRIM Multiplier, sec_trim_mult:  0x%02x\n", ext_csd[229]);
	}
	seq_printf(s, "[228] Boot information, boot_info: 0x%02x\n", ext_csd[228]);
	/* B45: reserved [227] */
	/* A441/A43: reserved [227] */
	seq_printf(s, "[226] Boot partition size, boot_size_mult : 0x%02x\n", ext_csd[226]);
	seq_printf(s, "[225] Access size, acc_size: 0x%02x\n", ext_csd[225]);
	seq_printf(s, "[224] High-capacity erase unit size, hc_erase_grp_size: 0x%02x\n", ext_csd[224]);
	seq_printf(s, "[223] High-capacity erase timeout, erase_timeout_mult: 0x%02x\n", ext_csd[223]);
	seq_printf(s, "[222] Reliable write sector count, rel_wr_sec_c: 0x%02x\n", ext_csd[222]);
	seq_printf(s, "[221] High-capacity write protect group size, hc_wp_grp_size: 0x%02x\n", ext_csd[221]);
	seq_printf(s, "[220] Sleep current(VCC), s_c_vcc: 0x%02x\n", ext_csd[220]);
	seq_printf(s, "[219] Sleep current(VCCQ), s_c_vccq: 0x%02x\n", ext_csd[219]);
	/* B45: reserved [218] */
	/* A441/A43: reserved [218] */
	seq_printf(s, "[217] Sleep/awake timeout, s_a_timeout: 0x%02x\n", ext_csd[217]);
	/* B45: reserved [216] */
	/* A441/A43: reserved [216] */
	seq_printf(s, "[215:212] Sector Count, sec_count: 0x%08x\n", (ext_csd[215] << 24) | (ext_csd[214] << 16) | (ext_csd[213] << 8)  | ext_csd[212]);
	/* B45: reserved [211] */
	/* A441/A43: reserved [211] */
	seq_printf(s, "[210] Minimum Write Performance for 8bit at 52MHz, min_perf_w_8_52: 0x%02x\n", ext_csd[210]);
	seq_printf(s, "[209] Minimum Read Performance for 8bit at 52MHz, min_perf_r_8_52: 0x%02x\n", ext_csd[209]);
	seq_printf(s, "[208] Minimum Write Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_w_8_26_4_52: 0x%02x\n", ext_csd[208]);
	seq_printf(s, "[207] Minimum Read Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_r_8_26_4_52: 0x%02x\n", ext_csd[207]);
	seq_printf(s, "[206] Minimum Write Performance for 4bit at 26MHz, min_perf_w_4_26: 0x%02x\n", ext_csd[206]);
	seq_printf(s, "[205] Minimum Read Performance for 4bit at 26MHz, min_perf_r_4_26: 0x%02x\n", ext_csd[205]);
	/* B45: reserved [204] */
	/* A441/A43: reserved [204] */
	seq_printf(s, "[203] Power class for 26MHz at 3.6V, pwr_cl_26_360: 0x%02x\n", ext_csd[203]);
	seq_printf(s, "[202] Power class for 52MHz at 3.6V, pwr_cl_52_360: 0x%02x\n", ext_csd[202]);
	seq_printf(s, "[201] Power class for 26MHz at 1.95V, pwr_cl_26_195: 0x%02x\n", ext_csd[201]);
	seq_printf(s, "[200] Power class for 52MHz at 1.95V, pwr_cl_52_195: 0x%02x\n", ext_csd[200]);

	/* A43: reserved [199:198] */
	if (ext_csd_rev >= 5) {
		seq_printf(s, "[199] Partition switching timing, partition_switch_time: 0x%02x\n", ext_csd[199]);
		seq_printf(s, "[198] Out-of-interrupt busy timing, out_of_interrupt_time: 0x%02x\n", ext_csd[198]);
	}

	/* B45: reserved [195] [193] [190] [188] [186] [184] [182] [180] [176] */
	/* A441/A43: reserved   [197] [195] [193] [190] [188]
	 * [186] [184] [182] [180] [176] */

	if (ext_csd_rev >= 6)
		seq_printf(s, "[197] IO Driver Strength, driver_strength: 0x%02x\n", ext_csd[197]);

	seq_printf(s, "[196] Device type, device_type: 0x%02x\n", ext_csd[196]);
	seq_printf(s, "[194] CSD structure version, csd_structure: 0x%02x\n", ext_csd[194]);
	seq_printf(s, "[192] Extended CSD revision, ext_csd_rev: 0x%02x\n", ext_csd[192]);
	seq_printf(s, "[191] Command set, cmd_set: 0x%02x\n", ext_csd[191]);
	seq_printf(s, "[189] Command set revision, cmd_set_rev: 0x%02x\n", ext_csd[189]);
	seq_printf(s, "[187] Power class, power_class: 0x%02x\n", ext_csd[187]);
	seq_printf(s, "[185] High-speed interface timing, hs_timing: 0x%02x\n", ext_csd[185]);
	/* bus_width: ext_csd[183] not readable */
	seq_printf(s, "[181] Erased memory content, erased_mem_cont: 0x%02x\n", ext_csd[181]);
	seq_printf(s, "[179] Partition configuration, partition_config: 0x%02x\n", ext_csd[179]);
	seq_printf(s, "[178] Boot config protection, boot_config_prot: 0x%02x\n", ext_csd[178]);
	seq_printf(s, "[177] Boot bus Conditions, boot_bus_conditions: 0x%02x\n", ext_csd[177]);
	seq_printf(s, "[175] High-density erase group definition, erase_group_def: 0x%02x\n", ext_csd[175]);

	/* A43: reserved [174:0] */
	if (ext_csd_rev >= 5) {
		seq_printf(s, "[174] Boot write protection status registers, boot_wp_status: 0x%02x\n", ext_csd[174]);
		seq_printf(s, "[173] Boot area write protection register, boot_wp: 0x%02x\n", ext_csd[173]);
		/* B45, A441: reserved [172] */
		seq_printf(s, "[171] User area write protection register, user_wp: 0x%02x\n", ext_csd[171]);
		/* B45, A441: reserved [170] */
		seq_printf(s, "[169] FW configuration, fw_config: 0x%02x\n", ext_csd[169]);
		seq_printf(s, "[168] RPMB Size, rpmb_size_mult: 0x%02x\n", ext_csd[168]);
		seq_printf(s, "[167] Write reliability setting register, wr_rel_set: 0x%02x\n", ext_csd[167]);
		seq_printf(s, "[166] Write reliability parameter register, wr_rel_param: 0x%02x\n", ext_csd[166]);
		/* sanitize_start ext_csd[165]: not readable
		 * bkops_start ext_csd[164]: only writable */
		seq_printf(s, "[163] Enable background operations handshake, bkops_en: 0x%02x\n", ext_csd[163]);
		seq_printf(s, "[162] H/W reset function, rst_n_function: 0x%02x\n", ext_csd[162]);
		seq_printf(s, "[161] HPI management, hpi_mgmt: 0x%02x\n", ext_csd[161]);
		seq_printf(s, "[160] Partitioning Support, partitioning_support: 0x%02x\n", ext_csd[160]);
		seq_printf(s, "[159:157] Max Enhanced Area Size, max_enh_size_mult: 0x%06x\n", (ext_csd[159] << 16) | (ext_csd[158] << 8) | ext_csd[157]);
		seq_printf(s, "[156] Partitions attribute, partitions_attribute: 0x%02x\n", ext_csd[156]);
		seq_printf(s, "[155] Partitioning Setting, partition_setting_completed: 0x%02x\n", ext_csd[155]);
		seq_printf(s, "[154:152] General Purpose Partition Size, gp_size_mult_4: 0x%06x\n", (ext_csd[154] << 16) | (ext_csd[153] << 8) | ext_csd[152]);
		seq_printf(s, "[151:149] General Purpose Partition Size, gp_size_mult_3: 0x%06x\n", (ext_csd[151] << 16) | (ext_csd[150] << 8) | ext_csd[149]);
		seq_printf(s, "[148:146] General Purpose Partition Size, gp_size_mult_2: 0x%06x\n", (ext_csd[148] << 16) | (ext_csd[147] << 8) | ext_csd[146]);
		seq_printf(s, "[145:143] General Purpose Partition Size, gp_size_mult_1: 0x%06x\n", (ext_csd[145] << 16) | (ext_csd[144] << 8) | ext_csd[143]);
		seq_printf(s, "[142:140] Enhanced User Data Area Size, enh_size_mult: 0x%06x\n", (ext_csd[142] << 16) | (ext_csd[141] << 8) | ext_csd[140]);
		seq_printf(s, "[139:136] Enhanced User Data Start Address, enh_start_addr: 0x%06x\n", (ext_csd[139] << 24) | (ext_csd[138] << 16) | (ext_csd[137] << 8) | ext_csd[136]);

		/* B45, A441: reserved [135] [133]  */
		seq_printf(s, "[134] Bad Block Management mode, sec_bad_blk_mgmnt: 0x%02x\n", ext_csd[134]);
		/* A441: reserved [133:0] */
	}
	/* B45 */
	if (ext_csd_rev >= 6) {
		int j;
		/* tcase_support ext_csd[132] not readable */
		seq_printf(s, "[131] Periodic Wake-up, periodic_wakeup: 0x%02x\n", ext_csd[131]);
		seq_printf(s, "[130] Program CID CSD in DDR mode support, program_cid_csd_ddr_support: 0x%02x\n",
				ext_csd[130]);
		/* B45: reserved [129:128] */

		for (j = 127; j >= 64; j--)
			seq_printf(s, "[127:64] Vendor Specific Fields, vendor_specific_field[%d]: 0x%02x\n",
					j, ext_csd[j]);

		seq_printf(s, "[63] Native sector size, native_sector_size: 0x%02x\n", ext_csd[63]);
		seq_printf(s, "[62] Sector size emulation, use_native_sector: 0x%02x\n", ext_csd[62]);
		seq_printf(s, "[61] Sector size, data_sector_size: 0x%02x\n", ext_csd[61]);
		seq_printf(s, "[60] 1st initialization after disabling sector size emulation, ini_timeout_emu: 0x%02x\n", ext_csd[60]);
		seq_printf(s, "[59] Class 6 commands control, class_6_ctrl: 0x%02x\n", ext_csd[59]);
		seq_printf(s, "[58] Number of addressed group to be Released, dyncap_needed: 0x%02x\n", ext_csd[58]);
		seq_printf(s, "[57:56] Exception events control, exception_events_ctrl: 0x%04x\n",
				(ext_csd[57] << 8) | ext_csd[56]);
		seq_printf(s, "[55:54] Exception events status, exception_events_status: 0x%04x\n",
				(ext_csd[55] << 8) | ext_csd[54]);
		seq_printf(s, "[53:52] Extended Partitions Attribute, ext_partitions_attribute: 0x%04x\n",
				(ext_csd[53] << 8) | ext_csd[52]);
		for (j = 51; j >= 37; j--)
			seq_printf(s, "[51:37]Context configuration, context_conf[%d]: 0x%02x\n", j,
					ext_csd[j]);

		seq_printf(s, "[36] Packed command status, packed_command_status: 0x%02x\n", ext_csd[36]);
		seq_printf(s, "[35] Packed command failure index, packed_failure_index: 0x%02x\n", ext_csd[35]);
		seq_printf(s, "[34] Power Off Notification, power_off_notification: 0x%02x\n", ext_csd[34]);
		seq_printf(s, "[33] Control to turn the Cache On Off, cache_ctrl: 0x%02x\n", ext_csd[33]);
		/* flush_cache ext_csd[32] not readable */
		/*Reserved [31:0] */
	}
#endif
out_free:
#ifndef CONFIG_MACH_LGE
	/* LGE_CHANGE
	* http://www.mail-archive.com/[email protected]/msg10669.html
	* 2013-06-28, [email protected]
	*/
	kfree(buf);
#endif
	kfree(ext_csd);
	return err;
}
static int CPRM_CMD_SecureRW(struct mmc_card *card,
	unsigned int command,
	unsigned int dir,
	unsigned long arg,
	unsigned char *buff,
	unsigned int length) {

	int err;
	int i = 0;
	struct mmc_request mrq;
	struct mmc_command cmd;
	struct mmc_command stop;
	struct mmc_data data;
	struct scatterlist sg;

	if (command == SD_ACMD25_SECURE_WRITE_MULTI_BLOCK ||
			command == SD_ACMD18_SECURE_READ_MULTI_BLOCK) {
		return -EINVAL;
	}

	memset(&cmd, 0, sizeof(struct mmc_command));

	cmd.opcode = MMC_APP_CMD;
	cmd.arg = card->rca << 16;
	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;

	//kishore
	mmc_rpm_hold(card->host, &card->dev);
	mmc_claim_host(card->host);
	
	err = mmc_wait_for_cmd(card->host, &cmd, 0);
	if (err)
	{
		printk("CPRM mmc_wait_for_cmd fail = %d ERROR\n", err);
		mmc_release_host(card->host);
		mmc_rpm_release(card->host, &card->dev);
		return (u32)-1;
	}
	if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
	{
		printk("CPRM mmc_host_is_spi fail ERROR\n");
		mmc_release_host(card->host);
		mmc_rpm_release(card->host, &card->dev);
		return (u32)-1;
	}

	printk("CPRM_CMD_SecureRW: 1, command : %d\n", command);

	memset(&cmd, 0, sizeof(struct mmc_command));

	cmd.opcode = command;

	if (command == SD_ACMD43_GET_MKB)
		cmd.arg = arg;
	else
		cmd.arg = 0;

	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

	memset(&data, 0, sizeof(struct mmc_data));

	data.timeout_ns = 100000000;
	data.timeout_clks = 0;
	data.blksz = length;
	data.blocks = 1;
	data.flags = dir;
	data.sg = &sg;
	data.sg_len = 1;

	stop.opcode = MMC_STOP_TRANSMISSION;
	stop.arg = 0;
	stop.flags = MMC_RSP_R1B | MMC_CMD_AC;

	memset(&mrq, 0, sizeof(struct mmc_request));

	mrq.cmd = &cmd;
	mrq.data = &data;

	if (data.blocks == 1)
		mrq.stop = NULL;
	else
		mrq.stop = &stop;

	printk(KERN_DEBUG"CPRM_CMD_SecureRW: 2\n");

	sg_init_one(&sg, buff, length);

	printk(KERN_DEBUG"CPRM_CMD_SecureRW: 3\n");


	
	
	mmc_wait_for_req(card->host, &mrq);

	//kishore
	mmc_release_host(card->host);
	mmc_rpm_release(card->host, &card->dev);
	
	
	printk(KERN_DEBUG"CPRM_CMD_SecureRW: 4\n");

	i = 0;
	do {
		printk(KERN_DEBUG"%x", buff[i++]);
		if (i > 10)
			break;
	} while (i < length);
	printk(KERN_DEBUG"\n");

	if (cmd.error) {
		printk(KERN_DEBUG "%s]cmd.error=%d\n ", __func__, cmd.error);
		return cmd.error;
	}

	if (data.error) {
		printk(KERN_DEBUG "%s]data.error=%d\n ", __func__, data.error);
		return data.error;
	}

	err = mmc_wait_busy(card);
	printk(KERN_DEBUG"CPRM_CMD_SecureRW: 5\n");

	if (err)
		return err;

	return 0;
}