Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7660e37c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "pinctrl: msm: Move driver probe and irq probe to TLMM implementation"

parents fe68ccc3 9779cbd3
Loading
Loading
Loading
Loading
+104 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/spinlock.h>
#include <linux/syscore_ops.h>
@@ -473,11 +474,11 @@ static void msm_tlmm_v3_set_intr_cfg_type(struct msm_tlmm_irq_chip *ic,
	udelay(5);
}

static irqreturn_t msm_tlmm_v3_irq_handle(int irq, void *data)
static irqreturn_t msm_tlmm_v3_gp_handle_irq(int irq,
						struct  msm_tlmm_irq_chip *ic)
{
	unsigned long i;
	unsigned int virq = 0;
	struct msm_tlmm_irq_chip *ic = (struct msm_tlmm_irq_chip *)data;
	struct irq_desc *desc = irq_to_desc(irq);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	struct msm_pintype_info *pinfo = ic_to_pintype(ic);
@@ -648,6 +649,7 @@ static struct msm_tlmm_irq_chip msm_tlmm_v3_gp_irq = {
			},
			.apps_id = TLMMV3_APPS_ID_DEFAULT,
			.domain_ops = &msm_tlmm_v3_gp_irqd_ops,
			.handler = msm_tlmm_v3_gp_handle_irq,
};

/* Power management core operations */
@@ -695,17 +697,10 @@ static struct syscore_ops msm_tlmm_v3_irq_syscore_ops = {
static int msm_tlmm_v3_gp_irq_init(int irq, struct msm_pintype_info *pinfo,
						struct device *tlmm_dev)
{
	int ret, num_irqs;
	int num_irqs;
	struct msm_tlmm_irq_chip *ic = pinfo->irq_chip;

	num_irqs = ic->num_irqs;
	ret = devm_request_irq(tlmm_dev, irq, msm_tlmm_v3_irq_handle,
						IRQF_TRIGGER_HIGH,
						dev_name(tlmm_dev), ic);
	if (ret) {
		dev_err(tlmm_dev, "unable to register irq %d\n", irq);
		return ret;
	}
	ic->enabled_irqs = devm_kzalloc(tlmm_dev, sizeof(unsigned long)
					* BITS_TO_LONGS(num_irqs), GFP_KERNEL);
	if (IS_ERR(ic->enabled_irqs)) {
@@ -734,6 +729,30 @@ static int msm_tlmm_v3_gp_irq_init(int irq, struct msm_pintype_info *pinfo,
	return 0;
}

static irqreturn_t msm_tlmm_v3_handle_irq(int irq, void *data)
{
	int i, num_pintypes;
	struct msm_pintype_info *pintypes, *pintype;
	struct msm_tlmm_irq_chip *ic;
	struct msm_tlmm_desc *tlmm_desc = (struct msm_tlmm_desc *)data;
	irqreturn_t ret = IRQ_NONE;

	pintypes = tlmm_desc->pintypes;
	num_pintypes = tlmm_desc->num_pintypes;
	for (i = 0; i < num_pintypes; i++) {
		pintype = &pintypes[i];
		if (!pintype->irq_chip)
			continue;
		ic = pintype->irq_chip;
		if (!ic->node)
			continue;
		ret = ic->handler(irq, ic);
		if (ret != IRQ_HANDLED)
			break;
	}
	return ret;
}

static struct msm_pintype_info tlmm_v3_pininfo[] = {
	{
		.prg_cfg = msm_tlmm_v3_gp_cfg,
@@ -767,3 +786,78 @@ struct msm_tlmm_pintype tlmm_v3_pintypes = {
	.pintype_info = tlmm_v3_pininfo,
};

static const struct of_device_id msm_tlmm_v3_dt_match[] = {
	{ .compatible = "qcom,msm-tlmm-v3",
		.data = &tlmm_v3_pintypes, },
	{},
};
MODULE_DEVICE_TABLE(of, msm_tlmm_v3_dt_match);

static int msm_tlmm_v3_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	const struct msm_tlmm_pintype *pinfo;
	struct msm_tlmm_desc *tlmm_desc;
	int irq, ret;
	struct resource *res;
	struct device_node *node = pdev->dev.of_node;

	match = of_match_node(msm_tlmm_v3_dt_match, node);
	if (IS_ERR(match))
		return PTR_ERR(match);
	pinfo = match->data;
	tlmm_desc = devm_kzalloc(&pdev->dev, sizeof(*tlmm_desc), GFP_KERNEL);
	if (!tlmm_desc) {
		dev_err(&pdev->dev, "Alloction failed for tlmm desc\n");
		return -ENOMEM;
	}
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "cannot find IO resource\n");
		return -ENOENT;
	}
	tlmm_desc->base = devm_ioremap(&pdev->dev, res->start,
							resource_size(res));
	if (IS_ERR(tlmm_desc->base))
		return PTR_ERR(tlmm_desc->base);
	tlmm_desc->irq = -EINVAL;
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res) {
		irq = res->start;
		ret = devm_request_irq(&pdev->dev, irq, msm_tlmm_v3_handle_irq,
							IRQF_TRIGGER_HIGH,
							dev_name(&pdev->dev),
							tlmm_desc);
		if (ret) {
			dev_err(&pdev->dev, "register for irq failed\n");
			return ret;
		}
		tlmm_desc->irq = irq;
	}
	tlmm_desc->pintypes = pinfo->pintype_info;
	tlmm_desc->num_pintypes = pinfo->num_entries;
	return msm_pinctrl_probe(pdev, tlmm_desc);
}

static struct platform_driver msm_tlmm_v3_drv = {
	.probe		= msm_tlmm_v3_probe,
	.driver = {
		.name	= "msm-tlmmv3-pinctrl",
		.owner	= THIS_MODULE,
		.of_match_table = of_match_ptr(msm_tlmm_v3_dt_match),
	},
};

static int __init msm_tlmm_v3_drv_register(void)
{
	return platform_driver_register(&msm_tlmm_v3_drv);
}
postcore_initcall(msm_tlmm_v3_drv_register);

static void __exit msm_tlmm_v3_drv_unregister(void)
{
	platform_driver_unregister(&msm_tlmm_v3_drv);
}
module_exit(msm_tlmm_v3_drv_unregister);

MODULE_LICENSE("GPLv2");
+7 −53
Original line number Diff line number Diff line
@@ -643,12 +643,6 @@ alloc_fail:
	return -ENOMEM;
}

static const struct of_device_id msm_pinctrl_dt_match[] = {
	{ .compatible = "qcom,msm-tlmm-v3",
		.data = &tlmm_v3_pintypes, },
	{},
};
MODULE_DEVICE_TABLE(of, msm_pinctrl_dt_match);

static void msm_pinctrl_cleanup_dd(struct msm_pinctrl_dd *dd)
{
@@ -665,17 +659,9 @@ static void msm_pinctrl_cleanup_dd(struct msm_pinctrl_dd *dd)
static int msm_pinctrl_get_drvdata(struct msm_pinctrl_dd *dd,
						struct platform_device *pdev)
{
	const struct of_device_id *match;
	const struct msm_tlmm_pintype *tlmm_info;
	int ret;
	struct device_node *node = pdev->dev.of_node;

	match = of_match_node(msm_pinctrl_dt_match, node);
	if (IS_ERR(match))
		return PTR_ERR(match);
	tlmm_info = match->data;
	dd->msm_pintype = tlmm_info->pintype_info;
	dd->num_pintypes = tlmm_info->num_entries;
	ret = msm_pinctrl_dt_parse_pintype(node, dd);
	if (ret)
		goto out;
@@ -777,11 +763,11 @@ static int msm_register_irqchip(struct msm_pinctrl_dd *dd)
	return 0;
}

static int msm_pinctrl_probe(struct platform_device *pdev)
int msm_pinctrl_probe(struct platform_device *pdev,
					struct msm_tlmm_desc *tlmm_info)
{
	struct msm_pinctrl_dd *dd;
	struct device *dev = &pdev->dev;
	struct resource *res;
	int ret;

	dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
@@ -789,20 +775,11 @@ static int msm_pinctrl_probe(struct platform_device *pdev)
		dev_err(dev, "Alloction failed for driver data\n");
		return -ENOMEM;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "cannot find IO resource\n");
		return -ENOENT;
	}
	dd->base = devm_ioremap(&pdev->dev, res->start,
							resource_size(res));
	if (IS_ERR(dd->base))
		return PTR_ERR(dd->base);
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res)
		dd->irq = res->start;
	dd->dev = dev;
	dd->msm_pintype = tlmm_info->pintypes;
	dd->base = tlmm_info->base;
	dd->irq = tlmm_info->irq;
	dd->num_pintypes = tlmm_info->num_pintypes;
	ret = msm_pinctrl_get_drvdata(dd, pdev);
	if (ret) {
		dev_err(&pdev->dev, "driver data not available\n");
@@ -818,27 +795,4 @@ static int msm_pinctrl_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, dd);
	return 0;
}

static struct platform_driver msm_pinctrl_driver = {
	.probe		= msm_pinctrl_probe,
	.driver = {
		.name	= "msm-pinctrl",
		.owner	= THIS_MODULE,
		.of_match_table = of_match_ptr(msm_pinctrl_dt_match),
	},
};

static int __init msm_pinctrl_drv_register(void)
{
	return platform_driver_register(&msm_pinctrl_driver);
}
postcore_initcall(msm_pinctrl_drv_register);

static void __exit msm_pinctrl_drv_unregister(void)
{
	platform_driver_unregister(&msm_pinctrl_driver);
}
module_exit(msm_pinctrl_drv_unregister);

MODULE_LICENSE("GPLv2");
EXPORT_SYMBOL(msm_pinctrl_probe);
+20 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/machine.h>
#include <linux/platform_device.h>

/**
 * struct msm_pin_group: group of pins having the same pinmux function.
@@ -60,6 +61,7 @@ struct msm_pmx_funcs {
 * @dev: TLMM device.
 * @device_node: device tree node of interrupt controller.
 * @pinfo: pintype information.
 * @handler: irq handler for given pintype interrupt controller
 */
struct msm_tlmm_irq_chip {
	int irq;
@@ -77,6 +79,7 @@ struct msm_tlmm_irq_chip {
	struct device *dev;
	struct device_node *node;
	void *pinfo;
	irqreturn_t (*handler)(int irq, struct msm_tlmm_irq_chip *ic);
};

/**
@@ -140,7 +143,22 @@ struct msm_pindesc {
	char name[20];
};

/* TLMM version specific data */
extern struct msm_tlmm_pintype tlmm_v3_pintypes;
/**
 * struct msm_tlmm_desc: descriptor for the TLMM hardware block
 * @base: base address of tlmm desc.
 * @irq: summary irq number for tlmm block. Must be > 0 if present.
 * @num_pintypes: Number of pintypes on the tlmm block for a given SOC.
 * @pintypes: pintypes supported on a given TLMM block for a given SOC.
 */
struct msm_tlmm_desc {
	void __iomem *base;
	int irq;
	unsigned int num_pintypes;
	struct msm_pintype_info *pintypes;
};

/* Common probe for all TLMM */
int msm_pinctrl_probe(struct platform_device *pdev,
					struct msm_tlmm_desc *tlmm_info);
#endif