* [PATCH v2 0/4] mfd: support dt on 88pm860x
@ 2012-09-21 10:06 Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 1/4] mfd: 88pm860x: use irqdomain Haojian Zhuang
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Haojian Zhuang @ 2012-09-21 10:06 UTC (permalink / raw)
To: sameo, linux-kernel, dmitry.torokhov
Changelog:
v2:
1. Resolve merge conflict since other patches also update 88pm860x-core.c
2. Add document of DT support
v1:
1. Updates the patch of max8925 of building issue.
2. Include Jett's PREG regulator patch.
3. Support DT in 88pm860x.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/4] mfd: 88pm860x: use irqdomain
2012-09-21 10:06 [PATCH v2 0/4] mfd: support dt on 88pm860x Haojian Zhuang
@ 2012-09-21 10:06 ` Haojian Zhuang
2012-09-28 23:28 ` Samuel Ortiz
2012-10-02 2:23 ` [PATCH] " Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 2/4] mfd: 88pm860x: support dt Haojian Zhuang
` (3 subsequent siblings)
4 siblings, 2 replies; 10+ messages in thread
From: Haojian Zhuang @ 2012-09-21 10:06 UTC (permalink / raw)
To: sameo, linux-kernel, dmitry.torokhov; +Cc: Haojian Zhuang
Use irqdomain and allocating interrupts. It's necessary for supporting
DT mode.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
drivers/mfd/88pm860x-core.c | 51 ++++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 13 deletions(-)
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 72bf290..b6766c9 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -15,6 +15,7 @@
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -520,15 +521,12 @@ static void pm860x_irq_sync_unlock(struct irq_data *data)
static void pm860x_irq_enable(struct irq_data *data)
{
- struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
- pm860x_irqs[data->irq - chip->irq_base].enable
- = pm860x_irqs[data->irq - chip->irq_base].offs;
+ pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
}
static void pm860x_irq_disable(struct irq_data *data)
{
- struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
- pm860x_irqs[data->irq - chip->irq_base].enable = 0;
+ pm860x_irqs[data->hwirq].enable = 0;
}
static struct irq_chip pm860x_irq_chip = {
@@ -539,6 +537,25 @@ static struct irq_chip pm860x_irq_chip = {
.irq_disable = pm860x_irq_disable,
};
+static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_data(virq, d->host_data);
+ irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
+ irq_set_nested_thread(virq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(virq, IRQF_VALID);
+#else
+ irq_set_noprobe(virq);
+#endif
+ return 0;
+}
+
+static struct irq_domain_ops pm860x_irq_domain_ops = {
+ .map = pm860x_irq_domain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
static int __devinit device_gpadc_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
@@ -593,13 +610,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
: chip->companion;
unsigned char status_buf[INT_STATUS_NUM];
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
- int i, data, mask, ret = -EINVAL;
- int __irq;
-
- if (!pdata || !pdata->irq_base) {
- dev_warn(chip->dev, "No interrupt support on IRQ base\n");
- return -EINVAL;
- }
+ int data, mask, ret = -EINVAL;
+ int nr_irqs, irq_base = -1;
+ struct device_node *node = i2c->dev.of_node;
mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
| PM8607_B0_MISC1_INT_MASK;
@@ -639,7 +652,19 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
goto out;
mutex_init(&chip->irq_lock);
- chip->irq_base = pdata->irq_base;
+
+ if (pdata && pdata->irq_base)
+ irq_base = pdata->irq_base;
+ nr_irqs = ARRAY_SIZE(pm860x_irqs);
+ chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
+ if (chip->irq_base < 0) {
+ dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
+ chip->irq_base);
+ ret = -EBUSY;
+ goto out;
+ }
+ irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
+ &pm860x_irq_domain_ops, chip);
chip->core_irq = i2c->irq;
if (!chip->core_irq)
goto out;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/4] mfd: 88pm860x: support dt
2012-09-21 10:06 [PATCH v2 0/4] mfd: support dt on 88pm860x Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 1/4] mfd: 88pm860x: use irqdomain Haojian Zhuang
@ 2012-09-21 10:06 ` Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 3/4] mfd: 88pm860x: move gpadc init into touch Haojian Zhuang
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Haojian Zhuang @ 2012-09-21 10:06 UTC (permalink / raw)
To: sameo, linux-kernel, dmitry.torokhov; +Cc: Haojian Zhuang
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
Documentation/devicetree/bindings/mfd/88pm860x.txt | 85 ++++++++++++++++++++
.../devicetree/bindings/regulator/88pm860x.txt | 30 +++++++
.../bindings/video/backlight/88pm860x.txt | 16 ++++
drivers/input/touchscreen/88pm860x-ts.c | 46 +++++++----
drivers/leds/leds-88pm860x.c | 33 +++++++-
drivers/mfd/88pm860x-core.c | 62 +++++++++++---
drivers/regulator/88pm8607.c | 35 +++++++-
drivers/rtc/rtc-88pm860x.c | 43 +++++++---
drivers/video/backlight/88pm860x_bl.c | 39 ++++++++-
include/linux/mfd/88pm860x.h | 4 +-
10 files changed, 352 insertions(+), 41 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/88pm860x.txt
create mode 100644 Documentation/devicetree/bindings/regulator/88pm860x.txt
create mode 100644 Documentation/devicetree/bindings/video/backlight/88pm860x.txt
diff --git a/Documentation/devicetree/bindings/mfd/88pm860x.txt b/Documentation/devicetree/bindings/mfd/88pm860x.txt
new file mode 100644
index 0000000..63f3ee3
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/88pm860x.txt
@@ -0,0 +1,85 @@
+* Marvell 88PM860x Power Management IC
+
+Required parent device properties:
+- compatible : "marvell,88pm860x"
+- reg : the I2C slave address for the 88pm860x chip
+- interrupts : IRQ line for the 88pm860x chip
+- interrupt-controller: describes the 88pm860x as an interrupt controller (has its own domain)
+- #interrupt-cells : should be 1.
+ - The cell is the 88pm860x local IRQ number
+
+Optional parent device properties:
+- marvell,88pm860x-irq-read-clr: inicates whether interrupt status is cleared by read
+- marvell,88pm860x-slave-addr: 88pm860x are two chips solution. <reg> stores the I2C address
+ of one chip, and this property stores the I2C address of
+ another chip.
+
+88pm860x consists of a large and varied group of sub-devices:
+
+Device Supply Names Description
+------ ------------ -----------
+88pm860x-onkey : : On key
+88pm860x-rtc : : RTC
+88pm8607 : : Regulators
+88pm860x-backlight : : Backlight
+88pm860x-led : : Led
+88pm860x-touch : : Touchscreen
+
+Example:
+
+ pmic: 88pm860x@34 {
+ compatible = "marvell,88pm860x";
+ reg = <0x34>;
+ interrupts = <4>;
+ interrupt-parent = <&intc>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ marvell,88pm860x-irq-read-clr;
+ marvell,88pm860x-slave-addr = <0x11>;
+
+ regulators {
+ BUCK1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ rtc {
+ marvell,88pm860x-vrtc = <1>;
+ };
+ touch {
+ marvell,88pm860x-gpadc-prebias = <1>;
+ marvell,88pm860x-gpadc-slot-cycle = <1>;
+ marvell,88pm860x-tsi-prebias = <6>;
+ marvell,88pm860x-pen-prebias = <16>;
+ marvell,88pm860x-pen-prechg = <2>;
+ marvell,88pm860x-resistor-X = <300>;
+ };
+ backlights {
+ backlight-0 {
+ marvell,88pm860x-iset = <4>;
+ marvell,88pm860x-pwm = <3>;
+ };
+ backlight-2 {
+ };
+ };
+ leds {
+ led0-red {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-green {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-blue {
+ marvell,88pm860x-iset = <12>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/88pm860x.txt b/Documentation/devicetree/bindings/regulator/88pm860x.txt
new file mode 100644
index 0000000..1267b3e
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/88pm860x.txt
@@ -0,0 +1,30 @@
+Marvell 88PM860x regulator
+
+Required properties:
+- compatible: "marvell,88pm860x"
+- reg: I2C slave address
+- regulators: A node that houses a sub-node for each regulator within the
+ device. Each sub-node is identified using the regulator-compatible
+ property, with valid values listed below.
+
+Example:
+
+ pmic: 88pm860x@34 {
+ compatible = "marvell,88pm860x";
+ reg = <0x34>;
+
+ regulators {
+ BUCK1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/video/backlight/88pm860x.txt b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
new file mode 100644
index 0000000..4e6a24c
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
@@ -0,0 +1,16 @@
+88pm860x-backlight bindings
+
+Optional properties:
+ - marvell,88pm860x-iset: Current supplies on backlight device.
+ - marvell,88pm860x-pwm: PWM frequency on backlight device.
+
+Example:
+
+ backlights {
+ backlight-0 {
+ marvell,88pm860x-iset = <4>;
+ marvell,88pm860x-pwm = <3>;
+ };
+ backlight-2 {
+ };
+
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 05f30b7..4f81e6e 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/input.h>
@@ -113,14 +114,31 @@ static void pm860x_touch_close(struct input_dev *dev)
pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
}
+#ifdef CONFIG_OF
+static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
+ int *res_x)
+{
+ struct device_node *np = pdev->dev.parent->of_node;
+ if (!np)
+ return -ENODEV;
+ np = of_find_node_by_name(np, "touch");
+ if (!np) {
+ dev_err(&pdev->dev, "Can't find touch node\n");
+ return -EINVAL;
+ }
+ of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
+ return 0;
+}
+#else
+#define pm860x_touch_dt_init(x, y) (-1)
+#endif
+
static int __devinit pm860x_touch_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm860x_platform_data *pm860x_pdata = \
- pdev->dev.parent->platform_data;
- struct pm860x_touch_pdata *pdata = NULL;
+ struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
struct pm860x_touch *touch;
- int irq, ret;
+ int irq, ret, res_x = 0;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -128,15 +146,13 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
return -EINVAL;
}
- if (!pm860x_pdata) {
- dev_err(&pdev->dev, "platform data is missing\n");
- return -EINVAL;
- }
-
- pdata = pm860x_pdata->touch;
- if (!pdata) {
- dev_err(&pdev->dev, "touchscreen data is missing\n");
- return -EINVAL;
+ if (pm860x_touch_dt_init(pdev, &res_x)) {
+ if (pdata)
+ res_x = pdata->res_x;
+ else {
+ dev_err(&pdev->dev, "failed to get platform data\n");
+ return -EINVAL;
+ }
}
touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
@@ -159,8 +175,8 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
touch->idev->close = pm860x_touch_close;
touch->chip = chip;
touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
- touch->irq = irq + chip->irq_base;
- touch->res_x = pdata->res_x;
+ touch->irq = irq;
+ touch->res_x = res_x;
input_set_drvdata(touch->idev, touch);
ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 70232b1..b7e8cc0 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/leds.h>
@@ -123,6 +124,33 @@ static void pm860x_led_set(struct led_classdev *cdev,
schedule_work(&data->work);
}
+#ifdef CONFIG_OF
+static int pm860x_led_dt_init(struct platform_device *pdev,
+ struct pm860x_led *data)
+{
+ struct device_node *nproot = pdev->dev.parent->of_node, *np;
+ int iset = 0;
+ if (!nproot)
+ return -ENODEV;
+ nproot = of_find_node_by_name(nproot, "leds");
+ if (!nproot) {
+ dev_err(&pdev->dev, "failed to find leds node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (!of_node_cmp(np->name, data->name)) {
+ of_property_read_u32(np, "marvell,88pm860x-iset",
+ &iset);
+ data->iset = PM8606_LED_CURRENT(iset);
+ break;
+ }
+ }
+ return 0;
+}
+#else
+#define pm860x_led_dt_init(x, y) (-1)
+#endif
+
static int pm860x_led_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -179,8 +207,9 @@ static int pm860x_led_probe(struct platform_device *pdev)
data->chip = chip;
data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
data->port = pdev->id;
- if (pdata && pdata->iset)
- data->iset = pdata->iset;
+ if (pm860x_led_dt_init(pdev, data))
+ if (pdata)
+ data->iset = pdata->iset;
data->current_brightness = 0;
data->cdev.name = data->name;
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index b6766c9..a2bc5bf 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -16,6 +16,8 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -1126,12 +1128,6 @@ static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
mfd_remove_devices(chip->dev);
}
-static const struct i2c_device_id pm860x_id_table[] = {
- { "88PM860x", 0 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
-
static int verify_addr(struct i2c_client *i2c)
{
unsigned short addr_8607[] = {0x30, 0x34};
@@ -1158,21 +1154,52 @@ static struct regmap_config pm860x_regmap_config = {
.val_bits = 8,
};
+static int __devinit pm860x_dt_init(struct device_node *np,
+ struct device *dev,
+ struct pm860x_platform_data *pdata)
+{
+ int ret;
+
+ if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
+ pdata->irq_mode = 1;
+ ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
+ &pdata->companion_addr);
+ if (ret) {
+ dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
+ "property\n");
+ pdata->companion_addr = 0;
+ }
+ return 0;
+}
+
static int __devinit pm860x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pm860x_platform_data *pdata = client->dev.platform_data;
+ struct device_node *node = client->dev.of_node;
struct pm860x_chip *chip;
int ret;
- if (!pdata) {
+ if (node && !pdata) {
+ /* parse DT to get platform data */
+ pdata = devm_kzalloc(&client->dev,
+ sizeof(struct pm860x_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ ret = pm860x_dt_init(node, &client->dev, pdata);
+ if (ret)
+ goto err;
+ } else if (!pdata) {
pr_info("No platform data in %s!\n", __func__);
return -EINVAL;
}
chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
+ if (chip == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
chip->id = verify_addr(client);
chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
@@ -1212,6 +1239,10 @@ static int __devinit pm860x_probe(struct i2c_client *client,
pm860x_device_init(chip, pdata);
return 0;
+err:
+ if (node)
+ devm_kfree(&client->dev, pdata);
+ return ret;
}
static int __devexit pm860x_remove(struct i2c_client *client)
@@ -1252,11 +1283,24 @@ static int pm860x_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
+static const struct i2c_device_id pm860x_id_table[] = {
+ { "88PM860x", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
+
+static const struct of_device_id pm860x_dt_ids[] = {
+ { .compatible = "marvell,88pm860x", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
+
static struct i2c_driver pm860x_driver = {
.driver = {
.name = "88PM860x",
.owner = THIS_MODULE,
.pm = &pm860x_pm_ops,
+ .of_match_table = of_match_ptr(pm860x_dt_ids),
},
.probe = pm860x_probe,
.remove = __devexit_p(pm860x_remove),
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index f96fbe3..1c5ab01 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@@ -364,6 +366,34 @@ static struct pm8607_regulator_info pm8606_regulator_info[] = {
PM8606_PREG(PREREGULATORB, 5),
};
+#ifdef CONFIG_OF
+static int pm8607_regulator_dt_init(struct platform_device *pdev,
+ struct pm8607_regulator_info *info,
+ struct regulator_config *config)
+{
+ struct device_node *nproot, *np;
+ nproot = pdev->dev.parent->of_node;
+ if (!nproot)
+ return -ENODEV;
+ nproot = of_find_node_by_name(nproot, "regulators");
+ if (!nproot) {
+ dev_err(&pdev->dev, "failed to find regulators node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (!of_node_cmp(np->name, info->desc.name)) {
+ config->init_data =
+ of_get_regulator_init_data(&pdev->dev, np);
+ config->of_node = np;
+ break;
+ }
+ }
+ return 0;
+}
+#else
+#define pm8607_regulator_dt_init(x, y, z) (-1)
+#endif
+
static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -402,9 +432,12 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
info->slope_double = 1;
config.dev = &pdev->dev;
- config.init_data = pdata;
config.driver_data = info;
+ if (pm8607_regulator_dt_init(pdev, info, &config))
+ if (pdata)
+ config.init_data = pdata;
+
if (chip->id == CHIP_PM8607)
config.regmap = chip->regmap;
else
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index feddefc..de9e854 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/mutex.h>
@@ -284,6 +285,28 @@ out:
}
#endif
+#ifdef CONFIG_OF
+static int __devinit pm860x_rtc_dt_init(struct platform_device *pdev,
+ struct pm860x_rtc_info *info)
+{
+ struct device_node *np = pdev->dev.parent->of_node;
+ int ret;
+ if (!np)
+ return -ENODEV;
+ np = of_find_node_by_name(np, "rtc");
+ if (!np) {
+ dev_err(&pdev->dev, "failed to find rtc node\n");
+ return -ENODEV;
+ }
+ ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc);
+ if (ret)
+ info->vrtc = 0;
+ return 0;
+}
+#else
+#define pm860x_rtc_dt_init(x, y) (-1)
+#endif
+
static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -294,8 +317,6 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
int ret;
pdata = pdev->dev.platform_data;
- if (pdata == NULL)
- dev_warn(&pdev->dev, "No platform data!\n");
info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL);
if (!info)
@@ -345,9 +366,11 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
}
}
rtc_tm_to_time(&tm, &ticks);
- if (pdata && pdata->sync) {
- pdata->sync(ticks);
- info->sync = pdata->sync;
+ if (pm860x_rtc_dt_init(pdev, info)) {
+ if (pdata && pdata->sync) {
+ pdata->sync(ticks);
+ info->sync = pdata->sync;
+ }
}
info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev,
@@ -366,10 +389,12 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
#ifdef VRTC_CALIBRATION
/* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */
- if (pdata && pdata->vrtc)
- info->vrtc = pdata->vrtc & 0x3;
- else
- info->vrtc = 1;
+ if (pm860x_rtc_dt_init(pdev, info)) {
+ if (pdata && pdata->vrtc)
+ info->vrtc = pdata->vrtc & 0x3;
+ else
+ info->vrtc = 1;
+ }
pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC);
/* calibrate VRTC */
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index 965161c..b7ec34c 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/fb.h>
@@ -159,6 +160,36 @@ static const struct backlight_ops pm860x_backlight_ops = {
.get_brightness = pm860x_backlight_get_brightness,
};
+#ifdef CONFIG_OF
+static int pm860x_backlight_dt_init(struct platform_device *pdev,
+ struct pm860x_backlight_data *data,
+ char *name)
+{
+ struct device_node *nproot = pdev->dev.parent->of_node, *np;
+ int iset = 0;
+ if (!nproot)
+ return -ENODEV;
+ nproot = of_find_node_by_name(nproot, "backlights");
+ if (!nproot) {
+ dev_err(&pdev->dev, "failed to find backlights node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (!of_node_cmp(np->name, name)) {
+ of_property_read_u32(np, "marvell,88pm860x-iset",
+ &iset);
+ data->iset = PM8606_WLED_CURRENT(iset);
+ of_property_read_u32(np, "marvell,88pm860x-pwm",
+ &data->pwm);
+ break;
+ }
+ }
+ return 0;
+}
+#else
+#define pm860x_backlight_dt_init(x, y, z) (-1)
+#endif
+
static int pm860x_backlight_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -203,9 +234,11 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
: chip->companion;
data->current_brightness = MAX_BRIGHTNESS;
- if (pdata) {
- data->pwm = pdata->pwm;
- data->iset = pdata->iset;
+ if (pm860x_backlight_dt_init(pdev, data, name)) {
+ if (pdata) {
+ data->pwm = pdata->pwm;
+ data->iset = pdata->iset;
+ }
}
memset(&props, 0, sizeof(struct backlight_properties));
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index d515e5c..ef3e6b7 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -306,7 +306,7 @@ struct pm860x_chip {
struct regmap *regmap_companion;
int buck3_double; /* DVC ramp slope double */
- unsigned short companion_addr;
+ int companion_addr;
unsigned short osc_vote;
int id;
int irq_mode;
@@ -376,7 +376,7 @@ struct pm860x_platform_data {
struct regulator_init_data *ldo_vibrator;
struct regulator_init_data *ldo14;
- unsigned short companion_addr; /* I2C address of companion chip */
+ int companion_addr; /* I2C address of companion chip */
int i2c_port; /* Controlled by GI2C or PI2C */
int irq_mode; /* Clear interrupt by read/write(0/1) */
int irq_base; /* IRQ base number of 88pm860x */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/4] mfd: 88pm860x: move gpadc init into touch
2012-09-21 10:06 [PATCH v2 0/4] mfd: support dt on 88pm860x Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 1/4] mfd: 88pm860x: use irqdomain Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 2/4] mfd: 88pm860x: support dt Haojian Zhuang
@ 2012-09-21 10:06 ` Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 4/4] ARM: dts: enable 88pm860x pmic Haojian Zhuang
2012-09-28 22:40 ` [PATCH v2 0/4] mfd: support dt on 88pm860x Samuel Ortiz
4 siblings, 0 replies; 10+ messages in thread
From: Haojian Zhuang @ 2012-09-21 10:06 UTC (permalink / raw)
To: sameo, linux-kernel, dmitry.torokhov; +Cc: Haojian Zhuang
The initilization of GPADC is moved from core driver to touch driver
with DT support.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
drivers/input/touchscreen/88pm860x-ts.c | 91 +++++++++++++++++++++++++++++--
drivers/mfd/88pm860x-core.c | 51 -----------------
2 files changed, 85 insertions(+), 57 deletions(-)
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 4f81e6e..326218d 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -116,9 +116,13 @@ static void pm860x_touch_close(struct input_dev *dev)
#ifdef CONFIG_OF
static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
+ struct pm860x_chip *chip,
int *res_x)
{
struct device_node *np = pdev->dev.parent->of_node;
+ struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+ : chip->companion;
+ int data, n, ret;
if (!np)
return -ENODEV;
np = of_find_node_by_name(np, "touch");
@@ -126,11 +130,43 @@ static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
dev_err(&pdev->dev, "Can't find touch node\n");
return -EINVAL;
}
+ /* set GPADC MISC1 register */
+ data = 0;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-prebias", &n))
+ data |= (n << 1) & PM8607_GPADC_PREBIAS_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-slot-cycle", &n))
+ data |= (n << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-off-scale", &n))
+ data |= (n << 5) & PM8607_GPADC_OFF_SCALE_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-sw-cal", &n))
+ data |= (n << 7) & PM8607_GPADC_SW_CAL_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set tsi prebias time */
+ if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
+ ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set prebias & prechg time of pen detect */
+ data = 0;
+ if (!of_property_read_u32(np, "marvell,88pm860x-pen-prebias", &n))
+ data |= n & PM8607_PD_PREBIAS_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-pen-prechg", &n))
+ data |= n & PM8607_PD_PRECHG_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
return 0;
}
#else
-#define pm860x_touch_dt_init(x, y) (-1)
+#define pm860x_touch_dt_init(x, y, z) (-1)
#endif
static int __devinit pm860x_touch_probe(struct platform_device *pdev)
@@ -138,7 +174,9 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
struct pm860x_touch *touch;
- int irq, ret, res_x = 0;
+ struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+ : chip->companion;
+ int irq, ret, res_x = 0, data = 0;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -146,14 +184,55 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
return -EINVAL;
}
- if (pm860x_touch_dt_init(pdev, &res_x)) {
- if (pdata)
+ if (pm860x_touch_dt_init(pdev, chip, &res_x)) {
+ if (pdata) {
+ /* set GPADC MISC1 register */
+ data = 0;
+ data |= (pdata->gpadc_prebias << 1)
+ & PM8607_GPADC_PREBIAS_MASK;
+ data |= (pdata->slot_cycle << 3)
+ & PM8607_GPADC_SLOT_CYCLE_MASK;
+ data |= (pdata->off_scale << 5)
+ & PM8607_GPADC_OFF_SCALE_MASK;
+ data |= (pdata->sw_cal << 7)
+ & PM8607_GPADC_SW_CAL_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c,
+ PM8607_GPADC_MISC1, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set tsi prebias time */
+ if (pdata->tsi_prebias) {
+ data = pdata->tsi_prebias;
+ ret = pm860x_reg_write(i2c,
+ PM8607_TSI_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set prebias & prechg time of pen detect */
+ data = 0;
+ data |= pdata->pen_prebias
+ & PM8607_PD_PREBIAS_MASK;
+ data |= (pdata->pen_prechg << 5)
+ & PM8607_PD_PRECHG_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c,
+ PM8607_PD_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
res_x = pdata->res_x;
- else {
+ } else {
dev_err(&pdev->dev, "failed to get platform data\n");
return -EINVAL;
}
}
+ /* enable GPADC */
+ ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, PM8607_GPADC_EN,
+ PM8607_GPADC_EN);
+ if (ret)
+ return ret;
touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
if (touch == NULL)
@@ -174,7 +253,7 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
touch->idev->open = pm860x_touch_open;
touch->idev->close = pm860x_touch_close;
touch->chip = chip;
- touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ touch->i2c = i2c;
touch->irq = irq;
touch->res_x = res_x;
input_set_drvdata(touch->idev, touch);
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index a2bc5bf..66acac2 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -558,53 +558,6 @@ static struct irq_domain_ops pm860x_irq_domain_ops = {
.xlate = irq_domain_xlate_onetwocell,
};
-static int __devinit device_gpadc_init(struct pm860x_chip *chip,
- struct pm860x_platform_data *pdata)
-{
- struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
- : chip->companion;
- int data;
- int ret;
-
- /* initialize GPADC without activating it */
-
- if (!pdata || !pdata->touch)
- return -EINVAL;
-
- /* set GPADC MISC1 register */
- data = 0;
- data |= (pdata->touch->gpadc_prebias << 1) & PM8607_GPADC_PREBIAS_MASK;
- data |= (pdata->touch->slot_cycle << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
- data |= (pdata->touch->off_scale << 5) & PM8607_GPADC_OFF_SCALE_MASK;
- data |= (pdata->touch->sw_cal << 7) & PM8607_GPADC_SW_CAL_MASK;
- if (data) {
- ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
- if (ret < 0)
- goto out;
- }
- /* set tsi prebias time */
- if (pdata->touch->tsi_prebias) {
- data = pdata->touch->tsi_prebias;
- ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
- if (ret < 0)
- goto out;
- }
- /* set prebias & prechg time of pen detect */
- data = 0;
- data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
- data |= (pdata->touch->pen_prechg << 5) & PM8607_PD_PRECHG_MASK;
- if (data) {
- ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
- if (ret < 0)
- goto out;
- }
-
- ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
- PM8607_GPADC_EN, PM8607_GPADC_EN);
-out:
- return ret;
-}
-
static int __devinit device_irq_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
@@ -1067,10 +1020,6 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
goto out;
}
- ret = device_gpadc_init(chip, pdata);
- if (ret < 0)
- goto out;
-
ret = device_irq_init(chip, pdata);
if (ret < 0)
goto out;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 4/4] ARM: dts: enable 88pm860x pmic
2012-09-21 10:06 [PATCH v2 0/4] mfd: support dt on 88pm860x Haojian Zhuang
` (2 preceding siblings ...)
2012-09-21 10:06 ` [PATCH v2 3/4] mfd: 88pm860x: move gpadc init into touch Haojian Zhuang
@ 2012-09-21 10:06 ` Haojian Zhuang
2012-09-28 22:40 ` [PATCH v2 0/4] mfd: support dt on 88pm860x Samuel Ortiz
4 siblings, 0 replies; 10+ messages in thread
From: Haojian Zhuang @ 2012-09-21 10:06 UTC (permalink / raw)
To: sameo, linux-kernel, dmitry.torokhov; +Cc: Haojian Zhuang
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
arch/arm/boot/dts/pxa910-dkb.dts | 137 ++++++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/pxa910.dtsi | 4 ++
2 files changed, 141 insertions(+)
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index e92be5a..595492a 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -29,6 +29,143 @@
};
twsi1: i2c@d4011000 {
status = "okay";
+
+ pmic: 88pm860x@34 {
+ compatible = "marvell,88pm860x";
+ reg = <0x34>;
+ interrupts = <4>;
+ interrupt-parent = <&intc>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ marvell,88pm860x-irq-read-clr;
+ marvell,88pm860x-slave-addr = <0x11>;
+
+ regulators {
+ BUCK1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO5 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO10 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO12 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO13 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ rtc {
+ marvell,88pm860x-vrtc = <1>;
+ };
+ touch {
+ marvell,88pm860x-gpadc-prebias = <1>;
+ marvell,88pm860x-gpadc-slot-cycle = <1>;
+ marvell,88pm860x-tsi-prebias = <6>;
+ marvell,88pm860x-pen-prebias = <16>;
+ marvell,88pm860x-pen-prechg = <2>;
+ marvell,88pm860x-resistor-X = <300>;
+ };
+ backlights {
+ backlight-0 {
+ marvell,88pm860x-iset = <4>;
+ marvell,88pm860x-pwm = <3>;
+ };
+ backlight-2 {
+ };
+ };
+ leds {
+ led0-red {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-green {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-blue {
+ marvell,88pm860x-iset = <12>;
+ };
+ };
+ };
};
rtc: rtc@d4010000 {
status = "okay";
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index aebf32d..1942e54 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -115,6 +115,8 @@
twsi1: i2c@d4011000 {
compatible = "mrvl,mmp-twsi";
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0xd4011000 0x1000>;
interrupts = <7>;
mrvl,i2c-fast-mode;
@@ -123,6 +125,8 @@
twsi2: i2c@d4037000 {
compatible = "mrvl,mmp-twsi";
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0xd4037000 0x1000>;
interrupts = <54>;
status = "disabled";
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 0/4] mfd: support dt on 88pm860x
2012-09-21 10:06 [PATCH v2 0/4] mfd: support dt on 88pm860x Haojian Zhuang
` (3 preceding siblings ...)
2012-09-21 10:06 ` [PATCH v2 4/4] ARM: dts: enable 88pm860x pmic Haojian Zhuang
@ 2012-09-28 22:40 ` Samuel Ortiz
4 siblings, 0 replies; 10+ messages in thread
From: Samuel Ortiz @ 2012-09-28 22:40 UTC (permalink / raw)
To: Haojian Zhuang; +Cc: linux-kernel, dmitry.torokhov
Hi Haojian,
On Fri, Sep 21, 2012 at 06:06:50PM +0800, Haojian Zhuang wrote:
> Changelog:
> v2:
> 1. Resolve merge conflict since other patches also update 88pm860x-core.c
> 2. Add document of DT support
All 4 patches applied, thanks.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/4] mfd: 88pm860x: use irqdomain
2012-09-21 10:06 ` [PATCH v2 1/4] mfd: 88pm860x: use irqdomain Haojian Zhuang
@ 2012-09-28 23:28 ` Samuel Ortiz
2012-10-02 2:25 ` Haojian Zhuang
2012-10-02 2:23 ` [PATCH] " Haojian Zhuang
1 sibling, 1 reply; 10+ messages in thread
From: Samuel Ortiz @ 2012-09-28 23:28 UTC (permalink / raw)
To: Haojian Zhuang; +Cc: linux-kernel, dmitry.torokhov
Hi Haojian:
On Fri, Sep 21, 2012 at 06:06:51PM +0800, Haojian Zhuang wrote:
> @@ -593,13 +610,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
> : chip->companion;
> unsigned char status_buf[INT_STATUS_NUM];
> unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
> - int i, data, mask, ret = -EINVAL;
That one breaks the build:
drivers/mfd/88pm860x-core.c: In function ‘device_irq_init’:
drivers/mfd/88pm860x-core.c:628:7: error: ‘i’ undeclared (first use in this
function)
drivers/mfd/88pm860x-core.c:628:7: note: each undeclared identifier is
reported only once for each function it appears in
drivers/mfd/88pm860x-core.c:629:3: error: ‘__irq’ undeclared (first use in
this function)
make[2]: *** [drivers/mfd/88pm860x-core.o] Error 1
I removed this patchset until it builds...
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] mfd: 88pm860x: use irqdomain
2012-09-21 10:06 ` [PATCH v2 1/4] mfd: 88pm860x: use irqdomain Haojian Zhuang
2012-09-28 23:28 ` Samuel Ortiz
@ 2012-10-02 2:23 ` Haojian Zhuang
1 sibling, 0 replies; 10+ messages in thread
From: Haojian Zhuang @ 2012-10-02 2:23 UTC (permalink / raw)
To: sameo, linux-kernel; +Cc: Haojian Zhuang
Use irqdomain and allocating interrupts. It's necessary for supporting
DT mode.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
drivers/mfd/88pm860x-core.c | 65 +++++++++++++++++++++++++------------------
1 file changed, 38 insertions(+), 27 deletions(-)
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 72bf290..5b56fe8 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -15,6 +15,7 @@
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -520,15 +521,12 @@ static void pm860x_irq_sync_unlock(struct irq_data *data)
static void pm860x_irq_enable(struct irq_data *data)
{
- struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
- pm860x_irqs[data->irq - chip->irq_base].enable
- = pm860x_irqs[data->irq - chip->irq_base].offs;
+ pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
}
static void pm860x_irq_disable(struct irq_data *data)
{
- struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
- pm860x_irqs[data->irq - chip->irq_base].enable = 0;
+ pm860x_irqs[data->hwirq].enable = 0;
}
static struct irq_chip pm860x_irq_chip = {
@@ -539,6 +537,25 @@ static struct irq_chip pm860x_irq_chip = {
.irq_disable = pm860x_irq_disable,
};
+static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_data(virq, d->host_data);
+ irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
+ irq_set_nested_thread(virq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(virq, IRQF_VALID);
+#else
+ irq_set_noprobe(virq);
+#endif
+ return 0;
+}
+
+static struct irq_domain_ops pm860x_irq_domain_ops = {
+ .map = pm860x_irq_domain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
static int __devinit device_gpadc_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
@@ -593,13 +610,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
: chip->companion;
unsigned char status_buf[INT_STATUS_NUM];
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
- int i, data, mask, ret = -EINVAL;
- int __irq;
-
- if (!pdata || !pdata->irq_base) {
- dev_warn(chip->dev, "No interrupt support on IRQ base\n");
- return -EINVAL;
- }
+ int data, mask, ret = -EINVAL;
+ int nr_irqs, irq_base = -1;
+ struct device_node *node = i2c->dev.of_node;
mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
| PM8607_B0_MISC1_INT_MASK;
@@ -639,25 +652,23 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
goto out;
mutex_init(&chip->irq_lock);
- chip->irq_base = pdata->irq_base;
+
+ if (pdata && pdata->irq_base)
+ irq_base = pdata->irq_base;
+ nr_irqs = ARRAY_SIZE(pm860x_irqs);
+ chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
+ if (chip->irq_base < 0) {
+ dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
+ chip->irq_base);
+ ret = -EBUSY;
+ goto out;
+ }
+ irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
+ &pm860x_irq_domain_ops, chip);
chip->core_irq = i2c->irq;
if (!chip->core_irq)
goto out;
- /* register IRQ by genirq */
- for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
- __irq = i + chip->irq_base;
- irq_set_chip_data(__irq, chip);
- irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
- handle_edge_irq);
- irq_set_nested_thread(__irq, 1);
-#ifdef CONFIG_ARM
- set_irq_flags(__irq, IRQF_VALID);
-#else
- irq_set_noprobe(__irq);
-#endif
- }
-
ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT,
"88pm860x", chip);
if (ret) {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/4] mfd: 88pm860x: use irqdomain
2012-09-28 23:28 ` Samuel Ortiz
@ 2012-10-02 2:25 ` Haojian Zhuang
2012-10-02 9:45 ` Samuel Ortiz
0 siblings, 1 reply; 10+ messages in thread
From: Haojian Zhuang @ 2012-10-02 2:25 UTC (permalink / raw)
To: Samuel Ortiz; +Cc: linux-kernel, dmitry.torokhov
On Sat, Sep 29, 2012 at 7:28 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
> Hi Haojian:
>
> On Fri, Sep 21, 2012 at 06:06:51PM +0800, Haojian Zhuang wrote:
>> @@ -593,13 +610,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
>> : chip->companion;
>> unsigned char status_buf[INT_STATUS_NUM];
>> unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
>> - int i, data, mask, ret = -EINVAL;
> That one breaks the build:
>
> drivers/mfd/88pm860x-core.c: In function ‘device_irq_init’:
> drivers/mfd/88pm860x-core.c:628:7: error: ‘i’ undeclared (first use in this
> function)
> drivers/mfd/88pm860x-core.c:628:7: note: each undeclared identifier is
> reported only once for each function it appears in
> drivers/mfd/88pm860x-core.c:629:3: error: ‘__irq’ undeclared (first use in
> this function)
> make[2]: *** [drivers/mfd/88pm860x-core.o] Error 1
>
> I removed this patchset until it builds...
>
I'm sorry for inconvenience. Now fix it.
Regards
Haojian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/4] mfd: 88pm860x: use irqdomain
2012-10-02 2:25 ` Haojian Zhuang
@ 2012-10-02 9:45 ` Samuel Ortiz
0 siblings, 0 replies; 10+ messages in thread
From: Samuel Ortiz @ 2012-10-02 9:45 UTC (permalink / raw)
To: Haojian Zhuang; +Cc: linux-kernel, dmitry.torokhov
Hi Haojian,
On Tue, Oct 02, 2012 at 10:25:06AM +0800, Haojian Zhuang wrote:
> > I removed this patchset until it builds...
> >
> I'm sorry for inconvenience. Now fix it.
All 4 patches applied now.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-10-02 9:45 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-21 10:06 [PATCH v2 0/4] mfd: support dt on 88pm860x Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 1/4] mfd: 88pm860x: use irqdomain Haojian Zhuang
2012-09-28 23:28 ` Samuel Ortiz
2012-10-02 2:25 ` Haojian Zhuang
2012-10-02 9:45 ` Samuel Ortiz
2012-10-02 2:23 ` [PATCH] " Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 2/4] mfd: 88pm860x: support dt Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 3/4] mfd: 88pm860x: move gpadc init into touch Haojian Zhuang
2012-09-21 10:06 ` [PATCH v2 4/4] ARM: dts: enable 88pm860x pmic Haojian Zhuang
2012-09-28 22:40 ` [PATCH v2 0/4] mfd: support dt on 88pm860x Samuel Ortiz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox