All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] sparse, llvm: Fix 'void *' pointer code generation
From: Pekka Enberg @ 2011-10-24 15:18 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Jonathan Neuschäfer, Linus Torvalds, linux-sparse,
	Christopher Li, Jeff Garzik
In-Reply-To: <4EA580B6.4070008@garzik.org>

On Mon, Oct 24, 2011 at 6:13 PM, Jeff Garzik <jeff@garzik.org> wrote:
>> Thanks for pointing that out. Jeff, does this look OK?
>
> I don't know what bit_size==-1 means off the top of my head, so I assume yes

So

  void *p;

looks as follows with test-inspect:

  0: SYM_NODE: p
    ctype.base_type: SYM_PTR: <noident>
      ctype.base_type: SYM_BASETYPE: void

[ btw, is there a text mode version of test-inspect? ]

where the SYM_BASETYPE of 'void' has -1 set as bit_size by the frontend.

                        Pekka

^ permalink raw reply

* [PATCH 1/3] mfd: Add S5M core driver
From: Sangbeom Kim @ 2011-10-21 10:28 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319192894-19292-1-git-send-email-sbkim73@samsung.com>

S5M series are pmic including mutiple functions.
It can support PMIC, RTC, Battery charger, codec.
This patch implement core driver for s5m series.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/s5m-core.c               |  235 +++++++++++++++++++++++++
 include/linux/mfd/s5m87xx/s5m-core.h |  313 ++++++++++++++++++++++++++++++++++
 include/linux/mfd/s5m87xx/s5m-pmic.h |  141 +++++++++++++++
 include/linux/mfd/s5m87xx/s5m-rtc.h  |   69 ++++++++
 4 files changed, 758 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/s5m-core.c
 create mode 100644 include/linux/mfd/s5m87xx/s5m-core.h
 create mode 100644 include/linux/mfd/s5m87xx/s5m-pmic.h
 create mode 100644 include/linux/mfd/s5m87xx/s5m-rtc.h

diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c
new file mode 100644
index 0000000..6dac3a1
--- /dev/null
+++ b/drivers/mfd/s5m-core.c
@@ -0,0 +1,235 @@
+/*
+ * s5m-core.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/mutex.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-rtc.h>
+#include <linux/regmap.h>
+
+int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, u8 *dest)
+{
+	int ret;
+	unsigned int val;
+
+	ret = regmap_read(s5m87xx->regmap, reg, &val);
+
+	if (ret < 0)
+		return ret;
+
+	ret &= 0xff;
+	*dest = ret;
+	return 0;
+}
+EXPORT_SYMBOL(s5m_reg_read);
+
+int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+	int ret;
+
+	ret = regmap_bulk_read(s5m87xx->regmap, reg, buf, count);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(s5m_bulk_read);
+
+int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value)
+{
+	int ret;
+
+	ret = regmap_write(s5m87xx->regmap, reg, value);
+	return ret;
+}
+EXPORT_SYMBOL(s5m_reg_write);
+
+int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+	int ret;
+
+	ret = regmap_raw_write(s5m87xx->regmap, reg, buf, count * sizeof(u16));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(s5m_bulk_write);
+
+int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask)
+{
+	int ret;
+
+	ret = regmap_update_bits(s5m87xx->regmap, reg, mask, val);
+	if (ret < 0)
+		return ret;
+
+	return ret;
+}
+EXPORT_SYMBOL(s5m_reg_update);
+
+static struct mfd_cell s5m87xx_devs[] = {
+	{
+		.name = "s5m8763-pmic",
+	}, {
+		.name = "s5m8767-pmic",
+	}, {
+		.name = "s5m-rtc",
+	}, {
+		.name = "s5m8763-charger",
+	},
+};
+
+static struct regmap_config s5m_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static int s5m_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct s5m87xx_platform_data *pdata = i2c->dev.platform_data;
+	struct s5m87xx_dev *s5m87xx;
+	int ret = 0;
+	int error;
+
+	s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL);
+	if (s5m87xx == NULL)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, s5m87xx);
+	s5m87xx->dev = &i2c->dev;
+	s5m87xx->i2c = i2c;
+	s5m87xx->irq = i2c->irq;
+	s5m87xx->type = id->driver_data;
+
+	if (pdata) {
+		s5m87xx->device_type = pdata->device_type;
+		s5m87xx->ono = pdata->ono;
+		s5m87xx->irq_base = pdata->irq_base;
+		s5m87xx->wakeup = pdata->wakeup;
+	}
+
+	s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config);
+        if (IS_ERR(s5m87xx->regmap)) {
+                error = PTR_ERR(s5m87xx->regmap);
+                dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+                        error);
+                goto err;
+        }
+
+	s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+	i2c_set_clientdata(s5m87xx->rtc, s5m87xx);
+
+	s5m_irq_init(s5m87xx);
+
+	pm_runtime_set_active(s5m87xx->dev);
+
+	ret = mfd_add_devices(s5m87xx->dev, -1,
+				s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs),
+				NULL, 0);
+	if (ret < 0)
+		goto err;
+
+	dev_info(s5m87xx->dev ,"SAMSUNG S5M MFD\n");
+	return ret;
+
+err:
+	mfd_remove_devices(s5m87xx->dev);
+	s5m_irq_exit(s5m87xx);
+	i2c_unregister_device(s5m87xx->rtc);
+	regmap_exit(s5m87xx->regmap);
+	kfree(s5m87xx);
+	return ret;
+}
+
+static int s5m_i2c_remove(struct i2c_client *i2c)
+{
+	struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+	mfd_remove_devices(s5m87xx->dev);
+	s5m_irq_exit(s5m87xx);
+	i2c_unregister_device(s5m87xx->rtc);
+	regmap_exit(s5m87xx->regmap);
+	kfree(s5m87xx);
+
+	return 0;
+}
+
+static const struct i2c_device_id s5m87xx_i2c_id[] = {
+	{ "s5m87xx", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id);
+
+static int s5m_suspend(struct i2c_client *i2c, pm_message_t state)
+{
+	struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+	if (s5m87xx->wakeup)
+		enable_irq_wake(s5m87xx->irq);
+
+	disable_irq(s5m87xx->irq);
+
+	return 0;
+}
+
+static int s5m_resume(struct i2c_client *i2c)
+{
+	struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+	if (s5m87xx->wakeup)
+		disable_irq_wake(s5m87xx->irq);
+
+	enable_irq(s5m87xx->irq);
+
+	return 0;
+}
+
+static struct i2c_driver s5m87xx_i2c_driver = {
+	.driver = {
+		   .name = "s5m87xx",
+		   .owner = THIS_MODULE,
+	},
+	.probe = s5m_i2c_probe,
+	.remove = s5m_i2c_remove,
+	.id_table = s5m87xx_i2c_id,
+	.suspend = s5m_suspend,
+	.resume = s5m_resume,
+};
+
+static int __init s5m87xx_i2c_init(void)
+{
+	return i2c_add_driver(&s5m87xx_i2c_driver);
+}
+
+subsys_initcall(s5m87xx_i2c_init);
+
+static void __exit s5m87xx_i2c_exit(void)
+{
+	i2c_del_driver(&s5m87xx_i2c_driver);
+}
+module_exit(s5m87xx_i2c_exit);
+
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_DESCRIPTION("Core support for the S5M87XX MFD");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/s5m87xx/s5m-core.h b/include/linux/mfd/s5m87xx/s5m-core.h
new file mode 100644
index 0000000..ddacd5b
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-core.h
@@ -0,0 +1,313 @@
+/*
+ * s5m-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_CORE_H
+#define __LINUX_MFD_S5M_CORE_H
+
+#define NUM_IRQ_REGS	4
+
+enum s5m_device_type {
+	S5M8751X,
+	S5M8763X,
+	S5M8767X,
+};
+
+/* S5M8767 registers */
+enum s5m8767_reg {
+	S5M8767_REG_ID,
+	S5M8767_REG_INT1,
+	S5M8767_REG_INT2,
+	S5M8767_REG_INT3,
+	S5M8767_REG_INT1M,
+	S5M8767_REG_INT2M,
+	S5M8767_REG_INT3M,
+	S5M8767_REG_STATUS1,
+	S5M8767_REG_STATUS2,
+	S5M8767_REG_STATUS3,
+	S5M8767_REG_CTRL1,
+	S5M8767_REG_CTRL2,
+	S5M8767_REG_LOWBAT1,
+	S5M8767_REG_LOWBAT2,
+	S5M8767_REG_BUCHG,
+	S5M8767_REG_DVSRAMP,
+	S5M8767_REG_DVSTIMER1,
+	S5M8767_REG_DVSTIMER2,
+	S5M8767_REG_DVSTIMER3,
+	S5M8767_REG_DVSTIMER4,
+	S5M8767_REG_LDO1,
+	S5M8767_REG_LDO2,
+	S5M8767_REG_LDO3,
+	S5M8767_REG_LDO4,
+	S5M8767_REG_LDO5,
+	S5M8767_REG_LDO6,
+	S5M8767_REG_LDO7,
+	S5M8767_REG_LDO8,
+	S5M8767_REG_LDO9,
+	S5M8767_REG_LDO10,
+	S5M8767_REG_LDO11,
+	S5M8767_REG_LDO12,
+	S5M8767_REG_LDO13,
+	S5M8767_REG_LDO14,
+	S5M8767_REG_LDO15,
+	S5M8767_REG_LDO16,
+	S5M8767_REG_LDO17,
+	S5M8767_REG_LDO18,
+	S5M8767_REG_LDO19,
+	S5M8767_REG_LDO20,
+	S5M8767_REG_LDO21,
+	S5M8767_REG_LDO22,
+	S5M8767_REG_LDO23,
+	S5M8767_REG_LDO24,
+	S5M8767_REG_LDO25,
+	S5M8767_REG_LDO26,
+	S5M8767_REG_LDO27,
+	S5M8767_REG_BUCK1CTRL1 = 0x35,
+	S5M8767_REG_BUCK1CTRL2,
+	S5M8767_REG_BUCK2CTRL,
+	S5M8767_REG_BUCK2DVS1,
+	S5M8767_REG_BUCK2DVS2,
+	S5M8767_REG_BUCK2DVS3,
+	S5M8767_REG_BUCK2DVS4,
+	S5M8767_REG_BUCK2DVS5,
+	S5M8767_REG_BUCK2DVS6,
+	S5M8767_REG_BUCK2DVS7,
+	S5M8767_REG_BUCK2DVS8,
+	S5M8767_REG_BUCK3CTRL,
+	S5M8767_REG_BUCK3DVS1,
+	S5M8767_REG_BUCK3DVS2,
+	S5M8767_REG_BUCK3DVS3,
+	S5M8767_REG_BUCK3DVS4,
+	S5M8767_REG_BUCK3DVS5,
+	S5M8767_REG_BUCK3DVS6,
+	S5M8767_REG_BUCK3DVS7,
+	S5M8767_REG_BUCK3DVS8,
+	S5M8767_REG_BUCK4CTRL,
+	S5M8767_REG_BUCK4DVS1,
+	S5M8767_REG_BUCK4DVS2,
+	S5M8767_REG_BUCK4DVS3,
+	S5M8767_REG_BUCK4DVS4,
+	S5M8767_REG_BUCK4DVS5,
+	S5M8767_REG_BUCK4DVS6,
+	S5M8767_REG_BUCK4DVS7,
+	S5M8767_REG_BUCK4DVS8,
+	S5M8767_REG_BUCK5CTRL1,
+	S5M8767_REG_BUCK5CTRL2,
+	S5M8767_REG_BUCK6CTRL1,
+	S5M8767_REG_BUCK6CTRL2,
+	S5M8767_REG_BUCK7CTRL1,
+	S5M8767_REG_BUCK7CTRL2,
+	S5M8767_REG_BUCK8CTRL1,
+	S5M8767_REG_BUCK8CTRL2,
+	S5M8767_REG_LDO1CTRL,
+	S5M8767_REG_LDO2CTRL,
+	S5M8767_REG_LDO3CTRL,
+	S5M8767_REG_LDO4CTRL,
+	S5M8767_REG_LDO5CTRL,
+	S5M8767_REG_LDO6CTRL,
+	S5M8767_REG_LDO7CTRL,
+	S5M8767_REG_LDO8CTRL,
+	S5M8767_REG_LDO9CTRL,
+	S5M8767_REG_LDO10CTRL,
+	S5M8767_REG_LDO11CTRL,
+	S5M8767_REG_LDO12CTRL,
+	S5M8767_REG_LDO13CTRL,
+	S5M8767_REG_LDO14CTRL,
+	S5M8767_REG_LDO15CTRL,
+	S5M8767_REG_LDO16CTRL,
+	S5M8767_REG_LDO17CTRL,
+	S5M8767_REG_LDO18CTRL,
+	S5M8767_REG_LDO19CTRL,
+	S5M8767_REG_LDO20CTRL,
+	S5M8767_REG_LDO21CTRL,
+	S5M8767_REG_LDO22CTRL,
+	S5M8767_REG_LDO23CTRL,
+	S5M8767_REG_LDO24CTRL,
+	S5M8767_REG_LDO25CTRL,
+	S5M8767_REG_LDO26CTRL,
+	S5M8767_REG_LDO27CTRL,
+};
+
+/* S5M8763 registers */
+enum s5m8763_reg {
+	S5M8763_REG_IRQ1,
+	S5M8763_REG_IRQ2,
+	S5M8763_REG_IRQ3,
+	S5M8763_REG_IRQ4,
+	S5M8763_REG_IRQM1,
+	S5M8763_REG_IRQM2,
+	S5M8763_REG_IRQM3,
+	S5M8763_REG_IRQM4,
+	S5M8763_REG_STATUS1,
+	S5M8763_REG_STATUS2,
+	S5M8763_REG_STATUSM1,
+	S5M8763_REG_STATUSM2,
+	S5M8763_REG_CHGR1,
+	S5M8763_REG_CHGR2,
+	S5M8763_REG_LDO_ACTIVE_DISCHARGE1,
+	S5M8763_REG_LDO_ACTIVE_DISCHARGE2,
+	S5M8763_REG_BUCK_ACTIVE_DISCHARGE3,
+	S5M8763_REG_ONOFF1,
+	S5M8763_REG_ONOFF2,
+	S5M8763_REG_ONOFF3,
+	S5M8763_REG_ONOFF4,
+	S5M8763_REG_BUCK1_VOLTAGE1,
+	S5M8763_REG_BUCK1_VOLTAGE2,
+	S5M8763_REG_BUCK1_VOLTAGE3,
+	S5M8763_REG_BUCK1_VOLTAGE4,
+	S5M8763_REG_BUCK2_VOLTAGE1,
+	S5M8763_REG_BUCK2_VOLTAGE2,
+	S5M8763_REG_BUCK3,
+	S5M8763_REG_BUCK4,
+	S5M8763_REG_LDO1_LDO2,
+	S5M8763_REG_LDO3,
+	S5M8763_REG_LDO4,
+	S5M8763_REG_LDO5,
+	S5M8763_REG_LDO6,
+	S5M8763_REG_LDO7,
+	S5M8763_REG_LDO7_LDO8,
+	S5M8763_REG_LDO9_LDO10,
+	S5M8763_REG_LDO11,
+	S5M8763_REG_LDO12,
+	S5M8763_REG_LDO13,
+	S5M8763_REG_LDO14,
+	S5M8763_REG_LDO15,
+	S5M8763_REG_LDO16,
+	S5M8763_REG_BKCHR,
+	S5M8763_REG_LBCNFG1,
+	S5M8763_REG_LBCNFG2,
+};
+
+enum s5m8767_irq {
+	S5M8767_IRQ_PWRR,
+	S5M8767_IRQ_PWRF,
+	S5M8767_IRQ_PWR1S,
+	S5M8767_IRQ_JIGR,
+	S5M8767_IRQ_JIGF,
+	S5M8767_IRQ_LOWBAT2,
+	S5M8767_IRQ_LOWBAT1,
+
+	S5M8767_IRQ_MRB,
+	S5M8767_IRQ_DVSOK2,
+	S5M8767_IRQ_DVSOK3,
+	S5M8767_IRQ_DVSOK4,
+
+	S5M8767_IRQ_RTC60S,
+	S5M8767_IRQ_RTCA1,
+	S5M8767_IRQ_RTCA2,
+	S5M8767_IRQ_SMPL,
+	S5M8767_IRQ_RTC1S,
+	S5M8767_IRQ_WTSR,
+
+	S5M8767_IRQ_NR,
+};
+
+#define S5M8767_IRQ_PWRR_MASK		(1 << 0)
+#define S5M8767_IRQ_PWRF_MASK		(1 << 1)
+#define S5M8767_IRQ_PWR1S_MASK		(1 << 3)
+#define S5M8767_IRQ_JIGR_MASK		(1 << 4)
+#define S5M8767_IRQ_JIGF_MASK		(1 << 5)
+#define S5M8767_IRQ_LOWBAT2_MASK	(1 << 6)
+#define S5M8767_IRQ_LOWBAT1_MASK	(1 << 7)
+
+#define S5M8767_IRQ_MRB_MASK		(1 << 2)
+#define S5M8767_IRQ_DVSOK2_MASK		(1 << 3)
+#define S5M8767_IRQ_DVSOK3_MASK		(1 << 4)
+#define S5M8767_IRQ_DVSOK4_MASK		(1 << 5)
+
+#define S5M8767_IRQ_RTC60S_MASK		(1 << 0)
+#define S5M8767_IRQ_RTCA1_MASK		(1 << 1)
+#define S5M8767_IRQ_RTCA2_MASK		(1 << 2)
+#define S5M8767_IRQ_SMPL_MASK		(1 << 3)
+#define S5M8767_IRQ_RTC1S_MASK		(1 << 4)
+#define S5M8767_IRQ_WTSR_MASK		(1 << 5)
+
+enum s5m8763_irq {
+	S5M8763_IRQ_VDCINF,
+	S5M8763_IRQ_VDCINR,
+	S5M8763_IRQ_JIGF,
+	S5M8763_IRQ_JIGR,
+	S5M8763_IRQ_PWRONF,
+	S5M8763_IRQ_PWRONR,
+
+	S5M8763_IRQ_WTSREVNT,
+	S5M8763_IRQ_SMPLEVNT,
+	S5M8763_IRQ_ALARM1,
+	S5M8763_IRQ_ALARM0,
+
+	S5M8763_IRQ_ONKEY1S,
+	S5M8763_IRQ_TOPOFFR,
+	S5M8763_IRQ_VDCINOVPR,
+	S5M8763_IRQ_CHGRSTF,
+	S5M8763_IRQ_DONER,
+	S5M8763_IRQ_CHGFAULT,
+
+	S5M8763_IRQ_LOBAT1,
+	S5M8763_IRQ_LOBAT2,
+
+	S5M8763_IRQ_NR,
+};
+
+#define S5M8763_IRQ_VDCINF_MASK		(1 << 2)
+#define S5M8763_IRQ_VDCINR_MASK		(1 << 3)
+#define S5M8763_IRQ_JIGF_MASK		(1 << 4)
+#define S5M8763_IRQ_JIGR_MASK		(1 << 5)
+#define S5M8763_IRQ_PWRONF_MASK		(1 << 6)
+#define S5M8763_IRQ_PWRONR_MASK		(1 << 7)
+
+#define S5M8763_IRQ_WTSREVNT_MASK	(1 << 0)
+#define S5M8763_IRQ_SMPLEVNT_MASK	(1 << 1)
+#define S5M8763_IRQ_ALARM1_MASK		(1 << 2)
+#define S5M8763_IRQ_ALARM0_MASK		(1 << 3)
+
+#define S5M8763_IRQ_ONKEY1S_MASK	(1 << 0)
+#define S5M8763_IRQ_TOPOFFR_MASK	(1 << 2)
+#define S5M8763_IRQ_VDCINOVPR_MASK	(1 << 3)
+#define S5M8763_IRQ_CHGRSTF_MASK	(1 << 4)
+#define S5M8763_IRQ_DONER_MASK		(1 << 5)
+#define S5M8763_IRQ_CHGFAULT_MASK	(1 << 7)
+
+#define S5M8763_IRQ_LOBAT1_MASK		(1 << 0)
+#define S5M8763_IRQ_LOBAT2_MASK		(1 << 1)
+
+#define S5M8763_ENRAMP                  (1 << 4)
+
+struct s5m87xx_dev {
+	struct device *dev;
+	struct i2c_client *i2c;
+	struct i2c_client *rtc;
+	struct mutex irqlock;
+	struct mutex iolock;
+
+	int device_type;
+	int irq_base;
+	int irq;
+	int ono;
+	u8 irq_masks_cur[NUM_IRQ_REGS];
+	u8 irq_masks_cache[NUM_IRQ_REGS];
+	int type;
+	bool wakeup;
+
+	struct regmap *regmap;
+};
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx);
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx);
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx);
+
+extern int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, u8 *dest);
+extern int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count,u8 *buf);
+extern int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value);
+extern int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count,u8 *buf);
+extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask);
+
+#endif /*  __LINUX_MFD_S5M_CORE_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-pmic.h b/include/linux/mfd/s5m87xx/s5m-pmic.h
new file mode 100644
index 0000000..2bb57b3
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-pmic.h
@@ -0,0 +1,141 @@
+/*
+ * s5m-pmic.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_PMIC_H
+#define __LINUX_MFD_S5M_PMIC_H
+
+#include <linux/regulator/machine.h>
+
+/* S5M8767 regulator ids */
+enum s5m8767_regulators {
+	S5M8767_LDO1,
+	S5M8767_LDO2,
+	S5M8767_LDO3,
+	S5M8767_LDO4,
+	S5M8767_LDO5,
+	S5M8767_LDO6,
+	S5M8767_LDO7,
+	S5M8767_LDO8,
+	S5M8767_LDO9,
+	S5M8767_LDO10,
+	S5M8767_LDO11,
+	S5M8767_LDO12,
+	S5M8767_LDO13,
+	S5M8767_LDO14,
+	S5M8767_LDO15,
+	S5M8767_LDO16,
+	S5M8767_LDO17,
+	S5M8767_LDO18,
+	S5M8767_LDO19,
+	S5M8767_LDO20,
+	S5M8767_LDO21,
+	S5M8767_LDO22,
+	S5M8767_LDO23,
+	S5M8767_LDO24,
+	S5M8767_LDO25,
+	S5M8767_LDO26,
+	S5M8767_LDO27,
+	S5M8767_BUCK1,
+	S5M8767_BUCK2,
+	S5M8767_BUCK3,
+	S5M8767_BUCK4,
+	S5M8767_BUCK5,
+	S5M8767_BUCK6,
+	S5M8767_BUCK7,
+	S5M8767_BUCK8,
+	S5M8767_32KHZAP_EN,
+	S5M8767_32KHZCP_EN,
+
+	S5M8767_REG_MAX,
+};
+
+/* S5M8763 regulator ids */
+enum s5m8763_regulators {
+	S5M8763_LDO1,
+	S5M8763_LDO2,
+	S5M8763_LDO3,
+	S5M8763_LDO4,
+	S5M8763_LDO5,
+	S5M8763_LDO6,
+	S5M8763_LDO7,
+	S5M8763_LDO8,
+	S5M8763_LDO9,
+	S5M8763_LDO10,
+	S5M8763_LDO11,
+	S5M8763_LDO12,
+	S5M8763_LDO13,
+	S5M8763_LDO14,
+	S5M8763_LDO15,
+	S5M8763_LDO16,
+	S5M8763_BUCK1,
+	S5M8763_BUCK2,
+	S5M8763_BUCK3,
+	S5M8763_BUCK4,
+	S5M8763_AP_EN32KHZ,
+	S5M8763_CP_EN32KHZ,
+	S5M8763_ENCHGVI,
+	S5M8763_ESAFEUSB1,
+	S5M8763_ESAFEUSB2,
+};
+
+/**
+ * s5m87xx_regulator_data - regulator data
+ * @id: regulator id
+ * @initdata: regulator init data (contraints, supplies, ...)
+ */
+struct s5m87xx_regulator_data {
+	int				id;
+	struct regulator_init_data	*initdata;
+};
+
+struct s5m87xx_platform_data {
+	struct s5m87xx_regulator_data	*regulators;
+	int				device_type;
+	int				num_regulators;
+	int				irq_base;
+	int				ono;
+	bool				wakeup;
+	bool				buck_voltage_lock;
+
+	int				buck_gpios[3];
+	int				buck_default_idx;
+	int				buck1_voltage[4];
+	int				buck2_voltage[8];
+	bool				buck2_gpiodvs;
+	int				buck3_voltage[8];
+	bool				buck3_gpiodvs;
+	int				buck4_voltage[8];
+	bool				buck4_gpiodvs;
+
+	int				buck1_set1;
+	int				buck1_set2;
+	int				buck2_set3;
+	int				buck_set1;
+	int				buck_set2;
+	int				buck_set3;
+	int				buck2_enable;
+	int				buck3_enable;
+	int				buck4_enable;
+	int				buck1_default_idx;
+	int				buck2_default_idx;
+	int				buck3_default_idx;
+	int				buck4_default_idx;
+	int				buck_ramp_delay;
+	bool				buck2_ramp_enable;
+	bool				buck3_ramp_enable;
+	bool				buck4_ramp_enable;
+
+
+};
+
+#endif /*  __LINUX_MFD_S5M_PMIC_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-rtc.h b/include/linux/mfd/s5m87xx/s5m-rtc.h
new file mode 100644
index 0000000..6f52e3c
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-rtc.h
@@ -0,0 +1,69 @@
+/*
+ * s5m-rtc.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_RTC_H
+#define __LINUX_MFD_S5M_RTC_H
+
+enum s5m_rtc_reg {
+	S5M_RTC_SEC,
+	S5M_RTC_MIN,
+	S5M_RTC_HOUR,
+	S5M_RTC_WEEKDAY,
+	S5M_RTC_DATE,
+	S5M_RTC_MONTH,
+	S5M_RTC_YEAR1,
+	S5M_RTC_YEAR2,
+	S5M_ALARM0_SEC,
+	S5M_ALARM0_MIN,
+	S5M_ALARM0_HOUR,
+	S5M_ALARM0_WEEKDAY,
+	S5M_ALARM0_DATE,
+	S5M_ALARM0_MONTH,
+	S5M_ALARM0_YEAR1,
+	S5M_ALARM0_YEAR2,
+	S5M_ALARM1_SEC,
+	S5M_ALARM1_MIN,
+	S5M_ALARM1_HOUR,
+	S5M_ALARM1_WEEKDAY,
+	S5M_ALARM1_DATE,
+	S5M_ALARM1_MONTH,
+	S5M_ALARM1_YEAR1,
+	S5M_ALARM1_YEAR2,
+	S5M_ALARM0_CONF,
+	S5M_ALARM1_CONF,
+	S5M_RTC_STATUS,
+	S5M_WTSR_SMPL_CNTL,
+	S5M_RTC_UDR_CON,
+};
+
+#define RTC_I2C_ADDR		(0x0C >> 1)
+
+#define HOUR_12			(1 << 7)
+#define HOUR_AMPM		(1 << 6)
+#define HOUR_PM			(1 << 5)
+#define ALARM0_STATUS		(1 << 1)
+#define ALARM1_STATUS		(1 << 2)
+#define UPDATE_AD		(1 << 0)
+
+enum {
+	RTC_SEC = 0,
+	RTC_MIN,
+	RTC_HOUR,
+	RTC_WEEKDAY,
+	RTC_DATE,
+	RTC_MONTH,
+	RTC_YEAR1,
+	RTC_YEAR2,
+};
+
+#endif /*  __LINUX_MFD_S5M_RTC_H */
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH 13/X] uprobes: introduce UTASK_SSTEP_TRAPPED logic
From: Ananth N Mavinakayanahalli @ 2011-10-24 15:16 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Srikar Dronamraju, Peter Zijlstra, Ingo Molnar, Steven Rostedt,
	Linux-mm, Arnaldo Carvalho de Melo, Linus Torvalds,
	Jonathan Corbet, Masami Hiramatsu, Hugh Dickins,
	Christoph Hellwig, Thomas Gleixner, Andi Kleen, Andrew Morton,
	Jim Keniston, Roland McGrath, LKML
