All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lina Iyer <ilina@codeaurora.org>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: jason@lakedaemon.net, marc.zyngier@arm.com,
	linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	sboyd@codeaurora.org, rnayak@codeaurora.org,
	asathyak@codeaurora.org
Subject: Re: [PATCH RFC v2 1/3] drivers: irqchip: pdc: Add PDC interrupt controller for QCOM SoCs
Date: Fri, 2 Feb 2018 16:41:02 +0000	[thread overview]
Message-ID: <20180202164102.GB5319@codeaurora.org> (raw)
In-Reply-To: <alpine.DEB.2.21.1802021551150.1472@nanos.tec.linutronix.de>

All valid comments. Will fix them all in the next rev.

Thanks Thomas.

-- Lina

On Fri, Feb 02 2018 at 15:37 +0000, Thomas Gleixner wrote:
>On Fri, 2 Feb 2018, Lina Iyer wrote:
>> +static inline void pdc_enable_intr(struct irq_data *d, bool on)
>> +{
>> +	int pin_out = d->hwirq;
>> +	u32 index, mask;
>> +	u32 enable;
>> +	unsigned long flags;
>> +
>> +	index = pin_out / 32;
>> +	mask = pin_out % 32;
>> +
>> +	spin_lock_irqsave(&pdc_lock, flags);
>
>Please make this a raw spinlock. Aside of that the _irqsave() is pointless
>as the chip callbacks are already called with interrupts disabled.
>
>> +	enable = pdc_reg_read(IRQ_ENABLE_BANK, index);
>> +	enable = on ? ENABLE_INTR(enable, mask) : CLEAR_INTR(enable, mask);
>
>You really should cache the enable register content to avoid the read back
>
>> +	pdc_reg_write(IRQ_ENABLE_BANK, index, enable);
>> +	spin_unlock_irqrestore(&pdc_lock, flags);
>> +}
>> +
>> +static void qcom_pdc_gic_mask(struct irq_data *d)
>> +{
>> +	pdc_enable_intr(d, false);
>> +	irq_chip_mask_parent(d);
>> +}
>> +
>> +static void qcom_pdc_gic_unmask(struct irq_data *d)
>> +{
>> +	pdc_enable_intr(d, true);
>> +	irq_chip_unmask_parent(d);
>> +}
>> +
>> +/*
>> + * GIC does not handle falling edge or active low. To allow falling edge and
>> + * active low interrupts to be handled at GIC, PDC has an inverter that inverts
>> + * falling edge into a rising edge and active low into an active high.
>> + * For the inverter to work, the polarity bit in the IRQ_CONFIG register has to
>> + * set as per the table below.
>> + * (polarity, falling edge, rising edge ) POLARITY
>> + * 3'b0 00  Level sensitive active low    LOW
>> + * 3'b0 01  Rising edge sensitive         NOT USED
>> + * 3'b0 10  Falling edge sensitive        LOW
>> + * 3'b0 11  Dual Edge sensitive           NOT USED
>> + * 3'b1 00  Level senstive active High    HIGH
>> + * 3'b1 01  Falling Edge sensitive        NOT USED
>> + * 3'b1 10  Rising edge sensitive         HIGH
>> + * 3'b1 11  Dual Edge sensitive           HIGH
>> + */
>> +enum pdc_irq_config_bits {
>> +	PDC_POLARITY_LOW	= 0, // 0 00
>
>What's wrong with
>
>       PDC_POLARITY_LOW		= 000b,
>       PDC_FALLING_EDGE		= 010b,
>
>instead of decimal and these weird comments ?
>
>> +static irq_hw_number_t get_irq_for_pin(int pin, struct pdc_pin_data *pdc_data)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; pdc_data[i].pin >= 0; i++)
>> +		if (pdc_data[i].pin == pin)
>> +			return pdc_data[i].hwirq;
>
>Please let the for() loop have braces. See:
>
>       https://marc.info/?l=linux-kernel&m=148467980905537&w=2
>
>> +
>> +	return pin;
>> +}
>> +
>> +static int qcom_pdc_translate(struct irq_domain *d,
>> +	struct irq_fwspec *fwspec, unsigned long *hwirq, unsigned int *type)
>
>Please align the arguments right of the opening brace:
>
>static int qcom_pdc_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 < 3)
>> +			return -EINVAL;
>> +
>> +		*hwirq = fwspec->param[1];
>> +		*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
>> +		return 0;
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>> +
>> +static int qcom_pdc_alloc(struct irq_domain *domain,
>> +			unsigned int virq, unsigned int nr_irqs, void *data)
>
>Ditto
>
>> +static int pdc_setup_pin_mapping(struct device_node *np,
>> +				struct pdc_pin_data **data)
>> +{
>> +	int ret;
>> +	int n, i, j, k, pins = 0;
>> +	int *val;
>
>I have no idea what's the rationale behind these 3 lines of int declarations.
>
>> +	struct pdc_pin_data *map;
>> +
>> +	n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
>> +	if (!n || n % 3)
>> +		return -EINVAL;
>> +
>> +	val = kcalloc(n, sizeof(u32), GFP_KERNEL);
>> +	if (!val)
>> +		return -ENOMEM;
>> +
>> +	ret = of_property_read_u32_array(np, "qcom,pdc-ranges", val, n);
>> +	if (ret)
>> +		return ret;
>> +
>> +	for (i = 0; i < n; i += 3)
>> +		pins += val[i + 2];
>> +
>> +	if (pins > PDC_MAX_IRQS)
>> +		return -EFAULT;
>> +
>> +	map = kcalloc(pins + 1, sizeof(*map), GFP_KERNEL);
>> +	if (!map) {
>> +		ret = -ENOMEM;
>> +		goto fail;
>> +	}
>> +
>> +	for (i = 0, k = 0; i < n; i += 3) {
>> +		for (j = 0; j < val[i + 2]; j++, k++) {
>> +			map[k].pin = val[i] + j;
>> +			map[k].hwirq = val[i + 1] + j;
>> +		}
>> +	}
>
>This all is really horrible to read. First of all the val[] array. That can
>be represented in a structure, right? Without looking at the DT patch the
>code lets me assume:
>
>   struct pdcrange {
>   	u32	pin;
>	u32	hwirq;
>	u32	numpins;
>	u32	unused;
>   };
>
>So the above becomes:
>
>	nelm = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
>	if (!nelm || nelm % 3)
>		return -EINVAL;
>
>	nranges = nelm / 4;
>	ranges = kcalloc(nranges, sizeof(*prng), GFP_KERNEL);
>	if (!ranges)
>		return -ENOMEM;
>
>which makes the pin counting readable:
>
>	for (i = 0; i < nranges; i++)
>		pins += ranges[i].numpins;
>
>And then allows to write the map initialization with:
>
>	*data = map;
>	for (i = 0; i < nranges; i++) {
>		for (j = 0; j < ranges[i].numpins; j++, map++) {
>			map->pin = ranges[i].pin + j;
>			map->hwirq = ranges[i].hwirq + j;
>		}
>	}
>	map->pin = -1;
>
>Hmm?
>
>> +int qcom_pdc_init(struct device_node *node, struct device_node *parent)
>> +{
>> +	struct irq_domain *parent_domain, *pdc_domain;
>> +	struct pdc_pin_data *pdc_data = NULL;
>> +	int ret;
>> +
>> +	pdc_base = of_iomap(node, 0);
>> +	if (!pdc_base) {
>> +		pr_err("%s(): unable to map PDC registers\n", node->full_name);
>> +		return -ENXIO;
>> +	}
>> +
>> +	parent_domain = irq_find_host(parent);
>> +	if (!parent_domain) {
>> +		pr_err("unable to obtain PDC parent domain\n");
>> +		ret = -ENXIO;
>> +		goto failure;
>> +	}
>> +
>> +	ret = pdc_setup_pin_mapping(node, &pdc_data);
>
>You can let pdc_setup_pin_mapping() return a pointer to pdc_data or NULL
>and check the pointer for ERR or NULL instead of having that ret
>indirection.
>
>> +	if (ret) {
>> +		pr_err("failed to setup PDC pin mapping\n");
>> +		goto failure;
>> +	}
>> +
>> +	pdc_domain = irq_domain_create_hierarchy(parent_domain, 0, PDC_MAX_IRQS,
>> +					of_fwnode_handle(node), &qcom_pdc_ops,
>> +					pdc_data);
>
>See comment about argument alignement above. Hint: shortening the *_domain
>variable names helps.
>
>Thanks,
>
>	tglx

  reply	other threads:[~2018-02-02 16:41 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-02 14:21 [PATCH RFC v2 0/3] irqchip: qcom: add support for PDC interrupt controller Lina Iyer
2018-02-02 14:21 ` [PATCH RFC v2 1/3] drivers: irqchip: pdc: Add PDC interrupt controller for QCOM SoCs Lina Iyer
2018-02-02 14:58   ` Marc Zyngier
2018-02-02 16:40     ` Lina Iyer
2018-02-23 12:16     ` Rasmus Villemoes
2018-02-23 13:37       ` Marc Zyngier
2018-02-23 13:58         ` Rasmus Villemoes
2018-02-02 15:37   ` Thomas Gleixner
2018-02-02 16:41     ` Lina Iyer [this message]
     [not found] ` <20180202142200.6229-1-ilina-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-02-02 14:21   ` [PATCH RFC v2 2/3] dt-bindings/interrupt-controller: pdc: descibe PDC device binding Lina Iyer
2018-02-02 14:21     ` Lina Iyer
2018-02-02 16:28     ` Marc Zyngier
     [not found]       ` <396cfc2f-7deb-0c93-7178-d9f5524f110e-5wv7dgnIgG8@public.gmane.org>
2018-02-02 16:46         ` Lina Iyer
2018-02-02 16:46           ` Lina Iyer
2018-02-02 17:02           ` Marc Zyngier
2018-02-02 14:22 ` [PATCH RFC v2 3/3] drivers: irqchip: pdc: log PDC info in FTRACE Lina Iyer
2018-02-02 15:57   ` Thomas Gleixner
2018-02-02 23:02     ` Lina Iyer
2018-02-05 15:18       ` Lina Iyer
2018-02-05 16:57         ` Steven Rostedt
2018-02-02 16:32   ` Steven Rostedt
2018-02-02 22:53     ` Lina Iyer
2018-02-05 15:50   ` Lina Iyer
2018-02-05 17:00     ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180202164102.GB5319@codeaurora.org \
    --to=ilina@codeaurora.org \
    --cc=asathyak@codeaurora.org \
    --cc=jason@lakedaemon.net \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=rnayak@codeaurora.org \
    --cc=sboyd@codeaurora.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.