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

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

Merge "drivers: irqchip: qcom: Add MSM8953 gpio pin data for MPM"

parents 9f5b441e c8aad111
Loading
Loading
Loading
Loading
+41 −14
Original line number Diff line number Diff line
@@ -8,13 +8,16 @@ replays it to the subsystem interrupt controller after it becomes operational.

Platform interrupt controller MPM is next in hierarchy, followed by others.

This defines 2 interrupt controllers to monitor the interrupts when the system is asleep:

One for to monitor the wakeup capable gic interrupts called wakegic.

Properties:

- compatible:
	Usage: required
	Value type: <string>
	Definition: Should contain "qcom,mpm" for mpm pin data
	and the respective target compatible flag.
	Definition: Should contain "qcom,mpm-gic" and the respective target compatible flag.

- interrupts:
	Usage: required
@@ -48,18 +51,42 @@ Properties:

Example:

mpm: mpm@7781b8 {
	compatible = "qcom,mpm";
wakegic: wake-gic@7781b8 {
	compatible = "qcom,mpm-gic", "qcom,mpm-gic-msm8953";
	interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>;
	reg = <0x7781b8 0x1000>,
	    <0x17911008 0x4>;   /* MSM_APCS_GCC_BASE 4K */
	reg = <0x601d4 0x1000>,
	    <0xb011008 0x4>;  /* MSM_APCS_GCC_BASE 4K */
	reg-names = "vmpm", "ipc";
	qcom,num-mpm-irqs = <96>;

	wakegic: wake-gic {
		compatible = "qcom,mpm-gic", "qcom,mpm-gic-msm8953";
	interrupt-controller;
		#interrupt-cells = <3>;
	interrupt-parent = <&intc>;
	#interrupt-cells = <3>;
};


One for to monitor the wakeup capable gpio interrupts called wakegpio.

properties:

- compatible:
	Usage: required
	Value type: <string>
	Definition: Should contain "qcom,mpm-gpio" and the respective target compatible flag.

- interrupt-parent:
	Usage: required
	Value type: <phandle>
	Definition: Specifies the interrupt parent necessary for hierarchical domain to operate.

- interrupt-controller:
	Usage: required
	Value type: <bool>
	Definition: Identifies the node as an interrupt controller.

Example:

wakegpio: wake-gpio {
	compatible = "qcom,mpm-gpio", "qcom,mpm-gpio-msm8953";
	interrupt-controller;
	interrupt-parent = <&tlmm>;
	#interrupt-cells = <2>;
};
+57 −0
Original line number Diff line number Diff line
@@ -22,3 +22,60 @@ const struct mpm_pin mpm_msm8953_gic_chip_data[] = {
	{88, 222}, /* ee0_krait_hlos_spmi_periph_irq */
	{-1},
};

const struct mpm_pin mpm_msm8953_gpio_chip_data[] = {
	{3, 38},
	{4, 1},
	{5, 5},
	{6, 9},
	{8, 37},
	{9, 36},
	{10, 13},
	{11, 35},
	{12, 17},
	{13, 21},
	{14, 54},
	{15, 34},
	{16, 31},
	{17, 58},
	{18, 28},
	{19, 42},
	{20, 25},
	{21, 12},
	{22, 43},
	{23, 44},
	{24, 45},
	{25, 46},
	{26, 48},
	{27, 65},
	{28, 93},
	{29, 97},
	{30, 63},
	{31, 70},
	{32, 71},
	{33, 72},
	{34, 81},
	{35, 85},
	{36, 90},
	{50, 67},
	{51, 73},
	{52, 74},
	{53, 62},
	{59, 59},
	{60, 60},
	{61, 61},
	{62, 86},
	{63, 87},
	{64, 91},
	{65, 129},
	{66, 130},
	{67, 131},
	{68, 132},
	{69, 133},
	{70, 137},
	{71, 138},
	{72, 139},
	{73, 140},
	{74, 141},
	{-1},
};
+156 −22
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ struct msm_mpm_device_data {
	void __iomem *mpm_ipc_reg;
	irq_hw_number_t ipc_irq;
	struct irq_domain *gic_chip_domain;
	struct irq_domain *gpio_chip_domain;
};

static int msm_pm_sleep_time_override;
@@ -200,19 +201,19 @@ static inline void msm_mpm_set_type(struct irq_data *d,
	}
}

static void msm_mpm_gic_chip_mask(struct irq_data *d)
static void msm_mpm_chip_mask(struct irq_data *d)
{
	msm_mpm_enable_irq(d, false);
	irq_chip_mask_parent(d);
}

static void msm_mpm_gic_chip_unmask(struct irq_data *d)
static void msm_mpm_chip_unmask(struct irq_data *d)
{
	msm_mpm_enable_irq(d, true);
	irq_chip_unmask_parent(d);
}

static int msm_mpm_gic_chip_set_type(struct irq_data *d, unsigned int type)
static int msm_mpm_chip_set_type(struct irq_data *d, unsigned int type)
{
	msm_mpm_set_type(d, type);
	return irq_chip_set_type_parent(d, type);
@@ -221,15 +222,70 @@ static int msm_mpm_gic_chip_set_type(struct irq_data *d, unsigned int type)
static struct irq_chip msm_mpm_gic_chip = {
	.name		= "mpm-gic",
	.irq_eoi	= irq_chip_eoi_parent,
	.irq_mask	= msm_mpm_gic_chip_mask,
	.irq_disable	= msm_mpm_gic_chip_mask,
	.irq_unmask	= msm_mpm_gic_chip_unmask,
	.irq_mask	= msm_mpm_chip_mask,
	.irq_disable	= msm_mpm_chip_mask,
	.irq_unmask	= msm_mpm_chip_unmask,
	.irq_retrigger	= irq_chip_retrigger_hierarchy,
	.irq_set_type	= msm_mpm_gic_chip_set_type,
	.irq_set_type	= msm_mpm_chip_set_type,
	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
#ifdef CONFIG_SMP
	.irq_set_affinity	= irq_chip_set_affinity_parent,
#endif
};

static struct irq_chip msm_mpm_gpio_chip = {
	.name		= "mpm-gpio",
	.irq_mask	= msm_mpm_chip_mask,
	.irq_disable	= msm_mpm_chip_mask,
	.irq_unmask	= msm_mpm_chip_unmask,
	.irq_set_type	= msm_mpm_chip_set_type,
	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
	.irq_retrigger          = irq_chip_retrigger_hierarchy,
	.irq_set_vcpu_affinity  = irq_chip_set_vcpu_affinity_parent,
	.irq_eoi                = irq_chip_eoi_parent,
	.irq_set_affinity	= irq_chip_set_affinity_parent,
};

static int msm_mpm_gpio_chip_translate(struct irq_domain *d,
		struct irq_fwspec *fwspec,
		unsigned long *hwirq,
		unsigned int *type)
{
	if (is_of_node(fwspec->fwnode)) {
		if (fwspec->param_count != 2)
			return -EINVAL;
		*hwirq = fwspec->param[0];
		*type = fwspec->param[1];
		return 0;
	}
	return -EINVAL;
}

static int msm_mpm_gpio_chip_alloc(struct irq_domain *domain,
		unsigned int virq,
		unsigned int nr_irqs,
		void *data)
{
	int ret = 0;
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	irq_hw_number_t hwirq;
	unsigned int type = IRQ_TYPE_NONE;

	ret = msm_mpm_gpio_chip_translate(domain, fwspec, &hwirq, &type);
	if (ret)
		return ret;

	irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
				&msm_mpm_gpio_chip, NULL);
	parent_fwspec = *fwspec;
	parent_fwspec.fwnode = domain->parent->fwnode;
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
					    &parent_fwspec);
}

static const struct irq_domain_ops msm_mpm_gpio_chip_domain_ops = {
	.translate	= msm_mpm_gpio_chip_translate,
	.alloc		= msm_mpm_gpio_chip_alloc,
	.free		= irq_domain_free_irqs_common,
};

static int msm_mpm_gic_chip_translate(struct irq_domain *d,
@@ -296,16 +352,21 @@ static void msm_mpm_enter_sleep(struct cpumask *cpumask)
	irq_set_affinity(msm_mpm_dev_data.ipc_irq, cpumask);
}

static int msm_get_mpm_pin_map(unsigned int mpm_irq)
static int msm_get_apps_irq(unsigned int mpm_irq)
{
	struct mpm_pin *mpm_gic_pin_map = NULL;
	struct mpm_pin *mpm_pin = NULL;
	int apps_irq;

	mpm_gic_pin_map = (struct mpm_pin *)
	mpm_pin = (struct mpm_pin *)
		msm_mpm_dev_data.gic_chip_domain->host_data;
	apps_irq = msm_get_irq_pin(mpm_irq, mpm_gic_pin_map);
	apps_irq = msm_get_irq_pin(mpm_irq, mpm_pin);
	if (apps_irq >= 0)
		return apps_irq;

	mpm_pin = (struct mpm_pin *)
		msm_mpm_dev_data.gpio_chip_domain->host_data;
	return  msm_get_irq_pin(mpm_irq, mpm_pin);

}

