From: Mika Westerberg <mika.westerberg@linux.intel.com>
To: Lee Jones <lee.jones@linaro.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Darren Hart <dvhart@infradead.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
"H . Peter Anvin" <hpa@zytor.com>,
x86@kernel.org, Zha Qipeng <qipeng.zha@intel.com>,
"David E . Box" <david.e.box@linux.intel.com>,
Guenter Roeck <linux@roeck-us.net>,
Heikki Krogerus <heikki.krogerus@linux.intel.com>,
Wim Van Sebroeck <wim@linux-watchdog.org>,
platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v8 18/19] platform/x86: intel_pmc_ipc: Convert to MFD
Date: Tue, 24 Mar 2020 14:22:16 +0200 [thread overview]
Message-ID: <20200324122216.GG2564@lahna.fi.intel.com> (raw)
In-Reply-To: <20200324115219.GB437932@dell>
On Tue, Mar 24, 2020 at 11:52:19AM +0000, Lee Jones wrote:
> On Tue, 03 Mar 2020, Mika Westerberg wrote:
>
> > This driver only creates a bunch of platform devices sharing resources
> > belonging to the PMC device. This is pretty much what MFD subsystem is
> > for so move the driver there, renaming it to intel_pmc_bxt.c which
> > should be more clear what it is.
> >
> > MFD subsystem provides nice helper APIs for subdevice creation so
> > convert the driver to use those. Unfortunately the ACPI device includes
> > separate resources for most of the subdevices so we cannot simply call
> > mfd_add_devices() to create all of them but instead we need to call it
> > separately for each device.
> >
> > The new MFD driver continues to expose two sysfs attributes that allow
> > userspace to send IPC commands to the PMC/SCU to avoid breaking any
> > existing applications that may use these. Generally this is bad idea so
> > document this in the ABI documentation.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > ---
> > .../ABI/obsolete/sysfs-driver-intel_pmc_bxt | 22 +
> > arch/x86/include/asm/intel_pmc_ipc.h | 47 --
> > arch/x86/include/asm/intel_telemetry.h | 1 +
> > drivers/mfd/Kconfig | 16 +-
> > drivers/mfd/Makefile | 1 +
> > drivers/mfd/intel_pmc_bxt.c | 504 ++++++++++++++
> > drivers/platform/x86/Kconfig | 16 +-
> > drivers/platform/x86/Makefile | 1 -
> > drivers/platform/x86/intel_pmc_ipc.c | 645 ------------------
> > .../platform/x86/intel_telemetry_debugfs.c | 12 +-
> > drivers/platform/x86/intel_telemetry_pltdrv.c | 2 +
> > drivers/usb/typec/tcpm/Kconfig | 2 +-
> > include/linux/mfd/intel_pmc_bxt.h | 43 ++
> > 13 files changed, 602 insertions(+), 710 deletions(-)
> > create mode 100644 Documentation/ABI/obsolete/sysfs-driver-intel_pmc_bxt
> > delete mode 100644 arch/x86/include/asm/intel_pmc_ipc.h
> > create mode 100644 drivers/mfd/intel_pmc_bxt.c
> > delete mode 100644 drivers/platform/x86/intel_pmc_ipc.c
> > create mode 100644 include/linux/mfd/intel_pmc_bxt.h
>
> [...]
>
> > +/*
> > + * We use the below templates to construct MFD cells. The struct
> > + * intel_pmc_dev instance holds the real MFD cells where we first copy
> > + * these and then fill the dynamic parts based on the extracted resources.
> > + */
> > +
> > +static const struct mfd_cell punit = {
> > + .name = "intel_punit_ipc",
> > +};
> > +
> > +static int update_no_reboot_bit(void *priv, bool set)
> > +{
> > + struct intel_pmc_dev *pmc = priv;
> > + u32 bits = PMC_CFG_NO_REBOOT_EN;
> > + u32 value = set ? bits : 0;
> > +
> > + return intel_pmc_gcr_update(pmc, PMC_GCR_PMC_CFG_REG, bits, value);
> > +}
> > +
> > +static const struct itco_wdt_platform_data tco_pdata = {
> > + .name = "Apollo Lake SoC",
> > + .version = 5,
> > + .update_no_reboot_bit = update_no_reboot_bit,
> > +};
> > +
> > +static const struct mfd_cell tco = {
> > + .name = "iTCO_wdt",
> > + .ignore_resource_conflicts = true,
> > +};
> > +
> > +static const struct resource telem_res[] = {
> > + DEFINE_RES_MEM(TELEM_PUNIT_SSRAM_OFFSET, TELEM_SSRAM_SIZE),
> > + DEFINE_RES_MEM(TELEM_PMC_SSRAM_OFFSET, TELEM_SSRAM_SIZE),
> > +};
> > +
> > +static const struct mfd_cell telem = {
> > + .name = "intel_telemetry",
> > + .resources = telem_res,
> > + .num_resources = ARRAY_SIZE(telem_res),
> > +};
> > +
> > +static int intel_pmc_get_tco_resources(struct platform_device *pdev,
> > + struct intel_pmc_dev *pmc)
> > +{
> > + struct itco_wdt_platform_data *pdata;
> > + struct resource *res, *tco_res;
> > +
> > + if (acpi_has_watchdog())
> > + return 0;
> > +
> > + res = platform_get_resource(pdev, IORESOURCE_IO,
> > + PLAT_RESOURCE_ACPI_IO_INDEX);
> > + if (!res) {
> > + dev_err(&pdev->dev, "Failed to get IO resource\n");
> > + return -EINVAL;
> > + }
> > +
> > + tco_res = devm_kcalloc(&pdev->dev, 2, sizeof(*tco_res), GFP_KERNEL);
> > + if (!tco_res)
> > + return -ENOMEM;
> > +
> > + tco_res[0].flags = IORESOURCE_IO;
> > + tco_res[0].start = res->start + TCO_BASE_OFFSET;
> > + tco_res[0].end = tco_res[0].start + TCO_REGS_SIZE - 1;
> > + tco_res[1].flags = IORESOURCE_IO;
> > + tco_res[1].start = res->start + SMI_EN_OFFSET;
> > + tco_res[1].end = tco_res[1].start + SMI_EN_SIZE - 1;
> > +
> > + pmc->cells[PMC_TCO].resources = tco_res;
> > + pmc->cells[PMC_TCO].num_resources = 2;
> > +
> > + pdata = devm_kmemdup(&pdev->dev, &tco_pdata, sizeof(*pdata), GFP_KERNEL);
> > + if (!pdata)
> > + return -ENOMEM;
>
> Why do you need to take a copy?
>
> This can be referenced directly in 'mfd_cell tco', no?
No because I'm filling the priv pointer dynamically. I've tried to
explain the same thing in the previous iterations already.
> > + pdata->no_reboot_priv = pmc;
>
> You're putting device data inside platform data?
>
> This doesn't sit right with me at all.
>
> You already saved it using platform_set_drvdata(), why do you need it
> twice? Why can't you export update_no_reboot_bit() and make it take
> 'struct intel_pmc_dev' or better yet 'pdev' as an argument?
This is a property of the iTCO_wdt driver, not part of this patch
series. I'm just using the interface it provides.
iTCO_wdt interface can of course be made better but I don't think it
should be part of this series.
> > + pmc->cells[PMC_TCO].platform_data = pdata;
> > + pmc->cells[PMC_TCO].pdata_size = sizeof(*pdata);
> > +
> > + return 0;
> > +}
> > +
> > +static int intel_pmc_get_resources(struct platform_device *pdev,
> > + struct intel_pmc_dev *pmc,
> > + struct intel_scu_ipc_data *scu_data)
> > +{
> > + struct resource *res, *punit_res;
> > + struct resource gcr_res;
> > + size_t npunit_res = 0;
> > + int ret;
> > +
> > + scu_data->irq = platform_get_irq_optional(pdev, 0);
> > +
> > + res = platform_get_resource(pdev, IORESOURCE_MEM,
> > + PLAT_RESOURCE_IPC_INDEX);
> > + if (!res) {
> > + dev_err(&pdev->dev, "Failed to get IPC resource\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* IPC registers */
> > + scu_data->mem.flags = res->flags;
> > + scu_data->mem.start = res->start;
> > + scu_data->mem.end = res->start + PLAT_RESOURCE_IPC_SIZE - 1;
> > +
> > + /* GCR registers */
> > + gcr_res.flags = res->flags;
> > + gcr_res.start = res->start + PLAT_RESOURCE_GCR_OFFSET;
> > + gcr_res.end = gcr_res.start + PLAT_RESOURCE_GCR_SIZE - 1;
> > +
> > + pmc->gcr_mem_base = devm_ioremap_resource(&pdev->dev, &gcr_res);
> > + if (IS_ERR(pmc->gcr_mem_base))
> > + return PTR_ERR(pmc->gcr_mem_base);
> > +
> > + pmc->cells[PMC_TCO] = tco;
> > + pmc->cells[PMC_PUNIT] = punit;
> > + pmc->cells[PMC_TELEM] = telem;
>
> Why are you still saving these to device data?
>
> What's stopping you operating on the structures directly?
OK, I've explained this in the previous iterations but here goes. The
problem is that the resources need to be filled dynamically as they are
whatever there is in the ACPI table.
Now, Consider that we have two PMC devices. It is possible that the
driver is bind to both in paraller which means that both are racing to
fill and use these structures leading to a corruption.
Another issue is that even if we have single device, the driver fills in
the structures and then we unbind it. These structures now are left with
that data which does not feel right.
Therefore I've put all we know in advance as const version of these
structures and then we use those as template to build custom ones based
on resources extracted from ACPI to individual instances.
next prev parent reply other threads:[~2020-03-24 12:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-03 13:36 [PATCH v8 00/19] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 01/19] platform/x86: intel_scu_ipc: Split out SCU IPC functionality from the SCU driver Mika Westerberg
2020-03-20 13:36 ` Lee Jones
2020-03-03 13:36 ` [PATCH v8 02/19] platform/x86: intel_scu_ipc: Log more information if SCU IPC command fails Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 03/19] platform/x86: intel_scu_ipc: Move legacy SCU IPC API to a separate header Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 04/19] platform/x86: intel_scu_ipc: Introduce new SCU IPC API Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 05/19] platform/x86: intel_mid_powerbtn: Convert to use " Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 06/19] watchdog: intel-mid_wdt: " Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 07/19] platform/x86: intel_scu_ipcutil: " Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 08/19] platform/x86: intel_scu_ipc: Add managed function to register SCU IPC Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 09/19] platform/x86: intel_pmc_ipc: Start using " Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 10/19] mfd: intel_soc_pmic: Add SCU IPC member to struct intel_soc_pmic Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 11/19] mfd: intel_soc_pmic_bxtwc: Convert to use new SCU IPC API Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 12/19] mfd: intel_soc_pmic_mrfld: " Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 13/19] platform/x86: intel_telemetry: " Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 14/19] platform/x86: intel_pmc_ipc: Drop intel_pmc_ipc_command() Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 15/19] x86/platform/intel-mid: Add empty stubs for intel_scu_devices_[create|destroy]() Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 16/19] platform/x86: intel_pmc_ipc: Move PCI IDs to intel_scu_pcidrv.c Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 17/19] platform/x86: intel_telemetry: Add telemetry_get_pltdata() Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 18/19] platform/x86: intel_pmc_ipc: Convert to MFD Mika Westerberg
2020-03-24 10:26 ` Andy Shevchenko
2020-03-24 11:27 ` Lee Jones
2020-03-24 11:52 ` Lee Jones
2020-03-24 12:22 ` Mika Westerberg [this message]
2020-03-24 14:22 ` Lee Jones
2020-03-24 14:46 ` Mika Westerberg
2020-03-03 13:36 ` [PATCH v8 19/19] MAINTAINERS: Update entry for Intel Broxton PMC driver Mika Westerberg
2020-03-17 8:43 ` [PATCH v8 00/19] platform/x86: Rework intel_scu_ipc and intel_pmc_ipc drivers Mika Westerberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200324122216.GG2564@lahna.fi.intel.com \
--to=mika.westerberg@linux.intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bp@alien8.de \
--cc=david.e.box@linux.intel.com \
--cc=dvhart@infradead.org \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=hpa@zytor.com \
--cc=lee.jones@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=mingo@redhat.com \
--cc=platform-driver-x86@vger.kernel.org \
--cc=qipeng.zha@intel.com \
--cc=tglx@linutronix.de \
--cc=wim@linux-watchdog.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox