[PATCH] mfd: twl4030-power: Fix PM idle pin configuration to not conflict with regulators
Tony Lindgren
tony at atomide.com
Tue Sep 2 17:24:45 PDT 2014
* Sebastian Andrzej Siewior <sebastian at breakpoint.cc> [140902 01:29]:
> On 2014-08-19 08:24:05 [-0700], Tony Lindgren wrote:
> >
> > This allows us to enable the PMIC configuration for n900.
> >
> > Fixes: 43fef47f94a1 (mfd: twl4030-power: Add a configuration to turn off oscillator during off-idle)
>
> My beaglebone-ab does not like this. With this patch applied I end up
> with:
> [ 2.437316] Waiting for root device /dev/mmcblk0p2...
> [ 4.428192] mmc0: card never left busy state
> [ 4.432647] mmc0: error -110 whilst initialising SD card
I assume you mean beagleboard-ab, not beaglebone-ab :)
> I noticed this after I disabled lock debugging and tracing (syscall tracing
> was enabled). Enabling both again makes the error go away.
> With debugging + tracing disabled (so the error pops up) and git bisect
> I get this commit (daebabd57) reported.
OK. Sounds like we still have a race between the regulator code
and twl4030-power.c for accessing some twl registers.
> A diff between a good/bad bootlog (with lock-debug + tracing switched
> off):
>
> | smartreflex smartreflex.0: omap_sr_probe: SmartReflex driver initialized
> | smartreflex smartreflex.1: omap_sr_probe: SmartReflex driver initialized
> | hsusb2_vbus: disabling
> | VPLL2: disabling
> | VUSB3V1: disabling
> |+VDAC: disabling
> |+VAUX3: disabling
This seems to be the reason. Seems you're on v3.17-rc3, but with
commit daebabd57 we are not even touching the group registers that
twl-regulator.c accesses for VDAC and VAUX3 as they are set to
TWL4030_RESCONFIG_UNDEF. So I'm a bit baffled what's going on.
> reverting this commit on top of -rc3 makes mmc0 work again.
Again, I assume you're talking about reverting daebabd57,
not 43fef47f94a1. Anyways, here's a debug hack I used earlier to
dump out the twl configuration in late_initcall and via sysfs
so maybe try that and see what the values are with working
and non-working case?
Regards,
Tony
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -358,6 +358,146 @@ out:
return err;
}
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static void twl4030_dump_resource(unsigned index, struct seq_file *s)
+{
+ int addr;
+ int err;
+ u8 type;
+ u8 grp;
+ u8 remap;
+
+ addr = res_config_addrs[index];
+
+ err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
+ addr + DEV_GRP_OFFSET);
+ if (err) {
+ pr_err("TWL4030 Resource group 0x%02x could not be read\n",
+ addr);
+ return;
+ }
+
+ err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
+ addr + TYPE_OFFSET);
+ if (err < 0) {
+ pr_err("TWL4030 Resource type 0x%02x could not be read\n",
+ addr);
+ return;
+ }
+
+ err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
+ addr + REMAP_OFFSET);
+ if (err < 0) {
+ pr_err("TWL4030 Resource 0x%02x remap could not be read\n",
+ addr);
+ return;
+ }
+
+ if (s)
+ seq_printf(s, "%i: addr: 0x%04x grp: 0x%04x type: 0x%04x remap: 0x%04x\n",
+ index, addr, grp, type, remap);
+ else
+ printk("%i: addr: 0x%04x grp: 0x%04x type: 0x%04x remap: 0x%04x\n",
+ index, addr, grp, type, remap);
+}
+
+static void twl4030_dump_resources(void)
+{
+ int i;
+
+ for (i = 1; i <= RES_MAIN_REF; i++)
+ twl4030_dump_resource(i, NULL);
+}
+
+static struct dentry *dbg_root;
+
+static int dbg_show(struct seq_file *s, void *unused)
+{
+ unsigned long offset = (unsigned long)s->private;
+
+ twl4030_dump_resource(offset, s);
+
+ return 0;
+}
+
+static ssize_t dbg_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *seqf;
+ unsigned long offset;
+ u8 val;
+ int res;
+
+ res = kstrtou8_from_user(user_buf, count, 0x10, &val);
+ if (res < 0)
+ return res;
+
+ seqf = file->private_data;
+ offset = (unsigned long)seqf->private;
+ offset = res_config_addrs[offset];
+
+ res = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
+ val, offset + DEV_GRP_OFFSET);
+ if (res < 0) {
+ pr_err("TWL4030 failed to program devgroup\n");
+ return res;
+ }
+
+ *ppos += count;
+
+ return count;
+}
+
+static int dbg_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_show, inode->i_private);
+}
+
+static const struct file_operations dbg_fops = {
+ .open = dbg_open,
+ .read = seq_read,
+ .write = dbg_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void __init dbg_init(struct twl4030_resconfig *rconfig)
+{
+ int i;
+
+ dbg_root = debugfs_create_dir("twl4030-power", NULL);
+ if (IS_ERR(dbg_root) || !dbg_root)
+ return;
+
+ for (i = 1; i <= RES_MAIN_REF; i++) {
+ u8 name[16];
+
+ sprintf(name, "0x%02x", res_config_addrs[i]);
+ (void)debugfs_create_file(name, S_IRUGO,
+ dbg_root,
+ (void *)i,
+ &dbg_fops);
+ }
+}
+
+static int __init dbg_initcall(void)
+{
+ twl4030_dump_resources();
+
+ return 0;
+}
+late_initcall(dbg_initcall);
+
+#else
+static inline void dbg_init(struct twl4030_resconfig *rconfig)
+{
+}
+#endif
+
static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
{
int rconfig_addr;
@@ -864,6 +1004,8 @@ relock:
return err2;
}
+ dbg_init(pdata->resource_config);
+
return err;
}
More information about the linux-arm-kernel
mailing list