9
0
Fork 0

Merge branch 'for-next/misc'

This commit is contained in:
Sascha Hauer 2016-01-11 13:11:06 +01:00
commit b9a2512aaa
28 changed files with 354 additions and 210 deletions

View File

@ -6,7 +6,10 @@ This driver provides an environment for barebox from the devicetree.
Required properties:
* ``compatible``: should be ``barebox,environment``
* ``device-path``: path to the environment
* ``device-path``: path to the device environment is on
Optional properties:
* ``file-path``: path to a file in the device named by device-path
The device-path is a multistring property. The first string should contain
a nodepath to the node containing the physical device of the environment or
@ -19,9 +22,19 @@ the path to the environment. Supported values for <type>:
be the label for MTD partitions, the number for DOS
partitions (beginning with 0) or the name for GPT partitions.
The file-path is the name of a file located in a FAT filesystem on the
device named in device-path. This filesystem will be mounted and the
environment loaded from the file's location in the directory tree.
Example::
environment@0 {
compatible = "barebox,environment";
device-path = &flash, "partname:barebox-environment";
};
environment@1 {
compatible = "barebox,environment";
device-path = &mmc, "partname:1";
file-path = "barebox.env";
};

View File

@ -55,8 +55,8 @@ Required properties:
``#size-cells = <1>``. Defines the ``offset`` and ``size`` of the
variable in the ``raw`` backend. ``size`` must fit the node
``type``. Variables are not allowed to overlap.
* ``type``: Should be ``uint8``, ``uint32``, ``enum32``, ``mac`` or
``string`` for the type of the variable
* ``type``: Should be ``uint8``, ``uint32``, ``int32``. ``enum32``, ``mac``
or ``string`` for the type of the variable
* ``names``: For ``enum32`` values only, this specifies the values
possible for ``enum32``.
@ -93,6 +93,7 @@ Variable Types
* ``uint8``:
* ``uint32``:
* ``int32``:
* ``enum32``: The ``default`` value is an integer representing an
offset into the names array.
* ``mac``:

View File

