Re: [PATCH 1/2] powerpc/kernel/sysfs: Refactor current sysfs.c

2020-03-05 Thread Michael Ellerman
On Fri, 2020-02-14 at 08:06:05 UTC, Kajol Jain wrote:
> From: Madhavan Srinivasan 
> 
> An attempt to refactor the current sysfs.c file.
> To start with a big chuck of macro #defines and dscr
> functions are moved to start of the file. Secondly,
> HAS_ #define macros are cleanup based on CONFIG_ options
> 
> Finally new HAS_ macro added:
> 1. HAS_PPC_PA6T (for PA6T) to separate out non-PMU SPRs.
> 2. HAS_PPC_PMC56 to separate out PMC SPR's from HAS_PPC_PMC_CLASSIC
>which come under CONFIG_PPC64.
> 
> Signed-off-by: Madhavan Srinivasan 

Series applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/fcdb524d440d6326c286006e16f252b40ba4fd6a

cheers


[PATCH 1/2] powerpc/kernel/sysfs: Refactor current sysfs.c

2020-02-14 Thread Kajol Jain
From: Madhavan Srinivasan 

An attempt to refactor the current sysfs.c file.
To start with a big chuck of macro #defines and dscr
functions are moved to start of the file. Secondly,
HAS_ #define macros are cleanup based on CONFIG_ options

Finally new HAS_ macro added:
1. HAS_PPC_PA6T (for PA6T) to separate out non-PMU SPRs.
2. HAS_PPC_PMC56 to separate out PMC SPR's from HAS_PPC_PMC_CLASSIC
   which come under CONFIG_PPC64.

Signed-off-by: Madhavan Srinivasan 
---
 arch/powerpc/kernel/sysfs.c | 375 +++-
 1 file changed, 200 insertions(+), 175 deletions(-)

diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 80a676d..74da5eb 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -87,6 +87,155 @@ static int __init setup_smt_snooze_delay(char *str)
 
 #endif /* CONFIG_PPC64 */
 
+#define __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, EXTRA) \
+static void read_##NAME(void *val) \
+{ \
+   *(unsigned long *)val = mfspr(ADDRESS); \
+} \
+static void write_##NAME(void *val) \
+{ \
+   EXTRA; \
+   mtspr(ADDRESS, *(unsigned long *)val);  \
+}
+
+#define __SYSFS_SPRSETUP_SHOW_STORE(NAME) \
+static ssize_t show_##NAME(struct device *dev, \
+   struct device_attribute *attr, \
+   char *buf) \
+{ \
+   struct cpu *cpu = container_of(dev, struct cpu, dev); \
+   unsigned long val; \
+   smp_call_function_single(cpu->dev.id, read_##NAME, &val, 1);\
+   return sprintf(buf, "%lx\n", val); \
+} \
+static ssize_t __used \
+   store_##NAME(struct device *dev, struct device_attribute *attr, \
+   const char *buf, size_t count) \
+{ \
+   struct cpu *cpu = container_of(dev, struct cpu, dev); \
+   unsigned long val; \
+   int ret = sscanf(buf, "%lx", &val); \
+   if (ret != 1) \
+   return -EINVAL; \
+   smp_call_function_single(cpu->dev.id, write_##NAME, &val, 1); \
+   return count; \
+}
+
+#define SYSFS_PMCSETUP(NAME, ADDRESS) \
+   __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ppc_enable_pmcs()) \
+   __SYSFS_SPRSETUP_SHOW_STORE(NAME)
+#define SYSFS_SPRSETUP(NAME, ADDRESS) \
+   __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ) \
+   __SYSFS_SPRSETUP_SHOW_STORE(NAME)
+
+#define SYSFS_SPRSETUP_SHOW_STORE(NAME) \
+   __SYSFS_SPRSETUP_SHOW_STORE(NAME)
+
+#ifdef CONFIG_PPC64
+
+/*
+ * This is the system wide DSCR register default value. Any
+ * change to this default value through the sysfs interface
+ * will update all per cpu DSCR default values across the
+ * system stored in their respective PACA structures.
+ */
+static unsigned long dscr_default;
+
+/**
+ * read_dscr() - Fetch the cpu specific DSCR default
+ * @val:   Returned cpu specific DSCR default value
+ *
+ * This function returns the per cpu DSCR default value
+ * for any cpu which is contained in it's PACA structure.
+ */
+static void read_dscr(void *val)
+{
+   *(unsigned long *)val = get_paca()->dscr_default;
+}
+
+
+/**
+ * write_dscr() - Update the cpu specific DSCR default
+ * @val:   New cpu specific DSCR default value to update
+ *
+ * This function updates the per cpu DSCR default value
+ * for any cpu which is contained in it's PACA structure.
+ */
+static void write_dscr(void *val)
+{
+   get_paca()->dscr_default = *(unsigned long *)val;
+   if (!current->thread.dscr_inherit) {
+   current->thread.dscr = *(unsigned long *)val;
+   mtspr(SPRN_DSCR, *(unsigned long *)val);
+   }
+}
+
+SYSFS_SPRSETUP_SHOW_STORE(dscr);
+static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr);
+
+static void add_write_permission_dev_attr(struct device_attribute *attr)
+{
+   attr->attr.mode |= 0200;
+}
+
+/**
+ * show_dscr_default() - Fetch the system wide DSCR default
+ * @dev:   Device structure
+ * @attr:  Device attribute structure
+ * @buf:   Interface buffer
+ *
+ * This function returns the system wide DSCR default value.
+ */
+static ssize_t show_dscr_default(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   return sprintf(buf, "%lx\n", dscr_default);
+}
+
+/**
+ * store_dscr_default() - Update the system wide DSCR default
+ * @dev:   Device structure
+ * @attr:  Device attribute structure
+ * @buf:   Interface buffer
+ * @count: Size of the update
+ *
+ * This function updates the system wide DSCR default value.
+ */
+static ssize_t __used store_dscr_default(struct device *dev,
+   struct device_attribute *attr, const char *buf,
+   size_t count)
+{
+   unsigned long val;
+   int ret = 0;
+
+   ret = sscanf(buf, "%lx", &val);
+   if (ret != 1)
+   return -EINVAL;
+   dscr_default = val;
+
+   on_each_cpu(write_dscr, &val, 1);
+
+   return count;
+}
+
+static DEVICE_ATTR(dscr_default, 0600,
+   show_dscr_default, store_dscr_default);
+
+static void s