In-Reply-To: <20111024144127.GA14975@redhat.com>

On Mon, Oct 24, 2011 at 04:41:27PM +0200, Oleg Nesterov wrote:
> On 10/22, Ananth N Mavinakayanahalli wrote:
> >
> > On Wed, Oct 19, 2011 at 11:53:44PM +0200, Oleg Nesterov wrote:
> > > Finally, add UTASK_SSTEP_TRAPPED state/code to handle the case when
> > > xol insn itself triggers the signal.
> > >
> > > In this case we should restart the original insn even if the task is
> > > already SIGKILL'ed (say, the coredump should report the correct ip).
> > > This is even more important if the task has a handler for SIGSEGV/etc,
> > > The _same_ instruction should be repeated again after return from the
> > > signal handler, and SSTEP can never finish in this case.
> >
> > Oleg,
> >
> > Not sure I understand this completely...
> 
> I hope you do not think I do ;)

I think you understand it better than you think you do :-)

> > When you say 'correct ip' you mean the original vaddr where we now have
> > a uprobe breakpoint and not the xol copy, right?
> 
> Yes,
> 
> > Coredump needs to report the correct ip, but should it also not report
> > correctly the instruction that caused the signal? Ergo, shouldn't we
> > put the original instruction back at the uprobed vaddr?
> 
> OK, now I see what you mean. I was confused by the "restore the original
> instruction before _restart_" suggestion.
> 
> Agreed! it would be nice to "hide" these int3's if we dump the core, but
> I think this is a bit off-topic. It makes sense to do this in any case,
> even if the core-dumping was triggered by another thread/insn. It makes
> sense to remove all int3's, not only at regs->ip location. But how can
> we do this? This is nontrivial.

I don't think that is a problem.. see below...

> And. Even worse. Suppose that you do "gdb probed_application". Now you
> see int3's in the disassemble output. What can we do?

In this case, nothing.

> I think we can do nothing, at least currently. This just reflects the
> fact that uprobe connects to inode, not to process/mm/etc.
> 
> What do you think?

Thinking further on this, in the normal 'running gdb on a core' case, we
won't have this problem, as the binary that we point gdb to, will be a
pristine one, without the uprobe int3s, right?

Ananth

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH 11/X] uprobes: x86: introduce xol_was_trapped()
From: Srikar Dronamraju @ 2011-10-24 14:55 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Peter Zijlstra, Ingo Molnar, Steven Rostedt, Linux-mm,
	Arnaldo Carvalho de Melo, Linus Torvalds, Jonathan Corbet,
	Masami Hiramatsu, Hugh Dickins, Christoph Hellwig,
	Ananth N Mavinakayanahalli, Thomas Gleixner, Andi Kleen,
	Andrew Morton, Jim Keniston, Roland McGrath, LKML
In-Reply-To: <20111019215307.GE16395@redhat.com>

> diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
> index 1c30cfd..f0fbdab 100644
> --- a/arch/x86/include/asm/uprobes.h
> +++ b/arch/x86/include/asm/uprobes.h
> @@ -39,6 +39,7 @@ struct uprobe_arch_info {
> 
>  struct uprobe_task_arch_info {
>  	unsigned long saved_scratch_register;
> +	unsigned long saved_trap_no;
>  };
>  #else
>  struct uprobe_arch_info {};


one nit
I had to add saved_trap_no to #else part (i.e uprobe_arch_info ). 

--
Thanks and Regards
Srikar


^ permalink raw reply

* [PATCH 1/3] mfd: Add S5M core driver
From: Sangbeom Kim @ 2011-10-23  7:30 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319355002-12674-1-git-send-email-sbkim73@samsung.com>

S5M series are pmic including mutiple functions.
It can support PMIC, RTC, Battery charger, codec.
This patch implement core driver for s5m series.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/s5m-core.c               |  235 +++++++++++++++++++++++++
 include/linux/mfd/s5m87xx/s5m-core.h |  313 ++++++++++++++++++++++++++++++++++
 include/linux/mfd/s5m87xx/s5m-pmic.h |  141 +++++++++++++++
 include/linux/mfd/s5m87xx/s5m-rtc.h  |   69 ++++++++
 4 files changed, 758 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/s5m-core.c
 create mode 100644 include/linux/mfd/s5m87xx/s5m-core.h
 create mode 100644 include/linux/mfd/s5m87xx/s5m-pmic.h
 create mode 100644 include/linux/mfd/s5m87xx/s5m-rtc.h

diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c
new file mode 100644
index 0000000..6dac3a1
--- /dev/null
+++ b/drivers/mfd/s5m-core.c
@@ -0,0 +1,235 @@
+/*
+ * s5m-core.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/mutex.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-rtc.h>
+#include <linux/regmap.h>
+
+int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, u8 *dest)
+{
+	int ret;
+	unsigned int val;
+
+	ret = regmap_read(s5m87xx->regmap, reg, &val);
+
+	if (ret < 0)
+		return ret;
+
+	ret &= 0xff;
+	*dest = ret;
+	return 0;
+}
+EXPORT_SYMBOL(s5m_reg_read);
+
+int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+	int ret;
+
+	ret = regmap_bulk_read(s5m87xx->regmap, reg, buf, count);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(s5m_bulk_read);
+
+int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value)
+{
+	int ret;
+
+	ret = regmap_write(s5m87xx->regmap, reg, value);
+	return ret;
+}
+EXPORT_SYMBOL(s5m_reg_write);
+
+int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+	int ret;
+
+	ret = regmap_raw_write(s5m87xx->regmap, reg, buf, count * sizeof(u16));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(s5m_bulk_write);
+
+int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask)
+{
+	int ret;
+
+	ret = regmap_update_bits(s5m87xx->regmap, reg, mask, val);
+	if (ret < 0)
+		return ret;
+
+	return ret;
+}
+EXPORT_SYMBOL(s5m_reg_update);
+
+static struct mfd_cell s5m87xx_devs[] = {
+	{
+		.name = "s5m8763-pmic",
+	}, {
+		.name = "s5m8767-pmic",
+	}, {
+		.name = "s5m-rtc",
+	}, {
+		.name = "s5m8763-charger",
+	},
+};
+
+static struct regmap_config s5m_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static int s5m_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct s5m87xx_platform_data *pdata = i2c->dev.platform_data;
+	struct s5m87xx_dev *s5m87xx;
+	int ret = 0;
+	int error;
+
+	s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL);
+	if (s5m87xx == NULL)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, s5m87xx);
+	s5m87xx->dev = &i2c->dev;
+	s5m87xx->i2c = i2c;
+	s5m87xx->irq = i2c->irq;
+	s5m87xx->type = id->driver_data;
+
+	if (pdata) {
+		s5m87xx->device_type = pdata->device_type;
+		s5m87xx->ono = pdata->ono;
+		s5m87xx->irq_base = pdata->irq_base;
+		s5m87xx->wakeup = pdata->wakeup;
+	}
+
+	s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config);
+        if (IS_ERR(s5m87xx->regmap)) {
+                error = PTR_ERR(s5m87xx->regmap);
+                dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+                        error);
+                goto err;
+        }
+
+	s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+	i2c_set_clientdata(s5m87xx->rtc, s5m87xx);
+
+	s5m_irq_init(s5m87xx);
+
+	pm_runtime_set_active(s5m87xx->dev);
+
+	ret = mfd_add_devices(s5m87xx->dev, -1,
+				s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs),
+				NULL, 0);
+	if (ret < 0)
+		goto err;
+
+	dev_info(s5m87xx->dev ,"SAMSUNG S5M MFD\n");
+	return ret;
+
+err:
+	mfd_remove_devices(s5m87xx->dev);
+	s5m_irq_exit(s5m87xx);
+	i2c_unregister_device(s5m87xx->rtc);
+	regmap_exit(s5m87xx->regmap);
+	kfree(s5m87xx);
+	return ret;
+}
+
+static int s5m_i2c_remove(struct i2c_client *i2c)
+{
+	struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+	mfd_remove_devices(s5m87xx->dev);
+	s5m_irq_exit(s5m87xx);
+	i2c_unregister_device(s5m87xx->rtc);
+	regmap_exit(s5m87xx->regmap);
+	kfree(s5m87xx);
+
+	return 0;
+}
+
+static const struct i2c_device_id s5m87xx_i2c_id[] = {
+	{ "s5m87xx", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id);
+
+static int s5m_suspend(struct i2c_client *i2c, pm_message_t state)
+{
+	struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+	if (s5m87xx->wakeup)
+		enable_irq_wake(s5m87xx->irq);
+
+	disable_irq(s5m87xx->irq);
+
+	return 0;
+}
+
+static int s5m_resume(struct i2c_client *i2c)
+{
+	struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+	if (s5m87xx->wakeup)
+		disable_irq_wake(s5m87xx->irq);
+
+	enable_irq(s5m87xx->irq);
+
+	return 0;
+}
+
+static struct i2c_driver s5m87xx_i2c_driver = {
+	.driver = {
+		   .name = "s5m87xx",
+		   .owner = THIS_MODULE,
+	},
+	.probe = s5m_i2c_probe,
+	.remove = s5m_i2c_remove,
+	.id_table = s5m87xx_i2c_id,
+	.suspend = s5m_suspend,
+	.resume = s5m_resume,
+};
+
+static int __init s5m87xx_i2c_init(void)
+{
+	return i2c_add_driver(&s5m87xx_i2c_driver);
+}
+
+subsys_initcall(s5m87xx_i2c_init);
+
+static void __exit s5m87xx_i2c_exit(void)
+{
+	i2c_del_driver(&s5m87xx_i2c_driver);
+}
+module_exit(s5m87xx_i2c_exit);
+
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_DESCRIPTION("Core support for the S5M87XX MFD");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/s5m87xx/s5m-core.h b/include/linux/mfd/s5m87xx/s5m-core.h
new file mode 100644
index 0000000..ddacd5b
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-core.h
@@ -0,0 +1,313 @@
+/*
+ * s5m-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_CORE_H
+#define __LINUX_MFD_S5M_CORE_H
+
+#define NUM_IRQ_REGS	4
+
+enum s5m_device_type {
+	S5M8751X,
+	S5M8763X,
+	S5M8767X,
+};
+
+/* S5M8767 registers */
+enum s5m8767_reg {
+	S5M8767_REG_ID,
+	S5M8767_REG_INT1,
+	S5M8767_REG_INT2,
+	S5M8767_REG_INT3,
+	S5M8767_REG_INT1M,
+	S5M8767_REG_INT2M,
+	S5M8767_REG_INT3M,
+	S5M8767_REG_STATUS1,
+	S5M8767_REG_STATUS2,
+	S5M8767_REG_STATUS3,
+	S5M8767_REG_CTRL1,
+	S5M8767_REG_CTRL2,
+	S5M8767_REG_LOWBAT1,
+	S5M8767_REG_LOWBAT2,
+	S5M8767_REG_BUCHG,
+	S5M8767_REG_DVSRAMP,
+	S5M8767_REG_DVSTIMER1,
+	S5M8767_REG_DVSTIMER2,
+	S5M8767_REG_DVSTIMER3,
+	S5M8767_REG_DVSTIMER4,
+	S5M8767_REG_LDO1,
+	S5M8767_REG_LDO2,
+	S5M8767_REG_LDO3,
+	S5M8767_REG_LDO4,
+	S5M8767_REG_LDO5,
+	S5M8767_REG_LDO6,
+	S5M8767_REG_LDO7,
+	S5M8767_REG_LDO8,
+	S5M8767_REG_LDO9,
+	S5M8767_REG_LDO10,
+	S5M8767_REG_LDO11,
+	S5M8767_REG_LDO12,
+	S5M8767_REG_LDO13,
+	S5M8767_REG_LDO14,
+	S5M8767_REG_LDO15,
+	S5M8767_REG_LDO16,
+	S5M8767_REG_LDO17,
+	S5M8767_REG_LDO18,
+	S5M8767_REG_LDO19,
+	S5M8767_REG_LDO20,
+	S5M8767_REG_LDO21,
+	S5M8767_REG_LDO22,
+	S5M8767_REG_LDO23,
+	S5M8767_REG_LDO24,
+	S5M8767_REG_LDO25,
+	S5M8767_REG_LDO26,
+	S5M8767_REG_LDO27,
+	S5M8767_REG_BUCK1CTRL1 = 0x35,
+	S5M8767_REG_BUCK1CTRL2,
+	S5M8767_REG_BUCK2CTRL,
+	S5M8767_REG_BUCK2DVS1,
+	S5M8767_REG_BUCK2DVS2,
+	S5M8767_REG_BUCK2DVS3,
+	S5M8767_REG_BUCK2DVS4,
+	S5M8767_REG_BUCK2DVS5,
+	S5M8767_REG_BUCK2DVS6,
+	S5M8767_REG_BUCK2DVS7,
+	S5M8767_REG_BUCK2DVS8,
+	S5M8767_REG_BUCK3CTRL,
+	S5M8767_REG_BUCK3DVS1,
+	S5M8767_REG_BUCK3DVS2,
+	S5M8767_REG_BUCK3DVS3,
+	S5M8767_REG_BUCK3DVS4,
+	S5M8767_REG_BUCK3DVS5,
+	S5M8767_REG_BUCK3DVS6,
+	S5M8767_REG_BUCK3DVS7,
+	S5M8767_REG_BUCK3DVS8,
+	S5M8767_REG_BUCK4CTRL,
+	S5M8767_REG_BUCK4DVS1,
+	S5M8767_REG_BUCK4DVS2,
+	S5M8767_REG_BUCK4DVS3,
+	S5M8767_REG_BUCK4DVS4,
+	S5M8767_REG_BUCK4DVS5,
+	S5M8767_REG_BUCK4DVS6,
+	S5M8767_REG_BUCK4DVS7,
+	S5M8767_REG_BUCK4DVS8,
+	S5M8767_REG_BUCK5CTRL1,
+	S5M8767_REG_BUCK5CTRL2,
+	S5M8767_REG_BUCK6CTRL1,
+	S5M8767_REG_BUCK6CTRL2,
+	S5M8767_REG_BUCK7CTRL1,
+	S5M8767_REG_BUCK7CTRL2,
+	S5M8767_REG_BUCK8CTRL1,
+	S5M8767_REG_BUCK8CTRL2,
+	S5M8767_REG_LDO1CTRL,
+	S5M8767_REG_LDO2CTRL,
+	S5M8767_REG_LDO3CTRL,
+	S5M8767_REG_LDO4CTRL,
+	S5M8767_REG_LDO5CTRL,
+	S5M8767_REG_LDO6CTRL,
+	S5M8767_REG_LDO7CTRL,
+	S5M8767_REG_LDO8CTRL,
+	S5M8767_REG_LDO9CTRL,
+	S5M8767_REG_LDO10CTRL,
+	S5M8767_REG_LDO11CTRL,
+	S5M8767_REG_LDO12CTRL,
+	S5M8767_REG_LDO13CTRL,
+	S5M8767_REG_LDO14CTRL,
+	S5M8767_REG_LDO15CTRL,
+	S5M8767_REG_LDO16CTRL,
+	S5M8767_REG_LDO17CTRL,
+	S5M8767_REG_LDO18CTRL,
+	S5M8767_REG_LDO19CTRL,
+	S5M8767_REG_LDO20CTRL,
+	S5M8767_REG_LDO21CTRL,
+	S5M8767_REG_LDO22CTRL,
+	S5M8767_REG_LDO23CTRL,
+	S5M8767_REG_LDO24CTRL,
+	S5M8767_REG_LDO25CTRL,
+	S5M8767_REG_LDO26CTRL,
+	S5M8767_REG_LDO27CTRL,
+};
+
+/* S5M8763 registers */
+enum s5m8763_reg {
+	S5M8763_REG_IRQ1,
+	S5M8763_REG_IRQ2,
+	S5M8763_REG_IRQ3,
+	S5M8763_REG_IRQ4,
+	S5M8763_REG_IRQM1,
+	S5M8763_REG_IRQM2,
+	S5M8763_REG_IRQM3,
+	S5M8763_REG_IRQM4,
+	S5M8763_REG_STATUS1,
+	S5M8763_REG_STATUS2,
+	S5M8763_REG_STATUSM1,
+	S5M8763_REG_STATUSM2,
+	S5M8763_REG_CHGR1,
+	S5M8763_REG_CHGR2,
+	S5M8763_REG_LDO_ACTIVE_DISCHARGE1,
+	S5M8763_REG_LDO_ACTIVE_DISCHARGE2,
+	S5M8763_REG_BUCK_ACTIVE_DISCHARGE3,
+	S5M8763_REG_ONOFF1,
+	S5M8763_REG_ONOFF2,
+	S5M8763_REG_ONOFF3,
+	S5M8763_REG_ONOFF4,
+	S5M8763_REG_BUCK1_VOLTAGE1,
+	S5M8763_REG_BUCK1_VOLTAGE2,
+	S5M8763_REG_BUCK1_VOLTAGE3,
+	S5M8763_REG_BUCK1_VOLTAGE4,
+	S5M8763_REG_BUCK2_VOLTAGE1,
+	S5M8763_REG_BUCK2_VOLTAGE2,
+	S5M8763_REG_BUCK3,
+	S5M8763_REG_BUCK4,
+	S5M8763_REG_LDO1_LDO2,
+	S5M8763_REG_LDO3,
+	S5M8763_REG_LDO4,
+	S5M8763_REG_LDO5,
+	S5M8763_REG_LDO6,
+	S5M8763_REG_LDO7,
+	S5M8763_REG_LDO7_LDO8,
+	S5M8763_REG_LDO9_LDO10,
+	S5M8763_REG_LDO11,
+	S5M8763_REG_LDO12,
+	S5M8763_REG_LDO13,
+	S5M8763_REG_LDO14,
+	S5M8763_REG_LDO15,
+	S5M8763_REG_LDO16,
+	S5M8763_REG_BKCHR,
+	S5M8763_REG_LBCNFG1,
+	S5M8763_REG_LBCNFG2,
+};
+
+enum s5m8767_irq {
+	S5M8767_IRQ_PWRR,
+	S5M8767_IRQ_PWRF,
+	S5M8767_IRQ_PWR1S,
+	S5M8767_IRQ_JIGR,
+	S5M8767_IRQ_JIGF,
+	S5M8767_IRQ_LOWBAT2,
+	S5M8767_IRQ_LOWBAT1,
+
+	S5M8767_IRQ_MRB,
+	S5M8767_IRQ_DVSOK2,
+	S5M8767_IRQ_DVSOK3,
+	S5M8767_IRQ_DVSOK4,
+
+	S5M8767_IRQ_RTC60S,
+	S5M8767_IRQ_RTCA1,
+	S5M8767_IRQ_RTCA2,
+	S5M8767_IRQ_SMPL,
+	S5M8767_IRQ_RTC1S,
+	S5M8767_IRQ_WTSR,
+
+	S5M8767_IRQ_NR,
+};
+
+#define S5M8767_IRQ_PWRR_MASK		(1 << 0)
+#define S5M8767_IRQ_PWRF_MASK		(1 << 1)
+#define S5M8767_IRQ_PWR1S_MASK		(1 << 3)
+#define S5M8767_IRQ_JIGR_MASK		(1 << 4)
+#define S5M8767_IRQ_JIGF_MASK		(1 << 5)
+#define S5M8767_IRQ_LOWBAT2_MASK	(1 << 6)
+#define S5M8767_IRQ_LOWBAT1_MASK	(1 << 7)
+
+#define S5M8767_IRQ_MRB_MASK		(1 << 2)
+#define S5M8767_IRQ_DVSOK2_MASK		(1 << 3)
+#define S5M8767_IRQ_DVSOK3_MASK		(1 << 4)
+#define S5M8767_IRQ_DVSOK4_MASK		(1 << 5)
+
+#define S5M8767_IRQ_RTC60S_MASK		(1 << 0)
+#define S5M8767_IRQ_RTCA1_MASK		(1 << 1)
+#define S5M8767_IRQ_RTCA2_MASK		(1 << 2)
+#define S5M8767_IRQ_SMPL_MASK		(1 << 3)
+#define S5M8767_IRQ_RTC1S_MASK		(1 << 4)
+#define S5M8767_IRQ_WTSR_MASK		(1 << 5)
+
+enum s5m8763_irq {
+	S5M8763_IRQ_VDCINF,
+	S5M8763_IRQ_VDCINR,
+	S5M8763_IRQ_JIGF,
+	S5M8763_IRQ_JIGR,
+	S5M8763_IRQ_PWRONF,
+	S5M8763_IRQ_PWRONR,
+
+	S5M8763_IRQ_WTSREVNT,
+	S5M8763_IRQ_SMPLEVNT,
+	S5M8763_IRQ_ALARM1,
+	S5M8763_IRQ_ALARM0,
+
+	S5M8763_IRQ_ONKEY1S,
+	S5M8763_IRQ_TOPOFFR,
+	S5M8763_IRQ_VDCINOVPR,
+	S5M8763_IRQ_CHGRSTF,
+	S5M8763_IRQ_DONER,
+	S5M8763_IRQ_CHGFAULT,
+
+	S5M8763_IRQ_LOBAT1,
+	S5M8763_IRQ_LOBAT2,
+
+	S5M8763_IRQ_NR,
+};
+
+#define S5M8763_IRQ_VDCINF_MASK		(1 << 2)
+#define S5M8763_IRQ_VDCINR_MASK		(1 << 3)
+#define S5M8763_IRQ_JIGF_MASK		(1 << 4)
+#define S5M8763_IRQ_JIGR_MASK		(1 << 5)
+#define S5M8763_IRQ_PWRONF_MASK		(1 << 6)
+#define S5M8763_IRQ_PWRONR_MASK		(1 << 7)
+
+#define S5M8763_IRQ_WTSREVNT_MASK	(1 << 0)
+#define S5M8763_IRQ_SMPLEVNT_MASK	(1 << 1)
+#define S5M8763_IRQ_ALARM1_MASK		(1 << 2)
+#define S5M8763_IRQ_ALARM0_MASK		(1 << 3)
+
+#define S5M8763_IRQ_ONKEY1S_MASK	(1 << 0)
+#define S5M8763_IRQ_TOPOFFR_MASK	(1 << 2)
+#define S5M8763_IRQ_VDCINOVPR_MASK	(1 << 3)
+#define S5M8763_IRQ_CHGRSTF_MASK	(1 << 4)
+#define S5M8763_IRQ_DONER_MASK		(1 << 5)
+#define S5M8763_IRQ_CHGFAULT_MASK	(1 << 7)
+
+#define S5M8763_IRQ_LOBAT1_MASK		(1 << 0)
+#define S5M8763_IRQ_LOBAT2_MASK		(1 << 1)
+
+#define S5M8763_ENRAMP                  (1 << 4)
+
+struct s5m87xx_dev {
+	struct device *dev;
+	struct i2c_client *i2c;
+	struct i2c_client *rtc;
+	struct mutex irqlock;
+	struct mutex iolock;
+
+	int device_type;
+	int irq_base;
+	int irq;
+	int ono;
+	u8 irq_masks_cur[NUM_IRQ_REGS];
+	u8 irq_masks_cache[NUM_IRQ_REGS];
+	int type;
+	bool wakeup;
+
+	struct regmap *regmap;
+};
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx);
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx);
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx);
+
+extern int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, u8 *dest);
+extern int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count,u8 *buf);
+extern int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value);
+extern int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count,u8 *buf);
+extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask);
+
+#endif /*  __LINUX_MFD_S5M_CORE_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-pmic.h b/include/linux/mfd/s5m87xx/s5m-pmic.h
new file mode 100644
index 0000000..2bb57b3
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-pmic.h
@@ -0,0 +1,141 @@
+/*
+ * s5m-pmic.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_PMIC_H
+#define __LINUX_MFD_S5M_PMIC_H
+
+#include <linux/regulator/machine.h>
+
+/* S5M8767 regulator ids */
+enum s5m8767_regulators {
+	S5M8767_LDO1,
+	S5M8767_LDO2,
+	S5M8767_LDO3,
+	S5M8767_LDO4,
+	S5M8767_LDO5,
+	S5M8767_LDO6,
+	S5M8767_LDO7,
+	S5M8767_LDO8,
+	S5M8767_LDO9,
+	S5M8767_LDO10,
+	S5M8767_LDO11,
+	S5M8767_LDO12,
+	S5M8767_LDO13,
+	S5M8767_LDO14,
+	S5M8767_LDO15,
+	S5M8767_LDO16,
+	S5M8767_LDO17,
+	S5M8767_LDO18,
+	S5M8767_LDO19,
+	S5M8767_LDO20,
+	S5M8767_LDO21,
+	S5M8767_LDO22,
+	S5M8767_LDO23,
+	S5M8767_LDO24,
+	S5M8767_LDO25,
+	S5M8767_LDO26,
+	S5M8767_LDO27,
+	S5M8767_BUCK1,
+	S5M8767_BUCK2,
+	S5M8767_BUCK3,
+	S5M8767_BUCK4,
+	S5M8767_BUCK5,
+	S5M8767_BUCK6,
+	S5M8767_BUCK7,
+	S5M8767_BUCK8,
+	S5M8767_32KHZAP_EN,
+	S5M8767_32KHZCP_EN,
+
+	S5M8767_REG_MAX,
+};
+
+/* S5M8763 regulator ids */
+enum s5m8763_regulators {
+	S5M8763_LDO1,
+	S5M8763_LDO2,
+	S5M8763_LDO3,
+	S5M8763_LDO4,
+	S5M8763_LDO5,
+	S5M8763_LDO6,
+	S5M8763_LDO7,
+	S5M8763_LDO8,
+	S5M8763_LDO9,
+	S5M8763_LDO10,
+	S5M8763_LDO11,
+	S5M8763_LDO12,
+	S5M8763_LDO13,
+	S5M8763_LDO14,
+	S5M8763_LDO15,
+	S5M8763_LDO16,
+	S5M8763_BUCK1,
+	S5M8763_BUCK2,
+	S5M8763_BUCK3,
+	S5M8763_BUCK4,
+	S5M8763_AP_EN32KHZ,
+	S5M8763_CP_EN32KHZ,
+	S5M8763_ENCHGVI,
+	S5M8763_ESAFEUSB1,
+	S5M8763_ESAFEUSB2,
+};
+
+/**
+ * s5m87xx_regulator_data - regulator data
+ * @id: regulator id
+ * @initdata: regulator init data (contraints, supplies, ...)
+ */
+struct s5m87xx_regulator_data {
+	int				id;
+	struct regulator_init_data	*initdata;
+};
+
+struct s5m87xx_platform_data {
+	struct s5m87xx_regulator_data	*regulators;
+	int				device_type;
+	int				num_regulators;
+	int				irq_base;
+	int				ono;
+	bool				wakeup;
+	bool				buck_voltage_lock;
+
+	int				buck_gpios[3];
+	int				buck_default_idx;
+	int				buck1_voltage[4];
+	int				buck2_voltage[8];
+	bool				buck2_gpiodvs;
+	int				buck3_voltage[8];
+	bool				buck3_gpiodvs;
+	int				buck4_voltage[8];
+	bool				buck4_gpiodvs;
+
+	int				buck1_set1;
+	int				buck1_set2;
+	int				buck2_set3;
+	int				buck_set1;
+	int				buck_set2;
+	int				buck_set3;
+	int				buck2_enable;
+	int				buck3_enable;
+	int				buck4_enable;
+	int				buck1_default_idx;
+	int				buck2_default_idx;
+	int				buck3_default_idx;
+	int				buck4_default_idx;
+	int				buck_ramp_delay;
+	bool				buck2_ramp_enable;
+	bool				buck3_ramp_enable;
+	bool				buck4_ramp_enable;
+
+
+};
+
+#endif /*  __LINUX_MFD_S5M_PMIC_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-rtc.h b/include/linux/mfd/s5m87xx/s5m-rtc.h
new file mode 100644
index 0000000..6f52e3c
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-rtc.h
@@ -0,0 +1,69 @@
+/*
+ * s5m-rtc.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_RTC_H
+#define __LINUX_MFD_S5M_RTC_H
+
+enum s5m_rtc_reg {
+	S5M_RTC_SEC,
+	S5M_RTC_MIN,
+	S5M_RTC_HOUR,
+	S5M_RTC_WEEKDAY,
+	S5M_RTC_DATE,
+	S5M_RTC_MONTH,
+	S5M_RTC_YEAR1,
+	S5M_RTC_YEAR2,
+	S5M_ALARM0_SEC,
+	S5M_ALARM0_MIN,
+	S5M_ALARM0_HOUR,
+	S5M_ALARM0_WEEKDAY,
+	S5M_ALARM0_DATE,
+	S5M_ALARM0_MONTH,
+	S5M_ALARM0_YEAR1,
+	S5M_ALARM0_YEAR2,
+	S5M_ALARM1_SEC,
+	S5M_ALARM1_MIN,
+	S5M_ALARM1_HOUR,
+	S5M_ALARM1_WEEKDAY,
+	S5M_ALARM1_DATE,
+	S5M_ALARM1_MONTH,
+	S5M_ALARM1_YEAR1,
+	S5M_ALARM1_YEAR2,
+	S5M_ALARM0_CONF,
+	S5M_ALARM1_CONF,
+	S5M_RTC_STATUS,
+	S5M_WTSR_SMPL_CNTL,
+	S5M_RTC_UDR_CON,
+};
+
+#define RTC_I2C_ADDR		(0x0C >> 1)
+
+#define HOUR_12			(1 << 7)
+#define HOUR_AMPM		(1 << 6)
+#define HOUR_PM			(1 << 5)
+#define ALARM0_STATUS		(1 << 1)
+#define ALARM1_STATUS		(1 << 2)
+#define UPDATE_AD		(1 << 0)
+
+enum {
+	RTC_SEC = 0,
+	RTC_MIN,
+	RTC_HOUR,
+	RTC_WEEKDAY,
+	RTC_DATE,
+	RTC_MONTH,
+	RTC_YEAR1,
+	RTC_YEAR2,
+};
+
+#endif /*  __LINUX_MFD_S5M_RTC_H */
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/3] mfd: Add s5m series irq support
From: Sangbeom Kim @ 2011-10-21 10:28 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319192894-19292-1-git-send-email-sbkim73@samsung.com>

