aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/python/stat-cpi.py
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2017-06-02 20:18:47 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2017-06-02 20:53:19 -0400
commit8d4b31376974855cd4fb176e5d63ba8e0407928e (patch)
treed3fa2356a1aa37333f33087fbade8aec1f075fdd /tools/perf/scripts/python/stat-cpi.py
parenteadcbfa58ae8693f0d6a0f591d8f51d55cf068e1 (diff)
Input: axp20x-pek - only check for "INTCFD9" ACPI device on Cherry Trail
Commit 9b13a4ca8d2c ("Input: axp20x-pek - do not register input device on some systems") added a check for the INTCFD9 ACPI device which also handles the powerbutton as on some systems the powerbutton is connected to both the PMIC, handled by axp20x-pek, and to a gpio on the SoC, handled by soc_button_array which attaches itself to the INTCFD9 ACPI device. Testing + comparing DSDTs has shown that this only happens on Cherry Trail devices with an AXP288 PMIC, the AXP288 PMIC is also used on Bay Trail devices but there the power button is only connected to the PMIC and not handled by soc_button_array. This means that the INTCFD9 check has caused a regression on Bay Trail devices, causing power-button presses to no longer be seen. This commit fixes this by limiting the check to devices where the ACPI node for the AXP288 contains a _HRV (hardware revision) attribute with a value of 3 which indicates we are dealing with a Cherry Trail platform. Fixes: 9b13a4ca8d2c ("Input: axp20x-pek - do not register input ...") Reported-by: Сергей Трусов <t.rus76@ya.ru> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'tools/perf/scripts/python/stat-cpi.py')
0 files changed, 0 insertions, 0 deletions
ref='#n165'>165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
/*
 * Celleb/Beat Interrupt controller
 *
 * (C) Copyright 2006-2007 TOSHIBA CORPORATION
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/percpu.h>
#include <linux/types.h>

#include <asm/machdep.h>

#include "beat_interrupt.h"
#include "beat_wrapper.h"

#define	MAX_IRQS	NR_IRQS
static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
static uint64_t	beatic_irq_mask_enable[(MAX_IRQS+255)/64];
static uint64_t	beatic_irq_mask_ack[(MAX_IRQS+255)/64];

static struct irq_host *beatic_host;

/*
 * In this implementation, "virq" == "IRQ plug number",
 * "(irq_hw_number_t)hwirq" == "IRQ outlet number".
 */

/* assumption: locked */
static inline void beatic_update_irq_mask(unsigned int irq_plug)
{
	int off;
	unsigned long masks[4];

	off = (irq_plug / 256) * 4;
	masks[0] = beatic_irq_mask_enable[off + 0]
		& beatic_irq_mask_ack[off + 0];
	masks[1] = beatic_irq_mask_enable[off + 1]
		& beatic_irq_mask_ack[off + 1];
	masks[2] = beatic_irq_mask_enable[off + 2]
		& beatic_irq_mask_ack[off + 2];
	masks[3] = beatic_irq_mask_enable[off + 3]
		& beatic_irq_mask_ack[off + 3];
	if (beat_set_interrupt_mask(irq_plug&~255UL,
		masks[0], masks[1], masks[2], masks[3]) != 0)
		panic("Failed to set mask IRQ!");
}

static void beatic_mask_irq(struct irq_data *d)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
	beatic_irq_mask_enable[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
	beatic_update_irq_mask(d->irq);
	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}

static void beatic_unmask_irq(struct irq_data *d)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
	beatic_irq_mask_enable[d->irq/64] |= 1UL << (63 - (d->irq%64));
	beatic_update_irq_mask(d->irq);
	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}

static void beatic_ack_irq(struct irq_data *d)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
	beatic_irq_mask_ack[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
	beatic_update_irq_mask(d->irq);
	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}

static void beatic_end_irq(struct irq_data *d)
{
	s64 err;
	unsigned long flags;

	err = beat_downcount_of_interrupt(d->irq);
	if (err != 0) {
		if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */
			panic("Failed to downcount IRQ! Error = %16llx", err);

		printk(KERN_ERR "IRQ over-downcounted, plug %d\n", d->irq);
	}
	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
	beatic_irq_mask_ack[d->irq/64] |= 1UL << (63 - (d->irq%64));
	beatic_update_irq_mask(d->irq);
	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}

static struct irq_chip beatic_pic = {
	.name = "CELL-BEAT",
	.irq_unmask = beatic_unmask_irq,
	.irq_mask = beatic_mask_irq,
	.irq_eoi = beatic_end_irq,
};

/*
 * Dispose binding hardware IRQ number (hw) and Virtuql IRQ number (virq),
 * update flags.
 *
 * Note that the number (virq) is already assigned at upper layer.
 */
static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
{
	beat_destruct_irq_plug(virq);
}

/*
 * Create or update binding hardware IRQ number (hw) and Virtuql
 * IRQ number (virq). This is called only once for a given mapping.
 *
 * Note that the number (virq) is already assigned at upper layer.
 */
static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
			       irq_hw_number_t hw)
{
	int64_t	err;

	err = beat_construct_and_connect_irq_plug(virq, hw);
	if (err < 0)
		return -EIO;

	irq_set_status_flags(virq, IRQ_LEVEL);
	irq_set_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq);
	return 0;
}

/*
 * Translate device-tree interrupt spec to irq_hw_number_t style (ulong),
 * to pass away to irq_create_mapping().
 *
 * Called from irq_create_of_mapping() only.
 * Note: We have only 1 entry to translate.
 */
static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
				 const u32 *intspec, unsigned int intsize,
				 irq_hw_number_t *out_hwirq,
				 unsigned int *out_flags)
{
	const u64 *intspec2 = (const u64 *)intspec;

	*out_hwirq = *intspec2;
	*out_flags |= IRQ_TYPE_LEVEL_LOW;
	return 0;
}