Re: [PATCH] fat: Replaced 11 magic to MSDOS_NAME for volume label
Looks good, Reviewed-by: Johannes Thumshirn -- Johannes ThumshirnSUSE Labs jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
Re: [PATCH] fat: Replaced 11 magic to MSDOS_NAME for volume label
Looks good, Reviewed-by: Johannes Thumshirn -- Johannes ThumshirnSUSE Labs jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
Re: [PATCH] printk: deduplicate print_prefix() calls
On (11/24/18 23:28), Tetsuo Handa wrote: > Since /sys/module/printk/parameters/time can change from N to Y between > "msg_print_text() called print_prefix() with buf == NULL" and > "msg_print_text() again calls print_prefix() with buf != NULL", it is not > safe for print_time() to unconditionally return 0 if printk_time == false. > > But print_prefix() is called by only msg_print_text(), and print_prefix() > is called once more for calculating output length of prefix, and there is > no need to recalculate it when one log entry contains multiple lines. Good catch. > Since max output length for syslog marker and timestamp are known to be > small enough, let's close this race by deduplicating print_prefix() calls. > > Signed-off-by: Tetsuo Handa Or we can change printk_time under logbuf lock? So msg_print_text will not race with it. Or we can "copy" the value of printk_time and use it in print_prefix(), and we will pick up an updated value next time we do msg_print_text()? Example: --- diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 1b2a029360b7..4c57f5d5b0b6 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1211,13 +1211,14 @@ static inline void boot_delay_msec(int level) #endif static bool printk_time = IS_ENABLED(CONFIG_PRINTK_TIME); +static bool printk_time_saved; module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); static size_t print_time(u64 ts, char *buf) { unsigned long rem_nsec; - if (!printk_time) + if (!printk_time_saved) return 0; rem_nsec = do_div(ts, 10); @@ -1258,6 +1259,8 @@ static size_t msg_print_text(const struct printk_log *msg, bool syslog, char *bu size_t text_size = msg->text_len; size_t len = 0; + printk_time_saved = printk_time; + do { const char *next = memchr(text, '\n', text_size); size_t text_len;
Re: [PATCH v2 0/2] driver: thermal: Move some drivers into subdirs
On 五, 2018-11-23 at 00:17 +0530, Amit Kucheria wrote: > On Fri, Oct 26, 2018 at 2:21 PM Amit Kucheria rg> wrote: > > > > > > Hi Rui, > > > > On Thu, Oct 4, 2018 at 1:22 PM Amit Kucheria > org> wrote: > > > > > > > > > Move the various drivers for Intel platforms into their own > > > subdir. Also > > > consolidate Qualcomm drivers into the qcom subdir. > > > > > > This cleans up the directory making it easier to find things. > > Any comments on these changes? > Rui? Eduardo? > the patches were not sent to linux-pm mailing list, and that's why I overlooked this patch set in patchwork. thanks, rui > > > > > > > > There is no great time to send patches that move files around, > > > but I'm told > > > that towards the end of the merge window is nicer. So here's an > > > attempt to > > > sneak it into 4.20 after everything else and hoping that these > > > files won't > > > change after 4.19-rc6. :-) > > > > > > This was generated and compile-tested against 4.19-rc6. If you > > > would like > > > me to try again a bit later, I'm happy to do so. > > > > > > Changes since v1: > > > - Removed a stray character that snuck into the Makefile > > > - Added Acks > > > - Rebased to v4.19-rc6 > > > > > > Amit Kucheria (2): > > > drivers: thermal: Move various drivers for intel platforms into > > > a > > > subdir > > > drivers: thermal: Move QCOM_SPMI_TEMP_ALARM into the qcom > > > subdir > > > > > > drivers/thermal/Kconfig | 94 +-- > > > > > > drivers/thermal/Makefile | 10 +- > > > drivers/thermal/intel/Kconfig | 77 > > > +++ > > > drivers/thermal/intel/Makefile| 12 +++ > > > .../{ => intel}/int340x_thermal/Kconfig | 0 > > > .../{ => intel}/int340x_thermal/Makefile | 0 > > > .../int340x_thermal/acpi_thermal_rel.c| 0 > > > .../int340x_thermal/acpi_thermal_rel.h| 0 > > > .../int340x_thermal/int3400_thermal.c | 0 > > > .../int340x_thermal/int3402_thermal.c | 0 > > > .../int340x_thermal/int3403_thermal.c | 0 > > > .../int340x_thermal/int3406_thermal.c | 0 > > > .../int340x_thermal/int340x_thermal_zone.c| 0 > > > .../int340x_thermal/int340x_thermal_zone.h| 0 > > > .../processor_thermal_device.c| 0 > > > .../{ => intel}/intel_bxt_pmic_thermal.c | 0 > > > .../thermal/{ => intel}/intel_pch_thermal.c | 0 > > > .../thermal/{ => intel}/intel_powerclamp.c| 0 > > > .../{ => intel}/intel_quark_dts_thermal.c | 0 > > > .../thermal/{ => intel}/intel_soc_dts_iosf.c | 0 > > > .../thermal/{ => intel}/intel_soc_dts_iosf.h | 0 > > > .../{ => intel}/intel_soc_dts_thermal.c | 0 > > > .../{ => intel}/x86_pkg_temp_thermal.c| 0 > > > drivers/thermal/qcom/Kconfig | 11 +++ > > > drivers/thermal/qcom/Makefile | 1 + > > > .../thermal/{ => qcom}/qcom-spmi-temp-alarm.c | 0 > > > 26 files changed, 107 insertions(+), 98 deletions(-) > > > create mode 100644 drivers/thermal/intel/Kconfig > > > create mode 100644 drivers/thermal/intel/Makefile > > > rename drivers/thermal/{ => intel}/int340x_thermal/Kconfig > > > (100%) > > > rename drivers/thermal/{ => intel}/int340x_thermal/Makefile > > > (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/acpi_thermal_rel.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/acpi_thermal_rel.h (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3400_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3402_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3403_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3406_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int340x_thermal_zone.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int340x_thermal_zone.h (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/processor_thermal_device.c (100%) > > > rename drivers/thermal/{ => intel}/intel_bxt_pmic_thermal.c > > > (100%) > > > rename drivers/thermal/{ => intel}/intel_pch_thermal.c (100%) > > > rename drivers/thermal/{ => intel}/intel_powerclamp.c (100%) > > > rename drivers/thermal/{ => intel}/intel_quark_dts_thermal.c > > > (100%) > > > rename drivers/thermal/{ => intel}/intel_soc_dts_iosf.c (100%) > > > rename drivers/thermal/{ => intel}/intel_soc_dts_iosf.h (100%) > > > rename drivers/thermal/{ => intel}/intel_soc_dts_thermal.c > > > (100%) > > > rename drivers/thermal/{ => intel}/x86_pkg_temp_thermal.c (100%) > > > rename drivers/thermal/{ => qcom}/qcom-spmi-temp-alarm.c (100%) > > > > > > -- > > > 2.17.1 > > >
Re: [PATCH] printk: deduplicate print_prefix() calls
On (11/24/18 23:28), Tetsuo Handa wrote: > Since /sys/module/printk/parameters/time can change from N to Y between > "msg_print_text() called print_prefix() with buf == NULL" and > "msg_print_text() again calls print_prefix() with buf != NULL", it is not > safe for print_time() to unconditionally return 0 if printk_time == false. > > But print_prefix() is called by only msg_print_text(), and print_prefix() > is called once more for calculating output length of prefix, and there is > no need to recalculate it when one log entry contains multiple lines. Good catch. > Since max output length for syslog marker and timestamp are known to be > small enough, let's close this race by deduplicating print_prefix() calls. > > Signed-off-by: Tetsuo Handa Or we can change printk_time under logbuf lock? So msg_print_text will not race with it. Or we can "copy" the value of printk_time and use it in print_prefix(), and we will pick up an updated value next time we do msg_print_text()? Example: --- diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 1b2a029360b7..4c57f5d5b0b6 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1211,13 +1211,14 @@ static inline void boot_delay_msec(int level) #endif static bool printk_time = IS_ENABLED(CONFIG_PRINTK_TIME); +static bool printk_time_saved; module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); static size_t print_time(u64 ts, char *buf) { unsigned long rem_nsec; - if (!printk_time) + if (!printk_time_saved) return 0; rem_nsec = do_div(ts, 10); @@ -1258,6 +1259,8 @@ static size_t msg_print_text(const struct printk_log *msg, bool syslog, char *bu size_t text_size = msg->text_len; size_t len = 0; + printk_time_saved = printk_time; + do { const char *next = memchr(text, '\n', text_size); size_t text_len;
Re: [PATCH v2 0/2] driver: thermal: Move some drivers into subdirs
On 五, 2018-11-23 at 00:17 +0530, Amit Kucheria wrote: > On Fri, Oct 26, 2018 at 2:21 PM Amit Kucheria rg> wrote: > > > > > > Hi Rui, > > > > On Thu, Oct 4, 2018 at 1:22 PM Amit Kucheria > org> wrote: > > > > > > > > > Move the various drivers for Intel platforms into their own > > > subdir. Also > > > consolidate Qualcomm drivers into the qcom subdir. > > > > > > This cleans up the directory making it easier to find things. > > Any comments on these changes? > Rui? Eduardo? > the patches were not sent to linux-pm mailing list, and that's why I overlooked this patch set in patchwork. thanks, rui > > > > > > > > There is no great time to send patches that move files around, > > > but I'm told > > > that towards the end of the merge window is nicer. So here's an > > > attempt to > > > sneak it into 4.20 after everything else and hoping that these > > > files won't > > > change after 4.19-rc6. :-) > > > > > > This was generated and compile-tested against 4.19-rc6. If you > > > would like > > > me to try again a bit later, I'm happy to do so. > > > > > > Changes since v1: > > > - Removed a stray character that snuck into the Makefile > > > - Added Acks > > > - Rebased to v4.19-rc6 > > > > > > Amit Kucheria (2): > > > drivers: thermal: Move various drivers for intel platforms into > > > a > > > subdir > > > drivers: thermal: Move QCOM_SPMI_TEMP_ALARM into the qcom > > > subdir > > > > > > drivers/thermal/Kconfig | 94 +-- > > > > > > drivers/thermal/Makefile | 10 +- > > > drivers/thermal/intel/Kconfig | 77 > > > +++ > > > drivers/thermal/intel/Makefile| 12 +++ > > > .../{ => intel}/int340x_thermal/Kconfig | 0 > > > .../{ => intel}/int340x_thermal/Makefile | 0 > > > .../int340x_thermal/acpi_thermal_rel.c| 0 > > > .../int340x_thermal/acpi_thermal_rel.h| 0 > > > .../int340x_thermal/int3400_thermal.c | 0 > > > .../int340x_thermal/int3402_thermal.c | 0 > > > .../int340x_thermal/int3403_thermal.c | 0 > > > .../int340x_thermal/int3406_thermal.c | 0 > > > .../int340x_thermal/int340x_thermal_zone.c| 0 > > > .../int340x_thermal/int340x_thermal_zone.h| 0 > > > .../processor_thermal_device.c| 0 > > > .../{ => intel}/intel_bxt_pmic_thermal.c | 0 > > > .../thermal/{ => intel}/intel_pch_thermal.c | 0 > > > .../thermal/{ => intel}/intel_powerclamp.c| 0 > > > .../{ => intel}/intel_quark_dts_thermal.c | 0 > > > .../thermal/{ => intel}/intel_soc_dts_iosf.c | 0 > > > .../thermal/{ => intel}/intel_soc_dts_iosf.h | 0 > > > .../{ => intel}/intel_soc_dts_thermal.c | 0 > > > .../{ => intel}/x86_pkg_temp_thermal.c| 0 > > > drivers/thermal/qcom/Kconfig | 11 +++ > > > drivers/thermal/qcom/Makefile | 1 + > > > .../thermal/{ => qcom}/qcom-spmi-temp-alarm.c | 0 > > > 26 files changed, 107 insertions(+), 98 deletions(-) > > > create mode 100644 drivers/thermal/intel/Kconfig > > > create mode 100644 drivers/thermal/intel/Makefile > > > rename drivers/thermal/{ => intel}/int340x_thermal/Kconfig > > > (100%) > > > rename drivers/thermal/{ => intel}/int340x_thermal/Makefile > > > (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/acpi_thermal_rel.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/acpi_thermal_rel.h (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3400_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3402_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3403_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int3406_thermal.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int340x_thermal_zone.c (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/int340x_thermal_zone.h (100%) > > > rename drivers/thermal/{ => > > > intel}/int340x_thermal/processor_thermal_device.c (100%) > > > rename drivers/thermal/{ => intel}/intel_bxt_pmic_thermal.c > > > (100%) > > > rename drivers/thermal/{ => intel}/intel_pch_thermal.c (100%) > > > rename drivers/thermal/{ => intel}/intel_powerclamp.c (100%) > > > rename drivers/thermal/{ => intel}/intel_quark_dts_thermal.c > > > (100%) > > > rename drivers/thermal/{ => intel}/intel_soc_dts_iosf.c (100%) > > > rename drivers/thermal/{ => intel}/intel_soc_dts_iosf.h (100%) > > > rename drivers/thermal/{ => intel}/intel_soc_dts_thermal.c > > > (100%) > > > rename drivers/thermal/{ => intel}/x86_pkg_temp_thermal.c (100%) > > > rename drivers/thermal/{ => qcom}/qcom-spmi-temp-alarm.c (100%) > > > > > > -- > > > 2.17.1 > > >
Re: linux-next: build warning after merge of the btrfs-kdave tree
On Mon, Nov 26, 2018 at 11:06:29AM +1100, Stephen Rothwell wrote: > Introduced by commit > > cf8cddd38bab3 ("btrfs: don't abuse REQ_OP_* flags for btrfs_map_block") > > exposed by my new use of -Wimplicit-fallthrough > > I am not sure why this has only turned up now (as opposed to earlier > today). It looks like something only in linux-next moved the code around a bit. Either way the fallthough looks fine, it will just need a little /*FALLTHRU*/ annotation.
Re: linux-next: build warning after merge of the btrfs-kdave tree
On Mon, Nov 26, 2018 at 11:06:29AM +1100, Stephen Rothwell wrote: > Introduced by commit > > cf8cddd38bab3 ("btrfs: don't abuse REQ_OP_* flags for btrfs_map_block") > > exposed by my new use of -Wimplicit-fallthrough > > I am not sure why this has only turned up now (as opposed to earlier > today). It looks like something only in linux-next moved the code around a bit. Either way the fallthough looks fine, it will just need a little /*FALLTHRU*/ annotation.
Re: [patch V2 26/28] x86/speculation: Enable prctl mode for spectre_v2_user
On Sun, Nov 25, 2018 at 07:33:54PM +0100, Thomas Gleixner wrote: > + prctl - Indirect branch speculation is enabled, > + but mitigation can be enabled via prctl s/can be/is only/ or "must be". Thanks, Dominik
Re: [patch V2 26/28] x86/speculation: Enable prctl mode for spectre_v2_user
On Sun, Nov 25, 2018 at 07:33:54PM +0100, Thomas Gleixner wrote: > + prctl - Indirect branch speculation is enabled, > + but mitigation can be enabled via prctl s/can be/is only/ or "must be". Thanks, Dominik
[PATCH 16/16] remoteproc/pru: Add support for INTC Interrupt map resource
Use the vendor specific resource mechanism to get the INTC mapping details from firmware. pru-software-support-package [1] has been historically using version 0 for this. However, the data structure is not scaleable and is not self sufficient. 1) it hard codes number of channel to host mappings so is not scaleable to newer SoCs than have more of these. 2) it does not contain the event to channel mappings within itself but relies on a pointer to point to another section in data memory. This causes a weird complication that the respective data section must be loaded before we can really use the INTC map. With this patch we drop support for version 0 and support version 1 which is a more robust and scalable data structure. It should be able to support a sufficiently large number (255) of sysevents, channels and host interrupts and is self contained so it can be used without dependency on order of loading sections. [1] git://git.ti.com/pru-software-support-package/pru-software-support-package.git Signed-off-by: Roger Quadros --- drivers/remoteproc/pru_rproc.c | 110 +++-- drivers/remoteproc/pru_rproc.h | 48 +++--- 2 files changed, 126 insertions(+), 32 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 540cce3..9e22c70 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -75,6 +75,7 @@ enum pru_mem { * @fw_name: name of firmware image used during loading * @gpmux_save: saved value for gpmux config * @dt_irqs: number of irqs configured from DT + * @fw_irqs: number of irqs configured from FW * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode @@ -101,6 +102,7 @@ struct pru_rproc { const char *fw_name; u8 gpmux_save; int dt_irqs; + int fw_irqs; struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; @@ -651,6 +653,107 @@ static void pru_rproc_kick(struct rproc *rproc, int vq_id) } } +/* + * parse the custom interrupt map resource and save the intc_config + * for use when booting the processor. + */ +static int pru_handle_vendor_intrmap(struct rproc *rproc, +struct fw_rsc_pruss_intrmap *rsc) +{ + int fw_irqs = 0, i, ret = 0; + u8 *arr; + struct device *dev = >dev; + struct pru_rproc *pru = rproc->priv; + + dev_dbg(dev, "vendor rsc intc: version %d\n", rsc->version); + + /* +* 0 was prototyping version. Not supported. +* 1 is currently supported version. +*/ + if (rsc->version == 0 || rsc->version > 1) { + dev_err(dev, "Unsupported version %d\n", rsc->version); + return -EINVAL; + } + + /* DT provided INTC config takes precedence */ + if (pru->dt_irqs) { + dev_info(dev, "INTC config in DT and FW. Using DT config.\n"); + return 0; + } + + arr = rsc->data; + + for (i = 0; i < ARRAY_SIZE(pru->intc_config.sysev_to_ch); i++) + pru->intc_config.sysev_to_ch[i] = -1; + + for (i = 0; i < ARRAY_SIZE(pru->intc_config.ch_to_host); i++) + pru->intc_config.ch_to_host[i] = -1; + + for (i = 0; i < rsc->num_maps * 3; i += 3) { + if (arr[i] < 0 || + arr[i] >= MAX_PRU_SYS_EVENTS) { + dev_err(dev, "bad sys event %d\n", arr[i]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 1] < 0 || + arr[i + 1] >= MAX_PRU_CHANNELS) { + dev_err(dev, "bad channel %d\n", arr[i + 1]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 2] < 0 || + arr[i + 2] >= MAX_PRU_CHANNELS) { + dev_err(dev, "bad host irq %d\n", arr[i + 2]); + ret = -EINVAL; + goto err; + } + + pru->intc_config.sysev_to_ch[arr[i]] = arr[i + 1]; + dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", arr[i], + arr[i + 1]); + + pru->intc_config.ch_to_host[arr[i + 1]] = arr[i + 2]; + dev_dbg(dev, "chnl-to-host[%d] -> %d\n", arr[i + 1], + arr[i + 2]); + + fw_irqs++; + } + + pru->fw_irqs = fw_irqs; + return 0; + +err: + pru->fw_irqs = 0; + return ret; +} + +/* PRU-specific vendor resource handler */ +static int pru_rproc_handle_vendor_rsc(struct rproc *rproc, + struct fw_rsc_vendor *ven_rsc) +{ + struct device *dev = rproc->dev.parent; + int ret = -EINVAL; + + struct
[PATCH 04/16] remoteproc/pru: Add PRU remoteproc driver
From: Suman Anna The Programmable Real-Time Unit Subsystem (PRUSS) consists of dual 32-bit RISC cores (Programmable Real-Time Units, or PRUs) for program execution. This patch adds a remoteproc platform driver for managing the individual PRU RISC cores life cycle. The PRU remoteproc driver uses the standard remoteproc core ELF loader. However, the PRUs do not have a unified address space, (has an Instruction RAM and a primary Data RAM at both 0x0) and leverage an added .da_to_va ops to use the standard ELF loader. This remoteproc driver does not have support for error recovery and system suspend/resume features. Different compatibles are used to allow providing scalability for instance-specific device data if needed. The driver uses a default firmware-name retrieved from device-tree, and the firmwares are expected to be present in the standard Linux firmware search paths. They can also be adjusted by userspace if required through the sysfs interface provided by the remoteproc core. The PRU remoteproc driver uses a client-driven boot methodology - it does _not_ support auto-boot so that the PRU load and boot is dictated by the corresponding client drivers for achieving various usecases. This allows flexibility for the client drivers or applications to set a firmware name (if needed) based on their desired functionality and boot the PRU. The sysfs bind and unbind attributes have also been suppressed so that the PRU devices cannot be unbound and thereby shutdown a PRU from underneath a PRU client driver. The driver currently supports the AM335x SoC, and support for other TI SoCs will be added in subsequent patches. [rog...@ti.com] Use request/release_mem_region() [rog...@ti.com] Strip INTC handling Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Roger Quadros --- drivers/remoteproc/Kconfig | 14 ++ drivers/remoteproc/Makefile| 1 + drivers/remoteproc/pru_rproc.c | 392 + drivers/remoteproc/pru_rproc.h | 65 +++ 4 files changed, 472 insertions(+) create mode 100644 drivers/remoteproc/pru_rproc.c create mode 100644 drivers/remoteproc/pru_rproc.h diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index f0abd26..333666e 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -197,6 +197,20 @@ config ST_REMOTEPROC config ST_SLIM_REMOTEPROC tristate +config PRUSS_REMOTEPROC + tristate "TI PRUSS remoteproc support" + depends on TI_PRUSS + default n + help + Support for TI PRU-ICSS remote processors via the remote processor + framework. + + Currently supported on AM33xx SoCs. + + Say Y or M here to support the Programmable Realtime Unit (PRU) + processors on various TI SoCs. It's safe to say N here if you're + not interested in the PRU or if you are unsure. + endif # REMOTEPROC endmenu diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index ce5d061..88a86cc 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -26,3 +26,4 @@ qcom_wcnss_pil-y += qcom_wcnss.o qcom_wcnss_pil-y += qcom_wcnss_iris.o obj-$(CONFIG_ST_REMOTEPROC)+= st_remoteproc.o obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o +obj-$(CONFIG_PRUSS_REMOTEPROC) += pru_rproc.o diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c new file mode 100644 index 000..c35f432 --- /dev/null +++ b/drivers/remoteproc/pru_rproc.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PRU-ICSS remoteproc driver for various TI SoCs + * + * Copyright (C) 2014-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Suman Anna + * Andrew F. Davis + */ + +#include +#include +#include +#include +#include +#include + +#include "remoteproc_internal.h" +#include "pru_rproc.h" + +/* PRU_ICSS_PRU_CTRL registers */ +#define PRU_CTRL_CTRL 0x +#define PRU_CTRL_STS 0x0004 +#define PRU_CTRL_WAKEUP_EN 0x0008 +#define PRU_CTRL_CYCLE 0x000C +#define PRU_CTRL_STALL 0x0010 +#define PRU_CTRL_CTBIR00x0020 +#define PRU_CTRL_CTBIR10x0024 +#define PRU_CTRL_CTPPR00x0028 +#define PRU_CTRL_CTPPR10x002C + +/* CTRL register bit-fields */ +#define CTRL_CTRL_SOFT_RST_N BIT(0) +#define CTRL_CTRL_EN BIT(1) +#define CTRL_CTRL_SLEEPING BIT(2) +#define CTRL_CTRL_CTR_EN BIT(3) +#define CTRL_CTRL_SINGLE_STEP BIT(8) +#define CTRL_CTRL_RUNSTATE BIT(15) + +/** + * enum pru_mem - PRU core memory range identifiers + */ +enum pru_mem { + PRU_MEM_IRAM = 0, + PRU_MEM_CTRL, + PRU_MEM_DEBUG, + PRU_MEM_MAX, +}; + +/** + * struct pru_rproc - PRU remoteproc structure + * @id: id of the PRU core within the PRUSS + * @pruss: back-reference to parent PRUSS structure + * @rproc:
[PATCH 15/16] remoteproc/pru: add support for parsing pru interrupt mapping from DT
From: Tero Kristo PRU interrupt mapping can now be parsed from devicetree also, from ti,pru-interrupt-map property. This is an alternative configuration method in addition to the legacy resource table config. If both are provided, the config in DT takes precedence. Signed-off-by: Tero Kristo [s-a...@ti.com: various fixes and cleanups] Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- drivers/remoteproc/pru_rproc.c | 109 +++-- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 84f006b..540cce3 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -63,6 +63,7 @@ enum pru_mem { * @irq_ring: IRQ number to use for processing vring buffers * @irq_kick: IRQ number to use to perform virtio kick * @mem_regions: data for each of the PRU memory regions + * @intc_config: PRU INTC configuration data * @dram0: PRUSS DRAM0 region * @dram1: PRUSS DRAM1 region * @shrdram: PRUSS SHARED RAM region @@ -73,6 +74,7 @@ enum pru_mem { * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading * @gpmux_save: saved value for gpmux config + * @dt_irqs: number of irqs configured from DT * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode @@ -87,6 +89,7 @@ struct pru_rproc { int irq_vring; int irq_kick; struct pruss_mem_region mem_regions[PRU_MEM_MAX]; + struct pruss_intc_config intc_config; struct pruss_mem_region dram0; struct pruss_mem_region dram1; struct pruss_mem_region shrdram; @@ -97,6 +100,7 @@ struct pru_rproc { u32 shrdram_da; const char *fw_name; u8 gpmux_save; + int dt_irqs; struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; @@ -180,6 +184,87 @@ static struct rproc *__pru_rproc_get(struct device_node *np, int index) return rproc; } +static int pru_get_intc_dt_config(struct device *dev, const char *propname, + int index, + struct pruss_intc_config *intc_config) +{ + struct device_node *np = dev->of_node; + struct property *prop; + int ret = 0, entries, i; + int dt_irqs = 0; + u32 *arr; + int max_system_events, max_pru_channels, max_pru_host_ints; + + max_system_events = MAX_PRU_SYS_EVENTS; + max_pru_channels = MAX_PRU_CHANNELS; + max_pru_host_ints = MAX_PRU_CHANNELS; + + prop = of_find_property(np, propname, NULL); + if (!prop) + return 0; + + entries = of_property_count_u32_elems(np, propname); + if (entries <= 0 || entries % 4) + return -EINVAL; + + arr = kmalloc_array(entries, sizeof(u32), GFP_KERNEL); + if (!arr) + return -ENOMEM; + + ret = of_property_read_u32_array(np, propname, arr, entries); + if (ret) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(intc_config->sysev_to_ch); i++) + intc_config->sysev_to_ch[i] = -1; + + for (i = 0; i < ARRAY_SIZE(intc_config->ch_to_host); i++) + intc_config->ch_to_host[i] = -1; + + for (i = 0; i < entries; i += 4) { + if (arr[i] != index) + continue; + + if (arr[i + 1] < 0 || + arr[i + 1] >= max_system_events) { + dev_dbg(dev, "bad sys event %d\n", arr[i + 1]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 2] < 0 || + arr[i + 2] >= max_pru_channels) { + dev_dbg(dev, "bad channel %d\n", arr[i + 2]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 3] < 0 || + arr[i + 3] >= max_pru_host_ints) { + dev_dbg(dev, "bad irq %d\n", arr[i + 3]); + ret = -EINVAL; + goto err; + } + + intc_config->sysev_to_ch[arr[i + 1]] = arr[i + 2]; + dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", arr[i + 1], + arr[i + 2]); + + intc_config->ch_to_host[arr[i + 2]] = arr[i + 3]; + dev_dbg(dev, "chnl-to-host[%d] -> %d\n", arr[i + 2], + arr[i + 3]); + + dt_irqs++; + } + + kfree(arr); + return dt_irqs; + +err: + kfree(arr); + return ret; +} + /** * pru_rproc_get() - get the PRU rproc instance from a device node * @np: the user/client device node @@ -251,6 +336,15 @@ struct rproc *pru_rproc_get(struct device_node *np, int index)
[PATCH 04/16] remoteproc/pru: Add PRU remoteproc driver
From: Suman Anna The Programmable Real-Time Unit Subsystem (PRUSS) consists of dual 32-bit RISC cores (Programmable Real-Time Units, or PRUs) for program execution. This patch adds a remoteproc platform driver for managing the individual PRU RISC cores life cycle. The PRU remoteproc driver uses the standard remoteproc core ELF loader. However, the PRUs do not have a unified address space, (has an Instruction RAM and a primary Data RAM at both 0x0) and leverage an added .da_to_va ops to use the standard ELF loader. This remoteproc driver does not have support for error recovery and system suspend/resume features. Different compatibles are used to allow providing scalability for instance-specific device data if needed. The driver uses a default firmware-name retrieved from device-tree, and the firmwares are expected to be present in the standard Linux firmware search paths. They can also be adjusted by userspace if required through the sysfs interface provided by the remoteproc core. The PRU remoteproc driver uses a client-driven boot methodology - it does _not_ support auto-boot so that the PRU load and boot is dictated by the corresponding client drivers for achieving various usecases. This allows flexibility for the client drivers or applications to set a firmware name (if needed) based on their desired functionality and boot the PRU. The sysfs bind and unbind attributes have also been suppressed so that the PRU devices cannot be unbound and thereby shutdown a PRU from underneath a PRU client driver. The driver currently supports the AM335x SoC, and support for other TI SoCs will be added in subsequent patches. [rog...@ti.com] Use request/release_mem_region() [rog...@ti.com] Strip INTC handling Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Roger Quadros --- drivers/remoteproc/Kconfig | 14 ++ drivers/remoteproc/Makefile| 1 + drivers/remoteproc/pru_rproc.c | 392 + drivers/remoteproc/pru_rproc.h | 65 +++ 4 files changed, 472 insertions(+) create mode 100644 drivers/remoteproc/pru_rproc.c create mode 100644 drivers/remoteproc/pru_rproc.h diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index f0abd26..333666e 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -197,6 +197,20 @@ config ST_REMOTEPROC config ST_SLIM_REMOTEPROC tristate +config PRUSS_REMOTEPROC + tristate "TI PRUSS remoteproc support" + depends on TI_PRUSS + default n + help + Support for TI PRU-ICSS remote processors via the remote processor + framework. + + Currently supported on AM33xx SoCs. + + Say Y or M here to support the Programmable Realtime Unit (PRU) + processors on various TI SoCs. It's safe to say N here if you're + not interested in the PRU or if you are unsure. + endif # REMOTEPROC endmenu diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index ce5d061..88a86cc 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -26,3 +26,4 @@ qcom_wcnss_pil-y += qcom_wcnss.o qcom_wcnss_pil-y += qcom_wcnss_iris.o obj-$(CONFIG_ST_REMOTEPROC)+= st_remoteproc.o obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o +obj-$(CONFIG_PRUSS_REMOTEPROC) += pru_rproc.o diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c new file mode 100644 index 000..c35f432 --- /dev/null +++ b/drivers/remoteproc/pru_rproc.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PRU-ICSS remoteproc driver for various TI SoCs + * + * Copyright (C) 2014-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Suman Anna + * Andrew F. Davis + */ + +#include +#include +#include +#include +#include +#include + +#include "remoteproc_internal.h" +#include "pru_rproc.h" + +/* PRU_ICSS_PRU_CTRL registers */ +#define PRU_CTRL_CTRL 0x +#define PRU_CTRL_STS 0x0004 +#define PRU_CTRL_WAKEUP_EN 0x0008 +#define PRU_CTRL_CYCLE 0x000C +#define PRU_CTRL_STALL 0x0010 +#define PRU_CTRL_CTBIR00x0020 +#define PRU_CTRL_CTBIR10x0024 +#define PRU_CTRL_CTPPR00x0028 +#define PRU_CTRL_CTPPR10x002C + +/* CTRL register bit-fields */ +#define CTRL_CTRL_SOFT_RST_N BIT(0) +#define CTRL_CTRL_EN BIT(1) +#define CTRL_CTRL_SLEEPING BIT(2) +#define CTRL_CTRL_CTR_EN BIT(3) +#define CTRL_CTRL_SINGLE_STEP BIT(8) +#define CTRL_CTRL_RUNSTATE BIT(15) + +/** + * enum pru_mem - PRU core memory range identifiers + */ +enum pru_mem { + PRU_MEM_IRAM = 0, + PRU_MEM_CTRL, + PRU_MEM_DEBUG, + PRU_MEM_MAX, +}; + +/** + * struct pru_rproc - PRU remoteproc structure + * @id: id of the PRU core within the PRUSS + * @pruss: back-reference to parent PRUSS structure + * @rproc:
[PATCH 15/16] remoteproc/pru: add support for parsing pru interrupt mapping from DT
From: Tero Kristo PRU interrupt mapping can now be parsed from devicetree also, from ti,pru-interrupt-map property. This is an alternative configuration method in addition to the legacy resource table config. If both are provided, the config in DT takes precedence. Signed-off-by: Tero Kristo [s-a...@ti.com: various fixes and cleanups] Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- drivers/remoteproc/pru_rproc.c | 109 +++-- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 84f006b..540cce3 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -63,6 +63,7 @@ enum pru_mem { * @irq_ring: IRQ number to use for processing vring buffers * @irq_kick: IRQ number to use to perform virtio kick * @mem_regions: data for each of the PRU memory regions + * @intc_config: PRU INTC configuration data * @dram0: PRUSS DRAM0 region * @dram1: PRUSS DRAM1 region * @shrdram: PRUSS SHARED RAM region @@ -73,6 +74,7 @@ enum pru_mem { * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading * @gpmux_save: saved value for gpmux config + * @dt_irqs: number of irqs configured from DT * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode @@ -87,6 +89,7 @@ struct pru_rproc { int irq_vring; int irq_kick; struct pruss_mem_region mem_regions[PRU_MEM_MAX]; + struct pruss_intc_config intc_config; struct pruss_mem_region dram0; struct pruss_mem_region dram1; struct pruss_mem_region shrdram; @@ -97,6 +100,7 @@ struct pru_rproc { u32 shrdram_da; const char *fw_name; u8 gpmux_save; + int dt_irqs; struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; @@ -180,6 +184,87 @@ static struct rproc *__pru_rproc_get(struct device_node *np, int index) return rproc; } +static int pru_get_intc_dt_config(struct device *dev, const char *propname, + int index, + struct pruss_intc_config *intc_config) +{ + struct device_node *np = dev->of_node; + struct property *prop; + int ret = 0, entries, i; + int dt_irqs = 0; + u32 *arr; + int max_system_events, max_pru_channels, max_pru_host_ints; + + max_system_events = MAX_PRU_SYS_EVENTS; + max_pru_channels = MAX_PRU_CHANNELS; + max_pru_host_ints = MAX_PRU_CHANNELS; + + prop = of_find_property(np, propname, NULL); + if (!prop) + return 0; + + entries = of_property_count_u32_elems(np, propname); + if (entries <= 0 || entries % 4) + return -EINVAL; + + arr = kmalloc_array(entries, sizeof(u32), GFP_KERNEL); + if (!arr) + return -ENOMEM; + + ret = of_property_read_u32_array(np, propname, arr, entries); + if (ret) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(intc_config->sysev_to_ch); i++) + intc_config->sysev_to_ch[i] = -1; + + for (i = 0; i < ARRAY_SIZE(intc_config->ch_to_host); i++) + intc_config->ch_to_host[i] = -1; + + for (i = 0; i < entries; i += 4) { + if (arr[i] != index) + continue; + + if (arr[i + 1] < 0 || + arr[i + 1] >= max_system_events) { + dev_dbg(dev, "bad sys event %d\n", arr[i + 1]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 2] < 0 || + arr[i + 2] >= max_pru_channels) { + dev_dbg(dev, "bad channel %d\n", arr[i + 2]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 3] < 0 || + arr[i + 3] >= max_pru_host_ints) { + dev_dbg(dev, "bad irq %d\n", arr[i + 3]); + ret = -EINVAL; + goto err; + } + + intc_config->sysev_to_ch[arr[i + 1]] = arr[i + 2]; + dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", arr[i + 1], + arr[i + 2]); + + intc_config->ch_to_host[arr[i + 2]] = arr[i + 3]; + dev_dbg(dev, "chnl-to-host[%d] -> %d\n", arr[i + 2], + arr[i + 3]); + + dt_irqs++; + } + + kfree(arr); + return dt_irqs; + +err: + kfree(arr); + return ret; +} + /** * pru_rproc_get() - get the PRU rproc instance from a device node * @np: the user/client device node @@ -251,6 +336,15 @@ struct rproc *pru_rproc_get(struct device_node *np, int index)
[PATCH 16/16] remoteproc/pru: Add support for INTC Interrupt map resource
Use the vendor specific resource mechanism to get the INTC mapping details from firmware. pru-software-support-package [1] has been historically using version 0 for this. However, the data structure is not scaleable and is not self sufficient. 1) it hard codes number of channel to host mappings so is not scaleable to newer SoCs than have more of these. 2) it does not contain the event to channel mappings within itself but relies on a pointer to point to another section in data memory. This causes a weird complication that the respective data section must be loaded before we can really use the INTC map. With this patch we drop support for version 0 and support version 1 which is a more robust and scalable data structure. It should be able to support a sufficiently large number (255) of sysevents, channels and host interrupts and is self contained so it can be used without dependency on order of loading sections. [1] git://git.ti.com/pru-software-support-package/pru-software-support-package.git Signed-off-by: Roger Quadros --- drivers/remoteproc/pru_rproc.c | 110 +++-- drivers/remoteproc/pru_rproc.h | 48 +++--- 2 files changed, 126 insertions(+), 32 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 540cce3..9e22c70 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -75,6 +75,7 @@ enum pru_mem { * @fw_name: name of firmware image used during loading * @gpmux_save: saved value for gpmux config * @dt_irqs: number of irqs configured from DT + * @fw_irqs: number of irqs configured from FW * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode @@ -101,6 +102,7 @@ struct pru_rproc { const char *fw_name; u8 gpmux_save; int dt_irqs; + int fw_irqs; struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; @@ -651,6 +653,107 @@ static void pru_rproc_kick(struct rproc *rproc, int vq_id) } } +/* + * parse the custom interrupt map resource and save the intc_config + * for use when booting the processor. + */ +static int pru_handle_vendor_intrmap(struct rproc *rproc, +struct fw_rsc_pruss_intrmap *rsc) +{ + int fw_irqs = 0, i, ret = 0; + u8 *arr; + struct device *dev = >dev; + struct pru_rproc *pru = rproc->priv; + + dev_dbg(dev, "vendor rsc intc: version %d\n", rsc->version); + + /* +* 0 was prototyping version. Not supported. +* 1 is currently supported version. +*/ + if (rsc->version == 0 || rsc->version > 1) { + dev_err(dev, "Unsupported version %d\n", rsc->version); + return -EINVAL; + } + + /* DT provided INTC config takes precedence */ + if (pru->dt_irqs) { + dev_info(dev, "INTC config in DT and FW. Using DT config.\n"); + return 0; + } + + arr = rsc->data; + + for (i = 0; i < ARRAY_SIZE(pru->intc_config.sysev_to_ch); i++) + pru->intc_config.sysev_to_ch[i] = -1; + + for (i = 0; i < ARRAY_SIZE(pru->intc_config.ch_to_host); i++) + pru->intc_config.ch_to_host[i] = -1; + + for (i = 0; i < rsc->num_maps * 3; i += 3) { + if (arr[i] < 0 || + arr[i] >= MAX_PRU_SYS_EVENTS) { + dev_err(dev, "bad sys event %d\n", arr[i]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 1] < 0 || + arr[i + 1] >= MAX_PRU_CHANNELS) { + dev_err(dev, "bad channel %d\n", arr[i + 1]); + ret = -EINVAL; + goto err; + } + + if (arr[i + 2] < 0 || + arr[i + 2] >= MAX_PRU_CHANNELS) { + dev_err(dev, "bad host irq %d\n", arr[i + 2]); + ret = -EINVAL; + goto err; + } + + pru->intc_config.sysev_to_ch[arr[i]] = arr[i + 1]; + dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", arr[i], + arr[i + 1]); + + pru->intc_config.ch_to_host[arr[i + 1]] = arr[i + 2]; + dev_dbg(dev, "chnl-to-host[%d] -> %d\n", arr[i + 1], + arr[i + 2]); + + fw_irqs++; + } + + pru->fw_irqs = fw_irqs; + return 0; + +err: + pru->fw_irqs = 0; + return ret; +} + +/* PRU-specific vendor resource handler */ +static int pru_rproc_handle_vendor_rsc(struct rproc *rproc, + struct fw_rsc_vendor *ven_rsc) +{ + struct device *dev = rproc->dev.parent; + int ret = -EINVAL; + + struct
[PATCH 12/16] dt-bindings: remoteproc: ti-pruss: Document application node bindings
From: Tero Kristo Add documentation for the Texas Instruments PRU application nodes. These are used to configure specific user applications for PRU instances. Signed-off-by: Tero Kristo [s-a...@ti.com: some binding updates] Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- .../devicetree/bindings/soc/ti/ti,pruss.txt| 43 ++ 1 file changed, 43 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt index 3e5f32f..94c91ee 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt @@ -210,6 +210,38 @@ used in TI Davinci SoCs. Please refer to the corresponding binding document, Documentation/devicetree/bindings/net/davinci-mdio.txt for details. +Application/User Nodes +=== +A PRU application/user node typically uses one or more PRU device nodes to +implement a PRU application/functionality. Each application/client node would +need a reference to at least a PRU node, and optionally pass some configuration +parameters. + +Required Properties: + +- prus : phandles to the PRU nodes used + +Optional Properties: + +- firmware-name: firmwares for the PRU cores, the default firmware + for the core from the PRU node will be used if not + provided. The firmware names should correspond to + the PRU cores listed in the 'prus' property +- ti,pruss-gp-mux-sel : array of values for the GP_MUX_SEL under PRUSS_GPCFG + register for a PRU. This selects the internal muxing + scheme for the PRU instance. If not provided, the + default out-of-reset value (0) for the PRU core is + used. Values should correspond to the PRU cores listed + in the 'prus' property +- ti,pru-interrupt-map : PRU interrupt mappings, containing an array of entries + with each entry consisting of 4 cell-values. First one + is an index towards the "prus" property to identify the + PRU core for the interrupt map, second is the PRU + System Event id, third is the PRU interrupt channel id + and fourth is the PRU host interrupt id. If provided, + this map will supercede any other configuration + provided through firmware + Example: 1. /* AM33xx PRU-ICSS */ @@ -397,3 +429,14 @@ Example: ... }; }; + +3: /* PRU application node example */ + app_node: app_node { + prus = <_0>, <_1>; + firmware-name = "pruss-app-fw", "pruss-app-fw-2"; + ti,pruss-gp-mux-sel = <2>, <1>; + /* setup interrupts for prus: + prus[0] => pru1_0: ev=16, chnl=2, host-irq=7, + prus[1] => pru1_1: ev=19, chnl=1, host-irq=3 */ + ti,pru-interrupt-map = <0 16 2 7 >, <1 19 1 3>; + } -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 09/16] remoteproc/pru: add APIs to get and put the PRU cores
From: Tero Kristo Add two new APIs, pru_rproc_get() and pru_rproc_put(), to the PRU driver to allow client drivers to acquire and release the remoteproc device associated with a PRU core. The PRU cores are treated as resources with only one client owning it at a time. The pru_rproc_get() function returns the rproc handle corresponding to a PRU core identified by the device tree "prus" property under the client node. The pru_rproc_put() is the complementary function to pru_rproc_get(). Signed-off-by: Tero Kristo [s-a...@ti.com: improve error checking, various fixes and cleanups] Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 112 + include/linux/pruss.h | 9 2 files changed, 121 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index fa3559b..2aa05b0 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -57,6 +57,7 @@ enum pru_mem { * @id: id of the PRU core within the PRUSS * @pruss: back-reference to parent PRUSS structure * @rproc: remoteproc pointer for this PRU core + * @client_np: client device node * @mbox: mailbox channel handle used for vring signalling with MPU * @client: mailbox client to request the mailbox channel * @irq_ring: IRQ number to use for processing vring buffers @@ -71,6 +72,7 @@ enum pru_mem { * @sdram_da: device address of secondary Data RAM for this PRU * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading + * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode */ @@ -78,6 +80,7 @@ struct pru_rproc { int id; struct pruss *pruss; struct rproc *rproc; + struct device_node *client_np; struct mbox_chan *mbox; struct mbox_client client; int irq_vring; @@ -92,6 +95,7 @@ struct pru_rproc { u32 sdram_da; u32 shrdram_da; const char *fw_name; + struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; }; @@ -126,6 +130,113 @@ void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, spin_unlock_irqrestore(>rmw_lock, flags); } +static struct rproc *__pru_rproc_get(struct device_node *np, int index) +{ + struct device_node *rproc_np = NULL; + struct platform_device *pdev; + struct rproc *rproc; + + rproc_np = of_parse_phandle(np, "prus", index); + if (!rproc_np || !of_device_is_available(rproc_np)) + return ERR_PTR(-ENODEV); + + pdev = of_find_device_by_node(rproc_np); + of_node_put(rproc_np); + + if (!pdev) + /* probably PRU not yet probed */ + return ERR_PTR(-EPROBE_DEFER); + + /* TODO: replace the crude string based check to make sure it is PRU */ + if (!strstr(dev_name(>dev), "pru")) { + put_device(>dev); + return ERR_PTR(-ENODEV); + } + + rproc = platform_get_drvdata(pdev); + put_device(>dev); + if (!rproc) + return ERR_PTR(-EPROBE_DEFER); + + get_device(>dev); + + return rproc; +} + +/** + * pru_rproc_get() - get the PRU rproc instance from a device node + * @np: the user/client device node + * @index: index to use for the prus property + * + * This function looks through a client device node's "prus" property at index + * @index and returns the rproc handle for a valid PRU remote processor if + * found. The function allows only one user to own the PRU rproc resource at + * a time. Caller must call pru_rproc_put() when done with using the rproc, + * not required if the function returns a failure. + * + * Returns the rproc handle on success, and an ERR_PTR on failure using one + * of the following error values + *-ENODEV if device is not found + *-EBUSY if PRU is already acquired by anyone + *-EPROBE_DEFER is PRU device is not probed yet + */ +struct rproc *pru_rproc_get(struct device_node *np, int index) +{ + struct rproc *rproc; + struct pru_rproc *pru; + + rproc = __pru_rproc_get(np, index); + if (IS_ERR(rproc)) + return rproc; + + pru = rproc->priv; + + mutex_lock(>lock); + + if (pru->client_np) { + mutex_unlock(>lock); + put_device(>dev); + return ERR_PTR(-EBUSY); + } + + pru->client_np = np; + + mutex_unlock(>lock); + + return rproc; +} +EXPORT_SYMBOL_GPL(pru_rproc_get); + +/** + * pru_rproc_put() - release the PRU rproc resource + * @rproc: the rproc resource to release + * + * Releases the PRU rproc resource and makes it available to other + * users. + */ +void pru_rproc_put(struct rproc *rproc) +{ + struct pru_rproc *pru; + + if (IS_ERR_OR_NULL(rproc)) +
[PATCH 03/16] remoteproc: Add support to handle device specific resource types
From: Suman Anna The remoteproc framework handles a fixed set of resource table entries today. To make it scalable across multiple platforms, it makes sense for the framework to provide a way for the device specific implementation to define and handle vendor specific resource types. These resource types would be very specific to an implementation instance that it does not make sense for the framework to handle it. There can be two types of such resources depending on whether they need to be handled prior to the loading of the firmware segments or after. A post-loading resource type is typically needed because it references a loaded segment pointer for conveying the resource information. For instance, a remoteproc implementation might want timers information embedded in the resource table so that the driver could parse the binary and enable accordingly. Another example would be hwspinlocks that it is using, to properly share system wide resources. A PRU post-loading vendor resource handler for interrupts requires the PRU event - interrupt channel information to be loaded into device memory. This patch adds a function pointer to the list of rproc_ops for the driver implementation to handle such custom vendor resources, and reuses the same handler between pre-loading and post-loading resource types, with the sub-types in the implementation handling the processing of those resource types. Signed-off-by: Suman Anna merge: remoteproc: simplify VENDOR specific resource We don't need PRE and POST loading as we'll fix the PRU resource table to be self sufficient. Earlier it was half baked with channel mapping located elsewhere in data section thus requiring data section to be loaded before we can figure out the full INTC map. Fix vendor resource to be TLV and definition agnostic. Show in debugfs. Signed-off-by: Roger Quadros --- drivers/remoteproc/remoteproc_core.c| 36 + drivers/remoteproc/remoteproc_debugfs.c | 3 +++ include/linux/remoteproc.h | 15 +- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 581e6e8..9e387ab 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -898,6 +898,41 @@ void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem) EXPORT_SYMBOL(rproc_add_carveout); /** + * rproc_handle_vendor_rsc() - provide implementation specific hook + *to handle vendor/custom resources + * @rproc: the remote processor + * @rsc: vendor resource to be handled by remoteproc drivers + * @offset: offset of the resource data in resource table + * @avail: size of available data + * + * Remoteproc implementations might want to add resource table entries + * that are not generic enough to be handled by the framework. This + * provides a hook to handle such custom resources. + * + * Returns 0 on success, or an appropriate error code otherwise + */ +static int rproc_handle_vendor_rsc(struct rproc *rproc, + struct fw_rsc_vendor *rsc, + int offset, int avail) +{ + struct device *dev = >dev; + + if (sizeof(*rsc) > avail) { + dev_err(dev, "vendor rsc is truncated\n"); + return -EINVAL; + } + + dev_dbg(dev, "vendor rsc:"); + + if (!rproc->ops->handle_vendor_rsc) { + dev_err(dev, "no vendor rsc handler! ignoring resource\n"); + return 0; + } + + return rproc->ops->handle_vendor_rsc(rproc, (void *)rsc); +} + +/** * rproc_mem_entry_init() - allocate and initialize rproc_mem_entry struct * @dev: pointer on device struct * @va: virtual address @@ -985,6 +1020,7 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = { [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout, [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem, [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace, + [RSC_VENDOR] = (rproc_handle_resource_t)rproc_handle_vendor_rsc, [RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev, }; diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index f330a9a..971c8ba 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c @@ -254,6 +254,9 @@ static int rproc_rsc_table_show(struct seq_file *seq, void *p) v->vring[j].pa); } break; + case RSC_VENDOR: + seq_printf(seq, "Entry %d is of type %s [Vendor specific]\n", + i, types[hdr->type]); default: seq_printf(seq, "Unknown resource type found: %d [hdr: %pK]\n",
[PATCH 11/16] soc: ti: pruss: add helper functions to set GPI mode, MII_RT_event and XFR
From: Suman Anna The PRUSS CFG module is represented as a syscon node and is currently managed by the PRUSS platform driver. Add easy accessor functions to set GPI mode, MII_RT event enable/disable and XFR (XIN XOUT) enable/disable to enable the PRUSS Ethernet usecase. These functions reuse the generic pruss_regmap_update() API function. Signed-off-by: Suman Anna --- include/linux/pruss.h | 115 ++ 1 file changed, 115 insertions(+) diff --git a/include/linux/pruss.h b/include/linux/pruss.h index c0a3b3e..7227aae 100644 --- a/include/linux/pruss.h +++ b/include/linux/pruss.h @@ -204,6 +204,69 @@ int pruss_intc_configure(struct pruss *pruss, int pruss_intc_unconfigure(struct pruss *pruss, struct pruss_intc_config *intc_config); +/** + * pruss_cfg_get_gpmux() - get the current GPMUX value for a PRU device + * @pruss: pruss instance + * @id: PRU identifier (0-1) + * @mux: pointer to store the current mux value into + */ +static inline int pruss_cfg_get_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 *mux) +{ + int ret = 0; + u32 val; + + ret = pruss_cfg_read(pruss, PRUSS_CFG_GPCFG(id), ); + if (!ret) + *mux = (u8)((val & PRUSS_GPCFG_PRU_MUX_SEL_MASK) >> + PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); + return ret; +} + +/** + * pruss_cfg_set_gpmux() - set the GPMUX value for a PRU device + * @pruss: pruss instance + * @pru_id: PRU identifier (0-1) + * @mux: new mux value for PRU + */ +static inline int pruss_cfg_set_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 mux) +{ + if (mux >= PRUSS_GP_MUX_SEL_MAX) + return -EINVAL; + + return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(id), + PRUSS_GPCFG_PRU_MUX_SEL_MASK, + (u32)mux << PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); +} + +/** + * pruss_cfg_miirt_enable() - Enable/disable MII RT Events + * @pruss: the pruss instance + * @enable: enable/disable + * + * Enable/disable the MII RT Events for the PRUSS. + */ +static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) +{ + u32 set = enable ? PRUSS_MII_RT_EVENT_EN : 0; + + return pruss_cfg_update(pruss, PRUSS_CFG_MII_RT, + PRUSS_MII_RT_EVENT_EN, set); +} + +/** + * pruss_cfg_xfr_enable() - Enable/disable XIN XOUT shift functionality + * @pruss: the pruss instance + * @enable: enable/disable + */ +static inline int pruss_cfg_xfr_enable(struct pruss *pruss, bool enable) +{ + u32 set = enable ? PRUSS_SPP_XFER_SHIFT_EN : 0; + + return pruss_cfg_update(pruss, PRUSS_CFG_SPP, + PRUSS_SPP_XFER_SHIFT_EN, set); +} #else static inline struct pruss *pruss_get(struct rproc *rproc) @@ -254,6 +317,28 @@ int pruss_intc_unconfigure(struct pruss *pruss, return -ENOTSUPP; } +static inline int pruss_cfg_get_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 *mux) +{ + return -ENOTSUPP; +} + +static inline int pruss_cfg_set_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 mux) +{ + return -ENOTSUPP; +} + +static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) +{ + return -ENOTSUPP; +} + +static inline int pruss_cfg_xfr_enable(struct pruss *pruss, bool enable) +{ + return -ENOTSUPP; +} + #endif /* CONFIG_TI_PRUSS */ #if IS_ENABLED(CONFIG_PRUSS_REMOTEPROC) @@ -263,6 +348,30 @@ void pru_rproc_put(struct rproc *rproc); enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc); int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr); +/** + * pruss_cfg_gpimode() - set the GPI mode of the PRU + * @pruss: the pruss instance handle + * @pru: the rproc instance handle of the PRU + * @mode: GPI mode to set + * + * Sets the GPI mode for a given PRU by programming the + * corresponding PRUSS_CFG_GPCFGx register + * + * Returns 0 on success, or an error code otherwise + */ +static inline int pruss_cfg_gpimode(struct pruss *pruss, struct rproc *pru, + enum pruss_gpi_mode mode) +{ + enum pruss_pru_id id = pru_rproc_get_id(pru); + + if (id < 0) + return -EINVAL; + + return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(id), + PRUSS_GPCFG_PRU_GPI_MODE_MASK, + mode << PRUSS_GPCFG_PRU_GPI_MODE_SHIFT); +} + #else static inline struct rproc *pru_rproc_get(struct device_node *node, int index) @@ -283,6 +392,12 @@ static inline int pru_rproc_set_ctable(struct rproc *rproc, return -ENOTSUPP; } +static inline int pruss_cfg_gpimode(struct pruss *pruss, struct rproc *pru, + enum pruss_gpi_mode mode) +{ + return -ENOTSUPP; +} + #endif /*
[PATCH 07/16] remoteproc/pru: Add support for virtio rpmsg stack
From: Suman Anna The PRU remoteproc driver has been enhanced to support the optional rpmsg stack using the virtio-ring based communication transport between MPU and a PRU core. This provides support to any firmware images supporting the virtio devices. The virtio-ring signalling support is provided either through a OMAP mailbox or through two PRU system events on OMAP-architecture based SoCs - one event used in each direction for kicking from one processor and receiving notification on the other processor. The virtio rpmsg signalling is enabled only using using PRU system events for interrupts on the Keystone-architecture based 66AK2G SoCs (it is possible to implement using an alternate Keystone specific IPCGR registers as well). The driver supports both signalling options, though the PRU events based signalling is the recommended option as it avoids an external peripheral access from the PRU side. It also provides a uniform solution across both the OMAP, Keystone and Davinci architectures. The PRU events based signalling takes precedence if both options are mentioned. Either of the options would require the corresponding firmware support though. A build dependency against MAILBOX is also added. Note that the OMAP Mailbox IP is not present on 66AK2G and Davinci SoCs, so it is only selected for OMAP-based SoCs. Signed-off-by: Suman Anna --- drivers/remoteproc/Kconfig | 2 + drivers/remoteproc/pru_rproc.c | 169 - 2 files changed, 168 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 333666e..b89acb0 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -200,6 +200,8 @@ config ST_SLIM_REMOTEPROC config PRUSS_REMOTEPROC tristate "TI PRUSS remoteproc support" depends on TI_PRUSS + select MAILBOX + select OMAP2PLUS_MBOX if ARCH_OMAP2PLUS default n help Support for TI PRU-ICSS remote processors via the remote processor diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 73a7f13..e0554b3 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,10 @@ enum pru_mem { * @id: id of the PRU core within the PRUSS * @pruss: back-reference to parent PRUSS structure * @rproc: remoteproc pointer for this PRU core + * @mbox: mailbox channel handle used for vring signalling with MPU + * @client: mailbox client to request the mailbox channel + * @irq_ring: IRQ number to use for processing vring buffers + * @irq_kick: IRQ number to use to perform virtio kick * @mem_regions: data for each of the PRU memory regions * @dram0: PRUSS DRAM0 region * @dram1: PRUSS DRAM1 region @@ -72,6 +77,10 @@ struct pru_rproc { int id; struct pruss *pruss; struct rproc *rproc; + struct mbox_chan *mbox; + struct mbox_client client; + int irq_vring; + int irq_kick; struct pruss_mem_region mem_regions[PRU_MEM_MAX]; struct pruss_mem_region dram0; struct pruss_mem_region dram1; @@ -233,22 +242,124 @@ static void pru_rproc_create_debug_entries(struct rproc *rproc) rproc, _rproc_debug_ss_fops); } +/** + * pru_rproc_mbox_callback() - inbound mailbox message handler + * @client: mailbox client pointer used for requesting the mailbox channel + * @data: mailbox payload + * + * This handler is invoked by omap's mailbox driver whenever a mailbox + * message is received. Usually, the mailbox payload simply contains + * the index of the virtqueue that is kicked by the PRU remote processor, + * and we let remoteproc core handle it. + * + * In addition to virtqueue indices, we might also have some out-of-band + * values that indicates different events. Those values are deliberately + * very big so they don't coincide with virtqueue indices. + */ +static void pru_rproc_mbox_callback(struct mbox_client *client, void *data) +{ + struct pru_rproc *pru = container_of(client, struct pru_rproc, client); + struct device *dev = >rproc->dev; + u32 msg = (u32)data; + + dev_dbg(dev, "mbox msg: 0x%x\n", msg); + + /* msg contains the index of the triggered vring */ + if (rproc_vq_interrupt(pru->rproc, msg) == IRQ_NONE) + dev_dbg(dev, "no message was found in vqid %d\n", msg); +} + +/** + * pru_rproc_vring_interrupt() - interrupt handler for processing vrings + * @irq: irq number associated with the PRU event MPU is listening on + * @data: interrupt handler data, will be a PRU rproc structure + * + * This handler is used by the PRU remoteproc driver when using PRU system + * events for processing the virtqueues. Unlike the mailbox IP, there is + * no payload associated with an interrupt, so either a unique event is + * used for each virtqueue kick, or a both virtqueues are
[PATCH 14/16] remoteproc/pru: configure firmware based on client setup
From: Tero Kristo Client device node property firmware-name is now used to configure firmware for the PRU instances. The default firmware is also restored once releasing the PRU resource. Signed-off-by: Tero Kristo Reviewed-by: Roger Quadros Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 9a08937..84f006b 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -132,6 +132,21 @@ void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, spin_unlock_irqrestore(>rmw_lock, flags); } +/** + * pru_rproc_set_firmware() - set firmware for a pru core + * @rproc: the rproc instance of the PRU + * @fw_name: the new firmware name, or NULL if default is desired + */ +static int pru_rproc_set_firmware(struct rproc *rproc, const char *fw_name) +{ + struct pru_rproc *pru = rproc->priv; + + if (!fw_name) + fw_name = pru->fw_name; + + return rproc_set_firmware(rproc, fw_name); +} + static struct rproc *__pru_rproc_get(struct device_node *np, int index) { struct device_node *rproc_np = NULL; @@ -189,6 +204,7 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) struct device *dev; int ret; u32 mux; + const char *fw_name; rproc = __pru_rproc_get(np, index); if (IS_ERR(rproc)) @@ -225,6 +241,16 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) } } + ret = of_property_read_string_index(np, "firmware-name", index, + _name); + if (!ret) { + ret = pru_rproc_set_firmware(rproc, fw_name); + if (ret) { + dev_err(dev, "failed to set firmware: %d\n", ret); + goto err; + } + } + return rproc; err: @@ -255,6 +281,7 @@ void pru_rproc_put(struct rproc *rproc) if (!pru->client_np) return; + pru_rproc_set_firmware(rproc, NULL); pruss_cfg_set_gpmux(pru->pruss, pru->id, pru->gpmux_save); mutex_lock(>lock); -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 13/16] remoteproc/pru: add support for configuring GPMUX based on client setup
From: Tero Kristo Client device node property ti,pruss-gp-mux-sel can now be used to configure the GPMUX config value for PRU. Signed-off-by: Tero Kristo [s-a...@ti.com: simplify the pru id usage] Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 28 1 file changed, 28 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index d8b823d..9a08937 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -72,6 +72,7 @@ enum pru_mem { * @sdram_da: device address of secondary Data RAM for this PRU * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading + * @gpmux_save: saved value for gpmux config * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode @@ -95,6 +96,7 @@ struct pru_rproc { u32 sdram_da; u32 shrdram_da; const char *fw_name; + u8 gpmux_save; struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; @@ -184,12 +186,16 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) { struct rproc *rproc; struct pru_rproc *pru; + struct device *dev; + int ret; + u32 mux; rproc = __pru_rproc_get(np, index); if (IS_ERR(rproc)) return rproc; pru = rproc->priv; + dev = >dev; mutex_lock(>lock); @@ -203,7 +209,27 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) mutex_unlock(>lock); + ret = pruss_cfg_get_gpmux(pru->pruss, pru->id, >gpmux_save); + if (ret) { + dev_err(dev, "failed to get cfg gpmux: %d\n", ret); + goto err; + } + + ret = of_property_read_u32_index(np, "ti,pruss-gp-mux-sel", index, +); + if (!ret) { + ret = pruss_cfg_set_gpmux(pru->pruss, pru->id, mux); + if (ret) { + dev_err(dev, "failed to set cfg gpmux: %d\n", ret); + goto err; + } + } + return rproc; + +err: + pru_rproc_put(rproc); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(pru_rproc_get); @@ -229,6 +255,8 @@ void pru_rproc_put(struct rproc *rproc) if (!pru->client_np) return; + pruss_cfg_set_gpmux(pru->pruss, pru->id, pru->gpmux_save); + mutex_lock(>lock); pru->client_np = NULL; mutex_unlock(>lock); -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 06/16] dt-bindings: remoteproc: ti-pruss: Update bindings for supporting rpmsg
From: Suman Anna Update the PRUSS DT bindings to add the properties required to support the optional virtio rpmsg stack using the virtio-ring based communication transport between MPU and a PRU core. Signed-off-by: Suman Anna --- .../devicetree/bindings/soc/ti/ti,pruss.txt| 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt index 24fedad..3e5f32f 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt @@ -175,6 +175,32 @@ Required Properties: - firmware-name : should contain the name of the default firmware image file located on the firmware search path +Optional Properties: + +The virtio based communication between the MPU and a PRU core _requires_ +either the 'mboxes' property, or the set of 'interrupt-parent', 'interrupts' +and 'interrupt-names' properties to be defined. The latter option is the +preferred choice. The 'mboxes' property is not applicable for 66AK2G and +DA850/OMAP-L138 SoCs. + +- mboxes : OMAP Mailbox specifier denoting the sub-mailbox, if using + a mailbox for IPC signalling between host and a PRU core. + The specifier format is as per the bindings, + Documentation/devicetree/bindings/mailbox/omap-mailbox.txt + This property should match with the sub-mailbox node used + in the corresponding firmware image. +- interrupt-parent : phandle to the PRUSS INTC node. Should be defined if + interrupts property is to be used. +- interrupts : array of interrupt specifiers if using PRU system events + for IPC signalling between host and a PRU core. This + property should match with the PRU system event used in + the corresponding firmware image. +- interrupt-names : should use one of the following names for each interrupt, + the name should match the corresponding PRU system event + number, + "vring" - for PRU to HOST virtqueue signalling + "kick" - for HOST to PRU virtqueue signalling + MDIO Child Node @@ -243,6 +269,9 @@ Example: <0x4a322400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am335x-pru0-fw"; + interrupt-parent = <_intc>; + interrupts = <16>, <17>; + interrupt-names = "vring", "kick"; }; pru1: pru@4a338000 { @@ -252,6 +281,10 @@ Example: <0x4a324400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am335x-pru1-fw"; + interrupt-parent = <_intc>; + interrupts = <18>, <19>; + interrupt-names = "vring", "kick"; + /* mboxes = < _pru1>; */ }; pruss_mdio: mdio@4a332400 { @@ -329,6 +362,9 @@ Example: <0x54422400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am437x-pru1_0-fw"; + interrupt-parent = <_intc>; + interrupts = <16>, <17>; + interrupt-names = "vring", "kick"; }; pru1_1: pru@54438000 { @@ -338,6 +374,9 @@ Example: <0x54424400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am437x-pru1_1-fw"; + interrupt-parent = <_intc>; + interrupts = <18>, <19>; + interrupt-names = "vring", "kick"; }; pruss1_mdio: mdio@54432400 { -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 08/16] remoteproc/pru: Add pru_rproc_set_ctable() function
Some firmwares expect the OS drivers to configure the CTABLE entries publishing dynamically allocated memory regions. For example, the PRU Ethernet firmwares use the C28 and C30 entries for retrieving the Shared RAM and System SRAM (OCMC) areas allocated by the PRU Ethernet client driver. Provide a way for users to do that through a new API, pru_rproc_set_ctable(). The API returns 0 on success and a negative value on error. NOTE: The programmable CTABLE entries are typically re-programmed by the PRU firmwares when dealing with a certain block of memory during block processing. This API provides an interface to the PRU client drivers to publish a dynamically allocated memory block with the PRU firmware using a CTABLE entry instead of a negotiated address in shared memory. Additional synchronization may be needed between the PRU client drivers and firmwares if different addresses needs to be published at run-time reusing the same CTABLE entry. Signed-off-by: Roger Quadros Signed-off-by: Andrew F. Davis [s-a...@ti.com: add the NOTE: on patch description, minor cleanups] Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 51 ++ include/linux/pruss.h | 29 2 files changed, 80 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index e0554b3..fa3559b 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -65,6 +65,7 @@ enum pru_mem { * @dram0: PRUSS DRAM0 region * @dram1: PRUSS DRAM1 region * @shrdram: PRUSS SHARED RAM region + * @rmw_lock: lock for read, modify, write operations on registers * @iram_da: device address of Instruction RAM for this PRU * @pdram_da: device address of primary Data RAM for this PRU * @sdram_da: device address of secondary Data RAM for this PRU @@ -85,6 +86,7 @@ struct pru_rproc { struct pruss_mem_region dram0; struct pruss_mem_region dram1; struct pruss_mem_region shrdram; + spinlock_t rmw_lock; /* register access lock */ u32 iram_da; u32 pdram_da; u32 sdram_da; @@ -107,6 +109,54 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) writel_relaxed(val, pru->mem_regions[PRU_MEM_CTRL].va + reg); } +static inline +void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, +u32 mask, u32 set) +{ + u32 val; + unsigned long flags; + + spin_lock_irqsave(>rmw_lock, flags); + + val = pru_control_read_reg(pru, reg); + val &= ~mask; + val |= (set & mask); + pru_control_write_reg(pru, reg, val); + + spin_unlock_irqrestore(>rmw_lock, flags); +} + +/** + * pru_rproc_set_ctable() - set the constant table index for the PRU + * @rproc: the rproc instance of the PRU + * @c: constant table index to set + * @addr: physical address to set it to + */ +int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr) +{ + struct pru_rproc *pru = rproc->priv; + unsigned int reg; + u32 mask, set; + u16 idx; + u16 idx_mask; + + /* pointer is 16 bit and index is 8-bit so mask out the rest */ + idx_mask = (c >= PRU_C28) ? 0x : 0xFF; + + /* ctable uses bit 8 and upwards only */ + idx = (addr >> 8) & idx_mask; + + /* configurable ctable (i.e. C24) starts at PRU_CTRL_CTBIR0 */ + reg = PRU_CTRL_CTBIR0 + 4 * (c >> 1); + mask = idx_mask << (16 * (c & 1)); + set = idx << (16 * (c & 1)); + + pru_control_set_reg(pru, reg, mask, set); + + return 0; +} +EXPORT_SYMBOL_GPL(pru_rproc_set_ctable); + static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg) { return readl_relaxed(pru->mem_regions[PRU_MEM_DEBUG].va + reg); @@ -537,6 +587,7 @@ static int pru_rproc_probe(struct platform_device *pdev) pru->pruss = platform_get_drvdata(ppdev); pru->rproc = rproc; pru->fw_name = fw_name; + spin_lock_init(>rmw_lock); ret = pruss_request_mem_region(pru->pruss, PRUSS_MEM_DRAM0, >dram0); diff --git a/include/linux/pruss.h b/include/linux/pruss.h index c797fb1..af04a1c 100644 --- a/include/linux/pruss.h +++ b/include/linux/pruss.h @@ -134,7 +134,22 @@ struct pruss_intc_config { s8 ch_to_host[MAX_PRU_CHANNELS]; }; +/** + * enum pru_ctable_idx - Configurable Constant table index identifiers + */ +enum pru_ctable_idx { + PRU_C24 = 0, + PRU_C25, + PRU_C26, + PRU_C27, + PRU_C28, + PRU_C29, + PRU_C30, + PRU_C31, +}; + struct pruss; +struct rproc; #if IS_ENABLED(CONFIG_TI_PRUSS) @@ -232,4 +247,18 @@ int pruss_intc_unconfigure(struct pruss *pruss, #endif /* CONFIG_TI_PRUSS */ +#if IS_ENABLED(CONFIG_PRUSS_REMOTEPROC) + +int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr); + +#else + +static inline
[PATCH 05/16] remoteproc/pru: Add pru-specific debugfs support
From: Suman Anna The remoteproc core creates certain standard debugfs entries, that does not give a whole lot of useful information for the PRUs. The PRU remoteproc driver is enhanced to add additional debugfs entries for PRU. These will be auto-cleaned up when the parent rproc debug directory is removed. The enhanced debugfs support adds two new entries: 'regs' and 'single_step'. The 'regs' dumps out the useful CTRL sub-module registers as well as each of the 32 GPREGs and CT_REGs registers. The GPREGs and CT_REGs though are printed only when the PRU is halted and accessible as per the IP design. The 'single_step' utilizes the single-step execution of the PRU cores. Writing a non-zero value performs a single step, and a zero value restores the PRU to execute in the same mode as the mode before the first single step. (note: if the PRU is halted because of a halt instruction, then no change occurs). Logic for setting the PC and jumping over a halt instruction shall be added in the future. Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 135 + 1 file changed, 135 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index c35f432..73a7f13 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -36,6 +37,10 @@ #define CTRL_CTRL_SINGLE_STEP BIT(8) #define CTRL_CTRL_RUNSTATE BIT(15) +/* PRU_ICSS_PRU_DEBUG registers */ +#define PRU_DEBUG_GPREG(x) (0x + (x) * 4) +#define PRU_DEBUG_CT_REG(x)(0x0080 + (x) * 4) + /** * enum pru_mem - PRU core memory range identifiers */ @@ -60,6 +65,8 @@ enum pru_mem { * @sdram_da: device address of secondary Data RAM for this PRU * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading + * @dbg_single_step: debug state variable to set PRU into single step mode + * @dbg_continuous: debug state variable to restore PRU execution mode */ struct pru_rproc { int id; @@ -74,6 +81,8 @@ struct pru_rproc { u32 sdram_da; u32 shrdram_da; const char *fw_name; + u32 dbg_single_step; + u32 dbg_continuous; }; static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, int len); @@ -100,6 +109,130 @@ void pru_debug_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) writel_relaxed(val, pru->mem_regions[PRU_MEM_DEBUG].va + reg); } +static int pru_rproc_debug_read_regs(struct seq_file *s, void *data) +{ + struct rproc *rproc = s->private; + struct pru_rproc *pru = rproc->priv; + int i, nregs = 32; + u32 pru_sts; + int pru_is_running; + + seq_puts(s, "== Control Registers ==\n"); + seq_printf(s, "CTRL := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTRL)); + pru_sts = pru_control_read_reg(pru, PRU_CTRL_STS); + seq_printf(s, "STS (PC) := 0x%08x (0x%08x)\n", pru_sts, pru_sts << 2); + seq_printf(s, "WAKEUP_EN := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_WAKEUP_EN)); + seq_printf(s, "CYCLE := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CYCLE)); + seq_printf(s, "STALL := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_STALL)); + seq_printf(s, "CTBIR0:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTBIR0)); + seq_printf(s, "CTBIR1:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTBIR1)); + seq_printf(s, "CTPPR0:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTPPR0)); + seq_printf(s, "CTPPR1:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTPPR1)); + + seq_puts(s, "=== Debug Registers ===\n"); + pru_is_running = pru_control_read_reg(pru, PRU_CTRL_CTRL) & + CTRL_CTRL_RUNSTATE; + if (pru_is_running) { + seq_puts(s, "PRU is executing, cannot print/access debug registers.\n"); + return 0; + } + + for (i = 0; i < nregs; i++) { + seq_printf(s, "GPREG%-2d := 0x%08x\tCT_REG%-2d := 0x%08x\n", + i, pru_debug_read_reg(pru, PRU_DEBUG_GPREG(i)), + i, pru_debug_read_reg(pru, PRU_DEBUG_CT_REG(i))); + } + + return 0; +} + +static int pru_rproc_debug_regs_open(struct inode *inode, struct file *file) +{ + return single_open(file, pru_rproc_debug_read_regs, inode->i_private); +} + +static const struct file_operations pru_rproc_debug_regs_ops = { + .open = pru_rproc_debug_regs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * Control PRU single-step mode + * + * This is a debug helper function used for controlling the
[PATCH 03/16] remoteproc: Add support to handle device specific resource types
From: Suman Anna The remoteproc framework handles a fixed set of resource table entries today. To make it scalable across multiple platforms, it makes sense for the framework to provide a way for the device specific implementation to define and handle vendor specific resource types. These resource types would be very specific to an implementation instance that it does not make sense for the framework to handle it. There can be two types of such resources depending on whether they need to be handled prior to the loading of the firmware segments or after. A post-loading resource type is typically needed because it references a loaded segment pointer for conveying the resource information. For instance, a remoteproc implementation might want timers information embedded in the resource table so that the driver could parse the binary and enable accordingly. Another example would be hwspinlocks that it is using, to properly share system wide resources. A PRU post-loading vendor resource handler for interrupts requires the PRU event - interrupt channel information to be loaded into device memory. This patch adds a function pointer to the list of rproc_ops for the driver implementation to handle such custom vendor resources, and reuses the same handler between pre-loading and post-loading resource types, with the sub-types in the implementation handling the processing of those resource types. Signed-off-by: Suman Anna merge: remoteproc: simplify VENDOR specific resource We don't need PRE and POST loading as we'll fix the PRU resource table to be self sufficient. Earlier it was half baked with channel mapping located elsewhere in data section thus requiring data section to be loaded before we can figure out the full INTC map. Fix vendor resource to be TLV and definition agnostic. Show in debugfs. Signed-off-by: Roger Quadros --- drivers/remoteproc/remoteproc_core.c| 36 + drivers/remoteproc/remoteproc_debugfs.c | 3 +++ include/linux/remoteproc.h | 15 +- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 581e6e8..9e387ab 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -898,6 +898,41 @@ void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem) EXPORT_SYMBOL(rproc_add_carveout); /** + * rproc_handle_vendor_rsc() - provide implementation specific hook + *to handle vendor/custom resources + * @rproc: the remote processor + * @rsc: vendor resource to be handled by remoteproc drivers + * @offset: offset of the resource data in resource table + * @avail: size of available data + * + * Remoteproc implementations might want to add resource table entries + * that are not generic enough to be handled by the framework. This + * provides a hook to handle such custom resources. + * + * Returns 0 on success, or an appropriate error code otherwise + */ +static int rproc_handle_vendor_rsc(struct rproc *rproc, + struct fw_rsc_vendor *rsc, + int offset, int avail) +{ + struct device *dev = >dev; + + if (sizeof(*rsc) > avail) { + dev_err(dev, "vendor rsc is truncated\n"); + return -EINVAL; + } + + dev_dbg(dev, "vendor rsc:"); + + if (!rproc->ops->handle_vendor_rsc) { + dev_err(dev, "no vendor rsc handler! ignoring resource\n"); + return 0; + } + + return rproc->ops->handle_vendor_rsc(rproc, (void *)rsc); +} + +/** * rproc_mem_entry_init() - allocate and initialize rproc_mem_entry struct * @dev: pointer on device struct * @va: virtual address @@ -985,6 +1020,7 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = { [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout, [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem, [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace, + [RSC_VENDOR] = (rproc_handle_resource_t)rproc_handle_vendor_rsc, [RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev, }; diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index f330a9a..971c8ba 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c @@ -254,6 +254,9 @@ static int rproc_rsc_table_show(struct seq_file *seq, void *p) v->vring[j].pa); } break; + case RSC_VENDOR: + seq_printf(seq, "Entry %d is of type %s [Vendor specific]\n", + i, types[hdr->type]); default: seq_printf(seq, "Unknown resource type found: %d [hdr: %pK]\n",
[PATCH 11/16] soc: ti: pruss: add helper functions to set GPI mode, MII_RT_event and XFR
From: Suman Anna The PRUSS CFG module is represented as a syscon node and is currently managed by the PRUSS platform driver. Add easy accessor functions to set GPI mode, MII_RT event enable/disable and XFR (XIN XOUT) enable/disable to enable the PRUSS Ethernet usecase. These functions reuse the generic pruss_regmap_update() API function. Signed-off-by: Suman Anna --- include/linux/pruss.h | 115 ++ 1 file changed, 115 insertions(+) diff --git a/include/linux/pruss.h b/include/linux/pruss.h index c0a3b3e..7227aae 100644 --- a/include/linux/pruss.h +++ b/include/linux/pruss.h @@ -204,6 +204,69 @@ int pruss_intc_configure(struct pruss *pruss, int pruss_intc_unconfigure(struct pruss *pruss, struct pruss_intc_config *intc_config); +/** + * pruss_cfg_get_gpmux() - get the current GPMUX value for a PRU device + * @pruss: pruss instance + * @id: PRU identifier (0-1) + * @mux: pointer to store the current mux value into + */ +static inline int pruss_cfg_get_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 *mux) +{ + int ret = 0; + u32 val; + + ret = pruss_cfg_read(pruss, PRUSS_CFG_GPCFG(id), ); + if (!ret) + *mux = (u8)((val & PRUSS_GPCFG_PRU_MUX_SEL_MASK) >> + PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); + return ret; +} + +/** + * pruss_cfg_set_gpmux() - set the GPMUX value for a PRU device + * @pruss: pruss instance + * @pru_id: PRU identifier (0-1) + * @mux: new mux value for PRU + */ +static inline int pruss_cfg_set_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 mux) +{ + if (mux >= PRUSS_GP_MUX_SEL_MAX) + return -EINVAL; + + return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(id), + PRUSS_GPCFG_PRU_MUX_SEL_MASK, + (u32)mux << PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); +} + +/** + * pruss_cfg_miirt_enable() - Enable/disable MII RT Events + * @pruss: the pruss instance + * @enable: enable/disable + * + * Enable/disable the MII RT Events for the PRUSS. + */ +static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) +{ + u32 set = enable ? PRUSS_MII_RT_EVENT_EN : 0; + + return pruss_cfg_update(pruss, PRUSS_CFG_MII_RT, + PRUSS_MII_RT_EVENT_EN, set); +} + +/** + * pruss_cfg_xfr_enable() - Enable/disable XIN XOUT shift functionality + * @pruss: the pruss instance + * @enable: enable/disable + */ +static inline int pruss_cfg_xfr_enable(struct pruss *pruss, bool enable) +{ + u32 set = enable ? PRUSS_SPP_XFER_SHIFT_EN : 0; + + return pruss_cfg_update(pruss, PRUSS_CFG_SPP, + PRUSS_SPP_XFER_SHIFT_EN, set); +} #else static inline struct pruss *pruss_get(struct rproc *rproc) @@ -254,6 +317,28 @@ int pruss_intc_unconfigure(struct pruss *pruss, return -ENOTSUPP; } +static inline int pruss_cfg_get_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 *mux) +{ + return -ENOTSUPP; +} + +static inline int pruss_cfg_set_gpmux(struct pruss *pruss, + enum pruss_pru_id id, u8 mux) +{ + return -ENOTSUPP; +} + +static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) +{ + return -ENOTSUPP; +} + +static inline int pruss_cfg_xfr_enable(struct pruss *pruss, bool enable) +{ + return -ENOTSUPP; +} + #endif /* CONFIG_TI_PRUSS */ #if IS_ENABLED(CONFIG_PRUSS_REMOTEPROC) @@ -263,6 +348,30 @@ void pru_rproc_put(struct rproc *rproc); enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc); int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr); +/** + * pruss_cfg_gpimode() - set the GPI mode of the PRU + * @pruss: the pruss instance handle + * @pru: the rproc instance handle of the PRU + * @mode: GPI mode to set + * + * Sets the GPI mode for a given PRU by programming the + * corresponding PRUSS_CFG_GPCFGx register + * + * Returns 0 on success, or an error code otherwise + */ +static inline int pruss_cfg_gpimode(struct pruss *pruss, struct rproc *pru, + enum pruss_gpi_mode mode) +{ + enum pruss_pru_id id = pru_rproc_get_id(pru); + + if (id < 0) + return -EINVAL; + + return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(id), + PRUSS_GPCFG_PRU_GPI_MODE_MASK, + mode << PRUSS_GPCFG_PRU_GPI_MODE_SHIFT); +} + #else static inline struct rproc *pru_rproc_get(struct device_node *node, int index) @@ -283,6 +392,12 @@ static inline int pru_rproc_set_ctable(struct rproc *rproc, return -ENOTSUPP; } +static inline int pruss_cfg_gpimode(struct pruss *pruss, struct rproc *pru, + enum pruss_gpi_mode mode) +{ + return -ENOTSUPP; +} + #endif /*
[PATCH 07/16] remoteproc/pru: Add support for virtio rpmsg stack
From: Suman Anna The PRU remoteproc driver has been enhanced to support the optional rpmsg stack using the virtio-ring based communication transport between MPU and a PRU core. This provides support to any firmware images supporting the virtio devices. The virtio-ring signalling support is provided either through a OMAP mailbox or through two PRU system events on OMAP-architecture based SoCs - one event used in each direction for kicking from one processor and receiving notification on the other processor. The virtio rpmsg signalling is enabled only using using PRU system events for interrupts on the Keystone-architecture based 66AK2G SoCs (it is possible to implement using an alternate Keystone specific IPCGR registers as well). The driver supports both signalling options, though the PRU events based signalling is the recommended option as it avoids an external peripheral access from the PRU side. It also provides a uniform solution across both the OMAP, Keystone and Davinci architectures. The PRU events based signalling takes precedence if both options are mentioned. Either of the options would require the corresponding firmware support though. A build dependency against MAILBOX is also added. Note that the OMAP Mailbox IP is not present on 66AK2G and Davinci SoCs, so it is only selected for OMAP-based SoCs. Signed-off-by: Suman Anna --- drivers/remoteproc/Kconfig | 2 + drivers/remoteproc/pru_rproc.c | 169 - 2 files changed, 168 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 333666e..b89acb0 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -200,6 +200,8 @@ config ST_SLIM_REMOTEPROC config PRUSS_REMOTEPROC tristate "TI PRUSS remoteproc support" depends on TI_PRUSS + select MAILBOX + select OMAP2PLUS_MBOX if ARCH_OMAP2PLUS default n help Support for TI PRU-ICSS remote processors via the remote processor diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 73a7f13..e0554b3 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,10 @@ enum pru_mem { * @id: id of the PRU core within the PRUSS * @pruss: back-reference to parent PRUSS structure * @rproc: remoteproc pointer for this PRU core + * @mbox: mailbox channel handle used for vring signalling with MPU + * @client: mailbox client to request the mailbox channel + * @irq_ring: IRQ number to use for processing vring buffers + * @irq_kick: IRQ number to use to perform virtio kick * @mem_regions: data for each of the PRU memory regions * @dram0: PRUSS DRAM0 region * @dram1: PRUSS DRAM1 region @@ -72,6 +77,10 @@ struct pru_rproc { int id; struct pruss *pruss; struct rproc *rproc; + struct mbox_chan *mbox; + struct mbox_client client; + int irq_vring; + int irq_kick; struct pruss_mem_region mem_regions[PRU_MEM_MAX]; struct pruss_mem_region dram0; struct pruss_mem_region dram1; @@ -233,22 +242,124 @@ static void pru_rproc_create_debug_entries(struct rproc *rproc) rproc, _rproc_debug_ss_fops); } +/** + * pru_rproc_mbox_callback() - inbound mailbox message handler + * @client: mailbox client pointer used for requesting the mailbox channel + * @data: mailbox payload + * + * This handler is invoked by omap's mailbox driver whenever a mailbox + * message is received. Usually, the mailbox payload simply contains + * the index of the virtqueue that is kicked by the PRU remote processor, + * and we let remoteproc core handle it. + * + * In addition to virtqueue indices, we might also have some out-of-band + * values that indicates different events. Those values are deliberately + * very big so they don't coincide with virtqueue indices. + */ +static void pru_rproc_mbox_callback(struct mbox_client *client, void *data) +{ + struct pru_rproc *pru = container_of(client, struct pru_rproc, client); + struct device *dev = >rproc->dev; + u32 msg = (u32)data; + + dev_dbg(dev, "mbox msg: 0x%x\n", msg); + + /* msg contains the index of the triggered vring */ + if (rproc_vq_interrupt(pru->rproc, msg) == IRQ_NONE) + dev_dbg(dev, "no message was found in vqid %d\n", msg); +} + +/** + * pru_rproc_vring_interrupt() - interrupt handler for processing vrings + * @irq: irq number associated with the PRU event MPU is listening on + * @data: interrupt handler data, will be a PRU rproc structure + * + * This handler is used by the PRU remoteproc driver when using PRU system + * events for processing the virtqueues. Unlike the mailbox IP, there is + * no payload associated with an interrupt, so either a unique event is + * used for each virtqueue kick, or a both virtqueues are
[PATCH 14/16] remoteproc/pru: configure firmware based on client setup
From: Tero Kristo Client device node property firmware-name is now used to configure firmware for the PRU instances. The default firmware is also restored once releasing the PRU resource. Signed-off-by: Tero Kristo Reviewed-by: Roger Quadros Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 9a08937..84f006b 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -132,6 +132,21 @@ void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, spin_unlock_irqrestore(>rmw_lock, flags); } +/** + * pru_rproc_set_firmware() - set firmware for a pru core + * @rproc: the rproc instance of the PRU + * @fw_name: the new firmware name, or NULL if default is desired + */ +static int pru_rproc_set_firmware(struct rproc *rproc, const char *fw_name) +{ + struct pru_rproc *pru = rproc->priv; + + if (!fw_name) + fw_name = pru->fw_name; + + return rproc_set_firmware(rproc, fw_name); +} + static struct rproc *__pru_rproc_get(struct device_node *np, int index) { struct device_node *rproc_np = NULL; @@ -189,6 +204,7 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) struct device *dev; int ret; u32 mux; + const char *fw_name; rproc = __pru_rproc_get(np, index); if (IS_ERR(rproc)) @@ -225,6 +241,16 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) } } + ret = of_property_read_string_index(np, "firmware-name", index, + _name); + if (!ret) { + ret = pru_rproc_set_firmware(rproc, fw_name); + if (ret) { + dev_err(dev, "failed to set firmware: %d\n", ret); + goto err; + } + } + return rproc; err: @@ -255,6 +281,7 @@ void pru_rproc_put(struct rproc *rproc) if (!pru->client_np) return; + pru_rproc_set_firmware(rproc, NULL); pruss_cfg_set_gpmux(pru->pruss, pru->id, pru->gpmux_save); mutex_lock(>lock); -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 13/16] remoteproc/pru: add support for configuring GPMUX based on client setup
From: Tero Kristo Client device node property ti,pruss-gp-mux-sel can now be used to configure the GPMUX config value for PRU. Signed-off-by: Tero Kristo [s-a...@ti.com: simplify the pru id usage] Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 28 1 file changed, 28 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index d8b823d..9a08937 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -72,6 +72,7 @@ enum pru_mem { * @sdram_da: device address of secondary Data RAM for this PRU * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading + * @gpmux_save: saved value for gpmux config * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode @@ -95,6 +96,7 @@ struct pru_rproc { u32 sdram_da; u32 shrdram_da; const char *fw_name; + u8 gpmux_save; struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; @@ -184,12 +186,16 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) { struct rproc *rproc; struct pru_rproc *pru; + struct device *dev; + int ret; + u32 mux; rproc = __pru_rproc_get(np, index); if (IS_ERR(rproc)) return rproc; pru = rproc->priv; + dev = >dev; mutex_lock(>lock); @@ -203,7 +209,27 @@ struct rproc *pru_rproc_get(struct device_node *np, int index) mutex_unlock(>lock); + ret = pruss_cfg_get_gpmux(pru->pruss, pru->id, >gpmux_save); + if (ret) { + dev_err(dev, "failed to get cfg gpmux: %d\n", ret); + goto err; + } + + ret = of_property_read_u32_index(np, "ti,pruss-gp-mux-sel", index, +); + if (!ret) { + ret = pruss_cfg_set_gpmux(pru->pruss, pru->id, mux); + if (ret) { + dev_err(dev, "failed to set cfg gpmux: %d\n", ret); + goto err; + } + } + return rproc; + +err: + pru_rproc_put(rproc); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(pru_rproc_get); @@ -229,6 +255,8 @@ void pru_rproc_put(struct rproc *rproc) if (!pru->client_np) return; + pruss_cfg_set_gpmux(pru->pruss, pru->id, pru->gpmux_save); + mutex_lock(>lock); pru->client_np = NULL; mutex_unlock(>lock); -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 06/16] dt-bindings: remoteproc: ti-pruss: Update bindings for supporting rpmsg
From: Suman Anna Update the PRUSS DT bindings to add the properties required to support the optional virtio rpmsg stack using the virtio-ring based communication transport between MPU and a PRU core. Signed-off-by: Suman Anna --- .../devicetree/bindings/soc/ti/ti,pruss.txt| 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt index 24fedad..3e5f32f 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt @@ -175,6 +175,32 @@ Required Properties: - firmware-name : should contain the name of the default firmware image file located on the firmware search path +Optional Properties: + +The virtio based communication between the MPU and a PRU core _requires_ +either the 'mboxes' property, or the set of 'interrupt-parent', 'interrupts' +and 'interrupt-names' properties to be defined. The latter option is the +preferred choice. The 'mboxes' property is not applicable for 66AK2G and +DA850/OMAP-L138 SoCs. + +- mboxes : OMAP Mailbox specifier denoting the sub-mailbox, if using + a mailbox for IPC signalling between host and a PRU core. + The specifier format is as per the bindings, + Documentation/devicetree/bindings/mailbox/omap-mailbox.txt + This property should match with the sub-mailbox node used + in the corresponding firmware image. +- interrupt-parent : phandle to the PRUSS INTC node. Should be defined if + interrupts property is to be used. +- interrupts : array of interrupt specifiers if using PRU system events + for IPC signalling between host and a PRU core. This + property should match with the PRU system event used in + the corresponding firmware image. +- interrupt-names : should use one of the following names for each interrupt, + the name should match the corresponding PRU system event + number, + "vring" - for PRU to HOST virtqueue signalling + "kick" - for HOST to PRU virtqueue signalling + MDIO Child Node @@ -243,6 +269,9 @@ Example: <0x4a322400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am335x-pru0-fw"; + interrupt-parent = <_intc>; + interrupts = <16>, <17>; + interrupt-names = "vring", "kick"; }; pru1: pru@4a338000 { @@ -252,6 +281,10 @@ Example: <0x4a324400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am335x-pru1-fw"; + interrupt-parent = <_intc>; + interrupts = <18>, <19>; + interrupt-names = "vring", "kick"; + /* mboxes = < _pru1>; */ }; pruss_mdio: mdio@4a332400 { @@ -329,6 +362,9 @@ Example: <0x54422400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am437x-pru1_0-fw"; + interrupt-parent = <_intc>; + interrupts = <16>, <17>; + interrupt-names = "vring", "kick"; }; pru1_1: pru@54438000 { @@ -338,6 +374,9 @@ Example: <0x54424400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am437x-pru1_1-fw"; + interrupt-parent = <_intc>; + interrupts = <18>, <19>; + interrupt-names = "vring", "kick"; }; pruss1_mdio: mdio@54432400 { -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 08/16] remoteproc/pru: Add pru_rproc_set_ctable() function
Some firmwares expect the OS drivers to configure the CTABLE entries publishing dynamically allocated memory regions. For example, the PRU Ethernet firmwares use the C28 and C30 entries for retrieving the Shared RAM and System SRAM (OCMC) areas allocated by the PRU Ethernet client driver. Provide a way for users to do that through a new API, pru_rproc_set_ctable(). The API returns 0 on success and a negative value on error. NOTE: The programmable CTABLE entries are typically re-programmed by the PRU firmwares when dealing with a certain block of memory during block processing. This API provides an interface to the PRU client drivers to publish a dynamically allocated memory block with the PRU firmware using a CTABLE entry instead of a negotiated address in shared memory. Additional synchronization may be needed between the PRU client drivers and firmwares if different addresses needs to be published at run-time reusing the same CTABLE entry. Signed-off-by: Roger Quadros Signed-off-by: Andrew F. Davis [s-a...@ti.com: add the NOTE: on patch description, minor cleanups] Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 51 ++ include/linux/pruss.h | 29 2 files changed, 80 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index e0554b3..fa3559b 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -65,6 +65,7 @@ enum pru_mem { * @dram0: PRUSS DRAM0 region * @dram1: PRUSS DRAM1 region * @shrdram: PRUSS SHARED RAM region + * @rmw_lock: lock for read, modify, write operations on registers * @iram_da: device address of Instruction RAM for this PRU * @pdram_da: device address of primary Data RAM for this PRU * @sdram_da: device address of secondary Data RAM for this PRU @@ -85,6 +86,7 @@ struct pru_rproc { struct pruss_mem_region dram0; struct pruss_mem_region dram1; struct pruss_mem_region shrdram; + spinlock_t rmw_lock; /* register access lock */ u32 iram_da; u32 pdram_da; u32 sdram_da; @@ -107,6 +109,54 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) writel_relaxed(val, pru->mem_regions[PRU_MEM_CTRL].va + reg); } +static inline +void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, +u32 mask, u32 set) +{ + u32 val; + unsigned long flags; + + spin_lock_irqsave(>rmw_lock, flags); + + val = pru_control_read_reg(pru, reg); + val &= ~mask; + val |= (set & mask); + pru_control_write_reg(pru, reg, val); + + spin_unlock_irqrestore(>rmw_lock, flags); +} + +/** + * pru_rproc_set_ctable() - set the constant table index for the PRU + * @rproc: the rproc instance of the PRU + * @c: constant table index to set + * @addr: physical address to set it to + */ +int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr) +{ + struct pru_rproc *pru = rproc->priv; + unsigned int reg; + u32 mask, set; + u16 idx; + u16 idx_mask; + + /* pointer is 16 bit and index is 8-bit so mask out the rest */ + idx_mask = (c >= PRU_C28) ? 0x : 0xFF; + + /* ctable uses bit 8 and upwards only */ + idx = (addr >> 8) & idx_mask; + + /* configurable ctable (i.e. C24) starts at PRU_CTRL_CTBIR0 */ + reg = PRU_CTRL_CTBIR0 + 4 * (c >> 1); + mask = idx_mask << (16 * (c & 1)); + set = idx << (16 * (c & 1)); + + pru_control_set_reg(pru, reg, mask, set); + + return 0; +} +EXPORT_SYMBOL_GPL(pru_rproc_set_ctable); + static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg) { return readl_relaxed(pru->mem_regions[PRU_MEM_DEBUG].va + reg); @@ -537,6 +587,7 @@ static int pru_rproc_probe(struct platform_device *pdev) pru->pruss = platform_get_drvdata(ppdev); pru->rproc = rproc; pru->fw_name = fw_name; + spin_lock_init(>rmw_lock); ret = pruss_request_mem_region(pru->pruss, PRUSS_MEM_DRAM0, >dram0); diff --git a/include/linux/pruss.h b/include/linux/pruss.h index c797fb1..af04a1c 100644 --- a/include/linux/pruss.h +++ b/include/linux/pruss.h @@ -134,7 +134,22 @@ struct pruss_intc_config { s8 ch_to_host[MAX_PRU_CHANNELS]; }; +/** + * enum pru_ctable_idx - Configurable Constant table index identifiers + */ +enum pru_ctable_idx { + PRU_C24 = 0, + PRU_C25, + PRU_C26, + PRU_C27, + PRU_C28, + PRU_C29, + PRU_C30, + PRU_C31, +}; + struct pruss; +struct rproc; #if IS_ENABLED(CONFIG_TI_PRUSS) @@ -232,4 +247,18 @@ int pruss_intc_unconfigure(struct pruss *pruss, #endif /* CONFIG_TI_PRUSS */ +#if IS_ENABLED(CONFIG_PRUSS_REMOTEPROC) + +int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr); + +#else + +static inline
[PATCH 05/16] remoteproc/pru: Add pru-specific debugfs support
From: Suman Anna The remoteproc core creates certain standard debugfs entries, that does not give a whole lot of useful information for the PRUs. The PRU remoteproc driver is enhanced to add additional debugfs entries for PRU. These will be auto-cleaned up when the parent rproc debug directory is removed. The enhanced debugfs support adds two new entries: 'regs' and 'single_step'. The 'regs' dumps out the useful CTRL sub-module registers as well as each of the 32 GPREGs and CT_REGs registers. The GPREGs and CT_REGs though are printed only when the PRU is halted and accessible as per the IP design. The 'single_step' utilizes the single-step execution of the PRU cores. Writing a non-zero value performs a single step, and a zero value restores the PRU to execute in the same mode as the mode before the first single step. (note: if the PRU is halted because of a halt instruction, then no change occurs). Logic for setting the PC and jumping over a halt instruction shall be added in the future. Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 135 + 1 file changed, 135 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index c35f432..73a7f13 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -36,6 +37,10 @@ #define CTRL_CTRL_SINGLE_STEP BIT(8) #define CTRL_CTRL_RUNSTATE BIT(15) +/* PRU_ICSS_PRU_DEBUG registers */ +#define PRU_DEBUG_GPREG(x) (0x + (x) * 4) +#define PRU_DEBUG_CT_REG(x)(0x0080 + (x) * 4) + /** * enum pru_mem - PRU core memory range identifiers */ @@ -60,6 +65,8 @@ enum pru_mem { * @sdram_da: device address of secondary Data RAM for this PRU * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading + * @dbg_single_step: debug state variable to set PRU into single step mode + * @dbg_continuous: debug state variable to restore PRU execution mode */ struct pru_rproc { int id; @@ -74,6 +81,8 @@ struct pru_rproc { u32 sdram_da; u32 shrdram_da; const char *fw_name; + u32 dbg_single_step; + u32 dbg_continuous; }; static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, int len); @@ -100,6 +109,130 @@ void pru_debug_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) writel_relaxed(val, pru->mem_regions[PRU_MEM_DEBUG].va + reg); } +static int pru_rproc_debug_read_regs(struct seq_file *s, void *data) +{ + struct rproc *rproc = s->private; + struct pru_rproc *pru = rproc->priv; + int i, nregs = 32; + u32 pru_sts; + int pru_is_running; + + seq_puts(s, "== Control Registers ==\n"); + seq_printf(s, "CTRL := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTRL)); + pru_sts = pru_control_read_reg(pru, PRU_CTRL_STS); + seq_printf(s, "STS (PC) := 0x%08x (0x%08x)\n", pru_sts, pru_sts << 2); + seq_printf(s, "WAKEUP_EN := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_WAKEUP_EN)); + seq_printf(s, "CYCLE := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CYCLE)); + seq_printf(s, "STALL := 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_STALL)); + seq_printf(s, "CTBIR0:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTBIR0)); + seq_printf(s, "CTBIR1:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTBIR1)); + seq_printf(s, "CTPPR0:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTPPR0)); + seq_printf(s, "CTPPR1:= 0x%08x\n", + pru_control_read_reg(pru, PRU_CTRL_CTPPR1)); + + seq_puts(s, "=== Debug Registers ===\n"); + pru_is_running = pru_control_read_reg(pru, PRU_CTRL_CTRL) & + CTRL_CTRL_RUNSTATE; + if (pru_is_running) { + seq_puts(s, "PRU is executing, cannot print/access debug registers.\n"); + return 0; + } + + for (i = 0; i < nregs; i++) { + seq_printf(s, "GPREG%-2d := 0x%08x\tCT_REG%-2d := 0x%08x\n", + i, pru_debug_read_reg(pru, PRU_DEBUG_GPREG(i)), + i, pru_debug_read_reg(pru, PRU_DEBUG_CT_REG(i))); + } + + return 0; +} + +static int pru_rproc_debug_regs_open(struct inode *inode, struct file *file) +{ + return single_open(file, pru_rproc_debug_read_regs, inode->i_private); +} + +static const struct file_operations pru_rproc_debug_regs_ops = { + .open = pru_rproc_debug_regs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * Control PRU single-step mode + * + * This is a debug helper function used for controlling the
[PATCH 12/16] dt-bindings: remoteproc: ti-pruss: Document application node bindings
From: Tero Kristo Add documentation for the Texas Instruments PRU application nodes. These are used to configure specific user applications for PRU instances. Signed-off-by: Tero Kristo [s-a...@ti.com: some binding updates] Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- .../devicetree/bindings/soc/ti/ti,pruss.txt| 43 ++ 1 file changed, 43 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt index 3e5f32f..94c91ee 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt @@ -210,6 +210,38 @@ used in TI Davinci SoCs. Please refer to the corresponding binding document, Documentation/devicetree/bindings/net/davinci-mdio.txt for details. +Application/User Nodes +=== +A PRU application/user node typically uses one or more PRU device nodes to +implement a PRU application/functionality. Each application/client node would +need a reference to at least a PRU node, and optionally pass some configuration +parameters. + +Required Properties: + +- prus : phandles to the PRU nodes used + +Optional Properties: + +- firmware-name: firmwares for the PRU cores, the default firmware + for the core from the PRU node will be used if not + provided. The firmware names should correspond to + the PRU cores listed in the 'prus' property +- ti,pruss-gp-mux-sel : array of values for the GP_MUX_SEL under PRUSS_GPCFG + register for a PRU. This selects the internal muxing + scheme for the PRU instance. If not provided, the + default out-of-reset value (0) for the PRU core is + used. Values should correspond to the PRU cores listed + in the 'prus' property +- ti,pru-interrupt-map : PRU interrupt mappings, containing an array of entries + with each entry consisting of 4 cell-values. First one + is an index towards the "prus" property to identify the + PRU core for the interrupt map, second is the PRU + System Event id, third is the PRU interrupt channel id + and fourth is the PRU host interrupt id. If provided, + this map will supercede any other configuration + provided through firmware + Example: 1. /* AM33xx PRU-ICSS */ @@ -397,3 +429,14 @@ Example: ... }; }; + +3: /* PRU application node example */ + app_node: app_node { + prus = <_0>, <_1>; + firmware-name = "pruss-app-fw", "pruss-app-fw-2"; + ti,pruss-gp-mux-sel = <2>, <1>; + /* setup interrupts for prus: + prus[0] => pru1_0: ev=16, chnl=2, host-irq=7, + prus[1] => pru1_1: ev=19, chnl=1, host-irq=3 */ + ti,pru-interrupt-map = <0 16 2 7 >, <1 19 1 3>; + } -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 09/16] remoteproc/pru: add APIs to get and put the PRU cores
From: Tero Kristo Add two new APIs, pru_rproc_get() and pru_rproc_put(), to the PRU driver to allow client drivers to acquire and release the remoteproc device associated with a PRU core. The PRU cores are treated as resources with only one client owning it at a time. The pru_rproc_get() function returns the rproc handle corresponding to a PRU core identified by the device tree "prus" property under the client node. The pru_rproc_put() is the complementary function to pru_rproc_get(). Signed-off-by: Tero Kristo [s-a...@ti.com: improve error checking, various fixes and cleanups] Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 112 + include/linux/pruss.h | 9 2 files changed, 121 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index fa3559b..2aa05b0 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -57,6 +57,7 @@ enum pru_mem { * @id: id of the PRU core within the PRUSS * @pruss: back-reference to parent PRUSS structure * @rproc: remoteproc pointer for this PRU core + * @client_np: client device node * @mbox: mailbox channel handle used for vring signalling with MPU * @client: mailbox client to request the mailbox channel * @irq_ring: IRQ number to use for processing vring buffers @@ -71,6 +72,7 @@ enum pru_mem { * @sdram_da: device address of secondary Data RAM for this PRU * @shrdram_da: device address of shared Data RAM * @fw_name: name of firmware image used during loading + * @lock: mutex to protect client usage * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode */ @@ -78,6 +80,7 @@ struct pru_rproc { int id; struct pruss *pruss; struct rproc *rproc; + struct device_node *client_np; struct mbox_chan *mbox; struct mbox_client client; int irq_vring; @@ -92,6 +95,7 @@ struct pru_rproc { u32 sdram_da; u32 shrdram_da; const char *fw_name; + struct mutex lock; /* client access lock */ u32 dbg_single_step; u32 dbg_continuous; }; @@ -126,6 +130,113 @@ void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, spin_unlock_irqrestore(>rmw_lock, flags); } +static struct rproc *__pru_rproc_get(struct device_node *np, int index) +{ + struct device_node *rproc_np = NULL; + struct platform_device *pdev; + struct rproc *rproc; + + rproc_np = of_parse_phandle(np, "prus", index); + if (!rproc_np || !of_device_is_available(rproc_np)) + return ERR_PTR(-ENODEV); + + pdev = of_find_device_by_node(rproc_np); + of_node_put(rproc_np); + + if (!pdev) + /* probably PRU not yet probed */ + return ERR_PTR(-EPROBE_DEFER); + + /* TODO: replace the crude string based check to make sure it is PRU */ + if (!strstr(dev_name(>dev), "pru")) { + put_device(>dev); + return ERR_PTR(-ENODEV); + } + + rproc = platform_get_drvdata(pdev); + put_device(>dev); + if (!rproc) + return ERR_PTR(-EPROBE_DEFER); + + get_device(>dev); + + return rproc; +} + +/** + * pru_rproc_get() - get the PRU rproc instance from a device node + * @np: the user/client device node + * @index: index to use for the prus property + * + * This function looks through a client device node's "prus" property at index + * @index and returns the rproc handle for a valid PRU remote processor if + * found. The function allows only one user to own the PRU rproc resource at + * a time. Caller must call pru_rproc_put() when done with using the rproc, + * not required if the function returns a failure. + * + * Returns the rproc handle on success, and an ERR_PTR on failure using one + * of the following error values + *-ENODEV if device is not found + *-EBUSY if PRU is already acquired by anyone + *-EPROBE_DEFER is PRU device is not probed yet + */ +struct rproc *pru_rproc_get(struct device_node *np, int index) +{ + struct rproc *rproc; + struct pru_rproc *pru; + + rproc = __pru_rproc_get(np, index); + if (IS_ERR(rproc)) + return rproc; + + pru = rproc->priv; + + mutex_lock(>lock); + + if (pru->client_np) { + mutex_unlock(>lock); + put_device(>dev); + return ERR_PTR(-EBUSY); + } + + pru->client_np = np; + + mutex_unlock(>lock); + + return rproc; +} +EXPORT_SYMBOL_GPL(pru_rproc_get); + +/** + * pru_rproc_put() - release the PRU rproc resource + * @rproc: the rproc resource to release + * + * Releases the PRU rproc resource and makes it available to other + * users. + */ +void pru_rproc_put(struct rproc *rproc) +{ + struct pru_rproc *pru; + + if (IS_ERR_OR_NULL(rproc)) +
[PATCH 10/16] remoteproc/pru: add pru_rproc_get_id() API to retrieve the PRU id
From: Suman Anna Export an API pru_rproc_get_id() to allow other PRUSS platform drivers to clients to retrieve the PRU id from a remoteproc handle associated with a PRU. The new function takes in a struct rproc pointer as argument. Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 27 +-- include/linux/pruss.h | 15 +++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 2aa05b0..d8b823d 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -238,6 +238,29 @@ void pru_rproc_put(struct rproc *rproc) EXPORT_SYMBOL_GPL(pru_rproc_put); /** + * pru_rproc_get_id() - get PRU id from a previously acquired PRU remoteproc + * @rproc: the rproc instance of the PRU + * + * Returns the PRU id of the PRU remote processor that has been acquired through + * a pru_rproc_get(), or a negative value on error + */ +enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc) +{ + struct pru_rproc *pru; + + if (IS_ERR_OR_NULL(rproc) || !rproc->dev.parent) + return -EINVAL; + + /* TODO: replace the crude string based check to make sure it is PRU */ + if (!strstr(dev_name(rproc->dev.parent), "pru")) + return -EINVAL; + + pru = rproc->priv; + return pru->id; +} +EXPORT_SYMBOL_GPL(pru_rproc_get_id); + +/** * pru_rproc_set_ctable() - set the constant table index for the PRU * @rproc: the rproc instance of the PRU * @c: constant table index to set @@ -643,9 +666,9 @@ static int pru_rproc_set_id(struct pru_rproc *pru) u32 mask2 = 0x38000; if ((pru->mem_regions[0].pa & mask1) == mask1) - pru->id = 0; + pru->id = PRUSS_PRU0; else if ((pru->mem_regions[0].pa & mask2) == mask2) - pru->id = 1; + pru->id = PRUSS_PRU1; else ret = -EINVAL; diff --git a/include/linux/pruss.h b/include/linux/pruss.h index 405039a..c0a3b3e 100644 --- a/include/linux/pruss.h +++ b/include/linux/pruss.h @@ -10,6 +10,15 @@ #ifndef __LINUX_PRUSS_H #define __LINUX_PRUSS_H +/** + * enum pruss_pru_id - PRU core identifiers + */ +enum pruss_pru_id { + PRUSS_PRU0 = 0, + PRUSS_PRU1, + PRUSS_NUM_PRUS, +}; + /* * PRU_ICSS_CFG registers * SYSCFG, ISRP, ISP, IESP, IECP, SCRP applicable on AM devices only @@ -251,6 +260,7 @@ int pruss_intc_unconfigure(struct pruss *pruss, struct rproc *pru_rproc_get(struct device_node *node, int index); void pru_rproc_put(struct rproc *rproc); +enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc); int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr); #else @@ -262,6 +272,11 @@ static inline struct rproc *pru_rproc_get(struct device_node *node, int index) static inline void pru_rproc_put(struct rproc *rproc) { } +static inline enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc) +{ + return -ENOTSUPP; +} + static inline int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr) { -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 10/16] remoteproc/pru: add pru_rproc_get_id() API to retrieve the PRU id
From: Suman Anna Export an API pru_rproc_get_id() to allow other PRUSS platform drivers to clients to retrieve the PRU id from a remoteproc handle associated with a PRU. The new function takes in a struct rproc pointer as argument. Signed-off-by: Suman Anna --- drivers/remoteproc/pru_rproc.c | 27 +-- include/linux/pruss.h | 15 +++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 2aa05b0..d8b823d 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -238,6 +238,29 @@ void pru_rproc_put(struct rproc *rproc) EXPORT_SYMBOL_GPL(pru_rproc_put); /** + * pru_rproc_get_id() - get PRU id from a previously acquired PRU remoteproc + * @rproc: the rproc instance of the PRU + * + * Returns the PRU id of the PRU remote processor that has been acquired through + * a pru_rproc_get(), or a negative value on error + */ +enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc) +{ + struct pru_rproc *pru; + + if (IS_ERR_OR_NULL(rproc) || !rproc->dev.parent) + return -EINVAL; + + /* TODO: replace the crude string based check to make sure it is PRU */ + if (!strstr(dev_name(rproc->dev.parent), "pru")) + return -EINVAL; + + pru = rproc->priv; + return pru->id; +} +EXPORT_SYMBOL_GPL(pru_rproc_get_id); + +/** * pru_rproc_set_ctable() - set the constant table index for the PRU * @rproc: the rproc instance of the PRU * @c: constant table index to set @@ -643,9 +666,9 @@ static int pru_rproc_set_id(struct pru_rproc *pru) u32 mask2 = 0x38000; if ((pru->mem_regions[0].pa & mask1) == mask1) - pru->id = 0; + pru->id = PRUSS_PRU0; else if ((pru->mem_regions[0].pa & mask2) == mask2) - pru->id = 1; + pru->id = PRUSS_PRU1; else ret = -EINVAL; diff --git a/include/linux/pruss.h b/include/linux/pruss.h index 405039a..c0a3b3e 100644 --- a/include/linux/pruss.h +++ b/include/linux/pruss.h @@ -10,6 +10,15 @@ #ifndef __LINUX_PRUSS_H #define __LINUX_PRUSS_H +/** + * enum pruss_pru_id - PRU core identifiers + */ +enum pruss_pru_id { + PRUSS_PRU0 = 0, + PRUSS_PRU1, + PRUSS_NUM_PRUS, +}; + /* * PRU_ICSS_CFG registers * SYSCFG, ISRP, ISP, IESP, IECP, SCRP applicable on AM devices only @@ -251,6 +260,7 @@ int pruss_intc_unconfigure(struct pruss *pruss, struct rproc *pru_rproc_get(struct device_node *node, int index); void pru_rproc_put(struct rproc *rproc); +enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc); int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr); #else @@ -262,6 +272,11 @@ static inline struct rproc *pru_rproc_get(struct device_node *node, int index) static inline void pru_rproc_put(struct rproc *rproc) { } +static inline enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc) +{ + return -ENOTSUPP; +} + static inline int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr) { -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 00/16] remoteproc: Add support for TI PRU
Hi, This is the second part of the series [1] and depends on it. It adds remoteproc support for the PRU processor cores present in the PRU-ICSS subsystem on TI SoCs. The PRU remoteproc driver uses the standard remoteproc core ELF loader. However, the PRUs do not have a unified address space, (has an Instruction RAM and a primary Data RAM at both 0x0) and leverage an added .da_to_va ops to use the standard ELF loader. This remoteproc driver does not have support for error recovery and system suspend/resume features. Different compatibles are used to allow providing scalability for instance-specific device data if needed. The driver uses a default firmware-name retrieved from device-tree, and the firmwares are expected to be present in the standard Linux firmware search paths. They can also be adjusted by userspace if required through the sysfs interface provided by the remoteproc core. The PRU remoteproc driver uses a client-driven boot methodology - it does _not_ support auto-boot so that the PRU load and boot is dictated by the corresponding client drivers for achieving various usecases. This allows flexibility for the client drivers or applications to set a firmware name (if needed) based on their desired functionality and boot the PRU. Finally it adds some helper APIs for client drivers to set PRU specific settings .e.g Constant Table, GPI mode, etc. Testing: To test the code with example firmware you can try the LAB5 tutorial http://processors.wiki.ti.com/index.php/PRU_Training:_Hands-on_Labs#LAB_5:_RPMsg_Communication_between_ARM_and_PRU with the pru-software-support package at [2] and the sample rpmsg-client driver. NOTE: you no longer need to build and run PRU_Halt example as shown in the tutorial. cheers, -roger [1] https://lkml.org/lkml/2018/11/22/948 [2] https://github.com/rogerq/pru-software-support-package/commits/upstream/pruss Roger Quadros (2): remoteproc/pru: Add pru_rproc_set_ctable() function remoteproc/pru: Add support for INTC Interrupt map resource Suman Anna (9): remoteproc: Extend rproc_da_to_va() API with a flags parameter remoteproc: Add a rproc_set_firmware() API remoteproc: Add support to handle device specific resource types remoteproc/pru: Add PRU remoteproc driver remoteproc/pru: Add pru-specific debugfs support dt-bindings: remoteproc: ti-pruss: Update bindings for supporting rpmsg remoteproc/pru: Add support for virtio rpmsg stack remoteproc/pru: add pru_rproc_get_id() API to retrieve the PRU id soc: ti: pruss: add helper functions to set GPI mode, MII_RT_event and XFR Tero Kristo (5): remoteproc/pru: add APIs to get and put the PRU cores dt-bindings: remoteproc: ti-pruss: Document application node bindings remoteproc/pru: add support for configuring GPMUX based on client setup remoteproc/pru: configure firmware based on client setup remoteproc/pru: add support for parsing pru interrupt mapping from DT .../devicetree/bindings/soc/ti/ti,pruss.txt| 82 ++ drivers/remoteproc/Kconfig | 16 + drivers/remoteproc/Makefile|1 + drivers/remoteproc/imx_rproc.c |2 +- drivers/remoteproc/keystone_remoteproc.c |3 +- drivers/remoteproc/pru_rproc.c | 1138 drivers/remoteproc/pru_rproc.h | 55 + drivers/remoteproc/qcom_q6v5_mss.c |5 +- drivers/remoteproc/qcom_q6v5_pas.c |2 +- drivers/remoteproc/qcom_q6v5_wcss.c|2 +- drivers/remoteproc/qcom_wcnss.c|2 +- drivers/remoteproc/remoteproc_core.c | 112 +- drivers/remoteproc/remoteproc_debugfs.c|3 + drivers/remoteproc/remoteproc_elf_loader.c |6 +- drivers/remoteproc/remoteproc_internal.h |2 +- drivers/remoteproc/remoteproc_sysfs.c | 33 +- drivers/remoteproc/st_slim_rproc.c |3 +- drivers/remoteproc/wkup_m3_rproc.c |3 +- include/linux/pruss.h | 168 +++ include/linux/remoteproc.h | 32 +- 20 files changed, 1620 insertions(+), 50 deletions(-) create mode 100644 drivers/remoteproc/pru_rproc.c create mode 100644 drivers/remoteproc/pru_rproc.h -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 00/16] remoteproc: Add support for TI PRU
Hi, This is the second part of the series [1] and depends on it. It adds remoteproc support for the PRU processor cores present in the PRU-ICSS subsystem on TI SoCs. The PRU remoteproc driver uses the standard remoteproc core ELF loader. However, the PRUs do not have a unified address space, (has an Instruction RAM and a primary Data RAM at both 0x0) and leverage an added .da_to_va ops to use the standard ELF loader. This remoteproc driver does not have support for error recovery and system suspend/resume features. Different compatibles are used to allow providing scalability for instance-specific device data if needed. The driver uses a default firmware-name retrieved from device-tree, and the firmwares are expected to be present in the standard Linux firmware search paths. They can also be adjusted by userspace if required through the sysfs interface provided by the remoteproc core. The PRU remoteproc driver uses a client-driven boot methodology - it does _not_ support auto-boot so that the PRU load and boot is dictated by the corresponding client drivers for achieving various usecases. This allows flexibility for the client drivers or applications to set a firmware name (if needed) based on their desired functionality and boot the PRU. Finally it adds some helper APIs for client drivers to set PRU specific settings .e.g Constant Table, GPI mode, etc. Testing: To test the code with example firmware you can try the LAB5 tutorial http://processors.wiki.ti.com/index.php/PRU_Training:_Hands-on_Labs#LAB_5:_RPMsg_Communication_between_ARM_and_PRU with the pru-software-support package at [2] and the sample rpmsg-client driver. NOTE: you no longer need to build and run PRU_Halt example as shown in the tutorial. cheers, -roger [1] https://lkml.org/lkml/2018/11/22/948 [2] https://github.com/rogerq/pru-software-support-package/commits/upstream/pruss Roger Quadros (2): remoteproc/pru: Add pru_rproc_set_ctable() function remoteproc/pru: Add support for INTC Interrupt map resource Suman Anna (9): remoteproc: Extend rproc_da_to_va() API with a flags parameter remoteproc: Add a rproc_set_firmware() API remoteproc: Add support to handle device specific resource types remoteproc/pru: Add PRU remoteproc driver remoteproc/pru: Add pru-specific debugfs support dt-bindings: remoteproc: ti-pruss: Update bindings for supporting rpmsg remoteproc/pru: Add support for virtio rpmsg stack remoteproc/pru: add pru_rproc_get_id() API to retrieve the PRU id soc: ti: pruss: add helper functions to set GPI mode, MII_RT_event and XFR Tero Kristo (5): remoteproc/pru: add APIs to get and put the PRU cores dt-bindings: remoteproc: ti-pruss: Document application node bindings remoteproc/pru: add support for configuring GPMUX based on client setup remoteproc/pru: configure firmware based on client setup remoteproc/pru: add support for parsing pru interrupt mapping from DT .../devicetree/bindings/soc/ti/ti,pruss.txt| 82 ++ drivers/remoteproc/Kconfig | 16 + drivers/remoteproc/Makefile|1 + drivers/remoteproc/imx_rproc.c |2 +- drivers/remoteproc/keystone_remoteproc.c |3 +- drivers/remoteproc/pru_rproc.c | 1138 drivers/remoteproc/pru_rproc.h | 55 + drivers/remoteproc/qcom_q6v5_mss.c |5 +- drivers/remoteproc/qcom_q6v5_pas.c |2 +- drivers/remoteproc/qcom_q6v5_wcss.c|2 +- drivers/remoteproc/qcom_wcnss.c|2 +- drivers/remoteproc/remoteproc_core.c | 112 +- drivers/remoteproc/remoteproc_debugfs.c|3 + drivers/remoteproc/remoteproc_elf_loader.c |6 +- drivers/remoteproc/remoteproc_internal.h |2 +- drivers/remoteproc/remoteproc_sysfs.c | 33 +- drivers/remoteproc/st_slim_rproc.c |3 +- drivers/remoteproc/wkup_m3_rproc.c |3 +- include/linux/pruss.h | 168 +++ include/linux/remoteproc.h | 32 +- 20 files changed, 1620 insertions(+), 50 deletions(-) create mode 100644 drivers/remoteproc/pru_rproc.c create mode 100644 drivers/remoteproc/pru_rproc.h -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
[PATCH 02/16] remoteproc: Add a rproc_set_firmware() API
From: Suman Anna A new API, rproc_set_firmware() is added to allow the remoteproc platform drivers and remoteproc client drivers to be able to configure a custom firmware name that is different from the default name used during remoteproc registration. This function is being introduced to provide a kernel-level equivalent of the current sysfs interface to remoteproc client drivers. This allows some remoteproc drivers to choose different firmwares at runtime when the remote processor is not running based on the functional feature it is providing using that remote processor. The TI PRU Ethernet driver will be an example of such usage as it requires to use different firmwares for different supported protocols. Also, update the firmware_store() function used by the sysfs interface to reuse this function to avoid code duplication. Signed-off-by: Suman Anna --- drivers/remoteproc/remoteproc_core.c | 61 +++ drivers/remoteproc/remoteproc_sysfs.c | 33 ++- include/linux/remoteproc.h| 1 + 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 39458a7..581e6e8 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -2151,6 +2151,67 @@ void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type) } EXPORT_SYMBOL(rproc_report_crash); +/** + * rproc_set_firmware() - assign a new firmware + * @rproc: rproc handle to which the new firmware is being assigned + * @fw_name: new firmware name to be assigned + * + * This function allows remoteproc drivers or clients to configure a custom + * firmware name that is different from the default name used during remoteproc + * registration. The function does not trigger a remote processor boot, + * only sets the firmware name used for a subsequent boot. This function + * should also be called only when the remote processor is offline. + * + * This allows either the userspace to configure a different name through + * sysfs or a kernel-level remoteproc or a remoteproc client driver to set + * a specific firmware when it is controlling the boot and shutdown of the + * remote processor. + * + * Returns 0 on success or a negative value upon failure + */ +int rproc_set_firmware(struct rproc *rproc, const char *fw_name) +{ + struct device *dev = rproc->dev.parent; + int ret, len; + char *p; + + if (!rproc || !fw_name) + return -EINVAL; + + ret = mutex_lock_interruptible(>lock); + if (ret) { + dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); + return -EINVAL; + } + + if (rproc->state != RPROC_OFFLINE) { + dev_err(dev, "can't change firmware while running\n"); + ret = -EBUSY; + goto out; + } + + len = strcspn(fw_name, "\n"); + if (!len) { + dev_err(dev, "can't provide a NULL firmware\n"); + ret = -EINVAL; + goto out; + } + + p = kstrndup(fw_name, len, GFP_KERNEL); + if (!p) { + ret = -ENOMEM; + goto out; + } + + kfree(rproc->firmware); + rproc->firmware = p; + +out: + mutex_unlock(>lock); + return ret; +} +EXPORT_SYMBOL(rproc_set_firmware); + static int __init remoteproc_init(void) { rproc_init_sysfs(); diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c index 3a4c3d7..6cf04a7 100644 --- a/drivers/remoteproc/remoteproc_sysfs.c +++ b/drivers/remoteproc/remoteproc_sysfs.c @@ -32,38 +32,9 @@ static ssize_t firmware_store(struct device *dev, const char *buf, size_t count) { struct rproc *rproc = to_rproc(dev); - char *p; - int err, len = count; + int err; - err = mutex_lock_interruptible(>lock); - if (err) { - dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, err); - return -EINVAL; - } - - if (rproc->state != RPROC_OFFLINE) { - dev_err(dev, "can't change firmware while running\n"); - err = -EBUSY; - goto out; - } - - len = strcspn(buf, "\n"); - if (!len) { - dev_err(dev, "can't provide a NULL firmware\n"); - err = -EINVAL; - goto out; - } - - p = kstrndup(buf, len, GFP_KERNEL); - if (!p) { - err = -ENOMEM; - goto out; - } - - kfree(rproc->firmware); - rproc->firmware = p; -out: - mutex_unlock(>lock); + err = rproc_set_firmware(rproc, buf); return err ? err : count; } diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 9e01a44..063468b 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -604,6 +604,7 @@
[PATCH 01/16] remoteproc: Extend rproc_da_to_va() API with a flags parameter
From: Suman Anna The rproc_da_to_va() API is currently used to perform any device to kernel address translations to meet the different needs of the remoteproc core/platform drivers (eg: loading). The function also invokes the da_to_va ops, if present, to allow the remoteproc platform drivers to provide address translation. However, not all platform implementations have linear address spaces, and may need an additional parameter to be able to perform proper translations. The rproc_da_to_va() API and the rproc .da_to_va ops have therefore been expanded to take in an additional flags field enabling some remoteproc implementations (like the TI PRUSS remoteproc driver) to use these flags. Also, define some semantics for this flags argument as this can vary from one implementation to another. A new flags type is encoded into the upper 16 bits along side the actual value in the lower 16-bits for the flags argument, to allow different individual implementations to have better flexibility in interpreting the flags as per their needs. Also, update the various remoteproc implementations that use the .da_to_va() ops for the new signature. Signed-off-by: Suman Anna --- drivers/remoteproc/imx_rproc.c | 2 +- drivers/remoteproc/keystone_remoteproc.c | 3 ++- drivers/remoteproc/qcom_q6v5_mss.c | 5 +++-- drivers/remoteproc/qcom_q6v5_pas.c | 2 +- drivers/remoteproc/qcom_q6v5_wcss.c| 2 +- drivers/remoteproc/qcom_wcnss.c| 2 +- drivers/remoteproc/remoteproc_core.c | 15 ++- drivers/remoteproc/remoteproc_elf_loader.c | 6 -- drivers/remoteproc/remoteproc_internal.h | 2 +- drivers/remoteproc/st_slim_rproc.c | 3 ++- drivers/remoteproc/wkup_m3_rproc.c | 3 ++- include/linux/remoteproc.h | 16 +++- 12 files changed, 43 insertions(+), 18 deletions(-) diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 54c07fd..14d7f15 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -211,7 +211,7 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da, return -ENOENT; } -static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, int len) +static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags) { struct imx_rproc *priv = rproc->priv; void *va = NULL; diff --git a/drivers/remoteproc/keystone_remoteproc.c b/drivers/remoteproc/keystone_remoteproc.c index aaac311..41c4d5c 100644 --- a/drivers/remoteproc/keystone_remoteproc.c +++ b/drivers/remoteproc/keystone_remoteproc.c @@ -254,7 +254,8 @@ static void keystone_rproc_kick(struct rproc *rproc, int vqid) * can be used either by the remoteproc core for loading (when using kernel * remoteproc loader), or by any rpmsg bus drivers. */ -static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len) +static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len, +u32 flags) { struct keystone_rproc *ksproc = rproc->priv; void __iomem *va = NULL; diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 01be731..3b77e12 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -971,7 +971,8 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc, int ret = 0; struct q6v5 *qproc = rproc->priv; unsigned long mask = BIT((unsigned long)segment->priv); - void *ptr = rproc_da_to_va(rproc, segment->da, segment->size); + void *ptr = rproc_da_to_va(rproc, segment->da, segment->size, + RPROC_FLAGS_NONE); /* Unlock mba before copying segments */ if (!qproc->dump_mba_loaded) @@ -1052,7 +1053,7 @@ static int q6v5_stop(struct rproc *rproc) return 0; } -static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len) +static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags) { struct q6v5 *qproc = rproc->priv; int offset; diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index b1e63fc..46e1c6b 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -167,7 +167,7 @@ static int adsp_stop(struct rproc *rproc) return ret; } -static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len) +static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags) { struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; int offset; diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c index f93e1e4..5b4d4c6 100644 --- a/drivers/remoteproc/qcom_q6v5_wcss.c +++ b/drivers/remoteproc/qcom_q6v5_wcss.c @@ -406,7 +406,7 @@ static int q6v5_wcss_stop(struct rproc *rproc) return 0; } -static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da,
[PATCH 02/16] remoteproc: Add a rproc_set_firmware() API
From: Suman Anna A new API, rproc_set_firmware() is added to allow the remoteproc platform drivers and remoteproc client drivers to be able to configure a custom firmware name that is different from the default name used during remoteproc registration. This function is being introduced to provide a kernel-level equivalent of the current sysfs interface to remoteproc client drivers. This allows some remoteproc drivers to choose different firmwares at runtime when the remote processor is not running based on the functional feature it is providing using that remote processor. The TI PRU Ethernet driver will be an example of such usage as it requires to use different firmwares for different supported protocols. Also, update the firmware_store() function used by the sysfs interface to reuse this function to avoid code duplication. Signed-off-by: Suman Anna --- drivers/remoteproc/remoteproc_core.c | 61 +++ drivers/remoteproc/remoteproc_sysfs.c | 33 ++- include/linux/remoteproc.h| 1 + 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 39458a7..581e6e8 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -2151,6 +2151,67 @@ void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type) } EXPORT_SYMBOL(rproc_report_crash); +/** + * rproc_set_firmware() - assign a new firmware + * @rproc: rproc handle to which the new firmware is being assigned + * @fw_name: new firmware name to be assigned + * + * This function allows remoteproc drivers or clients to configure a custom + * firmware name that is different from the default name used during remoteproc + * registration. The function does not trigger a remote processor boot, + * only sets the firmware name used for a subsequent boot. This function + * should also be called only when the remote processor is offline. + * + * This allows either the userspace to configure a different name through + * sysfs or a kernel-level remoteproc or a remoteproc client driver to set + * a specific firmware when it is controlling the boot and shutdown of the + * remote processor. + * + * Returns 0 on success or a negative value upon failure + */ +int rproc_set_firmware(struct rproc *rproc, const char *fw_name) +{ + struct device *dev = rproc->dev.parent; + int ret, len; + char *p; + + if (!rproc || !fw_name) + return -EINVAL; + + ret = mutex_lock_interruptible(>lock); + if (ret) { + dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); + return -EINVAL; + } + + if (rproc->state != RPROC_OFFLINE) { + dev_err(dev, "can't change firmware while running\n"); + ret = -EBUSY; + goto out; + } + + len = strcspn(fw_name, "\n"); + if (!len) { + dev_err(dev, "can't provide a NULL firmware\n"); + ret = -EINVAL; + goto out; + } + + p = kstrndup(fw_name, len, GFP_KERNEL); + if (!p) { + ret = -ENOMEM; + goto out; + } + + kfree(rproc->firmware); + rproc->firmware = p; + +out: + mutex_unlock(>lock); + return ret; +} +EXPORT_SYMBOL(rproc_set_firmware); + static int __init remoteproc_init(void) { rproc_init_sysfs(); diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c index 3a4c3d7..6cf04a7 100644 --- a/drivers/remoteproc/remoteproc_sysfs.c +++ b/drivers/remoteproc/remoteproc_sysfs.c @@ -32,38 +32,9 @@ static ssize_t firmware_store(struct device *dev, const char *buf, size_t count) { struct rproc *rproc = to_rproc(dev); - char *p; - int err, len = count; + int err; - err = mutex_lock_interruptible(>lock); - if (err) { - dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, err); - return -EINVAL; - } - - if (rproc->state != RPROC_OFFLINE) { - dev_err(dev, "can't change firmware while running\n"); - err = -EBUSY; - goto out; - } - - len = strcspn(buf, "\n"); - if (!len) { - dev_err(dev, "can't provide a NULL firmware\n"); - err = -EINVAL; - goto out; - } - - p = kstrndup(buf, len, GFP_KERNEL); - if (!p) { - err = -ENOMEM; - goto out; - } - - kfree(rproc->firmware); - rproc->firmware = p; -out: - mutex_unlock(>lock); + err = rproc_set_firmware(rproc, buf); return err ? err : count; } diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 9e01a44..063468b 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -604,6 +604,7 @@
[PATCH 01/16] remoteproc: Extend rproc_da_to_va() API with a flags parameter
From: Suman Anna The rproc_da_to_va() API is currently used to perform any device to kernel address translations to meet the different needs of the remoteproc core/platform drivers (eg: loading). The function also invokes the da_to_va ops, if present, to allow the remoteproc platform drivers to provide address translation. However, not all platform implementations have linear address spaces, and may need an additional parameter to be able to perform proper translations. The rproc_da_to_va() API and the rproc .da_to_va ops have therefore been expanded to take in an additional flags field enabling some remoteproc implementations (like the TI PRUSS remoteproc driver) to use these flags. Also, define some semantics for this flags argument as this can vary from one implementation to another. A new flags type is encoded into the upper 16 bits along side the actual value in the lower 16-bits for the flags argument, to allow different individual implementations to have better flexibility in interpreting the flags as per their needs. Also, update the various remoteproc implementations that use the .da_to_va() ops for the new signature. Signed-off-by: Suman Anna --- drivers/remoteproc/imx_rproc.c | 2 +- drivers/remoteproc/keystone_remoteproc.c | 3 ++- drivers/remoteproc/qcom_q6v5_mss.c | 5 +++-- drivers/remoteproc/qcom_q6v5_pas.c | 2 +- drivers/remoteproc/qcom_q6v5_wcss.c| 2 +- drivers/remoteproc/qcom_wcnss.c| 2 +- drivers/remoteproc/remoteproc_core.c | 15 ++- drivers/remoteproc/remoteproc_elf_loader.c | 6 -- drivers/remoteproc/remoteproc_internal.h | 2 +- drivers/remoteproc/st_slim_rproc.c | 3 ++- drivers/remoteproc/wkup_m3_rproc.c | 3 ++- include/linux/remoteproc.h | 16 +++- 12 files changed, 43 insertions(+), 18 deletions(-) diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 54c07fd..14d7f15 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -211,7 +211,7 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da, return -ENOENT; } -static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, int len) +static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags) { struct imx_rproc *priv = rproc->priv; void *va = NULL; diff --git a/drivers/remoteproc/keystone_remoteproc.c b/drivers/remoteproc/keystone_remoteproc.c index aaac311..41c4d5c 100644 --- a/drivers/remoteproc/keystone_remoteproc.c +++ b/drivers/remoteproc/keystone_remoteproc.c @@ -254,7 +254,8 @@ static void keystone_rproc_kick(struct rproc *rproc, int vqid) * can be used either by the remoteproc core for loading (when using kernel * remoteproc loader), or by any rpmsg bus drivers. */ -static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len) +static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, int len, +u32 flags) { struct keystone_rproc *ksproc = rproc->priv; void __iomem *va = NULL; diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 01be731..3b77e12 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -971,7 +971,8 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc, int ret = 0; struct q6v5 *qproc = rproc->priv; unsigned long mask = BIT((unsigned long)segment->priv); - void *ptr = rproc_da_to_va(rproc, segment->da, segment->size); + void *ptr = rproc_da_to_va(rproc, segment->da, segment->size, + RPROC_FLAGS_NONE); /* Unlock mba before copying segments */ if (!qproc->dump_mba_loaded) @@ -1052,7 +1053,7 @@ static int q6v5_stop(struct rproc *rproc) return 0; } -static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len) +static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags) { struct q6v5 *qproc = rproc->priv; int offset; diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index b1e63fc..46e1c6b 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -167,7 +167,7 @@ static int adsp_stop(struct rproc *rproc) return ret; } -static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len) +static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags) { struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; int offset; diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c index f93e1e4..5b4d4c6 100644 --- a/drivers/remoteproc/qcom_q6v5_wcss.c +++ b/drivers/remoteproc/qcom_q6v5_wcss.c @@ -406,7 +406,7 @@ static int q6v5_wcss_stop(struct rproc *rproc) return 0; } -static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da,
Re: [PATCH 01/17] dt-bindings: remoteproc: Add TI PRUSS bindings
Hi, On 23/11/18 18:24, Tony Lindgren wrote: > Hi, > > * Roger Quadros [181122 11:39]: >> From: Suman Anna >> +Example: >> + >> +1. /* AM33xx PRU-ICSS */ >> +pruss_soc_bus: pruss_soc_bus@4a326004 { >> +compatible = "ti,am3356-pruss-soc-bus"; >> +ti,hwmods = "pruss"; >> +reg = <0x4a326004 0x4>; >> +#address-cells = <1>; >> +#size-cells = <1>; >> +ranges; > > The top level interconnect target module driver should be just ti-sysc > as documented in Documentation/devicetree/bindings/bus/ti-sysc.txt. > AFAIK there is nothing PRU specific there. So let's not add yet > another custom interconnect target module handling code to deal with. > > I also posted a patch a while back for using reset-simple with > ti-sysc as "[PATCHv2] reset: ti-rstctrl: use the reset-simple driver". > Cool. I will try that out. >> +pruss_cfg: cfg@4a326000 { >> +compatible = "syscon"; >> +reg = <0x4a326000 0x2000>; >> +}; >> + >> +pruss_iep: iep@4a32e000 { >> +compatible = "syscon"; >> +reg = <0x4a32e000 0x31c>; >> +}; >> + >> +pruss_mii_rt: mii_rt@4a332000 { >> +compatible = "syscon"; >> +reg = <0x4a332000 0x58>; >> +}; > > Hmm what are these syscon register actually doing? Sseems like > they should be just handled by a phy driver nowadays? Not the PHY driver but the Ethernet driver. The PHY driver will be a davinci-MDIO device node (not yet in this series). I should probably add merge that with this series. The Ethernet device tree node will reference to these syscon nodes. e.g. pruss2_eth { compatible = "ti,am57-prueth"; prus = <_0>, <_1>; firmware-name = "ti-pruss/am57xx-pru0-prueth-fw.elf", "ti-pruss/am57xx-pru1-prueth-fw.elf"; sram = <>; interrupt-parent = <_intc>; --> mii-rt = <_mii_rt>; --> iep = <_iep>; } Do you see any issues with that? > > Other than that the binding looks OK to me. Good to finally > see some activity in getting the PRU support merged :) Thanks :) cheers, -roger -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Re: [PATCH 1/3] clk: samsung: exynos5420: add VPLL rate table for g3d clock
Hi, On 2018년 11월 23일 18:44, Anand Moon wrote: > From: Marian Mihailescu > > A specific clock rate table is added for VPLL so it is possible > to set frequency of the VPLL output clock that used by the g3d clock. > > Cc: Andrzej Hajda > Cc: Chanwoo Choi > Signed-off-by: Marian Mihailescu > Signed-off-by: Anand Moon > --- > drivers/clk/samsung/clk-exynos5420.c | 13 + > 1 file changed, 13 insertions(+) > > diff --git a/drivers/clk/samsung/clk-exynos5420.c > b/drivers/clk/samsung/clk-exynos5420.c > index 34cce3c5898f..34156bdfd0d2 100644 > --- a/drivers/clk/samsung/clk-exynos5420.c > +++ b/drivers/clk/samsung/clk-exynos5420.c > @@ -1303,6 +1303,18 @@ static const struct samsung_pll_rate_table > exynos5420_epll_24mhz_tbl[] = { > PLL_36XX_RATE(24 * MHZ, 32768001U, 131, 3, 5, 4719), > }; > > +static const struct samsung_pll_rate_table exynos5420_vpll_24mhz_tbl[] > __initconst = { > + PLL_35XX_RATE(24 * MHZ, 6U, 200, 2, 2), > + PLL_35XX_RATE(24 * MHZ, 54300U, 181, 2, 2), > + PLL_35XX_RATE(24 * MHZ, 53300U, 533, 6, 2), > + PLL_35XX_RATE(24 * MHZ, 48000U, 320, 4, 2), > + PLL_35XX_RATE(24 * MHZ, 42000U, 140, 2, 2), > + PLL_35XX_RATE(24 * MHZ, 35000U, 175, 3, 2), > + PLL_35XX_RATE(24 * MHZ, 26600U, 266, 3, 3), > + PLL_35XX_RATE(24 * MHZ, 17700U, 118, 2, 3), > + PLL_35XX_RATE(24 * MHZ, 1U, 200, 3, 4), > +}; VPLL has the same PMS table with apll/kpll/bpll. You don't need to add new 'exynos5420_vpll_24mhz_tbl' table. Just adding the missing frequency entries to 'exynos5420_pll2550x_24mhz_tbl' table. > + > static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { > [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, > APLL_CON0, NULL), > @@ -1428,6 +1440,7 @@ static void __init exynos5x_clk_init(struct device_node > *np, > exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; > exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; > exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl; > + exynos5x_plls[vpll].rate_table = exynos5420_vpll_24mhz_tbl; > } > > samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls), > -- Best Regards, Chanwoo Choi Samsung Electronics
Re: [PATCH 01/17] dt-bindings: remoteproc: Add TI PRUSS bindings
Hi, On 23/11/18 18:24, Tony Lindgren wrote: > Hi, > > * Roger Quadros [181122 11:39]: >> From: Suman Anna >> +Example: >> + >> +1. /* AM33xx PRU-ICSS */ >> +pruss_soc_bus: pruss_soc_bus@4a326004 { >> +compatible = "ti,am3356-pruss-soc-bus"; >> +ti,hwmods = "pruss"; >> +reg = <0x4a326004 0x4>; >> +#address-cells = <1>; >> +#size-cells = <1>; >> +ranges; > > The top level interconnect target module driver should be just ti-sysc > as documented in Documentation/devicetree/bindings/bus/ti-sysc.txt. > AFAIK there is nothing PRU specific there. So let's not add yet > another custom interconnect target module handling code to deal with. > > I also posted a patch a while back for using reset-simple with > ti-sysc as "[PATCHv2] reset: ti-rstctrl: use the reset-simple driver". > Cool. I will try that out. >> +pruss_cfg: cfg@4a326000 { >> +compatible = "syscon"; >> +reg = <0x4a326000 0x2000>; >> +}; >> + >> +pruss_iep: iep@4a32e000 { >> +compatible = "syscon"; >> +reg = <0x4a32e000 0x31c>; >> +}; >> + >> +pruss_mii_rt: mii_rt@4a332000 { >> +compatible = "syscon"; >> +reg = <0x4a332000 0x58>; >> +}; > > Hmm what are these syscon register actually doing? Sseems like > they should be just handled by a phy driver nowadays? Not the PHY driver but the Ethernet driver. The PHY driver will be a davinci-MDIO device node (not yet in this series). I should probably add merge that with this series. The Ethernet device tree node will reference to these syscon nodes. e.g. pruss2_eth { compatible = "ti,am57-prueth"; prus = <_0>, <_1>; firmware-name = "ti-pruss/am57xx-pru0-prueth-fw.elf", "ti-pruss/am57xx-pru1-prueth-fw.elf"; sram = <>; interrupt-parent = <_intc>; --> mii-rt = <_mii_rt>; --> iep = <_iep>; } Do you see any issues with that? > > Other than that the binding looks OK to me. Good to finally > see some activity in getting the PRU support merged :) Thanks :) cheers, -roger -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Re: [PATCH 1/3] clk: samsung: exynos5420: add VPLL rate table for g3d clock
Hi, On 2018년 11월 23일 18:44, Anand Moon wrote: > From: Marian Mihailescu > > A specific clock rate table is added for VPLL so it is possible > to set frequency of the VPLL output clock that used by the g3d clock. > > Cc: Andrzej Hajda > Cc: Chanwoo Choi > Signed-off-by: Marian Mihailescu > Signed-off-by: Anand Moon > --- > drivers/clk/samsung/clk-exynos5420.c | 13 + > 1 file changed, 13 insertions(+) > > diff --git a/drivers/clk/samsung/clk-exynos5420.c > b/drivers/clk/samsung/clk-exynos5420.c > index 34cce3c5898f..34156bdfd0d2 100644 > --- a/drivers/clk/samsung/clk-exynos5420.c > +++ b/drivers/clk/samsung/clk-exynos5420.c > @@ -1303,6 +1303,18 @@ static const struct samsung_pll_rate_table > exynos5420_epll_24mhz_tbl[] = { > PLL_36XX_RATE(24 * MHZ, 32768001U, 131, 3, 5, 4719), > }; > > +static const struct samsung_pll_rate_table exynos5420_vpll_24mhz_tbl[] > __initconst = { > + PLL_35XX_RATE(24 * MHZ, 6U, 200, 2, 2), > + PLL_35XX_RATE(24 * MHZ, 54300U, 181, 2, 2), > + PLL_35XX_RATE(24 * MHZ, 53300U, 533, 6, 2), > + PLL_35XX_RATE(24 * MHZ, 48000U, 320, 4, 2), > + PLL_35XX_RATE(24 * MHZ, 42000U, 140, 2, 2), > + PLL_35XX_RATE(24 * MHZ, 35000U, 175, 3, 2), > + PLL_35XX_RATE(24 * MHZ, 26600U, 266, 3, 3), > + PLL_35XX_RATE(24 * MHZ, 17700U, 118, 2, 3), > + PLL_35XX_RATE(24 * MHZ, 1U, 200, 3, 4), > +}; VPLL has the same PMS table with apll/kpll/bpll. You don't need to add new 'exynos5420_vpll_24mhz_tbl' table. Just adding the missing frequency entries to 'exynos5420_pll2550x_24mhz_tbl' table. > + > static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { > [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, > APLL_CON0, NULL), > @@ -1428,6 +1440,7 @@ static void __init exynos5x_clk_init(struct device_node > *np, > exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; > exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; > exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl; > + exynos5x_plls[vpll].rate_table = exynos5420_vpll_24mhz_tbl; > } > > samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls), > -- Best Regards, Chanwoo Choi Samsung Electronics
[PATCH] nios2: remove unneeded HAS_DMA define
kernel/dma/Kconfig globally defines HAS_DMA as follows: config HAS_DMA bool depends on !NO_DMA default y Signed-off-by: Masahiro Yamada --- arch/nios2/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 7e95506..69c4af1 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -37,9 +37,6 @@ config GENERIC_CALIBRATE_DELAY config NO_IOPORT_MAP def_bool y -config HAS_DMA - def_bool y - config FPU def_bool n -- 2.7.4
[PATCH] nios2: remove unneeded HAS_DMA define
kernel/dma/Kconfig globally defines HAS_DMA as follows: config HAS_DMA bool depends on !NO_DMA default y Signed-off-by: Masahiro Yamada --- arch/nios2/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 7e95506..69c4af1 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -37,9 +37,6 @@ config GENERIC_CALIBRATE_DELAY config NO_IOPORT_MAP def_bool y -config HAS_DMA - def_bool y - config FPU def_bool n -- 2.7.4
Re: [PATCH] mm: do not consider SWAP to calculate available when not necessary
On 11/26/18 3:01 AM, Matthew Wilcox wrote: > On Mon, Nov 26, 2018 at 07:58:23AM +0800, Yang Yang wrote: >> When si_mem_available() calculates 'available', it takes SWAP >> into account. But if CONFIG_SWAP is N or SWAP is off(some embedded system >> would like to do that), there is no need to consider it. > > I don't understand this patch. The pagecache can be written back to > storage if it is dirty, regardless of whether there is swap space. > >> @@ -4724,9 +4726,13 @@ long si_mem_available(void) >> * Not all the page cache can be freed, otherwise the system will >> * start swapping. Assume at least half of the page cache, or the I guess the first sentence in the comment above might be misleading by using the word 'swapping', where 'thrashing' would be more accurate and unambiguous. So this is not related to the swap, but to the assumption that somebody is accessing the pages in pagecache, and if too much would be freed, most accesses would mean reading data from disk, i.e. thrashing. >> * low watermark worth of cache, needs to stay. >> + * But if CONFIG_SWAP is N or SWAP is off, do not consider it. >> */ >> pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE]; >> -pagecache -= min(pagecache / 2, wmark_low); >> +#ifdef CONFIG_SWAP >> +if (i.totalswap > 0) >> +pagecache -= min(pagecache / 2, wmark_low); >> +#endif >> available += pagecache; >> >> /* >> -- >> 2.15.2 >>
Re: [PATCH] mm: do not consider SWAP to calculate available when not necessary
On 11/26/18 3:01 AM, Matthew Wilcox wrote: > On Mon, Nov 26, 2018 at 07:58:23AM +0800, Yang Yang wrote: >> When si_mem_available() calculates 'available', it takes SWAP >> into account. But if CONFIG_SWAP is N or SWAP is off(some embedded system >> would like to do that), there is no need to consider it. > > I don't understand this patch. The pagecache can be written back to > storage if it is dirty, regardless of whether there is swap space. > >> @@ -4724,9 +4726,13 @@ long si_mem_available(void) >> * Not all the page cache can be freed, otherwise the system will >> * start swapping. Assume at least half of the page cache, or the I guess the first sentence in the comment above might be misleading by using the word 'swapping', where 'thrashing' would be more accurate and unambiguous. So this is not related to the swap, but to the assumption that somebody is accessing the pages in pagecache, and if too much would be freed, most accesses would mean reading data from disk, i.e. thrashing. >> * low watermark worth of cache, needs to stay. >> + * But if CONFIG_SWAP is N or SWAP is off, do not consider it. >> */ >> pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE]; >> -pagecache -= min(pagecache / 2, wmark_low); >> +#ifdef CONFIG_SWAP >> +if (i.totalswap > 0) >> +pagecache -= min(pagecache / 2, wmark_low); >> +#endif >> available += pagecache; >> >> /* >> -- >> 2.15.2 >>
Re: [RFC][PATCH 08/14] function_graph: Remove unused task_curr_ret_stack()
On Wed, 21 Nov 2018 20:27:16 -0500 Steven Rostedt wrote: > From: "Steven Rostedt (VMware)" > > The static inline function task_curr_ret_stack() is unused, remove it. This looks able to be applied without this series. I think we should apply this to for-next branch? Reviewed-by: Masami Hiramatsu Thanks, > > Signed-off-by: Steven Rostedt (VMware) > --- > include/linux/ftrace.h | 10 -- > 1 file changed, 10 deletions(-) > > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h > index 477ff9412d26..5544df21a886 100644 > --- a/include/linux/ftrace.h > +++ b/include/linux/ftrace.h > @@ -819,11 +819,6 @@ extern void ftrace_graph_init_task(struct task_struct > *t); > extern void ftrace_graph_exit_task(struct task_struct *t); > extern void ftrace_graph_init_idle_task(struct task_struct *t, int cpu); > > -static inline int task_curr_ret_stack(struct task_struct *t) > -{ > - return t->curr_ret_stack; > -} > - > static inline void pause_graph_tracing(void) > { > atomic_inc(>tracing_graph_pause); > @@ -847,11 +842,6 @@ static inline int register_ftrace_graph(struct > fgraph_ops *ops); > } > static inline void unregister_ftrace_graph(struct fgraph_ops *ops) { } > > -static inline int task_curr_ret_stack(struct task_struct *tsk) > -{ > - return -1; > -} > - > static inline unsigned long > ftrace_graph_ret_addr(struct task_struct *task, int *idx, unsigned long ret, > unsigned long *retp) > -- > 2.19.1 > > -- Masami Hiramatsu
Re: [RFC][PATCH 08/14] function_graph: Remove unused task_curr_ret_stack()
On Wed, 21 Nov 2018 20:27:16 -0500 Steven Rostedt wrote: > From: "Steven Rostedt (VMware)" > > The static inline function task_curr_ret_stack() is unused, remove it. This looks able to be applied without this series. I think we should apply this to for-next branch? Reviewed-by: Masami Hiramatsu Thanks, > > Signed-off-by: Steven Rostedt (VMware) > --- > include/linux/ftrace.h | 10 -- > 1 file changed, 10 deletions(-) > > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h > index 477ff9412d26..5544df21a886 100644 > --- a/include/linux/ftrace.h > +++ b/include/linux/ftrace.h > @@ -819,11 +819,6 @@ extern void ftrace_graph_init_task(struct task_struct > *t); > extern void ftrace_graph_exit_task(struct task_struct *t); > extern void ftrace_graph_init_idle_task(struct task_struct *t, int cpu); > > -static inline int task_curr_ret_stack(struct task_struct *t) > -{ > - return t->curr_ret_stack; > -} > - > static inline void pause_graph_tracing(void) > { > atomic_inc(>tracing_graph_pause); > @@ -847,11 +842,6 @@ static inline int register_ftrace_graph(struct > fgraph_ops *ops); > } > static inline void unregister_ftrace_graph(struct fgraph_ops *ops) { } > > -static inline int task_curr_ret_stack(struct task_struct *tsk) > -{ > - return -1; > -} > - > static inline unsigned long > ftrace_graph_ret_addr(struct task_struct *task, int *idx, unsigned long ret, > unsigned long *retp) > -- > 2.19.1 > > -- Masami Hiramatsu
Re: [PATCH 3/3] ARM: dts: Add g3d bus nodes using VDD_INT for Exynos542x SoC
Hi Anand, CLK_DOUT_ACLK_G3D is the clock for GPU h/w and it requires the buck4_reg("vdd_g3d"). bus_wcore uses the buck3_reg("vdd_int"). bus_wcore and bus_g3d don't share the same voltage line. It is wrong to make 'bus_g3d' as the child of 'bus_wcore' because of using the different regulator. CLK_DOUT_ACLK_G3D and buck4_reg should be controlled from MALI driver with DEVFREQ framework. Unfortunately, MALI driver is not posted to mainline. On 2018년 11월 23일 18:44, Anand Moon wrote: > Add missing Netwwork on chip for g3d bus node using VDD_INI > for Exynos542x SoC. > > - CLK_DOUT_ACLK_G3D for G3D's AXI > > Cc: Chanwoo Choi > Signed-off-by: Anand Moon > --- > arch/arm/boot/dts/exynos5420.dtsi | 57 +-- > arch/arm/boot/dts/exynos5422-odroid-core.dtsi | 5 ++ > 2 files changed, 56 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/boot/dts/exynos5420.dtsi > b/arch/arm/boot/dts/exynos5420.dtsi > index aaff15880761..bc7203bb1282 100644 > --- a/arch/arm/boot/dts/exynos5420.dtsi > +++ b/arch/arm/boot/dts/exynos5420.dtsi > @@ -1047,6 +1047,14 @@ > status = "disabled"; > }; > > + bus_g3d: bus_g3d { > + compatible = "samsung,exynos-bus"; > + clocks = < CLK_DOUT_ACLK_G3D>; > + clock-names = "bus"; > + operating-points-v2 = <_g3d_opp_table>; > + status = "disabled"; > + }; > + > bus_jpeg: bus_jpeg { > compatible = "samsung,exynos-bus"; > clocks = < CLK_DOUT_ACLK300_JPEG>; > @@ -1245,7 +1253,44 @@ > }; > }; > > - bus_jpeg_opp_table: opp_table11 { > + bus_g3d_opp_table: opp_table11 { > + compatible = "operating-points-v2"; > + > + opp@6 { > + opp-hz = /bits/ 64 <6>; > + opp-microvolt = <1025000>; > + }; > + opp@54300 { > + opp-hz = /bits/ 64 <54300>; > + opp-microvolt = <987500>; > + }; > + opp@48000 { > + opp-hz = /bits/ 64 <48000>; > + opp-microvolt = <95>; > + }; > + opp@42000 { > + opp-hz = /bits/ 64 <42000>; > + opp-microvolt = <937500>; > + }; > + opp@35000 { > + opp-hz = /bits/ 64 <35000>; > + opp-microvolt = <90>; > + }; > + opp@26600 { > + opp-hz = /bits/ 64 <26600>; > + opp-microvolt = <862500>; > + }; > + opp@17700 { > + opp-hz = /bits/ 64 <17700>; > + opp-microvolt = <862500>; > + }; > + opp@1 { > + opp-hz = /bits/ 64 <1>; > + opp-microvolt = <862500>; > + }; > + }; > + > + bus_jpeg_opp_table: opp_table12 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1262,7 +1307,7 @@ > }; > }; > > - bus_jpeg_apb_opp_table: opp_table12 { > + bus_jpeg_apb_opp_table: opp_table13 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1279,7 +1324,7 @@ > }; > }; > > - bus_disp1_fimd_opp_table: opp_table13 { > + bus_disp1_fimd_opp_table: opp_table14 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1290,7 +1335,7 @@ > }; > }; > > - bus_disp1_opp_table: opp_table14 { > + bus_disp1_opp_table: opp_table15 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1304,7 +1349,7 @@ > }; > }; > > - bus_gscl_opp_table: opp_table15 { > + bus_gscl_opp_table: opp_table16 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1318,7 +1363,7 @@ > }; > }; > > - bus_mscl_opp_table: opp_table16 { > + bus_mscl_opp_table: opp_table17 { > compatible = "operating-points-v2"; > > opp00 { > diff --git
Re: [PATCH 3/3] ARM: dts: Add g3d bus nodes using VDD_INT for Exynos542x SoC
Hi Anand, CLK_DOUT_ACLK_G3D is the clock for GPU h/w and it requires the buck4_reg("vdd_g3d"). bus_wcore uses the buck3_reg("vdd_int"). bus_wcore and bus_g3d don't share the same voltage line. It is wrong to make 'bus_g3d' as the child of 'bus_wcore' because of using the different regulator. CLK_DOUT_ACLK_G3D and buck4_reg should be controlled from MALI driver with DEVFREQ framework. Unfortunately, MALI driver is not posted to mainline. On 2018년 11월 23일 18:44, Anand Moon wrote: > Add missing Netwwork on chip for g3d bus node using VDD_INI > for Exynos542x SoC. > > - CLK_DOUT_ACLK_G3D for G3D's AXI > > Cc: Chanwoo Choi > Signed-off-by: Anand Moon > --- > arch/arm/boot/dts/exynos5420.dtsi | 57 +-- > arch/arm/boot/dts/exynos5422-odroid-core.dtsi | 5 ++ > 2 files changed, 56 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/boot/dts/exynos5420.dtsi > b/arch/arm/boot/dts/exynos5420.dtsi > index aaff15880761..bc7203bb1282 100644 > --- a/arch/arm/boot/dts/exynos5420.dtsi > +++ b/arch/arm/boot/dts/exynos5420.dtsi > @@ -1047,6 +1047,14 @@ > status = "disabled"; > }; > > + bus_g3d: bus_g3d { > + compatible = "samsung,exynos-bus"; > + clocks = < CLK_DOUT_ACLK_G3D>; > + clock-names = "bus"; > + operating-points-v2 = <_g3d_opp_table>; > + status = "disabled"; > + }; > + > bus_jpeg: bus_jpeg { > compatible = "samsung,exynos-bus"; > clocks = < CLK_DOUT_ACLK300_JPEG>; > @@ -1245,7 +1253,44 @@ > }; > }; > > - bus_jpeg_opp_table: opp_table11 { > + bus_g3d_opp_table: opp_table11 { > + compatible = "operating-points-v2"; > + > + opp@6 { > + opp-hz = /bits/ 64 <6>; > + opp-microvolt = <1025000>; > + }; > + opp@54300 { > + opp-hz = /bits/ 64 <54300>; > + opp-microvolt = <987500>; > + }; > + opp@48000 { > + opp-hz = /bits/ 64 <48000>; > + opp-microvolt = <95>; > + }; > + opp@42000 { > + opp-hz = /bits/ 64 <42000>; > + opp-microvolt = <937500>; > + }; > + opp@35000 { > + opp-hz = /bits/ 64 <35000>; > + opp-microvolt = <90>; > + }; > + opp@26600 { > + opp-hz = /bits/ 64 <26600>; > + opp-microvolt = <862500>; > + }; > + opp@17700 { > + opp-hz = /bits/ 64 <17700>; > + opp-microvolt = <862500>; > + }; > + opp@1 { > + opp-hz = /bits/ 64 <1>; > + opp-microvolt = <862500>; > + }; > + }; > + > + bus_jpeg_opp_table: opp_table12 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1262,7 +1307,7 @@ > }; > }; > > - bus_jpeg_apb_opp_table: opp_table12 { > + bus_jpeg_apb_opp_table: opp_table13 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1279,7 +1324,7 @@ > }; > }; > > - bus_disp1_fimd_opp_table: opp_table13 { > + bus_disp1_fimd_opp_table: opp_table14 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1290,7 +1335,7 @@ > }; > }; > > - bus_disp1_opp_table: opp_table14 { > + bus_disp1_opp_table: opp_table15 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1304,7 +1349,7 @@ > }; > }; > > - bus_gscl_opp_table: opp_table15 { > + bus_gscl_opp_table: opp_table16 { > compatible = "operating-points-v2"; > > opp00 { > @@ -1318,7 +1363,7 @@ > }; > }; > > - bus_mscl_opp_table: opp_table16 { > + bus_mscl_opp_table: opp_table17 { > compatible = "operating-points-v2"; > > opp00 { > diff --git
Re: [PATCH v3 7/7] staging:iio:ad2s90: Move out of staging
On Fri, 2018-11-23 at 22:23 -0200, Matheus Tavares wrote: > Move ad2s90 resolver driver out of staging to the main tree. > Acked-by: Alexandru Ardelean > Signed-off-by: Matheus Tavares > Signed-off-by: Victor Colombo > --- > Changes in v3: > - none > > Changes in v2: > - Disabled git move detection, to see the whole code, as Jonathan > suggested > > drivers/iio/resolver/Kconfig | 10 ++ > drivers/iio/resolver/Makefile | 1 + > drivers/iio/resolver/ad2s90.c | 131 ++ > drivers/staging/iio/resolver/Kconfig | 10 -- > drivers/staging/iio/resolver/Makefile | 1 - > drivers/staging/iio/resolver/ad2s90.c | 131 -- > 6 files changed, 142 insertions(+), 142 deletions(-) > create mode 100644 drivers/iio/resolver/ad2s90.c > delete mode 100644 drivers/staging/iio/resolver/ad2s90.c > > diff --git a/drivers/iio/resolver/Kconfig b/drivers/iio/resolver/Kconfig > index 2ced9f22aa70..786801be54f6 100644 > --- a/drivers/iio/resolver/Kconfig > +++ b/drivers/iio/resolver/Kconfig > @@ -3,6 +3,16 @@ > # > menu "Resolver to digital converters" > > +config AD2S90 > + tristate "Analog Devices ad2s90 driver" > + depends on SPI > + help > + Say yes here to build support for Analog Devices spi resolver > + to digital converters, ad2s90, provides direct access via sysfs. > + > + To compile this driver as a module, choose M here: the > + module will be called ad2s90. > + > config AD2S1200 > tristate "Analog Devices ad2s1200/ad2s1205 driver" > depends on SPI > diff --git a/drivers/iio/resolver/Makefile > b/drivers/iio/resolver/Makefile > index 4e1dccae07e7..398d82d50028 100644 > --- a/drivers/iio/resolver/Makefile > +++ b/drivers/iio/resolver/Makefile > @@ -2,4 +2,5 @@ > # Makefile for Resolver/Synchro drivers > # > > +obj-$(CONFIG_AD2S90) += ad2s90.o > obj-$(CONFIG_AD2S1200) += ad2s1200.o > diff --git a/drivers/iio/resolver/ad2s90.c > b/drivers/iio/resolver/ad2s90.c > new file mode 100644 > index ..a41f5cb10da5 > --- /dev/null > +++ b/drivers/iio/resolver/ad2s90.c > @@ -0,0 +1,131 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * ad2s90.c simple support for the ADI Resolver to Digital Converters: > AD2S90 > + * > + * Copyright (c) 2010-2010 Analog Devices Inc. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +/* > + * Although chip's max frequency is 2Mhz, it needs 600ns between CS and > the > + * first falling edge of SCLK, so frequency should be at most 1 / (2 * > 6e-7) > + */ > +#define AD2S90_MAX_SPI_FREQ_HZ 83 > + > +struct ad2s90_state { > + struct mutex lock; /* lock to protect rx buffer */ > + struct spi_device *sdev; > + u8 rx[2] cacheline_aligned; > +}; > + > +static int ad2s90_read_raw(struct iio_dev *indio_dev, > +struct iio_chan_spec const *chan, > +int *val, > +int *val2, > +long m) > +{ > + int ret; > + struct ad2s90_state *st = iio_priv(indio_dev); > + > + if (chan->type != IIO_ANGL) > + return -EINVAL; > + > + switch (m) { > + case IIO_CHAN_INFO_SCALE: > + /* 2 * Pi / 2^12 */ > + *val = 6283; /* mV */ > + *val2 = 12; > + return IIO_VAL_FRACTIONAL_LOG2; > + case IIO_CHAN_INFO_RAW: > + mutex_lock(>lock); > + ret = spi_read(st->sdev, st->rx, 2); > + if (ret < 0) { > + mutex_unlock(>lock); > + return ret; > + } > + *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> > 4); > + > + mutex_unlock(>lock); > + > + return IIO_VAL_INT; > + default: > + break; > + } > + > + return -EINVAL; > +} > + > +static const struct iio_info ad2s90_info = { > + .read_raw = ad2s90_read_raw, > +}; > + > +static const struct iio_chan_spec ad2s90_chan = { > + .type = IIO_ANGL, > + .indexed = 1, > + .channel = 0, > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | > BIT(IIO_CHAN_INFO_SCALE), > +}; > + > +static int ad2s90_probe(struct spi_device *spi) > +{ > + struct iio_dev *indio_dev; > + struct ad2s90_state *st; > + > + if (spi->max_speed_hz > AD2S90_MAX_SPI_FREQ_HZ) { > + dev_err(>dev, "SPI CLK, %d Hz exceeds %d Hz\n", > + spi->max_speed_hz, AD2S90_MAX_SPI_FREQ_HZ); > + return -EINVAL; > + } > + > + indio_dev = devm_iio_device_alloc(>dev, sizeof(*st)); > + if (!indio_dev) > + return -ENOMEM; > + st = iio_priv(indio_dev); > + spi_set_drvdata(spi, indio_dev); > + > + mutex_init(>lock); > + st->sdev = spi; > + indio_dev->dev.parent = >dev; > + indio_dev->info = _info; > + indio_dev->modes = INDIO_DIRECT_MODE; > +
Re: [PATCH v3 7/7] staging:iio:ad2s90: Move out of staging
On Fri, 2018-11-23 at 22:23 -0200, Matheus Tavares wrote: > Move ad2s90 resolver driver out of staging to the main tree. > Acked-by: Alexandru Ardelean > Signed-off-by: Matheus Tavares > Signed-off-by: Victor Colombo > --- > Changes in v3: > - none > > Changes in v2: > - Disabled git move detection, to see the whole code, as Jonathan > suggested > > drivers/iio/resolver/Kconfig | 10 ++ > drivers/iio/resolver/Makefile | 1 + > drivers/iio/resolver/ad2s90.c | 131 ++ > drivers/staging/iio/resolver/Kconfig | 10 -- > drivers/staging/iio/resolver/Makefile | 1 - > drivers/staging/iio/resolver/ad2s90.c | 131 -- > 6 files changed, 142 insertions(+), 142 deletions(-) > create mode 100644 drivers/iio/resolver/ad2s90.c > delete mode 100644 drivers/staging/iio/resolver/ad2s90.c > > diff --git a/drivers/iio/resolver/Kconfig b/drivers/iio/resolver/Kconfig > index 2ced9f22aa70..786801be54f6 100644 > --- a/drivers/iio/resolver/Kconfig > +++ b/drivers/iio/resolver/Kconfig > @@ -3,6 +3,16 @@ > # > menu "Resolver to digital converters" > > +config AD2S90 > + tristate "Analog Devices ad2s90 driver" > + depends on SPI > + help > + Say yes here to build support for Analog Devices spi resolver > + to digital converters, ad2s90, provides direct access via sysfs. > + > + To compile this driver as a module, choose M here: the > + module will be called ad2s90. > + > config AD2S1200 > tristate "Analog Devices ad2s1200/ad2s1205 driver" > depends on SPI > diff --git a/drivers/iio/resolver/Makefile > b/drivers/iio/resolver/Makefile > index 4e1dccae07e7..398d82d50028 100644 > --- a/drivers/iio/resolver/Makefile > +++ b/drivers/iio/resolver/Makefile > @@ -2,4 +2,5 @@ > # Makefile for Resolver/Synchro drivers > # > > +obj-$(CONFIG_AD2S90) += ad2s90.o > obj-$(CONFIG_AD2S1200) += ad2s1200.o > diff --git a/drivers/iio/resolver/ad2s90.c > b/drivers/iio/resolver/ad2s90.c > new file mode 100644 > index ..a41f5cb10da5 > --- /dev/null > +++ b/drivers/iio/resolver/ad2s90.c > @@ -0,0 +1,131 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * ad2s90.c simple support for the ADI Resolver to Digital Converters: > AD2S90 > + * > + * Copyright (c) 2010-2010 Analog Devices Inc. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +/* > + * Although chip's max frequency is 2Mhz, it needs 600ns between CS and > the > + * first falling edge of SCLK, so frequency should be at most 1 / (2 * > 6e-7) > + */ > +#define AD2S90_MAX_SPI_FREQ_HZ 83 > + > +struct ad2s90_state { > + struct mutex lock; /* lock to protect rx buffer */ > + struct spi_device *sdev; > + u8 rx[2] cacheline_aligned; > +}; > + > +static int ad2s90_read_raw(struct iio_dev *indio_dev, > +struct iio_chan_spec const *chan, > +int *val, > +int *val2, > +long m) > +{ > + int ret; > + struct ad2s90_state *st = iio_priv(indio_dev); > + > + if (chan->type != IIO_ANGL) > + return -EINVAL; > + > + switch (m) { > + case IIO_CHAN_INFO_SCALE: > + /* 2 * Pi / 2^12 */ > + *val = 6283; /* mV */ > + *val2 = 12; > + return IIO_VAL_FRACTIONAL_LOG2; > + case IIO_CHAN_INFO_RAW: > + mutex_lock(>lock); > + ret = spi_read(st->sdev, st->rx, 2); > + if (ret < 0) { > + mutex_unlock(>lock); > + return ret; > + } > + *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> > 4); > + > + mutex_unlock(>lock); > + > + return IIO_VAL_INT; > + default: > + break; > + } > + > + return -EINVAL; > +} > + > +static const struct iio_info ad2s90_info = { > + .read_raw = ad2s90_read_raw, > +}; > + > +static const struct iio_chan_spec ad2s90_chan = { > + .type = IIO_ANGL, > + .indexed = 1, > + .channel = 0, > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | > BIT(IIO_CHAN_INFO_SCALE), > +}; > + > +static int ad2s90_probe(struct spi_device *spi) > +{ > + struct iio_dev *indio_dev; > + struct ad2s90_state *st; > + > + if (spi->max_speed_hz > AD2S90_MAX_SPI_FREQ_HZ) { > + dev_err(>dev, "SPI CLK, %d Hz exceeds %d Hz\n", > + spi->max_speed_hz, AD2S90_MAX_SPI_FREQ_HZ); > + return -EINVAL; > + } > + > + indio_dev = devm_iio_device_alloc(>dev, sizeof(*st)); > + if (!indio_dev) > + return -ENOMEM; > + st = iio_priv(indio_dev); > + spi_set_drvdata(spi, indio_dev); > + > + mutex_init(>lock); > + st->sdev = spi; > + indio_dev->dev.parent = >dev; > + indio_dev->info = _info; > + indio_dev->modes = INDIO_DIRECT_MODE; > +
Re: [RFC][PATCH 06/14] fgraph: Move function graph specific code into fgraph.c
On Thu, 22 Nov 2018 22:11:33 -0800 Joel Fernandes wrote: > On Wed, Nov 21, 2018 at 08:27:14PM -0500, Steven Rostedt wrote: > > From: "Steven Rostedt (VMware)" > > > > To make the function graph infrastructure more managable, the code needs to > > be in its own file (fgraph.c). Move the code that is specific for managing > > the function graph infrastructure out of ftrace.c and into fgraph.c > > > > Signed-off-by: Steven Rostedt (VMware) > > I think this patch causes a build error if CONFIG_FUNCTION_PROFILER is > disabled but function graph is enabled. The following diff fixes it for me. Good catch, I also confirmed it. I think we'd better to define an empty stub of ftrace_graph_graph_time_control(enable) in trace.h instead, since fgraph_graph_time is not used if CONFIG_FUNCTION_PROFILER=n. Thank you, > > thanks, > > - Joel > > 8<-- > > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c > index 3b8c307c7ff0..ce38bb962f91 100644 > --- a/kernel/trace/ftrace.c > +++ b/kernel/trace/ftrace.c > @@ -382,6 +382,15 @@ static void ftrace_update_pid_func(void) > update_ftrace_function(); > } > > +#ifdef CONFIG_FUNCTION_GRAPH_TRACER > +static bool fgraph_graph_time = true; > + > +void ftrace_graph_graph_time_control(bool enable) > +{ > + fgraph_graph_time = enable; > +} > +#endif > + > #ifdef CONFIG_FUNCTION_PROFILER > struct ftrace_profile { > struct hlist_node node; > @@ -783,12 +792,6 @@ function_profile_call(unsigned long ip, unsigned long > parent_ip, > } > > #ifdef CONFIG_FUNCTION_GRAPH_TRACER > -static bool fgraph_graph_time = true; > - > -void ftrace_graph_graph_time_control(bool enable) > -{ > - fgraph_graph_time = enable; > -} > > static int profile_graph_entry(struct ftrace_graph_ent *trace) > { -- Masami Hiramatsu
Re: [RFC][PATCH 06/14] fgraph: Move function graph specific code into fgraph.c
On Thu, 22 Nov 2018 22:11:33 -0800 Joel Fernandes wrote: > On Wed, Nov 21, 2018 at 08:27:14PM -0500, Steven Rostedt wrote: > > From: "Steven Rostedt (VMware)" > > > > To make the function graph infrastructure more managable, the code needs to > > be in its own file (fgraph.c). Move the code that is specific for managing > > the function graph infrastructure out of ftrace.c and into fgraph.c > > > > Signed-off-by: Steven Rostedt (VMware) > > I think this patch causes a build error if CONFIG_FUNCTION_PROFILER is > disabled but function graph is enabled. The following diff fixes it for me. Good catch, I also confirmed it. I think we'd better to define an empty stub of ftrace_graph_graph_time_control(enable) in trace.h instead, since fgraph_graph_time is not used if CONFIG_FUNCTION_PROFILER=n. Thank you, > > thanks, > > - Joel > > 8<-- > > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c > index 3b8c307c7ff0..ce38bb962f91 100644 > --- a/kernel/trace/ftrace.c > +++ b/kernel/trace/ftrace.c > @@ -382,6 +382,15 @@ static void ftrace_update_pid_func(void) > update_ftrace_function(); > } > > +#ifdef CONFIG_FUNCTION_GRAPH_TRACER > +static bool fgraph_graph_time = true; > + > +void ftrace_graph_graph_time_control(bool enable) > +{ > + fgraph_graph_time = enable; > +} > +#endif > + > #ifdef CONFIG_FUNCTION_PROFILER > struct ftrace_profile { > struct hlist_node node; > @@ -783,12 +792,6 @@ function_profile_call(unsigned long ip, unsigned long > parent_ip, > } > > #ifdef CONFIG_FUNCTION_GRAPH_TRACER > -static bool fgraph_graph_time = true; > - > -void ftrace_graph_graph_time_control(bool enable) > -{ > - fgraph_graph_time = enable; > -} > > static int profile_graph_entry(struct ftrace_graph_ent *trace) > { -- Masami Hiramatsu
[PATCH 1/2] kconfig: fix reverse dependency with tristate if-conditional
A Kconfig property can have an optional if-expression, which describes its visibility. The property is visible when the if-expression part is evaluated to 'y' or 'm'. The 'select' and 'imply' properties are internally converted to reverse dependencies, but they are wrongly converted if they have a tristate if-expression. Example: config A tristate "a" config B tristate "b" select A if C config C tristate "c" Currently, the reverse dependency of 'A' results in 'B && C'. It is incorrect because the combination of B=y and C=m allows 'A' to become 'm', while its lower limit must be 'y'. The reverse dependency should be 'B && C != n'. Randy Dunlap reported that people are trying to fix an individual Kconfig file [1], and I also found another example in the past, commit 9d9c98e89ee2 ("pcmcia: fix yenta dependency on PCCARD_NONSTATIC") but I suspect this is a bug of Kconfig itself. [1] https://www.spinics.net/lists/netfilter-devel/msg56985.html Reported-by: Taehee Yoo Reported-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/menu.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4cf15d4..2b18833 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -401,11 +401,13 @@ void menu_finalize(struct menu *parent) if (prop->type == P_SELECT) { struct symbol *es = prop_get_symbol(prop); es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + expr_alloc_and(expr_alloc_symbol(menu->sym), + expr_trans_compare(dep, E_UNEQUAL, _no))); } else if (prop->type == P_IMPLY) { struct symbol *es = prop_get_symbol(prop); es->implied.expr = expr_alloc_or(es->implied.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + expr_alloc_and(expr_alloc_symbol(menu->sym), + expr_trans_compare(dep, E_UNEQUAL, _no))); } } } -- 2.7.4
[PATCH 1/2] kconfig: fix reverse dependency with tristate if-conditional
A Kconfig property can have an optional if-expression, which describes its visibility. The property is visible when the if-expression part is evaluated to 'y' or 'm'. The 'select' and 'imply' properties are internally converted to reverse dependencies, but they are wrongly converted if they have a tristate if-expression. Example: config A tristate "a" config B tristate "b" select A if C config C tristate "c" Currently, the reverse dependency of 'A' results in 'B && C'. It is incorrect because the combination of B=y and C=m allows 'A' to become 'm', while its lower limit must be 'y'. The reverse dependency should be 'B && C != n'. Randy Dunlap reported that people are trying to fix an individual Kconfig file [1], and I also found another example in the past, commit 9d9c98e89ee2 ("pcmcia: fix yenta dependency on PCCARD_NONSTATIC") but I suspect this is a bug of Kconfig itself. [1] https://www.spinics.net/lists/netfilter-devel/msg56985.html Reported-by: Taehee Yoo Reported-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/menu.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4cf15d4..2b18833 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -401,11 +401,13 @@ void menu_finalize(struct menu *parent) if (prop->type == P_SELECT) { struct symbol *es = prop_get_symbol(prop); es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + expr_alloc_and(expr_alloc_symbol(menu->sym), + expr_trans_compare(dep, E_UNEQUAL, _no))); } else if (prop->type == P_IMPLY) { struct symbol *es = prop_get_symbol(prop); es->implied.expr = expr_alloc_or(es->implied.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + expr_alloc_and(expr_alloc_symbol(menu->sym), + expr_trans_compare(dep, E_UNEQUAL, _no))); } } } -- 2.7.4
[PATCH 2/2] kconfig: tests: test reverse dependency with tristate if-conditional
Add a test-case for the fixed reverse dependency handling. Signed-off-by: Masahiro Yamada --- .../kconfig/tests/revdep_with_tristate_if/Kconfig | 21 + .../tests/revdep_with_tristate_if/__init__.py | 14 ++ .../tests/revdep_with_tristate_if/expected_config | 9 + 3 files changed, 44 insertions(+) create mode 100644 scripts/kconfig/tests/revdep_with_tristate_if/Kconfig create mode 100644 scripts/kconfig/tests/revdep_with_tristate_if/__init__.py create mode 100644 scripts/kconfig/tests/revdep_with_tristate_if/expected_config diff --git a/scripts/kconfig/tests/revdep_with_tristate_if/Kconfig b/scripts/kconfig/tests/revdep_with_tristate_if/Kconfig new file mode 100644 index 000..2bd1141 --- /dev/null +++ b/scripts/kconfig/tests/revdep_with_tristate_if/Kconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 + +config MODULES + def_bool y + option modules + +config A + tristate + +config B + tristate "b" + default y + select A if C + imply D if C + +config C + tristate "c" + default m + +config D + tristate "d" diff --git a/scripts/kconfig/tests/revdep_with_tristate_if/__init__.py b/scripts/kconfig/tests/revdep_with_tristate_if/__init__.py new file mode 100644 index 000..ad95cec --- /dev/null +++ b/scripts/kconfig/tests/revdep_with_tristate_if/__init__.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +select/imply property with tristate if-conditional + +The reverse dependencies (select/imply) are used to define a lower limit +of another symbol. The current value of the selector is set to the lower +limit of the selectee. This did not handled correctly in the past when the +property has a tristate if-conditional. +""" + + +def test(conf): +assert conf.alldefconfig() == 0 +assert conf.config_matches('expected_config') diff --git a/scripts/kconfig/tests/revdep_with_tristate_if/expected_config b/scripts/kconfig/tests/revdep_with_tristate_if/expected_config new file mode 100644 index 000..9826223 --- /dev/null +++ b/scripts/kconfig/tests/revdep_with_tristate_if/expected_config @@ -0,0 +1,9 @@ +# +# Automatically generated file; DO NOT EDIT. +# Main menu +# +CONFIG_MODULES=y +CONFIG_A=y +CONFIG_B=y +CONFIG_C=m +CONFIG_D=y -- 2.7.4
[PATCH 2/2] kconfig: tests: test reverse dependency with tristate if-conditional
Add a test-case for the fixed reverse dependency handling. Signed-off-by: Masahiro Yamada --- .../kconfig/tests/revdep_with_tristate_if/Kconfig | 21 + .../tests/revdep_with_tristate_if/__init__.py | 14 ++ .../tests/revdep_with_tristate_if/expected_config | 9 + 3 files changed, 44 insertions(+) create mode 100644 scripts/kconfig/tests/revdep_with_tristate_if/Kconfig create mode 100644 scripts/kconfig/tests/revdep_with_tristate_if/__init__.py create mode 100644 scripts/kconfig/tests/revdep_with_tristate_if/expected_config diff --git a/scripts/kconfig/tests/revdep_with_tristate_if/Kconfig b/scripts/kconfig/tests/revdep_with_tristate_if/Kconfig new file mode 100644 index 000..2bd1141 --- /dev/null +++ b/scripts/kconfig/tests/revdep_with_tristate_if/Kconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 + +config MODULES + def_bool y + option modules + +config A + tristate + +config B + tristate "b" + default y + select A if C + imply D if C + +config C + tristate "c" + default m + +config D + tristate "d" diff --git a/scripts/kconfig/tests/revdep_with_tristate_if/__init__.py b/scripts/kconfig/tests/revdep_with_tristate_if/__init__.py new file mode 100644 index 000..ad95cec --- /dev/null +++ b/scripts/kconfig/tests/revdep_with_tristate_if/__init__.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +select/imply property with tristate if-conditional + +The reverse dependencies (select/imply) are used to define a lower limit +of another symbol. The current value of the selector is set to the lower +limit of the selectee. This did not handled correctly in the past when the +property has a tristate if-conditional. +""" + + +def test(conf): +assert conf.alldefconfig() == 0 +assert conf.config_matches('expected_config') diff --git a/scripts/kconfig/tests/revdep_with_tristate_if/expected_config b/scripts/kconfig/tests/revdep_with_tristate_if/expected_config new file mode 100644 index 000..9826223 --- /dev/null +++ b/scripts/kconfig/tests/revdep_with_tristate_if/expected_config @@ -0,0 +1,9 @@ +# +# Automatically generated file; DO NOT EDIT. +# Main menu +# +CONFIG_MODULES=y +CONFIG_A=y +CONFIG_B=y +CONFIG_C=m +CONFIG_D=y -- 2.7.4
Re: [patch V2 21/28] x86/speculation: Prepare for conditional IBPB in switch_mm()
On Sun, 25 Nov 2018, Andy Lutomirski wrote: > > On Nov 25, 2018, at 2:20 PM, Thomas Gleixner wrote: > > On Sun, 25 Nov 2018, Andi Kleen wrote: > > > >>> The current check whether two tasks belong to the same context is using > >>> the > >>> tasks context id. While correct, it's simpler to use the mm pointer > >>> because > >>> it allows to mangle the TIF_SPEC_IB bit into it. The context id based > >>> mechanism requires extra storage, which creates worse code. > >> > >> [We tried similar in some really early versions, but it was replaced > >> with the context id later.] > >> > >> One issue with using the pointer is that the pointer can be reused > >> when the original mm_struct is freed, and then gets reallocated > >> immediately to an attacker. Then the attacker may avoid the IBPB. > >> > >> Given it's probably hard to generate any reasonable leak bandwidth with > >> such a complex scenario, but it still seemed better to close the hole. > > > > Sorry, but that's really a purely academic exercise. > > I would guess that it’s actually very easy to force mm_struct* reuse. > Don’t the various allocators try to allocate hot memory? There’s nothing > hotter than a just-freed allocation of the same size. Sure, but this is about a indirect branch predictor attack against something which reuses the mm. So you'd need to pull off: P1 poisons branch predictor P1 exit P2 starts and resuses mm(P1) and uses the poisoned branch predictor the only thing between P1 and P2 is either idle or some other kernel thread, but no other user task. If that happens then the code would not issue IBPB as it assumes to switch back to the same process. Even if you can pull that off the speculation would hit the startup code of P2, which is truly a source of secret information. Creating a valuable attack based on mm reuse is really less proabable than a lottery jackpot. So using mm is really good enough and results in better assembly code which is surely more valuable than addressing some hypothetical hole. Thanks, tglx
Re: [patch V2 21/28] x86/speculation: Prepare for conditional IBPB in switch_mm()
On Sun, 25 Nov 2018, Andy Lutomirski wrote: > > On Nov 25, 2018, at 2:20 PM, Thomas Gleixner wrote: > > On Sun, 25 Nov 2018, Andi Kleen wrote: > > > >>> The current check whether two tasks belong to the same context is using > >>> the > >>> tasks context id. While correct, it's simpler to use the mm pointer > >>> because > >>> it allows to mangle the TIF_SPEC_IB bit into it. The context id based > >>> mechanism requires extra storage, which creates worse code. > >> > >> [We tried similar in some really early versions, but it was replaced > >> with the context id later.] > >> > >> One issue with using the pointer is that the pointer can be reused > >> when the original mm_struct is freed, and then gets reallocated > >> immediately to an attacker. Then the attacker may avoid the IBPB. > >> > >> Given it's probably hard to generate any reasonable leak bandwidth with > >> such a complex scenario, but it still seemed better to close the hole. > > > > Sorry, but that's really a purely academic exercise. > > I would guess that it’s actually very easy to force mm_struct* reuse. > Don’t the various allocators try to allocate hot memory? There’s nothing > hotter than a just-freed allocation of the same size. Sure, but this is about a indirect branch predictor attack against something which reuses the mm. So you'd need to pull off: P1 poisons branch predictor P1 exit P2 starts and resuses mm(P1) and uses the poisoned branch predictor the only thing between P1 and P2 is either idle or some other kernel thread, but no other user task. If that happens then the code would not issue IBPB as it assumes to switch back to the same process. Even if you can pull that off the speculation would hit the startup code of P2, which is truly a source of secret information. Creating a valuable attack based on mm reuse is really less proabable than a lottery jackpot. So using mm is really good enough and results in better assembly code which is surely more valuable than addressing some hypothetical hole. Thanks, tglx
Re: [GIT PULL] PHY: for 4.20 -rc
On Fri, Nov 23, 2018 at 04:00:08PM +0530, Kishon Vijay Abraham I wrote: > Hi Greg, > > Please find the pull request for 4.20 -rc below. > > It includes tuning parameter fix in qcom-qusb2 PHY driver, dt-bindings fix > for phy-qcom-qmp and a fix for randconfig error in uniphier-pcie. > > Consider merging this in the -rc cycle. > > Thanks > Kishon > > The following changes since commit 651022382c7f8da46cb4872a545ee1da6d097d2a: > > Linux 4.20-rc1 (2018-11-04 15:37:52 -0800) > > are available in the Git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git > tags/phy-for-4.20-rc Pulled and pushed out, thanks. greg k-h
[PATCH v2 4/4] net: macb: Add support for suspend/resume with full power down
When macb device is suspended and system is powered down, the clocks are removed and hence macb should be closed gracefully and restored upon resume. This patch does the same by switching off the net device, suspending phy and performing necessary cleanup of interrupts and BDs. Upon resume, all these are reinitialized again. Reset of macb device is done only when GEM is not a wake device. Even when gem is a wake device, tx queues can be stopped and ptp device can be closed (tsu clock will be disabled in pm_runtime_suspend) as wake event detection has no dependency on this. Signed-off-by: Kedareswara rao Appana Signed-off-by: Harini Katakam --- v2 changes: Fixed parameter passed to phy calls. drivers/net/ethernet/cadence/macb_main.c | 38 ++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 4b85ad7..dcb0194 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -4249,16 +4249,33 @@ static int __maybe_unused macb_suspend(struct device *dev) { struct net_device *netdev = dev_get_drvdata(dev); struct macb *bp = netdev_priv(netdev); + struct macb_queue *queue = bp->queues; + unsigned long flags; + unsigned int q; + + if (!netif_running(netdev)) + return 0; - netif_carrier_off(netdev); - netif_device_detach(netdev); if (bp->wol & MACB_WOL_ENABLED) { macb_writel(bp, IER, MACB_BIT(WOL)); macb_writel(bp, WOL, MACB_BIT(MAG)); enable_irq_wake(bp->queues[0].irq); + netif_device_detach(netdev); + } else { + netif_device_detach(netdev); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + napi_disable(>napi); + phy_stop(netdev->phydev); + phy_suspend(netdev->phydev); + spin_lock_irqsave(>lock, flags); + macb_reset_hw(bp); + spin_unlock_irqrestore(>lock, flags); } + netif_carrier_off(netdev); + if (bp->ptp_info) + bp->ptp_info->ptp_remove(netdev); pm_runtime_force_suspend(dev); return 0; @@ -4268,6 +4285,11 @@ static int __maybe_unused macb_resume(struct device *dev) { struct net_device *netdev = dev_get_drvdata(dev); struct macb *bp = netdev_priv(netdev); + struct macb_queue *queue = bp->queues; + unsigned int q; + + if (!netif_running(netdev)) + return 0; pm_runtime_force_resume(dev); @@ -4275,9 +4297,21 @@ static int __maybe_unused macb_resume(struct device *dev) macb_writel(bp, IDR, MACB_BIT(WOL)); macb_writel(bp, WOL, 0); disable_irq_wake(bp->queues[0].irq); + } else { + macb_writel(bp, NCR, MACB_BIT(MPE)); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + napi_enable(>napi); + phy_resume(netdev->phydev); + phy_init_hw(netdev->phydev); + phy_start(netdev->phydev); } + bp->macbgem_ops.mog_init_rings(bp); + macb_init_hw(bp); + macb_set_rx_mode(netdev); netif_device_attach(netdev); + if (bp->ptp_info) + bp->ptp_info->ptp_init(netdev); return 0; } -- 2.7.4
Re: [GIT PULL] PHY: for 4.20 -rc
On Fri, Nov 23, 2018 at 04:00:08PM +0530, Kishon Vijay Abraham I wrote: > Hi Greg, > > Please find the pull request for 4.20 -rc below. > > It includes tuning parameter fix in qcom-qusb2 PHY driver, dt-bindings fix > for phy-qcom-qmp and a fix for randconfig error in uniphier-pcie. > > Consider merging this in the -rc cycle. > > Thanks > Kishon > > The following changes since commit 651022382c7f8da46cb4872a545ee1da6d097d2a: > > Linux 4.20-rc1 (2018-11-04 15:37:52 -0800) > > are available in the Git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git > tags/phy-for-4.20-rc Pulled and pushed out, thanks. greg k-h
[PATCH v2 4/4] net: macb: Add support for suspend/resume with full power down
When macb device is suspended and system is powered down, the clocks are removed and hence macb should be closed gracefully and restored upon resume. This patch does the same by switching off the net device, suspending phy and performing necessary cleanup of interrupts and BDs. Upon resume, all these are reinitialized again. Reset of macb device is done only when GEM is not a wake device. Even when gem is a wake device, tx queues can be stopped and ptp device can be closed (tsu clock will be disabled in pm_runtime_suspend) as wake event detection has no dependency on this. Signed-off-by: Kedareswara rao Appana Signed-off-by: Harini Katakam --- v2 changes: Fixed parameter passed to phy calls. drivers/net/ethernet/cadence/macb_main.c | 38 ++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 4b85ad7..dcb0194 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -4249,16 +4249,33 @@ static int __maybe_unused macb_suspend(struct device *dev) { struct net_device *netdev = dev_get_drvdata(dev); struct macb *bp = netdev_priv(netdev); + struct macb_queue *queue = bp->queues; + unsigned long flags; + unsigned int q; + + if (!netif_running(netdev)) + return 0; - netif_carrier_off(netdev); - netif_device_detach(netdev); if (bp->wol & MACB_WOL_ENABLED) { macb_writel(bp, IER, MACB_BIT(WOL)); macb_writel(bp, WOL, MACB_BIT(MAG)); enable_irq_wake(bp->queues[0].irq); + netif_device_detach(netdev); + } else { + netif_device_detach(netdev); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + napi_disable(>napi); + phy_stop(netdev->phydev); + phy_suspend(netdev->phydev); + spin_lock_irqsave(>lock, flags); + macb_reset_hw(bp); + spin_unlock_irqrestore(>lock, flags); } + netif_carrier_off(netdev); + if (bp->ptp_info) + bp->ptp_info->ptp_remove(netdev); pm_runtime_force_suspend(dev); return 0; @@ -4268,6 +4285,11 @@ static int __maybe_unused macb_resume(struct device *dev) { struct net_device *netdev = dev_get_drvdata(dev); struct macb *bp = netdev_priv(netdev); + struct macb_queue *queue = bp->queues; + unsigned int q; + + if (!netif_running(netdev)) + return 0; pm_runtime_force_resume(dev); @@ -4275,9 +4297,21 @@ static int __maybe_unused macb_resume(struct device *dev) macb_writel(bp, IDR, MACB_BIT(WOL)); macb_writel(bp, WOL, 0); disable_irq_wake(bp->queues[0].irq); + } else { + macb_writel(bp, NCR, MACB_BIT(MPE)); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + napi_enable(>napi); + phy_resume(netdev->phydev); + phy_init_hw(netdev->phydev); + phy_start(netdev->phydev); } + bp->macbgem_ops.mog_init_rings(bp); + macb_init_hw(bp); + macb_set_rx_mode(netdev); netif_device_attach(netdev); + if (bp->ptp_info) + bp->ptp_info->ptp_init(netdev); return 0; } -- 2.7.4
Re: [GIT PULL] FSI fixes for 4.20
On Mon, Nov 26, 2018 at 10:37:08AM +1100, Benjamin Herrenschmidt wrote: > Hi Greg ! > > Here are two very minor fixes for FSI. One from Arnd is a Kconfig fixup > and has been rusting away in my tree for a while (I had forgotten about > it). The other one just removes a duplicate #include, courtesy of > Brajeswar Ghosh. > > The following changes since commit 2e6e902d185027f8e3cb8b7305238f7e35d6a436: > > Linux 4.20-rc4 (2018-11-25 14:19:31 -0800) > > are available in the Git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/benh/linux-fsi.git > tags/fsi-updates-2018-11-26 Now pulled, thanks. greg k-h
Re: [GIT PULL] FSI fixes for 4.20
On Mon, Nov 26, 2018 at 10:37:08AM +1100, Benjamin Herrenschmidt wrote: > Hi Greg ! > > Here are two very minor fixes for FSI. One from Arnd is a Kconfig fixup > and has been rusting away in my tree for a while (I had forgotten about > it). The other one just removes a duplicate #include, courtesy of > Brajeswar Ghosh. > > The following changes since commit 2e6e902d185027f8e3cb8b7305238f7e35d6a436: > > Linux 4.20-rc4 (2018-11-25 14:19:31 -0800) > > are available in the Git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/benh/linux-fsi.git > tags/fsi-updates-2018-11-26 Now pulled, thanks. greg k-h
Re: [PATCH] Fonts: New Terminus large console font
On Sun, Nov 25, 2018 at 10:47:34PM -0500, nimrud wrote: > This patch adds an option to compile-in a high resolution and large > Terminus (ter16x32) bitmap console font for use with HiDPI and Retina screens. > > The font was convereted from standard Terminus ter-i32b.psf (size 16x32) > with the help of psftools and minor hand editing deleting useless characters. > > This patch is non-intrusive, no options are enabled by default so most > users won't notice a thing. > > I am placing my changes under the GPL 2.0 just as source Terminus font. > > Signed-off-by: Amanoel Dawod Also, your "From:" line on your email does not match this name, so that needs to be fixed before we could take the patch :( thanks, greg k-h
Re: [PATCH] Fonts: New Terminus large console font
On Sun, Nov 25, 2018 at 10:47:34PM -0500, nimrud wrote: > This patch adds an option to compile-in a high resolution and large > Terminus (ter16x32) bitmap console font for use with HiDPI and Retina screens. > > The font was convereted from standard Terminus ter-i32b.psf (size 16x32) > with the help of psftools and minor hand editing deleting useless characters. > > This patch is non-intrusive, no options are enabled by default so most > users won't notice a thing. > > I am placing my changes under the GPL 2.0 just as source Terminus font. > > Signed-off-by: Amanoel Dawod Also, your "From:" line on your email does not match this name, so that needs to be fixed before we could take the patch :( thanks, greg k-h
Re: [PATCH] Fonts: New Terminus large console font
On Sun, Nov 25, 2018 at 10:47:34PM -0500, nimrud wrote: > This patch adds an option to compile-in a high resolution and large > Terminus (ter16x32) bitmap console font for use with HiDPI and Retina screens. > > The font was convereted from standard Terminus ter-i32b.psf (size 16x32) > with the help of psftools and minor hand editing deleting useless characters. > > This patch is non-intrusive, no options are enabled by default so most > users won't notice a thing. > > I am placing my changes under the GPL 2.0 just as source Terminus font. > > Signed-off-by: Amanoel Dawod > --- > include/linux/font.h |8 +- > lib/fonts/Kconfig | 10 + > lib/fonts/Makefile|1 + > lib/fonts/font_ter16x32.c | 2072 + > lib/fonts/fonts.c |4 + > 5 files changed, 2092 insertions(+), 3 deletions(-) > create mode 100644 lib/fonts/font_ter16x32.c > > diff --git a/include/linux/font.h b/include/linux/font.h > index d6821769dd1e..8ab5192e8a13 100644 > --- a/include/linux/font.h > +++ b/include/linux/font.h > @@ -29,9 +29,10 @@ struct font_desc { > #define FONT10x18_IDX 5 > #define SUN8x16_IDX 6 > #define SUN12x22_IDX 7 > -#define ACORN8x8_IDX 8 > -#define MINI4x6_IDX 9 > -#define FONT6x10_IDX 10 > +#define TER16x32_IDX 8 > +#define ACORN8x8_IDX 9 > +#define MINI4x6_IDX 10 > +#define FONT6x10_IDX 11 By changing the font names, did you just break anything? Why not just add your new one at the end of the list? thanks, greg k-h
Re: [PATCH] Fonts: New Terminus large console font
On Sun, Nov 25, 2018 at 10:47:34PM -0500, nimrud wrote: > This patch adds an option to compile-in a high resolution and large > Terminus (ter16x32) bitmap console font for use with HiDPI and Retina screens. > > The font was convereted from standard Terminus ter-i32b.psf (size 16x32) > with the help of psftools and minor hand editing deleting useless characters. > > This patch is non-intrusive, no options are enabled by default so most > users won't notice a thing. > > I am placing my changes under the GPL 2.0 just as source Terminus font. > > Signed-off-by: Amanoel Dawod > --- > include/linux/font.h |8 +- > lib/fonts/Kconfig | 10 + > lib/fonts/Makefile|1 + > lib/fonts/font_ter16x32.c | 2072 + > lib/fonts/fonts.c |4 + > 5 files changed, 2092 insertions(+), 3 deletions(-) > create mode 100644 lib/fonts/font_ter16x32.c > > diff --git a/include/linux/font.h b/include/linux/font.h > index d6821769dd1e..8ab5192e8a13 100644 > --- a/include/linux/font.h > +++ b/include/linux/font.h > @@ -29,9 +29,10 @@ struct font_desc { > #define FONT10x18_IDX 5 > #define SUN8x16_IDX 6 > #define SUN12x22_IDX 7 > -#define ACORN8x8_IDX 8 > -#define MINI4x6_IDX 9 > -#define FONT6x10_IDX 10 > +#define TER16x32_IDX 8 > +#define ACORN8x8_IDX 9 > +#define MINI4x6_IDX 10 > +#define FONT6x10_IDX 11 By changing the font names, did you just break anything? Why not just add your new one at the end of the list? thanks, greg k-h
Re: linux-next: build warnings after merge of the cifs tree
Hi Kees, On Sun, 25 Nov 2018 21:48:10 -0800 Kees Cook wrote: > > On Sun, Nov 25, 2018 at 4:52 PM Stephen Rothwell > wrote: > > > > On Sun, 25 Nov 2018 18:31:40 -0600 Steve French wrote: > > > > > > > > Both of those cases are intentional fallthroughs and there are > > > existing comments in the code noting the reasons for them to > > > fallthrough > > > > > > (also can see the reasoning for these in the commits which introduced > > > them from Sachin c369c9a4a7c82) and dde2356c84662) > > > > I am not questioning that :-) > > > > The gcc warning can be turned off by adding a /* fall through */ > > comment at the point the fall through happens. Kees and others are > > working on the several hundred other places that need annotating. > > Right. The goal is to avoid adding any _new_ cases of this. :) > > > This one just popped up. > > It's already working! :) Thanks Stephen! Actually this one was the product of how I filter out warnings ... it was an old one, but the line numbers changed. I have now started ignoring these if just the line numbers change. -- Cheers, Stephen Rothwell pgp8Wp7Wp03Zp.pgp Description: OpenPGP digital signature
Re: linux-next: build warnings after merge of the cifs tree
Hi Kees, On Sun, 25 Nov 2018 21:48:10 -0800 Kees Cook wrote: > > On Sun, Nov 25, 2018 at 4:52 PM Stephen Rothwell > wrote: > > > > On Sun, 25 Nov 2018 18:31:40 -0600 Steve French wrote: > > > > > > > > Both of those cases are intentional fallthroughs and there are > > > existing comments in the code noting the reasons for them to > > > fallthrough > > > > > > (also can see the reasoning for these in the commits which introduced > > > them from Sachin c369c9a4a7c82) and dde2356c84662) > > > > I am not questioning that :-) > > > > The gcc warning can be turned off by adding a /* fall through */ > > comment at the point the fall through happens. Kees and others are > > working on the several hundred other places that need annotating. > > Right. The goal is to avoid adding any _new_ cases of this. :) > > > This one just popped up. > > It's already working! :) Thanks Stephen! Actually this one was the product of how I filter out warnings ... it was an old one, but the line numbers changed. I have now started ignoring these if just the line numbers change. -- Cheers, Stephen Rothwell pgp8Wp7Wp03Zp.pgp Description: OpenPGP digital signature
Re: [patch V2 21/28] x86/speculation: Prepare for conditional IBPB in switch_mm()
On Sun, 25 Nov 2018, Andi Kleen wrote: > On Sun, Nov 25, 2018 at 11:20:50PM +0100, Thomas Gleixner wrote: > > On Sun, 25 Nov 2018, Andi Kleen wrote: > > > > > > The current check whether two tasks belong to the same context is using > > > > the > > > > tasks context id. While correct, it's simpler to use the mm pointer > > > > because > > > > it allows to mangle the TIF_SPEC_IB bit into it. The context id based > > > > mechanism requires extra storage, which creates worse code. > > > > > > [We tried similar in some really early versions, but it was replaced > > > with the context id later.] > > > > > > One issue with using the pointer is that the pointer can be reused > > > when the original mm_struct is freed, and then gets reallocated > > > immediately to an attacker. Then the attacker may avoid the IBPB. > > > > > > Given it's probably hard to generate any reasonable leak bandwidth with > > > such a complex scenario, but it still seemed better to close the hole. > > > > Sorry, but that's really a purely academic exercise. > > Ok fair enough. I guess it's acceptable if you add a comment explaining it. Will do. Thanks, tglx
Re: [patch V2 21/28] x86/speculation: Prepare for conditional IBPB in switch_mm()
On Sun, 25 Nov 2018, Andi Kleen wrote: > On Sun, Nov 25, 2018 at 11:20:50PM +0100, Thomas Gleixner wrote: > > On Sun, 25 Nov 2018, Andi Kleen wrote: > > > > > > The current check whether two tasks belong to the same context is using > > > > the > > > > tasks context id. While correct, it's simpler to use the mm pointer > > > > because > > > > it allows to mangle the TIF_SPEC_IB bit into it. The context id based > > > > mechanism requires extra storage, which creates worse code. > > > > > > [We tried similar in some really early versions, but it was replaced > > > with the context id later.] > > > > > > One issue with using the pointer is that the pointer can be reused > > > when the original mm_struct is freed, and then gets reallocated > > > immediately to an attacker. Then the attacker may avoid the IBPB. > > > > > > Given it's probably hard to generate any reasonable leak bandwidth with > > > such a complex scenario, but it still seemed better to close the hole. > > > > Sorry, but that's really a purely academic exercise. > > Ok fair enough. I guess it's acceptable if you add a comment explaining it. Will do. Thanks, tglx
Re: [RESEND PATCH 0/7] Add some fixes and new feature for SPRD DMA
Hi Vinod, On Tue, 6 Nov 2018 at 13:01, Baolin Wang wrote: > > This patchset removes the direction usage from struct dma_slave_config, > and add one new field to save the direction. It also fixes some issues > for link-list transfer. Moreover this patchset adds new 2-stage transfer > support for our DMA. Any comments for this patch set? Thanks. > > Baolin Wang (1): > dmaengine: sprd: Remove direction usage from struct dma_slave_config > > Eric Long (6): > dmaengine: sprd: Get transfer residue depending on the transfer > direction > dmaengine: sprd: Fix the last link-list configuration > dmaengine: sprd: Set cur_desc as NULL when free or terminate one dma > channel > dmaengine: sprd: Support DMA link-list cyclic callback > dmaengine: sprd: Support DMA 2-stage transfer mode > dmaengine: sprd: Add me as one of the module authors > > drivers/dma/sprd-dma.c | 152 > +- > include/linux/dma/sprd-dma.h | 62 - > 2 files changed, 194 insertions(+), 20 deletions(-) > > -- > 1.7.9.5 > -- Baolin Wang Best Regards
Re: [RESEND PATCH 0/7] Add some fixes and new feature for SPRD DMA
Hi Vinod, On Tue, 6 Nov 2018 at 13:01, Baolin Wang wrote: > > This patchset removes the direction usage from struct dma_slave_config, > and add one new field to save the direction. It also fixes some issues > for link-list transfer. Moreover this patchset adds new 2-stage transfer > support for our DMA. Any comments for this patch set? Thanks. > > Baolin Wang (1): > dmaengine: sprd: Remove direction usage from struct dma_slave_config > > Eric Long (6): > dmaengine: sprd: Get transfer residue depending on the transfer > direction > dmaengine: sprd: Fix the last link-list configuration > dmaengine: sprd: Set cur_desc as NULL when free or terminate one dma > channel > dmaengine: sprd: Support DMA link-list cyclic callback > dmaengine: sprd: Support DMA 2-stage transfer mode > dmaengine: sprd: Add me as one of the module authors > > drivers/dma/sprd-dma.c | 152 > +- > include/linux/dma/sprd-dma.h | 62 - > 2 files changed, 194 insertions(+), 20 deletions(-) > > -- > 1.7.9.5 > -- Baolin Wang Best Regards
Re: [PATCH v2] PCI: assign bus numbers present in EA capability for bridges
Hi Bjorn / Sean, Any comments? Thanks, Sundeep On Mon, Nov 19, 2018 at 6:44 PM wrote: > > From: Subbaraya Sundeep > > As per the spec, bridges with EA capability work > with fixed secondary and subordinate bus numbers. > Hence assign bus numbers to bridges from EA if the > capability exists. > > Signed-off-by: Subbaraya Sundeep > --- > Changes for v2: > No changes just added Sean Stalley who did EA support for BARs. > > drivers/pci/probe.c | 58 > --- > include/uapi/linux/pci_regs.h | 6 + > 2 files changed, 60 insertions(+), 4 deletions(-) > > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c > index b1c05b5..f41d2e6 100644 > --- a/drivers/pci/probe.c > +++ b/drivers/pci/probe.c > @@ -1030,6 +1030,40 @@ static void pci_enable_crs(struct pci_dev *pdev) > > static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, > unsigned int available_buses); > +/* > + * pci_ea_fixed_busnrs() - Read fixed Secondary and Subordinate bus > + * numbers from EA capability. > + * @dev: Bridge with EA > + * @secondary: updated with secondary bus number in EA > + * @subordinate: updated with subordinate bus number in EA > + * > + * If it is a bridge with EA capability then fixed bus numbers are > + * read from EA capability list and secondary, subordinate reference > + * variables will be updated. Otherwise secondary and subordinate reference > + * variables will be zeroed. > + */ > +static void pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *secondary, > + u8 *subordinate) > +{ > + int ea; > + int offset; > + u32 dw; > + > + *secondary = *subordinate = 0; > + > + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) > + return; > + > + /* find PCI EA capability in list */ > + ea = pci_find_capability(dev, PCI_CAP_ID_EA); > + if (!ea) > + return; > + > + offset = ea + PCI_EA_FIRST_ENT; > + pci_read_config_dword(dev, offset, ); > + *secondary = dw & PCI_EA_SEC_BUS_MASK; > + *subordinate = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; > +} > > /* > * pci_scan_bridge_extend() - Scan buses behind a bridge > @@ -1064,6 +1098,8 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, > struct pci_dev *dev, > u16 bctl; > u8 primary, secondary, subordinate; > int broken = 0; > + u8 fixed_sec, fixed_sub; > + int next_busnr; > > /* > * Make sure the bridge is powered on to be able to access config > @@ -1163,17 +1199,25 @@ static int pci_scan_bridge_extend(struct pci_bus > *bus, struct pci_dev *dev, > /* Clear errors */ > pci_write_config_word(dev, PCI_STATUS, 0x); > > + /* read bus numbers from EA */ > + pci_ea_fixed_busnrs(dev, _sec, _sub); > + > + next_busnr = max + 1; > + /* Use secondary bus number in EA */ > + if (fixed_sec) > + next_busnr = fixed_sec; > + > /* > * Prevent assigning a bus number that already exists. > * This can happen when a bridge is hot-plugged, so in this > * case we only re-scan this bus. > */ > - child = pci_find_bus(pci_domain_nr(bus), max+1); > + child = pci_find_bus(pci_domain_nr(bus), next_busnr); > if (!child) { > - child = pci_add_new_bus(bus, dev, max+1); > + child = pci_add_new_bus(bus, dev, next_busnr); > if (!child) > goto out; > - pci_bus_insert_busn_res(child, max+1, > + pci_bus_insert_busn_res(child, next_busnr, > bus->busn_res.end); > } > max++; > @@ -1234,7 +1278,13 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, > struct pci_dev *dev, > max += i; > } > > - /* Set subordinate bus number to its real value */ > + /* > +* Set subordinate bus number to its real value. > +* If fixed subordinate bus number exists from EA > +* capability then use it. > +*/ > + if (fixed_sub) > + max = fixed_sub; > pci_bus_update_busn_res_end(child, max); > pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); > } > diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h > index e1e9888..c3d0904 100644 > --- a/include/uapi/linux/pci_regs.h > +++ b/include/uapi/linux/pci_regs.h > @@ -372,6 +372,12 @@ > #define PCI_EA_FIRST_ENT_BRIDGE8 /* First EA Entry for Bridges > */ > #define
Re: [PATCH v2] PCI: assign bus numbers present in EA capability for bridges
Hi Bjorn / Sean, Any comments? Thanks, Sundeep On Mon, Nov 19, 2018 at 6:44 PM wrote: > > From: Subbaraya Sundeep > > As per the spec, bridges with EA capability work > with fixed secondary and subordinate bus numbers. > Hence assign bus numbers to bridges from EA if the > capability exists. > > Signed-off-by: Subbaraya Sundeep > --- > Changes for v2: > No changes just added Sean Stalley who did EA support for BARs. > > drivers/pci/probe.c | 58 > --- > include/uapi/linux/pci_regs.h | 6 + > 2 files changed, 60 insertions(+), 4 deletions(-) > > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c > index b1c05b5..f41d2e6 100644 > --- a/drivers/pci/probe.c > +++ b/drivers/pci/probe.c > @@ -1030,6 +1030,40 @@ static void pci_enable_crs(struct pci_dev *pdev) > > static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, > unsigned int available_buses); > +/* > + * pci_ea_fixed_busnrs() - Read fixed Secondary and Subordinate bus > + * numbers from EA capability. > + * @dev: Bridge with EA > + * @secondary: updated with secondary bus number in EA > + * @subordinate: updated with subordinate bus number in EA > + * > + * If it is a bridge with EA capability then fixed bus numbers are > + * read from EA capability list and secondary, subordinate reference > + * variables will be updated. Otherwise secondary and subordinate reference > + * variables will be zeroed. > + */ > +static void pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *secondary, > + u8 *subordinate) > +{ > + int ea; > + int offset; > + u32 dw; > + > + *secondary = *subordinate = 0; > + > + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) > + return; > + > + /* find PCI EA capability in list */ > + ea = pci_find_capability(dev, PCI_CAP_ID_EA); > + if (!ea) > + return; > + > + offset = ea + PCI_EA_FIRST_ENT; > + pci_read_config_dword(dev, offset, ); > + *secondary = dw & PCI_EA_SEC_BUS_MASK; > + *subordinate = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; > +} > > /* > * pci_scan_bridge_extend() - Scan buses behind a bridge > @@ -1064,6 +1098,8 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, > struct pci_dev *dev, > u16 bctl; > u8 primary, secondary, subordinate; > int broken = 0; > + u8 fixed_sec, fixed_sub; > + int next_busnr; > > /* > * Make sure the bridge is powered on to be able to access config > @@ -1163,17 +1199,25 @@ static int pci_scan_bridge_extend(struct pci_bus > *bus, struct pci_dev *dev, > /* Clear errors */ > pci_write_config_word(dev, PCI_STATUS, 0x); > > + /* read bus numbers from EA */ > + pci_ea_fixed_busnrs(dev, _sec, _sub); > + > + next_busnr = max + 1; > + /* Use secondary bus number in EA */ > + if (fixed_sec) > + next_busnr = fixed_sec; > + > /* > * Prevent assigning a bus number that already exists. > * This can happen when a bridge is hot-plugged, so in this > * case we only re-scan this bus. > */ > - child = pci_find_bus(pci_domain_nr(bus), max+1); > + child = pci_find_bus(pci_domain_nr(bus), next_busnr); > if (!child) { > - child = pci_add_new_bus(bus, dev, max+1); > + child = pci_add_new_bus(bus, dev, next_busnr); > if (!child) > goto out; > - pci_bus_insert_busn_res(child, max+1, > + pci_bus_insert_busn_res(child, next_busnr, > bus->busn_res.end); > } > max++; > @@ -1234,7 +1278,13 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, > struct pci_dev *dev, > max += i; > } > > - /* Set subordinate bus number to its real value */ > + /* > +* Set subordinate bus number to its real value. > +* If fixed subordinate bus number exists from EA > +* capability then use it. > +*/ > + if (fixed_sub) > + max = fixed_sub; > pci_bus_update_busn_res_end(child, max); > pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); > } > diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h > index e1e9888..c3d0904 100644 > --- a/include/uapi/linux/pci_regs.h > +++ b/include/uapi/linux/pci_regs.h > @@ -372,6 +372,12 @@ > #define PCI_EA_FIRST_ENT_BRIDGE8 /* First EA Entry for Bridges > */ > #define
Re: [PATCH v7 0/2] mtd: rawnand: meson: add Amlogic NAND driver support
Hi Boris and Miquel, How about the v7 patch? On 2018/11/17 0:40, Jianxin Pan wrote: These two patches try to add initial NAND driver support for Amlogic Meson SoCs, current it has been tested on GXL(p212) and AXG(s400) platform. Changes since V6 at [7] - use timings->tBERS_max as the maximum time out, delete NFC_CMD_RB_TIMEOUT - fix nand_rw_cmd and support small block flash and which row address less than 3 - fix coding style - replace readl/writel_* with readl/writel_relaxed* - delete ECC_SET_PROTECTED_OOB_BYTE and ECC_GET_PROTECTED_OOB_BYTE - implement dma access for read_buf and write_buf, more efficient. - delete waiting dma finish in write process and let NAND_CMD_PAGEPROG and RB command go on queuing - add waiting the completed flag of last ecc page be set, for more strict
Re: [PATCH v7 0/2] mtd: rawnand: meson: add Amlogic NAND driver support
Hi Boris and Miquel, How about the v7 patch? On 2018/11/17 0:40, Jianxin Pan wrote: These two patches try to add initial NAND driver support for Amlogic Meson SoCs, current it has been tested on GXL(p212) and AXG(s400) platform. Changes since V6 at [7] - use timings->tBERS_max as the maximum time out, delete NFC_CMD_RB_TIMEOUT - fix nand_rw_cmd and support small block flash and which row address less than 3 - fix coding style - replace readl/writel_* with readl/writel_relaxed* - delete ECC_SET_PROTECTED_OOB_BYTE and ECC_GET_PROTECTED_OOB_BYTE - implement dma access for read_buf and write_buf, more efficient. - delete waiting dma finish in write process and let NAND_CMD_PAGEPROG and RB command go on queuing - add waiting the completed flag of last ecc page be set, for more strict
Re: [PATCH 5/5] power: supply: sc27xx: Save last battery capacity
Hi Pavel, On Mon, 26 Nov 2018 at 05:48, Pavel Machek wrote: > > Hi! > > > Our charger manager can optimize the battery capacity periodically, so > > we can save last battery capacity into registers. Then next system > > power-on, we can read the last saved battery capacity as the initial > > battery capacity, which can make the battery capacity more accurate. > > > > Signed-off-by: Yuanjiang Yu > > Signed-off-by: Baolin Wang > > --- > > drivers/power/supply/sc27xx_fuel_gauge.c | 143 > > +- > > 1 file changed, 142 insertions(+), 1 deletion(-) > > > > > +static int sc27xx_fgu_set_property(struct power_supply *psy, > > +enum power_supply_property psp, > > +const union power_supply_propval *val) > > +{ > > + struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); > > + int ret; > > + > > + mutex_lock(>lock); > > + > > + switch (psp) { > > + case POWER_SUPPLY_PROP_CAPACITY: > > + ret = sc27xx_fgu_save_last_cap(data, val->intval); > > + if (ret < 0) > > + dev_err(data->dev, "failed to save battery > > capacity\n"); > > + break; > > + > > + default: > > + ret = -EINVAL; > > + } > > + > > + mutex_unlock(>lock); > > + return ret; > > if (psp != ) return -EINVAL; And you can do that outside > lock... > > Ok, OTOH this is easier to extend in future. Do you expect more > writable properties? Until now I think there are no writable properties, I think I can change it like you suggested. > > > +static int sc27xx_fgu_property_is_writeable(struct power_supply *psy, > > + enum power_supply_property psp) > > +{ > > + switch (psp) { > > + case POWER_SUPPLY_PROP_CAPACITY: > > + return 1; > > + > > + default: > > + return 0; > > + } > > +} > > > Same here. return psp == POWER_SUPPLY_PROP_CAPACITY; really looks > strange written like this. Sure. Thanks. -- Baolin Wang Best Regards
Re: [PATCH 5/5] power: supply: sc27xx: Save last battery capacity
Hi Pavel, On Mon, 26 Nov 2018 at 05:48, Pavel Machek wrote: > > Hi! > > > Our charger manager can optimize the battery capacity periodically, so > > we can save last battery capacity into registers. Then next system > > power-on, we can read the last saved battery capacity as the initial > > battery capacity, which can make the battery capacity more accurate. > > > > Signed-off-by: Yuanjiang Yu > > Signed-off-by: Baolin Wang > > --- > > drivers/power/supply/sc27xx_fuel_gauge.c | 143 > > +- > > 1 file changed, 142 insertions(+), 1 deletion(-) > > > > > +static int sc27xx_fgu_set_property(struct power_supply *psy, > > +enum power_supply_property psp, > > +const union power_supply_propval *val) > > +{ > > + struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); > > + int ret; > > + > > + mutex_lock(>lock); > > + > > + switch (psp) { > > + case POWER_SUPPLY_PROP_CAPACITY: > > + ret = sc27xx_fgu_save_last_cap(data, val->intval); > > + if (ret < 0) > > + dev_err(data->dev, "failed to save battery > > capacity\n"); > > + break; > > + > > + default: > > + ret = -EINVAL; > > + } > > + > > + mutex_unlock(>lock); > > + return ret; > > if (psp != ) return -EINVAL; And you can do that outside > lock... > > Ok, OTOH this is easier to extend in future. Do you expect more > writable properties? Until now I think there are no writable properties, I think I can change it like you suggested. > > > +static int sc27xx_fgu_property_is_writeable(struct power_supply *psy, > > + enum power_supply_property psp) > > +{ > > + switch (psp) { > > + case POWER_SUPPLY_PROP_CAPACITY: > > + return 1; > > + > > + default: > > + return 0; > > + } > > +} > > > Same here. return psp == POWER_SUPPLY_PROP_CAPACITY; really looks > strange written like this. Sure. Thanks. -- Baolin Wang Best Regards
Re: [PATCH 3/5] power: supply: sc27xx: Add fuel gauge low voltage alarm
Hi Pavel, On Mon, 26 Nov 2018 at 05:45, Pavel Machek wrote: > > On Wed 2018-11-14 17:07:06, Baolin Wang wrote: > > From: Yuanjiang Yu > > > > Add low voltage alarm support to make sure the battery capacity > > more accurate in lower voltage stage. > > > > Signed-off-by: Yuanjiang Yu > > Signed-off-by: Baolin Wang > > Should we also shut down the system when that happens, as battery is > empty? > > Or is there any lower threshold when we should do the shutdown? We do not shutdown the system when battery is empty in fuel gauge driver, instead we should do that in charger manager service or other upper layers. In fuel gauge driver, we should just supply the accurate battery capacity for upper layer. -- Baolin Wang Best Regards
Re: [PATCH 3/5] power: supply: sc27xx: Add fuel gauge low voltage alarm
Hi Pavel, On Mon, 26 Nov 2018 at 05:45, Pavel Machek wrote: > > On Wed 2018-11-14 17:07:06, Baolin Wang wrote: > > From: Yuanjiang Yu > > > > Add low voltage alarm support to make sure the battery capacity > > more accurate in lower voltage stage. > > > > Signed-off-by: Yuanjiang Yu > > Signed-off-by: Baolin Wang > > Should we also shut down the system when that happens, as battery is > empty? > > Or is there any lower threshold when we should do the shutdown? We do not shutdown the system when battery is empty in fuel gauge driver, instead we should do that in charger manager service or other upper layers. In fuel gauge driver, we should just supply the accurate battery capacity for upper layer. -- Baolin Wang Best Regards
[PATCH] RISC-V: Make BSS section as the last section in vmlinux.lds.S
The objcopy only emits loadable sections when creating flat kernel Image. To have minimal possible size of flat kernel Image, we should have all non-loadable sections after loadable sections. Currently, execption table section (loadable section) is after BSS section (non-loadable section) in the RISC-V vmlinux.lds.S. This is not optimal for having minimal flat kernel Image size hence this patch makes BSS section as the last section in RISC-V vmlinux.lds.S. In addition, we make BSS section aligned to 16byte instead of PAGE aligned which further reduces flat kernel Image size by few KBs. The flat kernel Image size of Linux-4.20-rc4 using GCC 8.2.0 is 8819980 bytes with current RISC-V vmlinux.lds.S and it reduces to 7991740 bytes with this patch applied using GCC 8.2.0. In summary, this patch reduces Linux-4.20-rc4 flat kernel Image size by 809 KB. Signed-off-by: Anup Patel --- arch/riscv/kernel/vmlinux.lds.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 65df1dfdc303..cc99eed44931 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -74,8 +74,6 @@ SECTIONS *(.sbss*) } - BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) - EXCEPTION_TABLE(0x10) NOTES @@ -83,6 +81,8 @@ SECTIONS *(.rel.dyn*) } + BSS_SECTION(0x10, 0x10, 0x10) + _end = .; STABS_DEBUG -- 2.17.1
[PATCH] RISC-V: Make BSS section as the last section in vmlinux.lds.S
The objcopy only emits loadable sections when creating flat kernel Image. To have minimal possible size of flat kernel Image, we should have all non-loadable sections after loadable sections. Currently, execption table section (loadable section) is after BSS section (non-loadable section) in the RISC-V vmlinux.lds.S. This is not optimal for having minimal flat kernel Image size hence this patch makes BSS section as the last section in RISC-V vmlinux.lds.S. In addition, we make BSS section aligned to 16byte instead of PAGE aligned which further reduces flat kernel Image size by few KBs. The flat kernel Image size of Linux-4.20-rc4 using GCC 8.2.0 is 8819980 bytes with current RISC-V vmlinux.lds.S and it reduces to 7991740 bytes with this patch applied using GCC 8.2.0. In summary, this patch reduces Linux-4.20-rc4 flat kernel Image size by 809 KB. Signed-off-by: Anup Patel --- arch/riscv/kernel/vmlinux.lds.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 65df1dfdc303..cc99eed44931 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -74,8 +74,6 @@ SECTIONS *(.sbss*) } - BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) - EXCEPTION_TABLE(0x10) NOTES @@ -83,6 +81,8 @@ SECTIONS *(.rel.dyn*) } + BSS_SECTION(0x10, 0x10, 0x10) + _end = .; STABS_DEBUG -- 2.17.1
Re: RFC: script to convert vsprintf uses of %pf to %ps and %pF to %pS
And I forgot to actually Cc Petr and Steven... Top-posting. --- Hi, Cc-ing Petr and Steven On (11/25/18 01:13), Joe Perches wrote: > commit 04b8eb7a4ccd ("symbol lookup: introduce > dereference_symbol_descriptor()}" > > deprecated vsprintf extension %pf and %pF. > > There are approximately these total uses of the symbolic > lookup vsprintf extensions %p[SsFf]: > > $ git grep '".*[^%]%p[SsFf]' | \ > grep -oh '%p[SsFf]' | sort | uniq -c | sort -rn > 231 %pS > 65 %ps > 60 %pf > 47 %pF I didn't bother to remove "pf/pF" because I didn't want to count on: a) everyone running checkpatch.pl b) everyone testing all printk-s they added I guess pf/pF still can sneak in. But I don't have a really strong opinion on this. If general consensus is that we shall remove deprecated specifiers, then I'm fine. > which is about a 3:1 ratio favoring %pS > > so a script to convert all the %pf uses to %ps and %pF uses to %pS > could be useful. > > There are a few files that appear should not be converted. > > $ git grep -w --name-only -i '%pf'| \ > grep -vP '^(?:Documentation|tools|include/linux/freezer.h)'| \ > xargs sed -i -e 's/%pf/%ps/g' -e 's/%pF/%pS/g' > > If that script above is run, it leaves the following patch > to be applied: After running this script I still have a bunch of leftovers: // // these two are probably not really relevant, but still - %pF/%pf // tools/lib/traceevent/event-parse.c: if (asprintf(, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0) tools/lib/traceevent/event-parse.c: if (asprintf(, "%s: %s", "%pf", printk->printk) < 0) arch/um/kernel/sysrq.c: pr_info(" [<%08lx>] %s%pF\n", address, reliable ? "" : "? ", arch/x86/xen/multicalls.c: printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n", kernel/async.c: pr_debug("calling %lli_%pF @ %i\n", kernel/async.c: pr_debug("initcall %lli_%pF returned 0 after %lld usecs\n", -ss
Re: RFC: script to convert vsprintf uses of %pf to %ps and %pF to %pS
And I forgot to actually Cc Petr and Steven... Top-posting. --- Hi, Cc-ing Petr and Steven On (11/25/18 01:13), Joe Perches wrote: > commit 04b8eb7a4ccd ("symbol lookup: introduce > dereference_symbol_descriptor()}" > > deprecated vsprintf extension %pf and %pF. > > There are approximately these total uses of the symbolic > lookup vsprintf extensions %p[SsFf]: > > $ git grep '".*[^%]%p[SsFf]' | \ > grep -oh '%p[SsFf]' | sort | uniq -c | sort -rn > 231 %pS > 65 %ps > 60 %pf > 47 %pF I didn't bother to remove "pf/pF" because I didn't want to count on: a) everyone running checkpatch.pl b) everyone testing all printk-s they added I guess pf/pF still can sneak in. But I don't have a really strong opinion on this. If general consensus is that we shall remove deprecated specifiers, then I'm fine. > which is about a 3:1 ratio favoring %pS > > so a script to convert all the %pf uses to %ps and %pF uses to %pS > could be useful. > > There are a few files that appear should not be converted. > > $ git grep -w --name-only -i '%pf'| \ > grep -vP '^(?:Documentation|tools|include/linux/freezer.h)'| \ > xargs sed -i -e 's/%pf/%ps/g' -e 's/%pF/%pS/g' > > If that script above is run, it leaves the following patch > to be applied: After running this script I still have a bunch of leftovers: // // these two are probably not really relevant, but still - %pF/%pf // tools/lib/traceevent/event-parse.c: if (asprintf(, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0) tools/lib/traceevent/event-parse.c: if (asprintf(, "%s: %s", "%pf", printk->printk) < 0) arch/um/kernel/sysrq.c: pr_info(" [<%08lx>] %s%pF\n", address, reliable ? "" : "? ", arch/x86/xen/multicalls.c: printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n", kernel/async.c: pr_debug("calling %lli_%pF @ %i\n", kernel/async.c: pr_debug("initcall %lli_%pF returned 0 after %lld usecs\n", -ss
Re: [PATCH 2/2] cpufreq: imx6q: save one condition block for normal case of nvmem read
On 26-11-18, 02:59, Anson Huang wrote: > Put return value checks of calling imx6ul_opp_check_speed_grading() > into one block to save one condition block for normal case. > > Signed-off-by: Anson Huang > --- > drivers/cpufreq/imx6q-cpufreq.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c > index 8cb9683..9fedf62 100644 > --- a/drivers/cpufreq/imx6q-cpufreq.c > +++ b/drivers/cpufreq/imx6q-cpufreq.c > @@ -405,9 +405,10 @@ static int imx6q_cpufreq_probe(struct platform_device > *pdev) > if (of_machine_is_compatible("fsl,imx6ul") || > of_machine_is_compatible("fsl,imx6ull")) { > ret = imx6ul_opp_check_speed_grading(cpu_dev); > - if (ret == -EPROBE_DEFER) > - return ret; > if (ret) { > + if (ret == -EPROBE_DEFER) > + return ret; > + > dev_err(cpu_dev, "failed to read ocotp: %d\n", > ret); > return ret; Acked-by: Viresh Kumar -- viresh
Re: [PATCH 2/2] cpufreq: imx6q: save one condition block for normal case of nvmem read
On 26-11-18, 02:59, Anson Huang wrote: > Put return value checks of calling imx6ul_opp_check_speed_grading() > into one block to save one condition block for normal case. > > Signed-off-by: Anson Huang > --- > drivers/cpufreq/imx6q-cpufreq.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c > index 8cb9683..9fedf62 100644 > --- a/drivers/cpufreq/imx6q-cpufreq.c > +++ b/drivers/cpufreq/imx6q-cpufreq.c > @@ -405,9 +405,10 @@ static int imx6q_cpufreq_probe(struct platform_device > *pdev) > if (of_machine_is_compatible("fsl,imx6ul") || > of_machine_is_compatible("fsl,imx6ull")) { > ret = imx6ul_opp_check_speed_grading(cpu_dev); > - if (ret == -EPROBE_DEFER) > - return ret; > if (ret) { > + if (ret == -EPROBE_DEFER) > + return ret; > + > dev_err(cpu_dev, "failed to read ocotp: %d\n", > ret); > return ret; Acked-by: Viresh Kumar -- viresh
Re: [PATCH 1/2] cpufreq: imx6q: remove unused code
On 26-11-18, 02:59, Anson Huang wrote: > In voltage scale down path, the return value is NOT > used at all, remove them to simplify the code. > > Signed-off-by: Anson Huang > --- > drivers/cpufreq/imx6q-cpufreq.c | 12 +++- > 1 file changed, 3 insertions(+), 9 deletions(-) > > diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c > index d8c3595..8cb9683 100644 > --- a/drivers/cpufreq/imx6q-cpufreq.c > +++ b/drivers/cpufreq/imx6q-cpufreq.c > @@ -177,22 +177,16 @@ static int imx6q_set_target(struct cpufreq_policy > *policy, unsigned int index) > /* scaling down? scale voltage after frequency */ > if (new_freq < old_freq) { > ret = regulator_set_voltage_tol(arm_reg, volt, 0); > - if (ret) { > + if (ret) > dev_warn(cpu_dev, >"failed to scale vddarm down: %d\n", ret); > - ret = 0; > - } > ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], > 0); > - if (ret) { > + if (ret) > dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", > ret); > - ret = 0; > - } > if (!IS_ERR(pu_reg)) { > ret = regulator_set_voltage_tol(pu_reg, > imx6_soc_volt[index], 0); > - if (ret) { > + if (ret) > dev_warn(cpu_dev, "failed to scale vddpu down: > %d\n", ret); > - ret = 0; > - } > } > } > Acked-by: Viresh Kumar -- viresh
Re: [PATCH 1/2] cpufreq: imx6q: remove unused code
On 26-11-18, 02:59, Anson Huang wrote: > In voltage scale down path, the return value is NOT > used at all, remove them to simplify the code. > > Signed-off-by: Anson Huang > --- > drivers/cpufreq/imx6q-cpufreq.c | 12 +++- > 1 file changed, 3 insertions(+), 9 deletions(-) > > diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c > index d8c3595..8cb9683 100644 > --- a/drivers/cpufreq/imx6q-cpufreq.c > +++ b/drivers/cpufreq/imx6q-cpufreq.c > @@ -177,22 +177,16 @@ static int imx6q_set_target(struct cpufreq_policy > *policy, unsigned int index) > /* scaling down? scale voltage after frequency */ > if (new_freq < old_freq) { > ret = regulator_set_voltage_tol(arm_reg, volt, 0); > - if (ret) { > + if (ret) > dev_warn(cpu_dev, >"failed to scale vddarm down: %d\n", ret); > - ret = 0; > - } > ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], > 0); > - if (ret) { > + if (ret) > dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", > ret); > - ret = 0; > - } > if (!IS_ERR(pu_reg)) { > ret = regulator_set_voltage_tol(pu_reg, > imx6_soc_volt[index], 0); > - if (ret) { > + if (ret) > dev_warn(cpu_dev, "failed to scale vddpu down: > %d\n", ret); > - ret = 0; > - } > } > } > Acked-by: Viresh Kumar -- viresh
Re: [PATCH V2 2/2] base/drivers/arch_topology: Default dmips-mhz if they are not set in DT
On 23-11-18, 11:32, Daniel Lezcano wrote: > On 23/11/2018 11:04, Viresh Kumar wrote: > > On 22-11-18, 13:36, Daniel Lezcano wrote: > >> In the case of asymmetric SoC with the same micro-architecture, we > >> have a group of CPUs with smaller OPPs than the other group. One > >> example is the 96boards dragonboard 820c. There is no dmips/MHz > >> difference between both groups, so no need to specify the values in > >> the DT. Unfortunately, without these defined, there is no scaling > >> capacity computation triggered, so we need to write > >> 'capacity-dmips-mhz' for each CPU with the same value in order to > >> force the scaled capacity computation. > >> > >> Fix this by setting a default capacity to SCHED_CAPACITY_SCALE, if no > >> 'capacity-dmips-mhz' is defined in the DT. > > > > We aren't doing this anymore. You should rather explain that we just > > allocate raw_capacity now and rest is left for > > init_cpu_capacity_callback() to fix. > > What about? > > "In the case of asymmetric SoC with the same micro-architecture, we > have a group of CPUs with smaller OPPs than the other group. One > example is the 96boards dragonboard 820c. There is no dmips/MHz > difference between both groups, so no need to specify the values in > the DT. Unfortunately, without these defined, there is no scaling > capacity computation triggered, so we need to write > 'capacity-dmips-mhz' for each CPU with the same value in order to > force the scaled capacity computation. > > In order to fix this situation, allocate 'raw_capacity' so the pointer > is set and the init_cpu_capacity_callback() function can be called." LGTM -- viresh
Re: [PATCH V2 2/2] base/drivers/arch_topology: Default dmips-mhz if they are not set in DT
On 23-11-18, 11:32, Daniel Lezcano wrote: > On 23/11/2018 11:04, Viresh Kumar wrote: > > On 22-11-18, 13:36, Daniel Lezcano wrote: > >> In the case of asymmetric SoC with the same micro-architecture, we > >> have a group of CPUs with smaller OPPs than the other group. One > >> example is the 96boards dragonboard 820c. There is no dmips/MHz > >> difference between both groups, so no need to specify the values in > >> the DT. Unfortunately, without these defined, there is no scaling > >> capacity computation triggered, so we need to write > >> 'capacity-dmips-mhz' for each CPU with the same value in order to > >> force the scaled capacity computation. > >> > >> Fix this by setting a default capacity to SCHED_CAPACITY_SCALE, if no > >> 'capacity-dmips-mhz' is defined in the DT. > > > > We aren't doing this anymore. You should rather explain that we just > > allocate raw_capacity now and rest is left for > > init_cpu_capacity_callback() to fix. > > What about? > > "In the case of asymmetric SoC with the same micro-architecture, we > have a group of CPUs with smaller OPPs than the other group. One > example is the 96boards dragonboard 820c. There is no dmips/MHz > difference between both groups, so no need to specify the values in > the DT. Unfortunately, without these defined, there is no scaling > capacity computation triggered, so we need to write > 'capacity-dmips-mhz' for each CPU with the same value in order to > force the scaled capacity computation. > > In order to fix this situation, allocate 'raw_capacity' so the pointer > is set and the init_cpu_capacity_callback() function can be called." LGTM -- viresh