diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index 713248913..0e213ce9d 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -52,6 +52,7 @@ #define ARCH_EXID_SAMA5D33 0x00414300 #define ARCH_EXID_SAMA5D34 0x00414301 #define ARCH_EXID_SAMA5D35 0x00584300 +#define ARCH_EXID_SAMA5D36 0x00004301 #define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91SAM9 0x01900000 @@ -104,7 +105,7 @@ enum at91_soc_subtype { /* SAMA5D3 */ AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, - AT91_SOC_SAMA5D35, + AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36, /* Unknown subtype */ AT91_SOC_SUBTYPE_NONE @@ -206,12 +207,14 @@ static inline int at91_soc_is_detected(void) #define cpu_is_sama5d33() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D33) #define cpu_is_sama5d34() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D34) #define cpu_is_sama5d35() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D35) +#define cpu_is_sama5d36() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D36) #else #define cpu_is_sama5d3() (0) #define cpu_is_sama5d31() (0) #define cpu_is_sama5d33() (0) #define cpu_is_sama5d34() (0) #define cpu_is_sama5d35() (0) +#define cpu_is_sama5d36() (0) #endif /* diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c index 1bfae14f6..85efb2d78 100644 --- a/arch/arm/mach-at91/sama5d3.c +++ b/arch/arm/mach-at91/sama5d3.c @@ -348,11 +348,13 @@ static void __init sama5d3_register_clocks(void) if ( cpu_is_sama5d33() || cpu_is_sama5d34() - || cpu_is_sama5d35() ) + || cpu_is_sama5d35() + || cpu_is_sama5d36()) clk_register(&macb0_clk); if ( cpu_is_sama5d31() - || cpu_is_sama5d35() ) + || cpu_is_sama5d35() + || cpu_is_sama5d36()) clk_register(&macb1_clk); if (!cpu_is_sama5d35()) diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 65d0588b4..7a7de9804 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -162,6 +162,8 @@ static void __init soc_detect(u32 dbgu_base) break; case ARCH_EXID_SAMA5D35: at91_soc_initdata.subtype = AT91_SOC_SAMA5D35; + case ARCH_EXID_SAMA5D36: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D36; break; } } @@ -205,6 +207,7 @@ static const char *soc_subtype_name[] = { [AT91_SOC_SAMA5D33] = "sama5d33", [AT91_SOC_SAMA5D34] = "sama5d34", [AT91_SOC_SAMA5D35] = "sama5d35", + [AT91_SOC_SAMA5D36] = "sama5d36", [AT91_SOC_SUBTYPE_NONE] = "Unknown" }; diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 4ef25ec45..43974f03c 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -14,6 +14,29 @@ config CLOCKSOURCE_CLPS711X bool depends on ARCH_CLPS711X +config CLOCKSOURCE_DUMMY + bool "Enable dummy software-only clocksource" + help + When porting barebox to a new SoC there might be a case + of broken or absent clocksource. This causes barebox serial + console to be non functional. + To solve the problem this software-only clocksource driver is used. + WARNING!!! This clocksource doesn't provide correct timing. + To adjust this clocksource please use CONFIG_CLOCKSOURCE_DUMMY_RATE. + The bigger rate valuest makes clocksource "faster". + It's possible to add this clocksource unconditionally. + This clocksource starts very early (pure_initcall) so + real clocksource will take over. + This can help if initialization order is wrong so that + the time functions are used before the real clocksource + was initialized. + +config CLOCKSOURCE_DUMMY_RATE + int + prompt "dummy clocksource rate" + depends on CLOCKSOURCE_DUMMY + default 1000 + config CLOCKSOURCE_MVEBU bool depends on ARCH_MVEBU diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 25b7f460d..834a15d1e 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_AMBA_SP804) += amba-sp804.o obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o obj-$(CONFIG_CLOCKSOURCE_CLPS711X) += clps711x.o +obj-$(CONFIG_CLOCKSOURCE_DUMMY) += dummy.o obj-$(CONFIG_CLOCKSOURCE_MVEBU) += mvebu.o obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o diff --git a/drivers/clocksource/dummy.c b/drivers/clocksource/dummy.c new file mode 100644 index 000000000..154a8cd67 --- /dev/null +++ b/drivers/clocksource/dummy.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 Antony Pavlov + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 +#include +#include + +static uint64_t dummy_counter; + +static uint64_t dummy_cs_read(void) +{ + static int first; + + if (!first) { + pr_warn("Warning: Using dummy clocksource\n"); + first = 1; + } + + dummy_counter += CONFIG_CLOCKSOURCE_DUMMY_RATE; + + return dummy_counter; +} + +static struct clocksource dummy_cs = { + .read = dummy_cs_read, + .mask = CLOCKSOURCE_MASK(32), +}; + +static int clocksource_init(void) +{ + dummy_counter = 0; + + clocks_calc_mult_shift(&dummy_cs.mult, &dummy_cs.shift, + 100000000, NSEC_PER_SEC, 10); + + pr_debug("clocksource_init: mult=%08x, shift=%08x\n", + dummy_cs.mult, dummy_cs.shift); + init_clock(&dummy_cs); + + return 0; +} +pure_initcall(clocksource_init); diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c index 3053a8e89..59712b811 100644 --- a/drivers/mtd/nand/nand_omap_gpmc.c +++ b/drivers/mtd/nand/nand_omap_gpmc.c @@ -940,7 +940,7 @@ static int gpmc_nand_probe(struct device_d *pdev) switch (pdata->device_width) { case 0: - printk("probe buswidth\n"); + dev_dbg(pdev, "probing buswidth\n"); nand->options |= NAND_BUSWIDTH_AUTO; break; case 8: diff --git a/drivers/net/ar231x.c b/drivers/net/ar231x.c index 5c091140a..515de17b1 100644 --- a/drivers/net/ar231x.c +++ b/drivers/net/ar231x.c @@ -419,15 +419,9 @@ static int ar231x_eth_probe(struct device_d *dev) return 0; } -static void ar231x_eth_remove(struct device_d *dev) -{ - -} - static struct driver_d ar231x_eth_driver = { .name = "ar231x_eth", .probe = ar231x_eth_probe, - .remove = ar231x_eth_remove, }; static int ar231x_eth_driver_init(void) diff --git a/drivers/net/at91_ether.c b/drivers/net/at91_ether.c index 25924cf7e..bf2f957a3 100644 --- a/drivers/net/at91_ether.c +++ b/drivers/net/at91_ether.c @@ -357,13 +357,8 @@ static int at91_ether_probe(struct device_d *dev) return 0; } -static void at91_ether_remove(struct device_d *dev) -{ -} - static struct driver_d at91_ether_driver = { .name = "at91_ether", .probe = at91_ether_probe, - .remove = at91_ether_remove, }; device_platform_driver(at91_ether_driver); diff --git a/drivers/net/designware.c b/drivers/net/designware.c index ecb4656e9..e706f54b3 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -477,10 +477,6 @@ static int dwc_ether_probe(struct device_d *dev) return 0; } -static void dwc_ether_remove(struct device_d *dev) -{ -} - static __maybe_unused struct of_device_id dwc_ether_compatible[] = { { .compatible = "snps,dwmac-3.70a", @@ -493,7 +489,6 @@ static __maybe_unused struct of_device_id dwc_ether_compatible[] = { static struct driver_d dwc_ether_driver = { .name = "designware_eth", .probe = dwc_ether_probe, - .remove = dwc_ether_remove, .of_compatible = DRV_OF_COMPAT(dwc_ether_compatible), }; device_platform_driver(dwc_ether_driver); diff --git a/drivers/of/base.c b/drivers/of/base.c index 104b6daea..c440a69e6 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1841,8 +1841,11 @@ int of_device_is_stdout_path(struct device_d *dev) struct device_node *dn; const char *name; - name = of_get_property(of_chosen, "linux,stdout-path", NULL); - if (name == NULL) + name = of_get_property(of_chosen, "stdout-path", NULL); + if (!name) + name = of_get_property(of_chosen, "linux,stdout-path", NULL); + + if (!name) return 0; dn = of_find_node_by_path(name); diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c index 0ee2b26dc..abac812cb 100644 --- a/drivers/video/imx-ipu-fb.c +++ b/drivers/video/imx-ipu-fb.c @@ -1047,14 +1047,9 @@ static int imxfb_probe(struct device_d *dev) return ret; } -static void imxfb_remove(struct device_d *dev) -{ -} - static struct driver_d imx3fb_driver = { .name = "imx-ipu-fb", .probe = imxfb_probe, - .remove = imxfb_remove, }; device_platform_driver(imx3fb_driver); diff --git a/drivers/video/imx.c b/drivers/video/imx.c index 1dd6511d0..b12c09c8c 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -580,13 +580,8 @@ static int imxfb_probe(struct device_d *dev) return 0; } -static void imxfb_remove(struct device_d *dev) -{ -} - static struct driver_d imxfb_driver = { .name = "imxfb", .probe = imxfb_probe, - .remove = imxfb_remove, }; device_platform_driver(imxfb_driver); diff --git a/drivers/video/pxa.c b/drivers/video/pxa.c index 529190bae..b4ce3a1bf 100644 --- a/drivers/video/pxa.c +++ b/drivers/video/pxa.c @@ -536,13 +536,8 @@ static int pxafb_probe(struct device_d *dev) return 0; } -static void pxafb_remove(struct device_d *dev) -{ -} - static struct driver_d pxafb_driver = { .name = "pxafb", .probe = pxafb_probe, - .remove = pxafb_remove, }; device_platform_driver(pxafb_driver); diff --git a/include/param.h b/include/param.h index e8458b5b2..eac3372f3 100644 --- a/include/param.h +++ b/include/param.h @@ -54,6 +54,11 @@ struct param_d *dev_add_param_ip(struct device_d *dev, const char *name, int (*get)(struct param_d *p, void *priv), IPaddr_t *ip, void *priv); +struct param_d *dev_add_param_mac(struct device_d *dev, const char *name, + int (*set)(struct param_d *p, void *priv), + int (*get)(struct param_d *p, void *priv), + u8 *mac, void *priv); + int dev_add_param_fixed(struct device_d *dev, char *name, const char *value); void dev_remove_param(struct param_d *p); @@ -126,6 +131,14 @@ static inline struct param_d *dev_add_param_ip(struct device_d *dev, const char return NULL; } +static inline struct param_d *dev_add_param_mac(struct device_d *dev, const char *name, + int (*set)(struct param_d *p, void *priv), + int (*get)(struct param_d *p, void *priv), + u8 *mac, void *priv) +{ + return NULL; +} + static inline int dev_add_param_fixed(struct device_d *dev, char *name, char *value) { return 0; diff --git a/lib/parameter.c b/lib/parameter.c index 9dfde3f69..baa2b156c 100644 --- a/lib/parameter.c +++ b/lib/parameter.c @@ -542,6 +542,93 @@ struct param_d *dev_add_param_ip(struct device_d *dev, const char *name, return &pi->param; } + +struct param_mac { + struct param_d param; + char *mac; + u8 mac_str[sizeof("xx:xx:xx:xx:xx:xx")]; + const char *format; + int (*set)(struct param_d *p, void *priv); + int (*get)(struct param_d *p, void *priv); +}; + +int string_to_ethaddr(const char *str, u8 enetaddr[6]); +void ethaddr_to_string(const u8 enetaddr[6], char *str); + +static inline struct param_mac *to_param_mac(struct param_d *p) +{ + return container_of(p, struct param_mac, param); +} + +static int param_mac_set(struct device_d *dev, struct param_d *p, const char *val) +{ + struct param_mac *pm = to_param_mac(p); + char mac_save[6]; + int ret; + + if (!val) + return -EINVAL; + + memcpy(mac_save, pm->mac, 6); + + ret = string_to_ethaddr(val, pm->mac); + if (ret) + goto out; + + if (!pm->set) + return 0; + + ret = pm->set(p, p->driver_priv); + if (ret) + goto out; + + return 0; +out: + memcpy(pm->mac, mac_save, 6); + + return ret; +} + +static const char *param_mac_get(struct device_d *dev, struct param_d *p) +{ + struct param_mac *pm = to_param_mac(p); + int ret; + + if (pm->get) { + ret = pm->get(p, p->driver_priv); + if (ret) + return NULL; + } + + ethaddr_to_string(pm->mac, p->value); + + return p->value; +} + +struct param_d *dev_add_param_mac(struct device_d *dev, const char *name, + int (*set)(struct param_d *p, void *priv), + int (*get)(struct param_d *p, void *priv), + u8 *mac, void *priv) +{ + struct param_mac *pm; + int ret; + + pm = xzalloc(sizeof(*pm)); + pm->mac = mac; + pm->set = set; + pm->get = get; + pm->param.driver_priv = priv; + pm->param.value = pm->mac_str; + + ret = __dev_add_param(&pm->param, dev, name, + param_mac_set, param_mac_get, 0); + if (ret) { + free(pm); + return ERR_PTR(ret); + } + + return &pm->param; +} #endif /** diff --git a/net/eth.c b/net/eth.c index 1f48f2df8..3ced3cddb 100644 --- a/net/eth.c +++ b/net/eth.c @@ -257,17 +257,9 @@ int eth_rx(void) return eth_current->recv(eth_current); } -static int eth_set_ethaddr(struct device_d *dev, struct param_d *param, const char *val) +static int eth_set_ethaddr(struct param_d *param, void *priv) { - struct eth_device *edev = dev_to_edev(dev); - - if (!val) - return dev_param_set_generic(dev, param, NULL); - - if (string_to_ethaddr(val, edev->ethaddr) < 0) - return -EINVAL; - - dev_param_set_generic(dev, param, val); + struct eth_device *edev = priv; edev->set_ethaddr(edev, edev->ethaddr); @@ -345,7 +337,7 @@ int eth_register(struct eth_device *edev) dev_add_param_ip(dev, "serverip", NULL, NULL, &edev->serverip, edev); dev_add_param_ip(dev, "gateway", NULL, NULL, &edev->gateway, edev); dev_add_param_ip(dev, "netmask", NULL, NULL, &edev->netmask, edev); - dev_add_param(dev, "ethaddr", eth_set_ethaddr, NULL, 0); + dev_add_param_mac(dev, "ethaddr", eth_set_ethaddr, NULL, edev->ethaddr, edev); if (edev->init) edev->init(edev); diff --git a/scripts/omap4_usbboot/omap4_usbboot.c b/scripts/omap4_usbboot/omap4_usbboot.c index e52108614..0e5abcb15 100644 --- a/scripts/omap4_usbboot/omap4_usbboot.c +++ b/scripts/omap4_usbboot/omap4_usbboot.c @@ -35,16 +35,17 @@ #define WHITE 8 #define RED 1 #define BLACK 0 -#define FORMAT "%c[%d;%d;%dm" -#define TARGET_FORMAT 0x1B, BRIGHT, RED+30, BLACK+40 -#define HOST_FORMAT 0x1B, RESET, WHITE+30, BLACK+40 -#define host_print(fmt, arg...) printf(FORMAT fmt FORMAT, \ +#define TFORMAT "%c[%d;%dm" +#define HFORMAT "%c[%dm" +#define TARGET_FORMAT 0x1B, BRIGHT, RED+30 +#define HOST_FORMAT 0x1B, RESET +#define host_print(fmt, arg...) printf(HFORMAT fmt TFORMAT, \ HOST_FORMAT, ##arg, TARGET_FORMAT) void panic(struct termios *t_restore) { tcsetattr(STDIN_FILENO, TCSANOW, t_restore); - printf(FORMAT, HOST_FORMAT); + printf(HFORMAT, HOST_FORMAT); exit(1); } @@ -354,7 +355,7 @@ int usb_boot( tcgetattr(STDIN_FILENO, &vars.t_restore); tn = vars.t_restore; tn.c_lflag &= ~(ICANON | ECHO); - printf(FORMAT, TARGET_FORMAT); + printf(TFORMAT, TARGET_FORMAT); tcsetattr(STDIN_FILENO, TCSANOW, &tn); if (pthread_create(&thread, NULL, listenerTask, &vars)) host_print("listenerTask failed\n"); @@ -375,7 +376,7 @@ int usb_boot( usb_close(usb); pthread_mutex_destroy(&vars.usb_mutex); tcsetattr(STDIN_FILENO, TCSANOW, &vars.t_restore); - printf(FORMAT, HOST_FORMAT); + printf(HFORMAT, HOST_FORMAT); return 0; } @@ -415,7 +416,7 @@ int main(int argc, char **argv) sz = s.st_size; close(fd); argv++; - printf(FORMAT, HOST_FORMAT); + printf(HFORMAT, HOST_FORMAT); for (once = 1;;) { usb = usb_open(match_omap4_bootloader); if (usb)