diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-07 11:54:19 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-07 11:54:19 +0100 |
commit | 6bbb1b51bf6fcc7ecc4ff3cb7c3cf472943faeac (patch) | |
tree | b7ee7acbf6928e3ff528e5633227bd6f91b86d21 | |
parent | 10ac493e963c9eea05f9e7f6c7e7d3e3db532ea7 (diff) | |
parent | 5a12d9036109f2a819e5e455102eb68db936608e (diff) | |
download | barebox-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.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-imx/clk-imx6.c | 40 | ||||
-rw-r--r-- | arch/arm/mach-imx/clk-pllv3.c | 83 | ||||
-rw-r--r-- | arch/arm/mach-imx/clk.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx-bbu-internal.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/devices-imx6.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/imx6-regs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap/gpmc.c | 10 | ||||
-rw-r--r-- | arch/mips/Makefile | 8 | ||||
-rw-r--r-- | common/bbu.c | 13 | ||||
-rw-r--r-- | drivers/ata/disk_ata_drive.c | 10 | ||||
-rw-r--r-- | drivers/base/platform.c | 4 | ||||
-rw-r--r-- | drivers/clk/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/clk-divider-table.c | 119 | ||||
-rw-r--r-- | drivers/i2c/i2c.c | 1 | ||||
-rw-r--r-- | drivers/mfd/stmpe-i2c.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_mxs.c | 13 | ||||
-rw-r--r-- | drivers/net/phy/mdio_bus.c | 2 | ||||
-rw-r--r-- | drivers/usb/otg/ulpi.c | 7 | ||||
-rw-r--r-- | include/linux/clk.h | 8 |
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, |