firmware: xilinx: Add xilinx specific sysfs interface
Subsystems (9)
v3 cover firmware: xilinx: Add xilinx specific sysfs interface
This patch series adds xilinx specific sysfs interface for below purposes:
- Register access
- Set shutdown scope
- Set boot health status bit
Also this patch series removes eemi ops and adds API corresponding to each eemi ops.
v3:
- Remove eemi ops function pointers and call real functions
- For ioctl eemi calls, make actual function calls rather than ioctl api
Rajan Vaja (24):
firmware: xilinx: Remove eemi ops for get_api_version
firmware: xilinx: Remove eemi ops for get_chipid
firmware: xilinx: Remove eemi ops for query_data
firmware: xilinx: Remove eemi ops for clock_enable
firmware: xilinx: Remove eemi ops for clock_disable
firmware: xilinx: Remove eemi ops for clock_getstate
firmware: xilinx: Remove eemi ops for clock_setdivider
firmware: xilinx: Remove eemi ops for clock_getdivider
firmware: xilinx: Remove eemi ops for clock set/get rate
firmware: xilinx: Remove eemi ops for clock set/get parent
firmware: xilinx: Use APIs instead of IOCTLs
firmware: xilinx: Remove eemi ops for reset_assert
firmware: xilinx: Remove eemi ops for reset_get_status
firmware: xilinx: Remove eemi ops for init_finalize
firmware: xilinx: Remove eemi ops for set_suspend_mode
firmware: xilinx: Remove eemi ops for request_node
firmware: xilinx: Remove eemi ops for release_node
firmware: xilinx: Remove eemi ops for set_requirement
firmware: xilinx: Remove eemi ops for fpga related APIs
firmware: xilinx: Add APIs to read/write GGS/PGGS registers
firmware: xilinx: Add sysfs interface
firmware: xilinx: Add system shutdown API interface
firmware: xilinx: Add sysfs to set shutdown scope
firmware: xilinx: Add sysfs and API to set boot health status
.../ABI/stable/sysfs-driver-firmware-zynqmp | 103 +++ drivers/clk/zynqmp/clk-gate-zynqmp.c | 9 +- drivers/clk/zynqmp/clk-mux-zynqmp.c | 6 +- drivers/clk/zynqmp/clkc.c | 17 +- drivers/clk/zynqmp/divider.c | 12 +- drivers/clk/zynqmp/pll.c | 29 +- drivers/firmware/xilinx/zynqmp-debug.c | 5 +- drivers/firmware/xilinx/zynqmp.c | 806 ++++++++++++++++++--- drivers/fpga/zynqmp-fpga.c | 12 +- drivers/mmc/host/sdhci-of-arasan.c | 33 +- drivers/nvmem/zynqmp_nvmem.c | 11 +- drivers/reset/reset-zynqmp.c | 26 +- drivers/soc/xilinx/zynqmp_pm_domains.c | 26 +- drivers/soc/xilinx/zynqmp_power.c | 17 +- drivers/spi/spi-zynqmp-gqspi.c | 5 - include/linux/firmware/xlnx-zynqmp.h | 102 +-- 16 files changed, 924 insertions(+), 295 deletions(-) create mode 100644 Documentation/ABI/stable/sysfs-driver-firmware-zynqmp
Signature · 7 lines
2.7.4 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v3 1/24 firmware: xilinx: Remove eemi ops for get_api_version
From: Rajan Vaja <[email protected]>
Use direct function calls instead of using eemi ops. So remove eemi ops for get_api_version and use direct function call.
--- drivers/firmware/xilinx/zynqmp-debug.c | 2 +- drivers/firmware/xilinx/zynqmp.c | 4 ++-- drivers/soc/xilinx/zynqmp_power.c | 4 ++-- include/linux/firmware/xlnx-zynqmp.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-)
drivers/firmware/xilinx/zynqmp-debug.c +1 -1
@@ -92,7 +92,7 @@ static int process_api_request(u32 pm_id, u64 *pm_api_arg, u32 *pm_api_ret)switch (pm_id) {case PM_GET_API_VERSION : - ret = eemi_ops->get_api_version (&pm_api_version); + ret =zynqmp_pm_get_api_version (&pm_api_version);sprintf (debugfs_buf,"PM-API Version = %d.%d\n" , pm_api_version >>16 , pm_api_version &0xffff );break ;
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -219,7 +219,7 @@ static u32 pm_tz_version;* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_get_api_version (u32 *version) +int zynqmp_pm_get_api_version (u32 *version) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -237,6 +237,7 @@ static int zynqmp_pm_get_api_version(u32 *version)return ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_get_api_version);/** * zynqmp_pm_get_chipid - Get silicon ID registers
@@ -708,7 +709,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .get_api_version = zynqmp_pm_get_api_version, .get_chipid = zynqmp_pm_get_chipid, .query_data = zynqmp_pm_query_data, .clock_enable = zynqmp_pm_clock_enable,
drivers/soc/xilinx/zynqmp_power.c +2 -2
@@ -186,11 +186,11 @@ static int zynqmp_pm_probe(struct platform_device *pdev)if (IS_ERR (eemi_ops))return PTR_ERR (eemi_ops); -if (!eemi_ops->get_api_version || !eemi_ops->init_finalize) +if (!eemi_ops->init_finalize)return -ENXIO ; eemi_ops->init_finalize (); - eemi_ops->get_api_version (&pm_api_version); +zynqmp_pm_get_api_version (&pm_api_version);/* Check PM API version number */ if (pm_api_version <ZYNQMP_PM_VERSION )
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -286,7 +286,6 @@ struct zynqmp_pm_query_data { };struct zynqmp_eemi_ops { -int (*get_api_version)(u32 *version);int (*get_chipid)(u32 *idcode,u32 *version);int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value);
@@ -317,6 +316,7 @@ struct zynqmp_eemi_ops { const enum zynqmp_pm_request_ack ack); }; +int zynqmp_pm_get_api_version (u32 *version);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 2/24 firmware: xilinx: Remove eemi ops for get_chipid
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of eemi ops for get_chipid.
--- drivers/firmware/xilinx/zynqmp.c | 4 ++-- drivers/nvmem/zynqmp_nvmem.c | 11 +---------- include/linux/firmware/xlnx-zynqmp.h | 2 +- 3 files changed, 4 insertions(+), 13 deletions(-)
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -247,7 +247,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_api_version);* Return: Returns the status of the operation and the idcode and version * registers in @idcode and @version. */ -static int zynqmp_pm_get_chipid (u32 *idcode,u32 *version) +int zynqmp_pm_get_chipid (u32 *idcode,u32 *version) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -261,6 +261,7 @@ static int zynqmp_pm_get_chipid(u32 *idcode, u32 *version)return ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_get_chipid);/** * zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version
@@ -709,7 +710,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .get_chipid = zynqmp_pm_get_chipid, .query_data = zynqmp_pm_query_data, .clock_enable = zynqmp_pm_clock_enable, .clock_disable = zynqmp_pm_clock_disable,
drivers/nvmem/zynqmp_nvmem.c +1 -10
@@ -16,8 +16,6 @@ struct zynqmp_nvmem_data {struct nvmem_device *nvmem; }; -static const struct zynqmp_eemi_ops *eemi_ops; -static int zynqmp_nvmem_read (void *context,unsigned int offset,void *val,size_t bytes) {
@@ -25,10 +23,7 @@ static int zynqmp_nvmem_read(void *context, unsigned int offset,int idcode, version;struct zynqmp_nvmem_data *priv = context; -if (!eemi_ops->get_chipid) -return -ENXIO ; - - ret = eemi_ops->get_chipid (&idcode, &version); + ret =zynqmp_pm_get_chipid (&idcode, &version);if (ret <0 )return ret;
@@ -61,10 +56,6 @@ static int zynqmp_nvmem_probe(struct platform_device *pdev)if (!priv)return -ENOMEM ; - eemi_ops =zynqmp_pm_get_eemi_ops (); -if (IS_ERR (eemi_ops)) -return PTR_ERR (eemi_ops); - priv->dev = dev; econfig.dev = dev; econfig.reg_read = zynqmp_nvmem_read;
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -286,7 +286,6 @@ struct zynqmp_pm_query_data { };struct zynqmp_eemi_ops { -int (*get_chipid)(u32 *idcode,u32 *version);int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value);int (*query_data)(struct zynqmp_pm_query_data qdata,u32 *out);
@@ -317,6 +316,7 @@ struct zynqmp_eemi_ops { };int zynqmp_pm_get_api_version (u32 *version); +int zynqmp_pm_get_chipid (u32 *idcode,u32 *version);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 3/24 firmware: xilinx: Remove eemi ops for query_data
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call for query_data instead of using eemi ops.
--- drivers/clk/zynqmp/clkc.c | 17 ++++++----------- drivers/clk/zynqmp/divider.c | 3 +-- drivers/firmware/xilinx/zynqmp-debug.c | 3 +-- drivers/firmware/xilinx/zynqmp.c | 4 ++-- include/linux/firmware/xlnx-zynqmp.h | 2 +- 5 files changed, 11 insertions(+), 18 deletions(-)
drivers/clk/zynqmp/clkc.c +6 -11
@@ -134,7 +134,6 @@ static struct clk_hw *(* const clk_topology[]) (const char *name, u32 clk_id,static struct zynqmp_clock *clock;static struct clk_hw_onecell_data *zynqmp_data;static unsigned int clock_max_idx; -static const struct zynqmp_eemi_ops *eemi_ops;/** * zynqmp_is_valid_clock() - Check whether clock is valid or not
@@ -206,7 +205,7 @@ static int zynqmp_pm_clock_get_num_clocks(u32 *nclocks) qdata.qid =PM_QID_CLOCK_GET_NUM_CLOCKS ; - ret = eemi_ops->query_data (qdata, ret_payload); + ret =zynqmp_pm_query_data (qdata, ret_payload); *nclocks = ret_payload[1 ];return ret;
@@ -231,7 +230,7 @@ static int zynqmp_pm_clock_get_name(u32 clock_id, qdata.qid =PM_QID_CLOCK_GET_NAME ; qdata.arg1 = clock_id; - eemi_ops->query_data (qdata, ret_payload); +zynqmp_pm_query_data (qdata, ret_payload);memcpy (response, ret_payload,sizeof (*response));return 0 ;
@@ -265,7 +264,7 @@ static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, qdata.arg1 = clock_id; qdata.arg2 = index; - ret = eemi_ops->query_data (qdata, ret_payload); + ret =zynqmp_pm_query_data (qdata, ret_payload);memcpy (response, &ret_payload[1 ],sizeof (*response));return ret;
@@ -296,7 +295,7 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id, qdata.qid =PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS ; qdata.arg1 = clk_id; - ret = eemi_ops->query_data (qdata, ret_payload); + ret =zynqmp_pm_query_data (qdata, ret_payload);if (ret)return ERR_PTR (ret);
@@ -339,7 +338,7 @@ static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, qdata.arg1 = clock_id; qdata.arg2 = index; - ret = eemi_ops->query_data (qdata, ret_payload); + ret =zynqmp_pm_query_data (qdata, ret_payload);memcpy (response, &ret_payload[1 ],sizeof (*response));return ret;
@@ -364,7 +363,7 @@ static int zynqmp_pm_clock_get_attributes(u32 clock_id, qdata.qid =PM_QID_CLOCK_GET_ATTRIBUTES ; qdata.arg1 = clock_id; - ret = eemi_ops->query_data (qdata, ret_payload); + ret =zynqmp_pm_query_data (qdata, ret_payload);memcpy (response, &ret_payload[1 ],sizeof (*response));return ret;
@@ -738,10 +737,6 @@ static int zynqmp_clock_probe(struct platform_device *pdev)int ret;struct device *dev = &pdev->dev; - eemi_ops =zynqmp_pm_get_eemi_ops (); -if (IS_ERR (eemi_ops)) -return PTR_ERR (eemi_ops); - ret =zynqmp_clk_setup (dev->of_node);return ret;
drivers/clk/zynqmp/divider.c +1 -2
@@ -258,7 +258,6 @@ static const struct clk_ops zynqmp_clk_divider_ops = {*/ u32 zynqmp_clk_get_max_divisor (u32 clk_id,u32 type) { -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();struct zynqmp_pm_query_data qdata = {0 };u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -266,7 +265,7 @@ u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type) qdata.qid =PM_QID_CLOCK_GET_MAX_DIVISOR ; qdata.arg1 = clk_id; qdata.arg2 = type; - ret = eemi_ops->query_data (qdata, ret_payload); + ret =zynqmp_pm_query_data (qdata, ret_payload);/* * To maintain backward compatibility return maximum possible value * (0xFFFF) if query for max divisor is not successful.
drivers/firmware/xilinx/zynqmp-debug.c +1 -2
@@ -85,7 +85,6 @@ static int get_pm_api_id(char *pm_api_req, u32 *pm_id)static int process_api_request (u32 pm_id,u64 *pm_api_arg,u32 *pm_api_ret) { -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();u32 pm_api_version;int ret;struct zynqmp_pm_query_data qdata = {0 };
@@ -102,7 +101,7 @@ static int process_api_request(u32 pm_id, u64 *pm_api_arg, u32 *pm_api_ret) qdata.arg2 = pm_api_arg[2 ]; qdata.arg3 = pm_api_arg[3 ]; - ret = eemi_ops->query_data (qdata, pm_api_ret); + ret =zynqmp_pm_query_data (qdata, pm_api_ret);if (ret)break ;
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -326,7 +326,7 @@ static int get_set_conduit_method(struct device_node *np)* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_query_data (struct zynqmp_pm_query_data qdata,u32 *out) +int zynqmp_pm_query_data (struct zynqmp_pm_query_data qdata,u32 *out) {int ret;
@@ -340,6 +340,7 @@ static int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out)*/ return qdata.qid ==PM_QID_CLOCK_GET_NAME ?0 : ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_query_data);/** * zynqmp_pm_clock_enable() - Enable the clock for given id
@@ -710,7 +711,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .query_data = zynqmp_pm_query_data, .clock_enable = zynqmp_pm_clock_enable, .clock_disable = zynqmp_pm_clock_disable, .clock_getstate = zynqmp_pm_clock_getstate,
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*query_data)(struct zynqmp_pm_query_data qdata,u32 *out);int (*clock_enable)(u32 clock_id);int (*clock_disable)(u32 clock_id);int (*clock_getstate)(u32 clock_id,u32 *state);
@@ -317,6 +316,7 @@ struct zynqmp_eemi_ops {int zynqmp_pm_get_api_version (u32 *version);int zynqmp_pm_get_chipid (u32 *idcode,u32 *version); +int zynqmp_pm_query_data (struct zynqmp_pm_query_data qdata,u32 *out);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 4/24 firmware: xilinx: Remove eemi ops for clock_enable
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call for clock_enable instead of eemi ops.
--- drivers/clk/zynqmp/clk-gate-zynqmp.c | 2 +- drivers/clk/zynqmp/pll.c | 3 +-- drivers/firmware/xilinx/zynqmp.c | 4 ++-- include/linux/firmware/xlnx-zynqmp.h | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-)
drivers/clk/zynqmp/clk-gate-zynqmp.c +1 -1
@@ -39,7 +39,7 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)int ret;const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_enable (clk_id); + ret =zynqmp_pm_clock_enable (clk_id);if (ret) pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
drivers/clk/zynqmp/pll.c +1 -2
@@ -246,12 +246,11 @@ static int zynqmp_pll_enable(struct clk_hw *hw)const char *clk_name =clk_hw_get_name (hw);u32 clk_id = clk->clk_id;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();if (zynqmp_pll_is_enabled (hw))return 0 ; - ret = eemi_ops->clock_enable (clk_id); + ret =zynqmp_pm_clock_enable (clk_id);if (ret)pr_warn_once ("%s() clock enable failed for %s, ret = %d\n" , __func__, clk_name, ret);
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -351,10 +351,11 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_query_data);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_enable (u32 clock_id) +int zynqmp_pm_clock_enable (u32 clock_id) {return zynqmp_pm_invoke_fn (PM_CLOCK_ENABLE , clock_id,0 ,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_enable);/** * zynqmp_pm_clock_disable() - Disable the clock for given id
@@ -711,7 +712,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .clock_enable = zynqmp_pm_clock_enable, .clock_disable = zynqmp_pm_clock_disable, .clock_getstate = zynqmp_pm_clock_getstate, .clock_setdivider = zynqmp_pm_clock_setdivider,
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*clock_enable)(u32 clock_id);int (*clock_disable)(u32 clock_id);int (*clock_getstate)(u32 clock_id,u32 *state);int (*clock_setdivider)(u32 clock_id,u32 divider);
@@ -317,6 +316,7 @@ struct zynqmp_eemi_ops {int zynqmp_pm_get_api_version (u32 *version);int zynqmp_pm_get_chipid (u32 *idcode,u32 *version);int zynqmp_pm_query_data (struct zynqmp_pm_query_data qdata,u32 *out); +int zynqmp_pm_clock_enable (u32 clock_id);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 5/24 firmware: xilinx: Remove eemi ops for clock_disable
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call for clock_disable instead using of eemi ops.
--- drivers/clk/zynqmp/clk-gate-zynqmp.c | 4 +--- drivers/clk/zynqmp/pll.c | 3 +-- drivers/firmware/xilinx/zynqmp.c | 4 ++-- include/linux/firmware/xlnx-zynqmp.h | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-)
drivers/clk/zynqmp/clk-gate-zynqmp.c +1 -3
@@ -37,7 +37,6 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)const char *clk_name =clk_hw_get_name (hw);u32 clk_id = gate->clk_id;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); ret =zynqmp_pm_clock_enable (clk_id);
@@ -58,9 +57,8 @@ static void zynqmp_clk_gate_disable(struct clk_hw *hw)const char *clk_name =clk_hw_get_name (hw);u32 clk_id = gate->clk_id;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_disable (clk_id); + ret =zynqmp_pm_clock_disable (clk_id);if (ret) pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
drivers/clk/zynqmp/pll.c +1 -2
@@ -268,12 +268,11 @@ static void zynqmp_pll_disable(struct clk_hw *hw)const char *clk_name =clk_hw_get_name (hw);u32 clk_id = clk->clk_id;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();if (!zynqmp_pll_is_enabled (hw))return ; - ret = eemi_ops->clock_disable (clk_id); + ret =zynqmp_pm_clock_disable (clk_id);if (ret)pr_warn_once ("%s() clock disable failed for %s, ret = %d\n" , __func__, clk_name, ret);
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -366,10 +366,11 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_enable);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_disable (u32 clock_id) +int zynqmp_pm_clock_disable (u32 clock_id) {return zynqmp_pm_invoke_fn (PM_CLOCK_DISABLE , clock_id,0 ,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_disable);/** * zynqmp_pm_clock_getstate() - Get the clock state for given id
@@ -712,7 +713,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .clock_disable = zynqmp_pm_clock_disable, .clock_getstate = zynqmp_pm_clock_getstate, .clock_setdivider = zynqmp_pm_clock_setdivider, .clock_getdivider = zynqmp_pm_clock_getdivider,
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*clock_disable)(u32 clock_id);int (*clock_getstate)(u32 clock_id,u32 *state);int (*clock_setdivider)(u32 clock_id,u32 divider);int (*clock_getdivider)(u32 clock_id,u32 *divider);
@@ -317,6 +316,7 @@ int zynqmp_pm_get_api_version(u32 *version);int zynqmp_pm_get_chipid (u32 *idcode,u32 *version);int zynqmp_pm_query_data (struct zynqmp_pm_query_data qdata,u32 *out);int zynqmp_pm_clock_enable (u32 clock_id); +int zynqmp_pm_clock_disable (u32 clock_id);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 6/24 firmware: xilinx: Remove eemi ops for clock_getstate
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of eemi ops for clock_getstate.
--- drivers/clk/zynqmp/clk-gate-zynqmp.c | 3 +-- drivers/clk/zynqmp/pll.c | 3 +-- drivers/firmware/xilinx/zynqmp.c | 4 ++-- include/linux/firmware/xlnx-zynqmp.h | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-)
drivers/clk/zynqmp/clk-gate-zynqmp.c +1 -2
@@ -77,9 +77,8 @@ static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)const char *clk_name =clk_hw_get_name (hw);u32 clk_id = gate->clk_id;int state, ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_getstate (clk_id, &state); + ret =zynqmp_pm_clock_getstate (clk_id, &state);if (ret) {pr_warn_once ("%s() clock get state failed for %s, ret = %d\n" , __func__, clk_name, ret);
drivers/clk/zynqmp/pll.c +1 -2
@@ -222,9 +222,8 @@ static int zynqmp_pll_is_enabled(struct clk_hw *hw)u32 clk_id = clk->clk_id;unsigned int state;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_getstate (clk_id, &state); + ret =zynqmp_pm_clock_getstate (clk_id, &state);if (ret) {pr_warn_once ("%s() clock get state failed for %s, ret = %d\n" , __func__, clk_name, ret);
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_disable);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_getstate (u32 clock_id,u32 *state) +int zynqmp_pm_clock_getstate (u32 clock_id,u32 *state) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -393,6 +393,7 @@ static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)return ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_getstate);/** * zynqmp_pm_clock_setdivider() - Set the clock divider for given id
@@ -713,7 +714,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .clock_getstate = zynqmp_pm_clock_getstate, .clock_setdivider = zynqmp_pm_clock_setdivider, .clock_getdivider = zynqmp_pm_clock_getdivider, .clock_setrate = zynqmp_pm_clock_setrate,
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*clock_getstate)(u32 clock_id,u32 *state);int (*clock_setdivider)(u32 clock_id,u32 divider);int (*clock_getdivider)(u32 clock_id,u32 *divider);int (*clock_setrate)(u32 clock_id,u64 rate);
@@ -317,6 +316,7 @@ int zynqmp_pm_get_chipid(u32 *idcode, u32 *version);int zynqmp_pm_query_data (struct zynqmp_pm_query_data qdata,u32 *out);int zynqmp_pm_clock_enable (u32 clock_id);int zynqmp_pm_clock_disable (u32 clock_id); +int zynqmp_pm_clock_getstate (u32 clock_id,u32 *state);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 7/24 firmware: xilinx: Remove eemi ops for clock_setdivider
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for clock_setdivider.
--- drivers/clk/zynqmp/divider.c | 3 +-- drivers/clk/zynqmp/pll.c | 4 ++-- drivers/firmware/xilinx/zynqmp.c | 4 ++-- include/linux/firmware/xlnx-zynqmp.h | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-)
drivers/clk/zynqmp/divider.c +1 -2
@@ -219,7 +219,6 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,u32 div_type = divider->div_type;u32 value, div;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); value =zynqmp_divider_get_val (parent_rate, rate, divider->flags);if (div_type ==TYPE_DIV1 ) {
@@ -233,7 +232,7 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,if (divider->flags &CLK_DIVIDER_POWER_OF_TWO ) div =__ffs (div); - ret = eemi_ops->clock_setdivider (clk_id, div); + ret =zynqmp_pm_clock_setdivider (clk_id, div);if (ret) pr_warn_once("%s() set divider failed for %s, ret = %d\n",
drivers/clk/zynqmp/pll.c +2 -2
@@ -187,7 +187,7 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate, rate = parent_rate * m; frac = (parent_rate * f) /FRAC_DIV ; - ret = eemi_ops->clock_setdivider (clk_id, m); + ret =zynqmp_pm_clock_setdivider (clk_id, m);if (ret == -EUSERS )WARN (1 ,"More than allowed devices are using the %s, which is forbidden\n" , clk_name);
@@ -201,7 +201,7 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate, fbdiv =DIV_ROUND_CLOSEST (rate, parent_rate); fbdiv =clamp_t (u32, fbdiv,PLL_FBDIV_MIN ,PLL_FBDIV_MAX ); - ret = eemi_ops->clock_setdivider (clk_id, fbdiv); + ret =zynqmp_pm_clock_setdivider (clk_id, fbdiv);if (ret)pr_warn_once ("%s() set divider failed for %s, ret = %d\n" , __func__, clk_name, ret);
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -405,11 +405,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getstate);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_setdivider (u32 clock_id,u32 divider) +int zynqmp_pm_clock_setdivider (u32 clock_id,u32 divider) {return zynqmp_pm_invoke_fn (PM_CLOCK_SETDIVIDER , clock_id, divider,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_setdivider);/** * zynqmp_pm_clock_getdivider() - Get the clock divider for given id
@@ -714,7 +715,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .clock_setdivider = zynqmp_pm_clock_setdivider, .clock_getdivider = zynqmp_pm_clock_getdivider, .clock_setrate = zynqmp_pm_clock_setrate, .clock_getrate = zynqmp_pm_clock_getrate,
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*clock_setdivider)(u32 clock_id,u32 divider);int (*clock_getdivider)(u32 clock_id,u32 *divider);int (*clock_setrate)(u32 clock_id,u64 rate);int (*clock_getrate)(u32 clock_id,u64 *rate);
@@ -317,6 +316,7 @@ int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out);int zynqmp_pm_clock_enable (u32 clock_id);int zynqmp_pm_clock_disable (u32 clock_id);int zynqmp_pm_clock_getstate (u32 clock_id,u32 *state); +int zynqmp_pm_clock_setdivider (u32 clock_id,u32 divider);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 8/24 firmware: xilinx: Remove eemi ops for clock_getdivider
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for clock_getdivider.
--- drivers/clk/zynqmp/divider.c | 6 ++---- drivers/clk/zynqmp/pll.c | 2 +- drivers/firmware/xilinx/zynqmp.c | 4 ++-- include/linux/firmware/xlnx-zynqmp.h | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-)
drivers/clk/zynqmp/divider.c +2 -4
@@ -83,9 +83,8 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,u32 div_type = divider->div_type;u32 div, value;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_getdivider (clk_id, &div); + ret =zynqmp_pm_clock_getdivider (clk_id, &div);if (ret) pr_warn_once("%s() get divider failed for %s, ret = %d\n",
@@ -163,11 +162,10 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,u32 div_type = divider->div_type;u32 bestdiv;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();/* if read only, just return current value */ if (divider->flags &CLK_DIVIDER_READ_ONLY ) { - ret = eemi_ops->clock_getdivider (clk_id, &bestdiv); + ret =zynqmp_pm_clock_getdivider (clk_id, &bestdiv);if (ret) pr_warn_once("%s() get divider failed for %s, ret = %d\n",
drivers/clk/zynqmp/pll.c +1 -1
@@ -141,7 +141,7 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,int ret;const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_getdivider (clk_id, &fbdiv); + ret =zynqmp_pm_clock_getdivider (clk_id, &fbdiv);if (ret)pr_warn_once ("%s() get divider failed for %s, ret = %d\n" , __func__, clk_name, ret);
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -422,7 +422,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setdivider);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_getdivider (u32 clock_id,u32 *divider) +int zynqmp_pm_clock_getdivider (u32 clock_id,u32 *divider) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -433,6 +433,7 @@ static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)return ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_getdivider);/** * zynqmp_pm_clock_setrate() - Set the clock rate for given id
@@ -715,7 +716,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .clock_getdivider = zynqmp_pm_clock_getdivider, .clock_setrate = zynqmp_pm_clock_setrate, .clock_getrate = zynqmp_pm_clock_getrate, .clock_setparent = zynqmp_pm_clock_setparent,
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*clock_getdivider)(u32 clock_id,u32 *divider);int (*clock_setrate)(u32 clock_id,u64 rate);int (*clock_getrate)(u32 clock_id,u64 *rate);int (*clock_setparent)(u32 clock_id,u32 parent_id);
@@ -317,6 +316,7 @@ int zynqmp_pm_clock_enable(u32 clock_id);int zynqmp_pm_clock_disable (u32 clock_id);int zynqmp_pm_clock_getstate (u32 clock_id,u32 *state);int zynqmp_pm_clock_setdivider (u32 clock_id,u32 divider); +int zynqmp_pm_clock_getdivider (u32 clock_id,u32 *divider);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 9/24 firmware: xilinx: Remove eemi ops for clock set/get rate
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of eemi ops for clock set/get rate.
--- drivers/firmware/xilinx/zynqmp.c | 8 ++++---- include/linux/firmware/xlnx-zynqmp.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-)
drivers/firmware/xilinx/zynqmp.c +4 -4
@@ -444,13 +444,14 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getdivider);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_setrate (u32 clock_id,u64 rate) +int zynqmp_pm_clock_setrate (u32 clock_id,u64 rate) {return zynqmp_pm_invoke_fn (PM_CLOCK_SETRATE , clock_id,lower_32_bits (rate),upper_32_bits (rate),0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_setrate);/** * zynqmp_pm_clock_getrate() - Get the clock rate for given id
@@ -462,7 +463,7 @@ static int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate)* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_getrate (u32 clock_id,u64 *rate) +int zynqmp_pm_clock_getrate (u32 clock_id,u64 *rate) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -473,6 +474,7 @@ static int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate)return ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_getrate);/** * zynqmp_pm_clock_setparent() - Set the clock parent for given id
@@ -716,8 +718,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .clock_setrate = zynqmp_pm_clock_setrate, - .clock_getrate = zynqmp_pm_clock_getrate, .clock_setparent = zynqmp_pm_clock_setparent, .clock_getparent = zynqmp_pm_clock_getparent, .ioctl = zynqmp_pm_ioctl,
include/linux/firmware/xlnx-zynqmp.h +2 -2
@@ -288,8 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*clock_setrate)(u32 clock_id,u64 rate); -int (*clock_getrate)(u32 clock_id,u64 *rate);int (*clock_setparent)(u32 clock_id,u32 parent_id);int (*clock_getparent)(u32 clock_id,u32 *parent_id);int (*ioctl)(u32 node_id,u32 ioctl_id,u32 arg1,u32 arg2,u32 *out);
@@ -317,6 +315,8 @@ int zynqmp_pm_clock_disable(u32 clock_id);int zynqmp_pm_clock_getstate (u32 clock_id,u32 *state);int zynqmp_pm_clock_setdivider (u32 clock_id,u32 divider);int zynqmp_pm_clock_getdivider (u32 clock_id,u32 *divider); +int zynqmp_pm_clock_setrate (u32 clock_id,u64 rate); +int zynqmp_pm_clock_getrate (u32 clock_id,u64 *rate);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 7 lines
2.7.4 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v3 10/24 firmware: xilinx: Remove eemi ops for clock set/get parent
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of eemi ops for clock set/get parent.
--- drivers/clk/zynqmp/clk-mux-zynqmp.c | 6 ++---- drivers/firmware/xilinx/zynqmp.c | 8 ++++---- include/linux/firmware/xlnx-zynqmp.h | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-)
drivers/clk/zynqmp/clk-mux-zynqmp.c +2 -4
@@ -47,9 +47,8 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)u32 clk_id = mux->clk_id;u32 val;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_getparent (clk_id, &val); + ret =zynqmp_pm_clock_getparent (clk_id, &val);if (ret) pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
@@ -71,9 +70,8 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)const char *clk_name =clk_hw_get_name (hw);u32 clk_id = mux->clk_id;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->clock_setparent (clk_id, index); + ret =zynqmp_pm_clock_setparent (clk_id, index);if (ret) pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n",
drivers/firmware/xilinx/zynqmp.c +4 -4
@@ -485,11 +485,12 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getrate);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_setparent (u32 clock_id,u32 parent_id) +int zynqmp_pm_clock_setparent (u32 clock_id,u32 parent_id) {return zynqmp_pm_invoke_fn (PM_CLOCK_SETPARENT , clock_id, parent_id,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_setparent);/** * zynqmp_pm_clock_getparent() - Get the clock parent for given id
@@ -501,7 +502,7 @@ static int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id)* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_clock_getparent (u32 clock_id,u32 *parent_id) +int zynqmp_pm_clock_getparent (u32 clock_id,u32 *parent_id) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -512,6 +513,7 @@ static int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id)return ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_clock_getparent);/** * zynqmp_is_valid_ioctl() - Check whether IOCTL ID is valid or not
@@ -718,8 +720,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .clock_setparent = zynqmp_pm_clock_setparent, - .clock_getparent = zynqmp_pm_clock_getparent, .ioctl = zynqmp_pm_ioctl, .reset_assert = zynqmp_pm_reset_assert, .reset_get_status = zynqmp_pm_reset_get_status,
include/linux/firmware/xlnx-zynqmp.h +2 -2
@@ -288,8 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*clock_setparent)(u32 clock_id,u32 parent_id); -int (*clock_getparent)(u32 clock_id,u32 *parent_id);int (*ioctl)(u32 node_id,u32 ioctl_id,u32 arg1,u32 arg2,u32 *out);int (*reset_assert)(const enum zynqmp_pm_reset reset,const enum zynqmp_pm_reset_action assert_flag);
@@ -317,6 +315,8 @@ int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider);int zynqmp_pm_clock_getdivider (u32 clock_id,u32 *divider);int zynqmp_pm_clock_setrate (u32 clock_id,u64 rate);int zynqmp_pm_clock_getrate (u32 clock_id,u64 *rate); +int zynqmp_pm_clock_setparent (u32 clock_id,u32 parent_id); +int zynqmp_pm_clock_getparent (u32 clock_id,u32 *parent_id);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 11/24 firmware: xilinx: Use APIs instead of IOCTLs
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Remove IOCTL API and use individual APIs for better readability.
--- drivers/clk/zynqmp/pll.c | 14 ++--- drivers/firmware/xilinx/zynqmp.c | 99 ++++++++++++++++++++++++++---------- drivers/mmc/host/sdhci-of-arasan.c | 33 +----------- include/linux/firmware/xlnx-zynqmp.h | 6 ++- 4 files changed, 83 insertions(+), 69 deletions(-)
drivers/clk/zynqmp/pll.c +4 -10
@@ -50,10 +50,8 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)const char *clk_name =clk_hw_get_name (hw);u32 ret_payload[PAYLOAD_ARG_CNT ];int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); - ret = eemi_ops->ioctl (0 ,IOCTL_GET_PLL_FRAC_MODE , clk_id,0 , - ret_payload); + ret =zynqmp_pm_get_pll_frac_mode (clk_id, ret_payload);if (ret)pr_warn_once ("%s() PLL get frac mode failed for %s, ret = %d\n" , __func__, clk_name, ret);
@@ -73,14 +71,13 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)const char *clk_name =clk_hw_get_name (hw);int ret;u32 mode; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();if (on) mode =PLL_MODE_FRAC ;else mode =PLL_MODE_INT ; - ret = eemi_ops->ioctl (0 ,IOCTL_SET_PLL_FRAC_MODE , clk_id, mode,NULL ); + ret =zynqmp_pm_set_pll_frac_mode (clk_id, mode);if (ret)pr_warn_once ("%s() PLL set frac mode failed for %s, ret = %d\n" , __func__, clk_name, ret);
@@ -139,7 +136,6 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,unsigned long rate, frac;u32 ret_payload[PAYLOAD_ARG_CNT ];int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops (); ret =zynqmp_pm_clock_getdivider (clk_id, &fbdiv);if (ret)
@@ -148,8 +144,7 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, rate = parent_rate * fbdiv;if (zynqmp_pll_get_mode (hw) ==PLL_MODE_FRAC ) { - eemi_ops->ioctl (0 ,IOCTL_GET_PLL_FRAC_DATA , clk_id,0 , - ret_payload); +zynqmp_pm_get_pll_frac_data (clk_id, ret_payload); data = ret_payload[1 ]; frac = (parent_rate * data) /FRAC_DIV ; rate = rate + frac;
@@ -177,7 +172,6 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,u32 fbdiv;long rate_div, frac, m, f;int ret; -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();if (zynqmp_pll_get_mode (hw) ==PLL_MODE_FRAC ) { rate_div = (rate *FRAC_DIV ) / parent_rate;
@@ -194,7 +188,7 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,else if (ret)pr_warn_once ("%s() set divider failed for %s, ret = %d\n" , __func__, clk_name, ret); - eemi_ops->ioctl (0 ,IOCTL_SET_PLL_FRAC_DATA , clk_id, f,NULL ); +zynqmp_pm_set_pll_frac_data (clk_id, f);return rate + frac; }
drivers/firmware/xilinx/zynqmp.c +72 -27
124 lines not on this page · raw message
drivers/mmc/host/sdhci-of-arasan.c +2 -31
@@ -98,10 +98,6 @@ struct sdhci_arasan_clk_data {void *clk_of_data; }; -struct sdhci_arasan_zynqmp_clk_data { -const struct zynqmp_eemi_ops *eemi_ops; -}; -/** * struct sdhci_arasan_data * @host: Pointer to the main SDHCI host structure.
@@ -630,9 +626,6 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees)struct sdhci_arasan_data *sdhci_arasan = container_of(clk_data, struct sdhci_arasan_data, clk_data);struct sdhci_host *host = sdhci_arasan->host; -struct sdhci_arasan_zynqmp_clk_data *zynqmp_clk_data = - clk_data->clk_of_data; -const struct zynqmp_eemi_ops *eemi_ops = zynqmp_clk_data->eemi_ops;const char *clk_name =clk_hw_get_name (hw);u32 node_id = !strcmp (clk_name,"clk_out_sd0" ) ?NODE_SD_0 :NODE_SD_1 ;u8 tap_delay, tap_max =0 ;
@@ -672,8 +665,7 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) tap_delay = (degrees * tap_max) /360 ;/* Set the Clock Phase */ - ret = eemi_ops->ioctl (node_id,IOCTL_SET_SD_TAPDELAY , -PM_TAPDELAY_OUTPUT , tap_delay,NULL ); + ret =zynqmp_pm_set_sd_tapdelay (node_id,PM_TAPDELAY_OUTPUT , tap_delay);if (ret)pr_err ("Error setting Output Tap Delay\n" );
@@ -702,9 +694,6 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees)struct sdhci_arasan_data *sdhci_arasan = container_of(clk_data, struct sdhci_arasan_data, clk_data);struct sdhci_host *host = sdhci_arasan->host; -struct sdhci_arasan_zynqmp_clk_data *zynqmp_clk_data = - clk_data->clk_of_data; -const struct zynqmp_eemi_ops *eemi_ops = zynqmp_clk_data->eemi_ops;const char *clk_name =clk_hw_get_name (hw);u32 node_id = !strcmp (clk_name,"clk_in_sd0" ) ?NODE_SD_0 :NODE_SD_1 ;u8 tap_delay, tap_max =0 ;
@@ -744,8 +733,7 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees) tap_delay = (degrees * tap_max) /360 ;/* Set the Clock Phase */ - ret = eemi_ops->ioctl (node_id,IOCTL_SET_SD_TAPDELAY , -PM_TAPDELAY_INPUT , tap_delay,NULL ); + ret =zynqmp_pm_set_sd_tapdelay (node_id,PM_TAPDELAY_INPUT , tap_delay);if (ret)pr_err ("Error setting Input Tap Delay\n" );
@@ -1232,23 +1220,6 @@ static int sdhci_arasan_probe(struct platform_device *pdev)if (ret) goto clk_disable_all; -if (of_device_is_compatible (np,"xlnx,zynqmp-8.9a" )) { -struct sdhci_arasan_zynqmp_clk_data *zynqmp_clk_data; -const struct zynqmp_eemi_ops *eemi_ops; - - zynqmp_clk_data =devm_kzalloc (&pdev->dev, -sizeof (*zynqmp_clk_data), -GFP_KERNEL ); - eemi_ops =zynqmp_pm_get_eemi_ops (); -if (IS_ERR (eemi_ops)) { - ret =PTR_ERR (eemi_ops); - goto unreg_clk; - } - - zynqmp_clk_data->eemi_ops = eemi_ops; - sdhci_arasan->clk_data.clk_of_data = zynqmp_clk_data; - } -arasan_dt_parse_clk_phases (&pdev->dev, &sdhci_arasan->clk_data); ret =mmc_of_parse (host->mmc);
include/linux/firmware/xlnx-zynqmp.h +5 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*ioctl)(u32 node_id,u32 ioctl_id,u32 arg1,u32 arg2,u32 *out);int (*reset_assert)(const enum zynqmp_pm_reset reset,const enum zynqmp_pm_reset_action assert_flag);int (*reset_get_status)(const enum zynqmp_pm_reset reset,u32 *status);
@@ -317,6 +316,11 @@ int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate);int zynqmp_pm_clock_getrate (u32 clock_id,u64 *rate);int zynqmp_pm_clock_setparent (u32 clock_id,u32 parent_id);int zynqmp_pm_clock_getparent (u32 clock_id,u32 *parent_id); +int zynqmp_pm_set_pll_frac_mode (u32 clk_id,u32 mode); +int zynqmp_pm_get_pll_frac_mode (u32 clk_id,u32 *mode); +int zynqmp_pm_set_pll_frac_data (u32 clk_id,u32 data); +int zynqmp_pm_get_pll_frac_data (u32 clk_id,u32 *data); +int zynqmp_pm_set_sd_tapdelay (u32 node_id,u32 type,u32 value);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 12/24 firmware: xilinx: Remove eemi ops for reset_assert
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for reset_assert.
--- drivers/firmware/xilinx/zynqmp.c | 6 +++--- drivers/reset/reset-zynqmp.c | 18 ++++++------------ include/linux/firmware/xlnx-zynqmp.h | 4 ++-- 3 files changed, 11 insertions(+), 17 deletions(-)
drivers/firmware/xilinx/zynqmp.c +3 -3
@@ -610,12 +610,13 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_reset_assert (const enum zynqmp_pm_reset reset, -const enum zynqmp_pm_reset_action assert_flag) +int zynqmp_pm_reset_assert (const enum zynqmp_pm_reset reset, +const enum zynqmp_pm_reset_action assert_flag) {return zynqmp_pm_invoke_fn (PM_RESET_ASSERT , reset, assert_flag,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_reset_assert);/** * zynqmp_pm_reset_get_status - Get status of the reset
@@ -766,7 +767,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .reset_assert = zynqmp_pm_reset_assert, .reset_get_status = zynqmp_pm_reset_get_status, .init_finalize = zynqmp_pm_init_finalize, .set_suspend_mode = zynqmp_pm_set_suspend_mode,
drivers/reset/reset-zynqmp.c +6 -12
@@ -27,19 +27,15 @@ to_zynqmp_reset_data(struct reset_controller_dev *rcdev)static int zynqmp_reset_assert (struct reset_controller_dev *rcdev,unsigned long id) { -struct zynqmp_reset_data *priv =to_zynqmp_reset_data (rcdev); - -return priv->eemi_ops->reset_assert (ZYNQMP_RESET_ID + id, -PM_RESET_ACTION_ASSERT ); +return zynqmp_pm_reset_assert (ZYNQMP_RESET_ID + id, +PM_RESET_ACTION_ASSERT ); }static int zynqmp_reset_deassert (struct reset_controller_dev *rcdev,unsigned long id) { -struct zynqmp_reset_data *priv =to_zynqmp_reset_data (rcdev); - -return priv->eemi_ops->reset_assert (ZYNQMP_RESET_ID + id, -PM_RESET_ACTION_RELEASE ); +return zynqmp_pm_reset_assert (ZYNQMP_RESET_ID + id, +PM_RESET_ACTION_RELEASE ); } static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
@@ -58,10 +54,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,static int zynqmp_reset_reset (struct reset_controller_dev *rcdev,unsigned long id) { -struct zynqmp_reset_data *priv =to_zynqmp_reset_data (rcdev); - -return priv->eemi_ops->reset_assert (ZYNQMP_RESET_ID + id, -PM_RESET_ACTION_PULSE ); +return zynqmp_pm_reset_assert (ZYNQMP_RESET_ID + id, +PM_RESET_ACTION_PULSE ); }static const struct reset_control_ops zynqmp_reset_ops = {
include/linux/firmware/xlnx-zynqmp.h +2 -2
@@ -288,8 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*reset_assert)(const enum zynqmp_pm_reset reset, -const enum zynqmp_pm_reset_action assert_flag);int (*reset_get_status)(const enum zynqmp_pm_reset reset,u32 *status);int (*init_finalize)(void );int (*set_suspend_mode)(u32 mode);
@@ -321,6 +319,8 @@ int zynqmp_pm_get_pll_frac_mode(u32 clk_id, u32 *mode);int zynqmp_pm_set_pll_frac_data (u32 clk_id,u32 data);int zynqmp_pm_get_pll_frac_data (u32 clk_id,u32 *data);int zynqmp_pm_set_sd_tapdelay (u32 node_id,u32 type,u32 value); +int zynqmp_pm_reset_assert (const enum zynqmp_pm_reset reset, +const enum zynqmp_pm_reset_action assert_flag);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 13/24 firmware: xilinx: Remove eemi ops for reset_get_status
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for reset_get_status.
--- drivers/firmware/xilinx/zynqmp.c | 5 ++--- drivers/reset/reset-zynqmp.c | 8 +------- include/linux/firmware/xlnx-zynqmp.h | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-)
drivers/firmware/xilinx/zynqmp.c +2 -3
@@ -625,8 +625,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_reset_assert);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_reset_get_status (const enum zynqmp_pm_reset reset, -u32 *status) +int zynqmp_pm_reset_get_status (const enum zynqmp_pm_reset reset,u32 *status) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -640,6 +639,7 @@ static int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset,return ret; } +EXPORT_SYMBOL_GPL (zynqmp_pm_reset_get_status);/** * zynqmp_pm_fpga_load - Perform the fpga load
@@ -767,7 +767,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .reset_get_status = zynqmp_pm_reset_get_status, .init_finalize = zynqmp_pm_init_finalize, .set_suspend_mode = zynqmp_pm_set_suspend_mode, .request_node = zynqmp_pm_request_node,
drivers/reset/reset-zynqmp.c +1 -7
@@ -15,7 +15,6 @@struct zynqmp_reset_data {struct reset_controller_dev rcdev; -const struct zynqmp_eemi_ops *eemi_ops; }; static inline struct zynqmp_reset_data *
@@ -41,10 +40,9 @@ static int zynqmp_reset_deassert(struct reset_controller_dev *rcdev,static int zynqmp_reset_status (struct reset_controller_dev *rcdev,unsigned long id) { -struct zynqmp_reset_data *priv =to_zynqmp_reset_data (rcdev);int val, err; - err = priv->eemi_ops->reset_get_status (ZYNQMP_RESET_ID + id, &val); + err =zynqmp_pm_reset_get_status (ZYNQMP_RESET_ID + id, &val);if (err)return err;
@@ -73,10 +71,6 @@ static int zynqmp_reset_probe(struct platform_device *pdev)if (!priv)return -ENOMEM ; - priv->eemi_ops =zynqmp_pm_get_eemi_ops (); -if (IS_ERR (priv->eemi_ops)) -return PTR_ERR (priv->eemi_ops); -platform_set_drvdata (pdev, priv); priv->rcdev.ops = &zynqmp_reset_ops;
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*reset_get_status)(const enum zynqmp_pm_reset reset,u32 *status);int (*init_finalize)(void );int (*set_suspend_mode)(u32 mode); int (*request_node)(const u32 node,
@@ -321,6 +320,7 @@ int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data);int zynqmp_pm_set_sd_tapdelay (u32 node_id,u32 type,u32 value);int zynqmp_pm_reset_assert (const enum zynqmp_pm_reset reset,const enum zynqmp_pm_reset_action assert_flag); +int zynqmp_pm_reset_get_status (const enum zynqmp_pm_reset reset,u32 *status);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 14/24 firmware: xilinx: Remove eemi ops for init_finalize
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of eemi ops for init_finalize.
--- drivers/firmware/xilinx/zynqmp.c | 4 ++-- drivers/soc/xilinx/zynqmp_power.c | 9 +-------- include/linux/firmware/xlnx-zynqmp.h | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-)
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -693,10 +693,11 @@ static int zynqmp_pm_fpga_get_status(u32 *value)* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_init_finalize (void ) +int zynqmp_pm_init_finalize (void ) {return zynqmp_pm_invoke_fn (PM_PM_INIT_FINALIZE ,0 ,0 ,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_init_finalize);/** * zynqmp_pm_set_suspend_mode() - Set system suspend mode
@@ -767,7 +768,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .init_finalize = zynqmp_pm_init_finalize, .set_suspend_mode = zynqmp_pm_set_suspend_mode, .request_node = zynqmp_pm_request_node, .release_node = zynqmp_pm_release_node,
drivers/soc/xilinx/zynqmp_power.c +1 -8
@@ -182,14 +182,7 @@ static int zynqmp_pm_probe(struct platform_device *pdev)u32 pm_api_version;struct mbox_client *client; - eemi_ops =zynqmp_pm_get_eemi_ops (); -if (IS_ERR (eemi_ops)) -return PTR_ERR (eemi_ops); - -if (!eemi_ops->init_finalize) -return -ENXIO ; - - eemi_ops->init_finalize (); +zynqmp_pm_init_finalize ();zynqmp_pm_get_api_version (&pm_api_version);/* Check PM API version number */
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*init_finalize)(void );int (*set_suspend_mode)(u32 mode); int (*request_node)(const u32 node, const u32 capabilities,
@@ -321,6 +320,7 @@ int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value);int zynqmp_pm_reset_assert (const enum zynqmp_pm_reset reset,const enum zynqmp_pm_reset_action assert_flag);int zynqmp_pm_reset_get_status (const enum zynqmp_pm_reset reset,u32 *status); +int zynqmp_pm_init_finalize (void );int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 15/24 firmware: xilinx: Remove eemi ops for set_suspend_mode
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of eemi ops for set_suspend_mode.
--- drivers/firmware/xilinx/zynqmp.c | 4 ++-- drivers/soc/xilinx/zynqmp_power.c | 6 +----- include/linux/firmware/xlnx-zynqmp.h | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-)
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -707,10 +707,11 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_init_finalize);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_set_suspend_mode (u32 mode) +int zynqmp_pm_set_suspend_mode (u32 mode) {return zynqmp_pm_invoke_fn (PM_SET_SUSPEND_MODE , mode,0 ,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_set_suspend_mode);/** * zynqmp_pm_request_node() - Request a node with specific capabilities
@@ -768,7 +769,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .set_suspend_mode = zynqmp_pm_set_suspend_mode, .request_node = zynqmp_pm_request_node, .release_node = zynqmp_pm_release_node, .set_requirement = zynqmp_pm_set_requirement,
drivers/soc/xilinx/zynqmp_power.c +1 -5
@@ -30,7 +30,6 @@ struct zynqmp_pm_work_struct {static struct zynqmp_pm_work_struct *zynqmp_pm_init_suspend_work;static struct mbox_chan *rx_chan; -static const struct zynqmp_eemi_ops *eemi_ops;enum pm_suspend_mode {PM_SUSPEND_MODE_FIRST =0 ,
@@ -155,9 +154,6 @@ static ssize_t suspend_mode_store(struct device *dev, {int md, ret = -EINVAL ; -if (!eemi_ops->set_suspend_mode) -return ret; -for (md =PM_SUSPEND_MODE_FIRST ; md <ARRAY_SIZE (suspend_modes); md++)if (suspend_modes[md] &&sysfs_streq (suspend_modes[md], buf)) {
@@ -166,7 +162,7 @@ static ssize_t suspend_mode_store(struct device *dev, }if (!ret && md != suspend_mode) { - ret = eemi_ops->set_suspend_mode (md); + ret =zynqmp_pm_set_suspend_mode (md);if (likely (!ret)) suspend_mode = md; }
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*set_suspend_mode)(u32 mode); int (*request_node)(const u32 node, const u32 capabilities, const u32 qos,
@@ -321,6 +320,7 @@ int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset, const enum zynqmp_pm_reset_action assert_flag);int zynqmp_pm_reset_get_status (const enum zynqmp_pm_reset reset,u32 *status);int zynqmp_pm_init_finalize (void ); +int zynqmp_pm_set_suspend_mode (u32 mode);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 16/24 firmware: xilinx: Remove eemi ops for request_node
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for request_node.
--- drivers/firmware/xilinx/zynqmp.c | 7 +++---- drivers/soc/xilinx/zynqmp_pm_domains.c | 5 +---- include/linux/firmware/xlnx-zynqmp.h | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-)
drivers/firmware/xilinx/zynqmp.c +3 -4
@@ -725,13 +725,13 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_suspend_mode);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_request_node (const u32 node,const u32 capabilities, -const u32 qos, -const enum zynqmp_pm_request_ack ack) +int zynqmp_pm_request_node (const u32 node,const u32 capabilities, +const u32 qos,const enum zynqmp_pm_request_ack ack) {return zynqmp_pm_invoke_fn (PM_REQUEST_NODE , node, capabilities, qos, ack,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_request_node);/** * zynqmp_pm_release_node() - Release a node
@@ -769,7 +769,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .request_node = zynqmp_pm_request_node, .release_node = zynqmp_pm_release_node, .set_requirement = zynqmp_pm_set_requirement, .fpga_load = zynqmp_pm_fpga_load,
drivers/soc/xilinx/zynqmp_pm_domains.c +1 -4
@@ -163,16 +163,13 @@ static int zynqmp_gpd_attach_dev(struct generic_pm_domain *domain,int ret;struct zynqmp_pm_domain *pd; -if (!eemi_ops->request_node) -return -ENXIO ; - pd = container_of(domain, struct zynqmp_pm_domain, gpd);/* If this is not the first device to attach there is nothing to do */ if (domain->device_count)return 0 ; - ret = eemi_ops->request_node (pd->node_id,0 ,0 , + ret =zynqmp_pm_request_node (pd->node_id,0 ,0 ,ZYNQMP_PM_REQUEST_ACK_BLOCKING );/* If requesting a node fails print and return the error */ if (ret) {
include/linux/firmware/xlnx-zynqmp.h +2 -4
@@ -288,10 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*request_node)(const u32 node, -const u32 capabilities, -const u32 qos, -const enum zynqmp_pm_request_ack ack);int (*release_node)(const u32 node); int (*set_requirement)(const u32 node, const u32 capabilities,
@@ -321,6 +317,8 @@ int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,int zynqmp_pm_reset_get_status (const enum zynqmp_pm_reset reset,u32 *status);int zynqmp_pm_init_finalize (void );int zynqmp_pm_set_suspend_mode (u32 mode); +int zynqmp_pm_request_node (const u32 node,const u32 capabilities, +const u32 qos,const enum zynqmp_pm_request_ack ack);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 17/24 firmware: xilinx: Remove eemi ops for release_node
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for release_node.
--- drivers/firmware/xilinx/zynqmp.c | 4 ++-- drivers/soc/xilinx/zynqmp_pm_domains.c | 5 +---- include/linux/firmware/xlnx-zynqmp.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-)
drivers/firmware/xilinx/zynqmp.c +2 -2
@@ -743,10 +743,11 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_request_node);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_release_node (const u32 node) +int zynqmp_pm_release_node (const u32 node) {return zynqmp_pm_invoke_fn (PM_RELEASE_NODE , node,0 ,0 ,0 ,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_release_node);/** * zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves
@@ -769,7 +770,6 @@ static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }static const struct zynqmp_eemi_ops eemi_ops = { - .release_node = zynqmp_pm_release_node, .set_requirement = zynqmp_pm_set_requirement, .fpga_load = zynqmp_pm_fpga_load, .fpga_get_status = zynqmp_pm_fpga_get_status,
drivers/soc/xilinx/zynqmp_pm_domains.c +1 -4
@@ -196,16 +196,13 @@ static void zynqmp_gpd_detach_dev(struct generic_pm_domain *domain,int ret;struct zynqmp_pm_domain *pd; -if (!eemi_ops->release_node) -return ; - pd = container_of(domain, struct zynqmp_pm_domain, gpd);/* If this is not the last device to detach there is nothing to do */ if (domain->device_count)return ; - ret = eemi_ops->release_node (pd->node_id); + ret =zynqmp_pm_release_node (pd->node_id);/* If releasing a node fails print the error and return */ if (ret) { pr_err("%s() %s release failed for node %d: %d\n",
include/linux/firmware/xlnx-zynqmp.h +1 -1
@@ -288,7 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*release_node)(const u32 node); int (*set_requirement)(const u32 node, const u32 capabilities, const u32 qos,
@@ -319,6 +318,7 @@ int zynqmp_pm_init_finalize(void);int zynqmp_pm_set_suspend_mode (u32 mode);int zynqmp_pm_request_node (const u32 node,const u32 capabilities,const u32 qos,const enum zynqmp_pm_request_ack ack); +int zynqmp_pm_release_node (const u32 node);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 18/24 firmware: xilinx: Remove eemi ops for set_requirement
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for set_requirement.
--- drivers/firmware/xilinx/zynqmp.c | 8 ++++---- drivers/soc/xilinx/zynqmp_pm_domains.c | 16 ++-------------- include/linux/firmware/xlnx-zynqmp.h | 7 +++---- 3 files changed, 9 insertions(+), 22 deletions(-)
drivers/firmware/xilinx/zynqmp.c +4 -4
@@ -761,16 +761,16 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_release_node);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_set_requirement (const u32 node,const u32 capabilities, -const u32 qos, -const enum zynqmp_pm_request_ack ack) +int zynqmp_pm_set_requirement (const u32 node,const u32 capabilities, +const u32 qos, +const enum zynqmp_pm_request_ack ack) {return zynqmp_pm_invoke_fn (PM_SET_REQUIREMENT , node, capabilities, qos, ack,NULL ); } +EXPORT_SYMBOL_GPL (zynqmp_pm_set_requirement);static const struct zynqmp_eemi_ops eemi_ops = { - .set_requirement = zynqmp_pm_set_requirement, .fpga_load = zynqmp_pm_fpga_load, .fpga_get_status = zynqmp_pm_fpga_get_status, };
drivers/soc/xilinx/zynqmp_pm_domains.c +2 -14
@@ -23,8 +23,6 @@/* Flag stating if PM nodes mapped to the PM domain has been requested */ #define ZYNQMP_PM_DOMAIN_REQUESTED BIT(0) -static const struct zynqmp_eemi_ops *eemi_ops; -static int min_capability;/**
@@ -76,11 +74,8 @@ static int zynqmp_gpd_power_on(struct generic_pm_domain *domain)int ret;struct zynqmp_pm_domain *pd; -if (!eemi_ops->set_requirement) -return -ENXIO ; - pd = container_of(domain, struct zynqmp_pm_domain, gpd); - ret = eemi_ops->set_requirement (pd->node_id, + ret =zynqmp_pm_set_requirement (pd->node_id,ZYNQMP_PM_CAPABILITY_ACCESS ,ZYNQMP_PM_MAX_QOS ,ZYNQMP_PM_REQUEST_ACK_BLOCKING );
@@ -111,9 +106,6 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)u32 capabilities = min_capability;bool may_wakeup; -if (!eemi_ops->set_requirement) -return -ENXIO ; - pd = container_of(domain, struct zynqmp_pm_domain, gpd);/* If domain is already released there is nothing to be done */
@@ -134,7 +126,7 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain) } } - ret = eemi_ops->set_requirement (pd->node_id, capabilities,0 , + ret =zynqmp_pm_set_requirement (pd->node_id, capabilities,0 ,ZYNQMP_PM_REQUEST_ACK_NO );/** * If powering down of any node inside this domain fails,
@@ -260,10 +252,6 @@ static int zynqmp_gpd_probe(struct platform_device *pdev)struct zynqmp_pm_domain *pd;struct device *dev = &pdev->dev; - eemi_ops =zynqmp_pm_get_eemi_ops (); -if (IS_ERR (eemi_ops)) -return PTR_ERR (eemi_ops); - pd =devm_kcalloc (dev,ZYNQMP_NUM_DOMAINS ,sizeof (*pd),GFP_KERNEL );if (!pd)return -ENOMEM ;
include/linux/firmware/xlnx-zynqmp.h +3 -4
@@ -288,10 +288,6 @@ struct zynqmp_pm_query_data {struct zynqmp_eemi_ops {int (*fpga_load)(const u64 address,const u32 size,const u32 flags);int (*fpga_get_status)(u32 *value); -int (*set_requirement)(const u32 node, -const u32 capabilities, -const u32 qos, -const enum zynqmp_pm_request_ack ack); };int zynqmp_pm_get_api_version (u32 *version);
@@ -319,6 +315,9 @@ int zynqmp_pm_set_suspend_mode(u32 mode);int zynqmp_pm_request_node (const u32 node,const u32 capabilities,const u32 qos,const enum zynqmp_pm_request_ack ack);int zynqmp_pm_release_node (const u32 node); +int zynqmp_pm_set_requirement (const u32 node,const u32 capabilities, +const u32 qos, +const enum zynqmp_pm_request_ack ack);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
PATCH v3 19/24 firmware: xilinx: Remove eemi ops for fpga related APIs
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Use direct function call instead of using eemi ops for fpga related APIs. Also remove eemi ops structure.
--- drivers/firmware/xilinx/zynqmp.c | 30 ++---------------------------- drivers/fpga/zynqmp-fpga.c | 12 ++---------- drivers/spi/spi-zynqmp-gqspi.c | 5 ----- include/linux/firmware/xlnx-zynqmp.h | 16 ++-------------- 4 files changed, 6 insertions(+), 57 deletions(-)
drivers/firmware/xilinx/zynqmp.c +2 -28
@@ -24,8 +24,6 @@#include <linux/firmware/xlnx-zynqmp.h> #include "zynqmp-debug.h" -static const struct zynqmp_eemi_ops *eemi_ops_tbl; -static bool feature_check_enabled;static u32 zynqmp_pm_features[PM_API_MAX ];
@@ -654,8 +652,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_reset_get_status);* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_fpga_load (const u64 address,const u32 size, -const u32 flags) +int zynqmp_pm_fpga_load (const u64 address,const u32 size,const u32 flags) {return zynqmp_pm_invoke_fn (PM_FPGA_LOAD ,lower_32_bits (address),upper_32_bits (address), size, flags,NULL );
@@ -670,7 +667,7 @@ static int zynqmp_pm_fpga_load(const u64 address, const u32 size,* * Return: Returns status, either success or error+reason */ -static int zynqmp_pm_fpga_get_status (u32 *value) +int zynqmp_pm_fpga_get_status (u32 *value) {u32 ret_payload[PAYLOAD_ARG_CNT ];int ret;
@@ -770,26 +767,6 @@ int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, }EXPORT_SYMBOL_GPL (zynqmp_pm_set_requirement); -static const struct zynqmp_eemi_ops eemi_ops = { - .fpga_load = zynqmp_pm_fpga_load, - .fpga_get_status = zynqmp_pm_fpga_get_status, -}; - -/** -* zynqmp_pm_get_eemi_ops - Get eemi ops functions -* -* Return: Pointer of eemi_ops structure -*/ -const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops (void ) -{ -if (eemi_ops_tbl) -return eemi_ops_tbl; -else -return ERR_PTR (-EPROBE_DEFER ); - -} -EXPORT_SYMBOL_GPL (zynqmp_pm_get_eemi_ops); -static int zynqmp_firmware_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -836,9 +813,6 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)pr_info ("%s Trustzone version v%d.%d\n" , __func__, pm_tz_version >>16 , pm_tz_version &0xFFFF ); -/* Assign eemi_ops_table */ - eemi_ops_tbl = &eemi_ops; -zynqmp_pm_api_debugfs_init (); ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, firmware_devs,
drivers/fpga/zynqmp-fpga.c +2 -10
@@ -40,16 +40,12 @@ static int zynqmp_fpga_ops_write_init(struct fpga_manager *mgr,static int zynqmp_fpga_ops_write (struct fpga_manager *mgr,const char *buf,size_t size) { -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();struct zynqmp_fpga_priv *priv;dma_addr_t dma_addr;u32 eemi_flags =0 ;char *kbuf;int ret; -if (IS_ERR_OR_NULL (eemi_ops) || !eemi_ops->fpga_load) -return -ENXIO ; - priv = mgr->priv; kbuf =dma_alloc_coherent (priv->dev, size, &dma_addr,GFP_KERNEL );
@@ -63,7 +59,7 @@ static int zynqmp_fpga_ops_write(struct fpga_manager *mgr,if (priv->flags &FPGA_MGR_PARTIAL_RECONFIG ) eemi_flags |=XILINX_ZYNQMP_PM_FPGA_PARTIAL ; - ret = eemi_ops->fpga_load (dma_addr, size, eemi_flags); + ret =zynqmp_pm_fpga_load (dma_addr, size, eemi_flags);dma_free_coherent (priv->dev, size, kbuf, dma_addr);
@@ -78,13 +74,9 @@ static int zynqmp_fpga_ops_write_complete(struct fpga_manager *mgr,static enum fpga_mgr_states zynqmp_fpga_ops_state (struct fpga_manager *mgr) { -const struct zynqmp_eemi_ops *eemi_ops =zynqmp_pm_get_eemi_ops ();u32 status; -if (IS_ERR_OR_NULL (eemi_ops) || !eemi_ops->fpga_get_status) -return FPGA_MGR_STATE_UNKNOWN ; - - eemi_ops->fpga_get_status (&status); +zynqmp_pm_fpga_get_status (&status);if (status &IXR_FPGA_DONE_MASK )return FPGA_MGR_STATE_OPERATING ;
drivers/spi/spi-zynqmp-gqspi.c +0 -5
@@ -135,7 +135,6 @@#define SPI_AUTOSUSPEND_TIMEOUT 3000enum mode_type {GQSPI_MODE_IO ,GQSPI_MODE_DMA }; -static const struct zynqmp_eemi_ops *eemi_ops;/** * struct zynqmp_qspi - Defines qspi driver instance
@@ -1015,10 +1014,6 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)struct zynqmp_qspi *xqspi;struct device *dev = &pdev->dev; - eemi_ops =zynqmp_pm_get_eemi_ops (); -if (IS_ERR (eemi_ops)) -return PTR_ERR (eemi_ops); - master =spi_alloc_master (&pdev->dev,sizeof (*xqspi));if (!master)return -ENOMEM ;
include/linux/firmware/xlnx-zynqmp.h +2 -14
@@ -285,11 +285,6 @@ struct zynqmp_pm_query_data {u32 arg3; }; -struct zynqmp_eemi_ops { -int (*fpga_load)(const u64 address,const u32 size,const u32 flags); -int (*fpga_get_status)(u32 *value); -}; -int zynqmp_pm_get_api_version (u32 *version);int zynqmp_pm_get_chipid (u32 *idcode,u32 *version);int zynqmp_pm_query_data (struct zynqmp_pm_query_data qdata,u32 *out);
@@ -318,16 +313,9 @@ int zynqmp_pm_release_node(const u32 node);int zynqmp_pm_set_requirement (const u32 node,const u32 capabilities,const u32 qos,const enum zynqmp_pm_request_ack ack); +int zynqmp_pm_fpga_load (const u64 address,const u32 size,const u32 flags); +int zynqmp_pm_fpga_get_status (u32 *value);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload); -#if IS_REACHABLE (CONFIG_ARCH_ZYNQMP ) -const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops (void ); -#else -static inline struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops (void ) -{ -return ERR_PTR (-ENODEV ); -} -#endif -#endif /* __FIRMWARE_ZYNQMP_H__ */
Signature · 7 lines
2.7.4 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v3 20/24 firmware: xilinx: Add APIs to read/write GGS/PGGS registers
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Add APIs to read/write PGGS and GGS registers.
--- drivers/firmware/xilinx/zynqmp.c | 66 ++++++++++++++++++++++++++++++++++++ include/linux/firmware/xlnx-zynqmp.h | 8 +++++ 2 files changed, 74 insertions(+)
drivers/firmware/xilinx/zynqmp.c +66 -0
@@ -601,6 +601,72 @@ int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value)EXPORT_SYMBOL_GPL (zynqmp_pm_set_sd_tapdelay);/** +* zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs) +* @index GGS register index +* @value Register value to be written +* +* This function writes value to GGS register. +* +* @return Returns status, either success or error+reason +*/ +int zynqmp_pm_write_ggs (u32 index,u32 value) +{ +return zynqmp_pm_invoke_fn (PM_IOCTL ,0 ,IOCTL_WRITE_GGS , + index, value,NULL ); +} +EXPORT_SYMBOL_GPL (zynqmp_pm_write_ggs); + +/** +* zynqmp_pm_write_ggs() - PM API for reading global general storage (ggs) +* @index GGS register index +* @value Register value to be written +* +* This function returns GGS register value. +* +* @return Returns status, either success or error+reason +*/ +int zynqmp_pm_read_ggs (u32 index,u32 *value) +{ +return zynqmp_pm_invoke_fn (PM_IOCTL ,0 ,IOCTL_READ_GGS , + index,0 , value); +} +EXPORT_SYMBOL_GPL (zynqmp_pm_read_ggs); + +/** +* zynqmp_pm_write_pggs() - PM API for writing persistent global general +* storage (pggs) +* @index PGGS register index +* @value Register value to be written +* +* This function writes value to PGGS register. +* +* @return Returns status, either success or error+reason +*/ +int zynqmp_pm_write_pggs (u32 index,u32 value) +{ +return zynqmp_pm_invoke_fn (PM_IOCTL ,0 ,IOCTL_WRITE_PGGS , index, value, +NULL ); +} +EXPORT_SYMBOL_GPL (zynqmp_pm_write_pggs); + +/** +* zynqmp_pm_write_pggs() - PM API for reading persistent global general +* storage (pggs) +* @index PGGS register index +* @value Register value to be written +* +* This function returns PGGS register value. +* +* @return Returns status, either success or error+reason +*/ +int zynqmp_pm_read_pggs (u32 index,u32 *value) +{ +return zynqmp_pm_invoke_fn (PM_IOCTL ,0 ,IOCTL_READ_PGGS , index,0 , + value); +} +EXPORT_SYMBOL_GPL (zynqmp_pm_read_pggs); + +/** * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release) * @reset: Reset to be configured * @assert_flag: Flag stating should reset be asserted (1) or
include/linux/firmware/xlnx-zynqmp.h +8 -0
@@ -105,6 +105,10 @@ enum pm_ioctl_id {IOCTL_GET_PLL_FRAC_MODE ,IOCTL_SET_PLL_FRAC_DATA ,IOCTL_GET_PLL_FRAC_DATA , +IOCTL_WRITE_GGS , +IOCTL_READ_GGS , +IOCTL_WRITE_PGGS , + IOCTL_READ_PGGS, }; enum pm_query_id {
@@ -315,6 +319,10 @@ int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, const enum zynqmp_pm_request_ack ack);int zynqmp_pm_fpga_load (const u64 address,const u32 size,const u32 flags);int zynqmp_pm_fpga_get_status (u32 *value); +int zynqmp_pm_write_ggs (u32 index,u32 value); +int zynqmp_pm_read_ggs (u32 index,u32 *value); +int zynqmp_pm_write_pggs (u32 index,u32 value); +int zynqmp_pm_read_pggs (u32 index,u32 *value);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
Re: [PATCH v3 20/24] firmware: xilinx: Add APIs to read/write GGS/PGGS registers
include/linux/firmware/xlnx-zynqmp.h enum pm_ioctl_id { · line 111
Quoted 10 lines · Jolly Shah
include/linux/firmware/xlnx-zynqmp.h +4
-0@@ -105,6 +105,10 @@ enum pm_ioctl_id {IOCTL_GET_PLL_FRAC_MODE ,IOCTL_SET_PLL_FRAC_DATA ,IOCTL_GET_PLL_FRAC_DATA , +IOCTL_WRITE_GGS , +IOCTL_READ_GGS , +IOCTL_WRITE_PGGS , + IOCTL_READ_PGGS,
You do not have explicit numbers here? Bold :)
greg k-h
RE: [PATCH v3 20/24] firmware: xilinx: Add APIs to read/write GGS/PGGS registers
Hi Greg,
Thanks for applying patches and review.
Please see my comment inline.
Quoted 18 lines
-----Original Message-----
From: Greg KH <[email protected]>
Sent: 18 March 2020 05:22 PM
To: Jolly Shah <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Michal Simek <[email protected]>; Rajan Vaja <[email protected]>; [email protected]; linux- [email protected]; Rajan Vaja <[email protected]>
Subject: Re: [PATCH v3 20/24] firmware: xilinx: Add APIs to read/write GGS/PGGS registersCAUTION: This message has originated from an External Source. Please use proper judgment and caution when opening attachments, clicking links, or responding to this email.
On Fri, Mar 06, 2020 at 03:47:28PM -0800, Jolly Shah wrote:
Quoted 12 lines
include/linux/firmware/xlnx-zynqmp.h enum pm_ioctl_id { · line 111
Quoted 10 lines
include/linux/firmware/xlnx-zynqmp.h +4
-0@@ -105,6 +105,10 @@ enum pm_ioctl_id {IOCTL_GET_PLL_FRAC_MODE ,IOCTL_SET_PLL_FRAC_DATA ,IOCTL_GET_PLL_FRAC_DATA , +IOCTL_WRITE_GGS , +IOCTL_READ_GGS , +IOCTL_WRITE_PGGS , + IOCTL_READ_PGGS,You do not have explicit numbers here? Bold :)
[Rajan] Here new IOCTL IDs are continuous so didn't mention explicit number. Are asking for adding numbers like below:
enum pm_ioctl_id {
...
IOCTL_GET_PLL_FRAC_DATA = 11,
IOCTL_WRITE_GGS = 12,
....
}Thanks,
Rajan
Quoted 1 line
greg k-h
Re: [PATCH v3 20/24] firmware: xilinx: Add APIs to read/write GGS/PGGS registers
Quoted 36 lines · Rajan Vaja
Hi Greg,
Thanks for applying patches and review.
Please see my comment inline.
Quoted 18 lines
-----Original Message-----
From: Greg KH <[email protected]>
Sent: 18 March 2020 05:22 PM
To: Jolly Shah <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Michal Simek <[email protected]>; Rajan Vaja <[email protected]>; [email protected]; linux- [email protected]; Rajan Vaja <[email protected]>
Subject: Re: [PATCH v3 20/24] firmware: xilinx: Add APIs to read/write GGS/PGGS registersCAUTION: This message has originated from an External Source. Please use proper judgment and caution when opening attachments, clicking links, or responding to this email.
On Fri, Mar 06, 2020 at 03:47:28PM -0800, Jolly Shah wrote:
Quoted 12 lines
include/linux/firmware/xlnx-zynqmp.h enum pm_ioctl_id { · line 111
Quoted 10 lines
include/linux/firmware/xlnx-zynqmp.h +4
-0@@ -105,6 +105,10 @@ enum pm_ioctl_id {IOCTL_GET_PLL_FRAC_MODE ,IOCTL_SET_PLL_FRAC_DATA ,IOCTL_GET_PLL_FRAC_DATA , +IOCTL_WRITE_GGS , +IOCTL_READ_GGS , +IOCTL_WRITE_PGGS , + IOCTL_READ_PGGS,You do not have explicit numbers here? Bold :)
Quoted 1 line
[Rajan] Here new IOCTL IDs are continuous so didn't mention explicit number.
Yes, but is that guaranteed by the compiler? I keep getting conflicting advice with that.
Quoted 7 lines
Are asking for adding numbers like below:
enum pm_ioctl_id { ... IOCTL_GET_PLL_FRAC_DATA = 11, IOCTL_WRITE_GGS = 12, .... }
Yes please, especially as your firmware is expecting the explicit values here, right? That way you _know_ everything is correct.
thanks,
greg k-h
PATCH v3 21/24 firmware: xilinx: Add sysfs interface
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Add firmware-ggs sysfs interface which provides read/write interface to global storage registers.
--- .../ABI/stable/sysfs-driver-firmware-zynqmp | 50 ++++ drivers/firmware/xilinx/zynqmp.c | 319 ++++++++++++++++++++- include/linux/firmware/xlnx-zynqmp.h | 4 + 3 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/stable/sysfs-driver-firmware-zynqmp
Documentation/ABI/stable/sysfs-driver-firmware-zynqmp new file +50 -0
@@ -0,0 +1,50 @@ +What: /sys/devices/platform/firmware\:zynqmp-firmware/ggs* +Date: March 2020 +KernelVersion: 5.6 +Contact: "Jolly Shah" <[email protected]> +Description: + Read/Write PMU global general storage register value, + GLOBAL_GEN_STORAGE{0:3}. + Global general storage register that can be used + by system to pass information between masters. + + The register is reset during system or power-on + resets. Three registers are used by the FSBL and + other Xilinx software products: GLOBAL_GEN_STORAGE{4:6}. + + Usage: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/ggs0 + # echo <mask> <value> > /sys/devices/platform/firmware\:zynqmp-firmware/ggs0 + + Example: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/ggs0 + # echo 0xFFFFFFFF 0x1234ABCD > /sys/devices/platform/firmware\:zynqmp-firmware/ggs0 + +Users: Xilinx + +What: /sys/devices/platform/firmware\:zynqmp-firmware/pggs* +Date: March 2020 +KernelVersion: 5.6 +Contact: "Jolly Shah" <[email protected]> +Description: + Read/Write PMU persistent global general storage register + value, PERS_GLOB_GEN_STORAGE{0:3}. + Persistent global general storage register that + can be used by system to pass information between + masters. + + This register is only reset by the power-on reset + and maintains its value through a system reset. + Four registers are used by the FSBL and other Xilinx + software products: PERS_GLOB_GEN_STORAGE{4:7}. + Register is reset only by a POR reset. + + Usage: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/pggs0 + # echo <mask> <value> > /sys/devices/platform/firmware\:zynqmp-firmware/pggs0 + + Example: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/pggs0 + # echo 0xFFFFFFFF 0x1234ABCD > /sys/devices/platform/firmware\:zynqmp-firmware/pggs0 + +Users: Xilinx
drivers/firmware/xilinx/zynqmp.c +318 -1
337 lines not on this page · raw message
include/linux/firmware/xlnx-zynqmp.h +4 -0
@@ -13,6 +13,8 @@#ifndef __FIRMWARE_ZYNQMP_H__#define __FIRMWARE_ZYNQMP_H__ +#include <linux/device.h> +#define ZYNQMP_PM_VERSION_MAJOR 1#define ZYNQMP_PM_VERSION_MINOR 0
@@ -42,6 +44,8 @@#define ZYNQMP_PM_MAX_QOS 100U +#define GSS_NUM_REGS (4) +/* Node capabilities */ #define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U
Signature · 1 line
2.7.4
Re: [PATCH v3 21/24] firmware: xilinx: Add sysfs interface
Quoted 9 lines · Jolly Shah
+/**
+ *ggs_store- Store global general storage (ggs) sysfs attribute
+ * @device: Device structure
+ * @attr: Device attribute structure
+ * @buf: User enteredshutdown_scopeattribute string
+ * @count: Size of buf
+ * @reg: Register number
+ *
+ * Return: count argument if request succeeds, the corresponding
Quoted 8 lines
+ * error code otherwise
+ *
+ * Helper function for storing a ggs register value.
+ *
+ * For example, the user-space interface for storing a value to the
+ * ggs0 register:
+ * echo0xFFFFFFFF0x1234ABCD> /sys/devices/platform/firmware\:zynqmp-firmware/ggs0
+ */
Do you really need a whole kernel_doc format for a static function? Anyway...
drivers/firmware/xilinx/zynqmp.c int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, · line 892
Quoted 11 lines
drivers/firmware/xilinx/zynqmp.c +11
-0+static ssize_t ggs_store (struct device *device, +struct device_attribute *attr, +const char *buf,size_t count, +u32 reg) +{ +char *kern_buff, *inbuf, *tok; +long mask, value; +int ret; +u32 ret_payload[PAYLOAD_ARG_CNT ]; + +if (!device || !attr || !buf || !count || reg >=GSS_NUM_REGS )
How can !device, !attr, !buf, or !count ever happen?
Do not check for things that are impossible please.
Quoted 29 lines
drivers/firmware/xilinx/zynqmp.c +29
-0+return -EINVAL ; + + kern_buff =kzalloc (count,GFP_KERNEL ); +if (!kern_buff) +return -ENOMEM ; + + ret =strlcpy (kern_buff, buf, count); +if (ret <0 ) { + count = -EFAULT ; + goto err; + } + + inbuf = kern_buff; + +/* Read the write mask */ + tok =strsep (&inbuf," " ); +if (!tok) { + count = -EFAULT ; + goto err; + } + + ret =kstrtol (tok,16 , &mask); +if (ret) { + count = -EFAULT ; + goto err; + } + +/* Read the write value */ + tok =strsep (&inbuf," " );
drivers/firmware/xilinx/zynqmp.c int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, · line 931
Quoted 10 lines
drivers/firmware/xilinx/zynqmp.c +10
-0+if (!tok) { + count = -EFAULT ; + goto err; + } + + ret =kstrtol (tok,16 , &value); +if (ret) { + count = -EFAULT ; + goto err; + }
sysfs files are "one value per file" which prevents this string parsing mess. Please do not do that.
Again, one value per file, not X values.
Quoted 35 lines
drivers/firmware/xilinx/zynqmp.c +34
-0+ + ret =zynqmp_pm_read_ggs (reg, ret_payload); +if (ret) { + count = -EFAULT ; + goto err; + } + ret_payload[1 ] &= ~mask; + value &= mask; + value |= ret_payload[1 ]; + + ret =zynqmp_pm_write_ggs (reg, value); +if (ret) + count = -EFAULT ; + +err: +kfree (kern_buff); + +return count; +} +/** +* pggs_store - Store persistent global general storage (pggs) sysfs attribute +* @device: Device structure +* @attr: Device attribute structure +* @buf: User entered shutdown_scope attribute string +* @count: Size of buf +* @reg: Register number +* +* Return: count argument if request succeeds, the corresponding +* error code otherwise +* +* Helper function for storing a pggs register value. +*/ +static ssize_t pggs_store(struct device *device, + struct device_attribute *attr,
drivers/firmware/xilinx/zynqmp.c int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, · line 1031
Quoted 10 lines
drivers/firmware/xilinx/zynqmp.c +10
-0+ const char *buf, size_t count, + u32 reg) +{ + char *kern_buff, *inbuf, *tok; +long mask, value; +int ret; +u32 ret_payload[PAYLOAD_ARG_CNT ]; + +if (!device || !attr || !buf || !count || reg >=GSS_NUM_REGS ) +return -EINVAL ;
Again, clean this up.
Quoted 5 lines
drivers/firmware/xilinx/zynqmp.c +5
-0+ + kern_buff =kzalloc (count,GFP_KERNEL ); +if (!kern_buff) +return -ENOMEM ; +
drivers/firmware/xilinx/zynqmp.c int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, · line 908
Quoted 10 lines
drivers/firmware/xilinx/zynqmp.c +10
-0+ ret =strlcpy (kern_buff, buf, count); +if (ret <0 ) { + count = -EFAULT ; + goto err; + } + + inbuf = kern_buff; + +/* Read the write mask */ + tok =strsep (&inbuf," " );
No need to parse when there is only one value.
Quoted 53 lines
drivers/firmware/xilinx/zynqmp.c +52
-0+if (!tok) { + count = -EFAULT ; + goto err; + } + + ret =kstrtol (tok,16 , &mask); +if (ret) { + count = -EFAULT ; + goto err; + } + +/* Read the write value */ + tok =strsep (&inbuf," " ); +if (!tok) { + count = -EFAULT ; + goto err; + } + + ret =kstrtol (tok,16 , &value); +if (ret) { + count = -EFAULT ; + goto err; + } + + ret =zynqmp_pm_read_pggs (reg, ret_payload); +if (ret) { + count = -EFAULT ; + goto err; + } + ret_payload[1 ] &= ~mask; + value &= mask; + value |= ret_payload[1 ]; + + ret =zynqmp_pm_write_pggs (reg, value); +if (ret) + count = -EFAULT ; + +err: +kfree (kern_buff); + +return count; +} +static struct attribute *zynqmp_ggs_attrs[] = { + &dev_attr_ggs0.attr, + &dev_attr_ggs1.attr, + &dev_attr_ggs2.attr, + &dev_attr_ggs3.attr, + &dev_attr_pggs0.attr, + &dev_attr_pggs1.attr, + &dev_attr_pggs2.attr, + &dev_attr_pggs3.attr, +NULL ,
drivers/firmware/xilinx/zynqmp.c int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, · line 1150
Quoted 10 lines
drivers/firmware/xilinx/zynqmp.c +10
-0+}; + +static const struct attribute_group ggs_attribute_group = { + .attrs = zynqmp_ggs_attrs, +}; + +const struct attribute_group *firmware_attribute_groups[] = { + &ggs_attribute_group, +NULL , +};
ATTRIBUTE_GROUPS()?
Quoted 17 lines
drivers/firmware/xilinx/zynqmp.c +2
-0+static int zynqmp_firmware_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;@@ -910,6 +1226,7 @@ static struct platform_driver zynqmp_firmware_driver = { .driver = { .name = "zynqmp_firmware", .of_match_table = zynqmp_firmware_of_match, + .dev_groups = firmware_attribute_groups, }, .probe = zynqmp_firmware_probe, .remove = zynqmp_firmware_remove,include/linux/firmware/xlnx-zynqmp.h +0
-0
include/linux/firmware/xlnx-zynqmp.h line 16
Quoted 4 lines
include/linux/firmware/xlnx-zynqmp.h +1
-0@@ -13,6 +13,8 @@#ifndef __FIRMWARE_ZYNQMP_H__#define __FIRMWARE_ZYNQMP_H__ +#include <linux/device.h>
Why is this needed here?
include/linux/firmware/xlnx-zynqmp.h line 51
Quoted 13 lines
include/linux/firmware/xlnx-zynqmp.h +3
-0+#define ZYNQMP_PM_VERSION_MAJOR 1#define ZYNQMP_PM_VERSION_MINOR 0@@ -42,6 +44,8 @@#define ZYNQMP_PM_MAX_QOS 100U +#define GSS_NUM_REGS (4) +/* Node capabilities */ #define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U
You are not adding anything that depends on device.h in this file, so just include the needed .h file in the .c file that needs it please.
Helps unwind .h include messes.
thanks,
greg k-h
PATCH v3 22/24 firmware: xilinx: Add system shutdown API interface
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Add system shutdown API interface which asks firmware to perform system shutdown/restart.
--- drivers/firmware/xilinx/zynqmp.c | 13 +++++++++++++ include/linux/firmware/xlnx-zynqmp.h | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-)
drivers/firmware/xilinx/zynqmp.c +13 -0
@@ -834,6 +834,19 @@ int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,EXPORT_SYMBOL_GPL (zynqmp_pm_set_requirement);/** +* zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart +* @type: Shutdown or restart? 0 for shutdown, 1 for restart +* @subtype: Specifies which system should be restarted or shut down +* +* Return: Returns status, either success or error+reason +*/ +int zynqmp_pm_system_shutdown (const u32 type,const u32 subtype) +{ +return zynqmp_pm_invoke_fn (PM_SYSTEM_SHUTDOWN , type, subtype, +0 ,0 ,NULL ); +} + +/** * ggs_show - Show global general storage (ggs) sysfs attribute * @device: Device structure * @attr: Device attribute structure
include/linux/firmware/xlnx-zynqmp.h +3 -1
@@ -66,7 +66,8 @@enum pm_api_id {PM_GET_API_VERSION =1 , -PM_REQUEST_NODE =13 , +PM_SYSTEM_SHUTDOWN =12 , +PM_REQUEST_NODE ,PM_RELEASE_NODE ,PM_SET_REQUIREMENT ,PM_RESET_ASSERT =17 ,
@@ -327,6 +328,7 @@ int zynqmp_pm_write_ggs(u32 index, u32 value);int zynqmp_pm_read_ggs (u32 index,u32 *value);int zynqmp_pm_write_pggs (u32 index,u32 value);int zynqmp_pm_read_pggs (u32 index,u32 *value); +int zynqmp_pm_system_shutdown (const u32 type,const u32 subtype);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
Re: [PATCH v3 22/24] firmware: xilinx: Add system shutdown API interface
Quoted 43 lines · Jolly Shah
From: Rajan Vaja <[email protected]>
Add system shutdown API interface which asks firmware to perform system shutdown/restart.
Signed-off-by Rajan Vaja <[email protected]>Signed-off-by Michal Simek <[email protected]>Signed-off-by Jolly Shah <[email protected]>Signed-off-by Jolly Shah <[email protected]>--- drivers/firmware/xilinx/zynqmp.c | 13 +++++++++++++ include/linux/firmware/xlnx-zynqmp.h | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-)drivers/firmware/xilinx/zynqmp.c +13
-0@@ -834,6 +834,19 @@ int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,EXPORT_SYMBOL_GPL (zynqmp_pm_set_requirement);/** +* zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart +* @type: Shutdown or restart? 0 for shutdown, 1 for restart +* @subtype: Specifies which system should be restarted or shut down +* +* Return: Returns status, either success or error+reason +*/ +int zynqmp_pm_system_shutdown (const u32 type,const u32 subtype) +{ +return zynqmp_pm_invoke_fn (PM_SYSTEM_SHUTDOWN , type, subtype, +0 ,0 ,NULL ); +} + +/** * ggs_show - Show global general storage (ggs) sysfs attribute * @device: Device structure * @attr: Device attribute structure include/linux/firmware/xlnx-zynqmp.h +0
-0
include/linux/firmware/xlnx-zynqmp.h line 70
Quoted 6 lines
include/linux/firmware/xlnx-zynqmp.h +2
-1@@ -66,7 +66,8 @@enum pm_api_id {PM_GET_API_VERSION =1 , -PM_REQUEST_NODE =13 , +PM_SYSTEM_SHUTDOWN =12 , +PM_REQUEST_NODE ,
So you might have changed the value of PM_REQUEST_NODE, is that ok?
Why remove the explicit value?
thanks,
greg k-h
PATCH v3 23/24 firmware: xilinx: Add sysfs to set shutdown scope
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
The Linux shutdown functionality implemented via PSCI system_off does not include an option to set a scope, i.e. which parts of the system to shut down.
This patch creates sysfs that allows to set the shutdown scope for the next shutdown request. When the next shutdown is performed, the platform specific portion of PSCI-system_off can use the chosen shutdown scope.
--- .../ABI/stable/sysfs-driver-firmware-zynqmp | 32 +++++ drivers/firmware/xilinx/zynqmp.c | 150 ++++++++++++++++++++- include/linux/firmware/xlnx-zynqmp.h | 12 ++ 3 files changed, 193 insertions(+), 1 deletion(-)
Documentation/ABI/stable/sysfs-driver-firmware-zynqmp +32 -0
@@ -48,3 +48,35 @@ Description: # echo 0xFFFFFFFF 0x1234ABCD > /sys/devices/platform/firmware\:zynqmp-firmware/pggs0 Users: Xilinx + +What: /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope +Date: March 2020 +KernelVersion: 5.6 +Contact: "Jolly Shah" <[email protected]> +Description: + This sysfs interface allows to set the shutdown scope for the + next shutdown request. When the next shutdown is performed, the + platform specific portion of PSCI-system_off can use the chosen + shutdown scope. + + Following are available shutdown scopes(subtypes): + + subsystem: Only the APU along with all of its peripherals + not used by other processing units will be + shut down. This may result in the FPD power + domain being shut down provided that no other + processing unit uses FPD peripherals or DRAM. + ps_only: The complete PS will be shut down, including the + RPU, PMU, etc. Only the PL domain (FPGA) + remains untouched. + system: The complete system/device is shut down. + + Usage: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + # echo <scope> > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + + Example: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + # echo "subsystem" > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + +Users: Xilinx
drivers/firmware/xilinx/zynqmp.c +149 -1
168 lines not on this page · raw message
include/linux/firmware/xlnx-zynqmp.h +12 -0
@@ -280,6 +280,18 @@ enum tap_delay_type { PM_TAPDELAY_OUTPUT, }; +enum zynqmp_pm_shutdown_type { +ZYNQMP_PM_SHUTDOWN_TYPE_SHUTDOWN , +ZYNQMP_PM_SHUTDOWN_TYPE_RESET , +ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY , +}; + +enum zynqmp_pm_shutdown_subtype { +ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM , +ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY , +ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM , +}; +/** * struct zynqmp_pm_query_data - PM query data * @qid: query ID
Signature · 1 line
2.7.4
Re: [PATCH v3 23/24] firmware: xilinx: Add sysfs to set shutdown scope
Quoted 206 lines · Jolly Shah
From: Rajan Vaja <[email protected]>
The Linux shutdown functionality implemented via PSCI
system_offdoes not include an option to set a scope, i.e. which parts of the system to shut down.This patch creates sysfs that allows to set the shutdown scope for the next shutdown request. When the next shutdown is performed, the platform specific portion of PSCI-system_off can use the chosen shutdown scope.
Signed-off-by Rajan Vaja <[email protected]>Signed-off-by Stefan Krsmanovic <[email protected]>Signed-off-by Michal Simek <[email protected]>Signed-off-by Jolly Shah <[email protected]>Signed-off-by Tejas Patel <[email protected]>Signed-off-by Jolly Shah <[email protected]>--- .../ABI/stable/sysfs-driver-firmware-zynqmp | 32 +++++ drivers/firmware/xilinx/zynqmp.c | 150 ++++++++++++++++++++- include/linux/firmware/xlnx-zynqmp.h | 12 ++ 3 files changed, 193 insertions(+), 1 deletion(-)Documentation/ABI/stable/sysfs-driver-firmware-zynqmp +32
-0@@ -48,3 +48,35 @@ Description: # echo 0xFFFFFFFF 0x1234ABCD > /sys/devices/platform/firmware\:zynqmp-firmware/pggs0 Users: Xilinx + +What: /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope +Date: March 2020 +KernelVersion: 5.6 +Contact: "Jolly Shah" <[email protected]> +Description: + This sysfs interface allows to set the shutdown scope for the + next shutdown request. When the next shutdown is performed, the + platform specific portion of PSCI-system_off can use the chosen + shutdown scope. + + Following are available shutdown scopes(subtypes): + + subsystem: Only the APU along with all of its peripherals + not used by other processing units will be + shut down. This may result in the FPD power + domain being shut down provided that no other + processing unit uses FPD peripherals or DRAM. + ps_only: The complete PS will be shut down, including the + RPU, PMU, etc. Only the PL domain (FPGA) + remains untouched. + system: The complete system/device is shut down. + + Usage: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + # echo <scope> > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + + Example: + # cat /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + # echo "subsystem" > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope + +Users: Xilinxdrivers/firmware/xilinx/zynqmp.c +136
-0@@ -847,6 +847,154 @@ int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype) }/** +* struct zynqmp_pm_shutdown_scope - Struct for shutdown scope +* @subtype: Shutdown subtype +* @name: Matching string for scope argument +* +* This struct encapsulates mapping between shutdown scope ID and string. +*/ +struct zynqmp_pm_shutdown_scope { +const enum zynqmp_pm_shutdown_subtype subtype; +const char *name; +}; + +static struct zynqmp_pm_shutdown_scope shutdown_scopes[] = { + [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM ] = { + .subtype =ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM , + .name ="subsystem" , + }, + [ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY ] = { + .subtype =ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY , + .name ="ps_only" , + }, + [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM ] = { + .subtype =ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM , + .name ="system" , + }, +}; + +static struct zynqmp_pm_shutdown_scope *selected_scope = + &shutdown_scopes[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM ]; + +/** +* zynqmp_pm_is_shutdown_scope_valid - Check if shutdown scope string is valid +* @scope_string: Shutdown scope string +* +* Return: Return pointer to matching shutdown scope struct from +* array of available options in system if string is valid, +* otherwise returns NULL. +*/ +static struct zynqmp_pm_shutdown_scope * +zynqmp_pm_is_shutdown_scope_valid (const char *scope_string) +{ +int count; + +for (count =0 ; count <ARRAY_SIZE (shutdown_scopes); count++) +if (sysfs_streq (scope_string, shutdown_scopes[count].name)) +return &shutdown_scopes[count]; + +return NULL ; +} + +/** +* shutdown_scope_show - Show shutdown_scope sysfs attribute +* @device: Device structure +* @attr: Device attribute structure +* @buf: Requested available shutdown_scope attributes string +* +* User-space interface for viewing the available scope options for system +* shutdown. Scope option for next shutdown call is marked with []. +* +* Usage: cat /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope +* +* Return: Number of bytes printed into the buffer. +*/ +static ssize_t shutdown_scope_show (struct device *device, +struct device_attribute *attr, +char *buf) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (shutdown_scopes); i++) { +if (&shutdown_scopes[i] == selected_scope) { +strcat (buf,"[" ); +strcat (buf, shutdown_scopes[i].name); +strcat (buf,"]" ); + }else { +strcat (buf, shutdown_scopes[i].name); + } +strcat (buf," " ); + } +strcat (buf,"\n" ); + +return strlen (buf); +} + +/** +* shutdown_scope_store - Store shutdown_scope sysfs attribute +* @device: Device structure +* @attr: Device attribute structure +* @buf: User entered shutdown_scope attribute string +* @count: Buffer size +* +* User-space interface for setting the scope for the next system shutdown. +* Usage: echo <scope> > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope +* +* The Linux shutdown functionality implemented via PSCI system_off does not +* include an option to set a scope, i.e. which parts of the system to shut +* down. +* +* This API function allows to set the shutdown scope for the next shutdown +* request by passing it to the ATF running in EL3. When the next shutdown +* is performed, the platform specific portion of PSCI-system_off can use +* the chosen shutdown scope. +* +* subsystem: Only the APU along with all of its peripherals not used by other +* processing units will be shut down. This may result in the FPD +* power domain being shut down provided that no other processing +* unit uses FPD peripherals or DRAM. +* ps_only: The complete PS will be shut down, including the RPU, PMU, etc. +* Only the PL domain (FPGA) remains untouched. +* system: The complete system/device is shut down. +* +* Return: count argument if request succeeds, the corresponding error +* code otherwise +*/ +static ssize_t shutdown_scope_store (struct device *device, +struct device_attribute *attr, +const char *buf,size_t count) +{ +int ret; +struct zynqmp_pm_shutdown_scope *scope; + + scope =zynqmp_pm_is_shutdown_scope_valid (buf); +if (!scope) +return -EINVAL ; + + ret =zynqmp_pm_system_shutdown (ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY , + scope->subtype); +if (ret) { +pr_err ("unable to set shutdown scope %s\n" , buf); +return ret; + } + + selected_scope = scope; + +return count; +} +
drivers/firmware/xilinx/zynqmp.c int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype) · line 995
Quoted 10 lines
drivers/firmware/xilinx/zynqmp.c +10
-0+static DEVICE_ATTR_RW (shutdown_scope); + +static struct attribute *zynqmp_shutdown_scope_attrs[] = { + &dev_attr_shutdown_scope.attr, +NULL , +}; + +static const struct attribute_group shutdown_scope_attribute_group = { + .attrs = zynqmp_shutdown_scope_attrs, +};
ATTRIBUTE_GROUPS()?
thanks,
greg k-h
PATCH v3 24/24 firmware: xilinx: Add sysfs and API to set boot health status
In reply to Jolly ShahFrom: Rajan Vaja <[email protected]>
Add sysfs interface to set boot health status from user space. Add API used by this interface to communicate with firmware.
If PMUFW is compiled with CHECK_HEALTHY_BOOT, it will check the healthy bit on FPD WDT expiration. If healthy bit is set by a user application running in Linux, PMUFW will do APU only restart. If healthy bit is not set during FPD WDT expiration, PMUFW will do system restart.
--- .../ABI/stable/sysfs-driver-firmware-zynqmp | 21 ++++++++ drivers/firmware/xilinx/zynqmp.c | 63 ++++++++++++++++++++++ include/linux/firmware/xlnx-zynqmp.h | 3 ++ 3 files changed, 87 insertions(+)
Documentation/ABI/stable/sysfs-driver-firmware-zynqmp +21 -0
@@ -80,3 +80,24 @@ Description: # echo "subsystem" > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope Users: Xilinx + +What: /sys/devices/platform/firmware\:zynqmp-firmware/health_status +Date: March 2020 +KernelVersion: 5.6 +Contact: "Jolly Shah" <[email protected]> +Description: + This sysfs interface allows to set the health status. If PMUFW + is compiled with CHECK_HEALTHY_BOOT, it will check the healthy + bit on FPD WDT expiration. If healthy bit is set by a user + application running in Linux, PMUFW will do APU only restart. If + healthy bit is not set during FPD WDT expiration, PMUFW will do + system restart. + + Usage: + Set healthy bit + # echo 1 > /sys/devices/platform/firmware\:zynqmp-firmware/health_status + + Unset healthy bit + # echo 0 > /sys/devices/platform/firmware\:zynqmp-firmware/health_status + +Users: Xilinx
drivers/firmware/xilinx/zynqmp.c +63 -0
81 lines not on this page · raw message
include/linux/firmware/xlnx-zynqmp.h +3 -0
@@ -114,6 +114,8 @@ enum pm_ioctl_id {IOCTL_READ_GGS ,IOCTL_WRITE_PGGS ,IOCTL_READ_PGGS , +/* Set healthy bit value */ + IOCTL_SET_BOOT_HEALTH_STATUS = 17, }; enum pm_query_id {
@@ -341,6 +343,7 @@ int zynqmp_pm_read_ggs(u32 index, u32 *value);int zynqmp_pm_write_pggs (u32 index,u32 value);int zynqmp_pm_read_pggs (u32 index,u32 *value);int zynqmp_pm_system_shutdown (const u32 type,const u32 subtype); +int zynqmp_pm_set_boot_health_status (u32 value);int zynqmp_pm_invoke_fn (u32 pm_api_id,u32 arg0,u32 arg1,u32 arg2,u32 arg3,u32 *ret_payload);
Signature · 1 line
2.7.4
Re: [PATCH v3 24/24] firmware: xilinx: Add sysfs and API to set boot health status
Quoted 101 lines · Jolly Shah
From: Rajan Vaja <[email protected]>
Add sysfs interface to set boot health status from user space. Add API used by this interface to communicate with firmware.
If PMUFW is compiled with
CHECK_HEALTHY_BOOT, it will check the healthy bit on FPD WDT expiration. If healthy bit is set by a user application running in Linux, PMUFW will do APU only restart. If healthy bit is not set during FPD WDT expiration, PMUFW will do system restart.Signed-off-by Rajan Vaja <[email protected]>Signed-off-by Michal Simek <[email protected]>Signed-off-by Jolly Shah <[email protected]>Signed-off-by Tejas Patel <[email protected]>Signed-off-by Jolly Shah <[email protected]>--- .../ABI/stable/sysfs-driver-firmware-zynqmp | 21 ++++++++ drivers/firmware/xilinx/zynqmp.c | 63 ++++++++++++++++++++++ include/linux/firmware/xlnx-zynqmp.h | 3 ++ 3 files changed, 87 insertions(+)Documentation/ABI/stable/sysfs-driver-firmware-zynqmp +21
-0@@ -80,3 +80,24 @@ Description: # echo "subsystem" > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope Users: Xilinx + +What: /sys/devices/platform/firmware\:zynqmp-firmware/health_status +Date: March 2020 +KernelVersion: 5.6 +Contact: "Jolly Shah" <[email protected]> +Description: + This sysfs interface allows to set the health status. If PMUFW + is compiled with CHECK_HEALTHY_BOOT, it will check the healthy + bit on FPD WDT expiration. If healthy bit is set by a user + application running in Linux, PMUFW will do APU only restart. If + healthy bit is not set during FPD WDT expiration, PMUFW will do + system restart. + + Usage: + Set healthy bit + # echo 1 > /sys/devices/platform/firmware\:zynqmp-firmware/health_status + + Unset healthy bit + # echo 0 > /sys/devices/platform/firmware\:zynqmp-firmware/health_status + +Users: Xilinxdrivers/firmware/xilinx/zynqmp.c +35
-0@@ -667,6 +667,21 @@ int zynqmp_pm_read_pggs(u32 index, u32 *value)EXPORT_SYMBOL_GPL (zynqmp_pm_read_pggs);/** +* zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status +* @value Status value to be written +* +* This function sets healthy bit value to indicate boot health status +* to firmware. +* +* @return Returns status, either success or error+reason +*/ +int zynqmp_pm_set_boot_health_status (u32 value) +{ +return zynqmp_pm_invoke_fn (PM_IOCTL ,0 ,IOCTL_SET_BOOT_HEALTH_STATUS , + value,0 ,NULL ); +} + +/** * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release) * @reset: Reset to be configured * @assert_flag: Flag stating should reset be asserted (1) or @@ -995,6 +1010,53 @@ static const struct attribute_group shutdown_scope_attribute_group = { };/** +* health_status_store - Store health_status sysfs attribute +* @device: Device structure +* @attr: Device attribute structure +* @buf: User entered health_status attribute string +* @count: Buffer size +* +* User-space interface for setting the boot health status. +* Usage: echo <value> > /sys/devices/platform/firmware\:zynqmp-firmware/health_status +* +* Value: +* 1 - Set healthy bit to 1 +* 0 - Unset healthy bit +* +* Return: count argument if request succeeds, the corresponding error +* code otherwise +*/ +static ssize_t health_status_store (struct device *device, +struct device_attribute *attr, +const char *buf,size_t count) +{
drivers/firmware/xilinx/zynqmp.c static const struct attribute_group shutdown_scope_attribute_group = { · line 1042
Quoted 10 lines
drivers/firmware/xilinx/zynqmp.c +10
-0+int ret; +unsigned int value; + + ret =kstrtouint (buf,10 , &value); +if (ret) +return ret; + + ret =zynqmp_pm_set_boot_health_status (value); +if (ret) { +pr_err ("unable to set healthy bit value to %u\n" , value);
You have a valid struct device right there, use it!
dev_err() please...
thanks,
greg k-h
Greg KH
AppliedQuoted 8 lines · Jolly Shah
This patch series adds xilinx specific sysfs interface for below purposes:
- Register access
- Set shutdown scope
- Set boot health status bitAlso this patch series removes eemi ops and adds API corresponding to each eemi ops.
I've applied the first 19 patches here, they looked good, thanks for doing that work, makes things a lot more "obvious" as to what is going on here.
The rest, please see my review comments and redo.
thanks,
greg k-h
Hi Greg,
Thanks for the review.
Quoted 14 lines
------Original Message------
From: 'Greg Kh' <[email protected]>
Sent: Wednesday, March 18, 2020 4:54AM
To: Jolly Shah <[email protected]>
Cc: [email protected] <[email protected]>, [email protected] <[email protected]>, [email protected] <[email protected]>, [email protected] <[email protected]>, [email protected] <[email protected]>, [email protected] <[email protected]>, [email protected] <[email protected]>, Michal Simek <[email protected]>, Rajan Vaja <[email protected]>, [email protected] <[email protected]>, [email protected] <[email protected]>
Subject: Re: [PATCH v3 00/24] firmware: xilinx: Add xilinx specific sysfs interfaceQuoted 6 lines · Jolly Shah
This patch series adds xilinx specific sysfs interface for below purposes:
- Register access
- Set shutdown scope
- Set boot health status bit
Quoted 9 lines
Quoted 2 lines
Also this patch series removes eemi ops and adds API corresponding to each eemi ops.
I've applied the first 19 patches here, they looked good, thanks for doing that work, makes things a lot more "obvious" as to what is going on here.
The rest, please see my review comments and redo.
Submitted v4 patchset. It addresses your review comments. Also took care of compilation issues observed for first 19 patches. Please review.
Thanks,
Jolly Shah
Quoted 4 lines
thanks,
greg k-h