omap2+: Add support for hwmod specific muxing of devices
authorTony Lindgren <tony@atomide.com>
Thu, 23 Dec 2010 02:42:35 +0000 (18:42 -0800)
committerTony Lindgren <tony@atomide.com>
Thu, 23 Dec 2010 02:42:35 +0000 (18:42 -0800)
This allows adding hwmod specific pads dynamically during the
platform device init.

Note that we don't currently have the hwmod specific signals
listed in the hwmod data, but struct omap_hwmod_mux_info will
make that possible if necessary.

Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/mux.h
arch/arm/plat-omap/include/plat/omap_hwmod.h

index 0fa3d74125bc25c5f48ee5c2507ca1c52cf19077..27eb51a224cb315b4302fbe08cbb43447954c8d4 100644 (file)
@@ -35,6 +35,8 @@
 
 #include <asm/system.h>
 
+#include <plat/omap_hwmod.h>
+
 #include "control.h"
 #include "mux.h"
 
@@ -252,6 +254,69 @@ int __init omap_mux_init_signal(const char *muxname, int val)
        return 0;
 }
 
+struct omap_hwmod_mux_info * __init
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
+{
+       struct omap_hwmod_mux_info *hmux;
+       int i;
+
+       if (!bpads || nr_pads < 1)
+               return NULL;
+
+       hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL);
+       if (!hmux)
+               goto err1;
+
+       hmux->nr_pads = nr_pads;
+
+       hmux->pads = kzalloc(sizeof(struct omap_device_pad) *
+                               nr_pads, GFP_KERNEL);
+       if (!hmux->pads)
+               goto err2;
+
+       for (i = 0; i < hmux->nr_pads; i++) {
+               struct omap_mux_partition *partition;
+               struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i];
+               struct omap_mux *mux;
+               int mux_mode;
+
+               mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux);
+               if (mux_mode < 0)
+                       goto err3;
+               if (!pad->partition)
+                       pad->partition = partition;
+               if (!pad->mux)
+                       pad->mux = mux;
+
+               pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL);
+               if (!pad->name) {
+                       int j;
+
+                       for (j = i - 1; j >= 0; j--)
+                               kfree(hmux->pads[j].name);
+                       goto err3;
+               }
+               strcpy(pad->name, bpad->name);
+
+               pad->flags = bpad->flags;
+               pad->enable = bpad->enable;
+               pad->idle = bpad->idle;
+               pad->off = bpad->off;
+               pr_debug("%s: Initialized %s\n", __func__, pad->name);
+       }
+
+       return hmux;
+
+err3:
+       kfree(hmux->pads);
+err2:
+       kfree(hmux);
+err1:
+       pr_err("%s: Could not allocate device mux entry\n", __func__);
+
+       return NULL;
+}
+
 #ifdef CONFIG_DEBUG_FS
 
 #define OMAP_MUX_MAX_NR_FLAGS  10
index f5f7f4938057fec15c642a24ac52e6dc345706f5..9c48b9d3ec29e9c0e0741f97699f94bb131831e9 100644 (file)
@@ -145,6 +145,32 @@ struct omap_board_mux {
        u16     value;
 };
 
+#define OMAP_DEVICE_PAD_ENABLED                BIT(7)  /* Not needed for board-*.c */
+#define OMAP_DEVICE_PAD_REMUX          BIT(1)  /* Dynamically remux a pad,
+                                                  needs enable, idle and off
+                                                  values */
+#define OMAP_DEVICE_PAD_WAKEUP         BIT(0)  /* Pad is wake-up capable */
+
+/**
+ * struct omap_device_pad - device specific pad configuration
+ * @name:              signal name
+ * @flags:             pad specific runtime flags
+ * @enable:            runtime value for a pad
+ * @idle:              idle value for a pad
+ * @off:               off value for a pad, defaults to safe mode
+ * @partition:         mux partition
+ * @mux:               mux register
+ */
+struct omap_device_pad {
+       char                            *name;
+       u8                              flags;
+       u16                             enable;
+       u16                             idle;
+       u16                             off;
+       struct omap_mux_partition       *partition;
+       struct omap_mux                 *mux;
+};
+
 #if defined(CONFIG_OMAP_MUX)
 
 /**
@@ -161,6 +187,14 @@ int omap_mux_init_gpio(int gpio, int val);
  */
 int omap_mux_init_signal(const char *muxname, int val);
 
+/**
+ * omap_hwmod_mux_init - initialize hwmod specific mux data
+ * @bpads:             Board specific device signal names
+ * @nr_pads:           Number of signal names for the device
+ */
+extern struct omap_hwmod_mux_info *
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
+
 #else
 
 static inline int omap_mux_init_gpio(int gpio, int val)
@@ -172,6 +206,12 @@ static inline int omap_mux_init_signal(char *muxname, int val)
        return 0;
 }
 
+static inline struct omap_hwmod_mux_info *
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
+{
+       return NULL;
+}
+
 static struct omap_board_mux *board_mux __initdata __maybe_unused;
 
 #endif
index b219a88cac2c845f63105f4b4aa2c8a3d7d85acc..6864a997f2ca662d0e470704c4d075f963c0cdb0 100644 (file)
@@ -80,6 +80,18 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
 /* Slave idle mode flag only */
 #define HWMOD_IDLEMODE_SMART_WKUP      (1 << 3)
 
+/**
+ * struct omap_hwmod_mux_info - hwmod specific mux configuration
+ * @pads:              array of omap_device_pad entries
+ * @nr_pads:           number of omap_device_pad entries
+ *
+ * Note that this is currently built during init as needed.
+ */
+struct omap_hwmod_mux_info {
+       int                             nr_pads;
+       struct omap_device_pad          *pads;
+};
+
 /**
  * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
  * @name: name of the IRQ channel (module local name)
@@ -487,6 +499,7 @@ struct omap_hwmod {
        const char                      *name;
        struct omap_hwmod_class         *class;
        struct omap_device              *od;
+       struct omap_hwmod_mux_info      *mux;
        struct omap_hwmod_irq_info      *mpu_irqs;
        struct omap_hwmod_dma_info      *sdma_reqs;
        struct omap_hwmod_rst_info      *rst_lines;