Message ID | 20170322153858.19656-1-hdegoede@redhat.com |
---|---|
State | New |
Headers | show |
On Wed, Mar 22, 2017 at 04:38:58PM +0100, Hans de Goede wrote: > On some Cherry Trail devices the ASL uses the GMMR GPIO to access > GPIOs so as to serialize MMIO accesses to GPIO registers with the > OS, because: > > "Due to a silicon issue, a shared lock must be used to prevent concurrent > accesses across the 4 GPIO controllers. > > See Intel Atom Z8000 Processor Series Specification Update (Rev. 005), > errata #CHT34, for further information." > > This commit adds support for this opregion, this fixes a number of > ASL errors on my Ezpad mini3 tablet and makes the otg port device/host > muxing which is controlled in firmware on this model work properly. > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 2017-03-22 at 16:38 +0100, Hans de Goede wrote: > On some Cherry Trail devices the ASL uses the GMMR GPIO to access > GPIOs so as to serialize MMIO accesses to GPIO registers with the > OS, because: > > "Due to a silicon issue, a shared lock must be used to prevent > concurrent > accesses across the 4 GPIO controllers. > > See Intel Atom Z8000 Processor Series Specification Update (Rev. 005), > errata #CHT34, for further information." > > This commit adds support for this opregion, this fixes a number of > ASL errors on my Ezpad mini3 tablet and makes the otg port device/host > muxing which is controlled in firmware on this model work properly. > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > +static acpi_status chv_pinctrl_mmio_access_handler(u32 function, > + acpi_physical_address address, u32 bits, u64 *value, > + void *handler_context, void *region_context) > +{ > + struct chv_pinctrl *pctrl = region_context; > + unsigned long flags; > + acpi_status ret = AE_OK; > + > + raw_spin_lock_irqsave(&chv_lock, flags); > + > + if (function == ACPI_WRITE) > + chv_writel((u32)(*value), pctrl->regs + > (u32)address); > + else if (function == ACPI_READ) > + *value = readl(pctrl->regs + (u32)address); > + else > + ret = AE_BAD_PARAMETER; > + > + raw_spin_unlock_irqrestore(&chv_lock, flags); > + > + return AE_OK; return ret; Didn't notice before, sorry.
Hi, On 22-03-17 18:00, Andy Shevchenko wrote: > On Wed, 2017-03-22 at 16:38 +0100, Hans de Goede wrote: >> On some Cherry Trail devices the ASL uses the GMMR GPIO to access >> GPIOs so as to serialize MMIO accesses to GPIO registers with the >> OS, because: >> >> "Due to a silicon issue, a shared lock must be used to prevent >> concurrent >> accesses across the 4 GPIO controllers. >> >> See Intel Atom Z8000 Processor Series Specification Update (Rev. 005), >> errata #CHT34, for further information." >> >> This commit adds support for this opregion, this fixes a number of >> ASL errors on my Ezpad mini3 tablet and makes the otg port device/host >> muxing which is controlled in firmware on this model work properly. >> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com> >> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > >> +static acpi_status chv_pinctrl_mmio_access_handler(u32 function, >> + acpi_physical_address address, u32 bits, u64 *value, >> + void *handler_context, void *region_context) >> +{ >> + struct chv_pinctrl *pctrl = region_context; >> + unsigned long flags; >> + acpi_status ret = AE_OK; >> + >> + raw_spin_lock_irqsave(&chv_lock, flags); >> + >> + if (function == ACPI_WRITE) >> + chv_writel((u32)(*value), pctrl->regs + >> (u32)address); >> + else if (function == ACPI_READ) >> + *value = readl(pctrl->regs + (u32)address); >> + else >> + ret = AE_BAD_PARAMETER; >> + >> + raw_spin_unlock_irqrestore(&chv_lock, flags); >> + > >> + return AE_OK; > > return ret; > > Didn't notice before, sorry. No problem, v3 coming up. Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index f80134e..4246493 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -148,6 +148,7 @@ struct chv_community { size_t ngpio_ranges; size_t ngpios; size_t nirqs; + acpi_adr_space_type acpi_space_id; }; struct chv_pin_context { @@ -404,6 +405,7 @@ static const struct chv_community southwest_community = { * trigger GPEs. */ .nirqs = 8, + .acpi_space_id = 0x91, }; static const struct pinctrl_pin_desc north_pins[] = { @@ -493,6 +495,7 @@ static const struct chv_community north_community = { * GPEs. */ .nirqs = 8, + .acpi_space_id = 0x92, }; static const struct pinctrl_pin_desc east_pins[] = { @@ -536,6 +539,7 @@ static const struct chv_community east_community = { .ngpio_ranges = ARRAY_SIZE(east_gpio_ranges), .ngpios = ARRAY_SIZE(east_pins), .nirqs = 16, + .acpi_space_id = 0x93, }; static const struct pinctrl_pin_desc southeast_pins[] = { @@ -662,6 +666,7 @@ static const struct chv_community southeast_community = { .ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges), .ngpios = ARRAY_SIZE(southeast_pins), .nirqs = 16, + .acpi_space_id = 0x94, }; static const struct chv_community *chv_communities[] = { @@ -1586,11 +1591,34 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) return 0; } +static acpi_status chv_pinctrl_mmio_access_handler(u32 function, + acpi_physical_address address, u32 bits, u64 *value, + void *handler_context, void *region_context) +{ + struct chv_pinctrl *pctrl = region_context; + unsigned long flags; + acpi_status ret = AE_OK; + + raw_spin_lock_irqsave(&chv_lock, flags); + + if (function == ACPI_WRITE) + chv_writel((u32)(*value), pctrl->regs + (u32)address); + else if (function == ACPI_READ) + *value = readl(pctrl->regs + (u32)address); + else + ret = AE_BAD_PARAMETER; + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return AE_OK; +} + static int chv_pinctrl_probe(struct platform_device *pdev) { struct chv_pinctrl *pctrl; struct acpi_device *adev; struct resource *res; + acpi_status status; int ret, irq, i; adev = ACPI_COMPANION(&pdev->dev); @@ -1646,11 +1674,29 @@ static int chv_pinctrl_probe(struct platform_device *pdev) if (ret) return ret; + status = acpi_install_address_space_handler(adev->handle, + pctrl->community->acpi_space_id, + chv_pinctrl_mmio_access_handler, + NULL, pctrl); + if (ACPI_FAILURE(status)) + dev_err(&pdev->dev, "failed to install ACPI addr space handler\n"); + platform_set_drvdata(pdev, pctrl); return 0; } +static int chv_pinctrl_remove(struct platform_device *pdev) +{ + struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); + + acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), + pctrl->community->acpi_space_id, + chv_pinctrl_mmio_access_handler); + + return 0; +} + #ifdef CONFIG_PM_SLEEP static int chv_pinctrl_suspend_noirq(struct device *dev) { @@ -1758,6 +1804,7 @@ MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); static struct platform_driver chv_pinctrl_driver = { .probe = chv_pinctrl_probe, + .remove = chv_pinctrl_remove, .driver = { .name = "cherryview-pinctrl", .pm = &chv_pinctrl_pm_ops,