From 34934c183b2880340c9ee8f7f36da5a77bffea46 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Tue, 2 Jul 2013 20:30:47 +0200 Subject: LED: add support for device tree parsing of gpio-leds This adds a driver option to probe GPIO LEDs from device tree compatible with "gpio-leds" device tree nodes. Signed-off-by: Sebastian Hesselbarth Signed-off-by: Sascha Hauer --- drivers/led/Kconfig | 4 ++++ drivers/led/led-gpio.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig index 8ca6ab8e44..3ead82e031 100644 --- a/drivers/led/Kconfig +++ b/drivers/led/Kconfig @@ -7,6 +7,10 @@ config LED_GPIO bool "gpio LED support" depends on GENERIC_GPIO +config LED_GPIO_OF + bool "support parsing gpio LEDs from device tree" + depends on LED_GPIO && OFTREE + config LED_GPIO_RGB bool "gpio rgb LED support" depends on LED_GPIO diff --git a/drivers/led/led-gpio.c b/drivers/led/led-gpio.c index 08dc9bad0d..54f9264d44 100644 --- a/drivers/led/led-gpio.c +++ b/drivers/led/led-gpio.c @@ -18,8 +18,10 @@ * */ #include +#include #include #include +#include static void led_gpio_set(struct led *led, unsigned int value) { @@ -194,3 +196,46 @@ void led_gpio_rgb_unregister(struct gpio_led *led) led_unregister(&led->led); } #endif /* CONFIG_LED_GPIO_RGB */ + +#ifdef CONFIG_LED_GPIO_OF + +static int led_gpio_of_probe(struct device_d *dev) +{ + struct device_node *child; + + for_each_child_of_node(dev->device_node, child) { + struct gpio_led *gled; + enum of_gpio_flags flags; + int gpio; + + gpio = of_get_named_gpio_flags(child, "gpios", 0, &flags); + if (gpio < 0) + continue; + + gled = xzalloc(sizeof(*gled)); + gled->led.name = xstrdup(child->name); + gled->gpio = gpio; + gled->active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0; + + dev_dbg(dev, "register led %s on gpio%d, active_low = %d\n", + gled->led.name, gled->gpio, gled->active_low); + + led_gpio_register(gled); + } + + return 0; +} + +static struct of_device_id led_gpio_of_ids[] = { + { .compatible = "gpio-leds", }, + { } +}; + +static struct driver_d led_gpio_of_driver = { + .name = "gpio-leds", + .probe = led_gpio_of_probe, + .of_compatible = DRV_OF_COMPAT(led_gpio_of_ids), +}; +device_platform_driver(led_gpio_of_driver); + +#endif /* CONFIG LED_GPIO_OF */ -- cgit v1.2.3 From 98df44ee7d6db3919a4dd11e227d1e0caedbfe86 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 8 Jul 2013 09:40:17 +0200 Subject: led: gpio: Add trigger support Signed-off-by: Sascha Hauer --- Documentation/devicetree/bindings/leds/common.txt | 8 ++++++ drivers/led/led-gpio.c | 33 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/common.txt diff --git a/Documentation/devicetree/bindings/leds/common.txt b/Documentation/devicetree/bindings/leds/common.txt new file mode 100644 index 0000000000..db264b332f --- /dev/null +++ b/Documentation/devicetree/bindings/leds/common.txt @@ -0,0 +1,8 @@ +Common leds properties. + +- linux,default-trigger barebox,default-trigger: This parameter, if present, is a + string defining the trigger assigned to the LED. Current triggers are: + "heartbeat" - LED flashes at a constant rate + "panic" - LED turns on when barebox panics + "net" - LED indicates network activity + diff --git a/drivers/led/led-gpio.c b/drivers/led/led-gpio.c index 54f9264d44..69db70fab8 100644 --- a/drivers/led/led-gpio.c +++ b/drivers/led/led-gpio.c @@ -199,6 +199,38 @@ void led_gpio_rgb_unregister(struct gpio_led *led) #ifdef CONFIG_LED_GPIO_OF +struct led_trg { + const char *str; + enum led_trigger trg; +}; + +static struct led_trg triggers[] = { + { .str = "heartbeat", LED_TRIGGER_HEARTBEAT, }, + { .str = "panic", LED_TRIGGER_PANIC, }, + { .str = "net", LED_TRIGGER_NET_TXRX, }, +}; + +static void led_of_parse_trigger(struct led *led, struct device_node *np) +{ + const char *trigger; + int i; + + trigger = of_get_property(np, "linux,default-trigger", NULL); + if (!trigger) + trigger = of_get_property(np, "barebox,default-trigger", NULL); + + if (!trigger) + return; + + for (i = 0; i < ARRAY_SIZE(triggers); i++) { + struct led_trg *trg = &triggers[i]; + if (!strcmp(trg->str, trigger)) { + led_set_trigger(trg->trg, led); + return; + } + } +} + static int led_gpio_of_probe(struct device_d *dev) { struct device_node *child; @@ -220,6 +252,7 @@ static int led_gpio_of_probe(struct device_d *dev) dev_dbg(dev, "register led %s on gpio%d, active_low = %d\n", gled->led.name, gled->gpio, gled->active_low); + led_of_parse_trigger(&gled->led, child); led_gpio_register(gled); } -- cgit v1.2.3 From 121c3d6e9c2fb4649f3349edc522c99f3b9585d9 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 24 May 2013 12:54:54 +0200 Subject: devfs: let devfs_add_partition return the new partition Useful for unregistering later or for adding addional flags. Signed-off-by: Sascha Hauer --- arch/x86/boards/x86_generic/generic_pc.c | 6 ++++-- commands/partition.c | 11 ++++++++--- common/environment.c | 10 ++++++++-- common/partitions.c | 12 ++++++++---- fs/devfs-core.c | 12 ++++++------ include/driver.h | 2 +- 6 files changed, 35 insertions(+), 18 deletions(-) diff --git a/arch/x86/boards/x86_generic/generic_pc.c b/arch/x86/boards/x86_generic/generic_pc.c index e49354ba75..9d3706923f 100644 --- a/arch/x86/boards/x86_generic/generic_pc.c +++ b/arch/x86/boards/x86_generic/generic_pc.c @@ -25,6 +25,7 @@ #include #include #include +#include /* * These datas are from the MBR, created by the linker and filled by the @@ -43,6 +44,7 @@ extern uint8_t pers_env_drive; static int devices_init(void) { int rc; + struct cdev *cdev; /* extended memory only */ add_mem_device("ram0", 0x0, bios_get_memsize() << 10, @@ -51,11 +53,11 @@ static int devices_init(void) NULL); if (pers_env_size != PATCH_AREA_PERS_SIZE_UNUSED) { - rc = devfs_add_partition("biosdisk0", + cdev = devfs_add_partition("biosdisk0", pers_env_storage * 512, (unsigned)pers_env_size * 512, DEVFS_PARTITION_FIXED, "env0"); - printf("Partition: %d\n", rc); + printf("Partition: %d\n", IS_ERR(cdev) ? PTR_ERR(cdev) : 0); } else printf("No persistent storage defined\n"); diff --git a/commands/partition.c b/commands/partition.c index 6f8d6343c8..6d37471f4f 100644 --- a/commands/partition.c +++ b/commands/partition.c @@ -35,6 +35,7 @@ #include #include #include +#include #define SIZE_REMAINING ((ulong)-1) @@ -48,7 +49,8 @@ static int mtd_part_do_parse_one(char *devname, const char *partstr, char *end; char buf[PATH_MAX] = {}; unsigned long flags = 0; - int ret; + int ret = 0; + struct cdev *cdev; memset(buf, 0, PATH_MAX); @@ -99,9 +101,12 @@ static int mtd_part_do_parse_one(char *devname, const char *partstr, *retsize = size; - ret = devfs_add_partition(devname, *offset, size, flags, buf); - if (ret) + cdev = devfs_add_partition(devname, *offset, size, flags, buf); + if (IS_ERR(cdev)) { + ret = PTR_ERR(cdev); printf("cannot create %s: %s\n", buf, strerror(-ret)); + } + return ret; } diff --git a/common/environment.c b/common/environment.c index 78cd45cce7..24487775d7 100644 --- a/common/environment.c +++ b/common/environment.c @@ -379,7 +379,7 @@ out: int envfs_register_partition(const char *devname, unsigned int partnr) { - struct cdev *cdev; + struct cdev *cdev, *part; char *partname; if (!devname) @@ -398,8 +398,14 @@ int envfs_register_partition(const char *devname, unsigned int partnr) return -ENODEV; } - return devfs_add_partition(partname, 0, cdev->size, + part = devfs_add_partition(partname, 0, cdev->size, DEVFS_PARTITION_FIXED, "env0"); + if (part) + return 0; + + free(partname); + + return -EINVAL; } EXPORT_SYMBOL(envfs_register_partition); #endif diff --git a/common/partitions.c b/common/partitions.c index 35a604c35f..38032a349c 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "partitions/parser.h" @@ -48,16 +49,19 @@ static int register_one_partition(struct block_device *blk, int ret; uint64_t start = part->first_sec * SECTOR_SIZE; uint64_t size = part->size * SECTOR_SIZE; + struct cdev *cdev; partition_name = asprintf("%s.%d", blk->cdev.name, no); if (!partition_name) return -ENOMEM; dev_dbg(blk->dev, "Registering partition %s on drive %s\n", partition_name, blk->cdev.name); - ret = devfs_add_partition(blk->cdev.name, + cdev = devfs_add_partition(blk->cdev.name, start, size, 0, partition_name); - if (ret) + if (IS_ERR(cdev)) { + ret = PTR_ERR(cdev); goto out; + } free(partition_name); @@ -70,10 +74,10 @@ static int register_one_partition(struct block_device *blk, dev_dbg(blk->dev, "Registering partition %s on drive %s\n", partition_name, blk->cdev.name); - ret = devfs_add_partition(blk->cdev.name, + cdev = devfs_add_partition(blk->cdev.name, start, size, 0, partition_name); - if (ret) + if (IS_ERR(cdev)) dev_warn(blk->dev, "Registering partition %s on drive %s failed\n", partition_name, blk->cdev.name); diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 262e0a2c34..a16866eab9 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -226,21 +226,21 @@ int devfs_remove(struct cdev *cdev) return 0; } -int devfs_add_partition(const char *devname, loff_t offset, loff_t size, +struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size, int flags, const char *name) { struct cdev *cdev, *new; cdev = cdev_by_name(name); if (cdev) - return -EEXIST; + return ERR_PTR(-EEXIST); cdev = cdev_by_name(devname); if (!cdev) - return -ENOENT; + return ERR_PTR(-ENOENT); if (offset + size > cdev->size) - return -EINVAL; + return ERR_PTR(-EINVAL); new = xzalloc(sizeof (*new)); new->name = strdup(name); @@ -257,14 +257,14 @@ int devfs_add_partition(const char *devname, loff_t offset, loff_t size, if (IS_ERR(new->mtd)) { int ret = PTR_ERR(new->mtd); free(new); - return ret; + return ERR_PTR(ret); } } #endif devfs_create(new); - return 0; + return new; } int devfs_del_partition(const char *name) diff --git a/include/driver.h b/include/driver.h index b18318fe0c..9f114fff58 100644 --- a/include/driver.h +++ b/include/driver.h @@ -469,7 +469,7 @@ int cdev_erase(struct cdev *cdev, size_t count, loff_t offset); #define DEVFS_IS_PARTITION (1 << 2) #define DEVFS_IS_CHARACTER_DEV (1 << 3) -int devfs_add_partition(const char *devname, loff_t offset, loff_t size, +struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size, int flags, const char *name); int devfs_del_partition(const char *name); -- cgit v1.2.3 From f57a85985b7ece8824c1dc2232962cbc8f96cb38 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 5 Jul 2013 09:17:30 +0200 Subject: of: export of_default_bus_match_table For code which wants to call of_platform_populate. Signed-off-by: Sascha Hauer --- include/of.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/of.h b/include/of.h index ebe8e3966b..0d8f6b3c67 100644 --- a/include/of.h +++ b/include/of.h @@ -679,4 +679,6 @@ static inline int of_property_write_u64(struct device_node *np, return of_property_write_u64_array(np, propname, &value, 1); } +extern const struct of_device_id of_default_bus_match_table[]; + #endif /* __OF_H */ -- cgit v1.2.3 From abf95154f5d139f2e54559955e80e1752989cc88 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 24 May 2013 23:31:29 +0200 Subject: of: partitions: factor out function to parse a single partition To make it usable for other code. Signed-off-by: Sascha Hauer --- drivers/of/partition.c | 58 ++++++++++++++++++++++++++++---------------------- include/of.h | 1 + 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/drivers/of/partition.c b/drivers/of/partition.c index e4b7d1e66b..d69251e666 100644 --- a/drivers/of/partition.c +++ b/drivers/of/partition.c @@ -23,44 +23,52 @@ #include #include -int of_parse_partitions(struct cdev *cdev, struct device_node *node) +struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node) { - struct device_node *n; const char *partname; char *filename; + struct cdev *new; + const __be32 *reg; + unsigned long offset, size; + const char *name; + int len; + unsigned long flags = 0; - for_each_child_of_node(node, n) { - const __be32 *reg; - unsigned long offset, size; - const char *name; - int len; - unsigned long flags = 0; + reg = of_get_property(node, "reg", &len); + if (!reg) + return NULL; + + offset = be32_to_cpu(reg[0]); + size = be32_to_cpu(reg[1]); + + partname = of_get_property(node, "label", &len); + if (!partname) + partname = of_get_property(node, "name", &len); + name = (char *)partname; - reg = of_get_property(n, "reg", &len); - if (!reg) - continue; + debug("add partition: %s.%s 0x%08lx 0x%08lx\n", cdev->name, partname, offset, size); - offset = be32_to_cpu(reg[0]); - size = be32_to_cpu(reg[1]); + if (of_get_property(node, "read-only", &len)) + flags = DEVFS_PARTITION_READONLY; - partname = of_get_property(n, "label", &len); - if (!partname) - partname = of_get_property(n, "name", &len); - name = (char *)partname; + filename = asprintf("%s.%s", cdev->name, partname); - debug("add partition: %s.%s 0x%08lx 0x%08lx\n", cdev->name, partname, offset, size); + new = devfs_add_partition(cdev->name, offset, size, flags, filename); - if (of_get_property(n, "read-only", &len)) - flags = DEVFS_PARTITION_READONLY; + if (cdev->mtd && cdev->mtd->type == MTD_NANDFLASH) + dev_add_bb_dev(filename, NULL); - filename = asprintf("%s.%s", cdev->name, partname); + free(filename); - devfs_add_partition(cdev->name, offset, size, flags, filename); + return new; +} - if (cdev->mtd && cdev->mtd->type == MTD_NANDFLASH) - dev_add_bb_dev(filename, NULL); +int of_parse_partitions(struct cdev *cdev, struct device_node *node) +{ + struct device_node *n; - free(filename); + for_each_child_of_node(node, n) { + of_parse_partition(cdev, n); } return 0; diff --git a/include/of.h b/include/of.h index 0d8f6b3c67..710383c30f 100644 --- a/include/of.h +++ b/include/of.h @@ -221,6 +221,7 @@ extern int of_platform_populate(struct device_node *root, struct device_d *parent); extern struct device_d *of_find_device_by_node(struct device_node *np); +struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node); int of_parse_partitions(struct cdev *cdev, struct device_node *node); int of_device_is_stdout_path(struct device_d *dev); const char *of_get_model(void); -- cgit v1.2.3 From bec70b3aaa1a750d32ac8c5299fb434454a87f07 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 10 Jul 2013 08:27:41 +0200 Subject: cdev: introduce partition names currently most partition cdevs have the name . This makes it hard to find a partition by . This introduces a partname field in struct cdev so that. Signed-off-by: Sascha Hauer --- fs/devfs-core.c | 3 +++ include/driver.h | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/devfs-core.c b/fs/devfs-core.c index a16866eab9..a2bea93ed6 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -244,6 +244,8 @@ struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size new = xzalloc(sizeof (*new)); new->name = strdup(name); + if (!strncmp(devname, name, strlen(devname))) + new->partname = xstrdup(name + strlen(devname) + 1); new->ops = cdev->ops; new->priv = cdev->priv; new->size = size; @@ -291,6 +293,7 @@ int devfs_del_partition(const char *name) return ret; free(cdev->name); + free(cdev->partname); free(cdev); return 0; diff --git a/include/driver.h b/include/driver.h index 9f114fff58..353af3a0cb 100644 --- a/include/driver.h +++ b/include/driver.h @@ -444,7 +444,10 @@ struct cdev { struct device_d *dev; struct list_head list; struct list_head devices_list; - char *name; + char *name; /* filename under /dev/ */ + char *partname; /* the partition name, usually the above without the + * device part, i.e. name = "nand0.barebox" -> partname = "barebox" + */ loff_t offset; loff_t size; unsigned int flags; -- cgit v1.2.3 From 2672c906a4b83cd2aef1ddc0b9d2ec54b89eba3d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 10 Jul 2013 08:48:00 +0200 Subject: cdev: allow to open a struct cdev cdev_open() opens a cdev by name. This introduces cdev_do_open which allows to open a cdev when the cdev is already found by other means. Signed-off-by: Sascha Hauer --- fs/devfs-core.c | 16 +++++++++++----- include/driver.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/fs/devfs-core.c b/fs/devfs-core.c index a2bea93ed6..816f244f1c 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -70,6 +70,14 @@ int cdev_find_free_index(const char *basename) return -EBUSY; /* all indexes are used */ } +int cdev_do_open(struct cdev *cdev, unsigned long flags) +{ + if (cdev->ops->open) + return cdev->ops->open(cdev, flags); + + return 0; +} + struct cdev *cdev_open(const char *name, unsigned long flags) { struct cdev *cdev = cdev_by_name(name); @@ -78,11 +86,9 @@ struct cdev *cdev_open(const char *name, unsigned long flags) if (!cdev) return NULL; - if (cdev->ops->open) { - ret = cdev->ops->open(cdev, flags); - if (ret) - return NULL; - } + ret = cdev_do_open(cdev, flags); + if (ret) + return NULL; return cdev; } diff --git a/include/driver.h b/include/driver.h index 353af3a0cb..7ac2eef845 100644 --- a/include/driver.h +++ b/include/driver.h @@ -460,6 +460,7 @@ int devfs_remove(struct cdev *); int cdev_find_free_index(const char *); struct cdev *cdev_by_name(const char *filename); struct cdev *cdev_open(const char *name, unsigned long flags); +int cdev_do_open(struct cdev *, unsigned long flags); void cdev_close(struct cdev *cdev); int cdev_flush(struct cdev *cdev); ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags); -- cgit v1.2.3 From 0ee203186d1adf98a04484ee9e601ca9714f0497 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 10 Jul 2013 08:49:46 +0200 Subject: cdev: add device_find_partition device_find_partition allows to find a partition of a device with a particular name. Signed-off-by: Sascha Hauer --- fs/devfs-core.c | 27 +++++++++++++++++++++++++++ include/driver.h | 1 + 2 files changed, 28 insertions(+) diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 816f244f1c..a92d4347f8 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -56,6 +56,33 @@ struct cdev *cdev_by_name(const char *filename) return NULL; } +/** + * device_find_partition - find a partition belonging to a physical device + * + * @dev: the device which should be searched for partitions + * @name: the partition name + */ +struct cdev *device_find_partition(struct device_d *dev, const char *name) +{ + struct cdev *cdev; + struct device_d *child; + + list_for_each_entry(cdev, &dev->cdevs, devices_list) { + if (!cdev->partname) + continue; + if (!strcmp(cdev->partname, name)) + return cdev; + } + + device_for_each_child(dev, child) { + cdev = device_find_partition(child, name); + if (cdev) + return cdev; + } + + return NULL; +} + int cdev_find_free_index(const char *basename) { int i; diff --git a/include/driver.h b/include/driver.h index 7ac2eef845..f95c93cca4 100644 --- a/include/driver.h +++ b/include/driver.h @@ -458,6 +458,7 @@ struct cdev { int devfs_create(struct cdev *); int devfs_remove(struct cdev *); int cdev_find_free_index(const char *); +struct cdev *device_find_partition(struct device_d *dev, const char *name); struct cdev *cdev_by_name(const char *filename); struct cdev *cdev_open(const char *name, unsigned long flags); int cdev_do_open(struct cdev *, unsigned long flags); -- cgit v1.2.3 From b2968cc8af06bfa851cf40fd5e4c845634a0caa4 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 10 Jul 2013 08:50:59 +0200 Subject: mci: set partnames of eMMC boot partitions Signed-off-by: Sascha Hauer --- drivers/mci/mci-core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 67668d53f0..02e6216caf 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -406,7 +406,7 @@ static int mci_calc_blk_cnt(uint64_t cap, unsigned shift) } static void mci_part_add(struct mci *mci, uint64_t size, - unsigned int part_cfg, char *name, int idx, bool ro, + unsigned int part_cfg, char *name, char *partname, int idx, bool ro, int area_type) { struct mci_part *part = &mci->part[mci->nr_parts]; @@ -414,6 +414,7 @@ static void mci_part_add(struct mci *mci, uint64_t size, part->mci = mci; part->size = size; part->blk.cdev.name = name; + part->blk.cdev.partname = partname; part->blk.blockbits = SECTOR_SHIFT; part->blk.num_blocks = mci_calc_blk_cnt(size, part->blk.blockbits); part->area_type = area_type; @@ -482,13 +483,14 @@ static int mmc_change_freq(struct mci *mci) unsigned int part_size; for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) { - char *name; + char *name, *partname; part_size = mci->ext_csd[EXT_CSD_BOOT_MULT] << 17; - name = asprintf("%s.boot%d", mci->cdevname, idx); + partname = asprintf("boot%d", idx); + name = asprintf("%s.%s", mci->cdevname, partname); mci_part_add(mci, part_size, EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, - name, idx, true, + name, partname, idx, true, MMC_BLK_DATA_AREA_BOOT); } @@ -1104,7 +1106,7 @@ static int mci_startup(struct mci *mci) err = mci_set_blocklen(mci, mci->read_bl_len); mci_part_add(mci, mci->capacity, 0, - mci->cdevname, 0, true, + mci->cdevname, NULL, 0, true, MMC_BLK_DATA_AREA_MAIN); return err; -- cgit v1.2.3 From c7b4d3669c64ab13e0b35ef0329b8354713c05c5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 11 Jul 2013 18:57:29 +0200 Subject: bus: Add imx-weim support Mostly taken from the kernel with support for other SoCs from Alexander Shiyan. Signed-off-by: Sascha Hauer Cc: Alexander Shiyan --- drivers/Kconfig | 1 + drivers/Makefile | 1 + drivers/bus/Kconfig | 7 ++ drivers/bus/Makefile | 1 + drivers/bus/imx-weim.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 drivers/bus/Kconfig create mode 100644 drivers/bus/Makefile create mode 100644 drivers/bus/imx-weim.c diff --git a/drivers/Kconfig b/drivers/Kconfig index 3a95e5140d..d34d2c7443 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -24,5 +24,6 @@ source "drivers/dma/Kconfig" source "drivers/gpio/Kconfig" source "drivers/w1/Kconfig" source "drivers/pinctrl/Kconfig" +source "drivers/bus/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index daf821c83c..ba1dc6df76 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -23,3 +23,4 @@ obj-y += gpio/ obj-$(CONFIG_OFTREE) += of/ obj-$(CONFIG_W1) += w1/ obj-y += pinctrl/ +obj-y += bus/ diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig new file mode 100644 index 0000000000..5938d3f2dc --- /dev/null +++ b/drivers/bus/Kconfig @@ -0,0 +1,7 @@ +menu "Bus devices" + +config IMX_WEIM + depends on ARCH_IMX + bool "i.MX WEIM driver" + +endmenu diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile new file mode 100644 index 0000000000..42a8d49479 --- /dev/null +++ b/drivers/bus/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_IMX_WEIM) += imx-weim.o diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c new file mode 100644 index 0000000000..78bccda15a --- /dev/null +++ b/drivers/bus/imx-weim.c @@ -0,0 +1,171 @@ +/* + * EIM driver for Freescale's i.MX chips + * + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include +#include +#include + +struct imx_weim_devtype { + unsigned int cs_count; + unsigned int cs_regs_count; + unsigned int cs_stride; +}; + +static const struct imx_weim_devtype imx1_weim_devtype = { + .cs_count = 6, + .cs_regs_count = 2, + .cs_stride = 0x08, +}; + +static const struct imx_weim_devtype imx27_weim_devtype = { + .cs_count = 6, + .cs_regs_count = 3, + .cs_stride = 0x10, +}; + +static const struct imx_weim_devtype imx50_weim_devtype = { + .cs_count = 4, + .cs_regs_count = 6, + .cs_stride = 0x18, +}; + +static const struct imx_weim_devtype imx51_weim_devtype = { + .cs_count = 6, + .cs_regs_count = 6, + .cs_stride = 0x18, +}; + +static struct of_device_id weim_id_table[] = { + { + /* i.MX1/21 */ + .compatible = "fsl,imx1-weim", + .data = (unsigned long)&imx1_weim_devtype, + }, { + /* i.MX25/27/31/35 */ + .compatible = "fsl,imx27-weim", + .data = (unsigned long)&imx27_weim_devtype, + }, { + /* i.MX50/53/6Q */ + .compatible = "fsl,imx50-weim", + .data = (unsigned long)&imx50_weim_devtype, + }, { + /* i.MX51 */ + .compatible = "fsl,imx51-weim", + .data = (unsigned long)&imx51_weim_devtype, + }, { + .compatible = "fsl,imx6q-weim", + .data = (unsigned long)&imx50_weim_devtype, + }, { + } +}; + +struct imx_weim { + struct device_d *dev; + void __iomem *base; + struct imx_weim_devtype *devtype; +}; + +/* Parse and set the timing for this device. */ +static int +weim_timing_setup(struct imx_weim *weim, struct device_node *np) +{ + struct imx_weim_devtype *devtype = weim->devtype; + u32 cs_idx, value[devtype->cs_regs_count]; + int i, ret; + + /* get the CS index from this child node's "reg" property. */ + ret = of_property_read_u32(np, "reg", &cs_idx); + if (ret) + return ret; + + if (cs_idx >= devtype->cs_count) + return -EINVAL; + + ret = of_property_read_u32_array(np, "fsl,weim-cs-timing", + value, devtype->cs_regs_count); + if (ret) + return ret; + + dev_dbg(weim->dev, "setting up cs for %s\n", np->name); + + /* set the timing for WEIM */ + for (i = 0; i < devtype->cs_regs_count; i++) + writel(value[i], weim->base + cs_idx * devtype->cs_stride + i * 4); + + return 0; +} + +static int weim_parse_dt(struct imx_weim *weim) +{ + struct device_node *child; + int ret; + + for_each_child_of_node(weim->dev->device_node, child) { + if (!child->name) + continue; + + ret = weim_timing_setup(weim, child); + if (ret) { + dev_err(weim->dev, "%s set timing failed.\n", + child->full_name); + return ret; + } + } + + ret = of_platform_populate(weim->dev->device_node, NULL, weim->dev); + if (ret) + dev_err(weim->dev, "%s fail to create devices.\n", + weim->dev->device_node->full_name); + return ret; +} + +static int weim_probe(struct device_d *dev) +{ + struct imx_weim_devtype *devtype; + struct imx_weim *weim; + int ret; + + ret = dev_get_drvdata(dev, (unsigned long *)&devtype); + if (ret) + return ret; + + weim = xzalloc(sizeof(*weim)); + + weim->dev = dev; + weim->devtype = devtype; + + /* get the resource */ + weim->base = dev_request_mem_region(dev, 0); + if (!weim->base) { + ret = -EBUSY; + goto weim_err; + } + + /* parse the device node */ + ret = weim_parse_dt(weim); + if (ret) { + goto weim_err; + } + + dev_info(dev, "WEIM driver registered.\n"); + + return 0; + +weim_err: + return ret; +} + +static struct driver_d weim_driver = { + .name = "imx-weim", + .of_compatible = DRV_OF_COMPAT(weim_id_table), + .probe = weim_probe, +}; +device_platform_driver(weim_driver); -- cgit v1.2.3 From 9cb5f51d0aeca9b2f18019d05b7b09884809037d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Jul 2013 14:36:26 +0200 Subject: of: partition: check for valid node So that users can call the of partition parsers without checking if they are probed from the devicetree. Signed-off-by: Sascha Hauer --- drivers/of/partition.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/of/partition.c b/drivers/of/partition.c index d69251e666..7199eff875 100644 --- a/drivers/of/partition.c +++ b/drivers/of/partition.c @@ -34,6 +34,9 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node) int len; unsigned long flags = 0; + if (!node) + return NULL; + reg = of_get_property(node, "reg", &len); if (!reg) return NULL; @@ -67,6 +70,9 @@ int of_parse_partitions(struct cdev *cdev, struct device_node *node) { struct device_node *n; + if (!node) + return -EINVAL; + for_each_child_of_node(node, n) { of_parse_partition(cdev, n); } -- cgit v1.2.3 From 3ae902ed7f06e9392624dad1ed23fd4f0dc9c38b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Jul 2013 15:36:40 +0200 Subject: of: Add convenience functions to en/disable devicenodes These functions allow to manipulate the "status" property of devicenodes effectively enabling/disabling devices. Signed-off-by: Sascha Hauer --- drivers/of/base.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/of.h | 5 +++++ 2 files changed, 70 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index e9f1f79324..0b1a8a2fa8 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1739,3 +1739,68 @@ int of_add_initrd(struct device_node *root, resource_size_t start, return 0; } + +/** + * of_device_enable - enable a devicenode device + * @node - the node to enable + * + * This deletes the status property of a devicenode effectively + * enabling the device. + */ +int of_device_enable(struct device_node *node) +{ + struct property *pp; + + pp = of_find_property(node, "status", NULL); + if (!pp) + return 0; + + of_delete_property(pp); + + return 0; +} + +/** + * of_device_enable_path - enable a devicenode + * @path - the nodepath to enable + * + * wrapper around of_device_enable taking the nodepath as argument + */ +int of_device_enable_path(const char *path) +{ + struct device_node *node; + + node = of_find_node_by_path(path); + if (!node) + return -ENODEV; + + return of_device_enable(node); +} + +/** + * of_device_enable - disable a devicenode device + * @node - the node to disable + * + * This sets the status of a devicenode to "disabled" + */ +int of_device_disable(struct device_node *node) +{ + return of_set_property(node, "status", "disabled", sizeof("disabled"), 1); +} + +/** + * of_device_disable_path - disable a devicenode + * @path - the nodepath to disable + * + * wrapper around of_device_disable taking the nodepath as argument + */ +int of_device_disable_path(const char *path) +{ + struct device_node *node; + + node = of_find_node_by_path(path); + if (!node) + return -ENODEV; + + return of_device_disable(node); +} diff --git a/include/of.h b/include/of.h index 710383c30f..7b600f038b 100644 --- a/include/of.h +++ b/include/of.h @@ -682,4 +682,9 @@ static inline int of_property_write_u64(struct device_node *np, extern const struct of_device_id of_default_bus_match_table[]; +int of_device_enable(struct device_node *node); +int of_device_enable_path(const char *path); +int of_device_disable(struct device_node *node); +int of_device_disable_path(const char *path); + #endif /* __OF_H */ -- cgit v1.2.3 From 309504327491b2f72c7b870d881f15c62fd95ed5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Jul 2013 13:00:29 +0200 Subject: mtd: Add devicetree partition parsing Signed-off-by: Sascha Hauer --- drivers/mtd/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index 37f4428dc3..f46ab4692d 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -365,6 +365,7 @@ int add_mtd_device(struct mtd_info *mtd, char *devname) } devfs_create(&mtd->cdev); + of_parse_partitions(&mtd->cdev, mtd->parent->device_node); list_for_each_entry(hook, &mtd_register_hooks, hook) if (hook->add_mtd_device) -- cgit v1.2.3 From da6c4b21a856139b709e466823e4e6ccaf5e195b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Jul 2013 14:38:05 +0200 Subject: mci: Add devicetree partition parsing MMC/SD cards normally have a DOS/GPT partition table, but sometimes barebox uses the unpartitioned area to store its environment. Add devicetree partition parsing also for SD/MMC cards so that we have a way to describe the partition in the devicetree. Signed-off-by: Sascha Hauer --- drivers/mci/mci-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 02e6216caf..66ddb5b4ff 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -1558,6 +1558,7 @@ static int mci_card_probe(struct mci *mci) dev_warn(&mci->dev, "No partition table found\n"); rc = 0; /* it's not a failure */ } + of_parse_partitions(&part->blk.cdev, host->hw_dev->device_node); } if (IS_ENABLED(CONFIG_MCI_MMC_BOOT_PARTITIONS) && -- cgit v1.2.3 From 874f318037b6941ad7261e398a03d177f3383eb1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 10 Jul 2013 08:54:44 +0200 Subject: Add configurability via devicetree This adds the possibility to configure the place for the environment from the devicetree and to partition devices from the devicetree. Configuration has the general form of devices with a regular compatible property. This allows to later add additional drivers or drivers with different behaviour (for example to add support for redundant environment). The configuration is all in the /chosen/barebox/ hierarchy of the devicetree. This separates the configuration from the hardware description. Also it makes it possible to store the configuration in a completely separate devicetree (or devicetree overlay). For the same reason all configuration is done using nodepathes rather than phandles. Signed-off-by: Sascha Hauer --- Documentation/devicetree/bindings/barebox.txt | 10 ++ .../bindings/barebox/barebox,environment.txt | 25 ++++ drivers/of/Kconfig | 9 ++ drivers/of/Makefile | 1 + drivers/of/barebox.c | 99 +++++++++++++ drivers/of/of_path.c | 155 +++++++++++++++++++++ include/of.h | 2 + 7 files changed, 301 insertions(+) create mode 100644 Documentation/devicetree/bindings/barebox.txt create mode 100644 Documentation/devicetree/bindings/barebox/barebox,environment.txt create mode 100644 drivers/of/barebox.c create mode 100644 drivers/of/of_path.c diff --git a/Documentation/devicetree/bindings/barebox.txt b/Documentation/devicetree/bindings/barebox.txt new file mode 100644 index 0000000000..5e8d461733 --- /dev/null +++ b/Documentation/devicetree/bindings/barebox.txt @@ -0,0 +1,10 @@ +barebox specific devicetree bindings +==================================== + +barebox uses some barebox specific devicetree bindings. All of these +are under the /chosen/ hierarchy in the devicetree. + +The bindings have the form of a device with regular 'compatible' properties. +drivers matching these devices do not handle physical devices but instead +influence / configure certain behaviours of barebox like the place where to +find the persistent environment. diff --git a/Documentation/devicetree/bindings/barebox/barebox,environment.txt b/Documentation/devicetree/bindings/barebox/barebox,environment.txt new file mode 100644 index 0000000000..5a8bf9c13b --- /dev/null +++ b/Documentation/devicetree/bindings/barebox/barebox,environment.txt @@ -0,0 +1,25 @@ +barebox environment +=================== + +This driver provides an environment for barebox from the devicetree. + +Required properties: +- compatible: should be "barebox,environment" +- device-path: path to the environment + +The device-path is a multistring property. The first string should be a +nodepath to the node containing the physical device of the environment. +The subsequent strings are of the form : to further describe +the path to the environment. Supported values for : + +partname: This describes a partition on a device. can + be the label for mtd partitions, the number for DOS + partitions (beginning with 0) or the name for GPT + partitions + +Example: + +environment@0 { + compatible = "barebox,environment"; + device-path = &flash, "partname:barebox-environment"; +}; diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 03ae599279..ab5eac8442 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -18,3 +18,12 @@ config OFDEVICE config OF_NET depends on NET def_bool y + +config OF_BAREBOX_DRIVERS + depends on OFDEVICE + bool "Enable barebox specific devicetree configuration drivers" + help + barebox supports being configured from devicetree. This enables + support for this feature. This currently allows to configure the + environment path from devicetree and to partition devices. See + Documentation/devicetree/bindings/barebox/ for more information. diff --git a/drivers/of/Makefile b/drivers/of/Makefile index e7d07334b0..97fea9d419 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o obj-$(CONFIG_GPIOLIB) += of_gpio.o obj-y += partition.o obj-y += of_net.o +obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o of_path.o diff --git a/drivers/of/barebox.c b/drivers/of/barebox.c new file mode 100644 index 0000000000..8977158992 --- /dev/null +++ b/drivers/of/barebox.c @@ -0,0 +1,99 @@ +/* + * barebox.c + * + * Copyright (c) 2013 Sascha Hauer , Pengutronix + * + * 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 +#include +#include +#include +#include + +struct of_partition { + struct list_head list; + char *nodepath; + struct device_d *dev; + struct device_node *of_partitions; +}; + +static LIST_HEAD(of_partition_list); + +struct device_d *of_find_device_by_node_path(const char *path) +{ + struct device_d *dev; + + for_each_device(dev) { + if (!dev->device_node) + continue; + if (!strcmp(path, dev->device_node->full_name)) + return dev; + } + + return NULL; +} + +static int environment_probe(struct device_d *dev) +{ + char *path; + int ret; + + ret = of_find_path(dev->device_node, "device-path", &path); + if (ret) + return ret; + + dev_info(dev, "setting default environment path to %s\n", path); + + default_environment_path = path; + + return 0; +} + +static struct of_device_id environment_dt_ids[] = { + { + .compatible = "barebox,environment", + }, { + /* sentinel */ + } +}; + +static struct driver_d environment_driver = { + .name = "barebox-environment", + .probe = environment_probe, + .of_compatible = environment_dt_ids, +}; + +static int barebox_of_driver_init(void) +{ + struct device_node *node; + + node = of_get_root_node(); + if (!node) + return 0; + + node = of_find_node_by_path("/chosen"); + if (!node) + return 0; + + of_platform_populate(node, of_default_bus_match_table, NULL); + + platform_driver_register(&environment_driver); + + return 0; +} +late_initcall(barebox_of_driver_init); diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c new file mode 100644 index 0000000000..ab8618e23d --- /dev/null +++ b/drivers/of/of_path.c @@ -0,0 +1,155 @@ +/* + * of_path.c + * + * Copyright (c) 2013 Sascha Hauer , Pengutronix + * + * 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 + +struct of_path { + struct cdev *cdev; + struct device_d *dev; +}; + +struct of_path_type { + const char *name; + int (*parse)(struct of_path *op, const char *str); +}; + +/** + * of_path_type_partname - find a partition based on physical device and + * partition name + * @op: of_path context + * @name: the partition name to find + */ +static int of_path_type_partname(struct of_path *op, const char *name) +{ + if (!op->dev) + return -EINVAL; + + op->cdev = device_find_partition(op->dev, name); + if (op->cdev) { + pr_debug("%s: found part '%s'\n", __func__, name); + return 0; + } else { + pr_debug("%s: cannot find part '%s'\n", __func__, name); + return -ENODEV; + } +} + +static struct of_path_type of_path_types[] = { + { + .name = "partname", + .parse = of_path_type_partname, + }, +}; + +static int of_path_parse_one(struct of_path *op, const char *str) +{ + int i, ret; + char *name, *desc; + + pr_debug("parsing: %s\n", str); + + name = xstrdup(str); + desc = strchr(name, ':'); + if (!desc) { + free(name); + return -EINVAL; + } + + *desc = 0; + desc++; + + for (i = 0; i < ARRAY_SIZE(of_path_types); i++) { + if (!strcmp(of_path_types[i].name, name)) { + ret = of_path_types[i].parse(op, desc); + goto out; + } + } + + ret = -EINVAL; +out: + free(name); + + return ret; +} + +/** + * of_find_path - translate a path description in the devicetree to a barebox + * path + * + * @node: the node containing the property with the path description + * @propname: the property name of the path description + * @outpath: if this function returns 0 outpath will contain the path belonging + * to the input path description. Must be freed with free(). + * + * pathes in the devicetree have the form of a multistring property. The first + * string contains the full path to the physical device containing the path. + * The remaining strings have the form ":". Currently supported + * for are: + * + * partname: - find a partition by its partition name. For mtd + * partitions this is the label. For DOS partitions + * this is the number beginning with 0. + * + * examples: + * + * device-path = &mmc0, "partname:0"; + * device-path = &norflash, "partname:barebox-environment"; + */ +int of_find_path(struct device_node *node, const char *propname, char **outpath) +{ + struct of_path op = {}; + struct device_node *rnode; + const char *path, *str; + int i, len, ret; + + path = of_get_property(node, propname, &len); + if (!path) + return -EINVAL; + + rnode = of_find_node_by_path(path); + if (!rnode) + return -ENODEV; + + op.dev = of_find_device_by_node_path(rnode->full_name); + if (!op.dev) + return -ENODEV; + + device_detect(op.dev); + + i = 1; + + while (1) { + ret = of_property_read_string_index(node, propname, i++, &str); + if (ret) + break; + + ret = of_path_parse_one(&op, str); + if (ret) + return ret; + } + + if (!op.cdev) + return -ENOENT; + + *outpath = asprintf("/dev/%s", op.cdev->name); + + return 0; +} diff --git a/include/of.h b/include/of.h index 7b600f038b..b99f0b2dae 100644 --- a/include/of.h +++ b/include/of.h @@ -229,6 +229,8 @@ void *of_flatten_dtb(struct device_node *node); int of_add_memory(struct device_node *node, bool dump); void of_add_memory_bank(struct device_node *node, bool dump, int r, u64 base, u64 size); +struct device_d *of_find_device_by_node_path(const char *path); +int of_find_path(struct device_node *node, const char *propname, char **outpath); #else static inline int of_parse_partitions(struct cdev *cdev, struct device_node *node) -- cgit v1.2.3 From a72e3b1f3861393e5f6a4ed867be3b66188a4fc5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 5 Jul 2013 10:38:01 +0200 Subject: ARM: i.MX Datamodul edmqx6: configure environment from devicetree This drops support for storing the environment in the eMMC, but the standard bootsource is the SPI NOR flash. Signed-off-by: Sascha Hauer --- arch/arm/boards/dmo-mx6-realq7/board.c | 26 ++++++++++---------------- arch/arm/configs/dmo-realq7_defconfig | 1 + arch/arm/dts/imx6q-dmo-realq7.dts | 31 +++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/arch/arm/boards/dmo-mx6-realq7/board.c b/arch/arm/boards/dmo-mx6-realq7/board.c index 9cf6c3175c..69d93f85fb 100644 --- a/arch/arm/boards/dmo-mx6-realq7/board.c +++ b/arch/arm/boards/dmo-mx6-realq7/board.c @@ -114,22 +114,6 @@ static int realq7_env_init(void) BBU_HANDLER_FLAG_DEFAULT, NULL, 0, 0x00907000); imx6_bbu_internal_mmc_register_handler("mmc", "/dev/mmc3.barebox", 0, NULL, 0, 0x00907000); - - switch (bootsource_get()) { - case BOOTSOURCE_MMC: - device_detect_by_name("mmc3"); - devfs_add_partition("mmc3", 0, SZ_1M, DEVFS_PARTITION_FIXED, "mmc3.barebox"); - devfs_add_partition("mmc3", SZ_1M, SZ_1M, DEVFS_PARTITION_FIXED, "mmc3.bareboxenv"); - default_environment_path = "/dev/mmc3.bareboxenv"; - break; - default: - case BOOTSOURCE_SPI: - devfs_add_partition("m25p0", 0, SZ_256K, DEVFS_PARTITION_FIXED, "m25p0.barebox"); - devfs_add_partition("m25p0", SZ_256K, SZ_256K, DEVFS_PARTITION_FIXED, "m25p0.bareboxenv"); - default_environment_path = "/dev/m25p0.bareboxenv"; - break; - } - return 0; } late_initcall(realq7_env_init); @@ -141,6 +125,16 @@ static int realq7_console_init(void) imx6_init_lowlevel(); + switch (bootsource_get()) { + case BOOTSOURCE_MMC: + of_device_enable_path("/chosen/environment-emmc"); + break; + default: + case BOOTSOURCE_SPI: + of_device_enable_path("/chosen/environment-spi"); + break; + } + return 0; } postcore_initcall(realq7_console_init); diff --git a/arch/arm/configs/dmo-realq7_defconfig b/arch/arm/configs/dmo-realq7_defconfig index ab8aa433c2..501a182b8e 100644 --- a/arch/arm/configs/dmo-realq7_defconfig +++ b/arch/arm/configs/dmo-realq7_defconfig @@ -71,6 +71,7 @@ CONFIG_NET_NFS=y CONFIG_NET_PING=y CONFIG_NET_RESOLV=y CONFIG_OFDEVICE=y +CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_NET_FEC_IMX=y CONFIG_DRIVER_SPI_IMX=y CONFIG_I2C=y diff --git a/arch/arm/dts/imx6q-dmo-realq7.dts b/arch/arm/dts/imx6q-dmo-realq7.dts index a33a700548..672f15d27d 100644 --- a/arch/arm/dts/imx6q-dmo-realq7.dts +++ b/arch/arm/dts/imx6q-dmo-realq7.dts @@ -19,6 +19,18 @@ chosen { linux,stdout-path = "/soc/aips-bus@02100000/serial@021e8000"; + + environment-emmc { + compatible = "barebox,environment"; + device-path = &usdhc4, "partname:barebox-environment"; + status = "disabled"; + }; + + environment-spi { + compatible = "barebox,environment"; + device-path = &flash, "partname:barebox-environment"; + status = "disabled"; + }; }; aliases { @@ -87,6 +99,18 @@ compatible = "m25p80"; spi-max-frequency = <40000000>; reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0x80000>; + }; + + partition@1 { + label = "barebox-environment"; + reg = <0x80000 0x20000>; + }; }; }; @@ -351,4 +375,11 @@ non-removable; bus-width = <8>; status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox-environment"; + reg = <0x0 0x80000>; + }; }; -- cgit v1.2.3 From e6cc6f080561f3a9921f635f0d65dbba6c5d4fb2 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Jul 2013 14:45:45 +0200 Subject: ARM: i.MX51 babbage: configure environment from devicetree While at it use offset 512k to allow bigger barebox binaries. Signed-off-by: Sascha Hauer --- arch/arm/boards/freescale-mx51-pdk/board.c | 5 ----- arch/arm/dts/imx51-babbage.dts | 12 ++++++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c index 2e7be8508c..cafcf37590 100644 --- a/arch/arm/boards/freescale-mx51-pdk/board.c +++ b/arch/arm/boards/freescale-mx51-pdk/board.c @@ -178,11 +178,6 @@ static int imx51_babbage_late_init(void) BBU_HANDLER_FLAG_DEFAULT, (void *)flash_header_imx51_babbage_start, flash_header_imx51_babbage_end - flash_header_imx51_babbage_start, 0); - device_detect_by_name("mmc0"); - - devfs_add_partition("mmc0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self0"); - devfs_add_partition("mmc0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0"); - return 0; } late_initcall(imx51_babbage_late_init); diff --git a/arch/arm/dts/imx51-babbage.dts b/arch/arm/dts/imx51-babbage.dts index 4950eef606..4edbccb1b4 100644 --- a/arch/arm/dts/imx51-babbage.dts +++ b/arch/arm/dts/imx51-babbage.dts @@ -19,6 +19,11 @@ chosen { linux,stdout-path = "/soc/aips@70000000/serial@73fbc000"; + + environment@0 { + compatible = "barebox,environment"; + device-path = &esdhc1, "partname:barebox-environment"; + }; }; memory { @@ -73,6 +78,13 @@ fsl,cd-controller; fsl,wp-controller; status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox-environment"; + reg = <0x80000 0x20000>; + }; }; &esdhc2 { -- cgit v1.2.3 From 58cb7b4ab504e26afcd8c1621147bba3a5389e87 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Jul 2013 14:49:46 +0200 Subject: ARM: i.MX53 QSB: configure environment from devicetree While at it use offset 512k to allow bigger barebox binaries. Signed-off-by: Sascha Hauer --- arch/arm/boards/freescale-mx53-loco/board.c | 4 ---- arch/arm/dts/imx53-qsb.dts | 12 ++++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/arm/boards/freescale-mx53-loco/board.c b/arch/arm/boards/freescale-mx53-loco/board.c index 3c8842c300..ec3c00d1ae 100644 --- a/arch/arm/boards/freescale-mx53-loco/board.c +++ b/arch/arm/boards/freescale-mx53-loco/board.c @@ -86,10 +86,6 @@ static int loco_late_init(void) if (!of_machine_is_compatible("fsl,imx53-qsb")) return 0; - device_detect_by_name("mmc0"); - - devfs_add_partition("mmc0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0"); - mc34708 = mc34708_get(); if (mc34708) { /* get the board revision from fuse */ diff --git a/arch/arm/dts/imx53-qsb.dts b/arch/arm/dts/imx53-qsb.dts index 1dfb48b216..3be4ff23e0 100644 --- a/arch/arm/dts/imx53-qsb.dts +++ b/arch/arm/dts/imx53-qsb.dts @@ -19,6 +19,11 @@ chosen { linux,stdout-path = "/soc/aips@50000000/serial@53fbc000"; + + environment@0 { + compatible = "barebox,environment"; + device-path = &esdhc1, "partname:barebox-environment"; + }; }; memory { @@ -119,6 +124,13 @@ pinctrl-0 = <&pinctrl_esdhc1_1>; cd-gpios = <&gpio3 13 0>; status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox-environment"; + reg = <0x80000 0x20000>; + }; }; &ssi2 { -- cgit v1.2.3 From 6a37488917b22fcf24d99c695ed1755198a9393b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Jul 2013 15:45:01 +0200 Subject: ARM: i.MX51 efikasb: configure environment from devicetree Signed-off-by: Sascha Hauer --- arch/arm/boards/efika-mx-smartbook/board.c | 29 ++++++++++------------------- arch/arm/dts/imx51-genesi-efika-sb.dts | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/arch/arm/boards/efika-mx-smartbook/board.c b/arch/arm/boards/efika-mx-smartbook/board.c index 1735c3e088..85ff466127 100644 --- a/arch/arm/boards/efika-mx-smartbook/board.c +++ b/arch/arm/boards/efika-mx-smartbook/board.c @@ -210,6 +210,16 @@ static int efikamx_usb_init(void) mxc_iomux_v3_setup_pad(MX51_PAD_EIM_A26__USBH2_STP); } + switch (bootsource_get()) { + case BOOTSOURCE_MMC: + of_device_enable_path("/chosen/environment-sd"); + break; + case BOOTSOURCE_SPI: + default: + of_device_enable_path("/chosen/environment-spi"); + break; + } + return 0; } console_initcall(efikamx_usb_init); @@ -230,7 +240,6 @@ extern char flash_header_imx51_genesi_efikasb_end[]; static int efikamx_late_init(void) { - enum bootsource bootsource; int i; if (!of_machine_is_compatible("genesi,imx51-sb")) @@ -255,24 +264,6 @@ static int efikamx_late_init(void) armlinux_set_architecture(2370); armlinux_set_revision(0x5100 | imx_silicon_revision()); - bootsource = bootsource_get(); - - switch (bootsource) { - case BOOTSOURCE_MMC: - device_detect_by_name("mmc1"); - - devfs_add_partition("mmc1", 0x00000, 0x80000, - DEVFS_PARTITION_FIXED, "self0"); - devfs_add_partition("mmc1", 0x80000, 0x80000, - DEVFS_PARTITION_FIXED, "env0"); - break; - case BOOTSOURCE_SPI: - default: - devfs_add_partition("m25p0", 0x80000, 0x20000, - DEVFS_PARTITION_FIXED, "env0"); - break; - } - return 0; } late_initcall(efikamx_late_init); diff --git a/arch/arm/dts/imx51-genesi-efika-sb.dts b/arch/arm/dts/imx51-genesi-efika-sb.dts index dc92b2a11f..21b7c7e495 100644 --- a/arch/arm/dts/imx51-genesi-efika-sb.dts +++ b/arch/arm/dts/imx51-genesi-efika-sb.dts @@ -18,6 +18,18 @@ chosen { linux,stdout-path = "/soc/aips@70000000/serial@73fbc000"; + + environment-sd { + compatible = "barebox,environment"; + device-path = &esdhc2, "partname:barebox-environment"; + status = "disabled"; + }; + + environment-spi { + compatible = "barebox,environment"; + device-path = &flash, "partname:barebox-environment"; + status = "disabled"; + }; }; memory { @@ -178,6 +190,13 @@ cd-gpios = <&gpio1 8 0>; wp-gpios = <&gpio1 7 0>; status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox-environment"; + reg = <0x80000 0x80000>; + }; }; &ecspi1 { @@ -290,6 +309,13 @@ compatible = "sst,sst25vf032b", "m25p80"; spi-max-frequency = <15000000>; reg = <1>; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox-environment"; + reg = <0x80000 0x80000>; + }; }; }; -- cgit v1.2.3