cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gpio-sch.c (10254B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * GPIO interface for Intel Poulsbo SCH
      4 *
      5 *  Copyright (c) 2010 CompuLab Ltd
      6 *  Author: Denis Turischev <denis@compulab.co.il>
      7 */
      8
      9#include <linux/acpi.h>
     10#include <linux/bitops.h>
     11#include <linux/errno.h>
     12#include <linux/gpio/driver.h>
     13#include <linux/io.h>
     14#include <linux/irq.h>
     15#include <linux/kernel.h>
     16#include <linux/module.h>
     17#include <linux/pci_ids.h>
     18#include <linux/platform_device.h>
     19#include <linux/types.h>
     20
     21#define GEN	0x00
     22#define GIO	0x04
     23#define GLV	0x08
     24#define GTPE	0x0c
     25#define GTNE	0x10
     26#define GGPE	0x14
     27#define GSMI	0x18
     28#define GTS	0x1c
     29
     30#define CORE_BANK_OFFSET	0x00
     31#define RESUME_BANK_OFFSET	0x20
     32
     33/*
     34 * iLB datasheet describes GPE0BLK registers, in particular GPE0E.GPIO bit.
     35 * Document Number: 328195-001
     36 */
     37#define GPE0E_GPIO	14
     38
     39struct sch_gpio {
     40	struct gpio_chip chip;
     41	spinlock_t lock;
     42	unsigned short iobase;
     43	unsigned short resume_base;
     44
     45	/* GPE handling */
     46	u32 gpe;
     47	acpi_gpe_handler gpe_handler;
     48};
     49
     50static unsigned int sch_gpio_offset(struct sch_gpio *sch, unsigned int gpio,
     51				unsigned int reg)
     52{
     53	unsigned int base = CORE_BANK_OFFSET;
     54
     55	if (gpio >= sch->resume_base) {
     56		gpio -= sch->resume_base;
     57		base = RESUME_BANK_OFFSET;
     58	}
     59
     60	return base + reg + gpio / 8;
     61}
     62
     63static unsigned int sch_gpio_bit(struct sch_gpio *sch, unsigned int gpio)
     64{
     65	if (gpio >= sch->resume_base)
     66		gpio -= sch->resume_base;
     67	return gpio % 8;
     68}
     69
     70static int sch_gpio_reg_get(struct sch_gpio *sch, unsigned int gpio, unsigned int reg)
     71{
     72	unsigned short offset, bit;
     73	u8 reg_val;
     74
     75	offset = sch_gpio_offset(sch, gpio, reg);
     76	bit = sch_gpio_bit(sch, gpio);
     77
     78	reg_val = !!(inb(sch->iobase + offset) & BIT(bit));
     79
     80	return reg_val;
     81}
     82
     83static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned int gpio, unsigned int reg,
     84			     int val)
     85{
     86	unsigned short offset, bit;
     87	u8 reg_val;
     88
     89	offset = sch_gpio_offset(sch, gpio, reg);
     90	bit = sch_gpio_bit(sch, gpio);
     91
     92	reg_val = inb(sch->iobase + offset);
     93
     94	if (val)
     95		outb(reg_val | BIT(bit), sch->iobase + offset);
     96	else
     97		outb((reg_val & ~BIT(bit)), sch->iobase + offset);
     98}
     99
    100static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned int gpio_num)
    101{
    102	struct sch_gpio *sch = gpiochip_get_data(gc);
    103	unsigned long flags;
    104
    105	spin_lock_irqsave(&sch->lock, flags);
    106	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
    107	spin_unlock_irqrestore(&sch->lock, flags);
    108	return 0;
    109}
    110
    111static int sch_gpio_get(struct gpio_chip *gc, unsigned int gpio_num)
    112{
    113	struct sch_gpio *sch = gpiochip_get_data(gc);
    114
    115	return sch_gpio_reg_get(sch, gpio_num, GLV);
    116}
    117
    118static void sch_gpio_set(struct gpio_chip *gc, unsigned int gpio_num, int val)
    119{
    120	struct sch_gpio *sch = gpiochip_get_data(gc);
    121	unsigned long flags;
    122
    123	spin_lock_irqsave(&sch->lock, flags);
    124	sch_gpio_reg_set(sch, gpio_num, GLV, val);
    125	spin_unlock_irqrestore(&sch->lock, flags);
    126}
    127
    128static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned int gpio_num,
    129				  int val)
    130{
    131	struct sch_gpio *sch = gpiochip_get_data(gc);
    132	unsigned long flags;
    133
    134	spin_lock_irqsave(&sch->lock, flags);
    135	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
    136	spin_unlock_irqrestore(&sch->lock, flags);
    137
    138	/*
    139	 * according to the datasheet, writing to the level register has no
    140	 * effect when GPIO is programmed as input.
    141	 * Actually the level register is read-only when configured as input.
    142	 * Thus presetting the output level before switching to output is _NOT_ possible.
    143	 * Hence we set the level after configuring the GPIO as output.
    144	 * But we cannot prevent a short low pulse if direction is set to high
    145	 * and an external pull-up is connected.
    146	 */
    147	sch_gpio_set(gc, gpio_num, val);
    148	return 0;
    149}
    150
    151static int sch_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio_num)
    152{
    153	struct sch_gpio *sch = gpiochip_get_data(gc);
    154
    155	if (sch_gpio_reg_get(sch, gpio_num, GIO))
    156		return GPIO_LINE_DIRECTION_IN;
    157
    158	return GPIO_LINE_DIRECTION_OUT;
    159}
    160
    161static const struct gpio_chip sch_gpio_chip = {
    162	.label			= "sch_gpio",
    163	.owner			= THIS_MODULE,
    164	.direction_input	= sch_gpio_direction_in,
    165	.get			= sch_gpio_get,
    166	.direction_output	= sch_gpio_direction_out,
    167	.set			= sch_gpio_set,
    168	.get_direction		= sch_gpio_get_direction,
    169};
    170
    171static int sch_irq_type(struct irq_data *d, unsigned int type)
    172{
    173	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    174	struct sch_gpio *sch = gpiochip_get_data(gc);
    175	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
    176	unsigned long flags;
    177	int rising, falling;
    178
    179	switch (type & IRQ_TYPE_SENSE_MASK) {
    180	case IRQ_TYPE_EDGE_RISING:
    181		rising = 1;
    182		falling = 0;
    183		break;
    184	case IRQ_TYPE_EDGE_FALLING:
    185		rising = 0;
    186		falling = 1;
    187		break;
    188	case IRQ_TYPE_EDGE_BOTH:
    189		rising = 1;
    190		falling = 1;
    191		break;
    192	default:
    193		return -EINVAL;
    194	}
    195
    196	spin_lock_irqsave(&sch->lock, flags);
    197
    198	sch_gpio_reg_set(sch, gpio_num, GTPE, rising);
    199	sch_gpio_reg_set(sch, gpio_num, GTNE, falling);
    200
    201	irq_set_handler_locked(d, handle_edge_irq);
    202
    203	spin_unlock_irqrestore(&sch->lock, flags);
    204
    205	return 0;
    206}
    207
    208static void sch_irq_ack(struct irq_data *d)
    209{
    210	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    211	struct sch_gpio *sch = gpiochip_get_data(gc);
    212	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
    213	unsigned long flags;
    214
    215	spin_lock_irqsave(&sch->lock, flags);
    216	sch_gpio_reg_set(sch, gpio_num, GTS, 1);
    217	spin_unlock_irqrestore(&sch->lock, flags);
    218}
    219
    220static void sch_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t gpio_num, int val)
    221{
    222	struct sch_gpio *sch = gpiochip_get_data(gc);
    223	unsigned long flags;
    224
    225	spin_lock_irqsave(&sch->lock, flags);
    226	sch_gpio_reg_set(sch, gpio_num, GGPE, val);
    227	spin_unlock_irqrestore(&sch->lock, flags);
    228}
    229
    230static void sch_irq_mask(struct irq_data *d)
    231{
    232	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    233	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
    234
    235	sch_irq_mask_unmask(gc, gpio_num, 0);
    236	gpiochip_disable_irq(gc, gpio_num);
    237}
    238
    239static void sch_irq_unmask(struct irq_data *d)
    240{
    241	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    242	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
    243
    244	gpiochip_enable_irq(gc, gpio_num);
    245	sch_irq_mask_unmask(gc, gpio_num, 1);
    246}
    247
    248static const struct irq_chip sch_irqchip = {
    249	.name = "sch_gpio",
    250	.irq_ack = sch_irq_ack,
    251	.irq_mask = sch_irq_mask,
    252	.irq_unmask = sch_irq_unmask,
    253	.irq_set_type = sch_irq_type,
    254	.flags = IRQCHIP_IMMUTABLE,
    255	GPIOCHIP_IRQ_RESOURCE_HELPERS,
    256};
    257
    258static u32 sch_gpio_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context)
    259{
    260	struct sch_gpio *sch = context;
    261	struct gpio_chip *gc = &sch->chip;
    262	unsigned long core_status, resume_status;
    263	unsigned long pending;
    264	unsigned long flags;
    265	int offset;
    266	u32 ret;
    267
    268	spin_lock_irqsave(&sch->lock, flags);
    269
    270	core_status = inl(sch->iobase + CORE_BANK_OFFSET + GTS);
    271	resume_status = inl(sch->iobase + RESUME_BANK_OFFSET + GTS);
    272
    273	spin_unlock_irqrestore(&sch->lock, flags);
    274
    275	pending = (resume_status << sch->resume_base) | core_status;
    276	for_each_set_bit(offset, &pending, sch->chip.ngpio)
    277		generic_handle_domain_irq(gc->irq.domain, offset);
    278
    279	/* Set returning value depending on whether we handled an interrupt */
    280	ret = pending ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
    281
    282	/* Acknowledge GPE to ACPICA */
    283	ret |= ACPI_REENABLE_GPE;
    284
    285	return ret;
    286}
    287
    288static void sch_gpio_remove_gpe_handler(void *data)
    289{
    290	struct sch_gpio *sch = data;
    291
    292	acpi_disable_gpe(NULL, sch->gpe);
    293	acpi_remove_gpe_handler(NULL, sch->gpe, sch->gpe_handler);
    294}
    295
    296static int sch_gpio_install_gpe_handler(struct sch_gpio *sch)
    297{
    298	struct device *dev = sch->chip.parent;
    299	acpi_status status;
    300
    301	status = acpi_install_gpe_handler(NULL, sch->gpe, ACPI_GPE_LEVEL_TRIGGERED,
    302					  sch->gpe_handler, sch);
    303	if (ACPI_FAILURE(status)) {
    304		dev_err(dev, "Failed to install GPE handler for %u: %s\n",
    305			sch->gpe, acpi_format_exception(status));
    306		return -ENODEV;
    307	}
    308
    309	status = acpi_enable_gpe(NULL, sch->gpe);
    310	if (ACPI_FAILURE(status)) {
    311		dev_err(dev, "Failed to enable GPE handler for %u: %s\n",
    312			sch->gpe, acpi_format_exception(status));
    313		acpi_remove_gpe_handler(NULL, sch->gpe, sch->gpe_handler);
    314		return -ENODEV;
    315	}
    316
    317	return devm_add_action_or_reset(dev, sch_gpio_remove_gpe_handler, sch);
    318}
    319
    320static int sch_gpio_probe(struct platform_device *pdev)
    321{
    322	struct gpio_irq_chip *girq;
    323	struct sch_gpio *sch;
    324	struct resource *res;
    325	int ret;
    326
    327	sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
    328	if (!sch)
    329		return -ENOMEM;
    330
    331	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
    332	if (!res)
    333		return -EBUSY;
    334
    335	if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
    336				 pdev->name))
    337		return -EBUSY;
    338
    339	spin_lock_init(&sch->lock);
    340	sch->iobase = res->start;
    341	sch->chip = sch_gpio_chip;
    342	sch->chip.label = dev_name(&pdev->dev);
    343	sch->chip.parent = &pdev->dev;
    344
    345	switch (pdev->id) {
    346	case PCI_DEVICE_ID_INTEL_SCH_LPC:
    347		sch->resume_base = 10;
    348		sch->chip.ngpio = 14;
    349
    350		/*
    351		 * GPIO[6:0] enabled by default
    352		 * GPIO7 is configured by the CMC as SLPIOVR
    353		 * Enable GPIO[9:8] core powered gpios explicitly
    354		 */
    355		sch_gpio_reg_set(sch, 8, GEN, 1);
    356		sch_gpio_reg_set(sch, 9, GEN, 1);
    357		/*
    358		 * SUS_GPIO[2:0] enabled by default
    359		 * Enable SUS_GPIO3 resume powered gpio explicitly
    360		 */
    361		sch_gpio_reg_set(sch, 13, GEN, 1);
    362		break;
    363
    364	case PCI_DEVICE_ID_INTEL_ITC_LPC:
    365		sch->resume_base = 5;
    366		sch->chip.ngpio = 14;
    367		break;
    368
    369	case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
    370		sch->resume_base = 21;
    371		sch->chip.ngpio = 30;
    372		break;
    373
    374	case PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB:
    375		sch->resume_base = 2;
    376		sch->chip.ngpio = 8;
    377		break;
    378
    379	default:
    380		return -ENODEV;
    381	}
    382
    383	platform_set_drvdata(pdev, sch);
    384
    385	girq = &sch->chip.irq;
    386	gpio_irq_chip_set_chip(girq, &sch_irqchip);
    387	girq->num_parents = 0;
    388	girq->parents = NULL;
    389	girq->parent_handler = NULL;
    390	girq->default_type = IRQ_TYPE_NONE;
    391	girq->handler = handle_bad_irq;
    392
    393	/* GPE setup is optional */
    394	sch->gpe = GPE0E_GPIO;
    395	sch->gpe_handler = sch_gpio_gpe_handler;
    396
    397	ret = sch_gpio_install_gpe_handler(sch);
    398	if (ret)
    399		dev_warn(&pdev->dev, "Can't setup GPE, no IRQ support\n");
    400
    401	return devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
    402}
    403
    404static struct platform_driver sch_gpio_driver = {
    405	.driver = {
    406		.name = "sch_gpio",
    407	},
    408	.probe		= sch_gpio_probe,
    409};
    410
    411module_platform_driver(sch_gpio_driver);
    412
    413MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
    414MODULE_DESCRIPTION("GPIO interface for Intel Poulsbo SCH");
    415MODULE_LICENSE("GPL v2");
    416MODULE_ALIAS("platform:sch_gpio");