summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/nand_base.c2
-rw-r--r--drivers/mtd/nand/omap_gpmc.c76
-rw-r--r--drivers/power/twl4030.c2
-rw-r--r--drivers/usb/musb/musb_udc.c30
4 files changed, 95 insertions, 15 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1092a797321..f37d45bdc4c 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2024,7 +2024,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
uint8_t *wbuf = buf;
/* Partial page write ? */
- if (unlikely(column || writelen < (mtd->writesize - 1))) {
+ if (unlikely(column || writelen < mtd->writesize)) {
cached = 0;
bytes = min_t(int, bytes - column, (int) writelen);
chip->pagebuf = -1;
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 1a636cad236..865065e03b3 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -390,6 +390,35 @@ static void micron_set_chip_ecc(struct mtd_info *mtd, int enable)
#endif
}
+void nand_disable_in_chip_ecc(void)
+{
+ struct nand_chip *nand;
+ struct mtd_info *mtd;
+
+ if (nand_curr_device < 0 ||
+ nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
+ !nand_info[nand_curr_device].name)
+ return;
+
+ mtd = &nand_info[nand_curr_device];
+ nand = mtd->priv;
+
+ /* If the NAND has in-chip ECC, disable it! */
+ if (nand->has_chip_ecc)
+ micron_set_chip_ecc(mtd, 0);
+}
+
+#ifdef CONFIG_CMD_NAND_CHIP_ECC
+static int micron_get_chip_ecc(struct mtd_info *mtd)
+{
+ uint8_t params[4];
+
+ nand_get_features(mtd, 0x90, params);
+
+ return ((params[0] & 0x08) != 0);
+}
+#endif
+
/**
* nand_read_oob_chipecc - read; get status to seeif chip ECC error
* @mtd: mtd info structure
@@ -610,6 +639,7 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode)
{
struct nand_chip *nand;
struct mtd_info *mtd;
+ int in_chip_ecc = 0;
if (nand_curr_device < 0 ||
nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
@@ -619,6 +649,12 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode)
mtd = &nand_info[nand_curr_device];
nand = mtd->priv;
+ if (mode == OMAP_ECC_CHIP && !nand->has_chip_ecc)
+ {
+ printf("NAND: Chip does not have internal ECC!\n");
+ return;
+ }
+
nand->options |= NAND_OWN_BUFFERS;
/* Reset ecc interface */
@@ -683,20 +719,12 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode)
nand->ecc.calculate = omap_calculate_ecc;
omap_hwecc_init(nand);
printf("NAND: HW ECC selected\n");
- if (nand->has_chip_ecc)
- micron_set_chip_ecc(mtd, 0);
} else if (mode == OMAP_ECC_SOFT) {
nand->ecc.mode = NAND_ECC_SOFT;
/* Use mtd default settings */
nand->ecc.layout = NULL;
printf("NAND: SW ECC selected\n");
- if (nand->has_chip_ecc)
- micron_set_chip_ecc(mtd, 0);
} else if (mode == OMAP_ECC_CHIP) {
- if (!nand->has_chip_ecc) {
- printf("NAND: Chip does not have internal ECC!\n");
- return;
- }
nand->ecc.bytes = 0;
nand->ecc.size = 2048;
nand->ecc.calculate = omap_calculate_chip_hwecc;
@@ -716,13 +744,17 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode)
nand->cmdfunc = omap_nand_command_lp;
else
printf("%s: Huh? not 16-bit wide\n", __FUNCTION__);
- micron_set_chip_ecc(mtd, 1);
printf("NAND: Internal to NAND ECC selected\n");
+ in_chip_ecc = 1;
} else {
printf("NAND: unknown ECC mode %d\n", mode);
return;
}
+ /* Enable/disable the in-chip ECC engine appropriately */
+ if (nand->has_chip_ecc)
+ micron_set_chip_ecc(mtd, in_chip_ecc);
+
current_ecc_method = mode;
/* Update NAND handling after ECC mode switch */
@@ -731,6 +763,32 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode)
nand->options &= ~NAND_OWN_BUFFERS;
}
+#ifdef CONFIG_CMD_NAND_CHIP_ECC
+int omap_nand_switch_chip_ecc(int get, int enable)
+{
+ struct nand_chip *nand;
+ struct mtd_info *mtd;
+
+ if (nand_curr_device < 0 ||
+ nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
+ !nand_info[nand_curr_device].name)
+ return -1;
+
+ mtd = &nand_info[nand_curr_device];
+ nand = mtd->priv;
+
+ /* If no in-chip ECC, punt! */
+ if (!nand->has_chip_ecc)
+ return -1;
+
+ if (get)
+ return micron_get_chip_ecc(mtd);
+
+ micron_set_chip_ecc(mtd, enable);
+ return 0;
+}
+#endif
+
/*
* Board-specific NAND initialization. The following members of the
* argument are board-specific:
diff --git a/drivers/power/twl4030.c b/drivers/power/twl4030.c
index b62ed176d25..92c8fd75b59 100644
--- a/drivers/power/twl4030.c
+++ b/drivers/power/twl4030.c
@@ -136,7 +136,7 @@ U_BOOT_CMD(poweroff, 1, 1, do_poweroff,
/* Enable the battery backup charger */
int twl4030_enable_bb_charging(unsigned int millivolts, unsigned int microamps)
{
- u8 val;
+ u8 val = 0;
if (millivolts >= 3200)
val = 0x0c;
diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
index 6f6ed61d08b..3ebdcf1daf4 100644
--- a/drivers/usb/musb/musb_udc.c
+++ b/drivers/usb/musb/musb_udc.c
@@ -180,11 +180,15 @@ static void musb_peri_softconnect(void)
/* Power on MUSB */
power = readb(&musbr->power);
power |= MUSB_POWER_SOFTCONN;
+#if USB_BCD_VERSION == 0x0200
+ power |= MUSB_POWER_HSENAB;
+#else
/*
* The usb device interface is usb 1.1
* Disable 2.0 high speed by clearring the hsenable bit.
*/
power &= ~MUSB_POWER_HSENAB;
+#endif
writeb(power, &musbr->power);
/* Check if device is in b-peripheral mode */
@@ -786,6 +790,9 @@ void udc_irq(void)
if (intrtx)
musb_peri_tx(intrtx);
} else {
+ udc_device->speed =
+ (readb(&musbr->power) & MUSB_POWER_HSMODE) ?
+ USB_SPEED_HIGH : USB_SPEED_FULL;
if (MUSB_INTR_SOF & intrusb) {
u8 faddr;
faddr = readb(&musbr->faddr);
@@ -881,10 +888,10 @@ void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
ep_addr = endpoint->endpoint_address;
if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) {
/* IN */
- epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
+ epinfo[((id - 1) * 2) + 1].epsize = endpoint->tx_packetSize;
} else {
/* OUT */
- epinfo[id * 2].epsize = endpoint->rcv_packetSize;
+ epinfo[(id - 1) * 2].epsize = endpoint->rcv_packetSize;
}
musb_configure_ep(&epinfo[0],
@@ -899,12 +906,27 @@ void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
void udc_connect(void)
{
- /* noop */
+ musb_peri_softconnect();
}
void udc_disconnect(void)
{
- /* noop */
+ u8 power, intrusb;
+ u16 intrrx, intrtx;
+
+ /* If musbr Null, never initialized MUSB! */
+ if (!musbr)
+ return;
+
+ /* Power off MUSB */
+ power = readb(&musbr->power);
+ power &= ~MUSB_POWER_SOFTCONN;
+ writeb(power, &musbr->power);
+
+ /* Read intr to clear */
+ intrusb = readb(&musbr->intrusb);
+ intrrx = readw(&musbr->intrrx);
+ intrtx = readw(&musbr->intrtx);
}
void udc_enable(struct usb_device_instance *device)