This patch support irq for s5m series.
Basically, S5M8767 and S5M8763 irq can be handled by this patch.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/s5m-irq.c |  486 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 486 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/s5m-irq.c

diff --git a/drivers/mfd/s5m-irq.c b/drivers/mfd/s5m-irq.c
new file mode 100644
index 0000000..6a4a71a
--- /dev/null
+++ b/drivers/mfd/s5m-irq.c
@@ -0,0 +1,486 @@
+/*
+ * s5m-irq.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+
+struct s5m_irq_data {
+	int reg;
+	int mask;
+};
+
+static struct s5m_irq_data s5m8767_irqs[] = {
+	[S5M8767_IRQ_PWRR] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWRR_MASK,
+	},
+	[S5M8767_IRQ_PWRF] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWRF_MASK,
+	},
+	[S5M8767_IRQ_PWR1S] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWR1S_MASK,
+	},
+	[S5M8767_IRQ_JIGR] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_JIGR_MASK,
+	},
+	[S5M8767_IRQ_JIGF] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_JIGF_MASK,
+	},
+	[S5M8767_IRQ_LOWBAT2] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_LOWBAT2_MASK,
+	},
+	[S5M8767_IRQ_LOWBAT1] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_LOWBAT1_MASK,
+	},
+	[S5M8767_IRQ_MRB] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_MRB_MASK,
+	},
+	[S5M8767_IRQ_DVSOK2] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK2_MASK,
+	},
+	[S5M8767_IRQ_DVSOK3] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK3_MASK,
+	},
+	[S5M8767_IRQ_DVSOK4] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK4_MASK,
+	},
+	[S5M8767_IRQ_RTC60S] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTC60S_MASK,
+	},
+	[S5M8767_IRQ_RTCA1] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTCA1_MASK,
+	},
+	[S5M8767_IRQ_RTCA2] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTCA2_MASK,
+	},
+	[S5M8767_IRQ_SMPL] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_SMPL_MASK,
+	},
+	[S5M8767_IRQ_RTC1S] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTC1S_MASK,
+	},
+	[S5M8767_IRQ_WTSR] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_WTSR_MASK,
+	},
+};
+
+static struct s5m_irq_data s5m8763_irqs[] = {
+	[S5M8763_IRQ_VDCINF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_VDCINF_MASK,
+	},
+	[S5M8763_IRQ_VDCINR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_VDCINR_MASK,
+	},
+	[S5M8763_IRQ_JIGF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_JIGF_MASK,
+	},
+	[S5M8763_IRQ_JIGR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_JIGR_MASK,
+	},
+	[S5M8763_IRQ_PWRONF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_PWRONF_MASK,
+	},
+	[S5M8763_IRQ_PWRONR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_PWRONR_MASK,
+	},
+	[S5M8763_IRQ_WTSREVNT] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_WTSREVNT_MASK,
+	},
+	[S5M8763_IRQ_SMPLEVNT] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_SMPLEVNT_MASK,
+	},
+	[S5M8763_IRQ_ALARM1] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_ALARM1_MASK,
+	},
+	[S5M8763_IRQ_ALARM0] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_ALARM0_MASK,
+	},
+	[S5M8763_IRQ_ONKEY1S] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_ONKEY1S_MASK,
+	},
+	[S5M8763_IRQ_TOPOFFR] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_TOPOFFR_MASK,
+	},
+	[S5M8763_IRQ_VDCINOVPR] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_VDCINOVPR_MASK,
+	},
+	[S5M8763_IRQ_CHGRSTF] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_CHGRSTF_MASK,
+	},
+	[S5M8763_IRQ_DONER] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_DONER_MASK,
+	},
+	[S5M8763_IRQ_CHGFAULT] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_CHGFAULT_MASK,
+	},
+	[S5M8763_IRQ_LOBAT1] = {
+		.reg = 4,
+		.mask = S5M8763_IRQ_LOBAT1_MASK,
+	},
+	[S5M8763_IRQ_LOBAT2] = {
+		.reg = 4,
+		.mask = S5M8763_IRQ_LOBAT2_MASK,
+	},
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8767_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+	return &s5m8767_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8767_irq_lock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_sync_unlock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+		if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+			s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+			s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+					s5m87xx->irq_masks_cur[i]);
+		}
+	}
+
+	mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_unmask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8767_irq_mask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8767_irq_chip = {
+	.name = "s5m8767",
+	.irq_bus_lock = s5m8767_irq_lock,
+	.irq_bus_sync_unlock = s5m8767_irq_sync_unlock,
+	.irq_mask = s5m8767_irq_mask,
+	.irq_unmask = s5m8767_irq_unmask,
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8763_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+	return &s5m8763_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8763_irq_lock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_sync_unlock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+		if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+			s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+			s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+					s5m87xx->irq_masks_cur[i]);
+		}
+	}
+
+	mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_unmask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8763_irq_mask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8763_irq_chip = {
+	.name = "s5m8763",
+	.irq_bus_lock = s5m8763_irq_lock,
+	.irq_bus_sync_unlock = s5m8763_irq_sync_unlock,
+	.irq_mask = s5m8763_irq_mask,
+	.irq_unmask = s5m8763_irq_unmask,
+};
+
+static irqreturn_t s5m8767_irq_thread(int irq, void *data)
+{
+	struct s5m87xx_dev *s5m87xx = data;
+	u8 irq_reg[NUM_IRQ_REGS-1];
+	int ret;
+	int i;
+
+	ret = s5m_bulk_read(s5m87xx, S5M8767_REG_INT1,
+				NUM_IRQ_REGS - 1, irq_reg);
+	if (ret < 0) {
+		dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+				ret);
+		return IRQ_NONE;
+	}
+
+	for (i = 0; i < NUM_IRQ_REGS - 1; i++)
+		irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+	for (i = 0; i < S5M8767_IRQ_NR; i++) {
+		if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask)
+			handle_nested_irq(s5m87xx->irq_base + i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t s5m8763_irq_thread(int irq, void *data)
+{
+	struct s5m87xx_dev *s5m87xx = data;
+	u8 irq_reg[NUM_IRQ_REGS];
+	int ret;
+	int i;
+
+	ret = s5m_bulk_read(s5m87xx, S5M8763_REG_IRQ1,
+				NUM_IRQ_REGS, irq_reg);
+	if (ret < 0) {
+		dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+				ret);
+		return IRQ_NONE;
+	}
+
+	for (i = 0; i < NUM_IRQ_REGS; i++)
+		irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+	for (i = 0; i < S5M8763_IRQ_NR; i++) {
+		if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask)
+			handle_nested_irq(s5m87xx->irq_base + i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx)
+{
+	if (s5m87xx->irq && s5m87xx->irq_base){
+		switch (s5m87xx->device_type) {
+		case S5M8763X:
+			s5m8763_irq_thread(s5m87xx->irq_base, s5m87xx);
+			break;
+		case S5M8767X:
+			s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx);
+			break;
+		default:
+			break;
+
+		}
+	}
+	return 0;
+}
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
+{
+	int i;
+	int cur_irq;
+	int ret = 0;
+	int type = s5m87xx->device_type;
+
+	if (!s5m87xx->irq) {
+		dev_warn(s5m87xx->dev,
+			 "No interrupt specified, no interrupts\n");
+		s5m87xx->irq_base = 0;
+		return 0;
+	}
+
+	if (!s5m87xx->irq_base) {
+		dev_err(s5m87xx->dev,
+			"No interrupt base specified, no interrupts\n");
+		return 0;
+	}
+
+	mutex_init(&s5m87xx->irqlock);
+
+	switch (type) {
+	case S5M8763X:
+		for (i = 0; i < NUM_IRQ_REGS; i++) {
+			s5m87xx->irq_masks_cur[i] = 0xff;
+			s5m87xx->irq_masks_cache[i] = 0xff;
+			s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+						0xff);
+		}
+
+		s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM1, 0xff);
+		s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM2, 0xff);
+
+		for (i = 0; i < S5M8763_IRQ_NR; i++) {
+			cur_irq = i + s5m87xx->irq_base;
+			irq_set_chip_data(cur_irq, s5m87xx);
+			irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip,
+						 handle_edge_irq);
+			irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+			set_irq_flags(cur_irq, IRQF_VALID);
+#else
+			irq_set_noprobe(cur_irq);
+#endif
+		}
+
+		ret = request_threaded_irq(s5m87xx->irq, NULL,
+					s5m8763_irq_thread,
+					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					"s5m87xx-irq", s5m87xx);
+		if (ret) {
+			dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+				s5m87xx->irq, ret);
+			return ret;
+		}
+		break;
+	case S5M8767X:
+		for (i = 0; i < NUM_IRQ_REGS - 1; i++) {
+			s5m87xx->irq_masks_cur[i] = 0xff;
+			s5m87xx->irq_masks_cache[i] = 0xff;
+			s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+						0xff);
+		}
+
+		for (i = 0; i < S5M8767_IRQ_NR; i++) {
+			cur_irq = i + s5m87xx->irq_base;
+			irq_set_chip_data(cur_irq, s5m87xx);
+			if (ret) {
+				dev_err(s5m87xx->dev,
+					"Failed to irq_set_chip_data %d: %d\n",
+					s5m87xx->irq, ret);
+				return ret;
+			}
+
+			irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip,
+						 handle_edge_irq);
+			irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+			set_irq_flags(cur_irq, IRQF_VALID);
+#else
+			irq_set_noprobe(cur_irq);
+#endif
+		}
+
+		ret = request_threaded_irq(s5m87xx->irq, NULL,
+					   s5m8767_irq_thread,
+					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					   "s5m87xx-irq", s5m87xx);
+		if (ret) {
+			dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+				s5m87xx->irq, ret);
+			return ret;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (!s5m87xx->ono)
+		return 0;
+
+	switch (type) {
+	case S5M8763X:
+		ret = request_threaded_irq(s5m87xx->ono, NULL,
+						s5m8763_irq_thread,
+						IRQF_TRIGGER_FALLING |
+						IRQF_TRIGGER_RISING |
+						IRQF_ONESHOT, "s5m87xx-ono",
+						s5m87xx);
+		break;
+	case S5M8767X:
+		ret = request_threaded_irq(s5m87xx->ono, NULL,
+					s5m8767_irq_thread,
+					IRQF_TRIGGER_FALLING |
+					IRQF_TRIGGER_RISING |
+					IRQF_ONESHOT, "s5m87xx-ono", s5m87xx);
+		break;
+	default:
+		break;
+	}
+
+	if (ret)
+		dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+			s5m87xx->ono, ret);
+
+	return 0;
+}
+
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx)
+{
+	if (s5m87xx->ono)
+		free_irq(s5m87xx->ono, s5m87xx);
+
+	if (s5m87xx->irq)
+		free_irq(s5m87xx->irq, s5m87xx);
+}
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH 13/X] uprobes: introduce UTASK_SSTEP_TRAPPED logic
From: Ananth N Mavinakayanahalli @ 2011-10-24 15:16 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Srikar Dronamraju, Peter Zijlstra, Ingo Molnar, Steven Rostedt,
	Linux-mm, Arnaldo Carvalho de Melo, Linus Torvalds,
	Jonathan Corbet, Masami Hiramatsu, Hugh Dickins,
	Christoph Hellwig, Thomas Gleixner, Andi Kleen, Andrew Morton,
	Jim Keniston, Roland McGrath, LKML
In-Reply-To: <20111024144127.GA14975@redhat.com>

On Mon, Oct 24, 2011 at 04:41:27PM +0200, Oleg Nesterov wrote:
> On 10/22, Ananth N Mavinakayanahalli wrote:
> >
> > On Wed, Oct 19, 2011 at 11:53:44PM +0200, Oleg Nesterov wrote:
> > > Finally, add UTASK_SSTEP_TRAPPED state/code to handle the case when
> > > xol insn itself triggers the signal.
> > >
> > > In this case we should restart the original insn even if the task is
> > > already SIGKILL'ed (say, the coredump should report the correct ip).
> > > This is even more important if the task has a handler for SIGSEGV/etc,
> > > The _same_ instruction should be repeated again after return from the
> > > signal handler, and SSTEP can never finish in this case.
> >
> > Oleg,
> >
> > Not sure I understand this completely...
> 
> I hope you do not think I do ;)

I think you understand it better than you think you do :-)

> > When you say 'correct ip' you mean the original vaddr where we now have
> > a uprobe breakpoint and not the xol copy, right?
> 
> Yes,
> 
> > Coredump needs to report the correct ip, but should it also not report
> > correctly the instruction that caused the signal? Ergo, shouldn't we
> > put the original instruction back at the uprobed vaddr?
> 
> OK, now I see what you mean. I was confused by the "restore the original
> instruction before _restart_" suggestion.
> 
> Agreed! it would be nice to "hide" these int3's if we dump the core, but
> I think this is a bit off-topic. It makes sense to do this in any case,
> even if the core-dumping was triggered by another thread/insn. It makes
> sense to remove all int3's, not only at regs->ip location. But how can
> we do this? This is nontrivial.

I don't think that is a problem.. see below...

> And. Even worse. Suppose that you do "gdb probed_application". Now you
> see int3's in the disassemble output. What can we do?

In this case, nothing.

> I think we can do nothing, at least currently. This just reflects the
> fact that uprobe connects to inode, not to process/mm/etc.
> 
> What do you think?

Thinking further on this, in the normal 'running gdb on a core' case, we
won't have this problem, as the binary that we point gdb to, will be a
pristine one, without the uprobe int3s, right?

Ananth


^ permalink raw reply

* [PATCH 3/3] mfd: Add S5M series configuration
From: Sangbeom Kim @ 2011-10-21 10:28 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319192894-19292-1-git-send-email-sbkim73@samsung.com>

This patch add S5M series configuration.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/Kconfig  |   12 ++++++++++++
 drivers/mfd/Makefile |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 21574bd..e280d2a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -386,6 +386,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_S5M_CORE
+	bool "SAMSUNG S5M Series Support"
+	depends on I2C=y && GENERIC_HARDIRQS
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  Say yes here to support for SAMSUNG S5M series.
+	  This is a Power Management IC.
+	  This driver provies common support for accessing the device,
+	  additional drivers must be enabled in order to use the functionality
+	  of the device
+
 config MFD_WM8400
 	tristate "Support Wolfson Microelectronics WM8400"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c580203..dfd05a2 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,3 +102,4 @@ obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
+obj-$(CONFIG_MFD_S5M_CORE)	+= s5m-core.o s5m-irq.o
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/3] mfd: Add S5M series configuration
From: Sangbeom Kim @ 2011-10-23  7:30 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319355002-12674-1-git-send-email-sbkim73@samsung.com>

This patch add S5M series configuration.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/Kconfig  |   12 ++++++++++++
 drivers/mfd/Makefile |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 21574bd..e280d2a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -386,6 +386,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_S5M_CORE
+	bool "SAMSUNG S5M Series Support"
+	depends on I2C=y && GENERIC_HARDIRQS
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  Say yes here to support for SAMSUNG S5M series.
+	  This is a Power Management IC.
+	  This driver provies common support for accessing the device,
+	  additional drivers must be enabled in order to use the functionality
+	  of the device
+
 config MFD_WM8400
 	tristate "Support Wolfson Microelectronics WM8400"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c580203..dfd05a2 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,3 +102,4 @@ obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
+obj-$(CONFIG_MFD_S5M_CORE)	+= s5m-core.o s5m-irq.o
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/3] mfd: S5M core driver initial release
From: Sangbeom Kim @ 2011-10-21 10:28 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie

Samsung has released various MFD series.
S5M8767 has pmic and rtc and battery charger.
S5M8763 has pmic, rtc, battery charger.
S5M8751 has pmic, codec, battery charger, backlight controller.
All devices are designed for mobile applications.
Sequencially, All driver will be posted.
This is initial version for MFD of S5M series.
The other driver will be submitted  separately.

Thanks,
Sangbeom.

^ permalink raw reply

* [PATCH 2/3] mfd: Add s5m series irq support
From: Sangbeom Kim @ 2011-10-23  7:30 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie, Sangbeom Kim
In-Reply-To: <1319355002-12674-1-git-send-email-sbkim73@samsung.com>

This patch support irq for s5m series.
Basically, S5M8767 and S5M8763 irq can be handled by this patch.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 drivers/mfd/s5m-irq.c |  486 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 486 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/s5m-irq.c

diff --git a/drivers/mfd/s5m-irq.c b/drivers/mfd/s5m-irq.c
new file mode 100644
index 0000000..6a4a71a
--- /dev/null
+++ b/drivers/mfd/s5m-irq.c
@@ -0,0 +1,486 @@
+/*
+ * s5m-irq.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+
+struct s5m_irq_data {
+	int reg;
+	int mask;
+};
+
+static struct s5m_irq_data s5m8767_irqs[] = {
+	[S5M8767_IRQ_PWRR] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWRR_MASK,
+	},
+	[S5M8767_IRQ_PWRF] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWRF_MASK,
+	},
+	[S5M8767_IRQ_PWR1S] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_PWR1S_MASK,
+	},
+	[S5M8767_IRQ_JIGR] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_JIGR_MASK,
+	},
+	[S5M8767_IRQ_JIGF] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_JIGF_MASK,
+	},
+	[S5M8767_IRQ_LOWBAT2] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_LOWBAT2_MASK,
+	},
+	[S5M8767_IRQ_LOWBAT1] = {
+		.reg = 2,
+		.mask = S5M8767_IRQ_LOWBAT1_MASK,
+	},
+	[S5M8767_IRQ_MRB] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_MRB_MASK,
+	},
+	[S5M8767_IRQ_DVSOK2] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK2_MASK,
+	},
+	[S5M8767_IRQ_DVSOK3] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK3_MASK,
+	},
+	[S5M8767_IRQ_DVSOK4] = {
+		.reg = 3,
+		.mask = S5M8767_IRQ_DVSOK4_MASK,
+	},
+	[S5M8767_IRQ_RTC60S] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTC60S_MASK,
+	},
+	[S5M8767_IRQ_RTCA1] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTCA1_MASK,
+	},
+	[S5M8767_IRQ_RTCA2] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTCA2_MASK,
+	},
+	[S5M8767_IRQ_SMPL] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_SMPL_MASK,
+	},
+	[S5M8767_IRQ_RTC1S] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_RTC1S_MASK,
+	},
+	[S5M8767_IRQ_WTSR] = {
+		.reg = 4,
+		.mask = S5M8767_IRQ_WTSR_MASK,
+	},
+};
+
+static struct s5m_irq_data s5m8763_irqs[] = {
+	[S5M8763_IRQ_VDCINF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_VDCINF_MASK,
+	},
+	[S5M8763_IRQ_VDCINR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_VDCINR_MASK,
+	},
+	[S5M8763_IRQ_JIGF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_JIGF_MASK,
+	},
+	[S5M8763_IRQ_JIGR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_JIGR_MASK,
+	},
+	[S5M8763_IRQ_PWRONF] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_PWRONF_MASK,
+	},
+	[S5M8763_IRQ_PWRONR] = {
+		.reg = 1,
+		.mask = S5M8763_IRQ_PWRONR_MASK,
+	},
+	[S5M8763_IRQ_WTSREVNT] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_WTSREVNT_MASK,
+	},
+	[S5M8763_IRQ_SMPLEVNT] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_SMPLEVNT_MASK,
+	},
+	[S5M8763_IRQ_ALARM1] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_ALARM1_MASK,
+	},
+	[S5M8763_IRQ_ALARM0] = {
+		.reg = 2,
+		.mask = S5M8763_IRQ_ALARM0_MASK,
+	},
+	[S5M8763_IRQ_ONKEY1S] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_ONKEY1S_MASK,
+	},
+	[S5M8763_IRQ_TOPOFFR] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_TOPOFFR_MASK,
+	},
+	[S5M8763_IRQ_VDCINOVPR] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_VDCINOVPR_MASK,
+	},
+	[S5M8763_IRQ_CHGRSTF] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_CHGRSTF_MASK,
+	},
+	[S5M8763_IRQ_DONER] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_DONER_MASK,
+	},
+	[S5M8763_IRQ_CHGFAULT] = {
+		.reg = 3,
+		.mask = S5M8763_IRQ_CHGFAULT_MASK,
+	},
+	[S5M8763_IRQ_LOBAT1] = {
+		.reg = 4,
+		.mask = S5M8763_IRQ_LOBAT1_MASK,
+	},
+	[S5M8763_IRQ_LOBAT2] = {
+		.reg = 4,
+		.mask = S5M8763_IRQ_LOBAT2_MASK,
+	},
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8767_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+	return &s5m8767_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8767_irq_lock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_sync_unlock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+		if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+			s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+			s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+					s5m87xx->irq_masks_cur[i]);
+		}
+	}
+
+	mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_unmask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8767_irq_mask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8767_irq_chip = {
+	.name = "s5m8767",
+	.irq_bus_lock = s5m8767_irq_lock,
+	.irq_bus_sync_unlock = s5m8767_irq_sync_unlock,
+	.irq_mask = s5m8767_irq_mask,
+	.irq_unmask = s5m8767_irq_unmask,
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8763_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+	return &s5m8763_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8763_irq_lock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_sync_unlock(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+		if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+			s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+			s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+					s5m87xx->irq_masks_cur[i]);
+		}
+	}
+
+	mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_unmask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8763_irq_mask(struct irq_data *data)
+{
+	struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+	struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+							       data->irq);
+
+	s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8763_irq_chip = {
+	.name = "s5m8763",
+	.irq_bus_lock = s5m8763_irq_lock,
+	.irq_bus_sync_unlock = s5m8763_irq_sync_unlock,
+	.irq_mask = s5m8763_irq_mask,
+	.irq_unmask = s5m8763_irq_unmask,
+};
+
+static irqreturn_t s5m8767_irq_thread(int irq, void *data)
+{
+	struct s5m87xx_dev *s5m87xx = data;
+	u8 irq_reg[NUM_IRQ_REGS-1];
+	int ret;
+	int i;
+
+	ret = s5m_bulk_read(s5m87xx, S5M8767_REG_INT1,
+				NUM_IRQ_REGS - 1, irq_reg);
+	if (ret < 0) {
+		dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+				ret);
+		return IRQ_NONE;
+	}
+
+	for (i = 0; i < NUM_IRQ_REGS - 1; i++)
+		irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+	for (i = 0; i < S5M8767_IRQ_NR; i++) {
+		if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask)
+			handle_nested_irq(s5m87xx->irq_base + i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t s5m8763_irq_thread(int irq, void *data)
+{
+	struct s5m87xx_dev *s5m87xx = data;
+	u8 irq_reg[NUM_IRQ_REGS];
+	int ret;
+	int i;
+
+	ret = s5m_bulk_read(s5m87xx, S5M8763_REG_IRQ1,
+				NUM_IRQ_REGS, irq_reg);
+	if (ret < 0) {
+		dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+				ret);
+		return IRQ_NONE;
+	}
+
+	for (i = 0; i < NUM_IRQ_REGS; i++)
+		irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+	for (i = 0; i < S5M8763_IRQ_NR; i++) {
+		if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask)
+			handle_nested_irq(s5m87xx->irq_base + i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx)
+{
+	if (s5m87xx->irq && s5m87xx->irq_base){
+		switch (s5m87xx->device_type) {
+		case S5M8763X:
+			s5m8763_irq_thread(s5m87xx->irq_base, s5m87xx);
+			break;
+		case S5M8767X:
+			s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx);
+			break;
+		default:
+			break;
+
+		}
+	}
+	return 0;
+}
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
+{
+	int i;
+	int cur_irq;
+	int ret = 0;
+	int type = s5m87xx->device_type;
+
+	if (!s5m87xx->irq) {
+		dev_warn(s5m87xx->dev,
+			 "No interrupt specified, no interrupts\n");
+		s5m87xx->irq_base = 0;
+		return 0;
+	}
+
+	if (!s5m87xx->irq_base) {
+		dev_err(s5m87xx->dev,
+			"No interrupt base specified, no interrupts\n");
+		return 0;
+	}
+
+	mutex_init(&s5m87xx->irqlock);
+
+	switch (type) {
+	case S5M8763X:
+		for (i = 0; i < NUM_IRQ_REGS; i++) {
+			s5m87xx->irq_masks_cur[i] = 0xff;
+			s5m87xx->irq_masks_cache[i] = 0xff;
+			s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+						0xff);
+		}
+
+		s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM1, 0xff);
+		s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM2, 0xff);
+
+		for (i = 0; i < S5M8763_IRQ_NR; i++) {
+			cur_irq = i + s5m87xx->irq_base;
+			irq_set_chip_data(cur_irq, s5m87xx);
+			irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip,
+						 handle_edge_irq);
+			irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+			set_irq_flags(cur_irq, IRQF_VALID);
+#else
+			irq_set_noprobe(cur_irq);
+#endif
+		}
+
+		ret = request_threaded_irq(s5m87xx->irq, NULL,
+					s5m8763_irq_thread,
+					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					"s5m87xx-irq", s5m87xx);
+		if (ret) {
+			dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+				s5m87xx->irq, ret);
+			return ret;
+		}
+		break;
+	case S5M8767X:
+		for (i = 0; i < NUM_IRQ_REGS - 1; i++) {
+			s5m87xx->irq_masks_cur[i] = 0xff;
+			s5m87xx->irq_masks_cache[i] = 0xff;
+			s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+						0xff);
+		}
+
+		for (i = 0; i < S5M8767_IRQ_NR; i++) {
+			cur_irq = i + s5m87xx->irq_base;
+			irq_set_chip_data(cur_irq, s5m87xx);
+			if (ret) {
+				dev_err(s5m87xx->dev,
+					"Failed to irq_set_chip_data %d: %d\n",
+					s5m87xx->irq, ret);
+				return ret;
+			}
+
+			irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip,
+						 handle_edge_irq);
+			irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+			set_irq_flags(cur_irq, IRQF_VALID);
+#else
+			irq_set_noprobe(cur_irq);
+#endif
+		}
+
+		ret = request_threaded_irq(s5m87xx->irq, NULL,
+					   s5m8767_irq_thread,
+					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					   "s5m87xx-irq", s5m87xx);
+		if (ret) {
+			dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+				s5m87xx->irq, ret);
+			return ret;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (!s5m87xx->ono)
+		return 0;
+
+	switch (type) {
+	case S5M8763X:
+		ret = request_threaded_irq(s5m87xx->ono, NULL,
+						s5m8763_irq_thread,
+						IRQF_TRIGGER_FALLING |
+						IRQF_TRIGGER_RISING |
+						IRQF_ONESHOT, "s5m87xx-ono",
+						s5m87xx);
+		break;
+	case S5M8767X:
+		ret = request_threaded_irq(s5m87xx->ono, NULL,
+					s5m8767_irq_thread,
+					IRQF_TRIGGER_FALLING |
+					IRQF_TRIGGER_RISING |
+					IRQF_ONESHOT, "s5m87xx-ono", s5m87xx);
+		break;
+	default:
+		break;
+	}
+
+	if (ret)
+		dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+			s5m87xx->ono, ret);
+
+	return 0;
+}
+
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx)
+{
+	if (s5m87xx->ono)
+		free_irq(s5m87xx->ono, s5m87xx);
+
+	if (s5m87xx->irq)
+		free_irq(s5m87xx->irq, s5m87xx);
+}
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/3] mfd: S5M series initial release
From: Sangbeom Kim @ 2011-10-23  7:29 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, broonie

Samsung is developing various multi function devices.
Currently, 3 devices are announced by samsung.
S5M8767 has pmic and rtc and battery charger.
S5M8763 has pmic, rtc, Li-ion battery charger
S5M8751 has pmic, codec, battery charger, backlight controller.
All devices are designed for mobile applications.
Sequencially, All driver will be posted.
This is initial version for MFD of S5M series.
The other driver will be submitted  separately.

[PATCH 1/3] mfd: Add S5M core driver
[PATCH 2/3] mfd: Add s5m series irq support
[PATCH 3/3] mfd: Add S5M series configuration

^ permalink raw reply

* [PATCH V5 1/3] SDHCI: S3C: Use generic clock names for sdhci bus clock options
From: Kukjin Kim @ 2011-10-24 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318588126-19167-2-git-send-email-rajeshwari.s@samsung.com>

On 10/14/11 12:28, Rajeshwari Shinde wrote:
> This patch modifies the driver to stop depending on the clock names
> being passed from the platform and switch over to bus clock lookup
> using generic clock names.
>
> Signed-off-by: Rajeshwari Shinde<rajeshwari.s@samsung.com>
> ---
>   drivers/mmc/host/sdhci-s3c.c |    6 ++----
>   1 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> index 82709b6..a5fde87 100644
> --- a/drivers/mmc/host/sdhci-s3c.c
> +++ b/drivers/mmc/host/sdhci-s3c.c
> @@ -435,14 +435,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>
>   	for (clks = 0, ptr = 0; ptr<  MAX_BUS_CLK; ptr++) {
>   		struct clk *clk;
> -		char *name = pdata->clocks[ptr];
> +		char name[14];
>
> -		if (name == NULL)
> -			continue;
> +		sprintf(name, "mmc_busclk.%d", ptr);
>
>   		clk = clk_get(dev, name);
>   		if (IS_ERR(clk)) {
> -			dev_err(dev, "failed to get clock %s\n", name);
>   			continue;
>   		}
>

Looks ok for me.

Chris, if you're ok on this, could you please add this in your tree for 
this merge window? or if you want, I will apply this to Samsung tree 
with other Rajeshwari's patches. I'm ok either...

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* Re: [PATCH V5 1/3] SDHCI: S3C: Use generic clock names for sdhci bus clock options
From: Kukjin Kim @ 2011-10-24 15:16 UTC (permalink / raw)
  To: Rajeshwari Shinde
  Cc: kgene.kim, linux-samsung-soc, linux-mmc, cjb, linux-arm-kernel
In-Reply-To: <1318588126-19167-2-git-send-email-rajeshwari.s@samsung.com>

On 10/14/11 12:28, Rajeshwari Shinde wrote:
> This patch modifies the driver to stop depending on the clock names
> being passed from the platform and switch over to bus clock lookup
> using generic clock names.
>
> Signed-off-by: Rajeshwari Shinde<rajeshwari.s@samsung.com>
> ---
>   drivers/mmc/host/sdhci-s3c.c |    6 ++----
>   1 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> index 82709b6..a5fde87 100644
> --- a/drivers/mmc/host/sdhci-s3c.c
> +++ b/drivers/mmc/host/sdhci-s3c.c
> @@ -435,14 +435,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>
>   	for (clks = 0, ptr = 0; ptr<  MAX_BUS_CLK; ptr++) {
>   		struct clk *clk;
> -		char *name = pdata->clocks[ptr];
> +		char name[14];
>
> -		if (name == NULL)
> -			continue;
> +		sprintf(name, "mmc_busclk.%d", ptr);
>
>   		clk = clk_get(dev, name);
>   		if (IS_ERR(clk)) {
> -			dev_err(dev, "failed to get clock %s\n", name);
>   			continue;
>   		}
>

Looks ok for me.

Chris, if you're ok on this, could you please add this in your tree for 
this merge window? or if you want, I will apply this to Samsung tree 
with other Rajeshwari's patches. I'm ok either...

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* Re: [PATCH 07/10] RDMA/cxgb4: DB Drop Recovery for RDMA and LLD queues.
From: Vipul Pandya @ 2011-10-24 15:16 UTC (permalink / raw)
  To: David Miller
  Cc: swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW,
	roland-BHEL68pLQRGGvPXPguhicg, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, divy-ut6Up61K2wZBDgjK7y7TUQ,
	dm-ut6Up61K2wZBDgjK7y7TUQ, kumaras-ut6Up61K2wZBDgjK7y7TUQ
In-Reply-To: <20111020.165703.1713724038045504243.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>



On 21-10-2011 02:27, David Miller wrote:

> From: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
> Date: Thu, 20 Oct 2011 12:28:07 -0500
> 
>> On 10/20/2011 12:17 PM, Roland Dreier wrote:
>>>> I believe 5 and 7 have build dependencies.
>>> Right, missed that one too.
>>>
>>> But it seems 4,6,8,9,10 are independent of the rest of the series?
>>>
>>> ie I can trivially apply them and then worry about working out
>>> the drivers/net / drivers/infiniband interdependency a bit later?
>>>
>>
>> Some of these might be dependent on prior patches the series.  But if
>> they aren't, yes, you could do that.
> 
> So, how do you guys want to do this?  If you give me a list of which
> patches I should put into net-next and leave the rest to the infiniband
> tree, that'd work fine for me as long as net-next is left in a working
> state independent of the infiniband tree.


Hi Dave Miller/Roland,

With respect to above dependencies we did some experiments and found
following things

1. We can apply three cxgb4 patches, 01 02 and 03, on net-next tree
successfully and build it.

2. Out of 7 RDMA/cxgb4 patches only 04, 08 and 10 can be applied
trivially and driver can be built successfully. If we try to apply
remaining patches, 05 06 07 and 09, either they will fail to apply or
give build failure. Moreover patches 05, 06, 07 and 09 can be applied on
top of 04, 08 and 10 cleanly.

Based on above results we would like to propose following two things.

1. We would like to recommend that all the patches get included in
Roland's infiniband tree since it has build dependencies.

2. Alternatively,
- Patches 01, 02 and 03 can be included in net-next tree.
- Patches 04, 08 and 10 can be included in Roland's infiniband tree at
present.
- Patches 05, 06, 07 and 09 have to wait till the net-next hits the
3.2-rc1.

Please let us know if you have any other suggestions.

Thanks,
Vipul
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: kdump: crash_kexec()-smp_send_stop() race in panic
From: Eric W. Biederman @ 2011-10-24 15:14 UTC (permalink / raw)
  To: holzheu; +Cc: heiko.carstens, kexec, linux-kernel, schwidefsky, akpm,
	Vivek Goyal
In-Reply-To: <1319468137.3615.16.camel@br98xy6r>

Michael Holzheu <holzheu@linux.vnet.ibm.com> writes:

> Hello Vivek,
>
> In our tests we ran into the following scenario:
>
> Two CPUs have called panic at the same time. The first CPU called
> crash_kexec() and the second CPU called smp_send_stop() in panic()
> before crash_kexec() finished on the first CPU. So the second CPU
> stopped the first CPU and therefore kdump failed.
>
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
>
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop CPU 1 (stop kdump)
>
> How should we fix this problem? One possibility could be to do
> smp_send_stop() before we call crash_kexec().
>
> What do you think?

smp_send_stop is insufficiently reliable to be used before crash_kexec.

My first reaction would be to test oops_in_progress and wait until
oops_in_progress == 1 before calling smp_send_stop.

Eric

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply

* Re: [PATCH] usb: fix unaligned access
From: Antony Pavlov @ 2011-10-24 15:14 UTC (permalink / raw)
  To: Fabian van der Werf; +Cc: barebox
In-Reply-To: <CAJeSw6Be=2jNOw1SSz1xB-7bXL9RyrUuLz+yWcZvxfNap6RkwQ@mail.gmail.com>

On 23 October 2011 13:29, Fabian van der Werf <fvanderwerf@gmail.com> wrote:
>>
>> Looks like a valid patch, I wonder that this never was a problem before.
>> ARM should break here aswell I think. What architecture are you using?
>>
>
> I am working with a pandaboard (arm cortex a9). The pandaboard has a
> usb ethernet controller, so I need usb to boot over tftp. I guess that
> most arm configurations don't need usb for booting, and in that case
> you won't run into this problem.

I have DUB-E100 USB Ethernet (ID 2001:3c05) connected to Toshiba AC100
(NVidia Tegra2 --- Cortex A9); tftp works fine without usb unaligned
access patch.

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply

* [PATCHES] dm-crypt parallelization
From: Mikulas Patocka @ 2011-10-24 15:14 UTC (permalink / raw)
  To: Alasdair G. Kergon, Milan Broz; +Cc: dm-devel

Hi

Here are patches for dm-crypt parallelization: 
http://people.redhat.com/mpatocka/patches/kernel/dm-crypt-paralelizace/

For each cpu, we create a kernel thread bound to that cpu. There is a 
global queue with sectors to be encrypted. We add requests to the queue 
and wake the per-cpu-threads. The threads pop requests from the queue and 
process them.

Mikulas

^ permalink raw reply

* Re: [PATCH] sparse, llvm: Fix 'void *' pointer code generation
From: Jeff Garzik @ 2011-10-24 15:13 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Jonathan Neuschäfer, Linus Torvalds, Pekka Enberg,
	linux-sparse, Christopher Li, Jeff Garzik
In-Reply-To: <alpine.LFD.2.02.1110241532340.14239@tux.localdomain>

On 10/24/2011 08:33 AM, Pekka Enberg wrote:
>> On Mon, Oct 24, 2011 at 02:56:41PM +0300, Pekka Enberg wrote:
>>> Fix the issue by switching to LLVMIntType(bits_per_pointer) in
>>> sym_basetype_type().
>
> On Mon, 24 Oct 2011, Jonathan Neuschäfer wrote:
>> You didn't update the commit message.
>
> Thanks for pointing that out. Jeff, does this look OK?

I don't know what bit_size==-1 means off the top of my head, so I assume 
yes ;-)

	Jeff




--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: kdump: crash_kexec()-smp_send_stop() race in panic
From: Eric W. Biederman @ 2011-10-24 15:14 UTC (permalink / raw)
  To: holzheu; +Cc: Vivek Goyal, akpm, schwidefsky, heiko.carstens, kexec,
	linux-kernel
In-Reply-To: <1319468137.3615.16.camel@br98xy6r>

Michael Holzheu <holzheu@linux.vnet.ibm.com> writes:

> Hello Vivek,
>
> In our tests we ran into the following scenario:
>
> Two CPUs have called panic at the same time. The first CPU called
> crash_kexec() and the second CPU called smp_send_stop() in panic()
> before crash_kexec() finished on the first CPU. So the second CPU
> stopped the first CPU and therefore kdump failed.
>
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
>
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop CPU 1 (stop kdump)
>
> How should we fix this problem? One possibility could be to do
> smp_send_stop() before we call crash_kexec().
>
> What do you think?

smp_send_stop is insufficiently reliable to be used before crash_kexec.

My first reaction would be to test oops_in_progress and wait until
oops_in_progress == 1 before calling smp_send_stop.

Eric

^ permalink raw reply

* Re: [Qemu-devel] [PATCH 1/5] monitor: screen_dump async
From: Gerd Hoffmann @ 2011-10-24 15:13 UTC (permalink / raw)
  To: Alon Levy; +Cc: qemu-devel, mlureau, armbru, lcapitulino
In-Reply-To: <1319457739-14562-2-git-send-email-alevy@redhat.com>

On 10/24/11 14:02, Alon Levy wrote:
> Make screen_dump monitor command an async command to allow next for qxl
> to implement it as a initiating call to red_worker and completion on
> callback, to fix a deadlock when issueing a screendump command via
> libvirt while connected with a libvirt controlled spice-gtk client.

Approach looks reasonable to me.  Patch breaks the build though, you've
missed a bunch of screen_dump functions in non-x86 targets.

cheers,
  Gerd

^ permalink raw reply

* Re: [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines
From: Pierre Riteau @ 2011-10-24 15:12 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Kevin Wolf, qemu-devel
In-Reply-To: <1318610959-17971-16-git-send-email-kwolf@redhat.com>

This commit (1c9805a398cc1125b4defa6367172c8c2c0bca9f in Git) breaks qemu-nbd for me. I cannot mount any VM image (raw or qcow2 format) with this commit or today's HEAD. Previous commit c5fbe57111ef59c315a71cd80e8b0af59e36ff21 works fine.

The qemu-nbd process hangs while reading disk:

31175 ?        Ss     0:00 qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw
31176 ?        S      0:00  \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw
31177 ?        D      0:00  \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw

In dmesg I see only:

[18304.541058]  nbd0:

Then, if I pkill -9 nbd, dmesg gets more verbose:

[18467.288183] nbd (pid 31175: qemu-nbd) got signal 9
[18467.303175] nbd0: shutting down socket
[18467.314446] nbd0: Receive control failed (result -4)
[18467.329354] end_request: I/O error, dev nbd0, sector 0
[18467.344771] __ratelimit: 38 callbacks suppressed
[18467.358620] Buffer I/O error on device nbd0, logical block 0
[18467.375591] Buffer I/O error on device nbd0, logical block 1
[18467.392560] Buffer I/O error on device nbd0, logical block 2
[18467.409530] Buffer I/O error on device nbd0, logical block 3
[18467.426508] nbd0: queue cleared
[18467.435962] nbd0: Attempted send on closed socket
[18467.450095] end_request: I/O error, dev nbd0, sector 0
[18467.465527] Buffer I/O error on device nbd0, logical block 0
[18467.482496] Buffer I/O error on device nbd0, logical block 1
[18467.499464] Buffer I/O error on device nbd0, logical block 2
[18467.516433] Buffer I/O error on device nbd0, logical block 3
[18467.533418] nbd0: Attempted send on closed socket
[18467.547539] end_request: I/O error, dev nbd0, sector 0
[18467.562945] Buffer I/O error on device nbd0, logical block 0
[18467.579917] Buffer I/O error on device nbd0, logical block 1
[18467.596897] nbd0: Attempted send on closed socket
[18467.611022] end_request: I/O error, dev nbd0, sector 0
[18467.626442] nbd0: Attempted send on closed socket
[18467.640569] end_request: I/O error, dev nbd0, sector 0
[18467.655984] ldm_validate_partition_table(): Disk read failed.
[18467.673242] nbd0: Attempted send on closed socket
[18467.687369] end_request: I/O error, dev nbd0, sector 0
[18467.702788] nbd0: Attempted send on closed socket
[18467.716915] end_request: I/O error, dev nbd0, sector 0
[18467.732359] nbd0: Attempted send on closed socket
[18467.746487] end_request: I/O error, dev nbd0, sector 0
[18467.761931] nbd0: Attempted send on closed socket
[18467.776058] end_request: I/O error, dev nbd0, sector 0
[18467.791473] Dev nbd0: unable to read RDB block 0
[18467.805348] nbd0: Attempted send on closed socket
[18467.819479] end_request: I/O error, dev nbd0, sector 0
[18467.834897] nbd0: Attempted send on closed socket
[18467.849025] end_request: I/O error, dev nbd0, sector 0
[18467.864446] nbd0: Attempted send on closed socket
[18467.878572] end_request: I/O error, dev nbd0, sector 0
[18467.893985]  unable to read partition table

-- 
Pierre Riteau -- PhD student, Myriads team, IRISA, Rennes, France
http://perso.univ-rennes1.fr/pierre.riteau/

On 14 oct. 2011, at 18:49, Kevin Wolf wrote:

> From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> 
> The bdrv_read()/bdrv_write() functions call .bdrv_read()/.bdrv_write().
> They should go through bdrv_co_do_readv() and bdrv_co_do_writev()
> instead in order to unify request processing code across sync, aio, and
> coroutine interfaces.  This is also an important step towards removing
> BlockDriverState .bdrv_read()/.bdrv_write() in the future.
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
> block.c |  112 +++++++++++++++++++++++++++++++++++----------------------------
> 1 files changed, 62 insertions(+), 50 deletions(-)
> 
> diff --git a/block.c b/block.c
> index f4731ec..ae8fc80 100644
> --- a/block.c
> +++ b/block.c
> @@ -44,6 +44,8 @@
> #include <windows.h>
> #endif
> 
> +#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
> +
> static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
> static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
>         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
> @@ -74,6 +76,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
> static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
> static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
>     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
> +static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
> +    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
> 
> static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
>     QTAILQ_HEAD_INITIALIZER(bdrv_states);
> @@ -1042,30 +1046,69 @@ static inline bool bdrv_has_async_flush(BlockDriver *drv)
>     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
> }
> 
> -/* return < 0 if error. See bdrv_write() for the return codes */
> -int bdrv_read(BlockDriverState *bs, int64_t sector_num,
> -              uint8_t *buf, int nb_sectors)
> +typedef struct RwCo {
> +    BlockDriverState *bs;
> +    int64_t sector_num;
> +    int nb_sectors;
> +    QEMUIOVector *qiov;
> +    bool is_write;
> +    int ret;
> +} RwCo;
> +
> +static void coroutine_fn bdrv_rw_co_entry(void *opaque)
> {
> -    BlockDriver *drv = bs->drv;
> +    RwCo *rwco = opaque;
> 
> -    if (!drv)
> -        return -ENOMEDIUM;
> +    if (!rwco->is_write) {
> +        rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
> +                                     rwco->nb_sectors, rwco->qiov);
> +    } else {
> +        rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
> +                                      rwco->nb_sectors, rwco->qiov);
> +    }
> +}
> 
> -    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
> -        QEMUIOVector qiov;
> -        struct iovec iov = {
> -            .iov_base = (void *)buf,
> -            .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
> -        };
> +/*
> + * Process a synchronous request using coroutines
> + */
> +static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
> +                      int nb_sectors, bool is_write)
> +{
> +    QEMUIOVector qiov;
> +    struct iovec iov = {
> +        .iov_base = (void *)buf,
> +        .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
> +    };
> +    Coroutine *co;
> +    RwCo rwco = {
> +        .bs = bs,
> +        .sector_num = sector_num,
> +        .nb_sectors = nb_sectors,
> +        .qiov = &qiov,
> +        .is_write = is_write,
> +        .ret = NOT_DONE,
> +    };
> 
> -        qemu_iovec_init_external(&qiov, &iov, 1);
> -        return bdrv_co_readv(bs, sector_num, nb_sectors, &qiov);
> -    }
> +    qemu_iovec_init_external(&qiov, &iov, 1);
> 
> -    if (bdrv_check_request(bs, sector_num, nb_sectors))
> -        return -EIO;
> +    if (qemu_in_coroutine()) {
> +        /* Fast-path if already in coroutine context */
> +        bdrv_rw_co_entry(&rwco);
> +    } else {
> +        co = qemu_coroutine_create(bdrv_rw_co_entry);
> +        qemu_coroutine_enter(co, &rwco);
> +        while (rwco.ret == NOT_DONE) {
> +            qemu_aio_wait();
> +        }
> +    }
> +    return rwco.ret;
> +}
> 
> -    return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
> +/* return < 0 if error. See bdrv_write() for the return codes */
> +int bdrv_read(BlockDriverState *bs, int64_t sector_num,
> +              uint8_t *buf, int nb_sectors)
> +{
> +    return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
> }
> 
> static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
> @@ -1105,36 +1148,7 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
> int bdrv_write(BlockDriverState *bs, int64_t sector_num,
>                const uint8_t *buf, int nb_sectors)
> {
> -    BlockDriver *drv = bs->drv;
> -
> -    if (!bs->drv)
> -        return -ENOMEDIUM;
> -
> -    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
> -        QEMUIOVector qiov;
> -        struct iovec iov = {
> -            .iov_base = (void *)buf,
> -            .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
> -        };
> -
> -        qemu_iovec_init_external(&qiov, &iov, 1);
> -        return bdrv_co_writev(bs, sector_num, nb_sectors, &qiov);
> -    }
> -
> -    if (bs->read_only)
> -        return -EACCES;
> -    if (bdrv_check_request(bs, sector_num, nb_sectors))
> -        return -EIO;
> -
> -    if (bs->dirty_bitmap) {
> -        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
> -    }
> -
> -    if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
> -        bs->wr_highest_sector = sector_num + nb_sectors - 1;
> -    }
> -
> -    return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
> +    return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
> }
> 
> int bdrv_pread(BlockDriverState *bs, int64_t offset,
> @@ -2912,8 +2926,6 @@ static void bdrv_rw_em_cb(void *opaque, int ret)
>     *(int *)opaque = ret;
> }
> 
> -#define NOT_DONE 0x7fffffff
> -
> static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
>                         uint8_t *buf, int nb_sectors)
> {
> -- 
> 1.7.6.4
> 
> 

^ permalink raw reply

* Re: [PATCH V2 09/11] libxl_json, Handle number abrove LONG_MAX.
From: Anthony PERARD @ 2011-10-24 15:12 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Xen Devel, Stefano Stabellini
In-Reply-To: <1319450257.3385.175.camel@zakaz.uk.xensource.com>

On Mon, Oct 24, 2011 at 10:57, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> On Thu, 2011-10-20 at 18:59 +0100, Anthony PERARD wrote:
>> The integers are now "long long" in the json_object. If strtoll failed to
>> convert a string into a number, the number is stored as it (a char*).
>>
>> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
>> ---
>>  tools/libxl/libxl_internal.h |    7 +++--
>>  tools/libxl/libxl_json.c     |   52 +++++++++++++++++++++++------------------
>>  2 files changed, 33 insertions(+), 26 deletions(-)
>>
>> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
>> index 5720b31..849b251 100644
>> --- a/tools/libxl/libxl_internal.h
>> +++ b/tools/libxl/libxl_internal.h
>> @@ -465,7 +465,8 @@ typedef enum {
>>      JSON_TRUE,
>>      JSON_FALSE,
>>      JSON_INTEGER,
>> -    JSON_DOUBLE,
>
> Did you accidentally remove this ...
>
>> +    /* number is store in string, it's too big to be a long long */
>> +    JSON_NUMBER,
>>      JSON_STRING,
>>      JSON_MAP,
>>      JSON_ARRAY,
>> @@ -475,7 +476,7 @@ typedef enum {
>>  typedef struct libxl__json_object {
>>      libxl__json_node_type type;
>>      union {
>> -        long i;
>> +        long long i;
>>          double d;
>
> ... or accidentally leave this?

I've accidentally leave this double, because I do not handle float
number as I do'nt need them yet. But I probably should parse them as
well, and keep double in the structure.

>>          char *string;
>>          /* List of libxl__json_object */
>> @@ -534,7 +535,7 @@ flexarray_t *libxl__json_object_get_array(const libxl__json_object *o)
>>      else
>>          return NULL;
>>  }
>> -static inline long libxl__json_object_get_integer(const libxl__json_object *o)
>> +static inline long long libxl__json_object_get_integer(const libxl__json_object *o)
>>  {
>>      if (libxl__json_object_is_integer(o))
>>          return o->u.i;
>> diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
>> index c743114..2d8f61e 100644
>> --- a/tools/libxl/libxl_json.c
>> +++ b/tools/libxl/libxl_json.c
>> @@ -44,6 +44,7 @@ struct libxl__yajl_ctx {
>>  #  define DEBUG_GEN(ctx, type)              yajl_gen_##type(ctx->g)
>>  #  define DEBUG_GEN_VALUE(ctx, type, value) yajl_gen_##type(ctx->g, value)
>>  #  define DEBUG_GEN_STRING(ctx, str, n)     yajl_gen_string(ctx->g, str, n)
>> +#  define DEBUG_GEN_NUMBER(ctx, str, n)     yajl_gen_number(ctx->g, str, n)
>>  #  define DEBUG_GEN_REPORT(yajl_ctx) \
>>      do { \
>>          const unsigned char *buf = NULL; \
>> @@ -60,6 +61,7 @@ struct libxl__yajl_ctx {
>>  #  define DEBUG_GEN(ctx, type)                  ((void)0)
>>  #  define DEBUG_GEN_VALUE(ctx, type, value)     ((void)0)
>>  #  define DEBUG_GEN_STRING(ctx, value, lenght)  ((void)0)
>> +#  define DEBUG_GEN_NUMBER(ctx, value, lenght)  ((void)0)
>
> that typo got propagated...
>
>>  #  define DEBUG_GEN_REPORT(ctx)                 ((void)0)
>>  #endif
>>
>> @@ -363,6 +365,7 @@ void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj)
>>          return;
>>      switch (obj->type) {
>>      case JSON_STRING:
>> +    case JSON_NUMBER:
>>          free(obj->u.string);
>>          break;
>>      case JSON_MAP: {
>> @@ -504,35 +507,38 @@ static int json_callback_boolean(void *opaque, int boolean)
>>      return 1;
>>  }
>>
>> -static int json_callback_integer(void *opaque, long value)
>> +static int json_callback_number(void *opaque, const char *s, unsigned int len)
>>  {
>>      libxl__yajl_ctx *ctx = opaque;
>> -    libxl__json_object *obj;
>> -
>> -    DEBUG_GEN_VALUE(ctx, integer, value);
>> +    libxl__json_object *obj = NULL;
>> +    long long i;
>>
>> -    if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
>> -        return 0;
>> -    obj->u.i = value;
>> +    /* should be replace by number */
>> +    DEBUG_GEN_NUMBER(ctx, s, len);
>>
>> -    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
>> -        libxl__json_object_free(ctx->gc, obj);
>> -        return 0;
>> -    }
>> +    i = strtoll(s, NULL, 10);
>>
>> -    return 1;
>> -}
>> +    if ((i == LLONG_MIN || i == LLONG_MAX) && errno == ERANGE) {
>> +        char *t = NULL;
>>
>> -static int json_callback_double(void *opaque, double value)
>> -{
>> -    libxl__yajl_ctx *ctx = opaque;
>> -    libxl__json_object *obj;
>> +        if ((obj = json_object_alloc(ctx->gc, JSON_NUMBER)) == NULL)
>> +            return 0;
>>
>> -    DEBUG_GEN_VALUE(ctx, double, value);
>> +        t = malloc(len + 1);
>> +        if (t == NULL) {
>> +            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
>> +                             "Failed to allocate");
>> +            return 0;
>> +        }
>> +        strncpy(t, s, len);
>> +        t[len] = 0;
>>
>> -    if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL)
>> -        return 0;
>> -    obj->u.d = value;
>> +        obj->u.string = t;
>> +    } else {
>> +        if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
>> +            return 0;
>> +        obj->u.i = i;
>> +    }
>>
>>      if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
>>          libxl__json_object_free(ctx->gc, obj);
>> @@ -706,9 +712,9 @@ static int json_callback_end_array(void *opaque)
>>  static yajl_callbacks callbacks = {
>>      json_callback_null,
>>      json_callback_boolean,
>> -    json_callback_integer,
>> -    json_callback_double,
>>      NULL,
>> +    NULL,
>> +    json_callback_number,
>>      json_callback_string,
>>      json_callback_start_map,
>>      json_callback_map_key,
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>



-- 
Anthony PERARD

^ permalink raw reply

* [PATCH V2 05/10] RDMA/cxgb4: Add DB Overflow Avoidance.
From: Vipul Pandya @ 2011-10-24 15:12 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: roland-BHEL68pLQRGGvPXPguhicg, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	divy-ut6Up61K2wZBDgjK7y7TUQ, dm-ut6Up61K2wZBDgjK7y7TUQ,
	kumaras-ut6Up61K2wZBDgjK7y7TUQ,
	swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW, Vipul Pandya

        - get FULL/EMPTY/DROP events from LLD

        - on FULL event, disable normal user mode DB rings.

        - add modify_qp semantics to allow user processes to call into
        the kernel to ring doobells without overflowing.

        Add DB Full/Empty/Drop stats.

        Mark queues when created indicating the doorbell state.

        If we're in the middle of db overflow avoidance, then newly created
        queues should start out in this mode.

        Bump the C4IW_UVERBS_ABI_VERSION to 2 so the user mode library can
        know if the driver supports the kernel mode db ringing.

Signed-off-by: Vipul Pandya <vipul-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
---
V2: Bump C4IW_UVERBS_ABI_VERSION to 2

 drivers/infiniband/hw/cxgb4/device.c   |   84 +++++++++++++++++++++++++++++--
 drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   37 ++++++++++++--
 drivers/infiniband/hw/cxgb4/qp.c       |   51 +++++++++++++++++++-
 drivers/infiniband/hw/cxgb4/user.h     |    2 +-
 4 files changed, 162 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 8483111..9062ed9 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -44,6 +44,12 @@ MODULE_DESCRIPTION("Chelsio T4 RDMA Driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
 
+struct uld_ctx {
+	struct list_head entry;
+	struct cxgb4_lld_info lldi;
+	struct c4iw_dev *dev;
+};
+
 static LIST_HEAD(uld_ctx_list);
 static DEFINE_MUTEX(dev_mutex);
 
@@ -263,6 +269,9 @@ static int stats_show(struct seq_file *seq, void *v)
 	seq_printf(seq, "  OCQPMEM: %10llu %10llu %10llu\n",
 			dev->rdev.stats.ocqp.total, dev->rdev.stats.ocqp.cur,
 			dev->rdev.stats.ocqp.max);
+	seq_printf(seq, "  DB FULL: %10llu\n", dev->rdev.stats.db_full);
+	seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty);
+	seq_printf(seq, "  DB DROP: %10llu\n", dev->rdev.stats.db_drop);
 	return 0;
 }
 
@@ -283,6 +292,9 @@ static ssize_t stats_clear(struct file *file, const char __user *buf,
 	dev->rdev.stats.pbl.max = 0;
 	dev->rdev.stats.rqt.max = 0;
 	dev->rdev.stats.ocqp.max = 0;
+	dev->rdev.stats.db_full = 0;
+	dev->rdev.stats.db_empty = 0;
+	dev->rdev.stats.db_drop = 0;
 	mutex_unlock(&dev->rdev.stats.lock);
 	return count;
 }
@@ -443,12 +455,6 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev)
 	c4iw_destroy_resource(&rdev->resource);
 }
 
-struct uld_ctx {
-	struct list_head entry;
-	struct cxgb4_lld_info lldi;
-	struct c4iw_dev *dev;
-};
-
 static void c4iw_dealloc(struct uld_ctx *ctx)
 {
 	c4iw_rdev_close(&ctx->dev->rdev);
@@ -514,6 +520,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
 	idr_init(&devp->mmidr);
 	spin_lock_init(&devp->lock);
 	mutex_init(&devp->rdev.stats.lock);
+	mutex_init(&devp->db_mutex);
 
 	if (c4iw_debugfs_root) {
 		devp->debugfs_root = debugfs_create_dir(
@@ -659,11 +666,76 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
 	return 0;
 }
 
+static int disable_qp_db(int id, void *p, void *data)
+{
+	struct c4iw_qp *qp = p;
+
+	t4_disable_wq_db(&qp->wq);
+	return 0;
+}
+
+static void stop_queues(struct uld_ctx *ctx)
+{
+	spin_lock_irq(&ctx->dev->lock);
+	ctx->dev->db_state = FLOW_CONTROL;
+	idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL);
+	spin_unlock_irq(&ctx->dev->lock);
+}
+
+static int enable_qp_db(int id, void *p, void *data)
+{
+	struct c4iw_qp *qp = p;
+
+	t4_enable_wq_db(&qp->wq);
+	return 0;
+}
+
+static void resume_queues(struct uld_ctx *ctx)
+{
+	spin_lock_irq(&ctx->dev->lock);
+	ctx->dev->db_state = NORMAL;
+	idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL);
+	spin_unlock_irq(&ctx->dev->lock);
+}
+
+static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...)
+{
+	struct uld_ctx *ctx = handle;
+
+	switch (control) {
+	case CXGB4_CONTROL_DB_FULL:
+		stop_queues(ctx);
+		mutex_lock(&ctx->dev->rdev.stats.lock);
+		ctx->dev->rdev.stats.db_full++;
+		mutex_unlock(&ctx->dev->rdev.stats.lock);
+		break;
+	case CXGB4_CONTROL_DB_EMPTY:
+		resume_queues(ctx);
+		mutex_lock(&ctx->dev->rdev.stats.lock);
+		ctx->dev->rdev.stats.db_empty++;
+		mutex_unlock(&ctx->dev->rdev.stats.lock);
+		break;
+	case CXGB4_CONTROL_DB_DROP:
+		printk(KERN_WARNING MOD "%s: Fatal DB DROP\n",
+		       pci_name(ctx->lldi.pdev));
+		mutex_lock(&ctx->dev->rdev.stats.lock);
+		ctx->dev->rdev.stats.db_drop++;
+		mutex_unlock(&ctx->dev->rdev.stats.lock);
+		break;
+	default:
+		printk(KERN_WARNING MOD "%s: unknown control cmd %u\n",
+		       pci_name(ctx->lldi.pdev), control);
+		break;
+	}
+	return 0;
+}
+
 static struct cxgb4_uld_info c4iw_uld_info = {
 	.name = DRV_NAME,
 	.add = c4iw_uld_add,
 	.rx_handler = c4iw_uld_rx_handler,
 	.state_change = c4iw_uld_state_change,
+	.control = c4iw_uld_control,
 };
 
 static int __init c4iw_init_module(void)
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index ec7c848..1924c19 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -117,6 +117,9 @@ struct c4iw_stats {
 	struct c4iw_stat pbl;
 	struct c4iw_stat rqt;
 	struct c4iw_stat ocqp;
+	u64  db_full;
+	u64  db_empty;
+	u64  db_drop;
 };
 
 struct c4iw_rdev {
@@ -192,6 +195,12 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev,
 	return wr_waitp->ret;
 }
 
+enum db_state {
+	NORMAL = 0,
+	FLOW_CONTROL = 1,
+	RECOVERY = 2
+};
+
 struct c4iw_dev {
 	struct ib_device ibdev;
 	struct c4iw_rdev rdev;
@@ -200,7 +209,9 @@ struct c4iw_dev {
 	struct idr qpidr;
 	struct idr mmidr;
 	spinlock_t lock;
+	struct mutex db_mutex;
 	struct dentry *debugfs_root;
+	enum db_state db_state;
 };
 
 static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
@@ -228,8 +239,8 @@ static inline struct c4iw_mr *get_mhp(struct c4iw_dev *rhp, u32 mmid)
 	return idr_find(&rhp->mmidr, mmid);
 }
 
-static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-				void *handle, u32 id)
+static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
+				 void *handle, u32 id, int lock)
 {
 	int ret;
 	int newid;
@@ -237,15 +248,29 @@ static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
 	do {
 		if (!idr_pre_get(idr, GFP_KERNEL))
 			return -ENOMEM;
-		spin_lock_irq(&rhp->lock);
+		if (lock)
+			spin_lock_irq(&rhp->lock);
 		ret = idr_get_new_above(idr, handle, id, &newid);
 		BUG_ON(newid != id);
-		spin_unlock_irq(&rhp->lock);
+		if (lock)
+			spin_unlock_irq(&rhp->lock);
 	} while (ret == -EAGAIN);
 
 	return ret;
 }
 
+static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
+				void *handle, u32 id)
+{
+	return _insert_handle(rhp, idr, handle, id, 1);
+}
+
+static inline int insert_handle_nolock(struct c4iw_dev *rhp, struct idr *idr,
+				       void *handle, u32 id)
+{
+	return _insert_handle(rhp, idr, handle, id, 0);
+}
+
 static inline void remove_handle(struct c4iw_dev *rhp, struct idr *idr, u32 id)
 {
 	spin_lock_irq(&rhp->lock);
@@ -369,6 +394,8 @@ struct c4iw_qp_attributes {
 	struct c4iw_ep *llp_stream_handle;
 	u8 layer_etype;
 	u8 ecode;
+	u16 sq_db_inc;
+	u16 rq_db_inc;
 };
 
 struct c4iw_qp {
@@ -443,6 +470,8 @@ static inline void insert_mmap(struct c4iw_ucontext *ucontext,
 
 enum c4iw_qp_attr_mask {
 	C4IW_QP_ATTR_NEXT_STATE = 1 << 0,
+	C4IW_QP_ATTR_SQ_DB = 1<<1,
+	C4IW_QP_ATTR_RQ_DB = 1<<2,
 	C4IW_QP_ATTR_ENABLE_RDMA_READ = 1 << 7,
 	C4IW_QP_ATTR_ENABLE_RDMA_WRITE = 1 << 8,
 	C4IW_QP_ATTR_ENABLE_RDMA_BIND = 1 << 9,
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 74df98e..36fc94d 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -34,6 +34,10 @@
 
 #include "iw_cxgb4.h"
 
+static int db_delay_usecs = 1;
+module_param(db_delay_usecs, int, 0644);
+MODULE_PARM_DESC(db_delay_usecs, "Usecs to delay awaiting db fifo to drain");
+
 static int ocqp_support = 1;
 module_param(ocqp_support, int, 0644);
 MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)");
@@ -1117,6 +1121,29 @@ out:
 	return ret;
 }
 
+/*
+ * Called by the library when the qp has user dbs disabled due to
+ * a DB_FULL condition.  This function will single-thread all user
+ * DB rings to avoid overflowing the hw db-fifo.
+ */
+static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc)
+{
+	int delay = db_delay_usecs;
+
+	mutex_lock(&qhp->rhp->db_mutex);
+	do {
+		if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) < 768) {
+			writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db);
+			break;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(usecs_to_jiffies(delay));
+		delay = min(delay << 1, 200000);
+	} while (1);
+	mutex_unlock(&qhp->rhp->db_mutex);
+	return 0;
+}
+
 int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
 		   enum c4iw_qp_attr_mask mask,
 		   struct c4iw_qp_attributes *attrs,
