summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-12-07 11:54:19 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-12-07 11:54:19 +0100
commit6bbb1b51bf6fcc7ecc4ff3cb7c3cf472943faeac (patch)
treeb7ee7acbf6928e3ff528e5633227bd6f91b86d21
parent10ac493e963c9eea05f9e7f6c7e7d3e3db532ea7 (diff)
parent5a12d9036109f2a819e5e455102eb68db936608e (diff)
downloadbarebox-6bbb1b51bf6fcc7ecc4ff3cb7c3cf472943faeac.tar.gz
barebox-6bbb1b51bf6fcc7ecc4ff3cb7c3cf472943faeac.tar.xz
Merge branch 'pu/clk' into for-next/clk
Conflicts: include/linux/clk.h
-rw-r--r--arch/arm/boards/karo-tx28/tx28.c6
-rw-r--r--arch/arm/mach-imx/clk-imx6.c40
-rw-r--r--arch/arm/mach-imx/clk-pllv3.c83
-rw-r--r--arch/arm/mach-imx/clk.h2
-rw-r--r--arch/arm/mach-imx/imx-bbu-internal.c2
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx6.h5
-rw-r--r--arch/arm/mach-imx/include/mach/imx6-regs.h2
-rw-r--r--arch/arm/mach-omap/gpmc.c10
-rw-r--r--arch/mips/Makefile8
-rw-r--r--common/bbu.c13
-rw-r--r--drivers/ata/disk_ata_drive.c10
-rw-r--r--drivers/base/platform.c4
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/clk-divider-table.c119
-rw-r--r--drivers/i2c/i2c.c1
-rw-r--r--drivers/mfd/stmpe-i2c.c2
-rw-r--r--drivers/mtd/nand/nand_mxs.c13
-rw-r--r--drivers/net/phy/mdio_bus.c2
-rw-r--r--drivers/usb/otg/ulpi.c7
-rw-r--r--include/linux/clk.h8
20 files changed, 224 insertions, 115 deletions
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
index a62cb8257f..6e8da155a3 100644
--- a/arch/arm/boards/karo-tx28/tx28.c
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -35,11 +35,12 @@ static const uint32_t tx28_pad_setup[] = {
GPMI_D6 | VE_3_3V | PULLUP(1),
GPMI_D7 | VE_3_3V | PULLUP(1),
GPMI_READY0 | VE_3_3V | PULLUP(0), /* external PU */
+ GPMI_CE0N | VE_3_3V | PULLUP(1),
GPMI_RDN | VE_3_3V | PULLUP(1),
GPMI_WRN | VE_3_3V | BITKEEPER(1),
GPMI_ALE | VE_3_3V | PULLUP(1),
GPMI_CLE | VE_3_3V | PULLUP(1),
- GPMI_RESETN_GPIO | VE_3_3V | GPIO_IN, /* act as WP, external PU */
+ GPMI_RESETN | VE_3_3V | PULLUP(0), /* external PU */
/* Network interface */
@@ -91,6 +92,9 @@ static int tx28_devices_init(void)
base_board_init();
+ add_generic_device("mxs_nand", 0, NULL, MXS_GPMI_BASE, 0x2000,
+ IORESOURCE_MEM, NULL);
+
return 0;
}
diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c
index a1da47a959..f78d3d2bcd 100644
--- a/arch/arm/mach-imx/clk-imx6.c
+++ b/arch/arm/mach-imx/clk-imx6.c
@@ -81,8 +81,9 @@ enum mx6q_clks {
gpmi_bch_apb, gpmi_bch, gpmi_io, gpmi_apb, sata, sdma, spba, ssi1,
ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3,
usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
- pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg,
+ pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
+ sata_ref, pcie_ref, sata_ref_100m, pcie_ref_125m, enet_ref,
clk_max
};
@@ -169,6 +170,14 @@ static const char *cko1_sels[] = {
"pll4_audio",
};
+static struct clk_div_table clk_enet_ref_table[] = {
+ { .val = 0, .div = 20, },
+ { .val = 1, .div = 10, },
+ { .val = 2, .div = 5, },
+ { .val = 3, .div = 4, },
+ { },
+};
+
static int imx6_ccm_probe(struct device_d *dev)
{
void __iomem *base, *anatop_base, *ccm_base;
@@ -186,15 +195,22 @@ static int imx6_ccm_probe(struct device_d *dev)
clks[ckih] = clk_fixed("ckih", ckih_rate);
clks[osc] = clk_fixed("osc", osc_rate);
- /* type name parent_name base gate_mask div_mask */
- clks[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x2000, 0x7f);
- clks[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x2000, 0x1);
- clks[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x2000, 0x3);
- clks[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x2000, 0x7f);
- clks[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x2000, 0x7f);
- clks[pll6_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll6_mlb", "osc", base + 0xd0, 0x2000, 0x0);
- clks[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x2000, 0x3);
- clks[pll8_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll8_enet", "osc", base + 0xe0, 0x182000, 0x3);
+ /* type name parent_name base div_mask */
+ clks[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
+ clks[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
+ clks[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
+ clks[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
+ clks[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
+ clks[pll8_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll8_mlb", "osc", base + 0xd0, 0x0);
+ clks[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
+ clks[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
+
+ clks[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
+ clks[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
+ clks[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
+ clks[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+ clks[enet_ref] = clk_divider_table("enet_ref", "pll6_enet", base + 0xe0, 0, 2, clk_enet_ref_table);
/* name parent_name reg idx */
clks[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
@@ -281,6 +297,7 @@ static int imx6_ccm_probe(struct device_d *dev)
clkdev_add_physbase(clks[ipg_per], MX6_I2C1_BASE_ADDR, NULL);
clkdev_add_physbase(clks[ipg_per], MX6_I2C2_BASE_ADDR, NULL);
clkdev_add_physbase(clks[ipg_per], MX6_I2C3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ahb], MX6_SATA_BASE_ADDR, NULL);
writel(0xffffffff, ccm_base + CCGR0);
writel(0xffffffff, ccm_base + CCGR1);
@@ -291,6 +308,9 @@ static int imx6_ccm_probe(struct device_d *dev)
writel(0xffffffff, ccm_base + CCGR6);
writel(0xffffffff, ccm_base + CCGR7);
+ clk_enable(clks[pll6_enet]);
+ clk_enable(clks[sata_ref_100m]);
+
return 0;
}
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
index e337e87f13..e38dcdfdaa 100644
--- a/arch/arm/mach-imx/clk-pllv3.c
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -35,7 +35,6 @@ struct clk_pllv3 {
struct clk clk;
void __iomem *base;
bool powerup_set;
- u32 gate_mask;
u32 div_mask;
const char *parent;
};
@@ -46,7 +45,7 @@ static int clk_pllv3_enable(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(clk);
u32 val;
- int ret;
+ int timeout = 10000;
val = readl(pll->base);
val &= ~BM_PLL_BYPASS;
@@ -57,12 +56,16 @@ static int clk_pllv3_enable(struct clk *clk)
writel(val, pll->base);
/* Wait for PLL to lock */
- ret = wait_on_timeout(10 * MSECOND, !(readl(pll->base) & BM_PLL_LOCK));
- if (ret)
- return ret;
+ while (timeout--) {
+ if (readl(pll->base) & BM_PLL_LOCK)
+ break;
+ }
+
+ if (!timeout)
+ return -ETIMEDOUT;
val = readl(pll->base);
- val |= pll->gate_mask;
+ val |= BM_PLL_ENABLE;
writel(val, pll->base);
return 0;
@@ -74,7 +77,7 @@ static void clk_pllv3_disable(struct clk *clk)
u32 val;
val = readl(pll->base);
- val &= ~pll->gate_mask;
+ val &= ~BM_PLL_ENABLE;
writel(val, pll->base);
val |= BM_PLL_BYPASS;
@@ -261,74 +264,13 @@ static const struct clk_ops clk_pllv3_av_ops = {
static unsigned long clk_pllv3_enet_recalc_rate(struct clk *clk,
unsigned long parent_rate)
{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 div = readl(pll->base) & pll->div_mask;
-
- switch (div) {
- case 0:
- return 25000000;
- case 1:
- return 50000000;
- case 2:
- return 100000000;
- case 3:
- return 125000000;
- }
-
- return 0;
-}
-
-static long clk_pllv3_enet_round_rate(struct clk *clk, unsigned long rate,
- unsigned long *prate)
-{
- if (rate >= 125000000)
- rate = 125000000;
- else if (rate >= 100000000)
- rate = 100000000;
- else if (rate >= 50000000)
- rate = 50000000;
- else
- rate = 25000000;
- return rate;
-}
-
-static int clk_pllv3_enet_set_rate(struct clk *clk, unsigned long rate,
- unsigned long parent_rate)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 val, div;
-
- switch (rate) {
- case 25000000:
- div = 0;
- break;
- case 50000000:
- div = 1;
- break;
- case 100000000:
- div = 2;
- break;
- case 125000000:
- div = 3;
- break;
- default:
- return -EINVAL;
- }
-
- val = readl(pll->base);
- val &= ~pll->div_mask;
- val |= div;
- writel(val, pll->base);
-
- return 0;
+ return 500000000;
}
static const struct clk_ops clk_pllv3_enet_ops = {
.enable = clk_pllv3_enable,
.disable = clk_pllv3_disable,
.recalc_rate = clk_pllv3_enet_recalc_rate,
- .round_rate = clk_pllv3_enet_round_rate,
- .set_rate = clk_pllv3_enet_set_rate,
};
static const struct clk_ops clk_pllv3_mlb_ops = {
@@ -338,7 +280,7 @@ static const struct clk_ops clk_pllv3_mlb_ops = {
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent, void __iomem *base,
- u32 gate_mask, u32 div_mask)
+ u32 div_mask)
{
struct clk_pllv3 *pll;
const struct clk_ops *ops;
@@ -367,7 +309,6 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
ops = &clk_pllv3_ops;
}
pll->base = base;
- pll->gate_mask = gate_mask;
pll->div_mask = div_mask;
pll->parent = parent;
pll->clk.ops = ops;
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 0f30082e1f..4a7298d846 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -42,7 +42,7 @@ enum imx_pllv3_type {
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent, void __iomem *base,
- u32 gate_mask, u32 div_mask);
+ u32 div_mask);
struct clk *imx_clk_pfd(const char *name, const char *parent,
void __iomem *reg, u8 idx);
diff --git a/arch/arm/mach-imx/imx-bbu-internal.c b/arch/arm/mach-imx/imx-bbu-internal.c
index c34f86f33a..a36a4271ed 100644
--- a/arch/arm/mach-imx/imx-bbu-internal.c
+++ b/arch/arm/mach-imx/imx-bbu-internal.c
@@ -72,7 +72,7 @@ static int imx_bbu_write_device(struct imx_internal_bbu_handler *imx_handler,
}
memcpy(buf + 0x1b8, mbr + 0x1b8, 0x48);
- free(buf);
+ free(mbr);
ret = lseek(fd, 0, SEEK_SET);
if (ret)
diff --git a/arch/arm/mach-imx/include/mach/devices-imx6.h b/arch/arm/mach-imx/include/mach/devices-imx6.h
index f8282e7fca..0f17016530 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx6.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx6.h
@@ -64,3 +64,8 @@ static inline struct device_d *imx6_add_i2c2(struct i2c_platform_data *pdata)
{
return imx_add_i2c((void *)MX6_I2C3_BASE_ADDR, 2, pdata);
}
+
+static inline struct device_d *imx6_add_sata(void)
+{
+ return add_generic_device("imx6-sata", 0, NULL, MX6_SATA_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+}
diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h
index 716e6b4f25..7c72cba838 100644
--- a/arch/arm/mach-imx/include/mach/imx6-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx6-regs.h
@@ -105,4 +105,6 @@
#define MX6_IP2APB_USBPHY1_BASE_ADDR (MX6_AIPS2_OFF_BASE_ADDR + 0x78000)
#define MX6_IP2APB_USBPHY2_BASE_ADDR (MX6_AIPS2_OFF_BASE_ADDR + 0x7C000)
+#define MX6_SATA_BASE_ADDR 0x02200000
+
#endif /* __MACH_IMX6_REGS_H */
diff --git a/arch/arm/mach-omap/gpmc.c b/arch/arm/mach-omap/gpmc.c
index ff8b58b772..73d8c44a3b 100644
--- a/arch/arm/mach-omap/gpmc.c
+++ b/arch/arm/mach-omap/gpmc.c
@@ -50,7 +50,7 @@ void gpmc_generic_init(unsigned int cfg)
unsigned int reg = GPMC_REG(CONFIG7_0);
char x = 0;
- debug("gpmccfg=%x\n", cfg);
+ debug("gpmccfg=0x%x\n", cfg);
/* Generic Configurations */
/* reset gpmc */
start = get_time_ns();
@@ -73,7 +73,7 @@ void gpmc_generic_init(unsigned int cfg)
* But NEVER run me in XIP mode! I will Die!
*/
while (x < GPMC_NUM_CS) {
- debug("gpmccs=%d Reg:%x <-0x0\n", x, reg);
+ debug("gpmccs=%d Reg:0x%x <-0x0\n", x, reg);
writel(0x0, reg);
reg += GPMC_CONFIG_CS_SIZE;
x++;
@@ -95,7 +95,7 @@ void gpmc_cs_config(char cs, struct gpmc_config *config)
{
unsigned int reg = GPMC_REG(CONFIG1_0) + (cs * GPMC_CONFIG_CS_SIZE);
unsigned char x = 0;
- debug("gpmccs=%x cfg=%x\n", cs, (unsigned int)config);
+ debug("gpmccs=0x%x cfg=0x%p\n", cs, config);
/* Disable the CS before reconfiguring */
writel(0x0, GPMC_REG(CONFIG7_0) + (cs * GPMC_CONFIG_CS_SIZE));
@@ -103,14 +103,14 @@ void gpmc_cs_config(char cs, struct gpmc_config *config)
/* Write the CFG1-6 regs */
while (x < 6) {
- debug("gpmccfg=%d Reg:%x <-0x%x\n",
+ debug("gpmccfg%d Reg:0x%x <-0x%08x\n",
x, reg, config->cfg[x]);
writel(config->cfg[x], reg);
reg += GPMC_CONFIG_REG_OFF;
x++;
}
/* reg now points to CFG7 */
- debug("gpmccfg=%d Reg:%x <-0x%x\n",
+ debug("gpmccfg%d Reg:0x%x <-0x%08x\n",
x, reg, (0x1 << 6) | /* CS enable */
((config->size & 0xF) << 8) | /* Size */
((config->base >> 24) & 0x3F));
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 5e40de760f..f32089d827 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -88,14 +88,18 @@ else
BOARD :=
endif
+ifeq ($(KBUILD_SRC),)
+CPPFLAGS += -I$(BOARD)/include
+else
+CPPFLAGS += -I$(srctree)/$(BOARD)/include
+endif
+
ifneq ($(machine-y),)
MACH := arch/mips/mach-$(machine-y)/
else
MACH :=
endif
-CPPFLAGS += -I$(BOARD)/include
-
common-y += $(BOARD) $(MACH)
common-y += arch/mips/lib/
common-y += arch/mips/boot/
diff --git a/common/bbu.c b/common/bbu.c
index 92f8d2b2f4..e31f645d9c 100644
--- a/common/bbu.c
+++ b/common/bbu.c
@@ -71,13 +71,13 @@ int bbu_confirm(struct bbu_data *data)
return -EINTR;
}
-static struct bbu_handler *bbu_find_handler(const char *name, unsigned long flags)
+static struct bbu_handler *bbu_find_handler(const char *name)
{
struct bbu_handler *handler;
list_for_each_entry(handler, &bbu_image_handlers, list) {
if (!name) {
- if (flags & BBU_HANDLER_FLAG_DEFAULT)
+ if (handler->flags & BBU_HANDLER_FLAG_DEFAULT)
return handler;
continue;
}
@@ -97,10 +97,13 @@ int barebox_update(struct bbu_data *data)
struct bbu_handler *handler;
int ret;
- handler = bbu_find_handler(data->handler_name, data->flags);
+ handler = bbu_find_handler(data->handler_name);
if (!handler)
return -ENODEV;
+ if (!data->handler_name)
+ data->handler_name = handler->name;
+
if (!data->devicefile)
data->devicefile = handler->devicefile;
@@ -137,11 +140,11 @@ void bbu_handlers_list(void)
*/
int bbu_register_handler(struct bbu_handler *handler)
{
- if (bbu_find_handler(handler->name, 0))
+ if (bbu_find_handler(handler->name))
return -EBUSY;
if (handler->flags & BBU_HANDLER_FLAG_DEFAULT &&
- bbu_find_handler(NULL, BBU_HANDLER_FLAG_DEFAULT))
+ bbu_find_handler(NULL))
return -EBUSY;
list_add_tail(&handler->list, &bbu_image_handlers);
diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c
index d5c583790c..6bb72a9756 100644
--- a/drivers/ata/disk_ata_drive.c
+++ b/drivers/ata/disk_ata_drive.c
@@ -540,14 +540,6 @@ static struct block_device_ops ata_ops = {
#endif
};
-/* until Barebox can handle 64 bit offsets */
-static int limit_disk_size(uint64_t val)
-{
- if (val > (__INT_MAX__ / SECTOR_SIZE))
- return (__INT_MAX__ / SECTOR_SIZE);
- return (int)val;
-}
-
/**
* Register an ATA drive behind an IDE like interface
* @param dev The interface device
@@ -584,7 +576,7 @@ int register_ata_drive(struct device_d *dev, struct ata_ioports *io)
if (rc == -1)
pr_err("Cannot find a free index for the disk node\n");
- drive->blk.num_blocks = limit_disk_size(ata_id_n_sectors(drive->id));
+ drive->blk.num_blocks = ata_id_n_sectors(drive->id);
drive->blk.cdev.name = asprintf("disk%d", rc);
drive->blk.blockbits = SECTOR_SHIFT;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ea4e37bbb7..e1a8472ff5 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -76,8 +76,8 @@ struct bus_type platform_bus = {
.remove = platform_remove,
};
-static int plarform_init(void)
+static int platform_init(void)
{
return bus_register(&platform_bus);
}
-pure_initcall(plarform_init);
+pure_initcall(platform_init);
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 3cc7163829..656b8594b1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o \
- clk-mux.o clk-gate.o
+ clk-mux.o clk-gate.o clk-divider-table.o
obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
diff --git a/drivers/clk/clk-divider-table.c b/drivers/clk/clk-divider-table.c
new file mode 100644
index 0000000000..204e24d576
--- /dev/null
+++ b/drivers/clk/clk-divider-table.c
@@ -0,0 +1,119 @@
+/*
+ * clk-divider-table.c - generic barebox clock support. Based on Linux clk support
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+struct clk_divider_table {
+ struct clk clk;
+ u8 shift;
+ u8 width;
+ void __iomem *reg;
+ const char *parent;
+ const struct clk_div_table *table;
+ int table_size;
+ int max_div_index;
+};
+
+static int clk_divider_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_divider_table *div =
+ container_of(clk, struct clk_divider_table, clk);
+ unsigned int val;
+ int i, div_index = -1;
+ unsigned long best = 0;
+
+ if (rate > parent_rate)
+ rate = parent_rate;
+ if (rate < parent_rate / div->table[div->max_div_index].div)
+ rate = parent_rate / div->table[div->max_div_index].div;
+
+ for (i = 0; i < div->table_size; i++) {
+ unsigned long now = parent_rate / div->table[i].div;
+
+ if (now <= rate && now >= best) {
+ best = now;
+ div_index = i;
+ }
+ }
+
+ val = readl(div->reg);
+ val &= ~(((1 << div->width) - 1) << div->shift);
+ val |= div_index << div->shift;
+ writel(val, div->reg);
+
+ return 0;
+}
+
+static unsigned long clk_divider_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_divider_table *div =
+ container_of(clk, struct clk_divider_table, clk);
+ unsigned int val;
+
+ val = readl(div->reg) >> div->shift;
+ val &= (1 << div->width) - 1;
+
+ if (val >= div->table_size)
+ return 0;
+
+ return parent_rate / div->table[val].div;
+}
+
+struct clk_ops clk_divider_table_ops = {
+ .set_rate = clk_divider_set_rate,
+ .recalc_rate = clk_divider_recalc_rate,
+};
+
+struct clk *clk_divider_table(const char *name,
+ const char *parent, void __iomem *reg, u8 shift, u8 width,
+ const struct clk_div_table *table)
+{
+ struct clk_divider_table *div = xzalloc(sizeof(*div));
+ const struct clk_div_table *clkt;
+ int ret, max_div = 0;
+
+ div->shift = shift;
+ div->reg = reg;
+ div->width = width;
+ div->parent = parent;
+ div->clk.ops = &clk_divider_table_ops;
+ div->clk.name = name;
+ div->clk.parent_names = &div->parent;
+ div->clk.num_parents = 1;
+ div->table = table;
+
+ for (clkt = div->table; clkt->div; clkt++) {
+ if (clkt->div > max_div) {
+ max_div = clkt->div;
+ div->max_div_index = div->table_size;
+ }
+ div->table_size++;
+ }
+
+ ret = clk_register(&div->clk);
+ if (ret) {
+ free(div);
+ return ERR_PTR(ret);
+ }
+
+ return &div->clk;
+}
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 94f23dd854..07eace94df 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -252,6 +252,7 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
strcpy(client->dev.name, chip->type);
client->dev.type_data = client;
client->dev.platform_data = chip->platform_data;
+ client->dev.id = DEVICE_ID_DYNAMIC;
client->dev.bus = &i2c_bus;
client->adapter = adapter;
client->addr = chip->addr;
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index d7c29cc636..3c2017ebe4 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -131,7 +131,7 @@ static int stmpe_probe(struct device_d *dev)
i2c_ci->read_reg = stmpe_reg_read;
i2c_ci->write_reg = stmpe_reg_write;
- if (pdata->blocks &= STMPE_BLOCK_GPIO)
+ if (pdata->blocks & STMPE_BLOCK_GPIO)
add_generic_device("stmpe-gpio", DEVICE_ID_DYNAMIC, NULL, 0, 0, IORESOURCE_MEM, i2c_ci);
devfs_create(&stmpe_dev->cdev);
diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 975a44f569..c4509d3dd6 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -1128,6 +1128,7 @@ int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info)
int mxs_nand_hw_init(struct mxs_nand_info *info)
{
void __iomem *gpmi_regs = (void *)MXS_GPMI_BASE;
+ void __iomem *bch_regs = (void __iomem *)MXS_BCH_BASE;
int i = 0, ret;
u32 val;
@@ -1153,6 +1154,15 @@ int mxs_nand_hw_init(struct mxs_nand_info *info)
if (ret)
return ret;
+ val = readl(gpmi_regs + GPMI_VERSION);
+ info->version = val >> GPMI_VERSION_MINOR_OFFSET;
+
+ /* Reset BCH. Don't use SFTRST on MX23 due to Errata #2847 */
+ ret = mxs_reset_block(bch_regs + BCH_CTRL,
+ info->version == GPMI_VERSION_TYPE_MX23);
+ if (ret)
+ return ret;
+
/*
* Choose NAND mode, set IRQ polarity, disable write protection and
* select BCH ECC.
@@ -1163,9 +1173,6 @@ int mxs_nand_hw_init(struct mxs_nand_info *info)
GPMI_CTRL1_BCH_MODE;
writel(val, gpmi_regs + GPMI_CTRL1);
- val = readl(gpmi_regs + GPMI_VERSION);
- info->version = val >> GPMI_VERSION_MINOR_OFFSET;
-
return 0;
err2:
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 35319b430b..762adfe020 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -106,7 +106,7 @@ static int mdio_bus_match(struct device_d *dev, struct driver_d *drv)
struct phy_device *phydev = to_phy_device(dev);
struct phy_driver *phydrv = to_phy_driver(drv);
- return ((phydrv->phy_id & phydrv->phy_id_mask) ==
+ return ((phydrv->phy_id & phydrv->phy_id_mask) !=
(phydev->phy_id & phydrv->phy_id_mask));
}
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
index d749280193..61cbadaf2d 100644
--- a/drivers/usb/otg/ulpi.c
+++ b/drivers/usb/otg/ulpi.c
@@ -181,8 +181,11 @@ int ulpi_set_vbus(void __iomem *view, int on)
int ulpi_setup(void __iomem *view, int on)
{
- if (ulpi_probe(view))
- return -1;
+ int ret;
+
+ ret = ulpi_probe(view);
+ if (ret)
+ return ret;
return ulpi_set_vbus(view, on);
}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1030b50c63..4389cf8b93 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -184,9 +184,17 @@ struct clk {
#define CLK_ALWAYS_ENABLED (1 << 0)
+struct clk_div_table {
+ unsigned int val;
+ unsigned int div;
+};
+
struct clk *clk_fixed(const char *name, int rate);
struct clk *clk_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width);
+struct clk *clk_divider_table(const char *name,
+ const char *parent, void __iomem *reg, u8 shift, u8 width,
+ const struct clk_div_table *table);
struct clk *clk_fixed_factor(const char *name,
const char *parent, unsigned int mult, unsigned int div);
struct clk *clk_mux(const char *name, void __iomem *reg,