|
@@ -870,3 +870,129 @@ static void __init omap_mux_package_init_balls(struct omap_ball *b,
|
|
}
|
|
}
|
|
|
|
|
|
#else /* CONFIG_DEBUG_FS */
|
|
#else /* CONFIG_DEBUG_FS */
|
|
|
|
+
|
|
|
|
+static inline void omap_mux_package_init_balls(struct omap_ball *b,
|
|
|
|
+ struct omap_mux *superset)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#endif /* CONFIG_DEBUG_FS */
|
|
|
|
+
|
|
|
|
+static int __init omap_mux_setup(char *options)
|
|
|
|
+{
|
|
|
|
+ if (!options)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ omap_mux_options = options;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+__setup("omap_mux=", omap_mux_setup);
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
|
|
|
|
+ * cmdline options only override the bootloader values.
|
|
|
|
+ * During development, please enable CONFIG_DEBUG_FS, and use the
|
|
|
|
+ * signal specific entries under debugfs.
|
|
|
|
+ */
|
|
|
|
+static void __init omap_mux_set_cmdline_signals(void)
|
|
|
|
+{
|
|
|
|
+ char *options, *next_opt, *token;
|
|
|
|
+
|
|
|
|
+ if (!omap_mux_options)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ options = kstrdup(omap_mux_options, GFP_KERNEL);
|
|
|
|
+ if (!options)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ next_opt = options;
|
|
|
|
+
|
|
|
|
+ while ((token = strsep(&next_opt, ",")) != NULL) {
|
|
|
|
+ char *keyval, *name;
|
|
|
|
+ unsigned long val;
|
|
|
|
+
|
|
|
|
+ keyval = token;
|
|
|
|
+ name = strsep(&keyval, "=");
|
|
|
|
+ if (name) {
|
|
|
|
+ int res;
|
|
|
|
+
|
|
|
|
+ res = strict_strtoul(keyval, 0x10, &val);
|
|
|
|
+ if (res < 0)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ omap_mux_init_signal(name, (u16)val);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ kfree(options);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int __init omap_mux_copy_names(struct omap_mux *src,
|
|
|
|
+ struct omap_mux *dst)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
|
|
|
|
+ if (src->muxnames[i]) {
|
|
|
|
+ dst->muxnames[i] = kstrdup(src->muxnames[i],
|
|
|
|
+ GFP_KERNEL);
|
|
|
|
+ if (!dst->muxnames[i])
|
|
|
|
+ goto free;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DEBUG_FS
|
|
|
|
+ for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
|
|
|
|
+ if (src->balls[i]) {
|
|
|
|
+ dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL);
|
|
|
|
+ if (!dst->balls[i])
|
|
|
|
+ goto free;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+free:
|
|
|
|
+ omap_mux_free_names(dst);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#endif /* CONFIG_OMAP_MUX */
|
|
|
|
+
|
|
|
|
+static struct omap_mux *omap_mux_get_by_gpio(
|
|
|
|
+ struct omap_mux_partition *partition,
|
|
|
|
+ int gpio)
|
|
|
|
+{
|
|
|
|
+ struct omap_mux_entry *e;
|
|
|
|
+ struct omap_mux *ret = NULL;
|
|
|
|
+
|
|
|
|
+ list_for_each_entry(e, &partition->muxmodes, node) {
|
|
|
|
+ struct omap_mux *m = &e->mux;
|
|
|
|
+ if (m->gpio == gpio) {
|
|
|
|
+ ret = m;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Needed for dynamic muxing of GPIO pins for off-idle */
|
|
|
|
+u16 omap_mux_get_gpio(int gpio)
|
|
|
|
+{
|
|
|
|
+ struct omap_mux_partition *partition;
|
|
|
|
+ struct omap_mux *m = NULL;
|
|
|
|
+
|
|
|
|
+ list_for_each_entry(partition, &mux_partitions, node) {
|
|
|
|
+ m = omap_mux_get_by_gpio(partition, gpio);
|
|
|
|
+ if (m)
|
|
|
|
+ return omap_mux_read(partition, m->reg_offset);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
|
|
|
|
+ pr_err("%s: Could not get gpio%i\n", __func__, gpio);
|
|
|
|
+
|
|
|
|
+ return OMAP_MUX_TERMINATOR;
|