@@ -1165,6 +1192,15 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
 		qhp->attr = newattr;
 	}
 
+	if (mask & C4IW_QP_ATTR_SQ_DB) {
+		ret = ring_kernel_db(qhp, qhp->wq.sq.qid, attrs->sq_db_inc);
+		goto out;
+	}
+	if (mask & C4IW_QP_ATTR_RQ_DB) {
+		ret = ring_kernel_db(qhp, qhp->wq.rq.qid, attrs->rq_db_inc);
+		goto out;
+	}
+
 	if (!(mask & C4IW_QP_ATTR_NEXT_STATE))
 		goto out;
 	if (qhp->attr.state == attrs->next_state)
@@ -1454,7 +1490,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
 	init_waitqueue_head(&qhp->wait);
 	atomic_set(&qhp->refcnt, 1);
 
-	ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
+	spin_lock_irq(&rhp->lock);
+	if (rhp->db_state != NORMAL)
+		t4_disable_wq_db(&qhp->wq);
+	ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
+	spin_unlock_irq(&rhp->lock);
 	if (ret)
 		goto err2;
 
@@ -1598,6 +1638,15 @@ int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 			 C4IW_QP_ATTR_ENABLE_RDMA_WRITE |
 			 C4IW_QP_ATTR_ENABLE_RDMA_BIND) : 0;
 
