Commit 2b3a7f06 authored by Shyam Sundar S K's avatar Shyam Sundar S K Committed by Hans de Goede

platform/x86/amd/pmf: Change return type of amd_pmf_set_dram_addr()

In the current code, the metrics table information was required only
for auto-mode or CnQF at a given time. Hence keeping the return type
of amd_pmf_set_dram_addr() as static made sense.

But with the addition of Smart PC builder feature, the metrics table
information has to be shared by the Smart PC also and this feature
resides outside of core.c.

To make amd_pmf_set_dram_addr() visible outside of core.c make it
as a non-static function and move the allocation of memory for
metrics table from amd_pmf_init_metrics_table() to amd_pmf_set_dram_addr()
as amd_pmf_set_dram_addr() is the common function to set the DRAM
address.

Add a suspend handler that can free up the allocated memory for getting
the metrics table information.
Reviewed-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarShyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20231212014705.2017474-4-Shyam-sundar.S-k@amd.comSigned-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent ae82cef7
...@@ -251,29 +251,37 @@ static const struct pci_device_id pmf_pci_ids[] = { ...@@ -251,29 +251,37 @@ static const struct pci_device_id pmf_pci_ids[] = {
{ } { }
}; };
static void amd_pmf_set_dram_addr(struct amd_pmf_dev *dev) int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer)
{ {
u64 phys_addr; u64 phys_addr;
u32 hi, low; u32 hi, low;
/* Get Metrics Table Address */
if (alloc_buffer) {
dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL);
if (!dev->buf)
return -ENOMEM;
}
phys_addr = virt_to_phys(dev->buf); phys_addr = virt_to_phys(dev->buf);
hi = phys_addr >> 32; hi = phys_addr >> 32;
low = phys_addr & GENMASK(31, 0); low = phys_addr & GENMASK(31, 0);
amd_pmf_send_cmd(dev, SET_DRAM_ADDR_HIGH, 0, hi, NULL); amd_pmf_send_cmd(dev, SET_DRAM_ADDR_HIGH, 0, hi, NULL);
amd_pmf_send_cmd(dev, SET_DRAM_ADDR_LOW, 0, low, NULL); amd_pmf_send_cmd(dev, SET_DRAM_ADDR_LOW, 0, low, NULL);
return 0;
} }
int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev)
{ {
/* Get Metrics Table Address */ int ret;
dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL);
if (!dev->buf)
return -ENOMEM;
INIT_DELAYED_WORK(&dev->work_buffer, amd_pmf_get_metrics); INIT_DELAYED_WORK(&dev->work_buffer, amd_pmf_get_metrics);
amd_pmf_set_dram_addr(dev); ret = amd_pmf_set_dram_addr(dev, true);
if (ret)
return ret;
/* /*
* Start collecting the metrics data after a small delay * Start collecting the metrics data after a small delay
...@@ -284,17 +292,30 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) ...@@ -284,17 +292,30 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev)
return 0; return 0;
} }
static int amd_pmf_suspend_handler(struct device *dev)
{
struct amd_pmf_dev *pdev = dev_get_drvdata(dev);
kfree(pdev->buf);
return 0;
}
static int amd_pmf_resume_handler(struct device *dev) static int amd_pmf_resume_handler(struct device *dev)
{ {
struct amd_pmf_dev *pdev = dev_get_drvdata(dev); struct amd_pmf_dev *pdev = dev_get_drvdata(dev);
int ret;
if (pdev->buf) if (pdev->buf) {
amd_pmf_set_dram_addr(pdev); ret = amd_pmf_set_dram_addr(pdev, false);
if (ret)
return ret;
}
return 0; return 0;
} }
static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmf_pm, NULL, amd_pmf_resume_handler); static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmf_pm, amd_pmf_suspend_handler, amd_pmf_resume_handler);
static void amd_pmf_init_features(struct amd_pmf_dev *dev) static void amd_pmf_init_features(struct amd_pmf_dev *dev)
{ {
......
...@@ -421,6 +421,7 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev); ...@@ -421,6 +421,7 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev);
int amd_pmf_get_power_source(void); int amd_pmf_get_power_source(void);
int apmf_install_handler(struct amd_pmf_dev *pmf_dev); int apmf_install_handler(struct amd_pmf_dev *pmf_dev);
int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);
int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer);
/* SPS Layer */ /* SPS Layer */
int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment