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:
parent
f521be6083
commit
3e57ad907c
@ -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";
|
||||
|
20
arch/sandbox/include/asm/irq.h
Normal file
20
arch/sandbox/include/asm/irq.h
Normal 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 */
|
@ -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/
|
||||
|
@ -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
|
||||
|
@ -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>)
|
||||
};
|
||||
|
22
drivers/misc/irq_sandbox_test.c
Normal file
22
drivers/misc/irq_sandbox_test.c
Normal 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,
|
||||
};
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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',
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user