+	/*
+	 * Use SQ_PSN and RQ_PSN to pass in IDX_INC values for
+	 * ringing the queue db when we're in DB_FULL mode.
+	 */
+	attrs.sq_db_inc = attr->sq_psn;
+	attrs.rq_db_inc = attr->rq_psn;
+	mask |= (attr_mask & IB_QP_SQ_PSN) ? C4IW_QP_ATTR_SQ_DB : 0;
+	mask |= (attr_mask & IB_QP_RQ_PSN) ? C4IW_QP_ATTR_RQ_DB : 0;
+
 	return c4iw_modify_qp(rhp, qhp, mask, &attrs, 0);
 }
 
diff --git a/drivers/infiniband/hw/cxgb4/user.h b/drivers/infiniband/hw/cxgb4/user.h
index e6669d5..32b754c 100644
--- a/drivers/infiniband/hw/cxgb4/user.h
+++ b/drivers/infiniband/hw/cxgb4/user.h
@@ -32,7 +32,7 @@
 #ifndef __C4IW_USER_H__
 #define __C4IW_USER_H__
 
-#define C4IW_UVERBS_ABI_VERSION	1
+#define C4IW_UVERBS_ABI_VERSION	2
 
 /*
  * Make sure that all structs defined in this file remain laid out so
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: Channel-less IIO events
From: Jonathan Cameron @ 2011-10-24 15:12 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: linux-iio@vger.kernel.org
In-Reply-To: <4EA57EB6.1020801@metafoo.de>

On 10/24/11 16:05, Lars-Peter Clausen wrote:
> On 10/24/2011 04:25 PM, Jonathan Cameron wrote:
>> On 10/24/11 14:47, Lars-Peter Clausen wrote:
>>> Hi,
>>>
>>> Some chips generate events which don't really map to a channel, but are
>>> rather chip global. For example over-temperature events.
>> That one is a channel.
>>> Do you think this is something we should add support for or should we rather
>>> use a dummy channel, which doesn't report any actual values, for propagating
>>> the event?
>> Yup, have a temp channel for that one.  Conceptually you might have two chips
>> that are otherwise identical but one has a readable temp channel, the other
>> doesn't.  Userspace that is interested only in events won't care about
>> this difference.  Also we want to report what the conditions are as if it were
>> a channel we could read.  We want to know at what temperature this occurs.
> 
> Ok, what should a read on such a channel return, an error value or just an
> dummy value?
Definitely error. We might need some magic to stop the channel showing up
in scan_elements if the chip uses buffering.  Also, if I recall, the magic
channel number -1 (as used for timestamps) stops it having a read attribute
in the first place (in place for timestamps).

> 
> 
>> [...]
>>>
>>> My idea for supporting channel-less events is to add a event_mask to struct
>>> iio_info, which would be used just like a channels event_mask, but there
>>> would be no index for the sysfs attributes and for events we would set the
>>> event number to 0xffff.
>> Could you give more examples?  The temp one to my mind definitely needs a
>> channel, perhaps others do not?  I am not against in principal but not
>> yet certain exactly when this would make sense...
> 
> over-temperature is the only one i've seen so far. but other could be
> under-current or voltage for the whole chip.
There I'd also create a bonus voltage / current channel.  Need these particular
ones to map well because we'll probably have hwmon based in kernel users for them.


^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.