summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-05-24 15:42:27 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2013-05-31 12:32:05 +0200
commit95e7982f99c03806b640c2e98e3e8e29ecefa3f1 (patch)
tree9549784580f7a6924c276353754162f647d4b255
parent9897dec869bfc54f704fd07dc85800aad2e37250 (diff)
downloadbarebox-95e7982f99c03806b640c2e98e3e8e29ecefa3f1.tar.gz
barebox-95e7982f99c03806b640c2e98e3e8e29ecefa3f1.tar.xz
devices: add detect mechanism
We often encounter the situation where slow devices should not be probed during startup since probing is slow and maybe unnecessary for unused devices. With MMC we have the 'probe' device parameter, for ata we have the same, for USB we have the 'usb' command. Overall this is not very consistent. With MMC there is the additional problem that the probe parameter is attached to the logical device when we often have the information which physical device we want to probe. This patch adds a 'detect' callback for devices and adds a command to detect devices and to list the devices which are actually detecable. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--commands/Kconfig9
-rw-r--r--commands/Makefile1
-rw-r--r--commands/detect.c77
-rw-r--r--drivers/base/driver.c7
-rw-r--r--include/driver.h8
5 files changed, 102 insertions, 0 deletions
diff --git a/commands/Kconfig b/commands/Kconfig
index 6a759ce204..a62ed9823b 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -728,6 +728,15 @@ config CMD_CLK
Say yes here to get clk_set_rate, clk_set_parent and clk_dump
commands to manipulate clocks on your system.
+config CMD_DETECT
+ tristate
+ prompt "detect"
+ help
+ say yes here to get the 'detect' command. Some devices take longer
+ time to probe, like slow disks or SD/MMC cards. These can defer the
+ actual probe of the client devices until they are needed. Use the
+ 'detect' command on the physical device to trigger probing.
+
menuconfig CMD_WD
bool
depends on WATCHDOG
diff --git a/commands/Makefile b/commands/Makefile
index 953ecc284b..419d93bc0e 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -90,3 +90,4 @@ obj-$(CONFIG_CMD_TFTP) += tftp.o
obj-$(CONFIG_CMD_FILETYPE) += filetype.o
obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o
obj-$(CONFIG_CMD_MIITOOL) += miitool.o
+obj-$(CONFIG_CMD_DETECT) += detect.o
diff --git a/commands/detect.c b/commands/detect.c
new file mode 100644
index 0000000000..0010a17779
--- /dev/null
+++ b/commands/detect.c
@@ -0,0 +1,77 @@
+/*
+ * detect.c - detect devices command
+ *
+ * Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de>, 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 <common.h>
+#include <command.h>
+#include <complete.h>
+#include <driver.h>
+#include <getopt.h>
+
+static int do_detect(int argc, char *argv[])
+{
+ struct device_d *dev;
+ int opt, i, ret;
+ int option_list = 0;
+ int option_error = 0;
+
+ while ((opt = getopt(argc, argv, "el")) > 0) {
+ switch (opt) {
+ case 'l':
+ option_list = 1;
+ break;
+ case 'e':
+ option_error = 1;
+ break;
+ }
+ }
+
+ if (option_list) {
+ for_each_device(dev) {
+ if (dev->detect)
+ printf("%s\n", dev_name(dev));
+ }
+ return 0;
+ }
+
+ if (argc == optind)
+ return COMMAND_ERROR_USAGE;
+
+ for (i = optind; i < argc; i++) {
+ dev = get_device_by_name(argv[i]);
+ if (!dev)
+ return -ENODEV;
+ ret = device_detect(dev);
+ if (ret && option_error)
+ return ret;
+ }
+
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(detect)
+BAREBOX_CMD_HELP_USAGE("detect [OPTIONS] [devices]\n")
+BAREBOX_CMD_HELP_OPT ("-l", "list detectable devices\n")
+BAREBOX_CMD_HELP_OPT ("-e", "bail out if one device fails to detect\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(detect)
+ .cmd = do_detect,
+ .usage = "detect devices",
+ BAREBOX_CMD_COMPLETE(device_complete)
+ BAREBOX_CMD_HELP(cmd_detect_help)
+BAREBOX_CMD_END
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index c8856304f5..810d0011f6 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -93,6 +93,13 @@ int device_probe(struct device_d *dev)
return 0;
}
+int device_detect(struct device_d *dev)
+{
+ if (!dev->detect)
+ return -ENOSYS;
+ return dev->detect(dev);
+}
+
static int match(struct driver_d *drv, struct device_d *dev)
{
int ret;
diff --git a/include/driver.h b/include/driver.h
index de195c5e5c..da4f446ec9 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -109,6 +109,11 @@ struct device_d {
struct of_device_id *of_id_entry;
void (*info) (struct device_d *);
+ /*
+ * For devices which take longer to probe this is called
+ * when the driver should actually detect client devices
+ */
+ int (*detect) (struct device_d *);
};
/** @brief Describes a driver present in the system */
@@ -152,6 +157,9 @@ int register_device(struct device_d *);
*/
int device_probe(struct device_d *dev);
+/* detect devices attached to this device (cards, disks,...) */
+int device_detect(struct device_d *dev);
+
/* Unregister a device. This function can fail, e.g. when the device
* has children.
*/