static void system_pm_exit_sleep(void)
@@ -407,7 +468,7 @@ static irqreturn_t msm_mpm_irq(int irq, void *dev_id)
		trace_mpm_wakeup_pending_irqs(i, pending);
		for_each_set_bit(k, &pending, 32) {
			mpm_irq = 32 * i + k;
			apps_irq = msm_get_mpm_pin_map(mpm_irq);
			apps_irq = msm_get_apps_irq(mpm_irq);
			desc = apps_irq ?
				irq_to_desc(apps_irq) : NULL;

@@ -420,7 +481,7 @@ static irqreturn_t msm_mpm_irq(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static int msm_mpm_probe(struct device_node *node)
static int msm_mpm_init(struct device_node *node)
{
	struct msm_mpm_device_data *dev = &msm_mpm_dev_data;
	int ret = 0;
@@ -485,12 +546,22 @@ static const struct of_device_id mpm_gic_chip_data_table[] = {

MODULE_DEVICE_TABLE(of, mpm_gic_chip_data_table);

static const struct of_device_id mpm_gpio_chip_data_table[] = {
	{
		.compatible = "qcom,mpm-gpio-msm8953",
		.data = mpm_msm8953_gpio_chip_data,
	},
	{}
};

MODULE_DEVICE_TABLE(of, mpm_gpio_chip_data_table);

static int __init mpm_gic_chip_init(struct device_node *node,
					struct device_node *parent)
{
	struct irq_domain *parent_domain;
	const struct of_device_id *id;
	struct device_node *parent_node;
	int ret;

	if (!parent) {
		pr_err("%s(): no parent for mpm-gic\n", node->full_name);
@@ -512,7 +583,8 @@ static int __init mpm_gic_chip_init(struct device_node *node,
	id = of_match_node(mpm_gic_chip_data_table, node);
	if (!id) {
		pr_err("can not find mpm_gic_data_table of_node\n");
		return -ENODEV;
		ret = -ENODEV;
		goto mpm_map_err;
	}

	msm_mpm_dev_data.gic_chip_domain = irq_domain_add_hierarchy(
@@ -520,13 +592,75 @@ static int __init mpm_gic_chip_init(struct device_node *node,
			&msm_mpm_gic_chip_domain_ops, (void *)id->data);
	if (!msm_mpm_dev_data.gic_chip_domain) {
		pr_err("gic domain add failed\n");
		return -ENOMEM;
		ret = -ENOMEM;
		goto mpm_map_err;
	}

	msm_mpm_dev_data.gic_chip_domain->name = "qcom,mpm-gic";

	parent_node = of_get_parent(node);
	return msm_mpm_probe(parent_node);
	ret = msm_mpm_init(node);
	if (!ret)
		return ret;
	irq_domain_remove(msm_mpm_dev_data.gic_chip_domain);

mpm_map_err:
	kfree(mpm_to_irq);
	return ret;
}

IRQCHIP_DECLARE(mpm_gic_chip, "qcom,mpm-gic", mpm_gic_chip_init);

static int mpm_gpio_chip_probe(struct platform_device *pdev)
{
	struct device_node *node, *parent;
	struct irq_domain *parent_domain;
	const struct of_device_id *id;

	node = pdev->dev.of_node;
	parent = of_irq_find_parent(node);
	if (!parent) {
		pr_err("%s(): no parent for mpm-gpio\n", node->full_name);
		return -ENXIO;
	}
	parent_domain = irq_find_host(parent);
	if (!parent_domain) {
		pr_err("unable to obtain gpio parent domain defer probe\n");
		return -EPROBE_DEFER;
	}
	id = of_match_node(mpm_gpio_chip_data_table, node);
	if (!id) {
		pr_err("match_table not found for mpm-gpio\n");
		return -ENODEV;
	}

	msm_mpm_dev_data.gpio_chip_domain = irq_domain_add_hierarchy(
			parent_domain, 0, num_mpm_irqs, node,
			&msm_mpm_gpio_chip_domain_ops, (void *)id->data);

	if (!msm_mpm_dev_data.gpio_chip_domain)
		return -ENOMEM;

	msm_mpm_dev_data.gpio_chip_domain->name = "qcom,mpm-gpio";

	return 0;
}

static const struct of_device_id msm_mpm_dt_match[] = {
	{ .compatible = "qcom,mpm-gpio"},
	{ },
};

static struct platform_driver msm_mpm_driver = {
	.probe = mpm_gpio_chip_probe,
	.driver = {
		.name = "qcom,mpm-gpio",
		.of_match_table = msm_mpm_dt_match,
	},
};

static int __init msm_mpm_gpio_init(void)
{
	return platform_driver_register(&msm_mpm_driver);
}

arch_initcall(msm_mpm_gpio_init)
+1 −0
Original line number Diff line number Diff line
@@ -22,5 +22,6 @@ struct mpm_pin {
};

extern const struct mpm_pin mpm_msm8953_gic_chip_data[];
extern const struct mpm_pin mpm_msm8953_gpio_chip_data[];

#endif /* __QCOM_MPM_H__ */