@ -235,7 +235,7 @@ static int cm_cogent_fixup(struct device_node *root, void *unused)
int ret;
struct device_node *node;
for_each_compatible_node(node, NULL, "atmel,hsmci") {
for_each_compatible_node_from(node, root, NULL, "atmel,hsmci") {
struct device_node *slotnode =
of_get_child_by_name(node, "slot");
if (!slotnode)

View File

@ -35,13 +35,13 @@ static int hb_fixup(struct device_node *root, void *unused)
__be32 latency;
if (!(reg & HB_PWRDOM_STAT_SATA)) {
for_each_compatible_node(node, NULL, "calxeda,hb-ahci")
for_each_compatible_node_from(node, root, NULL, "calxeda,hb-ahci")
of_set_property(node, "status", "disabled",
sizeof("disabled"), 1);
}
if (!(reg & HB_PWRDOM_STAT_EMMC)) {
for_each_compatible_node(node, NULL, "calxeda,hb-sdhci")
for_each_compatible_node_from(node, root, NULL, "calxeda,hb-sdhci")
of_set_property(node, "status", "disabled",
sizeof("disabled"), 1);
}

View File

@ -67,6 +67,7 @@ CONFIG_NET=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
CONFIG_OF_BAREBOX_DRIVERS=y
CONFIG_OF_BAREBOX_ENV_IN_FS=y
CONFIG_DRIVER_SERIAL_NS16550=y
CONFIG_DRIVER_NET_DESIGNWARE=y
CONFIG_MCI=y

View File

@ -1,4 +1,12 @@
/ {
chosen {
environment@0 {
compatible = "barebox,environment";
device-path = &mmc, "partname:1";
file-path = "barebox.env";
};
};
aliases {
mmc0 = &mmc;
};

View File

@ -426,7 +426,6 @@ static int imx_ocotp_probe(struct device_d *dev)
cdev->priv = priv;
cdev->size = 192;
cdev->name = "imx-ocotp";
cdev->device_node = dev->device_node;
ret = devfs_create(cdev);

View File

@ -103,41 +103,3 @@ static int socfpga_init(void)
return 0;
}
core_initcall(socfpga_init);
#if defined(CONFIG_ENV_HANDLING)
#define ENV_PATH "/boot/barebox.env"
static int socfpga_env_init(void)
{
struct stat s;
char *diskdev, *partname;
int ret;
diskdev = "mmc0";
device_detect_by_name(diskdev);
partname = asprintf("/dev/%s.1", diskdev);
ret = stat(partname, &s);
if (ret) {
pr_err("Failed to load environment: no device '%s'\n", diskdev);
goto out_free;
}
mkdir("/boot", 0666);
ret = mount(partname, "fat", "/boot", NULL);
if (ret) {
pr_err("Failed to load environment: mount %s failed (%d)\n", partname, ret);
goto out_free;
}
pr_debug("Loading default env from %s on device %s\n", ENV_PATH, diskdev);
default_environment_path_set(ENV_PATH);
out_free:
free(partname);
return 0;
}
late_initcall(socfpga_env_init);
#endif

View File

@ -21,7 +21,7 @@
static int do_devinfo_subtree(struct device_d *dev, int depth)
{
struct device_d *child;
struct cdev *cdev;
struct cdev *cdev, *cdevl;
int i;
for (i = 0; i < depth; i++)
@ -33,11 +33,14 @@ static int do_devinfo_subtree(struct device_d *dev, int depth)
list_for_each_entry(cdev, &dev->cdevs, devices_list) {
for (i = 0; i < depth + 1; i++)
printf(" ");
printf("`-- 0x%08llx-0x%08llx (%10s): /dev/%s\n",
printf("`-- 0x%08llx-0x%08llx (%10s): /dev/%s",
cdev->offset,
cdev->offset + cdev->size - 1,
size_human_readable(cdev->size),
cdev->name);
list_for_each_entry(cdevl, &cdev->links, link_entry)
printf(", %s", cdevl->name);
printf("\n");
}
} else {
printf("\n");

View File

@ -71,20 +71,14 @@ static int register_one_partition(struct block_device *blk,
if (!part->name[0])
return 0;
partition_name = asprintf("%s.%s", blk->cdev.name, part->name);
if (!partition_name)
return -ENOMEM;
partition_name = xasprintf("%s.%s", blk->cdev.name, part->name);
ret = devfs_create_link(cdev, partition_name);
if (ret)
dev_warn(blk->dev, "Failed to create link from %s to %s\n",
partition_name, blk->cdev.name);
free(partition_name);
dev_dbg(blk->dev, "Registering partition %s on drive %s\n",
partition_name, blk->cdev.name);
cdev = devfs_add_partition(blk->cdev.name,
start, size, 0, partition_name);
if (IS_ERR(cdev))
dev_warn(blk->dev, "Registering partition %s on drive %s failed\n",
partition_name, blk->cdev.name);
ret = 0;
return 0;
out:
free(partition_name);
return ret;

View File

@ -16,6 +16,7 @@ config PARTITION_DISK_DOS
config PARTITION_DISK_EFI
depends on PARTITION_DISK
select CRC32
select PRINTF_UUID
bool "EFI: GPT partition support"
help
Add support to handle partitions in GUID Partition Table style.

View File

@ -457,6 +457,7 @@ static void efi_partition(void *buf, struct block_device *blk,
pentry->size = le64_to_cpu(ptes[i].ending_lba) - pentry->first_sec;
pentry->size++;
part_set_efi_name(&ptes[i], pentry->name);
snprintf(pentry->partuuid, sizeof(pentry->partuuid), "%pUl", &ptes[i].unique_partition_guid);
pd->used_entries++;
}

View File

@ -66,6 +66,7 @@ enum state_variable_type {
STATE_TYPE_ENUM,
STATE_TYPE_U8,
STATE_TYPE_U32,
STATE_TYPE_S32,
STATE_TYPE_MAC,
STATE_TYPE_STRING,
};
@ -209,8 +210,8 @@ static struct state_variable *state_uint8_create(struct state *state,
return &su32->var;
}
static struct state_variable *state_uint32_create(struct state *state,
const char *name, struct device_node *node)
static struct state_variable *state_int32_create(struct state *state,
const char *name, struct device_node *node, const char *format)
{
struct state_uint32 *su32;
struct param_d *param;
@ -218,7 +219,7 @@ static struct state_variable *state_uint32_create(struct state *state,
su32 = xzalloc(sizeof(*su32));
param = dev_add_param_int(&state->dev, name, state_set_dirty,
NULL, &su32->value, "%u", state);
NULL, &su32->value, format, state);
if (IS_ERR(param)) {
free(su32);
return ERR_CAST(param);
@ -231,6 +232,18 @@ static struct state_variable *state_uint32_create(struct state *state,
return &su32->var;
}
static struct state_variable *state_uint32_create(struct state *state,
const char *name, struct device_node *node)
{
return state_int32_create(state, name, node, "%u");
}
static struct state_variable *state_sint32_create(struct state *state,
const char *name, struct device_node *node)
{
return state_int32_create(state, name, node, "%d");
}
/*
* enum32
*/
@ -605,6 +618,12 @@ static struct variable_type types[] = {
.export = state_string_export,
.import = state_string_import,
.create = state_string_create,
}, {
.type = STATE_TYPE_S32,
.type_name = "int32",
.export = state_uint32_export,
.import = state_uint32_import,
.create = state_sint32_create,
},
};

View File

@ -21,6 +21,9 @@ struct gpio_key {
int active_low;
int previous_state;
int debounce_interval;
u64 debounce_start;
};
struct gpio_keys {
@ -60,11 +63,17 @@ static void gpio_key_poller(struct poller_struct *poller)
gb = &gk->buttons[i];
val = gpio_get_value(gb->gpio);
if (val != gb->previous_state && val != gb->active_low) {
kfifo_put(gk->recv_fifo, (u_char*)&gb->code, sizeof(int));
debug("pressed gpio(%d) as %d\n", gb->gpio, gb->code);
if (!is_timeout(gb->debounce_start, gb->debounce_interval * MSECOND))
continue;
if (val != gb->previous_state) {
gb->debounce_start = get_time_ns();
if (val != gb->active_low) {
kfifo_put(gk->recv_fifo, (u_char*)&gb->code, sizeof(int));
debug("pressed gpio(%d) as %d\n", gb->gpio, gb->code);
}
gb->previous_state = val;
}
gb->previous_state = val;
}
}
@ -111,6 +120,7 @@ static int gpio_keys_probe_pdata(struct gpio_keys *gk, struct device_d *dev)
gk->buttons[i].gpio = pdata->buttons[i].gpio;
gk->buttons[i].code = pdata->buttons[i].code;
gk->buttons[i].active_low = pdata->buttons[i].active_low;
gk->buttons[i].debounce_interval = 20;
}
return 0;
@ -142,6 +152,11 @@ static int gpio_keys_probe_dt(struct gpio_keys *gk, struct device_d *dev)
if (ret)
return ret;
gk->buttons[i].debounce_interval = 20;
of_property_read_u32(npkey, "debounce-interval",
&gk->buttons[i].debounce_interval);
gk->buttons[i].code = keycode;
i++;

View File

@ -43,3 +43,10 @@ config OF_BAREBOX_DRIVERS
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.
config OF_BAREBOX_ENV_IN_FS
depends on OF_BAREBOX_DRIVERS
bool "Allow environment to come from file"
help
Allow the devie tree configuration of the barebox environment path
to specify a file in filesystem, which will be mounted.

View File

@ -24,7 +24,46 @@
#include <malloc.h>
#include <partition.h>
#include <envfs.h>
#include <linux/mtd/mtd.h>
#include <fs.h>
#define ENV_MNT_DIR "/boot" /* If env on filesystem, where to mount */
/* If dev describes a file on a fs, mount the fs and change devpath to
* point to the file's path. Otherwise leave devpath alone. Does
* nothing in env in a file support isn't enabled. */
static int environment_check_mount(struct device_d *dev, char **devpath)
{
const char *filepath;
int ret;
if (!IS_ENABLED(CONFIG_OF_BAREBOX_ENV_IN_FS))
return 0;
ret = of_property_read_string(dev->device_node, "file-path", &filepath);
if (ret == -EINVAL) {
/* No file-path so just use device-path */
return 0;
} else if (ret) {
/* file-path property exists, but has error */
dev_err(dev, "Problem with file-path property\n");
return ret;
}
/* Get device env is on and mount it */
mkdir(ENV_MNT_DIR, 0777);
ret = mount(*devpath, "fat", ENV_MNT_DIR, NULL);
if (ret) {
dev_err(dev, "Failed to load environment: mount %s failed (%d)\n",
*devpath, ret);
return ret;
}
/* Set env to be in a file on the now mounted device */
dev_dbg(dev, "Loading default env from %s on device %s\n",
filepath, *devpath);
*devpath = asprintf("%s/%s", ENV_MNT_DIR, filepath);
return 0;
}
static int environment_probe(struct device_d *dev)
{
@ -35,8 +74,12 @@ static int environment_probe(struct device_d *dev)
if (ret)
return ret;
dev_info(dev, "setting default environment path to %s\n", path);
/* Do we need to mount a fs and find env there? */
ret = environment_check_mount(dev, &path);
if (ret)
return ret;
dev_dbg(dev, "Setting default environment path to %s\n", path);
default_environment_path_set(path);
return 0;

View File

@ -23,16 +23,6 @@
#include <linux/mtd/mtd.h>
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);
};
struct device_d *of_find_device_by_node_path(const char *path)
{
struct device_d *dev;
@ -47,65 +37,6 @@ struct device_d *of_find_device_by_node_path(const char *path)
return NULL;
}
/**
* 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
*
@ -119,36 +50,32 @@ out:
*/
static int __of_find_path(struct device_node *node, const char *part, char **outpath, unsigned flags)
{
struct of_path op;
struct device_d *dev;
struct cdev *cdev;
bool add_bb = false;
int ret;
op.dev = of_find_device_by_node_path(node->full_name);
if (!op.dev) {
op.dev = of_find_device_by_node_path(node->parent->full_name);
if (!op.dev)
dev = of_find_device_by_node_path(node->full_name);
if (!dev) {
dev = of_find_device_by_node_path(node->parent->full_name);
if (!dev)
return -ENODEV;
}
device_detect(op.dev);
device_detect(dev);
if (part) {
/* Find a partition inside op.dev */
ret = of_path_parse_one(&op, part);
if (ret)
return ret;
} else {
/* node points directly to device */
op.cdev = cdev_by_device_node(node);
if (!op.cdev)
return -ENOENT;
}
if (part)
cdev = device_find_partition(dev, part);
else
cdev = cdev_by_device_node(node);
if ((flags & OF_FIND_PATH_FLAGS_BB) && op.cdev->mtd &&
mtd_can_have_bb(op.cdev->mtd))
if (!cdev)
return -ENOENT;
if ((flags & OF_FIND_PATH_FLAGS_BB) && cdev->mtd &&
mtd_can_have_bb(cdev->mtd))
add_bb = true;
*outpath = asprintf("/dev/%s%s", op.cdev->name, add_bb ? ".bb" : "");
*outpath = asprintf("/dev/%s%s", cdev->name, add_bb ? ".bb" : "");
return 0;
}
@ -198,8 +125,8 @@ int of_find_path(struct device_node *node, const char *propname, char **outpath,
{
struct device_node *rnode;
const char *path;
const char *part;
int ret;
const char *part = NULL;
const char partnamestr[] = "partname:";
path = of_get_property(node, propname, NULL);
if (!path)
@ -209,9 +136,15 @@ int of_find_path(struct device_node *node, const char *propname, char **outpath,
if (!rnode)
return -ENODEV;
ret = of_property_read_string_index(node, propname, 1, &part);
if (ret)
part = NULL;
of_property_read_string_index(node, propname, 1, &part);
if (part) {
if (!strncmp(part, partnamestr, sizeof(partnamestr) - 1)) {
part += sizeof(partnamestr) - 1;
} else {
pr_err("Invalid device-path: %s\n", part);
return -EINVAL;
}
}
return __of_find_path(rnode, part, outpath, flags);
}

View File

@ -13,6 +13,7 @@
#include <common.h>
#include <clock.h>
#include <abort.h>
#include <malloc.h>
#include <io.h>
#include <init.h>
@ -51,6 +52,8 @@ struct imx6_pcie {
#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2
#define PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK 0xf
#define PCIE_RC_LCSR 0x80
/* PCIe Port Logic registers (memory-mapped) */
#define PL_OFFSET 0x700
#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
@ -235,7 +238,10 @@ static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
val = readl(pp->dbi_base + PCIE_PL_PFLR);
val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
val |= PCIE_PL_PFLR_FORCE_LINK;
data_abort_mask();
writel(val, pp->dbi_base + PCIE_PL_PFLR);
data_abort_unmask();
gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2;
writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
@ -360,13 +366,29 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp)
}
}
static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
{
uint32_t tmp;
uint64_t start = get_time_ns();
while (!is_timeout(start, SECOND)) {
tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
/* Test if the speed change finished. */
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
return 0;
}
dev_err(pp->dev, "Speed change timeout\n");
return -EINVAL;
}
static int imx6_pcie_start_link(struct pcie_port *pp)
{
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
uint32_t tmp;
int ret;
u32 gpr12;
u64 start;
/*
* Force Gen1 operation when starting the link. In case the link is
@ -401,28 +423,22 @@ static int imx6_pcie_start_link(struct pcie_port *pp)
tmp |= PORT_LOGIC_SPEED_CHANGE;
writel(tmp, pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
start = get_time_ns();
while (!is_timeout(start, SECOND)) {
tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
/* Test if the speed change finished. */
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
break;
ret = imx6_pcie_wait_for_speed_change(pp);
if (ret) {
dev_err(pp->dev, "Failed to bring link up!\n");
return ret;
}
/* Make sure link training is finished as well! */
if (tmp & PORT_LOGIC_SPEED_CHANGE)
ret = -EINVAL;
else
ret = imx6_pcie_wait_for_link(pp);
ret = imx6_pcie_wait_for_link(pp);
if (ret) {
dev_err(pp->dev, "Failed to bring link up!\n");
} else {
tmp = readl(pp->dbi_base + 0x80);
dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
return ret;
}
return ret;
tmp = readl(pp->dbi_base + PCIE_RC_LCSR);
dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
return 0;
}
static void imx6_pcie_host_init(struct pcie_port *pp)
@ -592,9 +608,35 @@ static int __init imx6_pcie_probe(struct device_d *dev)
if (ret < 0)
return ret;
dev->priv = imx6_pcie;
return 0;
}
static void imx6_pcie_remove(struct device_d *dev)
{
struct imx6_pcie *imx6_pcie = dev->priv;
u32 val;
val = readl(imx6_pcie->pp.dbi_base + PCIE_PL_PFLR);
val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
val |= PCIE_PL_PFLR_FORCE_LINK;
data_abort_mask();
writel(val, imx6_pcie->pp.dbi_base + PCIE_PL_PFLR);
data_abort_unmask();
val = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
val &= ~IMX6Q_GPR12_PCIE_CTL_2;
writel(val, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
val = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
val |= IMX6Q_GPR1_PCIE_TEST_PD;
writel(val, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
val &= ~IMX6Q_GPR1_PCIE_REF_CLK_EN;
writel(val, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
}
static struct of_device_id imx6_pcie_of_match[] = {
{ .compatible = "fsl,imx6q-pcie", },
{},
@ -604,6 +646,7 @@ static struct driver_d imx6_pcie_driver = {
.name = "imx6-pcie",
.of_compatible = DRV_OF_COMPAT(imx6_pcie_of_match),
.probe = imx6_pcie_probe,
.remove = imx6_pcie_remove,
};
device_platform_driver(imx6_pcie_driver);

View File

@ -242,7 +242,8 @@ static int imx_chipidea_probe(struct device_d *dev)
ci->vbus = regulator_get(dev, "vbus");
regulator_enable(ci->vbus);
if (!IS_ERR(ci->vbus))
regulator_enable(ci->vbus);
base = dev_request_mem_region(dev, 0);
if (IS_ERR(base))

View File

@ -46,7 +46,18 @@ int devfs_partition_complete(struct string_list *sl, char *instr)
}
#endif
struct cdev *cdev_by_name(const char *filename)
struct cdev *cdev_readlink(struct cdev *cdev)
{
if (cdev->link)
cdev = cdev->link;
/* links to links are not allowed */
BUG_ON(cdev->link);
return cdev;
}
struct cdev *lcdev_by_name(const char *filename)
{
struct cdev *cdev;
@ -57,6 +68,17 @@ struct cdev *cdev_by_name(const char *filename)
return NULL;
}
struct cdev *cdev_by_name(const char *filename)
{
struct cdev *cdev;
cdev = lcdev_by_name(filename);
if (!cdev)
return NULL;
return cdev_readlink(cdev);
}
struct cdev *cdev_by_device_node(struct device_node *node)
{
struct cdev *cdev;
@ -65,7 +87,7 @@ struct cdev *cdev_by_device_node(struct device_node *node)
if (!cdev->device_node)
continue;
if (cdev->device_node == node)
return cdev;
return cdev_readlink(cdev);
}
return NULL;
}
@ -111,14 +133,6 @@ 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;
@ -131,9 +145,11 @@ struct cdev *cdev_open(const char *name, unsigned long flags)
if (!cdev)
return NULL;
ret = cdev_do_open(cdev, flags);
if (ret)
return NULL;
if (cdev->ops->open) {
ret = cdev->ops->open(cdev, flags);
if (ret)
return NULL;
}
return cdev;
}
@ -259,22 +275,59 @@ int devfs_create(struct cdev *new)
if (cdev)
return -EEXIST;
INIT_LIST_HEAD(&new->links);
list_add_tail(&new->list, &cdev_list);
if (new->dev)
if (new->dev) {
list_add_tail(&new->devices_list, &new->dev->cdevs);
if (!new->device_node)
new->device_node = new->dev->device_node;
}
return 0;
}
int devfs_create_link(struct cdev *cdev, const char *name)
{
struct cdev *new;
if (cdev_by_name(name))
return -EEXIST;
/*
* Create a link to the real cdev instead of creating
* a link to a link.
*/
cdev = cdev_readlink(cdev);
new = xzalloc(sizeof(*new));
new->name = xstrdup(name);
new->link = cdev;
INIT_LIST_HEAD(&new->links);
list_add_tail(&new->list, &cdev_list);
list_add_tail(&new->link_entry, &cdev->links);
return 0;
}
int devfs_remove(struct cdev *cdev)
{
struct cdev *c, *tmp;
if (cdev->open)
return -EBUSY;
list_del(&cdev->list);
if (cdev->dev)
list_del(&cdev->devices_list);
list_for_each_entry_safe(c, tmp, &cdev->links, link_entry)
devfs_remove(c);
if (cdev->link)
free(cdev);
return 0;
}

View File

@ -212,12 +212,18 @@ static int devfs_stat(struct device_d *_dev, const char *filename, struct stat *
{
struct cdev *cdev;
cdev = cdev_by_name(filename + 1);
cdev = lcdev_by_name(filename + 1);
if (!cdev)
return -ENOENT;
s->st_mode = S_IFCHR;
s->st_size = cdev->size;
if (cdev->link)
s->st_mode |= S_IFLNK;
cdev = cdev_readlink(cdev);
if (cdev->ops->write)
s->st_mode |= S_IWUSR;
if (cdev->ops->read)
@ -242,6 +248,24 @@ static void devfs_delete(struct device_d *dev)
{
}
static int devfs_readlink(struct device_d *dev, const char *pathname,
char *buf, size_t bufsz)
{
struct cdev *cdev;
cdev = cdev_by_name(pathname + 1);
if (!cdev)
return -ENOENT;
while (cdev->link)
cdev = cdev->link;
bufsz = min(bufsz, strlen(cdev->name));
memcpy(buf, cdev->name, bufsz);
return 0;
}
static struct fs_driver_d devfs_driver = {
.read = devfs_read,
.write = devfs_write,
@ -258,6 +282,7 @@ static struct fs_driver_d devfs_driver = {
.erase = devfs_erase,
.protect = devfs_protect,
.memmap = devfs_memmap,
.readlink = devfs_readlink,
.flags = FS_DRIVER_NO_DEV,
.drv = {
.probe = devfs_probe,

View File

@ -346,6 +346,9 @@ static void automount_mount(const char *path, int instat)
in_automount++;
if (fs_dev_root != get_fsdevice_by_path(path))
goto out;
list_for_each_entry(am, &automount_list, list) {
int len_path = strlen(path);
int len_am_path = strlen(am->path);
@ -377,12 +380,10 @@ static void automount_mount(const char *path, int instat)
if (ret)
printf("running automount command '%s' failed\n",
am->cmd);
else
automount_remove(am->path);
break;
}
out:
in_automount--;
}

View File

@ -15,10 +15,10 @@ typedef void (*kernel_entry_func)(int zero, int arch, void *params);
void bootstrap_boot(kernel_entry_func func, bool barebox);
#ifdef CONFIG_BOOTSTRAP_DEVFS
void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
void* bootstrap_read_devfs(const char *devname, bool use_bb, int offset,
int default_size, int max_size);
#else
static inline void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
static inline void* bootstrap_read_devfs(const char *devname, bool use_bb, int offset,
int default_size, int max_size)
{
return NULL;
@ -26,9 +26,9 @@ static inline void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
#endif
#ifdef CONFIG_BOOTSTRAP_DISK
void* bootstrap_read_disk(char *devname, char *fstype);
void* bootstrap_read_disk(const char *devname, const char *fstype);
#else
static inline void* bootstrap_read_disk(char *devname, char *fstype)
static inline void* bootstrap_read_disk(const char *devname, const char *fstype)
{
return NULL;
}

View File

@ -450,13 +450,18 @@ struct cdev {
int open;
struct mtd_info *mtd;
u8 dos_partition_type;
struct cdev *link;
struct list_head link_entry, links;
};
int devfs_create(struct cdev *);
int devfs_create_link(struct cdev *, const char *name);
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 *lcdev_by_name(const char *filename);
struct cdev *cdev_readlink(struct cdev *cdev);
struct cdev *cdev_by_device_node(struct device_node *node);
struct cdev *cdev_open(const char *name, unsigned long flags);
int cdev_do_open(struct cdev *, unsigned long flags);

View File

@ -641,9 +641,13 @@ static inline struct device_node *of_find_node_by_path_or_alias(
#define for_each_node_by_name_from(dn, root, name) \
for (dn = of_find_node_by_name(root, name); dn; \
dn = of_find_node_by_name(dn, name))
#define for_each_compatible_node(dn, type, compatible) \
for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
/* Iterate over compatible nodes starting from given root */
#define for_each_compatible_node_from(dn, root, type, compatible) \
for (dn = of_find_compatible_node(root, type, compatible); dn; \
dn = of_find_compatible_node(dn, type, compatible))
/* Iterate over compatible nodes in default device tree */
#define for_each_compatible_node(dn, type, compatible) \
for_each_compatible_node_from(dn, NULL, type, compatible)
static inline struct device_node *of_find_matching_node(
struct device_node *from,
const struct of_device_id *matches)
@ -732,6 +736,17 @@ static inline int of_property_read_u32(const struct device_node *np,
s; \
s = of_prop_next_string(prop, s))
/*
* struct device_node *n;
*
* of_property_for_each_phandle(np, root, "propname", n)
* printk("phandle points to: %s\n", n->full_name);
*/
#define of_property_for_each_phandle(np, root, propname, n) \
for (int _i = 0; \
(n = of_parse_phandle_from(np, root, propname, _i));\
_i++)
static inline int of_property_write_u8(struct device_node *np,
const char *propname, u8 value)
{

View File

@ -80,7 +80,7 @@ static unsigned int get_image_size(void *head)
}
#endif
void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
void* bootstrap_read_devfs(const char *devname, bool use_bb, int offset,
int default_size, int max_size)
{
int ret;

View File

@ -14,12 +14,12 @@
#include <libfile.h>
#include <bootstrap.h>
void* bootstrap_read_disk(char *dev, char *fstype)
void* bootstrap_read_disk(const char *dev, const char *fstype)
{
int ret;
void *buf;
int len;
char *path = "/";
const char *path = "/";
ret = mount(dev, fstype, path, NULL);
if (ret) {

View File

@ -1,6 +1,7 @@
#include <common.h>
#include <readkey.h>
#include <init.h>
#include <libbb.h>
#include <xfuncs.h>
#include <complete.h>
#include <linux/ctype.h>
@ -150,7 +151,7 @@ static void cread_add_char(char ichar, int insert, unsigned long *num,
/* room ??? */
if (insert || *num == *eol_num) {
if (*eol_num > len - 1) {
if (*eol_num > len - 2) {
getcmd_cbeep();
return;
}
@ -321,7 +322,7 @@ int readline(const char *prompt, char *buf, int len)
ERASE_TO_EOL();
/* copy new line into place and display */
strcpy(buf, hline);
safe_strncpy(buf, hline, len);
eol_num = strlen(buf);
REFRESH_TO_EOL();
continue;