On Monday, June 17, 2013 01:25:46 PM Heikki Krogerus wrote: > Intel LPSS provides an extra TX byte counter and an extra TX > completion interrupt for some of it's bus controllers. This > masks out the extra UART interrupt as there is no use for it. > > Otherwise, if the firmware does not mask the interrupt and > the driver does not clear it, it may cause interrupt flood > that freezes the board. > > Signed-off-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> Queued up for 3.11. Thanks, Rafael > --- > drivers/acpi/acpi_lpss.c | 30 ++++++++++++++++++++++++++++-- > 1 file changed, 28 insertions(+), 2 deletions(-) > > diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c > index f6d7605..bd9867f 100644 > --- a/drivers/acpi/acpi_lpss.c > +++ b/drivers/acpi/acpi_lpss.c > @@ -32,6 +32,8 @@ ACPI_MODULE_NAME("acpi_lpss"); > #define LPSS_GENERAL_LTR_MODE_SW BIT(2) > #define LPSS_SW_LTR 0x10 > #define LPSS_AUTO_LTR 0x14 > +#define LPSS_TX_INT 0x20 > +#define LPSS_TX_INT_MASK BIT(1) > > struct lpss_shared_clock { > const char *name; > @@ -39,6 +41,8 @@ struct lpss_shared_clock { > struct clk *clk; > }; > > +struct lpss_private_data; > + > struct lpss_device_desc { > bool clk_required; > const char *clkdev_name; > @@ -46,6 +50,7 @@ struct lpss_device_desc { > unsigned int prv_offset; > bool clk_gate; > struct lpss_shared_clock *shared_clock; > + void (*setup)(struct lpss_private_data *pdata); > }; > > static struct lpss_device_desc lpss_dma_desc = { > @@ -60,6 +65,15 @@ struct lpss_private_data { > const struct lpss_device_desc *dev_desc; > }; > > +static void lpss_uart_setup(struct lpss_private_data *pdata) > +{ > + unsigned int tx_int_offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; > + u32 reg; > + > + reg = readl(pdata->mmio_base + tx_int_offset); > + writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + tx_int_offset); > +} > + > static struct lpss_device_desc lpt_dev_desc = { > .clk_required = true, > .prv_offset = 0x800, > @@ -67,6 +81,14 @@ static struct lpss_device_desc lpt_dev_desc = { > .clk_gate = true, > }; > > +static struct lpss_device_desc lpt_uart_dev_desc = { > + .clk_required = true, > + .prv_offset = 0x800, > + .ltr_required = true, > + .clk_gate = true, > + .setup = lpss_uart_setup, > +}; > + > static struct lpss_device_desc lpt_sdio_dev_desc = { > .prv_offset = 0x1000, > .ltr_required = true, > @@ -82,6 +104,7 @@ static struct lpss_device_desc byt_uart_dev_desc = { > .prv_offset = 0x800, > .clk_gate = true, > .shared_clock = &uart_clock, > + .setup = lpss_uart_setup, > }; > > static struct lpss_shared_clock spi_clock = { > @@ -120,8 +143,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { > { "INT33C1", (unsigned long)&lpt_dev_desc }, > { "INT33C2", (unsigned long)&lpt_dev_desc }, > { "INT33C3", (unsigned long)&lpt_dev_desc }, > - { "INT33C4", (unsigned long)&lpt_dev_desc }, > - { "INT33C5", (unsigned long)&lpt_dev_desc }, > + { "INT33C4", (unsigned long)&lpt_uart_dev_desc }, > + { "INT33C5", (unsigned long)&lpt_uart_dev_desc }, > { "INT33C6", (unsigned long)&lpt_sdio_dev_desc }, > { "INT33C7", }, > > @@ -247,6 +270,9 @@ static int acpi_lpss_create_device(struct acpi_device *adev, > } > } > > + if (dev_desc->setup) > + dev_desc->setup(pdata); > + > adev->driver_data = pdata; > ret = acpi_create_platform_device(adev, id); > if (ret > 0) > -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html