summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ahci.c50
-rw-r--r--drivers/i2c/mxc_i2c.c22
-rw-r--r--drivers/input/cros_ec_keyb.c16
-rw-r--r--drivers/misc/i2c_eeprom.c1
-rw-r--r--drivers/mmc/mvebu_mmc.c103
-rw-r--r--drivers/mtd/nand/omap_gpmc.c3
6 files changed, 111 insertions, 84 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index c9a3beb79b..37d2d2a28e 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -137,6 +137,33 @@ static void sunxi_dma_init(volatile u8 *port_mmio)
}
#endif
+int ahci_reset(u32 base)
+{
+ int i = 1000;
+ u32 host_ctl_reg = base + HOST_CTL;
+ u32 tmp = readl(host_ctl_reg); /* global controller reset */
+
+ if ((tmp & HOST_RESET) == 0)
+ writel_with_flush(tmp | HOST_RESET, host_ctl_reg);
+
+ /*
+ * reset must complete within 1 second, or
+ * the hardware should be considered fried.
+ */
+ do {
+ udelay(1000);
+ tmp = readl(host_ctl_reg);
+ i--;
+ } while ((i > 0) && (tmp & HOST_RESET));
+
+ if (i == 0) {
+ printf("controller reset failed (0x%x)\n", tmp);
+ return -1;
+ }
+
+ return 0;
+}
+
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
#ifndef CONFIG_SCSI_AHCI_PLAT
@@ -156,23 +183,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
cap_save &= ((1 << 28) | (1 << 17));
cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */
- /* global controller reset */
- tmp = readl(mmio + HOST_CTL);
- if ((tmp & HOST_RESET) == 0)
- writel_with_flush(tmp | HOST_RESET, mmio + HOST_CTL);
-
- /* reset must complete within 1 second, or
- * the hardware should be considered fried.
- */
- i = 1000;
- do {
- udelay(1000);
- tmp = readl(mmio + HOST_CTL);
- if (!i--) {
- debug("controller reset failed (0x%x)\n", tmp);
- return -1;
- }
- } while (tmp & HOST_RESET);
+ ret = ahci_reset(probe_ent->mmio_base);
+ if (ret)
+ return ret;
writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
writel(cap_save, mmio + HOST_CAP);
@@ -997,12 +1010,11 @@ static int ata_io_flush(u8 port)
}
-void scsi_bus_reset(void)
+__weak void scsi_bus_reset(void)
{
/*Not implement*/
}
-
void scsi_print_error(ccb * pccb)
{
/*The ahci error info can be read in the ahci driver*/
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 021b2fe511..fc5ee35a1a 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -402,17 +402,6 @@ int bus_i2c_write(void *base, uchar chip, uint addr, int alen,
return ret;
}
-struct i2c_parms {
- void *base;
- void *idle_bus_data;
- int (*idle_bus_fn)(void *p);
-};
-
-struct sram_data {
- unsigned curr_i2c_bus;
- struct i2c_parms i2c_data[3];
-};
-
static void * const i2c_bases[] = {
#if defined(CONFIG_MX25)
(void *)IMX_I2C_BASE,
@@ -439,6 +428,17 @@ static void * const i2c_bases[] = {
#endif
};
+struct i2c_parms {
+ void *base;
+ void *idle_bus_data;
+ int (*idle_bus_fn)(void *p);
+};
+
+struct sram_data {
+ unsigned curr_i2c_bus;
+ struct i2c_parms i2c_data[ARRAY_SIZE(i2c_bases)];
+};
+
void *i2c_get_base(struct i2c_adapter *adap)
{
return i2c_bases[adap->hwadapnr];
diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c
index 47502b1763..49ee7b2c9b 100644
--- a/drivers/input/cros_ec_keyb.c
+++ b/drivers/input/cros_ec_keyb.c
@@ -18,6 +18,8 @@ DECLARE_GLOBAL_DATA_PTR;
enum {
KBC_MAX_KEYS = 8, /* Maximum keys held down at once */
+ KBC_REPEAT_RATE_MS = 30,
+ KBC_REPEAT_DELAY_MS = 240,
};
static struct keyb {
@@ -26,8 +28,6 @@ static struct keyb {
struct key_matrix matrix; /* The key matrix layer */
int key_rows; /* Number of keyboard rows */
int key_cols; /* Number of keyboard columns */
- unsigned int repeat_delay_ms; /* Time before autorepeat starts */
- unsigned int repeat_rate_ms; /* Autorepeat rate in ms */
int ghost_filter; /* 1 to enable ghost filter, else 0 */
int inited; /* 1 if keyboard is ready */
} config;
@@ -188,8 +188,8 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node,
* Get keyboard rows and columns - at present we are limited to
* 8 columns by the protocol (one byte per row scan)
*/
- config->key_rows = fdtdec_get_int(blob, node, "google,key-rows", 0);
- config->key_cols = fdtdec_get_int(blob, node, "google,key-columns", 0);
+ config->key_rows = fdtdec_get_int(blob, node, "keypad,num-rows", 0);
+ config->key_cols = fdtdec_get_int(blob, node, "keypad,num-columns", 0);
if (!config->key_rows || !config->key_cols ||
config->key_rows * config->key_cols / 8
> CROS_EC_KEYSCAN_COLS) {
@@ -197,10 +197,6 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node,
config->key_rows, config->key_cols);
return -1;
}
- config->repeat_delay_ms = fdtdec_get_int(blob, node,
- "google,repeat-delay-ms", 0);
- config->repeat_rate_ms = fdtdec_get_int(blob, node,
- "google,repeat-rate-ms", 0);
config->ghost_filter = fdtdec_get_bool(blob, node,
"google,ghost-filter");
return 0;
@@ -232,8 +228,8 @@ static int cros_ec_init_keyboard(struct stdio_dev *dev)
}
if (cros_ec_keyb_decode_fdt(blob, node, &config))
return -1;
- input_set_delays(&config.input, config.repeat_delay_ms,
- config.repeat_rate_ms);
+ input_set_delays(&config.input, KBC_REPEAT_DELAY_MS,
+ KBC_REPEAT_RATE_MS);
if (key_matrix_init(&config.matrix, config.key_rows,
config.key_cols, config.ghost_filter)) {
debug("%s: cannot init key matrix\n", __func__);
diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c
index d0548ecc4e..814134a2cb 100644
--- a/drivers/misc/i2c_eeprom.c
+++ b/drivers/misc/i2c_eeprom.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <linux/err.h>
#include <dm.h>
#include <i2c.h>
#include <i2c_eeprom.h>
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 9f98c3f37c..8ca09042d8 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -1,7 +1,7 @@
/*
* Marvell MMC/SD/SDIO driver
*
- * (C) Copyright 2012
+ * (C) Copyright 2012-2014
* Marvell Semiconductor <www.marvell.com>
* Written-by: Maen Suleiman, Gerald Kerma
*
@@ -23,6 +23,8 @@ DECLARE_GLOBAL_DATA_PTR;
#define MVEBU_TARGET_DRAM 0
+#define TIMEOUT_DELAY 5*CONFIG_SYS_HZ /* wait 5 seconds */
+
static void mvebu_mmc_write(u32 offs, u32 val)
{
writel(val, CONFIG_SYS_MMC_BASE + (offs));
@@ -63,37 +65,47 @@ static int mvebu_mmc_setup_data(struct mmc_data *data)
static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
- int timeout = 10;
+ ulong start;
ushort waittype = 0;
ushort resptype = 0;
ushort xfertype = 0;
ushort resp_indx = 0;
- debug("cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
- cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
-
- udelay(10*1000);
+ debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
+ DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME,
cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE));
- /* Checking if card is busy */
- while ((mvebu_mmc_read(SDIO_HW_STATE) & CARD_BUSY)) {
- if (timeout == 0) {
- printf("%s: card busy!\n", DRIVER_NAME);
- return -1;
- }
- timeout--;
- udelay(1000);
+ /*
+ * Hardware weirdness. The FIFO_EMPTY bit of the HW_STATE
+ * register is sometimes not set before a while when some
+ * "unusual" data block sizes are used (such as with the SWITCH
+ * command), even despite the fact that the XFER_DONE interrupt
+ * was raised. And if another data transfer starts before
+ * this bit comes to good sense (which eventually happens by
+ * itself) then the new transfer simply fails with a timeout.
+ */
+ if (!(mvebu_mmc_read(SDIO_HW_STATE) & CMD_FIFO_EMPTY)) {
+ ushort hw_state, count = 0;
+
+ start = get_timer(0);
+ do {
+ hw_state = mvebu_mmc_read(SDIO_HW_STATE);
+ if ((get_timer(0) - start) > TIMEOUT_DELAY) {
+ printf("%s : FIFO_EMPTY bit missing\n",
+ DRIVER_NAME);
+ break;
+ }
+ count++;
+ } while (!(hw_state & CMD_FIFO_EMPTY));
+ debug("%s *** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n",
+ DRIVER_NAME, hw_state, count, (get_timer(0) - (start)));
}
- /* Set up for a data transfer if we have one */
- if (data) {
- int err = mvebu_mmc_setup_data(data);
-
- if (err)
- return err;
- }
+ /* Clear status */
+ mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
+ mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
resptype = SDIO_CMD_INDEX(cmd->cmdidx);
@@ -119,6 +131,14 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
}
if (data) {
+ int err = mvebu_mmc_setup_data(data);
+
+ if (err) {
+ debug("%s: command DATA error :%x\n",
+ DRIVER_NAME, err);
+ return err;
+ }
+
resptype |= SDIO_CMD_DATA_PRESENT | SDIO_CMD_CHECK_DATACRC16;
xfertype |= SDIO_XFER_MODE_HW_WR_DATA_EN;
if (data->flags & MMC_DATA_READ) {
@@ -138,17 +158,10 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
/* Setting Xfer mode */
mvebu_mmc_write(SDIO_XFER_MODE, xfertype);
- mvebu_mmc_write(SDIO_NOR_INTR_STATUS, ~SDIO_NOR_CARD_INT);
- mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
-
/* Sending command */
mvebu_mmc_write(SDIO_CMD, resptype);
- mvebu_mmc_write(SDIO_NOR_INTR_EN, SDIO_POLL_MASK);
- mvebu_mmc_write(SDIO_ERR_INTR_EN, SDIO_POLL_MASK);
-
- /* Waiting for completion */
- timeout = 1000000;
+ start = get_timer(0);
while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) {
if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
@@ -156,21 +169,20 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
DRIVER_NAME, cmd->cmdidx,
mvebu_mmc_read(SDIO_ERR_INTR_STATUS));
if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
- (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
+ (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) {
+ debug("%s: command READ timed out\n",
+ DRIVER_NAME);
return TIMEOUT;
+ }
+ debug("%s: command READ error\n", DRIVER_NAME);
return COMM_ERR;
}
- timeout--;
- udelay(1);
- if (timeout <= 0) {
- printf("%s: command timed out\n", DRIVER_NAME);
+ if ((get_timer(0) - start) > TIMEOUT_DELAY) {
+ debug("%s: command timed out\n", DRIVER_NAME);
return TIMEOUT;
}
}
- if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
- (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
- return TIMEOUT;
/* Handling response */
if (cmd->resp_type & MMC_RSP_136) {
@@ -204,6 +216,11 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
cmd->response[1] = ((response[0] & 0xfc00) >> 10);
cmd->response[2] = 0;
cmd->response[3] = 0;
+ } else {
+ cmd->response[0] = 0;
+ cmd->response[1] = 0;
+ cmd->response[2] = 0;
+ cmd->response[3] = 0;
}
debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type);
@@ -213,6 +230,10 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
debug("[0x%x] ", cmd->response[3]);
debug("\n");
+ if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
+ (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
+ return TIMEOUT;
+
return 0;
}
@@ -251,9 +272,8 @@ static void mvebu_mmc_set_clk(unsigned int clock)
if (m > MVEBU_MMC_BASE_DIV_MAX)
m = MVEBU_MMC_BASE_DIV_MAX;
mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX);
+ debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m);
}
-
- udelay(10*1000);
}
static void mvebu_mmc_set_bus(unsigned int bus)
@@ -293,7 +313,6 @@ static void mvebu_mmc_set_bus(unsigned int bus)
"high-speed" : "");
mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
- udelay(10*1000);
}
static void mvebu_mmc_set_ios(struct mmc *mmc)
@@ -355,7 +374,7 @@ static void mvebu_window_setup(void)
static int mvebu_mmc_initialize(struct mmc *mmc)
{
- debug("%s: mvebu_mmc_initialize", DRIVER_NAME);
+ debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME);
/*
* Setting host parameters
@@ -384,8 +403,6 @@ static int mvebu_mmc_initialize(struct mmc *mmc)
/* SW reset */
mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
- udelay(10*1000);
-
return 0;
}
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 93829a40b6..459904d81c 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -368,8 +368,9 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
uint32_t error_loc[ELM_MAX_ERROR_COUNT];
enum bch_level bch_type;
uint32_t i, ecc_flag = 0;
- uint8_t count, err = 0;
+ uint8_t count;
uint32_t byte_pos, bit_pos;
+ int err = 0;
/* check calculated ecc */
for (i = 0; i < ecc->bytes && !ecc_flag; i++) {