irq: Tidy up of-platdata irq support

This function is available but not exported. More generally it does not
really work as intended.

Reimplement it and add a sandbox test too.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2021-08-07 07:24:11 -06:00
parent f521be6083
commit 3e57ad907c
9 changed files with 119 additions and 19 deletions

View File

@ -124,6 +124,19 @@
#sound-dai-cells = <1>;
};
irq_sandbox: irq-sbox {
u-boot,dm-spl;
compatible = "sandbox,irq";
interrupt-controller;
#interrupt-cells = <2>;
};
irq-test {
u-boot,dm-spl;
compatible = "sandbox,irq-test";
interrupts-extended = <&irq_sandbox 3 0>;
};
lcd {
u-boot,dm-pre-proper;
compatible = "sandbox,lcd-sdl";

View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2021 Google LLC
*/
#ifndef __SANDBOX_IRQ_H
#define __SANDBOX_IRQ_H
/**
* struct sandbox_irq_priv - private data for this driver
*
* @count: Counts the number calls to the read_and_clear() method
* @pending: true if an interrupt is pending, else false
*/
struct sandbox_irq_priv {
int count;
bool pending;
};
#endif /* __SANDBOX_IRQ_H */

View File

@ -42,7 +42,7 @@ obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
obj-$(CONFIG_IRQ) += irq-uclass.o
obj-$(CONFIG_SANDBOX) += irq_sandbox.o
obj-$(CONFIG_SANDBOX) += irq_sandbox.o irq_sandbox_test.o
obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o
obj-$(CONFIG_IMX8) += imx8/

View File

@ -64,8 +64,8 @@ int irq_read_and_clear(struct irq *irq)
}
#if CONFIG_IS_ENABLED(OF_PLATDATA)
int irq_get_by_driver_info(struct udevice *dev,
struct phandle_1_arg *cells, struct irq *irq)
int irq_get_by_phandle(struct udevice *dev, const struct phandle_2_arg *cells,
struct irq *irq)
{
int ret;
@ -74,6 +74,12 @@ int irq_get_by_driver_info(struct udevice *dev,
return ret;
irq->id = cells->arg[0];
/*
* Note: we could call irq_of_xlate_default() here to do this properly.
* For now, this is good enough for existing cases.
*/
irq->flags = cells->arg[1];
return 0;
}
#else

View File

@ -9,19 +9,9 @@
#include <dm.h>
#include <irq.h>
#include <acpi/acpi_device.h>
#include <asm/irq.h>
#include <asm/test.h>
/**
* struct sandbox_irq_priv - private data for this driver
*
* @count: Counts the number calls to the read_and_clear() method
* @pending: true if an interrupt is pending, else false
*/
struct sandbox_irq_priv {
int count;
bool pending;
};
static int sandbox_set_polarity(struct udevice *dev, uint irq, bool active_low)
{
if (irq > 10)
@ -103,10 +93,11 @@ static const struct udevice_id sandbox_irq_ids[] = {
{ }
};
U_BOOT_DRIVER(sandbox_irq_drv) = {
U_BOOT_DRIVER(sandbox_irq) = {
.name = "sandbox_irq",
.id = UCLASS_IRQ,
.of_match = sandbox_irq_ids,
.ops = &sandbox_irq_ops,
.priv_auto = sizeof(struct sandbox_irq_priv),
DM_HEADER(<asm/irq.h>)
};

View File

@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Sandbox driver for testing interrupts with of-platdata
*
* Copyright 2021 Google LLC
*/
#include <common.h>
#include <dm.h>
#include <irq.h>
#include <asm/irq.h>
static const struct udevice_id sandbox_irq_test_ids[] = {
{ .compatible = "sandbox,irq-test" },
{ }
};
U_BOOT_DRIVER(sandbox_irq_test) = {
.name = "sandbox_irq_test",
.id = UCLASS_MISC,
.of_match = sandbox_irq_test_ids,
};

View File

@ -200,6 +200,35 @@ int irq_restore_polarities(struct udevice *dev);
*/
int irq_read_and_clear(struct irq *irq);
struct phandle_2_arg;
/**
* irq_get_by_phandle() - Get an irq by its phandle information (of-platadata)
*
* This function is used when of-platdata is enabled.
*
* This looks up an irq using the phandle info. With dtoc, each phandle in the
* 'interrupts-extended ' property is transformed into an idx representing the
* device. For example:
*
* interrupts-extended = <&acpi_gpe 0x3c 0>;
*
* might result in:
*
* .interrupts_extended = {6, {0x3c, 0}},},
*
* indicating that the irq is udevice idx 6 in dt-plat.c with a arguments of
* 0x3c and 0.This function can return a valid irq given the above
* information. In this example it would return an irq containing the
* 'acpi_gpe' device and the irq ID 0x3c.
*
* @dev: Device containing the phandle
* @cells: Phandle info
* @irq: A pointer to a irq struct to initialise
* @return 0 if OK, or a negative error code
*/
int irq_get_by_phandle(struct udevice *dev, const struct phandle_2_arg *cells,
struct irq *irq);
/**
* irq_get_by_index - Get/request an irq by integer index.
*

View File

@ -4,6 +4,7 @@
#include <clk.h>
#include <dm.h>
#include <dt-structs.h>
#include <irq.h>
#include <dm/test.h>
#include <test/test.h>
#include <test/ut.h>
@ -28,11 +29,9 @@ static int dm_test_of_plat_props(struct unit_test_state *uts)
struct udevice *dev;
int i;
/* Skip the clock */
ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
ut_asserteq_str("sandbox_clk_test", dev->name);
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "sandbox_spl_test",
&dev));
ut_assertok(uclass_next_device_err(&dev));
plat = dev_get_plat(dev);
ut_assert(plat->boolval);
ut_asserteq(1, plat->intval);
@ -241,3 +240,22 @@ static int dm_test_of_plat_clk(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_of_plat_clk, UT_TESTF_SCAN_PDATA);
/* Test irqs with of-platdata */
static int dm_test_of_plat_irq(struct unit_test_state *uts)
{
struct dtd_sandbox_irq_test *plat;
struct udevice *dev;
struct irq irq;
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "sandbox_irq_test",
&dev));
plat = dev_get_plat(dev);
ut_assertok(irq_get_by_phandle(dev, &plat->interrupts_extended[0],
&irq));
ut_asserteq_str("sandbox_irq", irq.dev->name);
return 0;
}
DM_TEST(dm_test_of_plat_irq, UT_TESTF_SCAN_PDATA);

View File

@ -62,6 +62,7 @@ VAL_PREFIX = 'dtv_'
# a phandle property.
PHANDLE_PROPS = {
'clocks': '#clock-cells',
'interrupts-extended': '#interrupt-cells',
'gpios': '#gpio-cells',
'sandbox,emul': '#emul-cells',
}